Actualización

This commit is contained in:
Xes
2025-04-10 12:24:57 +02:00
parent 8969cc929d
commit 45420b6f0d
39760 changed files with 4303286 additions and 0 deletions

View File

@@ -0,0 +1,72 @@
<?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\Autoloader;
use ProxyManager\FileLocator\FileLocatorInterface;
use ProxyManager\Inflector\ClassNameInflectorInterface;
/**
* {@inheritDoc}
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class Autoloader implements AutoloaderInterface
{
/**
* @var \ProxyManager\FileLocator\FileLocatorInterface
*/
protected $fileLocator;
/**
* @var \ProxyManager\Inflector\ClassNameInflectorInterface
*/
protected $classNameInflector;
/**
* @param \ProxyManager\FileLocator\FileLocatorInterface $fileLocator
* @param \ProxyManager\Inflector\ClassNameInflectorInterface $classNameInflector
*/
public function __construct(FileLocatorInterface $fileLocator, ClassNameInflectorInterface $classNameInflector)
{
$this->fileLocator = $fileLocator;
$this->classNameInflector = $classNameInflector;
}
/**
* {@inheritDoc}
*/
public function __invoke(string $className) : bool
{
if (class_exists($className, false) || ! $this->classNameInflector->isProxyClassName($className)) {
return false;
}
$file = $this->fileLocator->getProxyFileName($className);
if (! file_exists($file)) {
return false;
}
/* @noinspection PhpIncludeInspection */
return (bool) require_once $file;
}
}

View File

@@ -0,0 +1,39 @@
<?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\Autoloader;
/**
* Basic autoloader utilities required to work with proxy files
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
interface AutoloaderInterface
{
/**
* Callback to allow the object to be handled as autoloader - tries to autoload the given class name
*
* @param string $className
*
* @return bool
*/
public function __invoke(string $className) : bool;
}

View File

@@ -0,0 +1,214 @@
<?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;
use ProxyManager\Autoloader\Autoloader;
use ProxyManager\Autoloader\AutoloaderInterface;
use ProxyManager\FileLocator\FileLocator;
use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy;
use ProxyManager\GeneratorStrategy\GeneratorStrategyInterface;
use ProxyManager\Inflector\ClassNameInflector;
use ProxyManager\Inflector\ClassNameInflectorInterface;
use ProxyManager\Signature\ClassSignatureGenerator;
use ProxyManager\Signature\ClassSignatureGeneratorInterface;
use ProxyManager\Signature\SignatureChecker;
use ProxyManager\Signature\SignatureCheckerInterface;
use ProxyManager\Signature\SignatureGenerator;
use ProxyManager\Signature\SignatureGeneratorInterface;
/**
* Base configuration class for the proxy manager - serves as micro disposable DIC/facade
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class Configuration
{
const DEFAULT_PROXY_NAMESPACE = 'ProxyManagerGeneratedProxy';
/**
* @var string|null
*/
protected $proxiesTargetDir;
/**
* @var string
*/
protected $proxiesNamespace = self::DEFAULT_PROXY_NAMESPACE;
/**
* @var GeneratorStrategyInterface|null
*/
protected $generatorStrategy;
/**
* @var callable|null
*/
protected $proxyAutoloader;
/**
* @var ClassNameInflectorInterface|null
*/
protected $classNameInflector;
/**
* @var SignatureGeneratorInterface|null
*/
protected $signatureGenerator;
/**
* @var SignatureCheckerInterface|null
*/
protected $signatureChecker;
/**
* @var ClassSignatureGeneratorInterface|null
*/
protected $classSignatureGenerator;
/**
* @param AutoloaderInterface $proxyAutoloader
*
* @return void
*/
public function setProxyAutoloader(AutoloaderInterface $proxyAutoloader)
{
$this->proxyAutoloader = $proxyAutoloader;
}
public function getProxyAutoloader() : AutoloaderInterface
{
return $this->proxyAutoloader
?: $this->proxyAutoloader = new Autoloader(
new FileLocator($this->getProxiesTargetDir()),
$this->getClassNameInflector()
);
}
/**
* @param string $proxiesNamespace
*
* @return void
*/
public function setProxiesNamespace(string $proxiesNamespace)
{
$this->proxiesNamespace = $proxiesNamespace;
}
public function getProxiesNamespace() : string
{
return $this->proxiesNamespace;
}
/**
* @param string $proxiesTargetDir
*
* @return void
*/
public function setProxiesTargetDir(string $proxiesTargetDir)
{
$this->proxiesTargetDir = $proxiesTargetDir;
}
public function getProxiesTargetDir() : string
{
return $this->proxiesTargetDir ?: $this->proxiesTargetDir = sys_get_temp_dir();
}
/**
* @param GeneratorStrategyInterface $generatorStrategy
*
* @return void
*/
public function setGeneratorStrategy(GeneratorStrategyInterface $generatorStrategy)
{
$this->generatorStrategy = $generatorStrategy;
}
public function getGeneratorStrategy() : GeneratorStrategyInterface
{
return $this->generatorStrategy
?: $this->generatorStrategy = new EvaluatingGeneratorStrategy();
}
/**
* @param ClassNameInflectorInterface $classNameInflector
*
* @return void
*/
public function setClassNameInflector(ClassNameInflectorInterface $classNameInflector)
{
$this->classNameInflector = $classNameInflector;
}
public function getClassNameInflector() : ClassNameInflectorInterface
{
return $this->classNameInflector
?: $this->classNameInflector = new ClassNameInflector($this->getProxiesNamespace());
}
/**
* @param SignatureGeneratorInterface $signatureGenerator
*
* @return void
*/
public function setSignatureGenerator(SignatureGeneratorInterface $signatureGenerator)
{
$this->signatureGenerator = $signatureGenerator;
}
public function getSignatureGenerator() : SignatureGeneratorInterface
{
return $this->signatureGenerator ?: $this->signatureGenerator = new SignatureGenerator();
}
/**
* @param SignatureCheckerInterface $signatureChecker
*
* @return void
*/
public function setSignatureChecker(SignatureCheckerInterface $signatureChecker)
{
$this->signatureChecker = $signatureChecker;
}
public function getSignatureChecker() : SignatureCheckerInterface
{
return $this->signatureChecker
?: $this->signatureChecker = new SignatureChecker($this->getSignatureGenerator());
}
/**
* @param ClassSignatureGeneratorInterface $classSignatureGenerator
*
* @return void
*/
public function setClassSignatureGenerator(ClassSignatureGeneratorInterface $classSignatureGenerator)
{
$this->classSignatureGenerator = $classSignatureGenerator;
}
public function getClassSignatureGenerator() : ClassSignatureGeneratorInterface
{
return $this->classSignatureGenerator
?: new ClassSignatureGenerator($this->getSignatureGenerator());
}
}

View File

@@ -0,0 +1,39 @@
<?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\Exception;
use BadMethodCallException;
/**
* Exception for forcefully disabled methods
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class DisabledMethodException extends BadMethodCallException implements ExceptionInterface
{
const NAME = __CLASS__;
public static function disabledMethod(string $method) : self
{
return new self(sprintf('Method "%s" is forcefully disabled', $method));
}
}

View 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\Exception;
/**
* Base exception class for the proxy manager
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
interface ExceptionInterface
{
}

View File

@@ -0,0 +1,62 @@
<?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\Exception;
use UnexpectedValueException;
/**
* Exception for non writable files
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class FileNotWritableException extends UnexpectedValueException implements ExceptionInterface
{
public static function fromInvalidMoveOperation(string $fromPath, string $toPath) : self
{
return new self(sprintf(
'Could not move file "%s" to location "%s": '
. 'either the source file is not readable, or the destination is not writable',
$fromPath,
$toPath
));
}
public static function fromNonWritableLocation($path) : self
{
$messages = [];
$destination = realpath($path);
if (! $destination) {
$messages[] = 'path does not exist';
}
if ($destination && ! is_file($destination)) {
$messages[] = 'exists and is not a file';
}
if ($destination && ! is_writable($destination)) {
$messages[] = 'is not writable';
}
return new self(sprintf('Could not write to path "%s": %s', $path, implode(', ', $messages)));
}
}

View File

@@ -0,0 +1,66 @@
<?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\Exception;
use InvalidArgumentException;
use ReflectionClass;
use ReflectionMethod;
/**
* Exception for invalid proxied classes
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class InvalidProxiedClassException extends InvalidArgumentException implements ExceptionInterface
{
public static function interfaceNotSupported(ReflectionClass $reflection) : self
{
return new self(sprintf('Provided interface "%s" cannot be proxied', $reflection->getName()));
}
public static function finalClassNotSupported(ReflectionClass $reflection) : self
{
return new self(sprintf('Provided class "%s" is final and cannot be proxied', $reflection->getName()));
}
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",
$reflection->getName(),
implode(
"\n",
array_map(
function (ReflectionMethod $reflectionMethod) : string {
return $reflectionMethod->getDeclaringClass()->getName() . '::' . $reflectionMethod->getName();
},
array_filter(
$reflection->getMethods(),
function (ReflectionMethod $method) : bool {
return $method->isAbstract() && $method->isProtected();
}
)
)
)
));
}
}

View File

@@ -0,0 +1,37 @@
<?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\Exception;
use InvalidArgumentException;
/**
* Exception for invalid directories
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class InvalidProxyDirectoryException extends InvalidArgumentException implements ExceptionInterface
{
public static function proxyDirectoryNotFound(string $directory) : self
{
return new self(sprintf('Provided directory "%s" does not exist', $directory));
}
}

View File

@@ -0,0 +1,44 @@
<?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\Exception;
use LogicException;
use ReflectionProperty;
/**
* Exception for invalid proxied classes
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class UnsupportedProxiedClassException extends LogicException implements ExceptionInterface
{
public static function unsupportedLocalizedReflectionProperty(ReflectionProperty $property) : self
{
return new self(
sprintf(
'Provided reflection property "%s" of class "%s" is private and cannot be localized in PHP 5.3',
$property->getName(),
$property->getDeclaringClass()->getName()
)
);
}
}

View File

@@ -0,0 +1,129 @@
<?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\Factory;
use ProxyManager\Configuration;
use ProxyManager\Generator\ClassGenerator;
use ProxyManager\ProxyGenerator\ProxyGeneratorInterface;
use ProxyManager\Version;
use ReflectionClass;
/**
* Base factory common logic
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
abstract class AbstractBaseFactory
{
/**
* @var \ProxyManager\Configuration
*/
protected $configuration;
/**
* Cached checked class names
*
* @var string[]
*/
private $checkedClasses = [];
/**
* @param \ProxyManager\Configuration $configuration
*/
public function __construct(Configuration $configuration = null)
{
$this->configuration = $configuration ?: new Configuration();
}
/**
* Generate a proxy from a class name
*
* @param string $className
* @param mixed[] $proxyOptions
*
* @return string proxy class name
*/
protected function generateProxy(string $className, array $proxyOptions = []) : string
{
if (isset($this->checkedClasses[$className])) {
return $this->checkedClasses[$className];
}
$proxyParameters = [
'className' => $className,
'factory' => get_class($this),
'proxyManagerVersion' => Version::getVersion(),
];
$proxyClassName = $this
->configuration
->getClassNameInflector()
->getProxyClassName($className, $proxyParameters);
if (! class_exists($proxyClassName)) {
$this->generateProxyClass(
$proxyClassName,
$className,
$proxyParameters,
$proxyOptions
);
}
$this
->configuration
->getSignatureChecker()
->checkSignature(new ReflectionClass($proxyClassName), $proxyParameters);
return $this->checkedClasses[$className] = $proxyClassName;
}
abstract protected function getGenerator() : ProxyGeneratorInterface;
/**
* Generates the provided `$proxyClassName` from the given `$className` and `$proxyParameters`
*
* @param string $proxyClassName
* @param string $className
* @param array $proxyParameters
* @param mixed[] $proxyOptions
*
* @return void
*/
private function generateProxyClass(
string $proxyClassName,
string $className,
array $proxyParameters,
array $proxyOptions = []
) {
$className = $this->configuration->getClassNameInflector()->getUserClassName($className);
$phpClass = new ClassGenerator($proxyClassName);
$this->getGenerator()->generate(new ReflectionClass($className), $phpClass, $proxyOptions);
$phpClass = $this->configuration->getClassSignatureGenerator()->addSignature($phpClass, $proxyParameters);
$this->configuration->getGeneratorStrategy()->generate($phpClass, $proxyOptions);
$autoloader = $this->configuration->getProxyAutoloader();
$autoloader($proxyClassName);
}
}

