1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Majora\Framework\Domain\Action; |
4
|
|
|
|
5
|
|
|
use Doctrine\Common\Collections\ArrayCollection; |
6
|
|
|
use Symfony\Component\PropertyAccess\PropertyAccess; |
7
|
|
|
use Symfony\Component\PropertyAccess\PropertyAccessorInterface; |
8
|
|
|
|
9
|
|
|
/** |
10
|
|
|
* Provides methods to use into action which are hydrated by forms |
11
|
|
|
*/ |
12
|
|
|
trait DynamicActionTrait |
13
|
|
|
{ |
14
|
|
|
/** |
15
|
|
|
* @var ArrayCollection |
16
|
|
|
*/ |
17
|
|
|
protected $attributes; |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* @var PropertyAccessorInterface |
21
|
|
|
*/ |
22
|
|
|
private $propertyAccessor; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* Magic call implementation which forward to dynamic getter / setter |
26
|
|
|
*/ |
27
|
|
|
public function __call($method, $arguments) |
28
|
|
|
{ |
29
|
|
|
switch (true) { |
30
|
|
|
|
31
|
|
|
// accessor ? |
32
|
|
View Code Duplication |
case strpos($method, 'get') === 0 : |
|
|
|
|
33
|
|
|
return $this->_get(lcfirst(preg_filter( |
34
|
|
|
'/^get(.+)/', '$1', $method |
35
|
|
|
))); |
36
|
|
|
|
37
|
|
|
// mutator ? |
38
|
|
View Code Duplication |
case strpos($method, 'set') === 0 : |
|
|
|
|
39
|
|
|
return $this->_set( |
40
|
|
|
lcfirst(preg_filter('/^set(.+)/', '$1', $method)), |
41
|
|
|
$arguments[0] |
42
|
|
|
); |
43
|
|
|
|
44
|
|
|
default: |
45
|
|
|
throw new \BadMethodCallException(sprintf('Method %s::%s() doesnt exists.', |
46
|
|
|
get_class($this), |
47
|
|
|
$method |
48
|
|
|
)); |
49
|
|
|
} |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* Return attribute map |
54
|
|
|
* |
55
|
|
|
* @return ArrayCollection |
56
|
|
|
*/ |
57
|
|
|
private function getAttributes() |
58
|
|
|
{ |
59
|
|
|
$this->attributes = $this->attributes ?: new ArrayCollection(); |
60
|
|
|
|
61
|
|
|
return $this->attributes; |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* Return internal property accessor |
66
|
|
|
* |
67
|
|
|
* @return PropertyAccessorInterface |
68
|
|
|
*/ |
69
|
|
|
private function getPropertyAccessor() |
70
|
|
|
{ |
71
|
|
|
$this->propertyAccessor = $this->propertyAccessor ?: |
72
|
|
|
PropertyAccess::createPropertyAccessor() |
73
|
|
|
; |
74
|
|
|
|
75
|
|
|
return $this->propertyAccessor; |
76
|
|
|
} |
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* Returns data under given key, null if undefined |
80
|
|
|
* |
81
|
|
|
* @param string $key |
82
|
|
|
* |
83
|
|
|
* @return mixed |
84
|
|
|
*/ |
85
|
|
|
protected function _get($key) |
86
|
|
|
{ |
87
|
|
|
return $this->getAttributes()->get($key); |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* Tests if given key exists |
92
|
|
|
* |
93
|
|
|
* @param string $key |
94
|
|
|
* |
95
|
|
|
* @return boolean |
96
|
|
|
*/ |
97
|
|
|
protected function _has($key) |
98
|
|
|
{ |
99
|
|
|
return $this->getAttributes()->containsKey($key); |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* Stores given key as given value |
104
|
|
|
* |
105
|
|
|
* @param string $key |
106
|
|
|
* @param mixed $value |
107
|
|
|
* |
108
|
|
|
* @return self |
109
|
|
|
*/ |
110
|
|
|
protected function _set($key, $value) |
111
|
|
|
{ |
112
|
|
|
$this->getAttributes()->set($key, $value); |
113
|
|
|
|
114
|
|
|
return $this; |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
/** |
118
|
|
|
* Define given field on given object, if accessible |
119
|
|
|
* |
120
|
|
|
* @param mixed $object |
121
|
|
|
* @param string $field |
122
|
|
|
* |
123
|
|
|
* @return mixed|null |
124
|
|
|
*/ |
125
|
|
|
protected function setIfDefined($object, $field) |
126
|
|
|
{ |
127
|
|
|
$propertyAccessor = $this->getPropertyAccessor(); |
128
|
|
|
if (!$this->_has($field)) { |
129
|
|
|
return $propertyAccessor->isReadable($object, $field) ? |
130
|
|
|
$propertyAccessor->getValue($object, $field) : |
131
|
|
|
null |
132
|
|
|
; |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
$propertyAccessor->setValue( |
136
|
|
|
$object, |
137
|
|
|
$field, |
138
|
|
|
$value = $this->_get($field) |
139
|
|
|
); |
140
|
|
|
|
141
|
|
|
return $value; |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
/** |
145
|
|
|
* @see NormalizableInterface::getScopes() |
146
|
|
|
*/ |
147
|
|
|
public static function getScopes() |
148
|
|
|
{ |
149
|
|
|
return array(); |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
/** |
153
|
|
|
* @see NormalizableInterface::normalize() |
154
|
|
|
*/ |
155
|
|
|
public function normalize($scope = 'default') |
156
|
|
|
{ |
157
|
|
|
$data = $this->getAttributes()->toArray(); |
158
|
|
|
|
159
|
|
|
$scopes = $this->getScopes(); |
160
|
|
|
if(empty($scopes[$scope])) { |
161
|
|
|
return $data; |
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
$normalizedData = array(); |
165
|
|
|
$propertyAccessor = PropertyAccess::createPropertyAccessor(); |
166
|
|
|
foreach ($scopes[$scope] as $field) { |
167
|
|
|
$normalizedData[$field] = $propertyAccessor->isReadable( |
168
|
|
|
$data, |
169
|
|
|
$propertyPath = strpos($field, '[') === 0 ? |
170
|
|
|
$field : |
171
|
|
|
sprintf('[%s]', $field) |
172
|
|
|
) ? |
173
|
|
|
$propertyAccessor->getValue($data, $propertyPath) : |
174
|
|
|
null |
175
|
|
|
; |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
return $normalizedData; |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
/** |
182
|
|
|
* @see NormalizableInterface::denormalize() |
183
|
|
|
*/ |
184
|
|
|
public function denormalize(array $objectData) |
185
|
|
|
{ |
186
|
|
|
foreach ($objectData as $key => $value) { |
187
|
|
|
$this->_set($key, $value); |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
return $this; |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
/** |
194
|
|
|
* @see SerializableInterface::serialize() |
195
|
|
|
*/ |
196
|
|
|
public function serialize($scope = 'default', PropertyAccessorInterface $propertyAccessor = null) |
|
|
|
|
197
|
|
|
{ |
198
|
|
|
@trigger_error(sprintf('The method %s() is deprecated and will be removed in 2.0. Use normalize() instead.', __METHOD__), E_USER_DEPRECATED); |
|
|
|
|
199
|
|
|
|
200
|
|
|
return $this->normalize($scope); |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
/** |
204
|
|
|
* @see SerializableInterface::deserialize() |
205
|
|
|
*/ |
206
|
|
|
public function deserialize(array $data, PropertyAccessorInterface $propertyAccessor = null) |
|
|
|
|
207
|
|
|
{ |
208
|
|
|
@trigger_error(sprintf('The method %s() is deprecated and will be removed in 2.0. Use denormalize() instead.', __METHOD__), E_USER_DEPRECATED); |
|
|
|
|
209
|
|
|
|
210
|
|
|
return $this->denormalize($data); |
211
|
|
|
} |
212
|
|
|
} |
213
|
|
|
|
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.