Completed
Push — master ( 798a5b...7a3632 )
by Christian
06:49 queued 05:03
created

VideoUploaderExtension   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 147
Duplicated Lines 0 %

Coupling/Cohesion

Dependencies 5

Test Coverage

Coverage 82.09%

Importance

Changes 0
Metric Value
wmc 12
cbo 5
dl 0
loc 147
ccs 55
cts 67
cp 0.8209
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A getExtendedType() 0 9 2
A __construct() 0 9 1
B configureOptions() 0 45 4
B buildView() 0 38 3
A setDefaultOptions() 0 9 2
1
<?php
2
3
/*
4
 * This file is part of the XabbuhPandaBundle package.
5
 *
6
 * (c) Christian Flothmann <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Xabbuh\PandaBundle\Form\Extension;
13
14
use Symfony\Component\Form\AbstractTypeExtension;
15
use Symfony\Component\Form\FormInterface;
16
use Symfony\Component\Form\FormView;
17
use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException;
18
use Symfony\Component\OptionsResolver\Options;
19
use Symfony\Component\OptionsResolver\OptionsResolver;
20
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
21
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
22
23
/**
24
 * Extends the {@link http://api.symfony.com/master/Symfony/Component/Form/Extension/Core/Type/FileType.html FileType}
25
 * by adding an option to mark such a field as a widget for using the
26
 * {@link http://www.pandastream.com/docs/video_uploader Panda uploader}.
27
 *
28
 * @author Christian Flothmann <[email protected]>
29
 */