View File

@@ -0,0 +1,66 @@
<?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\Factory;
use ProxyManager\Proxy\AccessInterceptorInterface;
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizerGenerator;
use ProxyManager\ProxyGenerator\ProxyGeneratorInterface;
/**
* Factory responsible of producing proxy objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class AccessInterceptorScopeLocalizerFactory extends AbstractBaseFactory
{
/**
* @var \ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizerGenerator|null
*/
private $generator;
/**
* @param object $instance the object to be localized within the access interceptor
* @param \Closure[] $prefixInterceptors an array (indexed by method name) of interceptor closures to be called
* before method logic is executed
* @param \Closure[] $suffixInterceptors an array (indexed by method name) of interceptor closures to be called
* after method logic is executed
*
* @return AccessInterceptorInterface
*/
public function createProxy(
$instance,
array $prefixInterceptors = [],
array $suffixInterceptors = []
) : AccessInterceptorInterface {
$proxyClassName = $this->generateProxy(get_class($instance));
return $proxyClassName::staticProxyConstructor($instance, $prefixInterceptors, $suffixInterceptors);
}
/**
* {@inheritDoc}
*/
protected function getGenerator() : ProxyGeneratorInterface
{
return $this->generator ?: $this->generator = new AccessInterceptorScopeLocalizerGenerator();
}
}

View File

@@ -0,0 +1,66 @@
<?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\Factory;
use ProxyManager\Proxy\AccessInterceptorValueHolderInterface;
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolderGenerator;
use ProxyManager\ProxyGenerator\ProxyGeneratorInterface;
/**
* Factory responsible of producing proxy objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class AccessInterceptorValueHolderFactory extends AbstractBaseFactory
{
/**
* @var \ProxyManager\ProxyGenerator\AccessInterceptorValueHolderGenerator|null
*/
private $generator;
/**
* @param object $instance the object to be wrapped within the value holder
* @param \Closure[] $prefixInterceptors an array (indexed by method name) of interceptor closures to be called
* before method logic is executed
* @param \Closure[] $suffixInterceptors an array (indexed by method name) of interceptor closures to be called
* after method logic is executed
*
* @return AccessInterceptorValueHolderInterface
*/
public function createProxy(
$instance,
array $prefixInterceptors = [],
array $suffixInterceptors = []
) : AccessInterceptorValueHolderInterface {
$proxyClassName = $this->generateProxy(get_class($instance));
return $proxyClassName::staticProxyConstructor($instance, $prefixInterceptors, $suffixInterceptors);
}
/**
* {@inheritDoc}
*/
protected function getGenerator() : ProxyGeneratorInterface
{
return $this->generator ?: $this->generator = new AccessInterceptorValueHolderGenerator();
}
}

View File

@@ -0,0 +1,96 @@
<?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\Factory;
use Closure;
use ProxyManager\Proxy\GhostObjectInterface;
use ProxyManager\ProxyGenerator\LazyLoadingGhostGenerator;
use ProxyManager\ProxyGenerator\ProxyGeneratorInterface;
/**
* Factory responsible of producing ghost instances
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class LazyLoadingGhostFactory extends AbstractBaseFactory
{
/**
* @var \ProxyManager\ProxyGenerator\LazyLoadingGhostGenerator|null
*/
private $generator;
/**
* {@inheritDoc}
*/
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
*/
public function createProxy(
string $className,
Closure $initializer,
array $proxyOptions = []
) : GhostObjectInterface {
$proxyClassName = $this->generateProxy($className, $proxyOptions);
return $proxyClassName::staticProxyConstructor($initializer);
}
}

View File

@@ -0,0 +1,57 @@
<?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\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
*/
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() : ProxyGeneratorInterface
{
return $this->generator ?: $this->generator = new LazyLoadingValueHolderGenerator();
}
}

View File

@@ -0,0 +1,60 @@
<?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\Factory;
use ProxyManager\Proxy\NullObjectInterface;
use ProxyManager\ProxyGenerator\NullObjectGenerator;
use ProxyManager\ProxyGenerator\ProxyGeneratorInterface;
/**
* Factory responsible of producing proxy objects
*
* @author Vincent Blanchon <blanchon.vincent@gmail.com>
* @license MIT
*/
class NullObjectFactory extends AbstractBaseFactory
{
/**
* @var \ProxyManager\ProxyGenerator\NullObjectGenerator|null
*/
private $generator;
/**
* @param object $instanceOrClassName the object to be wrapped or interface to transform to null object
*
* @return NullObjectInterface
*/
public function createProxy($instanceOrClassName) : NullObjectInterface
{
$className = is_object($instanceOrClassName) ? get_class($instanceOrClassName) : $instanceOrClassName;
$proxyClassName = $this->generateProxy($className);
return $proxyClassName::staticProxyConstructor();
}
/**
* {@inheritDoc}
*/
protected function getGenerator() : ProxyGeneratorInterface
{
return $this->generator ?: $this->generator = new NullObjectGenerator();
}
}

View File

@@ -0,0 +1,83 @@
<?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\Factory\RemoteObject\Adapter;
use ProxyManager\Factory\RemoteObject\AdapterInterface;
use Zend\Server\Client;
/**
* Remote Object base adapter
*
* @author Vincent Blanchon <blanchon.vincent@gmail.com>
* @license MIT
*/
abstract class BaseAdapter implements AdapterInterface
{
/**
* Adapter client
*
* @var \Zend\Server\Client
*/
protected $client;
/**
* Service name mapping
*
* @var string[]
*/
protected $map = [];
/**
* Constructor
*
* @param Client $client
* @param array $map map of service names to their aliases
*/
public function __construct(Client $client, array $map = [])
{
$this->client = $client;
$this->map = $map;
}
/**
* {@inheritDoc}
*/
public function call(string $wrappedClass, string $method, array $params = [])
{
$serviceName = $this->getServiceName($wrappedClass, $method);
if (isset($this->map[$serviceName])) {
$serviceName = $this->map[$serviceName];
}
return $this->client->call($serviceName, $params);
}
/**
* Get the service name will be used by the adapter
*
* @param string $wrappedClass
* @param string $method
*
* @return string Service name
*/
abstract protected function getServiceName(string $wrappedClass, string $method) : string;
}

View File

@@ -0,0 +1,38 @@
<?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\Factory\RemoteObject\Adapter;
/**
* Remote Object JSON RPC adapter
*
* @author Vincent Blanchon <blanchon.vincent@gmail.com>
* @license MIT
*/
class JsonRpc extends BaseAdapter
{
/**
* {@inheritDoc}
*/
protected function getServiceName(string $wrappedClass, string $method) : string
{
return $wrappedClass . '.' . $method;
}
}

View File

@@ -0,0 +1,38 @@
<?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\Factory\RemoteObject\Adapter;
/**
* Remote Object SOAP adapter
*
* @author Vincent Blanchon <blanchon.vincent@gmail.com>
* @license MIT
*/
class Soap extends BaseAdapter
{
/**
* {@inheritDoc}
*/
protected function getServiceName(string $wrappedClass, string $method) : string
{
return $method;
}
}

View File

@@ -0,0 +1,38 @@
<?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\Factory\RemoteObject\Adapter;
/**
* Remote Object XML RPC adapter
*
* @author Vincent Blanchon <blanchon.vincent@gmail.com>
* @license MIT
*/
class XmlRpc extends BaseAdapter
{
/**
* {@inheritDoc}
*/
protected function getServiceName(string $wrappedClass, string $method) : string
{
return $wrappedClass . '.' . $method;
}
}

View File

@@ -0,0 +1,39 @@
<?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\Factory\RemoteObject;
/**
* Remote Object adapter interface
*
* @author Vincent Blanchon <blanchon.vincent@gmail.com>
* @license MIT
*/
interface AdapterInterface
{
/**
* Call remote object
*
* @param string $wrappedClass
* @param string $method
* @param array $params
*/
public function call(string $wrappedClass, string $method, array $params = []);
}

View File

@@ -0,0 +1,81 @@
<?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\Factory;
use ProxyManager\Configuration;
use ProxyManager\Factory\RemoteObject\AdapterInterface;
use ProxyManager\Proxy\RemoteObjectInterface;
use ProxyManager\ProxyGenerator\ProxyGeneratorInterface;
use ProxyManager\ProxyGenerator\RemoteObjectGenerator;
/**
* Factory responsible of producing remote proxy objects
*
* @author Vincent Blanchon <blanchon.vincent@gmail.com>
* @license MIT
*/
class RemoteObjectFactory extends AbstractBaseFactory
{
/**
* @var AdapterInterface
*/
protected $adapter;
/**
* @var \ProxyManager\ProxyGenerator\RemoteObjectGenerator|null
*/
private $generator;
/**
* {@inheritDoc}
*
* @param AdapterInterface $adapter
* @param Configuration $configuration
*/
public function __construct(AdapterInterface $adapter, Configuration $configuration = null)
{
parent::__construct($configuration);
$this->adapter = $adapter;
}
/**
* @param string|object $instanceOrClassName
*
* @return RemoteObjectInterface
*/
public function createProxy($instanceOrClassName) : RemoteObjectInterface
{
$proxyClassName = $this->generateProxy(
is_object($instanceOrClassName) ? get_class($instanceOrClassName) : $instanceOrClassName
);
return $proxyClassName::staticProxyConstructor($this->adapter);
}
/**
* {@inheritDoc}
*/
protected function getGenerator() : ProxyGeneratorInterface
{
return $this->generator ?: $this->generator = new RemoteObjectGenerator();
}
}

View File

@@ -0,0 +1,59 @@
<?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\FileLocator;
use ProxyManager\Exception\InvalidProxyDirectoryException;
/**
* {@inheritDoc}
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class FileLocator implements FileLocatorInterface
{
/**
* @var string
*/
protected $proxiesDirectory;
/**
* @param string $proxiesDirectory
*
* @throws \ProxyManager\Exception\InvalidProxyDirectoryException
*/
public function __construct(string $proxiesDirectory)
{
$this->proxiesDirectory = realpath($proxiesDirectory);
if (false === $this->proxiesDirectory) {
throw InvalidProxyDirectoryException::proxyDirectoryNotFound($proxiesDirectory);
}
}
/**
* {@inheritDoc}
*/
public function getProxyFileName(string $className) : string
{
return $this->proxiesDirectory . DIRECTORY_SEPARATOR . str_replace('\\', '', $className) . '.php';
}
}

View File

@@ -0,0 +1,39 @@
<?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\FileLocator;
/**
* Basic autoloader utilities required to work with proxy files
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
interface FileLocatorInterface
{
/**
* Retrieves the file name for the given proxy
*
* @param string $className
*
* @return string
*/
public function getProxyFileName(string $className) : string;
}

View File

@@ -0,0 +1,56 @@
<?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;
use Zend\Code\Generator\ClassGenerator as ZendClassGenerator;
/**
* Class generator that ensures that interfaces/classes that are implemented/extended are FQCNs
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class ClassGenerator extends ZendClassGenerator
{
/**
* {@inheritDoc}
*/
public function setExtendedClass($extendedClass) : self
{
if ($extendedClass) {
$extendedClass = '\\' . trim($extendedClass, '\\');
}
return parent::setExtendedClass($extendedClass);
}
/**
* {@inheritDoc}
*/
public function setImplementedInterfaces(array $interfaces) : self
{
foreach ($interfaces as & $interface) {
$interface = '\\' . trim($interface, '\\');
}
return parent::setImplementedInterfaces($interfaces);
}
}

View File

@@ -0,0 +1,54 @@
<?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;
use ReflectionClass;
/**
* Method generator for magic methods
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MagicMethodGenerator extends MethodGenerator
{
/**
* @param ReflectionClass $originalClass
* @param string $name
* @param array $parameters
*/
public function __construct(ReflectionClass $originalClass, string $name, array $parameters = [])
{
parent::__construct(
$name,
$parameters,
static::FLAG_PUBLIC,
null,
$originalClass->hasMethod($name) ? '{@inheritDoc}' : null
);
$this->setReturnsReference(strtolower($name) === '__get');
if ($originalClass->hasMethod($name)) {
$this->setReturnsReference($originalClass->getMethod($name)->returnsReference());
}
}
}

View File

@@ -0,0 +1,45 @@
<?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;
use Zend\Code\Generator\MethodGenerator as ZendMethodGenerator;
use Zend\Code\Reflection\MethodReflection;
/**
* Method generator that fixes minor quirks in ZF2's method generator
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MethodGenerator extends ZendMethodGenerator
{
/**
* {@inheritDoc}
*/
public static function fromReflection(MethodReflection $reflectionMethod) : self
{
$method = parent::fromReflection($reflectionMethod);
$method->setInterface(false);
return $method;
}
}

