Form   F
last analyzed

Complexity

Total Complexity 51

Size/Duplication

Total Lines 698
Duplicated Lines 1.43 %

Coupling/Cohesion

Components 8
Dependencies 8

Importance

Changes 0
Metric Value
dl 10
loc 698
rs 3.7975
c 0
b 0
f 0
wmc 51
lcom 8
cbo 8

48 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 19 1
A setResponse() 0 6 1
A getResponse() 0 4 1
A getErrors() 0 4 1
A setErrors() 0 6 1
A hasErrors() 0 4 1
A hasError() 0 4 1
A setModel() 0 6 1
A getModel() 0 4 1
A setStream() 0 6 1
A getStream() 0 4 1
A setEntry() 0 6 1
A getEntry() 0 4 1
A setContent() 0 6 1
A getContent() 0 4 1
A addAction() 0 6 1
A setActions() 0 6 1
A getActions() 0 4 1
A addButton() 0 6 1
A setButtons() 0 6 1
A getButtons() 0 4 1
A setOptions() 0 6 1
A getOptions() 0 4 1
A setOption() 0 6 1
A getOption() 0 4 1
A getSections() 0 4 1
A setSections() 0 6 1
A addSection() 0 6 1
A addField() 0 6 1
A removeField() 0 6 1
A disableField() 0 8 1
A setFields() 0 6 1
A getFields() 0 4 1
A getEnabledFields() 0 4 1
A getField() 0 4 1
A setFieldValue() 0 8 2
A addData() 0 6 1
A setData() 0 6 1
A getData() 0 4 1
A setValue() 0 4 1
A getValue() 0 4 1
A setValues() 0 6 1
A getValues() 0 4 1
A getMode() 0 4 1
A setMode() 0 6 1
A isTranslatable() 0 6 1
A resetFields() 0 9 2
A getPresenter() 10 10 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 namespace Anomaly\Streams\Platform\Ui\Form;
2
3
use Anomaly\Streams\Platform\Addon\FieldType\FieldType;
4
use Anomaly\Streams\Platform\Entry\Contract\EntryInterface;
5
use Anomaly\Streams\Platform\Entry\EntryModel;
6
use Anomaly\Streams\Platform\Model\EloquentModel;
7
use Anomaly\Streams\Platform\Stream\Contract\StreamInterface;
8
use Anomaly\Streams\Platform\Support\Collection;
9
use Anomaly\Streams\Platform\Ui\Button\ButtonCollection;
10
use Anomaly\Streams\Platform\Ui\Button\Contract\ButtonInterface;
11
use Anomaly\Streams\Platform\Ui\Form\Component\Action\ActionCollection;
12
use Anomaly\Streams\Platform\Ui\Form\Component\Action\Contract\ActionInterface;
13
use Anomaly\Streams\Platform\Ui\Form\Component\Field\FieldCollection;
14
use Anomaly\Streams\Platform\Ui\Form\Component\Section\SectionCollection;
15
use Illuminate\Support\MessageBag;
16
use Illuminate\View\View;
17
use Robbo\Presenter\PresentableInterface;
18
use Symfony\Component\HttpFoundation\Response;
19
20
/**
21
 * Class Form
22
 *
23
 * @link    http://pyrocms.com/
24
 * @author  PyroCMS, Inc. <[email protected]>
25
 * @author  Ryan Thompson <[email protected]>
26
 */
