vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Mapping/Driver/AnnotationDriver.php line 76
<?phpdeclare(strict_types=1);namespace Doctrine\ODM\MongoDB\Mapping\Driver;use Doctrine\Common\Annotations\AnnotationReader;use Doctrine\Common\Annotations\Reader;use Doctrine\ODM\MongoDB\Events;use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;use Doctrine\ODM\MongoDB\Mapping\Annotations\AbstractIndex;use Doctrine\ODM\MongoDB\Mapping\Annotations\ShardKey;use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;use Doctrine\ODM\MongoDB\Mapping\MappingException;use Doctrine\Persistence\Mapping\Driver\ColocatedMappingDriver;use MongoDB\Driver\Exception\UnexpectedValueException;use ReflectionClass;use ReflectionMethod;use function array_merge;use function array_replace;use function assert;use function class_exists;use function constant;use function count;use function get_class;use function interface_exists;use function is_array;use function MongoDB\BSON\fromJSON;use function MongoDB\BSON\toPHP;use function trigger_deprecation;/*** The AnnotationDriver reads the mapping metadata from docblock annotations.*/class AnnotationDriver extends CompatibilityAnnotationDriver{use ColocatedMappingDriver;/*** The annotation reader.** @internal this property will be private in 3.0** @var Reader*/protected $reader;/*** Initializes a new AnnotationDriver that uses the given AnnotationReader for reading* docblock annotations.** @param Reader $reader The AnnotationReader to use, duck-typed.* @param string|string[]|null $paths One or multiple paths where mapping classes can be found.*/public function __construct($reader, $paths = null){$this->reader = $reader;$this->addPaths((array) $paths);}public function isTransient($className){$classAnnotations = $this->reader->getClassAnnotations(new ReflectionClass($className));foreach ($classAnnotations as $annot) {if ($annot instanceof ODM\AbstractDocument) {return false;}}return true;}public function loadMetadataForClass($className, \Doctrine\Persistence\Mapping\ClassMetadata $metadata): void{assert($metadata instanceof ClassMetadata);$reflClass = $metadata->getReflectionClass();$classAnnotations = $this->reader->getClassAnnotations($reflClass);$documentAnnot = null;foreach ($classAnnotations as $annot) {$classAnnotations[get_class($annot)] = $annot;if ($annot instanceof ODM\AbstractDocument) {if ($documentAnnot !== null) {throw MappingException::classCanOnlyBeMappedByOneAbstractDocument($className, $documentAnnot, $annot);}$documentAnnot = $annot;}// non-document class annotationsif ($annot instanceof ODM\AbstractIndex) {$this->addIndex($metadata, $annot);}if ($annot instanceof ODM\Indexes) {trigger_deprecation('doctrine/mongodb-odm','2.2','The "@Indexes" annotation used in class "%s" is deprecated. Specify all "@Index" and "@UniqueIndex" annotations on the class.',$className);$value = $annot->value;foreach (is_array($value) ? $value : [$value] as $index) {$this->addIndex($metadata, $index);}} elseif ($annot instanceof ODM\InheritanceType) {$metadata->setInheritanceType(constant(ClassMetadata::class . '::INHERITANCE_TYPE_' . $annot->value));} elseif ($annot instanceof ODM\DiscriminatorField) {$metadata->setDiscriminatorField($annot->value);} elseif ($annot instanceof ODM\DiscriminatorMap) {$value = $annot->value;assert(is_array($value));$metadata->setDiscriminatorMap($value);} elseif ($annot instanceof ODM\DiscriminatorValue) {$metadata->setDiscriminatorValue($annot->value);} elseif ($annot instanceof ODM\ChangeTrackingPolicy) {$metadata->setChangeTrackingPolicy(constant(ClassMetadata::class . '::CHANGETRACKING_' . $annot->value));} elseif ($annot instanceof ODM\DefaultDiscriminatorValue) {$metadata->setDefaultDiscriminatorValue($annot->value);} elseif ($annot instanceof ODM\ReadPreference) {$metadata->setReadPreference($annot->value, $annot->tags ?? []);} elseif ($annot instanceof ODM\Validation) {if (isset($annot->validator)) {try {$validatorBson = fromJSON($annot->validator);} catch (UnexpectedValueException $e) {throw MappingException::schemaValidationError($e->getCode(), $e->getMessage(), $className, 'validator');}$validator = toPHP($validatorBson, []);$metadata->setValidator($validator);}if (isset($annot->action)) {$metadata->setValidationAction($annot->action);}if (isset($annot->level)) {$metadata->setValidationLevel($annot->level);}}}if ($documentAnnot === null) {throw MappingException::classIsNotAValidDocument($className);}if ($documentAnnot instanceof ODM\MappedSuperclass) {$metadata->isMappedSuperclass = true;} elseif ($documentAnnot instanceof ODM\EmbeddedDocument) {$metadata->isEmbeddedDocument = true;} elseif ($documentAnnot instanceof ODM\QueryResultDocument) {$metadata->isQueryResultDocument = true;} elseif ($documentAnnot instanceof ODM\View) {if (! $documentAnnot->rootClass) {throw MappingException::viewWithoutRootClass($className);}if (! class_exists($documentAnnot->rootClass)) {throw MappingException::viewRootClassNotFound($className, $documentAnnot->rootClass);}$metadata->markViewOf($documentAnnot->rootClass);} elseif ($documentAnnot instanceof ODM\File) {$metadata->isFile = true;if ($documentAnnot->chunkSizeBytes !== null) {$metadata->setChunkSizeBytes($documentAnnot->chunkSizeBytes);}}if (isset($documentAnnot->db)) {$metadata->setDatabase($documentAnnot->db);}if (isset($documentAnnot->collection)) {$metadata->setCollection($documentAnnot->collection);}if (isset($documentAnnot->view)) {$metadata->setCollection($documentAnnot->view);}// Store bucketName as collection name for GridFS filesif (isset($documentAnnot->bucketName)) {$metadata->setBucketName($documentAnnot->bucketName);}if (isset($documentAnnot->repositoryClass)) {$metadata->setCustomRepositoryClass($documentAnnot->repositoryClass);}if (isset($documentAnnot->writeConcern)) {$metadata->setWriteConcern($documentAnnot->writeConcern);}if (isset($documentAnnot->indexes) && count($documentAnnot->indexes)) {trigger_deprecation('doctrine/mongodb-odm','2.2','The "indexes" parameter in the "%s" annotation for class "%s" is deprecated. Specify all "@Index" and "@UniqueIndex" annotations on the class.',$className,get_class($documentAnnot));foreach ($documentAnnot->indexes as $index) {$this->addIndex($metadata, $index);}}if (! empty($documentAnnot->readOnly)) {$metadata->markReadOnly();}foreach ($reflClass->getProperties() as $property) {if (($metadata->isMappedSuperclass && ! $property->isPrivate())||($metadata->isInheritedField($property->name) && $property->getDeclaringClass()->name !== $metadata->name)) {continue;}$indexes = [];$mapping = ['fieldName' => $property->getName()];$fieldAnnot = null;foreach ($this->reader->getPropertyAnnotations($property) as $annot) {if ($annot instanceof ODM\AbstractField) {$fieldAnnot = $annot;}if ($annot instanceof ODM\AbstractIndex) {$indexes[] = $annot;}if ($annot instanceof ODM\Indexes) {$value = $annot->value;foreach (is_array($value) ? $value : [$value] as $index) {$indexes[] = $index;}} elseif ($annot instanceof ODM\AlsoLoad) {$mapping['alsoLoadFields'] = (array) $annot->value;} elseif ($annot instanceof ODM\Version) {$mapping['version'] = true;} elseif ($annot instanceof ODM\Lock) {$mapping['lock'] = true;}}if ($fieldAnnot) {$mapping = array_replace($mapping, (array) $fieldAnnot);$metadata->mapField($mapping);}if (! $indexes) {continue;}foreach ($indexes as $index) {$name = $mapping['name'] ?? $mapping['fieldName'];$keys = [$name => $index->order ?: 'asc'];$this->addIndex($metadata, $index, $keys);}}// Set shard key after all fields to ensure we mapped all its keysif (isset($classAnnotations[ShardKey::class])) {assert($classAnnotations[ShardKey::class] instanceof ShardKey);$this->setShardKey($metadata, $classAnnotations[ShardKey::class]);}foreach ($reflClass->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {/* Filter for the declaring class only. Callbacks from parent* classes will already be registered.*/if ($method->getDeclaringClass()->name !== $reflClass->name) {continue;}foreach ($this->reader->getMethodAnnotations($method) as $annot) {if ($annot instanceof ODM\AlsoLoad) {$metadata->registerAlsoLoadMethod($method->getName(), $annot->value);}if (! isset($classAnnotations[ODM\HasLifecycleCallbacks::class])) {continue;}if ($annot instanceof ODM\PrePersist) {$metadata->addLifecycleCallback($method->getName(), Events::prePersist);} elseif ($annot instanceof ODM\PostPersist) {$metadata->addLifecycleCallback($method->getName(), Events::postPersist);} elseif ($annot instanceof ODM\PreUpdate) {$metadata->addLifecycleCallback($method->getName(), Events::preUpdate);} elseif ($annot instanceof ODM\PostUpdate) {$metadata->addLifecycleCallback($method->getName(), Events::postUpdate);} elseif ($annot instanceof ODM\PreRemove) {$metadata->addLifecycleCallback($method->getName(), Events::preRemove);} elseif ($annot instanceof ODM\PostRemove) {$metadata->addLifecycleCallback($method->getName(), Events::postRemove);} elseif ($annot instanceof ODM\PreLoad) {$metadata->addLifecycleCallback($method->getName(), Events::preLoad);} elseif ($annot instanceof ODM\PostLoad) {$metadata->addLifecycleCallback($method->getName(), Events::postLoad);} elseif ($annot instanceof ODM\PreFlush) {$metadata->addLifecycleCallback($method->getName(), Events::preFlush);}}}}/*** @param ClassMetadata<object> $class* @param array<string, int|string> $keys*/private function addIndex(ClassMetadata $class, AbstractIndex $index, array $keys = []): void{$keys = array_merge($keys, $index->keys);$options = [];$allowed = ['name', 'background', 'unique', 'sparse', 'expireAfterSeconds'];foreach ($allowed as $name) {if (! isset($index->$name)) {continue;}$options[$name] = $index->$name;}if (! empty($index->partialFilterExpression)) {$options['partialFilterExpression'] = $index->partialFilterExpression;}$options = array_merge($options, $index->options);$class->addIndex($keys, $options);}/*** @param ClassMetadata<object> $class** @throws MappingException*/private function setShardKey(ClassMetadata $class, ODM\ShardKey $shardKey): void{$options = [];$allowed = ['unique', 'numInitialChunks'];foreach ($allowed as $name) {if (! isset($shardKey->$name)) {continue;}$options[$name] = $shardKey->$name;}$class->setShardKey($shardKey->keys, $options);}/*** Retrieve the current annotation reader** @return Reader*/public function getReader(){trigger_deprecation('doctrine/mongodb-odm','2.4','%s is deprecated with no replacement',__METHOD__);return $this->reader;}/*** Factory method for the Annotation Driver** @param string[]|string $paths*/public static function create($paths = [], ?Reader $reader = null): AnnotationDriver{return new self($reader ?? new AnnotationReader(), $paths);}}interface_exists(\Doctrine\Persistence\Mapping\ClassMetadata::class);