Easyadminbundle: 3.1.8 breaks ImageField with VichImageType form type

Created on 18 Nov 2020  Â·  9Comments  Â·  Source: EasyCorp/EasyAdminBundle

Describe the bug
I have several ImageFields with a VichImageType type. They used to work, but 3.1.8 broke them.

To Reproduce
Add a field with this kind of setup:

ImageField::new('thumbnailFile')->setFormType(VichImageType::class)

You'll get the following error:

An error has occurred resolving the options of the form "Vich\UploaderBundle\Form\Type\VichImageType": The options "upload_dir", "upload_filename" do not exist. Defined options are: "action", "allow_delete", "allow_extra_fields", "allow_file_upload", "asset_helper", "attr", "attr_translation_parameters", "auto_initialize", "block_name", "block_prefix", "by_reference", "compound", "constraints", "csrf_field_name", "csrf_message", "csrf_protection", "csrf_token_id", "csrf_token_manager", "data", "data_class", "delete_label", "disabled", "download_label", "download_link", "download_uri", "ea_crud_form", "empty_data", "error_bubbling", "error_mapping", "extra_fields_message", "help", "help_attr", "help_html", "help_translation_parameters", "image_uri", "imagine_pattern", "inherit_data", "invalid_message", "invalid_message_parameters", "is_empty_callback", "label", "label_attr", "label_format", "label_html", "label_translation_parameters", "mapped", "method", "post_max_size_message", "property_path", "required", "row_attr", "storage_resolve_method", "translation_domain", "trim", "upload_max_size_message", "validation_groups".

Using VichImageType used to be handy, because it allows to define upload_destination and namer in a config file and forget it.

(OPTIONAL) Additional context
I guess it's linked to fd3dbf81562ec3130fc8b91281f0c6eb0215ed1b but cannot figure out why, yet.

Most helpful comment

All 9 comments

This was reported in Symfony Slack too.

I know it looks like a "BC break" but it's not. Let me explain. You were using a built-in field (Image) with a custom form type (Vich). I understand why you did that -> Image was half-implemented and didn't support file uploading, so you needed to "hack" a solution meanwhile.

I don't know if we can support Vich in this field ... but generally speaking, built-in fields should only use the form types they were designed for. If you "hack" a solution to change the form type, that's an unsupported case.

I don't know if it's a viable solution for you, but the new Image field has both a ->setUploadDirectory() and a ->setUploadedFileNamePattern() which are exactly what you are using via upload_destination and namer in Vich.

For now, let me close this issue and I'm going to open another generic issue about Vich.

Understood.

If anyone's interested, I've coded a small Service to help with that:

<?php

// src/Service/VichImageFieldService.php

namespace App\Service;

use App\Service\vo\VichImageFieldOptions;
use EasyCorp\Bundle\EasyAdminBundle\Field\ImageField;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\PropertyAccess\PropertyAccess;
use Vich\UploaderBundle\Mapping\PropertyMappingFactory;
use function Symfony\Component\String\s;

class VichImageFieldService {

    /**
     * @var PropertyMappingFactory
     */
    private $propertyMappingFactory;

    /**
     * @var KernelInterface
     */
    private $kernel;

    /**
     * VichImageFieldService constructor.
     *
     * @param PropertyMappingFactory $propertyMappingFactory
     * @param KernelInterface $kernel
     */
    public function __construct(PropertyMappingFactory $propertyMappingFactory, KernelInterface $kernel) {
        $this->propertyMappingFactory = $propertyMappingFactory;
        $this->kernel = $kernel;
    }

    public function getUploadDir($class, $field) {
        $pm = $this->propertyMappingFactory->fromField(new $class, $field);
        $uploadDestination = $pm->getUploadDestination();
        $projectDir = $this->kernel->getProjectDir();
        return s($uploadDestination)->after($projectDir)->toString();
    }

    public function getNamer($class, $field) {
        return function(UploadedFile $file) use ($class, $field) {
            $instance = new $class;
            $pm = $this->propertyMappingFactory->fromField($instance, $field);
            $pa = PropertyAccess::createPropertyAccessor();
            $pa->setValue($instance, $field, $file);
            return $pm->getNamer()->name($instance, $pm);
        };
    }

    public function setOptions(ImageField $imageField, $class, $field):ImageField {
        return $imageField->setUploadDir($this->getUploadDir($class, $field))->setUploadedFileNamePattern($this->getNamer($class, $field));
    }

}

You can use it like that:

(...)
// src/Controller/Admin/GameCrudController.php
    public function configureFields(string $pageName): iterable {
        return [
            IntegerField::new('id', 'ID')->hideOnForm(),
            $this->vichImageFieldService->setOptions(ImageField::new('thumbnailFileName'), Game::class, 'thumbnailFile'),
        ];
    }
(...)

Thinking of it, it could benefit from being a field configurator 🤔
Any thoughts @javiereguiluz?

Hum, warning: this script is not perfect, as the upload directory is prefixed to the file name when saving. So it breaks the file path when submitting the form (even when changing nothing).

Latest release (3.1.9) fixes my previous warning âš¡

Personnaly I move from VichUploaderBundle to EasyAdmin new upload method. Love it, thank you for the hard work :)

@javiereguiluz there is no doc on how to use this new Image field...
@quentint how did you finally solve this? I'm considering reverting to 3.1.7 now.

I think it's a shame not to report this as a BC break as previous version of AE supported Vich, and now we all have lot of apps using this "dual" setup. Switching to something else can be a burden (that said, as there is no doc, I have no clue...).
Thanks for your help!

Well, m'y implementation now works, so I'm using it as is. Did you try it?

@quentint with the specific Service above, right? I'll give it a try ;) How does your AE field configuration look like now?

Was this page helpful?
0 / 5 - 0 ratings