/** * Returns a collection of objects * * @param string $class The class of objects to fetch * @param string $url The URL to retrieve * @param mixed $parent The parent service/object * @return OpenCloud\Common\Collection */ public function collection($class, $url = null, $parent = null) { // Set the element names $collectionName = $class::JsonCollectionName(); $elementName = $class::JsonCollectionElement(); // Set the parent if empty if (!$parent) { $parent = $this; } // Set the URL if empty if (!$url) { $url = $parent->getUrl($class::resourceName()); } // Fetch the list $response = $this->getClient()->get($url)->send(); // Handle empty response $object = $response->getDecodedBody(); // @codeCoverageIgnoreStart if (empty($object)) { return new Collection($parent, $class, array()); } // See if there's a "next" link // Note: not sure if the current API offers links as top-level structures might have to refactor to allow // $nextPageUrl as method argument if (isset($object->links) && is_array($object->links)) { foreach ($object->links as $link) { if (isset($link->rel) && $link->rel == 'next') { if (isset($link->href)) { $nextPageUrl = $link->href; } else { $this->getLogger()->warning('Unexpected [links] found with no [href]'); } } } } // @codeCoverageIgnoreEnd // How should we populate the collection? $data = array(); if (!$collectionName || is_array($object)) { // No element name, just a plain object/array // @codeCoverageIgnoreStart $data = (array) $object; // @codeCoverageIgnoreEnd } elseif (isset($object->{$collectionName})) { if (!$elementName) { // The object has a top-level collection name only $data = $object->{$collectionName}; } else { // The object has element levels which need to be iterated over $data = array(); foreach ($object->{$collectionName} as $item) { $subValues = $item->{$elementName}; unset($item->{$elementName}); $data[] = array_merge((array) $item, (array) $subValues); } } } $collectionObject = new Collection($parent, $class, $data); // if there's a $nextPageUrl, then we need to establish a callback // @codeCoverageIgnoreStart if (!empty($nextPageUrl)) { $collectionObject->setNextPageCallback(array($this, 'Collection'), $nextPageUrl); } // @codeCoverageIgnoreEnd return $collectionObject; }
/** * returns a collection of objects * * @param string $class the class of objects to fetch * @param string $url (optional) the URL to retrieve * @param mixed $parent (optional) the parent service/object * @return OpenCloud\Common\Collection */ public function collection($class, $url = null, $parent = null) { // Set the element names $collectionName = $class::JsonCollectionName(); $elementName = $class::JsonCollectionElement(); // Set the parent if empty if (!$parent) { $parent = $this; } // Set the URL if empty if (!$url) { $url = $parent->url($class::ResourceName()); } // Save debug info $this->getLogger()->info('{class}:Collection({url}, {collectionClass}, {collectionName})', array('class' => get_class($this), 'url' => $url, 'collectionClass' => $class, 'collectionName' => $collectionName)); // Fetch the list $response = $this->request($url); $this->getLogger()->info('Response {status} [{body}]', array('status' => $response->httpStatus(), 'body' => $response->httpBody())); // Check return code if ($response->httpStatus() > 204) { throw new Exceptions\CollectionError(sprintf(Lang::translate('Unable to retrieve [%s] list from [%s], status [%d] response [%s]'), $class, $url, $response->httpStatus(), $response->httpBody())); } // Handle empty response if (strlen($response->httpBody()) == 0) { return new Collection($parent, $class, array()); } // Parse the return $object = json_decode($response->httpBody()); $this->checkJsonError(); // See if there's a "next" link // Note: not sure if the current API offers links as top-level structures; // might have to refactor to allow $nextPageUrl as method argument // @codeCoverageIgnoreStart if (isset($object->links) && is_array($object->links)) { foreach ($object->links as $link) { if (isset($link->rel) && $link->rel == 'next') { if (isset($link->href)) { $nextPageUrl = $link->href; } else { $this->getLogger()->warning('Unexpected [links] found with no [href]'); } } } } // @codeCoverageIgnoreEnd // How should we populate the collection? $data = array(); if (!$collectionName) { // No element name, just a plain object // @codeCoverageIgnoreStart $data = $object; // @codeCoverageIgnoreEnd } elseif (isset($object->{$collectionName})) { if (!$elementName) { // The object has a top-level collection name only $data = $object->{$collectionName}; } else { // The object has element levels which need to be iterated over $data = array(); foreach ($object->{$collectionName} as $item) { $subValues = $item->{$elementName}; unset($item->{$elementName}); $data[] = array_merge((array) $item, (array) $subValues); } } } $collectionObject = new Collection($parent, $class, $data); // if there's a $nextPageUrl, then we need to establish a callback // @codeCoverageIgnoreStart if (!empty($nextPageUrl)) { $collectionObject->setNextPageCallback(array($this, 'Collection'), $nextPageUrl); } // @codeCoverageIgnoreEnd return $collectionObject; }
/** * returns a collection of objects * * @param string $class the class of objects to fetch * @param string $url (optional) the URL to retrieve * @param mixed $parent (optional) the parent service/object * @param array $parm (optional) array of key/value pairs to use as * query strings * @return \OpenCloud\Collection */ public function Collection($class, $url = null, $parent = null, array $parm = array()) { // set the element name $collection = $class::JsonCollectionName(); $element = $class::JsonCollectionElement(); // save the parent if (!isset($parent)) { $parent = $this; } // determine the URL if (!$url) { $url = $parent->Url($class::ResourceName()); } // add query string parameters if (count($parm)) { $url .= '?' . $this->MakeQueryString($parm); } // save debug info $this->debug('%s:Collection(%s, %s, %s)', get_class($this), $url, $class, $collection); // fetch the list $response = $this->Request($url); $this->debug('response %d [%s]', $response->HttpStatus(), $response->HttpBody()); // check return code if ($response->HttpStatus() > 204) { throw new Exceptions\CollectionError(sprintf(Lang::translate('Unable to retrieve [%s] list from [%s], status [%d] response [%s]'), $class, $url, $response->HttpStatus(), $response->HttpBody())); } // handle empty response if (strlen($response->HttpBody()) == 0) { return new Collection($parent, $class, array()); } // parse the return $obj = json_decode($response->HttpBody()); if ($this->CheckJsonError()) { return false; } // see if there is a "next" link if (isset($obj->links)) { if (is_array($obj->links)) { foreach ($obj->links as $link) { if (isset($link->rel) && $link->rel == 'next') { if (isset($link->href)) { $next_page_url = $link->href; } else { throw new Exceptions\DomainError(Lang::translate('unexpected [links] found with no [href]')); } } } } } // and say goodbye if (!$collection) { $coll_obj = new Collection($parent, $class, $obj); } elseif (isset($obj->{$collection})) { if (!$element) { $coll_obj = new Collection($parent, $class, $obj->{$collection}); } else { // handle element levels $arr = array(); foreach ($obj->{$collection} as $index => $item) { $arr[] = $item->{$element}; } $coll_obj = new Collection($parent, $class, $arr); } } else { $coll_obj = new Collection($parent, $class, array()); } // if there's a $next_page_url, then we need to establish a // callback method if (isset($next_page_url)) { $coll_obj->SetNextPageCallback(array($this, 'Collection'), $next_page_url); } return $coll_obj; }