Shopware 6装饰ProductDefinition后前台报错:实体定义不存在
解决Shopware装饰ProductDefinition后台正常前台报错问题
问题描述
通过依赖注入装饰Shopware\Core\Content\Product\ProductDefinition,DI配置如下:
<?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="MyPlugin\Core\Content\Product\ProductDefinitionDecorator" decorates="Shopware\Core\Content\Product\ProductDefinition" public="false"> <tag name="shopware.entity.definition" entity="product"/> </service> </services> </container>
同时编写继承原ProductDefinition的ProductDefinitionDecorator类,重写defineFields方法修改库存相关字段。目前Shopware管理后台功能正常,但前台加载商品列表或详情页时,出现错误:"Definition for entity \"Shopware\Core\Content\Product\ProductDefinition\" does not exist"。装饰类已继承原类中值为product的ENTITY_NAME常量,尝试装饰SalesChannelProductDefinition仍无效,后台可识别商品字段修改但前台商品相关功能崩溃。
解决方案
1. 修正DI配置,注入原服务依赖
装饰实体定义时,必须将原ProductDefinition服务注入到装饰类中,否则Shopware无法解析原定义的关联依赖。修改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="MyPlugin\Core\Content\Product\ProductDefinitionDecorator" decorates="Shopware\Core\Content\Product\ProductDefinition" public="false"> <argument type="service" id="MyPlugin\Core\Content\Product\ProductDefinitionDecorator.inner"/> <tag name="shopware.entity.definition" entity="product"/> </service> </services> </container>
2. 调整装饰类实现,确保正确继承与委托
装饰类的构造函数需接收原ProductDefinition实例并传递给父类,重写defineFields时先调用父类方法获取完整字段集合,再做修改:
<?php namespace MyPlugin\Core\Content\Product; use Shopware\Core\Content\Product\ProductDefinition; use Shopware\Core\Framework\DataAbstractionLayer\FieldCollection; class ProductDefinitionDecorator extends ProductDefinition { private ProductDefinition $originalDefinition; public function __construct(ProductDefinition $originalDefinition) { $this->originalDefinition = $originalDefinition; parent::__construct($originalDefinition->getEntityName()); } public function defineFields(): FieldCollection { // 获取父类原有字段集合 $fields = parent::defineFields(); // 在这里执行库存字段修改逻辑,示例: // $fields->remove('stock'); // $fields->add(new IntField('custom_stock', 'customStock')); return $fields; } // 确保实体名称与原定义一致 public function getEntityName(): string { return $this->originalDefinition->getEntityName(); } }
3. 清理缓存并生成实体元数据
执行以下命令刷新缓存,确保新的实体定义被系统加载:
bin/console cache:clear bin/console system:generate:entities
4. 无需单独装饰SalesChannelProductDefinition
SalesChannelProductDefinition是基于ProductDefinition的扩展,只要原ProductDefinition装饰正确,前台销售渠道的商品数据会自动继承修改后的字段,无需单独装饰。
内容的提问来源于stack exchange,提问作者JFD
相关产品推荐
相关产品推荐

