summaryrefslogtreecommitdiff
path: root/vendor/doctrine/orm/src/Mapping/MappingException.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/doctrine/orm/src/Mapping/MappingException.php')
-rw-r--r--vendor/doctrine/orm/src/Mapping/MappingException.php691
1 files changed, 691 insertions, 0 deletions
diff --git a/vendor/doctrine/orm/src/Mapping/MappingException.php b/vendor/doctrine/orm/src/Mapping/MappingException.php
new file mode 100644
index 0000000..9b73242
--- /dev/null
+++ b/vendor/doctrine/orm/src/Mapping/MappingException.php
@@ -0,0 +1,691 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\ORM\Mapping;
6
7use BackedEnum;
8use Doctrine\ORM\Exception\ORMException;
9use Doctrine\Persistence\Mapping\MappingException as PersistenceMappingException;
10use LibXMLError;
11use ReflectionException;
12use ValueError;
13
14use function array_keys;
15use function array_map;
16use function array_values;
17use function get_debug_type;
18use function get_parent_class;
19use function implode;
20use function sprintf;
21
22use const PHP_EOL;
23
24/**
25 * A MappingException indicates that something is wrong with the mapping setup.
26 */
27class MappingException extends PersistenceMappingException implements ORMException
28{
29 /** @param class-string $entityName */
30 public static function identifierRequired(string $entityName): self
31 {
32 $parent = get_parent_class($entityName);
33 if ($parent !== false) {
34 return new self(sprintf(
35 'No identifier/primary key specified for Entity "%s" sub class of "%s". Every Entity must have an identifier/primary key.',
36 $entityName,
37 $parent,
38 ));
39 }
40
41 return new self(sprintf(
42 'No identifier/primary key specified for Entity "%s". Every Entity must have an identifier/primary key.',
43 $entityName,
44 ));
45 }
46
47 public static function invalidAssociationType(string $entityName, string $fieldName, int $type): self
48 {
49 return new self(sprintf(
50 'The association "%s#%s" must be of type "ClassMetadata::ONE_TO_MANY", "ClassMetadata::MANY_TO_MANY" or "ClassMetadata::MANY_TO_ONE", "%d" given.',
51 $entityName,
52 $fieldName,
53 $type,
54 ));
55 }
56
57 public static function invalidInheritanceType(string $entityName, int $type): self
58 {
59 return new self(sprintf("The inheritance type '%s' specified for '%s' does not exist.", $type, $entityName));
60 }
61
62 public static function generatorNotAllowedWithCompositeId(): self
63 {
64 return new self("Id generators can't be used with a composite id.");
65 }
66
67 public static function missingFieldName(string $entity): self
68 {
69 return new self(sprintf(
70 "The field or association mapping misses the 'fieldName' attribute in entity '%s'.",
71 $entity,
72 ));
73 }
74
75 public static function missingTargetEntity(string $fieldName): self
76 {
77 return new self(sprintf("The association mapping '%s' misses the 'targetEntity' attribute.", $fieldName));
78 }
79
80 public static function missingSourceEntity(string $fieldName): self
81 {
82 return new self(sprintf("The association mapping '%s' misses the 'sourceEntity' attribute.", $fieldName));
83 }
84
85 public static function missingEmbeddedClass(string $fieldName): self
86 {
87 return new self(sprintf("The embed mapping '%s' misses the 'class' attribute.", $fieldName));
88 }
89
90 public static function mappingFileNotFound(string $entityName, string $fileName): self
91 {
92 return new self(sprintf("No mapping file found named '%s' for class '%s'.", $fileName, $entityName));
93 }
94
95 /**
96 * Exception for invalid property name override.
97 *
98 * @param string $className The entity's name.
99 */
100 public static function invalidOverrideFieldName(string $className, string $fieldName): self
101 {
102 return new self(sprintf("Invalid field override named '%s' for class '%s'.", $fieldName, $className));
103 }
104
105 /**
106 * Exception for invalid property type override.
107 *
108 * @param string $className The entity's name.
109 */
110 public static function invalidOverrideFieldType(string $className, string $fieldName): self
111 {
112 return new self(sprintf(
113 "The column type of attribute '%s' on class '%s' could not be changed.",
114 $fieldName,
115 $className,
116 ));
117 }
118
119 public static function mappingNotFound(string $className, string $fieldName): self
120 {
121 return new self(sprintf("No mapping found for field '%s' on class '%s'.", $fieldName, $className));
122 }
123
124 public static function queryNotFound(string $className, string $queryName): self
125 {
126 return new self(sprintf("No query found named '%s' on class '%s'.", $queryName, $className));
127 }
128
129 public static function resultMappingNotFound(string $className, string $resultName): self
130 {
131 return new self(sprintf("No result set mapping found named '%s' on class '%s'.", $resultName, $className));
132 }
133
134 public static function emptyQueryMapping(string $entity, string $queryName): self
135 {
136 return new self(sprintf('Query named "%s" in "%s" could not be empty.', $queryName, $entity));
137 }
138
139 public static function nameIsMandatoryForQueryMapping(string $className): self
140 {
141 return new self(sprintf("Query name on entity class '%s' is not defined.", $className));
142 }
143
144 public static function missingQueryMapping(string $entity, string $queryName): self
145 {
146 return new self(sprintf(
147 'Query named "%s" in "%s requires a result class or result set mapping.',
148 $queryName,
149 $entity,
150 ));
151 }
152
153 public static function missingResultSetMappingEntity(string $entity, string $resultName): self
154 {
155 return new self(sprintf(
156 'Result set mapping named "%s" in "%s requires a entity class name.',
157 $resultName,
158 $entity,
159 ));
160 }
161
162 public static function missingResultSetMappingFieldName(string $entity, string $resultName): self
163 {
164 return new self(sprintf(
165 'Result set mapping named "%s" in "%s requires a field name.',
166 $resultName,
167 $entity,
168 ));
169 }
170
171 public static function oneToManyRequiresMappedBy(string $entityName, string $fieldName): MappingException
172 {
173 return new self(sprintf(
174 "OneToMany mapping on entity '%s' field '%s' requires the 'mappedBy' attribute.",
175 $entityName,
176 $fieldName,
177 ));
178 }
179
180 public static function joinTableRequired(string $fieldName): self
181 {
182 return new self(sprintf("The mapping of field '%s' requires an the 'joinTable' attribute.", $fieldName));
183 }
184
185 /**
186 * Called if a required option was not found but is required
187 *
188 * @param string $field Which field cannot be processed?
189 * @param string $expectedOption Which option is required
190 * @param string $hint Can optionally be used to supply a tip for common mistakes,
191 * e.g. "Did you think of the plural s?"
192 */
193 public static function missingRequiredOption(string $field, string $expectedOption, string $hint = ''): self
194 {
195 $message = "The mapping of field '" . $field . "' is invalid: The option '" . $expectedOption . "' is required.";
196
197 if (! empty($hint)) {
198 $message .= ' (Hint: ' . $hint . ')';
199 }
200
201 return new self($message);
202 }
203
204 /**
205 * Generic exception for invalid mappings.
206 */
207 public static function invalidMapping(string $fieldName): self
208 {
209 return new self(sprintf("The mapping of field '%s' is invalid.", $fieldName));
210 }
211
212 /**
213 * Exception for reflection exceptions - adds the entity name,
214 * because there might be long classnames that will be shortened
215 * within the stacktrace
216 *
217 * @param string $entity The entity's name
218 */
219 public static function reflectionFailure(string $entity, ReflectionException $previousException): self
220 {
221 return new self(sprintf('An error occurred in %s', $entity), 0, $previousException);
222 }
223
224 public static function joinColumnMustPointToMappedField(string $className, string $joinColumn): self
225 {
226 return new self(sprintf(
227 'The column %s must be mapped to a field in class %s since it is referenced by a join column of another class.',
228 $joinColumn,
229 $className,
230 ));
231 }
232
233 public static function joinColumnNotAllowedOnOneToOneInverseSide(string $className, string $fieldName): self
234 {
235 return new self(sprintf(
236 '%s#%s is a OneToOne inverse side, which does not allow join columns.',
237 $className,
238 $fieldName,
239 ));
240 }
241
242 /** @param class-string $className */
243 public static function classIsNotAValidEntityOrMappedSuperClass(string $className): self
244 {
245 $parent = get_parent_class($className);
246 if ($parent !== false) {
247 return new self(sprintf(
248 'Class "%s" sub class of "%s" is not a valid entity or mapped super class.',
249 $className,
250 $parent,
251 ));
252 }
253
254 return new self(sprintf(
255 'Class "%s" is not a valid entity or mapped super class.',
256 $className,
257 ));
258 }
259
260 /**
261 * @param string $entity The entity's name.
262 * @param string $fieldName The name of the field that was already declared.
263 */
264 public static function duplicateFieldMapping(string $entity, string $fieldName): self
265 {
266 return new self(sprintf(
267 'Property "%s" in "%s" was already declared, but it must be declared only once',
268 $fieldName,
269 $entity,
270 ));
271 }
272
273 public static function duplicateAssociationMapping(string $entity, string $fieldName): self
274 {
275 return new self(sprintf(
276 'Property "%s" in "%s" was already declared, but it must be declared only once',
277 $fieldName,
278 $entity,
279 ));
280 }
281
282 public static function duplicateQueryMapping(string $entity, string $queryName): self
283 {
284 return new self(sprintf(
285 'Query named "%s" in "%s" was already declared, but it must be declared only once',
286 $queryName,
287 $entity,
288 ));
289 }
290
291 public static function duplicateResultSetMapping(string $entity, string $resultName): self
292 {
293 return new self(sprintf(
294 'Result set mapping named "%s" in "%s" was already declared, but it must be declared only once',
295 $resultName,
296 $entity,
297 ));
298 }
299
300 public static function singleIdNotAllowedOnCompositePrimaryKey(string $entity): self
301 {
302 return new self('Single id is not allowed on composite primary key in entity ' . $entity);
303 }
304
305 public static function noIdDefined(string $entity): self
306 {
307 return new self('No ID defined for entity ' . $entity);
308 }
309
310 public static function unsupportedOptimisticLockingType(string $entity, string $fieldName, string $unsupportedType): self
311 {
312 return new self(sprintf(
313 'Locking type "%s" (specified in "%s", field "%s") is not supported by Doctrine.',
314 $unsupportedType,
315 $entity,
316 $fieldName,
317 ));
318 }
319
320 public static function fileMappingDriversRequireConfiguredDirectoryPath(string|null $path = null): self
321 {
322 if (! empty($path)) {
323 $path = '[' . $path . ']';
324 }
325
326 return new self(
327 'File mapping drivers must have a valid directory path, ' .
328 'however the given path ' . $path . ' seems to be incorrect!',
329 );
330 }
331
332 /**
333 * Returns an exception that indicates that a class used in a discriminator map does not exist.
334 * An example would be an outdated (maybe renamed) classname.
335 *
336 * @param string $className The class that could not be found
337 * @param string $owningClass The class that declares the discriminator map.
338 */
339 public static function invalidClassInDiscriminatorMap(string $className, string $owningClass): self
340 {
341 return new self(sprintf(
342 "Entity class '%s' used in the discriminator map of class '%s' " .
343 'does not exist.',
344 $className,
345 $owningClass,
346 ));
347 }
348
349 /**
350 * @param string[] $entries
351 * @param array<string,string> $map
352 */
353 public static function duplicateDiscriminatorEntry(string $className, array $entries, array $map): self
354 {
355 return new self(
356 'The entries ' . implode(', ', $entries) . " in discriminator map of class '" . $className . "' is duplicated. " .
357 'If the discriminator map is automatically generated you have to convert it to an explicit discriminator map now. ' .
358 'The entries of the current map are: @DiscriminatorMap({' . implode(', ', array_map(
359 static fn ($a, $b) => sprintf("'%s': '%s'", $a, $b),
360 array_keys($map),
361 array_values($map),
362 )) . '})',
363 );
364 }
365
366 /**
367 * @param class-string $rootEntityClass
368 * @param class-string $childEntityClass
369 */
370 public static function missingInheritanceTypeDeclaration(string $rootEntityClass, string $childEntityClass): self
371 {
372 return new self(sprintf(
373 "Entity class '%s' is a subclass of the root entity class '%s', but no inheritance mapping type was declared.",
374 $childEntityClass,
375 $rootEntityClass,
376 ));
377 }
378
379 public static function missingDiscriminatorMap(string $className): self
380 {
381 return new self(sprintf(
382 "Entity class '%s' is using inheritance but no discriminator map was defined.",
383 $className,
384 ));
385 }
386
387 public static function missingDiscriminatorColumn(string $className): self
388 {
389 return new self(sprintf(
390 "Entity class '%s' is using inheritance but no discriminator column was defined.",
391 $className,
392 ));
393 }
394
395 public static function invalidDiscriminatorColumnType(string $className, string $type): self
396 {
397 return new self(sprintf(
398 "Discriminator column type on entity class '%s' is not allowed to be '%s'. 'string' or 'integer' type variables are suggested!",
399 $className,
400 $type,
401 ));
402 }
403
404 public static function nameIsMandatoryForDiscriminatorColumns(string $className): self
405 {
406 return new self(sprintf("Discriminator column name on entity class '%s' is not defined.", $className));
407 }
408
409 public static function cannotVersionIdField(string $className, string $fieldName): self
410 {
411 return new self(sprintf(
412 "Setting Id field '%s' as versionable in entity class '%s' is not supported.",
413 $fieldName,
414 $className,
415 ));
416 }
417
418 public static function duplicateColumnName(string $className, string $columnName): self
419 {
420 return new self("Duplicate definition of column '" . $columnName . "' on entity '" . $className . "' in a field or discriminator column mapping.");
421 }
422
423 public static function illegalToManyAssociationOnMappedSuperclass(string $className, string $field): self
424 {
425 return new self("It is illegal to put an inverse side one-to-many or many-to-many association on mapped superclass '" . $className . '#' . $field . "'.");
426 }
427
428 public static function cannotMapCompositePrimaryKeyEntitiesAsForeignId(string $className, string $targetEntity, string $targetField): self
429 {
430 return new self("It is not possible to map entity '" . $className . "' with a composite primary key " .
431 "as part of the primary key of another entity '" . $targetEntity . '#' . $targetField . "'.");
432 }
433
434 public static function noSingleAssociationJoinColumnFound(string $className, string $field): self
435 {
436 return new self(sprintf("'%s#%s' is not an association with a single join column.", $className, $field));
437 }
438
439 public static function noFieldNameFoundForColumn(string $className, string $column): self
440 {
441 return new self(sprintf(
442 "Cannot find a field on '%s' that is mapped to column '%s'. Either the " .
443 'field does not exist or an association exists but it has multiple join columns.',
444 $className,
445 $column,
446 ));
447 }
448
449 public static function illegalOrphanRemovalOnIdentifierAssociation(string $className, string $field): self
450 {
451 return new self(sprintf(
452 "The orphan removal option is not allowed on an association that is part of the identifier in '%s#%s'.",
453 $className,
454 $field,
455 ));
456 }
457
458 public static function illegalOrphanRemoval(string $className, string $field): self
459 {
460 return new self('Orphan removal is only allowed on one-to-one and one-to-many ' .
461 'associations, but ' . $className . '#' . $field . ' is not.');
462 }
463
464 public static function illegalInverseIdentifierAssociation(string $className, string $field): self
465 {
466 return new self(sprintf(
467 "An inverse association is not allowed to be identifier in '%s#%s'.",
468 $className,
469 $field,
470 ));
471 }
472
473 public static function illegalToManyIdentifierAssociation(string $className, string $field): self
474 {
475 return new self(sprintf(
476 "Many-to-many or one-to-many associations are not allowed to be identifier in '%s#%s'.",
477 $className,
478 $field,
479 ));
480 }
481
482 public static function noInheritanceOnMappedSuperClass(string $className): self
483 {
484 return new self("It is not supported to define inheritance information on a mapped superclass '" . $className . "'.");
485 }
486
487 public static function mappedClassNotPartOfDiscriminatorMap(string $className, string $rootClassName): self
488 {
489 return new self(
490 "Entity '" . $className . "' has to be part of the discriminator map of '" . $rootClassName . "' " .
491 "to be properly mapped in the inheritance hierarchy. Alternatively you can make '" . $className . "' an abstract class " .
492 'to avoid this exception from occurring.',
493 );
494 }
495
496 public static function lifecycleCallbackMethodNotFound(string $className, string $methodName): self
497 {
498 return new self("Entity '" . $className . "' has no method '" . $methodName . "' to be registered as lifecycle callback.");
499 }
500
501 /** @param class-string $className */
502 public static function illegalLifecycleCallbackOnEmbeddedClass(string $event, string $className): self
503 {
504 return new self(sprintf(
505 <<<'EXCEPTION'
506 Context: Attempt to register lifecycle callback "%s" on embedded class "%s".
507 Problem: Registering lifecycle callbacks on embedded classes is not allowed.
508 EXCEPTION,
509 $event,
510 $className,
511 ));
512 }
513
514 public static function entityListenerClassNotFound(string $listenerName, string $className): self
515 {
516 return new self(sprintf('Entity Listener "%s" declared on "%s" not found.', $listenerName, $className));
517 }
518
519 public static function entityListenerMethodNotFound(string $listenerName, string $methodName, string $className): self
520 {
521 return new self(sprintf('Entity Listener "%s" declared on "%s" has no method "%s".', $listenerName, $className, $methodName));
522 }
523
524 public static function duplicateEntityListener(string $listenerName, string $methodName, string $className): self
525 {
526 return new self(sprintf('Entity Listener "%s#%s()" in "%s" was already declared, but it must be declared only once.', $listenerName, $methodName, $className));
527 }
528
529 /** @param class-string $className */
530 public static function invalidFetchMode(string $className, string $fetchMode): self
531 {
532 return new self("Entity '" . $className . "' has a mapping with invalid fetch mode '" . $fetchMode . "'");
533 }
534
535 public static function invalidGeneratedMode(int|string $generatedMode): self
536 {
537 return new self("Invalid generated mode '" . $generatedMode . "'");
538 }
539
540 public static function compositeKeyAssignedIdGeneratorRequired(string $className): self
541 {
542 return new self("Entity '" . $className . "' has a composite identifier but uses an ID generator other than manually assigning (Identity, Sequence). This is not supported.");
543 }
544
545 public static function invalidTargetEntityClass(string $targetEntity, string $sourceEntity, string $associationName): self
546 {
547 return new self('The target-entity ' . $targetEntity . " cannot be found in '" . $sourceEntity . '#' . $associationName . "'.");
548 }
549
550 /** @param string[] $cascades */
551 public static function invalidCascadeOption(array $cascades, string $className, string $propertyName): self
552 {
553 $cascades = implode(', ', array_map(static fn (string $e): string => "'" . $e . "'", $cascades));
554
555 return new self(sprintf(
556 "You have specified invalid cascade options for %s::$%s: %s; available options: 'remove', 'persist', 'refresh', and 'detach'",
557 $className,
558 $propertyName,
559 $cascades,
560 ));
561 }
562
563 public static function missingSequenceName(string $className): self
564 {
565 return new self(
566 sprintf('Missing "sequenceName" attribute for sequence id generator definition on class "%s".', $className),
567 );
568 }
569
570 public static function infiniteEmbeddableNesting(string $className, string $propertyName): self
571 {
572 return new self(
573 sprintf(
574 'Infinite nesting detected for embedded property %s::%s. ' .
575 'You cannot embed an embeddable from the same type inside an embeddable.',
576 $className,
577 $propertyName,
578 ),
579 );
580 }
581
582 public static function illegalOverrideOfInheritedProperty(string $className, string $propertyName, string $inheritFromClass): self
583 {
584 return new self(
585 sprintf(
586 'Overrides are only allowed for fields or associations declared in mapped superclasses or traits. This is not the case for %s::%s, which was inherited from %s.',
587 $className,
588 $propertyName,
589 $inheritFromClass,
590 ),
591 );
592 }
593
594 public static function invalidIndexConfiguration(string $className, string $indexName): self
595 {
596 return new self(
597 sprintf(
598 'Index %s for entity %s should contain columns or fields values, but not both.',
599 $indexName,
600 $className,
601 ),
602 );
603 }
604
605 public static function invalidUniqueConstraintConfiguration(string $className, string $indexName): self
606 {
607 return new self(
608 sprintf(
609 'Unique constraint %s for entity %s should contain columns or fields values, but not both.',
610 $indexName,
611 $className,
612 ),
613 );
614 }
615
616 public static function invalidOverrideType(string $expectdType, mixed $givenValue): self
617 {
618 return new self(sprintf(
619 'Expected %s, but %s was given.',
620 $expectdType,
621 get_debug_type($givenValue),
622 ));
623 }
624
625 public static function backedEnumTypeRequired(string $className, string $fieldName, string $enumType): self
626 {
627 return new self(sprintf(
628 'Attempting to map a non-backed enum type %s in entity %s::$%s. Please use backed enums only',
629 $enumType,
630 $className,
631 $fieldName,
632 ));
633 }
634
635 public static function nonEnumTypeMapped(string $className, string $fieldName, string $enumType): self
636 {
637 return new self(sprintf(
638 'Attempting to map non-enum type %s as enum in entity %s::$%s',
639 $enumType,
640 $className,
641 $fieldName,
642 ));
643 }
644
645 /**
646 * @param class-string $className
647 * @param class-string<BackedEnum> $enumType
648 */
649 public static function invalidEnumValue(
650 string $className,
651 string $fieldName,
652 string $value,
653 string $enumType,
654 ValueError $previous,
655 ): self {
656 return new self(sprintf(
657 <<<'EXCEPTION'
658Context: Trying to hydrate enum property "%s::$%s"
659Problem: Case "%s" is not listed in enum "%s"
660Solution: Either add the case to the enum type or migrate the database column to use another case of the enum
661EXCEPTION
662 ,
663 $className,
664 $fieldName,
665 $value,
666 $enumType,
667 ), 0, $previous);
668 }
669
670 /** @param LibXMLError[] $errors */
671 public static function fromLibXmlErrors(array $errors): self
672 {
673 $formatter = static fn (LibXMLError $error): string => sprintf(
674 'libxml error: %s in %s at line %d',
675 $error->message,
676 $error->file,
677 $error->line,
678 );
679
680 return new self(implode(PHP_EOL, array_map($formatter, $errors)));
681 }
682
683 public static function invalidAttributeOnEmbeddable(string $entityName, string $attributeName): self
684 {
685 return new self(sprintf(
686 'Attribute "%s" on embeddable "%s" is not allowed.',
687 $attributeName,
688 $entityName,
689 ));
690 }
691}