From 745cf2431a71d0e6c5f08f8605839279b2f7496e Mon Sep 17 00:00:00 2001 From: Devian Date: Thu, 22 Apr 2021 17:03:46 +0800 Subject: Initiate commit --- .../Common/Persistence/PersistentObject.php | 238 ++++++++++++ .../Persistence/AbstractManagerRegistry.php | 249 ++++++++++++ .../Doctrine/Persistence/ConnectionRegistry.php | 39 ++ .../Persistence/Event/LifecycleEventArgs.php | 60 +++ .../Event/LoadClassMetadataEventArgs.php | 45 +++ .../Persistence/Event/ManagerEventArgs.php | 30 ++ .../Persistence/Event/OnClearEventArgs.php | 58 +++ .../Persistence/Event/PreUpdateEventArgs.php | 114 ++++++ .../lib/Doctrine/Persistence/ManagerRegistry.php | 92 +++++ .../Mapping/AbstractClassMetadataFactory.php | 416 +++++++++++++++++++++ .../Doctrine/Persistence/Mapping/ClassMetadata.php | 154 ++++++++ .../Persistence/Mapping/ClassMetadataFactory.php | 53 +++ .../Mapping/Driver/AnnotationDriver.php | 256 +++++++++++++ .../Mapping/Driver/DefaultFileLocator.php | 163 ++++++++ .../Persistence/Mapping/Driver/FileDriver.php | 195 ++++++++++ .../Persistence/Mapping/Driver/FileLocator.php | 53 +++ .../Persistence/Mapping/Driver/MappingDriver.php | 37 ++ .../Mapping/Driver/MappingDriverChain.php | 146 ++++++++ .../Persistence/Mapping/Driver/PHPDriver.php | 44 +++ .../Persistence/Mapping/Driver/StaticPHPDriver.php | 130 +++++++ .../Mapping/Driver/SymfonyFileLocator.php | 232 ++++++++++++ .../Persistence/Mapping/MappingException.php | 96 +++++ .../Persistence/Mapping/ReflectionService.php | 71 ++++ .../Mapping/RuntimeReflectionService.php | 102 +++++ .../Mapping/StaticReflectionService.php | 71 ++++ .../Doctrine/Persistence/NotifyPropertyChanged.php | 20 + .../lib/Doctrine/Persistence/ObjectManager.php | 165 ++++++++ .../Doctrine/Persistence/ObjectManagerAware.php | 29 ++ .../Persistence/ObjectManagerDecorator.php | 116 ++++++ .../lib/Doctrine/Persistence/ObjectRepository.php | 71 ++++ .../Persistence/PropertyChangedListener.php | 22 ++ .../persistence/lib/Doctrine/Persistence/Proxy.php | 35 ++ .../Reflection/RuntimePublicReflectionProperty.php | 57 +++ .../TypedNoDefaultReflectionProperty.php | 48 +++ 34 files changed, 3707 insertions(+) create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Common/Persistence/PersistentObject.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/AbstractManagerRegistry.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/ConnectionRegistry.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/LifecycleEventArgs.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/LoadClassMetadataEventArgs.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/ManagerEventArgs.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/OnClearEventArgs.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/PreUpdateEventArgs.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/ManagerRegistry.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/AbstractClassMetadataFactory.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/ClassMetadata.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/ClassMetadataFactory.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/AnnotationDriver.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/DefaultFileLocator.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/FileDriver.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/FileLocator.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/MappingDriver.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/MappingDriverChain.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/PHPDriver.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/StaticPHPDriver.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/SymfonyFileLocator.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/MappingException.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/ReflectionService.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/RuntimeReflectionService.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/StaticReflectionService.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/NotifyPropertyChanged.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectManager.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectManagerAware.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectManagerDecorator.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectRepository.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/PropertyChangedListener.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/Proxy.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/Reflection/RuntimePublicReflectionProperty.php create mode 100644 vendor/doctrine/persistence/lib/Doctrine/Persistence/Reflection/TypedNoDefaultReflectionProperty.php (limited to 'vendor/doctrine/persistence/lib') diff --git a/vendor/doctrine/persistence/lib/Doctrine/Common/Persistence/PersistentObject.php b/vendor/doctrine/persistence/lib/Doctrine/Common/Persistence/PersistentObject.php new file mode 100644 index 0000000..d75f127 --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Common/Persistence/PersistentObject.php @@ -0,0 +1,238 @@ +getId(); // method exists through __call + */ +abstract class PersistentObject implements ObjectManagerAware +{ + /** @var ObjectManager|null */ + private static $objectManager = null; + + /** @var ClassMetadata|null */ + private $cm = null; + + /** + * Sets the object manager responsible for all persistent object base classes. + * + * @return void + */ + public static function setObjectManager(?ObjectManager $objectManager = null) + { + self::$objectManager = $objectManager; + } + + /** + * @return ObjectManager|null + */ + public static function getObjectManager() + { + return self::$objectManager; + } + + /** + * Injects the Doctrine Object Manager. + * + * @return void + * + * @throws RuntimeException + */ + public function injectObjectManager(ObjectManager $objectManager, ClassMetadata $classMetadata) + { + if ($objectManager !== self::$objectManager) { + throw new RuntimeException('Trying to use PersistentObject with different ObjectManager instances. ' . + 'Was PersistentObject::setObjectManager() called?'); + } + + $this->cm = $classMetadata; + } + + /** + * Sets a persistent fields value. + * + * @param string $field + * @param mixed[] $args + * + * @return void + * + * @throws BadMethodCallException When no persistent field exists by that name. + * @throws InvalidArgumentException When the wrong target object type is passed to an association. + */ + private function set($field, $args) + { + if ($this->cm->hasField($field) && ! $this->cm->isIdentifier($field)) { + $this->$field = $args[0]; + } elseif ($this->cm->hasAssociation($field) && $this->cm->isSingleValuedAssociation($field)) { + $targetClass = $this->cm->getAssociationTargetClass($field); + if (! ($args[0] instanceof $targetClass) && $args[0] !== null) { + throw new InvalidArgumentException("Expected persistent object of type '" . $targetClass . "'"); + } + + $this->$field = $args[0]; + $this->completeOwningSide($field, $targetClass, $args[0]); + } else { + throw new BadMethodCallException("no field with name '" . $field . "' exists on '" . $this->cm->getName() . "'"); + } + } + + /** + * Gets a persistent field value. + * + * @param string $field + * + * @return mixed + * + * @throws BadMethodCallException When no persistent field exists by that name. + */ + private function get($field) + { + if ($this->cm->hasField($field) || $this->cm->hasAssociation($field)) { + return $this->$field; + } + + throw new BadMethodCallException("no field with name '" . $field . "' exists on '" . $this->cm->getName() . "'"); + } + + /** + * If this is an inverse side association, completes the owning side. + * + * @param string $field + * @param ClassMetadata $targetClass + * @param object $targetObject + * + * @return void + */ + private function completeOwningSide($field, $targetClass, $targetObject) + { + // add this object on the owning side as well, for obvious infinite recursion + // reasons this is only done when called on the inverse side. + if (! $this->cm->isAssociationInverseSide($field)) { + return; + } + + $mappedByField = $this->cm->getAssociationMappedByTargetField($field); + $targetMetadata = self::$objectManager->getClassMetadata($targetClass); + + $setter = ($targetMetadata->isCollectionValuedAssociation($mappedByField) ? 'add' : 'set') . $mappedByField; + $targetObject->$setter($this); + } + + /** + * Adds an object to a collection. + * + * @param string $field + * @param mixed[] $args + * + * @return void + * + * @throws BadMethodCallException + * @throws InvalidArgumentException + */ + private function add($field, $args) + { + if (! $this->cm->hasAssociation($field) || ! $this->cm->isCollectionValuedAssociation($field)) { + throw new BadMethodCallException('There is no method add' . $field . '() on ' . $this->cm->getName()); + } + + $targetClass = $this->cm->getAssociationTargetClass($field); + if (! ($args[0] instanceof $targetClass)) { + throw new InvalidArgumentException("Expected persistent object of type '" . $targetClass . "'"); + } + + if (! ($this->$field instanceof Collection)) { + $this->$field = new ArrayCollection($this->$field ?: []); + } + + $this->$field->add($args[0]); + $this->completeOwningSide($field, $targetClass, $args[0]); + } + + /** + * Initializes Doctrine Metadata for this class. + * + * @return void + * + * @throws RuntimeException + */ + private function initializeDoctrine() + { + if ($this->cm !== null) { + return; + } + + if (! self::$objectManager) { + throw new RuntimeException('No runtime object manager set. Call PersistentObject#setObjectManager().'); + } + + $this->cm = self::$objectManager->getClassMetadata(static::class); + } + + /** + * Magic methods. + * + * @param string $method + * @param mixed[] $args + * + * @return mixed + * + * @throws BadMethodCallException + */ + public function __call($method, $args) + { + $this->initializeDoctrine(); + + $command = substr($method, 0, 3); + $field = lcfirst(substr($method, 3)); + if ($command === 'set') { + $this->set($field, $args); + } elseif ($command === 'get') { + return $this->get($field); + } elseif ($command === 'add') { + $this->add($field, $args); + } else { + throw new BadMethodCallException('There is no method ' . $method . ' on ' . $this->cm->getName()); + } + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/AbstractManagerRegistry.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/AbstractManagerRegistry.php new file mode 100644 index 0000000..63ff9b0 --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/AbstractManagerRegistry.php @@ -0,0 +1,249 @@ +name = $name; + $this->connections = $connections; + $this->managers = $managers; + $this->defaultConnection = $defaultConnection; + $this->defaultManager = $defaultManager; + $this->proxyInterfaceName = $proxyInterfaceName; + } + + /** + * Fetches/creates the given services. + * + * A service in this context is connection or a manager instance. + * + * @param string $name The name of the service. + * + * @return ObjectManager The instance of the given service. + */ + abstract protected function getService($name); + + /** + * Resets the given services. + * + * A service in this context is connection or a manager instance. + * + * @param string $name The name of the service. + * + * @return void + */ + abstract protected function resetService($name); + + /** + * Gets the name of the registry. + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * {@inheritdoc} + */ + public function getConnection($name = null) + { + if ($name === null) { + $name = $this->defaultConnection; + } + + if (! isset($this->connections[$name])) { + throw new InvalidArgumentException(sprintf('Doctrine %s Connection named "%s" does not exist.', $this->name, $name)); + } + + return $this->getService($this->connections[$name]); + } + + /** + * {@inheritdoc} + */ + public function getConnectionNames() + { + return $this->connections; + } + + /** + * {@inheritdoc} + */ + public function getConnections() + { + $connections = []; + foreach ($this->connections as $name => $id) { + $connections[$name] = $this->getService($id); + } + + return $connections; + } + + /** + * {@inheritdoc} + */ + public function getDefaultConnectionName() + { + return $this->defaultConnection; + } + + /** + * {@inheritdoc} + */ + public function getDefaultManagerName() + { + return $this->defaultManager; + } + + /** + * {@inheritdoc} + * + * @throws InvalidArgumentException + */ + public function getManager($name = null) + { + if ($name === null) { + $name = $this->defaultManager; + } + + if (! isset($this->managers[$name])) { + throw new InvalidArgumentException(sprintf('Doctrine %s Manager named "%s" does not exist.', $this->name, $name)); + } + + return $this->getService($this->managers[$name]); + } + + /** + * {@inheritdoc} + */ + public function getManagerForClass($class) + { + // Check for namespace alias + if (strpos($class, ':') !== false) { + [$namespaceAlias, $simpleClassName] = explode(':', $class, 2); + $class = $this->getAliasNamespace($namespaceAlias) . '\\' . $simpleClassName; + } + + $proxyClass = new ReflectionClass($class); + + if ($proxyClass->implementsInterface($this->proxyInterfaceName)) { + $parentClass = $proxyClass->getParentClass(); + + if (! $parentClass) { + return null; + } + + $class = $parentClass->getName(); + } + + foreach ($this->managers as $id) { + $manager = $this->getService($id); + + if (! $manager->getMetadataFactory()->isTransient($class)) { + return $manager; + } + } + + return null; + } + + /** + * {@inheritdoc} + */ + public function getManagerNames() + { + return $this->managers; + } + + /** + * {@inheritdoc} + */ + public function getManagers() + { + $dms = []; + foreach ($this->managers as $name => $id) { + $dms[$name] = $this->getService($id); + } + + return $dms; + } + + /** + * {@inheritdoc} + */ + public function getRepository($persistentObject, $persistentManagerName = null) + { + return $this + ->selectManager($persistentObject, $persistentManagerName) + ->getRepository($persistentObject); + } + + /** + * {@inheritdoc} + */ + public function resetManager($name = null) + { + if ($name === null) { + $name = $this->defaultManager; + } + + if (! isset($this->managers[$name])) { + throw new InvalidArgumentException(sprintf('Doctrine %s Manager named "%s" does not exist.', $this->name, $name)); + } + + // force the creation of a new document manager + // if the current one is closed + $this->resetService($this->managers[$name]); + + return $this->getManager($name); + } + + private function selectManager(string $persistentObjectName, ?string $persistentManagerName = null): ObjectManager + { + if ($persistentManagerName !== null) { + return $this->getManager($persistentManagerName); + } + + return $this->getManagerForClass($persistentObjectName) ?? $this->getManager(); + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/ConnectionRegistry.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/ConnectionRegistry.php new file mode 100644 index 0000000..73e33b5 --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/ConnectionRegistry.php @@ -0,0 +1,39 @@ +object = $object; + $this->objectManager = $objectManager; + } + + /** + * Retrieves the associated entity. + * + * @deprecated + * + * @return object + */ + public function getEntity() + { + return $this->object; + } + + /** + * Retrieves the associated object. + * + * @return object + */ + public function getObject() + { + return $this->object; + } + + /** + * Retrieves the associated ObjectManager. + * + * @return ObjectManager + */ + public function getObjectManager() + { + return $this->objectManager; + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/LoadClassMetadataEventArgs.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/LoadClassMetadataEventArgs.php new file mode 100644 index 0000000..627cc5c --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/LoadClassMetadataEventArgs.php @@ -0,0 +1,45 @@ +classMetadata = $classMetadata; + $this->objectManager = $objectManager; + } + + /** + * Retrieves the associated ClassMetadata. + * + * @return ClassMetadata + */ + public function getClassMetadata() + { + return $this->classMetadata; + } + + /** + * Retrieves the associated ObjectManager. + * + * @return ObjectManager + */ + public function getObjectManager() + { + return $this->objectManager; + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/ManagerEventArgs.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/ManagerEventArgs.php new file mode 100644 index 0000000..510aff2 --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/ManagerEventArgs.php @@ -0,0 +1,30 @@ +objectManager = $objectManager; + } + + /** + * Retrieves the associated ObjectManager. + * + * @return ObjectManager + */ + public function getObjectManager() + { + return $this->objectManager; + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/OnClearEventArgs.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/OnClearEventArgs.php new file mode 100644 index 0000000..ce288d8 --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/OnClearEventArgs.php @@ -0,0 +1,58 @@ +objectManager = $objectManager; + $this->entityClass = $entityClass; + } + + /** + * Retrieves the associated ObjectManager. + * + * @return ObjectManager + */ + public function getObjectManager() + { + return $this->objectManager; + } + + /** + * Returns the name of the entity class that is cleared, or null if all are cleared. + * + * @return string|null + */ + public function getEntityClass() + { + return $this->entityClass; + } + + /** + * Returns whether this event clears all entities. + * + * @return bool + */ + public function clearsAllEntities() + { + return $this->entityClass === null; + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/PreUpdateEventArgs.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/PreUpdateEventArgs.php new file mode 100644 index 0000000..177d944 --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/PreUpdateEventArgs.php @@ -0,0 +1,114 @@ +entityChangeSet = &$changeSet; + } + + /** + * Retrieves the entity changeset. + * + * @return mixed[][] + */ + public function getEntityChangeSet() + { + return $this->entityChangeSet; + } + + /** + * Checks if field has a changeset. + * + * @param string $field + * + * @return bool + */ + public function hasChangedField($field) + { + return isset($this->entityChangeSet[$field]); + } + + /** + * Gets the old value of the changeset of the changed field. + * + * @param string $field + * + * @return mixed + */ + public function getOldValue($field) + { + $this->assertValidField($field); + + return $this->entityChangeSet[$field][0]; + } + + /** + * Gets the new value of the changeset of the changed field. + * + * @param string $field + * + * @return mixed + */ + public function getNewValue($field) + { + $this->assertValidField($field); + + return $this->entityChangeSet[$field][1]; + } + + /** + * Sets the new value of this field. + * + * @param string $field + * @param mixed $value + * + * @return void + */ + public function setNewValue($field, $value) + { + $this->assertValidField($field); + + $this->entityChangeSet[$field][1] = $value; + } + + /** + * Asserts the field exists in changeset. + * + * @param string $field + * + * @return void + * + * @throws InvalidArgumentException + */ + private function assertValidField($field) + { + if (! isset($this->entityChangeSet[$field])) { + throw new InvalidArgumentException(sprintf( + 'Field "%s" is not a valid field of the entity "%s" in PreUpdateEventArgs.', + $field, + get_class($this->getObject()) + )); + } + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/ManagerRegistry.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/ManagerRegistry.php new file mode 100644 index 0000000..6f89e0c --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/ManagerRegistry.php @@ -0,0 +1,92 @@ + $persistentObject + * @psalm-return ObjectRepository + */ + public function getRepository($persistentObject, $persistentManagerName = null); + + /** + * Gets the object manager associated with a given class. + * + * @param string $class A persistent object class name. + * + * @return ObjectManager|null + */ + public function getManagerForClass($class); +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/AbstractClassMetadataFactory.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/AbstractClassMetadataFactory.php new file mode 100644 index 0000000..89dfdbb --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/AbstractClassMetadataFactory.php @@ -0,0 +1,416 @@ +cacheDriver = $cacheDriver; + } + + /** + * Gets the cache driver used by the factory to cache ClassMetadata instances. + * + * @return Cache|null + */ + public function getCacheDriver() + { + return $this->cacheDriver; + } + + /** + * Returns an array of all the loaded metadata currently in memory. + * + * @return ClassMetadata[] + */ + public function getLoadedMetadata() + { + return $this->loadedMetadata; + } + + /** + * Forces the factory to load the metadata of all classes known to the underlying + * mapping driver. + * + * @return ClassMetadata[] The ClassMetadata instances of all mapped classes. + */ + public function getAllMetadata() + { + if (! $this->initialized) { + $this->initialize(); + } + + $driver = $this->getDriver(); + $metadata = []; + foreach ($driver->getAllClassNames() as $className) { + $metadata[] = $this->getMetadataFor($className); + } + + return $metadata; + } + + /** + * Lazy initialization of this stuff, especially the metadata driver, + * since these are not needed at all when a metadata cache is active. + * + * @return void + */ + abstract protected function initialize(); + + /** + * Gets the fully qualified class-name from the namespace alias. + * + * @param string $namespaceAlias + * @param string $simpleClassName + * + * @return string + */ + abstract protected function getFqcnFromAlias($namespaceAlias, $simpleClassName); + + /** + * Returns the mapping driver implementation. + * + * @return MappingDriver + */ + abstract protected function getDriver(); + + /** + * Wakes up reflection after ClassMetadata gets unserialized from cache. + * + * @return void + */ + abstract protected function wakeupReflection(ClassMetadata $class, ReflectionService $reflService); + + /** + * Initializes Reflection after ClassMetadata was constructed. + * + * @return void + */ + abstract protected function initializeReflection(ClassMetadata $class, ReflectionService $reflService); + + /** + * Checks whether the class metadata is an entity. + * + * This method should return false for mapped superclasses or embedded classes. + * + * @return bool + */ + abstract protected function isEntity(ClassMetadata $class); + + /** + * Gets the class metadata descriptor for a class. + * + * @param string $className The name of the class. + * + * @return ClassMetadata + * + * @throws ReflectionException + * @throws MappingException + */ + public function getMetadataFor($className) + { + if (isset($this->loadedMetadata[$className])) { + return $this->loadedMetadata[$className]; + } + + // Check for namespace alias + if (strpos($className, ':') !== false) { + [$namespaceAlias, $simpleClassName] = explode(':', $className, 2); + + $realClassName = $this->getFqcnFromAlias($namespaceAlias, $simpleClassName); + } else { + $realClassName = $this->getRealClass($className); + } + + if (isset($this->loadedMetadata[$realClassName])) { + // We do not have the alias name in the map, include it + return $this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName]; + } + + $loadingException = null; + + try { + if ($this->cacheDriver) { + $cached = $this->cacheDriver->fetch($realClassName . $this->cacheSalt); + if ($cached instanceof ClassMetadata) { + $this->loadedMetadata[$realClassName] = $cached; + + $this->wakeupReflection($cached, $this->getReflectionService()); + } else { + foreach ($this->loadMetadata($realClassName) as $loadedClassName) { + $this->cacheDriver->save( + $loadedClassName . $this->cacheSalt, + $this->loadedMetadata[$loadedClassName] + ); + } + } + } else { + $this->loadMetadata($realClassName); + } + } catch (MappingException $loadingException) { + $fallbackMetadataResponse = $this->onNotFoundMetadata($realClassName); + + if (! $fallbackMetadataResponse) { + throw $loadingException; + } + + $this->loadedMetadata[$realClassName] = $fallbackMetadataResponse; + } + + if ($className !== $realClassName) { + // We do not have the alias name in the map, include it + $this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName]; + } + + return $this->loadedMetadata[$className]; + } + + /** + * Checks whether the factory has the metadata for a class loaded already. + * + * @param string $className + * + * @return bool TRUE if the metadata of the class in question is already loaded, FALSE otherwise. + */ + public function hasMetadataFor($className) + { + return isset($this->loadedMetadata[$className]); + } + + /** + * Sets the metadata descriptor for a specific class. + * + * NOTE: This is only useful in very special cases, like when generating proxy classes. + * + * @param string $className + * @param ClassMetadata $class + * + * @return void + */ + public function setMetadataFor($className, $class) + { + $this->loadedMetadata[$className] = $class; + } + + /** + * Gets an array of parent classes for the given entity class. + * + * @param string $name + * + * @return string[] + */ + protected function getParentClasses($name) + { + // Collect parent classes, ignoring transient (not-mapped) classes. + $parentClasses = []; + + foreach (array_reverse($this->getReflectionService()->getParentClasses($name)) as $parentClass) { + if ($this->getDriver()->isTransient($parentClass)) { + continue; + } + + $parentClasses[] = $parentClass; + } + + return $parentClasses; + } + + /** + * Loads the metadata of the class in question and all it's ancestors whose metadata + * is still not loaded. + * + * Important: The class $name does not necessarily exist at this point here. + * Scenarios in a code-generation setup might have access to XML/YAML + * Mapping files without the actual PHP code existing here. That is why the + * {@see Doctrine\Common\Persistence\Mapping\ReflectionService} interface + * should be used for reflection. + * + * @param string $name The name of the class for which the metadata should get loaded. + * + * @return string[] + */ + protected function loadMetadata($name) + { + if (! $this->initialized) { + $this->initialize(); + } + + $loaded = []; + + $parentClasses = $this->getParentClasses($name); + $parentClasses[] = $name; + + // Move down the hierarchy of parent classes, starting from the topmost class + $parent = null; + $rootEntityFound = false; + $visited = []; + $reflService = $this->getReflectionService(); + foreach ($parentClasses as $className) { + if (isset($this->loadedMetadata[$className])) { + $parent = $this->loadedMetadata[$className]; + if ($this->isEntity($parent)) { + $rootEntityFound = true; + array_unshift($visited, $className); + } + + continue; + } + + $class = $this->newClassMetadataInstance($className); + $this->initializeReflection($class, $reflService); + + $this->doLoadMetadata($class, $parent, $rootEntityFound, $visited); + + $this->loadedMetadata[$className] = $class; + + $parent = $class; + + if ($this->isEntity($class)) { + $rootEntityFound = true; + array_unshift($visited, $className); + } + + $this->wakeupReflection($class, $reflService); + + $loaded[] = $className; + } + + return $loaded; + } + + /** + * Provides a fallback hook for loading metadata when loading failed due to reflection/mapping exceptions + * + * Override this method to implement a fallback strategy for failed metadata loading + * + * @param string $className + * + * @return ClassMetadata|null + */ + protected function onNotFoundMetadata($className) + { + return null; + } + + /** + * Actually loads the metadata from the underlying metadata. + * + * @param ClassMetadata $class + * @param ClassMetadata|null $parent + * @param bool $rootEntityFound + * @param string[] $nonSuperclassParents All parent class names + * that are not marked as mapped superclasses. + * + * @return void + */ + abstract protected function doLoadMetadata($class, $parent, $rootEntityFound, array $nonSuperclassParents); + + /** + * Creates a new ClassMetadata instance for the given class name. + * + * @param string $className + * + * @return ClassMetadata + */ + abstract protected function newClassMetadataInstance($className); + + /** + * {@inheritDoc} + */ + public function isTransient($class) + { + if (! $this->initialized) { + $this->initialize(); + } + + // Check for namespace alias + if (strpos($class, ':') !== false) { + [$namespaceAlias, $simpleClassName] = explode(':', $class, 2); + $class = $this->getFqcnFromAlias($namespaceAlias, $simpleClassName); + } + + return $this->getDriver()->isTransient($class); + } + + /** + * Sets the reflectionService. + * + * @return void + */ + public function setReflectionService(ReflectionService $reflectionService) + { + $this->reflectionService = $reflectionService; + } + + /** + * Gets the reflection service associated with this metadata factory. + * + * @return ReflectionService + */ + public function getReflectionService() + { + if ($this->reflectionService === null) { + $this->reflectionService = new RuntimeReflectionService(); + } + + return $this->reflectionService; + } + + /** + * Gets the real class name of a class name that could be a proxy. + */ + private function getRealClass(string $class): string + { + $pos = strrpos($class, '\\' . Proxy::MARKER . '\\'); + + if ($pos === false) { + return $class; + } + + return substr($class, $pos + Proxy::MARKER_LENGTH + 2); + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/ClassMetadata.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/ClassMetadata.php new file mode 100644 index 0000000..7dc556c --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/ClassMetadata.php @@ -0,0 +1,154 @@ +reader = $reader; + if (! $paths) { + return; + } + + $this->addPaths((array) $paths); + } + + /** + * Appends lookup paths to metadata driver. + * + * @param string[] $paths + * + * @return void + */ + public function addPaths(array $paths) + { + $this->paths = array_unique(array_merge($this->paths, $paths)); + } + + /** + * Retrieves the defined metadata lookup paths. + * + * @return string[] + */ + public function getPaths() + { + return $this->paths; + } + + /** + * Append exclude lookup paths to metadata driver. + * + * @param string[] $paths + */ + public function addExcludePaths(array $paths) + { + $this->excludePaths = array_unique(array_merge($this->excludePaths, $paths)); + } + + /** + * Retrieve the defined metadata lookup exclude paths. + * + * @return string[] + */ + public function getExcludePaths() + { + return $this->excludePaths; + } + + /** + * Retrieve the current annotation reader + * + * @return Reader + */ + public function getReader() + { + return $this->reader; + } + + /** + * Gets the file extension used to look for mapping files under. + * + * @return string + */ + public function getFileExtension() + { + return $this->fileExtension; + } + + /** + * Sets the file extension used to look for mapping files under. + * + * @param string $fileExtension The file extension to set. + * + * @return void + */ + public function setFileExtension($fileExtension) + { + $this->fileExtension = $fileExtension; + } + + /** + * Returns whether the class with the specified name is transient. Only non-transient + * classes, that is entities and mapped superclasses, should have their metadata loaded. + * + * A class is non-transient if it is annotated with an annotation + * from the {@see AnnotationDriver::entityAnnotationClasses}. + * + * @param string $className + * + * @return bool + */ + public function isTransient($className) + { + $classAnnotations = $this->reader->getClassAnnotations(new ReflectionClass($className)); + + foreach ($classAnnotations as $annot) { + if (isset($this->entityAnnotationClasses[get_class($annot)])) { + return false; + } + } + + return true; + } + + /** + * {@inheritDoc} + */ + public function getAllClassNames() + { + if ($this->classNames !== null) { + return $this->classNames; + } + + if (! $this->paths) { + throw MappingException::pathRequired(); + } + + $classes = []; + $includedFiles = []; + + foreach ($this->paths as $path) { + if (! is_dir($path)) { + throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path); + } + + $iterator = new RegexIterator( + new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS), + RecursiveIteratorIterator::LEAVES_ONLY + ), + '/^.+' . preg_quote($this->fileExtension) . '$/i', + RecursiveRegexIterator::GET_MATCH + ); + + foreach ($iterator as $file) { + $sourceFile = $file[0]; + + if (! preg_match('(^phar:)i', $sourceFile)) { + $sourceFile = realpath($sourceFile); + } + + foreach ($this->excludePaths as $excludePath) { + $exclude = str_replace('\\', '/', realpath($excludePath)); + $current = str_replace('\\', '/', $sourceFile); + + if (strpos($current, $exclude) !== false) { + continue 2; + } + } + + require_once $sourceFile; + + $includedFiles[] = $sourceFile; + } + } + + $declared = get_declared_classes(); + + foreach ($declared as $className) { + $rc = new ReflectionClass($className); + $sourceFile = $rc->getFileName(); + if (! in_array($sourceFile, $includedFiles) || $this->isTransient($className)) { + continue; + } + + $classes[] = $className; + } + + $this->classNames = $classes; + + return $classes; + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/DefaultFileLocator.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/DefaultFileLocator.php new file mode 100644 index 0000000..a2eb17c --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/DefaultFileLocator.php @@ -0,0 +1,163 @@ +addPaths((array) $paths); + $this->fileExtension = $fileExtension; + } + + /** + * Appends lookup paths to metadata driver. + * + * @param string[] $paths + * + * @return void + */ + public function addPaths(array $paths) + { + $this->paths = array_unique(array_merge($this->paths, $paths)); + } + + /** + * Retrieves the defined metadata lookup paths. + * + * @return string[] + */ + public function getPaths() + { + return $this->paths; + } + + /** + * Gets the file extension used to look for mapping files under. + * + * @return string|null + */ + public function getFileExtension() + { + return $this->fileExtension; + } + + /** + * Sets the file extension used to look for mapping files under. + * + * @param string|null $fileExtension The file extension to set. + * + * @return void + */ + public function setFileExtension($fileExtension) + { + $this->fileExtension = $fileExtension; + } + + /** + * {@inheritDoc} + */ + public function findMappingFile($className) + { + $fileName = str_replace('\\', '.', $className) . $this->fileExtension; + + // Check whether file exists + foreach ($this->paths as $path) { + if (is_file($path . DIRECTORY_SEPARATOR . $fileName)) { + return $path . DIRECTORY_SEPARATOR . $fileName; + } + } + + throw MappingException::mappingFileNotFound($className, $fileName); + } + + /** + * {@inheritDoc} + */ + public function getAllClassNames($globalBasename) + { + $classes = []; + + if ($this->paths) { + foreach ($this->paths as $path) { + if (! is_dir($path)) { + throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path); + } + + $iterator = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($path), + RecursiveIteratorIterator::LEAVES_ONLY + ); + + foreach ($iterator as $file) { + $fileName = $file->getBasename($this->fileExtension); + + if ($fileName === $file->getBasename() || $fileName === $globalBasename) { + continue; + } + + // NOTE: All files found here means classes are not transient! + $classes[] = str_replace('.', '\\', $fileName); + } + } + } + + return $classes; + } + + /** + * {@inheritDoc} + */ + public function fileExists($className) + { + $fileName = str_replace('\\', '.', $className) . $this->fileExtension; + + // Check whether file exists + foreach ((array) $this->paths as $path) { + if (is_file($path . DIRECTORY_SEPARATOR . $fileName)) { + return true; + } + } + + return false; + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/FileDriver.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/FileDriver.php new file mode 100644 index 0000000..208a334 --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/FileDriver.php @@ -0,0 +1,195 @@ +locator = $locator; + } else { + $this->locator = new DefaultFileLocator((array) $locator, $fileExtension); + } + } + + /** + * Sets the global basename. + * + * @param string $file + * + * @return void + */ + public function setGlobalBasename($file) + { + $this->globalBasename = $file; + } + + /** + * Retrieves the global basename. + * + * @return string|null + */ + public function getGlobalBasename() + { + return $this->globalBasename; + } + + /** + * Gets the element of schema meta data for the class from the mapping file. + * This will lazily load the mapping file if it is not loaded yet. + * + * @param string $className + * + * @return ClassMetadata The element of schema meta data. + * + * @throws MappingException + */ + public function getElement($className) + { + if ($this->classCache === null) { + $this->initialize(); + } + + if (isset($this->classCache[$className])) { + return $this->classCache[$className]; + } + + $result = $this->loadMappingFile($this->locator->findMappingFile($className)); + if (! isset($result[$className])) { + throw MappingException::invalidMappingFile($className, str_replace('\\', '.', $className) . $this->locator->getFileExtension()); + } + + $this->classCache[$className] = $result[$className]; + + return $result[$className]; + } + + /** + * {@inheritDoc} + */ + public function isTransient($className) + { + if ($this->classCache === null) { + $this->initialize(); + } + + if (isset($this->classCache[$className])) { + return false; + } + + return ! $this->locator->fileExists($className); + } + + /** + * {@inheritDoc} + */ + public function getAllClassNames() + { + if ($this->classCache === null) { + $this->initialize(); + } + + if (! $this->classCache) { + return (array) $this->locator->getAllClassNames($this->globalBasename); + } + + return array_unique(array_merge( + array_keys($this->classCache), + (array) $this->locator->getAllClassNames($this->globalBasename) + )); + } + + /** + * Loads a mapping file with the given name and returns a map + * from class/entity names to their corresponding file driver elements. + * + * @param string $file The mapping file to load. + * + * @return ClassMetadata[] + */ + abstract protected function loadMappingFile($file); + + /** + * Initializes the class cache from all the global files. + * + * Using this feature adds a substantial performance hit to file drivers as + * more metadata has to be loaded into memory than might actually be + * necessary. This may not be relevant to scenarios where caching of + * metadata is in place, however hits very hard in scenarios where no + * caching is used. + * + * @return void + */ + protected function initialize() + { + $this->classCache = []; + if ($this->globalBasename === null) { + return; + } + + foreach ($this->locator->getPaths() as $path) { + $file = $path . '/' . $this->globalBasename . $this->locator->getFileExtension(); + if (! is_file($file)) { + continue; + } + + $this->classCache = array_merge( + $this->classCache, + $this->loadMappingFile($file) + ); + } + } + + /** + * Retrieves the locator used to discover mapping files by className. + * + * @return FileLocator + */ + public function getLocator() + { + return $this->locator; + } + + /** + * Sets the locator used to discover mapping files by className. + */ + public function setLocator(FileLocator $locator) + { + $this->locator = $locator; + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/FileLocator.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/FileLocator.php new file mode 100644 index 0000000..a4dd570 --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/FileLocator.php @@ -0,0 +1,53 @@ +defaultDriver; + } + + /** + * Set the default driver. + * + * @return void + */ + public function setDefaultDriver(MappingDriver $driver) + { + $this->defaultDriver = $driver; + } + + /** + * Adds a nested driver. + * + * @param string $namespace + * + * @return void + */ + public function addDriver(MappingDriver $nestedDriver, $namespace) + { + $this->drivers[$namespace] = $nestedDriver; + } + + /** + * Gets the array of nested drivers. + * + * @return MappingDriver[] $drivers + */ + public function getDrivers() + { + return $this->drivers; + } + + /** + * {@inheritDoc} + */ + public function loadMetadataForClass($className, ClassMetadata $metadata) + { + foreach ($this->drivers as $namespace => $driver) { + assert($driver instanceof MappingDriver); + if (strpos($className, $namespace) === 0) { + $driver->loadMetadataForClass($className, $metadata); + + return; + } + } + + if ($this->defaultDriver !== null) { + $this->defaultDriver->loadMetadataForClass($className, $metadata); + + return; + } + + throw MappingException::classNotFoundInNamespaces($className, array_keys($this->drivers)); + } + + /** + * {@inheritDoc} + */ + public function getAllClassNames() + { + $classNames = []; + $driverClasses = []; + + foreach ($this->drivers as $namespace => $driver) { + assert($driver instanceof MappingDriver); + $oid = spl_object_hash($driver); + + if (! isset($driverClasses[$oid])) { + $driverClasses[$oid] = $driver->getAllClassNames(); + } + + foreach ($driverClasses[$oid] as $className) { + if (strpos($className, $namespace) !== 0) { + continue; + } + + $classNames[$className] = true; + } + } + + if ($this->defaultDriver !== null) { + foreach ($this->defaultDriver->getAllClassNames() as $className) { + $classNames[$className] = true; + } + } + + return array_keys($classNames); + } + + /** + * {@inheritDoc} + */ + public function isTransient($className) + { + foreach ($this->drivers as $namespace => $driver) { + assert($driver instanceof MappingDriver); + if (strpos($className, $namespace) === 0) { + return $driver->isTransient($className); + } + } + + if ($this->defaultDriver !== null) { + return $this->defaultDriver->isTransient($className); + } + + return true; + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/PHPDriver.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/PHPDriver.php new file mode 100644 index 0000000..7b844ca --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/PHPDriver.php @@ -0,0 +1,44 @@ +metadata = $metadata; + + $this->loadMappingFile($this->locator->findMappingFile($className)); + } + + /** + * {@inheritDoc} + */ + protected function loadMappingFile($file) + { + $metadata = $this->metadata; + include $file; + + return [$metadata->getName() => $metadata]; + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/StaticPHPDriver.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/StaticPHPDriver.php new file mode 100644 index 0000000..3f7b5ca --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/StaticPHPDriver.php @@ -0,0 +1,130 @@ +addPaths((array) $paths); + } + + /** + * Adds paths. + * + * @param string[] $paths + * + * @return void + */ + public function addPaths(array $paths) + { + $this->paths = array_unique(array_merge($this->paths, $paths)); + } + + /** + * {@inheritdoc} + */ + public function loadMetadataForClass($className, ClassMetadata $metadata) + { + $className::loadMetadata($metadata); + } + + /** + * {@inheritDoc} + * + * @todo Same code exists in AnnotationDriver, should we re-use it somehow or not worry about it? + */ + public function getAllClassNames() + { + if ($this->classNames !== null) { + return $this->classNames; + } + + if (! $this->paths) { + throw MappingException::pathRequired(); + } + + $classes = []; + $includedFiles = []; + + foreach ($this->paths as $path) { + if (! is_dir($path)) { + throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path); + } + + $iterator = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($path), + RecursiveIteratorIterator::LEAVES_ONLY + ); + + foreach ($iterator as $file) { + if ($file->getBasename('.php') === $file->getBasename()) { + continue; + } + + $sourceFile = realpath($file->getPathName()); + require_once $sourceFile; + $includedFiles[] = $sourceFile; + } + } + + $declared = get_declared_classes(); + + foreach ($declared as $className) { + $rc = new ReflectionClass($className); + $sourceFile = $rc->getFileName(); + if (! in_array($sourceFile, $includedFiles) || $this->isTransient($className)) { + continue; + } + + $classes[] = $className; + } + + $this->classNames = $classes; + + return $classes; + } + + /** + * {@inheritdoc} + */ + public function isTransient($className) + { + return ! method_exists($className, 'loadMetadata'); + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/SymfonyFileLocator.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/SymfonyFileLocator.php new file mode 100644 index 0000000..c7ea1ac --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/SymfonyFileLocator.php @@ -0,0 +1,232 @@ +addNamespacePrefixes($prefixes); + $this->fileExtension = $fileExtension; + + if (empty($nsSeparator)) { + throw new InvalidArgumentException('Namespace separator should not be empty'); + } + + $this->nsSeparator = (string) $nsSeparator; + } + + /** + * Adds Namespace Prefixes. + * + * @param string[] $prefixes + * + * @return void + */ + public function addNamespacePrefixes(array $prefixes) + { + $this->prefixes = array_merge($this->prefixes, $prefixes); + $this->paths = array_merge($this->paths, array_keys($prefixes)); + } + + /** + * Gets Namespace Prefixes. + * + * @return string[] + */ + public function getNamespacePrefixes() + { + return $this->prefixes; + } + + /** + * {@inheritDoc} + */ + public function getPaths() + { + return $this->paths; + } + + /** + * {@inheritDoc} + */ + public function getFileExtension() + { + return $this->fileExtension; + } + + /** + * Sets the file extension used to look for mapping files under. + * + * @param string $fileExtension The file extension to set. + * + * @return void + */ + public function setFileExtension($fileExtension) + { + $this->fileExtension = $fileExtension; + } + + /** + * {@inheritDoc} + */ + public function fileExists($className) + { + $defaultFileName = str_replace('\\', $this->nsSeparator, $className) . $this->fileExtension; + foreach ($this->paths as $path) { + if (! isset($this->prefixes[$path])) { + // global namespace class + if (is_file($path . DIRECTORY_SEPARATOR . $defaultFileName)) { + return true; + } + + continue; + } + + $prefix = $this->prefixes[$path]; + + if (strpos($className, $prefix . '\\') !== 0) { + continue; + } + + $filename = $path . '/' . strtr(substr($className, strlen($prefix) + 1), '\\', $this->nsSeparator) . $this->fileExtension; + if (is_file($filename)) { + return true; + } + } + + return false; + } + + /** + * {@inheritDoc} + */ + public function getAllClassNames($globalBasename = null) + { + $classes = []; + + if ($this->paths) { + foreach ((array) $this->paths as $path) { + if (! is_dir($path)) { + throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path); + } + + $iterator = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($path), + RecursiveIteratorIterator::LEAVES_ONLY + ); + + foreach ($iterator as $file) { + $fileName = $file->getBasename($this->fileExtension); + + if ($fileName === $file->getBasename() || $fileName === $globalBasename) { + continue; + } + + // NOTE: All files found here means classes are not transient! + if (isset($this->prefixes[$path])) { + // Calculate namespace suffix for given prefix as a relative path from basepath to file path + $nsSuffix = strtr( + substr(realpath($file->getPath()), strlen(realpath($path))), + $this->nsSeparator, + '\\' + ); + + $classes[] = $this->prefixes[$path] . str_replace(DIRECTORY_SEPARATOR, '\\', $nsSuffix) . '\\' . str_replace($this->nsSeparator, '\\', $fileName); + } else { + $classes[] = str_replace($this->nsSeparator, '\\', $fileName); + } + } + } + } + + return $classes; + } + + /** + * {@inheritDoc} + */ + public function findMappingFile($className) + { + $defaultFileName = str_replace('\\', $this->nsSeparator, $className) . $this->fileExtension; + foreach ($this->paths as $path) { + if (! isset($this->prefixes[$path])) { + if (is_file($path . DIRECTORY_SEPARATOR . $defaultFileName)) { + return $path . DIRECTORY_SEPARATOR . $defaultFileName; + } + + continue; + } + + $prefix = $this->prefixes[$path]; + + if (strpos($className, $prefix . '\\') !== 0) { + continue; + } + + $filename = $path . '/' . strtr(substr($className, strlen($prefix) + 1), '\\', $this->nsSeparator) . $this->fileExtension; + if (is_file($filename)) { + return $filename; + } + } + + throw MappingException::mappingFileNotFound($className, substr($className, strrpos($className, '\\') + 1) . $this->fileExtension); + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/MappingException.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/MappingException.php new file mode 100644 index 0000000..1c5e0ca --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/MappingException.php @@ -0,0 +1,96 @@ +supportsTypedPropertiesWorkaround = version_compare((string) phpversion(), '7.4.0') >= 0; + } + + /** + * {@inheritDoc} + */ + public function getParentClasses($class) + { + if (! class_exists($class)) { + throw MappingException::nonExistingClass($class); + } + + return class_parents($class); + } + + /** + * {@inheritDoc} + */ + public function getClassShortName($class) + { + $reflectionClass = new ReflectionClass($class); + + return $reflectionClass->getShortName(); + } + + /** + * {@inheritDoc} + */ + public function getClassNamespace($class) + { + $reflectionClass = new ReflectionClass($class); + + return $reflectionClass->getNamespaceName(); + } + + /** + * {@inheritDoc} + */ + public function getClass($class) + { + return new ReflectionClass($class); + } + + /** + * {@inheritDoc} + */ + public function getAccessibleProperty($class, $property) + { + $reflectionProperty = new ReflectionProperty($class, $property); + + if ($reflectionProperty->isPublic()) { + $reflectionProperty = new RuntimePublicReflectionProperty($class, $property); + } elseif ($this->supportsTypedPropertiesWorkaround && ! array_key_exists($property, $this->getClass($class)->getDefaultProperties())) { + $reflectionProperty = new TypedNoDefaultReflectionProperty($class, $property); + } + + $reflectionProperty->setAccessible(true); + + return $reflectionProperty; + } + + /** + * {@inheritDoc} + */ + public function hasPublicMethod($class, $method) + { + try { + $reflectionMethod = new ReflectionMethod($class, $method); + } catch (ReflectionException $e) { + return false; + } + + return $reflectionMethod->isPublic(); + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/StaticReflectionService.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/StaticReflectionService.php new file mode 100644 index 0000000..b2c33ba --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/StaticReflectionService.php @@ -0,0 +1,71 @@ +find($id). + * + * @param string $className The class name of the object to find. + * @param mixed $id The identity of the object to find. + * + * @return object|null The found object. + * + * @template T + * @psalm-param class-string $className + * @psalm-return T|null + */ + public function find($className, $id); + + /** + * Tells the ObjectManager to make an instance managed and persistent. + * + * The object will be entered into the database as a result of the flush operation. + * + * NOTE: The persist operation always considers objects that are not yet known to + * this ObjectManager as NEW. Do not pass detached objects to the persist operation. + * + * @param object $object The instance to make managed and persistent. + * + * @return void + */ + public function persist($object); + + /** + * Removes an object instance. + * + * A removed object will be removed from the database as a result of the flush operation. + * + * @param object $object The object instance to remove. + * + * @return void + */ + public function remove($object); + + /** + * Merges the state of a detached object into the persistence context + * of this ObjectManager and returns the managed copy of the object. + * The object passed to merge will not become associated/managed with this ObjectManager. + * + * @deprecated Merge operation is deprecated and will be removed in Persistence 2.0. + * Merging should be part of the business domain of an application rather than + * a generic operation of ObjectManager. + * + * @param object $object + * + * @return object + */ + public function merge($object); + + /** + * Clears the ObjectManager. All objects that are currently managed + * by this ObjectManager become detached. + * + * @param string|null $objectName if given, only objects of this type will get detached. + * + * @return void + */ + public function clear($objectName = null); + + /** + * Detaches an object from the ObjectManager, causing a managed object to + * become detached. Unflushed changes made to the object if any + * (including removal of the object), will not be synchronized to the database. + * Objects which previously referenced the detached object will continue to + * reference it. + * + * @deprecated Detach operation is deprecated and will be removed in Persistence 2.0. Please use + * {@see ObjectManager::clear()} instead. + * + * @param object $object The object to detach. + * + * @return void + */ + public function detach($object); + + /** + * Refreshes the persistent state of an object from the database, + * overriding any local changes that have not yet been persisted. + * + * @param object $object The object to refresh. + * + * @return void + */ + public function refresh($object); + + /** + * Flushes all changes to objects that have been queued up to now to the database. + * This effectively synchronizes the in-memory state of managed objects with the + * database. + * + * @return void + */ + public function flush(); + + /** + * Gets the repository for a class. + * + * @param string $className + * + * @return ObjectRepository + * + * @template T + * @psalm-param class-string $className + * @psalm-return ObjectRepository + */ + public function getRepository($className); + + /** + * Returns the ClassMetadata descriptor for a class. + * + * The class name must be the fully-qualified class name without a leading backslash + * (as it is returned by get_class($obj)). + * + * @param string $className + * + * @return ClassMetadata + */ + public function getClassMetadata($className); + + /** + * Gets the metadata factory used to gather the metadata of classes. + * + * @return ClassMetadataFactory + */ + public function getMetadataFactory(); + + /** + * Helper method to initialize a lazy loading proxy or persistent collection. + * + * This method is a no-op for other objects. + * + * @param object $obj + * + * @return void + */ + public function initializeObject($obj); + + /** + * Checks if the object is part of the current UnitOfWork and therefore managed. + * + * @param object $object + * + * @return bool + */ + public function contains($object); +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectManagerAware.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectManagerAware.php new file mode 100644 index 0000000..2bf4335 --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectManagerAware.php @@ -0,0 +1,29 @@ +wrapped->find($className, $id); + } + + /** + * {@inheritdoc} + */ + public function persist($object) + { + $this->wrapped->persist($object); + } + + /** + * {@inheritdoc} + */ + public function remove($object) + { + $this->wrapped->remove($object); + } + + /** + * {@inheritdoc} + */ + public function merge($object) + { + return $this->wrapped->merge($object); + } + + /** + * {@inheritdoc} + */ + public function clear($objectName = null) + { + $this->wrapped->clear($objectName); + } + + /** + * {@inheritdoc} + */ + public function detach($object) + { + $this->wrapped->detach($object); + } + + /** + * {@inheritdoc} + */ + public function refresh($object) + { + $this->wrapped->refresh($object); + } + + /** + * {@inheritdoc} + */ + public function flush() + { + $this->wrapped->flush(); + } + + /** + * {@inheritdoc} + */ + public function getRepository($className) + { + return $this->wrapped->getRepository($className); + } + + /** + * {@inheritdoc} + */ + public function getClassMetadata($className) + { + return $this->wrapped->getClassMetadata($className); + } + + /** + * {@inheritdoc} + */ + public function getMetadataFactory() + { + return $this->wrapped->getMetadataFactory(); + } + + /** + * {@inheritdoc} + */ + public function initializeObject($obj) + { + $this->wrapped->initializeObject($obj); + } + + /** + * {@inheritdoc} + */ + public function contains($object) + { + return $this->wrapped->contains($object); + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectRepository.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectRepository.php new file mode 100644 index 0000000..1450e95 --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectRepository.php @@ -0,0 +1,71 @@ + The objects. + * + * @psalm-return T[] + */ + public function findAll(); + + /** + * Finds objects by a set of criteria. + * + * Optionally sorting and limiting details can be passed. An implementation may throw + * an UnexpectedValueException if certain values of the sorting or limiting details are + * not supported. + * + * @param mixed[] $criteria + * @param string[]|null $orderBy + * @param int|null $limit + * @param int|null $offset + * + * @return object[] The objects. + * + * @throws UnexpectedValueException + * + * @psalm-return T[] + */ + public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null); + + /** + * Finds a single object by a set of criteria. + * + * @param mixed[] $criteria The criteria. + * + * @return object|null The object. + * + * @psalm-return T|null + */ + public function findOneBy(array $criteria); + + /** + * Returns the class name of the object managed by the repository. + * + * @return string + */ + public function getClassName(); +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/PropertyChangedListener.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/PropertyChangedListener.php new file mode 100644 index 0000000..7ab057e --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/PropertyChangedListener.php @@ -0,0 +1,22 @@ +getName(); + + if ($object instanceof Proxy && ! $object->__isInitialized()) { + $originalInitializer = $object->__getInitializer(); + $object->__setInitializer(null); + $val = $object->$name ?? null; + $object->__setInitializer($originalInitializer); + + return $val; + } + + return isset($object->$name) ? parent::getValue($object) : null; + } + + /** + * {@inheritDoc} + * + * Avoids triggering lazy loading via `__set` if the provided object + * is a {@see \Doctrine\Common\Proxy\Proxy}. + * + * @link https://bugs.php.net/bug.php?id=63463 + */ + public function setValue($object, $value = null) + { + if (! ($object instanceof Proxy && ! $object->__isInitialized())) { + parent::setValue($object, $value); + + return; + } + + $originalInitializer = $object->__getInitializer(); + $object->__setInitializer(null); + parent::setValue($object, $value); + $object->__setInitializer($originalInitializer); + } +} diff --git a/vendor/doctrine/persistence/lib/Doctrine/Persistence/Reflection/TypedNoDefaultReflectionProperty.php b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Reflection/TypedNoDefaultReflectionProperty.php new file mode 100644 index 0000000..8c0479c --- /dev/null +++ b/vendor/doctrine/persistence/lib/Doctrine/Persistence/Reflection/TypedNoDefaultReflectionProperty.php @@ -0,0 +1,48 @@ +isInitialized($object) ? parent::getValue($object) : null; + } + + /** + * {@inheritDoc} + * + * Works around the problem with setting typed no default properties to + * NULL which is not supported, instead unset() to uninitialize. + * + * @link https://github.com/doctrine/orm/issues/7999 + */ + public function setValue($object, $value = null) + { + if ($value === null && $this->hasType() && ! $this->getType()->allowsNull()) { + $propertyName = $this->getName(); + + $unsetter = function () use ($propertyName) { + unset($this->$propertyName); + }; + $unsetter = $unsetter->bindTo($object, $this->getDeclaringClass()->getName()); + $unsetter(); + + return; + } + + parent::setValue($object, $value); + } +} -- cgit v1.2.3