DEV Community

Ingo Steinke
Ingo Steinke

Posted on

Shopware dev productivity and plugin validation

Finally, let me share some more things that I learned or rediscovered when validating and publishing a Symfony plugin to the Shopware marketplace:

We should make sure that our local setup meets the requirements: use PhpStorm with all required plugins and language support

  • PHP
  • Symfony
  • Shopware

Customize the IDE

The default directory tree view in the current PhpStorm version adds the challenge of verifying paths, as the minimalistic flat design makes the directory structure hard to discern. At least there is an appearance setting to bring back the vertical helper lines ("tree indent guides"). But can you tell if the import path in routes.xml is correct in the following screenshot?

PhpStorm screenshot with tree indent guides

Screenshot: the directory structure can be hard to discern in PhpStorm.

Use templates and quality tools...

... but without repeating other people's mistakes. Not only renowned community sites like StackOverflow are full of outdated or mismatching examples.

Official coding assistance like plugin create or theme create can also create code that does not fit our needs or that contains errors.

Cypress, Jest, and PHPUnit

See Shopware developers documentation: Extensions: Testing for best practices to use Cypress, Jest and PHPUnit to test Shopware 6 extensions without writing everything from scratch. The Shopware platform code contains test configurations we can reuse and extend as developers. The test suite is built on top of Cypress and some plugins like cypress-select-tests, cypress-log-to-output, and cypress-file-upload.

Minimalism vs. overwhelmingly explicit boilerplate code

While learning, we might get overwhelmed by an overload of what seems to be verbose boilerplate code without an actual purpose. Many tutorials don't make much sense except for the tutors who conceived them. This is why we must build our own working experiments and add our purpose! Also, there is often a lot of optional explicit code that we would not necessarily need to write in production projects thanks to default values, autowiring and code generating assistants, but which might help us understand what is going on thanks to its verbose explicitness. Verbose definitions and annotations might also improve IDE autocompletion and inspection!

Performance and customizability vs. simplicity

Another reason for verbosity and redundancy: if I understood their tutorials correctly, Shopware prioritised performance/speed optimization over convenience/developer experience in certain cases.

Other redundancies are optional if we don't want to change or extend the implicit defaults.

For example, creating a custom Entity class, as well as a custom EntityCollection class, is highly recommended but optional. Both will be replaced with generic classes otherwise, using instances of ArrayEntity instead of our own Entity collections.

A minimal custom entity definition

The most minimal example could be extended from an auto-generated theme stub, adding a database migration, an Entity Definition class, and extending an existing twig template to display our custom data in the storefront. That's it! In addition, we can, but we don't have to, define our own entity class and entity collection class, an entity repository route to add interactive frontend code to connect to an API to retrieve specific data dynamically, like the Shopware Academy store finder example.

If you feel there must be a simpler solution, there probably is.

Don't overengineer your requirements! You are probably right if you feel there must be a more straightforward solution. For example, to add custom fields to products in Shopware 6, we can conceive a new entity definition with a migration class for its distinct database table with foreign keys and one-to-one associations, writing hundreds of lines of boilerplate code. Or we can use Shopware's custom field system, which allows us "to extend entities, without writing a complete entity extension. This is possible by storing the additional data in a JSON field", as long as we only need scalar values and no complex data structures.

Caches can cause outdated error messages!

When we finally write the correct code, it might still not work until another bin/console cache:clear and/or bin/console plugin:refresh has removed every remnant of our previous attempts. See this similar (non-Shopware) StackOverflow question about "controller ... has no container set ... define it as a service subscriber", quoting the accepted answer:

The issue had to do with the cached files; deleting /var/cache prevented the error from occurring.

Don't forget to reinstall!

Uninstall dialog screenshot

When changing migration classes or plugin lifecycle methods like install, we must uninstall and reinstall the plugin to run our new code.

Install Symfony profiler

If there is no Symfony profiler yet, you can install it using composer:

composer require --dev symfony/profiler-pack

Use XDebug and adjust the default log level

We can set the default logging level from debug to warning in /var/www/html/config/packages/dev/monolog.yaml to prevent Shopware from writing hundreds of lines of deprecation notes (INFO level) to dev.log for each request. For the same reason, we usually don't want to enable Xdebug in Dockware by default, but use make xdebug-on or make xdebug-off on the command line inside the container, making sure to add operating-system specific settings like environment: - XDEBUG_REMOTE_HOST=172.17.0.1 for Linux in docker-compose.yml, to install the XDebug browser extension and start PhpStorm's XDebug listener in the settings or by clicking the bug icon in the status bar at the bottom of the IDE.

If you have never used XDebug before, you might wonder what is supposed to happen when it works. Simply said, it's a connection between the Symfony profiler output in your browser and the source code in your IDE. Clicking on a line number in a stack trace will open the file at the mentioned line in PhpStorm.

XDebug can help us debug errors (except those that silently fail with a white screen).

Inspect the database with adminer

Use adminer (or the SQL CLI) to verify tables and database entries. In a dockware default development setup: http://localhost//adminer.php (Server: 127.0.0.1, not localhost; database: shopware; initial login: root:root).

