Как в Symfony 5.1 подружить EasyAdmin 3, Entity и кастомную службу?

Моя задача: написать интернет-магазин, который будет продавать наборы фотографий. На продакшне фотографии будут храниться в Google Cloud Storage; на дев фотографии будут храниться локально.

Я решал задачу так:

  1. Создал doctrine entities Product и ImageFile (между ними есть связь 1 продукт ко многим файлам).
  2. Создал абстрактный класс FileStorage:
    abstract class FileStorage
    {
        private string $tmpDir;
    
        public static function factory(string $tmpDir, string $storageIdent)
        {
            switch ($storageIdent) {
                case 'local': return new FileStorageLocal($tmpDir);
                case 'google': return new FileStorageGoogle($tmpDir);
                default: throw new \Exception("Wrong storage ident: '{$ident}'");
            }
        }
    
        public function __construct(string $tmpDir)
        {
            $this->tmpDir = $tmpDir;
        }
    
        abstract public function upload(string $path);
        abstract public function download(string $ident, string $downloadFileName);
        abstract public function exists(string $ident): bool;
        abstract public function getHtmlLink(string $ident): string;
    
        protected function getIdent(string $path)
        {
            return md5_file($path) . '.' . pathinfo($path, PATHINFO_EXTENSION);
        }
    
        protected function getTmpDir()
        {
            return $this->tmpDir;
        }
    }
  1. Отнаследовал от базового класса FileStorageLocal и FileStorageGoogle.
  2. Создал в services.yaml службу, которая вызывает FileStorage::factory() и передаёт в фабрику параметры $tmpDir и $storageIdent, прописанные в файле .env (в будущем я сделаю разные параметры в .env.prod и .env.dev).
  3. Создал в ImageEntity метод:
    public function getHtmlLink(FileStorage $fileStorage)
    {
        return $fileStorage->getHtmlLink($this->getIdent());
    }
  1. В написанных мною контроллерах и шаблонах Twig я вызываю $imageFile->getHtmlLink() и передаю как параметр $fileStorage, полученный с помощью autowiring.

Всё было хорошо и всё работало, пока я не начал писать админку интернет-магазина. Для админки я решил использовать Easy Admin 3. Поэтому я создал ImageFileCrudController с таким методом:

public function configureFields(string $pageName): iterable
{
    return [
        ImageField::new('html_link')->hideOnForm(),
        TextField::new('original_file_name')->hideOnForm(),
        TextField::new('ident')->setFormTypeOption('disabled', 'disabled')->hideOnIndex(),
        AssociationField::new('product')->setSortable(false),
    ];
}

В результате получаю ошибку "Too few arguments to function App\Entity\ImageFile::getHtmlLink(), 0 passed in /var/www/html/vendor/symfony/property-access/PropertyAccessor.php on line 405 and exactly 1 expected". Я понимаю откуда ошибка взялась, но не понимаю, как её лучше исправить. Поэтому прошу у уважаемого сообщества помощи и совета по таким вопросам:

  1. Правильно ли я спроектировал взаимодействие ImageField, FileStorage, services.yaml и .env? Не видите ли вы способа сделать это проще и лучше?
  2. Нет ли в EasyAdmin 3 способа как-то перегрузить получение значения поля? Я слышал о кастомных полях, для которых пишутся свои собственные шаблоны twig. Можно ли передать в них аргументы из сервис-контейнера Symfony?
  3. Правильным ли был выбор Easy Admin 3? Может быть, у вас есть на примете более простая и универсальная админка?

Ответы (0 шт):