first commit
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\LazyProxy\Instantiator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
|
||||
/**
|
||||
* Lazy proxy instantiator, capable of instantiating a proxy given a container, the
|
||||
* service definitions and a callback that produces the real service instance.
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
*/
|
||||
interface InstantiatorInterface
|
||||
{
|
||||
/**
|
||||
* Instantiates a proxy object.
|
||||
*
|
||||
* @param string $id Identifier of the requested service
|
||||
* @param callable(object=) $realInstantiator A callback that is capable of producing the real service instance
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function instantiateProxy(ContainerInterface $container, Definition $definition, string $id, callable $realInstantiator);
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\LazyProxy\Instantiator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\LazyServiceDumper;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
final class LazyServiceInstantiator implements InstantiatorInterface
|
||||
{
|
||||
public function instantiateProxy(ContainerInterface $container, Definition $definition, string $id, callable $realInstantiator): object
|
||||
{
|
||||
$dumper = new LazyServiceDumper();
|
||||
|
||||
if (!$dumper->isProxyCandidate($definition, $asGhostObject, $id)) {
|
||||
throw new InvalidArgumentException(sprintf('Cannot instantiate lazy proxy for service "%s".', $id));
|
||||
}
|
||||
|
||||
if (!class_exists($proxyClass = $dumper->getProxyClass($definition, $asGhostObject), false)) {
|
||||
eval($dumper->getProxyCode($definition, $id));
|
||||
}
|
||||
|
||||
return $asGhostObject ? $proxyClass::createLazyGhost($realInstantiator) : $proxyClass::createLazyProxy($realInstantiator);
|
||||
}
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\LazyProxy\Instantiator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
|
||||
/**
|
||||
* Noop proxy instantiator - produces the real service instead of a proxy instance.
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
*/
|
||||
class RealServiceInstantiator implements InstantiatorInterface
|
||||
{
|
||||
public function instantiateProxy(ContainerInterface $container, Definition $definition, string $id, callable $realInstantiator): object
|
||||
{
|
||||
return $realInstantiator();
|
||||
}
|
||||
}
|
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\LazyProxy\PhpDumper;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
|
||||
/**
|
||||
* Lazy proxy dumper capable of generating the instantiation logic PHP code for proxied services.
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
*/
|
||||
interface DumperInterface
|
||||
{
|
||||
/**
|
||||
* Inspects whether the given definitions should produce proxy instantiation logic in the dumped container.
|
||||
*
|
||||
* @param bool|null &$asGhostObject Set to true after the call if the proxy is a ghost object
|
||||
* @param string|null $id
|
||||
*/
|
||||
public function isProxyCandidate(Definition $definition/* , ?bool &$asGhostObject = null, ?string $id = null */): bool;
|
||||
|
||||
/**
|
||||
* Generates the code to be used to instantiate a proxy in the dumped factory code.
|
||||
*/
|
||||
public function getProxyFactoryCode(Definition $definition, string $id, string $factoryCode): string;
|
||||
|
||||
/**
|
||||
* Generates the code for the lazy proxy.
|
||||
*
|
||||
* @param string|null $id
|
||||
*/
|
||||
public function getProxyCode(Definition $definition/* , ?string $id = null */): string;
|
||||
}
|
151
plugins/simplesaml/lib/vendor/symfony/dependency-injection/LazyProxy/PhpDumper/LazyServiceDumper.php
vendored
Normal file
151
plugins/simplesaml/lib/vendor/symfony/dependency-injection/LazyProxy/PhpDumper/LazyServiceDumper.php
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\LazyProxy\PhpDumper;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\VarExporter\Exception\LogicException;
|
||||
use Symfony\Component\VarExporter\ProxyHelper;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
final class LazyServiceDumper implements DumperInterface
|
||||
{
|
||||
public function __construct(
|
||||
private string $salt = '',
|
||||
) {
|
||||
}
|
||||
|
||||
public function isProxyCandidate(Definition $definition, ?bool &$asGhostObject = null, ?string $id = null): bool
|
||||
{
|
||||
$asGhostObject = false;
|
||||
|
||||
if ($definition->hasTag('proxy')) {
|
||||
if (!$definition->isLazy()) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid definition for service "%s": setting the "proxy" tag on a service requires it to be "lazy".', $id ?? $definition->getClass()));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$definition->isLazy()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!($class = $definition->getClass()) || !(class_exists($class) || interface_exists($class, false))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($definition->getFactory()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ($definition->getMethodCalls() as $call) {
|
||||
if ($call[2] ?? false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$asGhostObject = (bool) ProxyHelper::generateLazyGhost(new \ReflectionClass($class));
|
||||
} catch (LogicException) {
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getProxyFactoryCode(Definition $definition, string $id, string $factoryCode): string
|
||||
{
|
||||
$instantiation = 'return';
|
||||
|
||||
if ($definition->isShared()) {
|
||||
$instantiation .= sprintf(' $container->%s[%s] =', $definition->isPublic() && !$definition->isPrivate() ? 'services' : 'privates', var_export($id, true));
|
||||
}
|
||||
|
||||
$asGhostObject = str_contains($factoryCode, '$proxy');
|
||||
$proxyClass = $this->getProxyClass($definition, $asGhostObject);
|
||||
|
||||
if (!$asGhostObject) {
|
||||
return <<<EOF
|
||||
if (true === \$lazyLoad) {
|
||||
$instantiation \$container->createProxy('$proxyClass', static fn () => \\$proxyClass::createLazyProxy(static fn () => $factoryCode));
|
||||
}
|
||||
|
||||
|
||||
EOF;
|
||||
}
|
||||
|
||||
$factoryCode = sprintf('static fn ($proxy) => %s', $factoryCode);
|
||||
|
||||
return <<<EOF
|
||||
if (true === \$lazyLoad) {
|
||||
$instantiation \$container->createProxy('$proxyClass', static fn () => \\$proxyClass::createLazyGhost($factoryCode));
|
||||
}
|
||||
|
||||
|
||||
EOF;
|
||||
}
|
||||
|
||||
public function getProxyCode(Definition $definition, ?string $id = null): string
|
||||
{
|
||||
if (!$this->isProxyCandidate($definition, $asGhostObject, $id)) {
|
||||
throw new InvalidArgumentException(sprintf('Cannot instantiate lazy proxy for service "%s".', $id ?? $definition->getClass()));
|
||||
}
|
||||
$proxyClass = $this->getProxyClass($definition, $asGhostObject, $class);
|
||||
|
||||
if ($asGhostObject) {
|
||||
try {
|
||||
return (\PHP_VERSION_ID >= 80200 && $class?->isReadOnly() ? 'readonly ' : '').'class '.$proxyClass.ProxyHelper::generateLazyGhost($class);
|
||||
} catch (LogicException $e) {
|
||||
throw new InvalidArgumentException(sprintf('Cannot generate lazy ghost for service "%s".', $id ?? $definition->getClass()), 0, $e);
|
||||
}
|
||||
}
|
||||
$interfaces = [];
|
||||
|
||||
if ($definition->hasTag('proxy')) {
|
||||
foreach ($definition->getTag('proxy') as $tag) {
|
||||
if (!isset($tag['interface'])) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid definition for service "%s": the "interface" attribute is missing on a "proxy" tag.', $id ?? $definition->getClass()));
|
||||
}
|
||||
if (!interface_exists($tag['interface']) && !class_exists($tag['interface'], false)) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid definition for service "%s": several "proxy" tags found but "%s" is not an interface.', $id ?? $definition->getClass(), $tag['interface']));
|
||||
}
|
||||
if ('object' !== $definition->getClass() && !is_a($class->name, $tag['interface'], true)) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid "proxy" tag for service "%s": class "%s" doesn\'t implement "%s".', $id ?? $definition->getClass(), $definition->getClass(), $tag['interface']));
|
||||
}
|
||||
$interfaces[] = new \ReflectionClass($tag['interface']);
|
||||
}
|
||||
|
||||
$class = 1 === \count($interfaces) && !$interfaces[0]->isInterface() ? array_pop($interfaces) : null;
|
||||
} elseif ($class->isInterface()) {
|
||||
$interfaces = [$class];
|
||||
$class = null;
|
||||
}
|
||||
|
||||
try {
|
||||
return (\PHP_VERSION_ID >= 80200 && $class?->isReadOnly() ? 'readonly ' : '').'class '.$proxyClass.ProxyHelper::generateLazyProxy($class, $interfaces);
|
||||
} catch (LogicException $e) {
|
||||
throw new InvalidArgumentException(sprintf('Cannot generate lazy proxy for service "%s".', $id ?? $definition->getClass()), 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
public function getProxyClass(Definition $definition, bool $asGhostObject, ?\ReflectionClass &$class = null): string
|
||||
{
|
||||
$class = 'object' !== $definition->getClass() ? $definition->getClass() : 'stdClass';
|
||||
$class = new \ReflectionClass($class);
|
||||
|
||||
return preg_replace('/^.*\\\\/', '', $definition->getClass())
|
||||
.($asGhostObject ? 'Ghost' : 'Proxy')
|
||||
.ucfirst(substr(hash('sha256', $this->salt.'+'.$class->name.'+'.serialize($definition->getTag('proxy'))), -7));
|
||||
}
|
||||
}
|
39
plugins/simplesaml/lib/vendor/symfony/dependency-injection/LazyProxy/PhpDumper/NullDumper.php
vendored
Normal file
39
plugins/simplesaml/lib/vendor/symfony/dependency-injection/LazyProxy/PhpDumper/NullDumper.php
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\LazyProxy\PhpDumper;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
|
||||
/**
|
||||
* Null dumper, negates any proxy code generation for any given service definition.
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class NullDumper implements DumperInterface
|
||||
{
|
||||
public function isProxyCandidate(Definition $definition, ?bool &$asGhostObject = null, ?string $id = null): bool
|
||||
{
|
||||
return $asGhostObject = false;
|
||||
}
|
||||
|
||||
public function getProxyFactoryCode(Definition $definition, string $id, string $factoryCode): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function getProxyCode(Definition $definition, ?string $id = null): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
95
plugins/simplesaml/lib/vendor/symfony/dependency-injection/LazyProxy/ProxyHelper.php
vendored
Normal file
95
plugins/simplesaml/lib/vendor/symfony/dependency-injection/LazyProxy/ProxyHelper.php
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\LazyProxy;
|
||||
|
||||
trigger_deprecation('symfony/dependency-injection', '6.2', 'The "%s" class is deprecated, use "%s" instead.', ProxyHelper::class, \Symfony\Component\VarExporter\ProxyHelper::class);
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*
|
||||
* @deprecated since Symfony 6.2, use VarExporter's ProxyHelper instead
|
||||
*/
|
||||
class ProxyHelper
|
||||
{
|
||||
/**
|
||||
* @return string|null The FQCN or builtin name of the type hint, or null when the type hint references an invalid self|parent context
|
||||
*/
|
||||
public static function getTypeHint(\ReflectionFunctionAbstract $r, ?\ReflectionParameter $p = null, bool $noBuiltin = false): ?string
|
||||
{
|
||||
if ($p instanceof \ReflectionParameter) {
|
||||
$type = $p->getType();
|
||||
} else {
|
||||
$type = $r->getReturnType();
|
||||
}
|
||||
if (!$type) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return self::getTypeHintForType($type, $r, $noBuiltin);
|
||||
}
|
||||
|
||||
private static function getTypeHintForType(\ReflectionType $type, \ReflectionFunctionAbstract $r, bool $noBuiltin): ?string
|
||||
{
|
||||
$types = [];
|
||||
$glue = '|';
|
||||
if ($type instanceof \ReflectionUnionType) {
|
||||
$reflectionTypes = $type->getTypes();
|
||||
} elseif ($type instanceof \ReflectionIntersectionType) {
|
||||
$reflectionTypes = $type->getTypes();
|
||||
$glue = '&';
|
||||
} elseif ($type instanceof \ReflectionNamedType) {
|
||||
$reflectionTypes = [$type];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($reflectionTypes as $type) {
|
||||
if ($type instanceof \ReflectionIntersectionType) {
|
||||
$typeHint = self::getTypeHintForType($type, $r, $noBuiltin);
|
||||
if (null === $typeHint) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$types[] = sprintf('(%s)', $typeHint);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($type->isBuiltin()) {
|
||||
if (!$noBuiltin) {
|
||||
$types[] = $type->getName();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
$lcName = strtolower($type->getName());
|
||||
$prefix = $noBuiltin ? '' : '\\';
|
||||
|
||||
if ('self' !== $lcName && 'parent' !== $lcName) {
|
||||
$types[] = $prefix.$type->getName();
|
||||
continue;
|
||||
}
|
||||
if (!$r instanceof \ReflectionMethod) {
|
||||
continue;
|
||||
}
|
||||
if ('self' === $lcName) {
|
||||
$types[] = $prefix.$r->getDeclaringClass()->name;
|
||||
} else {
|
||||
$types[] = ($parent = $r->getDeclaringClass()->getParentClass()) ? $prefix.$parent->name : null;
|
||||
}
|
||||
}
|
||||
|
||||
sort($types);
|
||||
|
||||
return $types ? implode($glue, $types) : null;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user