/** * 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]); } }
/** * Create a new proxy object from the given document for * the given target node. * * TODO: We only pass the document here in order to correctly evaluate its locale * later. I wonder if it necessary. * * @param object $fromDocument * @param NodeInterface $targetNode * * @return \ProxyManager\Proxy\GhostObjectInterface */ public function createProxyForNode($fromDocument, NodeInterface $targetNode) { $eventDispatcher = $this->dispatcher; $registry = $this->registry; $targetMetadata = $this->metadataFactory->getMetadataForPhpcrNode($targetNode); // if node is already registered then just return the registered document if ($this->registry->hasNode($targetNode)) { $document = $this->registry->getDocumentForNode($targetNode); $locale = $registry->getOriginalLocaleForDocument($fromDocument); // If the parent is not loaded in the correct locale, reload it in the correct locale. if ($registry->getOriginalLocaleForDocument($document) !== $locale) { $hydrateEvent = new HydrateEvent($targetNode, $locale); $hydrateEvent->setDocument($document); $this->dispatcher->dispatch(Events::HYDRATE, $hydrateEvent); } return $document; } $initializer = function (LazyLoadingInterface $document, $method, array $parameters, &$initializer) use($fromDocument, $targetNode, $eventDispatcher, $registry) { $locale = $registry->getOriginalLocaleForDocument($fromDocument); $hydrateEvent = new HydrateEvent($targetNode, $locale); $hydrateEvent->setDocument($document); $eventDispatcher->dispatch(Events::HYDRATE, $hydrateEvent); $initializer = null; }; $proxy = $this->proxyFactory->createProxy($targetMetadata->getClass(), $initializer); $locale = $registry->getOriginalLocaleForDocument($fromDocument); $this->registry->registerDocument($proxy, $targetNode, $locale); return $proxy; }
public function createService(ServiceLocatorInterface $serviceLocator) { /** @var ServiceLocatorInterface $serviceLocator */ $serviceLocator = $serviceLocator->getServiceLocator(); $proxyConfig = $serviceLocator->get('ProxyManager\\Configuration'); $factory = new LazyLoadingGhostFactory($proxyConfig); $proxy = $factory->createProxy('SampleService\\Controller\\UserController', function ($proxy, $method, $parameters, &$initializer) use($serviceLocator) { static $flag = array(); if (isset($flag[$method])) { return; } $flag[$method] = true; /** @var \SampleService\Controller\UserController $proxy */ if ($method == 'getFilterForm') { $proxy->setFilterForm($serviceLocator->get('FormElementManager')->get('SampleService\\Form\\FilterForm')); } elseif ($method == 'getUserService') { $proxy->setUserService($serviceLocator->get('SampleService\\Service\\UserService')); } elseif ($method == 'getUserFilterService') { $proxy->setUserFilterService($serviceLocator->get('SampleService\\Service\\UserFilterService')); } }); return $proxy; }
/** * createProxy * * @param string $id * @access public * @return object */ public function createProxy($id) { $key = $this->mapping->getKeyFromId($id); $classMetadata = $this->mapping->getClassMetadataByKey($key); $modelName = $classMetadata->getModelName(); $sdk = $this; if ($this->proxyManagerConfig) { $factory = new LazyLoadingGhostFactory($this->proxyManagerConfig); } else { $factory = new LazyLoadingGhostFactory(); } $initializer = function (LazyLoadingInterface &$proxy, $method, array $parameters, &$initializer) use($sdk, $classMetadata, $id) { if ($method !== 'getId' && $method !== 'setId' && $method !== 'jsonSerialize') { $initializer = null; // disable initialization // load data and modify the object here if ($id) { $repository = $sdk->getRepository($classMetadata->getModelName()); $model = $repository->find($id); $attributeList = $classMetadata->getAttributeList(); foreach ($attributeList as $attribute) { $getter = 'get' . ucfirst($attribute->getName()); $setter = 'set' . ucfirst($attribute->getName()); $value = $model->{$getter}(); $proxy->{$setter}($value); } } return true; // confirm that initialization occurred correctly } }; $instance = $factory->createProxy($modelName, $initializer); $instance->setId($id); return $instance; }
/** * {@inheritDoc} * * @covers \ProxyManager\Factory\LazyLoadingGhostFactory::__construct * @covers \ProxyManager\Factory\LazyLoadingGhostFactory::createProxy * @covers \ProxyManager\Factory\LazyLoadingGhostFactory::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')); $this->signatureChecker->expects($this->atLeastOnce())->method('checkSignature'); $this->classSignatureGenerator->expects($this->once())->method('addSignature')->will($this->returnArgument(0)); $factory = new LazyLoadingGhostFactory($this->config); $initializer = function () { }; /* @var $proxy \ProxyManagerTestAsset\LazyLoadingMock */ $proxy = $factory->createProxy($className, $initializer); $this->assertInstanceOf($proxyClassName, $proxy); $this->assertSame($initializer, $proxy->initializer); }
require_once __DIR__ . '/../vendor/autoload.php'; use ProxyManager\Factory\LazyLoadingGhostFactory; class Foo { private $foo; public function __construct() { sleep(5); } public function setFoo($foo) { $this->foo = (string) $foo; } public function getFoo() { return $this->foo; } } $startTime = microtime(true); $factory = new LazyLoadingGhostFactory(); for ($i = 0; $i < 1000; $i += 1) { $proxy = $factory->createProxy('Foo', function ($proxy, $method, $parameters, &$initializer) { $initializer = null; $proxy->setFoo('Hello World!'); return true; }); } var_dump('time after 1000 instantiations: ' . (microtime(true) - $startTime)); echo $proxy->getFoo() . "\n"; var_dump('time after single call to doFoo: ' . (microtime(true) - $startTime));