
本文详细阐述了在Shopware订单对象中,如何正确获取产品自定义字段的策略。针对常见的语言依赖性问题,教程指出通过调整关联路径为`lineItems.product.default`,而非`translations`,可以有效访问非语言相关的自定义字段,并提供了具体的代码示例和最佳实践,帮助开发者高效集成自定义数据。
在Shopware的开发实践中,经常需要在订单处理流程中访问与产品相关的自定义字段(Custom Fields)。例如,一个产品可能有一个名为emakers_custom_field_warehouse_name的自定义字段,用于存储其所属仓库的名称。当订单生成后,开发者需要从订单行项目(Line Items)中获取该产品及其自定义字段信息。然而,直接尝试获取自定义字段可能会遇到因语言依赖性而导致的数据缺失问题。
在Shopware中,产品数据通常包含多语言翻译。自定义字段的配置也可能分为语言相关和非语言相关两种。当通过订单对象检索产品信息时,如果自定义字段是非语言相关的,但查询关联却指向了翻译实体,就可能无法正确获取这些字段。
以下是一个常见的初始查询尝试,旨在获取订单及其行项目中的产品翻译信息:
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\System\SalesChannel\Repository\SalesChannelRepositoryInterface; // 假设通过销售渠道仓库获取订单
// ... 在一个服务或控制器中 ...
public function getOrderWithProductCustomFields(string $orderId): ?OrderEntity
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('id', $orderId));
$criteria->addAssociations([
'deliveries.shippingOrderAddress.salutation',
'deliveries.shippingOrderAddress.country',
'orderCustomer.customer.group',
'lineItems.product.translations', // 初始尝试,关联产品翻译
]);
// 假设通过 orderRepository 注入
$orderObject = $this->orderRepository->search($criteria, Context::createDefaultContext())->first();
if ($orderObject) {
$firstLineItem = $orderObject->getLineItems()->first();
if ($firstLineItem && $firstLineItem->getProduct()) {
// 尝试获取自定义字段,此时可能为空
$customFields = $firstLineItem->getProduct()->getCustomFields();
// 尝试访问产品翻译,会报错:Attempted to call an undefined method named "getProductTranslations"
// $firstLineItem->getProduct()->getProductTranslations();
}
}
return $orderObject;
}在这种情况下,即使产品数据中确实存在emakers_custom_field_warehouse_name这样的自定义字段,通过$firstLineItem->getProduct()->getCustomFields()获取到的结果也可能是空的。进一步尝试直接调用getProductTranslations()方法也会导致错误,因为ProductEntity本身并没有直接暴露这个方法来获取所有翻译集合。
问题的核心在于,非语言相关的自定义字段通常存储在产品实体(ProductEntity)的默认数据中,而不是其语言翻译实体(ProductTranslationEntity)中。当通过'lineItems.product.translations'关联时,Shopware会加载与当前上下文语言匹配的产品翻译数据,而这些数据可能不包含非语言相关的自定义字段。
正确的做法是关联'lineItems.product.default'。这个关联会确保我们获取到产品实体的默认数据,其中就包含了那些不依赖于特定语言的自定义字段。
以下是修正后的Criteria配置:
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Checkout\Order\OrderEntity; // 引入OrderEntity
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; // 引入EntityRepository
// ... 在一个服务或控制器中 ...
class OrderService
{
private EntityRepository $orderRepository;
public function __construct(EntityRepository $orderRepository)
{
$this->orderRepository = $orderRepository;
}
public function getOrderWithProductCustomFields(string $orderId): ?OrderEntity
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('id', $orderId));
$criteria->addAssociations([
'deliveries.shippingOrderAddress.salutation',
'deliveries.shippingOrderAddress.country',
'orderCustomer.customer.group',
'lineItems.product.default', // 关键修改:关联产品默认数据
]);
$orderObject = $this->orderRepository->search($criteria, Context::createDefaultContext())->first();
if ($orderObject) {
$firstLineItem = $orderObject->getLineItems()->first();
if ($firstLineItem && $firstLineItem->getProduct()) {
// 现在可以正确获取自定义字段
$customFields = $firstLineItem->getProduct()->getCustomFields();
// 示例:访问特定自定义字段
if ($customFields && isset($customFields['emakers_custom_field_warehouse_name'])) {
$warehouseName = $customFields['emakers_custom_field_warehouse_name'];
// ... 处理 $warehouseName ...
}
return $orderObject;
}
}
return null;
}
}通过将关联从'lineItems.product.translations'改为'lineItems.product.default',$firstLineItem->getProduct()->getCustomFields()现在将能成功返回包含emakers_custom_field_warehouse_name在内的所有非语言相关自定义字段。
在Shopware的实体关联中:
因此,当需要访问那些全局的、非语言相关的自定义字段时,应优先考虑关联.default。如果确实需要访问特定语言下的可翻译自定义字段,则需要确保该自定义字段在后台被配置为可翻译,并且在查询时使用正确的语言上下文。
通过理解Shopware的数据关联机制,特别是default和translations的区别,开发者可以更精确、高效地在订单对象中获取所需的产品自定义字段,从而构建健壮的Shopware应用程序。
以上就是Shopware订单对象中获取产品自定义字段的正确方法的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号