将 EntityManager 注入 AbstractResourceType Sylius

Inject EntityManager into AbstractResourceType Sylius

我整天都在寻找一种方法来访问 Sylius 中 ProductType(它扩展了 AbstractResourceType)中的渠道实体。具体来说,我需要在 ProductType class (src/Sylius/Bundle/ProductBundle/Form/Type/ProductType.php)

的 buildForm() 函数中获取 'US_Web_Store' 渠道实体

这是我的代码:

src/Sylius/Bundle/ProductBundle/Form/Type/ProductType.php

namespace Sylius\Bundle\ProductBundle\Form\Type;

use Doctrine\ORM\EntityManagerInterface;

class ProductType extends AbstractResourceType
{

    private $variantResolver;
    private $em;

    public function __construct($dataClass, $validationGroups, ProductVariantResolverInterface $variantResolver, EntityManagerInterface $em) {
        parent::__construct($dataClass, $validationGroups);

        $this->variantResolver = $variantResolver;
        $this->em = $em;
    }

    public function buildForm(FormBuilderInterface $builder, array $options) {

        $product = $builder->getData();
        $product->addChannel($this->container->get('sylius.repository.channel')->findOneBy(['code' => 'US_Web_Store']));

        [...]
    }

}

然后在src/Sylius/Bundle/ProductBundle/Resources/config/services.xml:

<service id="product.form.type.product" class="Sylius\Bundle\ProductBundle\Form\Type\ProductType">
    <argument type="service" id="doctrine.orm.entity_manager"/>
</service>

我得到的错误是:

类型错误:传递给 Sylius\Bundle\ProductBundle\Form\Type\ProductType::__construct() 的参数 4 必须实现给定的接口 Doctrine\ORM\EntityManagerInterface、none

我还尝试通过以下方式传递频道存储库:

但遇到了同样的问题。没有任何东西传递给控制器​​,所以我确信我在这里遗漏了一些基本的东西。

您的代码中存在一些问题。

  1. 您正在使用来自 SyliusProductType,这意味着它将被使用而不是默认的。但是,您的服务 ID 与 Sylius 中的不同(您有 product.form.type.product,在 Sylius 中是 sylius.form.type.product)。结果,您将有两个使用相同 Sylius\Bundle\ProductBundle\Form\Type\ProductType 的服务。您遇到的异常是由 sylius.form.type.product 服务引起的,该服务现在使用需要第四个参数的 class,但它没有得到它。如果您使用相同的键命名服务,它仍然会抛出异常,因为您需要将所有 4 个参数传递给服务定义中的构造函数,因为文档的 craigh. If you don't know what they are, you should look at the definition of sylius.form.type.product service. To get known about the most proper way of overriding Sylius forms, checkout the Customizing Forms 章节已经注意到了这一点。
  2. 如果您想通过代码获取频道,您应该始终为此使用存储库(sylius.repository.channel 服务)。
  3. 如果您只想在新创建的产品上设置渠道,为什么不为此使用自定义工厂?这是更干净的方式,将来不应导致任何意外错误。同样,请查看 proper documentation chapter 以了解如何正确执行此操作。

希望对您有所帮助 ;)