vendor/vich/uploader-bundle/src/Form/Type/VichFileType.php line 27

Open in your IDE?
  1. <?php
  2. namespace Vich\UploaderBundle\Form\Type;
  3. use Symfony\Component\Form\AbstractType;
  4. use Symfony\Component\Form\Extension\Core\Type;
  5. use Symfony\Component\Form\FormBuilderInterface;
  6. use Symfony\Component\Form\FormEvent;
  7. use Symfony\Component\Form\FormEvents;
  8. use Symfony\Component\Form\FormInterface;
  9. use Symfony\Component\Form\FormView;
  10. use Symfony\Component\OptionsResolver\Options;
  11. use Symfony\Component\OptionsResolver\OptionsResolver;
  12. use Symfony\Component\PropertyAccess\PropertyAccess;
  13. use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
  14. use Symfony\Component\PropertyAccess\PropertyPath;
  15. use Vich\UploaderBundle\Form\DataTransformer\FileTransformer;
  16. use Vich\UploaderBundle\Handler\UploadHandler;
  17. use Vich\UploaderBundle\Mapping\PropertyMappingFactory;
  18. use Vich\UploaderBundle\Storage\StorageInterface;
  19. /**
  20.  * @author Kévin Gomez <contact@kevingomez.fr>
  21.  * @author Konstantin Myakshin <koc-dp@yandex.ru>
  22.  * @author Massimiliano Arione <max.arione@gmail.com>
  23.  */
  24. class VichFileType extends AbstractType
  25. {
  26.     /**
  27.      * @var StorageInterface
  28.      */
  29.     protected $storage;
  30.     /**
  31.      * @var UploadHandler
  32.      */
  33.     protected $handler;
  34.     /**
  35.      * @var PropertyMappingFactory
  36.      */
  37.     protected $factory;
  38.     /**
  39.      * @var PropertyAccessorInterface
  40.      */
  41.     protected $propertyAccessor;
  42.     public function __construct(
  43.         StorageInterface $storage,
  44.         UploadHandler $handler,
  45.         PropertyMappingFactory $factory,
  46.         PropertyAccessorInterface $propertyAccessor null
  47.     ) {
  48.         $this->storage $storage;
  49.         $this->handler $handler;
  50.         $this->factory $factory;
  51.         $this->propertyAccessor $propertyAccessor ?: PropertyAccess::createPropertyAccessor();
  52.     }
  53.     public function configureOptions(OptionsResolver $resolver): void
  54.     {
  55.         $resolver->setDefaults([
  56.             'allow_delete' => true,
  57.             'asset_helper' => false,
  58.             'download_link' => null,
  59.             'download_uri' => true,
  60.             'download_label' => 'vich_uploader.link.download',
  61.             'delete_label' => 'vich_uploader.form_label.delete_confirm',
  62.             'error_bubbling' => false,
  63.         ]);
  64.         $resolver->setAllowedTypes('allow_delete''bool');
  65.         $resolver->setAllowedTypes('asset_helper''bool');
  66.         $resolver->setAllowedTypes('download_link', ['null''bool']);
  67.         $resolver->setAllowedTypes('download_uri', ['bool''string''callable']);
  68.         $resolver->setAllowedTypes('download_label', ['bool''string''callable'PropertyPath::class]);
  69.         $resolver->setAllowedTypes('error_bubbling''bool');
  70.         $downloadUriNormalizer = static function (Options $options$downloadUri) {
  71.             if (null !== $options['download_link']) {
  72.                 @\trigger_error('The "download_link" option is deprecated since version 1.6 and will be removed in 2.0. You should use "download_uri" instead.'E_USER_DEPRECATED);
  73.                 return $options['download_link'];
  74.             }
  75.             return $downloadUri;
  76.         };
  77.         $resolver->setNormalizer('download_uri'$downloadUriNormalizer);
  78.     }
  79.     public function buildForm(FormBuilderInterface $builder, array $options): void
  80.     {
  81.         $builder->add('file'Type\FileType::class, [
  82.             'required' => $options['required'],
  83.             'label' => $options['label'],
  84.             'attr' => $options['attr'],
  85.             'translation_domain' => $options['translation_domain'],
  86.         ]);
  87.         $builder->addModelTransformer(new FileTransformer());
  88.         if ($options['allow_delete']) {
  89.             $this->buildDeleteField($builder$options);
  90.         }
  91.     }
  92.     protected function buildDeleteField(FormBuilderInterface $builder, array $options): void
  93.     {
  94.         // add delete only if there is a file
  95.         $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($options): void {
  96.             $form $event->getForm();
  97.             $parent $form->getParent();
  98.             // no object: no delete button
  99.             if (null === $parent) {
  100.                 return;
  101.             }
  102.             $object $parent->getData();
  103.             // no object or no uploaded file: no delete button
  104.             if (null === $object || null === $this->storage->resolveUri($object$form->getName())) {
  105.                 return;
  106.             }
  107.             $form->add('delete'Type\CheckboxType::class, [
  108.                 'label' => $options['delete_label'],
  109.                 'mapped' => false,
  110.                 'translation_domain' => $options['translation_domain'],
  111.                 'required' => false,
  112.             ]);
  113.         });
  114.         // delete file if needed
  115.         $builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event): void {
  116.             $form $event->getForm();
  117.             $object $form->getParent()->getData();
  118.             $delete $form->has('delete') ? $form->get('delete')->getData() : false;
  119.             if (!$delete) {
  120.                 return;
  121.             }
  122.             $this->handler->remove($object$form->getName());
  123.         });
  124.     }
  125.     public function buildView(FormView $viewFormInterface $form, array $options): void
  126.     {
  127.         $object $form->getParent()->getData();
  128.         $view->vars['object'] = $object;
  129.         $view->vars['download_uri'] = null;
  130.         if ($options['download_uri'] && $object) {
  131.             $view->vars['download_uri'] = $this->resolveUriOption($options['download_uri'], $object$form);
  132.             $view->vars \array_replace(
  133.                 $view->vars,
  134.                 $this->resolveDownloadLabel($options['download_label'], $object$form)
  135.             );
  136.         }
  137.         $view->vars['asset_helper'] = $options['asset_helper'];
  138.     }
  139.     public function getBlockPrefix(): string
  140.     {
  141.         return 'vich_file';
  142.     }
  143.     protected function resolveUriOption($uriOption$objectFormInterface $form)
  144.     {
  145.         if (true === $uriOption) {
  146.             return $this->storage->resolveUri($object$form->getName());
  147.         }
  148.         if (\is_callable($uriOption)) {
  149.             return $uriOption($object$this->storage->resolveUri($object$form->getName()));
  150.         }
  151.         return $uriOption;
  152.     }
  153.     protected function resolveDownloadLabel($downloadLabel$objectFormInterface $form): array
  154.     {
  155.         if (true === $downloadLabel) {
  156.             $mapping $this->factory->fromField($object$form->getName());
  157.             return ['download_label' => $mapping->readProperty($object'originalName'), 'translation_domain' => false];
  158.         }
  159.         if (\is_callable($downloadLabel)) {
  160.             $result $downloadLabel($object);
  161.             return [
  162.                 'download_label' => $result['download_label'] ?? $result,
  163.                 'translation_domain' => $result['translation_domain'] ?? false,
  164.             ];
  165.         }
  166.         if ($downloadLabel instanceof PropertyPath) {
  167.             return [
  168.                 'download_label' => $this->propertyAccessor->getValue($object$downloadLabel),
  169.                 'translation_domain' => false,
  170.             ];
  171.         }
  172.         return ['download_label' => $downloadLabel];
  173.     }
  174. }