Form   C
last analyzed

Complexity

Total Complexity 56

Size/Duplication

Total Lines 366
Duplicated Lines 0 %

Test Coverage

Coverage 55.2%

Importance

Changes 0
Metric Value
wmc 56
eloc 116
dl 0
loc 366
ccs 69
cts 125
cp 0.552
rs 5.5199
c 0
b 0
f 0

23 Methods

Rating   Name   Duplication   Size   Complexity  
A setIsDescriptionsEnabled() 0 4 1
A setDescription() 0 5 1
A isValid() 0 17 3
A getFormName() 0 7 2
A setIsDisableElementsCapable() 0 5 1
A add() 0 7 2
A setParam() 0 16 2
A prepare() 0 10 2
A getParent() 0 3 1
A setValidate() 0 3 1
A isDisableElementsCapable() 0 5 2
A setOptions() 0 14 5
A hasParent() 0 3 1
A isDescriptionsEnabled() 0 3 1
A getHydrator() 0 8 2
A setParams() 0 6 2
C disableElements() 0 34 12
A isDisableCapable() 0 5 2
A addClass() 0 14 4
A setParent() 0 4 1
A setIsDisableCapable() 0 5 1
A attachInputFilterDefaults() 0 15 6
A addHydratorStrategies() 0 2 1

How to fix   Complexity   

Complex Class

Complex classes like Form often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Form, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * YAWIK
4
 *
5
 * @filesource
