init
This commit is contained in:
@@ -0,0 +1 @@
|
||||
<?php
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Persistence;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use BadMethodCallException;
|
||||
use MailPoetVendor\Doctrine\Common\Collections\ArrayCollection;
|
||||
use MailPoetVendor\Doctrine\Common\Collections\Collection;
|
||||
use MailPoetVendor\Doctrine\Persistence\Mapping\ClassMetadata;
|
||||
use MailPoetVendor\Doctrine\Persistence\ObjectManager;
|
||||
use MailPoetVendor\Doctrine\Persistence\ObjectManagerAware;
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
use function lcfirst;
|
||||
use function substr;
|
||||
abstract class PersistentObject implements ObjectManagerAware
|
||||
{
|
||||
private static $objectManager = null;
|
||||
private $cm = null;
|
||||
public static function setObjectManager(?ObjectManager $objectManager = null)
|
||||
{
|
||||
self::$objectManager = $objectManager;
|
||||
}
|
||||
public static function getObjectManager()
|
||||
{
|
||||
return self::$objectManager;
|
||||
}
|
||||
public function injectObjectManager(ObjectManager $objectManager, ClassMetadata $classMetadata)
|
||||
{
|
||||
if ($objectManager !== self::$objectManager) {
|
||||
throw new RuntimeException('Trying to use PersistentObject with different ObjectManager instances. ' . 'Was PersistentObject::setObjectManager() called?');
|
||||
}
|
||||
$this->cm = $classMetadata;
|
||||
}
|
||||
private function set($field, $args)
|
||||
{
|
||||
if ($this->cm->hasField($field) && !$this->cm->isIdentifier($field)) {
|
||||
$this->{$field} = $args[0];
|
||||
} elseif ($this->cm->hasAssociation($field) && $this->cm->isSingleValuedAssociation($field)) {
|
||||
$targetClass = $this->cm->getAssociationTargetClass($field);
|
||||
if ($targetClass !== null && !$args[0] instanceof $targetClass && $args[0] !== null) {
|
||||
throw new InvalidArgumentException("Expected persistent object of type '" . $targetClass . "'");
|
||||
}
|
||||
$this->{$field} = $args[0];
|
||||
$this->completeOwningSide($field, $targetClass, $args[0]);
|
||||
} else {
|
||||
throw new BadMethodCallException("no field with name '" . $field . "' exists on '" . $this->cm->getName() . "'");
|
||||
}
|
||||
}
|
||||
private function get($field)
|
||||
{
|
||||
if ($this->cm->hasField($field) || $this->cm->hasAssociation($field)) {
|
||||
return $this->{$field};
|
||||
}
|
||||
throw new BadMethodCallException("no field with name '" . $field . "' exists on '" . $this->cm->getName() . "'");
|
||||
}
|
||||
private function completeOwningSide($field, $targetClass, $targetObject)
|
||||
{
|
||||
// add this object on the owning side as well, for obvious infinite recursion
|
||||
// reasons this is only done when called on the inverse side.
|
||||
if (!$this->cm->isAssociationInverseSide($field)) {
|
||||
return;
|
||||
}
|
||||
$mappedByField = $this->cm->getAssociationMappedByTargetField($field);
|
||||
$targetMetadata = self::$objectManager->getClassMetadata($targetClass);
|
||||
$setter = ($targetMetadata->isCollectionValuedAssociation($mappedByField) ? 'add' : 'set') . $mappedByField;
|
||||
$targetObject->{$setter}($this);
|
||||
}
|
||||
private function add($field, $args)
|
||||
{
|
||||
if (!$this->cm->hasAssociation($field) || !$this->cm->isCollectionValuedAssociation($field)) {
|
||||
throw new BadMethodCallException('There is no method add' . $field . '() on ' . $this->cm->getName());
|
||||
}
|
||||
$targetClass = $this->cm->getAssociationTargetClass($field);
|
||||
if ($targetClass !== null && !$args[0] instanceof $targetClass) {
|
||||
throw new InvalidArgumentException("Expected persistent object of type '" . $targetClass . "'");
|
||||
}
|
||||
if (!$this->{$field} instanceof Collection) {
|
||||
$this->{$field} = new ArrayCollection($this->{$field} ?: []);
|
||||
}
|
||||
$this->{$field}->add($args[0]);
|
||||
$this->completeOwningSide($field, $targetClass, $args[0]);
|
||||
}
|
||||
private function initializeDoctrine()
|
||||
{
|
||||
if ($this->cm !== null) {
|
||||
return;
|
||||
}
|
||||
if (!self::$objectManager) {
|
||||
throw new RuntimeException('No runtime object manager set. Call PersistentObject#setObjectManager().');
|
||||
}
|
||||
$this->cm = self::$objectManager->getClassMetadata(static::class);
|
||||
}
|
||||
public function __call($method, $args)
|
||||
{
|
||||
$this->initializeDoctrine();
|
||||
$command = substr($method, 0, 3);
|
||||
$field = lcfirst(substr($method, 3));
|
||||
if ($command === 'set') {
|
||||
$this->set($field, $args);
|
||||
} elseif ($command === 'get') {
|
||||
return $this->get($field);
|
||||
} elseif ($command === 'add') {
|
||||
$this->add($field, $args);
|
||||
} else {
|
||||
throw new BadMethodCallException('There is no method ' . $method . ' on ' . $this->cm->getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
<?php
|
||||
@@ -0,0 +1 @@
|
||||
<?php
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Deprecations\Deprecation;
|
||||
use InvalidArgumentException;
|
||||
use ReflectionClass;
|
||||
use function explode;
|
||||
use function sprintf;
|
||||
use function strpos;
|
||||
abstract class AbstractManagerRegistry implements ManagerRegistry
|
||||
{
|
||||
private $name;
|
||||
private $connections;
|
||||
private $managers;
|
||||
private $defaultConnection;
|
||||
private $defaultManager;
|
||||
private $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;
|
||||
}
|
||||
protected abstract function getService($name);
|
||||
protected abstract function resetService($name);
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
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]);
|
||||
}
|
||||
public function getConnectionNames()
|
||||
{
|
||||
return $this->connections;
|
||||
}
|
||||
public function getConnections()
|
||||
{
|
||||
$connections = [];
|
||||
foreach ($this->connections as $name => $id) {
|
||||
$connections[$name] = $this->getService($id);
|
||||
}
|
||||
return $connections;
|
||||
}
|
||||
public function getDefaultConnectionName()
|
||||
{
|
||||
return $this->defaultConnection;
|
||||
}
|
||||
public function getDefaultManagerName()
|
||||
{
|
||||
return $this->defaultManager;
|
||||
}
|
||||
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]);
|
||||
}
|
||||
public function getManagerForClass($class)
|
||||
{
|
||||
$className = $this->getRealClassName($class);
|
||||
$proxyClass = new ReflectionClass($className);
|
||||
if ($proxyClass->implementsInterface($this->proxyInterfaceName)) {
|
||||
$parentClass = $proxyClass->getParentClass();
|
||||
if (!$parentClass) {
|
||||
return null;
|
||||
}
|
||||
$className = $parentClass->getName();
|
||||
}
|
||||
foreach ($this->managers as $id) {
|
||||
$manager = $this->getService($id);
|
||||
if (!$manager->getMetadataFactory()->isTransient($className)) {
|
||||
return $manager;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public function getManagerNames()
|
||||
{
|
||||
return $this->managers;
|
||||
}
|
||||
public function getManagers()
|
||||
{
|
||||
$dms = [];
|
||||
foreach ($this->managers as $name => $id) {
|
||||
$dms[$name] = $this->getService($id);
|
||||
}
|
||||
return $dms;
|
||||
}
|
||||
public function getRepository($persistentObject, $persistentManagerName = null)
|
||||
{
|
||||
return $this->selectManager($persistentObject, $persistentManagerName)->getRepository($persistentObject);
|
||||
}
|
||||
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();
|
||||
}
|
||||
private function getRealClassName(string $classNameOrAlias) : string
|
||||
{
|
||||
// Check for namespace alias
|
||||
if (strpos($classNameOrAlias, ':') !== \false) {
|
||||
Deprecation::trigger('doctrine/persistence', 'https://github.com/doctrine/persistence/issues/204', 'Short namespace aliases such as "%s" are deprecated, use ::class constant instead.', $classNameOrAlias);
|
||||
[$namespaceAlias, $simpleClassName] = explode(':', $classNameOrAlias, 2);
|
||||
return $this->getAliasNamespace($namespaceAlias) . '\\' . $simpleClassName;
|
||||
}
|
||||
return $classNameOrAlias;
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
interface ConnectionRegistry
|
||||
{
|
||||
public function getDefaultConnectionName();
|
||||
public function getConnection($name = null);
|
||||
public function getConnections();
|
||||
public function getConnectionNames();
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Event;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Common\EventArgs;
|
||||
use MailPoetVendor\Doctrine\Persistence\ObjectManager;
|
||||
class LifecycleEventArgs extends EventArgs
|
||||
{
|
||||
private $objectManager;
|
||||
private $object;
|
||||
public function __construct($object, ObjectManager $objectManager)
|
||||
{
|
||||
$this->object = $object;
|
||||
$this->objectManager = $objectManager;
|
||||
}
|
||||
public function getEntity()
|
||||
{
|
||||
return $this->object;
|
||||
}
|
||||
public function getObject()
|
||||
{
|
||||
return $this->object;
|
||||
}
|
||||
public function getObjectManager()
|
||||
{
|
||||
return $this->objectManager;
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Event;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Common\EventArgs;
|
||||
use MailPoetVendor\Doctrine\Persistence\Mapping\ClassMetadata;
|
||||
use MailPoetVendor\Doctrine\Persistence\ObjectManager;
|
||||
class LoadClassMetadataEventArgs extends EventArgs
|
||||
{
|
||||
private $classMetadata;
|
||||
private $objectManager;
|
||||
public function __construct(ClassMetadata $classMetadata, ObjectManager $objectManager)
|
||||
{
|
||||
$this->classMetadata = $classMetadata;
|
||||
$this->objectManager = $objectManager;
|
||||
}
|
||||
public function getClassMetadata()
|
||||
{
|
||||
return $this->classMetadata;
|
||||
}
|
||||
public function getObjectManager()
|
||||
{
|
||||
return $this->objectManager;
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Event;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Common\EventArgs;
|
||||
use MailPoetVendor\Doctrine\Persistence\ObjectManager;
|
||||
class ManagerEventArgs extends EventArgs
|
||||
{
|
||||
private $objectManager;
|
||||
public function __construct(ObjectManager $objectManager)
|
||||
{
|
||||
$this->objectManager = $objectManager;
|
||||
}
|
||||
public function getObjectManager()
|
||||
{
|
||||
return $this->objectManager;
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Event;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Common\EventArgs;
|
||||
use MailPoetVendor\Doctrine\Persistence\ObjectManager;
|
||||
class OnClearEventArgs extends EventArgs
|
||||
{
|
||||
private $objectManager;
|
||||
private $entityClass;
|
||||
public function __construct($objectManager, $entityClass = null)
|
||||
{
|
||||
$this->objectManager = $objectManager;
|
||||
$this->entityClass = $entityClass;
|
||||
}
|
||||
public function getObjectManager()
|
||||
{
|
||||
return $this->objectManager;
|
||||
}
|
||||
public function getEntityClass()
|
||||
{
|
||||
return $this->entityClass;
|
||||
}
|
||||
public function clearsAllEntities()
|
||||
{
|
||||
return $this->entityClass === null;
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Event;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Persistence\ObjectManager;
|
||||
use InvalidArgumentException;
|
||||
use function get_class;
|
||||
use function sprintf;
|
||||
class PreUpdateEventArgs extends LifecycleEventArgs
|
||||
{
|
||||
private $entityChangeSet;
|
||||
public function __construct($entity, ObjectManager $objectManager, array &$changeSet)
|
||||
{
|
||||
parent::__construct($entity, $objectManager);
|
||||
$this->entityChangeSet =& $changeSet;
|
||||
}
|
||||
public function getEntityChangeSet()
|
||||
{
|
||||
return $this->entityChangeSet;
|
||||
}
|
||||
public function hasChangedField($field)
|
||||
{
|
||||
return isset($this->entityChangeSet[$field]);
|
||||
}
|
||||
public function getOldValue($field)
|
||||
{
|
||||
$this->assertValidField($field);
|
||||
return $this->entityChangeSet[$field][0];
|
||||
}
|
||||
public function getNewValue($field)
|
||||
{
|
||||
$this->assertValidField($field);
|
||||
return $this->entityChangeSet[$field][1];
|
||||
}
|
||||
public function setNewValue($field, $value)
|
||||
{
|
||||
$this->assertValidField($field);
|
||||
$this->entityChangeSet[$field][1] = $value;
|
||||
}
|
||||
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())));
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
<?php
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
interface ManagerRegistry extends ConnectionRegistry
|
||||
{
|
||||
public function getDefaultManagerName();
|
||||
public function getManager($name = null);
|
||||
public function getManagers();
|
||||
public function resetManager($name = null);
|
||||
public function getAliasNamespace($alias);
|
||||
public function getManagerNames();
|
||||
public function getRepository($persistentObject, $persistentManagerName = null);
|
||||
public function getManagerForClass($class);
|
||||
}
|
||||
+248
@@ -0,0 +1,248 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Mapping;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Common\Cache\Cache;
|
||||
use MailPoetVendor\Doctrine\Common\Cache\Psr6\CacheAdapter;
|
||||
use MailPoetVendor\Doctrine\Common\Cache\Psr6\DoctrineProvider;
|
||||
use MailPoetVendor\Doctrine\Deprecations\Deprecation;
|
||||
use MailPoetVendor\Doctrine\Persistence\Mapping\Driver\MappingDriver;
|
||||
use MailPoetVendor\Doctrine\Persistence\Proxy;
|
||||
use MailPoetVendor\Psr\Cache\CacheItemPoolInterface;
|
||||
use ReflectionException;
|
||||
use function array_combine;
|
||||
use function array_keys;
|
||||
use function array_map;
|
||||
use function array_reverse;
|
||||
use function array_unshift;
|
||||
use function assert;
|
||||
use function explode;
|
||||
use function is_array;
|
||||
use function str_replace;
|
||||
use function strpos;
|
||||
use function strrpos;
|
||||
use function substr;
|
||||
abstract class AbstractClassMetadataFactory implements ClassMetadataFactory
|
||||
{
|
||||
protected $cacheSalt = '__CLASSMETADATA__';
|
||||
private $cacheDriver;
|
||||
private $cache;
|
||||
private $loadedMetadata = [];
|
||||
protected $initialized = \false;
|
||||
private $reflectionService = null;
|
||||
private $proxyClassNameResolver = null;
|
||||
public function setCacheDriver(?Cache $cacheDriver = null)
|
||||
{
|
||||
Deprecation::trigger('doctrine/persistence', 'https://github.com/doctrine/persistence/issues/184', '%s is deprecated. Use setCache() with a PSR-6 cache instead.', __METHOD__);
|
||||
$this->cacheDriver = $cacheDriver;
|
||||
if ($cacheDriver === null) {
|
||||
$this->cache = null;
|
||||
return;
|
||||
}
|
||||
$this->cache = CacheAdapter::wrap($cacheDriver);
|
||||
}
|
||||
public function getCacheDriver()
|
||||
{
|
||||
Deprecation::trigger('doctrine/persistence', 'https://github.com/doctrine/persistence/issues/184', '%s is deprecated. Use getCache() instead.', __METHOD__);
|
||||
return $this->cacheDriver;
|
||||
}
|
||||
public function setCache(CacheItemPoolInterface $cache) : void
|
||||
{
|
||||
$this->cache = $cache;
|
||||
$this->cacheDriver = DoctrineProvider::wrap($cache);
|
||||
}
|
||||
protected final function getCache() : ?CacheItemPoolInterface
|
||||
{
|
||||
return $this->cache;
|
||||
}
|
||||
public function getLoadedMetadata()
|
||||
{
|
||||
return $this->loadedMetadata;
|
||||
}
|
||||
public function getAllMetadata()
|
||||
{
|
||||
if (!$this->initialized) {
|
||||
$this->initialize();
|
||||
}
|
||||
$driver = $this->getDriver();
|
||||
$metadata = [];
|
||||
foreach ($driver->getAllClassNames() as $className) {
|
||||
$metadata[] = $this->getMetadataFor($className);
|
||||
}
|
||||
return $metadata;
|
||||
}
|
||||
public function setProxyClassNameResolver(ProxyClassNameResolver $resolver) : void
|
||||
{
|
||||
$this->proxyClassNameResolver = $resolver;
|
||||
}
|
||||
protected abstract function initialize();
|
||||
protected abstract function getFqcnFromAlias($namespaceAlias, $simpleClassName);
|
||||
protected abstract function getDriver();
|
||||
protected abstract function wakeupReflection(ClassMetadata $class, ReflectionService $reflService);
|
||||
protected abstract function initializeReflection(ClassMetadata $class, ReflectionService $reflService);
|
||||
protected abstract function isEntity(ClassMetadata $class);
|
||||
public function getMetadataFor($className)
|
||||
{
|
||||
if (isset($this->loadedMetadata[$className])) {
|
||||
return $this->loadedMetadata[$className];
|
||||
}
|
||||
// Check for namespace alias
|
||||
if (strpos($className, ':') !== \false) {
|
||||
Deprecation::trigger('doctrine/persistence', 'https://github.com/doctrine/persistence/issues/204', 'Short namespace aliases such as "%s" are deprecated, use ::class constant instead.', $className);
|
||||
[$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->cache) {
|
||||
$cached = $this->cache->getItem($this->getCacheKey($realClassName))->get();
|
||||
if ($cached instanceof ClassMetadata) {
|
||||
$this->loadedMetadata[$realClassName] = $cached;
|
||||
$this->wakeupReflection($cached, $this->getReflectionService());
|
||||
} else {
|
||||
$loadedMetadata = $this->loadMetadata($realClassName);
|
||||
$classNames = array_combine(array_map([$this, 'getCacheKey'], $loadedMetadata), $loadedMetadata);
|
||||
assert(is_array($classNames));
|
||||
foreach ($this->cache->getItems(array_keys($classNames)) as $item) {
|
||||
if (!isset($classNames[$item->getKey()])) {
|
||||
continue;
|
||||
}
|
||||
$item->set($this->loadedMetadata[$classNames[$item->getKey()]]);
|
||||
$this->cache->saveDeferred($item);
|
||||
}
|
||||
$this->cache->commit();
|
||||
}
|
||||
} 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];
|
||||
}
|
||||
public function hasMetadataFor($className)
|
||||
{
|
||||
return isset($this->loadedMetadata[$className]);
|
||||
}
|
||||
public function setMetadataFor($className, $class)
|
||||
{
|
||||
$this->loadedMetadata[$className] = $class;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
protected function onNotFoundMetadata($className)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
protected abstract function doLoadMetadata($class, $parent, $rootEntityFound, array $nonSuperclassParents);
|
||||
protected abstract function newClassMetadataInstance($className);
|
||||
public function isTransient($className)
|
||||
{
|
||||
if (!$this->initialized) {
|
||||
$this->initialize();
|
||||
}
|
||||
// Check for namespace alias
|
||||
if (strpos($className, ':') !== \false) {
|
||||
Deprecation::trigger('doctrine/persistence', 'https://github.com/doctrine/persistence/issues/204', 'Short namespace aliases such as "%s" are deprecated, use ::class constant instead.', $className);
|
||||
[$namespaceAlias, $simpleClassName] = explode(':', $className, 2);
|
||||
$className = $this->getFqcnFromAlias($namespaceAlias, $simpleClassName);
|
||||
}
|
||||
return $this->getDriver()->isTransient($className);
|
||||
}
|
||||
public function setReflectionService(ReflectionService $reflectionService)
|
||||
{
|
||||
$this->reflectionService = $reflectionService;
|
||||
}
|
||||
public function getReflectionService()
|
||||
{
|
||||
if ($this->reflectionService === null) {
|
||||
$this->reflectionService = new RuntimeReflectionService();
|
||||
}
|
||||
return $this->reflectionService;
|
||||
}
|
||||
protected function getCacheKey(string $realClassName) : string
|
||||
{
|
||||
return str_replace('\\', '__', $realClassName) . $this->cacheSalt;
|
||||
}
|
||||
private function getRealClass(string $class) : string
|
||||
{
|
||||
if ($this->proxyClassNameResolver === null) {
|
||||
$this->createDefaultProxyClassNameResolver();
|
||||
}
|
||||
assert($this->proxyClassNameResolver !== null);
|
||||
return $this->proxyClassNameResolver->resolveClassName($class);
|
||||
}
|
||||
private function createDefaultProxyClassNameResolver() : void
|
||||
{
|
||||
$this->proxyClassNameResolver = new class implements ProxyClassNameResolver
|
||||
{
|
||||
public function resolveClassName(string $className) : string
|
||||
{
|
||||
$pos = strrpos($className, '\\' . Proxy::MARKER . '\\');
|
||||
if ($pos === \false) {
|
||||
return $className;
|
||||
}
|
||||
return substr($className, $pos + Proxy::MARKER_LENGTH + 2);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Mapping;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use ReflectionClass;
|
||||
interface ClassMetadata
|
||||
{
|
||||
public function getName();
|
||||
public function getIdentifier();
|
||||
public function getReflectionClass();
|
||||
public function isIdentifier($fieldName);
|
||||
public function hasField($fieldName);
|
||||
public function hasAssociation($fieldName);
|
||||
public function isSingleValuedAssociation($fieldName);
|
||||
public function isCollectionValuedAssociation($fieldName);
|
||||
public function getFieldNames();
|
||||
public function getIdentifierFieldNames();
|
||||
public function getAssociationNames();
|
||||
public function getTypeOfField($fieldName);
|
||||
public function getAssociationTargetClass($assocName);
|
||||
public function isAssociationInverseSide($assocName);
|
||||
public function getAssociationMappedByTargetField($assocName);
|
||||
public function getIdentifierValues($object);
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Mapping;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
interface ClassMetadataFactory
|
||||
{
|
||||
public function getAllMetadata();
|
||||
public function getMetadataFor($className);
|
||||
public function hasMetadataFor($className);
|
||||
public function setMetadataFor($className, $class);
|
||||
public function isTransient($className);
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Mapping\Driver;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Common\Annotations\Reader;
|
||||
use ReflectionClass;
|
||||
use function get_class;
|
||||
abstract class AnnotationDriver implements MappingDriver
|
||||
{
|
||||
use ColocatedMappingDriver;
|
||||
protected $reader;
|
||||
protected $entityAnnotationClasses = [];
|
||||
public function __construct($reader, $paths = null)
|
||||
{
|
||||
$this->reader = $reader;
|
||||
$this->addPaths((array) $paths);
|
||||
}
|
||||
public function getReader()
|
||||
{
|
||||
return $this->reader;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Mapping\Driver;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\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 assert;
|
||||
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;
|
||||
trait ColocatedMappingDriver
|
||||
{
|
||||
protected $paths = [];
|
||||
protected $excludePaths = [];
|
||||
protected $fileExtension = '.php';
|
||||
protected $classNames;
|
||||
public function addPaths(array $paths)
|
||||
{
|
||||
$this->paths = array_unique(array_merge($this->paths, $paths));
|
||||
}
|
||||
public function getPaths()
|
||||
{
|
||||
return $this->paths;
|
||||
}
|
||||
public function addExcludePaths(array $paths)
|
||||
{
|
||||
$this->excludePaths = array_unique(array_merge($this->excludePaths, $paths));
|
||||
}
|
||||
public function getExcludePaths()
|
||||
{
|
||||
return $this->excludePaths;
|
||||
}
|
||||
public function getFileExtension()
|
||||
{
|
||||
return $this->fileExtension;
|
||||
}
|
||||
public function setFileExtension(string $fileExtension)
|
||||
{
|
||||
$this->fileExtension = $fileExtension;
|
||||
}
|
||||
public abstract function isTransient($className);
|
||||
public function getAllClassNames()
|
||||
{
|
||||
if ($this->classNames !== null) {
|
||||
return $this->classNames;
|
||||
}
|
||||
if (!$this->paths) {
|
||||
throw MappingException::pathRequiredForDriver(static::class);
|
||||
}
|
||||
$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) === 0) {
|
||||
$sourceFile = realpath($sourceFile);
|
||||
}
|
||||
foreach ($this->excludePaths as $excludePath) {
|
||||
$realExcludePath = realpath($excludePath);
|
||||
assert($realExcludePath !== \false);
|
||||
$exclude = str_replace('\\', '/', $realExcludePath);
|
||||
$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;
|
||||
}
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Mapping\Driver;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Persistence\Mapping\MappingException;
|
||||
use RecursiveDirectoryIterator;
|
||||
use RecursiveIteratorIterator;
|
||||
use function array_merge;
|
||||
use function array_unique;
|
||||
use function is_dir;
|
||||
use function is_file;
|
||||
use function str_replace;
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
class DefaultFileLocator implements FileLocator
|
||||
{
|
||||
protected $paths = [];
|
||||
protected $fileExtension;
|
||||
public function __construct($paths, $fileExtension = null)
|
||||
{
|
||||
$this->addPaths((array) $paths);
|
||||
$this->fileExtension = $fileExtension;
|
||||
}
|
||||
public function addPaths(array $paths)
|
||||
{
|
||||
$this->paths = array_unique(array_merge($this->paths, $paths));
|
||||
}
|
||||
public function getPaths()
|
||||
{
|
||||
return $this->paths;
|
||||
}
|
||||
public function getFileExtension()
|
||||
{
|
||||
return $this->fileExtension;
|
||||
}
|
||||
public function setFileExtension($fileExtension)
|
||||
{
|
||||
$this->fileExtension = $fileExtension;
|
||||
}
|
||||
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);
|
||||
}
|
||||
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!
|
||||
$class = str_replace('.', '\\', $fileName);
|
||||
$classes[] = $class;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $classes;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Mapping\Driver;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Persistence\Mapping\ClassMetadata;
|
||||
use MailPoetVendor\Doctrine\Persistence\Mapping\MappingException;
|
||||
use function array_keys;
|
||||
use function array_merge;
|
||||
use function array_unique;
|
||||
use function array_values;
|
||||
use function is_file;
|
||||
use function str_replace;
|
||||
abstract class FileDriver implements MappingDriver
|
||||
{
|
||||
protected $locator;
|
||||
protected $classCache;
|
||||
protected $globalBasename;
|
||||
public function __construct($locator, $fileExtension = null)
|
||||
{
|
||||
if ($locator instanceof FileLocator) {
|
||||
$this->locator = $locator;
|
||||
} else {
|
||||
$this->locator = new DefaultFileLocator((array) $locator, $fileExtension);
|
||||
}
|
||||
}
|
||||
public function setGlobalBasename($file)
|
||||
{
|
||||
$this->globalBasename = $file;
|
||||
}
|
||||
public function getGlobalBasename()
|
||||
{
|
||||
return $this->globalBasename;
|
||||
}
|
||||
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];
|
||||
}
|
||||
public function isTransient($className)
|
||||
{
|
||||
if ($this->classCache === null) {
|
||||
$this->initialize();
|
||||
}
|
||||
if (isset($this->classCache[$className])) {
|
||||
return \false;
|
||||
}
|
||||
return !$this->locator->fileExists($className);
|
||||
}
|
||||
public function getAllClassNames()
|
||||
{
|
||||
if ($this->classCache === null) {
|
||||
$this->initialize();
|
||||
}
|
||||
if (!$this->classCache) {
|
||||
return (array) $this->locator->getAllClassNames($this->globalBasename);
|
||||
}
|
||||
return array_values(array_unique(array_merge(array_keys($this->classCache), (array) $this->locator->getAllClassNames($this->globalBasename))));
|
||||
}
|
||||
protected abstract function loadMappingFile($file);
|
||||
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));
|
||||
}
|
||||
}
|
||||
public function getLocator()
|
||||
{
|
||||
return $this->locator;
|
||||
}
|
||||
public function setLocator(FileLocator $locator)
|
||||
{
|
||||
$this->locator = $locator;
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Mapping\Driver;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
interface FileLocator
|
||||
{
|
||||
public function findMappingFile($className);
|
||||
public function getAllClassNames($globalBasename);
|
||||
public function fileExists($className);
|
||||
public function getPaths();
|
||||
public function getFileExtension();
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Mapping\Driver;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Persistence\Mapping\ClassMetadata;
|
||||
interface MappingDriver
|
||||
{
|
||||
public function loadMetadataForClass($className, ClassMetadata $metadata);
|
||||
public function getAllClassNames();
|
||||
public function isTransient($className);
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Mapping\Driver;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Persistence\Mapping\ClassMetadata;
|
||||
use MailPoetVendor\Doctrine\Persistence\Mapping\MappingException;
|
||||
use function array_keys;
|
||||
use function assert;
|
||||
use function spl_object_hash;
|
||||
use function strpos;
|
||||
class MappingDriverChain implements MappingDriver
|
||||
{
|
||||
private $defaultDriver;
|
||||
private $drivers = [];
|
||||
public function getDefaultDriver()
|
||||
{
|
||||
return $this->defaultDriver;
|
||||
}
|
||||
public function setDefaultDriver(MappingDriver $driver)
|
||||
{
|
||||
$this->defaultDriver = $driver;
|
||||
}
|
||||
public function addDriver(MappingDriver $nestedDriver, $namespace)
|
||||
{
|
||||
$this->drivers[$namespace] = $nestedDriver;
|
||||
}
|
||||
public function getDrivers()
|
||||
{
|
||||
return $this->drivers;
|
||||
}
|
||||
public function loadMetadataForClass($className, ClassMetadata $metadata)
|
||||
{
|
||||
foreach ($this->drivers as $namespace => $driver) {
|
||||
assert($driver instanceof MappingDriver);
|
||||
if (strpos($className, $namespace) === 0) {
|
||||
$driver->loadMetadataForClass($className, $metadata);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ($this->defaultDriver !== null) {
|
||||
$this->defaultDriver->loadMetadataForClass($className, $metadata);
|
||||
return;
|
||||
}
|
||||
throw MappingException::classNotFoundInNamespaces($className, array_keys($this->drivers));
|
||||
}
|
||||
public function getAllClassNames()
|
||||
{
|
||||
$classNames = [];
|
||||
$driverClasses = [];
|
||||
foreach ($this->drivers as $namespace => $driver) {
|
||||
assert($driver instanceof MappingDriver);
|
||||
$oid = spl_object_hash($driver);
|
||||
if (!isset($driverClasses[$oid])) {
|
||||
$driverClasses[$oid] = $driver->getAllClassNames();
|
||||
}
|
||||
foreach ($driverClasses[$oid] as $className) {
|
||||
if (strpos($className, $namespace) !== 0) {
|
||||
continue;
|
||||
}
|
||||
$classNames[$className] = \true;
|
||||
}
|
||||
}
|
||||
if ($this->defaultDriver !== null) {
|
||||
foreach ($this->defaultDriver->getAllClassNames() as $className) {
|
||||
$classNames[$className] = \true;
|
||||
}
|
||||
}
|
||||
return array_keys($classNames);
|
||||
}
|
||||
public function isTransient($className)
|
||||
{
|
||||
foreach ($this->drivers as $namespace => $driver) {
|
||||
assert($driver instanceof MappingDriver);
|
||||
if (strpos($className, $namespace) === 0) {
|
||||
return $driver->isTransient($className);
|
||||
}
|
||||
}
|
||||
if ($this->defaultDriver !== null) {
|
||||
return $this->defaultDriver->isTransient($className);
|
||||
}
|
||||
return \true;
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Mapping\Driver;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Persistence\Mapping\ClassMetadata;
|
||||
class PHPDriver extends FileDriver
|
||||
{
|
||||
protected $metadata;
|
||||
public function __construct($locator)
|
||||
{
|
||||
parent::__construct($locator, '.php');
|
||||
}
|
||||
public function loadMetadataForClass($className, ClassMetadata $metadata)
|
||||
{
|
||||
$this->metadata = $metadata;
|
||||
$this->loadMappingFile($this->locator->findMappingFile($className));
|
||||
}
|
||||
protected function loadMappingFile($file)
|
||||
{
|
||||
$metadata = $this->metadata;
|
||||
include $file;
|
||||
return [$metadata->getName() => $metadata];
|
||||
}
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Mapping\Driver;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Persistence\Mapping\ClassMetadata;
|
||||
use MailPoetVendor\Doctrine\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;
|
||||
class StaticPHPDriver implements MappingDriver
|
||||
{
|
||||
private $paths = [];
|
||||
private $classNames;
|
||||
public function __construct($paths)
|
||||
{
|
||||
$this->addPaths((array) $paths);
|
||||
}
|
||||
public function addPaths(array $paths)
|
||||
{
|
||||
$this->paths = array_unique(array_merge($this->paths, $paths));
|
||||
}
|
||||
public function loadMetadataForClass($className, ClassMetadata $metadata)
|
||||
{
|
||||
$className::loadMetadata($metadata);
|
||||
}
|
||||
public function getAllClassNames()
|
||||
{
|
||||
if ($this->classNames !== null) {
|
||||
return $this->classNames;
|
||||
}
|
||||
if (!$this->paths) {
|
||||
throw MappingException::pathRequiredForDriver(static::class);
|
||||
}
|
||||
$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;
|
||||
}
|
||||
public function isTransient($className)
|
||||
{
|
||||
return !method_exists($className, 'loadMetadata');
|
||||
}
|
||||
}
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Mapping\Driver;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Persistence\Mapping\MappingException;
|
||||
use InvalidArgumentException;
|
||||
use RecursiveDirectoryIterator;
|
||||
use RecursiveIteratorIterator;
|
||||
use function array_keys;
|
||||
use function array_merge;
|
||||
use function assert;
|
||||
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;
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
class SymfonyFileLocator implements FileLocator
|
||||
{
|
||||
protected $paths = [];
|
||||
protected $prefixes = [];
|
||||
protected $fileExtension;
|
||||
private $nsSeparator;
|
||||
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;
|
||||
}
|
||||
public function addNamespacePrefixes(array $prefixes)
|
||||
{
|
||||
$this->prefixes = array_merge($this->prefixes, $prefixes);
|
||||
$this->paths = array_merge($this->paths, array_keys($prefixes));
|
||||
}
|
||||
public function getNamespacePrefixes()
|
||||
{
|
||||
return $this->prefixes;
|
||||
}
|
||||
public function getPaths()
|
||||
{
|
||||
return $this->paths;
|
||||
}
|
||||
public function getFileExtension()
|
||||
{
|
||||
return $this->fileExtension;
|
||||
}
|
||||
public function setFileExtension($fileExtension)
|
||||
{
|
||||
$this->fileExtension = $fileExtension;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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
|
||||
$basepath = realpath($path);
|
||||
$filepath = realpath($file->getPath());
|
||||
assert($basepath !== \false);
|
||||
assert($filepath !== \false);
|
||||
$nsSuffix = strtr(substr($filepath, strlen($basepath)), $this->nsSeparator, '\\');
|
||||
$class = $this->prefixes[$path] . str_replace(DIRECTORY_SEPARATOR, '\\', $nsSuffix) . '\\' . str_replace($this->nsSeparator, '\\', $fileName);
|
||||
} else {
|
||||
$class = str_replace($this->nsSeparator, '\\', $fileName);
|
||||
}
|
||||
$classes[] = $class;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $classes;
|
||||
}
|
||||
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, (int) strrpos($className, '\\') + 1) . $this->fileExtension);
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
<?php
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Mapping;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use Exception;
|
||||
use function implode;
|
||||
use function sprintf;
|
||||
class MappingException extends Exception
|
||||
{
|
||||
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)));
|
||||
}
|
||||
public static function pathRequired()
|
||||
{
|
||||
return new self('Specifying the paths to your entities is required ' . 'in the AnnotationDriver to retrieve all class names.');
|
||||
}
|
||||
public static function pathRequiredForDriver(string $driverClassName) : self
|
||||
{
|
||||
return new self(sprintf('Specifying the paths to your entities is required when using %s to retrieve all class names.', $driverClassName));
|
||||
}
|
||||
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!', (string) $path));
|
||||
}
|
||||
public static function mappingFileNotFound($entityName, $fileName)
|
||||
{
|
||||
return new self(sprintf("No mapping file found named '%s' for class '%s'.", $fileName, $entityName));
|
||||
}
|
||||
public static function invalidMappingFile($entityName, $fileName)
|
||||
{
|
||||
return new self(sprintf("Invalid mapping file '%s' for class '%s'.", $fileName, $entityName));
|
||||
}
|
||||
public static function nonExistingClass($className)
|
||||
{
|
||||
return new self(sprintf("Class '%s' does not exist", $className));
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Mapping;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Persistence\Proxy;
|
||||
interface ProxyClassNameResolver
|
||||
{
|
||||
public function resolveClassName(string $className) : string;
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Mapping;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use ReflectionClass;
|
||||
use ReflectionProperty;
|
||||
interface ReflectionService
|
||||
{
|
||||
public function getParentClasses($class);
|
||||
public function getClassShortName($class);
|
||||
public function getClassNamespace($class);
|
||||
public function getClass($class);
|
||||
public function getAccessibleProperty($class, $property);
|
||||
public function hasPublicMethod($class, $method);
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Mapping;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Persistence\Reflection\RuntimePublicReflectionProperty;
|
||||
use MailPoetVendor\Doctrine\Persistence\Reflection\TypedNoDefaultReflectionProperty;
|
||||
use MailPoetVendor\Doctrine\Persistence\Reflection\TypedNoDefaultRuntimePublicReflectionProperty;
|
||||
use ReflectionClass;
|
||||
use ReflectionException;
|
||||
use ReflectionMethod;
|
||||
use ReflectionProperty;
|
||||
use function array_key_exists;
|
||||
use function assert;
|
||||
use function class_exists;
|
||||
use function class_parents;
|
||||
use function phpversion;
|
||||
use function version_compare;
|
||||
class RuntimeReflectionService implements ReflectionService
|
||||
{
|
||||
private $supportsTypedPropertiesWorkaround;
|
||||
public function __construct()
|
||||
{
|
||||
$this->supportsTypedPropertiesWorkaround = version_compare((string) phpversion(), '7.4.0') >= 0;
|
||||
}
|
||||
public function getParentClasses($class)
|
||||
{
|
||||
if (!class_exists($class)) {
|
||||
throw MappingException::nonExistingClass($class);
|
||||
}
|
||||
$parents = class_parents($class);
|
||||
assert($parents !== \false);
|
||||
return $parents;
|
||||
}
|
||||
public function getClassShortName($class)
|
||||
{
|
||||
$reflectionClass = new ReflectionClass($class);
|
||||
return $reflectionClass->getShortName();
|
||||
}
|
||||
public function getClassNamespace($class)
|
||||
{
|
||||
$reflectionClass = new ReflectionClass($class);
|
||||
return $reflectionClass->getNamespaceName();
|
||||
}
|
||||
public function getClass($class)
|
||||
{
|
||||
return new ReflectionClass($class);
|
||||
}
|
||||
public function getAccessibleProperty($class, $property)
|
||||
{
|
||||
$reflectionProperty = new ReflectionProperty($class, $property);
|
||||
if ($this->supportsTypedPropertiesWorkaround && !array_key_exists($property, $this->getClass($class)->getDefaultProperties())) {
|
||||
if ($reflectionProperty->isPublic()) {
|
||||
$reflectionProperty = new TypedNoDefaultRuntimePublicReflectionProperty($class, $property);
|
||||
} else {
|
||||
$reflectionProperty = new TypedNoDefaultReflectionProperty($class, $property);
|
||||
}
|
||||
} elseif ($reflectionProperty->isPublic()) {
|
||||
$reflectionProperty = new RuntimePublicReflectionProperty($class, $property);
|
||||
}
|
||||
$reflectionProperty->setAccessible(\true);
|
||||
return $reflectionProperty;
|
||||
}
|
||||
public function hasPublicMethod($class, $method)
|
||||
{
|
||||
try {
|
||||
$reflectionMethod = new ReflectionMethod($class, $method);
|
||||
} catch (ReflectionException $e) {
|
||||
return \false;
|
||||
}
|
||||
return $reflectionMethod->isPublic();
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Mapping;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use function strpos;
|
||||
use function strrev;
|
||||
use function strrpos;
|
||||
use function substr;
|
||||
class StaticReflectionService implements ReflectionService
|
||||
{
|
||||
public function getParentClasses($class)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
public function getClassShortName($class)
|
||||
{
|
||||
$nsSeparatorLastPosition = strrpos($class, '\\');
|
||||
if ($nsSeparatorLastPosition !== \false) {
|
||||
$class = substr($class, $nsSeparatorLastPosition + 1);
|
||||
}
|
||||
return $class;
|
||||
}
|
||||
public function getClassNamespace($class)
|
||||
{
|
||||
$namespace = '';
|
||||
if (strpos($class, '\\') !== \false) {
|
||||
$namespace = strrev(substr(strrev($class), (int) strpos(strrev($class), '\\') + 1));
|
||||
}
|
||||
return $namespace;
|
||||
}
|
||||
public function getClass($class)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
public function getAccessibleProperty($class, $property)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
public function hasPublicMethod($class, $method)
|
||||
{
|
||||
return \true;
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
<?php
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
interface NotifyPropertyChanged
|
||||
{
|
||||
public function addPropertyChangedListener(PropertyChangedListener $listener);
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Persistence\Mapping\ClassMetadata;
|
||||
use MailPoetVendor\Doctrine\Persistence\Mapping\ClassMetadataFactory;
|
||||
interface ObjectManager
|
||||
{
|
||||
public function find($className, $id);
|
||||
public function persist($object);
|
||||
public function remove($object);
|
||||
public function merge($object);
|
||||
public function clear($objectName = null);
|
||||
public function detach($object);
|
||||
public function refresh($object);
|
||||
public function flush();
|
||||
public function getRepository($className);
|
||||
public function getClassMetadata($className);
|
||||
public function getMetadataFactory();
|
||||
public function initializeObject($obj);
|
||||
public function contains($object);
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Persistence\Mapping\ClassMetadata;
|
||||
interface ObjectManagerAware
|
||||
{
|
||||
public function injectObjectManager(ObjectManager $objectManager, ClassMetadata $classMetadata);
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
abstract class ObjectManagerDecorator implements ObjectManager
|
||||
{
|
||||
protected $wrapped;
|
||||
public function find($className, $id)
|
||||
{
|
||||
return $this->wrapped->find($className, $id);
|
||||
}
|
||||
public function persist($object)
|
||||
{
|
||||
$this->wrapped->persist($object);
|
||||
}
|
||||
public function remove($object)
|
||||
{
|
||||
$this->wrapped->remove($object);
|
||||
}
|
||||
public function merge($object)
|
||||
{
|
||||
return $this->wrapped->merge($object);
|
||||
}
|
||||
public function clear($objectName = null)
|
||||
{
|
||||
$this->wrapped->clear($objectName);
|
||||
}
|
||||
public function detach($object)
|
||||
{
|
||||
$this->wrapped->detach($object);
|
||||
}
|
||||
public function refresh($object)
|
||||
{
|
||||
$this->wrapped->refresh($object);
|
||||
}
|
||||
public function flush()
|
||||
{
|
||||
$this->wrapped->flush();
|
||||
}
|
||||
public function getRepository($className)
|
||||
{
|
||||
return $this->wrapped->getRepository($className);
|
||||
}
|
||||
public function getClassMetadata($className)
|
||||
{
|
||||
return $this->wrapped->getClassMetadata($className);
|
||||
}
|
||||
public function getMetadataFactory()
|
||||
{
|
||||
return $this->wrapped->getMetadataFactory();
|
||||
}
|
||||
public function initializeObject($obj)
|
||||
{
|
||||
$this->wrapped->initializeObject($obj);
|
||||
}
|
||||
public function contains($object)
|
||||
{
|
||||
return $this->wrapped->contains($object);
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use UnexpectedValueException;
|
||||
interface ObjectRepository
|
||||
{
|
||||
public function find($id);
|
||||
public function findAll();
|
||||
public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null);
|
||||
public function findOneBy(array $criteria);
|
||||
public function getClassName();
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
interface PropertyChangedListener
|
||||
{
|
||||
public function propertyChanged($sender, $propertyName, $oldValue, $newValue);
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
interface Proxy
|
||||
{
|
||||
public const MARKER = '__CG__';
|
||||
public const MARKER_LENGTH = 6;
|
||||
public function __load();
|
||||
public function __isInitialized();
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Reflection;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use BackedEnum;
|
||||
use ReflectionProperty;
|
||||
use ReturnTypeWillChange;
|
||||
class EnumReflectionProperty extends ReflectionProperty
|
||||
{
|
||||
private $originalReflectionProperty;
|
||||
private $enumType;
|
||||
public function __construct(ReflectionProperty $originalReflectionProperty, string $enumType)
|
||||
{
|
||||
$this->originalReflectionProperty = $originalReflectionProperty;
|
||||
$this->enumType = $enumType;
|
||||
}
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getValue($object = null)
|
||||
{
|
||||
if ($object === null) {
|
||||
return null;
|
||||
}
|
||||
$enum = $this->originalReflectionProperty->getValue($object);
|
||||
if ($enum === null) {
|
||||
return null;
|
||||
}
|
||||
return $enum->value;
|
||||
}
|
||||
public function setValue($object, $value = null) : void
|
||||
{
|
||||
if ($value !== null) {
|
||||
$value = $this->enumType::from($value);
|
||||
}
|
||||
$this->originalReflectionProperty->setValue($object, $value);
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Reflection;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Common\Proxy\Proxy;
|
||||
use ReflectionProperty;
|
||||
use ReturnTypeWillChange;
|
||||
class RuntimePublicReflectionProperty extends ReflectionProperty
|
||||
{
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getValue($object = null)
|
||||
{
|
||||
$name = $this->getName();
|
||||
if ($object instanceof Proxy && !$object->__isInitialized()) {
|
||||
$originalInitializer = $object->__getInitializer();
|
||||
$object->__setInitializer(null);
|
||||
$val = $object->{$name} ?? null;
|
||||
$object->__setInitializer($originalInitializer);
|
||||
return $val;
|
||||
}
|
||||
return isset($object->{$name}) ? parent::getValue($object) : null;
|
||||
}
|
||||
#[\ReturnTypeWillChange]
|
||||
public function setValue($object, $value = null)
|
||||
{
|
||||
if (!($object instanceof Proxy && !$object->__isInitialized())) {
|
||||
parent::setValue($object, $value);
|
||||
return;
|
||||
}
|
||||
$originalInitializer = $object->__getInitializer();
|
||||
$object->__setInitializer(null);
|
||||
parent::setValue($object, $value);
|
||||
$object->__setInitializer($originalInitializer);
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Reflection;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use ReflectionProperty;
|
||||
class TypedNoDefaultReflectionProperty extends ReflectionProperty
|
||||
{
|
||||
use TypedNoDefaultReflectionPropertyBase;
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Reflection;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use Closure;
|
||||
use ReturnTypeWillChange;
|
||||
use function assert;
|
||||
trait TypedNoDefaultReflectionPropertyBase
|
||||
{
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getValue($object = null)
|
||||
{
|
||||
return $object !== null && $this->isInitialized($object) ? parent::getValue($object) : null;
|
||||
}
|
||||
#[\ReturnTypeWillChange]
|
||||
public function setValue($object, $value = null)
|
||||
{
|
||||
if ($value === null && $this->hasType() && !$this->getType()->allowsNull()) {
|
||||
$propertyName = $this->getName();
|
||||
$unsetter = function () use($propertyName) : void {
|
||||
unset($this->{$propertyName});
|
||||
};
|
||||
$unsetter = $unsetter->bindTo($object, $this->getDeclaringClass()->getName());
|
||||
assert($unsetter instanceof Closure);
|
||||
$unsetter();
|
||||
return;
|
||||
}
|
||||
parent::setValue($object, $value);
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Persistence\Reflection;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
class TypedNoDefaultRuntimePublicReflectionProperty extends RuntimePublicReflectionProperty
|
||||
{
|
||||
use TypedNoDefaultReflectionPropertyBase;
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
<?php
|
||||
+1
@@ -0,0 +1 @@
|
||||
<?php
|
||||
@@ -0,0 +1 @@
|
||||
<?php
|
||||
Reference in New Issue
Block a user