Augmentation vers version 3.3.0
This commit is contained in:
@@ -16,11 +16,14 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptor\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\Properties;
|
||||
use ProxyManager\ProxyGenerator\Util\UnsetPropertiesGenerator;
|
||||
use ReflectionClass;
|
||||
use ReflectionProperty;
|
||||
|
||||
/**
|
||||
* Magic `__wakeup` for lazy loading value holder objects
|
||||
@@ -32,19 +35,16 @@ class MagicWakeup extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
*/
|
||||
public function __construct(ReflectionClass $originalClass)
|
||||
{
|
||||
parent::__construct($originalClass, '__wakeup');
|
||||
|
||||
/* @var $publicProperties \ReflectionProperty[] */
|
||||
$publicProperties = $originalClass->getProperties(ReflectionProperty::IS_PUBLIC);
|
||||
$unsetProperties = array();
|
||||
|
||||
foreach ($publicProperties as $publicProperty) {
|
||||
$unsetProperties[] = '$this->' . $publicProperty->getName();
|
||||
}
|
||||
|
||||
$this->setBody($unsetProperties ? 'unset(' . implode(', ', $unsetProperties) . ");" : '');
|
||||
$this->setBody(UnsetPropertiesGenerator::generateSnippet(
|
||||
Properties::fromReflectionClass($originalClass),
|
||||
'this'
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptor\MethodGenerator;
|
||||
|
||||
use Closure;
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
/**
|
||||
@@ -33,6 +36,10 @@ class SetMethodPrefixInterceptor extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param PropertyGenerator $prefixInterceptor
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(PropertyGenerator $prefixInterceptor)
|
||||
{
|
||||
@@ -40,11 +47,11 @@ class SetMethodPrefixInterceptor extends MethodGenerator
|
||||
|
||||
$interceptor = new ParameterGenerator('prefixInterceptor');
|
||||
|
||||
$interceptor->setType('Closure');
|
||||
$interceptor->setType(Closure::class);
|
||||
$interceptor->setDefaultValue(null);
|
||||
$this->setParameter(new ParameterGenerator('methodName'));
|
||||
$this->setParameter(new ParameterGenerator('methodName', 'string'));
|
||||
$this->setParameter($interceptor);
|
||||
$this->setDocblock('{@inheritDoc}');
|
||||
$this->setDocBlock('{@inheritDoc}');
|
||||
$this->setBody('$this->' . $prefixInterceptor->getName() . '[$methodName] = $prefixInterceptor;');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptor\MethodGenerator;
|
||||
|
||||
use Closure;
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
/**
|
||||
@@ -33,6 +36,10 @@ class SetMethodSuffixInterceptor extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param PropertyGenerator $suffixInterceptor
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(PropertyGenerator $suffixInterceptor)
|
||||
{
|
||||
@@ -40,11 +47,11 @@ class SetMethodSuffixInterceptor extends MethodGenerator
|
||||
|
||||
$interceptor = new ParameterGenerator('suffixInterceptor');
|
||||
|
||||
$interceptor->setType('Closure');
|
||||
$interceptor->setType(Closure::class);
|
||||
$interceptor->setDefaultValue(null);
|
||||
$this->setParameter(new ParameterGenerator('methodName'));
|
||||
$this->setParameter(new ParameterGenerator('methodName', 'string'));
|
||||
$this->setParameter($interceptor);
|
||||
$this->setDocblock('{@inheritDoc}');
|
||||
$this->setDocBlock('{@inheritDoc}');
|
||||
$this->setBody('$this->' . $suffixInterceptor->getName() . '[$methodName] = $suffixInterceptor;');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptor\PropertyGenerator;
|
||||
|
||||
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
|
||||
@@ -31,13 +33,15 @@ class MethodPrefixInterceptors extends PropertyGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(UniqueIdentifierGenerator::getIdentifier('methodPrefixInterceptors'));
|
||||
|
||||
$this->setDefaultValue(array());
|
||||
$this->setDefaultValue([]);
|
||||
$this->setVisibility(self::VISIBILITY_PRIVATE);
|
||||
$this->setDocblock('@var \\Closure[] map of interceptors to be called per-method before execution');
|
||||
$this->setDocBlock('@var \\Closure[] map of interceptors to be called per-method before execution');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptor\PropertyGenerator;
|
||||
|
||||
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
|
||||
@@ -31,13 +33,15 @@ class MethodSuffixInterceptors extends PropertyGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(UniqueIdentifierGenerator::getIdentifier('methodSuffixInterceptors'));
|
||||
|
||||
$this->setDefaultValue(array());
|
||||
$this->setDefaultValue([]);
|
||||
$this->setVisibility(self::VISIBILITY_PRIVATE);
|
||||
$this->setDocblock('@var \\Closure[] map of interceptors to be called per-method after execution');
|
||||
$this->setDocBlock('@var \\Closure[] map of interceptors to be called per-method after execution');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\Properties;
|
||||
use ReflectionClass;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
/**
|
||||
* The `bindProxyProperties` method implementation for access interceptor scope localizers
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*/
|
||||
class BindProxyProperties extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $prefixInterceptors
|
||||
* @param PropertyGenerator $suffixInterceptors
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
PropertyGenerator $prefixInterceptors,
|
||||
PropertyGenerator $suffixInterceptors
|
||||
) {
|
||||
parent::__construct(
|
||||
'bindProxyProperties',
|
||||
[
|
||||
new ParameterGenerator('localizedObject', $originalClass->getName()),
|
||||
new ParameterGenerator('prefixInterceptors', 'array', []),
|
||||
new ParameterGenerator('suffixInterceptors', 'array', []),
|
||||
],
|
||||
static::FLAG_PRIVATE,
|
||||
null,
|
||||
"@override constructor to setup interceptors\n\n"
|
||||
. "@param \\" . $originalClass->getName() . " \$localizedObject\n"
|
||||
. "@param \\Closure[] \$prefixInterceptors method interceptors to be used before method logic\n"
|
||||
. "@param \\Closure[] \$suffixInterceptors method interceptors to be used before method logic"
|
||||
);
|
||||
|
||||
$localizedProperties = [];
|
||||
|
||||
$properties = Properties::fromReflectionClass($originalClass);
|
||||
|
||||
foreach ($properties->getAccessibleProperties() as $property) {
|
||||
$propertyName = $property->getName();
|
||||
|
||||
$localizedProperties[] = '$this->' . $propertyName . ' = & $localizedObject->' . $propertyName . ';';
|
||||
}
|
||||
|
||||
foreach ($properties->getPrivateProperties() as $property) {
|
||||
$propertyName = $property->getName();
|
||||
|
||||
$localizedProperties[] = "\\Closure::bind(function () use (\$localizedObject) {\n "
|
||||
. '$this->' . $propertyName . ' = & $localizedObject->' . $propertyName . ";\n"
|
||||
. '}, $this, ' . var_export($property->getDeclaringClass()->getName(), true)
|
||||
. ')->__invoke();';
|
||||
}
|
||||
|
||||
$this->setBody(
|
||||
($localizedProperties ? implode("\n\n", $localizedProperties) . "\n\n" : '')
|
||||
. '$this->' . $prefixInterceptors->getName() . " = \$prefixInterceptors;\n"
|
||||
. '$this->' . $suffixInterceptors->getName() . " = \$suffixInterceptors;"
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
@@ -37,30 +39,31 @@ class InterceptedMethod extends MethodGenerator
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $suffixInterceptors
|
||||
*
|
||||
* @return self
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public static function generateMethod(
|
||||
MethodReflection $originalMethod,
|
||||
PropertyGenerator $prefixInterceptors,
|
||||
PropertyGenerator $suffixInterceptors
|
||||
) {
|
||||
) : self {
|
||||
/* @var $method self */
|
||||
$method = static::fromReflection($originalMethod);
|
||||
$forwardedParams = array();
|
||||
$forwardedParams = [];
|
||||
|
||||
foreach ($originalMethod->getParameters() as $parameter) {
|
||||
$forwardedParams[] = '$' . $parameter->getName();
|
||||
$forwardedParams[] = ($parameter->isVariadic() ? '...' : '') . '$' . $parameter->getName();
|
||||
}
|
||||
|
||||
$method->setDocblock('{@inheritDoc}');
|
||||
$method->setBody(
|
||||
InterceptorGenerator::createInterceptedMethodBody(
|
||||
'$returnValue = parent::'
|
||||
. $originalMethod->getName() . '(' . implode(', ', $forwardedParams) . ');',
|
||||
$method,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
)
|
||||
);
|
||||
$method->setDocBlock('{@inheritDoc}');
|
||||
$method->setBody(InterceptorGenerator::createInterceptedMethodBody(
|
||||
'$returnValue = parent::'
|
||||
. $originalMethod->getName() . '(' . implode(', ', $forwardedParams) . ');',
|
||||
$method,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors,
|
||||
$originalMethod
|
||||
));
|
||||
|
||||
return $method;
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\Util\InterceptorGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\GetMethodIfExists;
|
||||
use ReflectionClass;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
@@ -33,6 +36,10 @@ class MagicClone extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $prefixInterceptors
|
||||
* @param PropertyGenerator $suffixInterceptors
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
@@ -41,13 +48,14 @@ class MagicClone extends MagicMethodGenerator
|
||||
) {
|
||||
parent::__construct($originalClass, '__clone');
|
||||
|
||||
$this->setBody(
|
||||
InterceptorGenerator::createInterceptedMethodBody(
|
||||
$originalClass->hasMethod('__clone') ? '$returnValue = parent::__clone();' : '$returnValue = null;',
|
||||
$this,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
)
|
||||
);
|
||||
$parent = GetMethodIfExists::get($originalClass, '__clone');
|
||||
|
||||
$this->setBody(InterceptorGenerator::createInterceptedMethodBody(
|
||||
$parent ? '$returnValue = parent::__clone();' : '$returnValue = null;',
|
||||
$this,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors,
|
||||
$parent
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\GetMethodIfExists;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\Util\InterceptorGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
|
||||
use ReflectionClass;
|
||||
@@ -37,21 +40,24 @@ class MagicGet extends MagicMethodGenerator
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $prefixInterceptors
|
||||
* @param PropertyGenerator $suffixInterceptors
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
PropertyGenerator $prefixInterceptors,
|
||||
PropertyGenerator $suffixInterceptors
|
||||
) {
|
||||
parent::__construct($originalClass, '__get', array(new ParameterGenerator('name')));
|
||||
parent::__construct($originalClass, '__get', [new ParameterGenerator('name')]);
|
||||
|
||||
$override = $originalClass->hasMethod('__get');
|
||||
$parent = GetMethodIfExists::get($originalClass, '__get');
|
||||
|
||||
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
$this->setDocBlock(($parent ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
|
||||
if ($override) {
|
||||
$callParent = '$returnValue = & parent::__get($name);';
|
||||
} else {
|
||||
$callParent = '$returnValue = & parent::__get($name);';
|
||||
|
||||
if (! $parent) {
|
||||
$callParent = PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
PublicScopeSimulator::OPERATION_GET,
|
||||
'name',
|
||||
@@ -61,13 +67,12 @@ class MagicGet extends MagicMethodGenerator
|
||||
);
|
||||
}
|
||||
|
||||
$this->setBody(
|
||||
InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
)
|
||||
);
|
||||
$this->setBody(InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors,
|
||||
$parent
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\GetMethodIfExists;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\Util\InterceptorGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
|
||||
use ReflectionClass;
|
||||
@@ -37,21 +40,24 @@ class MagicIsset extends MagicMethodGenerator
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $prefixInterceptors
|
||||
* @param PropertyGenerator $suffixInterceptors
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
PropertyGenerator $prefixInterceptors,
|
||||
PropertyGenerator $suffixInterceptors
|
||||
) {
|
||||
parent::__construct($originalClass, '__isset', array(new ParameterGenerator('name')));
|
||||
parent::__construct($originalClass, '__isset', [new ParameterGenerator('name')]);
|
||||
|
||||
$override = $originalClass->hasMethod('__isset');
|
||||
$parent = GetMethodIfExists::get($originalClass, '__isset');
|
||||
|
||||
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
$this->setDocBlock(($parent ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
|
||||
if ($override) {
|
||||
$callParent = '$returnValue = & parent::__isset($name);';
|
||||
} else {
|
||||
$callParent = '$returnValue = & parent::__isset($name);';
|
||||
|
||||
if (! $parent) {
|
||||
$callParent = PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
PublicScopeSimulator::OPERATION_ISSET,
|
||||
'name',
|
||||
@@ -61,13 +67,12 @@ class MagicIsset extends MagicMethodGenerator
|
||||
);
|
||||
}
|
||||
|
||||
$this->setBody(
|
||||
InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
)
|
||||
);
|
||||
$this->setBody(InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors,
|
||||
$parent
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\GetMethodIfExists;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\Util\InterceptorGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
|
||||
use ReflectionClass;
|
||||
@@ -37,6 +40,9 @@ class MagicSet extends MagicMethodGenerator
|
||||
* @param \ReflectionClass $originalClass
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $prefixInterceptors
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $suffixInterceptors
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
@@ -46,16 +52,16 @@ class MagicSet extends MagicMethodGenerator
|
||||
parent::__construct(
|
||||
$originalClass,
|
||||
'__set',
|
||||
array(new ParameterGenerator('name'), new ParameterGenerator('value'))
|
||||
[new ParameterGenerator('name'), new ParameterGenerator('value')]
|
||||
);
|
||||
|
||||
$override = $originalClass->hasMethod('__set');
|
||||
$parent = GetMethodIfExists::get($originalClass, '__set');
|
||||
|
||||
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
$this->setDocBlock(($parent ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
|
||||
if ($override) {
|
||||
$callParent = '$returnValue = & parent::__set($name, $value);';
|
||||
} else {
|
||||
$callParent = '$returnValue = & parent::__set($name, $value);';
|
||||
|
||||
if (! $parent) {
|
||||
$callParent = PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
PublicScopeSimulator::OPERATION_SET,
|
||||
'name',
|
||||
@@ -65,13 +71,12 @@ class MagicSet extends MagicMethodGenerator
|
||||
);
|
||||
}
|
||||
|
||||
$this->setBody(
|
||||
InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
)
|
||||
);
|
||||
$this->setBody(InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors,
|
||||
$parent
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\Util\InterceptorGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\GetMethodIfExists;
|
||||
use ReflectionClass;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
@@ -33,6 +36,10 @@ class MagicSleep extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $prefixInterceptors
|
||||
* @param PropertyGenerator $suffixInterceptors
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
@@ -41,17 +48,16 @@ class MagicSleep extends MagicMethodGenerator
|
||||
) {
|
||||
parent::__construct($originalClass, '__sleep');
|
||||
|
||||
$callParent = $originalClass->hasMethod('__sleep')
|
||||
? '$returnValue = & parent::__sleep();'
|
||||
: '$returnValue = array_keys((array) $this);';
|
||||
$parent = GetMethodIfExists::get($originalClass, '__sleep');
|
||||
|
||||
$this->setBody(
|
||||
InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
)
|
||||
);
|
||||
$callParent = $parent ? '$returnValue = & parent::__sleep();' : '$returnValue = array_keys((array) $this);';
|
||||
|
||||
$this->setBody(InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors,
|
||||
$parent
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\GetMethodIfExists;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\Util\InterceptorGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
|
||||
use ReflectionClass;
|
||||
@@ -37,21 +40,24 @@ class MagicUnset extends MagicMethodGenerator
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $prefixInterceptors
|
||||
* @param PropertyGenerator $suffixInterceptors
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
PropertyGenerator $prefixInterceptors,
|
||||
PropertyGenerator $suffixInterceptors
|
||||
) {
|
||||
parent::__construct($originalClass, '__unset', array(new ParameterGenerator('name')));
|
||||
parent::__construct($originalClass, '__unset', [new ParameterGenerator('name')]);
|
||||
|
||||
$override = $originalClass->hasMethod('__unset');
|
||||
$parent = GetMethodIfExists::get($originalClass, '__unset');
|
||||
|
||||
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
$this->setDocBlock(($parent ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
|
||||
if ($override) {
|
||||
$callParent = '$returnValue = & parent::__unset($name);';
|
||||
} else {
|
||||
$callParent = '$returnValue = & parent::__unset($name);';
|
||||
|
||||
if (! $parent) {
|
||||
$callParent = PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
PublicScopeSimulator::OPERATION_UNSET,
|
||||
'name',
|
||||
@@ -61,13 +67,12 @@ class MagicUnset extends MagicMethodGenerator
|
||||
);
|
||||
}
|
||||
|
||||
$this->setBody(
|
||||
InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
)
|
||||
);
|
||||
$this->setBody(InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors,
|
||||
$parent
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
* The `staticProxyConstructor` implementation for an access interceptor scope localizer proxy
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*/
|
||||
class StaticProxyConstructor extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(ReflectionClass $originalClass)
|
||||
{
|
||||
parent::__construct('staticProxyConstructor', [], static::FLAG_PUBLIC | static::FLAG_STATIC);
|
||||
|
||||
$localizedObject = new ParameterGenerator('localizedObject');
|
||||
$prefix = new ParameterGenerator('prefixInterceptors');
|
||||
$suffix = new ParameterGenerator('suffixInterceptors');
|
||||
|
||||
$localizedObject->setType($originalClass->getName());
|
||||
$prefix->setDefaultValue([]);
|
||||
$suffix->setDefaultValue([]);
|
||||
$prefix->setType('array');
|
||||
$suffix->setType('array');
|
||||
|
||||
$this->setParameter($localizedObject);
|
||||
$this->setParameter($prefix);
|
||||
$this->setParameter($suffix);
|
||||
$this->setReturnType($originalClass->getName());
|
||||
|
||||
$this->setDocBlock(
|
||||
"Constructor to setup interceptors\n\n"
|
||||
. "@param \\" . $originalClass->getName() . " \$localizedObject\n"
|
||||
. "@param \\Closure[] \$prefixInterceptors method interceptors to be used before method logic\n"
|
||||
. "@param \\Closure[] \$suffixInterceptors method interceptors to be used before method logic\n\n"
|
||||
. '@return self'
|
||||
);
|
||||
$this->setBody(
|
||||
'static $reflection;' . "\n\n"
|
||||
. '$reflection = $reflection ?: $reflection = new \ReflectionClass(__CLASS__);' . "\n"
|
||||
. '$instance = $reflection->newInstanceWithoutConstructor();' . "\n\n"
|
||||
. '$instance->bindProxyProperties($localizedObject, $prefixInterceptors, $suffixInterceptors);' . "\n\n"
|
||||
. 'return $instance;'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -16,9 +16,12 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\Util;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
use ProxyManager\Generator\Util\ProxiedMethodReturnExpression;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
/**
|
||||
@@ -27,8 +30,7 @@ use Zend\Code\Generator\PropertyGenerator;
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*
|
||||
* @internal - this class is just here as a small utility for this component,
|
||||
* don't use it in your own code
|
||||
* @private - this class is just here as a small utility for this component, don't use it in your own code
|
||||
*/
|
||||
class InterceptorGenerator
|
||||
{
|
||||
@@ -39,19 +41,21 @@ class InterceptorGenerator
|
||||
* @param \ProxyManager\Generator\MethodGenerator $method
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $prefixInterceptors
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $suffixInterceptors
|
||||
* @param \ReflectionMethod|null $originalMethod
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function createInterceptedMethodBody(
|
||||
$methodBody,
|
||||
string $methodBody,
|
||||
MethodGenerator $method,
|
||||
PropertyGenerator $prefixInterceptors,
|
||||
PropertyGenerator $suffixInterceptors
|
||||
) {
|
||||
$name = var_export($method->getName(), true);
|
||||
$prefixInterceptors = $prefixInterceptors->getName();
|
||||
$suffixInterceptors = $suffixInterceptors->getName();
|
||||
$params = array();
|
||||
PropertyGenerator $suffixInterceptors,
|
||||
?\ReflectionMethod $originalMethod
|
||||
) : string {
|
||||
$name = var_export($method->getName(), true);
|
||||
$prefixInterceptorsName = $prefixInterceptors->getName();
|
||||
$suffixInterceptorsName = $suffixInterceptors->getName();
|
||||
$params = [];
|
||||
|
||||
foreach ($method->getParameters() as $parameter) {
|
||||
$parameterName = $parameter->getName();
|
||||
@@ -60,23 +64,23 @@ class InterceptorGenerator
|
||||
|
||||
$paramsString = 'array(' . implode(', ', $params) . ')';
|
||||
|
||||
return "if (isset(\$this->$prefixInterceptors" . "[$name])) {\n"
|
||||
return "if (isset(\$this->$prefixInterceptorsName" . "[$name])) {\n"
|
||||
. " \$returnEarly = false;\n"
|
||||
. " \$prefixReturnValue = \$this->$prefixInterceptors" . "[$name]->__invoke("
|
||||
. " \$prefixReturnValue = \$this->$prefixInterceptorsName" . "[$name]->__invoke("
|
||||
. "\$this, \$this, $name, $paramsString, \$returnEarly);\n\n"
|
||||
. " if (\$returnEarly) {\n"
|
||||
. " return \$prefixReturnValue;\n"
|
||||
. ' ' . ProxiedMethodReturnExpression::generate('$prefixReturnValue', $originalMethod) . "\n"
|
||||
. " }\n"
|
||||
. "}\n\n"
|
||||
. $methodBody . "\n\n"
|
||||
. "if (isset(\$this->$suffixInterceptors" . "[$name])) {\n"
|
||||
. "if (isset(\$this->$suffixInterceptorsName" . "[$name])) {\n"
|
||||
. " \$returnEarly = false;\n"
|
||||
. " \$suffixReturnValue = \$this->$suffixInterceptors" . "[$name]->__invoke("
|
||||
. " \$suffixReturnValue = \$this->$suffixInterceptorsName" . "[$name]->__invoke("
|
||||
. "\$this, \$this, $name, $paramsString, \$returnValue, \$returnEarly);\n\n"
|
||||
. " if (\$returnEarly) {\n"
|
||||
. " return \$suffixReturnValue;\n"
|
||||
. ' ' . ProxiedMethodReturnExpression::generate('$suffixReturnValue', $originalMethod) . "\n"
|
||||
. " }\n"
|
||||
. "}\n\n"
|
||||
. "return \$returnValue;";
|
||||
. ProxiedMethodReturnExpression::generate('$returnValue', $originalMethod);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,13 +16,18 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator;
|
||||
|
||||
use ProxyManager\Exception\InvalidProxiedClassException;
|
||||
use ProxyManager\Generator\Util\ClassGeneratorUtils;
|
||||
use ProxyManager\Proxy\AccessInterceptorInterface;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptor\MethodGenerator\SetMethodPrefixInterceptor;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptor\MethodGenerator\SetMethodSuffixInterceptor;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptor\PropertyGenerator\MethodPrefixInterceptors;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\Constructor;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptor\PropertyGenerator\MethodSuffixInterceptors;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\BindProxyProperties;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\InterceptedMethod;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\MagicClone;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\MagicGet;
|
||||
@@ -30,6 +35,7 @@ use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\MagicSet;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\MagicSleep;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\MagicUnset;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\StaticProxyConstructor;
|
||||
use ProxyManager\ProxyGenerator\Assertion\CanProxyAssertion;
|
||||
use ProxyManager\ProxyGenerator\Util\ProxiedMethodsFilter;
|
||||
use ReflectionClass;
|
||||
@@ -51,15 +57,19 @@ class AccessInterceptorScopeLocalizerGenerator implements ProxyGeneratorInterfac
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws InvalidProxiedClassException
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function generate(ReflectionClass $originalClass, ClassGenerator $classGenerator)
|
||||
{
|
||||
CanProxyAssertion::assertClassCanBeProxied($originalClass, false);
|
||||
|
||||
$classGenerator->setExtendedClass($originalClass->getName());
|
||||
$classGenerator->setImplementedInterfaces(array('ProxyManager\\Proxy\\AccessInterceptorInterface'));
|
||||
$classGenerator->setImplementedInterfaces([AccessInterceptorInterface::class]);
|
||||
$classGenerator->addPropertyFromGenerator($prefixInterceptors = new MethodPrefixInterceptors());
|
||||
$classGenerator->addPropertyFromGenerator($suffixInterceptors = new MethodPrefixInterceptors());
|
||||
$classGenerator->addPropertyFromGenerator($suffixInterceptors = new MethodSuffixInterceptors());
|
||||
|
||||
array_map(
|
||||
function (MethodGenerator $generatedMethod) use ($originalClass, $classGenerator) {
|
||||
@@ -67,20 +77,15 @@ class AccessInterceptorScopeLocalizerGenerator implements ProxyGeneratorInterfac
|
||||
},
|
||||
array_merge(
|
||||
array_map(
|
||||
function (ReflectionMethod $method) use ($prefixInterceptors, $suffixInterceptors) {
|
||||
return InterceptedMethod::generateMethod(
|
||||
new MethodReflection($method->getDeclaringClass()->getName(), $method->getName()),
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
);
|
||||
},
|
||||
$this->buildMethodInterceptor($prefixInterceptors, $suffixInterceptors),
|
||||
ProxiedMethodsFilter::getProxiedMethods(
|
||||
$originalClass,
|
||||
array('__get', '__set', '__isset', '__unset', '__clone', '__sleep')
|
||||
['__get', '__set', '__isset', '__unset', '__clone', '__sleep']
|
||||
)
|
||||
),
|
||||
array(
|
||||
new Constructor($originalClass, $prefixInterceptors, $suffixInterceptors),
|
||||
[
|
||||
new StaticProxyConstructor($originalClass),
|
||||
new BindProxyProperties($originalClass, $prefixInterceptors, $suffixInterceptors),
|
||||
new SetMethodPrefixInterceptor($prefixInterceptors),
|
||||
new SetMethodSuffixInterceptor($suffixInterceptors),
|
||||
new MagicGet($originalClass, $prefixInterceptors, $suffixInterceptors),
|
||||
@@ -89,8 +94,21 @@ class AccessInterceptorScopeLocalizerGenerator implements ProxyGeneratorInterfac
|
||||
new MagicUnset($originalClass, $prefixInterceptors, $suffixInterceptors),
|
||||
new MagicSleep($originalClass, $prefixInterceptors, $suffixInterceptors),
|
||||
new MagicClone($originalClass, $prefixInterceptors, $suffixInterceptors),
|
||||
)
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private function buildMethodInterceptor(
|
||||
MethodPrefixInterceptors $prefixInterceptors,
|
||||
MethodSuffixInterceptors $suffixInterceptors
|
||||
) : callable {
|
||||
return function (ReflectionMethod $method) use ($prefixInterceptors, $suffixInterceptors) : InterceptedMethod {
|
||||
return InterceptedMethod::generateMethod(
|
||||
new MethodReflection($method->getDeclaringClass()->getName(), $method->getName()),
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
@@ -38,32 +40,33 @@ class InterceptedMethod extends MethodGenerator
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $suffixInterceptors
|
||||
*
|
||||
* @return self
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public static function generateMethod(
|
||||
MethodReflection $originalMethod,
|
||||
PropertyGenerator $valueHolderProperty,
|
||||
PropertyGenerator $prefixInterceptors,
|
||||
PropertyGenerator $suffixInterceptors
|
||||
) {
|
||||
) : self {
|
||||
/* @var $method self */
|
||||
$method = static::fromReflection($originalMethod);
|
||||
$forwardedParams = array();
|
||||
$forwardedParams = [];
|
||||
|
||||
foreach ($originalMethod->getParameters() as $parameter) {
|
||||
$forwardedParams[] = '$' . $parameter->getName();
|
||||
$forwardedParams[] = ($parameter->isVariadic() ? '...' : '') . '$' . $parameter->getName();
|
||||
}
|
||||
|
||||
$method->setDocblock('{@inheritDoc}');
|
||||
$method->setBody(
|
||||
InterceptorGenerator::createInterceptedMethodBody(
|
||||
'$returnValue = $this->' . $valueHolderProperty->getName() . '->'
|
||||
. $originalMethod->getName() . '(' . implode(', ', $forwardedParams) . ');',
|
||||
$method,
|
||||
$valueHolderProperty,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
)
|
||||
);
|
||||
$method->setDocBlock('{@inheritDoc}');
|
||||
$method->setBody(InterceptorGenerator::createInterceptedMethodBody(
|
||||
'$returnValue = $this->' . $valueHolderProperty->getName() . '->'
|
||||
. $originalMethod->getName() . '(' . implode(', ', $forwardedParams) . ');',
|
||||
$method,
|
||||
$valueHolderProperty,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors,
|
||||
$originalMethod
|
||||
));
|
||||
|
||||
return $method;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
@@ -32,6 +34,11 @@ class MagicClone extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $valueHolderProperty
|
||||
* @param PropertyGenerator $prefixInterceptors
|
||||
* @param PropertyGenerator $suffixInterceptors
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
@@ -52,7 +59,7 @@ class MagicClone extends MagicMethodGenerator
|
||||
. "}\n\n"
|
||||
. "foreach (\$this->$suffix as \$key => \$value) {\n"
|
||||
. " \$this->$suffix" . "[\$key] = clone \$value;\n"
|
||||
. "}"
|
||||
. '}'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\GetMethodIfExists;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\Util\InterceptorGenerator;
|
||||
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
|
||||
@@ -36,6 +39,15 @@ class MagicGet extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $valueHolder
|
||||
* @param PropertyGenerator $prefixInterceptors
|
||||
* @param PropertyGenerator $suffixInterceptors
|
||||
* @param PublicPropertiesMap $publicProperties
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
@@ -44,12 +56,12 @@ class MagicGet extends MagicMethodGenerator
|
||||
PropertyGenerator $suffixInterceptors,
|
||||
PublicPropertiesMap $publicProperties
|
||||
) {
|
||||
parent::__construct($originalClass, '__get', array(new ParameterGenerator('name')));
|
||||
parent::__construct($originalClass, '__get', [new ParameterGenerator('name')]);
|
||||
|
||||
$override = $originalClass->hasMethod('__get');
|
||||
$parent = GetMethodIfExists::get($originalClass, '__get');
|
||||
$valueHolderName = $valueHolder->getName();
|
||||
|
||||
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
$this->setDocBlock(($parent ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
|
||||
$callParent = PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
PublicScopeSimulator::OPERATION_GET,
|
||||
@@ -65,14 +77,13 @@ class MagicGet extends MagicMethodGenerator
|
||||
. "\n} else {\n $callParent\n}\n\n";
|
||||
}
|
||||
|
||||
$this->setBody(
|
||||
InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$valueHolder,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
)
|
||||
);
|
||||
$this->setBody(InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$valueHolder,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors,
|
||||
$parent
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\GetMethodIfExists;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\Util\InterceptorGenerator;
|
||||
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
|
||||
@@ -36,6 +39,14 @@ class MagicIsset extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $valueHolder
|
||||
* @param PropertyGenerator $prefixInterceptors
|
||||
* @param PropertyGenerator $suffixInterceptors
|
||||
* @param PublicPropertiesMap $publicProperties
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
@@ -44,12 +55,12 @@ class MagicIsset extends MagicMethodGenerator
|
||||
PropertyGenerator $suffixInterceptors,
|
||||
PublicPropertiesMap $publicProperties
|
||||
) {
|
||||
parent::__construct($originalClass, '__isset', array(new ParameterGenerator('name')));
|
||||
parent::__construct($originalClass, '__isset', [new ParameterGenerator('name')]);
|
||||
|
||||
$override = $originalClass->hasMethod('__isset');
|
||||
$parent = GetMethodIfExists::get($originalClass, '__isset');
|
||||
$valueHolderName = $valueHolder->getName();
|
||||
|
||||
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
$this->setDocBlock(($parent ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
|
||||
$callParent = PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
PublicScopeSimulator::OPERATION_ISSET,
|
||||
@@ -65,14 +76,13 @@ class MagicIsset extends MagicMethodGenerator
|
||||
. "\n} else {\n $callParent\n}\n\n";
|
||||
}
|
||||
|
||||
$this->setBody(
|
||||
InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$valueHolder,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
)
|
||||
);
|
||||
$this->setBody(InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$valueHolder,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors,
|
||||
$parent
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\GetMethodIfExists;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\Util\InterceptorGenerator;
|
||||
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
|
||||
@@ -36,6 +39,14 @@ class MagicSet extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $valueHolder
|
||||
* @param PropertyGenerator $prefixInterceptors
|
||||
* @param PropertyGenerator $suffixInterceptors
|
||||
* @param PublicPropertiesMap $publicProperties
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
@@ -47,13 +58,13 @@ class MagicSet extends MagicMethodGenerator
|
||||
parent::__construct(
|
||||
$originalClass,
|
||||
'__set',
|
||||
array(new ParameterGenerator('name'), new ParameterGenerator('value'))
|
||||
[new ParameterGenerator('name'), new ParameterGenerator('value')]
|
||||
);
|
||||
|
||||
$override = $originalClass->hasMethod('__set');
|
||||
$parent = GetMethodIfExists::get($originalClass, '__set');
|
||||
$valueHolderName = $valueHolder->getName();
|
||||
|
||||
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
$this->setDocBlock(($parent ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
|
||||
$callParent = PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
PublicScopeSimulator::OPERATION_SET,
|
||||
@@ -69,14 +80,13 @@ class MagicSet extends MagicMethodGenerator
|
||||
. "\n} else {\n $callParent\n}\n\n";
|
||||
}
|
||||
|
||||
$this->setBody(
|
||||
InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$valueHolder,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
)
|
||||
);
|
||||
$this->setBody(InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$valueHolder,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors,
|
||||
$parent
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\GetMethodIfExists;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\Util\InterceptorGenerator;
|
||||
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
|
||||
@@ -36,6 +39,14 @@ class MagicUnset extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $valueHolder
|
||||
* @param PropertyGenerator $prefixInterceptors
|
||||
* @param PropertyGenerator $suffixInterceptors
|
||||
* @param PublicPropertiesMap $publicProperties
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
@@ -44,12 +55,12 @@ class MagicUnset extends MagicMethodGenerator
|
||||
PropertyGenerator $suffixInterceptors,
|
||||
PublicPropertiesMap $publicProperties
|
||||
) {
|
||||
parent::__construct($originalClass, '__unset', array(new ParameterGenerator('name')));
|
||||
parent::__construct($originalClass, '__unset', [new ParameterGenerator('name')]);
|
||||
|
||||
$override = $originalClass->hasMethod('__unset');
|
||||
$parent = GetMethodIfExists::get($originalClass, '__unset');
|
||||
$valueHolderName = $valueHolder->getName();
|
||||
|
||||
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
$this->setDocBlock(($parent ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
|
||||
$callParent = PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
PublicScopeSimulator::OPERATION_UNSET,
|
||||
@@ -67,14 +78,13 @@ class MagicUnset extends MagicMethodGenerator
|
||||
|
||||
$callParent .= '$returnValue = false;';
|
||||
|
||||
$this->setBody(
|
||||
InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$valueHolder,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
)
|
||||
);
|
||||
$this->setBody(InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$valueHolder,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors,
|
||||
$parent
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\Properties;
|
||||
use ProxyManager\ProxyGenerator\Util\UnsetPropertiesGenerator;
|
||||
use ReflectionClass;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
/**
|
||||
* The `staticProxyConstructor` implementation for access interceptor value holders
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*/
|
||||
class StaticProxyConstructor extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $valueHolder
|
||||
* @param PropertyGenerator $prefixInterceptors
|
||||
* @param PropertyGenerator $suffixInterceptors
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
PropertyGenerator $valueHolder,
|
||||
PropertyGenerator $prefixInterceptors,
|
||||
PropertyGenerator $suffixInterceptors
|
||||
) {
|
||||
parent::__construct('staticProxyConstructor', [], static::FLAG_PUBLIC | static::FLAG_STATIC);
|
||||
|
||||
$prefix = new ParameterGenerator('prefixInterceptors');
|
||||
$suffix = new ParameterGenerator('suffixInterceptors');
|
||||
|
||||
$prefix->setDefaultValue([]);
|
||||
$suffix->setDefaultValue([]);
|
||||
$prefix->setType('array');
|
||||
$suffix->setType('array');
|
||||
|
||||
$this->setParameter(new ParameterGenerator('wrappedObject'));
|
||||
$this->setParameter($prefix);
|
||||
$this->setParameter($suffix);
|
||||
$this->setReturnType($originalClass->getName());
|
||||
|
||||
$this->setDocBlock(
|
||||
"Constructor to setup interceptors\n\n"
|
||||
. "@param \\" . $originalClass->getName() . " \$wrappedObject\n"
|
||||
. "@param \\Closure[] \$prefixInterceptors method interceptors to be used before method logic\n"
|
||||
. "@param \\Closure[] \$suffixInterceptors method interceptors to be used before method logic\n\n"
|
||||
. '@return self'
|
||||
);
|
||||
|
||||
$this->setBody(
|
||||
'static $reflection;' . "\n\n"
|
||||
. '$reflection = $reflection ?: $reflection = new \ReflectionClass(__CLASS__);' . "\n"
|
||||
. '$instance = (new \ReflectionClass(get_class()))->newInstanceWithoutConstructor();' . "\n\n"
|
||||
. UnsetPropertiesGenerator::generateSnippet(Properties::fromReflectionClass($originalClass), 'instance')
|
||||
. '$instance->' . $valueHolder->getName() . " = \$wrappedObject;\n"
|
||||
. '$instance->' . $prefixInterceptors->getName() . " = \$prefixInterceptors;\n"
|
||||
. '$instance->' . $suffixInterceptors->getName() . " = \$suffixInterceptors;\n\n"
|
||||
. 'return $instance;'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -16,9 +16,12 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\Util;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
use ProxyManager\Generator\Util\ProxiedMethodReturnExpression;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
/**
|
||||
@@ -27,8 +30,7 @@ use Zend\Code\Generator\PropertyGenerator;
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*
|
||||
* @internal - this class is just here as a small utility for this component,
|
||||
* don't use it in your own code
|
||||
* @private - this class is just here as a small utility for this component, don't use it in your own code
|
||||
*/
|
||||
class InterceptorGenerator
|
||||
{
|
||||
@@ -40,21 +42,23 @@ class InterceptorGenerator
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $valueHolder
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $prefixInterceptors
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $suffixInterceptors
|
||||
* @param \ReflectionMethod|null $originalMethod
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function createInterceptedMethodBody(
|
||||
$methodBody,
|
||||
string $methodBody,
|
||||
MethodGenerator $method,
|
||||
PropertyGenerator $valueHolder,
|
||||
PropertyGenerator $prefixInterceptors,
|
||||
PropertyGenerator $suffixInterceptors
|
||||
) {
|
||||
$name = var_export($method->getName(), true);
|
||||
$valueHolder = $valueHolder->getName();
|
||||
$prefixInterceptors = $prefixInterceptors->getName();
|
||||
$suffixInterceptors = $suffixInterceptors->getName();
|
||||
$params = array();
|
||||
PropertyGenerator $suffixInterceptors,
|
||||
?\ReflectionMethod $originalMethod
|
||||
) : string {
|
||||
$name = var_export($method->getName(), true);
|
||||
$valueHolderName = $valueHolder->getName();
|
||||
$prefixInterceptorsName = $prefixInterceptors->getName();
|
||||
$suffixInterceptorsName = $suffixInterceptors->getName();
|
||||
$params = [];
|
||||
|
||||
foreach ($method->getParameters() as $parameter) {
|
||||
$parameterName = $parameter->getName();
|
||||
@@ -63,23 +67,23 @@ class InterceptorGenerator
|
||||
|
||||
$paramsString = 'array(' . implode(', ', $params) . ')';
|
||||
|
||||
return "if (isset(\$this->$prefixInterceptors" . "[$name])) {\n"
|
||||
return "if (isset(\$this->$prefixInterceptorsName" . "[$name])) {\n"
|
||||
. " \$returnEarly = false;\n"
|
||||
. " \$prefixReturnValue = \$this->$prefixInterceptors" . "[$name]->__invoke("
|
||||
. "\$this, \$this->$valueHolder, $name, $paramsString, \$returnEarly);\n\n"
|
||||
. " \$prefixReturnValue = \$this->$prefixInterceptorsName" . "[$name]->__invoke("
|
||||
. "\$this, \$this->$valueHolderName, $name, $paramsString, \$returnEarly);\n\n"
|
||||
. " if (\$returnEarly) {\n"
|
||||
. " return \$prefixReturnValue;\n"
|
||||
. ' ' . ProxiedMethodReturnExpression::generate('$prefixReturnValue', $originalMethod) . "\n"
|
||||
. " }\n"
|
||||
. "}\n\n"
|
||||
. $methodBody . "\n\n"
|
||||
. "if (isset(\$this->$suffixInterceptors" . "[$name])) {\n"
|
||||
. "if (isset(\$this->$suffixInterceptorsName" . "[$name])) {\n"
|
||||
. " \$returnEarly = false;\n"
|
||||
. " \$suffixReturnValue = \$this->$suffixInterceptors" . "[$name]->__invoke("
|
||||
. "\$this, \$this->$valueHolder, $name, $paramsString, \$returnValue, \$returnEarly);\n\n"
|
||||
. " \$suffixReturnValue = \$this->$suffixInterceptorsName" . "[$name]->__invoke("
|
||||
. "\$this, \$this->$valueHolderName, $name, $paramsString, \$returnValue, \$returnEarly);\n\n"
|
||||
. " if (\$returnEarly) {\n"
|
||||
. " return \$suffixReturnValue;\n"
|
||||
. ' ' . ProxiedMethodReturnExpression::generate('$suffixReturnValue', $originalMethod) . "\n"
|
||||
. " }\n"
|
||||
. "}\n\n"
|
||||
. "return \$returnValue;";
|
||||
. ProxiedMethodReturnExpression::generate('$returnValue', $originalMethod);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,25 +16,31 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator;
|
||||
|
||||
use ProxyManager\Exception\InvalidProxiedClassException;
|
||||
use ProxyManager\Generator\Util\ClassGeneratorUtils;
|
||||
use ProxyManager\Proxy\AccessInterceptorValueHolderInterface;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptor\MethodGenerator\MagicWakeup;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptor\MethodGenerator\SetMethodPrefixInterceptor;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptor\MethodGenerator\SetMethodSuffixInterceptor;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptor\PropertyGenerator\MethodPrefixInterceptors;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptor\PropertyGenerator\MethodSuffixInterceptors;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\Constructor;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\InterceptedMethod;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\MagicClone;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\MagicGet;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\MagicIsset;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\MagicSet;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\MagicUnset;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\StaticProxyConstructor;
|
||||
use ProxyManager\ProxyGenerator\Assertion\CanProxyAssertion;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingValueHolder\PropertyGenerator\ValueHolderProperty;
|
||||
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\Util\Properties;
|
||||
use ProxyManager\ProxyGenerator\Util\ProxiedMethodsFilter;
|
||||
use ProxyManager\ProxyGenerator\ValueHolder\MethodGenerator\Constructor;
|
||||
use ProxyManager\ProxyGenerator\ValueHolder\MethodGenerator\GetWrappedValueHolderValue;
|
||||
use ProxyManager\ProxyGenerator\ValueHolder\MethodGenerator\MagicSleep;
|
||||
use ReflectionClass;
|
||||
@@ -56,16 +62,17 @@ class AccessInterceptorValueHolderGenerator implements ProxyGeneratorInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws InvalidProxiedClassException
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function generate(ReflectionClass $originalClass, ClassGenerator $classGenerator)
|
||||
{
|
||||
CanProxyAssertion::assertClassCanBeProxied($originalClass);
|
||||
|
||||
$publicProperties = new PublicPropertiesMap($originalClass);
|
||||
$interfaces = array(
|
||||
'ProxyManager\\Proxy\\AccessInterceptorInterface',
|
||||
'ProxyManager\\Proxy\\ValueHolderInterface',
|
||||
);
|
||||
$publicProperties = new PublicPropertiesMap(Properties::fromReflectionClass($originalClass));
|
||||
$interfaces = [AccessInterceptorValueHolderInterface::class];
|
||||
|
||||
if ($originalClass->isInterface()) {
|
||||
$interfaces[] = $originalClass->getName();
|
||||
@@ -85,18 +92,12 @@ class AccessInterceptorValueHolderGenerator implements ProxyGeneratorInterface
|
||||
},
|
||||
array_merge(
|
||||
array_map(
|
||||
function (ReflectionMethod $method) use ($prefixInterceptors, $suffixInterceptors, $valueHolder) {
|
||||
return InterceptedMethod::generateMethod(
|
||||
new MethodReflection($method->getDeclaringClass()->getName(), $method->getName()),
|
||||
$valueHolder,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
);
|
||||
},
|
||||
$this->buildMethodInterceptor($prefixInterceptors, $suffixInterceptors, $valueHolder),
|
||||
ProxiedMethodsFilter::getProxiedMethods($originalClass)
|
||||
),
|
||||
array(
|
||||
new Constructor($originalClass, $valueHolder, $prefixInterceptors, $suffixInterceptors),
|
||||
[
|
||||
Constructor::generateMethod($originalClass, $valueHolder),
|
||||
new StaticProxyConstructor($originalClass, $valueHolder, $prefixInterceptors, $suffixInterceptors),
|
||||
new GetWrappedValueHolderValue($valueHolder),
|
||||
new SetMethodPrefixInterceptor($prefixInterceptors),
|
||||
new SetMethodSuffixInterceptor($suffixInterceptors),
|
||||
@@ -130,9 +131,24 @@ class AccessInterceptorValueHolderGenerator implements ProxyGeneratorInterface
|
||||
),
|
||||
new MagicClone($originalClass, $valueHolder, $prefixInterceptors, $suffixInterceptors),
|
||||
new MagicSleep($originalClass, $valueHolder),
|
||||
new MagicWakeup($originalClass, $valueHolder),
|
||||
)
|
||||
new MagicWakeup($originalClass),
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private function buildMethodInterceptor(
|
||||
MethodPrefixInterceptors $prefixes,
|
||||
MethodSuffixInterceptors $suffixes,
|
||||
ValueHolderProperty $valueHolder
|
||||
) : callable {
|
||||
return function (ReflectionMethod $method) use ($prefixes, $suffixes, $valueHolder) : InterceptedMethod {
|
||||
return InterceptedMethod::generateMethod(
|
||||
new MethodReflection($method->getDeclaringClass()->getName(), $method->getName()),
|
||||
$valueHolder,
|
||||
$prefixes,
|
||||
$suffixes
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\Assertion;
|
||||
|
||||
use BadMethodCallException;
|
||||
@@ -47,7 +49,7 @@ final class CanProxyAssertion
|
||||
*
|
||||
* @throws InvalidProxiedClassException
|
||||
*/
|
||||
public static function assertClassCanBeProxied(ReflectionClass $originalClass, $allowInterfaces = true)
|
||||
public static function assertClassCanBeProxied(ReflectionClass $originalClass, bool $allowInterfaces = true) : void
|
||||
{
|
||||
self::isNotFinal($originalClass);
|
||||
self::hasNoAbstractProtectedMethods($originalClass);
|
||||
@@ -62,7 +64,7 @@ final class CanProxyAssertion
|
||||
*
|
||||
* @throws InvalidProxiedClassException
|
||||
*/
|
||||
private static function isNotFinal(ReflectionClass $originalClass)
|
||||
private static function isNotFinal(ReflectionClass $originalClass) : void
|
||||
{
|
||||
if ($originalClass->isFinal()) {
|
||||
throw InvalidProxiedClassException::finalClassNotSupported($originalClass);
|
||||
@@ -74,11 +76,11 @@ final class CanProxyAssertion
|
||||
*
|
||||
* @throws InvalidProxiedClassException
|
||||
*/
|
||||
private static function hasNoAbstractProtectedMethods(ReflectionClass $originalClass)
|
||||
private static function hasNoAbstractProtectedMethods(ReflectionClass $originalClass) : void
|
||||
{
|
||||
$protectedAbstract = array_filter(
|
||||
$originalClass->getMethods(),
|
||||
function (ReflectionMethod $method) {
|
||||
function (ReflectionMethod $method) : bool {
|
||||
return $method->isAbstract() && $method->isProtected();
|
||||
}
|
||||
);
|
||||
@@ -93,7 +95,7 @@ final class CanProxyAssertion
|
||||
*
|
||||
* @throws InvalidProxiedClassException
|
||||
*/
|
||||
private static function isNotInterface(ReflectionClass $originalClass)
|
||||
private static function isNotInterface(ReflectionClass $originalClass) : void
|
||||
{
|
||||
if ($originalClass->isInterface()) {
|
||||
throw InvalidProxiedClassException::interfaceNotSupported($originalClass);
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoading\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\Properties;
|
||||
use ProxyManager\ProxyGenerator\Util\UnsetPropertiesGenerator;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
/**
|
||||
* The `staticProxyConstructor` implementation for lazy loading proxies
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*/
|
||||
class StaticProxyConstructor extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Static constructor
|
||||
*
|
||||
* @param PropertyGenerator $initializerProperty
|
||||
* @param Properties $properties
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(PropertyGenerator $initializerProperty, Properties $properties)
|
||||
{
|
||||
parent::__construct('staticProxyConstructor', [], static::FLAG_PUBLIC | static::FLAG_STATIC);
|
||||
|
||||
$this->setParameter(new ParameterGenerator('initializer'));
|
||||
|
||||
$this->setDocBlock("Constructor for lazy initialization\n\n@param \\Closure|null \$initializer");
|
||||
$this->setBody(
|
||||
'static $reflection;' . "\n\n"
|
||||
. '$reflection = $reflection ?: $reflection = new \ReflectionClass(__CLASS__);' . "\n"
|
||||
. '$instance = (new \ReflectionClass(get_class()))->newInstanceWithoutConstructor();' . "\n\n"
|
||||
. UnsetPropertiesGenerator::generateSnippet($properties, 'instance')
|
||||
. '$instance->' . $initializerProperty->getName() . ' = $initializer;' . "\n\n"
|
||||
. 'return $instance;'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -16,11 +16,15 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\Properties;
|
||||
use ReflectionProperty;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
/**
|
||||
@@ -34,34 +38,160 @@ class CallInitializer extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param PropertyGenerator $initializerProperty
|
||||
* @param PropertyGenerator $initTracker
|
||||
* @param Properties $properties
|
||||
*/
|
||||
public function __construct(
|
||||
PropertyGenerator $initializerProperty,
|
||||
PropertyGenerator $publicPropsDefaults,
|
||||
PropertyGenerator $initTracker
|
||||
PropertyGenerator $initTracker,
|
||||
Properties $properties
|
||||
) {
|
||||
parent::__construct(UniqueIdentifierGenerator::getIdentifier('callInitializer'));
|
||||
$this->setDocblock("Triggers initialization logic for this ghost object");
|
||||
$docBlock = <<<'DOCBLOCK'
|
||||
Triggers initialization logic for this ghost object
|
||||
|
||||
$this->setParameters(array(
|
||||
new ParameterGenerator('methodName'),
|
||||
new ParameterGenerator('parameters', 'array'),
|
||||
));
|
||||
@param string $methodName
|
||||
@param mixed[] $parameters
|
||||
|
||||
$this->setVisibility(static::VISIBILITY_PRIVATE);
|
||||
@return mixed
|
||||
DOCBLOCK;
|
||||
|
||||
parent::__construct(
|
||||
UniqueIdentifierGenerator::getIdentifier('callInitializer'),
|
||||
[
|
||||
new ParameterGenerator('methodName'),
|
||||
new ParameterGenerator('parameters', 'array'),
|
||||
],
|
||||
static::FLAG_PRIVATE,
|
||||
null,
|
||||
$docBlock
|
||||
);
|
||||
|
||||
$initializer = $initializerProperty->getName();
|
||||
$initialization = $initTracker->getName();
|
||||
|
||||
$this->setBody(
|
||||
'if ($this->' . $initialization . ' || ! $this->' . $initializer . ') {' . "\n return;\n}\n\n"
|
||||
. "\$this->" . $initialization . " = true;\n\n"
|
||||
. "foreach (self::\$" . $publicPropsDefaults->getName() . " as \$key => \$default) {\n"
|
||||
. " \$this->\$key = \$default;\n"
|
||||
. "}\n\n"
|
||||
. '$this->' . $initializer . '->__invoke'
|
||||
. '($this, $methodName, $parameters, $this->' . $initializer . ');' . "\n\n"
|
||||
. "\$this->" . $initialization . " = false;"
|
||||
$bodyTemplate = <<<'PHP'
|
||||
if ($this->%s || ! $this->%s) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->%s = true;
|
||||
|
||||
%s
|
||||
%s
|
||||
|
||||
$result = $this->%s->__invoke($this, $methodName, $parameters, $this->%s, $properties);
|
||||
$this->%s = false;
|
||||
|
||||
return $result;
|
||||
PHP;
|
||||
|
||||
$this->setBody(sprintf(
|
||||
$bodyTemplate,
|
||||
$initialization,
|
||||
$initializer,
|
||||
$initialization,
|
||||
$this->propertiesInitializationCode($properties),
|
||||
$this->propertiesReferenceArrayCode($properties),
|
||||
$initializer,
|
||||
$initializer,
|
||||
$initialization
|
||||
));
|
||||
}
|
||||
|
||||
private function propertiesInitializationCode(Properties $properties) : string
|
||||
{
|
||||
$assignments = [];
|
||||
|
||||
foreach ($properties->getAccessibleProperties() as $property) {
|
||||
$assignments[] = '$this->'
|
||||
. $property->getName()
|
||||
. ' = ' . $this->getExportedPropertyDefaultValue($property)
|
||||
. ';';
|
||||
}
|
||||
|
||||
foreach ($properties->getGroupedPrivateProperties() as $className => $privateProperties) {
|
||||
$cacheKey = 'cache' . str_replace('\\', '_', $className);
|
||||
$assignments[] = 'static $' . $cacheKey . ";\n\n"
|
||||
. '$' . $cacheKey . ' ?: $' . $cacheKey . " = \\Closure::bind(function (\$instance) {\n"
|
||||
. $this->getPropertyDefaultsAssignments($privateProperties) . "\n"
|
||||
. '}, null, ' . var_export($className, true) . ");\n\n"
|
||||
. '$' . $cacheKey . "(\$this);\n\n";
|
||||
}
|
||||
|
||||
return implode("\n", $assignments) . "\n\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ReflectionProperty[] $properties
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getPropertyDefaultsAssignments(array $properties) : string
|
||||
{
|
||||
return implode(
|
||||
"\n",
|
||||
array_map(
|
||||
function (ReflectionProperty $property) : string {
|
||||
return ' $instance->' . $property->getName()
|
||||
. ' = ' . $this->getExportedPropertyDefaultValue($property) . ';';
|
||||
},
|
||||
$properties
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private function propertiesReferenceArrayCode(Properties $properties) : string
|
||||
{
|
||||
$assignments = [];
|
||||
|
||||
foreach ($properties->getAccessibleProperties() as $propertyInternalName => $property) {
|
||||
$assignments[] = ' '
|
||||
. var_export($propertyInternalName, true) . ' => & $this->' . $property->getName()
|
||||
. ',';
|
||||
}
|
||||
|
||||
$code = "\$properties = [\n" . implode("\n", $assignments) . "\n];\n\n";
|
||||
|
||||
// must use assignments, as direct reference during array definition causes a fatal error (not sure why)
|
||||
foreach ($properties->getGroupedPrivateProperties() as $className => $classPrivateProperties) {
|
||||
$cacheKey = 'cacheFetch' . str_replace('\\', '_', $className);
|
||||
|
||||
$code .= 'static $' . $cacheKey . ";\n\n"
|
||||
. '$' . $cacheKey . ' ?: $' . $cacheKey
|
||||
. " = \\Closure::bind(function (\$instance, array & \$properties) {\n"
|
||||
. $this->generatePrivatePropertiesAssignmentsCode($classPrivateProperties)
|
||||
. "}, \$this, " . var_export($className, true) . ");\n\n"
|
||||
. '$' . $cacheKey . "(\$this, \$properties);";
|
||||
}
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ReflectionProperty[] $properties indexed by internal name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function generatePrivatePropertiesAssignmentsCode(array $properties) : string
|
||||
{
|
||||
$code = '';
|
||||
|
||||
foreach ($properties as $property) {
|
||||
$key = "\0" . $property->getDeclaringClass()->getName() . "\0" . $property->getName();
|
||||
$code .= ' $properties[' . var_export($key, true) . '] = '
|
||||
. '& $instance->' . $property->getName() . ";\n";
|
||||
}
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
private function getExportedPropertyDefaultValue(ReflectionProperty $property) : string
|
||||
{
|
||||
$name = $property->getName();
|
||||
$defaults = $property->getDeclaringClass()->getDefaultProperties();
|
||||
|
||||
return var_export($defaults[$name] ?? null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
@@ -32,11 +34,15 @@ class GetProxyInitializer extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param PropertyGenerator $initializerProperty
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(PropertyGenerator $initializerProperty)
|
||||
{
|
||||
parent::__construct('getProxyInitializer');
|
||||
$this->setDocblock('{@inheritDoc}');
|
||||
$this->setDocBlock('{@inheritDoc}');
|
||||
$this->setBody('return $this->' . $initializerProperty->getName() . ';');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
@@ -33,15 +35,21 @@ class InitializeProxy extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param PropertyGenerator $initializerProperty
|
||||
* @param ZendMethodGenerator $callInitializer
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(PropertyGenerator $initializerProperty, ZendMethodGenerator $callInitializer)
|
||||
{
|
||||
parent::__construct('initializeProxy');
|
||||
$this->setDocblock('{@inheritDoc}');
|
||||
$this->setDocBlock('{@inheritDoc}');
|
||||
$this->setReturnType('bool');
|
||||
|
||||
$this->setBody(
|
||||
'return $this->' . $initializerProperty->getName() . ' && $this->' . $callInitializer->getName()
|
||||
. '(\'initializeProxy\', array());'
|
||||
. '(\'initializeProxy\', []);'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
@@ -32,11 +34,16 @@ class IsProxyInitialized extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param PropertyGenerator $initializerProperty
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(PropertyGenerator $initializerProperty)
|
||||
{
|
||||
parent::__construct('isProxyInitialized');
|
||||
$this->setDocblock('{@inheritDoc}');
|
||||
$this->setDocBlock('{@inheritDoc}');
|
||||
$this->setReturnType('bool');
|
||||
$this->setBody('return ! $this->' . $initializerProperty->getName() . ';');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
@@ -33,6 +35,10 @@ class MagicClone extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $initializerProperty
|
||||
* @param MethodGenerator $callInitializer
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
@@ -43,7 +49,7 @@ class MagicClone extends MagicMethodGenerator
|
||||
|
||||
$this->setBody(
|
||||
'$this->' . $initializerProperty->getName() . ' && $this->' . $callInitializer->getName()
|
||||
. '(\'__clone\', array());'
|
||||
. '(\'__clone\', []);'
|
||||
. ($originalClass->hasMethod('__clone') ? "\n\nparent::__clone();" : '')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -16,10 +16,15 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingGhost\PropertyGenerator\InitializationTracker;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingGhost\PropertyGenerator\PrivatePropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingGhost\PropertyGenerator\ProtectedPropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
|
||||
use ReflectionClass;
|
||||
@@ -35,43 +40,120 @@ use Zend\Code\Generator\PropertyGenerator;
|
||||
class MagicGet extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* @param \ReflectionClass $originalClass
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $initializerProperty
|
||||
* @param \Zend\Code\Generator\MethodGenerator $callInitializer
|
||||
* @param \ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap $publicProperties
|
||||
* @var string
|
||||
*/
|
||||
private $callParentTemplate = <<<'PHP'
|
||||
$this->%s && ! $this->%s && $this->%s('__get', array('name' => $name));
|
||||
|
||||
if (isset(self::$%s[$name])) {
|
||||
return $this->$name;
|
||||
}
|
||||
|
||||
if (isset(self::$%s[$name])) {
|
||||
if ($this->%s) {
|
||||
return $this->$name;
|
||||
}
|
||||
|
||||
// check protected property access via compatible class
|
||||
$callers = debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT, 2);
|
||||
$caller = isset($callers[1]) ? $callers[1] : [];
|
||||
$object = isset($caller['object']) ? $caller['object'] : '';
|
||||
$expectedType = self::$%s[$name];
|
||||
|
||||
if ($object instanceof $expectedType) {
|
||||
return $this->$name;
|
||||
}
|
||||
|
||||
$class = isset($caller['class']) ? $caller['class'] : '';
|
||||
|
||||
if ($class === $expectedType || is_subclass_of($class, $expectedType) || $class === 'ReflectionProperty') {
|
||||
return $this->$name;
|
||||
}
|
||||
} elseif (isset(self::$%s[$name])) {
|
||||
// check private property access via same class
|
||||
$callers = debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT, 2);
|
||||
$caller = isset($callers[1]) ? $callers[1] : [];
|
||||
$class = isset($caller['class']) ? $caller['class'] : '';
|
||||
|
||||
static $accessorCache = [];
|
||||
|
||||
if (isset(self::$%s[$name][$class])) {
|
||||
$cacheKey = $class . '#' . $name;
|
||||
$accessor = isset($accessorCache[$cacheKey])
|
||||
? $accessorCache[$cacheKey]
|
||||
: $accessorCache[$cacheKey] = \Closure::bind(function & ($instance) use ($name) {
|
||||
return $instance->$name;
|
||||
}, null, $class);
|
||||
|
||||
return $accessor($this);
|
||||
}
|
||||
|
||||
if ($this->%s || 'ReflectionProperty' === $class) {
|
||||
$tmpClass = key(self::$%s[$name]);
|
||||
$cacheKey = $tmpClass . '#' . $name;
|
||||
$accessor = isset($accessorCache[$cacheKey])
|
||||
? $accessorCache[$cacheKey]
|
||||
: $accessorCache[$cacheKey] = \Closure::bind(function & ($instance) use ($name) {
|
||||
return $instance->$name;
|
||||
}, null, $tmpClass);
|
||||
|
||||
return $accessor($this);
|
||||
}
|
||||
}
|
||||
|
||||
%s
|
||||
PHP;
|
||||
|
||||
/**
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $initializerProperty
|
||||
* @param MethodGenerator $callInitializer
|
||||
* @param PublicPropertiesMap $publicProperties
|
||||
* @param ProtectedPropertiesMap $protectedProperties
|
||||
* @param PrivatePropertiesMap $privateProperties
|
||||
* @param InitializationTracker $initializationTracker
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
PropertyGenerator $initializerProperty,
|
||||
MethodGenerator $callInitializer,
|
||||
PublicPropertiesMap $publicProperties
|
||||
PublicPropertiesMap $publicProperties,
|
||||
ProtectedPropertiesMap $protectedProperties,
|
||||
PrivatePropertiesMap $privateProperties,
|
||||
InitializationTracker $initializationTracker
|
||||
) {
|
||||
parent::__construct($originalClass, '__get', array(new ParameterGenerator('name')));
|
||||
parent::__construct($originalClass, '__get', [new ParameterGenerator('name')]);
|
||||
|
||||
$override = $originalClass->hasMethod('__get');
|
||||
$callParent = '';
|
||||
$override = $originalClass->hasMethod('__get');
|
||||
|
||||
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
$this->setDocBlock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
|
||||
if (! $publicProperties->isEmpty()) {
|
||||
$callParent = 'if (isset(self::$' . $publicProperties->getName() . "[\$name])) {\n"
|
||||
. ' return $this->$name;'
|
||||
. "\n}\n\n";
|
||||
}
|
||||
$parentAccess = 'return parent::__get($name);';
|
||||
|
||||
if ($override) {
|
||||
$callParent .= 'return parent::__get($name);';
|
||||
} else {
|
||||
$callParent .= PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
if (! $override) {
|
||||
$parentAccess = PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
PublicScopeSimulator::OPERATION_GET,
|
||||
'name'
|
||||
);
|
||||
}
|
||||
|
||||
$this->setBody(
|
||||
'$this->' . $initializerProperty->getName() . ' && $this->' . $callInitializer->getName()
|
||||
. '(\'__get\', array(\'name\' => $name));'
|
||||
. "\n\n" . $callParent
|
||||
);
|
||||
$this->setBody(sprintf(
|
||||
$this->callParentTemplate,
|
||||
$initializerProperty->getName(),
|
||||
$initializationTracker->getName(),
|
||||
$callInitializer->getName(),
|
||||
$publicProperties->getName(),
|
||||
$protectedProperties->getName(),
|
||||
$initializationTracker->getName(),
|
||||
$protectedProperties->getName(),
|
||||
$privateProperties->getName(),
|
||||
$privateProperties->getName(),
|
||||
$initializationTracker->getName(),
|
||||
$privateProperties->getName(),
|
||||
$parentAccess
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,14 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingGhost\PropertyGenerator\PrivatePropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingGhost\PropertyGenerator\ProtectedPropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
|
||||
use ReflectionClass;
|
||||
@@ -35,43 +39,110 @@ use Zend\Code\Generator\PropertyGenerator;
|
||||
class MagicIsset extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* @param \ReflectionClass $originalClass
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $initializerProperty
|
||||
* @param \Zend\Code\Generator\MethodGenerator $callInitializer
|
||||
* @param \ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap $publicProperties
|
||||
* @var string
|
||||
*/
|
||||
private $callParentTemplate = <<<'PHP'
|
||||
%s
|
||||
|
||||
if (isset(self::$%s[$name])) {
|
||||
return isset($this->$name);
|
||||
}
|
||||
|
||||
if (isset(self::$%s[$name])) {
|
||||
// check protected property access via compatible class
|
||||
$callers = debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT, 2);
|
||||
$caller = isset($callers[1]) ? $callers[1] : [];
|
||||
$object = isset($caller['object']) ? $caller['object'] : '';
|
||||
$expectedType = self::$%s[$name];
|
||||
|
||||
if ($object instanceof $expectedType) {
|
||||
return isset($this->$name);
|
||||
}
|
||||
|
||||
$class = isset($caller['class']) ? $caller['class'] : '';
|
||||
|
||||
if ($class === $expectedType || is_subclass_of($class, $expectedType)) {
|
||||
return isset($this->$name);
|
||||
}
|
||||
} else {
|
||||
// check private property access via same class
|
||||
$callers = debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT, 2);
|
||||
$caller = isset($callers[1]) ? $callers[1] : [];
|
||||
$class = isset($caller['class']) ? $caller['class'] : '';
|
||||
|
||||
static $accessorCache = [];
|
||||
|
||||
if (isset(self::$%s[$name][$class])) {
|
||||
$cacheKey = $class . '#' . $name;
|
||||
$accessor = isset($accessorCache[$cacheKey])
|
||||
? $accessorCache[$cacheKey]
|
||||
: $accessorCache[$cacheKey] = \Closure::bind(function ($instance) use ($name) {
|
||||
return isset($instance->$name);
|
||||
}, null, $class);
|
||||
|
||||
return $accessor($this);
|
||||
}
|
||||
|
||||
if ('ReflectionProperty' === $class) {
|
||||
$tmpClass = key(self::$%s[$name]);
|
||||
$cacheKey = $tmpClass . '#' . $name;
|
||||
$accessor = isset($accessorCache[$cacheKey])
|
||||
? $accessorCache[$cacheKey]
|
||||
: $accessorCache[$cacheKey] = \Closure::bind(function ($instance) use ($name) {
|
||||
return isset($instance->$name);
|
||||
}, null, $tmpClass);
|
||||
|
||||
return $accessor($this);
|
||||
}
|
||||
}
|
||||
|
||||
%s
|
||||
PHP;
|
||||
|
||||
/**
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $initializerProperty
|
||||
* @param MethodGenerator $callInitializer
|
||||
* @param PublicPropertiesMap $publicProperties
|
||||
* @param ProtectedPropertiesMap $protectedProperties
|
||||
* @param PrivatePropertiesMap $privateProperties
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
PropertyGenerator $initializerProperty,
|
||||
MethodGenerator $callInitializer,
|
||||
PublicPropertiesMap $publicProperties
|
||||
PublicPropertiesMap $publicProperties,
|
||||
ProtectedPropertiesMap $protectedProperties,
|
||||
PrivatePropertiesMap $privateProperties
|
||||
) {
|
||||
parent::__construct($originalClass, '__isset', array(new ParameterGenerator('name')));
|
||||
parent::__construct($originalClass, '__isset', [new ParameterGenerator('name')]);
|
||||
|
||||
$override = $originalClass->hasMethod('__isset');
|
||||
$callParent = '';
|
||||
$override = $originalClass->hasMethod('__isset');
|
||||
|
||||
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
$this->setDocBlock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
|
||||
if (! $publicProperties->isEmpty()) {
|
||||
$callParent = 'if (isset(self::$' . $publicProperties->getName() . "[\$name])) {\n"
|
||||
. ' return isset($this->$name);'
|
||||
. "\n}\n\n";
|
||||
}
|
||||
$parentAccess = 'return parent::__isset($name);';
|
||||
|
||||
if ($override) {
|
||||
$callParent .= 'return parent::__isset($name);';
|
||||
} else {
|
||||
$callParent .= PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
if (! $override) {
|
||||
$parentAccess = PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
PublicScopeSimulator::OPERATION_ISSET,
|
||||
'name'
|
||||
);
|
||||
}
|
||||
|
||||
$this->setBody(
|
||||
$this->setBody(sprintf(
|
||||
$this->callParentTemplate,
|
||||
'$this->' . $initializerProperty->getName() . ' && $this->' . $callInitializer->getName()
|
||||
. '(\'__isset\', array(\'name\' => $name));'
|
||||
. "\n\n" . $callParent
|
||||
);
|
||||
. '(\'__isset\', array(\'name\' => $name));',
|
||||
$publicProperties->getName(),
|
||||
$protectedProperties->getName(),
|
||||
$protectedProperties->getName(),
|
||||
$privateProperties->getName(),
|
||||
$privateProperties->getName(),
|
||||
$parentAccess
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,14 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingGhost\PropertyGenerator\PrivatePropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingGhost\PropertyGenerator\ProtectedPropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
|
||||
use ReflectionClass;
|
||||
@@ -35,47 +39,116 @@ use Zend\Code\Generator\PropertyGenerator;
|
||||
class MagicSet extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* @param \ReflectionClass $originalClass
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $initializerProperty
|
||||
* @param \Zend\Code\Generator\MethodGenerator $callInitializer
|
||||
* @param \ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap $publicProperties
|
||||
* @var string
|
||||
*/
|
||||
private $callParentTemplate = <<<'PHP'
|
||||
%s
|
||||
|
||||
if (isset(self::$%s[$name])) {
|
||||
return ($this->$name = $value);
|
||||
}
|
||||
|
||||
if (isset(self::$%s[$name])) {
|
||||
// check protected property access via compatible class
|
||||
$callers = debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT, 2);
|
||||
$caller = isset($callers[1]) ? $callers[1] : [];
|
||||
$object = isset($caller['object']) ? $caller['object'] : '';
|
||||
$expectedType = self::$%s[$name];
|
||||
|
||||
if ($object instanceof $expectedType) {
|
||||
return ($this->$name = $value);
|
||||
}
|
||||
|
||||
$class = isset($caller['class']) ? $caller['class'] : '';
|
||||
|
||||
if ($class === $expectedType || is_subclass_of($class, $expectedType) || $class === 'ReflectionProperty') {
|
||||
return ($this->$name = $value);
|
||||
}
|
||||
} elseif (isset(self::$%s[$name])) {
|
||||
// check private property access via same class
|
||||
$callers = debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT, 2);
|
||||
$caller = isset($callers[1]) ? $callers[1] : [];
|
||||
$class = isset($caller['class']) ? $caller['class'] : '';
|
||||
|
||||
static $accessorCache = [];
|
||||
|
||||
if (isset(self::$%s[$name][$class])) {
|
||||
$cacheKey = $class . '#' . $name;
|
||||
$accessor = isset($accessorCache[$cacheKey])
|
||||
? $accessorCache[$cacheKey]
|
||||
: $accessorCache[$cacheKey] = \Closure::bind(function ($instance, $value) use ($name) {
|
||||
return ($instance->$name = $value);
|
||||
}, null, $class);
|
||||
|
||||
return $accessor($this, $value);
|
||||
}
|
||||
|
||||
if ('ReflectionProperty' === $class) {
|
||||
$tmpClass = key(self::$%s[$name]);
|
||||
$cacheKey = $tmpClass . '#' . $name;
|
||||
$accessor = isset($accessorCache[$cacheKey])
|
||||
? $accessorCache[$cacheKey]
|
||||
: $accessorCache[$cacheKey] = \Closure::bind(function ($instance, $value) use ($name) {
|
||||
return ($instance->$name = $value);
|
||||
}, null, $tmpClass);
|
||||
|
||||
return $accessor($this, $value);
|
||||
}
|
||||
}
|
||||
|
||||
%s
|
||||
PHP;
|
||||
|
||||
/**
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $initializerProperty
|
||||
* @param MethodGenerator $callInitializer
|
||||
* @param PublicPropertiesMap $publicProperties
|
||||
* @param ProtectedPropertiesMap $protectedProperties
|
||||
* @param PrivatePropertiesMap $privateProperties
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
PropertyGenerator $initializerProperty,
|
||||
MethodGenerator $callInitializer,
|
||||
PublicPropertiesMap $publicProperties
|
||||
PublicPropertiesMap $publicProperties,
|
||||
ProtectedPropertiesMap $protectedProperties,
|
||||
PrivatePropertiesMap $privateProperties
|
||||
) {
|
||||
parent::__construct(
|
||||
$originalClass,
|
||||
'__set',
|
||||
array(new ParameterGenerator('name'), new ParameterGenerator('value'))
|
||||
[new ParameterGenerator('name'), new ParameterGenerator('value')]
|
||||
);
|
||||
|
||||
$override = $originalClass->hasMethod('__set');
|
||||
$callParent = '';
|
||||
$override = $originalClass->hasMethod('__set');
|
||||
|
||||
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
$this->setDocBlock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
|
||||
if (! $publicProperties->isEmpty()) {
|
||||
$callParent = 'if (isset(self::$' . $publicProperties->getName() . "[\$name])) {\n"
|
||||
. ' return ($this->$name = $value);'
|
||||
. "\n}\n\n";
|
||||
}
|
||||
$parentAccess = 'return parent::__set($name, $value);';
|
||||
|
||||
if ($override) {
|
||||
$callParent .= 'return parent::__set($name, $value);';
|
||||
} else {
|
||||
$callParent .= PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
if (! $override) {
|
||||
$parentAccess = PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
PublicScopeSimulator::OPERATION_SET,
|
||||
'name',
|
||||
'value'
|
||||
);
|
||||
}
|
||||
|
||||
$this->setBody(
|
||||
$this->setBody(sprintf(
|
||||
$this->callParentTemplate,
|
||||
'$this->' . $initializerProperty->getName() . ' && $this->' . $callInitializer->getName()
|
||||
. '(\'__set\', array(\'name\' => $name, \'value\' => $value));' . "\n\n" . $callParent
|
||||
);
|
||||
. '(\'__set\', array(\'name\' => $name, \'value\' => $value));',
|
||||
$publicProperties->getName(),
|
||||
$protectedProperties->getName(),
|
||||
$protectedProperties->getName(),
|
||||
$privateProperties->getName(),
|
||||
$privateProperties->getName(),
|
||||
$privateProperties->getName(),
|
||||
$parentAccess
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
@@ -33,6 +35,10 @@ class MagicSleep extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $initializerProperty
|
||||
* @param MethodGenerator $callInitializer
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
@@ -43,7 +49,7 @@ class MagicSleep extends MagicMethodGenerator
|
||||
|
||||
$this->setBody(
|
||||
'$this->' . $initializerProperty->getName() . ' && $this->' . $callInitializer->getName()
|
||||
. '(\'__sleep\', array());' . "\n\n"
|
||||
. '(\'__sleep\', []);' . "\n\n"
|
||||
. ($originalClass->hasMethod('__sleep') ? 'return parent::__sleep();' : 'return array_keys((array) $this);')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -16,10 +16,14 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingGhost\PropertyGenerator\PrivatePropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingGhost\PropertyGenerator\ProtectedPropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
|
||||
use ReflectionClass;
|
||||
@@ -35,44 +39,117 @@ use Zend\Code\Generator\PropertyGenerator;
|
||||
class MagicUnset extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* @param \ReflectionClass $originalClass
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $initializerProperty
|
||||
* @param \Zend\Code\Generator\MethodGenerator $callInitializer
|
||||
* @param \ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap $publicProperties
|
||||
* @var string
|
||||
*/
|
||||
private $callParentTemplate = <<<'PHP'
|
||||
%s
|
||||
|
||||
if (isset(self::$%s[$name])) {
|
||||
unset($this->$name);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset(self::$%s[$name])) {
|
||||
// check protected property access via compatible class
|
||||
$callers = debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT, 2);
|
||||
$caller = isset($callers[1]) ? $callers[1] : [];
|
||||
$object = isset($caller['object']) ? $caller['object'] : '';
|
||||
$expectedType = self::$%s[$name];
|
||||
|
||||
if ($object instanceof $expectedType) {
|
||||
unset($this->$name);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$class = isset($caller['class']) ? $caller['class'] : '';
|
||||
|
||||
if ($class === $expectedType || is_subclass_of($class, $expectedType) || $class === 'ReflectionProperty') {
|
||||
unset($this->$name);
|
||||
|
||||
return;
|
||||
}
|
||||
} elseif (isset(self::$%s[$name])) {
|
||||
// check private property access via same class
|
||||
$callers = debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT, 2);
|
||||
$caller = isset($callers[1]) ? $callers[1] : [];
|
||||
$class = isset($caller['class']) ? $caller['class'] : '';
|
||||
|
||||
static $accessorCache = [];
|
||||
|
||||
if (isset(self::$%s[$name][$class])) {
|
||||
$cacheKey = $class . '#' . $name;
|
||||
$accessor = isset($accessorCache[$cacheKey])
|
||||
? $accessorCache[$cacheKey]
|
||||
: $accessorCache[$cacheKey] = \Closure::bind(function ($instance) use ($name) {
|
||||
unset($instance->$name);
|
||||
}, null, $class);
|
||||
|
||||
return $accessor($this);
|
||||
}
|
||||
|
||||
if ('ReflectionProperty' === $class) {
|
||||
$tmpClass = key(self::$%s[$name]);
|
||||
$cacheKey = $tmpClass . '#' . $name;
|
||||
$accessor = isset($accessorCache[$cacheKey])
|
||||
? $accessorCache[$cacheKey]
|
||||
: $accessorCache[$cacheKey] = \Closure::bind(function ($instance) use ($name) {
|
||||
unset($instance->$name);
|
||||
}, null, $tmpClass);
|
||||
|
||||
return $accessor($this);
|
||||
}
|
||||
}
|
||||
|
||||
%s
|
||||
PHP;
|
||||
|
||||
/**
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $initializerProperty
|
||||
* @param MethodGenerator $callInitializer
|
||||
* @param PublicPropertiesMap $publicProperties
|
||||
* @param ProtectedPropertiesMap $protectedProperties
|
||||
* @param PrivatePropertiesMap $privateProperties
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
PropertyGenerator $initializerProperty,
|
||||
MethodGenerator $callInitializer,
|
||||
PublicPropertiesMap $publicProperties
|
||||
PublicPropertiesMap $publicProperties,
|
||||
ProtectedPropertiesMap $protectedProperties,
|
||||
PrivatePropertiesMap $privateProperties
|
||||
) {
|
||||
parent::__construct($originalClass, '__unset', array(new ParameterGenerator('name')));
|
||||
parent::__construct($originalClass, '__unset', [new ParameterGenerator('name')]);
|
||||
|
||||
$override = $originalClass->hasMethod('__unset');
|
||||
$callParent = '';
|
||||
$override = $originalClass->hasMethod('__unset');
|
||||
|
||||
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
$this->setDocBlock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
|
||||
if (! $publicProperties->isEmpty()) {
|
||||
$callParent = 'if (isset(self::$' . $publicProperties->getName() . "[\$name])) {\n"
|
||||
. ' unset($this->$name);'
|
||||
. "\n\n return;"
|
||||
. "\n}\n\n";
|
||||
}
|
||||
$parentAccess = 'return parent::__unset($name);';
|
||||
|
||||
if ($override) {
|
||||
$callParent .= "return parent::__unset(\$name);";
|
||||
} else {
|
||||
$callParent .= PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
if (! $override) {
|
||||
$parentAccess = PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
PublicScopeSimulator::OPERATION_UNSET,
|
||||
'name'
|
||||
);
|
||||
}
|
||||
|
||||
$this->setBody(
|
||||
$this->setBody(sprintf(
|
||||
$this->callParentTemplate,
|
||||
'$this->' . $initializerProperty->getName() . ' && $this->' . $callInitializer->getName()
|
||||
. '(\'__unset\', array(\'name\' => $name));'
|
||||
. "\n\n" . $callParent
|
||||
);
|
||||
. '(\'__unset\', array(\'name\' => $name));',
|
||||
$publicProperties->getName(),
|
||||
$protectedProperties->getName(),
|
||||
$protectedProperties->getName(),
|
||||
$privateProperties->getName(),
|
||||
$privateProperties->getName(),
|
||||
$privateProperties->getName(),
|
||||
$parentAccess
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
/**
|
||||
@@ -33,17 +35,17 @@ class SetProxyInitializer extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param PropertyGenerator $initializerProperty
|
||||
*/
|
||||
public function __construct(PropertyGenerator $initializerProperty)
|
||||
{
|
||||
parent::__construct('setProxyInitializer');
|
||||
|
||||
$initializerParameter = new ParameterGenerator('initializer');
|
||||
|
||||
$initializerParameter->setType('Closure');
|
||||
$initializerParameter->setDefaultValue(null);
|
||||
$this->setParameter($initializerParameter);
|
||||
$this->setDocblock('{@inheritDoc}');
|
||||
$this->setBody('$this->' . $initializerProperty->getName() . ' = $initializer;');
|
||||
parent::__construct(
|
||||
'setProxyInitializer',
|
||||
[(new ParameterGenerator('initializer', 'Closure'))->setDefaultValue(null)],
|
||||
self::FLAG_PUBLIC,
|
||||
'$this->' . $initializerProperty->getName() . ' = $initializer;',
|
||||
'{@inheritDoc}'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingGhost\PropertyGenerator;
|
||||
|
||||
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
|
||||
@@ -31,13 +33,15 @@ class InitializationTracker extends PropertyGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(UniqueIdentifierGenerator::getIdentifier('initializationTracker'));
|
||||
|
||||
$this->setVisibility(self::VISIBILITY_PRIVATE);
|
||||
$this->setDocblock('@var bool tracks initialization status - true while the object is initializing');
|
||||
$this->setDocBlock('@var bool tracks initialization status - true while the object is initializing');
|
||||
$this->setDefaultValue(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingGhost\PropertyGenerator;
|
||||
|
||||
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
|
||||
@@ -31,12 +33,14 @@ class InitializerProperty extends PropertyGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(UniqueIdentifierGenerator::getIdentifier('initializer'));
|
||||
|
||||
$this->setVisibility(self::VISIBILITY_PRIVATE);
|
||||
$this->setDocblock('@var \\Closure|null initializer responsible for generating the wrapped object');
|
||||
$this->setDocBlock('@var \\Closure|null initializer responsible for generating the wrapped object');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingGhost\PropertyGenerator;
|
||||
|
||||
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\Properties;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
/**
|
||||
* Property that contains the initializer for a lazy object
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*/
|
||||
class PrivatePropertiesMap extends PropertyGenerator
|
||||
{
|
||||
const KEY_DEFAULT_VALUE = 'defaultValue';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Properties $properties
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(Properties $properties)
|
||||
{
|
||||
parent::__construct(
|
||||
UniqueIdentifierGenerator::getIdentifier('privateProperties')
|
||||
);
|
||||
|
||||
$this->setVisibility(self::VISIBILITY_PRIVATE);
|
||||
$this->setStatic(true);
|
||||
$this->setDocBlock(
|
||||
'@var array[][] visibility and default value of defined properties, indexed by property name and class name'
|
||||
);
|
||||
$this->setDefaultValue($this->getMap($properties));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Properties $properties
|
||||
*
|
||||
* @return int[][]|mixed[][]
|
||||
*/
|
||||
private function getMap(Properties $properties) : array
|
||||
{
|
||||
$map = [];
|
||||
|
||||
foreach ($properties->getPrivateProperties() as $property) {
|
||||
$propertyKey = & $map[$property->getName()];
|
||||
|
||||
$propertyKey[$property->getDeclaringClass()->getName()] = true;
|
||||
}
|
||||
|
||||
return $map;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingGhost\PropertyGenerator;
|
||||
|
||||
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\Properties;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
/**
|
||||
* Property that contains the protected instance lazy-loadable properties of an object
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*/
|
||||
class ProtectedPropertiesMap extends PropertyGenerator
|
||||
{
|
||||
const KEY_DEFAULT_VALUE = 'defaultValue';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Properties $properties
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(Properties $properties)
|
||||
{
|
||||
parent::__construct(
|
||||
UniqueIdentifierGenerator::getIdentifier('protectedProperties')
|
||||
);
|
||||
|
||||
$this->setVisibility(self::VISIBILITY_PRIVATE);
|
||||
$this->setStatic(true);
|
||||
$this->setDocBlock(
|
||||
'@var string[][] declaring class name of defined protected properties, indexed by property name'
|
||||
);
|
||||
$this->setDefaultValue($this->getMap($properties));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Properties $properties
|
||||
*
|
||||
* @return int[][]|mixed[][]
|
||||
*/
|
||||
private function getMap(Properties $properties) : array
|
||||
{
|
||||
$map = [];
|
||||
|
||||
foreach ($properties->getProtectedProperties() as $property) {
|
||||
$map[$property->getName()] = $property->getDeclaringClass()->getName();
|
||||
}
|
||||
|
||||
return $map;
|
||||
}
|
||||
}
|
||||
@@ -16,16 +16,20 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator;
|
||||
|
||||
use ProxyManager\Exception\InvalidProxiedClassException;
|
||||
use ProxyManager\Generator\MethodGenerator as ProxyManagerMethodGenerator;
|
||||
use ProxyManager\Generator\Util\ClassGeneratorUtils;
|
||||
use ProxyManager\Proxy\GhostObjectInterface;
|
||||
use ProxyManager\ProxyGenerator\Assertion\CanProxyAssertion;
|
||||
use ProxyManager\ProxyGenerator\LazyLoading\MethodGenerator\Constructor;
|
||||
use ProxyManager\ProxyGenerator\LazyLoading\MethodGenerator\StaticProxyConstructor;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator\CallInitializer;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator\GetProxyInitializer;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator\InitializeProxy;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator\IsProxyInitialized;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator\LazyLoadingMethodInterceptor;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator\MagicClone;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator\MagicGet;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator\MagicIsset;
|
||||
@@ -35,8 +39,10 @@ use ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator\MagicUnset;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator\SetProxyInitializer;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingGhost\PropertyGenerator\InitializationTracker;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingGhost\PropertyGenerator\InitializerProperty;
|
||||
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesDefaults;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingGhost\PropertyGenerator\PrivatePropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingGhost\PropertyGenerator\ProtectedPropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\Util\Properties;
|
||||
use ProxyManager\ProxyGenerator\Util\ProxiedMethodsFilter;
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
@@ -56,59 +62,104 @@ class LazyLoadingGhostGenerator implements ProxyGeneratorInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @throws InvalidProxiedClassException
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function generate(ReflectionClass $originalClass, ClassGenerator $classGenerator)
|
||||
public function generate(ReflectionClass $originalClass, ClassGenerator $classGenerator, array $proxyOptions = [])
|
||||
{
|
||||
CanProxyAssertion::assertClassCanBeProxied($originalClass);
|
||||
CanProxyAssertion::assertClassCanBeProxied($originalClass, false);
|
||||
|
||||
$interfaces = array('ProxyManager\\Proxy\\GhostObjectInterface');
|
||||
$publicProperties = new PublicPropertiesMap($originalClass);
|
||||
$publicPropsDefaults = new PublicPropertiesDefaults($originalClass);
|
||||
$filteredProperties = Properties::fromReflectionClass($originalClass)
|
||||
->filter($proxyOptions['skippedProperties'] ?? []);
|
||||
|
||||
if ($originalClass->isInterface()) {
|
||||
$interfaces[] = $originalClass->getName();
|
||||
} else {
|
||||
$classGenerator->setExtendedClass($originalClass->getName());
|
||||
}
|
||||
$publicProperties = new PublicPropertiesMap($filteredProperties);
|
||||
$privateProperties = new PrivatePropertiesMap($filteredProperties);
|
||||
$protectedProperties = new ProtectedPropertiesMap($filteredProperties);
|
||||
|
||||
$classGenerator->setImplementedInterfaces($interfaces);
|
||||
$classGenerator->setExtendedClass($originalClass->getName());
|
||||
$classGenerator->setImplementedInterfaces([GhostObjectInterface::class]);
|
||||
$classGenerator->addPropertyFromGenerator($initializer = new InitializerProperty());
|
||||
$classGenerator->addPropertyFromGenerator($initializationTracker = new InitializationTracker());
|
||||
$classGenerator->addPropertyFromGenerator($publicProperties);
|
||||
$classGenerator->addPropertyFromGenerator($publicPropsDefaults);
|
||||
$classGenerator->addPropertyFromGenerator($privateProperties);
|
||||
$classGenerator->addPropertyFromGenerator($protectedProperties);
|
||||
|
||||
$init = new CallInitializer($initializer, $publicPropsDefaults, $initializationTracker);
|
||||
$init = new CallInitializer($initializer, $initializationTracker, $filteredProperties);
|
||||
|
||||
array_map(
|
||||
function (MethodGenerator $generatedMethod) use ($originalClass, $classGenerator) {
|
||||
ClassGeneratorUtils::addMethodIfNotFinal($originalClass, $classGenerator, $generatedMethod);
|
||||
},
|
||||
array_merge(
|
||||
array_map(
|
||||
function (ReflectionMethod $method) use ($initializer, $init) {
|
||||
return LazyLoadingMethodInterceptor::generateMethod(
|
||||
new MethodReflection($method->getDeclaringClass()->getName(), $method->getName()),
|
||||
$initializer,
|
||||
$init
|
||||
);
|
||||
},
|
||||
ProxiedMethodsFilter::getProxiedMethods($originalClass)
|
||||
),
|
||||
array(
|
||||
$this->getAbstractProxiedMethods($originalClass),
|
||||
[
|
||||
$init,
|
||||
new Constructor($originalClass, $initializer),
|
||||
new MagicGet($originalClass, $initializer, $init, $publicProperties),
|
||||
new MagicSet($originalClass, $initializer, $init, $publicProperties),
|
||||
new MagicIsset($originalClass, $initializer, $init, $publicProperties),
|
||||
new MagicUnset($originalClass, $initializer, $init, $publicProperties),
|
||||
new MagicClone($originalClass, $initializer, $init, $publicProperties),
|
||||
new MagicSleep($originalClass, $initializer, $init, $publicProperties),
|
||||
new StaticProxyConstructor($initializer, $filteredProperties),
|
||||
new MagicGet(
|
||||
$originalClass,
|
||||
$initializer,
|
||||
$init,
|
||||
$publicProperties,
|
||||
$protectedProperties,
|
||||
$privateProperties,
|
||||
$initializationTracker
|
||||
),
|
||||
new MagicSet(
|
||||
$originalClass,
|
||||
$initializer,
|
||||
$init,
|
||||
$publicProperties,
|
||||
$protectedProperties,
|
||||
$privateProperties
|
||||
),
|
||||
new MagicIsset(
|
||||
$originalClass,
|
||||
$initializer,
|
||||
$init,
|
||||
$publicProperties,
|
||||
$protectedProperties,
|
||||
$privateProperties
|
||||
),
|
||||
new MagicUnset(
|
||||
$originalClass,
|
||||
$initializer,
|
||||
$init,
|
||||
$publicProperties,
|
||||
$protectedProperties,
|
||||
$privateProperties
|
||||
),
|
||||
new MagicClone($originalClass, $initializer, $init),
|
||||
new MagicSleep($originalClass, $initializer, $init),
|
||||
new SetProxyInitializer($initializer),
|
||||
new GetProxyInitializer($initializer),
|
||||
new InitializeProxy($initializer, $init),
|
||||
new IsProxyInitialized($initializer),
|
||||
)
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all abstract methods to be proxied
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
*
|
||||
* @return MethodGenerator[]
|
||||
*/
|
||||
private function getAbstractProxiedMethods(ReflectionClass $originalClass) : array
|
||||
{
|
||||
return array_map(
|
||||
function (ReflectionMethod $method) : ProxyManagerMethodGenerator {
|
||||
$generated = ProxyManagerMethodGenerator
|
||||
::fromReflection(new MethodReflection($method->getDeclaringClass()->getName(), $method->getName()));
|
||||
|
||||
$generated->setAbstract(false);
|
||||
|
||||
return $generated;
|
||||
},
|
||||
ProxiedMethodsFilter::getAbstractProxiedMethods($originalClass)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
@@ -32,11 +34,15 @@ class GetProxyInitializer extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param PropertyGenerator $initializerProperty
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(PropertyGenerator $initializerProperty)
|
||||
{
|
||||
parent::__construct('getProxyInitializer');
|
||||
$this->setDocblock('{@inheritDoc}');
|
||||
$this->setDocBlock('{@inheritDoc}');
|
||||
$this->setBody('return $this->' . $initializerProperty->getName() . ';');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
@@ -32,11 +34,17 @@ class InitializeProxy extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param PropertyGenerator $initializerProperty
|
||||
* @param PropertyGenerator $valueHolderProperty
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(PropertyGenerator $initializerProperty, PropertyGenerator $valueHolderProperty)
|
||||
{
|
||||
parent::__construct('initializeProxy');
|
||||
$this->setDocblock('{@inheritDoc}');
|
||||
$this->setDocBlock('{@inheritDoc}');
|
||||
$this->setReturnType('bool');
|
||||
|
||||
$initializer = $initializerProperty->getName();
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
@@ -32,11 +34,16 @@ class IsProxyInitialized extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param PropertyGenerator $valueHolderProperty
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(PropertyGenerator $valueHolderProperty)
|
||||
{
|
||||
parent::__construct('isProxyInitialized');
|
||||
$this->setDocblock('{@inheritDoc}');
|
||||
$this->setDocBlock('{@inheritDoc}');
|
||||
$this->setReturnType('bool');
|
||||
$this->setBody('return null !== $this->' . $valueHolderProperty->getName() . ';');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,12 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
use ProxyManager\Generator\Util\ProxiedMethodReturnExpression;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
use Zend\Code\Reflection\MethodReflection;
|
||||
|
||||
@@ -35,26 +38,29 @@ class LazyLoadingMethodInterceptor extends MethodGenerator
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $initializerProperty
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $valueHolderProperty
|
||||
*
|
||||
* @return LazyLoadingMethodInterceptor|static
|
||||
* @return self
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public static function generateMethod(
|
||||
MethodReflection $originalMethod,
|
||||
PropertyGenerator $initializerProperty,
|
||||
PropertyGenerator $valueHolderProperty
|
||||
) {
|
||||
) : self {
|
||||
/* @var $method self */
|
||||
$method = static::fromReflection($originalMethod);
|
||||
$initializerName = $initializerProperty->getName();
|
||||
$valueHolderName = $valueHolderProperty->getName();
|
||||
$parameters = $originalMethod->getParameters();
|
||||
$methodName = $originalMethod->getName();
|
||||
$initializerParams = array();
|
||||
$forwardedParams = array();
|
||||
$initializerParams = [];
|
||||
$forwardedParams = [];
|
||||
|
||||
foreach ($parameters as $parameter) {
|
||||
$parameterName = $parameter->getName();
|
||||
$variadicPrefix = $parameter->isVariadic() ? '...' : '';
|
||||
$initializerParams[] = var_export($parameterName, true) . ' => $' . $parameterName;
|
||||
$forwardedParams[] = '$' . $parameterName;
|
||||
$forwardedParams[] = $variadicPrefix . '$' . $parameterName;
|
||||
}
|
||||
|
||||
$method->setBody(
|
||||
@@ -62,10 +68,12 @@ class LazyLoadingMethodInterceptor extends MethodGenerator
|
||||
. ' && $this->' . $initializerName
|
||||
. '->__invoke($this->' . $valueHolderName . ', $this, ' . var_export($methodName, true)
|
||||
. ', array(' . implode(', ', $initializerParams) . '), $this->' . $initializerName . ");\n\n"
|
||||
. 'return $this->' . $valueHolderName . '->'
|
||||
. $methodName . '(' . implode(', ', $forwardedParams) . ');'
|
||||
. ProxiedMethodReturnExpression::generate(
|
||||
'$this->' . $valueHolderName . '->' . $methodName . '(' . implode(', ', $forwardedParams) . ')',
|
||||
$originalMethod
|
||||
)
|
||||
);
|
||||
$method->setDocblock('{@inheritDoc}');
|
||||
$method->setDocBlock('{@inheritDoc}');
|
||||
|
||||
return $method;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
@@ -32,6 +34,10 @@ class MagicClone extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $initializerProperty
|
||||
* @param PropertyGenerator $valueHolderProperty
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
|
||||
use ReflectionClass;
|
||||
@@ -35,6 +37,14 @@ class MagicGet extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $initializerProperty
|
||||
* @param PropertyGenerator $valueHolderProperty
|
||||
* @param PublicPropertiesMap $publicProperties
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
@@ -42,9 +52,11 @@ class MagicGet extends MagicMethodGenerator
|
||||
PropertyGenerator $valueHolderProperty,
|
||||
PublicPropertiesMap $publicProperties
|
||||
) {
|
||||
parent::__construct($originalClass, '__get', array(new ParameterGenerator('name')));
|
||||
parent::__construct($originalClass, '__get', [new ParameterGenerator('name')]);
|
||||
|
||||
$this->setDocblock(($originalClass->hasMethod('__get') ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
$hasParent = $originalClass->hasMethod('__get');
|
||||
|
||||
$this->setDocBlock(($hasParent ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
|
||||
$initializer = $initializerProperty->getName();
|
||||
$valueHolder = $valueHolderProperty->getName();
|
||||
@@ -52,16 +64,33 @@ class MagicGet extends MagicMethodGenerator
|
||||
. ' return $this->' . $valueHolder . '->$name;'
|
||||
. "\n}\n\n";
|
||||
|
||||
$callParent .= PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
PublicScopeSimulator::OPERATION_GET,
|
||||
'name',
|
||||
null,
|
||||
$valueHolderProperty
|
||||
);
|
||||
if ($hasParent) {
|
||||
$this->setInitializerBody(
|
||||
$initializer,
|
||||
$valueHolder,
|
||||
$callParent . 'return $this->' . $valueHolder . '->__get($name);'
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->setInitializerBody(
|
||||
$initializer,
|
||||
$valueHolder,
|
||||
$callParent . PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
PublicScopeSimulator::OPERATION_GET,
|
||||
'name',
|
||||
null,
|
||||
$valueHolderProperty
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private function setInitializerBody(string $initializer, string $valueHolder, string $callParent) : void
|
||||
{
|
||||
$this->setBody(
|
||||
'$this->' . $initializer . ' && $this->' . $initializer
|
||||
. '->__invoke($this->' . $valueHolder . ', $this, \'__get\', array(\'name\' => $name), $this->'
|
||||
. '->__invoke($this->' . $valueHolder . ', $this, \'__get\', [\'name\' => $name], $this->'
|
||||
. $initializer . ');'
|
||||
. "\n\n" . $callParent
|
||||
);
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
|
||||
use ReflectionClass;
|
||||
@@ -35,6 +37,14 @@ class MagicIsset extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $initializerProperty
|
||||
* @param PropertyGenerator $valueHolderProperty
|
||||
* @param PublicPropertiesMap $publicProperties
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
@@ -42,13 +52,13 @@ class MagicIsset extends MagicMethodGenerator
|
||||
PropertyGenerator $valueHolderProperty,
|
||||
PublicPropertiesMap $publicProperties
|
||||
) {
|
||||
parent::__construct($originalClass, '__isset', array(new ParameterGenerator('name')));
|
||||
parent::__construct($originalClass, '__isset', [new ParameterGenerator('name')]);
|
||||
|
||||
$initializer = $initializerProperty->getName();
|
||||
$valueHolder = $valueHolderProperty->getName();
|
||||
$callParent = '';
|
||||
|
||||
$this->setDocblock(($originalClass->hasMethod('__isset') ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
$this->setDocBlock(($originalClass->hasMethod('__isset') ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
|
||||
if (! $publicProperties->isEmpty()) {
|
||||
$callParent = 'if (isset(self::$' . $publicProperties->getName() . "[\$name])) {\n"
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
|
||||
use ReflectionClass;
|
||||
@@ -35,6 +37,14 @@ class MagicSet extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $initializerProperty
|
||||
* @param PropertyGenerator $valueHolderProperty
|
||||
* @param PublicPropertiesMap $publicProperties
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
@@ -45,16 +55,15 @@ class MagicSet extends MagicMethodGenerator
|
||||
parent::__construct(
|
||||
$originalClass,
|
||||
'__set',
|
||||
array(new ParameterGenerator('name'), new ParameterGenerator('value'))
|
||||
[new ParameterGenerator('name'), new ParameterGenerator('value')]
|
||||
);
|
||||
|
||||
$hasParent = $originalClass->hasMethod('__set');
|
||||
$initializer = $initializerProperty->getName();
|
||||
$valueHolder = $valueHolderProperty->getName();
|
||||
$callParent = '';
|
||||
|
||||
$this->setDocblock(
|
||||
($originalClass->hasMethod('__set') ? "{@inheritDoc}\n" : '') . "@param string \$name\n@param mixed \$value"
|
||||
);
|
||||
$this->setDocBlock(($hasParent ? "{@inheritDoc}\n" : '') . "@param string \$name\n@param mixed \$value");
|
||||
|
||||
if (! $publicProperties->isEmpty()) {
|
||||
$callParent = 'if (isset(self::$' . $publicProperties->getName() . "[\$name])) {\n"
|
||||
@@ -62,12 +71,14 @@ class MagicSet extends MagicMethodGenerator
|
||||
. "\n}\n\n";
|
||||
}
|
||||
|
||||
$callParent .= PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
PublicScopeSimulator::OPERATION_SET,
|
||||
'name',
|
||||
'value',
|
||||
$valueHolderProperty
|
||||
);
|
||||
$callParent .= $hasParent
|
||||
? 'return $this->' . $valueHolder . '->__set($name, $value);'
|
||||
: PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
PublicScopeSimulator::OPERATION_SET,
|
||||
'name',
|
||||
'value',
|
||||
$valueHolderProperty
|
||||
);
|
||||
|
||||
$this->setBody(
|
||||
'$this->' . $initializer . ' && $this->' . $initializer
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
@@ -32,6 +34,10 @@ class MagicSleep extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $initializerProperty
|
||||
* @param PropertyGenerator $valueHolderProperty
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
|
||||
use ReflectionClass;
|
||||
@@ -35,6 +37,14 @@ class MagicUnset extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $initializerProperty
|
||||
* @param PropertyGenerator $valueHolderProperty
|
||||
* @param PublicPropertiesMap $publicProperties
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
@@ -42,13 +52,14 @@ class MagicUnset extends MagicMethodGenerator
|
||||
PropertyGenerator $valueHolderProperty,
|
||||
PublicPropertiesMap $publicProperties
|
||||
) {
|
||||
parent::__construct($originalClass, '__unset', array(new ParameterGenerator('name')));
|
||||
parent::__construct($originalClass, '__unset', [new ParameterGenerator('name')]);
|
||||
|
||||
$hasParent = $originalClass->hasMethod('__unset');
|
||||
$initializer = $initializerProperty->getName();
|
||||
$valueHolder = $valueHolderProperty->getName();
|
||||
$callParent = '';
|
||||
|
||||
$this->setDocblock(($originalClass->hasMethod('__isset') ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
$this->setDocBlock(($hasParent ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
|
||||
if (! $publicProperties->isEmpty()) {
|
||||
$callParent = 'if (isset(self::$' . $publicProperties->getName() . "[\$name])) {\n"
|
||||
@@ -56,12 +67,14 @@ class MagicUnset extends MagicMethodGenerator
|
||||
. "\n}\n\n";
|
||||
}
|
||||
|
||||
$callParent .= PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
PublicScopeSimulator::OPERATION_UNSET,
|
||||
'name',
|
||||
null,
|
||||
$valueHolderProperty
|
||||
);
|
||||
$callParent .= $hasParent
|
||||
? 'return $this->' . $valueHolder . '->__unset($name);'
|
||||
: PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
PublicScopeSimulator::OPERATION_UNSET,
|
||||
'name',
|
||||
null,
|
||||
$valueHolderProperty
|
||||
);
|
||||
|
||||
$this->setBody(
|
||||
'$this->' . $initializer . ' && $this->' . $initializer
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingValueHolder\MethodGenerator;
|
||||
|
||||
use Closure;
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
/**
|
||||
@@ -33,6 +36,10 @@ class SetProxyInitializer extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param PropertyGenerator $initializerProperty
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(PropertyGenerator $initializerProperty)
|
||||
{
|
||||
@@ -40,10 +47,10 @@ class SetProxyInitializer extends MethodGenerator
|
||||
|
||||
$initializerParameter = new ParameterGenerator('initializer');
|
||||
|
||||
$initializerParameter->setType('Closure');
|
||||
$initializerParameter->setType(Closure::class);
|
||||
$initializerParameter->setDefaultValue(null);
|
||||
$this->setParameter($initializerParameter);
|
||||
$this->setDocblock('{@inheritDoc}');
|
||||
$this->setDocBlock('{@inheritDoc}');
|
||||
$this->setBody('$this->' . $initializerProperty->getName() . ' = $initializer;');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingValueHolder\PropertyGenerator;
|
||||
|
||||
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
|
||||
@@ -31,12 +33,14 @@ class InitializerProperty extends PropertyGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(UniqueIdentifierGenerator::getIdentifier('initializer'));
|
||||
|
||||
$this->setVisibility(self::VISIBILITY_PRIVATE);
|
||||
$this->setDocblock('@var \\Closure|null initializer responsible for generating the wrapped object');
|
||||
$this->setDocBlock('@var \\Closure|null initializer responsible for generating the wrapped object');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingValueHolder\PropertyGenerator;
|
||||
|
||||
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
|
||||
@@ -31,12 +33,14 @@ class ValueHolderProperty extends PropertyGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(UniqueIdentifierGenerator::getIdentifier('valueHolder'));
|
||||
|
||||
$this->setVisibility(self::VISIBILITY_PRIVATE);
|
||||
$this->setDocblock('@var \\Closure|null initializer responsible for generating the wrapped object');
|
||||
$this->setDocBlock('@var \\Closure|null initializer responsible for generating the wrapped object');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,12 +16,16 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator;
|
||||
|
||||
use ProxyManager\Exception\InvalidProxiedClassException;
|
||||
use ProxyManager\Generator\Util\ClassGeneratorUtils;
|
||||
use ProxyManager\Proxy\VirtualProxyInterface;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptor\MethodGenerator\MagicWakeup;
|
||||
use ProxyManager\ProxyGenerator\Assertion\CanProxyAssertion;
|
||||
use ProxyManager\ProxyGenerator\LazyLoading\MethodGenerator\Constructor;
|
||||
use ProxyManager\ProxyGenerator\LazyLoading\MethodGenerator\StaticProxyConstructor;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingValueHolder\MethodGenerator\GetProxyInitializer;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingValueHolder\MethodGenerator\InitializeProxy;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingValueHolder\MethodGenerator\IsProxyInitialized;
|
||||
@@ -36,7 +40,9 @@ use ProxyManager\ProxyGenerator\LazyLoadingValueHolder\MethodGenerator\SetProxyI
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingValueHolder\PropertyGenerator\InitializerProperty;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingValueHolder\PropertyGenerator\ValueHolderProperty;
|
||||
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\Util\Properties;
|
||||
use ProxyManager\ProxyGenerator\Util\ProxiedMethodsFilter;
|
||||
use ProxyManager\ProxyGenerator\ValueHolder\MethodGenerator\Constructor;
|
||||
use ProxyManager\ProxyGenerator\ValueHolder\MethodGenerator\GetWrappedValueHolderValue;
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
@@ -56,13 +62,17 @@ class LazyLoadingValueHolderGenerator implements ProxyGeneratorInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @throws InvalidProxiedClassException
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function generate(ReflectionClass $originalClass, ClassGenerator $classGenerator)
|
||||
{
|
||||
CanProxyAssertion::assertClassCanBeProxied($originalClass);
|
||||
|
||||
$interfaces = array('ProxyManager\\Proxy\\VirtualProxyInterface');
|
||||
$publicProperties = new PublicPropertiesMap($originalClass);
|
||||
$interfaces = [VirtualProxyInterface::class];
|
||||
$publicProperties = new PublicPropertiesMap(Properties::fromReflectionClass($originalClass));
|
||||
|
||||
if ($originalClass->isInterface()) {
|
||||
$interfaces[] = $originalClass->getName();
|
||||
@@ -81,17 +91,12 @@ class LazyLoadingValueHolderGenerator implements ProxyGeneratorInterface
|
||||
},
|
||||
array_merge(
|
||||
array_map(
|
||||
function (ReflectionMethod $method) use ($initializer, $valueHolder) {
|
||||
return LazyLoadingMethodInterceptor::generateMethod(
|
||||
new MethodReflection($method->getDeclaringClass()->getName(), $method->getName()),
|
||||
$initializer,
|
||||
$valueHolder
|
||||
);
|
||||
},
|
||||
$this->buildLazyLoadingMethodInterceptor($initializer, $valueHolder),
|
||||
ProxiedMethodsFilter::getProxiedMethods($originalClass)
|
||||
),
|
||||
array(
|
||||
new Constructor($originalClass, $initializer),
|
||||
[
|
||||
new StaticProxyConstructor($initializer, Properties::fromReflectionClass($originalClass)),
|
||||
Constructor::generateMethod($originalClass, $valueHolder),
|
||||
new MagicGet($originalClass, $initializer, $valueHolder, $publicProperties),
|
||||
new MagicSet($originalClass, $initializer, $valueHolder, $publicProperties),
|
||||
new MagicIsset($originalClass, $initializer, $valueHolder, $publicProperties),
|
||||
@@ -104,8 +109,21 @@ class LazyLoadingValueHolderGenerator implements ProxyGeneratorInterface
|
||||
new InitializeProxy($initializer, $valueHolder),
|
||||
new IsProxyInitialized($valueHolder),
|
||||
new GetWrappedValueHolderValue($valueHolder),
|
||||
)
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private function buildLazyLoadingMethodInterceptor(
|
||||
InitializerProperty $initializer,
|
||||
ValueHolderProperty $valueHolder
|
||||
) : callable {
|
||||
return function (ReflectionMethod $method) use ($initializer, $valueHolder) : LazyLoadingMethodInterceptor {
|
||||
return LazyLoadingMethodInterceptor::generateMethod(
|
||||
new MethodReflection($method->getDeclaringClass()->getName(), $method->getName()),
|
||||
$initializer,
|
||||
$valueHolder
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\NullObject\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
@@ -33,21 +35,29 @@ class NullObjectMethodInterceptor extends MethodGenerator
|
||||
/**
|
||||
* @param \Zend\Code\Reflection\MethodReflection $originalMethod
|
||||
*
|
||||
* @return NullObjectMethodInterceptor|static
|
||||
* @return self|static
|
||||
*/
|
||||
public static function generateMethod(MethodReflection $originalMethod)
|
||||
public static function generateMethod(MethodReflection $originalMethod) : self
|
||||
{
|
||||
/* @var $method self */
|
||||
$method = static::fromReflection($originalMethod);
|
||||
|
||||
if ('void' === (string) $originalMethod->getReturnType()) {
|
||||
$method->setBody('');
|
||||
|
||||
return $method;
|
||||
}
|
||||
|
||||
if ($originalMethod->returnsReference()) {
|
||||
$reference = UniqueIdentifierGenerator::getIdentifier('ref');
|
||||
|
||||
$method->setBody("\$$reference = null;\nreturn \$$reference;");
|
||||
} else {
|
||||
$method->setBody('');
|
||||
|
||||
return $method;
|
||||
}
|
||||
|
||||
$method->setBody('');
|
||||
|
||||
return $method;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\NullObject\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\Properties;
|
||||
use ReflectionClass;
|
||||
use ReflectionProperty;
|
||||
|
||||
/**
|
||||
* The `staticProxyConstructor` implementation for null object proxies
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*/
|
||||
class StaticProxyConstructor extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass Reflection of the class to proxy
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(ReflectionClass $originalClass)
|
||||
{
|
||||
parent::__construct('staticProxyConstructor', [], static::FLAG_PUBLIC | static::FLAG_STATIC);
|
||||
|
||||
$nullableProperties = array_map(
|
||||
function (ReflectionProperty $publicProperty) : string {
|
||||
return '$instance->' . $publicProperty->getName() . ' = null;';
|
||||
},
|
||||
Properties::fromReflectionClass($originalClass)->getPublicProperties()
|
||||
);
|
||||
|
||||
$this->setDocBlock('Constructor for null object initialization');
|
||||
$this->setBody(
|
||||
'static $reflection;' . "\n\n"
|
||||
. '$reflection = $reflection ?: $reflection = new \ReflectionClass(__CLASS__);' . "\n"
|
||||
. '$instance = (new \ReflectionClass(get_class()))->newInstanceWithoutConstructor();' . "\n\n"
|
||||
. ($nullableProperties ? implode("\n", $nullableProperties) . "\n\n" : '')
|
||||
. 'return $instance;'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -16,12 +16,16 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator;
|
||||
|
||||
use ProxyManager\Exception\InvalidProxiedClassException;
|
||||
use ProxyManager\Generator\Util\ClassGeneratorUtils;
|
||||
use ProxyManager\Proxy\NullObjectInterface;
|
||||
use ProxyManager\ProxyGenerator\Assertion\CanProxyAssertion;
|
||||
use ProxyManager\ProxyGenerator\NullObject\MethodGenerator\Constructor;
|
||||
use ProxyManager\ProxyGenerator\NullObject\MethodGenerator\NullObjectMethodInterceptor;
|
||||
use ProxyManager\ProxyGenerator\NullObject\MethodGenerator\StaticProxyConstructor;
|
||||
use ProxyManager\ProxyGenerator\Util\ProxiedMethodsFilter;
|
||||
use ReflectionClass;
|
||||
use Zend\Code\Generator\ClassGenerator;
|
||||
@@ -39,20 +43,25 @@ class NullObjectGenerator implements ProxyGeneratorInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @throws InvalidProxiedClassException
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function generate(ReflectionClass $originalClass, ClassGenerator $classGenerator)
|
||||
{
|
||||
CanProxyAssertion::assertClassCanBeProxied($originalClass);
|
||||
|
||||
$interfaces = array('ProxyManager\\Proxy\\NullObjectInterface');
|
||||
$interfaces = [NullObjectInterface::class];
|
||||
|
||||
if ($originalClass->isInterface()) {
|
||||
$interfaces[] = $originalClass->getName();
|
||||
} else {
|
||||
$classGenerator->setExtendedClass($originalClass->getName());
|
||||
}
|
||||
|
||||
$classGenerator->setImplementedInterfaces($interfaces);
|
||||
|
||||
foreach (ProxiedMethodsFilter::getProxiedMethods($originalClass) as $method) {
|
||||
foreach (ProxiedMethodsFilter::getProxiedMethods($originalClass, []) as $method) {
|
||||
$classGenerator->addMethodFromGenerator(
|
||||
NullObjectMethodInterceptor::generateMethod(
|
||||
new MethodReflection($method->getDeclaringClass()->getName(), $method->getName())
|
||||
@@ -60,6 +69,10 @@ class NullObjectGenerator implements ProxyGeneratorInterface
|
||||
);
|
||||
}
|
||||
|
||||
ClassGeneratorUtils::addMethodIfNotFinal($originalClass, $classGenerator, new Constructor($originalClass));
|
||||
ClassGeneratorUtils::addMethodIfNotFinal(
|
||||
$originalClass,
|
||||
$classGenerator,
|
||||
new StaticProxyConstructor($originalClass)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,11 +16,12 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\PropertyGenerator;
|
||||
|
||||
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
|
||||
use ReflectionClass;
|
||||
use ReflectionProperty;
|
||||
use ProxyManager\ProxyGenerator\Util\Properties;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
/**
|
||||
@@ -34,30 +35,32 @@ class PublicPropertiesMap extends PropertyGenerator
|
||||
/**
|
||||
* @var bool[]
|
||||
*/
|
||||
private $publicProperties = array();
|
||||
private $publicProperties = [];
|
||||
|
||||
/**
|
||||
* @param \ReflectionClass $originalClass
|
||||
* @param Properties $properties
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(ReflectionClass $originalClass)
|
||||
public function __construct(Properties $properties)
|
||||
{
|
||||
parent::__construct(UniqueIdentifierGenerator::getIdentifier('publicProperties'));
|
||||
|
||||
foreach ($originalClass->getProperties(ReflectionProperty::IS_PUBLIC) as $publicProperty) {
|
||||
foreach ($properties->getPublicProperties() as $publicProperty) {
|
||||
$this->publicProperties[$publicProperty->getName()] = true;
|
||||
}
|
||||
|
||||
$this->setDefaultValue($this->publicProperties);
|
||||
$this->setVisibility(self::VISIBILITY_PRIVATE);
|
||||
$this->setStatic(true);
|
||||
$this->setDocblock('@var bool[] map of public properties of the parent class');
|
||||
$this->setDocBlock('@var bool[] map of public properties of the parent class');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool whether there are no public properties
|
||||
*/
|
||||
public function isEmpty()
|
||||
public function isEmpty() : bool
|
||||
{
|
||||
return empty($this->publicProperties);
|
||||
return ! $this->publicProperties;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator;
|
||||
|
||||
use ReflectionClass;
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\RemoteObject\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ReflectionClass;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
@@ -35,12 +37,14 @@ class MagicGet extends MagicMethodGenerator
|
||||
* Constructor
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $adapterProperty
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(ReflectionClass $originalClass, PropertyGenerator $adapterProperty)
|
||||
{
|
||||
parent::__construct($originalClass, '__get', array(new ParameterGenerator('name')));
|
||||
parent::__construct($originalClass, '__get', [new ParameterGenerator('name')]);
|
||||
|
||||
$this->setDocblock('@param string $name');
|
||||
$this->setDocBlock('@param string $name');
|
||||
$this->setBody(
|
||||
'$return = $this->' . $adapterProperty->getName() . '->call(' . var_export($originalClass->getName(), true)
|
||||
. ', \'__get\', array($name));' . "\n\n" . 'return $return;'
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\RemoteObject\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ReflectionClass;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
@@ -35,12 +37,14 @@ class MagicIsset extends MagicMethodGenerator
|
||||
* Constructor
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $adapterProperty
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(ReflectionClass $originalClass, PropertyGenerator $adapterProperty)
|
||||
{
|
||||
parent::__construct($originalClass, '__isset', array(new ParameterGenerator('name')));
|
||||
parent::__construct($originalClass, '__isset', [new ParameterGenerator('name')]);
|
||||
|
||||
$this->setDocblock('@param string $name');
|
||||
$this->setDocBlock('@param string $name');
|
||||
$this->setBody(
|
||||
'$return = $this->' . $adapterProperty->getName() . '->call(' . var_export($originalClass->getName(), true)
|
||||
. ', \'__isset\', array($name));' . "\n\n"
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\RemoteObject\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ReflectionClass;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
@@ -35,16 +37,18 @@ class MagicSet extends MagicMethodGenerator
|
||||
* Constructor
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $adapterProperty
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(ReflectionClass $originalClass, PropertyGenerator $adapterProperty)
|
||||
{
|
||||
parent::__construct(
|
||||
$originalClass,
|
||||
'__set',
|
||||
array(new ParameterGenerator('name'), new ParameterGenerator('value'))
|
||||
[new ParameterGenerator('name'), new ParameterGenerator('value')]
|
||||
);
|
||||
|
||||
$this->setDocblock('@param string \$name\n@param mixed \$value');
|
||||
$this->setDocBlock('@param string \$name\n@param mixed \$value');
|
||||
$this->setBody(
|
||||
'$return = $this->' . $adapterProperty->getName() . '->call(' . var_export($originalClass->getName(), true)
|
||||
. ', \'__set\', array($name, $value));' . "\n\n"
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\RemoteObject\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ReflectionClass;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
@@ -36,12 +38,14 @@ class MagicUnset extends MagicMethodGenerator
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $adapterProperty
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(ReflectionClass $originalClass, PropertyGenerator $adapterProperty)
|
||||
{
|
||||
parent::__construct($originalClass, '__unset', array(new ParameterGenerator('name')));
|
||||
parent::__construct($originalClass, '__unset', [new ParameterGenerator('name')]);
|
||||
|
||||
$this->setDocblock('@param string $name');
|
||||
$this->setDocBlock('@param string $name');
|
||||
$this->setBody(
|
||||
'$return = $this->' . $adapterProperty->getName() . '->call(' . var_export($originalClass->getName(), true)
|
||||
. ', \'__unset\', array($name));' . "\n\n"
|
||||
|
||||
@@ -16,10 +16,14 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\RemoteObject\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
use ProxyManager\Generator\Util\ProxiedMethodReturnExpression;
|
||||
use ReflectionClass;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
use Zend\Code\Reflection\MethodReflection;
|
||||
|
||||
@@ -36,26 +40,27 @@ class RemoteObjectMethod extends MethodGenerator
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $adapterProperty
|
||||
* @param \ReflectionClass $originalClass
|
||||
*
|
||||
* @return RemoteObjectMethod|static
|
||||
* @return self|static
|
||||
*/
|
||||
public static function generateMethod(
|
||||
MethodReflection $originalMethod,
|
||||
PropertyGenerator $adapterProperty,
|
||||
ReflectionClass $originalClass
|
||||
) {
|
||||
) : self {
|
||||
/* @var $method self */
|
||||
$method = static::fromReflection($originalMethod);
|
||||
$parameters = $originalMethod->getParameters();
|
||||
$list = array();
|
||||
|
||||
foreach ($parameters as $parameter) {
|
||||
$list[] = '$' . $parameter->getName();
|
||||
}
|
||||
$list = array_values(array_map(
|
||||
function (ParameterGenerator $parameter) : string {
|
||||
return '$' . $parameter->getName();
|
||||
},
|
||||
$method->getParameters()
|
||||
));
|
||||
|
||||
$method->setBody(
|
||||
'$return = $this->' . $adapterProperty->getName() . '->call(' . var_export($originalClass->getName(), true)
|
||||
'$return = $this->' . $adapterProperty->getName()
|
||||
. '->call(' . var_export($originalClass->getName(), true)
|
||||
. ', ' . var_export($originalMethod->getName(), true) . ', array('. implode(', ', $list) .'));' . "\n\n"
|
||||
. 'return $return;'
|
||||
. ProxiedMethodReturnExpression::generate('$return', $originalMethod)
|
||||
);
|
||||
|
||||
return $method;
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\RemoteObject\MethodGenerator;
|
||||
|
||||
use ProxyManager\Factory\RemoteObject\AdapterInterface;
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\Properties;
|
||||
use ProxyManager\ProxyGenerator\Util\UnsetPropertiesGenerator;
|
||||
use ReflectionClass;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
/**
|
||||
* The `staticProxyConstructor` implementation for remote object proxies
|
||||
*
|
||||
* @author Vincent Blanchon <blanchon.vincent@gmail.com>
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*/
|
||||
class StaticProxyConstructor extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass Reflection of the class to proxy
|
||||
* @param PropertyGenerator $adapter Adapter property
|
||||
*/
|
||||
public function __construct(ReflectionClass $originalClass, PropertyGenerator $adapter)
|
||||
{
|
||||
$adapterName = $adapter->getName();
|
||||
|
||||
parent::__construct(
|
||||
'staticProxyConstructor',
|
||||
[new ParameterGenerator($adapterName, AdapterInterface::class)],
|
||||
MethodGenerator::FLAG_PUBLIC | MethodGenerator::FLAG_STATIC,
|
||||
null,
|
||||
'Constructor for remote object control\n\n'
|
||||
. '@param \\ProxyManager\\Factory\\RemoteObject\\AdapterInterface \$adapter'
|
||||
);
|
||||
|
||||
$body = 'static $reflection;' . "\n\n"
|
||||
. '$reflection = $reflection ?: $reflection = new \ReflectionClass(__CLASS__);' . "\n"
|
||||
. '$instance = (new \ReflectionClass(get_class()))->newInstanceWithoutConstructor();' . "\n\n"
|
||||
. '$instance->' . $adapterName . ' = $' . $adapterName . ";\n\n"
|
||||
. UnsetPropertiesGenerator::generateSnippet(Properties::fromReflectionClass($originalClass), 'instance');
|
||||
|
||||
$this->setBody($body . "\n\nreturn \$instance;");
|
||||
}
|
||||
}
|
||||
@@ -16,8 +16,11 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\RemoteObject\PropertyGenerator;
|
||||
|
||||
use ProxyManager\Factory\RemoteObject\AdapterInterface;
|
||||
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
@@ -31,12 +34,14 @@ class AdapterProperty extends PropertyGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(UniqueIdentifierGenerator::getIdentifier('adapter'));
|
||||
|
||||
$this->setVisibility(self::VISIBILITY_PRIVATE);
|
||||
$this->setDocblock('@var \\ProxyManager\\Factory\\RemoteObject\\AdapterInterface Remote web service adapter');
|
||||
$this->setDocBlock('@var \\' . AdapterInterface::class . ' Remote web service adapter');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,16 +16,20 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator;
|
||||
|
||||
use ProxyManager\Exception\InvalidProxiedClassException;
|
||||
use ProxyManager\Generator\Util\ClassGeneratorUtils;
|
||||
use ProxyManager\Proxy\RemoteObjectInterface;
|
||||
use ProxyManager\ProxyGenerator\Assertion\CanProxyAssertion;
|
||||
use ProxyManager\ProxyGenerator\RemoteObject\MethodGenerator\Constructor;
|
||||
use ProxyManager\ProxyGenerator\RemoteObject\MethodGenerator\MagicGet;
|
||||
use ProxyManager\ProxyGenerator\RemoteObject\MethodGenerator\MagicIsset;
|
||||
use ProxyManager\ProxyGenerator\RemoteObject\MethodGenerator\MagicSet;
|
||||
use ProxyManager\ProxyGenerator\RemoteObject\MethodGenerator\MagicUnset;
|
||||
use ProxyManager\ProxyGenerator\RemoteObject\MethodGenerator\RemoteObjectMethod;
|
||||
use ProxyManager\ProxyGenerator\RemoteObject\MethodGenerator\StaticProxyConstructor;
|
||||
use ProxyManager\ProxyGenerator\RemoteObject\PropertyGenerator\AdapterProperty;
|
||||
use ProxyManager\ProxyGenerator\Util\ProxiedMethodsFilter;
|
||||
use ReflectionClass;
|
||||
@@ -46,12 +50,15 @@ class RemoteObjectGenerator implements ProxyGeneratorInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @throws InvalidProxiedClassException
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function generate(ReflectionClass $originalClass, ClassGenerator $classGenerator)
|
||||
{
|
||||
CanProxyAssertion::assertClassCanBeProxied($originalClass);
|
||||
|
||||
$interfaces = array('ProxyManager\\Proxy\\RemoteObjectInterface');
|
||||
$interfaces = [RemoteObjectInterface::class];
|
||||
|
||||
if ($originalClass->isInterface()) {
|
||||
$interfaces[] = $originalClass->getName();
|
||||
@@ -68,7 +75,7 @@ class RemoteObjectGenerator implements ProxyGeneratorInterface
|
||||
},
|
||||
array_merge(
|
||||
array_map(
|
||||
function (ReflectionMethod $method) use ($adapter, $originalClass) {
|
||||
function (ReflectionMethod $method) use ($adapter, $originalClass) : RemoteObjectMethod {
|
||||
return RemoteObjectMethod::generateMethod(
|
||||
new MethodReflection($method->getDeclaringClass()->getName(), $method->getName()),
|
||||
$adapter,
|
||||
@@ -77,16 +84,16 @@ class RemoteObjectGenerator implements ProxyGeneratorInterface
|
||||
},
|
||||
ProxiedMethodsFilter::getProxiedMethods(
|
||||
$originalClass,
|
||||
array('__get', '__set', '__isset', '__unset')
|
||||
['__get', '__set', '__isset', '__unset']
|
||||
)
|
||||
),
|
||||
array(
|
||||
new Constructor($originalClass, $adapter),
|
||||
[
|
||||
new StaticProxyConstructor($originalClass, $adapter),
|
||||
new MagicGet($originalClass, $adapter),
|
||||
new MagicSet($originalClass, $adapter),
|
||||
new MagicIsset($originalClass, $adapter),
|
||||
new MagicUnset($originalClass, $adapter),
|
||||
)
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
42
vendor/ocramius/proxy-manager/src/ProxyManager/ProxyGenerator/Util/GetMethodIfExists.php
vendored
Normal file
42
vendor/ocramius/proxy-manager/src/ProxyManager/ProxyGenerator/Util/GetMethodIfExists.php
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\Util;
|
||||
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
|
||||
/**
|
||||
* Internal utility class - allows fetching a method from a given class, if it exists
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*/
|
||||
final class GetMethodIfExists
|
||||
{
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public static function get(ReflectionClass $class, string $method) : ?ReflectionMethod
|
||||
{
|
||||
return $class->hasMethod($method) ? $class->getMethod($method) : null;
|
||||
}
|
||||
}
|
||||
166
vendor/ocramius/proxy-manager/src/ProxyManager/ProxyGenerator/Util/Properties.php
vendored
Normal file
166
vendor/ocramius/proxy-manager/src/ProxyManager/ProxyGenerator/Util/Properties.php
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\Util;
|
||||
|
||||
use ReflectionClass;
|
||||
use ReflectionProperty;
|
||||
|
||||
/**
|
||||
* DTO containing the list of all non-static proxy properties and utility methods to access them
|
||||
* in various formats/collections
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*/
|
||||
final class Properties
|
||||
{
|
||||
/**
|
||||
* @var array|\ReflectionProperty[]
|
||||
*/
|
||||
private $properties;
|
||||
|
||||
/**
|
||||
* @param ReflectionProperty[] $properties
|
||||
*/
|
||||
private function __construct(array $properties)
|
||||
{
|
||||
$this->properties = $properties;
|
||||
}
|
||||
|
||||
public static function fromReflectionClass(ReflectionClass $reflection) : self
|
||||
{
|
||||
$class = $reflection;
|
||||
$properties = [];
|
||||
|
||||
do {
|
||||
$properties = array_merge(
|
||||
$properties,
|
||||
array_values(array_filter(
|
||||
$class->getProperties(),
|
||||
function (ReflectionProperty $property) use ($class) : bool {
|
||||
return $class->getName() === $property->getDeclaringClass()->getName()
|
||||
&& ! $property->isStatic();
|
||||
}
|
||||
))
|
||||
);
|
||||
} while ($class = $class->getParentClass());
|
||||
|
||||
return new self($properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $excludedProperties
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function filter(array $excludedProperties) : self
|
||||
{
|
||||
$properties = $this->getInstanceProperties();
|
||||
|
||||
foreach ($excludedProperties as $propertyName) {
|
||||
unset($properties[$propertyName]);
|
||||
}
|
||||
|
||||
return new self($properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ReflectionProperty[] indexed by the property internal visibility-aware name
|
||||
*/
|
||||
public function getPublicProperties() : array
|
||||
{
|
||||
$publicProperties = [];
|
||||
|
||||
foreach ($this->properties as $property) {
|
||||
if ($property->isPublic()) {
|
||||
$publicProperties[$property->getName()] = $property;
|
||||
}
|
||||
}
|
||||
|
||||
return $publicProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ReflectionProperty[] indexed by the property internal visibility-aware name (\0*\0propertyName)
|
||||
*/
|
||||
public function getProtectedProperties() : array
|
||||
{
|
||||
$protectedProperties = [];
|
||||
|
||||
foreach ($this->properties as $property) {
|
||||
if ($property->isProtected()) {
|
||||
$protectedProperties["\0*\0" . $property->getName()] = $property;
|
||||
}
|
||||
}
|
||||
|
||||
return $protectedProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ReflectionProperty[] indexed by the property internal visibility-aware name (\0ClassName\0propertyName)
|
||||
*/
|
||||
public function getPrivateProperties() : array
|
||||
{
|
||||
$privateProperties = [];
|
||||
|
||||
foreach ($this->properties as $property) {
|
||||
if ($property->isPrivate()) {
|
||||
$declaringClass = $property->getDeclaringClass()->getName();
|
||||
|
||||
$privateProperties["\0" . $declaringClass . "\0" . $property->getName()] = $property;
|
||||
}
|
||||
}
|
||||
|
||||
return $privateProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ReflectionProperty[] indexed by the property internal visibility-aware name (\0*\0propertyName)
|
||||
*/
|
||||
public function getAccessibleProperties() : array
|
||||
{
|
||||
return array_merge($this->getPublicProperties(), $this->getProtectedProperties());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ReflectionProperty[][] indexed by class name and property name
|
||||
*/
|
||||
public function getGroupedPrivateProperties() : array
|
||||
{
|
||||
$propertiesMap = [];
|
||||
|
||||
foreach ($this->getPrivateProperties() as $property) {
|
||||
$class = & $propertiesMap[$property->getDeclaringClass()->getName()];
|
||||
|
||||
$class[$property->getName()] = $property;
|
||||
}
|
||||
|
||||
return $propertiesMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ReflectionProperty[] indexed by the property internal visibility-aware name (\0*\0propertyName)
|
||||
*/
|
||||
public function getInstanceProperties() : array
|
||||
{
|
||||
return array_merge($this->getAccessibleProperties(), $this->getPrivateProperties());
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\Util;
|
||||
|
||||
use ReflectionClass;
|
||||
@@ -27,30 +29,74 @@ use ReflectionMethod;
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*/
|
||||
class ProxiedMethodsFilter
|
||||
final class ProxiedMethodsFilter
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private static $defaultExcluded = [
|
||||
'__get',
|
||||
'__set',
|
||||
'__isset',
|
||||
'__unset',
|
||||
'__clone',
|
||||
'__sleep',
|
||||
'__wakeup',
|
||||
];
|
||||
|
||||
/**
|
||||
* @param ReflectionClass $class reflection class from which methods should be extracted
|
||||
* @param string[] $excluded methods to be ignored
|
||||
*
|
||||
* @return ReflectionMethod[]
|
||||
*/
|
||||
public static function getProxiedMethods(
|
||||
ReflectionClass $class,
|
||||
array $excluded = array('__get', '__set', '__isset', '__unset', '__clone', '__sleep', '__wakeup')
|
||||
) {
|
||||
public static function getProxiedMethods(ReflectionClass $class, array $excluded = null) : array
|
||||
{
|
||||
return self::doFilter($class, (null === $excluded) ? self::$defaultExcluded : $excluded);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ReflectionClass $class reflection class from which methods should be extracted
|
||||
* @param string[] $excluded methods to be ignored
|
||||
*
|
||||
* @return ReflectionMethod[]
|
||||
*/
|
||||
public static function getAbstractProxiedMethods(ReflectionClass $class, array $excluded = null) : array
|
||||
{
|
||||
return self::doFilter($class, (null === $excluded) ? self::$defaultExcluded : $excluded, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ReflectionClass $class
|
||||
* @param string[] $excluded
|
||||
* @param bool $requireAbstract
|
||||
*
|
||||
* @return ReflectionMethod[]
|
||||
*/
|
||||
private static function doFilter(ReflectionClass $class, array $excluded, bool $requireAbstract = false) : array
|
||||
{
|
||||
$ignored = array_flip(array_map('strtolower', $excluded));
|
||||
|
||||
return array_filter(
|
||||
$class->getMethods(ReflectionMethod::IS_PUBLIC),
|
||||
function (ReflectionMethod $method) use ($ignored) {
|
||||
return ! (
|
||||
$method->isConstructor()
|
||||
|| isset($ignored[strtolower($method->getName())])
|
||||
|| $method->isFinal()
|
||||
|| $method->isStatic()
|
||||
function (ReflectionMethod $method) use ($ignored, $requireAbstract) : bool {
|
||||
return (! $requireAbstract || $method->isAbstract()) && ! (
|
||||
\array_key_exists(strtolower($method->getName()), $ignored)
|
||||
|| self::methodCannotBeProxied($method)
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the method cannot be proxied
|
||||
*
|
||||
* @param ReflectionMethod $method
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function methodCannotBeProxied(ReflectionMethod $method) : bool
|
||||
{
|
||||
return $method->isConstructor() || $method->isFinal() || $method->isStatic();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\Util;
|
||||
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
@@ -53,12 +55,12 @@ class PublicScopeSimulator
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public static function getPublicAccessSimulationCode(
|
||||
$operationType,
|
||||
$nameParameter,
|
||||
string $operationType,
|
||||
string $nameParameter,
|
||||
$valueParameter = null,
|
||||
PropertyGenerator $valueHolder = null,
|
||||
$returnPropertyName = null
|
||||
) {
|
||||
) : string {
|
||||
$byRef = self::getByRefReturnValue($operationType);
|
||||
$value = static::OPERATION_SET === $operationType ? ', $value' : '';
|
||||
$target = '$this';
|
||||
@@ -71,7 +73,7 @@ class PublicScopeSimulator
|
||||
. 'if (! $realInstanceReflection->hasProperty($' . $nameParameter . ')) {' . "\n"
|
||||
. ' $targetObject = ' . $target . ';' . "\n\n"
|
||||
. self::getUndefinedPropertyNotice($operationType, $nameParameter)
|
||||
. ' ' . self::getOperation($operationType, $nameParameter, $valueParameter) . ";\n"
|
||||
. ' ' . self::getOperation($operationType, $nameParameter, $valueParameter) . "\n"
|
||||
. " return;\n"
|
||||
. '}' . "\n\n"
|
||||
. '$targetObject = ' . self::getTargetObject($valueHolder) . ";\n"
|
||||
@@ -94,18 +96,23 @@ class PublicScopeSimulator
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function getUndefinedPropertyNotice($operationType, $nameParameter)
|
||||
private static function getUndefinedPropertyNotice(string $operationType, string $nameParameter) : string
|
||||
{
|
||||
if (static::OPERATION_GET !== $operationType) {
|
||||
return '';
|
||||
}
|
||||
|
||||
//
|
||||
return ' $backtrace = debug_backtrace(false);' . "\n"
|
||||
. ' trigger_error(\'Undefined property: \' . get_parent_class($this) . \'::$\' . $'
|
||||
. $nameParameter
|
||||
. ' . \' in \' . $backtrace[0][\'file\'] . \' on line \' . $backtrace[0][\'line\'], \E_USER_NOTICE);'
|
||||
. "\n";
|
||||
. ' trigger_error(' . "\n"
|
||||
. ' sprintf(' . "\n"
|
||||
. ' \'Undefined property: %s::$%s in %s on line %s\',' . "\n"
|
||||
. ' get_parent_class($this),' . "\n"
|
||||
. ' $' . $nameParameter . ',' . "\n"
|
||||
. ' $backtrace[0][\'file\'],' . "\n"
|
||||
. ' $backtrace[0][\'line\']' . "\n"
|
||||
. ' ),' . "\n"
|
||||
. ' \E_USER_NOTICE' . "\n"
|
||||
. ' );' . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,7 +126,7 @@ class PublicScopeSimulator
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function getByRefReturnValue($operationType)
|
||||
private static function getByRefReturnValue(string $operationType) : string
|
||||
{
|
||||
return (static::OPERATION_GET === $operationType || static::OPERATION_SET === $operationType) ? '& ' : '';
|
||||
}
|
||||
@@ -131,7 +138,7 @@ class PublicScopeSimulator
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function getTargetObject(PropertyGenerator $valueHolder = null)
|
||||
private static function getTargetObject(PropertyGenerator $valueHolder = null) : string
|
||||
{
|
||||
if ($valueHolder) {
|
||||
return '$this->' . $valueHolder->getName();
|
||||
@@ -149,11 +156,11 @@ class PublicScopeSimulator
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
private static function getOperation($operationType, $nameParameter, $valueParameter)
|
||||
private static function getOperation(string $operationType, string $nameParameter, $valueParameter) : string
|
||||
{
|
||||
switch ($operationType) {
|
||||
case static::OPERATION_GET:
|
||||
return 'return $targetObject->$' . $nameParameter . ";";
|
||||
return 'return $targetObject->$' . $nameParameter . ';';
|
||||
case static::OPERATION_SET:
|
||||
if (! $valueParameter) {
|
||||
throw new \InvalidArgumentException('Parameter $valueParameter not provided');
|
||||
@@ -170,21 +177,15 @@ class PublicScopeSimulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates code to bind operations to the parent scope if supported by the current PHP implementation
|
||||
* Generates code to bind operations to the parent scope
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function getScopeReBind()
|
||||
private static function getScopeReBind() : string
|
||||
{
|
||||
if (! method_exists('Closure', 'bind')) {
|
||||
// @codeCoverageIgnoreStart
|
||||
return '';
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
return ' $backtrace = debug_backtrace(true);' . "\n"
|
||||
. ' $scopeObject = isset($backtrace[1][\'object\'])'
|
||||
. ' ? $backtrace[1][\'object\'] : new \stdClass();' . "\n"
|
||||
. ' $accessor = $accessor->bindTo($scopeObject, get_class($scopeObject));' . "\n";
|
||||
return '$backtrace = debug_backtrace(true);' . "\n"
|
||||
. '$scopeObject = isset($backtrace[1][\'object\'])'
|
||||
. ' ? $backtrace[1][\'object\'] : new \ProxyManager\Stub\EmptyClassStub();' . "\n"
|
||||
. '$accessor = $accessor->bindTo($scopeObject, get_class($scopeObject));' . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
110
vendor/ocramius/proxy-manager/src/ProxyManager/ProxyGenerator/Util/UnsetPropertiesGenerator.php
vendored
Normal file
110
vendor/ocramius/proxy-manager/src/ProxyManager/ProxyGenerator/Util/UnsetPropertiesGenerator.php
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\Util;
|
||||
|
||||
/**
|
||||
* Generates code necessary to unset all the given properties from a particular given instance string name
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*/
|
||||
final class UnsetPropertiesGenerator
|
||||
{
|
||||
private static $closureTemplate = <<<'PHP'
|
||||
\Closure::bind(function (\%s $instance) {
|
||||
%s
|
||||
}, $%s, %s)->__invoke($%s);
|
||||
PHP;
|
||||
|
||||
public static function generateSnippet(Properties $properties, string $instanceName) : string
|
||||
{
|
||||
return self::generateUnsetAccessiblePropertiesCode($properties, $instanceName)
|
||||
. self::generateUnsetPrivatePropertiesCode($properties, $instanceName);
|
||||
}
|
||||
|
||||
private static function generateUnsetAccessiblePropertiesCode(Properties $properties, string $instanceName) : string
|
||||
{
|
||||
$accessibleProperties = $properties->getAccessibleProperties();
|
||||
|
||||
if (! $accessibleProperties) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return self::generateUnsetStatement($accessibleProperties, $instanceName) . "\n\n";
|
||||
}
|
||||
|
||||
private static function generateUnsetPrivatePropertiesCode(Properties $properties, string $instanceName) : string
|
||||
{
|
||||
$groups = $properties->getGroupedPrivateProperties();
|
||||
|
||||
if (! $groups) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$unsetClosureCalls = [];
|
||||
|
||||
/* @var $privateProperties \ReflectionProperty[] */
|
||||
foreach ($groups as $privateProperties) {
|
||||
/* @var $firstProperty \ReflectionProperty */
|
||||
$firstProperty = reset($privateProperties);
|
||||
|
||||
$unsetClosureCalls[] = self::generateUnsetClassPrivatePropertiesBlock(
|
||||
$firstProperty->getDeclaringClass(),
|
||||
$privateProperties,
|
||||
$instanceName
|
||||
);
|
||||
}
|
||||
|
||||
return implode("\n\n", $unsetClosureCalls) . "\n\n";
|
||||
}
|
||||
|
||||
private static function generateUnsetClassPrivatePropertiesBlock(
|
||||
\ReflectionClass $declaringClass,
|
||||
array $properties,
|
||||
string $instanceName
|
||||
) : string {
|
||||
$declaringClassName = $declaringClass->getName();
|
||||
|
||||
return sprintf(
|
||||
self::$closureTemplate,
|
||||
$declaringClassName,
|
||||
self::generateUnsetStatement($properties, 'instance'),
|
||||
$instanceName,
|
||||
var_export($declaringClassName, true),
|
||||
$instanceName
|
||||
);
|
||||
}
|
||||
|
||||
private static function generateUnsetStatement(array $properties, string $instanceName) : string
|
||||
{
|
||||
return 'unset('
|
||||
. implode(
|
||||
', ',
|
||||
array_map(
|
||||
function (\ReflectionProperty $property) use ($instanceName) : string {
|
||||
return '$' . $instanceName . '->' . $property->getName();
|
||||
},
|
||||
$properties
|
||||
)
|
||||
)
|
||||
. ');';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\ValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\Properties;
|
||||
use ProxyManager\ProxyGenerator\Util\UnsetPropertiesGenerator;
|
||||
use ReflectionClass;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
use Zend\Code\Reflection\MethodReflection;
|
||||
|
||||
/**
|
||||
* The `__construct` implementation for lazy loading proxies
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*/
|
||||
class Constructor extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $valueHolder
|
||||
*
|
||||
* @return self
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public static function generateMethod(ReflectionClass $originalClass, PropertyGenerator $valueHolder) : self
|
||||
{
|
||||
$originalConstructor = self::getConstructor($originalClass);
|
||||
|
||||
$constructor = $originalConstructor
|
||||
? self::fromReflection($originalConstructor)
|
||||
: new self('__construct');
|
||||
|
||||
$constructor->setDocBlock('{@inheritDoc}');
|
||||
$constructor->setBody(
|
||||
'static $reflection;' . "\n\n"
|
||||
. 'if (! $this->' . $valueHolder->getName() . ') {' . "\n"
|
||||
. ' $reflection = $reflection ?: new \ReflectionClass('
|
||||
. var_export($originalClass->getName(), true)
|
||||
. ");\n"
|
||||
. ' $this->' . $valueHolder->getName() . ' = $reflection->newInstanceWithoutConstructor();' . "\n"
|
||||
. UnsetPropertiesGenerator::generateSnippet(Properties::fromReflectionClass($originalClass), 'this')
|
||||
. '}'
|
||||
. self::generateOriginalConstructorCall($originalClass, $valueHolder)
|
||||
);
|
||||
|
||||
return $constructor;
|
||||
}
|
||||
|
||||
private static function generateOriginalConstructorCall(
|
||||
ReflectionClass $class,
|
||||
PropertyGenerator $valueHolder
|
||||
) : string {
|
||||
$originalConstructor = self::getConstructor($class);
|
||||
|
||||
if (! $originalConstructor) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$constructor = self::fromReflection($originalConstructor);
|
||||
|
||||
return "\n\n"
|
||||
. '$this->' . $valueHolder->getName() . '->' . $constructor->getName() . '('
|
||||
. implode(
|
||||
', ',
|
||||
array_map(
|
||||
function (ParameterGenerator $parameter) : string {
|
||||
return ($parameter->getVariadic() ? '...' : '') . '$' . $parameter->getName();
|
||||
},
|
||||
$constructor->getParameters()
|
||||
)
|
||||
)
|
||||
. ');';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ReflectionClass $class
|
||||
*
|
||||
* @return MethodReflection|null
|
||||
*/
|
||||
private static function getConstructor(ReflectionClass $class)
|
||||
{
|
||||
$constructors = array_map(
|
||||
function (\ReflectionMethod $method) : MethodReflection {
|
||||
return new MethodReflection(
|
||||
$method->getDeclaringClass()->getName(),
|
||||
$method->getName()
|
||||
);
|
||||
},
|
||||
array_filter(
|
||||
$class->getMethods(),
|
||||
function (\ReflectionMethod $method) : bool {
|
||||
return $method->isConstructor();
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
return reset($constructors) ?: null;
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\ValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
@@ -32,11 +34,15 @@ class GetWrappedValueHolderValue extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param PropertyGenerator $valueHolderProperty
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(PropertyGenerator $valueHolderProperty)
|
||||
{
|
||||
parent::__construct('getWrappedValueHolderValue');
|
||||
$this->setDocblock('{@inheritDoc}');
|
||||
$this->setDocBlock('{@inheritDoc}');
|
||||
$this->setBody('return $this->' . $valueHolderProperty->getName() . ';');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\ValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
@@ -32,6 +34,9 @@ class MagicSleep extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $valueHolderProperty
|
||||
*/
|
||||
public function __construct(ReflectionClass $originalClass, PropertyGenerator $valueHolderProperty)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user