6
 * @copyright (c) 2013 - 2016 Cross Solution (http://cross-solution.de)
7
 * @license   MIT
8
 */
9
10
namespace Core\Form;
11
12
use Core\Form\Hydrator\HydratorStrategyProviderInterface;
13
use Laminas\Form\Form as LaminasForm;
14
use Laminas\Form\FieldsetInterface;
15
use Core\Entity\Hydrator\EntityHydrator;
16
use Laminas\Hydrator\HydratorInterface;
17
use Laminas\Hydrator\StrategyEnabledInterface;
0 ignored issues
show
Bug introduced by
The type Laminas\Hydrator\StrategyEnabledInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
use Laminas\InputFilter\InputFilterInterface;
19
use Laminas\EventManager\EventManagerAwareTrait;
20
21
/**
22
 * Core form.
23
 *
24
 * @author Mathias Gelhausen <[email protected]>
25
 */
26
class Form extends LaminasForm implements
27
    DescriptionAwareFormInterface,
28
                                       DisableElementsCapableInterface,
29
                                       FormParentInterface
30
{
31
    use EventManagerAwareTrait, HydratorStrategyAwareTrait;
0 ignored issues
show
Bug introduced by
The trait Laminas\EventManager\EventManagerAwareTrait requires the property $eventIdentifier which is not provided by Core\Form\Form.
Loading history...
32
    
33
    const EVENT_IS_VALID = 'validate';
34
    const EVENT_PREPARE = 'prepare';
35
    
36
    /**
37
     * Form parameters.
38
     * An array of key  => value pairs which are rendered as hidden fields.
39
     *
40
     * @var array
41
     */
42
    protected $params;
43
44
    /**
45
     * @var LaminasForm
46
     */
47
    protected $parent;
48
49
    /**
50
     * Flag, if descriptions handling is enabled or not.
51
     *
52
     * @var bool
53
     */
54
    protected $isDescriptionsEnabled = false;
55
56
    /**
57
     * @param array|\Traversable|\Laminas\Form\ElementInterface $elementOrFieldset
58
     * @param array                                          $flags
59
     *
60
     * @return $this
61
     */
62 24
    public function add($elementOrFieldset, array $flags = array())
63
    {
64 24
        parent::add($elementOrFieldset, $flags);
65 24
        if ($elementOrFieldset instanceof FormParentInterface) {
66
            $elementOrFieldset->setParent($this);
67
        }
68 24
        return $this;
69
    }
70
71
    /**
72
     * @param bool $flag
73
     *
74
     * @return $this
75
     */
76 3
    public function setIsDescriptionsEnabled($flag)
77
    {
78 3
        $this->isDescriptionsEnabled = (bool) $flag;
79 3
        return $this;
80
    }
81
82
    /**
83
     * @return bool
84
     */
85 5
    public function isDescriptionsEnabled()
86
    {
87 5
        return $this->isDescriptionsEnabled;
88
    }
89
90
    /**
91
     * @param string $description
92
     *
93
     * @return $this
94
     */
95 3
    public function setDescription($description, $params = null)
96
    {
97 3
        $this->options['description'] = $description;
98 3
        $this->options['description_params'] = $params;
99 3
        return $this;
100
    }
101
102
    /**
103
     * @param bool $flag
104
     *
105
     * @return $this
106
     */
107 1
    public function setIsDisableCapable($flag)
108
    {
109 1
        $this->options['is_disable_capable'] = $flag;
110
111 1
        return $this;
112
    }
113
114
    /**
115
     * @return bool
116
     */
117 1
    public function isDisableCapable()
118
    {
119 1
        return isset($this->options['is_disable_capable'])
120 1
               ? $this->options['is_disable_capable']
121 1
               : true;
122
    }
123
124
    /**
125
     * @param bool $flag
126
     *
127
     * @return $this
128
     */
129 1
    public function setIsDisableElementsCapable($flag)
130
    {
131 1
        $this->options['is_disable_elements_capable'] = $flag;
132
133 1
        return $this;
134
    }
135
136
    /**
137
     * @return bool
138
     */
139 1
    public function isDisableElementsCapable()
140
    {
141 1
        return isset($this->options['is_disable_elements_capable'])
142 1
               ? $this->options['is_disable_elements_capable']
143 1
               : true;
144
    }
145
146
    /**
147
     * @param array $map
148
     *
149
     * @return $this
150
     */
151
    public function disableElements(array $map)
152
    {
153
        if (!$this->isDisableElementsCapable()) {
154
            return $this;
155
        }
156
157
        foreach ($map as $key => $name) {
158
            if (is_numeric($key)) {
159
                $key = $name;
160
                $name = null;
161
            }
162
163
            if (!$this->has($key)) {
164
                continue;
165
            }
166
167
            $element = $this->get($key);
168
169
            if (null === $name) {
170
                if (($element instanceof DisableCapableInterface && $element->isDisableCapable())
171
                    || false !== $element->getOption('is_disable_capable')) {
172
                    $this->remove($element);
0 ignored issues
show
Bug introduced by
$element of type Laminas\Form\ElementInte...\Form\FieldsetInterface is incompatible with the type string expected by parameter $elementOrFieldset of Laminas\Form\Fieldset::remove(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

172
                    $this->remove(/** @scrutinizer ignore-type */ $element);
Loading history...
173
                }
174
                continue;
175
            }
176
177
            if ($element instanceof FieldsetInterface
178
                && $element instanceof DisableElementsCapableInterface
179
                && $element->isDisableElementsCapable()
180
            ) {
181
                $element->disableElements($name);
182
            }
183
        }
184
        return $this;
185
    }
186
187
188
189
190
    /**
191
     * @return \Laminas\Hydrator\HydratorInterface
192
     */
193 4
    public function getHydrator()
194
    {
195 4
        if (!$this->hydrator) {
196 3
            $hydrator = new EntityHydrator();
197 3
            $this->addHydratorStrategies($hydrator);
198 3
            $this->setHydrator($hydrator);
199
        }
200 4
        return $this->hydrator;
201
    }
202
203
    /**
204
     * @param array|\Traversable $options
205
     *
206
     * @return $this
207
     */
208 2
    public function setOptions($options)
209
    {
210 2
        $desc = isset($this->options['description']) ? $this->options['description'] : null;
211
212 2
        parent::setOptions($options);
213
214 2
        if (isset($options['enable_descriptions'])) {
215 1
            $this->setIsDescriptionsEnabled($options['enable_descriptions']);
216
        }
217
218 2
        if (!isset($options['description']) && null !== $desc) {
219
            $this->options['description'] = $desc;
220
        }
221 2
        return $this;
222
    }
223
224
    /**
225
     * Sets many form parameters at once.
226
     *
227
     * @param array $params
228
     *
229
     * @return self
230
     */
231 1
    public function setParams(array $params)
232
    {
233 1
        foreach ($params as $key => $value) {
234
            $this->setParam($key, $value);
235
        }
236 1
        return $this;
237
    }
238
239
    /**
240
     * Sets a form parameter.
241
     *
242
     * @param string $key
243
     * @param string $value
244
     *
245
     * @return self
246
     */
247
    public function setParam($key, $value)
248
    {
249
        if ($this->has($key)) {
250
            $this->get($key)->setValue($value);
251
        } else {
252
            $this->add(
253
                [
254
                    'type'       => 'hidden',
255
                    'name'       => $key,
256
                    'attributes' => [
257
                        'value' => $value
258
                    ]
259
                ]
260
            );
261
        }
262
        return $this;
263
    }
264
265
    /**
266
     * Adds hydrator strategies to the default hydrator upon instanciation.
267
     *
268
     * @param \Laminas\Hydrator\HydratorInterface $hydrator
269
     */
270
    protected function addHydratorStrategies($hydrator)
0 ignored issues
show
Unused Code introduced by
The parameter $hydrator is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

270
    protected function addHydratorStrategies(/** @scrutinizer ignore-unused */ $hydrator)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
271
    {
272
    }
273
274
    /**
275
     * @param $spec
276
     *
277
     * @return $this
278
     */
279 2
    public function addClass($spec)
280
    {
281 2
        $class = array();
282 2
        if ($this->hasAttribute('class')) {
283 1
            $class = $this->getAttribute('class');
284
        }
285 2
        if (!is_array($class)) {
286 1
            $class = explode(' ', $class);
0 ignored issues
show
Bug introduced by
It seems like $class can also be of type null; however, parameter $string of explode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

286
            $class = explode(' ', /** @scrutinizer ignore-type */ $class);
Loading history...
287
        }
288 2
        if (!in_array($spec, $class)) {
289 2
            $class[] = $spec;
290
        }
291 2
        $this->setAttribute('class', implode(' ', $class));
292 2
        return $this;
293
    }
294
295
    /**
296
     * @return Form
297
     */
298
    public function setValidate()
299
    {
300
        return $this->addClass('validate');
301
    }
302
303
    /**
304
     * {@inheritDoc}
305
     * Rebinds the bound object or sets data to the filtered values.
306
     */
307
    public function isValid()
308
    {
309
        $isValid = parent::isValid();
310
        if ($isValid) {
311
            if (is_object($this->object)) {
312
                $this->bind($this->object);
313
            } else {
314
                $filter = $this->getInputFilter();
315
                $this->setData($filter->getValues());
316
            }
317
        }
318
        
319
        $this->getEventManager()->trigger(static::EVENT_IS_VALID, $this, [
320
            'isValid' => $isValid
321
        ]);
322
        
323
        return $isValid;
324
    }
325
326
    public function getFormName()
327
    {
328
        $name = $this->getBaseFieldset()->getAttribute('name');
329
        if (empty($name)) {
330
            throw new \RuntimeException('missing name for form');
331
        }
332
        return $name;
333
    }
334
335 1
    public function setParent($parent)
336
    {
337 1
        $this->parent = $parent;
338 1
        return $this;
339
    }
340
341
    public function getParent()
342
    {
343
        return $this->parent;
344
    }
345
346
347
    public function hasParent()
348
    {
349
        return isset($this->parent);
350
    }
351
352
    /**
353
     * reassurance, that no required inputFilter is set on a non-existing field, this mistake is otherwise hard to detect
354
     * there is still a lot to do on this issue
355
     * @param InputFilterInterface $inputFilter
356
     * @param FieldsetInterface $fieldset
357
     * @throws \RuntimeException
358
     */
359 4
    public function attachInputFilterDefaults(InputFilterInterface $inputFilter, FieldsetInterface $fieldset)
360
    {
361 4
        parent::attachInputFilterDefaults($inputFilter, $fieldset);
362
        /* @var $inputFilter \Laminas\InputFilter\InputFilter */
363 4
        foreach ($inputFilter->getInputs() as $name => $input) {
364 4
            if (!$input instanceof InputFilterInterface) {
365
                /* @var $input \Laminas\InputFilter\Input */
366 4
                $required = $input->isRequired();
367 4
                $inputExists = $fieldset->has($name);
368 4
                if (!$inputExists && $required) {
369
                    $fieldsetName = '';
370
                    if ($fieldset->hasAttribute('name')) {
371
                        $fieldsetName = 'in Fieldset "' . $fieldset->getAttribute('name') . '" ';
372
                    }
373
                    throw new \RuntimeException('input for "' . $name . '" ' . $fieldsetName . 'is required but a input-field with this name is not defined');
374
                }
375
            }
376
        }
377
    }
378
379
    /**
380
     * @see \Laminas\Form\Form::prepare()
381
     */
382 4
    public function prepare()
383
    {
384 4
        if ($this->isPrepared) {
385 1
            return $this;
386
        }
387
        
388 4
        parent::prepare();
389 4
        $this->getEventManager()->trigger(static::EVENT_PREPARE, $this);
390
        
391 4
        return $this;
392
    }
393
}
394