diff --git a/composer.json b/composer.json index a2e7dcea..0c10ed45 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,8 @@ }, "autoload": { "psr-4": { - "Doctrine\\Common\\": "lib/Doctrine/Common" + "Doctrine\\Common\\": "lib/Doctrine/Common", + "Doctrine\\Persistence\\": "lib/Doctrine/Persistence" } }, "autoload-dev": { diff --git a/lib/Doctrine/Common/NotifyPropertyChanged.php b/lib/Doctrine/Common/NotifyPropertyChanged.php index 5ebcda38..b570bb80 100644 --- a/lib/Doctrine/Common/NotifyPropertyChanged.php +++ b/lib/Doctrine/Common/NotifyPropertyChanged.php @@ -2,19 +2,30 @@ namespace Doctrine\Common; -/** - * Interface for classes that notify event listeners of changes to their managed properties. - * - * This interface is implemented by objects that manually want to notify their object manager or - * other listeners when properties change, instead of relying on the object manager to compute - * property changes itself when changes are to be persisted. - */ -interface NotifyPropertyChanged -{ +use const E_USER_DEPRECATED; +use function class_alias; +use function interface_exists; +use function sprintf; +use function trigger_error; + +if (! interface_exists(\Doctrine\Persistence\NotifyPropertyChanged::class, false)) { + @trigger_error(sprintf( + 'The %s\NotifyPropertyChanged class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\NotifyPropertyChanged instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} + +class_alias( + \Doctrine\Persistence\NotifyPropertyChanged::class, + __NAMESPACE__ . '\NotifyPropertyChanged' +); + +if (false) { /** - * Adds a listener that wants to be notified about property changes. - * - * @return void + * @deprecated 1.3 Use Doctrine\Persistence\NotifyPropertyChanged */ - public function addPropertyChangedListener(PropertyChangedListener $listener); + interface NotifyPropertyChanged extends \Doctrine\Persistence\NotifyPropertyChanged + { + } } diff --git a/lib/Doctrine/Common/Persistence/AbstractManagerRegistry.php b/lib/Doctrine/Common/Persistence/AbstractManagerRegistry.php index 980abdbf..00f5e1e9 100644 --- a/lib/Doctrine/Common/Persistence/AbstractManagerRegistry.php +++ b/lib/Doctrine/Common/Persistence/AbstractManagerRegistry.php @@ -2,245 +2,30 @@ namespace Doctrine\Common\Persistence; -use InvalidArgumentException; -use ReflectionClass; -use function explode; +use const E_USER_DEPRECATED; +use function class_alias; +use function class_exists; use function sprintf; -use function strpos; - -/** - * Abstract implementation of the ManagerRegistry contract. - */ -abstract class AbstractManagerRegistry implements ManagerRegistry -{ - /** @var string */ - private $name; - - /** @var string[] */ - private $connections; - - /** @var string[] */ - private $managers; - - /** @var string */ - private $defaultConnection; - - /** @var string */ - private $defaultManager; - - /** @var string */ - private $proxyInterfaceName; - - /** - * @param string $name - * @param string[] $connections - * @param string[] $managers - * @param string $defaultConnection - * @param string $defaultManager - * @param string $proxyInterfaceName - */ - public function __construct($name, array $connections, array $managers, $defaultConnection, $defaultManager, $proxyInterfaceName) - { - $this->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; - } - } - } - - /** - * {@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; - } +use function trigger_error; + +if (! class_exists(\Doctrine\Persistence\AbstractManagerRegistry::class, false)) { + @trigger_error(sprintf( + 'The %s\AbstractManagerRegistry class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\AbstractManagerRegistry instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} - /** - * {@inheritdoc} - */ - public function getRepository($persistentObjectName, $persistentManagerName = null) - { - return $this - ->selectManager($persistentObjectName, $persistentManagerName) - ->getRepository($persistentObjectName); - } +class_alias( + \Doctrine\Persistence\AbstractManagerRegistry::class, + __NAMESPACE__ . '\AbstractManagerRegistry' +); +if (false) { /** - * {@inheritdoc} + * @deprecated 1.3 Use Doctrine\Persistence\AbstractManagerRegistry */ - public function resetManager($name = null) + abstract class AbstractManagerRegistry extends \Doctrine\Persistence\AbstractManagerRegistry { - 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/lib/Doctrine/Common/Persistence/ConnectionRegistry.php b/lib/Doctrine/Common/Persistence/ConnectionRegistry.php index 59046d44..169ed917 100644 --- a/lib/Doctrine/Common/Persistence/ConnectionRegistry.php +++ b/lib/Doctrine/Common/Persistence/ConnectionRegistry.php @@ -2,38 +2,30 @@ namespace Doctrine\Common\Persistence; -/** - * Contract covering connection for a Doctrine persistence layer ManagerRegistry class to implement. - */ -interface ConnectionRegistry -{ - /** - * Gets the default connection name. - * - * @return string The default connection name. - */ - public function getDefaultConnectionName(); +use const E_USER_DEPRECATED; +use function class_alias; +use function interface_exists; +use function sprintf; +use function trigger_error; - /** - * Gets the named connection. - * - * @param string $name The connection name (null for the default one). - * - * @return object - */ - public function getConnection($name = null); +if (! interface_exists(\Doctrine\Persistence\ConnectionRegistry::class, false)) { + @trigger_error(sprintf( + 'The %s\ConnectionRegistry class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\ConnectionRegistry instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} - /** - * Gets an array of all registered connections. - * - * @return object[] An array of Connection instances. - */ - public function getConnections(); +class_alias( + \Doctrine\Persistence\ConnectionRegistry::class, + __NAMESPACE__ . '\ConnectionRegistry' +); +if (false) { /** - * Gets all connection names. - * - * @return string[] An array of connection names. + * @deprecated 1.3 Use Doctrine\Persistence\ConnectionRegistry */ - public function getConnectionNames(); + interface ConnectionRegistry extends \Doctrine\Persistence\ConnectionRegistry + { + } } diff --git a/lib/Doctrine/Common/Persistence/Event/LifecycleEventArgs.php b/lib/Doctrine/Common/Persistence/Event/LifecycleEventArgs.php index 7575a21e..62121869 100644 --- a/lib/Doctrine/Common/Persistence/Event/LifecycleEventArgs.php +++ b/lib/Doctrine/Common/Persistence/Event/LifecycleEventArgs.php @@ -2,59 +2,30 @@ namespace Doctrine\Common\Persistence\Event; -use Doctrine\Common\EventArgs; -use Doctrine\Common\Persistence\ObjectManager; - -/** - * Lifecycle Events are triggered by the UnitOfWork during lifecycle transitions - * of entities. - */ -class LifecycleEventArgs extends EventArgs -{ - /** @var ObjectManager */ - private $objectManager; - - /** @var object */ - private $object; - - /** - * @param object $object - */ - public function __construct($object, ObjectManager $objectManager) - { - $this->object = $object; - $this->objectManager = $objectManager; - } - - /** - * Retrieves the associated entity. - * - * @deprecated - * - * @return object - */ - public function getEntity() - { - return $this->object; - } +use const E_USER_DEPRECATED; +use function class_alias; +use function class_exists; +use function sprintf; +use function trigger_error; + +if (! class_exists(\Doctrine\Persistence\Event\LifecycleEventArgs::class, false)) { + @trigger_error(sprintf( + 'The %s\LifecycleEventArgs class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\Event\LifecycleEventArgs instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} - /** - * Retrieves the associated object. - * - * @return object - */ - public function getObject() - { - return $this->object; - } +class_alias( + \Doctrine\Persistence\Event\LifecycleEventArgs::class, + __NAMESPACE__ . '\LifecycleEventArgs' +); +if (false) { /** - * Retrieves the associated ObjectManager. - * - * @return ObjectManager + * @deprecated 1.3 Use Doctrine\Persistence\Event\LifecycleEventArgs */ - public function getObjectManager() + class LifecycleEventArgs extends \Doctrine\Persistence\Event\LifecycleEventArgs { - return $this->objectManager; } } diff --git a/lib/Doctrine/Common/Persistence/Event/LoadClassMetadataEventArgs.php b/lib/Doctrine/Common/Persistence/Event/LoadClassMetadataEventArgs.php index 3fcf1b80..49be7973 100644 --- a/lib/Doctrine/Common/Persistence/Event/LoadClassMetadataEventArgs.php +++ b/lib/Doctrine/Common/Persistence/Event/LoadClassMetadataEventArgs.php @@ -2,44 +2,30 @@ namespace Doctrine\Common\Persistence\Event; -use Doctrine\Common\EventArgs; -use Doctrine\Common\Persistence\Mapping\ClassMetadata; -use Doctrine\Common\Persistence\ObjectManager; +use const E_USER_DEPRECATED; +use function class_alias; +use function class_exists; +use function sprintf; +use function trigger_error; -/** - * Class that holds event arguments for a loadMetadata event. - */ -class LoadClassMetadataEventArgs extends EventArgs -{ - /** @var ClassMetadata */ - private $classMetadata; - - /** @var ObjectManager */ - private $objectManager; - - public function __construct(ClassMetadata $classMetadata, ObjectManager $objectManager) - { - $this->classMetadata = $classMetadata; - $this->objectManager = $objectManager; - } +if (! class_exists(\Doctrine\Persistence\Event\LoadClassMetadataEventArgs::class, false)) { + @trigger_error(sprintf( + 'The %s\LoadClassMetadataEventArgs class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\Event\LoadClassMetadataEventArgs instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} - /** - * Retrieves the associated ClassMetadata. - * - * @return ClassMetadata - */ - public function getClassMetadata() - { - return $this->classMetadata; - } +class_alias( + \Doctrine\Persistence\Event\LoadClassMetadataEventArgs::class, + __NAMESPACE__ . '\LoadClassMetadataEventArgs' +); +if (false) { /** - * Retrieves the associated ObjectManager. - * - * @return ObjectManager + * @deprecated 1.3 Use Doctrine\Persistence\Event\LoadClassMetadataEventArgs */ - public function getObjectManager() + class LoadClassMetadataEventArgs extends \Doctrine\Persistence\Event\LoadClassMetadataEventArgs { - return $this->objectManager; } } diff --git a/lib/Doctrine/Common/Persistence/Event/ManagerEventArgs.php b/lib/Doctrine/Common/Persistence/Event/ManagerEventArgs.php index 4ade9916..09e0eba4 100644 --- a/lib/Doctrine/Common/Persistence/Event/ManagerEventArgs.php +++ b/lib/Doctrine/Common/Persistence/Event/ManagerEventArgs.php @@ -2,29 +2,30 @@ namespace Doctrine\Common\Persistence\Event; -use Doctrine\Common\EventArgs; -use Doctrine\Common\Persistence\ObjectManager; +use const E_USER_DEPRECATED; +use function class_alias; +use function class_exists; +use function sprintf; +use function trigger_error; -/** - * Provides event arguments for the preFlush event. - */ -class ManagerEventArgs extends EventArgs -{ - /** @var ObjectManager */ - private $objectManager; +if (! class_exists(\Doctrine\Persistence\Event\ManagerEventArgs::class, false)) { + @trigger_error(sprintf( + 'The %s\ManagerEventArgs class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\Event\ManagerEventArgs instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} - public function __construct(ObjectManager $objectManager) - { - $this->objectManager = $objectManager; - } +class_alias( + \Doctrine\Persistence\Event\ManagerEventArgs::class, + __NAMESPACE__ . '\ManagerEventArgs' +); +if (false) { /** - * Retrieves the associated ObjectManager. - * - * @return ObjectManager + * @deprecated 1.3 Use Doctrine\Persistence\Event\ManagerEventArgs */ - public function getObjectManager() + class ManagerEventArgs extends \Doctrine\Persistence\Event\ManagerEventArgs { - return $this->objectManager; } } diff --git a/lib/Doctrine/Common/Persistence/Event/OnClearEventArgs.php b/lib/Doctrine/Common/Persistence/Event/OnClearEventArgs.php index a32e35bd..71f364a6 100644 --- a/lib/Doctrine/Common/Persistence/Event/OnClearEventArgs.php +++ b/lib/Doctrine/Common/Persistence/Event/OnClearEventArgs.php @@ -2,57 +2,30 @@ namespace Doctrine\Common\Persistence\Event; -use Doctrine\Common\EventArgs; -use Doctrine\Common\Persistence\ObjectManager; - -/** - * Provides event arguments for the onClear event. - */ -class OnClearEventArgs extends EventArgs -{ - /** @var ObjectManager */ - private $objectManager; - - /** @var string|null */ - private $entityClass; - - /** - * @param ObjectManager $objectManager The object manager. - * @param string|null $entityClass The optional entity class. - */ - public function __construct($objectManager, $entityClass = null) - { - $this->objectManager = $objectManager; - $this->entityClass = $entityClass; - } - - /** - * Retrieves the associated ObjectManager. - * - * @return ObjectManager - */ - public function getObjectManager() - { - return $this->objectManager; - } +use const E_USER_DEPRECATED; +use function class_alias; +use function class_exists; +use function sprintf; +use function trigger_error; + +if (! class_exists(\Doctrine\Persistence\Event\OnClearEventArgs::class, false)) { + @trigger_error(sprintf( + 'The %s\OnClearEventArgs class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\Event\OnClearEventArgs instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} - /** - * 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; - } +class_alias( + \Doctrine\Persistence\Event\OnClearEventArgs::class, + __NAMESPACE__ . '\OnClearEventArgs' +); +if (false) { /** - * Returns whether this event clears all entities. - * - * @return bool + * @deprecated 1.3 Use Doctrine\Persistence\Event\OnClearEventArgs */ - public function clearsAllEntities() + class OnClearEventArgs extends \Doctrine\Persistence\Event\OnClearEventArgs { - return $this->entityClass === null; } } diff --git a/lib/Doctrine/Common/Persistence/Event/PreUpdateEventArgs.php b/lib/Doctrine/Common/Persistence/Event/PreUpdateEventArgs.php index 40a4782c..a61acd89 100644 --- a/lib/Doctrine/Common/Persistence/Event/PreUpdateEventArgs.php +++ b/lib/Doctrine/Common/Persistence/Event/PreUpdateEventArgs.php @@ -2,112 +2,30 @@ namespace Doctrine\Common\Persistence\Event; -use Doctrine\Common\Persistence\ObjectManager; -use InvalidArgumentException; -use function get_class; +use const E_USER_DEPRECATED; +use function class_alias; +use function class_exists; use function sprintf; +use function trigger_error; + +if (! class_exists(\Doctrine\Persistence\Event\PreUpdateEventArgs::class, false)) { + @trigger_error(sprintf( + 'The %s\PreUpdateEventArgs class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\Event\PreUpdateEventArgs instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} -/** - * Class that holds event arguments for a preUpdate event. - */ -class PreUpdateEventArgs extends LifecycleEventArgs -{ - /** @var mixed[][] */ - private $entityChangeSet; - - /** - * @param object $entity - * @param mixed[][] $changeSet - */ - public function __construct($entity, ObjectManager $objectManager, array &$changeSet) - { - parent::__construct($entity, $objectManager); - - $this->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; - } +class_alias( + \Doctrine\Persistence\Event\PreUpdateEventArgs::class, + __NAMESPACE__ . '\PreUpdateEventArgs' +); +if (false) { /** - * Asserts the field exists in changeset. - * - * @param string $field - * - * @return void - * - * @throws InvalidArgumentException + * @deprecated 1.3 Use Doctrine\Persistence\Event\PreUpdateEventArgs */ - private function assertValidField($field) + class PreUpdateEventArgs extends \Doctrine\Persistence\Event\PreUpdateEventArgs { - 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/lib/Doctrine/Common/Persistence/ManagerRegistry.php b/lib/Doctrine/Common/Persistence/ManagerRegistry.php index fdfdf916..100d9752 100644 --- a/lib/Doctrine/Common/Persistence/ManagerRegistry.php +++ b/lib/Doctrine/Common/Persistence/ManagerRegistry.php @@ -2,87 +2,30 @@ namespace Doctrine\Common\Persistence; -/** - * Contract covering object managers for a Doctrine persistence layer ManagerRegistry class to implement. - */ -interface ManagerRegistry extends ConnectionRegistry -{ - /** - * Gets the default object manager name. - * - * @return string The default object manager name. - */ - public function getDefaultManagerName(); - - /** - * Gets a named object manager. - * - * @param string $name The object manager name (null for the default one). - * - * @return ObjectManager - */ - public function getManager($name = null); - - /** - * Gets an array of all registered object managers. - * - * @return ObjectManager[] An array of ObjectManager instances - */ - public function getManagers(); - - /** - * Resets a named object manager. - * - * This method is useful when an object manager has been closed - * because of a rollbacked transaction AND when you think that - * it makes sense to get a new one to replace the closed one. - * - * Be warned that you will get a brand new object manager as - * the existing one is not useable anymore. This means that any - * other object with a dependency on this object manager will - * hold an obsolete reference. You can inject the registry instead - * to avoid this problem. - * - * @param string|null $name The object manager name (null for the default one). - * - * @return ObjectManager - */ - public function resetManager($name = null); - - /** - * Resolves a registered namespace alias to the full namespace. - * - * This method looks for the alias in all registered object managers. - * - * @param string $alias The alias. - * - * @return string The full namespace. - */ - public function getAliasNamespace($alias); - - /** - * Gets all object manager names. - * - * @return string[] An array of object manager names. - */ - public function getManagerNames(); +use const E_USER_DEPRECATED; +use function class_alias; +use function interface_exists; +use function sprintf; +use function trigger_error; + +if (! interface_exists(\Doctrine\Persistence\ManagerRegistry::class, false)) { + @trigger_error(sprintf( + 'The %s\ManagerRegistry class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\ManagerRegistry instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} - /** - * Gets the ObjectRepository for a persistent object. - * - * @param string $persistentObject The name of the persistent object. - * @param string $persistentManagerName The object manager name (null for the default one). - * - * @return ObjectRepository - */ - public function getRepository($persistentObject, $persistentManagerName = null); +class_alias( + \Doctrine\Persistence\ManagerRegistry::class, + __NAMESPACE__ . '\ManagerRegistry' +); +if (false) { /** - * Gets the object manager associated with a given class. - * - * @param string $class A persistent object class name. - * - * @return ObjectManager|null + * @deprecated 1.3 Use Doctrine\Persistence\ManagerRegistry */ - public function getManagerForClass($class); + interface ManagerRegistry extends \Doctrine\Persistence\ManagerRegistry + { + } } diff --git a/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php b/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php index 3a3948e9..31505234 100644 --- a/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php +++ b/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php @@ -2,413 +2,30 @@ namespace Doctrine\Common\Persistence\Mapping; -use Doctrine\Common\Cache\Cache; -use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver; -use Doctrine\Common\Persistence\Proxy; -use ReflectionException; -use function array_reverse; -use function array_unshift; -use function explode; -use function strpos; -use function strrpos; -use function substr; - -/** - * 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 relational database. - * - * This class was abstracted from the ORM ClassMetadataFactory. - */ -abstract class AbstractClassMetadataFactory implements ClassMetadataFactory -{ - /** - * Salt used by specific Object Manager implementation. - * - * @var string - */ - protected $cacheSalt = '$CLASSMETADATA'; - - /** @var Cache|null */ - private $cacheDriver; - - /** @var ClassMetadata[] */ - private $loadedMetadata = []; - - /** @var bool */ - protected $initialized = false; - - /** @var ReflectionService|null */ - private $reflectionService = null; - - /** - * Sets the cache driver used by the factory to cache ClassMetadata instances. - * - * @return void - */ - public function setCacheDriver(?Cache $cacheDriver = null) - { - $this->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(); - } +use const E_USER_DEPRECATED; +use function class_alias; +use function class_exists; +use function sprintf; +use function trigger_error; + +if (! class_exists(\Doctrine\Persistence\Mapping\AbstractClassMetadataFactory::class, false)) { + @trigger_error(sprintf( + 'The %s\AbstractClassMetadataFactory class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\Mapping\AbstractClassMetadataFactory instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} - return $this->reflectionService; - } +class_alias( + \Doctrine\Persistence\Mapping\AbstractClassMetadataFactory::class, + __NAMESPACE__ . '\AbstractClassMetadataFactory' +); +if (false) { /** - * Gets the real class name of a class name that could be a proxy. + * @deprecated 1.3 Use Doctrine\Persistence\Mapping\AbstractClassMetadataFactory */ - private function getRealClass(string $class) : string + class AbstractClassMetadataFactory extends \Doctrine\Persistence\Mapping\AbstractClassMetadataFactory { - $pos = strrpos($class, '\\' . Proxy::MARKER . '\\'); - - if ($pos === false) { - return $class; - } - - return substr($class, $pos + Proxy::MARKER_LENGTH + 2); } } diff --git a/lib/Doctrine/Common/Persistence/Mapping/ClassMetadata.php b/lib/Doctrine/Common/Persistence/Mapping/ClassMetadata.php index 5b3fe0ba..707ea517 100644 --- a/lib/Doctrine/Common/Persistence/Mapping/ClassMetadata.php +++ b/lib/Doctrine/Common/Persistence/Mapping/ClassMetadata.php @@ -2,153 +2,30 @@ namespace Doctrine\Common\Persistence\Mapping; -use ReflectionClass; - -/** - * Contract for a Doctrine persistence layer ClassMetadata class to implement. - */ -interface ClassMetadata -{ - /** - * Gets the fully-qualified class name of this persistent class. - * - * @return string - */ - public function getName(); - - /** - * Gets the mapped identifier field name. - * - * The returned structure is an array of the identifier field names. - * - * @return mixed[] - */ - public function getIdentifier(); - - /** - * Gets the ReflectionClass instance for this mapped class. - * - * @return ReflectionClass - */ - public function getReflectionClass(); - - /** - * Checks if the given field name is a mapped identifier for this class. - * - * @param string $fieldName - * - * @return bool - */ - public function isIdentifier($fieldName); - - /** - * Checks if the given field is a mapped property for this class. - * - * @param string $fieldName - * - * @return bool - */ - public function hasField($fieldName); - - /** - * Checks if the given field is a mapped association for this class. - * - * @param string $fieldName - * - * @return bool - */ - public function hasAssociation($fieldName); - - /** - * Checks if the given field is a mapped single valued association for this class. - * - * @param string $fieldName - * - * @return bool - */ - public function isSingleValuedAssociation($fieldName); - - /** - * Checks if the given field is a mapped collection valued association for this class. - * - * @param string $fieldName - * - * @return bool - */ - public function isCollectionValuedAssociation($fieldName); - - /** - * A numerically indexed list of field names of this persistent class. - * - * This array includes identifier fields if present on this class. - * - * @return string[] - */ - public function getFieldNames(); - - /** - * Returns an array of identifier field names numerically indexed. - * - * @return string[] - */ - public function getIdentifierFieldNames(); - - /** - * Returns a numerically indexed list of association names of this persistent class. - * - * This array includes identifier associations if present on this class. - * - * @return string[] - */ - public function getAssociationNames(); - - /** - * Returns a type name of this field. - * - * This type names can be implementation specific but should at least include the php types: - * integer, string, boolean, float/double, datetime. - * - * @param string $fieldName - * - * @return string - */ - public function getTypeOfField($fieldName); - - /** - * Returns the target class name of the given association. - * - * @param string $assocName - * - * @return string - */ - public function getAssociationTargetClass($assocName); - - /** - * Checks if the association is the inverse side of a bidirectional association. - * - * @param string $assocName - * - * @return bool - */ - public function isAssociationInverseSide($assocName); +use const E_USER_DEPRECATED; +use function class_alias; +use function interface_exists; +use function sprintf; +use function trigger_error; + +if (! interface_exists(\Doctrine\Persistence\Mapping\ClassMetadata::class, false)) { + @trigger_error(sprintf( + 'The %s\ClassMetadata class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\Mapping\ClassMetadata instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} - /** - * Returns the target field of the owning side of the association. - * - * @param string $assocName - * - * @return string - */ - public function getAssociationMappedByTargetField($assocName); +class_alias( + \Doctrine\Persistence\Mapping\ClassMetadata::class, + __NAMESPACE__ . '\ClassMetadata' +); +if (false) { /** - * Returns the identifier of this object as an array with field name as key. - * - * Has to return an empty array if no identifier isset. - * - * @param object $object - * - * @return mixed[] + * @deprecated 1.3 Use Doctrine\Persistence\Mapping\ClassMetadata */ - public function getIdentifierValues($object); + interface ClassMetadata extends \Doctrine\Persistence\Mapping\ClassMetadata + { + } } diff --git a/lib/Doctrine/Common/Persistence/Mapping/ClassMetadataFactory.php b/lib/Doctrine/Common/Persistence/Mapping/ClassMetadataFactory.php index a051739d..a8e3578f 100644 --- a/lib/Doctrine/Common/Persistence/Mapping/ClassMetadataFactory.php +++ b/lib/Doctrine/Common/Persistence/Mapping/ClassMetadataFactory.php @@ -2,52 +2,30 @@ namespace Doctrine\Common\Persistence\Mapping; -/** - * Contract for a Doctrine persistence layer ClassMetadata class to implement. - */ -interface ClassMetadataFactory -{ - /** - * 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(); - - /** - * Gets the class metadata descriptor for a class. - * - * @param string $className The name of the class. - * - * @return ClassMetadata - */ - public function getMetadataFor($className); +use const E_USER_DEPRECATED; +use function class_alias; +use function interface_exists; +use function sprintf; +use function trigger_error; - /** - * 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); +if (! interface_exists(\Doctrine\Persistence\Mapping\ClassMetadataFactory::class, false)) { + @trigger_error(sprintf( + 'The %s\ClassMetadataFactory class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\Mapping\ClassMetadataFactory instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} - /** - * Sets the metadata descriptor for a specific class. - * - * @param string $className - * @param ClassMetadata $class - */ - public function setMetadataFor($className, $class); +class_alias( + \Doctrine\Persistence\Mapping\ClassMetadataFactory::class, + __NAMESPACE__ . '\ClassMetadataFactory' +); +if (false) { /** - * Returns whether the class with the specified name should have its metadata loaded. - * This is only the case if it is either mapped directly or as a MappedSuperclass. - * - * @param string $className - * - * @return bool + * @deprecated 1.3 Use Doctrine\Persistence\Mapping\ClassMetadataFactory */ - public function isTransient($className); + interface ClassMetadataFactory extends \Doctrine\Persistence\Mapping\ClassMetadataFactory + { + } } diff --git a/lib/Doctrine/Common/Persistence/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/Common/Persistence/Mapping/Driver/AnnotationDriver.php index 1dc2cb16..b3e1ae93 100644 --- a/lib/Doctrine/Common/Persistence/Mapping/Driver/AnnotationDriver.php +++ b/lib/Doctrine/Common/Persistence/Mapping/Driver/AnnotationDriver.php @@ -2,254 +2,30 @@ namespace Doctrine\Common\Persistence\Mapping\Driver; -use Doctrine\Common\Annotations\Reader; -use Doctrine\Common\Persistence\Mapping\MappingException; -use FilesystemIterator; -use RecursiveDirectoryIterator; -use RecursiveIteratorIterator; -use RecursiveRegexIterator; -use ReflectionClass; -use RegexIterator; -use function array_merge; -use function array_unique; -use function get_class; -use function get_declared_classes; -use function in_array; -use function is_dir; -use function preg_match; -use function preg_quote; -use function realpath; -use function str_replace; -use function strpos; - -/** - * The AnnotationDriver reads the mapping metadata from docblock annotations. - */ -abstract class AnnotationDriver implements MappingDriver -{ - /** - * The annotation reader. - * - * @var Reader - */ - protected $reader; - - /** - * The paths where to look for mapping files. - * - * @var string[] - */ - protected $paths = []; - - /** - * The paths excluded from path where to look for mapping files. - * - * @var string[] - */ - protected $excludePaths = []; - - /** - * The file extension of mapping documents. - * - * @var string - */ - protected $fileExtension = '.php'; - - /** - * Cache for AnnotationDriver#getAllClassNames(). - * - * @var string[]|null - */ - protected $classNames; - - /** - * Name of the entity annotations as keys. - * - * @var string[] - */ - protected $entityAnnotationClasses = []; - - /** - * 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; - 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; - } - } +use const E_USER_DEPRECATED; +use function class_alias; +use function class_exists; +use function sprintf; +use function trigger_error; + +if (! class_exists(\Doctrine\Persistence\Mapping\Driver\AnnotationDriver::class, false)) { + @trigger_error(sprintf( + 'The %s\AnnotationDriver class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\Mapping\Driver\AnnotationDriver instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} - return true; - } +class_alias( + \Doctrine\Persistence\Mapping\Driver\AnnotationDriver::class, + __NAMESPACE__ . '\AnnotationDriver' +); +if (false) { /** - * {@inheritDoc} + * @deprecated 1.3 Use Doctrine\Persistence\Mapping\Driver\AnnotationDriver */ - public function getAllClassNames() + abstract class AnnotationDriver extends \Doctrine\Persistence\Mapping\Driver\AnnotationDriver { - 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/lib/Doctrine/Common/Persistence/Mapping/Driver/DefaultFileLocator.php b/lib/Doctrine/Common/Persistence/Mapping/Driver/DefaultFileLocator.php index 7cc68e75..7f11dd7d 100644 --- a/lib/Doctrine/Common/Persistence/Mapping/Driver/DefaultFileLocator.php +++ b/lib/Doctrine/Common/Persistence/Mapping/Driver/DefaultFileLocator.php @@ -2,160 +2,30 @@ namespace Doctrine\Common\Persistence\Mapping\Driver; -use Doctrine\Common\Persistence\Mapping\MappingException; -use RecursiveDirectoryIterator; -use RecursiveIteratorIterator; -use const DIRECTORY_SEPARATOR; -use function array_merge; -use function array_unique; -use function is_dir; -use function is_file; -use function str_replace; - -/** - * Locates the file that contains the metadata information for a given class name. - * - * This behavior is independent of the actual content of the file. It just detects - * the file which is responsible for the given class name. - */ -class DefaultFileLocator implements FileLocator -{ - /** - * The paths where to look for mapping files. - * - * @var string[] - */ - protected $paths = []; - - /** - * The file extension of mapping documents. - * - * @var string|null - */ - protected $fileExtension; - - /** - * Initializes a new FileDriver that looks in the given path(s) for mapping - * documents and operates in the specified operating mode. - * - * @param string|string[] $paths One or multiple paths where mapping documents can be found. - * @param string|null $fileExtension The file extension of mapping documents, usually prefixed with a dot. - */ - public function __construct($paths, $fileExtension = null) - { - $this->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); - } - } - } +use const E_USER_DEPRECATED; +use function class_alias; +use function class_exists; +use function sprintf; +use function trigger_error; + +if (! class_exists(\Doctrine\Persistence\Mapping\Driver\DefaultFileLocator::class, false)) { + @trigger_error(sprintf( + 'The %s\DefaultFileLocator class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\Mapping\Driver\DefaultFileLocator instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} - return $classes; - } +class_alias( + \Doctrine\Persistence\Mapping\Driver\DefaultFileLocator::class, + __NAMESPACE__ . '\DefaultFileLocator' +); +if (false) { /** - * {@inheritDoc} + * @deprecated 1.3 Use Doctrine\Persistence\Mapping\Driver\DefaultFileLocator */ - public function fileExists($className) + class DefaultFileLocator extends \Doctrine\Persistence\Mapping\Driver\DefaultFileLocator { - $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/lib/Doctrine/Common/Persistence/Mapping/Driver/FileDriver.php b/lib/Doctrine/Common/Persistence/Mapping/Driver/FileDriver.php index b31a9f7a..01d6118e 100644 --- a/lib/Doctrine/Common/Persistence/Mapping/Driver/FileDriver.php +++ b/lib/Doctrine/Common/Persistence/Mapping/Driver/FileDriver.php @@ -2,193 +2,30 @@ namespace Doctrine\Common\Persistence\Mapping\Driver; -use Doctrine\Common\Persistence\Mapping\ClassMetadata; -use Doctrine\Common\Persistence\Mapping\MappingException; -use function array_keys; -use function array_merge; -use function array_unique; -use function is_file; -use function str_replace; - -/** - * Base driver for file-based metadata drivers. - * - * A file driver operates in a mode where it loads the mapping files of individual - * classes on demand. This requires the user to adhere to the convention of 1 mapping - * file per class and the file names of the mapping files must correspond to the full - * class name, including namespace, with the namespace delimiters '\', replaced by dots '.'. - */ -abstract class FileDriver implements MappingDriver -{ - /** @var FileLocator */ - protected $locator; - - /** @var ClassMetadata[]|null */ - protected $classCache; - - /** @var string|null */ - protected $globalBasename; - - /** - * Initializes a new FileDriver that looks in the given path(s) for mapping - * documents and operates in the specified operating mode. - * - * @param string|string[]|FileLocator $locator A FileLocator or one/multiple paths - * where mapping documents can be found. - * @param string|null $fileExtension - */ - public function __construct($locator, $fileExtension = null) - { - if ($locator instanceof FileLocator) { - $this->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) - ); - } - } +use const E_USER_DEPRECATED; +use function class_alias; +use function class_exists; +use function sprintf; +use function trigger_error; + +if (! class_exists(\Doctrine\Persistence\Mapping\Driver\FileDriver::class, false)) { + @trigger_error(sprintf( + 'The %s\FileDriver class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\Mapping\Driver\FileDriver instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} - /** - * Retrieves the locator used to discover mapping files by className. - * - * @return FileLocator - */ - public function getLocator() - { - return $this->locator; - } +class_alias( + \Doctrine\Persistence\Mapping\Driver\FileDriver::class, + __NAMESPACE__ . '\FileDriver' +); +if (false) { /** - * Sets the locator used to discover mapping files by className. + * @deprecated 1.3 Use Doctrine\Persistence\Mapping\Driver\FileDriver */ - public function setLocator(FileLocator $locator) + abstract class FileDriver extends \Doctrine\Persistence\Mapping\Driver\FileDriver { - $this->locator = $locator; } } diff --git a/lib/Doctrine/Common/Persistence/Mapping/Driver/FileLocator.php b/lib/Doctrine/Common/Persistence/Mapping/Driver/FileLocator.php index 3b367419..ae43c783 100644 --- a/lib/Doctrine/Common/Persistence/Mapping/Driver/FileLocator.php +++ b/lib/Doctrine/Common/Persistence/Mapping/Driver/FileLocator.php @@ -2,52 +2,30 @@ namespace Doctrine\Common\Persistence\Mapping\Driver; -/** - * Locates the file that contains the metadata information for a given class name. - * - * This behavior is independent of the actual content of the file. It just detects - * the file which is responsible for the given class name. - */ -interface FileLocator -{ - /** - * Locates mapping file for the given class name. - * - * @param string $className - * - * @return string - */ - public function findMappingFile($className); - - /** - * Gets all class names that are found with this file locator. - * - * @param string $globalBasename Passed to allow excluding the basename. - * - * @return string[] - */ - public function getAllClassNames($globalBasename); +use const E_USER_DEPRECATED; +use function class_alias; +use function interface_exists; +use function sprintf; +use function trigger_error; - /** - * Checks if a file can be found for this class name. - * - * @param string $className - * - * @return bool - */ - public function fileExists($className); +if (! interface_exists(\Doctrine\Persistence\Mapping\Driver\FileLocator::class, false)) { + @trigger_error(sprintf( + 'The %s\FileLocator class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\Mapping\Driver\FileLocator instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} - /** - * Gets all the paths that this file locator looks for mapping files. - * - * @return string[] - */ - public function getPaths(); +class_alias( + \Doctrine\Persistence\Mapping\Driver\FileLocator::class, + __NAMESPACE__ . '\FileLocator' +); +if (false) { /** - * Gets the file extension that mapping files are suffixed with. - * - * @return string + * @deprecated 1.3 Use Doctrine\Persistence\Mapping\Driver\FileLocator */ - public function getFileExtension(); + interface FileLocator extends \Doctrine\Persistence\Mapping\Driver\FileLocator + { + } } diff --git a/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriver.php b/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriver.php index aaa7ac7e..45b40ed4 100644 --- a/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriver.php +++ b/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriver.php @@ -2,36 +2,30 @@ namespace Doctrine\Common\Persistence\Mapping\Driver; -use Doctrine\Common\Persistence\Mapping\ClassMetadata; +use const E_USER_DEPRECATED; +use function class_alias; +use function interface_exists; +use function sprintf; +use function trigger_error; -/** - * Contract for metadata drivers. - */ -interface MappingDriver -{ - /** - * Loads the metadata for the specified class into the provided container. - * - * @param string $className - * - * @return void - */ - public function loadMetadataForClass($className, ClassMetadata $metadata); +if (! interface_exists(\Doctrine\Persistence\Mapping\Driver\MappingDriver::class, false)) { + @trigger_error(sprintf( + 'The %s\MappingDriver class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\Mapping\Driver\MappingDriver instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} - /** - * Gets the names of all mapped classes known to this driver. - * - * @return string[] The names of all mapped classes known to this driver. - */ - public function getAllClassNames(); +class_alias( + \Doctrine\Persistence\Mapping\Driver\MappingDriver::class, + __NAMESPACE__ . '\MappingDriver' +); +if (false) { /** - * Returns whether the class with the specified name should have its metadata loaded. - * This is only the case if it is either mapped as an Entity or a MappedSuperclass. - * - * @param string $className - * - * @return bool + * @deprecated 1.3 Use Doctrine\Persistence\Mapping\Driver\MappingDriver */ - public function isTransient($className); + interface MappingDriver extends \Doctrine\Persistence\Mapping\Driver\MappingDriver + { + } } diff --git a/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriverChain.php b/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriverChain.php index 5b0f536e..f8c5594e 100644 --- a/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriverChain.php +++ b/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriverChain.php @@ -2,143 +2,30 @@ namespace Doctrine\Common\Persistence\Mapping\Driver; -use Doctrine\Common\Persistence\Mapping\ClassMetadata; -use Doctrine\Common\Persistence\Mapping\MappingException; -use function array_keys; -use function spl_object_hash; -use function strpos; - -/** - * The DriverChain allows you to add multiple other mapping drivers for - * certain namespaces. - */ -class MappingDriverChain implements MappingDriver -{ - /** - * The default driver. - * - * @var MappingDriver|null - */ - private $defaultDriver; - - /** @var MappingDriver[] */ - private $drivers = []; - - /** - * Gets the default driver. - * - * @return MappingDriver|null - */ - public function getDefaultDriver() - { - return $this->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) - { - /** @var MappingDriver $driver */ - foreach ($this->drivers as $namespace => $driver) { - 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 = []; - - /** @var MappingDriver $driver */ - foreach ($this->drivers as $namespace => $driver) { - $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; - } - } +use const E_USER_DEPRECATED; +use function class_alias; +use function class_exists; +use function sprintf; +use function trigger_error; + +if (! class_exists(\Doctrine\Persistence\Mapping\Driver\MappingDriverChain::class, false)) { + @trigger_error(sprintf( + 'The %s\MappingDriverChain class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\Mapping\Driver\MappingDriverChain instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} - return array_keys($classNames); - } +class_alias( + \Doctrine\Persistence\Mapping\Driver\MappingDriverChain::class, + __NAMESPACE__ . '\MappingDriverChain' +); +if (false) { /** - * {@inheritDoc} + * @deprecated 1.3 Use Doctrine\Persistence\Mapping\Driver\MappingDriverChain */ - public function isTransient($className) + class MappingDriverChain extends \Doctrine\Persistence\Mapping\Driver\MappingDriverChain { - /** @var MappingDriver $driver */ - foreach ($this->drivers as $namespace => $driver) { - if (strpos($className, $namespace) === 0) { - return $driver->isTransient($className); - } - } - - if ($this->defaultDriver !== null) { - return $this->defaultDriver->isTransient($className); - } - - return true; } } diff --git a/lib/Doctrine/Common/Persistence/Mapping/Driver/PHPDriver.php b/lib/Doctrine/Common/Persistence/Mapping/Driver/PHPDriver.php index 03e1746c..d591d4b2 100644 --- a/lib/Doctrine/Common/Persistence/Mapping/Driver/PHPDriver.php +++ b/lib/Doctrine/Common/Persistence/Mapping/Driver/PHPDriver.php @@ -2,43 +2,30 @@ namespace Doctrine\Common\Persistence\Mapping\Driver; -use Doctrine\Common\Persistence\Mapping\ClassMetadata; - -/** - * The PHPDriver includes php files which just populate ClassMetadataInfo - * instances with plain PHP code. - */ -class PHPDriver extends FileDriver -{ - /** @var ClassMetadata */ - protected $metadata; - - /** - * {@inheritDoc} - */ - public function __construct($locator) - { - parent::__construct($locator, '.php'); - } - - /** - * {@inheritDoc} - */ - public function loadMetadataForClass($className, ClassMetadata $metadata) - { - $this->metadata = $metadata; +use const E_USER_DEPRECATED; +use function class_alias; +use function class_exists; +use function sprintf; +use function trigger_error; + +if (! class_exists(\Doctrine\Persistence\Mapping\Driver\PHPDriver::class, false)) { + @trigger_error(sprintf( + 'The %s\PHPDriver class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\Mapping\Driver\PHPDriver instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} - $this->loadMappingFile($this->locator->findMappingFile($className)); - } +class_alias( + \Doctrine\Persistence\Mapping\Driver\PHPDriver::class, + __NAMESPACE__ . '\PHPDriver' +); +if (false) { /** - * {@inheritDoc} + * @deprecated 1.3 Use Doctrine\Persistence\Mapping\Driver\PHPDriver */ - protected function loadMappingFile($file) + class PHPDriver extends \Doctrine\Persistence\Mapping\Driver\PHPDriver { - $metadata = $this->metadata; - include $file; - - return [$metadata->getName() => $metadata]; } } diff --git a/lib/Doctrine/Common/Persistence/Mapping/Driver/StaticPHPDriver.php b/lib/Doctrine/Common/Persistence/Mapping/Driver/StaticPHPDriver.php index f309fa9d..159bac99 100644 --- a/lib/Doctrine/Common/Persistence/Mapping/Driver/StaticPHPDriver.php +++ b/lib/Doctrine/Common/Persistence/Mapping/Driver/StaticPHPDriver.php @@ -2,128 +2,30 @@ namespace Doctrine\Common\Persistence\Mapping\Driver; -use Doctrine\Common\Persistence\Mapping\ClassMetadata; -use Doctrine\Common\Persistence\Mapping\MappingException; -use RecursiveDirectoryIterator; -use RecursiveIteratorIterator; -use ReflectionClass; -use function array_merge; -use function array_unique; -use function get_declared_classes; -use function in_array; -use function is_dir; -use function method_exists; -use function realpath; - -/** - * The StaticPHPDriver calls a static loadMetadata() method on your entity - * classes where you can manually populate the ClassMetadata instance. - */ -class StaticPHPDriver implements MappingDriver -{ - /** - * Paths of entity directories. - * - * @var string[] - */ - private $paths = []; - - /** - * Map of all class names. - * - * @var string[] - */ - private $classNames; - - /** - * @param string[]|string $paths - */ - public function __construct($paths) - { - $this->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; +use const E_USER_DEPRECATED; +use function class_alias; +use function class_exists; +use function sprintf; +use function trigger_error; + +if (! class_exists(\Doctrine\Persistence\Mapping\Driver\StaticPHPDriver::class, false)) { + @trigger_error(sprintf( + 'The %s\Driver\StaticPHPDriver class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\Mapping\Driver\StaticPHPDriver instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} - return $classes; - } +class_alias( + \Doctrine\Persistence\Mapping\Driver\StaticPHPDriver::class, + __NAMESPACE__ . '\StaticPHPDriver' +); +if (false) { /** - * {@inheritdoc} + * @deprecated 1.3 Use Doctrine\Persistence\Mapping\Driver\StaticPHPDriver */ - public function isTransient($className) + class StaticPHPDriver extends \Doctrine\Persistence\Mapping\Driver\StaticPHPDriver { - return ! method_exists($className, 'loadMetadata'); } } diff --git a/lib/Doctrine/Common/Persistence/Mapping/Driver/SymfonyFileLocator.php b/lib/Doctrine/Common/Persistence/Mapping/Driver/SymfonyFileLocator.php index a151790b..b3ce58e7 100644 --- a/lib/Doctrine/Common/Persistence/Mapping/Driver/SymfonyFileLocator.php +++ b/lib/Doctrine/Common/Persistence/Mapping/Driver/SymfonyFileLocator.php @@ -2,229 +2,30 @@ namespace Doctrine\Common\Persistence\Mapping\Driver; -use Doctrine\Common\Persistence\Mapping\MappingException; -use InvalidArgumentException; -use RecursiveDirectoryIterator; -use RecursiveIteratorIterator; -use const DIRECTORY_SEPARATOR; -use function array_keys; -use function array_merge; -use function is_dir; -use function is_file; -use function realpath; -use function str_replace; -use function strlen; -use function strpos; -use function strrpos; -use function strtr; -use function substr; - -/** - * The Symfony File Locator makes a simplifying assumptions compared - * to the DefaultFileLocator. By assuming paths only contain entities of a certain - * namespace the mapping files consists of the short classname only. - */ -class SymfonyFileLocator implements FileLocator -{ - /** - * The paths where to look for mapping files. - * - * @var string[] - */ - protected $paths = []; - - /** - * A map of mapping directory path to namespace prefix used to expand class shortnames. - * - * @var string[] - */ - protected $prefixes = []; - - /** - * File extension that is searched for. - * - * @var string|null - */ - protected $fileExtension; - - /** - * Represents PHP namespace delimiters when looking for files - * - * @var string - */ - private $nsSeparator; - - /** - * @param string[] $prefixes - * @param string|null $fileExtension - * @param string $nsSeparator String which would be used when converting FQCN to filename and vice versa. Should not be empty - */ - public function __construct(array $prefixes, $fileExtension = null, $nsSeparator = '.') - { - $this->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); - } - } - } - } +use const E_USER_DEPRECATED; +use function class_alias; +use function class_exists; +use function sprintf; +use function trigger_error; + +if (! class_exists(\Doctrine\Persistence\Mapping\Driver\SymfonyFileLocator::class, false)) { + @trigger_error(sprintf( + 'The %s\SymfonyFileLocator class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\Mapping\Driver\SymfonyFileLocator instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} - return $classes; - } +class_alias( + \Doctrine\Persistence\Mapping\Driver\SymfonyFileLocator::class, + __NAMESPACE__ . '\SymfonyFileLocator' +); +if (false) { /** - * {@inheritDoc} + * @deprecated 1.3 Use Doctrine\Persistence\Mapping\Driver\SymfonyFileLocator */ - public function findMappingFile($className) + class SymfonyFileLocator extends \Doctrine\Persistence\Mapping\Driver\SymfonyFileLocator { - $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/lib/Doctrine/Common/Persistence/Mapping/MappingException.php b/lib/Doctrine/Common/Persistence/Mapping/MappingException.php index bae8ac5a..21600e95 100644 --- a/lib/Doctrine/Common/Persistence/Mapping/MappingException.php +++ b/lib/Doctrine/Common/Persistence/Mapping/MappingException.php @@ -2,94 +2,30 @@ namespace Doctrine\Common\Persistence\Mapping; -use Exception; -use function implode; +use const E_USER_DEPRECATED; +use function class_alias; +use function class_exists; use function sprintf; +use function trigger_error; + +if (! class_exists(\Doctrine\Persistence\Mapping\MappingException::class, false)) { + @trigger_error(sprintf( + 'The %s\MappingException class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\Mapping\MappingException instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} -/** - * A MappingException indicates that something is wrong with the mapping setup. - */ -class MappingException extends Exception -{ - /** - * @param string $className - * @param string[] $namespaces - * - * @return self - */ - public static function classNotFoundInNamespaces($className, $namespaces) - { - return new self(sprintf( - "The class '%s' was not found in the chain configured namespaces %s", - $className, - implode(', ', $namespaces) - )); - } - - /** - * @return self - */ - public static function pathRequired() - { - return new self('Specifying the paths to your entities is required ' . - 'in the AnnotationDriver to retrieve all class names.'); - } - - /** - * @param string|null $path - * - * @return self - */ - public static function fileMappingDriversRequireConfiguredDirectoryPath($path = null) - { - if (! empty($path)) { - $path = '[' . $path . ']'; - } - - return new self(sprintf( - 'File mapping drivers must have a valid directory path, ' . - 'however the given path %s seems to be incorrect!', - $path - )); - } - - /** - * @param string $entityName - * @param string $fileName - * - * @return self - */ - public static function mappingFileNotFound($entityName, $fileName) - { - return new self(sprintf( - "No mapping file found named '%s' for class '%s'.", - $fileName, - $entityName - )); - } - - /** - * @param string $entityName - * @param string $fileName - * - * @return self - */ - public static function invalidMappingFile($entityName, $fileName) - { - return new self(sprintf( - "Invalid mapping file '%s' for class '%s'.", - $fileName, - $entityName - )); - } +class_alias( + \Doctrine\Persistence\Mapping\MappingException::class, + __NAMESPACE__ . '\MappingException' +); +if (false) { /** - * @param string $className - * - * @return self + * @deprecated 1.3 Use Doctrine\Persistence\Mapping\MappingException */ - public static function nonExistingClass($className) + class MappingException extends \Doctrine\Persistence\Mapping\MappingException { - return new self(sprintf("Class '%s' does not exist", $className)); } } diff --git a/lib/Doctrine/Common/Persistence/Mapping/ReflectionService.php b/lib/Doctrine/Common/Persistence/Mapping/ReflectionService.php index 73502b17..eaaff3ea 100644 --- a/lib/Doctrine/Common/Persistence/Mapping/ReflectionService.php +++ b/lib/Doctrine/Common/Persistence/Mapping/ReflectionService.php @@ -2,70 +2,30 @@ namespace Doctrine\Common\Persistence\Mapping; -use ReflectionClass; -use ReflectionProperty; - -/** - * Very simple reflection service abstraction. - * - * This is required inside metadata layers that may require either - * static or runtime reflection. - */ -interface ReflectionService -{ - /** - * Returns an array of the parent classes (not interfaces) for the given class. - * - * @param string $class - * - * @return string[] - * - * @throws MappingException - */ - public function getParentClasses($class); - - /** - * Returns the shortname of a class. - * - * @param string $class - * - * @return string - */ - public function getClassShortName($class); - - /** - * @param string $class - * - * @return string - */ - public function getClassNamespace($class); - - /** - * Returns a reflection class instance or null. - * - * @param string $class - * - * @return ReflectionClass|null - */ - public function getClass($class); +use const E_USER_DEPRECATED; +use function class_alias; +use function interface_exists; +use function sprintf; +use function trigger_error; + +if (! interface_exists(\Doctrine\Persistence\Mapping\ReflectionService::class, false)) { + @trigger_error(sprintf( + 'The %s\ReflectionService class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\Mapping\ReflectionService instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} - /** - * Returns an accessible property (setAccessible(true)) or null. - * - * @param string $class - * @param string $property - * - * @return ReflectionProperty|null - */ - public function getAccessibleProperty($class, $property); +class_alias( + \Doctrine\Persistence\Mapping\ReflectionService::class, + __NAMESPACE__ . '\ReflectionService' +); +if (false) { /** - * Checks if the class have a public method with the given name. - * - * @param mixed $class - * @param mixed $method - * - * @return bool + * @deprecated 1.3 Use Doctrine\Persistence\Mapping\ReflectionService */ - public function hasPublicMethod($class, $method); + interface ReflectionService extends \Doctrine\Persistence\Mapping\ReflectionService + { + } } diff --git a/lib/Doctrine/Common/Persistence/Mapping/RuntimeReflectionService.php b/lib/Doctrine/Common/Persistence/Mapping/RuntimeReflectionService.php index cb429c05..dfb137d9 100644 --- a/lib/Doctrine/Common/Persistence/Mapping/RuntimeReflectionService.php +++ b/lib/Doctrine/Common/Persistence/Mapping/RuntimeReflectionService.php @@ -2,86 +2,30 @@ namespace Doctrine\Common\Persistence\Mapping; -use Doctrine\Common\Reflection\RuntimePublicReflectionProperty; -use ReflectionClass; -use ReflectionException; -use ReflectionMethod; -use ReflectionProperty; +use const E_USER_DEPRECATED; +use function class_alias; use function class_exists; -use function class_parents; - -/** - * PHP Runtime Reflection Service. - */ -class RuntimeReflectionService implements ReflectionService -{ - /** - * {@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); - } - - $reflectionProperty->setAccessible(true); +use function sprintf; +use function trigger_error; + +if (! class_exists(\Doctrine\Persistence\Mapping\RuntimeReflectionService::class, false)) { + @trigger_error(sprintf( + 'The %s\RuntimeReflectionService class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\Mapping\RuntimeReflectionService instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} - return $reflectionProperty; - } +class_alias( + \Doctrine\Persistence\Mapping\RuntimeReflectionService::class, + __NAMESPACE__ . '\RuntimeReflectionService' +); +if (false) { /** - * {@inheritDoc} + * @deprecated 1.3 Use Doctrine\Persistence\Mapping\RuntimeReflectionService */ - public function hasPublicMethod($class, $method) + class RuntimeReflectionService extends \Doctrine\Persistence\Mapping\RuntimeReflectionService { - try { - $reflectionMethod = new ReflectionMethod($class, $method); - } catch (ReflectionException $e) { - return false; - } - - return $reflectionMethod->isPublic(); } } diff --git a/lib/Doctrine/Common/Persistence/Mapping/StaticReflectionService.php b/lib/Doctrine/Common/Persistence/Mapping/StaticReflectionService.php index a82cebb1..cfd7343e 100644 --- a/lib/Doctrine/Common/Persistence/Mapping/StaticReflectionService.php +++ b/lib/Doctrine/Common/Persistence/Mapping/StaticReflectionService.php @@ -2,70 +2,30 @@ namespace Doctrine\Common\Persistence\Mapping; -use function strpos; -use function strrev; -use function strrpos; -use function substr; - -/** - * PHP Runtime Reflection Service. - */ -class StaticReflectionService implements ReflectionService -{ - /** - * {@inheritDoc} - */ - public function getParentClasses($class) - { - return []; - } - - /** - * {@inheritDoc} - */ - public function getClassShortName($className) - { - if (strpos($className, '\\') !== false) { - $className = substr($className, strrpos($className, '\\') + 1); - } - - return $className; - } - - /** - * {@inheritDoc} - */ - public function getClassNamespace($className) - { - $namespace = ''; - if (strpos($className, '\\') !== false) { - $namespace = strrev(substr(strrev($className), strpos(strrev($className), '\\') + 1)); - } - - return $namespace; - } - - /** - * {@inheritDoc} - */ - public function getClass($class) - { - return null; - } +use const E_USER_DEPRECATED; +use function class_alias; +use function class_exists; +use function sprintf; +use function trigger_error; + +if (! class_exists(\Doctrine\Persistence\Mapping\StaticReflectionService::class, false)) { + @trigger_error(sprintf( + 'The %s\StaticReflectionService class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\Mapping\StaticReflectionService instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} - /** - * {@inheritDoc} - */ - public function getAccessibleProperty($class, $property) - { - return null; - } +class_alias( + \Doctrine\Persistence\Mapping\StaticReflectionService::class, + __NAMESPACE__ . '\StaticReflectionService' +); +if (false) { /** - * {@inheritDoc} + * @deprecated 1.3 Use Doctrine\Persistence\Mapping\StaticReflectionService */ - public function hasPublicMethod($class, $method) + class StaticReflectionService extends \Doctrine\Persistence\Mapping\StaticReflectionService { - return true; } } diff --git a/lib/Doctrine/Common/Persistence/ObjectManager.php b/lib/Doctrine/Common/Persistence/ObjectManager.php index a3f15025..dd68c373 100644 --- a/lib/Doctrine/Common/Persistence/ObjectManager.php +++ b/lib/Doctrine/Common/Persistence/ObjectManager.php @@ -2,156 +2,30 @@ namespace Doctrine\Common\Persistence; -use Doctrine\Common\Persistence\Mapping\ClassMetadata; -use Doctrine\Common\Persistence\Mapping\ClassMetadataFactory; - -/** - * Contract for a Doctrine persistence layer ObjectManager class to implement. - */ -interface ObjectManager -{ - /** - * Finds an object by its identifier. - * - * This is just a convenient shortcut for getRepository($className)->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. - */ - 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 - */ - 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(); +use const E_USER_DEPRECATED; +use function class_alias; +use function interface_exists; +use function sprintf; +use function trigger_error; + +if (! interface_exists(\Doctrine\Persistence\ObjectManager::class, false)) { + @trigger_error(sprintf( + 'The %s\ObjectManager class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\ObjectManager instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} - /** - * 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); +class_alias( + \Doctrine\Persistence\ObjectManager::class, + __NAMESPACE__ . '\ObjectManager' +); +if (false) { /** - * Checks if the object is part of the current UnitOfWork and therefore managed. - * - * @param object $object - * - * @return bool + * @deprecated 1.3 Use Doctrine\Persistence\ObjectManager */ - public function contains($object); + interface ObjectManager extends \Doctrine\Persistence\ObjectManager + { + } } diff --git a/lib/Doctrine/Common/Persistence/ObjectManagerAware.php b/lib/Doctrine/Common/Persistence/ObjectManagerAware.php index 7d3aaf02..07f6a6b7 100644 --- a/lib/Doctrine/Common/Persistence/ObjectManagerAware.php +++ b/lib/Doctrine/Common/Persistence/ObjectManagerAware.php @@ -2,28 +2,30 @@ namespace Doctrine\Common\Persistence; -use Doctrine\Common\Persistence\Mapping\ClassMetadata; +use const E_USER_DEPRECATED; +use function class_alias; +use function interface_exists; +use function sprintf; +use function trigger_error; -/** - * Makes a Persistent Objects aware of its own object-manager. - * - * Using this interface the managing object manager and class metadata instances - * are injected into the persistent object after construction. This allows - * you to implement ActiveRecord functionality on top of the persistence-ignorance - * that Doctrine propagates. - * - * Word of Warning: This is a very powerful hook to change how you can work with your domain models. - * Using this hook will break the Single Responsibility Principle inside your Domain Objects - * and increase the coupling of database and objects. - * - * Every ObjectManager has to implement this functionality itself. - */ -interface ObjectManagerAware -{ +if (! interface_exists(\Doctrine\Persistence\ObjectManagerAware::class, false)) { + @trigger_error(sprintf( + 'The %s\ObjectManagerAware class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\ObjectManagerAware instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} + +class_alias( + \Doctrine\Persistence\ObjectManagerAware::class, + __NAMESPACE__ . '\ObjectManagerAware' +); + +if (false) { /** - * Injects responsible ObjectManager and the ClassMetadata into this persistent object. - * - * @return void + * @deprecated 1.3 Use Doctrine\Persistence\ObjectManagerAware */ - public function injectObjectManager(ObjectManager $objectManager, ClassMetadata $classMetadata); + interface ObjectManagerAware extends \Doctrine\Persistence\ObjectManagerAware + { + } } diff --git a/lib/Doctrine/Common/Persistence/ObjectManagerDecorator.php b/lib/Doctrine/Common/Persistence/ObjectManagerDecorator.php index 4d1f0021..5f6e015c 100644 --- a/lib/Doctrine/Common/Persistence/ObjectManagerDecorator.php +++ b/lib/Doctrine/Common/Persistence/ObjectManagerDecorator.php @@ -2,115 +2,30 @@ namespace Doctrine\Common\Persistence; -/** - * Base class to simplify ObjectManager decorators - */ -abstract class ObjectManagerDecorator implements ObjectManager -{ - /** @var ObjectManager */ - protected $wrapped; - - /** - * {@inheritdoc} - */ - public function find($className, $id) - { - return $this->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(); - } +use const E_USER_DEPRECATED; +use function class_alias; +use function class_exists; +use function sprintf; +use function trigger_error; + +if (! class_exists(\Doctrine\Persistence\ObjectManagerDecorator::class, false)) { + @trigger_error(sprintf( + 'The %s\ObjectManagerDecorator class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\ObjectManagerDecorator instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} - /** - * {@inheritdoc} - */ - public function initializeObject($obj) - { - $this->wrapped->initializeObject($obj); - } +class_alias( + \Doctrine\Persistence\ObjectManagerDecorator::class, + __NAMESPACE__ . '\ObjectManagerDecorator' +); +if (false) { /** - * {@inheritdoc} + * @deprecated 1.3 Use Doctrine\Persistence\ObjectManagerDecorator */ - public function contains($object) + abstract class ObjectManagerDecorator extends \Doctrine\Persistence\ObjectManagerDecorator { - return $this->wrapped->contains($object); } } diff --git a/lib/Doctrine/Common/Persistence/ObjectRepository.php b/lib/Doctrine/Common/Persistence/ObjectRepository.php index aa6f9f5b..7e94579d 100644 --- a/lib/Doctrine/Common/Persistence/ObjectRepository.php +++ b/lib/Doctrine/Common/Persistence/ObjectRepository.php @@ -2,60 +2,30 @@ namespace Doctrine\Common\Persistence; -use UnexpectedValueException; +use const E_USER_DEPRECATED; +use function class_alias; +use function interface_exists; +use function sprintf; +use function trigger_error; -/** - * Contract for a Doctrine persistence layer ObjectRepository class to implement. - */ -interface ObjectRepository -{ - /** - * Finds an object by its primary key / identifier. - * - * @param mixed $id The identifier. - * - * @return object|null The object. - */ - public function find($id); - - /** - * Finds all objects in the repository. - * - * @return object[] The objects. - */ - 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 - */ - public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null); +if (! interface_exists(\Doctrine\Persistence\ObjectRepository::class, false)) { + @trigger_error(sprintf( + 'The %s\ObjectRepository class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\ObjectRepository instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} - /** - * Finds a single object by a set of criteria. - * - * @param mixed[] $criteria The criteria. - * - * @return object|null The object. - */ - public function findOneBy(array $criteria); +class_alias( + \Doctrine\Persistence\ObjectRepository::class, + __NAMESPACE__ . '\ObjectRepository' +); +if (false) { /** - * Returns the class name of the object managed by the repository. - * - * @return string + * @deprecated 1.3 Use Doctrine\Persistence\ObjectRepository */ - public function getClassName(); + interface ObjectRepository extends \Doctrine\Persistence\ObjectRepository + { + } } diff --git a/lib/Doctrine/Common/Persistence/PersistentObject.php b/lib/Doctrine/Common/Persistence/PersistentObject.php index cf3b12ae..b45b65ed 100644 --- a/lib/Doctrine/Common/Persistence/PersistentObject.php +++ b/lib/Doctrine/Common/Persistence/PersistentObject.php @@ -5,9 +5,10 @@ use BadMethodCallException; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; -use Doctrine\Common\Persistence\Mapping\ClassMetadata; +use Doctrine\Persistence\Mapping\ClassMetadata; use InvalidArgumentException; use RuntimeException; +use function class_exists; use function lcfirst; use function substr; @@ -230,3 +231,5 @@ public function __call($method, $args) } } } + +class_exists(\Doctrine\Common\Persistence\PersistentObject::class); diff --git a/lib/Doctrine/Common/Persistence/Proxy.php b/lib/Doctrine/Common/Persistence/Proxy.php index 31220f73..e7a31eba 100644 --- a/lib/Doctrine/Common/Persistence/Proxy.php +++ b/lib/Doctrine/Common/Persistence/Proxy.php @@ -2,34 +2,30 @@ namespace Doctrine\Common\Persistence; -/** - * Interface for proxy classes. - */ -interface Proxy -{ - /** - * Marker for Proxy class names. - */ - public const MARKER = '__CG__'; +use const E_USER_DEPRECATED; +use function class_alias; +use function interface_exists; +use function sprintf; +use function trigger_error; - /** - * Length of the proxy marker. - */ - public const MARKER_LENGTH = 6; +if (! interface_exists(\Doctrine\Persistence\Proxy::class, false)) { + @trigger_error(sprintf( + 'The %s\Proxy class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\Proxy instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} - /** - * Initializes this proxy if its not yet initialized. - * - * Acts as a no-op if already initialized. - * - * @return void - */ - public function __load(); +class_alias( + \Doctrine\Persistence\Proxy::class, + __NAMESPACE__ . '\Proxy' +); +if (false) { /** - * Returns whether this proxy is initialized or not. - * - * @return bool + * @deprecated 1.3 Use Doctrine\Persistence\Proxy */ - public function __isInitialized(); + interface Proxy extends \Doctrine\Persistence\Proxy + { + } } diff --git a/lib/Doctrine/Common/PropertyChangedListener.php b/lib/Doctrine/Common/PropertyChangedListener.php index 66230c41..fb8ce214 100644 --- a/lib/Doctrine/Common/PropertyChangedListener.php +++ b/lib/Doctrine/Common/PropertyChangedListener.php @@ -2,21 +2,30 @@ namespace Doctrine\Common; -/** - * Contract for classes that are potential listeners of a {@see NotifyPropertyChanged} - * implementor. - */ -interface PropertyChangedListener -{ +use const E_USER_DEPRECATED; +use function class_alias; +use function interface_exists; +use function sprintf; +use function trigger_error; + +if (! interface_exists(\Doctrine\Persistence\PropertyChangedListener::class, false)) { + @trigger_error(sprintf( + 'The %s\PropertyChangedListener class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0.' + . ' Use \Doctrine\Persistence\PropertyChangedListener instead.', + __NAMESPACE__ + ), E_USER_DEPRECATED); +} + +class_alias( + \Doctrine\Persistence\PropertyChangedListener::class, + __NAMESPACE__ . '\PropertyChangedListener' +); + +if (false) { /** - * Collect information about a property change. - * - * @param object $sender The object on which the property changed. - * @param string $propertyName The name of the property that changed. - * @param mixed $oldValue The old value of the property that changed. - * @param mixed $newValue The new value of the property that changed. - * - * @return void + * @deprecated 1.3 Use Doctrine\Persistence\PropertyChangedListener */ - public function propertyChanged($sender, $propertyName, $oldValue, $newValue); + interface PropertyChangedListener extends \Doctrine\Persistence\PropertyChangedListener + { + } } diff --git a/lib/Doctrine/Persistence/AbstractManagerRegistry.php b/lib/Doctrine/Persistence/AbstractManagerRegistry.php new file mode 100644 index 00000000..3827d621 --- /dev/null +++ b/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; + } + } + } + + /** + * {@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($persistentObjectName, $persistentManagerName = null) + { + return $this + ->selectManager($persistentObjectName, $persistentManagerName) + ->getRepository($persistentObjectName); + } + + /** + * {@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(); + } +} + +class_exists(\Doctrine\Common\Persistence\AbstractManagerRegistry::class); diff --git a/lib/Doctrine/Persistence/ConnectionRegistry.php b/lib/Doctrine/Persistence/ConnectionRegistry.php new file mode 100644 index 00000000..a822c719 --- /dev/null +++ b/lib/Doctrine/Persistence/ConnectionRegistry.php @@ -0,0 +1,43 @@ +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; + } +} + +class_exists(\Doctrine\Common\Persistence\Event\LifecycleEventArgs::class); diff --git a/lib/Doctrine/Persistence/Event/LoadClassMetadataEventArgs.php b/lib/Doctrine/Persistence/Event/LoadClassMetadataEventArgs.php new file mode 100644 index 00000000..31aae4a0 --- /dev/null +++ b/lib/Doctrine/Persistence/Event/LoadClassMetadataEventArgs.php @@ -0,0 +1,48 @@ +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; + } +} + +class_exists(\Doctrine\Common\Persistence\Event\LoadClassMetadataEventArgs::class); diff --git a/lib/Doctrine/Persistence/Event/ManagerEventArgs.php b/lib/Doctrine/Persistence/Event/ManagerEventArgs.php new file mode 100644 index 00000000..66dd9035 --- /dev/null +++ b/lib/Doctrine/Persistence/Event/ManagerEventArgs.php @@ -0,0 +1,33 @@ +objectManager = $objectManager; + } + + /** + * Retrieves the associated ObjectManager. + * + * @return ObjectManager + */ + public function getObjectManager() + { + return $this->objectManager; + } +} + +class_exists(\Doctrine\Common\Persistence\Event\ManagerEventArgs::class); diff --git a/lib/Doctrine/Persistence/Event/OnClearEventArgs.php b/lib/Doctrine/Persistence/Event/OnClearEventArgs.php new file mode 100644 index 00000000..cc263c13 --- /dev/null +++ b/lib/Doctrine/Persistence/Event/OnClearEventArgs.php @@ -0,0 +1,61 @@ +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; + } +} + +class_exists(\Doctrine\Common\Persistence\Event\OnClearEventArgs::class); diff --git a/lib/Doctrine/Persistence/Event/PreUpdateEventArgs.php b/lib/Doctrine/Persistence/Event/PreUpdateEventArgs.php new file mode 100644 index 00000000..b9f83764 --- /dev/null +++ b/lib/Doctrine/Persistence/Event/PreUpdateEventArgs.php @@ -0,0 +1,116 @@ +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()) + )); + } + } +} + +class_exists(\Doctrine\Common\Persistence\Event\PreUpdateEventArgs::class); diff --git a/lib/Doctrine/Persistence/ManagerRegistry.php b/lib/Doctrine/Persistence/ManagerRegistry.php new file mode 100644 index 00000000..b28664ce --- /dev/null +++ b/lib/Doctrine/Persistence/ManagerRegistry.php @@ -0,0 +1,92 @@ +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); + } +} + +class_exists(\Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory::class); diff --git a/lib/Doctrine/Persistence/Mapping/ClassMetadata.php b/lib/Doctrine/Persistence/Mapping/ClassMetadata.php new file mode 100644 index 00000000..7b995d56 --- /dev/null +++ b/lib/Doctrine/Persistence/Mapping/ClassMetadata.php @@ -0,0 +1,157 @@ +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; + } +} + +class_exists(\Doctrine\Persistence\Mapping\Driver\AnnotationDriver::class); diff --git a/lib/Doctrine/Persistence/Mapping/Driver/DefaultFileLocator.php b/lib/Doctrine/Persistence/Mapping/Driver/DefaultFileLocator.php new file mode 100644 index 00000000..4f49bc2d --- /dev/null +++ b/lib/Doctrine/Persistence/Mapping/Driver/DefaultFileLocator.php @@ -0,0 +1,164 @@ +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; + } +} + +class_exists(\Doctrine\Common\Persistence\Mapping\Driver\DefaultFileLocator::class); diff --git a/lib/Doctrine/Persistence/Mapping/Driver/FileDriver.php b/lib/Doctrine/Persistence/Mapping/Driver/FileDriver.php new file mode 100644 index 00000000..ed445d8c --- /dev/null +++ b/lib/Doctrine/Persistence/Mapping/Driver/FileDriver.php @@ -0,0 +1,197 @@ +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; + } +} + +class_exists(\Doctrine\Common\Persistence\Mapping\Driver\FileDriver::class); diff --git a/lib/Doctrine/Persistence/Mapping/Driver/FileLocator.php b/lib/Doctrine/Persistence/Mapping/Driver/FileLocator.php new file mode 100644 index 00000000..bce3c03e --- /dev/null +++ b/lib/Doctrine/Persistence/Mapping/Driver/FileLocator.php @@ -0,0 +1,57 @@ +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) + { + /** @var MappingDriver $driver */ + foreach ($this->drivers as $namespace => $driver) { + 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 = []; + + /** @var MappingDriver $driver */ + foreach ($this->drivers as $namespace => $driver) { + $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) + { + /** @var MappingDriver $driver */ + foreach ($this->drivers as $namespace => $driver) { + if (strpos($className, $namespace) === 0) { + return $driver->isTransient($className); + } + } + + if ($this->defaultDriver !== null) { + return $this->defaultDriver->isTransient($className); + } + + return true; + } +} + +class_exists(\Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain::class); diff --git a/lib/Doctrine/Persistence/Mapping/Driver/PHPDriver.php b/lib/Doctrine/Persistence/Mapping/Driver/PHPDriver.php new file mode 100644 index 00000000..9a480ec0 --- /dev/null +++ b/lib/Doctrine/Persistence/Mapping/Driver/PHPDriver.php @@ -0,0 +1,47 @@ +metadata = $metadata; + + $this->loadMappingFile($this->locator->findMappingFile($className)); + } + + /** + * {@inheritDoc} + */ + protected function loadMappingFile($file) + { + $metadata = $this->metadata; + include $file; + + return [$metadata->getName() => $metadata]; + } +} + +class_exists(\Doctrine\Common\Persistence\Mapping\Driver\PHPDriver::class); diff --git a/lib/Doctrine/Persistence/Mapping/Driver/StaticPHPDriver.php b/lib/Doctrine/Persistence/Mapping/Driver/StaticPHPDriver.php new file mode 100644 index 00000000..bda0ef77 --- /dev/null +++ b/lib/Doctrine/Persistence/Mapping/Driver/StaticPHPDriver.php @@ -0,0 +1,132 @@ +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'); + } +} + +class_exists(\Doctrine\Common\Persistence\Mapping\Driver\StaticPHPDriver::class); diff --git a/lib/Doctrine/Persistence/Mapping/Driver/SymfonyFileLocator.php b/lib/Doctrine/Persistence/Mapping/Driver/SymfonyFileLocator.php new file mode 100644 index 00000000..3124c666 --- /dev/null +++ b/lib/Doctrine/Persistence/Mapping/Driver/SymfonyFileLocator.php @@ -0,0 +1,233 @@ +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); + } +} + +class_exists(\Doctrine\Common\Persistence\Mapping\Driver\SymfonyFileLocator::class); diff --git a/lib/Doctrine/Persistence/Mapping/MappingException.php b/lib/Doctrine/Persistence/Mapping/MappingException.php new file mode 100644 index 00000000..9729e5f6 --- /dev/null +++ b/lib/Doctrine/Persistence/Mapping/MappingException.php @@ -0,0 +1,98 @@ +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); + } + + $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(); + } +} + +class_exists(\Doctrine\Common\Persistence\Mapping\RuntimeReflectionService::class); diff --git a/lib/Doctrine/Persistence/Mapping/StaticReflectionService.php b/lib/Doctrine/Persistence/Mapping/StaticReflectionService.php new file mode 100644 index 00000000..ac24e457 --- /dev/null +++ b/lib/Doctrine/Persistence/Mapping/StaticReflectionService.php @@ -0,0 +1,74 @@ +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. + */ + 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 + */ + 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); +} + +interface_exists(\Doctrine\Common\Persistence\ObjectManager::class); diff --git a/lib/Doctrine/Persistence/ObjectManagerAware.php b/lib/Doctrine/Persistence/ObjectManagerAware.php new file mode 100644 index 00000000..2bf43359 --- /dev/null +++ b/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); + } +} + +class_exists(\Doctrine\Common\Persistence\ObjectManagerDecorator::class); diff --git a/lib/Doctrine/Persistence/ObjectRepository.php b/lib/Doctrine/Persistence/ObjectRepository.php new file mode 100644 index 00000000..7661be20 --- /dev/null +++ b/lib/Doctrine/Persistence/ObjectRepository.php @@ -0,0 +1,64 @@ + lib/Doctrine/Common/Persistence/AbstractManagerRegistry.php lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php + lib/Doctrine/Persistence/AbstractManagerRegistry.php + lib/Doctrine/Persistence/Mapping/AbstractClassMetadataFactory.php lib/Doctrine/Common/Persistence/Mapping/MappingException.php + lib/Doctrine/Persistence/Mapping/MappingException.php diff --git a/phpstan.neon b/phpstan.neon index 3e316609..00019f1b 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -14,4 +14,4 @@ parameters: - %currentWorkingDirectory%/tests/Doctrine/Tests/Common/Persistence/Mapping/_files/TestEntity.php ignoreErrors: - '#Call to an undefined method Doctrine\\Tests\\Common\\Persistence\\TestObject#' - - '#Method Doctrine\\Tests\\Common\\Persistence\\Mapping\\TestFileDriver\:\:loadMappingFile\(\) should return array\ but returns array\\.#' + - '#Method Doctrine\\Tests\\Common\\Persistence\\Mapping\\TestFileDriver\:\:loadMappingFile\(\) should return array\ but returns array\\.#' diff --git a/tests/Doctrine/Tests/Common/Persistence/ManagerRegistryTest.php b/tests/Doctrine/Tests/Common/Persistence/ManagerRegistryTest.php index aaa36972..6f3033ee 100644 --- a/tests/Doctrine/Tests/Common/Persistence/ManagerRegistryTest.php +++ b/tests/Doctrine/Tests/Common/Persistence/ManagerRegistryTest.php @@ -2,13 +2,13 @@ namespace Doctrine\Tests\Common\Persistence; -use Doctrine\Common\Persistence\AbstractManagerRegistry; -use Doctrine\Common\Persistence\Mapping\ClassMetadata; -use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver; -use Doctrine\Common\Persistence\ObjectManager; -use Doctrine\Common\Persistence\ObjectManagerAware; -use Doctrine\Common\Persistence\ObjectRepository; -use Doctrine\Common\Persistence\Proxy; +use Doctrine\Persistence\AbstractManagerRegistry; +use Doctrine\Persistence\Mapping\ClassMetadata; +use Doctrine\Persistence\Mapping\Driver\MappingDriver; +use Doctrine\Persistence\ObjectManager; +use Doctrine\Persistence\ObjectManagerAware; +use Doctrine\Persistence\ObjectRepository; +use Doctrine\Persistence\Proxy; use Doctrine\Tests\Common\Persistence\Mapping\TestClassMetadataFactory; use Doctrine\Tests\DoctrineTestCase; use PHPUnit\Framework\MockObject\MockObject; diff --git a/tests/Doctrine/Tests/Common/Persistence/Mapping/AnnotationDriverTest.php b/tests/Doctrine/Tests/Common/Persistence/Mapping/AnnotationDriverTest.php index f0abcd1f..d4f9cde7 100644 --- a/tests/Doctrine/Tests/Common/Persistence/Mapping/AnnotationDriverTest.php +++ b/tests/Doctrine/Tests/Common/Persistence/Mapping/AnnotationDriverTest.php @@ -3,9 +3,9 @@ namespace Doctrine\Tests\Common\Persistence\Mapping; use Doctrine\Common\Annotations\AnnotationReader; -use Doctrine\Common\Persistence\Mapping\ClassMetadata; -use Doctrine\Common\Persistence\Mapping\Driver\AnnotationDriver; use Doctrine\Entity; +use Doctrine\Persistence\Mapping\ClassMetadata; +use Doctrine\Persistence\Mapping\Driver\AnnotationDriver; use Doctrine\TestClass; use PHPUnit\Framework\TestCase; diff --git a/tests/Doctrine/Tests/Common/Persistence/Mapping/ClassMetadataFactoryTest.php b/tests/Doctrine/Tests/Common/Persistence/Mapping/ClassMetadataFactoryTest.php index f08dffea..d81294fe 100644 --- a/tests/Doctrine/Tests/Common/Persistence/Mapping/ClassMetadataFactoryTest.php +++ b/tests/Doctrine/Tests/Common/Persistence/Mapping/ClassMetadataFactoryTest.php @@ -4,9 +4,9 @@ use Doctrine\Common\Cache\ArrayCache; use Doctrine\Common\Cache\Cache; -use Doctrine\Common\Persistence\Mapping\ClassMetadata; -use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver; -use Doctrine\Common\Persistence\Mapping\MappingException; +use Doctrine\Persistence\Mapping\ClassMetadata; +use Doctrine\Persistence\Mapping\Driver\MappingDriver; +use Doctrine\Persistence\Mapping\MappingException; use Doctrine\Tests\DoctrineTestCase; use PHPUnit_Framework_MockObject_MockObject; use stdClass; diff --git a/tests/Doctrine/Tests/Common/Persistence/Mapping/DefaultFileLocatorTest.php b/tests/Doctrine/Tests/Common/Persistence/Mapping/DefaultFileLocatorTest.php index ff8e3bd4..2d0b66fa 100644 --- a/tests/Doctrine/Tests/Common/Persistence/Mapping/DefaultFileLocatorTest.php +++ b/tests/Doctrine/Tests/Common/Persistence/Mapping/DefaultFileLocatorTest.php @@ -2,8 +2,8 @@ namespace Doctrine\Tests\Common\Persistence\Mapping; -use Doctrine\Common\Persistence\Mapping\Driver\DefaultFileLocator; -use Doctrine\Common\Persistence\Mapping\MappingException; +use Doctrine\Persistence\Mapping\Driver\DefaultFileLocator; +use Doctrine\Persistence\Mapping\MappingException; use Doctrine\Tests\DoctrineTestCase; use const DIRECTORY_SEPARATOR; use function sort; diff --git a/tests/Doctrine/Tests/Common/Persistence/Mapping/DriverChainTest.php b/tests/Doctrine/Tests/Common/Persistence/Mapping/DriverChainTest.php index 207e0b3b..3ed094b9 100644 --- a/tests/Doctrine/Tests/Common/Persistence/Mapping/DriverChainTest.php +++ b/tests/Doctrine/Tests/Common/Persistence/Mapping/DriverChainTest.php @@ -2,10 +2,10 @@ namespace Doctrine\Tests\Common\Persistence\Mapping; -use Doctrine\Common\Persistence\Mapping\ClassMetadata; -use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver; -use Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain; -use Doctrine\Common\Persistence\Mapping\MappingException; +use Doctrine\Persistence\Mapping\ClassMetadata; +use Doctrine\Persistence\Mapping\Driver\MappingDriver; +use Doctrine\Persistence\Mapping\Driver\MappingDriverChain; +use Doctrine\Persistence\Mapping\MappingException; use Doctrine\Tests\DoctrineTestCase; use PHPUnit_Framework_MockObject_MockObject; diff --git a/tests/Doctrine/Tests/Common/Persistence/Mapping/FileDriverTest.php b/tests/Doctrine/Tests/Common/Persistence/Mapping/FileDriverTest.php index 965f7d17..c5a3f3d1 100644 --- a/tests/Doctrine/Tests/Common/Persistence/Mapping/FileDriverTest.php +++ b/tests/Doctrine/Tests/Common/Persistence/Mapping/FileDriverTest.php @@ -2,9 +2,9 @@ namespace Doctrine\Tests\Common\Persistence\Mapping; -use Doctrine\Common\Persistence\Mapping\ClassMetadata; -use Doctrine\Common\Persistence\Mapping\Driver\FileDriver; -use Doctrine\Common\Persistence\Mapping\Driver\FileLocator; +use Doctrine\Persistence\Mapping\ClassMetadata; +use Doctrine\Persistence\Mapping\Driver\FileDriver; +use Doctrine\Persistence\Mapping\Driver\FileLocator; use Doctrine\Tests\DoctrineTestCase; use function strpos; diff --git a/tests/Doctrine/Tests/Common/Persistence/Mapping/PHPDriverTest.php b/tests/Doctrine/Tests/Common/Persistence/Mapping/PHPDriverTest.php index 72203c90..843f61ed 100644 --- a/tests/Doctrine/Tests/Common/Persistence/Mapping/PHPDriverTest.php +++ b/tests/Doctrine/Tests/Common/Persistence/Mapping/PHPDriverTest.php @@ -2,8 +2,8 @@ namespace Doctrine\Tests\Common\Persistence\Mapping; -use Doctrine\Common\Persistence\Mapping\ClassMetadata; -use Doctrine\Common\Persistence\Mapping\Driver\PHPDriver; +use Doctrine\Persistence\Mapping\ClassMetadata; +use Doctrine\Persistence\Mapping\Driver\PHPDriver; use Doctrine\Tests\DoctrineTestCase; use PHPUnit_Framework_MockObject_MockObject; diff --git a/tests/Doctrine/Tests/Common/Persistence/Mapping/RuntimeReflectionServiceTest.php b/tests/Doctrine/Tests/Common/Persistence/Mapping/RuntimeReflectionServiceTest.php index 1da9eb4c..e449cc05 100644 --- a/tests/Doctrine/Tests/Common/Persistence/Mapping/RuntimeReflectionServiceTest.php +++ b/tests/Doctrine/Tests/Common/Persistence/Mapping/RuntimeReflectionServiceTest.php @@ -2,9 +2,9 @@ namespace Doctrine\Tests\Common\Persistence\Mapping; -use Doctrine\Common\Persistence\Mapping\MappingException; -use Doctrine\Common\Persistence\Mapping\RuntimeReflectionService; use Doctrine\Common\Reflection\RuntimePublicReflectionProperty; +use Doctrine\Persistence\Mapping\MappingException; +use Doctrine\Persistence\Mapping\RuntimeReflectionService; use PHPUnit\Framework\TestCase; use ReflectionProperty; use function count; diff --git a/tests/Doctrine/Tests/Common/Persistence/Mapping/StaticPHPDriverTest.php b/tests/Doctrine/Tests/Common/Persistence/Mapping/StaticPHPDriverTest.php index 8c3ec565..7bf4acaf 100644 --- a/tests/Doctrine/Tests/Common/Persistence/Mapping/StaticPHPDriverTest.php +++ b/tests/Doctrine/Tests/Common/Persistence/Mapping/StaticPHPDriverTest.php @@ -2,8 +2,8 @@ namespace Doctrine\Tests\Common\Persistence\Mapping; -use Doctrine\Common\Persistence\Mapping\ClassMetadata; -use Doctrine\Common\Persistence\Mapping\Driver\StaticPHPDriver; +use Doctrine\Persistence\Mapping\ClassMetadata; +use Doctrine\Persistence\Mapping\Driver\StaticPHPDriver; use Doctrine\Tests\DoctrineTestCase; use PHPUnit_Framework_MockObject_MockObject; diff --git a/tests/Doctrine/Tests/Common/Persistence/Mapping/StaticReflectionServiceTest.php b/tests/Doctrine/Tests/Common/Persistence/Mapping/StaticReflectionServiceTest.php index ad6baf23..96ed4788 100644 --- a/tests/Doctrine/Tests/Common/Persistence/Mapping/StaticReflectionServiceTest.php +++ b/tests/Doctrine/Tests/Common/Persistence/Mapping/StaticReflectionServiceTest.php @@ -2,7 +2,7 @@ namespace Doctrine\Tests\Common\Persistence\Mapping; -use Doctrine\Common\Persistence\Mapping\StaticReflectionService; +use Doctrine\Persistence\Mapping\StaticReflectionService; use PHPUnit\Framework\TestCase; use stdClass; use function count; diff --git a/tests/Doctrine/Tests/Common/Persistence/Mapping/SymfonyFileLocatorTest.php b/tests/Doctrine/Tests/Common/Persistence/Mapping/SymfonyFileLocatorTest.php index f26e9314..3e243980 100644 --- a/tests/Doctrine/Tests/Common/Persistence/Mapping/SymfonyFileLocatorTest.php +++ b/tests/Doctrine/Tests/Common/Persistence/Mapping/SymfonyFileLocatorTest.php @@ -2,8 +2,8 @@ namespace Doctrine\Tests\Common\Persistence\Mapping; -use Doctrine\Common\Persistence\Mapping\Driver\SymfonyFileLocator; -use Doctrine\Common\Persistence\Mapping\MappingException; +use Doctrine\Persistence\Mapping\Driver\SymfonyFileLocator; +use Doctrine\Persistence\Mapping\MappingException; use Doctrine\Tests\DoctrineTestCase; use const DIRECTORY_SEPARATOR; use function realpath; diff --git a/tests/Doctrine/Tests/Common/Persistence/Mapping/TestClassMetadataFactory.php b/tests/Doctrine/Tests/Common/Persistence/Mapping/TestClassMetadataFactory.php index 0bb09619..2cb902a6 100644 --- a/tests/Doctrine/Tests/Common/Persistence/Mapping/TestClassMetadataFactory.php +++ b/tests/Doctrine/Tests/Common/Persistence/Mapping/TestClassMetadataFactory.php @@ -4,10 +4,10 @@ namespace Doctrine\Tests\Common\Persistence\Mapping; -use Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory; -use Doctrine\Common\Persistence\Mapping\ClassMetadata; -use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver; -use Doctrine\Common\Persistence\Mapping\ReflectionService; +use Doctrine\Persistence\Mapping\AbstractClassMetadataFactory; +use Doctrine\Persistence\Mapping\ClassMetadata; +use Doctrine\Persistence\Mapping\Driver\MappingDriver; +use Doctrine\Persistence\Mapping\ReflectionService; class TestClassMetadataFactory extends AbstractClassMetadataFactory { diff --git a/tests/Doctrine/Tests/Common/Persistence/ObjectManagerDecoratorTest.php b/tests/Doctrine/Tests/Common/Persistence/ObjectManagerDecoratorTest.php index f32089e7..f8b38124 100644 --- a/tests/Doctrine/Tests/Common/Persistence/ObjectManagerDecoratorTest.php +++ b/tests/Doctrine/Tests/Common/Persistence/ObjectManagerDecoratorTest.php @@ -2,8 +2,8 @@ namespace Doctrine\Tests\Common\Persistence; -use Doctrine\Common\Persistence\ObjectManager; -use Doctrine\Common\Persistence\ObjectManagerDecorator; +use Doctrine\Persistence\ObjectManager; +use Doctrine\Persistence\ObjectManagerDecorator; use PHPUnit\Framework\TestCase; use PHPUnit_Framework_MockObject_MockObject; use ReflectionClass; diff --git a/tests/Doctrine/Tests/Common/Persistence/PersistentObjectTest.php b/tests/Doctrine/Tests/Common/Persistence/PersistentObjectTest.php index dd2de513..5882ec37 100644 --- a/tests/Doctrine/Tests/Common/Persistence/PersistentObjectTest.php +++ b/tests/Doctrine/Tests/Common/Persistence/PersistentObjectTest.php @@ -3,10 +3,10 @@ namespace Doctrine\Tests\Common\Persistence; use BadMethodCallException; -use Doctrine\Common\Persistence\Mapping\ClassMetadata; -use Doctrine\Common\Persistence\Mapping\ReflectionService; -use Doctrine\Common\Persistence\ObjectManager; use Doctrine\Common\Persistence\PersistentObject; +use Doctrine\Persistence\Mapping\ClassMetadata; +use Doctrine\Persistence\Mapping\ReflectionService; +use Doctrine\Persistence\ObjectManager; use Doctrine\Tests\DoctrineTestCase; use InvalidArgumentException; use PHPUnit_Framework_MockObject_MockObject;