/** * Verifies that proxies generated from different factories will retain their specific implementation * and won't conflict * * @dataProvider getTestedClasses */ public function testCanGenerateMultipleDifferentProxiesForSameClass($className) { $skipScopeLocalizerTests = false; $ghostProxyFactory = new LazyLoadingGhostFactory(); $virtualProxyFactory = new LazyLoadingValueHolderFactory(); $accessInterceptorFactory = new AccessInterceptorValueHolderFactory(); $accessInterceptorScopeLocalizerFactory = new AccessInterceptorScopeLocalizerFactory(); $initializer = function () { }; $reflectionClass = new ReflectionClass($className); if (!method_exists('Closure', 'bind') && $reflectionClass->getProperties(ReflectionProperty::IS_PRIVATE)) { $skipScopeLocalizerTests = true; } $generated = array($ghostProxyFactory->createProxy($className, $initializer), $virtualProxyFactory->createProxy($className, $initializer), $accessInterceptorFactory->createProxy(new $className())); if (!$skipScopeLocalizerTests) { $generated[] = $accessInterceptorScopeLocalizerFactory->createProxy(new $className()); } foreach ($generated as $key => $proxy) { $this->assertInstanceOf($className, $proxy); foreach ($generated as $comparedKey => $comparedProxy) { if ($comparedKey === $key) { continue; } $this->assertNotSame(get_class($comparedProxy), get_class($proxy)); } } $this->assertInstanceOf('ProxyManager\\Proxy\\GhostObjectInterface', $generated[0]); $this->assertInstanceOf('ProxyManager\\Proxy\\VirtualProxyInterface', $generated[1]); $this->assertInstanceOf('ProxyManager\\Proxy\\AccessInterceptorInterface', $generated[2]); $this->assertInstanceOf('ProxyManager\\Proxy\\ValueHolderInterface', $generated[2]); if (!$skipScopeLocalizerTests) { $this->assertInstanceOf('ProxyManager\\Proxy\\AccessInterceptorInterface', $generated[3]); } }
/** * @param $class * @param $id * @return \ProxyManager\Proxy\VirtualProxyInterface */ public function getService($class, $id) { $container = $this->container; return $this->factory->createProxy($class, function (&$wrappedObject, $proxy, $method, $parameters, &$initializer) use($container, $id) { $wrappedObject = $container->get($id); $initializer = null; }); }
/** * {@inheritdoc} */ public function instantiateProxy(ContainerInterface $container, Definition $definition, $id, $realInstantiator) { return $this->factory->createProxy($definition->getClass(), function (&$wrappedInstance, LazyLoadingInterface $proxy) use($realInstantiator) { $wrappedInstance = call_user_func($realInstantiator); $proxy->setProxyInitializer(null); return true; }); }
private function createAliasProxy(LifecycleEventArgs $args, Node $node) { $factory = new LazyLoadingValueHolderFactory(); return $factory->createProxy(Alias::class, function (&$wrappedObject, $proxy, $method, $parameters, &$initializer) use($args, $node) { $wrappedObject = $args->getObjectManager()->getRepository('ClasticAliasBundle:Alias')->findOneBy(array('node' => $node)); $initializer = null; return true; }); }
/** * {@inheritdoc} */ public function createProxy($className, callable $initializerCallback) { if ($this->proxyFactory === null) { return $initializerCallback(); } return $this->proxyFactory->createProxy($className, function (&$wrappedObject, $proxy, $method, $parameters, &$initializer) use($initializerCallback) { $wrappedObject = $initializerCallback($proxy, $method, $parameters); $initializer = null; }); }
/** * @param $name * @return AbstractRepository */ public function getRepository($name) { $configuration = $this->getProxyFactoryConfiguration(); $factory = new LazyLoadingValueHolderFactory($configuration); $initializer = function (&$wrappedObject, LazyLoadingInterface $proxy, $method, array $parameters, &$initializer) use($name) { $initializer = null; $wrappedObject = $this->getEntityManager()->getRepository($name); return true; }; return $factory->createProxy('PhraseanetSDK\\Repository\\' . ucfirst($name), $initializer); }
/** * @param string $className * @param callable $definition * * @return VirtualProxyInterface * * @throws \InvalidArgumentException When $definition callable doesn't return $className instance */ public function getLazyServiceDefinition($className, callable $definition) { return $this->lazyLoadingFactory->createProxy($className, function (&$wrappedObject, $proxy, $method, $parameters, &$initializer) use($className, $definition) { $wrappedObject = call_user_func($definition); $initializer = null; // extra defensive programming in action if (!$wrappedObject instanceof $className) { throw new \InvalidArgumentException(sprintf('Object "%s" is not instance of "%s"', is_object($wrappedObject) ? get_class($wrappedObject) : gettype($wrappedObject), $className)); } return true; }); }
/** * @param Schema $fromSchema * @return Schema */ public function createToSchema(Schema $fromSchema) { $originalSchemaManipulator = $this->originalSchemaManipulator; if ($fromSchema instanceof LazyLoadingInterface && !$fromSchema->isProxyInitialized()) { return $this->proxyFactory->createProxy(Schema::class, function (&$wrappedObject, $proxy, $method, array $parameters, &$initializer) use($originalSchemaManipulator, $fromSchema) { $initializer = null; $wrappedObject = $originalSchemaManipulator->createToSchema($fromSchema); return true; }); } return $this->originalSchemaManipulator->createToSchema($fromSchema); }
/** * {@inheritDoc} * * @return \ProxyManager\Proxy\VirtualProxyInterface */ public function __invoke(ContainerInterface $container, $name, callable $callback, array $options = null) { $initializer = function (&$wrappedInstance, LazyLoadingInterface $proxy) use($callback) { $proxy->setProxyInitializer(null); $wrappedInstance = $callback(); return true; }; if (isset($this->servicesMap[$name])) { return $this->proxyFactory->createProxy($this->servicesMap[$name], $initializer); } throw new Exception\ServiceNotFoundException(sprintf('The requested service "%s" was not found in the provided services map', $name)); }
/** * @param $contactHandle * @return Contact proxy object */ public function build($contactHandle) { $factory = new LazyLoadingValueHolderFactory(); $initializer = function (&$wrappedObject, LazyLoadingInterface $proxy, $method, array $parameters, &$initializer) use($contactHandle) { $initializer = null; // disable further initialization $result = $this->contactAPI->get($contactHandle); $wrappedObject = (new Contact($contactHandle))->setId($result['id'])->setCompany($result['orgname'])->setType($result['type'])->setVatNumber($result['vat_number'])->setFirstName($result['given'])->setLastName($result['family'])->setStreet($result['streetaddr'])->setZip($result['zip'])->setCity($result['city'])->setCountry($result['country'])->setEmail($result['email'])->setPhone($result['phone'])->setMobile($result['mobile'])->setFax($result['fax'])->setLanguage($result['lang'])->setHideAddress($result['data_obfuscated'])->setHideEmail($result['mail_obfuscated']); return true; // confirm that initialization occurred correctly }; return $factory->createProxy('EdsiTech\\GandiBundle\\Model\\Contact', $initializer); }
/** * {@inheritDoc} * * @return object|\ProxyManager\Proxy\LazyLoadingInterface|\ProxyManager\Proxy\ValueHolderInterface */ public function createDelegatorWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName, $callback) { $initializer = function (&$wrappedInstance, LazyLoadingInterface $proxy) use($callback) { $proxy->setProxyInitializer(null); $wrappedInstance = call_user_func($callback); return true; }; if (isset($this->servicesMap[$requestedName])) { return $this->proxyFactory->createProxy($this->servicesMap[$requestedName], $initializer); } elseif (isset($this->servicesMap[$name])) { return $this->proxyFactory->createProxy($this->servicesMap[$name], $initializer); } throw new Exception\InvalidServiceNameException(sprintf('The requested service "%s" was not found in the provided services map', $requestedName)); }
/** * Returns Proxy Document for uuid. * * @param string $uuid * @param string $locale * * @return object */ private function getResource($uuid, $locale) { return $this->proxyFactory->createProxy(PageDocument::class, function (&$wrappedObject, LazyLoadingInterface $proxy, $method, array $parameters, &$initializer) use($uuid, $locale) { $initializer = null; $wrappedObject = $this->documentManager->find($uuid, $locale); return true; }); }
/** * @param $domainName * @return Domain proxy object */ public function build($domainName) { $factory = new LazyLoadingValueHolderFactory(); $initializer = function (&$wrappedObject, LazyLoadingInterface $proxy, $method, array $parameters, &$initializer) use($domainName) { $initializer = null; // disable further initialization $wrappedObject = new Domain($domainName); $result = $this->domainAPI->getInfo($wrappedObject); $wrappedObject->setAuthInfo($result['authinfo'])->setNameservers($result['nameservers'])->setAutorenew($result['autorenew']['active'])->setTld($result['tld'])->setStatus($result['status'])->setOwnerContact(new Contact($result['contacts']['owner']['handle']))->setAdminContact(new Contact($result['contacts']['admin']['handle']))->setBillContact(new Contact($result['contacts']['bill']['handle']))->setTechContact(new Contact($result['contacts']['tech']['handle']))->setResellerContact(new Contact($result['contacts']['reseller']['handle']))->setCreated(new \DateTime($result['date_registry_creation']))->setUpdated(new \DateTime($result['date_updated']))->setExpire(new \DateTime($result['date_registry_end'])); $wrappedObject->setLock(false); foreach ($result['status'] as $status) { if ('clientTransferProhibited' == $status) { $wrappedObject->setLock(true); } } return true; // confirm that initialization occurred correctly }; return $factory->createProxy('EdsiTech\\GandiBundle\\Model\\Domain', $initializer); }
/** * Returns a proxy instance * * @param ClassDefinition $definition * @param array $parameters * * @return object Proxy instance */ private function createProxy(ClassDefinition $definition, array $parameters) { // waiting for PHP 5.4+ support $resolver = $this; /** @noinspection PhpUnusedParameterInspection */ $proxy = $this->proxyFactory->createProxy($definition->getClassName(), function (&$wrappedObject, $proxy, $method, $parameters, &$initializer) use($resolver, $definition, $parameters) { $wrappedObject = $resolver->createInstance($definition, $parameters); $initializer = null; // turning off further lazy initialization return true; }); return $proxy; }
public function create($hiddenServiceName, $proxyClassName) { $container = $this->container; /** * @var object $wrappedObject the instance (passed by reference) of the wrapped object, * set it to your real object * @var object $proxy the instance proxy that is being initialized * @var string $method the name of the method that triggered lazy initialization * @var string $parameters an ordered list of parameters passed to the method that * triggered initialization, indexed by parameter name * @var \Closure $initializer a reference to the property that is the initializer for the * proxy. Set it to null to disable further initialization * * @return bool true on success */ $initializer = function (&$wrappedObject, $proxy, $method, $parameters, &$initializer) use($container, $hiddenServiceName) { $wrappedObject = $container->getService($hiddenServiceName); $initializer = null; return true; }; return $this->proxyFactory->createProxy($proxyClassName, $initializer); }
/** * @param array $user * * @return \DanielBadura\Redmine\Api\Struct\User|\ProxyManager\Proxy\VirtualProxyInterface */ public function user(array $user) { $userRepository = $this->client->getUserRepository(); $userStruct = $this->getIdentity($user, $userRepository); if ($userStruct !== null) { return $userStruct; } $factory = new LazyLoadingValueHolderFactory(); $initializer = function (&$wrappedObject, LazyLoadingInterface $proxy, $method) use($user, $userRepository) { if ($method == 'getId' || $method == 'getName') { if (!$wrappedObject) { $wrappedObject = new User($user['id'], $user['name']); } } else { $wrappedObject = $userRepository->find($user['id']); $proxy->setProxyInitializer(null); $userRepository->getMap()->setIdentity($wrappedObject->getId(), $wrappedObject); } return true; }; $user = $factory->createProxy('DanielBadura\\Redmine\\Api\\Struct\\User', $initializer); return $user; }
/** * Will create a symfony route. * * @param RouteInterface $route * @param Request $request * * @return Route */ protected function createRoute(RouteInterface $route, Request $request) { $routePath = $this->requestAnalyzer->getResourceLocatorPrefix() . $route->getPath(); if ($route->isHistory()) { return new Route($routePath, ['_controller' => 'SuluWebsiteBundle:Redirect:redirect', 'url' => $request->getSchemeAndHttpHost() . $this->requestAnalyzer->getResourceLocatorPrefix() . $route->getTarget()->getPath() . ($request->getQueryString() ? '?' . $request->getQueryString() : '')]); } $symfonyRoute = $this->proxyFactory->createProxy(Route::class, function (&$wrappedObject, LazyLoadingInterface $proxy, $method, array $parameters, &$initializer) use($routePath, $route, $request) { $initializer = null; // disable initialization $wrappedObject = new Route($routePath, $this->routeDefaultsProvider->getByEntity($route->getEntityClass(), $route->getEntityId(), $request->getLocale())); return true; }); return $this->symfonyRouteCache[$route->getId()] = $symfonyRoute; }
public function testDownload() { $mimeType = 'application/json'; $size = 999; $data = $this->generateString(200); $fileName = tempnam('', 'splitter-test-file'); file_put_contents($fileName, $data); $fileHash = 'my-hash'; $chunk1 = new Chunk(); $chunk1->setHash('hash1'); $chunk1->setData(substr($data, 0, 100)); $chunk2 = new Chunk(); $chunk2->setHash('hash2'); $chunk2->setData(substr($data, 100, 100)); $file = new ChunkFile(); $file->setHash($fileHash); $file->setChunks(array($chunk1, $chunk2)); $file->setMimeType($mimeType); $file->setSize($size); $fileSplitter = new FileSplitter(100); $chunkManager = $this->prophesize(ChunkManagerInterface::class); $factory = $this->prophesize(FactoryInterface::class); $proxyFactory = new LazyLoadingValueHolderFactory(); $chunkManager->upload()->should(new NoCallsPrediction()); $chunkManager->download()->should(new NoCallsPrediction()); $chunkManager->downloadProxy($chunk1->getHash())->willReturn($chunk1); $chunkManager->downloadProxy($chunk2->getHash())->willReturn($chunk2); $factory->createHash()->should(new NoCallsPrediction()); $factory->createFileHash()->should(new NoCallsPrediction()); $factory->createProxy(Argument::type('string'), Argument::type('callable'))->will(function ($args) use($proxyFactory) { return $proxyFactory->createProxy($args[0], $args[1]); }); $manager = new ChunkFileManager($fileSplitter, $chunkManager->reveal(), $factory->reveal()); $result = $manager->download($fileHash, array($chunk1->getHash(), $chunk2->getHash()), $mimeType, $size); $this->assertEquals($file->getHash(), $result->getHash()); $this->assertEquals($file->getChunks(), $result->getChunks()); $this->assertEquals($mimeType, $result->getMimeType()); $this->assertEquals($size, $result->getSize()); }
<?php require_once __DIR__ . '/../vendor/autoload.php'; use ProxyManager\Factory\LazyLoadingValueHolderFactory; class Foo { public function __construct() { sleep(5); } public function doFoo() { echo "Foo!"; } } $startTime = microtime(true); $factory = new LazyLoadingValueHolderFactory(); for ($i = 0; $i < 1000; $i += 1) { $proxy = $factory->createProxy('Foo', function (&$wrappedObject, $proxy, $method, $parameters, &$initializer) { $initializer = null; $wrappedObject = new Foo(); return true; }); } var_dump('time after 1000 instantiations: ' . (microtime(true) - $startTime)); $proxy->doFoo(); var_dump('time after single call to doFoo: ' . (microtime(true) - $startTime));
/** * {@inheritDoc} * * @covers \ProxyManager\Factory\LazyLoadingValueHolderFactory::__construct * @covers \ProxyManager\Factory\LazyLoadingValueHolderFactory::createProxy * @covers \ProxyManager\Factory\LazyLoadingValueHolderFactory::getGenerator * * NOTE: serious mocking going on in here (a class is generated on-the-fly) - careful */ public function testWillTryAutoGeneration() { $className = UniqueIdentifierGenerator::getIdentifier('foo'); $proxyClassName = UniqueIdentifierGenerator::getIdentifier('bar'); $generator = $this->getMock('ProxyManager\\GeneratorStrategy\\GeneratorStrategyInterface'); $autoloader = $this->getMock('ProxyManager\\Autoloader\\AutoloaderInterface'); $this->config->expects($this->any())->method('getGeneratorStrategy')->will($this->returnValue($generator)); $this->config->expects($this->any())->method('getProxyAutoloader')->will($this->returnValue($autoloader)); $generator->expects($this->once())->method('generate')->with($this->callback(function (ClassGenerator $targetClass) use($proxyClassName) { return $targetClass->getName() === $proxyClassName; })); // simulate autoloading $autoloader->expects($this->once())->method('__invoke')->with($proxyClassName)->will($this->returnCallback(function () use($proxyClassName) { eval('class ' . $proxyClassName . ' extends \\ProxyManagerTestAsset\\LazyLoadingMock {}'); })); $this->inflector->expects($this->once())->method('getProxyClassName')->with($className)->will($this->returnValue($proxyClassName)); $this->inflector->expects($this->once())->method('getUserClassName')->with($className)->will($this->returnValue('ProxyManagerTestAsset\\LazyLoadingMock')); $factory = new LazyLoadingValueHolderFactory($this->config); $initializer = function () { }; /* @var $proxy \ProxyManagerTestAsset\LazyLoadingMock */ $proxy = $factory->createProxy($className, $initializer); $this->assertInstanceOf($proxyClassName, $proxy); $this->assertSame($initializer, $proxy->initializer); }
/** * @param string $uuid * @return Task */ public function getReference($uuid) { if (isset($this->tasks[$uuid])) { return $this->tasks[$uuid]; } $factory = new LazyLoadingValueHolderFactory(); $initializer = function (&$wrappedObject, LazyLoadingInterface $proxy, $method) use($uuid) { if ('getUuid' == $method) { if (!$wrappedObject) { $wrappedObject = new UuidContainer($uuid); } } else { $proxy->setProxyInitializer(null); $wrappedObject = $this->exportOne($uuid); } }; $task = $factory->createProxy(Task::class, $initializer); return $this->tasks[$uuid] = $task; }
/** * Creates a new lazy proxy instance of the given class with * the given initializer. * * @param string $className name of the class to be proxied * @param \Closure $initializer initializer to be passed to the proxy * * @return \ProxyManager\Proxy\LazyLoadingInterface */ public function createProxy($className, \Closure $initializer) { $this->createProxyManager(); return $this->proxyManager->createProxy($className, $initializer); }
/** * Transform Entity to proxy object * * @param $objSrc * @return mixed * @throws \Exception */ public function transform($objSrc) { // No need to transform scalar or null values if (is_scalar($objSrc) || is_null($objSrc)) { return $objSrc; } $objSrcData = $this->hydrator->extract($objSrc); $objSrcClass = $this->annotationReader->getDoctrineProxyResolver()->unwrapDoctrineProxyClass(get_class($objSrc)); $proxyClass = $this->annotationReader->getProxyTargetClass(get_class($objSrc)); if (!$proxyClass) { return $objSrc; } if ($proxyClass != $objSrcClass) { $doctrineAnnotations = $this->annotationReader->getDoctrineAnnotations($this->class); $associations = $doctrineAnnotations->getAssociationNames(); /** * Lazy Load Associations */ foreach ($associations as $key) { if (isset($objSrcData[$key])) { $propertyValue = $objSrcData[$key]; $factory = new LazyLoadingValueHolderFactory(); $initializer = function (&$wrappedObject, LazyLoadingInterface $proxy, $method, array $parameters, &$initializer) use($propertyValue) { $initializer = null; if ($propertyValue instanceof ArrayCollection) { $items = array(); foreach ($propertyValue as $item) { $items[] = $this->proxyManager->transform($item); } $wrappedObject = new ArrayCollection($items); } else { $wrappedObject = $this->proxyManager->transform($propertyValue); } return true; }; // check if property final $reflectionClass = new \ReflectionClass(get_class($propertyValue)); if ($reflectionClass->isFinal()) { $objSrcData[$key] = $propertyValue; } else { if ($propertyValue instanceof Collection) { $objSrcData[$key] = $factory->createProxy(get_class($propertyValue), $initializer); } else { $objSrcData[$key] = $factory->createProxy($this->annotationReader->getProxyTargetClass(get_class($propertyValue)), $initializer); } } } } $objDest = $this->proxyManager->instantiate($proxyClass); /** * Throw Exceptions */ if (!$objDest instanceof $objSrcClass) { throw new \Exception('The proxy target class should extend the underlying data object. Proxy Class: ' . $proxyClass); } if (!$this->isProxy($objDest)) { throw new \Exception('The proxy target class should use the Proxy trait. Proxy Class: ' . $proxyClass); } /** * Hydrate the data */ $this->hydrate($objSrcData, $objDest); /** * Sync Properties */ $syncProperties = $this->annotationReader->getProxySyncedProperties($this->class); if ($syncProperties == Constants::SYNC_PROPERTIES_ALL) { $syncProperties = array_keys($objSrcData); } /** * Sync Methods */ $syncMethods = $this->annotationReader->getProxySyncMethods($this->class); if ($syncMethods == Constants::SYNC_METHODS_ALL) { $syncMethods = array(); foreach (array_keys($objSrcData) as $property) { $syncMethods[] = Inflector::camelize('set_' . $property); } foreach ($associations as $associationKey => $association) { $associationKey = Inflector::singularize($associationKey); $associationKeyPlural = Inflector::pluralize($associationKey); $syncMethods[] = Inflector::camelize('add_' . $associationKey); $syncMethods[] = Inflector::camelize('remove_' . $associationKey); $syncMethods[] = Inflector::camelize('set_' . $associationKeyPlural); $syncMethods[] = Inflector::camelize('set_' . $associationKey); } } elseif ($syncMethods == Constants::SYNC_METHODS_NONE) { $syncMethods = array(); } /** * Set properties on proxied object */ PropertyAccess::set($objDest, 'dataObject', $objSrc); PropertyAccess::set($objDest, 'transformer', $this); PropertyAccess::set($objDest, 'syncProperties', $syncProperties); PropertyAccess::set($objDest, 'syncMethods', $syncMethods); /** * Attach Interceptors */ $factory = new Factory(); $proxy = $factory->createProxy($objDest, array()); foreach ($syncMethods as $syncMethod) { $proxy->setMethodSuffixInterceptor($syncMethod, function ($proxy, $instance) use($syncMethod) { $syncMethods = PropertyAccess::get($instance, 'syncMethods'); if (is_array($syncMethods) && in_array($syncMethod, $syncMethods)) { $instance->syncData(); } }); } return $proxy; } return $objSrc; }
/** * Get an argument proxy for a given alias to provide to the injector. * * @since 0.2.0 * * @param string $alias Alias that needs the argument. * @param string $interface Interface that the proxy implements. * @param callable $callable Callable used to initialize the proxy. * * @return object Argument proxy to provide to the inspector. */ protected function getArgumentProxy($alias, $interface, $callable) { if (null === $interface) { $interface = 'stdClass'; } $factory = new LazyLoadingValueHolderFactory(); $initializer = function (&$wrappedObject, LazyLoadingInterface $proxy, $method, array $parameters, &$initializer) use($alias, $interface, $callable) { $initializer = null; $wrappedObject = $callable($alias, $interface); return true; }; return $factory->createProxy($interface, $initializer); }