Adding a Custom Field as Extension

Shopware 6′ custom fields is a very powerful yet easy to use mechanism to customize the standard data model and functionality. Custom fields for an entity are stored in a pre-defined json field with that entity. This mechanism is very flexible, and allows even out-of-the-box translations for custom fields, however it has two major flaws:

First, it creates some inevitable performance overhead. If you need to search that field (say an ERP product id) from a PHP script, be aware that, since it is wrapped in an SQL json field, there is no related database index.

Second, it relies on a pre-defined json field being defined for that entity. If the makers of Shopware decided to leave that off for an entity, that’s it – no custom fields for this entity.

Luckily, there is a simple alternative to custom fields provided in Shopware’s Data Access Layer (DAL) entity extensions. While it needs a litte bit more code than a simple custom field, there is no big magic behind it. Read and learn here how to create additional fields for any entity in Shopware 6.___STEADY_PAYWALL___

Get the code from my Github repo

For your convenience, I have prepared the example as a plugin. You may want to download it from my github repo:

https://github.com/vanWittlaer/blog-example-one

This article assumes that your are familiar with PHP and Symfony basics. For all relevant Shopware 6 developer documentation, please refer to https://developer.shopware.com/docs/.

To try the example, you need access to a Shopware 6 development environment. In particular to build the administration components, webpack must be installed which is usually not the case on hosted servers or production servers in general.

Let me quickly walk through the example code:

Defining the custom entity extension

You’ll find the relevant code inside the folder DataAbstractionLayer/Extension. It actually takes three classes to define the extension:

  1. PromotionDiscountAddonsEntity.php defines the entity extension for usage from your PHP (and, implicitly, JavaScript) code.
  2. PromotionDiscountAddonsDefinition.php maps the entity’s properties to database level fields.
  3. PromotionDiscountAddonsCollection.php defines the collection to be used e.g. in search results from the repository.

Note that the definition has to be registered as a service with the tag shopware.entity.definition in your services.xml file (which is located in the Resources/config folder).

The class found in DataAbstractionLayer/Extension/PromotionDiscountAddonsExtension.php links the custom extension to its main entity. As the definition it needs to be defined in your services.xml file.

Creating the physical database table

To create the physical table for the extension, we make use of Symfony’s migration functionality (look for ‘database:create-migration’ in the docs if you don’t know how to create a migration). The resulting migration can be found in Migration/Migration1643116081_PromotionDiscountAddons.php. Note the fields created_at and updated_at that should be in every table. And just make sure you chose the correct column definitions for all fields.

Make the extensions fields available in the administration

To get the extension fields to show up and become editable in the admin, you need some combination of JavaScript and Twig files, that can be found in the folder Resources/app/administration/src.

The code in Resources/app/administration/src/module/sw-promotion/component/sw-promotion-discount-component extends the promotion discount view to display the additional field.

Since Shopware does not create the extension instance ‘by default’, we need to create it explicitly whenever a new promotion discount instance is created. This is what the code in Resources/app/administration/src/module/sw-promotion/view/sw-promotion-detail-discounts/index.js does. It overrides the Shopware-provided onAddDiscount method, adding some logic to create the extension instance whenever a new promotion discount instance is added.

Remember that whenever you have added or changed administration components, you need to run

$ bin/console build-administration.sh

from the console. This way, the minimized js file for your plugin’s admin component will be compiled and stored in Resources/public/administration/js/van-wittlaer-example-one.js. Should you intend to publish your plugin in the store or by other means, it is important to save and include this file as part of your code.

Now, when you add a promotion discount in the administration, you will notice the additional field ‘Promotion Discount Key’, as shown in the screenshot below.

Accessing the extension from PHP

To demonstrate how to access the entity extension from within PHP, I have added a small command. You can find it in Command/ListPromotionDiscountsCommand.php.

Share your feedback!

Did I miss something? Do you know a smarter way to do it? Please let me and other readers know and add your comments below!

Leave a Reply

Your email address will not be published.