如何在Shopware插件中覆盖ProductDefinition的默认值?
如何通过Shopware插件覆盖产品默认值?
\Shopware\Core\Content\Product\ProductDefinition::getDefaults 定义了产品部分字段的默认值:
public function getDefaults(): array { return [ 'isCloseout' => false, 'minPurchase' => 1, 'purchaseSteps' => 1, 'shippingFree' => false, 'restockTime' => null, 'active' => true, 'markAsTopseller' => false, ]; }
需求场景
通过REST API创建和更新产品时,要求:
- 创建产品时默认
active=false - 更新产品时,若请求中省略
active字段,保留后台已设置的当前值(不自动覆盖)
由于无法在每次更新前查询产品,希望通过插件修改默认值,避免使用composer补丁。
解决方案:使用事件监听实现
Shopware支持通过事件监听机制,在产品持久化前拦截并修改默认值,完全符合插件扩展规范,无需修改核心代码。
步骤1:创建事件订阅者
编写一个订阅者类,监听ProductBeforeWriteEvent事件,在新创建产品且未指定active字段时,手动设置默认值为false:
<?php namespace YourPluginNamespace\Subscriber; use Shopware\Core\Content\Product\Event\ProductBeforeWriteEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class ProductDefaultActiveSubscriber implements EventSubscriberInterface { public static function getSubscribedEvents(): array { return [ ProductBeforeWriteEvent::class => 'onProductBeforeWrite', ]; } public function onProductBeforeWrite(ProductBeforeWriteEvent $event): void { $product = $event->getProduct(); // 仅对新创建的产品生效,且未主动设置active字段时 if ($product->getId() === null && !$product->has('active')) { $product->set('active', false); } } }
步骤2:注册订阅者
在插件的src/Resources/config/services.xml中注册该订阅者:
<?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="YourPluginNamespace\Subscriber\ProductDefaultActiveSubscriber"> <tag name="kernel.event_subscriber"/> </service> </services> </container>
效果说明
- 创建产品:当REST API请求中省略
active字段时,会自动设置为false,替代核心默认的true - 更新产品:若请求中未携带
active字段,由于产品已有ID,订阅者不会修改该字段,保留后台设置的当前值
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

