/** * @param MessageInterface $object * @param array $data * * @return MessageInterface */ private function _doHydrate(MessageInterface $object, $data) { $reflected = new \ReflectionClass($object); if ($object instanceof MessageCollectionInterface && $object instanceof ArrayCollectionInterface) { foreach ($data->{$object->getDataMemberName()} as $singleData) { $class = $object->createChildClass(); $object->add($this->_doHydrate($class, $singleData)); } } foreach ($data as $key => $value) { if ($reflected->hasProperty($key)) { $property = $reflected->getProperty($key); $setter = $this->generateSetter($key); $doc = new DocBlock($property); if ($doc->hasTag('var')) { $tags = $doc->getTagsByName('var'); if (count($tags) !== 1) { throw new RuntimeException('Property "' . $property->getName() . '" of class ' . $property->getDeclaringClass() . 'has more @var tags. Only one is allowed.'); } $type = $tags[0]->getType(); switch (true) { /** * Internal type Enum */ /*case $type === '\\Enum': $getter = $this->generateGetter($key); $object->{$getter}()->setValue($value); break;*/ /** * All basic types */ case in_array(strtolower($type), $this->basicTypes, false): $object->{$setter}($value); break; /** * Object types - special cases first */ /** * Object types - special cases first */ case $type === '\\DateTime': $class = new \DateTime($value); $object->{$setter}($class); break; case $type === '\\DateTimeZone': if (empty($value)) { continue; } $class = new \DateTimeZone($value); $object->{$setter}($class); break; case !is_array($value) && class_exists($type, true): $class = new $type($value); $object->{$setter}($class); break; /** * Try to find class and hydrate object */ /** * Try to find class and hydrate object */ default: $possibleClassNames = []; $possibleClassNames[] = $this->baseNS . $type; $possibleClassNames[] = $reflected->getNamespaceName() . $type; $possibleClassNames[] = $type; foreach ($possibleClassNames as $className) { if (class_exists($className, true)) { $class = new $className(); $hydrated = $this->_doHydrate($class, $value); $object->{$setter}($hydrated); continue 2; } } /** * Class not found, we use raw $value. */ $object->{$setter}($value); break; } } } elseif ($key === '_links') { foreach ($value as $link) { $object->addMethod($link->method, $link->rel, $link->href); } } } return $object; }