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 Doctrine\ODM\CouchDB\Mapping; |
||
4 | |||
5 | use Doctrine\Common\Persistence\Mapping\ClassMetadata AS IClassMetadata, |
||
6 | Doctrine\Instantiator\Instantiator, |
||
7 | ReflectionClass, |
||
8 | ReflectionProperty; |
||
9 | |||
10 | /** |
||
11 | * Metadata class |
||
12 | * |
||
13 | * @license http://www.opensource.org/licenses/lgpl-license.php LGPL |
||
14 | * @link www.doctrine-project.com |
||
15 | * @since 1.0 |
||
16 | * @author Benjamin Eberlei <[email protected]> |
||
17 | * @author Lukas Kahwe Smith <[email protected]> |
||
18 | */ |
||
19 | class ClassMetadata implements IClassMetadata |
||
20 | { |
||
21 | const IDGENERATOR_UUID = 1; |
||
22 | const IDGENERATOR_ASSIGNED = 2; |
||
23 | |||
24 | const TO_ONE = 5; |
||
25 | const TO_MANY = 10; |
||
26 | const ONE_TO_ONE = 1; |
||
27 | const ONE_TO_MANY = 2; |
||
28 | const MANY_TO_ONE = 4; |
||
29 | const MANY_TO_MANY = 8; |
||
30 | |||
31 | const CASCADE_PERSIST = 1; |
||
32 | const CASCADE_REMOVE = 2; |
||
33 | const CASCADE_MERGE = 4; |
||
34 | const CASCADE_DETACH = 8; |
||
35 | const CASCADE_REFRESH = 16; |
||
36 | const CASCADE_ALL = 31; |
||
37 | |||
38 | public $idGenerator = self::IDGENERATOR_UUID; |
||
39 | |||
40 | /** |
||
41 | * READ-ONLY: The field name of the document identifier. |
||
42 | */ |
||
43 | public $identifier; |
||
44 | |||
45 | /** |
||
46 | * READ-ONLY: The name of the document class. |
||
47 | */ |
||
48 | public $name; |
||
49 | |||
50 | /** |
||
51 | * READ-ONLY: The root document class name. |
||
52 | */ |
||
53 | public $rootDocumentName; |
||
54 | |||
55 | /** |
||
56 | * READ-ONLY: Is this entity in an inheritance hierachy? |
||
57 | */ |
||
58 | public $inInheritanceHierachy = false; |
||
59 | |||
60 | /** |
||
61 | * READ-ONLY: a list of all parent classes. |
||
62 | */ |
||
63 | public $parentClasses = array(); |
||
64 | |||
65 | /** |
||
66 | * READ-ONLY: The namespace the document class is contained in. |
||
67 | * |
||
68 | * @var string |
||
69 | * @todo Not really needed. Usage could be localized. |
||
70 | */ |
||
71 | public $namespace; |
||
72 | |||
73 | /** |
||
74 | * The name of the custom repository class used for the document class. |
||
75 | * (Optional). |
||
76 | * |
||
77 | * @var string |
||
78 | */ |
||
79 | public $customRepositoryClassName; |
||
80 | |||
81 | /** |
||
82 | * READ-ONLY: The field mappings of the class. |
||
83 | * Keys are field names and values are mapping definitions. |
||
84 | * |
||
85 | * The mapping definition array has the following values: |
||
86 | * |
||
87 | * - <b>fieldName</b> (string) |
||
88 | * The name of the field in the Document. |
||
89 | * |
||
90 | * - <b>id</b> (boolean, optional) |
||
91 | * Marks the field as the primary key of the document. Multiple fields of an |
||
92 | * document can have the id attribute, forming a composite key. |
||
93 | * |
||
94 | * @var array |
||
95 | */ |
||
96 | public $fieldMappings = array(); |
||
97 | |||
98 | /** |
||
99 | * An array of indexed fields, accessible through a generic view shipped with Doctrine. |
||
100 | * |
||
101 | * @var array |
||
102 | */ |
||
103 | public $indexes = array(); |
||
104 | |||
105 | /** |
||
106 | * Is this class indexed? If yes, then a findAll() query can be executed for this type. |
||
107 | * |
||
108 | * @var bool |
||
109 | */ |
||
110 | public $indexed = false; |
||
111 | |||
112 | /** |
||
113 | * An array of json result-key-names to field-names |
||
114 | * |
||
115 | * @var array |
||
116 | */ |
||
117 | public $jsonNames = array(); |
||
118 | |||
119 | /** |
||
120 | * READ-ONLY: Array of fields to also load with a given method. |
||
121 | * |
||
122 | * @var array |
||
123 | */ |
||
124 | public $alsoLoadMethods = array(); |
||
125 | |||
126 | /** |
||
127 | * READ-ONLY: Whether this class describes the mapping of a mapped superclass. |
||
128 | * |
||
129 | * @var boolean |
||
130 | */ |
||
131 | public $isMappedSuperclass = false; |
||
132 | |||
133 | /** |
||
134 | * READ-ONLY: Whether this class describes the mapping of a embedded document. |
||
135 | * |
||
136 | * @var boolean |
||
137 | */ |
||
138 | public $isEmbeddedDocument = false; |
||
139 | |||
140 | /** |
||
141 | * READ-ONLY: Wheather the document or embedded document is read-only and will be skipped in change-tracking. |
||
142 | * |
||
143 | * This should be set to true for value objects, for example attachments. Replacing the reference with a new |
||
144 | * value object will trigger an update. |
||
145 | * |
||
146 | * @var bool |
||
147 | */ |
||
148 | public $isReadOnly = false; |
||
149 | |||
150 | /** |
||
151 | * READ-ONLY |
||
152 | * |
||
153 | * @var array |
||
154 | */ |
||
155 | public $associationsMappings = array(); |
||
156 | |||
157 | /** |
||
158 | * CouchDB documents are always versioned, this flag determines if this version is exposed to the userland. |
||
159 | * |
||
160 | * @var bool |
||
161 | */ |
||
162 | public $isVersioned = false; |
||
163 | |||
164 | /** |
||
165 | * Version Field stores the CouchDB Revision |
||
166 | * |
||
167 | * @var string |
||
168 | */ |
||
169 | public $versionField = null; |
||
170 | |||
171 | /** |
||
172 | * @var bool |
||
173 | */ |
||
174 | public $hasAttachments = false; |
||
175 | |||
176 | /** |
||
177 | * Field that stores the attachments as a key->value array of file-names to attachment objects. |
||
178 | * |
||
179 | * @var string |
||
180 | */ |
||
181 | public $attachmentField = null; |
||
182 | |||
183 | /** |
||
184 | * If in an inheritance scenario the attachment field is on a super class, this is its name. |
||
185 | * |
||
186 | * @var string|null |
||
187 | */ |
||
188 | public $attachmentDeclaredClass = null; |
||
189 | |||
190 | /** |
||
191 | * The ReflectionClass instance of the mapped class. |
||
192 | * |
||
193 | * @var ReflectionClass |
||
194 | */ |
||
195 | public $reflClass; |
||
196 | |||
197 | /** |
||
198 | * The ReflectionProperty instances of the mapped class. |
||
199 | * |
||
200 | * @var array |
||
201 | */ |
||
202 | public $reflFields = array(); |
||
203 | |||
204 | /** |
||
205 | * @var \Doctrine\Instantiator\InstantiatorInterface |
||
206 | */ |
||
207 | private $instantiator; |
||
208 | |||
209 | /** |
||
210 | * Initializes a new ClassMetadata instance that will hold the object-document mapping |
||
211 | * metadata of the class with the given name. |
||
212 | * |
||
213 | * @param string $documentName The name of the document class the new instance is used for. |
||
214 | */ |
||
215 | public function __construct($documentName) |
||
216 | { |
||
217 | $this->name = $documentName; |
||
218 | $this->rootDocumentName = $documentName; |
||
219 | $this->instantiator = new Instantiator(); |
||
220 | } |
||
221 | |||
222 | /** |
||
223 | * Used to derive a class metadata of the current instance for a mapped child class. |
||
224 | * |
||
225 | * @param ClassMetadata $child |
||
226 | * @throws \InvalidArgumentException |
||
227 | */ |
||
228 | public function deriveChildMetadata($child) |
||
229 | { |
||
230 | if (!is_subclass_of($child->name, $this->name)) { |
||
231 | throw new \InvalidArgumentException("Only child class names of '".$this->name."' are valid values."); |
||
232 | } |
||
233 | |||
234 | $child->isMappedSuperclass = false; |
||
235 | $child->isEmbeddedDocument = false; |
||
236 | |||
237 | foreach ($this->fieldMappings AS $fieldName => $fieldMapping) { |
||
238 | $child->fieldMappings[$fieldName] = $fieldMapping; |
||
239 | |||
240 | if (!isset($fieldMapping['declared'])) { |
||
241 | $child->fieldMappings[$fieldName]['declared'] = $this->name; |
||
242 | } |
||
243 | } |
||
244 | |||
245 | foreach ($this->associationsMappings AS $assocName => $assocMapping) { |
||
246 | $child->associationsMappings[$assocName] = $assocMapping; |
||
247 | |||
248 | if (!isset($assocMapping['declared'])) { |
||
249 | $child->associationsMappings[$assocName]['declared'] = $this->name; |
||
250 | } |
||
251 | } |
||
252 | |||
253 | if ($this->attachmentField) { |
||
254 | $child->attachmentField = $this->attachmentField; |
||
255 | |||
256 | if (!$child->attachmentDeclaredClass) { |
||
257 | $child->attachmentDeclaredClass = $this->name; |
||
258 | } |
||
259 | } |
||
260 | } |
||
261 | |||
262 | /** |
||
263 | * Determines which fields get serialized. |
||
264 | * |
||
265 | * It is only serialized what is necessary for best unserialization performance. |
||
266 | * That means any metadata properties that are not set or empty or simply have |
||
267 | * their default value are NOT serialized. |
||
268 | * |
||
269 | * Parts that are also NOT serialized because they can not be properly unserialized: |
||
270 | * - reflClass (ReflectionClass) |
||
271 | * - reflFields (ReflectionProperty array) |
||
272 | * |
||
273 | * @return array The names of all the fields that should be serialized. |
||
274 | */ |
||
275 | public function __sleep() |
||
276 | { |
||
277 | // This metadata is always serialized/cached. |
||
278 | $serialized = array( |
||
279 | 'name', |
||
280 | 'associationsMappings', |
||
281 | 'fieldMappings', |
||
282 | 'jsonNames', |
||
283 | 'idGenerator', |
||
284 | 'identifier', |
||
285 | 'rootDocumentName', |
||
286 | ); |
||
287 | |||
288 | if ($this->inInheritanceHierachy) { |
||
289 | $serialized[] = 'inInheritanceHierachy'; |
||
290 | } |
||
291 | |||
292 | if ($this->parentClasses) { |
||
293 | $serialized[] = 'parentClasses'; |
||
294 | } |
||
295 | |||
296 | if ($this->isVersioned) { |
||
297 | $serialized[] = 'isVersioned'; |
||
298 | $serialized[] = 'versionField'; |
||
299 | } |
||
300 | |||
301 | if ($this->customRepositoryClassName) { |
||
302 | $serialized[] = 'customRepositoryClassName'; |
||
303 | } |
||
304 | |||
305 | if ($this->hasAttachments) { |
||
306 | $serialized[] = 'hasAttachments'; |
||
307 | $serialized[] = 'attachmentField'; |
||
308 | if ($this->attachmentDeclaredClass) { |
||
309 | $serialized[] = 'attachmentDeclaredClass'; |
||
310 | } |
||
311 | } |
||
312 | |||
313 | if ($this->isReadOnly) { |
||
314 | $serialized[] = 'isReadOnly'; |
||
315 | } |
||
316 | |||
317 | if ($this->isMappedSuperclass) { |
||
318 | $serialized[] = 'isMappedSuperclass'; |
||
319 | } |
||
320 | |||
321 | if ($this->indexed) { |
||
322 | $serialized[] = 'indexed'; |
||
323 | } |
||
324 | if ($this->indexes) { |
||
325 | $serialized[] = 'indexes'; |
||
326 | } |
||
327 | |||
328 | return $serialized; |
||
329 | } |
||
330 | |||
331 | /** |
||
332 | * Restores some state that can not be serialized/unserialized. |
||
333 | */ |
||
334 | public function wakeupReflection($reflService) |
||
335 | { |
||
336 | // Restore ReflectionClass and properties |
||
337 | $this->reflClass = $reflService->getClass($this->name); |
||
338 | $this->namespace = $reflService->getClassNamespace($this->name); |
||
339 | $this->instantiator = $this->instantiator ?: new Instantiator(); |
||
340 | |||
341 | View Code Duplication | foreach ($this->fieldMappings as $field => $mapping) { |
|
0 ignored issues
–
show
|
|||
342 | if (isset($mapping['declared'])) { |
||
343 | $reflField = new \ReflectionProperty($mapping['declared'], $field); |
||
344 | } else { |
||
345 | $reflField = $this->reflClass->getProperty($field); |
||
346 | } |
||
347 | $reflField->setAccessible(true); |
||
348 | $this->reflFields[$field] = $reflField; |
||
349 | } |
||
350 | |||
351 | View Code Duplication | foreach ($this->associationsMappings as $field => $mapping) { |
|
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...
|
|||
352 | if (isset($mapping['declared'])) { |
||
353 | $reflField = new \ReflectionProperty($mapping['declared'], $field); |
||
354 | } else { |
||
355 | $reflField = $this->reflClass->getProperty($field); |
||
356 | } |
||
357 | |||
358 | $reflField->setAccessible(true); |
||
359 | $this->reflFields[$field] = $reflField; |
||
360 | } |
||
361 | |||
362 | if ($this->hasAttachments) { |
||
363 | if ($this->attachmentDeclaredClass) { |
||
364 | $reflField = new \ReflectionProperty($this->attachmentDeclaredClass, $this->attachmentField); |
||
365 | } else { |
||
366 | $reflField = $this->reflClass->getProperty($this->attachmentField); |
||
367 | } |
||
368 | $reflField->setAccessible(true); |
||
369 | $this->reflFields[$this->attachmentField] = $reflField; |
||
370 | } |
||
371 | } |
||
372 | |||
373 | /** |
||
374 | * Creates a new instance of the mapped class, without invoking the constructor. |
||
375 | * |
||
376 | * @return object |
||
377 | */ |
||
378 | public function newInstance() |
||
379 | { |
||
380 | return $this->instantiator->instantiate($this->name); |
||
381 | } |
||
382 | |||
383 | /** |
||
384 | * Gets the ReflectionClass instance of the mapped class. |
||
385 | * |
||
386 | * @return ReflectionClass |
||
387 | */ |
||
388 | public function getReflectionClass() |
||
389 | { |
||
390 | if ( ! $this->reflClass) { |
||
391 | $this->reflClass = new ReflectionClass($this->name); |
||
392 | } |
||
393 | return $this->reflClass; |
||
394 | } |
||
395 | |||
396 | /** |
||
397 | * Gets the ReflectionPropertys of the mapped class. |
||
398 | * |
||
399 | * @return array An array of ReflectionProperty instances. |
||
400 | */ |
||
401 | public function getReflectionProperties() |
||
402 | { |
||
403 | return $this->reflFields; |
||
404 | } |
||
405 | |||
406 | /** |
||
407 | * Gets a ReflectionProperty for a specific field of the mapped class. |
||
408 | * |
||
409 | * @param string $name |
||
410 | * @return ReflectionProperty |
||
411 | */ |
||
412 | public function getReflectionProperty($name) |
||
413 | { |
||
414 | return $this->reflFields[$name]; |
||
415 | } |
||
416 | |||
417 | |||
418 | /** |
||
419 | * Sets the document identifier of a document. |
||
420 | * |
||
421 | * @param object $document |
||
422 | * @param mixed $id |
||
423 | */ |
||
424 | public function setIdentifierValue($document, $id) |
||
425 | { |
||
426 | $this->reflFields[$this->identifier]->setValue($document, $id); |
||
427 | } |
||
428 | |||
429 | /** |
||
430 | * Gets the document identifier. |
||
431 | * |
||
432 | * @param object $document |
||
433 | * @return string $id |
||
434 | */ |
||
435 | public function getIdentifierValue($document) |
||
436 | { |
||
437 | return (string) $this->reflFields[$this->identifier]->getValue($document); |
||
438 | } |
||
439 | |||
440 | /** |
||
441 | * Get identifier values of this document. |
||
442 | * |
||
443 | * Since CouchDB only allows exactly one identifier field this is a proxy |
||
444 | * to {@see getIdentifierValue()} and returns an array with the identifier |
||
445 | * field as a key. |
||
446 | * |
||
447 | * @param object $document |
||
448 | * @return array |
||
449 | */ |
||
450 | public function getIdentifierValues($document) |
||
451 | { |
||
452 | return array($this->identifier => $this->getIdentifierValue($document)); |
||
453 | } |
||
454 | |||
455 | /** |
||
456 | * Sets the specified field to the specified value on the given document. |
||
457 | * |
||
458 | * @param object $document |
||
459 | * @param string $field |
||
460 | * @param mixed $value |
||
461 | */ |
||
462 | public function setFieldValue($document, $field, $value) |
||
463 | { |
||
464 | $this->reflFields[$field]->setValue($document, $value); |
||
465 | } |
||
466 | |||
467 | /** |
||
468 | * Gets the specified field's value off the given document. |
||
469 | * |
||
470 | * @param object $document |
||
471 | * @param string $field |
||
472 | */ |
||
473 | public function getFieldValue($document, $field) |
||
474 | { |
||
475 | return $this->reflFields[$field]->getValue($document); |
||
476 | } |
||
477 | |||
478 | /** |
||
479 | * Checks whether a field is part of the identifier/primary key field(s). |
||
480 | * |
||
481 | * @param string $fieldName The field name |
||
482 | * @return boolean TRUE if the field is part of the table identifier/primary key field(s), |
||
483 | * FALSE otherwise. |
||
484 | */ |
||
485 | public function isIdentifier($fieldName) |
||
486 | { |
||
487 | return $this->identifier === $fieldName ? true : false; |
||
488 | } |
||
489 | |||
490 | /** |
||
491 | * INTERNAL: |
||
492 | * Sets the mapped identifier field of this class. |
||
493 | * |
||
494 | * @param string $identifier |
||
495 | * @throws MappingException |
||
496 | */ |
||
497 | public function setIdentifier($identifier) |
||
498 | { |
||
499 | if ($this->isEmbeddedDocument) { |
||
500 | throw new MappingException('EmbeddedDocument should not have id field'); |
||
501 | } |
||
502 | $this->identifier = $identifier; |
||
503 | } |
||
504 | |||
505 | /** |
||
506 | * Gets the mapped identifier field of this class. |
||
507 | * |
||
508 | * @return string $identifier |
||
509 | */ |
||
510 | public function getIdentifier() |
||
511 | { |
||
512 | return $this->identifier; |
||
513 | } |
||
514 | |||
515 | /** |
||
516 | * Get identifier field names of this class.; |
||
517 | * |
||
518 | * Since CouchDB only allows exactly one identifier field this is a proxy |
||
519 | * to {@see getIdentifier()} and returns an array. |
||
520 | * |
||
521 | * @return array |
||
522 | */ |
||
523 | public function getIdentifierFieldNames() |
||
524 | { |
||
525 | return array($this->identifier); |
||
526 | } |
||
527 | |||
528 | /** |
||
529 | * Checks whether the class has a (mapped) field with a certain name. |
||
530 | * |
||
531 | * @param $fieldName |
||
532 | * @return boolean |
||
533 | */ |
||
534 | public function hasField($fieldName) |
||
535 | { |
||
536 | return isset($this->fieldMappings[$fieldName]); |
||
537 | } |
||
538 | |||
539 | /** |
||
540 | * Registers a custom repository class for the document class. |
||
541 | * |
||
542 | * @param string $repositoryClassName The class name of the custom mapper. |
||
543 | */ |
||
544 | public function setCustomRepositoryClass($repositoryClassName) |
||
545 | { |
||
546 | $this->customRepositoryClassName = $repositoryClassName; |
||
547 | } |
||
548 | |||
549 | /** |
||
550 | * The name of this Document class. |
||
551 | * |
||
552 | * @return string $name The Document class name. |
||
553 | */ |
||
554 | public function getName() |
||
555 | { |
||
556 | return $this->name; |
||
557 | } |
||
558 | |||
559 | /** |
||
560 | * The namespace this Document class belongs to. |
||
561 | * |
||
562 | * @return string $namespace The namespace name. |
||
563 | */ |
||
564 | public function getNamespace() |
||
565 | { |
||
566 | return $this->namespace; |
||
567 | } |
||
568 | |||
569 | /** |
||
570 | * Set the field that will contain attachments of this document. |
||
571 | * |
||
572 | * @param string $fieldName |
||
573 | * @throws MappingException |
||
574 | */ |
||
575 | public function mapAttachments($fieldName) |
||
576 | { |
||
577 | if (isset($this->fieldMappings[$fieldName]) || isset($this->associationsMappings[$fieldName])) { |
||
578 | throw MappingException::duplicateFieldMapping($this->name, $fieldName); |
||
579 | } |
||
580 | |||
581 | $this->hasAttachments = true; |
||
582 | $this->attachmentField = $fieldName; |
||
583 | } |
||
584 | |||
585 | /** |
||
586 | * Map an embedded object |
||
587 | * |
||
588 | * - fieldName - The name of the property/field on the mapped php class |
||
589 | * - jsonName - JSON key name of this field in CouchDB. |
||
590 | * - targetDocument - Name of the target document |
||
591 | * - embedded - one or many embedded objects? |
||
592 | * |
||
593 | * @param array $mapping |
||
594 | */ |
||
595 | public function mapEmbedded(array $mapping) |
||
596 | { |
||
597 | $mapping = $this->validateAndCompleteReferenceMapping($mapping); |
||
598 | |||
599 | $this->mapField($mapping); |
||
600 | } |
||
601 | |||
602 | /** |
||
603 | * Map a field. |
||
604 | * |
||
605 | * - type - The Doctrine Type of this field. |
||
606 | * - fieldName - The name of the property/field on the mapped php class |
||
607 | * - jsonName - JSON key name of this field in CouchDB. |
||
608 | * - name - The JSON key of this field in the CouchDB document |
||
609 | * - id - True for an ID field. |
||
610 | * - strategy - ID Generator strategy when the field is an id-field. |
||
611 | * - indexed - Is this field indexed for the Doctrine CouchDB repository view |
||
612 | * - isVersionField - Is this field containing the revision number of this document? |
||
613 | * |
||
614 | * @param array $mapping The mapping information. |
||
615 | */ |
||
616 | public function mapField(array $mapping) |
||
617 | { |
||
618 | $mapping = $this->validateAndCompleteFieldMapping($mapping); |
||
619 | |||
620 | if (!isset($mapping['type'])) { |
||
621 | $mapping['type'] = "mixed"; |
||
622 | } |
||
623 | |||
624 | if (isset($mapping['id']) && $mapping['id'] === true) { |
||
625 | $mapping['type'] = 'string'; |
||
626 | $mapping['jsonName'] = '_id'; |
||
627 | $this->setIdentifier($mapping['fieldName']); |
||
628 | if (isset($mapping['strategy'])) { |
||
629 | $this->idGenerator = constant('Doctrine\ODM\CouchDB\Mapping\ClassMetadata::IDGENERATOR_' . strtoupper($mapping['strategy'])); |
||
630 | unset($mapping['strategy']); |
||
631 | } |
||
632 | } else if (isset($mapping['isVersionField'])) { |
||
633 | $this->isVersioned = true; |
||
634 | $this->versionField = $mapping['fieldName']; |
||
635 | } |
||
636 | |||
637 | $mapping = $this->checkAndStoreIndexMapping($mapping); |
||
638 | |||
639 | $this->fieldMappings[$mapping['fieldName']] = $mapping; |
||
640 | $this->jsonNames[$mapping['jsonName']] = $mapping['fieldName']; |
||
641 | } |
||
642 | |||
643 | protected function validateAndCompleteFieldMapping($mapping) |
||
644 | { |
||
645 | if ( ! isset($mapping['fieldName']) || !$mapping['fieldName']) { |
||
646 | throw new MappingException("Mapping a property requires to specify the name."); |
||
647 | } |
||
648 | if ( ! isset($mapping['jsonName'])) { |
||
649 | $mapping['jsonName'] = $mapping['fieldName']; |
||
650 | } |
||
651 | if (isset($this->fieldMappings[$mapping['fieldName']]) || isset($this->associationsMappings[$mapping['fieldName']])) { |
||
652 | throw MappingException::duplicateFieldMapping($this->name, $mapping['fieldName']); |
||
653 | } |
||
654 | |||
655 | return $mapping; |
||
656 | } |
||
657 | |||
658 | protected function validateAndCompleteReferenceMapping($mapping) |
||
659 | { |
||
660 | if (isset($mapping['targetDocument']) && $mapping['targetDocument'] && strpos($mapping['targetDocument'], '\\') === false && strlen($this->namespace)) { |
||
661 | $mapping['targetDocument'] = $this->namespace . '\\' . $mapping['targetDocument']; |
||
662 | } |
||
663 | return $mapping; |
||
664 | } |
||
665 | |||
666 | protected function validateAndCompleteAssociationMapping($mapping) |
||
667 | { |
||
668 | $mapping = $this->validateAndCompleteFieldMapping($mapping); |
||
669 | |||
670 | $mapping['sourceDocument'] = $this->name; |
||
671 | $mapping = $this->validateAndCompleteReferenceMapping($mapping); |
||
672 | return $mapping; |
||
673 | } |
||
674 | |||
675 | View Code Duplication | public function mapManyToOne($mapping) |
|
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...
|
|||
676 | { |
||
677 | $mapping = $this->validateAndCompleteAssociationMapping($mapping); |
||
678 | |||
679 | $mapping['isOwning'] = true; |
||
680 | $mapping['type'] = self::MANY_TO_ONE; |
||
681 | |||
682 | $mapping = $this->checkAndStoreIndexMapping($mapping); |
||
683 | |||
684 | $this->storeAssociationMapping($mapping); |
||
685 | } |
||
686 | |||
687 | View Code Duplication | public function mapManyToMany($mapping) |
|
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...
|
|||
688 | { |
||
689 | $mapping = $this->validateAndCompleteAssociationMapping($mapping); |
||
690 | |||
691 | $mapping['isOwning'] = empty($mapping['mappedBy']); |
||
692 | $mapping['type'] = self::MANY_TO_MANY; |
||
693 | |||
694 | $this->storeAssociationMapping($mapping); |
||
695 | } |
||
696 | |||
697 | private function checkAndStoreIndexMapping($mapping) |
||
698 | { |
||
699 | if (isset($mapping['indexed']) && $mapping['indexed']) { |
||
700 | $this->indexes[] = $mapping['fieldName']; |
||
701 | } |
||
702 | unset($mapping['indexed']); |
||
703 | |||
704 | return $mapping; |
||
705 | } |
||
706 | |||
707 | private function storeAssociationMapping($mapping) |
||
708 | { |
||
709 | $this->associationsMappings[$mapping['fieldName']] = $mapping; |
||
710 | $this->jsonNames[$mapping['jsonName']] = $mapping['fieldName']; |
||
711 | } |
||
712 | |||
713 | /** |
||
714 | * A numerically indexed list of field names of this persistent class. |
||
715 | * |
||
716 | * This array includes identifier fields if present on this class. |
||
717 | * |
||
718 | * @return array |
||
719 | */ |
||
720 | public function getFieldNames() |
||
721 | { |
||
722 | return array_keys($this->fieldMappings); |
||
723 | } |
||
724 | |||
725 | /** |
||
726 | * Gets the mapping of a field. |
||
727 | * |
||
728 | * @param string $fieldName The field name. |
||
729 | * @return array The field mapping. |
||
730 | * @throws MappingException |
||
731 | */ |
||
732 | public function getFieldMapping($fieldName) |
||
733 | { |
||
734 | if ( ! isset($this->fieldMappings[$fieldName])) { |
||
735 | throw MappingException::mappingNotFound($this->name, $fieldName); |
||
736 | } |
||
737 | return $this->fieldMappings[$fieldName]; |
||
738 | } |
||
739 | |||
740 | /** |
||
741 | * Gets the type of a field. |
||
742 | * |
||
743 | * @param string $fieldName |
||
744 | * @return Type |
||
745 | */ |
||
746 | public function getTypeOfField($fieldName) |
||
747 | { |
||
748 | return isset($this->fieldMappings[$fieldName]) ? |
||
749 | $this->fieldMappings[$fieldName]['type'] : null; |
||
750 | } |
||
751 | |||
752 | /** |
||
753 | * Checks if the given field is a mapped association for this class. |
||
754 | * |
||
755 | * @param string $fieldName |
||
756 | * @return boolean |
||
757 | */ |
||
758 | public function hasAssociation($fieldName) |
||
759 | { |
||
760 | return isset($this->associationsMappings[$fieldName]); |
||
761 | } |
||
762 | |||
763 | public function isCollectionValuedAssociation($name) |
||
764 | { |
||
765 | // TODO: included @EmbedMany here also? |
||
766 | return isset($this->associationsMappings[$name]) && ($this->associationsMappings[$name]['type'] & self::TO_MANY); |
||
767 | } |
||
768 | |||
769 | /** |
||
770 | * Checks if the given field is a mapped single valued association for this class. |
||
771 | * |
||
772 | * @param string $fieldName |
||
773 | * @return boolean |
||
774 | */ |
||
775 | public function isSingleValuedAssociation($fieldName) |
||
776 | { |
||
777 | return isset($this->associationsMappings[$fieldName]) && |
||
778 | ($this->associationsMappings[$fieldName]['type'] & self::TO_ONE); |
||
779 | } |
||
780 | |||
781 | /** |
||
782 | * A numerically indexed list of association names of this persistent class. |
||
783 | * |
||
784 | * This array includes identifier associations if present on this class. |
||
785 | * |
||
786 | * @return array |
||
787 | */ |
||
788 | public function getAssociationNames() |
||
789 | { |
||
790 | return array_keys($this->associationsMappings); |
||
791 | } |
||
792 | |||
793 | /** |
||
794 | * Returns the target class name of the given association. |
||
795 | * |
||
796 | * @param string $assocName |
||
797 | * @return string |
||
798 | * @throws \InvalidArgumentException |
||
799 | */ |
||
800 | public function getAssociationTargetClass($assocName) |
||
801 | { |
||
802 | if (!isset($this->associationsMappings[$assocName])) { |
||
803 | throw new \InvalidArgumentException("Association name expected, '" . $assocName ."' is not an association."); |
||
804 | } |
||
805 | return $this->associationsMappings[$assocName]['targetDocument']; |
||
806 | } |
||
807 | |||
808 | /** |
||
809 | * {@inheritDoc} |
||
810 | */ |
||
811 | public function getAssociationMappedByTargetField($assocName) |
||
812 | { |
||
813 | return $this->associationsMappings[$assocName]['mappedBy']; |
||
814 | } |
||
815 | |||
816 | /** |
||
817 | * {@inheritDoc} |
||
818 | */ |
||
819 | public function isAssociationInverseSide($assocName) |
||
820 | { |
||
821 | return isset($this->associationsMappings[$assocName]) && ! $this->associationsMappings[$assocName]; |
||
822 | } |
||
823 | |||
824 | public function isInheritedField($field) |
||
825 | { |
||
826 | return isset($this->fieldMappings[$field]['declared']); |
||
827 | } |
||
828 | |||
829 | public function isInheritedAssociation($field) |
||
830 | { |
||
831 | return isset($this->associationsMappings[$field]['declared']); |
||
832 | } |
||
833 | |||
834 | public function setParentClasses($classes) |
||
835 | { |
||
836 | $this->parentClasses = $classes; |
||
837 | $this->inInheritanceHierachy = true; |
||
838 | if (count($classes) > 0) { |
||
839 | $this->rootDocumentName = array_pop($classes); |
||
840 | } |
||
841 | } |
||
842 | |||
843 | public function markInheritanceRoot() |
||
844 | { |
||
845 | if ($this->parentClasses) { |
||
846 | throw MappingException::invalidInheritanceRoot($this->name, $this->parentClasses); |
||
847 | } |
||
848 | $this->inInheritanceHierachy = true; |
||
849 | } |
||
850 | |||
851 | /** |
||
852 | * Initializes a new ClassMetadata instance that will hold the object-relational mapping |
||
853 | * metadata of the class with the given name. |
||
854 | * |
||
855 | * @param \Doctrine\Common\Persistence\Mapping\ReflectionService $reflService The reflection service. |
||
856 | * |
||
857 | * @return void |
||
858 | */ |
||
859 | public function initializeReflection($reflService) |
||
860 | { |
||
861 | $this->reflClass = $reflService->getClass($this->name); |
||
862 | $this->namespace = $reflService->getClassNamespace($this->name); |
||
863 | |||
864 | if ($this->reflClass) { |
||
865 | $this->name = $this->rootDocumentName = $this->reflClass->getName(); |
||
866 | } |
||
867 | } |
||
868 | } |
||
869 | |||
870 |
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.