全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Shopware订单对象中获取产品自定义字段的正确方法

本文详细阐述了在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 与 translations

在Shopware的实体关联中:

  • .translations: 用于加载当前上下文语言下的实体翻译数据。如果自定义字段被配置为“可翻译”,则它们会存储在翻译实体中。但如果自定义字段是全局的、非语言相关的,它们则不会出现在这里。
  • .default: 通常指向实体的主数据或默认数据。对于产品而言,这包含了产品的基础信息以及那些不依赖于特定语言的自定义字段。当自定义字段不是可翻译的(即在Shopware后台创建时未勾选“可翻译”选项),它们就会存储在这里。

因此,当需要访问那些全局的、非语言相关的自定义字段时,应优先考虑关联.default。如果确实需要访问特定语言下的可翻译自定义字段,则需要确保该自定义字段在后台被配置为可翻译,并且在查询时使用正确的语言上下文。

实践建议

  1. 明确自定义字段类型: 在Shopware后台创建自定义字段时,要清楚其是“可翻译”还是“不可翻译”。这决定了在代码中如何正确地通过关联来访问它们。
  2. 选择合适的关联路径:
    • 对于非语言相关的自定义字段,使用.default关联。
    • 对于语言相关的自定义字段,如果需要特定语言的翻译,可以使用.translations并确保上下文语言正确。
  3. 考虑性能: 过多的关联会增加数据库查询的复杂度和数据量。只关联你真正需要的数据,避免不必要的关联。
  4. 上下文管理: Context::createDefaultContext()通常用于获取系统默认上下文。如果你的操作需要在特定的销售渠道或语言环境下执行,请确保使用相应的上下文对象。
  5. 空值检查: 始终对获取到的实体和自定义字段数组进行空值检查,以避免潜在的null引用错误。

通过理解Shopware的数据关联机制,特别是default和translations的区别,开发者可以更精确、高效地在订单对象中获取所需的产品自定义字段,从而构建健壮的Shopware应用程序。


# go  # 多语言  # 区别  # NULL  # 对象  # default  # 数据库  # 自定义  # 在这里  # 联会  # 销售渠道  # 象中  # 是一个  # 器中  # 加载  # 就会  # 也会 


相关文章: 合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?  青浦网站制作公司有哪些,苹果官网发货地是哪里?  猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?  制作充值网站的软件,做人力招聘为什么要自己交端口钱?  制作电商网页,电商供应链怎么做?  C++时间戳转换成日期时间的步骤和示例代码  北京企业网站设计制作公司,北京铁路集团官方网站?  如何在西部数码注册域名并快速搭建网站?  利用JavaScript实现拖拽改变元素大小  建站之家VIP精选网站模板与SEO优化教程整合指南  怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?  文字头像制作网站推荐软件,醒图能自动配文字吗?  零服务器AI建站解决方案:快速部署与云端平台低成本实践  香港服务器网站推广:SEO优化与外贸独立站搭建策略  如何通过WDCP绑定主域名及创建子域名站点?  整人网站在线制作软件,整蛊网站退不出去必须要打我是白痴才能出去?  杭州银行网站设计制作流程,杭州银行怎么开通认证方式?  制作网站的过程怎么写,用凡科建站如何制作自己的网站?  武汉外贸网站制作公司,现在武汉外贸前景怎么样啊?  做企业网站制作流程,企业网站制作基本流程有哪些?  如何通过VPS搭建网站快速盈利?  如何用已有域名快速搭建网站?  如何选择可靠的免备案建站服务器?  怎么用手机制作网站链接,dw怎么把手机适应页面变成网页?  网站网页制作专业公司,怎样制作自己的网页?  建站之星2.7模板快速切换与批量管理功能操作指南  建站之星在线版空间:自助建站+智能模板一键生成方案  如何在Golang中使用encoding/gob序列化对象_存储和传输数据  手机怎么制作网站教程步骤,手机怎么做自己的网页链接?  如何快速生成橙子建站落地页链接?  湖南网站制作公司,湖南上善若水科技有限公司做什么的?  c++23 std::expected怎么用 c++优雅处理函数错误返回【详解】  建站之星后台搭建步骤解析:模板选择与产品管理实操指南  教学论文网站制作软件有哪些,写论文用什么软件 ?  PHP 500报错的快速解决方法  如何选购建站域名与空间?自助平台全解析  如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?  如何高效配置香港服务器实现快速建站?  如何选择PHP开源工具快速搭建网站?  建站中国官网:模板定制+SEO优化+建站流程一站式指南  网站app免费制作软件,能免费看各大网站视频的手机app?  建站主机选虚拟主机还是云服务器更好?  如何在新浪SAE免费搭建个人博客?  表情包在线制作网站免费,表情包怎么弄?  香港服务器网站测试全流程:性能评估、SEO加载与移动适配优化  建站VPS能否同时实现高效与安全翻墙?  如何基于云服务器快速搭建个人网站?  建站之星手机一键生成:多端自适应+小程序开发快速建站指南  如何通过西部建站助手安装IIS服务器?  如何打造高效商业网站?建站目的决定转化率 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。