Recently we released the B2B Suite for Shopware 6, which has the same features as the B2B Suite for Shopware 5. In this article, we want to take a look at the changes which were made to support Shopware 6. Thereby we want to focus on the breaking changes and the resulting changes for plugin developers.
Introduction to hybrid plugins
In the blog article “Large Scale Plugin Architecture”, my colleague Jan Philipp talked about the macro architecture of hybrid plugins like the B2B-Suite. Sadly, we still had to introduce breaking changes to make the B2B-Suite compatible with both Shopware 6 and Shopware 5. This is especially important for migrating an existing B2B-Suite project from Shopware 5 to Shopware 6.
More importantly, we want to list up the different hard breaks, which were not deprecated previously.
The new “bridge” layer
As described in the previously mentioned blog post, we use the dependency inversion principle to depend on an interface to wrap the data access, which is owned by our domain.
While just working with Shopware 5, the architecture was built as shown in the image below.
Because of this, we only had to duplicate our bridge layer and adapt it accordingly to Shopware 6.
It was mostly rewriting the bridge or moving existing framework logic to the bridge layer, which is already implemented in Shopware 6.
The frontend bridge
Also, because of the usage of a frontend bridge, it was possible to do the same.
As shown in our component guide, each component consists of multiple layers.
- Shop bridge
Due to the changes in the plugin system, it was not possible to reuse the plugin itself. Therefore we had to rewrite it.
It resulted in the following layering:
As seen in the previously shown graphics, we had to change multiple places to support Shopware 6, but this is not all.
Due to the field changes of ids from
binary, we had to change our internal logics as well.
Unfortunately, we could not deprecate them, because it would require to deprecate all repositories as well, to be consistent.
E.g., one of our main tables, which is used to assign contacts to debtors, is
It uses a combination between
context shows the table and the
key is the corresponding id.
We had to introduce a way to use our current architecture with both id types for a hybrid plugin.
IdValue is an abstraction of id values.
It can represent three different values:
If you would like to create a new
IdValue, you just have to provide the
value as a parameter to
Thereby the IdValue creates the corresponding class based on the Shopware version and the value type.
Afterward, you can receive the internal value via
$idValue->getValue() and the storage value
For example a
UUIdValue->getValue() would return the
Hex value of the UUID and
UUIdValue->getStorageValue() the corresponding
Changes in the Repository
So, but how does it look like in practice?
Often we use functions like
fetchOneById(int $id, ...): Entity; in our repositories.
These had to change to:
The most important part here is the change of the parameter
fetchOneById(IdValue $id, ...) and that the usage of the storage value for filtering
In your plugins
Since these changes are hard breaks, you have to change your code accordingly.
Let’s take a look at a controller action that used the
fetchOneById in the past.
Here, you just had to change the
$id variable to an
IdValue, and we are done.
The introduction of the IdValues does not only affect the PHP-Code but also the usage in the templates.
Therefore it is not possible to just use the id.
You have to access the value via the function
In twig templates, it looks like this:
In smarty templates:
The new Shopware version involves Twig as the template engine. Therefore we changed our template accordingly to twig. Smarty is still used for Shopware 5.
The Shopware 5 plugin system had a state manager capable of handling jQuery plugins provided by a plugin.
Since Shopware 6 is just using jQuery slim, it does not include the complete functionality which we require.
Therefore we added different jQuery polyfills to complete the functionality. Also, we added a new
PluginInstance, which provides the prototype of the Shopware 5 plugins.
Currently, we are working on replacing these plugins with a TypeScript approach to ensure a higher quality and stability - while making full use of the new storefront plugin system of Shopware 6. The existing plugins can be extended simply by accessing the jQuery object, which contains each plugin instance as an object.
In the future, the new TypeScript based plugins can be extended just by following the official Shopware 6 documentation.
With Shopware 6, a new custom field management was introduced, so we had to change the storage of our customer-related attributes.
For this, we introduced the new table
b2b_customer_data for the customer’s attributes.
It is the counterpart to the added
s_user_attributes fields in Shopware 5 and shows debtors and sales representatives.
Since the administration interface implementation is related to Shopware, we had to recreate the administration module with Vue.
For the implementation, we added a new controller layer that depends on Shopware for the administration.
It behaves like the Shopware 5 backend controllers.
It is shown in the plugin chapter of this article.
With the new B2B-Suite release, we dropped some PHP versions. So the minimal PHP version is 7.2.
With the drop, we also applied some of the latest PHP features.
The most recognizable change is the appliance of the
void return type.
We know that this is a breaking change, but because of the number of deprecations this would involve, because of the already existing breaking changes, and because of the improvement of security, we think this is bearable.
This change results in a fatal error if you extend an existing function, which got a new
How to fix the fatal error
For plugin developers, fixing the problem should be easy as long as you have programmed according to our doc types.
As seen in this article, the work for migrating the B2B-Suite got much easier because of our chosen architecture.
Nevertheless, we couldn’t do it without breaking changes.
Hopefully, this article helped you to deal with the changes which were introduced with the migration.