Alfredao

ObjectHydrator

Feb 11th, 2014
208
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 5.47 KB | None | 0 0
  1. <?php
  2.  
  3. namespace Application\Hydrator;
  4.  
  5. use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
  6. use Application\Hydrator\Strategy\Datetime as DateTimeStrategy;
  7. use Zend\Stdlib\Hydrator\Strategy\StrategyInterface;
  8.  
  9. class ObjectHydrator extends DoctrineHydrator
  10. {
  11.  
  12.     /**
  13.      *
  14.      * @var \Zend\Stdlib\Hydrator\Strategy\StrategyInterface
  15.      */
  16.     protected $dateTimeStrategy;
  17.    
  18.     /**
  19.      * Hydrate the object using a by-value logic (this means that it uses the entity API, in this
  20.      * case, setters)
  21.      *
  22.      * @param  array  $data
  23.      * @param  object $object
  24.      * @throws RuntimeException
  25.      * @return object
  26.      */
  27.     protected function hydrateByValue(array $data, $object)
  28.     {
  29.         $tryObject = $this->tryConvertArrayToObject($data, $object);
  30.         $metadata  = $this->metadata;
  31.  
  32.         if (is_object($tryObject)) {
  33.             $object = $tryObject;
  34.         }
  35.  
  36.         foreach ($data as $field => $value) {
  37.             $value  = $this->handleTypeConversions($value, $field);
  38.             $setter = 'set' . ucfirst($field);
  39.  
  40.             if ($metadata->hasAssociation($field)) {
  41.                 $target = $metadata->getAssociationTargetClass($field);
  42.  
  43.                 if ($metadata->isSingleValuedAssociation($field)) {
  44.                     if (! method_exists($object, $setter)) {
  45.                         continue;
  46.                     }
  47.  
  48.                     $value = $this->toOne($target, $this->hydrateValue($field, $value, $data));
  49.  
  50.                     if (null === $value
  51.                         && !current($metadata->getReflectionClass()->getMethod($setter)->getParameters())->allowsNull()
  52.                     ) {
  53.                         continue;
  54.                     }
  55.  
  56.                     $object->$setter($value);
  57.                 } elseif ($metadata->isCollectionValuedAssociation($field)) {
  58.                     $this->toMany($object, $field, $target, $value);
  59.                 }
  60.             } else {
  61.                 if (! method_exists($object, $setter)) {
  62.                     continue;
  63.                 }
  64.  
  65.                 $object->$setter($this->hydrateValue($field, $value, $data));
  66.             }
  67.         }
  68.  
  69.         return $object;
  70.     }
  71.  
  72.     /**
  73.      * Hydrate the object using a by-reference logic (this means that values are modified directly without
  74.      * using the public API, in this case setters, and hence override any logic that could be done in those
  75.      * setters)
  76.      *
  77.      * @param  array  $data
  78.      * @param  object $object
  79.      * @return object
  80.      */
  81.     protected function hydrateByReference(array $data, $object)
  82.     {
  83.         $tryObject   = $this->tryConvertArrayToObject($data, $object);
  84.         $metadata = $this->metadata;
  85.         $refl     = $metadata->getReflectionClass();
  86.  
  87.         if (is_object($tryObject)) {
  88.             $object = $tryObject;
  89.         }
  90.  
  91.         foreach ($data as $field => $value) {
  92.             // Ignore unknown fields
  93.             if (!$refl->hasProperty($field)) {
  94.                 continue;
  95.             }
  96.  
  97.             $value        = $this->handleTypeConversions($value, $field);
  98.             $reflProperty = $refl->getProperty($field);
  99.             $reflProperty->setAccessible(true);
  100.  
  101.             if ($metadata->hasAssociation($field)) {
  102.                 $target = $metadata->getAssociationTargetClass($field);
  103.  
  104.                 if ($metadata->isSingleValuedAssociation($field)) {
  105.                     $value = $this->toOne($target, $this->hydrateValue($field, $value, $data));
  106.                     $reflProperty->setValue($object, $value);
  107.                 } elseif ($metadata->isCollectionValuedAssociation($field)) {
  108.                     $this->toMany($object, $field, $target, $value);
  109.                 }
  110.             } else {
  111.                 $reflProperty->setValue($object, $this->hydrateValue($field, $value, $data));
  112.             }
  113.         }
  114.  
  115.         return $object;
  116.     }
  117.  
  118.  
  119.     /**
  120.      * Handle various type conversions that should be supported natively by Doctrine (like DateTime)
  121.      *
  122.      * @param  mixed  $value
  123.      * @param  string $typeOfField
  124.      * @return DateTime
  125.      */
  126.     protected function handleTypeConversions($value, $field)
  127.     {
  128.         switch($this->metadata->getTypeOfField($field)) {
  129.             case 'datetimetz':
  130.             case 'datetime':
  131.             case 'time':
  132.             case 'date':
  133.                 if ('' === $value) {
  134.                     return null;
  135.                 }
  136.  
  137.                 if (is_int($value)) {
  138.                     $dateTime = new DateTime();
  139.                     $dateTime->setTimestamp($value);
  140.                     $value = $dateTime;
  141.                 } elseif (is_string($value) && $this->hasStrategy($field)) {
  142.                     $value = $this->getStrategy($field)->hydrate($value);
  143.                 } else {
  144.                     $value = $this->getDateTimeStrategy()->hydrate($value);
  145.                 }
  146.  
  147.                 break;
  148.             default:
  149.         }
  150.  
  151.         return $value;
  152.     }
  153.  
  154.     /**
  155.      *
  156.      * @return StrategyInterface
  157.      */
  158.     public function getDateTimeStrategy()
  159.     {
  160.         return $this->dateTimeStrategy ?: $this->dateTimeStrategy = new DateTimeStrategy();
  161.     }
  162.  
  163.     /**
  164.      *
  165.      * @param StrategyInterface $dateTimeStrategy
  166.      * @return \Application\Hydrator\ObjectHydrator
  167.      */
  168.     public function setDateTimeStrategy(StrategyInterface $dateTimeStrategy)
  169.     {
  170.         $this->dateTimeStrategy = $dateTimeStrategy;
  171.         return $this;
  172.     }
  173.    
  174. }
Advertisement
Add Comment
Please, Sign In to add comment