/** * @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; }
/** * @param $object * @param $options * @return Uri * @throws Exception */ private function prepareEndpointUri(MessageInterface $object, array $options) { $endpoint = $object->getEndpoint(); $defaultParams = $object->getDefaultParams(); $params = array_key_exists('params', $options) ? $options['params'] : []; if (substr($endpoint, 0, 4) !== 'http') { $endpoint = $this->apiUri . $endpoint; } $params = array_merge($params, $defaultParams); foreach ($params as $key => $value) { $endpoint = str_replace('{' . $key . '}', $value, $endpoint); } if (preg_match('/.*{.*}.*/', $endpoint)) { throw new Exception('Not all endpoint parameters was replaced: ' . $endpoint); } $uri = new Uri($endpoint); if (array_key_exists('paging', $options)) { $paging = $options['paging']; if (array_key_exists('offset', $paging)) { if (!is_numeric($paging['offset']) || $paging['offset'] < 0) { throw new RuntimeException('Paging offset cam be only positive number and 0.'); } $uri = Uri::withQueryValue($uri, 'offset', $paging['offset']); } if (array_key_exists('count', $paging)) { if (!is_numeric($paging['count']) || $paging['count'] < 1) { throw new RuntimeException('Paging count cam be only positive number.'); } $uri = Uri::withQueryValue($uri, 'count', $paging['count']); } } if (array_key_exists('fields', $options)) { if (is_array($options['fields'])) { $fields = implode(',', $options['fields']); } else { $fields = $options['fields']; } $uri = Uri::withQueryValue($uri, 'fields', $fields); } if (array_key_exists('exclude_fields', $options)) { if (array_key_exists('fields', $options)) { throw new RuntimeException('You can not use "fields" and "exclude_fields" in one API query.'); } if (is_array($options['exclude_fields'])) { $exclude_fields = implode(',', $options['exclude_fields']); } else { $exclude_fields = $options['exclude_fields']; } $uri = Uri::withQueryValue($uri, 'exclude_fields', $exclude_fields); } return $uri; }