Appearance
Development & testing
For developers
Working on the plugin itself: the local stack, quality gates, tests, assets and releases. Branch and commit rules are also kept in CONTRIBUTING.md in the repository.
Local stack
The repository ships its own Docker stack (docker-compose.yml, Dockerfile, Makefile; service shopware, image based on dockware/shopware:6.7.8.0). From the plugin root:
bash
make up # start the stack and prepare the project
make shell # bash inside the container
make help # every target| Target | Does |
|---|---|
up / down / restart / build | Start, stop, restart, rebuild the container |
shell, plugin-list | Shell in the container; list plugins |
test | PHPUnit (phpunit.dist.xml); filter with make test FILTER=SomeTest |
test-coverage | Coverage report (text, clover, HTML) |
analyse | PHPStan (phpstan.dist.neon), src/ only |
cs / cs-fix | php-cs-fixer dry-run / apply |
validate-plugin | shopware-cli extension validate --full --store-compliance |
zip | Distributable archive into build/ (shopware-cli extension zip --release) |
changelog | Render the changelog as the Shopware Store would |
cli | Any shopware-cli command: make cli ARGS="--version" |
fixture-load, resync, prepare | Load fixtures; sync the config/ directory into the project; full preparation |
Inside an existing Shopware project instead, the plugin lives in custom/static-plugins/KmhClickAndPickSW (or custom/plugins/).
Quality gates
Run before every push:
bash
make cs-fix && make analyse && make test- PHPStan level 9 on
src/, zero errors. - php-cs-fixer clean (
.php-cs-fixer.dist.php); aphpcs.dist.xmlruleset is also included. - PHPUnit green at 100 % line coverage.
CI (.github/workflows/php.yml) runs: composer validate → PHP lint → PHPStan → php-cs-fixer dry-run → PHPUnit without the kernel group → coverage-check … 100.
Tests
tests/Unit/mirrorssrc/; plainTestCasewith mocks, no kernel.tests/Integration/is kernel-backed and tagged#[Group('kernel')]— currentlyCheckout/Cart/CartValidationTest. It needs a booted Shopware with a database (make testin the stack).- CI excludes the kernel group:
--exclude-group kernel. beStrictAboutCoverageMetadatais on: every test declares#[CoversClass]/#[UsesClass].- Coverage counts
src/exceptMigration/,Resources/,DependencyInjection/,Entity/and the plugin bootstrap.
Administration logic has a Jest spec next to the code (kmh-order-pickup-info/pickup-view.spec.js).
Assets
The built Administration (src/Resources/public/administration/) and Storefront (src/Resources/app/storefront/dist/) assets are committed and generated — never edit them by hand. Rebuild after changing src/Resources/app/** or after renaming the plugin:
bash
# only this plugin, from the host
shopware-cli extension build .
# or the whole project, inside Shopware
bin/build-administration.sh && bin/build-storefront.shThen publish them in the shop: bin/console assets:install, bin/console theme:compile, bin/console cache:clear.
A stale build is the usual reason the Pickup Locations menu or the checkout fields are missing — the entry name must be kmh-click-and-pick-s-w.
Conventions
- Feature-first modules: keep a change inside its module and reach other modules through a service.
- New DAL entities go under
src/Entity/…and are auto-tagged. If you add a constructor-injected*Interfacewith a single implementation, add an explicitalias:— Symfony doesn't auto-alias. - Pickup times are local wall-clock in the location's zone: use
PickupLocationAvailabilityService/PickupTimeSlotService, don't re-implement time-zone logic. - Schema changes need a new migration under
src/Migration/with idempotent DDL (IF NOT EXISTS, column/index guards). Don't edit a released migration — installs that already ran it won't pick up the change. - A new table with a foreign key to a plugin table must be added to the drop list in
KmhClickAndPickSW::uninstall()(children before parents). - Conventional Commits; branch off
develop(feature/…,fix/…);mainis the release branch. - Specification work lives in
openspec/(baseline specs and change proposals).
Releasing
- Bump
versionincomposer.jsonand add aCHANGELOG.mdsection. - Rebuild the assets and run the quality gates.
make validate-plugin, thenmake zip.
Debugging
| Look at | For |
|---|---|
sales_channel_api_context.payload (pickupLocationId, pickupTime, pickupComment) | The in-progress checkout selection |
kmh_order_pickup_location / order.extensions.kmhPickupLocation | What was stored with an order |
var/log/<env>-<date>.log | Notification problems — the flow actions log and swallow them (invalid email, missing template, mail or SMS errors, no phone number) |
Browser network tab: …/pickup-locations and …/slots | The <option> HTML the checkout receives |