View File

@@ -0,0 +1,50 @@
<?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;
use ReflectionClass;
use Zend\Code\Generator\ClassGenerator;
use Zend\Code\Generator\MethodGenerator;
/**
* Util class to help to generate code
*
* @author Jefersson Nathan <malukenho@phpse.net>
* @license MIT
*/
final class ClassGeneratorUtils
{
public static function addMethodIfNotFinal(
ReflectionClass $originalClass,
ClassGenerator $classGenerator,
MethodGenerator $generatedMethod
) : bool {
$methodName = $generatedMethod->getName();
if ($originalClass->hasMethod($methodName) && $originalClass->getMethod($methodName)->isFinal()) {
return false;
}
$classGenerator->addMethodFromGenerator($generatedMethod);
return true;
}
}

View File

@@ -0,0 +1,55 @@
<?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 capable of generating unique
* valid class/property/method identifiers
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
abstract class UniqueIdentifierGenerator
{
const VALID_IDENTIFIER_FORMAT = '/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]+$/';
const DEFAULT_IDENTIFIER = 'g';
/**
* Generates a valid unique identifier from the given name
*
* @param string $name
*
* @return string
*/
public static function getIdentifier(string $name) : string
{
return str_replace(
'.',
'',
uniqid(
preg_match(static::VALID_IDENTIFIER_FORMAT, $name)
? $name
: static::DEFAULT_IDENTIFIER,
true
)
);
}
}

View File

@@ -0,0 +1,40 @@
<?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\GeneratorStrategy;
use Zend\Code\Generator\ClassGenerator;
/**
* Generator strategy that generates the class body
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class BaseGeneratorStrategy implements GeneratorStrategyInterface
{
/**
* {@inheritDoc}
*/
public function generate(ClassGenerator $classGenerator) : string
{
return $classGenerator->generate();
}
}

View File

@@ -0,0 +1,72 @@
<?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\GeneratorStrategy;
use Zend\Code\Generator\ClassGenerator;
/**
* Generator strategy that produces the code and evaluates it at runtime
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class EvaluatingGeneratorStrategy implements GeneratorStrategyInterface
{
/**
* @var bool flag indicating whether {@see eval} can be used
*/
private $canEval = true;
/**
* Constructor
*/
public function __construct()
{
$this->canEval = ! ini_get('suhosin.executor.disable_eval');
}
/**
* Evaluates the generated code before returning it
*
* {@inheritDoc}
*/
public function generate(ClassGenerator $classGenerator) : string
{
$code = $classGenerator->generate();
if (! $this->canEval) {
// @codeCoverageIgnoreStart
$fileName = sys_get_temp_dir() . '/EvaluatingGeneratorStrategy.php.tmp.' . uniqid('', true);
file_put_contents($fileName, "<?php\n" . $code);
/* @noinspection PhpIncludeInspection */
require $fileName;
unlink($fileName);
return $code;
// @codeCoverageIgnoreEnd
}
eval($code);
return $code;
}
}

View File

@@ -0,0 +1,107 @@
<?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\GeneratorStrategy;
use ProxyManager\Exception\FileNotWritableException;
use ProxyManager\FileLocator\FileLocatorInterface;
use Zend\Code\Generator\ClassGenerator;
/**
* Generator strategy that writes the generated classes to disk while generating them
*
* {@inheritDoc}
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class FileWriterGeneratorStrategy implements GeneratorStrategyInterface
{
/**
* @var \ProxyManager\FileLocator\FileLocatorInterface
*/
protected $fileLocator;
/**
* @var callable
*/
private $emptyErrorHandler;
/**
* @param \ProxyManager\FileLocator\FileLocatorInterface $fileLocator
*/
public function __construct(FileLocatorInterface $fileLocator)
{
$this->fileLocator = $fileLocator;
$this->emptyErrorHandler = function () {
};
}
/**
* Write generated code to disk and return the class code
*
* {@inheritDoc}
*/
public function generate(ClassGenerator $classGenerator) : string
{
$className = trim($classGenerator->getNamespaceName(), '\\')
. '\\' . trim($classGenerator->getName(), '\\');
$generatedCode = $classGenerator->generate();
$fileName = $this->fileLocator->getProxyFileName($className);
set_error_handler($this->emptyErrorHandler);
try {
$this->writeFile("<?php\n\n" . $generatedCode, $fileName);
} catch (FileNotWritableException $fileNotWritable) {
throw $fileNotWritable;
} finally {
restore_error_handler();
}
return $generatedCode;
}
/**
* Writes the source file in such a way that race conditions are avoided when the same file is written
* multiple times in a short time period
*
* @param string $source
* @param string $location
*
* @return void
*
* @throws FileNotWritableException
*/
private function writeFile(string $source, string $location)
{
$tmpFileName = $location . '.' . uniqid('', true);
if (! file_put_contents($tmpFileName, $source)) {
throw FileNotWritableException::fromNonWritableLocation($tmpFileName);
}
if (! rename($tmpFileName, $location)) {
unlink($tmpFileName);
throw FileNotWritableException::fromInvalidMoveOperation($tmpFileName, $location);
}
}
}

View 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\GeneratorStrategy;
use Zend\Code\Generator\ClassGenerator;
/**
* Generator strategy interface - defines basic behavior of class generators
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
interface GeneratorStrategyInterface
{
/**
* Generate the provided class
*
* @param ClassGenerator $classGenerator
*
* @return string the class body
*/
public function generate(ClassGenerator $classGenerator) : string;
}

View File

@@ -0,0 +1,100 @@
<?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\Inflector;
use ProxyManager\Inflector\Util\ParameterHasher;
/**
* {@inheritDoc}
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
final class ClassNameInflector implements ClassNameInflectorInterface
{
/**
* @var string
*/
protected $proxyNamespace;
/**
* @var int
*/
private $proxyMarkerLength;
/**
* @var string
*/
private $proxyMarker;
/**
* @var \ProxyManager\Inflector\Util\ParameterHasher
*/
private $parameterHasher;
/**
* @param string $proxyNamespace
*/
public function __construct(string $proxyNamespace)
{
$this->proxyNamespace = $proxyNamespace;
$this->proxyMarker = '\\' . static::PROXY_MARKER . '\\';
$this->proxyMarkerLength = strlen($this->proxyMarker);
$this->parameterHasher = new ParameterHasher();
}
/**
* {@inheritDoc}
*/
public function getUserClassName(string $className) : string
{
$className = ltrim($className, '\\');
if (false === $position = strrpos($className, $this->proxyMarker)) {
return $className;
}
return substr(
$className,
$this->proxyMarkerLength + $position,
strrpos($className, '\\') - ($position + $this->proxyMarkerLength)
);
}
/**
* {@inheritDoc}
*/
public function getProxyClassName(string $className, array $options = []) : string
{
return $this->proxyNamespace
. $this->proxyMarker
. $this->getUserClassName($className)
. '\\Generated' . $this->parameterHasher->hashParameters($options);
}
/**
* {@inheritDoc}
*/
public function isProxyClassName(string $className) : bool
{
return false !== strrpos($className, $this->proxyMarker);
}
}

View File

@@ -0,0 +1,63 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license.
*/
declare(strict_types=1);
namespace ProxyManager\Inflector;
/**
* Interface for a proxy- to user-class and user- to proxy-class name inflector
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
interface ClassNameInflectorInterface
{
/**
* Marker for proxy classes - classes containing this marker are considered proxies
*/
const PROXY_MARKER = '__PM__';
/**
* Retrieve the class name of a user-defined class
*
* @param string $className
*
* @return string
*/
public function getUserClassName(string $className) : string;
/**
* Retrieve the class name of the proxy for the given user-defined class name
*
* @param string $className
* @param array $options arbitrary options to be used for the generated class name
*
* @return string
*/
public function getProxyClassName(string $className, array $options = []) : string;
/**
* Retrieve whether the provided class name is a proxy
*
* @param string $className
*
* @return bool
*/
public function isProxyClassName(string $className) : bool;
}

View File

@@ -0,0 +1,43 @@
<?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\Inflector\Util;
/**
* Encodes parameters into a class-name safe string
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class ParameterEncoder
{
/**
* Converts the given parameters into a set of characters that are safe to
* use in a class name
*
* @param array $parameters
*
* @return string
*/
public function encodeParameters(array $parameters) : string
{
return base64_encode(serialize($parameters));
}
}

View File

@@ -0,0 +1,42 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license.
*/
declare(strict_types=1);
namespace ProxyManager\Inflector\Util;
/**
* Converts given parameters into a likely unique hash
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class ParameterHasher
{
/**
* Converts the given parameters into a likely-unique hash
*
* @param array $parameters
*
* @return string
*/
public function hashParameters(array $parameters) : string
{
return md5(serialize($parameters));
}
}

View File

@@ -0,0 +1,66 @@
<?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;
/**
* Access interceptor object marker
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
interface AccessInterceptorInterface extends ProxyInterface
{
/**
* Set or remove the prefix interceptor for a method
*
* @link https://github.com/Ocramius/ProxyManager/blob/master/docs/access-interceptor-value-holder.md
*
* A prefix interceptor should have a signature like following:
*
* <code>
* $interceptor = function ($proxy, $instance, string $method, array $params, & $returnEarly) {};
* </code>
*
* @param string $methodName name of the intercepted method
* @param \Closure|null $prefixInterceptor interceptor closure or null to unset the currently active interceptor
*
* @return void
*/
public function setMethodPrefixInterceptor(string $methodName, \Closure $prefixInterceptor = null);
/**
* Set or remove the suffix interceptor for a method
*
* @link https://github.com/Ocramius/ProxyManager/blob/master/docs/access-interceptor-value-holder.md
*
* A prefix interceptor should have a signature like following:
*
* <code>
* $interceptor = function ($proxy, $instance, string $method, array $params, $returnValue, & $returnEarly) {};
* </code>
*
* @param string $methodName name of the intercepted method
* @param \Closure|null $suffixInterceptor interceptor closure or null to unset the currently active interceptor
*
* @return void
*/
public function setMethodSuffixInterceptor(string $methodName, \Closure $suffixInterceptor = null);
}

View 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
{
}

View File

@@ -0,0 +1,33 @@
<?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\Exception;
use RuntimeException;
/**
* Remote object exception
*
* @author Vincent Blanchon <blanchon.vincent@gmail.com>
* @license MIT
*/
class RemoteObjectException extends RuntimeException
{
}

View 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;
/**
* Fallback value holder object marker
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
interface FallbackValueHolderInterface extends ProxyInterface
{
}

View 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;
/**
* Ghost object marker
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
interface GhostObjectInterface extends LazyLoadingInterface
{
}

View File

@@ -0,0 +1,66 @@
<?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;
/**
* Lazy loading object identifier
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
interface LazyLoadingInterface extends ProxyInterface
{
/**
* Set or unset the initializer for the proxy instance
*
* @link https://github.com/Ocramius/ProxyManager/blob/master/docs/lazy-loading-value-holder.md#lazy-initialization
*
* An initializer should have a signature like following:
*
* <code>
* $initializer = function (& $wrappedObject, $proxy, string $method, array $parameters, & $initializer) {};
* </code>
*
* @param \Closure|null $initializer
*
* @return mixed
*/
public function setProxyInitializer(\Closure $initializer = null);
/**
* @return \Closure|null
*/
public function getProxyInitializer();
/**
* Force initialization of the proxy
*
* @return bool true if the proxy could be initialized
*/
public function initializeProxy() : bool;
/**
* Retrieves current initialization status of the proxy
*
* @return bool
*/
public function isProxyInitialized() : bool;
}

View 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;
/**
* Null object marker
*
* @author Vincent Blanchon <blanchon.vincent@gmail.com>
* @license MIT
*/
interface NullObjectInterface extends ProxyInterface
{
}

View 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;
/**
* Base proxy marker
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
interface ProxyInterface
{
}

View 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;
/**
* Remote object marker
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
interface RemoteObjectInterface extends ProxyInterface
{
}

View 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;
/**
* Smart reference object marker
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
interface SmartReferenceInterface extends ProxyInterface
{
}

View File

@@ -0,0 +1,35 @@
<?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;
/**
* Value holder marker
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
interface ValueHolderInterface extends ProxyInterface
{
/**
* @return object|null the wrapped value
*/
public function getWrappedValueHolderValue();
}