27
class Form implements PresentableInterface
28
{
29
30
    /**
31
     * The form model.
32
     *
33
     * @var null|mixed
34
     */
35
    protected $model = null;
36
37
    /**
38
     * The form stream.
39
     *
40
     * @var null|StreamInterface
41
     */
42
    protected $stream = null;
43
44
    /**
45
     * The form entry.
46
     *
47
     * @var mixed
48
     */
49
    protected $entry = null;
50
51
    /**
52
     * The form content.
53
     *
54
     * @var null|string
55
     */
56
    protected $content = null;
57
58
    /**
59
     * The form response.
60
     *
61
     * @var null|Response
62
     */
63
    protected $response = null;
64
65
    /**
66
     * The form model. This is set
67
     * to create / edit automatically.
68
     *
69
     * @var null|string
70
     */
71
    protected $mode = null;
72
73
    /**
74
     * The form data.
75
     *
76
     * @var Collection
77
     */
78
    protected $data;
79
80
    /**
81
     * The form errors.
82
     *
83
     * @var MessageBag
84
     */
85
    protected $errors;
86
87
    /**
88
     * The form values.
89
     *
90
     * @var Collection
91
     */
92
    protected $values;
93
94
    /**
95
     * The form fields.
96
     *
97
     * @var FieldCollection
98
     */
99
    protected $fields;
100
101
    /**
102
     * The form options.
103
     *
104
     * @var Collection
105
     */
106
    protected $options;
107
108
    /**
109
     * The form actions.
110
     *
111
     * @var ActionCollection
112
     */
113
    protected $actions;
114
115
    /**
116
     * The form buttons.
117
     *
118
     * @var ButtonCollection
119
     */
120
    protected $buttons;
121
122
    /**
123
     * The form sections.
124
     *
125
     * @var SectionCollection
126
     */
127
    protected $sections;
128
129
    /**
130
     * Create a new Form instance.
131
     *
132
     * @param Collection        $data
133
     * @param Collection        $values
134
     * @param Collection        $options
135
     * @param MessageBag        $errors
136
     * @param FieldCollection   $fields
137
     * @param ActionCollection  $actions
138
     * @param ButtonCollection  $buttons
139
     * @param SectionCollection $sections
140
     */
141
    public function __construct(
142
        Collection $data,
143
        Collection $values,
144
        Collection $options,
145
        MessageBag $errors,
146
        FieldCollection $fields,
147
        ActionCollection $actions,
148
        ButtonCollection $buttons,
149
        SectionCollection $sections
150
    ) {
151
        $this->data     = $data;
152
        $this->values   = $values;
153
        $this->fields   = $fields;
154
        $this->errors   = $errors;
155
        $this->actions  = $actions;
156
        $this->buttons  = $buttons;
157
        $this->options  = $options;
158
        $this->sections = $sections;
159
    }
160
161
    /**
162
     * Set the form response.
163
     *
164
     * @param  null|false|Response $response
165
     * @return $this
166
     */
167
    public function setResponse(Response $response)
168
    {
169
        $this->response = $response;
170
171
        return $this;
172
    }
173
174
    /**
175
     * Get the form response.
176
     *
177
     * @return null|Response
178
     */
179
    public function getResponse()
180
    {
181
        return $this->response;
182
    }
183
184
    /**
185
     * Get the errors.
186
     *
187
     * @return MessageBag
188
     */
189
    public function getErrors()
190
    {
191
        return $this->errors;
192
    }
193
194
    /**
195
     * Set the errors.
196
     *
197
     * @param  MessageBag $errors
198
     * @return $this
199
     */
200
    public function setErrors(MessageBag $errors)
201
    {
202
        $this->errors = $errors;
203
204
        return $this;
205
    }
206
207
    /**
208
     * Return whether the form has errors or not.
209
     *
210
     * @return bool
211
     */
212
    public function hasErrors()
213
    {
214
        return !$this->errors->isEmpty();
215
    }
216
217
    /**
218
     * Return whether a field has errors or not.
219
     *
220
     * @return bool
221
     */
222
    public function hasError($fieldName)
223
    {
224
        return $this->errors->has($fieldName);
225
    }
226
227
    /**
228
     * Set the model object.
229
     *
230
     * @param $model
231
     * @return $this
232
     */
233
    public function setModel($model)
234
    {
235
        $this->model = $model;
236
237
        return $this;
238
    }
239
240
    /**
241
     * Get the model object.
242
     *
243
     * @return null|EloquentModel|EntryModel
244
     */
245
    public function getModel()
246
    {
247
        return $this->model;
248
    }
249
250
    /**
251
     * Set the form stream.
252
     *
253
     * @param  StreamInterface $stream
254
     * @return $this
255
     */
256
    public function setStream(StreamInterface $stream)
257
    {
258
        $this->stream = $stream;
259
260
        return $this;
261
    }
262
263
    /**
264
     * Get the form stream.
265
     *
266
     * @return null|StreamInterface
267
     */
268
    public function getStream()
269
    {
270
        return $this->stream;
271
    }
272
273
    /**
274
     * Set the entry.
275
     *
276
     * @param  mixed $entry
277
     * @return $this
278
     */
279
    public function setEntry($entry)
280
    {
281
        $this->entry = $entry;
282
283
        return $this;
284
    }
285
286
    /**
287
     * Get the entry.
288
     *
289
     * @return EloquentModel|EntryInterface
290
     */
291
    public function getEntry()
292
    {
293
        return $this->entry;
294
    }
295
296
    /**
297
     * Set the form content.
298
     *
299
     * @param  string $content
300
     * @return $this
301
     */
302
    public function setContent($content)
303
    {
304
        $this->content = $content;
305
306
        return $this;
307
    }
308
309
    /**
310
     * Get the form content.
311
     *
312
     * @return null|View
313
     */
314
    public function getContent()
315
    {
316
        return $this->content;
317
    }
318
319
    /**
320
     * Add an action to the actions collection.
321
     *
322
     * @param  ActionInterface $action
323
     * @return $this
324
     */
325
    public function addAction(ActionInterface $action)
326
    {
327
        $this->actions->put($action->getSlug(), $action);
328
329
        return $this;
330
    }
331
332
    /**
333
     * Set the form actions.
334
     *
335
     * @param  ActionCollection $actions
336
     * @return $this
337
     */
338
    public function setActions(ActionCollection $actions)
339
    {
340
        $this->actions = $actions;
341
342
        return $this;
343
    }
344
345
    /**
346
     * Get the form actions.
347
     *
348
     * @return ActionCollection
349
     */
350
    public function getActions()
351
    {
352
        return $this->actions;
353
    }
354
355
    /**
356
     * Add a button to the buttons collection.
357
     *
358
     * @param  ButtonInterface $button
359
     * @return $this
360
     */
361
    public function addButton(ButtonInterface $button)
362
    {
363
        $this->buttons->push($button);
364
365
        return $this;
366
    }
367
368
    /**
369
     * Set the form buttons.
370
     *
371
     * @param  ButtonCollection $buttons
372
     * @return $this
373
     */
374
    public function setButtons(ButtonCollection $buttons)
375
    {
376
        $this->buttons = $buttons;
377
378
        return $this;
379
    }
380
381
    /**
382
     * Get the form buttons.
383
     *
384
     * @return ButtonCollection
385
     */
386
    public function getButtons()
387
    {
388
        return $this->buttons;
389
    }
390
391
    /**
392
     * Set the options.
393
     *
394
     * @param  Collection $options
395
     * @return $this
396
     */
397
    public function setOptions(Collection $options)
398
    {
399
        $this->options = $options;
400
401
        return $this;
402
    }
403
404
    /**
405
     * Get the options.
406
     *
407
     * @return Collection
408
     */
409
    public function getOptions()
410
    {
411
        return $this->options;
412
    }
413
414
    /**
415
     * Set an option.
416
     *
417
     * @param $key
418
     * @param $value
419
     * @return $this
420
     */
421
    public function setOption($key, $value)
422
    {
423
        $this->options->put($key, $value);
424
425
        return $this;
426
    }
427
428
    /**
429
     * Get an option value.
430
     *
431
     * @param        $key
432
     * @param  null  $default
433
     * @return mixed
434
     */
435
    public function getOption($key, $default = null)
436
    {
437
        return $this->options->get($key, $default);
438
    }
439
440
    /**
441
     * Get the sections.
442
     *
443
     * @return SectionCollection
444
     */
445
    public function getSections()
446
    {
447
        return $this->sections;
448
    }
449
450
    /**
451
     * Set the sections.
452
     *
453
     * @param  SectionCollection $sections
454
     * @return $this
455
     */
456
    public function setSections(SectionCollection $sections)
457
    {
458
        $this->sections = $sections;
459
460
        return $this;
461
    }
462
463
    /**
464
     * Add a section.
465
     *
466
     * @param $slug
467
     * @param $section
468
     * @return $this
469
     */
470
    public function addSection($slug, $section)
471
    {
472
        $this->sections->put($slug, $section);
473
474
        return $this;
475
    }
476
477
    /**
478
     * Add a field to the collection of fields.
479
     *
480
     * @param  FieldType $field
481
     * @return $this
482
     */
483
    public function addField(FieldType $field)
484
    {
485
        $this->fields->push($field);
486
487
        return $this;
488
    }
489
490
    /**
491
     * Remove a field.
492
     *
493
     * @param $field
494
     * @return $this
495
     */
496
    public function removeField($field)
497
    {
498
        $this->fields->forget($field);
499
500
        return $this;
501
    }
502
503
    /**
504
     * Disable a field.
505
     *
506
     * @param $field
507
     * @return $this
508
     */
509
    public function disableField($field)
510
    {
511
        $field = $this->getField($field);
512
513
        $field->setDisabled(true);
514
515
        return $this;
516
    }
517
518
    /**
519
     * Set the form views.
520
     *
521
     * @param  Collection $fields
522
     * @return $this
523
     */
524
    public function setFields(Collection $fields)
525
    {
526
        $this->fields = $fields;
0 ignored issues
show
Documentation Bug introduced by
$fields is of type object<Anomaly\Streams\P...orm\Support\Collection>, but the property $fields was declared to be of type object<Anomaly\Streams\P...\Field\FieldCollection>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
527
528
        return $this;
529
    }
530
531
    /**
532
     * Get the form fields.
533
     *
534
     * @return FieldCollection
535
     */
536
    public function getFields()
537
    {
538
        return $this->fields;
539
    }
540
541
    /**
542
     * Get the enabled fields.
543
     *
544
     * @return FieldCollection
545
     */
546
    public function getEnabledFields()
547
    {
548
        return $this->fields->enabled();
549
    }
550
551
    /**
552
     * Get a form field.
553
     *
554
     * @param $field
555
     * @return FieldType|mixed
556
     */
557
    public function getField($field)
558
    {
559
        return $this->fields->get($field);
560
    }
561
562
    /**
563
     * Set a field value.
564
     *
565
     * @param $field
566
     * @param $value
567
     * @return $this
568
     */
569
    public function setFieldValue($field, $value)
570
    {
571
        if ($field = $this->getField($field)) {
572
            $field->setValue($value);
573
        }
574
575
        return $this;
576
    }
577
578
    /**
579
     * Add data to the view data collection.
580
     *
581
     * @param $key
582
     * @param $value
583
     * @return $this
584
     */
585
    public function addData($key, $value)
586
    {
587
        $this->data->put($key, $value);
588
589
        return $this;
590
    }
591
592
    /**
593
     * Set the form data.
594
     *
595
     * @param  Collection $data
596
     * @return $this
597
     */
598
    public function setData(Collection $data)
599
    {
600
        $this->data = $data;
601
602
        return $this;
603
    }
604
605
    /**
606
     * Get the form data.
607
     *
608
     * @return Collection
609
     */
610
    public function getData()
611
    {
612
        return $this->data;
613
    }
614
615
    /**
616
     * Set a value on the value collection.
617
     *
618
     * @param $key
619
     * @param $value
620
     */
621
    public function setValue($key, $value)
622
    {
623
        $this->values->put($key, $value);
624
    }
625
626
    /**
627
     * Get a value from the value collection.
628
     *
629
     * @param        $key
630
     * @param  null  $default
631
     * @return mixed
632
     */
633
    public function getValue($key, $default = null)
634
    {
635
        return $this->values->get($key, $default);
636
    }
637
638
    /**
639
     * Set the form values.
640
     *
641
     * @param  Collection $values
642
     * @return $this
643
     */
644
    public function setValues(Collection $values)
645
    {
646
        $this->values = $values;
647
648
        return $this;
649
    }
650
651
    /**
652
     * Get the form values.
653
     *
654
     * @return Collection
655
     */
656
    public function getValues()
657
    {
658
        return $this->values;
659
    }
660
661
    /**
662
     * Get the mode.
663
     *
664
     * @return null|string
665
     */
666
    public function getMode()
667
    {
668
        return $this->mode;
669
    }
670
671
    /**
672
     * Set the mode.
673
     *
674
     * @param $mode
675
     * @return $this
676
     */
677
    public function setMode($mode)
678
    {
679
        $this->mode = $mode;
680
681
        return $this;
682
    }
683
684
    /**
685
     * Return whether the form is translatable or not.
686
     *
687
     * @return bool
688
     */
689
    public function isTranslatable()
690
    {
691
        $fields = $this->fields->translatable();
692
693
        return (!$fields->isEmpty());
694
    }
695
696
    /**
697
     * Reset field values.
698
     */
699
    public function resetFields()
700
    {
701
        /* @var FieldType $field */
702
        foreach ($this->getFields() as $field) {
703
            $field->setValue(null);
704
        }
705
706
        return $this;
707
    }
708
709
    /**
710
     * Return a created presenter.
711
     *
712
     * @return FormPresenter
713
     */
714 View Code Duplication
    public function getPresenter()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
715
    {
716
        $presenter = get_class($this) . 'Presenter';
717
718
        if (class_exists($presenter)) {
719
            return app()->make($presenter, ['object' => $this]);
720
        }
721
722
        return app()->make(FormPresenter::class, ['object' => $this]);
723
    }
724
}
725