vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadataFactory.php line 175
<?phpdeclare(strict_types=1);namespace Doctrine\ODM\MongoDB\Mapping;use Doctrine\Common\EventManager;use Doctrine\ODM\MongoDB\Configuration;use Doctrine\ODM\MongoDB\ConfigurationException;use Doctrine\ODM\MongoDB\DocumentManager;use Doctrine\ODM\MongoDB\Event\LoadClassMetadataEventArgs;use Doctrine\ODM\MongoDB\Event\OnClassMetadataNotFoundEventArgs;use Doctrine\ODM\MongoDB\Events;use Doctrine\ODM\MongoDB\Id\AlnumGenerator;use Doctrine\ODM\MongoDB\Id\AutoGenerator;use Doctrine\ODM\MongoDB\Id\IdGenerator;use Doctrine\ODM\MongoDB\Id\IncrementGenerator;use Doctrine\ODM\MongoDB\Id\UuidGenerator;use Doctrine\Persistence\Mapping\AbstractClassMetadataFactory;use Doctrine\Persistence\Mapping\ClassMetadata as ClassMetadataInterface;use Doctrine\Persistence\Mapping\Driver\MappingDriver;use Doctrine\Persistence\Mapping\ReflectionService;use ReflectionException;use function assert;use function get_class;use function get_class_methods;use function in_array;use function interface_exists;use function trigger_deprecation;use function ucfirst;/*** The ClassMetadataFactory is used to create ClassMetadata objects that contain all the* metadata mapping informations of a class which describes how a class should be mapped* to a document database.** @internal** @method list<ClassMetadata> getAllMetadata()* @method ClassMetadata[] getLoadedMetadata()* @method ClassMetadata getMetadataFor($className)*/final class ClassMetadataFactory extends AbstractClassMetadataFactory{/** @var string */protected $cacheSalt = '$MONGODBODMCLASSMETADATA';/** @var DocumentManager The DocumentManager instance */private $dm;/** @var Configuration The Configuration instance */private $config;/** @var MappingDriver The used metadata driver. */private $driver;/** @var EventManager The event manager instance */private $evm;public function setDocumentManager(DocumentManager $dm): void{$this->dm = $dm;}public function setConfiguration(Configuration $config): void{$this->config = $config;}/*** Lazy initialization of this stuff, especially the metadata driver,* since these are not needed at all when a metadata cache is active.*/protected function initialize(): void{$driver = $this->config->getMetadataDriverImpl();if ($driver === null) {throw ConfigurationException::noMetadataDriverConfigured();}$this->driver = $driver;$this->evm = $this->dm->getEventManager();$this->initialized = true;}/*** @param string $className*/protected function onNotFoundMetadata($className){if (! $this->evm->hasListeners(Events::onClassMetadataNotFound)) {return null;}$eventArgs = new OnClassMetadataNotFoundEventArgs($className, $this->dm);$this->evm->dispatchEvent(Events::onClassMetadataNotFound, $eventArgs);return $eventArgs->getFoundMetadata();}/*** @deprecated** @param string $namespaceAlias* @param string $simpleClassName*/protected function getFqcnFromAlias($namespaceAlias, $simpleClassName): string{return $this->config->getDocumentNamespace($namespaceAlias) . '\\' . $simpleClassName;}protected function getDriver(): MappingDriver{return $this->driver;}protected function wakeupReflection(ClassMetadataInterface $class, ReflectionService $reflService): void{}protected function initializeReflection(ClassMetadataInterface $class, ReflectionService $reflService): void{}protected function isEntity(ClassMetadataInterface $class): bool{assert($class instanceof ClassMetadata);return ! $class->isMappedSuperclass && ! $class->isEmbeddedDocument && ! $class->isQueryResultDocument && ! $class->isView();}/*** @param bool $rootEntityFound*/protected function doLoadMetadata($class, $parent, $rootEntityFound, array $nonSuperclassParents = []): void{assert($class instanceof ClassMetadata);if ($parent instanceof ClassMetadata) {$class->setInheritanceType($parent->inheritanceType);$class->setDiscriminatorField($parent->discriminatorField);$class->setDiscriminatorMap($parent->discriminatorMap);$class->setDefaultDiscriminatorValue($parent->defaultDiscriminatorValue);$class->setIdGeneratorType($parent->generatorType);$this->addInheritedFields($class, $parent);$this->addInheritedRelations($class, $parent);$this->addInheritedIndexes($class, $parent);$this->setInheritedShardKey($class, $parent);$class->setIdentifier($parent->identifier);$class->setVersioned($parent->isVersioned);$class->setVersionField($parent->versionField);$class->setLifecycleCallbacks($parent->lifecycleCallbacks);$class->setAlsoLoadMethods($parent->alsoLoadMethods);$class->setChangeTrackingPolicy($parent->changeTrackingPolicy);$class->setReadPreference($parent->readPreference, $parent->readPreferenceTags);$class->setWriteConcern($parent->writeConcern);if ($parent->isMappedSuperclass) {$class->setCustomRepositoryClass($parent->customRepositoryClassName);}if ($parent->isFile) {$class->isFile = true;$class->setBucketName($parent->bucketName);if ($parent->chunkSizeBytes !== null) {$class->setChunkSizeBytes($parent->chunkSizeBytes);}}}// Invoke drivertry {$this->driver->loadMetadataForClass($class->getName(), $class);} catch (ReflectionException $e) {throw MappingException::reflectionFailure($class->getName(), $e);}$this->validateIdentifier($class);if ($parent instanceof ClassMetadata && $rootEntityFound && $parent->generatorType === $class->generatorType) {if ($parent->generatorType) {$class->setIdGeneratorType($parent->generatorType);}if ($parent->generatorOptions) {$class->setIdGeneratorOptions($parent->generatorOptions);}if ($parent->idGenerator) {$class->setIdGenerator($parent->idGenerator);}} else {$this->completeIdGeneratorMapping($class);}if ($parent instanceof ClassMetadata && $parent->isInheritanceTypeSingleCollection()) {$class->setDatabase($parent->getDatabase());$class->setCollection($parent->getCollection());}$class->setParentClasses($nonSuperclassParents);if (! $this->evm->hasListeners(Events::loadClassMetadata)) {return;}$eventArgs = new LoadClassMetadataEventArgs($class, $this->dm);$this->evm->dispatchEvent(Events::loadClassMetadata, $eventArgs);// phpcs:ignore SlevomatCodingStandard.ControlStructures.EarlyExit.EarlyExitNotUsedif ($class->isChangeTrackingNotify()) {trigger_deprecation('doctrine/mongodb-odm','2.4','NOTIFY tracking policy used in class "%s" is deprecated. Please use DEFERRED_EXPLICIT instead.',$class->name);}}/*** Validates the identifier mapping.** @throws MappingException*/protected function validateIdentifier(ClassMetadata $class): void{if (! $class->identifier && $this->isEntity($class)) {throw MappingException::identifierRequired($class->name);}}protected function newClassMetadataInstance($className): ClassMetadata{return new ClassMetadata($className);}private function completeIdGeneratorMapping(ClassMetadata $class): void{$idGenOptions = $class->generatorOptions;switch ($class->generatorType) {case ClassMetadata::GENERATOR_TYPE_AUTO:$class->setIdGenerator(new AutoGenerator());break;case ClassMetadata::GENERATOR_TYPE_INCREMENT:$incrementGenerator = new IncrementGenerator();if (isset($idGenOptions['key'])) {$incrementGenerator->setKey((string) $idGenOptions['key']);}if (isset($idGenOptions['collection'])) {$incrementGenerator->setCollection((string) $idGenOptions['collection']);}if (isset($idGenOptions['startingId'])) {$incrementGenerator->setStartingId((int) $idGenOptions['startingId']);}$class->setIdGenerator($incrementGenerator);break;case ClassMetadata::GENERATOR_TYPE_UUID:$uuidGenerator = new UuidGenerator();if (isset($idGenOptions['salt'])) {$uuidGenerator->setSalt((string) $idGenOptions['salt']);}$class->setIdGenerator($uuidGenerator);break;case ClassMetadata::GENERATOR_TYPE_ALNUM:$alnumGenerator = new AlnumGenerator();if (isset($idGenOptions['pad'])) {$alnumGenerator->setPad((int) $idGenOptions['pad']);}if (isset($idGenOptions['chars'])) {$alnumGenerator->setChars((string) $idGenOptions['chars']);} elseif (isset($idGenOptions['awkwardSafe'])) {$alnumGenerator->setAwkwardSafeMode((bool) $idGenOptions['awkwardSafe']);}$class->setIdGenerator($alnumGenerator);break;case ClassMetadata::GENERATOR_TYPE_CUSTOM:if (empty($idGenOptions['class'])) {throw MappingException::missingIdGeneratorClass($class->name);}$customGenerator = new $idGenOptions['class']();unset($idGenOptions['class']);if (! $customGenerator instanceof IdGenerator) {throw MappingException::classIsNotAValidGenerator(get_class($customGenerator));}$methods = get_class_methods($customGenerator);foreach ($idGenOptions as $name => $value) {$method = 'set' . ucfirst($name);if (! in_array($method, $methods)) {throw MappingException::missingGeneratorSetter(get_class($customGenerator), $name);}$customGenerator->$method($value);}$class->setIdGenerator($customGenerator);break;case ClassMetadata::GENERATOR_TYPE_NONE:break;default:throw new MappingException('Unknown generator type: ' . $class->generatorType);}}/*** Adds inherited fields to the subclass mapping.*/private function addInheritedFields(ClassMetadata $subClass, ClassMetadata $parentClass): void{foreach ($parentClass->fieldMappings as $fieldName => $mapping) {if (! isset($mapping['inherited']) && ! $parentClass->isMappedSuperclass) {$mapping['inherited'] = $parentClass->name;}if (! isset($mapping['declared'])) {$mapping['declared'] = $parentClass->name;}$subClass->addInheritedFieldMapping($mapping);}foreach ($parentClass->reflFields as $name => $field) {$subClass->reflFields[$name] = $field;}}/*** Adds inherited association mappings to the subclass mapping.** @throws MappingException*/private function addInheritedRelations(ClassMetadata $subClass, ClassMetadata $parentClass): void{foreach ($parentClass->associationMappings as $field => $mapping) {if ($parentClass->isMappedSuperclass) {$mapping['sourceDocument'] = $subClass->name;}if (! isset($mapping['inherited']) && ! $parentClass->isMappedSuperclass) {$mapping['inherited'] = $parentClass->name;}if (! isset($mapping['declared'])) {$mapping['declared'] = $parentClass->name;}$subClass->addInheritedAssociationMapping($mapping);}}/*** Adds inherited indexes to the subclass mapping.*/private function addInheritedIndexes(ClassMetadata $subClass, ClassMetadata $parentClass): void{foreach ($parentClass->indexes as $index) {$subClass->addIndex($index['keys'], $index['options']);}}/*** Adds inherited shard key to the subclass mapping.*/private function setInheritedShardKey(ClassMetadata $subClass, ClassMetadata $parentClass): void{if (! $parentClass->isSharded()) {return;}$subClass->setShardKey($parentClass->shardKey['keys'],$parentClass->shardKey['options']);}}interface_exists(ClassMetadataInterface::class);interface_exists(ReflectionService::class);