Completed
Push — master ( 0e48fe...1653dd )
by Benoit
16:54 queued 06:48
created

ImageType::configureOptions()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 24
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 24
rs 8.9713
c 0
b 0
f 0
cc 1
eloc 19
nc 1
nop 1
1
<?php
2
3
namespace Presta\ImageBundle\Form\Type;
4
5
use Presta\ImageBundle\Form\DataTransformer\Base64ToImageTransformer;
6
use Presta\ImageBundle\Model\AspectRatio;
7
use Symfony\Component\Form\AbstractType;
8
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
9
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
10
use Symfony\Component\Form\FormBuilderInterface;
11
use Symfony\Component\Form\FormEvent;
12
use Symfony\Component\Form\FormEvents;
13
use Symfony\Component\Form\FormInterface;
14
use Symfony\Component\Form\FormView;
15
use Symfony\Component\OptionsResolver\OptionsResolver;
16
use Symfony\Component\Translation\TranslatorInterface;
17
use Vich\UploaderBundle\Handler\UploadHandler;
18
use Vich\UploaderBundle\Storage\StorageInterface;
19
20
/**
21
 * @author Benoit Jouhaud <[email protected]>
22
 */
23
class ImageType extends AbstractType
24
{
25
    /**
26
     * @var TranslatorInterface
27
     */
28
    private $translator;
29
30
    /**
31
     * @var StorageInterface
32
     */
33
    private $storage;
34
35
    /**
36
     * @var UploadHandler
37
     */
38
    protected $handler;
39
40
    /**
41
     * @param TranslatorInterface $translator
42
     * @param StorageInterface $storage
43
     * @param UploadHandler $handler
44
     */
45
    public function __construct(TranslatorInterface $translator, StorageInterface $storage, UploadHandler $handler)
46
    {
47
        $this->translator = $translator;
48
        $this->storage = $storage;
49
        $this->handler = $handler;
50
    }
51
52
    /**
53
     * {@inheritdoc}
54
     */
55
    public function buildForm(FormBuilderInterface $builder, array $options)
56
    {
57
        $builder
58
            ->add('base64', HiddenType::class, [
59
                'attr' => [
60
                    'class' => 'cropper-base64',
61
                ],
62
            ])
63
        ;
64
65
        $builder->addModelTransformer(new Base64ToImageTransformer);
66
67
        if ($options['allow_delete']) {
68
            $this->buildDeleteField($builder, $options);
69
        }
70
    }
71
72
    /**
73
     * {@inheritdoc}
74
     */
75
    public function configureOptions(OptionsResolver $resolver)
76
    {
77
        $aspectRatios = [];
78
79
        $this->addAspectRatio($aspectRatios, '16_9', 1.78);
80
        $this->addAspectRatio($aspectRatios, '4_3', 1.33);
81
        $this->addAspectRatio($aspectRatios, '1', 1);
82
        $this->addAspectRatio($aspectRatios, '2_3', 0.66);
83
        $this->addAspectRatio($aspectRatios, 'nan', null, true);
84
85
        $resolver
86
            ->setDefault('allow_delete', true)
87
            ->setDefault('delete_label', 'btn_delete')
88
            ->setDefault('aspect_ratios', $aspectRatios)
89
            ->setDefault('cropper_options', ['autoCropArea' => 1])
90
            ->setDefault('max_width', 320)
91
            ->setDefault('max_height', 180)
92
            ->setDefault('download_uri', null)
93
            ->setDefault('download_link', true)
94
            ->setDefault('enable_locale', true)
95
            ->setDefault('enable_remote', true)
96
            ->setDefault('translation_domain', 'PrestaImageBundle')
97
        ;
98
    }
99
100
    /**
101
     * {@inheritdoc}
102
     */
103
    public function buildView(FormView $view, FormInterface $form, array $options)
104
    {
105
        $view->vars['aspect_ratios'] = $options['aspect_ratios'];
106
        $view->vars['cropper_options'] = json_encode($options['cropper_options']);
107
        $view->vars['max_width'] = $options['max_width'];
108
        $view->vars['max_height'] = $options['max_height'];
109
        $view->vars['enable_locale'] = $options['enable_locale'];
110
        $view->vars['enable_remote'] = $options['enable_remote'];
111
        $view->vars['object'] = $form->getParent()->getData();
112
113
        if ($options['download_link'] && $view->vars['object']) {
114
            $view->vars['download_uri'] = $this->storage->resolveUri($form->getParent()->getData(), $form->getName());
115
        }
116
    }
117
118
    /**
119
     * @param FormBuilderInterface $builder
120
     * @param array $options
121
     */
122
    protected function buildDeleteField(FormBuilderInterface $builder, array $options)
123
    {
124
        // add delete only if there is a file
125
        $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($options) {
126
            $form = $event->getForm();
127
            $object = $form->getParent()->getData();
128
129
            // no object or no uploaded file: no delete button
130
            if (null === $object || null === $this->storage->resolvePath($object, $form->getName())) {
131
                return;
132
            }
133
134
            $form->add('delete', CheckboxType::class, [
135
                'label' => $options['delete_label'],
136
                'required' => false,
137
                'mapped' => false,
138
                'translation_domain' => $options['translation_domain']
139
            ]);
140
        });
141
142
        // delete file if needed
143
        $builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) use ($options) {
144
            $form = $event->getForm();
145
            $delete = $form->has('delete') ? $form->get('delete')->getData() : false;
146
            $entity = $form->getParent()->getData();
147
148
            if (!$delete) {
149
                return;
150
            }
151
152
            $this->handler->remove($entity, $form->getName());
153
        });
154
    }
155
156
    /**
157
     * @param array $aspectRatios
158
     * @param string $key
159
     * @param float $value
160
     * @param bool $checked
161
     */
162
    private function addAspectRatio(array &$aspectRatios, $key, $value, $checked = false)
163
    {
164
        $label = $this->translator->trans(sprintf('aspect_ratio.%s', $key), [], 'PrestaImageBundle');
165
166
        $aspectRatios[$key] = new AspectRatio($value, $label, $checked);
167
    }
168
}
169