/**
  *
  * @param Properties $properties
  *
  * @return int[][]|mixed[][]
  */
 private function getMap(Properties $properties)
 {
     $map = [];
     foreach ($properties->getProtectedProperties() as $property) {
         $map[$property->getName()] = $property->getDeclaringClass()->getName();
     }
     return $map;
 }
 /**
  * @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;
 }
 /**
  * @param Properties $properties
  */
 public function __construct(Properties $properties)
 {
     parent::__construct(UniqueIdentifierGenerator::getIdentifier('publicProperties'));
     foreach ($properties->getPublicProperties() as $publicProperty) {
         $this->publicProperties[$publicProperty->getName()] = true;
     }
     $this->setDefaultValue($this->publicProperties);
     $this->setVisibility(self::VISIBILITY_PRIVATE);
     $this->setStatic(true);
     $this->setDocblock('@var bool[] map of public properties of the parent class');
 }
 /**
  * @param Properties $properties
  *
  * @return string
  */
 private function generateUnsetPropertiesCode(Properties $properties)
 {
     $code = '';
     if ($accessibleProperties = $properties->getAccessibleProperties()) {
         $code .= $this->getUnsetPropertiesGroupCode($accessibleProperties) . "\n";
     }
     foreach ($properties->getGroupedPrivateProperties() as $className => $privateProperties) {
         $cacheKey = 'cache' . str_replace('\\', '_', $className);
         $code .= 'static $' . $cacheKey . ";\n\n" . '$' . $cacheKey . ' ?: $' . $cacheKey . " = \\Closure::bind(function (\$instance) {\n" . '    ' . $this->getUnsetPropertiesGroupCode($privateProperties) . '}, null, ' . var_export($className, true) . ");\n\n" . '$' . $cacheKey . "(\$instance);\n\n";
     }
     return $code;
 }
 /**
  * Constructor
  *
  * @param ReflectionClass   $originalClass Reflection of the class to proxy
  * @param PropertyGenerator $adapter       Adapter property
  */
 public function __construct(ReflectionClass $originalClass, PropertyGenerator $adapter)
 {
     $adapterName = $adapter->getName();
     parent::__construct('staticProxyConstructor', [new ParameterGenerator($adapterName, AdapterInterface::class)], MethodGenerator::FLAG_PUBLIC | MethodGenerator::FLAG_STATIC, null, 'Constructor for remote object control\\n\\n' . '@param \\ProxyManager\\Factory\\RemoteObject\\AdapterInterface \\$adapter');
     $body = 'static $reflection;' . "\n\n" . '$reflection = $reflection ?: $reflection = new \\ReflectionClass(__CLASS__);' . "\n" . '$instance = (new \\ReflectionClass(get_class()))->newInstanceWithoutConstructor();' . "\n\n" . '$instance->' . $adapterName . ' = $' . $adapterName . ";\n\n" . UnsetPropertiesGenerator::generateSnippet(Properties::fromReflectionClass($originalClass), 'instance');
     $this->setBody($body . "\n\nreturn \$instance;");
 }
Example #6
0
 /**
  * @param ReflectionClass $class
  *
  * @return string
  */
 private static function getUnsetPropertiesString(ReflectionClass $class)
 {
     $unsetProperties = implode("\n    ", array_map(function (ReflectionProperty $unsetProperty) {
         return 'unset($this->' . $unsetProperty->getName() . ');';
     }, Properties::fromReflectionClass($class)->getPublicProperties()));
     return $unsetProperties ? "\n    " . $unsetProperties . "\n" : '';
 }
Example #7
0
 /**
  * Constructor
  *
  * @param ReflectionClass $originalClass
  */
 public function __construct(ReflectionClass $originalClass)
 {
     parent::__construct($originalClass, '__wakeup');
     $unsetProperties = array_map(function (ReflectionProperty $property) {
         return '$this->' . $property->getName();
     }, Properties::fromReflectionClass($originalClass)->getPublicProperties());
     $this->setBody($unsetProperties ? 'unset(' . implode(', ', $unsetProperties) . ");" : '');
 }
