Subida del módulo y tema de PrestaShop

This commit is contained in:
Kaloyan
2026-04-09 18:31:51 +02:00
parent 12c253296f
commit 16b3ff9424
39262 changed files with 7418797 additions and 0 deletions

19
vendor/doctrine/common/LICENSE vendored Normal file
View File

@@ -0,0 +1,19 @@
Copyright (c) 2006-2015 Doctrine Project
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

39
vendor/doctrine/common/UPGRADE_TO_2_1 vendored Normal file
View File

@@ -0,0 +1,39 @@
This document details all the possible changes that you should investigate when updating
your project from Doctrine Common 2.0.x to 2.1
## AnnotationReader changes
The annotation reader was heavily refactored between 2.0 and 2.1-RC1. In theory the operation of the new reader should be backwards compatible, but it has to be setup differently to work that way:
$reader = new \Doctrine\Common\Annotations\AnnotationReader();
$reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\');
// new code necessary starting here
$reader->setIgnoreNotImportedAnnotations(true);
$reader->setEnableParsePhpImports(false);
$reader = new \Doctrine\Common\Annotations\CachedReader(
new \Doctrine\Common\Annotations\IndexedReader($reader), new ArrayCache()
);
## Annotation Base class or @Annotation
Beginning after 2.1-RC2 you have to either extend ``Doctrine\Common\Annotations\Annotation`` or add @Annotation to your annotations class-level docblock, otherwise the class will simply be ignored.
## Removed methods on AnnotationReader
* AnnotationReader::setAutoloadAnnotations()
* AnnotationReader::getAutoloadAnnotations()
* AnnotationReader::isAutoloadAnnotations()
## AnnotationRegistry
Autoloading through the PHP autoloader is removed from the 2.1 AnnotationReader. Instead you have to use the global AnnotationRegistry for loading purposes:
\Doctrine\Common\Annotations\AnnotationRegistry::registerFile($fileWithAnnotations);
\Doctrine\Common\Annotations\AnnotationRegistry::registerAutoloadNamespace($namespace, $dirs = null);
\Doctrine\Common\Annotations\AnnotationRegistry::registerAutoloadNamespaces($namespaces);
\Doctrine\Common\Annotations\AnnotationRegistry::registerLoader($callable);
The $callable for registering a loader accepts a class as first and only parameter and must try to silently autoload it. On success true has to be returned.
The registerAutoloadNamespace function registers a PSR-0 compatible silent autoloader for all classes with the given namespace in the given directories.
If null is passed as directory the include path will be used.

61
vendor/doctrine/common/UPGRADE_TO_2_2 vendored Normal file
View File

@@ -0,0 +1,61 @@
This document details all the possible changes that you should investigate when
updating your project from Doctrine Common 2.1 to 2.2:
## Annotation Changes
- AnnotationReader::setIgnoreNotImportedAnnotations has been removed, you need to
add ignore annotation names which are supposed to be ignored via
AnnotationReader::addGlobalIgnoredName
- AnnotationReader::setAutoloadAnnotations was deprecated by the AnnotationRegistry
in 2.1 and has been removed in 2.2
- AnnotationReader::setEnableParsePhpImports was added to ease transition to the new
annotation mechanism in 2.1 and is removed in 2.2
- AnnotationReader::isParsePhpImportsEnabled is removed (see above)
- AnnotationReader::setDefaultAnnotationNamespace was deprecated in favor of explicit
configuration in 2.1 and will be removed in 2.2 (for isolated projects where you
have full-control over _all_ available annotations, we offer a dedicated reader
class ``SimpleAnnotationReader``)
- AnnotationReader::setAnnotationCreationFunction was deprecated in 2.1 and will be
removed in 2.2. We only offer two creation mechanisms which cannot be changed
anymore to allow the same reader instance to work with all annotations regardless
of which library they are coming from.
- AnnotationReader::setAnnotationNamespaceAlias was deprecated in 2.1 and will be
removed in 2.2 (see setDefaultAnnotationNamespace)
- If you use a class as annotation which has not the @Annotation marker in it's
class block, we will now throw an exception instead of silently ignoring it. You
can however still achieve the previous behavior using the @IgnoreAnnotation, or
AnnotationReader::addGlobalIgnoredName (the exception message will contain detailed
instructions when you run into this problem).
## Cache Changes
- Renamed old AbstractCache to CacheProvider
- Dropped the support to the following functions of all cache providers:
- CacheProvider::deleteByWildcard
- CacheProvider::deleteByRegEx
- CacheProvider::deleteByPrefix
- CacheProvider::deleteBySuffix
- CacheProvider::deleteAll will not remove ALL entries, it will only mark them as invalid
- CacheProvider::flushAll will remove ALL entries, namespaced or not
- Added support to MemcachedCache
- Added support to WincacheCache
## ClassLoader Changes
- ClassLoader::fileExistsInIncludePath() no longer exists. Use the native stream_resolve_include_path() PHP function

