it-bens / shopware-code-based-plugin-configuration
提供基于代码和类型的方式创建 Shopware 配置的软件包,除了 XML 文件。
Requires
- php: ^8.1
- shopware/core: ^6.5
Requires (Dev)
- captainhook/captainhook: ^5.23
- captainhook/plugin-composer: ^5.3
- frosh/shopware-rector: ^0.3.0
- phpstan/phpstan: ^1.10
- phpstan/phpstan-phpunit: ^1.3
- phpstan/phpstan-symfony: ^1.3
- phpunit/phpunit: ^10.5
- rector/rector: ^1.0
- symplify/coding-standard: ^12.0
- symplify/easy-coding-standard: ^12.1
This package is auto-updated.
Last update: 2024-09-28 00:06:03 UTC
README
Shopware 提供了一种简单的方法来创建插件配置,而无需实现任何前端代码:[链接](https://developer.shopware.com/docs/guides/plugins/plugins/plugin-fundamentals/add-plugin-configuration.html)
尽管底层系统对于内部配置生成非常灵活,但 config.xml
文件是利用此系统的唯一方式。本软件包旨在提供另一种方法:基于代码的配置生成。
这是一个 Shopware 插件吗?
不是。虽然此软件包与 Shopware 相关联,但它不会对其自身的事件做出反应。它旨在由 Shopware 插件使用。
如何在 Shopware 插件中添加此软件包?
首先,必须通过 composer 安装此软件包
composer require it-bens/shopware-code-based-plugin-configuration
这可以在插件的 composer.json
文件中完成。但请记住在插件类中启用 composer。
public function executeComposerCommands(): bool { return true; }
此软件包提供了两个 Symfony 编译器通过。`ConfigurationCardConfigReaderPass` 将添加所有必要的配置生成服务到服务容器中。它可以通过插件的 `build` 方法添加。
use ITB\ShopwareCodeBasedPluginConfiguration\DependencyInjection\ConfigurationCardConfigReaderPass; public function build(ContainerBuilder $container): void { // ... parent::build($container); $container->addCompilerPass(new ConfigurationCardConfigReaderPass()); }
为什么默认配置值缺失?
虽然提到的编译器通过足够在运行时生成插件配置,但缺少了一个方便的功能:默认值。需要 `ConfigurationCardConfigSaverPass` 来“黑客”Shopware 插件配置持久性。
use ITB\ShopwareCodeBasedPluginConfiguration\DependencyInjection\ConfigurationCardConfigReaderPass; use ITB\ShopwareCodeBasedPluginConfiguration\DependencyInjection\ConfigurationCardConfigSaverPass; public function build(ContainerBuilder $container): void { // ... parent::build($container); $container->addCompilerPass(new ConfigurationCardConfigReaderPass()); $container->addCompilerPass(new ConfigurationCardConfigSaverPass()); }
有关为什么这是必要的以及为什么使用是“黑客式”的详细信息,请参阅[此处](#user-content-shopware-plugin-configuration-persistence)。
我如何使用此软件包?
将配置编码到卡片中
此软件包提供了定义配置卡片(如在 Shopware 插件管理中看到)的类。
一个 ConfigurationCard
有英文标题,德文标题和一个 ConfigurationInputField
对象列表。支持的 ConfigurationInputField
实现包括
BoolField
IntegerField
SingleSelectField
TextField
这些实现中的一些在所需信息方面有所不同。但由于它们主要需要相同的信息,所有都需要一个 GeneralFieldInputInformation
对象。以下是一个包含所有类型输入字段的配置卡片的示例
use ITB\ShopwareCodeBasedPluginConfiguration\ConfigurationCard; use ITB\ShopwareCodeBasedPluginConfiguration\ConfigurationInputField\BoolField; use ITB\ShopwareCodeBasedPluginConfiguration\ConfigurationInputField\IntegerField; use ITB\ShopwareCodeBasedPluginConfiguration\ConfigurationInputField\SingleSelectField; use ITB\ShopwareCodeBasedPluginConfiguration\ConfigurationInputField\SingleSelectFieldOption; use ITB\ShopwareCodeBasedPluginConfiguration\ConfigurationInputField\TextField; use ITB\ShopwareCodeBasedPluginConfiguration\GeneralFieldInputInformation; $enabledFieldInformation = new GeneralFieldInputInformation( name: 'enabled', labelInEnglish: 'Enabled', labelInGerman: 'Aktiviert', helpTextInEnglish: 'Enable or disable the feature', helpTextInGerman: 'Aktiviere oder deaktiviere das Feature' ); $enabledField = new BoolField(new GeneralFieldInformation(generalInformation: $enabledFieldInformation, defaultValue: false); $integerFieldInformation = new GeneralFieldInputInformation( name: 'position', labelInEnglish: 'Position', labelInGerman: 'Position', helpTextInEnglish: 'The position in the list', helpTextInGerman: 'Die Position in der Liste' ); $integerField = new IntegerField(new GeneralFieldInformation(generalInformation: $integerFieldInformation, defaultValue: 0); $selectFieldInformation = new GeneralFieldInputInformation( name: 'color', labelInEnglish: 'Color', labelInGerman: 'Farbe', helpTextInEnglish: 'The color of the item', helpTextInGerman: 'Die Farbe des Elements' ); $selectField = new SingleSelectField( new GeneralFieldInformation(generalInformation: $selectFieldInformation, defaultValue: 'red'), [ new SingleSelectFieldOption(id: 'red', nameInEnglish: 'Red', nameInGerman: 'Rot'), new SingleSelectFieldOption(id: 'blue', nameInEnglish: 'Blue', nameInGerman: 'Blau'), new SingleSelectFieldOption(id: 'green', nameInEnglish: 'Green', nameInGerman: 'Grün'), ] ); $textFieldInformation = new GeneralFieldInputInformation( name: 'description', labelInEnglish: 'Description', labelInGerman: 'Beschreibung', helpTextInEnglish: 'A description of the item', helpTextInGerman: 'Eine Beschreibung des Elements' ); $textField = new TextField(new GeneralFieldInformation(generalInformation: $textFieldInformation, defaultValue: ''); $configurationCard = new ConfigurationCard( titleInEnglish: 'General Settings', titleInGerman: 'Allgemeine Einstellungen', inputFields: [$enabledField, $integerField, $selectField, $textField] );
将卡片注入到配置中
该软件包使用实现 `ConfigurationCardProvider` 接口的服务。您可以创建尽可能多的服务实例实现。由于 Shopware 为所有插件使用相同的加载机制,因此必须声明 `ConfigurationCardProvider` 的范围。这是在插件类的 `getBundleClasses` 方法中完成的。
/** * @return class-string<Bundle>[] */ public function getBundleClasses(): array { return [ YourPluginClass::class ]; }
使用 getPriority
方法对注册了同一插件的多个提供者进行排序。
public function getPriority(): int { return 100; }
最后,使用 getConfigurationCards
方法返回配置卡片。
/** * @return ConfigurationCard[] */ public function getConfigurationCards(): array { return $this->configurationCards; }
软件包是如何工作的?
该软件包装饰了Shopware的Shopware\Core\System\SystemConfig\Util\ConfigReader
服务。此服务用于读取插件的config.xml
文件。它将XML文件解码为数组。该软件包保留了插件基于XML的配置,并通过匹配配置卡片提供者的数据扩展它。
装饰通过编译器步骤分三步进行
- 收集并标记实现
ConfigurationCardProvider
接口的所有服务。 - 创建一个
ConfigurationCardProviderProvider
定义,它接收(1)中的所有服务。 - 创建
ConfigurationCardConfigReader
定义,并装饰了Shopware\Core\System\SystemConfig\Util\ConfigReader
服务,并将ConfigurationCardProviderProvider
注入到ConfigurationCardConfigReader
中。 - 将
ConfigurationCardConfigReader
设置为Shopware\Core\System\SystemConfig\Util\ConfigReader
服务的别名以替换它。
Shopware插件配置持久化
Shopware将其数据库中的插件配置保存为键值对。当安装插件时,Shopware使用Shopware\Core\System\SystemConfig\Util\ConfigReader
读取配置并持久化默认值。然而,插件的服务在插件激活期间而不是在安装期间添加到DI容器中。这意味着允许基于代码配置生成的服务装饰在安装期间未使用。因此,只持久化config.xml
文件中的默认值。
该软件包提供了一个服务订阅者,它订阅Shopware的PluginPostActivateEvent
和PluginPostUpdateEvent
。该服务需要插件/包实例来执行配置持久化。订阅者通过使用在注册的ConfigurationCardProvider
实例中定义的包基类以及从KernelPluginCollection
服务中获取插件实例来检查是否需要配置持久化。编译器步骤负责服务定义、参数注入和订阅标记。
Shopware会检查已持久化的配置值,并且不会覆盖它们。因此,使用此软件包的插件的多次安装/卸载/激活/停用不会重置配置值,除非使用“删除所有数据”选项。
插件激活后,HTTP缓存可能会被重置。为了避免新持久化的配置值的问题,事件订阅者以100的优先级注册,以便尽可能早地执行(至少在优先级为0的其他事件订阅者之前)。
贡献
我很高兴看到软件开发商社区喜欢开源,就像我一样!♥
这就是为什么我感激每一个提交的问题(最好是建设性的)以及每个提供其他甚至更好的代码到这个软件包的拉取请求。
你们都太棒了!