DiffElementBuilder::build()   C
last analyzed

Complexity

Conditions 11
Paths 10

Size

Total Lines 56
Code Lines 45

Duplication

Lines 24
Ratio 42.86 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 24
loc 56
rs 6.5481
cc 11
eloc 45
nc 10
nop 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * @link    https://github.com/nnx-framework/form-comparator
4
 * @author  Malofeykin Andrey  <[email protected]>
5
 */
6
namespace Nnx\FormComparator\Comparator;
7
use Nnx\FormComparator\Comparator\Diff\AbstractCollectionElement;
8
use Webmozart\Assert\Assert;
9
use Zend\Form\Element\Collection;
10
use Zend\Form\ElementInterface;
11
use Zend\Form\FormInterface;
12
13
/**
14
 * Class DiffElementBuilder
15
 *
16
 * @package Nnx\FormComparator\Comparator
17
 */
18
class DiffElementBuilder
19
{
20
    /**
21
     * Элемент был создан
22
     *
23
     * @var string
24
     */
25
    const INSERT_ELEMENT_MODE = 'insertElement';
26
27
    /**
28
     * Элемент был удален
29
     *
30
     * @var string
31
     */
32
    const DELETE_ELEMENT_MODE = 'deleteElement';
33
34
    /**
35
     * Элемент был изменен
36
     *
37
     * @var string
38
     */
39
    const UPDATE_ELEMENT_MODE = 'updateElement';
40
41
    /**
42
     * Элемент был создан
43
     *
44
     * @var string
45
     */
46
    const INSERT_COLLECTION_MODE = 'insertCollection';
47
48
    /**
49
     * Элемент был удален
50
     *
51
     * @var string
52
     */
53
    const DELETE_COLLECTION_MODE = 'deleteCollection';
54
55
    /**
56
     * Элемент был изменен
57
     *
58
     * @var string
59
     */
60
    const UPDATE_COLLECTION_MODE = 'updateCollection';
61
62
    /**
63
     * Определяет какой объект создавать
64
     *
65
     * @var string
66
     */
67
    private $mode;
68
69
    /**
70
     * Путь до элемента
71
     *
72
     * @var string
73
     */
74
    private $pathToElement;
75
76
    /**
77
     * Заголовок элемента который сравнивают
78
     *
79
     * @var string
80
     */
81
    private $sourceLabel;
82
83
    /**
84
     * Значение элемента который сравнивают
85
     *
86
     * @var mixed
87
     */
88
    private $sourceValue;
89
90
    /**
91
     * Значение элемента с которым сравнивают
92
     *
93
     * @var mixed
94
     */
95
    private $targetValue;
96
97
    /**
98
     * Форма которую сравнивают
99
     *
100
     * @var FormInterface
101
     */
102
    private $sourceForm;
103
104
    /**
105
     * Форма с которой сравнивают
106
     *
107
     * @var FormInterface
108
     */
109
    private $targetForm;
110
111
    /**
112
     * Элемент который сравнивают
113
     *
114
     * @var ElementInterface
115
     */
116
    private $sourceElement;
117
118
    /**
119
     * Элемент с которым сравнивают
120
     *
121
     * @var ElementInterface
122
     */
123
    private $targetElement;
124
125
    /**
126
     * @var AbstractCollectionElement[]
127
     */
128
    private $collectionElementsDiff;
129
130
    /**
131
     * Сервис для создания коллекции объектов описывающих разницу между коллекциями
132
     *
133
     * @var CollectionDiffService
134
     */
135
    private $collectionDiffService;
136
137
    /**
138
     * Допустимые режимы
139
     *
140
     * @var array
141
     */
142
    private $accessMode = [
143
        self::DELETE_ELEMENT_MODE => self::DELETE_ELEMENT_MODE,
144
        self::UPDATE_ELEMENT_MODE => self::UPDATE_ELEMENT_MODE,
145
        self::INSERT_ELEMENT_MODE => self::INSERT_ELEMENT_MODE,
146
        self::INSERT_COLLECTION_MODE => self::INSERT_COLLECTION_MODE,
147
        self::UPDATE_COLLECTION_MODE => self::UPDATE_COLLECTION_MODE,
148
        self::DELETE_COLLECTION_MODE => self::DELETE_COLLECTION_MODE,
149
    ];
150
151
    /**
152
     * DiffBuilder constructor.
153
     *
154
     * @param string $mode
155
     */
156
    public function __construct($mode)
157
    {
158
        Assert::keyExists($this->accessMode, $mode);
159
        $this->mode = $mode;
160
    }
161
162
    /**
163
     * Элемент который сравнивают
164
     *
165
     * @return ElementInterface
166
     */
167
    public function getSourceElement()
168
    {
169
        Assert::isInstanceOf($this->sourceElement, ElementInterface::class);
170
        return $this->sourceElement;
171
    }
172
173
    /**
174
     * Элемент с которым сравнивают
175
     *
176
     * @return ElementInterface
177
     */
178
    public function getTargetElement()
179
    {
180
        Assert::isInstanceOf($this->targetElement, ElementInterface::class);
181
        return $this->targetElement;
182
    }
183
184
    /**
185
     *  Устанавливает элемент который сравнивают
186
     *
187
     * @param ElementInterface $sourceElement
188
     *
189
     * @return $this
190
     */
191
    public function setSourceElement(ElementInterface $sourceElement)
192
    {
193
        $this->sourceElement = $sourceElement;
194
195
        return $this;
196
    }
197
198
    /**
199
     * Возвращает элемент который сравнивают
200
     *
201
     * @param ElementInterface $targetElement
202
     *
203
     * @return $this
204
     */
205
    public function setTargetElement(ElementInterface $targetElement)
206
    {
207
        $this->targetElement = $targetElement;
208
209
        return $this;
210
    }
211
212
    /**
213
     * Возвращает форму которую сравнивают
214
     *
215
     * @return FormInterface
216
     */
217
    public function getSourceForm()
218
    {
219
        Assert::isInstanceOf($this->targetForm, FormInterface::class);
220
        return $this->sourceForm;
221
    }
222
223
    /**
224
     * Возвращает форму с которой сравнивают
225
     *
226
     * @return FormInterface
227
     */
228
    public function getTargetForm()
229
    {
230
        Assert::isInstanceOf($this->targetForm, FormInterface::class);
231
        return $this->targetForm;
232
    }
233
234
    /**
235
     * Устанавливает форма которую сравнивают
236
     *
237
     * @param FormInterface $sourceForm
238
     *
239
     * @return $this
240
     */
241
    public function setSourceForm(FormInterface $sourceForm)
242
    {
243
        $this->sourceForm = $sourceForm;
244
245
        return $this;
246
    }
247
248
    /**
249
     * Устанавливает форму с которой сравнивают
250
     *
251
     * @param FormInterface $targetForm
252
     *
253
     * @return $this
254
     */
255
    public function setTargetForm(FormInterface $targetForm)
256
    {
257
        $this->targetForm = $targetForm;
258
259
        return $this;
260
    }
261
262
263
264
    /**
265
     * Путь до элемента
266
     *
267
     * @return string
268
     */
269
    public function getPathToElement()
270
    {
271
        Assert::string($this->pathToElement);
272
        Assert::notEmpty($this->pathToElement);
273
        return $this->pathToElement;
274
    }
275
276
    /**
277
     * Устанавливает путь до элемента
278
     *
279
     * @param string $pathToElement
280
     *
281
     * @return $this
282
     */
283
    public function setPathToElement($pathToElement)
284
    {
285
        $this->pathToElement = $pathToElement;
286
287
        return $this;
288
    }
289
290
    /**
291
     * Заголовок элемента который сравнивают
292
     *
293
     * @return string
294
     */
295
    public function getSourceLabel()
296
    {
297
        return $this->sourceLabel;
298
    }
299
300
    /**
301
     * Устанавливают заголовок элемента который сравнивают
302
     *
303
     * @param string $sourceLabel
304
     *
305
     * @return $this
306
     */
307
    public function setSourceLabel($sourceLabel)
308
    {
309
        $this->sourceLabel = $sourceLabel;
310
311
        return $this;
312
    }
313
314
    /**
315
     * Значение элемента который сравнивают
316
     *
317
     * @return mixed
318
     */
319
    public function getSourceValue()
320
    {
321
        return $this->sourceValue;
322
    }
323
324
    /**
325
     * Устанавливает значение элемента который сравнивают
326
     *
327
     * @param mixed $sourceValue
328
     *
329
     * @return $this
330
     */
331
    public function setSourceValue($sourceValue)
332
    {
333
        $this->sourceValue = $sourceValue;
334
335
        return $this;
336
    }
337
338
    /**
339
     * Возвращают значение элемента с которым сравнивают
340
     *
341
     * @return mixed
342
     */
343
    public function getTargetValue()
344
    {
345
        return $this->targetValue;
346
    }
347
348
    /**
349
     * Устанавливают значение элемента с которым сравнивают
350
     *
351
     * @param mixed $targetValue
352
     *
353
     * @return $this
354
     */
355
    public function setTargetValue($targetValue)
356
    {
357
        $this->targetValue = $targetValue;
358
359
        return $this;
360
    }
361
362
    /**
363
     * Создает объект описывающий различие между двумя элементами формы
364
     *
365
     * @return AbstractDiff
366
     * @throws \Nnx\FormComparator\Comparator\CollectionDiffService\Exception\RuntimeException
367
     * @throws \Nnx\FormComparator\Comparator\Exception\DomainException
368
     */
369
    public function build()
370
    {
371
        switch ($this->mode) {
372
            case self::DELETE_ELEMENT_MODE:
373
                $diff = new Diff\DeleteElement($this);
374
                break;
375
            case self::INSERT_ELEMENT_MODE:
376
                $diff = new Diff\InsertElement($this);
377
                break;
378
            case self::UPDATE_ELEMENT_MODE:
379
                $diff = new Diff\UpdateElement($this);
380
                break;
381
            case self::UPDATE_COLLECTION_MODE:
382
                $sourceCollection = $this->getSourceElement();
383
                $targetCollection = $this->getTargetElement();
384
                $prefixPath = $this->getPathToElement();
385
                if ($sourceCollection instanceof Collection && $targetCollection instanceof Collection) {
386
                    $this->collectionElementsDiff = $this->getCollectionDiffService()
387
                        ->buildDiffUpdatedCollection($sourceCollection, $targetCollection, $prefixPath);
388
                } else {
389
                    throw new Exception\DomainException('Invalid collections');
390
                }
391
392
                $diff = new Diff\UpdateCollection($this);
393
                break;
394 View Code Duplication
            case self::INSERT_COLLECTION_MODE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
395
                $sourceCollection = $this->getSourceElement();
396
                $prefixPath = $this->getPathToElement();
397
                if ($sourceCollection instanceof Collection) {
398
                    $this->collectionElementsDiff = $this->getCollectionDiffService()
399
                        ->buildDiffInsertedCollection($sourceCollection, $prefixPath);
400
                } else {
401
                    throw new Exception\DomainException('Invalid collections');
402
                }
403
404
                $diff = new Diff\InsertCollection($this);
405
                break;
406 View Code Duplication
            case self::DELETE_COLLECTION_MODE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
407
                $sourceCollection = $this->getSourceElement();
408
                $prefixPath = $this->getPathToElement();
409
                if ($sourceCollection instanceof Collection) {
410
                    $this->collectionElementsDiff = $this->getCollectionDiffService()
411
                        ->buildDiffDeletedCollection($sourceCollection, $prefixPath);
412
                } else {
413
                    throw new Exception\DomainException('Invalid collections');
414
                }
415
416
                $diff = new Diff\DeleteCollection($this);
417
                break;
418
            default:
419
                throw new Exception\DomainException(sprintf('Unknown mode %s', $this->mode));
420
421
        }
422
423
        return $diff;
424
    }
425
426
    /**
427
     * Возвращает объекты описывающие разницу между двумя коллекциями
428
     *
429
     * @return Diff\AbstractCollectionElement[]
430
     */
431
    public function getCollectionElementsDiff()
432
    {
433
        Assert::isArray($this->collectionElementsDiff);
434
        return $this->collectionElementsDiff;
435
    }
436
    
437
    /**
438
     * Определяет какой объект создавать
439
     *
440
     * @return string
441
     */
442
    public function getMode()
443
    {
444
        return $this->mode;
445
    }
446
447
    /**
448
     * Сервис для создания коллекции объектов описывающих разницу между коллекциями
449
     *
450
     * @return CollectionDiffService
451
     */
452
    protected function getCollectionDiffService()
453
    {
454
        if (null === $this->collectionDiffService) {
455
            $this->collectionDiffService = new CollectionDiffService();
456
        }
457
        return $this->collectionDiffService;
458
    }
459
}
460