View File

@@ -0,0 +1,285 @@
<?php
namespace Doctrine\Common;
use function class_exists;
use function interface_exists;
use function is_array;
use function is_file;
use function reset;
use function spl_autoload_functions;
use function spl_autoload_register;
use function spl_autoload_unregister;
use function str_replace;
use function stream_resolve_include_path;
use function strpos;
use function trait_exists;
use function trigger_error;
use const DIRECTORY_SEPARATOR;
use const E_USER_DEPRECATED;
@trigger_error(ClassLoader::class . ' is deprecated.', E_USER_DEPRECATED);
/**
* A <tt>ClassLoader</tt> is an autoloader for class files that can be
* installed on the SPL autoload stack. It is a class loader that either loads only classes
* of a specific namespace or all namespaces and it is suitable for working together
* with other autoloaders in the SPL autoload stack.
*
* If no include path is configured through the constructor or {@link setIncludePath}, a ClassLoader
* relies on the PHP <code>include_path</code>.
*
* @deprecated The ClassLoader is deprecated and will be removed in version 4.0 of doctrine/common.
*/
class ClassLoader
{
/**
* PHP file extension.
*
* @var string
*/
protected $fileExtension = '.php';
/**
* Current namespace.
*
* @var string|null
*/
protected $namespace;
/**
* Current include path.
*
* @var string|null
*/
protected $includePath;
/**
* PHP namespace separator.
*
* @var string
*/
protected $namespaceSeparator = '\\';
/**
* Creates a new <tt>ClassLoader</tt> that loads classes of the
* specified namespace from the specified include path.
*
* If no include path is given, the ClassLoader relies on the PHP include_path.
* If neither a namespace nor an include path is given, the ClassLoader will
* be responsible for loading all classes, thereby relying on the PHP include_path.
*
* @param string|null $ns The namespace of the classes to load.
* @param string|null $includePath The base include path to use.
*/
public function __construct($ns = null, $includePath = null)
{
$this->namespace = $ns;
$this->includePath = $includePath;
}
/**
* Sets the namespace separator used by classes in the namespace of this ClassLoader.
*
* @param string $sep The separator to use.
*
* @return void
*/
public function setNamespaceSeparator($sep)
{
$this->namespaceSeparator = $sep;
}
/**
* Gets the namespace separator used by classes in the namespace of this ClassLoader.
*
* @return string
*/
public function getNamespaceSeparator()
{
return $this->namespaceSeparator;
}
/**
* Sets the base include path for all class files in the namespace of this ClassLoader.
*
* @param string|null $includePath
*
* @return void
*/
public function setIncludePath($includePath)
{
$this->includePath = $includePath;
}
/**
* Gets the base include path for all class files in the namespace of this ClassLoader.
*
* @return string|null
*/
public function getIncludePath()
{
return $this->includePath;
}
/**
* Sets the file extension of class files in the namespace of this ClassLoader.
*
* @param string $fileExtension
*
* @return void
*/
public function setFileExtension($fileExtension)
{
$this->fileExtension = $fileExtension;
}
/**
* Gets the file extension of class files in the namespace of this ClassLoader.
*
* @return string
*/
public function getFileExtension()
{
return $this->fileExtension;
}
/**
* Registers this ClassLoader on the SPL autoload stack.
*
* @return void
*/
public function register()
{
spl_autoload_register([$this, 'loadClass']);
}
/**
* Removes this ClassLoader from the SPL autoload stack.
*
* @return void
*/
public function unregister()
{
spl_autoload_unregister([$this, 'loadClass']);
}
/**
* Loads the given class or interface.
*
* @param string $className The name of the class to load.
* @psalm-param class-string $className
*
* @return bool TRUE if the class has been successfully loaded, FALSE otherwise.
*/
public function loadClass($className)
{
if (self::typeExists($className)) {
return true;
}
if (! $this->canLoadClass($className)) {
return false;
}
require($this->includePath !== null ? $this->includePath . DIRECTORY_SEPARATOR : '')
. str_replace($this->namespaceSeparator, DIRECTORY_SEPARATOR, $className)
. $this->fileExtension;
return self::typeExists($className);
}
/**
* Asks this ClassLoader whether it can potentially load the class (file) with
* the given name.
*
* @param string $className The fully-qualified name of the class.
* @psalm-param class-string $className
*
* @return bool TRUE if this ClassLoader can load the class, FALSE otherwise.
*/
public function canLoadClass($className)
{
if ($this->namespace !== null && strpos($className, $this->namespace . $this->namespaceSeparator) !== 0) {
return false;
}
$file = str_replace($this->namespaceSeparator, DIRECTORY_SEPARATOR, $className) . $this->fileExtension;
if ($this->includePath !== null) {
return is_file($this->includePath . DIRECTORY_SEPARATOR . $file);
}
return stream_resolve_include_path($file) !== false;
}
/**
* Checks whether a class with a given name exists. A class "exists" if it is either
* already defined in the current request or if there is an autoloader on the SPL
* autoload stack that is a) responsible for the class in question and b) is able to
* load a class file in which the class definition resides.
*
* If the class is not already defined, each autoloader in the SPL autoload stack
* is asked whether it is able to tell if the class exists. If the autoloader is
* a <tt>ClassLoader</tt>, {@link canLoadClass} is used, otherwise the autoload
* function of the autoloader is invoked and expected to return a value that
* evaluates to TRUE if the class (file) exists. As soon as one autoloader reports
* that the class exists, TRUE is returned.
*
* Note that, depending on what kinds of autoloaders are installed on the SPL
* autoload stack, the class (file) might already be loaded as a result of checking
* for its existence. This is not the case with a <tt>ClassLoader</tt>, who separates
* these responsibilities.
*
* @param string $className The fully-qualified name of the class.
* @psalm-param class-string $className
*
* @return bool TRUE if the class exists as per the definition given above, FALSE otherwise.
*/
public static function classExists($className)
{
return self::typeExists($className, true);
}
/**
* Gets the <tt>ClassLoader</tt> from the SPL autoload stack that is responsible
* for (and is able to load) the class with the given name.
*
* @param string $className The name of the class.
* @psalm-param class-string $className
*
* @return ClassLoader|null The <tt>ClassLoader</tt> for the class or NULL if no such <tt>ClassLoader</tt> exists.
*/
public static function getClassLoader($className)
{
foreach (spl_autoload_functions() as $loader) {
if (! is_array($loader)) {
continue;
}
$classLoader = reset($loader);
if ($classLoader instanceof ClassLoader && $classLoader->canLoadClass($className)) {
return $classLoader;
}
}
return null;
}
/**
* Checks whether a given type exists
*
* @param string $type
* @param bool $autoload
*
* @return bool
*/
private static function typeExists($type, $autoload = false)
{
return class_exists($type, $autoload)
|| interface_exists($type, $autoload)
|| trait_exists($type, $autoload);
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Doctrine\Common;
use Exception;
/**
* Base exception class for package Doctrine\Common.
*
* @deprecated The doctrine/common package is deprecated, please use specific packages and their exceptions instead.
*/
class CommonException extends Exception
{
}

View File

@@ -0,0 +1,26 @@
<?php
namespace Doctrine\Common;
/**
* Comparable interface that allows to compare two value objects to each other for similarity.
*
* @link www.doctrine-project.org
*/
interface Comparable
{
/**
* Compares the current object to the passed $other.
*
* Returns 0 if they are semantically equal, 1 if the other object
* is less than the current one, or -1 if its more than the current one.
*
* This method should not check for identity using ===, only for semantical equality for example
* when two different DateTime instances point to the exact same Date + TZ.
*
* @param mixed $other
*
* @return int
*/
public function compareTo($other);
}

View File

@@ -0,0 +1,244 @@
<?php
namespace Doctrine\Common\Proxy;
use Doctrine\Common\Proxy\Exception\InvalidArgumentException;
use Doctrine\Common\Proxy\Exception\OutOfBoundsException;
use Doctrine\Common\Util\ClassUtils;
use Doctrine\Persistence\Mapping\ClassMetadata;
use Doctrine\Persistence\Mapping\ClassMetadataFactory;
use function class_exists;
use function file_exists;
use function filemtime;
use function in_array;
/**
* Abstract factory for proxy objects.
*/
abstract class AbstractProxyFactory
{
/**
* Never autogenerate a proxy and rely that it was generated by some
* process before deployment.
*/
public const AUTOGENERATE_NEVER = 0;
/**
* Always generates a new proxy in every request.
*
* This is only sane during development.
*/
public const AUTOGENERATE_ALWAYS = 1;
/**
* Autogenerate the proxy class when the proxy file does not exist.
*
* This strategy causes a file_exists() call whenever any proxy is used the
* first time in a request.
*/
public const AUTOGENERATE_FILE_NOT_EXISTS = 2;
/**
* Generate the proxy classes using eval().
*
* This strategy is only sane for development, and even then it gives me
* the creeps a little.
*/
public const AUTOGENERATE_EVAL = 3;
/**
* Autogenerate the proxy class when the proxy file does not exist or
* when the proxied file changed.
*
* This strategy causes a file_exists() call whenever any proxy is used the
* first time in a request. When the proxied file is changed, the proxy will
* be updated.
*/
public const AUTOGENERATE_FILE_NOT_EXISTS_OR_CHANGED = 4;
private const AUTOGENERATE_MODES = [
self::AUTOGENERATE_NEVER,
self::AUTOGENERATE_ALWAYS,
self::AUTOGENERATE_FILE_NOT_EXISTS,
self::AUTOGENERATE_EVAL,
self::AUTOGENERATE_FILE_NOT_EXISTS_OR_CHANGED,
];
/** @var ClassMetadataFactory */
private $metadataFactory;
/** @var ProxyGenerator the proxy generator responsible for creating the proxy classes/files. */
private $proxyGenerator;
/** @var int Whether to automatically (re)generate proxy classes. */
private $autoGenerate;
/** @var ProxyDefinition[] */
private $definitions = [];
/**
* @param bool|int $autoGenerate
*
* @throws InvalidArgumentException When auto generate mode is not valid.
*/
public function __construct(ProxyGenerator $proxyGenerator, ClassMetadataFactory $metadataFactory, $autoGenerate)
{
$this->proxyGenerator = $proxyGenerator;
$this->metadataFactory = $metadataFactory;
$this->autoGenerate = (int) $autoGenerate;
if (! in_array($this->autoGenerate, self::AUTOGENERATE_MODES, true)) {
throw InvalidArgumentException::invalidAutoGenerateMode($autoGenerate);
}
}
/**
* Gets a reference proxy instance for the entity of the given type and identified by
* the given identifier.
*
* @param string $className
* @param array<mixed> $identifier
*
* @return Proxy
*
* @throws OutOfBoundsException
*/
public function getProxy($className, array $identifier)
{
$definition = $this->definitions[$className] ?? $this->getProxyDefinition($className);
$fqcn = $definition->proxyClassName;
$proxy = new $fqcn($definition->initializer, $definition->cloner);
foreach ($definition->identifierFields as $idField) {
if (! isset($identifier[$idField])) {
throw OutOfBoundsException::missingPrimaryKeyValue($className, $idField);
}
$definition->reflectionFields[$idField]->setValue($proxy, $identifier[$idField]);
}
return $proxy;
}
/**
* Generates proxy classes for all given classes.
*
* @param ClassMetadata[] $classes The classes (ClassMetadata instances)
* for which to generate proxies.
* @param string $proxyDir The target directory of the proxy classes. If not specified, the
* directory configured on the Configuration of the EntityManager used
* by this factory is used.
*
* @return int Number of generated proxies.
*/
public function generateProxyClasses(array $classes, $proxyDir = null)
{
$generated = 0;
foreach ($classes as $class) {
if ($this->skipClass($class)) {
continue;
}
$proxyFileName = $this->proxyGenerator->getProxyFileName($class->getName(), $proxyDir);
$this->proxyGenerator->generateProxyClass($class, $proxyFileName);
$generated += 1;
}
return $generated;
}
/**
* Reset initialization/cloning logic for an un-initialized proxy
*
* @return Proxy
*
* @throws InvalidArgumentException
*/
public function resetUninitializedProxy(Proxy $proxy)
{
if ($proxy->__isInitialized()) {
throw InvalidArgumentException::unitializedProxyExpected($proxy);
}
$className = ClassUtils::getClass($proxy);
$definition = $this->definitions[$className] ?? $this->getProxyDefinition($className);
$proxy->__setInitializer($definition->initializer);
$proxy->__setCloner($definition->cloner);
return $proxy;
}
/**
* Get a proxy definition for the given class name.
*
* @param string $className
* @psalm-param class-string $className
*
* @return ProxyDefinition
*/
private function getProxyDefinition($className)
{
$classMetadata = $this->metadataFactory->getMetadataFor($className);
$className = $classMetadata->getName(); // aliases and case sensitivity
$this->definitions[$className] = $this->createProxyDefinition($className);
$proxyClassName = $this->definitions[$className]->proxyClassName;
if (! class_exists($proxyClassName, false)) {
$fileName = $this->proxyGenerator->getProxyFileName($className);
switch ($this->autoGenerate) {
case self::AUTOGENERATE_NEVER:
require $fileName;
break;
case self::AUTOGENERATE_FILE_NOT_EXISTS:
if (! file_exists($fileName)) {
$this->proxyGenerator->generateProxyClass($classMetadata, $fileName);
}
require $fileName;
break;
case self::AUTOGENERATE_ALWAYS:
$this->proxyGenerator->generateProxyClass($classMetadata, $fileName);
require $fileName;
break;
case self::AUTOGENERATE_EVAL:
$this->proxyGenerator->generateProxyClass($classMetadata, false);
break;
case self::AUTOGENERATE_FILE_NOT_EXISTS_OR_CHANGED:
if (! file_exists($fileName) || filemtime($fileName) < filemtime($classMetadata->getReflectionClass()->getFileName())) {
$this->proxyGenerator->generateProxyClass($classMetadata, $fileName);
}
require $fileName;
break;
}
}
return $this->definitions[$className];
}
/**
* Determine if this class should be skipped during proxy generation.
*
* @return bool
*/
abstract protected function skipClass(ClassMetadata $metadata);
/**
* @param string $className
* @psalm-param class-string $className
*
* @return ProxyDefinition
*/
abstract protected function createProxyDefinition($className);
}

View File

@@ -0,0 +1,99 @@
<?php
namespace Doctrine\Common\Proxy;
use Closure;
use Doctrine\Common\Proxy\Exception\InvalidArgumentException;
use function call_user_func;
use function file_exists;
use function is_callable;
use function ltrim;
use function spl_autoload_register;
use function str_replace;
use function strlen;
use function strpos;
use function substr;
use const DIRECTORY_SEPARATOR;
/**
* Special Autoloader for Proxy classes, which are not PSR-0 compliant.
*
* @internal
*/
class Autoloader
{
/**
* Resolves proxy class name to a filename based on the following pattern.
*
* 1. Remove Proxy namespace from class name.
* 2. Remove namespace separators from remaining class name.
* 3. Return PHP filename from proxy-dir with the result from 2.
*
* @param string $proxyDir
* @param string $proxyNamespace
* @param string $className
* @psalm-param class-string $className
*
* @return string
*
* @throws InvalidArgumentException
*/
public static function resolveFile($proxyDir, $proxyNamespace, $className)
{
if (strpos($className, $proxyNamespace) !== 0) {
throw InvalidArgumentException::notProxyClass($className, $proxyNamespace);
}
// remove proxy namespace from class name
$classNameRelativeToProxyNamespace = substr($className, strlen($proxyNamespace));
// remove namespace separators from remaining class name
$fileName = str_replace('\\', '', $classNameRelativeToProxyNamespace);
return $proxyDir . DIRECTORY_SEPARATOR . $fileName . '.php';
}
/**
* Registers and returns autoloader callback for the given proxy dir and namespace.
*
* @param string $proxyDir
* @param string $proxyNamespace
* @param callable|null $notFoundCallback Invoked when the proxy file is not found.
*
* @return Closure
*
* @throws InvalidArgumentException
*/
public static function register($proxyDir, $proxyNamespace, $notFoundCallback = null)
{
$proxyNamespace = ltrim($proxyNamespace, '\\');
if ($notFoundCallback !== null && ! is_callable($notFoundCallback)) {
throw InvalidArgumentException::invalidClassNotFoundCallback($notFoundCallback);
}
$autoloader = static function ($className) use ($proxyDir, $proxyNamespace, $notFoundCallback) {
if ($proxyNamespace === '') {
return;
}
if (strpos($className, $proxyNamespace) !== 0) {
return;
}
$file = Autoloader::resolveFile($proxyDir, $proxyNamespace, $className);
if ($notFoundCallback && ! file_exists($file)) {
call_user_func($notFoundCallback, $proxyDir, $proxyNamespace, $className);
}
require $file;
};
spl_autoload_register($autoloader);
return $autoloader;
}
}

View File

@@ -0,0 +1,110 @@
<?php
namespace Doctrine\Common\Proxy\Exception;
use Doctrine\Persistence\Proxy;
use InvalidArgumentException as BaseInvalidArgumentException;
use function get_class;
use function gettype;
use function is_object;
use function sprintf;
/**
* Proxy Invalid Argument Exception.
*
* @link www.doctrine-project.org
*/
class InvalidArgumentException extends BaseInvalidArgumentException implements ProxyException
{
/** @return self */
public static function proxyDirectoryRequired()
{
return new self('You must configure a proxy directory. See docs for details');
}
/**
* @param string $className
* @param string $proxyNamespace
* @psalm-param class-string $className
*
* @return self
*/
public static function notProxyClass($className, $proxyNamespace)
{
return new self(sprintf('The class "%s" is not part of the proxy namespace "%s"', $className, $proxyNamespace));
}
/**
* @param string $name
*
* @return self
*/
public static function invalidPlaceholder($name)
{
return new self(sprintf('Provided placeholder for "%s" must be either a string or a valid callable', $name));
}
/** @return self */
public static function proxyNamespaceRequired()
{
return new self('You must configure a proxy namespace');
}
/** @return self */
public static function unitializedProxyExpected(Proxy $proxy)
{
return new self(sprintf('Provided proxy of type "%s" must not be initialized.', get_class($proxy)));
}
/**
* @param mixed $callback
*
* @return self
*/
public static function invalidClassNotFoundCallback($callback)
{
$type = is_object($callback) ? get_class($callback) : gettype($callback);
return new self(sprintf('Invalid \$notFoundCallback given: must be a callable, "%s" given', $type));
}
/**
* @param string $className
* @psalm-param class-string $className
*
* @return self
*/
public static function classMustNotBeAbstract($className)
{
return new self(sprintf('Unable to create a proxy for an abstract class "%s".', $className));
}
/**
* @param string $className
* @psalm-param class-string $className
*
* @return self
*/
public static function classMustNotBeFinal($className)
{
return new self(sprintf('Unable to create a proxy for a final class "%s".', $className));
}
/**
* @param string $className
* @psalm-param class-string $className
*
* @return self
*/
public static function classMustNotBeReadOnly($className)
{
return new self(sprintf('Unable to create a proxy for a readonly class "%s".', $className));
}
/** @param mixed $value */
public static function invalidAutoGenerateMode($value): self
{
return new self(sprintf('Invalid auto generate mode "%s" given.', $value));
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace Doctrine\Common\Proxy\Exception;
use OutOfBoundsException as BaseOutOfBoundsException;
use function sprintf;
/**
* Proxy Invalid Argument Exception.
*
* @link www.doctrine-project.org
*/
class OutOfBoundsException extends BaseOutOfBoundsException implements ProxyException
{
/**
* @param string $className
* @param string $idField
* @psalm-param class-string $className
*
* @return self
*/
public static function missingPrimaryKeyValue($className, $idField)
{
return new self(sprintf('Missing value for primary key %s on %s', $idField, $className));
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace Doctrine\Common\Proxy\Exception;
/**
* Base exception interface for proxy exceptions.
*
* @link www.doctrine-project.org
*/
interface ProxyException
{
}

View File

@@ -0,0 +1,72 @@
<?php
namespace Doctrine\Common\Proxy\Exception;
use Throwable;
use UnexpectedValueException as BaseUnexpectedValueException;
use function sprintf;
/**
* Proxy Unexpected Value Exception.
*
* @link www.doctrine-project.org
*/
class UnexpectedValueException extends BaseUnexpectedValueException implements ProxyException
{
/**
* @param string $proxyDirectory
*
* @return self
*/
public static function proxyDirectoryNotWritable($proxyDirectory)
{
return new self(sprintf('Your proxy directory "%s" must be writable', $proxyDirectory));
}
/**
* @param string $className
* @param string $methodName
* @param string $parameterName
* @psalm-param class-string $className
*
* @return self
*/
public static function invalidParameterTypeHint(
$className,
$methodName,
$parameterName,
?Throwable $previous = null
) {
return new self(
sprintf(
'The type hint of parameter "%s" in method "%s" in class "%s" is invalid.',
$parameterName,
$methodName,
$className
),
0,
$previous
);
}
/**
* @param string $className
* @param string $methodName
* @psalm-param class-string $className
*
* @return self
*/
public static function invalidReturnTypeHint($className, $methodName, ?Throwable $previous = null)
{
return new self(
sprintf(
'The return type of method "%s" in class "%s" is invalid.',
$methodName,
$className
),
0,
$previous
);
}
}

View File

@@ -0,0 +1,68 @@
<?php
namespace Doctrine\Common\Proxy;
use Closure;
use Doctrine\Persistence\Proxy as BaseProxy;
/**
* Interface for proxy classes.
*
* @template T of object
* @template-extends BaseProxy<T>
*/
interface Proxy extends BaseProxy
{
/**
* Marks the proxy as initialized or not.
*
* @param bool $initialized
*
* @return void
*/
public function __setInitialized($initialized);
/**
* Sets the initializer callback to be used when initializing the proxy. That
* initializer should accept 3 parameters: $proxy, $method and $params. Those
* are respectively the proxy object that is being initialized, the method name
* that triggered initialization and the parameters passed to that method.
*
* @return void
*/
public function __setInitializer(?Closure $initializer = null);
/**
* Retrieves the initializer callback used to initialize the proxy.
*
* @see __setInitializer
*
* @return Closure|null
*/
public function __getInitializer();
/**
* Sets the callback to be used when cloning the proxy. That initializer should accept
* a single parameter, which is the cloned proxy instance itself.
*
* @return void
*/
public function __setCloner(?Closure $cloner = null);
/**
* Retrieves the callback to be used when cloning the proxy.
*
* @see __setCloner
*
* @return Closure|null
*/
public function __getCloner();
/**
* Retrieves the list of lazy loaded properties for a given proxy
*
* @return array<string, mixed> Keys are the property names, and values are the default values
* for those properties.
*/
public function __getLazyProperties();
}

View File

@@ -0,0 +1,42 @@
<?php
namespace Doctrine\Common\Proxy;
use ReflectionProperty;
/**
* Definition structure how to create a proxy.
*/
class ProxyDefinition
{
/** @var string */
public $proxyClassName;
/** @var array<string> */
public $identifierFields;
/** @var ReflectionProperty[] */
public $reflectionFields;
/** @var callable */
public $initializer;
/** @var callable */
public $cloner;
/**
* @param string $proxyClassName
* @param array<string> $identifierFields
* @param array<string, ReflectionProperty> $reflectionFields
* @param callable $initializer
* @param callable $cloner
*/
public function __construct($proxyClassName, array $identifierFields, array $reflectionFields, $initializer, $cloner)
{
$this->proxyClassName = $proxyClassName;
$this->identifierFields = $identifierFields;
$this->reflectionFields = $reflectionFields;
$this->initializer = $initializer;
$this->cloner = $cloner;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,113 @@
<?php
namespace Doctrine\Common\Util;
use Doctrine\Persistence\Proxy;
use ReflectionClass;
use function get_class;
use function get_parent_class;
use function ltrim;
use function rtrim;
use function strrpos;
use function substr;
/**
* Class and reflection related functionality for objects that
* might or not be proxy objects at the moment.
*/
class ClassUtils
{
/**
* Gets the real class name of a class name that could be a proxy.
*
* @param string $className
* @psalm-param class-string<Proxy<T>>|class-string<T> $className
*
* @return string
* @psalm-return class-string<T>
*
* @template T of object
*/
public static function getRealClass($className)
{
$pos = strrpos($className, '\\' . Proxy::MARKER . '\\');
if ($pos === false) {
/** @psalm-var class-string<T> */
return $className;
}
return substr($className, $pos + Proxy::MARKER_LENGTH + 2);
}
/**
* Gets the real class name of an object (even if its a proxy).
*
* @param object $object
* @psalm-param Proxy<T>|T $object
*
* @return string
* @psalm-return class-string<T>
*
* @template T of object
*/
public static function getClass($object)
{
return self::getRealClass(get_class($object));
}
/**
* Gets the real parent class name of a class or object.
*
* @param string $className
* @psalm-param class-string $className
*
* @return string
* @psalm-return class-string
*/
public static function getParentClass($className)
{
return get_parent_class(self::getRealClass($className));
}
/**
* Creates a new reflection class.
*
* @param string $className
* @psalm-param class-string $className
*
* @return ReflectionClass
*/
public static function newReflectionClass($className)
{
return new ReflectionClass(self::getRealClass($className));
}
/**
* Creates a new reflection object.
*
* @param object $object
*
* @return ReflectionClass
*/
public static function newReflectionObject($object)
{
return self::newReflectionClass(self::getClass($object));
}
/**
* Given a class name and a proxy namespace returns the proxy name.
*
* @param string $className
* @param string $proxyNamespace
* @psalm-param class-string $className
*
* @return string
* @psalm-return class-string
*/
public static function generateProxyClassName($className, $proxyNamespace)
{
return rtrim($proxyNamespace, '\\') . '\\' . Proxy::MARKER . '\\' . ltrim($className, '\\');
}
}

View File

@@ -0,0 +1,185 @@
<?php
namespace Doctrine\Common\Util;
use ArrayIterator;
use ArrayObject;
use DateTimeInterface;
use Doctrine\Common\Collections\Collection;
use Doctrine\Persistence\Proxy;
use stdClass;
use function array_keys;
use function count;
use function end;
use function explode;
use function extension_loaded;
use function get_class;
use function html_entity_decode;
use function ini_get;
use function ini_set;
use function is_array;
use function is_object;
use function method_exists;
use function ob_end_clean;
use function ob_get_contents;
use function ob_start;
use function spl_object_hash;
use function strip_tags;
use function var_dump;
/**
* Static class containing most used debug methods.
*
* @deprecated The Debug class is deprecated, please use symfony/var-dumper instead.
*
* @link www.doctrine-project.org
*/
final class Debug
{
/**
* Private constructor (prevents instantiation).
*/
private function __construct()
{
}
/**
* Prints a dump of the public, protected and private properties of $var.
*
* @link https://xdebug.org/
*
* @param mixed $var The variable to dump.
* @param int $maxDepth The maximum nesting level for object properties.
* @param bool $stripTags Whether output should strip HTML tags.
* @param bool $echo Send the dumped value to the output buffer
*
* @return string
*/
public static function dump($var, $maxDepth = 2, $stripTags = true, $echo = true)
{
$html = ini_get('html_errors');
if ($html !== true) {
ini_set('html_errors', 'on');
}
if (extension_loaded('xdebug')) {
ini_set('xdebug.var_display_max_depth', $maxDepth);
}
$var = self::export($var, $maxDepth);
ob_start();
var_dump($var);
$dump = ob_get_contents();
ob_end_clean();
$dumpText = ($stripTags ? strip_tags(html_entity_decode($dump)) : $dump);
ini_set('html_errors', $html);
if ($echo) {
echo $dumpText;
}
return $dumpText;
}
/**
* @param mixed $var
* @param int $maxDepth
*
* @return mixed
*/
public static function export($var, $maxDepth)
{
$return = null;
$isObj = is_object($var);
if ($var instanceof Collection) {
$var = $var->toArray();
}
if (! $maxDepth) {
return is_object($var) ? get_class($var)
: (is_array($var) ? 'Array(' . count($var) . ')' : $var);
}
if (is_array($var)) {
$return = [];
foreach ($var as $k => $v) {
$return[$k] = self::export($v, $maxDepth - 1);
}
return $return;
}
if (! $isObj) {
return $var;
}
$return = new stdClass();
if ($var instanceof DateTimeInterface) {
$return->__CLASS__ = get_class($var);
$return->date = $var->format('c');
$return->timezone = $var->getTimezone()->getName();
return $return;
}
$return->__CLASS__ = ClassUtils::getClass($var);
if ($var instanceof Proxy) {
$return->__IS_PROXY__ = true;
$return->__PROXY_INITIALIZED__ = $var->__isInitialized();
}
if ($var instanceof ArrayObject || $var instanceof ArrayIterator) {
$return->__STORAGE__ = self::export($var->getArrayCopy(), $maxDepth - 1);
}
return self::fillReturnWithClassAttributes($var, $return, $maxDepth);
}
/**
* Fill the $return variable with class attributes
* Based on obj2array function from {@see https://secure.php.net/manual/en/function.get-object-vars.php#47075}
*
* @param object $var
* @param int $maxDepth
*
* @return mixed
*/
private static function fillReturnWithClassAttributes($var, stdClass $return, $maxDepth)
{
$clone = (array) $var;
foreach (array_keys($clone) as $key) {
$aux = explode("\0", $key);
$name = end($aux);
if ($aux[0] === '') {
$name .= ':' . ($aux[1] === '*' ? 'protected' : $aux[1] . ':private');
}
$return->$name = self::export($clone[$key], $maxDepth - 1);
}
return $return;
}
/**
* Returns a string representation of an object.
*
* @param object $obj
*
* @return string
*/
public static function toString($obj)
{
return method_exists($obj, '__toString') ? (string) $obj : get_class($obj) . '@' . spl_object_hash($obj);
}
}