Sylius / Symfony: загрузка изображений с пользовательским объектом - PullRequest
0 голосов
/ 19 октября 2019

Я пытаюсь использовать Sylius 'ImagesUploadListener для пользовательского объекта. В документации говорится, что я должен прослушать событие типа "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 }

1 Ответ

1 голос
/ 19 октября 2019

Должно быть событие, к которому нужно подключиться, если вы правильно создали сущность (способ 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 (Product), чтобы вы могли выполнить проверку типа.

Не забудьте зарегистрировать 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,
              }
...