View 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;
/**
* Virtual Proxy - a lazy initializing object wrapping around the proxied subject
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
interface VirtualProxyInterface extends LazyLoadingInterface, ValueHolderInterface
{
}

View File

@@ -0,0 +1,50 @@
<?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\AccessInterceptor\MethodGenerator;
use ProxyManager\Generator\MagicMethodGenerator;
use ProxyManager\ProxyGenerator\Util\Properties;
use ProxyManager\ProxyGenerator\Util\UnsetPropertiesGenerator;
use ReflectionClass;
/**
* Magic `__wakeup` for lazy loading value holder objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MagicWakeup extends MagicMethodGenerator
{
/**
* Constructor
*
* @param ReflectionClass $originalClass
*/
public function __construct(ReflectionClass $originalClass)
{
parent::__construct($originalClass, '__wakeup');
$this->setBody(UnsetPropertiesGenerator::generateSnippet(
Properties::fromReflectionClass($originalClass),
'this'
));
}
}

View File

@@ -0,0 +1,55 @@
<?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\AccessInterceptor\MethodGenerator;
use Closure;
use ProxyManager\Generator\MethodGenerator;
use Zend\Code\Generator\ParameterGenerator;
use Zend\Code\Generator\PropertyGenerator;
/**
* Implementation for {@see \ProxyManager\Proxy\AccessInterceptorInterface::setMethodPrefixInterceptor}
* for access interceptor objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class SetMethodPrefixInterceptor extends MethodGenerator
{
/**
* Constructor
*
* @param PropertyGenerator $prefixInterceptor
*/
public function __construct(PropertyGenerator $prefixInterceptor)
{
parent::__construct('setMethodPrefixInterceptor');
$interceptor = new ParameterGenerator('prefixInterceptor');
$interceptor->setType(Closure::class);
$interceptor->setDefaultValue(null);
$this->setParameter(new ParameterGenerator('methodName', 'string'));
$this->setParameter($interceptor);
$this->setDocblock('{@inheritDoc}');
$this->setBody('$this->' . $prefixInterceptor->getName() . '[$methodName] = $prefixInterceptor;');
}
}

View File

@@ -0,0 +1,55 @@
<?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\AccessInterceptor\MethodGenerator;
use Closure;
use ProxyManager\Generator\MethodGenerator;
use Zend\Code\Generator\ParameterGenerator;
use Zend\Code\Generator\PropertyGenerator;
/**
* Implementation for {@see \ProxyManager\Proxy\AccessInterceptorInterface::setMethodSuffixInterceptor}
* for access interceptor objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class SetMethodSuffixInterceptor extends MethodGenerator
{
/**
* Constructor
*
* @param PropertyGenerator $suffixInterceptor
*/
public function __construct(PropertyGenerator $suffixInterceptor)
{
parent::__construct('setMethodSuffixInterceptor');
$interceptor = new ParameterGenerator('suffixInterceptor');
$interceptor->setType(Closure::class);
$interceptor->setDefaultValue(null);
$this->setParameter(new ParameterGenerator('methodName', 'string'));
$this->setParameter($interceptor);
$this->setDocblock('{@inheritDoc}');
$this->setBody('$this->' . $suffixInterceptor->getName() . '[$methodName] = $suffixInterceptor;');
}
}

View File

@@ -0,0 +1,45 @@
<?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\AccessInterceptor\PropertyGenerator;
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
use Zend\Code\Generator\PropertyGenerator;
/**
* Property that contains the interceptor for operations to be executed before method execution
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MethodPrefixInterceptors extends PropertyGenerator
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct(UniqueIdentifierGenerator::getIdentifier('methodPrefixInterceptors'));
$this->setDefaultValue([]);
$this->setVisibility(self::VISIBILITY_PRIVATE);
$this->setDocblock('@var \\Closure[] map of interceptors to be called per-method before execution');
}
}

View File

@@ -0,0 +1,45 @@
<?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\AccessInterceptor\PropertyGenerator;
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
use Zend\Code\Generator\PropertyGenerator;
/**
* Property that contains the interceptor for operations to be executed after method execution
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MethodSuffixInterceptors extends PropertyGenerator
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct(UniqueIdentifierGenerator::getIdentifier('methodSuffixInterceptors'));
$this->setDefaultValue([]);
$this->setVisibility(self::VISIBILITY_PRIVATE);
$this->setDocblock('@var \\Closure[] map of interceptors to be called per-method after execution');
}
}

View File

@@ -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(
(empty($localizedProperties) ? '' : implode("\n\n", $localizedProperties) . "\n\n")
. '$this->' . $prefixInterceptors->getName() . " = \$prefixInterceptors;\n"
. '$this->' . $suffixInterceptors->getName() . " = \$suffixInterceptors;"
);
}
}

View File

@@ -0,0 +1,69 @@
<?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 ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\Util\InterceptorGenerator;
use Zend\Code\Generator\PropertyGenerator;
use Zend\Code\Reflection\MethodReflection;
/**
* Method with additional pre- and post- interceptor logic in the body
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class InterceptedMethod extends MethodGenerator
{
/**
* @param \Zend\Code\Reflection\MethodReflection $originalMethod
* @param \Zend\Code\Generator\PropertyGenerator $prefixInterceptors
* @param \Zend\Code\Generator\PropertyGenerator $suffixInterceptors
*
* @return self
*/
public static function generateMethod(
MethodReflection $originalMethod,
PropertyGenerator $prefixInterceptors,
PropertyGenerator $suffixInterceptors
) : self {
/* @var $method self */
$method = static::fromReflection($originalMethod);
$forwardedParams = [];
foreach ($originalMethod->getParameters() as $parameter) {
$forwardedParams[] = ($parameter->isVariadic() ? '...' : '') . '$' . $parameter->getName();
}
$method->setDocblock('{@inheritDoc}');
$method->setBody(
InterceptorGenerator::createInterceptedMethodBody(
'$returnValue = parent::'
. $originalMethod->getName() . '(' . implode(', ', $forwardedParams) . ');',
$method,
$prefixInterceptors,
$suffixInterceptors
)
);
return $method;
}
}

View File

@@ -0,0 +1,59 @@
<?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\MagicMethodGenerator;
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\Util\InterceptorGenerator;
use ReflectionClass;
use Zend\Code\Generator\PropertyGenerator;
/**
* Magic `__clone` for lazy loading ghost objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MagicClone extends MagicMethodGenerator
{
/**
* Constructor
*
* @param ReflectionClass $originalClass
* @param PropertyGenerator $prefixInterceptors
* @param PropertyGenerator $suffixInterceptors
*/
public function __construct(
ReflectionClass $originalClass,
PropertyGenerator $prefixInterceptors,
PropertyGenerator $suffixInterceptors
) {
parent::__construct($originalClass, '__clone');
$this->setBody(
InterceptorGenerator::createInterceptedMethodBody(
$originalClass->hasMethod('__clone') ? '$returnValue = parent::__clone();' : '$returnValue = null;',
$this,
$prefixInterceptors,
$suffixInterceptors
)
);
}
}

View File

@@ -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\AccessInterceptorScopeLocalizer\MethodGenerator;
use ProxyManager\Generator\MagicMethodGenerator;
use Zend\Code\Generator\ParameterGenerator;
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\Util\InterceptorGenerator;
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
use ReflectionClass;
use Zend\Code\Generator\PropertyGenerator;
/**
* Magic `__get` for lazy loading ghost objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MagicGet extends MagicMethodGenerator
{
/**
* @param ReflectionClass $originalClass
* @param PropertyGenerator $prefixInterceptors
* @param PropertyGenerator $suffixInterceptors
*/
public function __construct(
ReflectionClass $originalClass,
PropertyGenerator $prefixInterceptors,
PropertyGenerator $suffixInterceptors
) {
parent::__construct($originalClass, '__get', [new ParameterGenerator('name')]);
$override = $originalClass->hasMethod('__get');
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
if ($override) {
$callParent = '$returnValue = & parent::__get($name);';
} else {
$callParent = PublicScopeSimulator::getPublicAccessSimulationCode(
PublicScopeSimulator::OPERATION_GET,
'name',
null,
null,
'returnValue'
);
}
$this->setBody(
InterceptorGenerator::createInterceptedMethodBody(
$callParent,
$this,
$prefixInterceptors,
$suffixInterceptors
)
);
}
}

View File

@@ -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\AccessInterceptorScopeLocalizer\MethodGenerator;
use ProxyManager\Generator\MagicMethodGenerator;
use Zend\Code\Generator\ParameterGenerator;
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\Util\InterceptorGenerator;
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
use ReflectionClass;
use Zend\Code\Generator\PropertyGenerator;
/**
* Magic `__isset` method for lazy loading ghost objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MagicIsset extends MagicMethodGenerator
{
/**
* @param ReflectionClass $originalClass
* @param PropertyGenerator $prefixInterceptors
* @param PropertyGenerator $suffixInterceptors
*/
public function __construct(
ReflectionClass $originalClass,
PropertyGenerator $prefixInterceptors,
PropertyGenerator $suffixInterceptors
) {
parent::__construct($originalClass, '__isset', [new ParameterGenerator('name')]);
$override = $originalClass->hasMethod('__isset');
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
if ($override) {
$callParent = '$returnValue = & parent::__isset($name);';
} else {
$callParent = PublicScopeSimulator::getPublicAccessSimulationCode(
PublicScopeSimulator::OPERATION_ISSET,
'name',
null,
null,
'returnValue'
);
}
$this->setBody(
InterceptorGenerator::createInterceptedMethodBody(
$callParent,
$this,
$prefixInterceptors,
$suffixInterceptors
)
);
}
}

View File

@@ -0,0 +1,79 @@
<?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\MagicMethodGenerator;
use Zend\Code\Generator\ParameterGenerator;
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\Util\InterceptorGenerator;
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
use ReflectionClass;
use Zend\Code\Generator\PropertyGenerator;
/**
* Magic `__set` for lazy loading ghost objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MagicSet extends MagicMethodGenerator
{
/**
* @param \ReflectionClass $originalClass
* @param \Zend\Code\Generator\PropertyGenerator $prefixInterceptors
* @param \Zend\Code\Generator\PropertyGenerator $suffixInterceptors
*/
public function __construct(
ReflectionClass $originalClass,
PropertyGenerator $prefixInterceptors,
PropertyGenerator $suffixInterceptors
) {
parent::__construct(
$originalClass,
'__set',
[new ParameterGenerator('name'), new ParameterGenerator('value')]
);
$override = $originalClass->hasMethod('__set');
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
if ($override) {
$callParent = '$returnValue = & parent::__set($name, $value);';
} else {
$callParent = PublicScopeSimulator::getPublicAccessSimulationCode(
PublicScopeSimulator::OPERATION_SET,
'name',
'value',
null,
'returnValue'
);
}
$this->setBody(
InterceptorGenerator::createInterceptedMethodBody(
$callParent,
$this,
$prefixInterceptors,
$suffixInterceptors
)
);
}
}

View File

@@ -0,0 +1,63 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license.
*/
declare(strict_types=1);
namespace ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator;
use ProxyManager\Generator\MagicMethodGenerator;
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\Util\InterceptorGenerator;
use ReflectionClass;
use Zend\Code\Generator\PropertyGenerator;
/**
* Magic `__sleep` for lazy loading ghost objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MagicSleep extends MagicMethodGenerator
{
/**
* Constructor
*
* @param ReflectionClass $originalClass
* @param PropertyGenerator $prefixInterceptors
* @param PropertyGenerator $suffixInterceptors
*/
public function __construct(
ReflectionClass $originalClass,
PropertyGenerator $prefixInterceptors,
PropertyGenerator $suffixInterceptors
) {
parent::__construct($originalClass, '__sleep');
$callParent = $originalClass->hasMethod('__sleep')
? '$returnValue = & parent::__sleep();'
: '$returnValue = array_keys((array) $this);';
$this->setBody(
InterceptorGenerator::createInterceptedMethodBody(
$callParent,
$this,
$prefixInterceptors,
$suffixInterceptors
)
);
}
}

View File

