PluginProbe ʕ •ᴥ•ʔ
MailPoet – Newsletters, Email Marketing, and Automation / 5.36.0
MailPoet – Newsletters, Email Marketing, and Automation v5.36.0
5.36.0 5.35.1 5.35.0 5.34.3 5.34.2 5.34.1 5.34.0 5.33.1 5.33.0 5.32.0 5.31.0 5.30.0 5.29.0 5.28.1 5.28.0 5.27.0 5.26.0 5.26.1 5.25.0 5.24.0 4.43.0 4.43.1 4.44.0 4.44.1 4.45.0 4.46.0 4.47.0 4.48.0 4.48.1 4.48.2 4.49.0 4.49.1 4.5.0 4.5.1 4.5.2 4.50.0 4.50.1 4.51.0 4.51.1 4.51.2 4.52.0 4.53.0 4.54.0 4.55.0 4.56.0 4.57.0 4.58.0 4.58.1 4.58.2 4.6.0 4.6.1 4.6.2 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 5.0.0 5.0.1 5.0.2 5.1.0 5.1.1 5.10.0 5.10.1 5.11.0 5.12.0 5.12.1 5.12.10 5.12.11 5.12.12 5.12.13 5.12.2 5.12.3 5.12.4 5.12.5 5.12.6 5.12.7 5.12.8 5.12.9 5.13.0 5.13.1 5.13.2 5.14.0 5.14.1 5.14.2 5.14.3 5.15.0 5.15.1 5.16.0 5.16.1 5.16.2 5.16.3 5.16.4 5.17.0 5.17.1 5.17.2 5.17.3 5.17.4 5.17.5 5.17.6 5.18.0 5.19.0 5.2.0 5.2.1 5.2.2 5.2.3 5.20.0 5.21.0 5.21.1 5.21.2 5.21.3 5.22.0 5.22.1 5.22.2 5.22.3 5.22.4 5.23.0 5.23.1 5.23.2 5.3.0 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.3.7 5.4.0 5.4.1 5.4.2 5.5.0 5.5.1 5.5.2 5.6.0 5.6.1 5.6.2 5.6.3 5.6.4 5.7.0 5.7.1 5.8.0 5.8.1 5.9.0 3.0.0-beta.15 3.7.1 3.0.0-beta.16 3.7.2 3.0.0-beta.17 3.7.3 3.0.0-beta.18 3.7.4 3.0.0-beta.19 3.7.5 3.0.0-beta.2 3.7.6 3.0.0-beta.20 3.7.8 3.0.0-beta.21 3.70.0 3.0.0-beta.22 3.71.0 3.0.0-beta.23 3.71.1 3.0.0-beta.23.1 3.71.2 3.0.0-beta.23.2 3.71.3 3.0.0-beta.24 3.72.0 3.0.0-beta.25 3.73.0 3.0.0-beta.26 3.73.1 3.0.0-beta.27 3.73.2 3.0.0-beta.28 3.74.0 3.0.0-beta.29 3.74.1 3.0.0-beta.3 3.74.2 3.0.0-beta.30 3.74.3 3.0.0-beta.31 3.75.0 3.0.0-beta.32 3.75.1 3.0.0-beta.33 3.76.0 3.0.0-beta.33.1 3.77.0 3.0.0-beta.34.0.0 3.77.1 3.0.0-beta.36.0.0 3.78.0 3.0.0-beta.36.0.1 3.79.0 3.0.0-beta.36.2.0 3.8 3.0.0-beta.36.3.0 3.8.1 3.0.0-beta.36.3.1 3.8.2 3.0.0-beta.37.0.0 3.8.3 3.0.0-beta.4 3.8.4 3.0.0-beta.5 3.8.5 3.0.0-beta.6 3.8.6 3.0.0-beta.7 3.80.0 3.0.0-beta.7.1 3.81.0 3.0.0-beta.8 3.82.0 3.0.0-beta.9 3.83.0 3.0.0-rc.1.0.0 3.84.0 3.0.0-rc.1.0.1 3.84.1 3.0.0-rc.1.0.2 3.85.0 3.0.0-rc.1.0.3 3.85.1 3.0.0-rc.1.0.4 3.86.0 3.0.0-rc.2.0.0 3.87.0 3.0.0-rc.2.0.1 3.87.1 3.0.0-rc.2.0.2 3.87.2 3.0.0-rc.2.0.3 3.88.0 3.0.1 3.88.1 3.0.2 3.88.2 3.0.3 3.89.0 3.0.4 3.89.1 3.0.5 3.89.2 3.0.6 3.89.3 3.0.7 3.89.4 3.0.8 3.9.0 3.0.9 3.9.1 3.1.0 3.90.0 3.10 3.90.1 3.10.1 3.90.2 3.100.0 3.91.0 3.100.1 3.91.1 3.100.2 3.92.0 3.101.0 3.92.1 3.101.1 3.93.0 3.102.0 3.93.1 3.102.1 3.94.0 3.103.0 3.95.0 3.103.1 3.95.1 3.11.0 3.96.0 3.11.1 3.96.1 3.11.2 3.97.0 3.11.3 3.98.0 3.11.4 3.98.1 3.11.5 3.99.0 3.12.0 3.99.1 3.12.1 4.0.0 3.13.0 4.0.1 3.14.0 4.1.0 3.14.1 4.1.1 3.15.0 4.10.0 3.16.0 4.11.0 3.16.1 4.11.1 3.16.2 4.12.0 3.16.3 4.12.1 3.17.0 4.12.2 3.17.1 4.13.0 3.17.2 4.14.0 3.18.0 4.15.0 3.18.1 4.16.0 3.18.2 4.17.0 3.19.0 4.17.1 3.19.1 4.18.0 3.19.2 4.18.1 3.19.3 4.19.0 3.2.0 4.2.0 3.2.1 4.20.0 3.2.2 4.20.1 3.2.3 4.20.2 3.2.4 4.21.0 3.2.5 4.22.0 3.20.0 4.22.1 3.21.0 4.22.2 3.21.1 4.23.0 3.22.0 4.24.0 3.23.0 4.25.0 3.23.1 4.26.0 3.23.2 4.26.1 3.24.0 4.27.0 3.25.0 4.28.0 3.25.1 4.29.0 3.26.0 4.3.0 3.26.1 4.3.1 3.27.0 4.30.0 3.28.0 4.31.0 3.29.0 4.31.1 3.3.0 4.32.0 3.3.1 4.33.0 3.3.2 4.34.0 3.3.3 4.35.0 3.3.4 4.35.1 3.3.5 4.36.0 3.3.6 4.37.0 3.30.0 4.38.0 3.31.0 4.39.0 3.31.1 4.4.0 3.32.0 4.40.0 3.32.1 4.41.0 3.32.2 4.41.1 3.33.0 4.41.2 3.34.0 4.41.3 3.34.1 4.42.0 3.34.2 4.42.1 3.34.3 3.34.4 3.35.0 3.35.1 3.35.3 3.35.4 3.36.0 3.37.0 3.37.1 3.37.2 3.37.3 3.38.0 3.38.1 3.39.0 3.39.1 3.39.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.40.0 3.40.1 3.41.0 3.41.1 3.41.2 3.42.0 3.42.1 3.42.2 3.42.3 3.43.0 3.43.1 3.44.0 3.45.0 3.45.1 3.46.0 3.46.1 3.46.10 3.46.11 3.46.12 3.46.13 3.46.14 3.46.2 3.46.3 3.46.4 3.46.5 3.46.6 3.46.7 3.46.8 3.46.9 3.47.0 3.47.1 3.47.10 3.47.11 3.47.2 3.47.3 3.47.5 3.47.6 3.47.7 3.47.9 3.48.0 3.48.1 3.49.0 3.49.1 3.5.0 3.5.1 3.50.0 3.51.0 3.51.1 3.51.2 3.52.0 3.53.0 3.54.0 3.54.1 3.54.2 3.54.3 3.55.0 3.55.1 3.56.0 3.56.1 3.56.2 3.57.0 3.57.1 3.58.0 3.59.0 3.59.1 3.59.2 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.60.0 3.60.1 3.60.10 3.60.11 3.60.12 3.60.2 3.60.3 3.60.4 3.60.6 3.60.7 3.60.8 3.60.9 3.61.0 3.62.0 3.62.1 3.63.0 3.64.0 3.64.1 3.64.2 3.64.3 3.65.0 trunk 3.65.1 3.0.0 3.66.0 3.0.0-beta.1 3.67.0 3.0.0-beta.10 3.67.1 3.0.0-beta.11 3.68.0 3.0.0-beta.12 3.69.0 3.0.0-beta.13 3.69.1 3.0.0-beta.14 3.7.0
mailpoet / vendor-prefixed / doctrine / orm / src / Mapping / ClassMetadataFactory.php
mailpoet / vendor-prefixed / doctrine / orm / src / Mapping Last commit date
Builder 9 months ago Driver 9 months ago Exception 9 months ago Reflection 9 months ago Annotation.php 9 months ago AnsiQuoteStrategy.php 9 months ago AssociationOverride.php 9 months ago AssociationOverrides.php 9 months ago AttributeOverride.php 9 months ago AttributeOverrides.php 9 months ago Cache.php 9 months ago ChainTypedFieldMapper.php 9 months ago ChangeTrackingPolicy.php 9 months ago ClassMetadata.php 9 months ago ClassMetadataFactory.php 9 months ago ClassMetadataInfo.php 9 months ago Column.php 9 months ago ColumnResult.php 9 months ago CustomIdGenerator.php 9 months ago DefaultEntityListenerResolver.php 9 months ago DefaultNamingStrategy.php 9 months ago DefaultQuoteStrategy.php 9 months ago DefaultTypedFieldMapper.php 9 months ago DiscriminatorColumn.php 9 months ago DiscriminatorMap.php 9 months ago Embeddable.php 9 months ago Embedded.php 9 months ago Entity.php 9 months ago EntityListenerResolver.php 9 months ago EntityListeners.php 9 months ago EntityResult.php 9 months ago FieldResult.php 9 months ago GeneratedValue.php 9 months ago HasLifecycleCallbacks.php 9 months ago Id.php 9 months ago Index.php 9 months ago InheritanceType.php 9 months ago InverseJoinColumn.php 9 months ago JoinColumn.php 9 months ago JoinColumnProperties.php 9 months ago JoinColumns.php 9 months ago JoinTable.php 9 months ago ManyToMany.php 9 months ago ManyToOne.php 9 months ago MappedSuperclass.php 9 months ago MappingAttribute.php 9 months ago MappingException.php 9 months ago NamedNativeQueries.php 9 months ago NamedNativeQuery.php 9 months ago NamedQueries.php 9 months ago NamedQuery.php 9 months ago NamingStrategy.php 9 months ago OneToMany.php 9 months ago OneToOne.php 9 months ago OrderBy.php 9 months ago PostLoad.php 9 months ago PostPersist.php 9 months ago PostRemove.php 9 months ago PostUpdate.php 9 months ago PreFlush.php 9 months ago PrePersist.php 9 months ago PreRemove.php 9 months ago PreUpdate.php 9 months ago QuoteStrategy.php 9 months ago ReflectionEmbeddedProperty.php 9 months ago ReflectionEnumProperty.php 9 months ago ReflectionReadonlyProperty.php 9 months ago SequenceGenerator.php 9 months ago SqlResultSetMapping.php 9 months ago SqlResultSetMappings.php 9 months ago Table.php 9 months ago TypedFieldMapper.php 9 months ago UnderscoreNamingStrategy.php 9 months ago UniqueConstraint.php 9 months ago Version.php 9 months ago
ClassMetadataFactory.php
546 lines
1 <?php
2 declare (strict_types=1);
3 namespace MailPoetVendor\Doctrine\ORM\Mapping;
4 if (!defined('ABSPATH')) exit;
5 use MailPoetVendor\Doctrine\Common\EventManager;
6 use MailPoetVendor\Doctrine\DBAL\Platforms;
7 use MailPoetVendor\Doctrine\DBAL\Platforms\AbstractPlatform;
8 use MailPoetVendor\Doctrine\DBAL\Platforms\MySQLPlatform;
9 use MailPoetVendor\Doctrine\DBAL\Platforms\SqlitePlatform;
10 use MailPoetVendor\Doctrine\DBAL\Platforms\SQLServerPlatform;
11 use MailPoetVendor\Doctrine\Deprecations\Deprecation;
12 use MailPoetVendor\Doctrine\ORM\EntityManagerInterface;
13 use MailPoetVendor\Doctrine\ORM\Event\LoadClassMetadataEventArgs;
14 use MailPoetVendor\Doctrine\ORM\Event\OnClassMetadataNotFoundEventArgs;
15 use MailPoetVendor\Doctrine\ORM\Events;
16 use MailPoetVendor\Doctrine\ORM\Exception\ORMException;
17 use MailPoetVendor\Doctrine\ORM\Id\AssignedGenerator;
18 use MailPoetVendor\Doctrine\ORM\Id\BigIntegerIdentityGenerator;
19 use MailPoetVendor\Doctrine\ORM\Id\IdentityGenerator;
20 use MailPoetVendor\Doctrine\ORM\Id\SequenceGenerator;
21 use MailPoetVendor\Doctrine\ORM\Id\UuidGenerator;
22 use MailPoetVendor\Doctrine\ORM\Mapping\Exception\CannotGenerateIds;
23 use MailPoetVendor\Doctrine\ORM\Mapping\Exception\InvalidCustomGenerator;
24 use MailPoetVendor\Doctrine\ORM\Mapping\Exception\UnknownGeneratorType;
25 use MailPoetVendor\Doctrine\ORM\Proxy\DefaultProxyClassNameResolver;
26 use MailPoetVendor\Doctrine\Persistence\Mapping\AbstractClassMetadataFactory;
27 use MailPoetVendor\Doctrine\Persistence\Mapping\ClassMetadata as ClassMetadataInterface;
28 use MailPoetVendor\Doctrine\Persistence\Mapping\Driver\MappingDriver;
29 use MailPoetVendor\Doctrine\Persistence\Mapping\ReflectionService;
30 use ReflectionClass;
31 use ReflectionException;
32 use function assert;
33 use function class_exists;
34 use function count;
35 use function end;
36 use function explode;
37 use function get_class;
38 use function in_array;
39 use function is_a;
40 use function is_subclass_of;
41 use function str_contains;
42 use function strlen;
43 use function strtolower;
44 use function substr;
45 class ClassMetadataFactory extends AbstractClassMetadataFactory
46 {
47 private $em;
48 private $targetPlatform;
49 private $driver;
50 private $evm;
51 private $embeddablesActiveNesting = [];
52 private const NON_IDENTITY_DEFAULT_STRATEGY = ['MailPoetVendor\\Doctrine\\DBAL\\Platforms\\PostgreSqlPlatform' => ClassMetadata::GENERATOR_TYPE_SEQUENCE, Platforms\OraclePlatform::class => ClassMetadata::GENERATOR_TYPE_SEQUENCE, Platforms\PostgreSQLPlatform::class => ClassMetadata::GENERATOR_TYPE_SEQUENCE];
53 public function setEntityManager(EntityManagerInterface $em)
54 {
55 parent::setProxyClassNameResolver(new DefaultProxyClassNameResolver());
56 $this->em = $em;
57 }
58 protected function initialize()
59 {
60 $this->driver = $this->em->getConfiguration()->getMetadataDriverImpl();
61 $this->evm = $this->em->getEventManager();
62 $this->initialized = \true;
63 }
64 protected function onNotFoundMetadata($className)
65 {
66 if (!$this->evm->hasListeners(Events::onClassMetadataNotFound)) {
67 return null;
68 }
69 $eventArgs = new OnClassMetadataNotFoundEventArgs($className, $this->em);
70 $this->evm->dispatchEvent(Events::onClassMetadataNotFound, $eventArgs);
71 $classMetadata = $eventArgs->getFoundMetadata();
72 assert($classMetadata instanceof ClassMetadata || $classMetadata === null);
73 return $classMetadata;
74 }
75 protected function doLoadMetadata($class, $parent, $rootEntityFound, array $nonSuperclassParents)
76 {
77 if ($parent) {
78 $class->setInheritanceType($parent->inheritanceType);
79 $class->setDiscriminatorColumn($parent->discriminatorColumn);
80 $class->setIdGeneratorType($parent->generatorType);
81 $this->addInheritedFields($class, $parent);
82 $this->addInheritedRelations($class, $parent);
83 $this->addInheritedEmbeddedClasses($class, $parent);
84 $class->setIdentifier($parent->identifier);
85 $class->setVersioned($parent->isVersioned);
86 $class->setVersionField($parent->versionField);
87 $class->setDiscriminatorMap($parent->discriminatorMap);
88 $class->addSubClasses($parent->subClasses);
89 $class->setLifecycleCallbacks($parent->lifecycleCallbacks);
90 $class->setChangeTrackingPolicy($parent->changeTrackingPolicy);
91 if (!empty($parent->customGeneratorDefinition)) {
92 $class->setCustomGeneratorDefinition($parent->customGeneratorDefinition);
93 }
94 if ($parent->isMappedSuperclass) {
95 $class->setCustomRepositoryClass($parent->customRepositoryClassName);
96 }
97 }
98 // Invoke driver
99 try {
100 $this->driver->loadMetadataForClass($class->getName(), $class);
101 } catch (ReflectionException $e) {
102 throw MappingException::reflectionFailure($class->getName(), $e);
103 }
104 // If this class has a parent the id generator strategy is inherited.
105 // However this is only true if the hierarchy of parents contains the root entity,
106 // if it consists of mapped superclasses these don't necessarily include the id field.
107 if ($parent && $rootEntityFound) {
108 $this->inheritIdGeneratorMapping($class, $parent);
109 } else {
110 $this->completeIdGeneratorMapping($class);
111 }
112 if (!$class->isMappedSuperclass) {
113 if ($rootEntityFound && $class->isInheritanceTypeNone()) {
114 Deprecation::trigger('doctrine/orm', 'https://github.com/doctrine/orm/pull/10431', "Entity class '%s' is a subclass of the root entity class '%s', but no inheritance mapping type was declared. This is a misconfiguration and will be an error in Doctrine ORM 3.0.", $class->name, end($nonSuperclassParents));
115 }
116 foreach ($class->embeddedClasses as $property => $embeddableClass) {
117 if (isset($embeddableClass['inherited'])) {
118 continue;
119 }
120 if (isset($this->embeddablesActiveNesting[$embeddableClass['class']])) {
121 throw MappingException::infiniteEmbeddableNesting($class->name, $property);
122 }
123 $this->embeddablesActiveNesting[$class->name] = \true;
124 $embeddableMetadata = $this->getMetadataFor($embeddableClass['class']);
125 if ($embeddableMetadata->isEmbeddedClass) {
126 $this->addNestedEmbeddedClasses($embeddableMetadata, $class, $property);
127 }
128 $identifier = $embeddableMetadata->getIdentifier();
129 if (!empty($identifier)) {
130 $this->inheritIdGeneratorMapping($class, $embeddableMetadata);
131 }
132 $class->inlineEmbeddable($property, $embeddableMetadata);
133 unset($this->embeddablesActiveNesting[$class->name]);
134 }
135 }
136 if ($parent) {
137 if ($parent->isInheritanceTypeSingleTable()) {
138 $class->setPrimaryTable($parent->table);
139 }
140 $this->addInheritedIndexes($class, $parent);
141 if ($parent->cache) {
142 $class->cache = $parent->cache;
143 }
144 if ($parent->containsForeignIdentifier) {
145 $class->containsForeignIdentifier = \true;
146 }
147 if ($parent->containsEnumIdentifier) {
148 $class->containsEnumIdentifier = \true;
149 }
150 if (!empty($parent->namedQueries)) {
151 $this->addInheritedNamedQueries($class, $parent);
152 }
153 if (!empty($parent->namedNativeQueries)) {
154 $this->addInheritedNamedNativeQueries($class, $parent);
155 }
156 if (!empty($parent->sqlResultSetMappings)) {
157 $this->addInheritedSqlResultSetMappings($class, $parent);
158 }
159 if (!empty($parent->entityListeners) && empty($class->entityListeners)) {
160 $class->entityListeners = $parent->entityListeners;
161 }
162 }
163 $class->setParentClasses($nonSuperclassParents);
164 if ($class->isRootEntity() && !$class->isInheritanceTypeNone() && !$class->discriminatorMap) {
165 $this->addDefaultDiscriminatorMap($class);
166 }
167 // During the following event, there may also be updates to the discriminator map as per GH-1257/GH-8402.
168 // So, we must not discover the missing subclasses before that.
169 if ($this->evm->hasListeners(Events::loadClassMetadata)) {
170 $eventArgs = new LoadClassMetadataEventArgs($class, $this->em);
171 $this->evm->dispatchEvent(Events::loadClassMetadata, $eventArgs);
172 }
173 $this->findAbstractEntityClassesNotListedInDiscriminatorMap($class);
174 if ($class->changeTrackingPolicy === ClassMetadata::CHANGETRACKING_NOTIFY) {
175 Deprecation::trigger('doctrine/orm', 'https://github.com/doctrine/orm/issues/8383', 'NOTIFY Change Tracking policy used in "%s" is deprecated, use deferred explicit instead.', $class->name);
176 }
177 $this->validateRuntimeMetadata($class, $parent);
178 }
179 protected function validateRuntimeMetadata($class, $parent)
180 {
181 if (!$class->reflClass) {
182 // only validate if there is a reflection class instance
183 return;
184 }
185 $class->validateIdentifier();
186 $class->validateAssociations();
187 $class->validateLifecycleCallbacks($this->getReflectionService());
188 // verify inheritance
189 if (!$class->isMappedSuperclass && !$class->isInheritanceTypeNone()) {
190 if (!$parent) {
191 if (count($class->discriminatorMap) === 0) {
192 throw MappingException::missingDiscriminatorMap($class->name);
193 }
194 if (!$class->discriminatorColumn) {
195 throw MappingException::missingDiscriminatorColumn($class->name);
196 }
197 foreach ($class->subClasses as $subClass) {
198 if ((new ReflectionClass($subClass))->name !== $subClass) {
199 throw MappingException::invalidClassInDiscriminatorMap($subClass, $class->name);
200 }
201 }
202 } else {
203 assert($parent instanceof ClassMetadataInfo);
204 // https://github.com/doctrine/orm/issues/8746
205 if (!$class->reflClass->isAbstract() && !in_array($class->name, $class->discriminatorMap, \true)) {
206 throw MappingException::mappedClassNotPartOfDiscriminatorMap($class->name, $class->rootEntityName);
207 }
208 }
209 } elseif ($class->isMappedSuperclass && $class->name === $class->rootEntityName && (count($class->discriminatorMap) || $class->discriminatorColumn)) {
210 // second condition is necessary for mapped superclasses in the middle of an inheritance hierarchy
211 throw MappingException::noInheritanceOnMappedSuperClass($class->name);
212 }
213 }
214 protected function newClassMetadataInstance($className)
215 {
216 return new ClassMetadata($className, $this->em->getConfiguration()->getNamingStrategy(), $this->em->getConfiguration()->getTypedFieldMapper());
217 }
218 private function addDefaultDiscriminatorMap(ClassMetadata $class) : void
219 {
220 $allClasses = $this->driver->getAllClassNames();
221 $fqcn = $class->getName();
222 $map = [$this->getShortName($class->name) => $fqcn];
223 $duplicates = [];
224 foreach ($allClasses as $subClassCandidate) {
225 if (is_subclass_of($subClassCandidate, $fqcn)) {
226 $shortName = $this->getShortName($subClassCandidate);
227 if (isset($map[$shortName])) {
228 $duplicates[] = $shortName;
229 }
230 $map[$shortName] = $subClassCandidate;
231 }
232 }
233 if ($duplicates) {
234 throw MappingException::duplicateDiscriminatorEntry($class->name, $duplicates, $map);
235 }
236 $class->setDiscriminatorMap($map);
237 }
238 private function findAbstractEntityClassesNotListedInDiscriminatorMap(ClassMetadata $rootEntityClass) : void
239 {
240 // Only root classes in inheritance hierarchies need contain a discriminator map,
241 // so skip for other classes.
242 if (!$rootEntityClass->isRootEntity() || $rootEntityClass->isInheritanceTypeNone()) {
243 return;
244 }
245 $processedClasses = [$rootEntityClass->name => \true];
246 foreach ($rootEntityClass->subClasses as $knownSubClass) {
247 $processedClasses[$knownSubClass] = \true;
248 }
249 foreach ($rootEntityClass->discriminatorMap as $declaredClassName) {
250 // This fetches non-transient parent classes only
251 $parentClasses = $this->getParentClasses($declaredClassName);
252 foreach ($parentClasses as $parentClass) {
253 if (isset($processedClasses[$parentClass])) {
254 continue;
255 }
256 $processedClasses[$parentClass] = \true;
257 // All non-abstract entity classes must be listed in the discriminator map, and
258 // this will be validated/enforced at runtime (possibly at a later time, when the
259 // subclass is loaded, but anyways). Also, subclasses is about entity classes only.
260 // That means we can ignore non-abstract classes here. The (expensive) driver
261 // check for mapped superclasses need only be run for abstract candidate classes.
262 if (!(new ReflectionClass($parentClass))->isAbstract() || $this->peekIfIsMappedSuperclass($parentClass)) {
263 continue;
264 }
265 // We have found a non-transient, non-mapped-superclass = an entity class (possibly abstract, but that does not matter)
266 $rootEntityClass->addSubClass($parentClass);
267 }
268 }
269 }
270 private function peekIfIsMappedSuperclass(string $className) : bool
271 {
272 $reflService = $this->getReflectionService();
273 $class = $this->newClassMetadataInstance($className);
274 $this->initializeReflection($class, $reflService);
275 $this->driver->loadMetadataForClass($className, $class);
276 return $class->isMappedSuperclass;
277 }
278 private function getShortName(string $className) : string
279 {
280 if (!str_contains($className, '\\')) {
281 return strtolower($className);
282 }
283 $parts = explode('\\', $className);
284 return strtolower(end($parts));
285 }
286 private function addMappingInheritanceInformation(array &$mapping, ClassMetadata $parentClass) : void
287 {
288 if (!isset($mapping['inherited']) && !$parentClass->isMappedSuperclass) {
289 $mapping['inherited'] = $parentClass->name;
290 }
291 if (!isset($mapping['declared'])) {
292 $mapping['declared'] = $parentClass->name;
293 }
294 }
295 private function addInheritedFields(ClassMetadata $subClass, ClassMetadata $parentClass) : void
296 {
297 foreach ($parentClass->fieldMappings as $mapping) {
298 $this->addMappingInheritanceInformation($mapping, $parentClass);
299 $subClass->addInheritedFieldMapping($mapping);
300 }
301 foreach ($parentClass->reflFields as $name => $field) {
302 $subClass->reflFields[$name] = $field;
303 }
304 }
305 private function addInheritedRelations(ClassMetadata $subClass, ClassMetadata $parentClass) : void
306 {
307 foreach ($parentClass->associationMappings as $field => $mapping) {
308 $this->addMappingInheritanceInformation($mapping, $parentClass);
309 // When the class inheriting the relation ($subClass) is the first entity class since the
310 // relation has been defined in a mapped superclass (or in a chain
311 // of mapped superclasses) above, then declare this current entity class as the source of
312 // the relationship.
313 // According to the definitions given in https://github.com/doctrine/orm/pull/10396/,
314 // this is the case <=> ! isset($mapping['inherited']).
315 if (!isset($mapping['inherited'])) {
316 $mapping['sourceEntity'] = $subClass->name;
317 }
318 $subClass->addInheritedAssociationMapping($mapping);
319 }
320 }
321 private function addInheritedEmbeddedClasses(ClassMetadata $subClass, ClassMetadata $parentClass) : void
322 {
323 foreach ($parentClass->embeddedClasses as $field => $embeddedClass) {
324 $this->addMappingInheritanceInformation($embeddedClass, $parentClass);
325 $subClass->embeddedClasses[$field] = $embeddedClass;
326 }
327 }
328 private function addNestedEmbeddedClasses(ClassMetadata $subClass, ClassMetadata $parentClass, string $prefix) : void
329 {
330 foreach ($subClass->embeddedClasses as $property => $embeddableClass) {
331 if (isset($embeddableClass['inherited'])) {
332 continue;
333 }
334 $embeddableMetadata = $this->getMetadataFor($embeddableClass['class']);
335 $parentClass->mapEmbedded(['fieldName' => $prefix . '.' . $property, 'class' => $embeddableMetadata->name, 'columnPrefix' => $embeddableClass['columnPrefix'], 'declaredField' => $embeddableClass['declaredField'] ? $prefix . '.' . $embeddableClass['declaredField'] : $prefix, 'originalField' => $embeddableClass['originalField'] ?: $property]);
336 }
337 }
338 private function addInheritedIndexes(ClassMetadata $subClass, ClassMetadata $parentClass) : void
339 {
340 if (!$parentClass->isMappedSuperclass) {
341 return;
342 }
343 foreach (['uniqueConstraints', 'indexes'] as $indexType) {
344 if (isset($parentClass->table[$indexType])) {
345 foreach ($parentClass->table[$indexType] as $indexName => $index) {
346 if (isset($subClass->table[$indexType][$indexName])) {
347 continue;
348 // Let the inheriting table override indices
349 }
350 $subClass->table[$indexType][$indexName] = $index;
351 }
352 }
353 }
354 }
355 private function addInheritedNamedQueries(ClassMetadata $subClass, ClassMetadata $parentClass) : void
356 {
357 foreach ($parentClass->namedQueries as $name => $query) {
358 if (!isset($subClass->namedQueries[$name])) {
359 // @phpstan-ignore method.deprecated
360 $subClass->addNamedQuery(['name' => $query['name'], 'query' => $query['query']]);
361 }
362 }
363 }
364 private function addInheritedNamedNativeQueries(ClassMetadata $subClass, ClassMetadata $parentClass) : void
365 {
366 foreach ($parentClass->namedNativeQueries as $name => $query) {
367 if (!isset($subClass->namedNativeQueries[$name])) {
368 // @phpstan-ignore method.deprecated
369 $subClass->addNamedNativeQuery(['name' => $query['name'], 'query' => $query['query'], 'isSelfClass' => $query['isSelfClass'], 'resultSetMapping' => $query['resultSetMapping'], 'resultClass' => $query['isSelfClass'] ? $subClass->name : $query['resultClass']]);
370 }
371 }
372 }
373 private function addInheritedSqlResultSetMappings(ClassMetadata $subClass, ClassMetadata $parentClass) : void
374 {
375 foreach ($parentClass->sqlResultSetMappings as $name => $mapping) {
376 if (!isset($subClass->sqlResultSetMappings[$name])) {
377 $entities = [];
378 foreach ($mapping['entities'] as $entity) {
379 $entities[] = ['fields' => $entity['fields'], 'isSelfClass' => $entity['isSelfClass'], 'discriminatorColumn' => $entity['discriminatorColumn'], 'entityClass' => $entity['isSelfClass'] ? $subClass->name : $entity['entityClass']];
380 }
381 $subClass->addSqlResultSetMapping(['name' => $mapping['name'], 'columns' => $mapping['columns'], 'entities' => $entities]);
382 }
383 }
384 }
385 private function completeIdGeneratorMapping(ClassMetadataInfo $class) : void
386 {
387 $idGenType = $class->generatorType;
388 if ($idGenType === ClassMetadata::GENERATOR_TYPE_AUTO) {
389 $class->setIdGeneratorType($this->determineIdGeneratorStrategy($this->getTargetPlatform()));
390 }
391 // Create & assign an appropriate ID generator instance
392 switch ($class->generatorType) {
393 case ClassMetadata::GENERATOR_TYPE_IDENTITY:
394 $sequenceName = null;
395 $fieldName = $class->identifier ? $class->getSingleIdentifierFieldName() : null;
396 $platform = $this->getTargetPlatform();
397 // Platforms that do not have native IDENTITY support need a sequence to emulate this behaviour.
398 // @phpstan-ignore method.deprecated
399 if (!$platform instanceof MySQLPlatform && !$platform instanceof SqlitePlatform && !$platform instanceof SQLServerPlatform && $platform->usesSequenceEmulatedIdentityColumns()) {
400 Deprecation::trigger('doctrine/orm', 'https://github.com/doctrine/orm/issues/8850', <<<'DEPRECATION'
401 Context: Loading metadata for class %s
402 Problem: Using identity columns emulated with a sequence is deprecated and will not be possible in Doctrine ORM 3.0.
403 Solution: Use the SEQUENCE generator strategy instead.
404 DEPRECATION
405 , $class->name, get_class($this->getTargetPlatform()));
406 $columnName = $class->getSingleIdentifierColumnName();
407 $quoted = isset($class->fieldMappings[$fieldName]['quoted']) || isset($class->table['quoted']);
408 $sequencePrefix = $class->getSequencePrefix($this->getTargetPlatform());
409 // @phpstan-ignore method.deprecated
410 $sequenceName = $this->getTargetPlatform()->getIdentitySequenceName($sequencePrefix, $columnName);
411 $definition = ['sequenceName' => $this->truncateSequenceName($sequenceName)];
412 if ($quoted) {
413 $definition['quoted'] = \true;
414 }
415 $sequenceName = $this->em->getConfiguration()->getQuoteStrategy()->getSequenceName($definition, $class, $this->getTargetPlatform());
416 }
417 $generator = $fieldName && $class->fieldMappings[$fieldName]['type'] === 'bigint' ? new BigIntegerIdentityGenerator($sequenceName) : new IdentityGenerator($sequenceName);
418 $class->setIdGenerator($generator);
419 break;
420 case ClassMetadata::GENERATOR_TYPE_SEQUENCE:
421 // If there is no sequence definition yet, create a default definition
422 $definition = $class->sequenceGeneratorDefinition;
423 if (!$definition) {
424 $fieldName = $class->getSingleIdentifierFieldName();
425 $sequenceName = $class->getSequenceName($this->getTargetPlatform());
426 $quoted = isset($class->fieldMappings[$fieldName]['quoted']) || isset($class->table['quoted']);
427 $definition = ['sequenceName' => $this->truncateSequenceName($sequenceName), 'allocationSize' => 1, 'initialValue' => 1];
428 if ($quoted) {
429 $definition['quoted'] = \true;
430 }
431 $class->setSequenceGeneratorDefinition($definition);
432 }
433 $sequenceGenerator = new SequenceGenerator($this->em->getConfiguration()->getQuoteStrategy()->getSequenceName($definition, $class, $this->getTargetPlatform()), (int) $definition['allocationSize']);
434 $class->setIdGenerator($sequenceGenerator);
435 break;
436 case ClassMetadata::GENERATOR_TYPE_NONE:
437 $class->setIdGenerator(new AssignedGenerator());
438 break;
439 // @phpstan-ignore classConstant.deprecated
440 case ClassMetadata::GENERATOR_TYPE_UUID:
441 Deprecation::trigger('doctrine/orm', 'https://github.com/doctrine/orm/issues/7312', 'Mapping for %s: the "UUID" id generator strategy is deprecated with no replacement', $class->name);
442 // @phpstan-ignore method.deprecatedClass, new.deprecatedClass
443 $class->setIdGenerator(new UuidGenerator());
444 break;
445 case ClassMetadata::GENERATOR_TYPE_CUSTOM:
446 $definition = $class->customGeneratorDefinition;
447 if ($definition === null) {
448 throw InvalidCustomGenerator::onClassNotConfigured();
449 }
450 if (!class_exists($definition['class'])) {
451 throw InvalidCustomGenerator::onMissingClass($definition);
452 }
453 $class->setIdGenerator(new $definition['class']());
454 break;
455 default:
456 throw UnknownGeneratorType::create($class->generatorType);
457 }
458 }
459 private function determineIdGeneratorStrategy(AbstractPlatform $platform) : int
460 {
461 assert($this->em !== null);
462 foreach ($this->em->getConfiguration()->getIdentityGenerationPreferences() as $platformFamily => $strategy) {
463 if (is_a($platform, $platformFamily)) {
464 return $strategy;
465 }
466 }
467 foreach (self::NON_IDENTITY_DEFAULT_STRATEGY as $platformFamily => $strategy) {
468 if (is_a($platform, $platformFamily)) {
469 if ($platform instanceof Platforms\PostgreSQLPlatform || is_a($platform, 'MailPoetVendor\\Doctrine\\DBAL\\Platforms\\PostgreSqlPlatform')) {
470 Deprecation::trigger('doctrine/orm', 'https://github.com/doctrine/orm/issues/8893', <<<'DEPRECATION'
471 Relying on non-optimal defaults for ID generation is deprecated, and IDENTITY
472 results in SERIAL, which is not recommended.
473 Instead, configure identifier generation strategies explicitly through
474 configuration.
475 We currently recommend "SEQUENCE" for "%s", so you should use
476 $configuration->setIdentityGenerationPreferences([
477 "%s" => ClassMetadata::GENERATOR_TYPE_SEQUENCE,
478 ]);
479 DEPRECATION
480 , $platformFamily, $platformFamily);
481 }
482 return $strategy;
483 }
484 }
485 if ($platform->supportsIdentityColumns()) {
486 return ClassMetadata::GENERATOR_TYPE_IDENTITY;
487 }
488 if ($platform->supportsSequences()) {
489 return ClassMetadata::GENERATOR_TYPE_SEQUENCE;
490 }
491 throw CannotGenerateIds::withPlatform($platform);
492 }
493 private function truncateSequenceName(string $schemaElementName) : string
494 {
495 $platform = $this->getTargetPlatform();
496 if (!$platform instanceof Platforms\OraclePlatform && !$platform instanceof Platforms\SQLAnywherePlatform) {
497 return $schemaElementName;
498 }
499 $maxIdentifierLength = $platform->getMaxIdentifierLength();
500 if (strlen($schemaElementName) > $maxIdentifierLength) {
501 return substr($schemaElementName, 0, $maxIdentifierLength);
502 }
503 return $schemaElementName;
504 }
505 private function inheritIdGeneratorMapping(ClassMetadataInfo $class, ClassMetadataInfo $parent) : void
506 {
507 if ($parent->isIdGeneratorSequence()) {
508 $class->setSequenceGeneratorDefinition($parent->sequenceGeneratorDefinition);
509 }
510 if ($parent->generatorType) {
511 $class->setIdGeneratorType($parent->generatorType);
512 }
513 if ($parent->idGenerator) {
514 $class->setIdGenerator($parent->idGenerator);
515 }
516 }
517 protected function wakeupReflection(ClassMetadataInterface $class, ReflectionService $reflService)
518 {
519 $class->wakeupReflection($reflService);
520 }
521 protected function initializeReflection(ClassMetadataInterface $class, ReflectionService $reflService)
522 {
523 $class->initializeReflection($reflService);
524 }
525 protected function getFqcnFromAlias($namespaceAlias, $simpleClassName)
526 {
527 $classString = $this->em->getConfiguration()->getEntityNamespace($namespaceAlias) . '\\' . $simpleClassName;
528 return $classString;
529 }
530 protected function getDriver()
531 {
532 return $this->driver;
533 }
534 protected function isEntity(ClassMetadataInterface $class)
535 {
536 return !$class->isMappedSuperclass;
537 }
538 private function getTargetPlatform() : Platforms\AbstractPlatform
539 {
540 if (!$this->targetPlatform) {
541 $this->targetPlatform = $this->em->getConnection()->getDatabasePlatform();
542 }
543 return $this->targetPlatform;
544 }
545 }
546