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
|
|
|
|
8
|
|
|
use Webmozart\Assert\Assert; |
9
|
|
|
use Zend\Form\Element\Collection; |
10
|
|
|
use Zend\Form\ElementInterface; |
11
|
|
|
use Zend\Form\FieldsetInterface; |
12
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* Class DiffContext |
15
|
|
|
* |
16
|
|
|
* @package Nnx\FormComparator\Comparator |
17
|
|
|
*/ |
18
|
|
|
class DiffContext |
19
|
|
|
{ |
20
|
|
|
/** |
21
|
|
|
* Элемент который сравнивают |
22
|
|
|
* |
23
|
|
|
* @var ElementInterface |
24
|
|
|
*/ |
25
|
|
|
private $source; |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* Элемент с которым сравнивают |
29
|
|
|
* |
30
|
|
|
* @var ElementInterface |
31
|
|
|
*/ |
32
|
|
|
private $target; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* @var AbstractDiff[] |
36
|
|
|
*/ |
37
|
|
|
private $diff = []; |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* Определяет путь до элементов которые в данный момент сравниваются |
41
|
|
|
* |
42
|
|
|
* @var string |
43
|
|
|
*/ |
44
|
|
|
private $prefixPath; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* FormDiffBuilderContext constructor. |
48
|
|
|
* |
49
|
|
|
* @param ElementInterface $source |
50
|
|
|
* @param ElementInterface $target |
51
|
|
|
* |
52
|
|
|
* @throws \Nnx\FormComparator\Comparator\Exception\IncorrectElementTypeException |
53
|
|
|
*/ |
54
|
|
|
public function __construct(ElementInterface $source, ElementInterface $target) |
55
|
|
|
{ |
56
|
|
|
$this->setComparableElements($source, $target); |
57
|
|
|
|
58
|
|
|
$this->prefixPath = $source->getName(); |
59
|
|
|
|
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* Определяет путь до элементов которые в данный момент сравниваются |
64
|
|
|
* |
65
|
|
|
* @param string $prefixPath |
66
|
|
|
* |
67
|
|
|
* @return $this |
68
|
|
|
*/ |
69
|
|
|
public function setPrefixPath($prefixPath) |
70
|
|
|
{ |
71
|
|
|
$this->prefixPath = $prefixPath; |
72
|
|
|
|
73
|
|
|
return $this; |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Устанавливает сравниваемые элементы |
79
|
|
|
* |
80
|
|
|
* @param ElementInterface $source |
81
|
|
|
* @param ElementInterface $target |
82
|
|
|
* |
83
|
|
|
* |
84
|
|
|
* @return $this |
85
|
|
|
* @throws \Nnx\FormComparator\Comparator\Exception\IncorrectElementTypeException |
86
|
|
|
*/ |
87
|
|
|
public function setComparableElements(ElementInterface $source = null, ElementInterface $target = null) |
88
|
|
|
{ |
89
|
|
|
$this->source = $source; |
90
|
|
|
$this->target = $target; |
91
|
|
|
|
92
|
|
|
if (null !== $source && null !== $target) { |
93
|
|
|
$sourceName = $this->source->getName(); |
94
|
|
|
$targetName = $this->target->getName(); |
95
|
|
|
|
96
|
|
|
Assert::eq($sourceName, $targetName); |
97
|
|
|
|
98
|
|
|
$this->validateElementType($source, $target); |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
return $this; |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
|
105
|
|
|
/** |
106
|
|
|
* Проверка того что элементы совпадают по типам. |
107
|
|
|
* |
108
|
|
|
* Т.е. если сравниваемый элемент является коллекцией, то и элемент с которым сравнивают должен быть коллекцией. |
109
|
|
|
* Если сравниваемый элемент является Fieldset'ом, то и элемент с которым сравнивают должен быть Fieldset'ом |
110
|
|
|
* |
111
|
|
|
* @param ElementInterface $sourceElement |
112
|
|
|
* @param ElementInterface $targetElement |
113
|
|
|
* |
114
|
|
|
* @throws \Nnx\FormComparator\Comparator\Exception\IncorrectElementTypeException |
115
|
|
|
*/ |
116
|
|
View Code Duplication |
protected function validateElementType(ElementInterface $sourceElement, ElementInterface $targetElement) |
|
|
|
|
117
|
|
|
{ |
118
|
|
|
$baseType = ElementInterface::class; |
119
|
|
|
if ($sourceElement instanceof Collection) { |
120
|
|
|
$baseType = Collection::class; |
121
|
|
|
} elseif ($sourceElement instanceof FieldsetInterface) { |
122
|
|
|
$baseType = FieldsetInterface::class; |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
if (!$targetElement instanceof $baseType) { |
126
|
|
|
$targetElementName = $targetElement->getName(); |
127
|
|
|
$targetElementClass = get_class($targetElement); |
128
|
|
|
$errMsg = sprintf( |
129
|
|
|
'Element %s not implement %s', |
130
|
|
|
is_string($targetElementName) ? sprintf('%s(%s)', $targetElementName, $targetElementClass) : $targetElementClass, |
131
|
|
|
$baseType |
132
|
|
|
); |
133
|
|
|
throw new Exception\IncorrectElementTypeException($errMsg); |
134
|
|
|
} |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
/** |
138
|
|
|
* Элемент который сравнивают |
139
|
|
|
* |
140
|
|
|
* @return ElementInterface |
141
|
|
|
*/ |
142
|
|
|
public function getSource() |
143
|
|
|
{ |
144
|
|
|
return $this->source; |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
/** |
148
|
|
|
* Элемент с которым сравнивают |
149
|
|
|
* |
150
|
|
|
* @return ElementInterface |
151
|
|
|
*/ |
152
|
|
|
public function getTarget() |
153
|
|
|
{ |
154
|
|
|
return $this->target; |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
/** |
158
|
|
|
* Добавляет объект описывающий различия между двумя элементами формы |
159
|
|
|
* |
160
|
|
|
* @param AbstractDiff $diff |
161
|
|
|
* |
162
|
|
|
* @return $this |
163
|
|
|
*/ |
164
|
|
|
public function addDiff(AbstractDiff $diff) |
165
|
|
|
{ |
166
|
|
|
$this->diff[] = $diff; |
167
|
|
|
|
168
|
|
|
return $this; |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
/** |
172
|
|
|
* Возвращает объекты описывающие различия между двумя элементами формы |
173
|
|
|
* |
174
|
|
|
* @return AbstractDiff[] |
175
|
|
|
*/ |
176
|
|
|
public function getDiff() |
177
|
|
|
{ |
178
|
|
|
return $this->diff; |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
/** |
182
|
|
|
* Возвращает путь до элементов которые в данный момент сравниваются |
183
|
|
|
* |
184
|
|
|
* @return string |
185
|
|
|
*/ |
186
|
|
|
public function getPrefixPath() |
187
|
|
|
{ |
188
|
|
|
return $this->prefixPath; |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
|
192
|
|
|
|
193
|
|
|
} |
194
|
|
|
|
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.