public function testManyToOneAssociation()
 {
     $association1 = new TestAssociation1();
     $association1->setField1('a');
     $association2 = new TestAssociation1();
     $association2->setField1('b');
     $collection = new ArrayCollection(array($association1, $association2));
     $this->dataObject1->setAssociation2($collection);
     $emMock = Mockery::mock('Doctrine\\ORM\\EntityManagerInterface');
     $classMetaDataMock = Mockery::mock('Doctrine\\ORM\\Mapping\\ClassMetadata');
     $emMock->shouldReceive('getClassMetadata')->andReturn($classMetaDataMock);
     $classMetaDataMock->shouldReceive('getAssociationNames')->andReturn(array('association1', 'association2'));
     $sut = new ProxyManager($emMock);
     $proxy = $sut->transform($this->dataObject1);
     $this->assertTrue($proxy->getAssociation2() instanceof ArrayCollection);
     $this->assertEquals(2, count($proxy->getAssociation2()));
     $item1 = $proxy->getAssociation2()[0];
     $item2 = $proxy->getAssociation2()[1];
     $this->assertTrue($item1 instanceof TestAssociationProxy1);
     $this->assertEquals('a', $item1->getField1());
     $this->assertTrue($item2 instanceof TestAssociationProxy1);
     $this->assertEquals('b', $item2->getField1());
 }
Beispiel #2
0
 /**
  * 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;
 }