.. rst-class:: outdated How to add images to an entity? =============================== .. danger:: We're sorry but **this documentation section is outdated**. Please have that in mind when trying to use it. You can help us making documentation up to date via Sylius Github. Thank you! Extending entities with an ``images`` field is quite a popular use case. In this cookbook we will present how to **add image to the Shipping Method entity**. Instructions: ------------- 1. Extend the ShippingMethod class with the ImagesAwareInterface ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In order to override the ``ShippingMethod`` that lives inside of the SyliusCoreBundle, you have to create your own ShippingMethod class that will extend it: .. code-block:: php images = new ArrayCollection(); } /** * {@inheritdoc} */ public function getImages(): Collection { return $this->images; } /** * {@inheritdoc} */ public function getImagesByType(string $type): Collection { return $this->images->filter(function (ImageInterface $image) use ($type) { return $type === $image->getType(); }); } /** * {@inheritdoc} */ public function hasImages(): bool { return !$this->images->isEmpty(); } /** * {@inheritdoc} */ public function hasImage(ImageInterface $image): bool { return $this->images->contains($image); } /** * {@inheritdoc} */ public function addImage(ImageInterface $image): void { $image->setOwner($this); $this->images->add($image); } /** * {@inheritdoc} */ public function removeImage(ImageInterface $image): void { if ($this->hasImage($image)) { $image->setOwner(null); $this->images->removeElement($image); } } } .. tip:: Read more about customizing models in the docs :doc:`here `. 2. Register your extended ShippingMethod as a resource's model class ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ With such a configuration you will register your ``ShippingMethod`` class in order to override the default one: .. code-block:: yaml # config/packages/sylius_shipping.yaml sylius_shipping: resources: shipping_method: classes: model: App\Entity\ShippingMethod 3. Create the ShippingMethodImage class ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In the ``App\Entity`` namespace place the ``ShippingMethodImage`` class which should look like this: .. code-block:: php `. **Create the form extension class** for the ``Sylius\Bundle\ShippingBundle\Form\Type\ShippingMethodType``: It needs to have the images field as a CollectionType. .. code-block:: php add('images', CollectionType::class, [ 'entry_type' => ShippingMethodImageType::class, 'allow_add' => true, 'allow_delete' => true, 'by_reference' => false, 'label' => 'sylius.form.shipping_method.images', ]); } /** * {@inheritdoc} */ public function getExtendedType(): string { return ShippingMethodType::class; } } .. tip:: In case you need only a single image upload, this can be done in 2 very easy steps. First, in the code for the form provided above set ``allow_add`` and ``allow_delete`` to ``false`` Second, in the ``__construct`` method of the ``ShippingMethod`` entity you defined earlier add the following: .. code-block:: php public function __construct() { parent::__construct(); $this->images = new ArrayCollection(); $this->addImage(new ShippingMethodImage()); } Register the form extension as a service: .. code-block:: yaml # services.yml services: app.form.extension.type.shipping_method: class: App\Form\Extension\ShippingMethodTypeExtension tags: - { name: form.type_extension, extended_type: Sylius\Bundle\ShippingBundle\Form\Type\ShippingMethodType } 11. Declare the ImagesUploadListener service ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In order to handle the image upload you need to attach the ``ImagesUploadListener`` to the ``ShippingMethod`` entity events: .. code-block:: yaml # services.yml services: 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.shipping_method.pre_create, method: uploadImages } - { name: kernel.event_listener, event: sylius.shipping_method.pre_update, method: uploadImages } 12. Render the images field in the form view ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In order to achieve that you will need to customize the form view from the ``SyliusAdminBundle/views/ShippingMethod/_form.html.twig`` file. Copy and paste its contents into your own ``app/Resources/SyliusAdminBundle/views/ShippingMethod/_form.html.twig`` file, and render the ``{{ form_row(form.images) }}`` field. .. code-block:: twig {# app/Resources/SyliusAdminBundle/views/ShippingMethod/_form.html.twig #} {% from '@SyliusAdmin/Macro/translationForm.html.twig' import translationForm %}
{{ form_errors(form) }}
{{ form_row(form.code) }} {{ form_row(form.zone) }} {{ form_row(form.position) }}
{{ form_row(form.enabled) }}

{{ 'sylius.ui.availability'|trans }}

{{ form_row(form.channels) }}

{{ 'sylius.ui.category_requirements'|trans }}

{{ form_row(form.category) }} {% for categoryRequirementChoiceForm in form.categoryRequirement %} {{ form_row(categoryRequirementChoiceForm) }} {% endfor %}

{{ 'sylius.ui.taxes'|trans }}

{{ form_row(form.taxCategory) }}

{{ 'sylius.ui.shipping_charges'|trans }}

{{ form_row(form.calculator) }} {% for name, calculatorConfigurationPrototype in form.vars.prototypes %}
{% endfor %} {# Here you go! #} {{ form_row(form.images) }}
{% if form.configuration is defined %} {% for field in form.configuration %} {{ form_row(field) }} {% endfor %} {% endif %}
{{ translationForm(form.translations) }}
.. tip:: Learn more about customizing templates :doc:`here `. 13. Validation ^^^^^^^^^^^^^^ Your form so far is working fine, but don't forget about validation. The easiest way is using validation config files under the ``App/Resources/config/validation`` folder. This could look like this e.g.: .. code-block:: yaml # src\Resources\config\validation\ShippingMethodImage.yml App\Entity\ShippingMethodImage: properties: file: - Image: groups: [sylius] maxHeight: 1000 maxSize: 10240000 maxWidth: 1000 mimeTypes: - "image/png" - "image/jpg" - "image/jpeg" - "image/gif" mimeTypesMessage: 'This file format is not allowed. Please use PNG, JPG or GIF files.' minHeight: 200 minWidth: 200 This defines the validation constraints for each image entity. Now connecting the validation of the ``ShippingMethod`` to the validation of each single ``Image Entity`` is left: .. code-block:: yaml # src\Resources\config\validation\ShippingMethod.yml App\Entity\ShippingMethod: properties: ... images: - Valid: ~ Learn more ---------- * `GridBundle documentation `_ * `ResourceBundle documentation `_ * :doc:`Customization Guide `