Shopware 6 development recap (2022)
Tags: php, programming, symfony, shopware
Published: 2022-02-06 23:51:17

**Note** that this post is from 2022, and **some of the described tools and functions have since been changed or deprecated!** See [Shopware 6 changes since the academy training videos](https://dev.to/ingosteinke/shopware-changes-since-the-60-dev-training-videos-481o) for more details.

I started using Shopware 6 in 2020 when I built a back-end API plugin without any official training. Thanks to a good (enough) documentation, a helpful community, and Shopware being based on open-source software, I got along with the framework and started to like it, so I decided to take the official developer training later.

In 2021, I did a lot of front-end web development, and when I got involved in Shopware projects, I mostly did front-end (CSS) as well, and time passed without me getting certified as a full-stack Shopware 6 developer.

I have had different local Shopware installations, including a classic "LAMP stack" with a native Apache server installation for Shopware 5. I tried Dockware, but currently the official development repository (also using Docker) does a good job on localhost. I have an end-user installation on a shared host to test my themes and plugins.

Coming back to Shopware development after a while, I have to recap how to start the server, how to use the command line interface, and which notation to use for namespaces and services in which file.

## Starting a local Shopware container

As there is a `docker-compose.yml`, it might seem obvious to type `docker-compose up` to start, and use `docker exec` to open a shell inside the container, which is possible, but mixing the Docker way and the Shopware way can cause permission problems sooner or later.

```
psh.phar docker:start
psh.phar docker:ssh
```

Using the PHP shell helper `psh` (pronounced "P. S. H. far") and its subcommand `docker:ssh` which is named "ssh" only for historical reasons.

## psh.phar, bin/console or the admin app?

Many tasks can be done either way using `psh.phar`, `bin/console` or by clicking in the admin web app in the browser. I once forgot my admin credentials, so I used the command line to create a new user. Another reason to prefer the console is that you can write down and copy-paste the CLI commands from your repository's README.

Using console commands (`bin/console`) without `psh.phar` is a common Symfony style and the preferred alternative.

Always check if you are actually inside your Shopware container (or on the server) before executing a command! Mostly everything (apart from starting and stopping) must be done inside, like compiling a theme and clearing the cache.

```
bin/console theme:compile
bin/console cache:clear
```

## Should I clear the cache?

As the styles and scripts are loaded with cache busting parameters, we shouldn't need to clear the cache if all we did was modify some style sheets, we only need the compilation, which includes processing our SCSS, so we don't need to bother about Webpack when using Shopware.

Some servers have a small default memory limit that might not be enough for admin tasks, so we might need to specify a larger limit manually by adding PHP options:

```
php -d memory_limit=10G bin/console theme:compile
php -d memory_limit=10G bin/console cache:clear
```

### There is more than one /var

Inside the app container, we can use

```
tail var/log/dev.log
```

to see the latest logs, but beware, this is `var/log` below your initial working directory. There is also `/var/log` inside the container, but that does not contain the logs written by our Shopware application.

## Don't touch the running system

Sometimes our software stops working, or we might want to update our dependencies. If the shop is up and running, we don't need to use composer ever again, unless something is broken. Shopware will offer to upgrade our installation to the latest development release when we open our admin UI in 
the browser, and this should actually work despite the initial Docker-based installation.

## Plugin development

Remember that a plugin is just a Symfony bundle. Plus some Shopware extras on top, but Shopware 6 is much more Symfony-like than Shopware 5, and if in doubt or missing documentation, we can fall back to the underlying software's documentation instead, so we have

 * PHP
 * Symfony
 * Twig
 * SCSS / CSS
 * Bootstrap
 * Vue.js (admin UI only)
 * JavaScript / ECMAScript

Also we have the Shopware framework and its default plugins to look for coding examples.

File names and folder structures also follow the existing code that should be extended. But as Twig blocks override the original ones with the same name by default, we have to make a parent call if we want to extend them instead. Always prefer to extend existing code so that we produce minimal patches and avoid compatibility problems for future feature updates in the original Shopware software.

### Seek guidance and assistance

Apart from documentation and helpful community, use your tools! Don't take tutorials for granted, not even the official ones at [Shopware Academy](https://academy.shopware.com/), they might be outdated and contain errors.

Always make sure that the tools and documentation match your current Shopware version! Otherwise, at least take them with a grain of salt! If in doubt, don't use any Shopware 5 stuff for Shopware 6! Also check if something might only apply to an earlier Shopware 6 version.

Use [PhpStorm](https://www.jetbrains.com/phpstorm/) with  [Symfony support](https://plugins.jetbrains.com/plugin/7219-symfony-support/) and follow the recommendations [by Shopware](https://developers.shopware.com/developers-guide/phpstorm/) and [by JetBrains](https://www.jetbrains.com/help/phpstorm/shopware-integration.html#code-completion-shopware). Use any other official static code completion and analysis tools you can get ([PHPStan](https://phpstan.org) etc.) and learn to use PhpStorm shortcuts and functionality, like opening a linked dependency or generating boilerplate code.

Tabnine assistant for PhpStorm is a plugin, like a local coding copilot, that will suggest code completion based on common patterns found in open-source projects applied to the current project, which might or might not be a good idea. AI tools like Copilot, chatGPT, or JetBrains AI, are optional. Proper namespaces and type hinting annotations should give the IDE enough information to suggest useful (and only useful) auto-completion.

![Screenshot of automatic code completion suggestions in PhpStorm suggesting Shopware Core Framework DataAbstractionLayer when typing use EntityCo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hff0024js412h9kv2dsj.png)

You don't have to start typing complete namespace paths. Try the actual class name or even abbreviations. Keep typing until you get the right suggestion. In most cases, importing from Shopware\\Core\\Framework is a good idea, but as [recognition is easier than recall](https://www.nngroup.com/articles/recognition-and-recall/#:~:text=Recognition%20is%20easier%20than%20recall,more%20likely%20to%20pick%20it.&text=In%20our%20everyday%20life,%20we,us%20retrieve%20information%20from%20memory.), the suggestions can help you focus on getting things done instead of wasting time looking up or trying to remember boilerplate code.

### Hit Alt+Shift+Enter

Don't waste time writing `import` statements at all. Use what you need to use, and hit Alt+Shift+Enter to let your IDE help you.

![Screenshot of assistance dialog saying undefined class EntityCollection Import class Alt + Shift + Enter](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u4qr77jpmnj04cb1vka3.png)

Use the [Symfony profiler](https://symfony.com/doc/current/profiler.html) when testing your code, look in your error logs, and if you're unsure about your data, you can `dump` it on your local website.

### Build, validate, and upload

This is where every tutorial ends: nobody used to tell you how to pack, test, and ship your plugins. Once they are built, you can test them locally and copy the directories to any other shop, but you need to create a zip archive to release your code as an official extension.

[Frosh plugin uploader](https://github.com/FriendsOfShopware/FroshPluginUploader) can validate and pack a plugin based on the latest commit in your current repository. Be careful if you have more than one branch!

### Who am I, where am I, what is my origin?

Also be careful about your working directory, if you have more than one repository! In my development setup, I have

* [my own wrapper repository](https://github.com/openmindculture/fractal-shopware-demo)
  * [development](https://github.com/shopware/development)
     * [platform](https://github.com/shopware/platform)
        * custom/plugins
            * [IngoSDev6CertPrep](https://github.com/openmindculture/IngoSDev6CertPrep)
            * other themes and plugins

I can create or check out my own plugin repositories inside the `plugins` directory. Each plugin has its own repository.

It helps to remember some bash, git, and Docker commands as well, like

```
pwd
git remote show origin
git log -p (optionally followed by a directory)
git diff --cached
git branch
docker ps
docker network ls
docker volume ls
```

And if Docker goes totally crazy (which is Docker's fault and used to happen with any other multiple container start/stop scenario), use the infamous [functions to brutally remove everything Docker related](https://stackoverflow.com/questions/34658836/docker-is-in-volume-in-use-but-there-arent-any-docker-containers).

### Where is our shop and why isn't it working?

Maybe we forgot which localhost port Shopware is supposed to be found by default (8000), or we forgot that we started another server on the same port (which might not even be run by docker), or maybe we shouldn't use `localhost:8000` but some alias subdomain necessary for plugin licensing or to prevent CORS issues in the browser.

Maybe the server is up, but the storefront shows an error.

In that case, try to open the admin UI. If that still works, check the storefront settings. Maybe we need to reassign our theme to the sales channel (or assign the default theme when our own theme is broken), deactivate broken plugins, rebuild the current theme, rebuild the storefront, or clear the cache. All that can also be done (and maybe should be done) on the command line.

## Insomnia and the rabbit hole of technical details

Testing API endpoints, using [Insomnia](https://insomnia.rest), [Postman](https://www.postman.com), or good old [curl](https://manpages.org/curl), we might need to add an explicit access permission (unlike the storefront that seems to have permission and CSRF mechanisms out of the box). Again, the academy tutorial video used an early release of Shopware 6 that had quite simplistic permission management in the admin UI. Adding an "Integration" for Insomnia with "Read" permissions can now be achieved at Settings -> System -> Users & Permissions by creating a new role `admin_api_reader`. If that's not documented and straightforward enough, there is a tab called "detailed privileges" that shows the technical names like `acl_role`, `plugin`, `foo_log_entry` etc.

As I did not intend to dive deep into the permission system, I might give Insomnia full access to everything, as long as this is restricted to my `localhost` server with a demo shop and no real customer data anyway.

## Pragmatic focus

Don't waste too much time on things that don't work.
Is it a blocker? Do we have another installation without the error? Is it a bug? Maybe we updated too early, or we missed a critical update. Do we have other tasks that are not blocked by the problem?

Same with tutorials, notes, or code that seemed to work yesterday: don't focus on what should be, but rather find a way to make things work now. As Shopware 6 is still relatively new, be prepared for breaking changes.

### Tutorial videos as an inspiration

There are free videos on YouTube, [ShopwareTV](https://tv.shopware.com/) and [academy.shopware.com](https://academy.shopware.com/) featuring official developer training and helpful sessions from Shopware Community Days and Shopware Boost Days.

{% youtube https://www.youtube.com/watch?v=L57ZmEsihSo %} 

Some of the information in the tutorial videos is outdated, some other details have been wrong from the start, and mostly the mistakes will be corrected in a later chapter, so don't worry if the examples don't work for you.

Shopware told me that they want to show authentic users and developers, and that even the professionals working at their headquarters make mistakes, too. That also means you can't just watch the videos along the way and copy-paste the ready-made code. Even the documentation has been reorganized after the videos were taken, so you might have to use a search engine and creative browsing to find what you are looking for. But being forced to use your own brain, you will have a better understanding based on your experience in the end.

So let's take the videos as an inspiration for research, development, and experiment!

You can also research how other plugins authors worked on GitHub (which might or might not be a good example) and get an idea of how the front-end is supposed to work by examining existing online shops build with Shopware 6, like [Armed Angels](https://www.armedangels.com/), a sustainable fashion brand from Cologne, Germany.

Ask questions and browse for answers in the Shopware forums, on StackOverflow, or, if you prefer some day-to-day activity and a better chance to get an answer, join the [shopwarecommunity slack](shopwarecommunity.slack.com) which obsoletes the former live discussion on gitter.im.

## Vendor prefix

If you plan to release anything in the official extension store to make it easier to use in a shop (or to show off your skills to potential customers or employers), you need to choose a handle that you will not be able to change after you release your first extension!

All of your extensions will also start with that handle, and it can't be very long, so I could not use my GitHub name `openminculture`. Instead, I chose `IngoS` which is an abbreviation of my name and also matches an "Ingo's" prefix in a human-readable title.