30
class VideoUploaderExtension extends AbstractTypeExtension
31
{
32
    /**
33
     * The url generator
34
     * @var UrlGeneratorInterface
35
     */
36
    private $urlGenerator;
37
38
    /**
39
     * General options to configure the display of widget components
40
     * @var array
41
     */
42
    private $defaultOptions;
43
44
    /**
45
     * Constructor.
46
     *
47
     * @param UrlGeneratorInterface $urlGenerator   The url generator
48
     * @param array                 $defaultOptions Default display options for widget objects
49
     */
50 17
    public function __construct(UrlGeneratorInterface $urlGenerator, array $defaultOptions)
51
    {
52 17
        $this->urlGenerator = $urlGenerator;
53 17
        $this->defaultOptions = array_replace(array(
54 17
            'multiple_files' => false,
55
            'cancel_button' => true,
56
            'progress_bar' => true,
57
        ), $defaultOptions);
58 17
    }
59
60
    /**
61
     * {@inheritDoc}
62
     */
63 17
    public function getExtendedType()
64
    {
65
        // BC with Symfony < 2.8
66 17
        if (!method_exists('Symfony\Component\Form\AbstractType', 'getBlockPrefix')) {
67
            return 'file';
68
        }
69
70 17
        return 'Symfony\Component\Form\Extension\Core\Type\FileType';
71
    }
72
73
    /**
74
     * {@inheritDoc}
75
     */
76
    public function setDefaultOptions(OptionsResolverInterface $resolver)
77
    {
78
        // BC for symfony 2.6 and older which don't have the forward-compatibility layer
79
        if (!$resolver instanceof OptionsResolver) {
80
            throw new \InvalidArgumentException(sprintf('Custom resolver "%s" must extend "Symfony\Component\OptionsResolver\OptionsResolver".', get_class($resolver)));
81
        }
82
83
        $this->configureOptions($resolver);
84
    }
85
86
    /**
87
     * {@inheritDoc}
88
     */
89 17
    public function configureOptions(OptionsResolver $resolver)
90
    {
91 17
        $resolver->setDefaults(array(
92 17
            'panda_widget' => false,
93
            'panda_widget_version' => 2,
94
            'cloud' => null,
95
        ));
96 17
        $resolver->setDefaults($this->defaultOptions);
97
98 17
        $cloudNormalizer = function (Options $options, $cloud) {
99 16
            if (!$options['panda_widget']) {
100 4
                return null;
101
            }
102
103 12
            if (null === $cloud) {
104 1
                throw new InvalidOptionsException('The "cloud" option is required when enabling the panda widget.');
105
            }
106
107 11
            return $cloud;
108 17
        };
109
110 17
        if (method_exists($resolver, 'setNormalizer')) {
111 17
            $resolver->setNormalizer('cloud', $cloudNormalizer);
112 17
            $resolver->setAllowedValues('panda_widget', array(true, false, 'yes', 'no'));
113 17
            $resolver->setAllowedValues('panda_widget_version', array(1, 2));
114 17
            $resolver->setAllowedTypes('cancel_button', 'bool');
115 17
            $resolver->setAllowedTypes('cloud', array('null', 'string'));
116 17
            $resolver->setAllowedTypes('multiple_files', 'bool');
117 17
            $resolver->setAllowedTypes('panda_widget', array('bool', 'string'));
118 17
            $resolver->setAllowedTypes('progress_bar', 'bool');
119
        } else {
120
            $resolver->setNormalizers(array('cloud' => $cloudNormalizer));
0 ignored issues
show
Bug introduced by
The method setNormalizers() does not exist on Symfony\Component\OptionsResolver\OptionsResolver. Did you maybe mean setNormalizer()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
121
            $resolver->setAllowedValues(
122
                array("panda_widget" => array(true, false, 'yes', 'no')),
0 ignored issues
show
Documentation introduced by
array('panda_widget' => ...e, false, 'yes', 'no')) is of type array<string,array<integ...",\"3\":\"string\"}>"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
123
                array("panda_widget_version" => array(1, 2))
124
            );
125
            $resolver->setAllowedTypes(array(
0 ignored issues
show
Documentation introduced by
array('cancel_button' =>...rogress_bar' => 'bool') is of type array<string,string|arra...rogress_bar":"string"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Bug introduced by
The call to setAllowedTypes() misses a required argument $allowedTypes.

This check looks for function calls that miss required arguments.

Loading history...
126
                'cancel_button' => 'bool',
127
                'cloud' => array('null', 'string'),
128
                'multiple_files' => 'bool',
129
                'panda_widget' => array('bool', 'string'),
130
                'progress_bar' => 'bool',
131
            ));
132
        }
133 17
    }
134
135
    /**
136
     * {@inheritDoc}
137
     */
138 12
    public function buildView(FormView $view, FormInterface $form, array $options)
139
    {
140 12
        if (!$options['panda_widget'] || !isset($view->vars['id'])) {
141 1
            $view->vars["panda_uploader"] = false;
142
143 1
            return;
144
        }
145
146 11
        $view->vars["panda_uploader"] = true;
147
148 11
        $widgetVersion = $options["panda_widget_version"];
149
150
        // generate widgets' ids
151 11
        $formId = $view->vars["id"];
152 11
        $browseButtonId = "browse_button_$formId";
153 11
        $cancelButtonId = "cancel_button_$formId";
154 11
        $progressBarId = "progress_bar_$formId";
155
156
        // set input field attributes accordingly (widget ids will be
157
        // read from there by the javascript uploader implementation)
158 11
        $view->vars["attr"]["panda-uploader"] = "v$widgetVersion";
159 11
        $view->vars["attr"]["authorise-url"] = $this->urlGenerator->generate(
160 11
            "xabbuh_panda_authorise_upload",
161 11
            array("cloud" => $options["cloud"])
162
        );
163 11
        $view->vars["attr"]["multiple_files"] = var_export($options["multiple_files"], true);
164 11
        $view->vars["attr"]["browse-button-id"] = $browseButtonId;
165 11
        $view->vars["attr"]["cancel-button-id"] = $cancelButtonId;
166 11
        $view->vars["attr"]["progress-bar-id"] = $progressBarId;
167
168 11
        $view->vars["browse_button_id"] = $browseButtonId;
169 11
        $view->vars["browse_button_label"] = "Browse";
170 11
        $view->vars["cancel_button"] = $options["cancel_button"];
171 11
        $view->vars["cancel_button_id"] = $cancelButtonId;
172 11
        $view->vars["cancel_button_label"] = "Cancel";
173 11
        $view->vars["progress_bar"] = $options["progress_bar"];
174 11
        $view->vars["progress_bar_id"] = $progressBarId;
175 11
    }
176
}
177