ntzrbtr / shopware-custom-fields
Define custom field sets for Shopware 6 in PHP and install, update and uninstall them from plugins
Requires
- php: ^8.4
- shopware/core: ^6.7
Requires (Dev)
- phpstan/extension-installer: ^1.4
- phpstan/phpstan: ^2.1
- phpstan/phpstan-deprecation-rules: ^2.0
- phpunit/phpunit: ^12.5
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Define custom field sets for Shopware 6 in PHP and install, update and uninstall them from your plugin's lifecycle.
- Custom field sets are identified by their name; installing an existing set updates it in place (ids of existing fields are kept, so stored values survive).
- Fields that are no longer part of a set are removed on update.
- Relations to entities are synchronized (added and removed) as well.
- Labels can be given as a string (used for
de-DEanden-GB) or as an array with both locales. - Field positions follow the order of the fields in the set.
Installation
composer require ntzrbtr/shopware-custom-fields
Usage
Define a custom field set
Create a provider per custom field set:
use Netzarbeiter\Shopware\CustomFields\CustomField; use Netzarbeiter\Shopware\CustomFields\CustomFieldSet; use Netzarbeiter\Shopware\CustomFields\Provider\CustomFieldSetProviderInterface; use Shopware\Core\Checkout\Order\OrderDefinition; use Shopware\Core\System\CustomField\CustomFieldTypes; class OrderDataSetProvider implements CustomFieldSetProviderInterface { public function getCustomFieldSet(): CustomFieldSet { return new CustomFieldSet( name: 'order_data', entities: [OrderDefinition::ENTITY_NAME], label: [ 'de-DE' => 'Zusätzliche Bestelldaten', 'en-GB' => 'Additional order data', ], customFields: [ new CustomField( name: 'order_data_exported', type: CustomFieldTypes::CHECKBOX, label: [ 'de-DE' => 'Exportiert?', 'en-GB' => 'Exported?', ] ), new CustomField( name: 'order_data_note', type: CustomFieldTypes::TEXT, label: 'Note', config: [ 'componentName' => 'sw-textarea-field', ], ), ] ); } }
The config of a field is merged recursively into the defaults (componentName: sw-field,
customFieldType: text, the label), so you can override or add any custom field config Shopware supports.
Further options of a field:
| Option | Default | Meaning |
|---|---|---|
allowCustomerWrite |
true |
Customers may write the field (e.g. via Store API) |
allowCartExpose |
false |
Field is available in the cart (e.g. on line items) |
storeApiAware |
true |
Field is included in Store API responses |
includeInSearch |
false |
Field can be used in the product search configuration |
new CustomField( name: 'product_internal_note', type: CustomFieldTypes::TEXT, label: 'Internal note', allowCustomerWrite: false, storeApiAware: false, );
Register the services
The installer is not registered automatically; add it to your plugin's services.yaml:
services: _defaults: autowire: true autoconfigure: true _instanceof: Netzarbeiter\Shopware\CustomFields\Provider\CustomFieldSetProviderInterface: tags: ['netzarbeiter.shopware.custom_fields.provider'] Netzarbeiter\Shopware\CustomFields\CustomFieldSetInstaller: ~ Vendor\MyPlugin\CustomField\Provider\: resource: '../../CustomField/Provider'
All services tagged with netzarbeiter.shopware.custom_fields.provider are injected into the installer. You have
to assign the tag yourself as shown above. Keep the _instanceof entry in the same file as your providers, as it
only applies to services defined in that file.
Install from the plugin lifecycle
While a plugin is being installed, its services are not yet part of the container, so create the installer manually in that case and pass the providers explicitly:
use Netzarbeiter\Shopware\CustomFields\CustomFieldSetInstaller; use Shopware\Core\Framework\Plugin; use Shopware\Core\Framework\Plugin\Context\InstallContext; use Shopware\Core\Framework\Plugin\Context\UninstallContext; use Shopware\Core\Framework\Plugin\Context\UpdateContext; class MyPlugin extends Plugin { public function install(InstallContext $installContext): void { $this->getCustomFieldSetInstaller()->installAll($installContext->getContext()); } public function update(UpdateContext $updateContext): void { $this->getCustomFieldSetInstaller()->installAll($updateContext->getContext()); } public function uninstall(UninstallContext $uninstallContext): void { parent::uninstall($uninstallContext); if ($uninstallContext->keepUserData()) { return; } $this->getCustomFieldSetInstaller()->uninstallAll($uninstallContext->getContext()); } private function getCustomFieldSetInstaller(): CustomFieldSetInstaller { if ($this->container->has(CustomFieldSetInstaller::class)) { return $this->container->get(CustomFieldSetInstaller::class); } return new CustomFieldSetInstaller( $this->container->get('custom_field.repository'), $this->container->get('custom_field_set.repository'), $this->container->get('custom_field_set_relation.repository'), [ new OrderDataSetProvider(), ] ); } }
Single sets can be handled with install() and uninstall(); getCustomFieldSets() returns the sets of all
providers, e.g. to build mappings for an import.
Requirements
- PHP 8.4 or newer
- Shopware 6.7
Development
composer install vendor/bin/phpunit vendor/bin/phpstan analyse
Releasing
- Move the entries under
[Unreleased]inCHANGELOG.mdto a new version section. - Commit, then tag and push:
git tag v1.2.3 && git push origin v1.2.3 - The release workflow creates the GitHub release with the changelog entry as notes; Packagist picks up the new tag automatically.
License
MIT, see LICENSE.