@@ -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\AccessInterceptorScopeLocalizer\MethodGenerator;
use ProxyManager\Generator\MagicMethodGenerator;
use Zend\Code\Generator\ParameterGenerator;
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\Util\InterceptorGenerator;
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
use ReflectionClass;
use Zend\Code\Generator\PropertyGenerator;
/**
* Magic `__unset` method for lazy loading ghost objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MagicUnset extends MagicMethodGenerator
{
/**
* @param ReflectionClass $originalClass
* @param PropertyGenerator $prefixInterceptors
* @param PropertyGenerator $suffixInterceptors
*/
public function __construct(
ReflectionClass $originalClass,
PropertyGenerator $prefixInterceptors,
PropertyGenerator $suffixInterceptors
) {
parent::__construct($originalClass, '__unset', [new ParameterGenerator('name')]);
$override = $originalClass->hasMethod('__unset');
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
if ($override) {
$callParent = '$returnValue = & parent::__unset($name);';
} else {
$callParent = PublicScopeSimulator::getPublicAccessSimulationCode(
PublicScopeSimulator::OPERATION_UNSET,
'name',
null,
null,
'returnValue'
);
}
$this->setBody(
InterceptorGenerator::createInterceptedMethodBody(
$callParent,
$this,
$prefixInterceptors,
$suffixInterceptors
)
);
}
}

View File

@@ -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\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
*/
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;'
);
}
}

View File

@@ -0,0 +1,83 @@
<?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\Util;
use ProxyManager\Generator\MethodGenerator;
use Zend\Code\Generator\PropertyGenerator;
/**
* Utility to create pre- and post- method interceptors around a given method body
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*
* @private - this class is just here as a small utility for this component, don't use it in your own code
*/
class InterceptorGenerator
{
/**
* @param string $methodBody the body of the previously generated code.
* It MUST assign the return value to a variable
* `$returnValue` instead of directly returning
* @param \ProxyManager\Generator\MethodGenerator $method
* @param \Zend\Code\Generator\PropertyGenerator $prefixInterceptors
* @param \Zend\Code\Generator\PropertyGenerator $suffixInterceptors
*
* @return string
*/
public static function createInterceptedMethodBody(
string $methodBody,
MethodGenerator $method,
PropertyGenerator $prefixInterceptors,
PropertyGenerator $suffixInterceptors
) : string {
$name = var_export($method->getName(), true);
$prefixInterceptors = $prefixInterceptors->getName();
$suffixInterceptors = $suffixInterceptors->getName();
$params = [];
foreach ($method->getParameters() as $parameter) {
$parameterName = $parameter->getName();
$params[] = var_export($parameterName, true) . ' => $' . $parameter->getName();
}
$paramsString = 'array(' . implode(', ', $params) . ')';
return "if (isset(\$this->$prefixInterceptors" . "[$name])) {\n"
. " \$returnEarly = false;\n"
. " \$prefixReturnValue = \$this->$prefixInterceptors" . "[$name]->__invoke("
. "\$this, \$this, $name, $paramsString, \$returnEarly);\n\n"
. " if (\$returnEarly) {\n"
. " return \$prefixReturnValue;\n"
. " }\n"
. "}\n\n"
. $methodBody . "\n\n"
. "if (isset(\$this->$suffixInterceptors" . "[$name])) {\n"
. " \$returnEarly = false;\n"
. " \$suffixReturnValue = \$this->$suffixInterceptors" . "[$name]->__invoke("
. "\$this, \$this, $name, $paramsString, \$returnValue, \$returnEarly);\n\n"
. " if (\$returnEarly) {\n"
. " return \$suffixReturnValue;\n"
. " }\n"
. "}\n\n"
. "return \$returnValue;";
}
}

View File

@@ -0,0 +1,109 @@
<?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;
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\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;
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\MagicIsset;
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;
use ReflectionMethod;
use Zend\Code\Generator\ClassGenerator;
use Zend\Code\Generator\MethodGenerator;
use Zend\Code\Reflection\MethodReflection;
/**
* Generator for proxies implementing {@see \ProxyManager\Proxy\ValueHolderInterface}
* and localizing scope of the proxied object at instantiation
*
* {@inheritDoc}
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class AccessInterceptorScopeLocalizerGenerator implements ProxyGeneratorInterface
{
/**
* {@inheritDoc}
*/
public function generate(ReflectionClass $originalClass, ClassGenerator $classGenerator)
{
CanProxyAssertion::assertClassCanBeProxied($originalClass, false);
$classGenerator->setExtendedClass($originalClass->getName());
$classGenerator->setImplementedInterfaces([AccessInterceptorInterface::class]);
$classGenerator->addPropertyFromGenerator($prefixInterceptors = new MethodPrefixInterceptors());
$classGenerator->addPropertyFromGenerator($suffixInterceptors = new MethodSuffixInterceptors());
array_map(
function (MethodGenerator $generatedMethod) use ($originalClass, $classGenerator) {
ClassGeneratorUtils::addMethodIfNotFinal($originalClass, $classGenerator, $generatedMethod);
},
array_merge(
array_map(
$this->buildMethodInterceptor($prefixInterceptors, $suffixInterceptors),
ProxiedMethodsFilter::getProxiedMethods(
$originalClass,
['__get', '__set', '__isset', '__unset', '__clone', '__sleep']
)
),
[
new StaticProxyConstructor($originalClass, $prefixInterceptors, $suffixInterceptors),
new BindProxyProperties($originalClass, $prefixInterceptors, $suffixInterceptors),
new SetMethodPrefixInterceptor($prefixInterceptors),
new SetMethodSuffixInterceptor($suffixInterceptors),
new MagicGet($originalClass, $prefixInterceptors, $suffixInterceptors),
new MagicSet($originalClass, $prefixInterceptors, $suffixInterceptors),
new MagicIsset($originalClass, $prefixInterceptors, $suffixInterceptors),
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
);
};
}
}

View File

@@ -0,0 +1,72 @@
<?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\AccessInterceptorValueHolder\MethodGenerator\Util\InterceptorGenerator;
use Zend\Code\Generator\PropertyGenerator;
use Zend\Code\Reflection\MethodReflection;
/**
* Method with additional pre- and post- interceptor logic in the body
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class InterceptedMethod extends MethodGenerator
{
/**
* @param \Zend\Code\Reflection\MethodReflection $originalMethod
* @param \Zend\Code\Generator\PropertyGenerator $valueHolderProperty
* @param \Zend\Code\Generator\PropertyGenerator $prefixInterceptors
* @param \Zend\Code\Generator\PropertyGenerator $suffixInterceptors
*
* @return self
*/
public static function generateMethod(
MethodReflection $originalMethod,
PropertyGenerator $valueHolderProperty,
PropertyGenerator $prefixInterceptors,
PropertyGenerator $suffixInterceptors
) : self {
/* @var $method self */
$method = static::fromReflection($originalMethod);
$forwardedParams = [];
foreach ($originalMethod->getParameters() as $parameter) {
$forwardedParams[] = ($parameter->isVariadic() ? '...' : '') . '$' . $parameter->getName();
}
$method->setDocblock('{@inheritDoc}');
$method->setBody(
InterceptorGenerator::createInterceptedMethodBody(
'$returnValue = $this->' . $valueHolderProperty->getName() . '->'
. $originalMethod->getName() . '(' . implode(', ', $forwardedParams) . ');',
$method,
$valueHolderProperty,
$prefixInterceptors,
$suffixInterceptors
)
);
return $method;
}
}

View File

@@ -0,0 +1,65 @@
<?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\MagicMethodGenerator;
use ReflectionClass;
use Zend\Code\Generator\PropertyGenerator;
/**
* Magic `__clone` for lazy loading value holder objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MagicClone extends MagicMethodGenerator
{
/**
* Constructor
*
* @param ReflectionClass $originalClass
* @param PropertyGenerator $valueHolderProperty
* @param PropertyGenerator $prefixInterceptors
* @param PropertyGenerator $suffixInterceptors
*/
public function __construct(
ReflectionClass $originalClass,
PropertyGenerator $valueHolderProperty,
PropertyGenerator $prefixInterceptors,
PropertyGenerator $suffixInterceptors
) {
parent::__construct($originalClass, '__clone');
$valueHolder = $valueHolderProperty->getName();
$prefix = $prefixInterceptors->getName();
$suffix = $suffixInterceptors->getName();
$this->setBody(
"\$this->$valueHolder = clone \$this->$valueHolder;\n\n"
. "foreach (\$this->$prefix as \$key => \$value) {\n"
. " \$this->$prefix" . "[\$key] = clone \$value;\n"
. "}\n\n"
. "foreach (\$this->$suffix as \$key => \$value) {\n"
. " \$this->$suffix" . "[\$key] = clone \$value;\n"
. "}"
);
}
}

View File

@@ -0,0 +1,86 @@
<?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\MagicMethodGenerator;
use Zend\Code\Generator\ParameterGenerator;
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\Util\InterceptorGenerator;
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
use ReflectionClass;
use Zend\Code\Generator\PropertyGenerator;
/**
* Magic `__get` for method interceptor value holder objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MagicGet extends MagicMethodGenerator
{
/**
* Constructor
*
* @param ReflectionClass $originalClass
* @param PropertyGenerator $valueHolder
* @param PropertyGenerator $prefixInterceptors
* @param PropertyGenerator $suffixInterceptors
* @param PublicPropertiesMap $publicProperties
*/
public function __construct(
ReflectionClass $originalClass,
PropertyGenerator $valueHolder,
PropertyGenerator $prefixInterceptors,
PropertyGenerator $suffixInterceptors,
PublicPropertiesMap $publicProperties
) {
parent::__construct($originalClass, '__get', [new ParameterGenerator('name')]);
$override = $originalClass->hasMethod('__get');
$valueHolderName = $valueHolder->getName();
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
$callParent = PublicScopeSimulator::getPublicAccessSimulationCode(
PublicScopeSimulator::OPERATION_GET,
'name',
'value',
$valueHolder,
'returnValue'
);
if (! $publicProperties->isEmpty()) {
$callParent = 'if (isset(self::$' . $publicProperties->getName() . "[\$name])) {\n"
. ' $returnValue = & $this->' . $valueHolderName . '->$name;'
. "\n} else {\n $callParent\n}\n\n";
}
$this->setBody(
InterceptorGenerator::createInterceptedMethodBody(
$callParent,
$this,
$valueHolder,
$prefixInterceptors,
$suffixInterceptors
)
);
}
}

View File

@@ -0,0 +1,85 @@
<?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\MagicMethodGenerator;
use Zend\Code\Generator\ParameterGenerator;
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\Util\InterceptorGenerator;
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
use ReflectionClass;
use Zend\Code\Generator\PropertyGenerator;
/**
* Magic `__isset` for method interceptor value holder objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MagicIsset extends MagicMethodGenerator
{
/**
* Constructor
* @param ReflectionClass $originalClass
* @param PropertyGenerator $valueHolder
* @param PropertyGenerator $prefixInterceptors
* @param PropertyGenerator $suffixInterceptors
* @param PublicPropertiesMap $publicProperties
*/
public function __construct(
ReflectionClass $originalClass,
PropertyGenerator $valueHolder,
PropertyGenerator $prefixInterceptors,
PropertyGenerator $suffixInterceptors,
PublicPropertiesMap $publicProperties
) {
parent::__construct($originalClass, '__isset', [new ParameterGenerator('name')]);
$override = $originalClass->hasMethod('__isset');
$valueHolderName = $valueHolder->getName();
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
$callParent = PublicScopeSimulator::getPublicAccessSimulationCode(
PublicScopeSimulator::OPERATION_ISSET,
'name',
'value',
$valueHolder,
'returnValue'
);
if (! $publicProperties->isEmpty()) {
$callParent = 'if (isset(self::$' . $publicProperties->getName() . "[\$name])) {\n"
. ' $returnValue = isset($this->' . $valueHolderName . '->$name);'
. "\n} else {\n $callParent\n}\n\n";
}
$this->setBody(
InterceptorGenerator::createInterceptedMethodBody(
$callParent,
$this,
$valueHolder,
$prefixInterceptors,
$suffixInterceptors
)
);
}
}

View File