Example #8
0
 /**
  * Constructor
  *
  * @param ReflectionClass   $originalClass
  * @param PropertyGenerator $valueHolder
  *
  * @return self
  */
 public static function generateMethod(ReflectionClass $originalClass, PropertyGenerator $valueHolder) : self
 {
     $originalConstructor = self::getConstructor($originalClass);
     $constructor = $originalConstructor ? self::fromReflection($originalConstructor) : new self('__construct');
     $constructor->setDocblock('{@inheritDoc}');
     $constructor->setBody('static $reflection;' . "\n\n" . 'if (! $this->' . $valueHolder->getName() . ') {' . "\n" . '    $reflection = $reflection ?: new \\ReflectionClass(' . var_export($originalClass->getName(), true) . ");\n" . '    $this->' . $valueHolder->getName() . ' = $reflection->newInstanceWithoutConstructor();' . "\n" . UnsetPropertiesGenerator::generateSnippet(Properties::fromReflectionClass($originalClass), 'this') . "}" . self::generateOriginalConstructorCall($originalClass, $valueHolder));
     return $constructor;
 }
 /**
  * Constructor
  *
  * @param ReflectionClass $originalClass Reflection of the class to proxy
  */
 public function __construct(ReflectionClass $originalClass)
 {
     parent::__construct('staticProxyConstructor', [], static::FLAG_PUBLIC | static::FLAG_STATIC);
     $nullableProperties = array_map(function (ReflectionProperty $publicProperty) {
         return '$instance->' . $publicProperty->getName() . ' = null;';
     }, Properties::fromReflectionClass($originalClass)->getPublicProperties());
     $this->setDocblock("Constructor for null object initialization");
     $this->setBody('static $reflection;' . "\n\n" . '$reflection = $reflection ?: $reflection = new \\ReflectionClass(__CLASS__);' . "\n" . '$instance = (new \\ReflectionClass(get_class()))->newInstanceWithoutConstructor();' . "\n\n" . ($nullableProperties ? implode("\n", $nullableProperties) . "\n\n" : '') . 'return $instance;');
 }
 /**
  * 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;");
 }
 /**
  * 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;');
 }
 /**
  * {@inheritDoc}
  */
 public function generate(ReflectionClass $originalClass, ClassGenerator $classGenerator)
 {
     CanProxyAssertion::assertClassCanBeProxied($originalClass);
     $interfaces = [VirtualProxyInterface::class];
     $publicProperties = new PublicPropertiesMap(Properties::fromReflectionClass($originalClass));
     if ($originalClass->isInterface()) {
         $interfaces[] = $originalClass->getName();
     } else {
         $classGenerator->setExtendedClass($originalClass->getName());
     }
     $classGenerator->setImplementedInterfaces($interfaces);
     $classGenerator->addPropertyFromGenerator($valueHolder = new ValueHolderProperty());
     $classGenerator->addPropertyFromGenerator($initializer = new InitializerProperty());
     $classGenerator->addPropertyFromGenerator($publicProperties);
     array_map(function (MethodGenerator $generatedMethod) use($originalClass, $classGenerator) {
         ClassGeneratorUtils::addMethodIfNotFinal($originalClass, $classGenerator, $generatedMethod);
     }, array_merge(array_map($this->buildLazyLoadingMethodInterceptor($initializer, $valueHolder), ProxiedMethodsFilter::getProxiedMethods($originalClass)), [new StaticProxyConstructor($initializer, Properties::fromReflectionClass($originalClass)), Constructor::generateMethod($originalClass, $valueHolder), new MagicGet($originalClass, $initializer, $valueHolder, $publicProperties), new MagicSet($originalClass, $initializer, $valueHolder, $publicProperties), new MagicIsset($originalClass, $initializer, $valueHolder, $publicProperties), new MagicUnset($originalClass, $initializer, $valueHolder, $publicProperties), new MagicClone($originalClass, $initializer, $valueHolder), new MagicSleep($originalClass, $initializer, $valueHolder), new MagicWakeup($originalClass), new SetProxyInitializer($initializer), new GetProxyInitializer($initializer), new InitializeProxy($initializer, $valueHolder), new IsProxyInitialized($valueHolder), new GetWrappedValueHolderValue($valueHolder)]));
 }
 /**
  * {@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)]));
 }
 /**
  * {@inheritDoc}
  */
 public function generate(ReflectionClass $originalClass, ClassGenerator $classGenerator)
 {
     CanProxyAssertion::assertClassCanBeProxied($originalClass);
     $publicProperties = new PublicPropertiesMap(Properties::fromReflectionClass($originalClass));
     $interfaces = [AccessInterceptorInterface::class, ValueHolderInterface::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(function (ReflectionMethod $method) use($prefixInterceptors, $suffixInterceptors, $valueHolder) {
         return InterceptedMethod::generateMethod(new MethodReflection($method->getDeclaringClass()->getName(), $method->getName()), $valueHolder, $prefixInterceptors, $suffixInterceptors);
     }, 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)]));
 }
Example #15
0
 /**
  * @param Properties $properties
  *
  * @return string
  */
 private function propertiesReferenceArrayCode(Properties $properties)
 {
     $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;
 }
Example #16
0
 /**
  * Constructor
  *
  * @param ReflectionClass $originalClass
  */
 public function __construct(ReflectionClass $originalClass)
 {
     parent::__construct($originalClass, '__wakeup');
     $this->setBody(UnsetPropertiesGenerator::generateSnippet(Properties::fromReflectionClass($originalClass), 'this'));
 }