Augmentation vers version 3.3.0
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Autoloader;
|
||||
|
||||
use ProxyManager\FileLocator\FileLocatorInterface;
|
||||
@@ -52,7 +54,7 @@ class Autoloader implements AutoloaderInterface
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function __invoke($className)
|
||||
public function __invoke(string $className) : bool
|
||||
{
|
||||
if (class_exists($className, false) || ! $this->classNameInflector->isProxyClassName($className)) {
|
||||
return false;
|
||||
@@ -64,6 +66,8 @@ class Autoloader implements AutoloaderInterface
|
||||
return false;
|
||||
}
|
||||
|
||||
/* @noinspection PhpIncludeInspection */
|
||||
/* @noinspection UsingInclusionOnceReturnValueInspection */
|
||||
return (bool) require_once $file;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Autoloader;
|
||||
|
||||
/**
|
||||
@@ -33,5 +35,5 @@ interface AutoloaderInterface
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function __invoke($className);
|
||||
public function __invoke(string $className) : bool;
|
||||
}
|
||||
|
||||
@@ -16,12 +16,14 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager;
|
||||
|
||||
use ProxyManager\Autoloader\Autoloader;
|
||||
use ProxyManager\Autoloader\AutoloaderInterface;
|
||||
use ProxyManager\FileLocator\FileLocator;
|
||||
use ProxyManager\GeneratorStrategy\FileWriterGeneratorStrategy;
|
||||
use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy;
|
||||
use ProxyManager\GeneratorStrategy\GeneratorStrategyInterface;
|
||||
use ProxyManager\Inflector\ClassNameInflector;
|
||||
use ProxyManager\Inflector\ClassNameInflectorInterface;
|
||||
@@ -82,37 +84,12 @@ class Configuration
|
||||
*/
|
||||
protected $classSignatureGenerator;
|
||||
|
||||
/**
|
||||
* @deprecated deprecated since version 0.5
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function setAutoGenerateProxies()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*
|
||||
* @deprecated deprecated since version 0.5
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function doesAutoGenerateProxies()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AutoloaderInterface $proxyAutoloader
|
||||
*/
|
||||
public function setProxyAutoloader(AutoloaderInterface $proxyAutoloader)
|
||||
public function setProxyAutoloader(AutoloaderInterface $proxyAutoloader) : void
|
||||
{
|
||||
$this->proxyAutoloader = $proxyAutoloader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AutoloaderInterface
|
||||
*/
|
||||
public function getProxyAutoloader()
|
||||
public function getProxyAutoloader() : AutoloaderInterface
|
||||
{
|
||||
return $this->proxyAutoloader
|
||||
?: $this->proxyAutoloader = new Autoloader(
|
||||
@@ -121,119 +98,75 @@ class Configuration
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $proxiesNamespace
|
||||
*/
|
||||
public function setProxiesNamespace($proxiesNamespace)
|
||||
public function setProxiesNamespace(string $proxiesNamespace) : void
|
||||
{
|
||||
$this->proxiesNamespace = $proxiesNamespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getProxiesNamespace()
|
||||
public function getProxiesNamespace() : string
|
||||
{
|
||||
return $this->proxiesNamespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $proxiesTargetDir
|
||||
*/
|
||||
public function setProxiesTargetDir($proxiesTargetDir)
|
||||
public function setProxiesTargetDir(string $proxiesTargetDir) : void
|
||||
{
|
||||
$this->proxiesTargetDir = (string) $proxiesTargetDir;
|
||||
$this->proxiesTargetDir = $proxiesTargetDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getProxiesTargetDir()
|
||||
public function getProxiesTargetDir() : string
|
||||
{
|
||||
return $this->proxiesTargetDir ?: $this->proxiesTargetDir = sys_get_temp_dir();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param GeneratorStrategyInterface $generatorStrategy
|
||||
*/
|
||||
public function setGeneratorStrategy(GeneratorStrategyInterface $generatorStrategy)
|
||||
public function setGeneratorStrategy(GeneratorStrategyInterface $generatorStrategy) : void
|
||||
{
|
||||
$this->generatorStrategy = $generatorStrategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return GeneratorStrategyInterface
|
||||
*/
|
||||
public function getGeneratorStrategy()
|
||||
public function getGeneratorStrategy() : GeneratorStrategyInterface
|
||||
{
|
||||
return $this->generatorStrategy
|
||||
?: $this->generatorStrategy = new FileWriterGeneratorStrategy(
|
||||
new FileLocator($this->getProxiesTargetDir())
|
||||
);
|
||||
?: $this->generatorStrategy = new EvaluatingGeneratorStrategy();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassNameInflectorInterface $classNameInflector
|
||||
*/
|
||||
public function setClassNameInflector(ClassNameInflectorInterface $classNameInflector)
|
||||
public function setClassNameInflector(ClassNameInflectorInterface $classNameInflector) : void
|
||||
{
|
||||
$this->classNameInflector = $classNameInflector;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ClassNameInflectorInterface
|
||||
*/
|
||||
public function getClassNameInflector()
|
||||
public function getClassNameInflector() : ClassNameInflectorInterface
|
||||
{
|
||||
return $this->classNameInflector
|
||||
?: $this->classNameInflector = new ClassNameInflector($this->getProxiesNamespace());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SignatureGeneratorInterface $signatureGenerator
|
||||
*/
|
||||
public function setSignatureGenerator(SignatureGeneratorInterface $signatureGenerator)
|
||||
public function setSignatureGenerator(SignatureGeneratorInterface $signatureGenerator) : void
|
||||
{
|
||||
$this->signatureGenerator = $signatureGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SignatureGeneratorInterface
|
||||
*/
|
||||
public function getSignatureGenerator()
|
||||
public function getSignatureGenerator() : SignatureGeneratorInterface
|
||||
{
|
||||
return $this->signatureGenerator ?: $this->signatureGenerator = new SignatureGenerator();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SignatureCheckerInterface $signatureChecker
|
||||
*/
|
||||
public function setSignatureChecker(SignatureCheckerInterface $signatureChecker)
|
||||
public function setSignatureChecker(SignatureCheckerInterface $signatureChecker) : void
|
||||
{
|
||||
$this->signatureChecker = $signatureChecker;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SignatureCheckerInterface
|
||||
*/
|
||||
public function getSignatureChecker()
|
||||
public function getSignatureChecker() : SignatureCheckerInterface
|
||||
{
|
||||
return $this->signatureChecker
|
||||
?: $this->signatureChecker = new SignatureChecker($this->getSignatureGenerator());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassSignatureGeneratorInterface $classSignatureGenerator
|
||||
*/
|
||||
public function setClassSignatureGenerator(ClassSignatureGeneratorInterface $classSignatureGenerator)
|
||||
public function setClassSignatureGenerator(ClassSignatureGeneratorInterface $classSignatureGenerator) : void
|
||||
{
|
||||
$this->classSignatureGenerator = $classSignatureGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ClassSignatureGeneratorInterface
|
||||
*/
|
||||
public function getClassSignatureGenerator()
|
||||
public function getClassSignatureGenerator() : ClassSignatureGeneratorInterface
|
||||
{
|
||||
return $this->classSignatureGenerator
|
||||
?: new ClassSignatureGenerator($this->getSignatureGenerator());
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Exception;
|
||||
|
||||
use BadMethodCallException;
|
||||
@@ -30,13 +32,8 @@ class DisabledMethodException extends BadMethodCallException implements Exceptio
|
||||
{
|
||||
const NAME = __CLASS__;
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function disabledMethod($method)
|
||||
public static function disabledMethod(string $method) : self
|
||||
{
|
||||
return new self(sprintf('Method "%s" is forcefully disabled', (string) $method));
|
||||
return new self(sprintf('Method "%s" is forcefully disabled', $method));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Exception;
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,11 +16,10 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Exception;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
use UnexpectedValueException;
|
||||
|
||||
/**
|
||||
@@ -31,13 +30,7 @@ use UnexpectedValueException;
|
||||
*/
|
||||
class FileNotWritableException extends UnexpectedValueException implements ExceptionInterface
|
||||
{
|
||||
/**
|
||||
* @param string $fromPath
|
||||
* @param string $toPath
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function fromInvalidMoveOperation($fromPath, $toPath)
|
||||
public static function fromInvalidMoveOperation(string $fromPath, string $toPath) : self
|
||||
{
|
||||
return new self(sprintf(
|
||||
'Could not move file "%s" to location "%s": '
|
||||
@@ -48,19 +41,26 @@ class FileNotWritableException extends UnexpectedValueException implements Excep
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated this method is unused, and will be removed in ProxyManager 3.0.0
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function fromNonWritableLocation($path)
|
||||
public static function fromNonWritableLocation($path) : self
|
||||
{
|
||||
$messages = array();
|
||||
$messages = [];
|
||||
$destination = realpath($path);
|
||||
|
||||
if (($destination = realpath($path)) && ! is_file($destination)) {
|
||||
if (! $destination) {
|
||||
$messages[] = 'path does not exist';
|
||||
}
|
||||
|
||||
if ($destination && ! is_file($destination)) {
|
||||
$messages[] = 'exists and is not a file';
|
||||
}
|
||||
|
||||
if (! is_writable($destination)) {
|
||||
if ($destination && ! is_writable($destination)) {
|
||||
$messages[] = 'is not writable';
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Exception;
|
||||
|
||||
use InvalidArgumentException;
|
||||
@@ -30,32 +32,17 @@ use ReflectionMethod;
|
||||
*/
|
||||
class InvalidProxiedClassException extends InvalidArgumentException implements ExceptionInterface
|
||||
{
|
||||
/**
|
||||
* @param ReflectionClass $reflection
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function interfaceNotSupported(ReflectionClass $reflection)
|
||||
public static function interfaceNotSupported(ReflectionClass $reflection) : self
|
||||
{
|
||||
return new self(sprintf('Provided interface "%s" cannot be proxied', $reflection->getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ReflectionClass $reflection
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function finalClassNotSupported(ReflectionClass $reflection)
|
||||
public static function finalClassNotSupported(ReflectionClass $reflection) : self
|
||||
{
|
||||
return new self(sprintf('Provided class "%s" is final and cannot be proxied', $reflection->getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ReflectionClass $reflection
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function abstractProtectedMethodsNotSupported(ReflectionClass $reflection)
|
||||
public static function abstractProtectedMethodsNotSupported(ReflectionClass $reflection) : self
|
||||
{
|
||||
return new self(sprintf(
|
||||
'Provided class "%s" has following protected abstract methods, and therefore cannot be proxied:' . "\n%s",
|
||||
@@ -63,12 +50,12 @@ class InvalidProxiedClassException extends InvalidArgumentException implements E
|
||||
implode(
|
||||
"\n",
|
||||
array_map(
|
||||
function (ReflectionMethod $reflectionMethod) {
|
||||
function (ReflectionMethod $reflectionMethod) : string {
|
||||
return $reflectionMethod->getDeclaringClass()->getName() . '::' . $reflectionMethod->getName();
|
||||
},
|
||||
array_filter(
|
||||
$reflection->getMethods(),
|
||||
function (ReflectionMethod $method) {
|
||||
function (ReflectionMethod $method) : bool {
|
||||
return $method->isAbstract() && $method->isProtected();
|
||||
}
|
||||
)
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Exception;
|
||||
|
||||
use InvalidArgumentException;
|
||||
@@ -28,13 +30,8 @@ use InvalidArgumentException;
|
||||
*/
|
||||
class InvalidProxyDirectoryException extends InvalidArgumentException implements ExceptionInterface
|
||||
{
|
||||
/**
|
||||
* @param string $directory
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function proxyDirectoryNotFound($directory)
|
||||
public static function proxyDirectoryNotFound(string $directory) : self
|
||||
{
|
||||
return new self(sprintf('Provided directory "%s" does not exist', (string) $directory));
|
||||
return new self(sprintf('Provided directory "%s" does not exist', $directory));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Exception;
|
||||
|
||||
use LogicException;
|
||||
@@ -29,12 +31,7 @@ use ReflectionProperty;
|
||||
*/
|
||||
class UnsupportedProxiedClassException extends LogicException implements ExceptionInterface
|
||||
{
|
||||
/**
|
||||
* @param ReflectionProperty $property
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function unsupportedLocalizedReflectionProperty(ReflectionProperty $property)
|
||||
public static function unsupportedLocalizedReflectionProperty(ReflectionProperty $property) : self
|
||||
{
|
||||
return new self(
|
||||
sprintf(
|
||||
|
||||
@@ -16,10 +16,15 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Factory;
|
||||
|
||||
use ProxyManager\Configuration;
|
||||
use ProxyManager\Generator\ClassGenerator;
|
||||
use ProxyManager\ProxyGenerator\ProxyGeneratorInterface;
|
||||
use ProxyManager\Signature\Exception\InvalidSignatureException;
|
||||
use ProxyManager\Signature\Exception\MissingSignatureException;
|
||||
use ProxyManager\Version;
|
||||
use ReflectionClass;
|
||||
|
||||
@@ -41,7 +46,7 @@ abstract class AbstractBaseFactory
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
private $checkedClasses = array();
|
||||
private $checkedClasses = [];
|
||||
|
||||
/**
|
||||
* @param \ProxyManager\Configuration $configuration
|
||||
@@ -53,27 +58,39 @@ abstract class AbstractBaseFactory
|
||||
|
||||
/**
|
||||
* Generate a proxy from a class name
|
||||
* @param string $className
|
||||
*
|
||||
* @param string $className
|
||||
* @param mixed[] $proxyOptions
|
||||
*
|
||||
* @return string proxy class name
|
||||
*
|
||||
* @throws InvalidSignatureException
|
||||
* @throws MissingSignatureException
|
||||
* @throws \OutOfBoundsException
|
||||
*/
|
||||
protected function generateProxy($className)
|
||||
protected function generateProxy(string $className, array $proxyOptions = []) : string
|
||||
{
|
||||
if (isset($this->checkedClasses[$className])) {
|
||||
if (\array_key_exists($className, $this->checkedClasses)) {
|
||||
return $this->checkedClasses[$className];
|
||||
}
|
||||
|
||||
$proxyParameters = array(
|
||||
$proxyParameters = [
|
||||
'className' => $className,
|
||||
'factory' => get_class($this),
|
||||
'proxyManagerVersion' => Version::VERSION
|
||||
);
|
||||
'proxyManagerVersion' => Version::getVersion(),
|
||||
];
|
||||
$proxyClassName = $this
|
||||
->configuration
|
||||
->getClassNameInflector()
|
||||
->getProxyClassName($className, $proxyParameters);
|
||||
|
||||
if (! class_exists($proxyClassName)) {
|
||||
$this->generateProxyClass($proxyClassName, $className, $proxyParameters);
|
||||
$this->generateProxyClass(
|
||||
$proxyClassName,
|
||||
$className,
|
||||
$proxyParameters,
|
||||
$proxyOptions
|
||||
);
|
||||
}
|
||||
|
||||
$this
|
||||
@@ -84,29 +101,33 @@ abstract class AbstractBaseFactory
|
||||
return $this->checkedClasses[$className] = $proxyClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \ProxyManager\ProxyGenerator\ProxyGeneratorInterface
|
||||
*/
|
||||
abstract protected function getGenerator();
|
||||
abstract protected function getGenerator() : ProxyGeneratorInterface;
|
||||
|
||||
/**
|
||||
* Generates the provided `$proxyClassName` from the given `$className` and `$proxyParameters`
|
||||
* @param string $proxyClassName
|
||||
* @param string $className
|
||||
* @param array $proxyParameters
|
||||
*
|
||||
* @return void
|
||||
* @param string $proxyClassName
|
||||
* @param string $className
|
||||
* @param array $proxyParameters
|
||||
* @param mixed[] $proxyOptions
|
||||
*/
|
||||
private function generateProxyClass($proxyClassName, $className, array $proxyParameters)
|
||||
{
|
||||
private function generateProxyClass(
|
||||
string $proxyClassName,
|
||||
string $className,
|
||||
array $proxyParameters,
|
||||
array $proxyOptions = []
|
||||
) : void {
|
||||
$className = $this->configuration->getClassNameInflector()->getUserClassName($className);
|
||||
$phpClass = new ClassGenerator($proxyClassName);
|
||||
|
||||
$this->getGenerator()->generate(new ReflectionClass($className), $phpClass);
|
||||
$this->getGenerator()->generate(new ReflectionClass($className), $phpClass, $proxyOptions);
|
||||
|
||||
$phpClass = $this->configuration->getClassSignatureGenerator()->addSignature($phpClass, $proxyParameters);
|
||||
|
||||
$this->configuration->getGeneratorStrategy()->generate($phpClass);
|
||||
$this->configuration->getProxyAutoloader()->__invoke($proxyClassName);
|
||||
$this->configuration->getGeneratorStrategy()->generate($phpClass, $proxyOptions);
|
||||
|
||||
$autoloader = $this->configuration->getProxyAutoloader();
|
||||
|
||||
$autoloader($proxyClassName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,15 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Factory;
|
||||
|
||||
use ProxyManager\Proxy\AccessInterceptorInterface;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizerGenerator;
|
||||
use ProxyManager\ProxyGenerator\ProxyGeneratorInterface;
|
||||
use ProxyManager\Signature\Exception\InvalidSignatureException;
|
||||
use ProxyManager\Signature\Exception\MissingSignatureException;
|
||||
|
||||
/**
|
||||
* Factory responsible of producing proxy objects
|
||||
@@ -40,19 +46,26 @@ class AccessInterceptorScopeLocalizerFactory extends AbstractBaseFactory
|
||||
* @param \Closure[] $suffixInterceptors an array (indexed by method name) of interceptor closures to be called
|
||||
* after method logic is executed
|
||||
*
|
||||
* @return \ProxyManager\Proxy\AccessInterceptorInterface
|
||||
* @return AccessInterceptorInterface
|
||||
*
|
||||
* @throws InvalidSignatureException
|
||||
* @throws MissingSignatureException
|
||||
* @throws \OutOfBoundsException
|
||||
*/
|
||||
public function createProxy($instance, array $prefixInterceptors = array(), array $suffixInterceptors = array())
|
||||
{
|
||||
public function createProxy(
|
||||
$instance,
|
||||
array $prefixInterceptors = [],
|
||||
array $suffixInterceptors = []
|
||||
) : AccessInterceptorInterface {
|
||||
$proxyClassName = $this->generateProxy(get_class($instance));
|
||||
|
||||
return new $proxyClassName($instance, $prefixInterceptors, $suffixInterceptors);
|
||||
return $proxyClassName::staticProxyConstructor($instance, $prefixInterceptors, $suffixInterceptors);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getGenerator()
|
||||
protected function getGenerator() : ProxyGeneratorInterface
|
||||
{
|
||||
return $this->generator ?: $this->generator = new AccessInterceptorScopeLocalizerGenerator();
|
||||
}
|
||||
|
||||
@@ -16,9 +16,15 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Factory;
|
||||
|
||||
use ProxyManager\Proxy\AccessInterceptorValueHolderInterface;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolderGenerator;
|
||||
use ProxyManager\ProxyGenerator\ProxyGeneratorInterface;
|
||||
use ProxyManager\Signature\Exception\InvalidSignatureException;
|
||||
use ProxyManager\Signature\Exception\MissingSignatureException;
|
||||
|
||||
/**
|
||||
* Factory responsible of producing proxy objects
|
||||
@@ -40,19 +46,26 @@ class AccessInterceptorValueHolderFactory extends AbstractBaseFactory
|
||||
* @param \Closure[] $suffixInterceptors an array (indexed by method name) of interceptor closures to be called
|
||||
* after method logic is executed
|
||||
*
|
||||
* @return \ProxyManager\Proxy\AccessInterceptorInterface|\ProxyManager\Proxy\ValueHolderInterface
|
||||
* @return AccessInterceptorValueHolderInterface
|
||||
*
|
||||
* @throws InvalidSignatureException
|
||||
* @throws MissingSignatureException
|
||||
* @throws \OutOfBoundsException
|
||||
*/
|
||||
public function createProxy($instance, array $prefixInterceptors = array(), array $suffixInterceptors = array())
|
||||
{
|
||||
public function createProxy(
|
||||
$instance,
|
||||
array $prefixInterceptors = [],
|
||||
array $suffixInterceptors = []
|
||||
) : AccessInterceptorValueHolderInterface {
|
||||
$proxyClassName = $this->generateProxy(get_class($instance));
|
||||
|
||||
return new $proxyClassName($instance, $prefixInterceptors, $suffixInterceptors);
|
||||
return $proxyClassName::staticProxyConstructor($instance, $prefixInterceptors, $suffixInterceptors);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getGenerator()
|
||||
protected function getGenerator() : ProxyGeneratorInterface
|
||||
{
|
||||
return $this->generator ?: $this->generator = new AccessInterceptorValueHolderGenerator();
|
||||
}
|
||||
|
||||
@@ -16,19 +16,24 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Factory;
|
||||
|
||||
use Closure;
|
||||
use ProxyManager\Proxy\GhostObjectInterface;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingGhostGenerator;
|
||||
use ProxyManager\ProxyGenerator\ProxyGeneratorInterface;
|
||||
use ProxyManager\Signature\Exception\InvalidSignatureException;
|
||||
use ProxyManager\Signature\Exception\MissingSignatureException;
|
||||
|
||||
/**
|
||||
* Factory responsible of producing ghost instances
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*
|
||||
* @method \ProxyManager\Proxy\GhostObjectInterface createProxy($className, \Closure $initializer)
|
||||
*/
|
||||
class LazyLoadingGhostFactory extends AbstractLazyFactory
|
||||
class LazyLoadingGhostFactory extends AbstractBaseFactory
|
||||
{
|
||||
/**
|
||||
* @var \ProxyManager\ProxyGenerator\LazyLoadingGhostGenerator|null
|
||||
@@ -38,8 +43,60 @@ class LazyLoadingGhostFactory extends AbstractLazyFactory
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getGenerator()
|
||||
protected function getGenerator() : ProxyGeneratorInterface
|
||||
{
|
||||
return $this->generator ?: $this->generator = new LazyLoadingGhostGenerator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new lazy proxy instance of the given class with
|
||||
* the given initializer
|
||||
*
|
||||
* Please refer to the following documentation when using this method:
|
||||
*
|
||||
* @link https://github.com/Ocramius/ProxyManager/blob/master/docs/lazy-loading-ghost-object.md
|
||||
*
|
||||
* @param string $className name of the class to be proxied
|
||||
* @param Closure $initializer initializer to be passed to the proxy. The initializer closure should have following
|
||||
* signature:
|
||||
*
|
||||
* <code>
|
||||
* $initializer = function (
|
||||
* GhostObjectInterface $proxy,
|
||||
* string $method,
|
||||
* array $parameters,
|
||||
* & $initializer,
|
||||
* array $properties
|
||||
* ) {};
|
||||
* </code>
|
||||
*
|
||||
* Where:
|
||||
* - $proxy is the proxy instance on which the initializer is acting
|
||||
* - $method is the name of the method that triggered the lazy initialization
|
||||
* - $parameters are the parameters that were passed to $method
|
||||
* - $initializer by-ref initializer - should be assigned null in the initializer body
|
||||
* - $properties a by-ref map of the properties of the object, indexed by PHP
|
||||
* internal property name. Assign values to it to initialize the
|
||||
* object state
|
||||
*
|
||||
* @param mixed[] $proxyOptions a set of options to be used when generating the proxy. Currently supports only
|
||||
* key "skippedProperties", which allows to skip lazy-loading of some properties.
|
||||
* "skippedProperties" is a string[], containing a list of properties referenced
|
||||
* via PHP's internal property name (i.e. "\0ClassName\0propertyName")
|
||||
*
|
||||
* @return GhostObjectInterface
|
||||
*
|
||||
* @throws MissingSignatureException
|
||||
* @throws InvalidSignatureException
|
||||
* @throws \OutOfBoundsException
|
||||
*/
|
||||
public function createProxy(
|
||||
string $className,
|
||||
Closure $initializer,
|
||||
array $proxyOptions = []
|
||||
) : GhostObjectInterface {
|
||||
$proxyClassName = $this->generateProxy($className, $proxyOptions);
|
||||
|
||||
return $proxyClassName::staticProxyConstructor($initializer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,29 +16,41 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Factory;
|
||||
|
||||
use ProxyManager\Proxy\VirtualProxyInterface;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerator;
|
||||
use ProxyManager\ProxyGenerator\ProxyGeneratorInterface;
|
||||
|
||||
/**
|
||||
* Factory responsible of producing virtual proxy instances
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*
|
||||
* @method \ProxyManager\Proxy\VirtualProxyInterface createProxy($className, \Closure $initializer)
|
||||
*/
|
||||
class LazyLoadingValueHolderFactory extends AbstractLazyFactory
|
||||
class LazyLoadingValueHolderFactory extends AbstractBaseFactory
|
||||
{
|
||||
/**
|
||||
* @var \ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerator|null
|
||||
*/
|
||||
private $generator;
|
||||
|
||||
public function createProxy(
|
||||
string $className,
|
||||
\Closure $initializer,
|
||||
array $proxyOptions = []
|
||||
) : VirtualProxyInterface {
|
||||
$proxyClassName = $this->generateProxy($className, $proxyOptions);
|
||||
|
||||
return $proxyClassName::staticProxyConstructor($initializer);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getGenerator()
|
||||
protected function getGenerator() : ProxyGeneratorInterface
|
||||
{
|
||||
return $this->generator ?: $this->generator = new LazyLoadingValueHolderGenerator();
|
||||
}
|
||||
|
||||
@@ -16,9 +16,15 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Factory;
|
||||
|
||||
use ProxyManager\Proxy\NullObjectInterface;
|
||||
use ProxyManager\ProxyGenerator\NullObjectGenerator;
|
||||
use ProxyManager\ProxyGenerator\ProxyGeneratorInterface;
|
||||
use ProxyManager\Signature\Exception\InvalidSignatureException;
|
||||
use ProxyManager\Signature\Exception\MissingSignatureException;
|
||||
|
||||
/**
|
||||
* Factory responsible of producing proxy objects
|
||||
@@ -36,20 +42,24 @@ class NullObjectFactory extends AbstractBaseFactory
|
||||
/**
|
||||
* @param object $instanceOrClassName the object to be wrapped or interface to transform to null object
|
||||
*
|
||||
* @return \ProxyManager\Proxy\NullobjectInterface
|
||||
* @return NullObjectInterface
|
||||
*
|
||||
* @throws InvalidSignatureException
|
||||
* @throws MissingSignatureException
|
||||
* @throws \OutOfBoundsException
|
||||
*/
|
||||
public function createProxy($instanceOrClassName)
|
||||
public function createProxy($instanceOrClassName) : NullObjectInterface
|
||||
{
|
||||
$className = is_object($instanceOrClassName) ? get_class($instanceOrClassName) : $instanceOrClassName;
|
||||
$proxyClassName = $this->generateProxy($className);
|
||||
|
||||
return new $proxyClassName();
|
||||
return $proxyClassName::staticProxyConstructor();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getGenerator()
|
||||
protected function getGenerator() : ProxyGeneratorInterface
|
||||
{
|
||||
return $this->generator ?: $this->generator = new NullObjectGenerator();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Factory\RemoteObject\Adapter;
|
||||
|
||||
use ProxyManager\Factory\RemoteObject\AdapterInterface;
|
||||
@@ -41,7 +43,7 @@ abstract class BaseAdapter implements AdapterInterface
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $map = array();
|
||||
protected $map = [];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@@ -49,7 +51,7 @@ abstract class BaseAdapter implements AdapterInterface
|
||||
* @param Client $client
|
||||
* @param array $map map of service names to their aliases
|
||||
*/
|
||||
public function __construct(Client $client, array $map = array())
|
||||
public function __construct(Client $client, array $map = [])
|
||||
{
|
||||
$this->client = $client;
|
||||
$this->map = $map;
|
||||
@@ -58,11 +60,11 @@ abstract class BaseAdapter implements AdapterInterface
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function call($wrappedClass, $method, array $params = array())
|
||||
public function call(string $wrappedClass, string $method, array $params = [])
|
||||
{
|
||||
$serviceName = $this->getServiceName($wrappedClass, $method);
|
||||
|
||||
if (isset($this->map[$serviceName])) {
|
||||
if (\array_key_exists($serviceName, $this->map)) {
|
||||
$serviceName = $this->map[$serviceName];
|
||||
}
|
||||
|
||||
@@ -77,5 +79,5 @@ abstract class BaseAdapter implements AdapterInterface
|
||||
*
|
||||
* @return string Service name
|
||||
*/
|
||||
abstract protected function getServiceName($wrappedClass, $method);
|
||||
abstract protected function getServiceName(string $wrappedClass, string $method) : string;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Factory\RemoteObject\Adapter;
|
||||
|
||||
/**
|
||||
@@ -29,7 +31,7 @@ class JsonRpc extends BaseAdapter
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getServiceName($wrappedClass, $method)
|
||||
protected function getServiceName(string $wrappedClass, string $method) : string
|
||||
{
|
||||
return $wrappedClass . '.' . $method;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Factory\RemoteObject\Adapter;
|
||||
|
||||
/**
|
||||
@@ -29,8 +31,8 @@ class Soap extends BaseAdapter
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getServiceName($wrappedClass, $method)
|
||||
protected function getServiceName(string $wrappedClass, string $method) : string
|
||||
{
|
||||
return (string) $method;
|
||||
return $method;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Factory\RemoteObject\Adapter;
|
||||
|
||||
/**
|
||||
@@ -29,7 +31,7 @@ class XmlRpc extends BaseAdapter
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getServiceName($wrappedClass, $method)
|
||||
protected function getServiceName(string $wrappedClass, string $method) : string
|
||||
{
|
||||
return $wrappedClass . '.' . $method;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Factory\RemoteObject;
|
||||
|
||||
/**
|
||||
@@ -33,5 +35,5 @@ interface AdapterInterface
|
||||
* @param string $method
|
||||
* @param array $params
|
||||
*/
|
||||
public function call($wrappedClass, $method, array $params = array());
|
||||
public function call(string $wrappedClass, string $method, array $params = []);
|
||||
}
|
||||
|
||||
@@ -16,11 +16,17 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Factory;
|
||||
|
||||
use ProxyManager\Configuration;
|
||||
use ProxyManager\Factory\RemoteObject\AdapterInterface;
|
||||
use ProxyManager\Proxy\RemoteObjectInterface;
|
||||
use ProxyManager\ProxyGenerator\ProxyGeneratorInterface;
|
||||
use ProxyManager\ProxyGenerator\RemoteObjectGenerator;
|
||||
use ProxyManager\Signature\Exception\InvalidSignatureException;
|
||||
use ProxyManager\Signature\Exception\MissingSignatureException;
|
||||
|
||||
/**
|
||||
* Factory responsible of producing remote proxy objects
|
||||
@@ -56,20 +62,25 @@ class RemoteObjectFactory extends AbstractBaseFactory
|
||||
/**
|
||||
* @param string|object $instanceOrClassName
|
||||
*
|
||||
* @return \ProxyManager\Proxy\RemoteObjectInterface
|
||||
* @return RemoteObjectInterface
|
||||
*
|
||||
* @throws InvalidSignatureException
|
||||
* @throws MissingSignatureException
|
||||
* @throws \OutOfBoundsException
|
||||
*/
|
||||
public function createProxy($instanceOrClassName)
|
||||
public function createProxy($instanceOrClassName) : RemoteObjectInterface
|
||||
{
|
||||
$className = is_object($instanceOrClassName) ? get_class($instanceOrClassName) : $instanceOrClassName;
|
||||
$proxyClassName = $this->generateProxy($className);
|
||||
$proxyClassName = $this->generateProxy(
|
||||
is_object($instanceOrClassName) ? get_class($instanceOrClassName) : $instanceOrClassName
|
||||
);
|
||||
|
||||
return new $proxyClassName($this->adapter);
|
||||
return $proxyClassName::staticProxyConstructor($this->adapter);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getGenerator()
|
||||
protected function getGenerator() : ProxyGeneratorInterface
|
||||
{
|
||||
return $this->generator ?: $this->generator = new RemoteObjectGenerator();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\FileLocator;
|
||||
|
||||
use ProxyManager\Exception\InvalidProxyDirectoryException;
|
||||
@@ -38,19 +40,21 @@ class FileLocator implements FileLocatorInterface
|
||||
*
|
||||
* @throws \ProxyManager\Exception\InvalidProxyDirectoryException
|
||||
*/
|
||||
public function __construct($proxiesDirectory)
|
||||
public function __construct(string $proxiesDirectory)
|
||||
{
|
||||
$this->proxiesDirectory = realpath($proxiesDirectory);
|
||||
$absolutePath = realpath($proxiesDirectory);
|
||||
|
||||
if (false === $this->proxiesDirectory) {
|
||||
if (false === $absolutePath) {
|
||||
throw InvalidProxyDirectoryException::proxyDirectoryNotFound($proxiesDirectory);
|
||||
}
|
||||
|
||||
$this->proxiesDirectory = $absolutePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getProxyFileName($className)
|
||||
public function getProxyFileName(string $className) : string
|
||||
{
|
||||
return $this->proxiesDirectory . DIRECTORY_SEPARATOR . str_replace('\\', '', $className) . '.php';
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\FileLocator;
|
||||
|
||||
/**
|
||||
@@ -33,5 +35,5 @@ interface FileLocatorInterface
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getProxyFileName($className);
|
||||
public function getProxyFileName(string $className) : string;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Generator;
|
||||
|
||||
use Zend\Code\Generator\ClassGenerator as ZendClassGenerator;
|
||||
@@ -31,7 +33,7 @@ class ClassGenerator extends ZendClassGenerator
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function setExtendedClass($extendedClass)
|
||||
public function setExtendedClass($extendedClass) : parent
|
||||
{
|
||||
if ($extendedClass) {
|
||||
$extendedClass = '\\' . trim($extendedClass, '\\');
|
||||
@@ -43,7 +45,7 @@ class ClassGenerator extends ZendClassGenerator
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function setImplementedInterfaces(array $interfaces)
|
||||
public function setImplementedInterfaces(array $interfaces) : parent
|
||||
{
|
||||
foreach ($interfaces as & $interface) {
|
||||
$interface = '\\' . trim($interface, '\\');
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Generator;
|
||||
|
||||
use ReflectionClass;
|
||||
@@ -33,7 +35,7 @@ class MagicMethodGenerator extends MethodGenerator
|
||||
* @param string $name
|
||||
* @param array $parameters
|
||||
*/
|
||||
public function __construct(ReflectionClass $originalClass, $name, array $parameters = array())
|
||||
public function __construct(ReflectionClass $originalClass, string $name, array $parameters = [])
|
||||
{
|
||||
parent::__construct(
|
||||
$name,
|
||||
|
||||
@@ -16,9 +16,10 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Generator;
|
||||
|
||||
use Zend\Code\Generator\DocBlockGenerator;
|
||||
use Zend\Code\Generator\MethodGenerator as ZendMethodGenerator;
|
||||
use Zend\Code\Reflection\MethodReflection;
|
||||
|
||||
@@ -31,131 +32,15 @@ use Zend\Code\Reflection\MethodReflection;
|
||||
class MethodGenerator extends ZendMethodGenerator
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $returnsReference = false;
|
||||
|
||||
/**
|
||||
* @param boolean $returnsReference
|
||||
*/
|
||||
public function setReturnsReference($returnsReference)
|
||||
{
|
||||
$this->returnsReference = (bool) $returnsReference;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function returnsReference()
|
||||
{
|
||||
return $this->returnsReference;
|
||||
}
|
||||
|
||||
/**
|
||||
* @override enforces generation of \ProxyManager\Generator\MethodGenerator
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public static function fromReflection(MethodReflection $reflectionMethod)
|
||||
public static function fromReflection(MethodReflection $reflectionMethod) : self
|
||||
{
|
||||
/* @var $method self */
|
||||
$method = new static();
|
||||
$method = parent::fromReflection($reflectionMethod);
|
||||
|
||||
$method->setSourceContent($reflectionMethod->getContents(false));
|
||||
$method->setSourceDirty(false);
|
||||
|
||||
if ($reflectionMethod->getDocComment() != '') {
|
||||
$method->setDocBlock(DocBlockGenerator::fromReflection($reflectionMethod->getDocBlock()));
|
||||
}
|
||||
|
||||
$method->setFinal($reflectionMethod->isFinal());
|
||||
$method->setVisibility(self::extractVisibility($reflectionMethod));
|
||||
|
||||
foreach ($reflectionMethod->getParameters() as $reflectionParameter) {
|
||||
$method->setParameter(ParameterGenerator::fromReflection($reflectionParameter));
|
||||
}
|
||||
|
||||
$method->setStatic($reflectionMethod->isStatic());
|
||||
$method->setName($reflectionMethod->getName());
|
||||
$method->setBody($reflectionMethod->getBody());
|
||||
$method->setReturnsReference($reflectionMethod->returnsReference());
|
||||
$method->setInterface(false);
|
||||
|
||||
return $method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the visibility for the given method reflection
|
||||
*
|
||||
* @param MethodReflection $reflectionMethod
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function extractVisibility(MethodReflection $reflectionMethod)
|
||||
{
|
||||
if ($reflectionMethod->isPrivate()) {
|
||||
return static::VISIBILITY_PRIVATE;
|
||||
}
|
||||
|
||||
if ($reflectionMethod->isProtected()) {
|
||||
return static::VISIBILITY_PROTECTED;
|
||||
}
|
||||
|
||||
return static::VISIBILITY_PUBLIC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @override fixes by-reference return value in zf2's method generator
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function generate()
|
||||
{
|
||||
$output = '';
|
||||
$indent = $this->getIndentation();
|
||||
|
||||
if (null !== ($docBlock = $this->getDocBlock())) {
|
||||
$docBlock->setIndentation($indent);
|
||||
|
||||
$output .= $docBlock->generate();
|
||||
}
|
||||
|
||||
$output .= $indent . $this->generateMethodDeclaration() . self::LINE_FEED . $indent . '{' . self::LINE_FEED;
|
||||
|
||||
if ($this->body) {
|
||||
$output .= preg_replace('#^(.+?)$#m', $indent . $indent . '$1', trim($this->body))
|
||||
. self::LINE_FEED;
|
||||
}
|
||||
|
||||
$output .= $indent . '}' . self::LINE_FEED;
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function generateMethodDeclaration()
|
||||
{
|
||||
$output = $this->generateVisibility()
|
||||
. ' function '
|
||||
. (($this->returnsReference()) ? '& ' : '')
|
||||
. $this->getName() . '(';
|
||||
|
||||
$parameterOutput = array();
|
||||
|
||||
foreach ($this->getParameters() as $parameter) {
|
||||
$parameterOutput[] = $parameter->generate();
|
||||
}
|
||||
|
||||
return $output . implode(', ', $parameterOutput) . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function generateVisibility()
|
||||
{
|
||||
return $this->isAbstract() ? 'abstract ' : (($this->isFinal()) ? 'final ' : '')
|
||||
. ($this->getVisibility() . (($this->isStatic()) ? ' static' : ''));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Generator\Util;
|
||||
|
||||
use ReflectionClass;
|
||||
@@ -30,18 +32,11 @@ use Zend\Code\Generator\MethodGenerator;
|
||||
*/
|
||||
final class ClassGeneratorUtils
|
||||
{
|
||||
/**
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param ClassGenerator $classGenerator
|
||||
* @param MethodGenerator $generatedMethod
|
||||
*
|
||||
* @return void|false
|
||||
*/
|
||||
public static function addMethodIfNotFinal(
|
||||
ReflectionClass $originalClass,
|
||||
ClassGenerator $classGenerator,
|
||||
MethodGenerator $generatedMethod
|
||||
) {
|
||||
) : bool {
|
||||
$methodName = $generatedMethod->getName();
|
||||
|
||||
if ($originalClass->hasMethod($methodName) && $originalClass->getMethod($methodName)->isFinal()) {
|
||||
@@ -49,5 +44,7 @@ final class ClassGeneratorUtils
|
||||
}
|
||||
|
||||
$classGenerator->addMethodFromGenerator($generatedMethod);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
41
vendor/ocramius/proxy-manager/src/ProxyManager/Generator/Util/ProxiedMethodReturnExpression.php
vendored
Normal file
41
vendor/ocramius/proxy-manager/src/ProxyManager/Generator/Util/ProxiedMethodReturnExpression.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?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\Generator\Util;
|
||||
|
||||
/**
|
||||
* Utility class to generate return expressions in method, given a method signature.
|
||||
*
|
||||
* This is required since return expressions may be forbidden by the method signature (void).
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*/
|
||||
final class ProxiedMethodReturnExpression
|
||||
{
|
||||
public static function generate(string $returnedValueExpression, ?\ReflectionMethod $originalMethod) : string
|
||||
{
|
||||
if ($originalMethod && 'void' === (string) $originalMethod->getReturnType()) {
|
||||
return $returnedValueExpression . ";\nreturn;";
|
||||
}
|
||||
|
||||
return 'return ' . $returnedValueExpression . ';';
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Generator\Util;
|
||||
|
||||
/**
|
||||
@@ -37,7 +39,7 @@ abstract class UniqueIdentifierGenerator
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getIdentifier($name)
|
||||
public static function getIdentifier(string $name) : string
|
||||
{
|
||||
return str_replace(
|
||||
'.',
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\GeneratorStrategy;
|
||||
|
||||
use Zend\Code\Generator\ClassGenerator;
|
||||
@@ -31,7 +33,7 @@ class BaseGeneratorStrategy implements GeneratorStrategyInterface
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function generate(ClassGenerator $classGenerator)
|
||||
public function generate(ClassGenerator $classGenerator) : string
|
||||
{
|
||||
return $classGenerator->generate();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\GeneratorStrategy;
|
||||
|
||||
use Zend\Code\Generator\ClassGenerator;
|
||||
@@ -38,7 +40,9 @@ class EvaluatingGeneratorStrategy implements GeneratorStrategyInterface
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// @codeCoverageIgnoreStart
|
||||
$this->canEval = ! ini_get('suhosin.executor.disable_eval');
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,21 +50,22 @@ class EvaluatingGeneratorStrategy implements GeneratorStrategyInterface
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function generate(ClassGenerator $classGenerator)
|
||||
public function generate(ClassGenerator $classGenerator) : string
|
||||
{
|
||||
$code = $classGenerator->generate();
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
if (! $this->canEval) {
|
||||
// @codeCoverageIgnoreStart
|
||||
$fileName = sys_get_temp_dir() . '/EvaluatingGeneratorStrategy.php.tmp.' . uniqid('', true);
|
||||
$fileName = tempnam(sys_get_temp_dir(), 'EvaluatingGeneratorStrategy.php.tmp.');
|
||||
|
||||
file_put_contents($fileName, "<?php\n" . $code);
|
||||
/* @noinspection PhpIncludeInspection */
|
||||
require $fileName;
|
||||
unlink($fileName);
|
||||
|
||||
return $code;
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
eval($code);
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\GeneratorStrategy;
|
||||
|
||||
use ProxyManager\Exception\FileNotWritableException;
|
||||
@@ -56,8 +58,10 @@ class FileWriterGeneratorStrategy implements GeneratorStrategyInterface
|
||||
* Write generated code to disk and return the class code
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @throws FileNotWritableException
|
||||
*/
|
||||
public function generate(ClassGenerator $classGenerator)
|
||||
public function generate(ClassGenerator $classGenerator) : string
|
||||
{
|
||||
$className = trim($classGenerator->getNamespaceName(), '\\')
|
||||
. '\\' . trim($classGenerator->getName(), '\\');
|
||||
@@ -68,15 +72,11 @@ class FileWriterGeneratorStrategy implements GeneratorStrategyInterface
|
||||
|
||||
try {
|
||||
$this->writeFile("<?php\n\n" . $generatedCode, $fileName);
|
||||
} catch (FileNotWritableException $fileNotWritable) {
|
||||
|
||||
return $generatedCode;
|
||||
} finally {
|
||||
restore_error_handler();
|
||||
|
||||
throw $fileNotWritable;
|
||||
}
|
||||
|
||||
restore_error_handler();
|
||||
|
||||
return $generatedCode;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,13 +88,11 @@ class FileWriterGeneratorStrategy implements GeneratorStrategyInterface
|
||||
*
|
||||
* @throws FileNotWritableException
|
||||
*/
|
||||
private function writeFile($source, $location)
|
||||
private function writeFile(string $source, string $location) : void
|
||||
{
|
||||
$tmpFileName = $location . '.' . uniqid('', true);
|
||||
$tmpFileName = tempnam($location, 'temporaryProxyManagerFile');
|
||||
|
||||
if (! file_put_contents($tmpFileName, $source)) {
|
||||
throw FileNotWritableException::fromNonWritableLocation($tmpFileName);
|
||||
}
|
||||
file_put_contents($tmpFileName, $source);
|
||||
|
||||
if (! rename($tmpFileName, $location)) {
|
||||
unlink($tmpFileName);
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\GeneratorStrategy;
|
||||
|
||||
use Zend\Code\Generator\ClassGenerator;
|
||||
@@ -35,5 +37,5 @@ interface GeneratorStrategyInterface
|
||||
*
|
||||
* @return string the class body
|
||||
*/
|
||||
public function generate(ClassGenerator $classGenerator);
|
||||
public function generate(ClassGenerator $classGenerator) : string;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Inflector;
|
||||
|
||||
use ProxyManager\Inflector\Util\ParameterHasher;
|
||||
@@ -51,9 +53,9 @@ final class ClassNameInflector implements ClassNameInflectorInterface
|
||||
/**
|
||||
* @param string $proxyNamespace
|
||||
*/
|
||||
public function __construct($proxyNamespace)
|
||||
public function __construct(string $proxyNamespace)
|
||||
{
|
||||
$this->proxyNamespace = (string) $proxyNamespace;
|
||||
$this->proxyNamespace = $proxyNamespace;
|
||||
$this->proxyMarker = '\\' . static::PROXY_MARKER . '\\';
|
||||
$this->proxyMarkerLength = strlen($this->proxyMarker);
|
||||
$this->parameterHasher = new ParameterHasher();
|
||||
@@ -62,7 +64,7 @@ final class ClassNameInflector implements ClassNameInflectorInterface
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getUserClassName($className)
|
||||
public function getUserClassName(string $className) : string
|
||||
{
|
||||
$className = ltrim($className, '\\');
|
||||
|
||||
@@ -80,7 +82,7 @@ final class ClassNameInflector implements ClassNameInflectorInterface
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getProxyClassName($className, array $options = array())
|
||||
public function getProxyClassName(string $className, array $options = []) : string
|
||||
{
|
||||
return $this->proxyNamespace
|
||||
. $this->proxyMarker
|
||||
@@ -91,7 +93,7 @@ final class ClassNameInflector implements ClassNameInflectorInterface
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function isProxyClassName($className)
|
||||
public function isProxyClassName(string $className) : bool
|
||||
{
|
||||
return false !== strrpos($className, $this->proxyMarker);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Inflector;
|
||||
|
||||
/**
|
||||
@@ -38,7 +40,7 @@ interface ClassNameInflectorInterface
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUserClassName($className);
|
||||
public function getUserClassName(string $className) : string;
|
||||
|
||||
/**
|
||||
* Retrieve the class name of the proxy for the given user-defined class name
|
||||
@@ -48,7 +50,7 @@ interface ClassNameInflectorInterface
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getProxyClassName($className, array $options = array());
|
||||
public function getProxyClassName(string $className, array $options = []) : string;
|
||||
|
||||
/**
|
||||
* Retrieve whether the provided class name is a proxy
|
||||
@@ -57,5 +59,5 @@ interface ClassNameInflectorInterface
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isProxyClassName($className);
|
||||
public function isProxyClassName(string $className) : bool;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Inflector\Util;
|
||||
|
||||
/**
|
||||
@@ -34,7 +36,7 @@ class ParameterEncoder
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function encodeParameters(array $parameters)
|
||||
public function encodeParameters(array $parameters) : string
|
||||
{
|
||||
return base64_encode(serialize($parameters));
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Inflector\Util;
|
||||
|
||||
/**
|
||||
@@ -33,7 +35,7 @@ class ParameterHasher
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function hashParameters(array $parameters)
|
||||
public function hashParameters(array $parameters) : string
|
||||
{
|
||||
return md5(serialize($parameters));
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Proxy;
|
||||
|
||||
/**
|
||||
@@ -34,7 +36,7 @@ interface AccessInterceptorInterface extends ProxyInterface
|
||||
* A prefix interceptor should have a signature like following:
|
||||
*
|
||||
* <code>
|
||||
* $prefixInterceptor = function ($proxy, $instance, $method, $params, & $returnEarly) {};
|
||||
* $interceptor = function ($proxy, $instance, string $method, array $params, & $returnEarly) {};
|
||||
* </code>
|
||||
*
|
||||
* @param string $methodName name of the intercepted method
|
||||
@@ -42,7 +44,7 @@ interface AccessInterceptorInterface extends ProxyInterface
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setMethodPrefixInterceptor($methodName, \Closure $prefixInterceptor = null);
|
||||
public function setMethodPrefixInterceptor(string $methodName, \Closure $prefixInterceptor = null);
|
||||
|
||||
/**
|
||||
* Set or remove the suffix interceptor for a method
|
||||
@@ -52,7 +54,7 @@ interface AccessInterceptorInterface extends ProxyInterface
|
||||
* A prefix interceptor should have a signature like following:
|
||||
*
|
||||
* <code>
|
||||
* $suffixInterceptor = function ($proxy, $instance, $method, $params, $returnValue, & $returnEarly) {};
|
||||
* $interceptor = function ($proxy, $instance, string $method, array $params, $returnValue, & $returnEarly) {};
|
||||
* </code>
|
||||
*
|
||||
* @param string $methodName name of the intercepted method
|
||||
@@ -60,5 +62,5 @@ interface AccessInterceptorInterface extends ProxyInterface
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setMethodSuffixInterceptor($methodName, \Closure $suffixInterceptor = null);
|
||||
public function setMethodSuffixInterceptor(string $methodName, \Closure $suffixInterceptor = null);
|
||||
}
|
||||
|
||||
31
vendor/ocramius/proxy-manager/src/ProxyManager/Proxy/AccessInterceptorValueHolderInterface.php
vendored
Normal file
31
vendor/ocramius/proxy-manager/src/ProxyManager/Proxy/AccessInterceptorValueHolderInterface.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?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\Proxy;
|
||||
|
||||
/**
|
||||
* Aggregates AccessInterceptor and ValueHolderInterface, mostly for return type hinting
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*/
|
||||
interface AccessInterceptorValueHolderInterface extends AccessInterceptorInterface, ValueHolderInterface
|
||||
{
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Proxy\Exception;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Proxy;
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Proxy;
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Proxy;
|
||||
|
||||
/**
|
||||
@@ -34,7 +36,7 @@ interface LazyLoadingInterface extends ProxyInterface
|
||||
* An initializer should have a signature like following:
|
||||
*
|
||||
* <code>
|
||||
* $initializer = function (& $wrappedObject, $proxy, $method, $parameters, & $initializer) {};
|
||||
* $initializer = function (& $wrappedObject, $proxy, string $method, array $parameters, & $initializer) {};
|
||||
* </code>
|
||||
*
|
||||
* @param \Closure|null $initializer
|
||||
@@ -53,12 +55,12 @@ interface LazyLoadingInterface extends ProxyInterface
|
||||
*
|
||||
* @return bool true if the proxy could be initialized
|
||||
*/
|
||||
public function initializeProxy();
|
||||
public function initializeProxy() : bool;
|
||||
|
||||
/**
|
||||
* Retrieves current initialization status of the proxy
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isProxyInitialized();
|
||||
public function isProxyInitialized() : bool;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Proxy;
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Proxy;
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Proxy;
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Proxy;
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Proxy;
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Proxy;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user