This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace Sulu\Component\DocumentManager\Subscriber\Core; |
||
4 | |||
5 | use PHPCR\NodeInterface; |
||
6 | use Sulu\Component\DocumentManager\DocumentAccessor; |
||
7 | use Sulu\Component\DocumentManager\DocumentRegistry; |
||
8 | use Sulu\Component\DocumentManager\Event\AbstractMappingEvent; |
||
9 | use Sulu\Component\DocumentManager\Event\PersistEvent; |
||
10 | use Sulu\Component\DocumentManager\Events; |
||
11 | use Sulu\Component\DocumentManager\Exception\InvalidLocaleException; |
||
12 | use Sulu\Component\DocumentManager\MetadataFactoryInterface; |
||
13 | use Sulu\Component\DocumentManager\PropertyEncoder; |
||
14 | use Sulu\Component\DocumentManager\ProxyFactory; |
||
15 | use Symfony\Component\EventDispatcher\EventSubscriberInterface; |
||
16 | |||
17 | /** |
||
18 | * This subscriber uses the field map in the metadata to map fields from |
||
19 | * the PHPCR nodes to the document and vice-versa. |
||
20 | */ |
||
21 | class MappingSubscriber implements EventSubscriberInterface |
||
22 | { |
||
23 | /** |
||
24 | * @var MetadataFactoryInterface |
||
25 | */ |
||
26 | private $factory; |
||
27 | |||
28 | /** |
||
29 | * @var PropertyEncoder |
||
30 | */ |
||
31 | private $encoder; |
||
32 | |||
33 | /** |
||
34 | * @var ProxyFactory |
||
35 | */ |
||
36 | private $proxyFactory; |
||
37 | |||
38 | /** |
||
39 | * @var DocumentRegistry |
||
40 | */ |
||
41 | private $documentRegistry; |
||
42 | |||
43 | /** |
||
44 | * @param MetadataFactoryInterface $factory |
||
45 | * @param PropertyEncoder $encoder |
||
46 | * @param ProxyFactory $proxyFactory |
||
47 | * @param DocumentRegistry $documentRegistry |
||
48 | */ |
||
49 | public function __construct( |
||
50 | MetadataFactoryInterface $factory, |
||
51 | PropertyEncoder $encoder, |
||
52 | ProxyFactory $proxyFactory, |
||
53 | DocumentRegistry $documentRegistry |
||
54 | ) { |
||
55 | $this->factory = $factory; |
||
56 | $this->encoder = $encoder; |
||
57 | $this->proxyFactory = $proxyFactory; |
||
58 | $this->documentRegistry = $documentRegistry; |
||
59 | } |
||
60 | |||
61 | /** |
||
62 | * {@inheritdoc} |
||
63 | */ |
||
64 | public static function getSubscribedEvents() |
||
65 | { |
||
66 | return [ |
||
67 | Events::HYDRATE => ['handleHydrate', -100], |
||
68 | Events::PERSIST => ['handlePersist', -100], |
||
69 | ]; |
||
70 | } |
||
71 | |||
72 | /** |
||
73 | * @param PersistEvent $event |
||
74 | */ |
||
75 | public function handlePersist(PersistEvent $event) |
||
76 | { |
||
77 | $metadata = $this->factory->getMetadataForClass(get_class($event->getDocument())); |
||
78 | $locale = $event->getLocale(); |
||
79 | $node = $event->getNode(); |
||
80 | $accessor = $event->getAccessor(); |
||
81 | |||
82 | View Code Duplication | foreach ($metadata->getFieldMappings() as $fieldName => $fieldMapping) { |
|
0 ignored issues
–
show
|
|||
83 | if (false === $fieldMapping['mapped']) { |
||
84 | continue; |
||
85 | } |
||
86 | |||
87 | switch ($fieldMapping['type']) { |
||
88 | case 'reference': |
||
89 | $this->persistReference($node, $accessor, $fieldName, $locale, $fieldMapping); |
||
90 | break; |
||
91 | default: |
||
92 | $this->persistGeneric($node, $accessor, $fieldName, $locale, $fieldMapping); |
||
93 | } |
||
94 | } |
||
95 | } |
||
96 | |||
97 | /** |
||
98 | * Persist a reference field type. |
||
99 | * |
||
100 | * @param NodeInterface $node |
||
101 | * @param DocumentAccessor $accessor |
||
102 | * @param mixed $fieldName |
||
103 | * @param mixed $locale |
||
104 | * @param mixed $fieldMapping |
||
105 | */ |
||
106 | private function persistReference( |
||
107 | NodeInterface $node, |
||
108 | DocumentAccessor $accessor, |
||
109 | $fieldName, |
||
110 | $locale, |
||
111 | $fieldMapping |
||
112 | ) { |
||
113 | $referenceDocument = $accessor->get($fieldName); |
||
114 | |||
115 | if (!$referenceDocument) { |
||
116 | return; |
||
117 | } |
||
118 | |||
119 | if ($fieldMapping['multiple']) { |
||
120 | throw new \InvalidArgumentException( |
||
121 | sprintf( |
||
122 | 'Mapping references as multiple not currently supported (when mapping "%s")', |
||
123 | $fieldName |
||
124 | ) |
||
125 | ); |
||
126 | } |
||
127 | |||
128 | try { |
||
129 | $referenceNode = $this->documentRegistry->getNodeForDocument($referenceDocument); |
||
130 | $phpcrName = $this->encoder->encode($fieldMapping['encoding'], $fieldMapping['property'], $locale); |
||
131 | $node->setProperty($phpcrName, $referenceNode); |
||
132 | } catch (InvalidLocaleException $ex) { |
||
133 | // arguments unvalid no valid propertyname could be generated (e.g. no locale given for localized encoding) |
||
134 | return; |
||
135 | } |
||
136 | } |
||
137 | |||
138 | /** |
||
139 | * Persist "scalar" field types. |
||
140 | * |
||
141 | * @param NodeInterface $node |
||
142 | * @param DocumentAccessor $accessor |
||
143 | * @param mixed $fieldName |
||
144 | * @param mixed $locale |
||
145 | * @param array $fieldMapping |
||
146 | */ |
||
147 | View Code Duplication | private function persistGeneric( |
|
0 ignored issues
–
show
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...
|
|||
148 | NodeInterface $node, |
||
149 | DocumentAccessor $accessor, |
||
150 | $fieldName, |
||
151 | $locale, |
||
152 | array $fieldMapping |
||
153 | ) { |
||
154 | try { |
||
155 | $phpcrName = $this->encoder->encode($fieldMapping['encoding'], $fieldMapping['property'], $locale); |
||
156 | $value = $accessor->get($fieldName); |
||
157 | $this->validateFieldValue($value, $fieldName, $fieldMapping); |
||
158 | $node->setProperty($phpcrName, $value); |
||
159 | } catch (InvalidLocaleException $ex) { |
||
160 | // arguments unvalid no valid propertyname could be generated (e.g. no locale given for localized encoding) |
||
161 | return; |
||
162 | } |
||
163 | } |
||
164 | |||
165 | /** |
||
166 | * @param AbstractMappingEvent $event |
||
167 | */ |
||
168 | public function handleHydrate(AbstractMappingEvent $event) |
||
169 | { |
||
170 | $class = get_class($event->getDocument()); |
||
171 | |||
172 | // TODO: Return false here in case this is for instance an UnknownDocument. |
||
173 | // But we should probably map the UnknownDocument and let an Exception be |
||
174 | // thrown in other cases. |
||
175 | if (false === $this->factory->hasMetadataForClass($class)) { |
||
176 | return; |
||
177 | } |
||
178 | |||
179 | $metadata = $this->factory->getMetadataForClass($class); |
||
180 | $locale = $event->getLocale(); |
||
181 | $node = $event->getNode(); |
||
182 | $accessor = $event->getAccessor(); |
||
183 | $document = $event->getDocument(); |
||
184 | |||
185 | View Code Duplication | foreach ($metadata->getFieldMappings() as $fieldName => $fieldMapping) { |
|
0 ignored issues
–
show
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...
|
|||
186 | if (false === $fieldMapping['mapped']) { |
||
187 | continue; |
||
188 | } |
||
189 | |||
190 | switch ($fieldMapping['type']) { |
||
191 | case 'reference': |
||
192 | $this->hydrateReferenceField($node, $document, $accessor, $fieldName, $locale, $fieldMapping); |
||
193 | break; |
||
194 | default: |
||
195 | $this->hydrateGenericField($node, $accessor, $fieldName, $locale, $fieldMapping); |
||
196 | } |
||
197 | } |
||
198 | } |
||
199 | |||
200 | /** |
||
201 | * Hydrate reference field types. |
||
202 | * |
||
203 | * @param NodeInterface $node |
||
204 | * @param mixed $document |
||
205 | * @param DocumentAccessor $accessor |
||
206 | * @param mixed $fieldName |
||
207 | * @param mixed $locale |
||
208 | * @param array $fieldMapping |
||
209 | */ |
||
210 | View Code Duplication | private function hydrateReferenceField( |
|
0 ignored issues
–
show
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...
|
|||
211 | NodeInterface $node, |
||
212 | $document, |
||
213 | DocumentAccessor $accessor, |
||
214 | $fieldName, |
||
215 | $locale, |
||
216 | array $fieldMapping |
||
217 | ) { |
||
218 | try { |
||
219 | $phpcrName = $this->encoder->encode($fieldMapping['encoding'], $fieldMapping['property'], $locale); |
||
220 | $referencedNode = $node->getPropertyValueWithDefault( |
||
221 | $phpcrName, |
||
222 | $this->getDefaultValue($fieldMapping) |
||
223 | ); |
||
224 | |||
225 | if ($referencedNode) { |
||
226 | $accessor->set( |
||
227 | $fieldName, |
||
228 | $this->proxyFactory->createProxyForNode($document, $referencedNode) |
||
229 | ); |
||
230 | } |
||
231 | } catch (InvalidLocaleException $ex) { |
||
232 | // arguments unvalid no valid propertyname could be generated (e.g. no locale given for localized encoding) |
||
233 | return; |
||
234 | } |
||
235 | } |
||
236 | |||
237 | /** |
||
238 | * Hydrate "scalar" field types. |
||
239 | * |
||
240 | * @param NodeInterface $node |
||
241 | * @param DocumentAccessor $accessor |
||
242 | * @param mixed $fieldName |
||
243 | * @param mixed $locale |
||
244 | * @param array $fieldMapping |
||
245 | */ |
||
246 | private function hydrateGenericField( |
||
247 | NodeInterface $node, |
||
248 | DocumentAccessor $accessor, |
||
249 | $fieldName, |
||
250 | $locale, |
||
251 | array $fieldMapping |
||
252 | ) { |
||
253 | try { |
||
254 | $phpcrName = $this->encoder->encode($fieldMapping['encoding'], $fieldMapping['property'], $locale); |
||
255 | $value = $node->getPropertyValueWithDefault( |
||
256 | $phpcrName, |
||
257 | $this->getDefaultValue($fieldMapping) |
||
258 | ); |
||
259 | $accessor->set($fieldName, $value); |
||
260 | } catch (InvalidLocaleException $ex) { |
||
261 | // arguments unvalid no valid propertyname could be generated (e.g. no locale given for localized encoding) |
||
262 | return; |
||
263 | } |
||
264 | } |
||
265 | |||
266 | private function getDefaultValue(array $fieldMapping) |
||
267 | { |
||
268 | if ($fieldMapping['default']) { |
||
269 | return $fieldMapping['default']; |
||
270 | } |
||
271 | |||
272 | return $fieldMapping['multiple'] ? [] : null; |
||
273 | } |
||
274 | |||
275 | private function validateFieldValue($value, $fieldName, $fieldMapping) |
||
276 | { |
||
277 | View Code Duplication | if ($fieldMapping['multiple'] && !is_array($value)) { |
|
0 ignored issues
–
show
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...
|
|||
278 | throw new \InvalidArgumentException( |
||
279 | sprintf( |
||
280 | 'Field "%s" is mapped as multiple, and therefore must be an array, got "%s"', |
||
281 | $fieldName, |
||
282 | is_object($value) ? get_class($value) : gettype($value) |
||
283 | ) |
||
284 | ); |
||
285 | } |
||
286 | } |
||
287 | } |
||
288 |
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.