@@ -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\AccessInterceptorValueHolder\MethodGenerator;
use ProxyManager\Generator\MagicMethodGenerator;
use Zend\Code\Generator\ParameterGenerator;
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\Util\InterceptorGenerator;
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
use ReflectionClass;
use Zend\Code\Generator\PropertyGenerator;
/**
* Magic `__set` for method interceptor value holder objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MagicSet extends MagicMethodGenerator
{
/**
* Constructor
* @param ReflectionClass $originalClass
* @param PropertyGenerator $valueHolder
* @param PropertyGenerator $prefixInterceptors
* @param PropertyGenerator $suffixInterceptors
* @param PublicPropertiesMap $publicProperties
*/
public function __construct(
ReflectionClass $originalClass,
PropertyGenerator $valueHolder,
PropertyGenerator $prefixInterceptors,
PropertyGenerator $suffixInterceptors,
PublicPropertiesMap $publicProperties
) {
parent::__construct(
$originalClass,
'__set',
[new ParameterGenerator('name'), new ParameterGenerator('value')]
);
$override = $originalClass->hasMethod('__set');
$valueHolderName = $valueHolder->getName();
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
$callParent = PublicScopeSimulator::getPublicAccessSimulationCode(
PublicScopeSimulator::OPERATION_SET,
'name',
'value',
$valueHolder,
'returnValue'
);
if (! $publicProperties->isEmpty()) {
$callParent = 'if (isset(self::$' . $publicProperties->getName() . "[\$name])) {\n"
. ' $returnValue = ($this->' . $valueHolderName . '->$name = $value);'
. "\n} else {\n $callParent\n}\n\n";
}
$this->setBody(
InterceptorGenerator::createInterceptedMethodBody(
$callParent,
$this,
$valueHolder,
$prefixInterceptors,
$suffixInterceptors
)
);
}
}

View File

@@ -0,0 +1,87 @@
<?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\MagicMethodGenerator;
use Zend\Code\Generator\ParameterGenerator;
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\Util\InterceptorGenerator;
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
use ReflectionClass;
use Zend\Code\Generator\PropertyGenerator;
/**
* Magic `__unset` for method interceptor value holder objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MagicUnset extends MagicMethodGenerator
{
/**
* Constructor
* @param ReflectionClass $originalClass
* @param PropertyGenerator $valueHolder
* @param PropertyGenerator $prefixInterceptors
* @param PropertyGenerator $suffixInterceptors
* @param PublicPropertiesMap $publicProperties
*/
public function __construct(
ReflectionClass $originalClass,
PropertyGenerator $valueHolder,
PropertyGenerator $prefixInterceptors,
PropertyGenerator $suffixInterceptors,
PublicPropertiesMap $publicProperties
) {
parent::__construct($originalClass, '__unset', [new ParameterGenerator('name')]);
$override = $originalClass->hasMethod('__unset');
$valueHolderName = $valueHolder->getName();
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
$callParent = PublicScopeSimulator::getPublicAccessSimulationCode(
PublicScopeSimulator::OPERATION_UNSET,
'name',
'value',
$valueHolder,
'returnValue'
);
if (! $publicProperties->isEmpty()) {
$callParent = 'if (isset(self::$' . $publicProperties->getName() . "[\$name])) {\n"
. ' unset($this->' . $valueHolderName . '->$name);'
. "\n} else {\n $callParent\n}\n\n";
}
$callParent .= '$returnValue = false;';
$this->setBody(
InterceptorGenerator::createInterceptedMethodBody(
$callParent,
$this,
$valueHolder,
$prefixInterceptors,
$suffixInterceptors
)
);
}
}

View File

@@ -0,0 +1,86 @@
<?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
*/
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;'
);
}
}

View File

@@ -0,0 +1,86 @@
<?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\Util;
use ProxyManager\Generator\MethodGenerator;
use Zend\Code\Generator\PropertyGenerator;
/**
* Utility to create pre- and post- method interceptors around a given method body
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*
* @private - this class is just here as a small utility for this component, don't use it in your own code
*/
class InterceptorGenerator
{
/**
* @param string $methodBody the body of the previously generated code.
* It MUST assign the return value to a variable
* `$returnValue` instead of directly returning
* @param \ProxyManager\Generator\MethodGenerator $method
* @param \Zend\Code\Generator\PropertyGenerator $valueHolder
* @param \Zend\Code\Generator\PropertyGenerator $prefixInterceptors
* @param \Zend\Code\Generator\PropertyGenerator $suffixInterceptors
*
* @return string
*/
public static function createInterceptedMethodBody(
string $methodBody,
MethodGenerator $method,
PropertyGenerator $valueHolder,
PropertyGenerator $prefixInterceptors,
PropertyGenerator $suffixInterceptors
) : string {
$name = var_export($method->getName(), true);
$valueHolder = $valueHolder->getName();
$prefixInterceptors = $prefixInterceptors->getName();
$suffixInterceptors = $suffixInterceptors->getName();
$params = [];
foreach ($method->getParameters() as $parameter) {
$parameterName = $parameter->getName();
$params[] = var_export($parameterName, true) . ' => $' . $parameter->getName();
}
$paramsString = 'array(' . implode(', ', $params) . ')';
return "if (isset(\$this->$prefixInterceptors" . "[$name])) {\n"
. " \$returnEarly = false;\n"
. " \$prefixReturnValue = \$this->$prefixInterceptors" . "[$name]->__invoke("
. "\$this, \$this->$valueHolder, $name, $paramsString, \$returnEarly);\n\n"
. " if (\$returnEarly) {\n"
. " return \$prefixReturnValue;\n"
. " }\n"
. "}\n\n"
. $methodBody . "\n\n"
. "if (isset(\$this->$suffixInterceptors" . "[$name])) {\n"
. " \$returnEarly = false;\n"
. " \$suffixReturnValue = \$this->$suffixInterceptors" . "[$name]->__invoke("
. "\$this, \$this->$valueHolder, $name, $paramsString, \$returnValue, \$returnEarly);\n\n"
. " if (\$returnEarly) {\n"
. " return \$suffixReturnValue;\n"
. " }\n"
. "}\n\n"
. "return \$returnValue;";
}
}

View File

@@ -0,0 +1,149 @@
<?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;
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\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;
use ReflectionMethod;
use Zend\Code\Generator\ClassGenerator;
use Zend\Code\Generator\MethodGenerator;
use Zend\Code\Reflection\MethodReflection;
/**
* Generator for proxies implementing {@see \ProxyManager\Proxy\ValueHolderInterface}
* and {@see \ProxyManager\Proxy\AccessInterceptorInterface}
*
* {@inheritDoc}
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class AccessInterceptorValueHolderGenerator implements ProxyGeneratorInterface
{
/**
* {@inheritDoc}
*/
public function generate(ReflectionClass $originalClass, ClassGenerator $classGenerator)
{
CanProxyAssertion::assertClassCanBeProxied($originalClass);
$publicProperties = new PublicPropertiesMap(Properties::fromReflectionClass($originalClass));
$interfaces = [AccessInterceptorValueHolderInterface::class];
if ($originalClass->isInterface()) {
$interfaces[] = $originalClass->getName();
} else {
$classGenerator->setExtendedClass($originalClass->getName());
}
$classGenerator->setImplementedInterfaces($interfaces);
$classGenerator->addPropertyFromGenerator($valueHolder = new ValueHolderProperty());
$classGenerator->addPropertyFromGenerator($prefixInterceptors = new MethodPrefixInterceptors());
$classGenerator->addPropertyFromGenerator($suffixInterceptors = new MethodSuffixInterceptors());
$classGenerator->addPropertyFromGenerator($publicProperties);
array_map(
function (MethodGenerator $generatedMethod) use ($originalClass, $classGenerator) {
ClassGeneratorUtils::addMethodIfNotFinal($originalClass, $classGenerator, $generatedMethod);
},
array_merge(
array_map(
$this->buildMethodInterceptor($prefixInterceptors, $suffixInterceptors, $valueHolder),
ProxiedMethodsFilter::getProxiedMethods($originalClass)
),
[
Constructor::generateMethod($originalClass, $valueHolder),
new StaticProxyConstructor($originalClass, $valueHolder, $prefixInterceptors, $suffixInterceptors),
new GetWrappedValueHolderValue($valueHolder),
new SetMethodPrefixInterceptor($prefixInterceptors),
new SetMethodSuffixInterceptor($suffixInterceptors),
new MagicGet(
$originalClass,
$valueHolder,
$prefixInterceptors,
$suffixInterceptors,
$publicProperties
),
new MagicSet(
$originalClass,
$valueHolder,
$prefixInterceptors,
$suffixInterceptors,
$publicProperties
),
new MagicIsset(
$originalClass,
$valueHolder,
$prefixInterceptors,
$suffixInterceptors,
$publicProperties
),
new MagicUnset(
$originalClass,
$valueHolder,
$prefixInterceptors,
$suffixInterceptors,
$publicProperties
),
new MagicClone($originalClass, $valueHolder, $prefixInterceptors, $suffixInterceptors),
new MagicSleep($originalClass, $valueHolder),
new MagicWakeup($originalClass, $valueHolder),
]
)
);
}
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
);
};
}
}

View File

@@ -0,0 +1,112 @@
<?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\Assertion;
use BadMethodCallException;
use ProxyManager\Exception\InvalidProxiedClassException;
use ReflectionClass;
use ReflectionMethod;
/**
* Assertion that verifies that a class can be proxied
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
final class CanProxyAssertion
{
/**
* Disabled constructor: not meant to be instantiated
*
* @throws BadMethodCallException
*/
public function __construct()
{
throw new BadMethodCallException('Unsupported constructor.');
}
/**
* @param ReflectionClass $originalClass
* @param bool $allowInterfaces
*
* @return void
*
* @throws InvalidProxiedClassException
*/
public static function assertClassCanBeProxied(ReflectionClass $originalClass, bool $allowInterfaces = true)
{
self::isNotFinal($originalClass);
self::hasNoAbstractProtectedMethods($originalClass);
if (! $allowInterfaces) {
self::isNotInterface($originalClass);
}
}
/**
* @param ReflectionClass $originalClass
*
* @return void
*
* @throws InvalidProxiedClassException
*/
private static function isNotFinal(ReflectionClass $originalClass)
{
if ($originalClass->isFinal()) {
throw InvalidProxiedClassException::finalClassNotSupported($originalClass);
}
}
/**
* @param ReflectionClass $originalClass
*
* @return void
*
* @throws InvalidProxiedClassException
*/
private static function hasNoAbstractProtectedMethods(ReflectionClass $originalClass)
{
$protectedAbstract = array_filter(
$originalClass->getMethods(),
function (ReflectionMethod $method) : bool {
return $method->isAbstract() && $method->isProtected();
}
);
if ($protectedAbstract) {
throw InvalidProxiedClassException::abstractProtectedMethodsNotSupported($originalClass);
}
}
/**
* @param ReflectionClass $originalClass
*
* @return void
*
* @throws InvalidProxiedClassException
*/
private static function isNotInterface(ReflectionClass $originalClass)
{
if ($originalClass->isInterface()) {
throw InvalidProxiedClassException::interfaceNotSupported($originalClass);
}
}
}

View File

@@ -0,0 +1,59 @@
<?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
*/
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;'
);
}
}

View File

@@ -0,0 +1,197 @@
<?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\MethodGenerator;
use ProxyManager\Generator\MethodGenerator;
use Zend\Code\Generator\ParameterGenerator;
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
use ProxyManager\ProxyGenerator\Util\Properties;
use ReflectionProperty;
use Zend\Code\Generator\PropertyGenerator;
/**
* Implementation for {@see \ProxyManager\Proxy\LazyLoadingInterface::isProxyInitialized}
* for lazy loading value holder objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class CallInitializer extends MethodGenerator
{
/**
* Constructor
*
* @param PropertyGenerator $initializerProperty
* @param PropertyGenerator $initTracker
* @param Properties $properties
*/
public function __construct(
PropertyGenerator $initializerProperty,
PropertyGenerator $initTracker,
Properties $properties
) {
$docblock = <<<'DOCBLOCK'
Triggers initialization logic for this ghost object
@param string $methodName
@param mixed[] $parameters
@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();
$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(isset($defaults[$name]) ? $defaults[$name] : null, true);
}
}

View File

@@ -0,0 +1,46 @@
<?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\MethodGenerator;
use ProxyManager\Generator\MethodGenerator;
use Zend\Code\Generator\PropertyGenerator;
/**
* Implementation for {@see \ProxyManager\Proxy\LazyLoadingInterface::getProxyInitializer}
* for lazy loading value holder objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class GetProxyInitializer extends MethodGenerator
{
/**
* Constructor
*
* @param PropertyGenerator $initializerProperty
*/
public function __construct(PropertyGenerator $initializerProperty)
{
parent::__construct('getProxyInitializer');
$this->setDocblock('{@inheritDoc}');
$this->setBody('return $this->' . $initializerProperty->getName() . ';');
}
}

View File

