【问题标题】:Sylius/Symfony: Image Upload with custom entitySylius/Symfony:使用自定义实体上传图片
【发布时间】:2019-10-19 11:58:26
【问题描述】:

我正在尝试将 Sylius 的 ImagesUploadListener 用于自定义实体。 在documentation 中,它说我应该听一个像“sylius.shipping_method.pre_create”这样的事件。对于我的自定义实体,没有可以调用的事件。

所以我尝试的是挂钩 product.pre_create 事件并将我的实体作为参数,但似乎图像上传仅在产品实体上触发,而我的实体配置被忽略。虽然 ImagesUploadListener 被触发了两次,一次来自核心,一次来自我的配置。

我得到的错误是“列'路径'不能为空”,这基本上意味着 ImagesUploadListener 在保存实体之前没有执行图像上传。

    app.listener.images_upload:
        class: Sylius\Bundle\CoreBundle\EventListener\ImagesUploadListener
        parent: sylius.listener.images_upload
        autowire: true
        autoconfigure: false
        public: false
        tags:
            - { name: kernel.event_listener, event: sylius.product.pre_create, entity: MyBundle\Entity\MyEntity, method: uploadImages }

【问题讨论】:

    标签: symfony sylius


    【解决方案1】:

    如果您正确创建了实体(Sylius 方式),则应该有一个事件可以触发。您需要将实体定义为资源:

    # config/packages/sylius_resource.yaml
    sylius_resource:
        resources:
            app.name_of_etity:
                driver: doctrine/orm
                classes:
                    model: App\Entity\NameOfEntity
    

    如果您这样定义资源,则事件将是:

    event: app.system_manual.pre_create
    event: app.app.name_of_entity.pre_update
    

    按照本指南: https://docs.sylius.com/en/1.6/cookbook/entities/custom-model.html

    更新

    因为您正在通过现有产品表单管理您的自定义实体,所以上述内容将不起作用。要使其工作,您可以创建自己的事件侦听器。

    final class ProductSeoTranslationImagesUploadListener
    {
        /** @var ImageUploaderInterface */
        private $uploader;
    
        public function __construct(ImageUploaderInterface $uploader)
        {
            $this->uploader = $uploader;
        }
    
        public function uploadImages(GenericEvent $event): void
        {
            $subject = $event->getSubject();
            // Add a ProductSeoInterface so you can use this check: 
            Assert::isInstanceOf($subject, ProductSeoInterface::class);
            foreach ($subject->getSeo()->getTranslations() as $translation) {
                Assert::isInstanceOf($translation, ImagesAwareInterface::class);
                $this->uploadSubjectImages($translation);
            }
        }
    
        private function uploadSubjectImages(ImagesAwareInterface $subject): void
        {
            $images = $subject->getImages();
            foreach ($images as $image) {
                if ($image->hasFile()) {
                    $this->uploader->upload($image);
                }
    
                // Upload failed? Let's remove that image.
                if (null === $image->getPath()) {
                    $images->removeElement($image);
                }
            }
        }
    }
    
    

    提示:创建(产品)SeoInterface,以便您可以执行类型检查。

    别忘了注册eventListener:

    App\EventListener\ProductSeoTranslationImagesUploadListener:
            tags:
                - {
                      name: kernel.event_listener,
                      event: sylius.product.pre_create,
                      method: uploadImages,
                  }
                - {
                      name: kernel.event_listener,
                      event: sylius.product.pre_update,
                      method: uploadImages,
                  }
    

    【讨论】:

    • 感谢您的回答!我正在开发一个 sylius 插件,所以我假设插件名称空间必须是事件名称的一部分。到目前为止,我尝试过:sylius.my_entity.pre_update、my_bundle.my_entity.pre_update、sylius.my_bundle.my_entity.pre_update。但我总是在“未调用的侦听器”列表中找到事件名称。所以这些不是被触发的事件。有什么方法可以找出在请求期间触发了哪些事件?
    • 您是否检查了 Profiler 中的孤立事件选项卡?您是否将实体定义为捆绑包中的资源?该 ID 应与事件 ID 相同。
    • 孤立事件中没有任何相关内容。该实体被定义为名称为“sylius_better_seo_plugin.product_seo_translation”的资源。所以我尝试了“sylius_better_seo_plugin.product_seo_translation.pre_update”作为一个事件。我只在“未调用的侦听器”中看到它。
    • 我看到您将其称为“product_seo_translation”,所以我假设您正在将实体字段添加到现有的产品表单中,还是单独的表单?如果您使用的是产品表单,它应该与您的原始配置“sylius.product.pre_create”一起使用。所以可能还有其他问题
    • 产品 > product_seo > product_seo_translation。是的,它以现有产品形式进行管理。但是,当我使用“sylius.product.pre_create”时,将为产品实体而不是 product_seo_translation 实体完成图像上传。
    猜你喜欢
    • 2021-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-06
    • 1970-01-01
    • 1970-01-01
    • 2021-08-02
    相关资源
    最近更新 更多