Beispiel #1
0
	/**
	 * Returns all collections the item is in
	 *
	 * @param boolean [$asKeys=false] Return collection keys instead of collection objects
	 * @return array Array of Zotero_Collection objects, or keys if $asKeys=true
	 */
	public function getCollections($asKeys=false) {
		if (!$this->loaded['collections']) {
			$this->loadCollections();
		}
		if ($asKeys) {
			return $this->collections;
		}
		return array_map(function ($key) {
			return Zotero_Collections::getByLibraryAndKey(
				$this->libraryID, $key, true
			);
		}, $this->collections);
	}
Beispiel #2
0
 /**
  * Recursively save collections from the top down
  */
 private static function saveCollections($collections, $userID)
 {
     $originalLength = sizeOf($collections);
     $unsaved = array();
     $toSave = array();
     for ($i = 0, $len = sizeOf($collections); $i < $len; $i++) {
         $toSave[$collections[$i]->key] = true;
     }
     for ($i = 0; $i < sizeOf($collections); $i++) {
         $collection = $collections[$i];
         $key = $collection->key;
         $parentKey = $collection->parentKey;
         // Top-level collection, so save
         if (!$parentKey) {
             $collection->save($userID);
             unset($toSave[$key]);
             continue;
         }
         $parentCollection = Zotero_Collections::getByLibraryAndKey($collection->libraryID, $parentKey);
         // Parent collection exists and doesn't need to be saved, so save
         if ($parentCollection && empty($toSave[$parentCollection->key])) {
             $collection->save($userID);
             unset($toSave[$key]);
             continue;
         }
         // Add to unsaved list
         $unsaved[] = $collection;
         continue;
     }
     if ($unsaved) {
         if ($originalLength == sizeOf($unsaved)) {
             throw new Exception("Incomplete collection hierarchy cannot be saved", Z_ERROR_COLLECTION_NOT_FOUND);
         }
         self::saveCollections($unsaved, $userID);
     }
 }
    public function tags()
    {
        $this->allowMethods(array('GET'));
        if (!$this->permissions->canAccess($this->objectLibraryID)) {
            $this->e403();
        }
        $tags = array();
        $totalResults = 0;
        $name = $this->objectName;
        $fixedValues = array();
        // Set of tags matching name
        if ($name && $this->subset != 'tags') {
            $tagIDs = Zotero_Tags::getIDs($this->objectLibraryID, $name);
            if (!$tagIDs) {
                $this->e404();
            }
            $title = "Tags matching ‘" . $name . "’";
        } else {
            if ($this->scopeObject) {
                // If id, redirect to key URL
                if ($this->scopeObjectID) {
                    if (!in_array($this->scopeObject, array("collections", "items"))) {
                        $this->e400();
                    }
                    $className = 'Zotero_' . ucwords($this->scopeObject);
                    $obj = call_user_func(array($className, 'get'), $this->objectLibraryID, $this->scopeObjectID);
                    if (!$obj) {
                        $this->e404("Scope " . substr($this->scopeObject, 0, -1) . " not found");
                    }
                    $base = call_user_func(array('Zotero_API', 'get' . substr(ucwords($this->scopeObject), 0, -1) . 'URI'), $obj);
                    $qs = !empty($_SERVER['QUERY_STRING']) ? '?' . $_SERVER['QUERY_STRING'] : '';
                    header("Location: " . $base . "/tags" . $qs);
                    exit;
                }
                switch ($this->scopeObject) {
                    case 'collections':
                        $collection = Zotero_Collections::getByLibraryAndKey($this->objectLibraryID, $this->scopeObjectKey);
                        if (!$collection) {
                            $this->e404();
                        }
                        $title = "Tags in Collection ‘" . $collection->name . "’";
                        $counts = $collection->getTagItemCounts();
                        $tagIDs = array();
                        if ($counts) {
                            foreach ($counts as $tagID => $count) {
                                $tagIDs[] = $tagID;
                                $fixedValues[$tagID] = array('numItems' => $count);
                            }
                        }
                        break;
                    case 'items':
                        $item = Zotero_Items::getByLibraryAndKey($this->objectLibraryID, $this->scopeObjectKey);
                        if (!$item) {
                            $this->e404();
                        }
                        $title = "Tags of '" . $item->getDisplayTitle() . "'";
                        $tagIDs = $item->getTags(true);
                        break;
                    default:
                        throw new Exception("Invalid tags scope object '{$this->scopeObject}'");
                }
            } else {
                $title = "Tags";
                $results = Zotero_Tags::getAllAdvanced($this->objectLibraryID, $this->queryParams);
                $tags = $results['objects'];
                $totalResults = $results['total'];
            }
        }
        if (!empty($tagIDs)) {
            foreach ($tagIDs as $tagID) {
                $tags[] = Zotero_Tags::get($this->objectLibraryID, $tagID);
            }
            // Fake sorting and limiting
            $totalResults = sizeOf($tags);
            $key = $this->queryParams['order'];
            // 'title' order means 'name' for tags
            if ($key == 'title') {
                $key = 'name';
            }
            $dir = $this->queryParams['sort'];
            $cmp = create_function('$a, $b', '$dir = "' . $dir . '" == "asc" ? 1 : -1;
				if ($a->' . $key . ' == $b->' . $key . ') {
					return 0;
				}
				else {
					return ($a->' . $key . ' > $b->' . $key . ') ? $dir : ($dir * -1);}');
            usort($tags, $cmp);
            $tags = array_slice($tags, $this->queryParams['start'], $this->queryParams['limit']);
        }
        $this->responseXML = Zotero_Atom::createAtomFeed($this->getFeedNamePrefix($this->objectLibraryID) . $title, $this->uri, $tags, $totalResults, $this->queryParams, $this->apiVersion, $this->permissions, $fixedValues);
        $this->end();
    }
Beispiel #4
0
    /**
     * Returns an array of descendent collections and items
     *	(rows of 'id', 'type' ('item' or 'collection'), 'parent', and,
     * 	if collection, 'name' and the nesting 'level')
     *
     * @param	bool		$recursive	Descend into subcollections
     * @param	bool		$nested		Return multidimensional array with 'children'
     *									nodes instead of flat array
     * @param	string	$type		'item', 'collection', or FALSE for both
     */
    public function getChildren($recursive = false, $nested = false, $type = false, $level = 1)
    {
        $toReturn = array();
        // 0 == collection
        // 1 == item
        $children = Zotero_DB::query('SELECT collectionID AS id, 
				0 AS type, collectionName AS collectionName, `key`
				FROM collections WHERE parentCollectionID=?
				UNION SELECT itemID AS id, 1 AS type, NULL AS collectionName, `key`
				FROM collectionItems JOIN items USING (itemID) WHERE collectionID=?', array($this->id, $this->id), Zotero_Shards::getByLibraryID($this->libraryID));
        if ($type) {
            switch ($type) {
                case 'item':
                case 'collection':
                    break;
                default:
                    throw "Invalid type '{$type}'";
            }
        }
        for ($i = 0, $len = sizeOf($children); $i < $len; $i++) {
            // This seems to not work without parseInt() even though
            // typeof children[i]['type'] == 'number' and
            // children[i]['type'] === parseInt(children[i]['type']),
            // which sure seems like a bug to me
            switch ($children[$i]['type']) {
                case 0:
                    if (!$type || $type == 'collection') {
                        $toReturn[] = array('id' => $children[$i]['id'], 'name' => $children[$i]['collectionName'], 'key' => $children[$i]['key'], 'type' => 'collection', 'level' => $level, 'parent' => $this->id);
                    }
                    if ($recursive) {
                        $col = Zotero_Collections::getByLibraryAndKey($this->libraryID, $children[$i]['key']);
                        $descendents = $col->getChildren(true, $nested, $type, $level + 1);
                        if ($nested) {
                            $toReturn[sizeOf($toReturn) - 1]['children'] = $descendents;
                        } else {
                            for ($j = 0, $len2 = sizeOf($descendents); $j < $len2; $j++) {
                                $toReturn[] = $descendents[$j];
                            }
                        }
                    }
                    break;
                case 1:
                    if (!$type || $type == 'item') {
                        $toReturn[] = array('id' => $children[$i]['id'], 'key' => $children[$i]['key'], 'type' => 'item', 'parent' => $this->id);
                    }
                    break;
            }
        }
        return $toReturn;
    }
 public function collections()
 {
     // Check for general library access
     if (!$this->permissions->canAccess($this->objectLibraryID)) {
         $this->e403();
     }
     if ($this->isWriteMethod()) {
         // Check for library write access
         if (!$this->permissions->canWrite($this->objectLibraryID)) {
             $this->e403("Write access denied");
         }
         // Make sure library hasn't been modified
         if (!$this->singleObject) {
             $libraryTimestampChecked = $this->checkLibraryIfUnmodifiedSinceVersion();
         }
         Zotero_Libraries::updateVersionAndTimestamp($this->objectLibraryID);
     }
     $collectionIDs = array();
     $collectionKeys = array();
     $results = array();
     // Single collection
     if ($this->singleObject) {
         $this->allowMethods(['HEAD', 'GET', 'PUT', 'PATCH', 'DELETE']);
         if (!Zotero_ID::isValidKey($this->objectKey)) {
             $this->e404();
         }
         $collection = Zotero_Collections::getByLibraryAndKey($this->objectLibraryID, $this->objectKey);
         if ($this->isWriteMethod()) {
             $collection = $this->handleObjectWrite('collection', $collection ? $collection : null);
             $this->queryParams['content'] = ['json'];
         }
         if (!$collection) {
             $this->e404("Collection not found");
         }
         $this->libraryVersion = $collection->version;
         if ($this->method == 'HEAD') {
             $this->end();
         }
         switch ($this->queryParams['format']) {
             case 'atom':
                 $this->responseXML = Zotero_Collections::convertCollectionToAtom($collection, $this->queryParams);
                 break;
             case 'json':
                 $json = $collection->toResponseJSON($this->queryParams, $this->permissions);
                 echo Zotero_Utilities::formatJSON($json);
                 break;
             default:
                 throw new Exception("Unexpected format '" . $this->queryParams['format'] . "'");
         }
     } else {
         $this->allowMethods(['HEAD', 'GET', 'POST', 'DELETE']);
         $this->libraryVersion = Zotero_Libraries::getUpdatedVersion($this->objectLibraryID);
         if ($this->scopeObject) {
             $this->allowMethods(array('GET'));
             switch ($this->scopeObject) {
                 case 'collections':
                     $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::search($this->objectLibraryID, true, $this->queryParams);
             } else {
                 // Create a collection
                 if ($this->method == 'POST') {
                     $this->queryParams['format'] = 'writereport';
                     $obj = $this->jsonDecode($this->body);
                     $results = Zotero_Collections::updateMultipleFromJSON($obj, $this->queryParams, $this->objectLibraryID, $this->userID, $this->permissions, $libraryTimestampChecked ? 0 : 1, null);
                     if ($cacheKey = $this->getWriteTokenCacheKey()) {
                         Z_Core::$MC->set($cacheKey, true, $this->writeTokenCacheTime);
                     }
                     if ($this->apiVersion < 2) {
                         $uri = Zotero_API::getCollectionsURI($this->objectLibraryID);
                         $keys = array_merge(get_object_vars($results['success']), get_object_vars($results['unchanged']));
                         $queryString = "collectionKey=" . urlencode(implode(",", $keys)) . "&format=atom&content=json&order=collectionKeyList&sort=asc";
                         if ($this->apiKey) {
                             $queryString .= "&key=" . $this->apiKey;
                         }
                         $uri .= "?" . $queryString;
                         $this->queryParams = Zotero_API::parseQueryParams($queryString, $this->action, true, $this->apiVersion);
                         $title = "Collections";
                         $results = Zotero_Collections::search($this->objectLibraryID, false, $this->queryParams);
                     }
                 } else {
                     if ($this->method == 'DELETE') {
                         Zotero_DB::beginTransaction();
                         foreach ($this->queryParams['collectionKey'] as $collectionKey) {
                             Zotero_Collections::delete($this->objectLibraryID, $collectionKey);
                         }
                         Zotero_DB::commit();
                         $this->e204();
                     } else {
                         $title = "Collections";
                         $results = Zotero_Collections::search($this->objectLibraryID, false, $this->queryParams);
                     }
                 }
             }
         }
         if ($collectionIDs) {
             $this->queryParams['collectionIDs'] = $collectionIDs;
             $results = Zotero_Collections::search($this->objectLibraryID, false, $this->queryParams);
         }
         $options = ['action' => $this->action, 'uri' => $this->uri, 'results' => $results, 'requestParams' => $this->queryParams, 'permissions' => $this->permissions, 'head' => $this->method == 'HEAD'];
         switch ($this->queryParams['format']) {
             case 'atom':
                 $this->responseXML = Zotero_API::multiResponse(array_merge($options, ['title' => $this->getFeedNamePrefix($this->objectLibraryID) . $title]));
                 break;
             case 'json':
             case 'keys':
             case 'versions':
             case 'writereport':
                 Zotero_API::multiResponse($options);
                 break;
             default:
                 throw new Exception("Unexpected format '" . $this->queryParams['format'] . "'");
         }
     }
     $this->end();
 }
Beispiel #6
0
 public function items()
 {
     // Check for general library access
     if (!$this->permissions->canAccess($this->objectLibraryID)) {
         $this->e403();
     }
     if ($this->isWriteMethod()) {
         // Check for library write access
         if (!$this->permissions->canWrite($this->objectLibraryID)) {
             $this->e403("Write access denied");
         }
         // Make sure library hasn't been modified
         if (!$this->singleObject) {
             $libraryTimestampChecked = $this->checkLibraryIfUnmodifiedSinceVersion();
         }
         // We don't update the library version in file mode, because currently
         // to avoid conflicts in the client the timestamp can't change
         // when the client updates file metadata
         if (!$this->fileMode) {
             Zotero_Libraries::updateVersionAndTimestamp($this->objectLibraryID);
         }
     }
     $itemIDs = array();
     $itemKeys = array();
     $results = array();
     $title = "";
     //
     // Single item
     //
     if ($this->singleObject) {
         if ($this->fileMode) {
             if ($this->fileView) {
                 $this->allowMethods(array('HEAD', 'GET', 'POST'));
             } else {
                 $this->allowMethods(array('HEAD', 'GET', 'PUT', 'POST', 'PATCH'));
             }
         } else {
             $this->allowMethods(array('HEAD', 'GET', 'PUT', 'PATCH', 'DELETE'));
         }
         if (!$this->objectLibraryID || !Zotero_ID::isValidKey($this->objectKey)) {
             $this->e404();
         }
         $item = Zotero_Items::getByLibraryAndKey($this->objectLibraryID, $this->objectKey);
         if ($item) {
             // If no access to the note, don't show that it exists
             if ($item->isNote() && !$this->permissions->canAccess($this->objectLibraryID, 'notes')) {
                 $this->e404();
             }
             // Make sure URL libraryID matches item libraryID
             if ($this->objectLibraryID != $item->libraryID) {
                 $this->e404("Item does not exist");
             }
             // File access mode
             if ($this->fileMode) {
                 $this->_handleFileRequest($item);
             }
             if ($this->scopeObject) {
                 switch ($this->scopeObject) {
                     // Remove item from collection
                     case 'collections':
                         $this->allowMethods(array('DELETE'));
                         $collection = Zotero_Collections::getByLibraryAndKey($this->objectLibraryID, $this->scopeObjectKey);
                         if (!$collection) {
                             $this->e404("Collection not found");
                         }
                         if (!$collection->hasItem($item->id)) {
                             $this->e404("Item not found in collection");
                         }
                         $collection->removeItem($item->id);
                         $this->e204();
                     default:
                         $this->e400();
                 }
             }
         } else {
             // Possibly temporary workaround to block unnecessary full syncs
             if ($this->fileMode && $this->httpAuth && $this->method == 'POST') {
                 // If > 2 requests for missing file, trigger a full sync via 404
                 $cacheKey = "apiMissingFile_" . $this->objectLibraryID . "_" . $this->objectKey;
                 $set = Z_Core::$MC->get($cacheKey);
                 if (!$set) {
                     Z_Core::$MC->set($cacheKey, 1, 86400);
                 } else {
                     if ($set < 2) {
                         Z_Core::$MC->increment($cacheKey);
                     } else {
                         Z_Core::$MC->delete($cacheKey);
                         $this->e404("A file sync error occurred. Please sync again.");
                     }
                 }
                 $this->e500("A file sync error occurred. Please sync again.");
             }
         }
         if ($this->isWriteMethod()) {
             $item = $this->handleObjectWrite('item', $item ? $item : null);
             if ($this->apiVersion < 2 && ($this->method == 'PUT' || $this->method == 'PATCH')) {
                 $this->queryParams['format'] = 'atom';
                 $this->queryParams['content'] = ['json'];
             }
         }
         if (!$item) {
             $this->e404("Item does not exist");
         }
         $this->libraryVersion = $item->version;
         if ($this->method == 'HEAD') {
             $this->end();
         }
         // Display item
         switch ($this->queryParams['format']) {
             case 'atom':
                 $this->responseXML = Zotero_Items::convertItemToAtom($item, $this->queryParams, $this->permissions);
                 break;
             case 'bib':
                 echo Zotero_Cite::getBibliographyFromCitationServer(array($item), $this->queryParams);
                 break;
             case 'csljson':
                 $json = Zotero_Cite::getJSONFromItems(array($item), true);
                 echo Zotero_Utilities::formatJSON($json);
                 break;
             case 'json':
                 $json = $item->toResponseJSON($this->queryParams, $this->permissions);
                 echo Zotero_Utilities::formatJSON($json);
                 break;
             default:
                 $export = Zotero_Translate::doExport(array($item), $this->queryParams['format']);
                 $this->queryParams['format'] = null;
                 header("Content-Type: " . $export['mimeType']);
                 echo $export['body'];
                 break;
         }
     } else {
         $this->allowMethods(array('HEAD', 'GET', 'POST', 'DELETE'));
         $this->libraryVersion = Zotero_Libraries::getUpdatedVersion($this->objectLibraryID);
         $includeTrashed = $this->queryParams['includeTrashed'];
         if ($this->scopeObject) {
             $this->allowMethods(array('GET', 'POST'));
             switch ($this->scopeObject) {
                 case 'collections':
                     // TEMP
                     if (Zotero_ID::isValidKey($this->scopeObjectKey)) {
                         $collection = Zotero_Collections::getByLibraryAndKey($this->objectLibraryID, $this->scopeObjectKey);
                     } else {
                         $collection = false;
                     }
                     if (!$collection) {
                         // If old collectionID, redirect
                         if ($this->method == 'GET' && Zotero_Utilities::isPosInt($this->scopeObjectKey)) {
                             $collection = Zotero_Collections::get($this->objectLibraryID, $this->scopeObjectKey);
                             if ($collection) {
                                 $qs = !empty($_SERVER['QUERY_STRING']) ? '?' . $_SERVER['QUERY_STRING'] : '';
                                 $base = Zotero_API::getCollectionURI($collection);
                                 $this->redirect($base . "/items" . $qs, 301);
                             }
                         }
                         $this->e404("Collection not found");
                     }
                     // Add items to collection
                     if ($this->method == 'POST') {
                         $itemKeys = explode(' ', $this->body);
                         $itemIDs = array();
                         foreach ($itemKeys as $key) {
                             try {
                                 $item = Zotero_Items::getByLibraryAndKey($this->objectLibraryID, $key);
                             } catch (Exception $e) {
                                 if ($e->getCode() == Z_ERROR_OBJECT_LIBRARY_MISMATCH) {
                                     $item = false;
                                 } else {
                                     throw $e;
                                 }
                             }
                             if (!$item) {
                                 throw new Exception("Item '{$key}' not found in library", Z_ERROR_INVALID_INPUT);
                             }
                             if ($item->getSource()) {
                                 throw new Exception("Child items cannot be added to collections directly", Z_ERROR_INVALID_INPUT);
                             }
                             $itemIDs[] = $item->id;
                         }
                         $collection->addItems($itemIDs);
                         $this->e204();
                     }
                     if ($this->subset == 'top' || $this->apiVersion < 2) {
                         $title = "Top-Level Items in Collection ‘" . $collection->name . "’";
                         $itemIDs = $collection->getItems();
                     } else {
                         $title = "Items in Collection ‘" . $collection->name . "’";
                         $itemIDs = $collection->getItems(true);
                     }
                     break;
                 case 'tags':
                     if ($this->apiVersion >= 2) {
                         $this->e404();
                     }
                     $this->allowMethods(array('GET'));
                     $tagIDs = Zotero_Tags::getIDs($this->objectLibraryID, $this->scopeObjectName);
                     if (!$tagIDs) {
                         $this->e404("Tag not found");
                     }
                     foreach ($tagIDs as $tagID) {
                         $tag = new Zotero_Tag();
                         $tag->libraryID = $this->objectLibraryID;
                         $tag->id = $tagID;
                         // Use a real tag name, in case case differs
                         if (!$title) {
                             $title = "Items of Tag ‘" . $tag->name . "’";
                         }
                         $itemKeys = array_merge($itemKeys, $tag->getLinkedItems(true));
                     }
                     $itemKeys = array_unique($itemKeys);
                     break;
                 default:
                     $this->e404();
             }
         } else {
             // Top-level items
             if ($this->subset == 'top') {
                 $this->allowMethods(array('GET'));
                 $title = "Top-Level Items";
                 $results = Zotero_Items::search($this->objectLibraryID, true, $this->queryParams, $includeTrashed, $this->permissions);
             } else {
                 if ($this->subset == 'trash') {
                     $this->allowMethods(array('GET'));
                     $title = "Deleted Items";
                     $this->queryParams['trashedItemsOnly'] = true;
                     $includeTrashed = true;
                     $results = Zotero_Items::search($this->objectLibraryID, false, $this->queryParams, $includeTrashed, $this->permissions);
                 } else {
                     if ($this->subset == 'children') {
                         $item = Zotero_Items::getByLibraryAndKey($this->objectLibraryID, $this->objectKey);
                         if (!$item) {
                             $this->e404("Item not found");
                         }
                         if ($item->isAttachment()) {
                             $this->e400("/children cannot be called on attachment items");
                         }
                         if ($item->isNote()) {
                             $this->e400("/children cannot be called on note items");
                         }
                         if ($item->getSource()) {
                             $this->e400("/children cannot be called on child items");
                         }
                         // Create new child items
                         if ($this->method == 'POST') {
                             if ($this->apiVersion >= 2) {
                                 $this->allowMethods(array('GET'));
                             }
                             Zotero_DB::beginTransaction();
                             $obj = $this->jsonDecode($this->body);
                             $results = Zotero_Items::updateMultipleFromJSON($obj, $this->queryParams, $this->objectLibraryID, $this->userID, $this->permissions, $libraryTimestampChecked ? 0 : 1, $item);
                             Zotero_DB::commit();
                             if ($cacheKey = $this->getWriteTokenCacheKey()) {
                                 Z_Core::$MC->set($cacheKey, true, $this->writeTokenCacheTime);
                             }
                             $uri = Zotero_API::getItemsURI($this->objectLibraryID);
                             $keys = array_merge(get_object_vars($results['success']), get_object_vars($results['unchanged']));
                             $queryString = "itemKey=" . urlencode(implode(",", $keys)) . "&format=atom&content=json&order=itemKeyList&sort=asc";
                             if ($this->apiKey) {
                                 $queryString .= "&key=" . $this->apiKey;
                             }
                             $uri .= "?" . $queryString;
                             $this->queryParams = Zotero_API::parseQueryParams($queryString, $this->action, false);
                             $this->responseCode = 201;
                             $title = "Items";
                             $results = Zotero_Items::search($this->objectLibraryID, false, $this->queryParams, $includeTrashed, $this->permissions);
                         } else {
                             $title = "Child Items of ‘" . $item->getDisplayTitle() . "’";
                             $notes = $item->getNotes();
                             $attachments = $item->getAttachments();
                             $itemIDs = array_merge($notes, $attachments);
                         }
                     } else {
                         // Create new items
                         if ($this->method == 'POST') {
                             $this->queryParams['format'] = 'writereport';
                             $obj = $this->jsonDecode($this->body);
                             // Server-side translation
                             if (isset($obj->url)) {
                                 if ($this->apiVersion == 1) {
                                     Zotero_DB::beginTransaction();
                                 }
                                 $token = $this->getTranslationToken($obj);
                                 $results = Zotero_Items::addFromURL($obj, $this->queryParams, $this->objectLibraryID, $this->userID, $this->permissions, $token);
                                 if ($this->apiVersion == 1) {
                                     Zotero_DB::commit();
                                 }
                                 // Multiple choices
                                 if ($results instanceof stdClass) {
                                     $this->queryParams['format'] = null;
                                     header("Content-Type: application/json");
                                     if ($this->queryParams['v'] >= 2) {
                                         echo Zotero_Utilities::formatJSON(['url' => $obj->url, 'token' => $token, 'items' => $results->select]);
                                     } else {
                                         echo Zotero_Utilities::formatJSON($results->select);
                                     }
                                     $this->e300();
                                 } else {
                                     if (is_int($results)) {
                                         switch ($results) {
                                             case 501:
                                                 $this->e501("No translators found for URL");
                                                 break;
                                             default:
                                                 $this->e500("Error translating URL");
                                         }
                                     } else {
                                         if ($this->apiVersion == 1) {
                                             $uri = Zotero_API::getItemsURI($this->objectLibraryID);
                                             $keys = array_merge(get_object_vars($results['success']), get_object_vars($results['unchanged']));
                                             $queryString = "itemKey=" . urlencode(implode(",", $keys)) . "&format=atom&content=json&order=itemKeyList&sort=asc";
                                             if ($this->apiKey) {
                                                 $queryString .= "&key=" . $this->apiKey;
                                             }
                                             $uri .= "?" . $queryString;
                                             $this->queryParams = Zotero_API::parseQueryParams($queryString, $this->action, false);
                                             $this->responseCode = 201;
                                             $title = "Items";
                                             $results = Zotero_Items::search($this->objectLibraryID, false, $this->queryParams, $includeTrashed, $this->permissions);
                                         }
                                     }
                                 }
                                 // Otherwise return write status report
                             } else {
                                 if ($this->apiVersion < 2) {
                                     Zotero_DB::beginTransaction();
                                 }
                                 $results = Zotero_Items::updateMultipleFromJSON($obj, $this->queryParams, $this->objectLibraryID, $this->userID, $this->permissions, $libraryTimestampChecked ? 0 : 1, null);
                                 if ($this->apiVersion < 2) {
                                     Zotero_DB::commit();
                                     $uri = Zotero_API::getItemsURI($this->objectLibraryID);
                                     $keys = array_merge(get_object_vars($results['success']), get_object_vars($results['unchanged']));
                                     $queryString = "itemKey=" . urlencode(implode(",", $keys)) . "&format=atom&content=json&order=itemKeyList&sort=asc";
                                     if ($this->apiKey) {
                                         $queryString .= "&key=" . $this->apiKey;
                                     }
                                     $uri .= "?" . $queryString;
                                     $this->queryParams = Zotero_API::parseQueryParams($queryString, $this->action, false);
                                     $this->responseCode = 201;
                                     $title = "Items";
                                     $results = Zotero_Items::search($this->objectLibraryID, false, $this->queryParams, $includeTrashed, $this->permissions);
                                 }
                             }
                             if ($cacheKey = $this->getWriteTokenCacheKey()) {
                                 Z_Core::$MC->set($cacheKey, true, $this->writeTokenCacheTime);
                             }
                         } else {
                             if ($this->method == 'DELETE') {
                                 Zotero_DB::beginTransaction();
                                 foreach ($this->queryParams['itemKey'] as $itemKey) {
                                     Zotero_Items::delete($this->objectLibraryID, $itemKey);
                                 }
                                 Zotero_DB::commit();
                                 $this->e204();
                             } else {
                                 $title = "Items";
                                 $results = Zotero_Items::search($this->objectLibraryID, false, $this->queryParams, $includeTrashed, $this->permissions);
                             }
                         }
                     }
                 }
             }
         }
         if ($itemIDs || $itemKeys) {
             if ($itemIDs) {
                 $this->queryParams['itemIDs'] = $itemIDs;
             }
             if ($itemKeys) {
                 $this->queryParams['itemKey'] = $itemKeys;
             }
             $results = Zotero_Items::search($this->objectLibraryID, false, $this->queryParams, $includeTrashed, $this->permissions);
         }
         if ($this->queryParams['format'] == 'bib') {
             $maxBibItems = Zotero_API::MAX_BIBLIOGRAPHY_ITEMS;
             if ($results['total'] > $maxBibItems) {
                 $this->e413("Cannot generate bibliography with more than {$maxBibItems} items");
             }
         }
         $this->generateMultiResponse($results, $title);
     }
     $this->end();
 }
 private function getParent()
 {
     if ($this->_parent !== false) {
         if (!$this->_parent) {
             return null;
         }
         if (is_int($this->_parent)) {
             return $this->_parent;
         }
         $parentCollection = Zotero_Collections::getByLibraryAndKey($this->libraryID, $this->_parent);
         if (!$parentCollection) {
             throw new Exception("Source collection for keyed parent doesn't exist");
         }
         // Replace stored key with id
         $this->_parent = $parentCollection->id;
         return $parentCollection->id;
     }
     if (!$this->id) {
         return false;
     }
     $sql = "SELECT parentCollectionID FROM collections WHERE collectionID=?";
     $parentCollectionID = Zotero_DB::valueQuery($sql, $this->id, Zotero_Shards::getByLibraryID($this->libraryID));
     if (!$parentCollectionID) {
         $parentCollectionID = null;
     }
     $this->_parent = $parentCollectionID;
     return $parentCollectionID;
 }
Beispiel #8
0
 public function tags()
 {
     $this->allowMethods(['HEAD', 'GET', 'DELETE']);
     if (!$this->permissions->canAccess($this->objectLibraryID)) {
         $this->e403();
     }
     if ($this->isWriteMethod()) {
         // Check for library write access
         if (!$this->permissions->canWrite($this->objectLibraryID)) {
             $this->e403("Write access denied");
         }
         // Make sure library hasn't been modified
         $this->checkLibraryIfUnmodifiedSinceVersion(true);
         Zotero_Libraries::updateVersionAndTimestamp($this->objectLibraryID);
     }
     $tagIDs = array();
     $results = array();
     $name = $this->objectName;
     $fixedValues = array();
     $this->libraryVersion = Zotero_Libraries::getUpdatedVersion($this->objectLibraryID);
     // Set of tags matching name
     if ($name && $this->subset != 'tags') {
         $this->allowMethods(array('GET'));
         $tagIDs = Zotero_Tags::getIDs($this->objectLibraryID, $name);
         if (!$tagIDs) {
             $this->e404();
         }
         $title = "Tags matching ‘" . $name . "’";
     } else {
         $this->allowMethods(array('GET', 'DELETE'));
         if ($this->scopeObject) {
             $this->allowMethods(array('GET'));
             switch ($this->scopeObject) {
                 case 'collections':
                     $collection = Zotero_Collections::getByLibraryAndKey($this->objectLibraryID, $this->scopeObjectKey);
                     if (!$collection) {
                         $this->e404();
                     }
                     $title = "Tags in Collection ‘" . $collection->name . "’";
                     $counts = $collection->getTagItemCounts();
                     $tagIDs = array();
                     if ($counts) {
                         foreach ($counts as $tagID => $count) {
                             $tagIDs[] = $tagID;
                             $fixedValues[$tagID] = array('numItems' => $count);
                         }
                     }
                     break;
                 case 'items':
                     $item = Zotero_Items::getByLibraryAndKey($this->objectLibraryID, $this->scopeObjectKey);
                     if (!$item) {
                         $this->e404();
                     }
                     $title = "Tags of '" . $item->getDisplayTitle() . "'";
                     $tagIDs = $item->getTags(true);
                     break;
                 default:
                     throw new Exception("Invalid tags scope object '{$this->scopeObject}'");
             }
         } else {
             if ($this->method == 'DELETE') {
                 // Filter for specific tags with "?tag=foo || bar"
                 $tagNames = !empty($this->queryParams['tag']) ? explode(' || ', $this->queryParams['tag']) : array();
                 Zotero_DB::beginTransaction();
                 foreach ($tagNames as $tagName) {
                     $tagIDs = Zotero_Tags::getIDs($this->objectLibraryID, $tagName);
                     foreach ($tagIDs as $tagID) {
                         $tag = Zotero_Tags::get($this->objectLibraryID, $tagID, true);
                         Zotero_Tags::delete($this->objectLibraryID, $tag->key);
                     }
                 }
                 Zotero_DB::commit();
                 $this->e204();
             } else {
                 $title = "Tags";
                 $results = Zotero_Tags::search($this->objectLibraryID, $this->queryParams);
             }
         }
     }
     if ($tagIDs) {
         $this->queryParams['tagIDs'] = $tagIDs;
         $results = Zotero_Tags::search($this->objectLibraryID, $this->queryParams);
     }
     $this->generateMultiResponse($results, $title, $fixedValues);
     $this->end();
 }