public function collections() { if (($this->method == 'POST' || $this->method == 'PUT') && !$this->body) { $this->e400("{$this->method} data not provided"); } $collections = array(); // Single collection if (($this->objectID || $this->objectKey) && $this->subset != 'collections') { $this->allowMethods(array('GET', 'PUT', 'DELETE')); // If id, redirect to key URL if ($this->objectID) { $this->allowMethods(array('GET')); $collection = Zotero_Collections::get($this->objectLibraryID, $this->objectID); if (!$collection) { $this->e404("Collection not found"); } $qs = !empty($_SERVER['QUERY_STRING']) ? '?' . $_SERVER['QUERY_STRING'] : ''; header("Location: " . Zotero_API::getCollectionURI($collection) . $qs); exit; } $collection = Zotero_Collections::getByLibraryAndKey($this->objectLibraryID, $this->objectKey); if (!$collection) { $this->e404("Collection not found"); } // In single-collection mode, require public pref to be enabled if (!$this->permissions->canAccess($this->objectLibraryID)) { $this->e403(); } if ($this->method == 'PUT' || $this->method == 'DELETE') { if (!$this->permissions->canWrite($this->objectLibraryID)) { $this->e403("Write access denied"); } if (!Z_CONFIG::$TESTING_SITE || empty($_GET['skipetag'])) { if (empty($_SERVER['HTTP_IF_MATCH'])) { $this->e400("If-Match header not provided"); } if (!preg_match('/^"?([a-f0-9]{32})"?$/', $_SERVER['HTTP_IF_MATCH'], $matches)) { $this->e400("Invalid ETag in If-Match header"); } if ($collection->etag != $matches[1]) { $this->e412("ETag does not match current version of collection"); } } if ($this->method == 'PUT') { $obj = $this->jsonDecode($this->body); Zotero_Collections::updateFromJSON($collection, $obj); $this->queryParams['format'] = 'atom'; $this->queryParams['content'] = array('json'); if ($cacheKey = $this->getWriteTokenCacheKey()) { Z_Core::$MC->set($cacheKey, true, $this->writeTokenCacheTime); } } else { Zotero_Collections::delete($this->objectLibraryID, $this->objectKey, true); $this->e204(); } } $this->responseXML = Zotero_Collections::convertCollectionToAtom($collection, $this->queryParams['content']); } else { $this->allowMethods(array('GET', 'POST')); if (!$this->permissions->canAccess($this->objectLibraryID)) { $this->e403(); } if ($this->scopeObject) { $this->allowMethods(array('GET')); switch ($this->scopeObject) { case 'collections': // If id, redirect to key URL if ($this->scopeObjectID) { $collection = Zotero_Collections::get($this->objectLibraryID, $this->scopeObjectID); if (!$collection) { $this->e404("Collection not found"); } $qs = !empty($_SERVER['QUERY_STRING']) ? '?' . $_SERVER['QUERY_STRING'] : ''; header("Location: " . Zotero_API::getCollectionURI($collection) . $qs); exit; } $collection = Zotero_Collections::getByLibraryAndKey($this->objectLibraryID, $this->scopeObjectKey); if (!$collection) { $this->e404("Collection not found"); } $title = "Child Collections of ‘{$collection->name}'’"; $collectionIDs = $collection->getChildCollections(); break; default: throw new Exception("Invalid collections scope object '{$this->scopeObject}'"); } } else { // Top-level items if ($this->subset == 'top') { $this->allowMethods(array('GET')); $title = "Top-Level Collections"; $results = Zotero_Collections::getAllAdvanced($this->objectLibraryID, true, $this->queryParams); } else { // Create a collection if ($this->method == 'POST') { if (!$this->permissions->canWrite($this->objectLibraryID)) { $this->e403("Write access denied"); } $obj = $this->jsonDecode($this->body); $collection = Zotero_Collections::addFromJSON($obj, $this->objectLibraryID); if ($cacheKey = $this->getWriteTokenCacheKey()) { Z_Core::$MC->set($cacheKey, true, $this->writeTokenCacheTime); } $uri = Zotero_API::getCollectionURI($collection); $queryString = "content=json"; if ($this->apiKey) { $queryString .= "&key=" . $this->apiKey; } $uri .= "?" . $queryString; $this->queryParams = Zotero_API::parseQueryParams($queryString, $this->action, true); } $title = "Collections"; $results = Zotero_Collections::getAllAdvanced($this->objectLibraryID, false, $this->queryParams); } $collections = $results['collections']; $totalResults = $results['total']; } if (!empty($collectionIDs)) { foreach ($collectionIDs as $collectionID) { $collections[] = Zotero_Collections::get($this->objectLibraryID, $collectionID); } // Fake sorting and limiting $totalResults = sizeOf($collections); $key = $this->queryParams['order']; if ($key == 'title') { $key = 'name'; } $dir = $this->queryParams['sort']; usort($collections, function ($a, $b) use($key, $dir) { $dir = $dir == "asc" ? 1 : -1; if ($a->{$key} == $b->{$key}) { return 0; } else { return $a->{$key} > $b->{$key} ? $dir : $dir * -1; } }); $collections = array_slice($collections, $this->queryParams['start'], $this->queryParams['limit']); } $this->responseXML = Zotero_Atom::createAtomFeed($this->getFeedNamePrefix($this->objectLibraryID) . $title, $this->uri, $collections, $totalResults, $this->queryParams, $this->apiVersion, $this->permissions); } $this->end(); }