@@ -0,0 +1,53 @@
<?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\MethodGenerator;
use ProxyManager\Generator\MethodGenerator;
use Zend\Code\Generator\MethodGenerator as ZendMethodGenerator;
use Zend\Code\Generator\PropertyGenerator;
/**
* Implementation for {@see \ProxyManager\Proxy\LazyLoadingInterface::initializeProxy}
* for lazy loading ghost objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class InitializeProxy extends MethodGenerator
{
/**
* Constructor
*
* @param PropertyGenerator $initializerProperty
* @param ZendMethodGenerator $callInitializer
*/
public function __construct(PropertyGenerator $initializerProperty, ZendMethodGenerator $callInitializer)
{
parent::__construct('initializeProxy');
$this->setDocblock('{@inheritDoc}');
$this->setReturnType('bool');
$this->setBody(
'return $this->' . $initializerProperty->getName() . ' && $this->' . $callInitializer->getName()
. '(\'initializeProxy\', []);'
);
}
}

View File

@@ -0,0 +1,47 @@
<?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\MethodGenerator;
use ProxyManager\Generator\MethodGenerator;
use Zend\Code\Generator\PropertyGenerator;
/**
* Implementation for {@see \ProxyManager\Proxy\LazyLoadingInterface::isProxyInitialized}
* for lazy loading value holder objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class IsProxyInitialized extends MethodGenerator
{
/**
* Constructor
*
* @param PropertyGenerator $initializerProperty
*/
public function __construct(PropertyGenerator $initializerProperty)
{
parent::__construct('isProxyInitialized');
$this->setDocblock('{@inheritDoc}');
$this->setReturnType('bool');
$this->setBody('return ! $this->' . $initializerProperty->getName() . ';');
}
}

View File

@@ -0,0 +1,56 @@
<?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\MethodGenerator;
use ProxyManager\Generator\MagicMethodGenerator;
use ReflectionClass;
use Zend\Code\Generator\MethodGenerator;
use Zend\Code\Generator\PropertyGenerator;
/**
* Magic `__clone` for lazy loading ghost objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MagicClone extends MagicMethodGenerator
{
/**
* Constructor
*
* @param ReflectionClass $originalClass
* @param PropertyGenerator $initializerProperty
* @param MethodGenerator $callInitializer
*/
public function __construct(
ReflectionClass $originalClass,
PropertyGenerator $initializerProperty,
MethodGenerator $callInitializer
) {
parent::__construct($originalClass, '__clone');
$this->setBody(
'$this->' . $initializerProperty->getName() . ' && $this->' . $callInitializer->getName()
. '(\'__clone\', []);'
. ($originalClass->hasMethod('__clone') ? "\n\nparent::__clone();" : '')
);
}
}

View File

@@ -0,0 +1,156 @@
<?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\MethodGenerator;
use ProxyManager\Generator\MagicMethodGenerator;
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;
use Zend\Code\Generator\MethodGenerator;
use Zend\Code\Generator\PropertyGenerator;
/**
* Magic `__get` for lazy loading ghost objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MagicGet extends MagicMethodGenerator
{
/**
* @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
*/
public function __construct(
ReflectionClass $originalClass,
PropertyGenerator $initializerProperty,
MethodGenerator $callInitializer,
PublicPropertiesMap $publicProperties,
ProtectedPropertiesMap $protectedProperties,
PrivatePropertiesMap $privateProperties,
InitializationTracker $initializationTracker
) {
parent::__construct($originalClass, '__get', [new ParameterGenerator('name')]);
$override = $originalClass->hasMethod('__get');
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
$parentAccess = 'return parent::__get($name);';
if (! $override) {
$parentAccess = PublicScopeSimulator::getPublicAccessSimulationCode(
PublicScopeSimulator::OPERATION_GET,
'name'
);
}
$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
));
}
}

View File

@@ -0,0 +1,145 @@
<?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\MethodGenerator;
use ProxyManager\Generator\MagicMethodGenerator;
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;
use Zend\Code\Generator\MethodGenerator;
use Zend\Code\Generator\PropertyGenerator;
/**
* Magic `__isset` method for lazy loading ghost objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MagicIsset extends MagicMethodGenerator
{
/**
* @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
*/
public function __construct(
ReflectionClass $originalClass,
PropertyGenerator $initializerProperty,
MethodGenerator $callInitializer,
PublicPropertiesMap $publicProperties,
ProtectedPropertiesMap $protectedProperties,
PrivatePropertiesMap $privateProperties
) {
parent::__construct($originalClass, '__isset', [new ParameterGenerator('name')]);
$override = $originalClass->hasMethod('__isset');
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
$parentAccess = 'return parent::__isset($name);';
if (! $override) {
$parentAccess = PublicScopeSimulator::getPublicAccessSimulationCode(
PublicScopeSimulator::OPERATION_ISSET,
'name'
);
}
$this->setBody(sprintf(
$this->callParentTemplate,
'$this->' . $initializerProperty->getName() . ' && $this->' . $callInitializer->getName()
. '(\'__isset\', array(\'name\' => $name));',
$publicProperties->getName(),
$protectedProperties->getName(),
$protectedProperties->getName(),
$privateProperties->getName(),
$privateProperties->getName(),
$parentAccess
));
}
}

View File

@@ -0,0 +1,151 @@
<?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\MethodGenerator;
use ProxyManager\Generator\MagicMethodGenerator;
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;
use Zend\Code\Generator\MethodGenerator;
use Zend\Code\Generator\PropertyGenerator;
/**
* Magic `__set` for lazy loading ghost objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MagicSet extends MagicMethodGenerator
{
/**
* @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
*/
public function __construct(
ReflectionClass $originalClass,
PropertyGenerator $initializerProperty,
MethodGenerator $callInitializer,
PublicPropertiesMap $publicProperties,
ProtectedPropertiesMap $protectedProperties,
PrivatePropertiesMap $privateProperties
) {
parent::__construct(
$originalClass,
'__set',
[new ParameterGenerator('name'), new ParameterGenerator('value')]
);
$override = $originalClass->hasMethod('__set');
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
$parentAccess = 'return parent::__set($name, $value);';
if (! $override) {
$parentAccess = PublicScopeSimulator::getPublicAccessSimulationCode(
PublicScopeSimulator::OPERATION_SET,
'name',
'value'
);
}
$this->setBody(sprintf(
$this->callParentTemplate,
'$this->' . $initializerProperty->getName() . ' && $this->' . $callInitializer->getName()
. '(\'__set\', array(\'name\' => $name, \'value\' => $value));',
$publicProperties->getName(),
$protectedProperties->getName(),
$protectedProperties->getName(),
$privateProperties->getName(),
$privateProperties->getName(),
$privateProperties->getName(),
$parentAccess
));
}
}

View File

@@ -0,0 +1,56 @@
<?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\MethodGenerator;
use ProxyManager\Generator\MagicMethodGenerator;
use ReflectionClass;
use Zend\Code\Generator\MethodGenerator;
use Zend\Code\Generator\PropertyGenerator;
/**
* Magic `__sleep` for lazy loading ghost objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MagicSleep extends MagicMethodGenerator
{
/**
* Constructor
*
* @param ReflectionClass $originalClass
* @param PropertyGenerator $initializerProperty
* @param MethodGenerator $callInitializer
*/
public function __construct(
ReflectionClass $originalClass,
PropertyGenerator $initializerProperty,
MethodGenerator $callInitializer
) {
parent::__construct($originalClass, '__sleep');
$this->setBody(
'$this->' . $initializerProperty->getName() . ' && $this->' . $callInitializer->getName()
. '(\'__sleep\', []);' . "\n\n"
. ($originalClass->hasMethod('__sleep') ? 'return parent::__sleep();' : 'return array_keys((array) $this);')
);
}
}

View File

@@ -0,0 +1,152 @@
<?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\MethodGenerator;
use ProxyManager\Generator\MagicMethodGenerator;
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;
use Zend\Code\Generator\MethodGenerator;
use Zend\Code\Generator\PropertyGenerator;
/**
* Magic `__unset` method for lazy loading ghost objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MagicUnset extends MagicMethodGenerator
{
/**
* @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
*/
public function __construct(
ReflectionClass $originalClass,
PropertyGenerator $initializerProperty,
MethodGenerator $callInitializer,
PublicPropertiesMap $publicProperties,
ProtectedPropertiesMap $protectedProperties,
PrivatePropertiesMap $privateProperties
) {
parent::__construct($originalClass, '__unset', [new ParameterGenerator('name')]);
$override = $originalClass->hasMethod('__unset');
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
$parentAccess = 'return parent::__unset($name);';
if (! $override) {
$parentAccess = PublicScopeSimulator::getPublicAccessSimulationCode(
PublicScopeSimulator::OPERATION_UNSET,
'name'
);
}
$this->setBody(sprintf(
$this->callParentTemplate,
'$this->' . $initializerProperty->getName() . ' && $this->' . $callInitializer->getName()
. '(\'__unset\', array(\'name\' => $name));',
$publicProperties->getName(),
$protectedProperties->getName(),
$protectedProperties->getName(),
$privateProperties->getName(),
$privateProperties->getName(),
$privateProperties->getName(),
$parentAccess
));
}
}

View File

@@ -0,0 +1,51 @@
<?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\MethodGenerator;
use ProxyManager\Generator\MethodGenerator;
use Zend\Code\Generator\ParameterGenerator;
use Zend\Code\Generator\PropertyGenerator;
/**
* Implementation for {@see \ProxyManager\Proxy\LazyLoadingInterface::setProxyInitializer}
* for lazy loading value holder objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class SetProxyInitializer extends MethodGenerator
{
/**
* Constructor
*
* @param PropertyGenerator $initializerProperty
*/
public function __construct(PropertyGenerator $initializerProperty)
{
parent::__construct(
'setProxyInitializer',
[(new ParameterGenerator('initializer', 'Closure'))->setDefaultValue(null)],
self::FLAG_PUBLIC,
'$this->' . $initializerProperty->getName() . ' = $initializer;',
'{@inheritDoc}'
);
}
}

View File

@@ -0,0 +1,45 @@
<?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 Zend\Code\Generator\PropertyGenerator;
/**
* Property that contains the initializer for a lazy object
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class InitializationTracker extends PropertyGenerator
{
/**
* Constructor
*/
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->setDefaultValue(false);
}
}

View File

@@ -0,0 +1,44 @@
<?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 Zend\Code\Generator\PropertyGenerator;
/**
* Property that contains the initializer for a lazy object
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class InitializerProperty extends PropertyGenerator
{
/**
* Constructor
*/
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');
}
}

View File

@@ -0,0 +1,73 @@
<?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
*/
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;
}
}

View File

@@ -0,0 +1,72 @@
<?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
*/
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;
}
}

View File

@@ -0,0 +1,157 @@
<?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;
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\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\MagicClone;
use ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator\MagicGet;
use ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator\MagicIsset;
use ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator\MagicSet;
use ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator\MagicSleep;
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\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;
use Zend\Code\Generator\ClassGenerator;
use Zend\Code\Generator\MethodGenerator;
use Zend\Code\Reflection\MethodReflection;
/**
* Generator for proxies implementing {@see \ProxyManager\Proxy\GhostObjectInterface}
*
* {@inheritDoc}
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class LazyLoadingGhostGenerator implements ProxyGeneratorInterface
{
/**
* {@inheritDoc}
*/
public function generate(ReflectionClass $originalClass, ClassGenerator $classGenerator, array $proxyOptions = [])
{
CanProxyAssertion::assertClassCanBeProxied($originalClass, false);
$filteredProperties = Properties::fromReflectionClass($originalClass)
->filter(isset($proxyOptions['skippedProperties']) ? $proxyOptions['skippedProperties'] : []);
$publicProperties = new PublicPropertiesMap($filteredProperties);
$privateProperties = new PrivatePropertiesMap($filteredProperties);
$protectedProperties = new ProtectedPropertiesMap($filteredProperties);
$classGenerator->setExtendedClass($originalClass->getName());
$classGenerator->setImplementedInterfaces([GhostObjectInterface::class]);
$classGenerator->addPropertyFromGenerator($initializer = new InitializerProperty());
$classGenerator->addPropertyFromGenerator($initializationTracker = new InitializationTracker());
$classGenerator->addPropertyFromGenerator($publicProperties);
$classGenerator->addPropertyFromGenerator($privateProperties);
$classGenerator->addPropertyFromGenerator($protectedProperties);
$init = new CallInitializer($initializer, $initializationTracker, $filteredProperties);
array_map(
function (MethodGenerator $generatedMethod) use ($originalClass, $classGenerator) {
ClassGeneratorUtils::addMethodIfNotFinal($originalClass, $classGenerator, $generatedMethod);
},
array_merge(
$this->getAbstractProxiedMethods($originalClass),
[
$init,
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, $publicProperties),
new MagicSleep($originalClass, $initializer, $init, $publicProperties),
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 {
return ProxyManagerMethodGenerator
::fromReflection(new MethodReflection($method->getDeclaringClass()->getName(), $method->getName()))
->setAbstract(false);
},
ProxiedMethodsFilter::getAbstractProxiedMethods($originalClass)
);
}
}