Debug, research, review and learn!

A bug in the software framework or its tools and extensions is no impossible reason for a problem, but it seems extremely unlikely that we were the first to find and report it. We should check search results, forums, issues, and release notes and remember known problems and necessary workarounds (like typing bin/console debug:router --no-debug or other similarly peculiar idioms to prevent having to search for helpful output in the midst of irrelevant deprecation notes displayed due to unhelpful default log levels).

Solution strategies: google the error message, try to follow your gut feeling or inspect every piece of code and take notes and screenshots so you can review the situation later and learn about your coding vulnerabilities and how to fix them in the future.

Always use the latest documentation and don't be afraid to ask "silly" questions (Slack, StackOverflow, forum) if you have faced a specific challenge when extending or maintaining Shopware code.

Build and verify!

I had some issues using the storefront watcher, so I tend to rely on these manual steps to build and verify a modified theme after starting and entering the container:

  • docker-compose up -d
  • docker exec -it shop bash
  • bin/console plugin:refresh
  • bin/console theme:compile (if it's a theme)
  • bin/build-storefront.sh
  • bin/console cache:clear

After this, we can open or reload localhost in our browser.

Validations, inspections and debug commands:

There are several validations, inspections and debug console commands, and there is the third-party extension shopware-cli (see below).

  • bin/console snippets:validate validates all snippets
  • bin/console lint:container validates the service container
  • bin/console lint:twig <path-to-twig-file> validates a specific twig template file
  • bin/console debug:twig shows twig commands and namespaces
  • bin/console debug:router shows all configured routes
  • bin/console lists all available bin/console commands.

Adding a verbosity flag (-v or -vv or -vvv for the most verbose output) can sometimes reveal helpful details that are not part of the default output.

Community blogs

Given the state of documentation and the neglected community forum, we are lucky that individuals like Jan Schmidak (Shopwarian) or Björn Meyer (BrocksiNet) write posts like Custom fields in Shopware 6 or CustomFields, Properties and Entity Extensions for Shopware 6.

Thanks for sharing your knowledge! 👍🙏🎉

Don't get fooled by deprecations!

Beyond all that, we can focus on frontend customization and adding missing services in the backend and not get fooled by breaking changes, like introducing a mandatory hyphen in a frontend class name in Shopware 6.6 and other recent deprecations.

Question software decisions!

Last but not least, question software decisions! If, for example, a framework keeps causing frequent problems or increases development and maintenance efforts, then it may not be the right tool. Aspects to consider: documentation, support, security, stability, performance, accessibility. Are there best practices? Are they easy to discover? Does your working code still work after a framework upgrade? Can upgrades break production systems without a rollback option? Do manufacturers or community members answer questions and suggestions quickly and helpfully?

Coding standards and safe modes

Shopware, for example, has embraced modern coding standards and an open-source system (Symfony) as its foundation. However, WordPress, rightfully criticized for different problems, has introduced safe mode and recovery options that are easy to use even for non-tech-savvy website owners.

Frustrating developer experience: worth in the long run?

Comparing effort to rewards/income can be a more measurable way to evaluate software decisions. Maybe some software has many problems, but few alternatives for a given requirement, and a frustrating developer experience can be rewarded by billing hours and hours to customers with sufficient budgets. The more often you do this, the more efficiently you can scale your business and resell existing solutions.

This post sums up my series about Shopware 6 development. I think I'm done. I would rather spend my learning time on accessibility, UX, and ecological sustainability than trying to make sense of poorly documented implementation details, whether that's Shopware, Gutenberg, Elementor or React, and focus more on front-end web development and performance optimization again.

Top comments (1)

Collapse
 
ingosteinke profile image
Ingo Steinke

Minimum memory and other official requirements

Some hosters have enough resources but limit the defaults, so you might spot what looks like an arithmetic anomaly, when allocating 3399608 bytes exhausts the allowed memory size of 134217728 bytes, until you increase your memory limit to the recommended 512M. See Shopware Update fails due to exhausted memory size caused by deactivating extensions for more details and note that similar questions used to yield answers like "Why do you need that much memory? Is it a specific function/database query causing the issue? Can you optimise it? Are you sure, you really want to allocate that much memory? Typically, changing the memory limit on shared hosts isn't possible. It would be counter-productive to the idea of shared hosting. What do you need this much space for anyway? 512 MB sounds like an insane amount of RAM." Although common sense has shifted towards "with such a low memory limit, it's most probably enough to increase the memory limit and not a bug," we might still want to keep the default limit.

Instead of trying to raise the defaults, like by adding an .htaccess line like php_value memory_limit 512M, we could raise the limit only for critical command line options and let the stricter limits apply to end-user access to our storefront.

php -d memory_limit=512M ./bin/console system:install --basic-setup

After installing Shopware's production template according to their installation documentation we might find out some other requirements that are not documented explicitly.

  1. Adjust the .env file to your database
  2. Run ./bin/console system:install --basic-setup