This commit is contained in:
emmymayo
2025-02-05 23:15:46 +01:00
commit 7269c99357
16995 changed files with 3389680 additions and 0 deletions
@@ -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());
}
}
}
@@ -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;
}
}
@@ -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();
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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())));
}
}
}
@@ -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);
}
@@ -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);
}
};
}
}
@@ -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);
}
@@ -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);
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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();
}
@@ -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);
}
@@ -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;
}
}
@@ -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];
}
}
@@ -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');
}
}
@@ -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);
}
}
@@ -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));
}
}
@@ -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;
}
@@ -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);
}
@@ -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();
}
}
@@ -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;
}
}
@@ -0,0 +1,7 @@
<?php
namespace MailPoetVendor\Doctrine\Persistence;
if (!defined('ABSPATH')) exit;
interface NotifyPropertyChanged
{
public function addPropertyChangedListener(PropertyChangedListener $listener);
}
@@ -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);
}
@@ -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);
}
@@ -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);
}
}
@@ -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();
}
@@ -0,0 +1,7 @@
<?php
namespace MailPoetVendor\Doctrine\Persistence;
if (!defined('ABSPATH')) exit;
interface PropertyChangedListener
{
public function propertyChanged($sender, $propertyName, $oldValue, $newValue);
}
@@ -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();
}
@@ -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);
}
}
@@ -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);
}
}
@@ -0,0 +1,8 @@
<?php
namespace MailPoetVendor\Doctrine\Persistence\Reflection;
if (!defined('ABSPATH')) exit;
use ReflectionProperty;
class TypedNoDefaultReflectionProperty extends ReflectionProperty
{
use TypedNoDefaultReflectionPropertyBase;
}
@@ -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);
}
}
@@ -0,0 +1,7 @@
<?php
namespace MailPoetVendor\Doctrine\Persistence\Reflection;
if (!defined('ABSPATH')) exit;
class TypedNoDefaultRuntimePublicReflectionProperty extends RuntimePublicReflectionProperty
{
use TypedNoDefaultReflectionPropertyBase;
}