1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* YAWIK |
4
|
|
|
* |
5
|
|
|
* @filesource |
6
|
|
|
* @license MIT |
7
|
|
|
* @copyright 2013 - 2016 Cross Solution <http://cross-solution.de> |
8
|
|
|
*/ |
9
|
|
|
|
10
|
|
|
/** */ |
11
|
|
|
namespace Core\Form\Hydrator\Strategy; |
12
|
|
|
|
13
|
|
|
use Core\Entity\Tree\AbstractLeafs; |
14
|
|
|
use Core\Entity\Tree\NodeInterface; |
15
|
|
|
use Doctrine\Common\Collections\ArrayCollection; |
16
|
|
|
use Doctrine\Common\Collections\Collection; |
17
|
|
|
use Zend\Hydrator\Strategy\StrategyInterface; |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* Hydrator strategy for TreeSelect form element. |
21
|
|
|
* |
22
|
|
|
* @author Mathias Gelhausen <[email protected]> |
23
|
|
|
* @since 0.29 |
24
|
|
|
*/ |
25
|
|
|
class TreeSelectStrategy implements StrategyInterface |
26
|
|
|
{ |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* The selected leafs. |
30
|
|
|
* |
31
|
|
|
* @var AbstractLeafs |
32
|
|
|
*/ |
33
|
|
|
private $attachedLeafs; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* The root node. |
37
|
|
|
* |
38
|
|
|
* @var NodeInterface |
39
|
|
|
*/ |
40
|
|
|
private $treeRoot; |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* Flag wether multiple selections are allowed. |
44
|
|
|
* |
45
|
|
|
* @var bool|callable |
46
|
|
|
*/ |
47
|
|
|
private $allowSelectMultipleItems = false; |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* Set the selected leafs. |
51
|
|
|
* |
52
|
|
|
* @param AbstractLeafs $attachedLeafs |
53
|
|
|
* |
54
|
|
|
* @return self |
55
|
|
|
*/ |
56
|
|
|
public function setAttachedLeafs(AbstractLeafs $attachedLeafs) |
57
|
|
|
{ |
58
|
|
|
$this->attachedLeafs = $attachedLeafs; |
59
|
|
|
|
60
|
|
|
return $this; |
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* Get the selected leafs. |
65
|
|
|
* |
66
|
|
|
* @return AbstractLeafs |
67
|
|
|
*/ |
68
|
|
|
public function getAttachedLeafs() |
69
|
|
|
{ |
70
|
|
|
return $this->attachedLeafs; |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* Set the root node. |
75
|
|
|
* |
76
|
|
|
* @param NodeInterface $treeRoot |
77
|
|
|
* |
78
|
|
|
* @return self |
79
|
|
|
*/ |
80
|
|
|
public function setTreeRoot(NodeInterface $treeRoot) |
81
|
|
|
{ |
82
|
|
|
$this->treeRoot = $treeRoot; |
83
|
|
|
|
84
|
|
|
return $this; |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* Get the root node. |
89
|
|
|
* |
90
|
|
|
* @return NodeInterface |
91
|
|
|
*/ |
92
|
|
|
public function getTreeRoot() |
93
|
|
|
{ |
94
|
|
|
return $this->treeRoot; |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
/** |
98
|
|
|
* Set the allow multiple selections flag. |
99
|
|
|
* |
100
|
|
|
* @param Callable|bool $flagOrCallback When a Callable is passed, it must return bool. |
101
|
|
|
* |
102
|
|
|
* @return self |
103
|
|
|
*/ |
104
|
|
|
public function setAllowSelectMultipleItems($flagOrCallback) |
105
|
|
|
{ |
106
|
|
|
$this->allowSelectMultipleItems = $flagOrCallback; |
107
|
|
|
|
108
|
|
|
return $this; |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* Are multiple selections allowed? |
113
|
|
|
* |
114
|
|
|
* @return bool |
115
|
|
|
*/ |
116
|
|
|
public function allowSelectMultipleItems() |
|
|
|
|
117
|
|
|
{ |
118
|
|
|
$flagOrCallback = $this->allowSelectMultipleItems; |
119
|
|
|
|
120
|
|
|
return is_callable($flagOrCallback) ? (bool) $flagOrCallback() : (bool) $flagOrCallback; |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
public function extract($value) |
124
|
|
|
{ |
125
|
|
|
if (!$value instanceOf AbstractLeafs) { |
126
|
|
|
throw new \InvalidArgumentException('$value must be an instance of ' . AbstractLeafs::class); |
127
|
|
|
} |
128
|
|
|
/* @var AbstractLeafs $value |
129
|
|
|
* @var NodeInterface $item */ |
130
|
|
|
|
131
|
|
|
$this->setAttachedLeafs($value); |
132
|
|
|
|
133
|
|
|
if (!$this->allowSelectMultipleItems()) { |
134
|
|
|
$item = $value->getItems()->first(); |
135
|
|
|
return $item ? $this->getItemValue($item) : null; |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
$data = []; |
139
|
|
|
foreach ($value->getItems() as $item) { |
140
|
|
|
$data[] = $this->getItemValue($item); |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
return $data; |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
public function hydrate($value) |
147
|
|
|
{ |
148
|
|
|
$root = $this->getTreeRoot(); |
149
|
|
|
$object = $this->getAttachedLeafs(); |
150
|
|
|
$items = new ArrayCollection(); |
151
|
|
|
|
152
|
|
|
if (!$this->allowSelectMultipleItems()) { |
153
|
|
|
$value = [$value]; |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
foreach ($value as $itemValue) { |
157
|
|
|
$leaf = $this->findLeaf($root, $itemValue); |
|
|
|
|
158
|
|
|
|
159
|
|
|
if ($leaf) { |
160
|
|
|
$items->add($leaf); |
161
|
|
|
} |
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
$object->setItems($items); |
165
|
|
|
|
166
|
|
|
return $object; |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
/** |
170
|
|
|
* Get item value for use in the option tag. |
171
|
|
|
* |
172
|
|
|
* @param NodeInterface $item |
173
|
|
|
* |
174
|
|
|
* @return string item value prepended with all parent values except root node. |
175
|
|
|
*/ |
176
|
|
View Code Duplication |
private function getItemValue(NodeInterface $item) |
|
|
|
|
177
|
|
|
{ |
178
|
|
|
$parts = [ $item->getValue() ]; |
179
|
|
|
|
180
|
|
|
while ($item = $item->getParent()) { |
181
|
|
|
$parts[] = $item->getValue(); |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
array_pop($parts); // No root node. |
185
|
|
|
|
186
|
|
|
$parts = array_reverse($parts); |
187
|
|
|
$value = join('-', $parts); |
188
|
|
|
|
189
|
|
|
return $value; |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
/** |
193
|
|
|
* Find a leaf with a concrete value in the tree. |
194
|
|
|
* |
195
|
|
|
* @param NodeInterface $leaf |
196
|
|
|
* @param string $value |
197
|
|
|
* |
198
|
|
|
* @return NodeInterface|null |
199
|
|
|
*/ |
200
|
|
|
private function findLeaf(NodeInterface $leaf, $value) |
201
|
|
|
{ |
202
|
|
|
$parts = is_array($value) ? $value : explode('-', $value); |
203
|
|
|
$value = array_shift($parts); |
204
|
|
|
|
205
|
|
|
/* @var NodeInterface $item */ |
206
|
|
|
foreach ($leaf->getChildren() as $item) { |
207
|
|
|
if ($item->getValue() == $value) { |
208
|
|
|
if (count($parts)) { |
209
|
|
|
return $this->findLeaf($item, $parts); |
|
|
|
|
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
return $item; |
213
|
|
|
} |
214
|
|
|
} |
215
|
|
|
|
216
|
|
|
return null; |
217
|
|
|
} |
218
|
|
|
} |
This check examines a number of code elements and verifies that they conform to the given naming conventions.
You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.