View File

@@ -0,0 +1,46 @@
<?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\LazyLoadingValueHolder\MethodGenerator;
use ProxyManager\Generator\MethodGenerator;
use Zend\Code\Generator\PropertyGenerator;
/**
* Implementation for {@see \ProxyManager\Proxy\LazyLoadingInterface::getProxyInitializer}
* for lazy loading value holder objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class GetProxyInitializer extends MethodGenerator
{
/**
* Constructor
*
* @param PropertyGenerator $initializerProperty
*/
public function __construct(PropertyGenerator $initializerProperty)
{
parent::__construct('getProxyInitializer');
$this->setDocblock('{@inheritDoc}');
$this->setBody('return $this->' . $initializerProperty->getName() . ';');
}
}

View File

@@ -0,0 +1,55 @@
<?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\LazyLoadingValueHolder\MethodGenerator;
use ProxyManager\Generator\MethodGenerator;
use Zend\Code\Generator\PropertyGenerator;
/**
* Implementation for {@see \ProxyManager\Proxy\LazyLoadingInterface::initializeProxy}
* for lazy loading value holder objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class InitializeProxy extends MethodGenerator
{
/**
* Constructor
*
* @param PropertyGenerator $initializerProperty
* @param PropertyGenerator $valueHolderProperty
*/
public function __construct(PropertyGenerator $initializerProperty, PropertyGenerator $valueHolderProperty)
{
parent::__construct('initializeProxy');
$this->setDocblock('{@inheritDoc}');
$this->setReturnType('bool');
$initializer = $initializerProperty->getName();
$this->setBody(
'return $this->' . $initializer . ' && $this->' . $initializer
. '->__invoke($this->' . $valueHolderProperty->getName()
. ', $this, \'initializeProxy\', array(), $this->' . $initializer . ');'
);
}
}

View File

@@ -0,0 +1,47 @@
<?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\LazyLoadingValueHolder\MethodGenerator;
use ProxyManager\Generator\MethodGenerator;
use Zend\Code\Generator\PropertyGenerator;
/**
* Implementation for {@see \ProxyManager\Proxy\LazyLoadingInterface::isProxyInitialized}
* for lazy loading value holder objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class IsProxyInitialized extends MethodGenerator
{
/**
* Constructor
*
* @param PropertyGenerator $valueHolderProperty
*/
public function __construct(PropertyGenerator $valueHolderProperty)
{
parent::__construct('isProxyInitialized');
$this->setDocblock('{@inheritDoc}');
$this->setReturnType('bool');
$this->setBody('return null !== $this->' . $valueHolderProperty->getName() . ';');
}
}

View File

@@ -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\LazyLoadingValueHolder\MethodGenerator;
use ProxyManager\Generator\MethodGenerator;
use Zend\Code\Generator\PropertyGenerator;
use Zend\Code\Reflection\MethodReflection;
/**
* Method decorator for lazy loading value holder objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class LazyLoadingMethodInterceptor extends MethodGenerator
{
/**
* @param \Zend\Code\Reflection\MethodReflection $originalMethod
* @param \Zend\Code\Generator\PropertyGenerator $initializerProperty
* @param \Zend\Code\Generator\PropertyGenerator $valueHolderProperty
*
* @return self|static
*/
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 = [];
$forwardedParams = [];
foreach ($parameters as $parameter) {
$parameterName = $parameter->getName();
$variadicPrefix = $parameter->isVariadic() ? '...' : '';
$initializerParams[] = var_export($parameterName, true) . ' => $' . $parameterName;
$forwardedParams[] = $variadicPrefix . '$' . $parameterName;
}
$method->setBody(
'$this->' . $initializerName
. ' && $this->' . $initializerName
. '->__invoke($this->' . $valueHolderName . ', $this, ' . var_export($methodName, true)
. ', array(' . implode(', ', $initializerParams) . '), $this->' . $initializerName . ");\n\n"
. 'return $this->' . $valueHolderName . '->'
. $methodName . '(' . implode(', ', $forwardedParams) . ');'
);
$method->setDocblock('{@inheritDoc}');
return $method;
}
}

View File

@@ -0,0 +1,59 @@
<?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\LazyLoadingValueHolder\MethodGenerator;
use ProxyManager\Generator\MagicMethodGenerator;
use ReflectionClass;
use Zend\Code\Generator\PropertyGenerator;
/**
* Magic `__clone` for lazy loading value holder objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MagicClone extends MagicMethodGenerator
{
/**
* Constructor
*
* @param ReflectionClass $originalClass
* @param PropertyGenerator $initializerProperty
* @param PropertyGenerator $valueHolderProperty
*/
public function __construct(
ReflectionClass $originalClass,
PropertyGenerator $initializerProperty,
PropertyGenerator $valueHolderProperty
) {
parent::__construct($originalClass, '__clone');
$initializer = $initializerProperty->getName();
$valueHolder = $valueHolderProperty->getName();
$this->setBody(
'$this->' . $initializer . ' && $this->' . $initializer
. '->__invoke($this->' . $valueHolder
. ', $this, \'__clone\', array(), $this->' . $initializer . ');' . "\n\n"
. '$this->' . $valueHolder . ' = clone $this->' . $valueHolder . ';'
);
}
}

View File

@@ -0,0 +1,102 @@
<?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\LazyLoadingValueHolder\MethodGenerator;
use ProxyManager\Generator\MagicMethodGenerator;
use Zend\Code\Generator\ParameterGenerator;
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
use ReflectionClass;
use Zend\Code\Generator\PropertyGenerator;
/**
* Magic `__get` for lazy loading value holder objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MagicGet extends MagicMethodGenerator
{
/**
* Constructor
*
* @param ReflectionClass $originalClass
* @param PropertyGenerator $initializerProperty
* @param PropertyGenerator $valueHolderProperty
* @param PublicPropertiesMap $publicProperties
*/
public function __construct(
ReflectionClass $originalClass,
PropertyGenerator $initializerProperty,
PropertyGenerator $valueHolderProperty,
PublicPropertiesMap $publicProperties
) {
parent::__construct($originalClass, '__get', [new ParameterGenerator('name')]);
$hasParent = $originalClass->hasMethod('__get');
$this->setDocblock(($hasParent ? "{@inheritDoc}\n" : '') . '@param string $name');
$initializer = $initializerProperty->getName();
$valueHolder = $valueHolderProperty->getName();
$callParent = 'if (isset(self::$' . $publicProperties->getName() . "[\$name])) {\n"
. ' return $this->' . $valueHolder . '->$name;'
. "\n}\n\n";
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
)
);
}
/**
* @param string $initializer
* @param string $valueHolder
* @param string $callParent
*
* @return void
*/
private function setInitializerBody(string $initializer, string $valueHolder, string $callParent)
{
$this->setBody(
'$this->' . $initializer . ' && $this->' . $initializer
. '->__invoke($this->' . $valueHolder . ', $this, \'__get\', [\'name\' => $name], $this->'
. $initializer . ');'
. "\n\n" . $callParent
);
}
}

View File

@@ -0,0 +1,79 @@
<?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\LazyLoadingValueHolder\MethodGenerator;
use ProxyManager\Generator\MagicMethodGenerator;
use Zend\Code\Generator\ParameterGenerator;
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
use ReflectionClass;
use Zend\Code\Generator\PropertyGenerator;
/**
* Magic `__isset` method for lazy loading value holder objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MagicIsset extends MagicMethodGenerator
{
/**
* Constructor
*
* @param ReflectionClass $originalClass
* @param PropertyGenerator $initializerProperty
* @param PropertyGenerator $valueHolderProperty
* @param PublicPropertiesMap $publicProperties
*/
public function __construct(
ReflectionClass $originalClass,
PropertyGenerator $initializerProperty,
PropertyGenerator $valueHolderProperty,
PublicPropertiesMap $publicProperties
) {
parent::__construct($originalClass, '__isset', [new ParameterGenerator('name')]);
$initializer = $initializerProperty->getName();
$valueHolder = $valueHolderProperty->getName();
$callParent = '';
$this->setDocblock(($originalClass->hasMethod('__isset') ? "{@inheritDoc}\n" : '') . '@param string $name');
if (! $publicProperties->isEmpty()) {
$callParent = 'if (isset(self::$' . $publicProperties->getName() . "[\$name])) {\n"
. ' return isset($this->' . $valueHolder . '->$name);'
. "\n}\n\n";
}
$callParent .= PublicScopeSimulator::getPublicAccessSimulationCode(
PublicScopeSimulator::OPERATION_ISSET,
'name',
null,
$valueHolderProperty
);
$this->setBody(
'$this->' . $initializer . ' && $this->' . $initializer
. '->__invoke($this->' . $valueHolder . ', $this, \'__isset\', array(\'name\' => $name), $this->'
. $initializer . ');' . "\n\n" . $callParent
);
}
}

View File

@@ -0,0 +1,87 @@
<?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\LazyLoadingValueHolder\MethodGenerator;
use ProxyManager\Generator\MagicMethodGenerator;
use Zend\Code\Generator\ParameterGenerator;
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
use ReflectionClass;
use Zend\Code\Generator\PropertyGenerator;
/**
* Magic `__set` for lazy loading value holder objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MagicSet extends MagicMethodGenerator
{
/**
* Constructor
*
* @param ReflectionClass $originalClass
* @param PropertyGenerator $initializerProperty
* @param PropertyGenerator $valueHolderProperty
* @param PublicPropertiesMap $publicProperties
*/
public function __construct(
ReflectionClass $originalClass,
PropertyGenerator $initializerProperty,
PropertyGenerator $valueHolderProperty,
PublicPropertiesMap $publicProperties
) {
parent::__construct(
$originalClass,
'__set',
[new ParameterGenerator('name'), new ParameterGenerator('value')]
);
$hasParent = $originalClass->hasMethod('__set');
$initializer = $initializerProperty->getName();
$valueHolder = $valueHolderProperty->getName();
$callParent = '';
$this->setDocblock(($hasParent ? "{@inheritDoc}\n" : '') . "@param string \$name\n@param mixed \$value");
if (! $publicProperties->isEmpty()) {
$callParent = 'if (isset(self::$' . $publicProperties->getName() . "[\$name])) {\n"
. ' return ($this->' . $valueHolder . '->$name = $value);'
. "\n}\n\n";
}
$callParent .= $hasParent
? 'return $this->' . $valueHolder . '->__set($name, $value);'
: PublicScopeSimulator::getPublicAccessSimulationCode(
PublicScopeSimulator::OPERATION_SET,
'name',
'value',
$valueHolderProperty
);
$this->setBody(
'$this->' . $initializer . ' && $this->' . $initializer
. '->__invoke($this->' . $valueHolder . ', $this, '
. '\'__set\', array(\'name\' => $name, \'value\' => $value), $this->' . $initializer . ');'
. "\n\n" . $callParent
);
}
}

View File

@@ -0,0 +1,59 @@
<?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\LazyLoadingValueHolder\MethodGenerator;
use ProxyManager\Generator\MagicMethodGenerator;
use ReflectionClass;
use Zend\Code\Generator\PropertyGenerator;
/**
* Magic `__sleep` for lazy loading value holder objects
*
* @author Marco Pivetta <ocramius@gmail.com>
* @license MIT
*/
class MagicSleep extends MagicMethodGenerator
{
/**
* Constructor
*
* @param ReflectionClass $originalClass
* @param PropertyGenerator $initializerProperty
* @param PropertyGenerator $valueHolderProperty
*/
public function __construct(
ReflectionClass $originalClass,
PropertyGenerator $initializerProperty,
PropertyGenerator $valueHolderProperty
) {
parent::__construct($originalClass, '__sleep');
$initializer = $initializerProperty->getName();
$valueHolder = $valueHolderProperty->getName();
$this->setBody(
'$this->' . $initializer . ' && $this->' . $initializer
. '->__invoke($this->' . $valueHolder . ', $this, \'__sleep\', array(), $this->'
. $initializer . ');' . "\n\n"
. 'return array(' . var_export($valueHolder, true) . ');'
);
}
}

Some files were not shown because too many files have changed in this diff Show More