コード例 #1
0
ファイル: URI.inc.php プロジェクト: robinpaulson/dataserver
 public static function getLibraryURI($libraryID, $skipNames = false)
 {
     $libraryType = Zotero_Libraries::getType($libraryID);
     switch ($libraryType) {
         case 'user':
             $id = Zotero_Users::getUserIDFromLibraryID($libraryID);
             return self::getUserURI($id, $skipNames);
         case 'group':
             $id = Zotero_Groups::getGroupIDFromLibraryID($libraryID);
             $group = Zotero_Groups::get($id);
             return self::getGroupURI($group, $skipNames);
     }
 }
コード例 #2
0
ファイル: URI.inc.php プロジェクト: selenus/dataserver
 public static function getLibraryURI($libraryID, $www = false, $useSlug = false)
 {
     $libraryType = Zotero_Libraries::getType($libraryID);
     switch ($libraryType) {
         case 'user':
             $id = Zotero_Users::getUserIDFromLibraryID($libraryID);
             return self::getUserURI($id, $www, $useSlug);
         case 'publications':
             $id = Zotero_Users::getUserIDFromLibraryID($libraryID);
             return self::getUserURI($id, $www, $useSlug) . "/publications";
         case 'group':
             $id = Zotero_Groups::getGroupIDFromLibraryID($libraryID);
             $group = Zotero_Groups::get($id);
             return self::getGroupURI($group, $www, $useSlug);
         default:
             throw new Exception("Invalid library type '{$libraryType}'");
     }
 }
コード例 #3
0
ファイル: Keys.inc.php プロジェクト: selenus/dataserver
 public static function getUserKeysWithLibrary($userID, $libraryID)
 {
     $libraryType = Zotero_Libraries::getType($libraryID);
     $sql = "SELECT keyID FROM `keys` JOIN keyPermissions USING (keyID) " . "WHERE userID=? AND (libraryID=?";
     // If group library, include keys with access to all groups
     if ($libraryType == 'group') {
         $sql .= " OR libraryID=0";
     }
     $sql .= ") AND permission='library' AND granted=1";
     $keyIDs = Zotero_DB::columnQuery($sql, [$userID, $libraryID]);
     $keys = [];
     if ($keyIDs) {
         foreach ($keyIDs as $keyID) {
             $keyObj = new Zotero_Key();
             $keyObj->id = $keyID;
             $keys[] = $keyObj;
         }
     }
     return $keys;
 }
コード例 #4
0
ファイル: Items.inc.php プロジェクト: robinpaulson/dataserver
 private static function validateJSONItem($json, $libraryID, $item = null, $isChild = false)
 {
     $isNew = !$item;
     if (!is_object($json)) {
         throw new Exception("Invalid item object (found " . gettype($json) . " '" . $json . "')", Z_ERROR_INVALID_INPUT);
     }
     if (isset($json->items) && is_array($json->items)) {
         throw new Exception("An 'items' array is not valid for item updates", Z_ERROR_INVALID_INPUT);
     }
     if (isset($json->itemType) && $json->itemType == "attachment") {
         $requiredProps = array('linkMode', 'tags');
     } else {
         if (isset($json->itemType) && $json->itemType == "attachment") {
             $requiredProps = array('tags');
         } else {
             if ($isNew) {
                 $requiredProps = array('itemType');
             } else {
                 $requiredProps = array('itemType', 'creators', 'tags');
             }
         }
     }
     foreach ($requiredProps as $prop) {
         if (!isset($json->{$prop})) {
             throw new Exception("'{$prop}' property not provided", Z_ERROR_INVALID_INPUT);
         }
     }
     foreach ($json as $key => $val) {
         switch ($key) {
             case 'itemType':
                 if (!is_string($val)) {
                     throw new Exception("'itemType' must be a string", Z_ERROR_INVALID_INPUT);
                 }
                 if ($isChild) {
                     switch ($val) {
                         case 'note':
                         case 'attachment':
                             break;
                         default:
                             throw new Exception("Child item must be note or attachment", Z_ERROR_INVALID_INPUT);
                     }
                 } else {
                     if ($val == 'attachment' && (!$item || !$item->getSource())) {
                         if ($json->linkMode == 'linked_url' || $json->linkMode == 'imported_url' && (empty($json->contentType) || $json->contentType != 'application/pdf')) {
                             throw new Exception("Only file attachments and PDFs can be top-level items", Z_ERROR_INVALID_INPUT);
                         }
                     }
                 }
                 if (!Zotero_ItemTypes::getID($val)) {
                     throw new Exception("'{$val}' is not a valid itemType", Z_ERROR_INVALID_INPUT);
                 }
                 break;
             case 'tags':
                 if (!is_array($val)) {
                     throw new Exception("'tags' property must be an array", Z_ERROR_INVALID_INPUT);
                 }
                 foreach ($val as $tag) {
                     $empty = true;
                     foreach ($tag as $k => $v) {
                         switch ($k) {
                             case 'tag':
                                 if (!is_scalar($v)) {
                                     throw new Exception("Invalid tag name", Z_ERROR_INVALID_INPUT);
                                 }
                                 if ($v === "") {
                                     throw new Exception("Tag cannot be empty", Z_ERROR_INVALID_INPUT);
                                 }
                                 break;
                             case 'type':
                                 if (!is_numeric($v)) {
                                     throw new Exception("Invalid tag type '{$v}'", Z_ERROR_INVALID_INPUT);
                                 }
                                 break;
                             default:
                                 throw new Exception("Invalid tag property '{$k}'", Z_ERROR_INVALID_INPUT);
                         }
                         $empty = false;
                     }
                     if ($empty) {
                         throw new Exception("Tag object is empty", Z_ERROR_INVALID_INPUT);
                     }
                 }
                 break;
             case 'creators':
                 if (!is_array($val)) {
                     throw new Exception("'creators' property must be an array", Z_ERROR_INVALID_INPUT);
                 }
                 foreach ($val as $creator) {
                     $empty = true;
                     if (!isset($creator->creatorType)) {
                         throw new Exception("creator object must contain 'creatorType'", Z_ERROR_INVALID_INPUT);
                     }
                     if ((!isset($creator->name) || trim($creator->name) == "") && (!isset($creator->firstName) || trim($creator->firstName) == "") && (!isset($creator->lastName) || trim($creator->lastName) == "")) {
                         // On item creation, ignore single nameless creator,
                         // because that's in the item template that the API returns
                         if (sizeOf($val) == 1 && $isNew) {
                             continue;
                         } else {
                             throw new Exception("creator object must contain 'firstName'/'lastName' or 'name'", Z_ERROR_INVALID_INPUT);
                         }
                     }
                     foreach ($creator as $k => $v) {
                         switch ($k) {
                             case 'creatorType':
                                 $creatorTypeID = Zotero_CreatorTypes::getID($v);
                                 if (!$creatorTypeID) {
                                     throw new Exception("'{$v}' is not a valid creator type", Z_ERROR_INVALID_INPUT);
                                 }
                                 $itemTypeID = Zotero_ItemTypes::getID($json->itemType);
                                 if (!Zotero_CreatorTypes::isValidForItemType($creatorTypeID, $itemTypeID)) {
                                     throw new Exception("'{$v}' is not a valid creator type for item type '" . $json->itemType . "'", Z_ERROR_INVALID_INPUT);
                                 }
                                 break;
                             case 'firstName':
                                 if (!isset($creator->lastName)) {
                                     throw new Exception("'lastName' creator field must be set if 'firstName' is set", Z_ERROR_INVALID_INPUT);
                                 }
                                 if (isset($creator->name)) {
                                     throw new Exception("'firstName' and 'name' creator fields are mutually exclusive", Z_ERROR_INVALID_INPUT);
                                 }
                                 break;
                             case 'lastName':
                                 if (!isset($creator->firstName)) {
                                     throw new Exception("'firstName' creator field must be set if 'lastName' is set", Z_ERROR_INVALID_INPUT);
                                 }
                                 if (isset($creator->name)) {
                                     throw new Exception("'lastName' and 'name' creator fields are mutually exclusive", Z_ERROR_INVALID_INPUT);
                                 }
                                 break;
                             case 'name':
                                 if (isset($creator->firstName)) {
                                     throw new Exception("'firstName' and 'name' creator fields are mutually exclusive", Z_ERROR_INVALID_INPUT);
                                 }
                                 if (isset($creator->lastName)) {
                                     throw new Exception("'lastName' and 'name' creator fields are mutually exclusive", Z_ERROR_INVALID_INPUT);
                                 }
                                 break;
                             default:
                                 throw new Exception("Invalid creator property '{$k}'", Z_ERROR_INVALID_INPUT);
                         }
                         $empty = false;
                     }
                     if ($empty) {
                         throw new Exception("Creator object is empty", Z_ERROR_INVALID_INPUT);
                     }
                 }
                 break;
             case 'note':
                 switch ($json->itemType) {
                     case 'note':
                     case 'attachment':
                         break;
                     default:
                         throw new Exception("'note' property is valid only for note and attachment items", Z_ERROR_INVALID_INPUT);
                 }
                 break;
             case 'attachments':
             case 'notes':
                 if (!$isNew) {
                     throw new Exception("'{$key}' property is valid only for new items", Z_ERROR_INVALID_INPUT);
                 }
                 if (!is_array($val)) {
                     throw new Exception("'{$key}' property must be an array", Z_ERROR_INVALID_INPUT);
                 }
                 foreach ($val as $child) {
                     // Check child item type ('attachment' or 'note')
                     $t = substr($key, 0, -1);
                     if (isset($child->itemType) && $child->itemType != $t) {
                         throw new Exception("Child {$t} must be of itemType '{$t}'", Z_ERROR_INVALID_INPUT);
                     }
                     if ($key == 'note') {
                         if (!isset($child->note)) {
                             throw new Exception("'note' property not provided for child note", Z_ERROR_INVALID_INPUT);
                         }
                     }
                 }
                 break;
             case 'deleted':
                 break;
                 // Attachment properties
             // Attachment properties
             case 'linkMode':
                 try {
                     $linkMode = Zotero_Attachments::linkModeNameToNumber($val, true);
                 } catch (Exception $e) {
                     throw new Exception("'{$val}' is not a valid linkMode", Z_ERROR_INVALID_INPUT);
                 }
                 // Don't allow changing of linkMode
                 if ($item && $linkMode != $item->attachmentLinkMode) {
                     throw new Exception("Cannot change attachment linkMode", Z_ERROR_INVALID_INPUT);
                 }
                 break;
             case 'contentType':
             case 'charset':
             case 'filename':
             case 'md5':
             case 'mtime':
                 if ($json->itemType != 'attachment') {
                     throw new Exception("'{$key}' is valid only for attachment items", Z_ERROR_INVALID_INPUT);
                 }
                 switch ($key) {
                     case 'filename':
                     case 'md5':
                     case 'mtime':
                         if (strpos($json->linkMode, 'imported_') !== 0) {
                             throw new Exception("'{$key}' is valid only for imported attachment items", Z_ERROR_INVALID_INPUT);
                         }
                         break;
                 }
                 switch ($key) {
                     case 'contentType':
                     case 'charset':
                     case 'filename':
                         $propName = 'attachment' . ucwords($key);
                         break;
                     case 'md5':
                         $propName = 'attachmentStorageHash';
                         break;
                     case 'mtime':
                         $propName = 'attachmentStorageModTime';
                         break;
                 }
                 if (Zotero_Libraries::getType($libraryID) == 'group') {
                     if ($item && $item->{$propName} !== $val || !$item && $val !== null && $val !== "") {
                         throw new Exception("Cannot change '{$key}' directly in group library", Z_ERROR_INVALID_INPUT);
                     }
                 } else {
                     if ($key == 'md5') {
                         if ($val && !preg_match("/^[a-f0-9]{32}\$/", $val)) {
                             throw new Exception("'{$val}' is not a valid MD5 hash", Z_ERROR_INVALID_INPUT);
                         }
                     }
                 }
                 break;
             default:
                 if (!Zotero_ItemFields::getID($key)) {
                     throw new Exception("Invalid property '{$key}'", Z_ERROR_INVALID_INPUT);
                 }
                 if (is_array($val)) {
                     throw new Exception("Unexpected array for property '{$key}'", Z_ERROR_INVALID_INPUT);
                 }
                 break;
         }
     }
 }
コード例 #5
0
ファイル: Item.inc.php プロジェクト: kskod/dataserver
	public function toResponseJSON($requestParams=[], Zotero_Permissions $permissions, $sharedData=null) {
		$t = microtime(true);
		
		if (!$this->loaded['primaryData']) {
			$this->loadPrimaryData();
		}
		if (!$this->loaded['itemData']) {
			$this->loadItemData();
		}
		
		// Uncached stuff or parts of the cache key
		$version = $this->version;
		$parent = $this->getSource();
		$isRegularItem = !$parent && $this->isRegularItem();
		$downloadDetails = $permissions->canAccess($this->libraryID, 'files')
								? Zotero_Storage::getDownloadDetails($this)
								: false;
		if ($isRegularItem) {
			$numChildren = $permissions->canAccess($this->libraryID, 'notes')
								? $this->numChildren()
								: $this->numAttachments();
		}
		$libraryType = Zotero_Libraries::getType($this->libraryID);
		
		// Any query parameters that have an effect on the output
		// need to be added here
		$allowedParams = [
			'include',
			'style',
			'css',
			'linkwrap'
		];
		$cachedParams = Z_Array::filterKeys($requestParams, $allowedParams);
		
		$cacheVersion = 1;
		$cacheKey = "jsonEntry_" . $this->libraryID . "/" . $this->id . "_"
			. md5(
				$version
				. json_encode($cachedParams)
				. ($downloadDetails ? 'hasFile' : '')
				// For groups, include the group WWW URL, which can change
				. ($libraryType == 'group' ? Zotero_URI::getItemURI($this, true) : '')
			)
			. "_" . $requestParams['v']
			// For code-based changes
			. "_" . $cacheVersion
			// For data-based changes
			. (isset(Z_CONFIG::$CACHE_VERSION_RESPONSE_JSON_ITEM)
				? "_" . Z_CONFIG::$CACHE_VERSION_RESPONSE_JSON_ITEM
				: "")
			// If there's bib content, include the bib cache version
			. ((in_array('bib', $requestParams['include'])
					&& isset(Z_CONFIG::$CACHE_VERSION_BIB))
				? "_" . Z_CONFIG::$CACHE_VERSION_BIB
				: "");
		
		$cached = Z_Core::$MC->get($cacheKey);
		if (false && $cached) {
			// Make sure numChildren reflects the current permissions
			if ($isRegularItem) {
				$json = json_decode($cached);
				$json['numChildren'] = $numChildren;
				$cached = json_encode($json);
			}
			
			//StatsD::timing("api.items.itemToResponseJSON.cached", (microtime(true) - $t) * 1000);
			//StatsD::increment("memcached.items.itemToResponseJSON.hit");
			
			// Skip the cache every 10 times for now, to ensure cache sanity
			if (!Z_Core::probability(10)) {
				return $cached;
			}
		}
		
		
		$json = [
			'key' => $this->key,
			'version' => $version,
			'library' => Zotero_Libraries::toJSON($this->libraryID)
		];
		
		$json['links'] = [
			'self' => [
				'href' => Zotero_API::getItemURI($this),
				'type' => 'application/json'
			],
			'alternate' => [
				'href' => Zotero_URI::getItemURI($this, true),
				'type' => 'text/html'
			]
		];
		
		if ($parent) {
			$parentItem = Zotero_Items::get($this->libraryID, $parent);
			$json['links']['up'] = [
				'href' => Zotero_API::getItemURI($parentItem),
				'type' => 'application/json'
			];
		}
		
		// If appropriate permissions and the file is stored in ZFS, get file request link
		if ($downloadDetails) {
			$details = $downloadDetails;
			$type = $this->attachmentMIMEType;
			if ($type) {
				$json['links']['enclosure'] = [
					'type' => $type
				];
			}
			$json['links']['enclosure']['href'] = $details['url'];
			if (!empty($details['filename'])) {
				$json['links']['enclosure']['title'] = $details['filename'];
			}
			if (isset($details['size'])) {
				$json['links']['enclosure']['length'] = $details['size'];
			}
		}
		
		// 'meta'
		$json['meta'] = new stdClass;
		
		if (Zotero_Libraries::getType($this->libraryID) == 'group') {
			$createdByUserID = $this->createdByUserID;
			$lastModifiedByUserID = $this->lastModifiedByUserID;
			
			if ($createdByUserID) {
				$json['meta']->createdByUser = Zotero_Users::toJSON($createdByUserID);
			}
			
			if ($lastModifiedByUserID && $lastModifiedByUserID != $createdByUserID) {
				$json['meta']->lastModifiedByUser = Zotero_Users::toJSON($lastModifiedByUserID);
			}
		}
		
		if ($isRegularItem) {
			$val = $this->getCreatorSummary();
			if ($val !== '') {
				$json['meta']->creatorSummary = $val;
			}
			
			$val = $this->getField('date', true, true, true);
			if ($val !== '') {
				$sqlDate = Zotero_Date::multipartToSQL($val);
				if (substr($sqlDate, 0, 4) !== '0000') {
					$json['meta']->parsedDate = Zotero_Date::sqlToISO8601($sqlDate);
				}
			}
			
			$json['meta']->numChildren = $numChildren;
		}
		
		// 'include'
		$include = $requestParams['include'];
		
		foreach ($include as $type) {
			if ($type == 'html') {
				$json[$type] = trim($this->toHTML());
			}
			else if ($type == 'citation') {
				if (isset($sharedData[$type][$this->libraryID . "/" . $this->key])) {
					$html = $sharedData[$type][$this->libraryID . "/" . $this->key];
				}
				else {
					if ($sharedData !== null) {
						//error_log("Citation not found in sharedData -- retrieving individually");
					}
					$html = Zotero_Cite::getCitationFromCiteServer($this, $requestParams);
				}
				$json[$type] = $html;
			}
			else if ($type == 'bib') {
				if (isset($sharedData[$type][$this->libraryID . "/" . $this->key])) {
					$html = $sharedData[$type][$this->libraryID . "/" . $this->key];
				}
				else {
					if ($sharedData !== null) {
						//error_log("Bibliography not found in sharedData -- retrieving individually");
					}
					$html = Zotero_Cite::getBibliographyFromCitationServer([$this], $requestParams);
					
					// Strip prolog
					$html = preg_replace('/^<\?xml.+\n/', "", $html);
					$html = trim($html);
				}
				$json[$type] = $html;
			}
			else if ($type == 'data') {
				$json[$type] = $this->toJSON(true, $requestParams, true);
			}
			else if ($type == 'csljson') {
				$json[$type] = $this->toCSLItem();
			}
			else if (in_array($type, Zotero_Translate::$exportFormats)) {
				$export = Zotero_Translate::doExport([$this], $type);
				$json[$type] = $export['body'];
				unset($export);
			}
		}
		

		// TEMP
		if ($cached) {
			$uncached = Zotero_Utilities::formatJSON($json);
			if ($cached != $uncached) {
				error_log("Cached JSON item entry does not match");
				error_log("  Cached: " . $cached);
				error_log("Uncached: " . $uncached);
				
				//Z_Core::$MC->set($cacheKey, $uncached, 3600); // 1 hour for now
			}
		}
		else {
			/*Z_Core::$MC->set($cacheKey, $xmlstr, 3600); // 1 hour for now
			StatsD::timing("api.items.itemToAtom.uncached", (microtime(true) - $t) * 1000);
			StatsD::increment("memcached.items.itemToAtom.miss");*/
		}
		
		return $json;
	}
コード例 #6
0
ファイル: Item.inc.php プロジェクト: robinpaulson/dataserver
 public function toSolrDocument()
 {
     $doc = new SolrInputDocument();
     $uri = Zotero_Solr::getItemURI($this->libraryID, $this->key);
     $doc->addField("uri", $uri);
     // Primary fields
     foreach (Zotero_Items::$primaryFields as $field) {
         switch ($field) {
             case 'itemID':
             case 'numAttachments':
             case 'numNotes':
                 continue 2;
             case 'itemTypeID':
                 $xmlField = 'itemType';
                 $xmlValue = Zotero_ItemTypes::getName($this->{$field});
                 break;
             case 'dateAdded':
             case 'dateModified':
             case 'serverDateModified':
                 $xmlField = $field;
                 $xmlValue = Zotero_Date::sqlToISO8601($this->{$field});
                 break;
             default:
                 $xmlField = $field;
                 $xmlValue = $this->{$field};
         }
         $doc->addField($xmlField, $xmlValue);
     }
     // Title for sorting
     $title = $this->getDisplayTitle(true);
     $title = $title ? $title : '';
     // Strip HTML from note titles
     if ($this->isNote()) {
         // Clean and strip HTML, giving us an HTML-encoded plaintext string
         $title = strip_tags($GLOBALS['HTMLPurifier']->purify($title));
         // Unencode plaintext string
         $title = html_entity_decode($title);
     }
     // Strip some characters
     $sortTitle = preg_replace("/^[\\[\\'\"]*(.*)[\\]\\'\"]*\$/", "\$1", $title);
     if ($sortTitle) {
         $doc->addField('titleSort', $sortTitle);
     }
     // Item data
     $fieldIDs = $this->getUsedFields();
     foreach ($fieldIDs as $fieldID) {
         $val = $this->getField($fieldID);
         if ($val == '') {
             continue;
         }
         $fieldName = Zotero_ItemFields::getName($fieldID);
         switch ($fieldName) {
             // As is
             case 'title':
                 $val = $title;
                 break;
                 // Date fields
             // Date fields
             case 'date':
                 // Add user part as text
                 $doc->addField($fieldName . "_t", Zotero_Date::multipartToStr($val));
                 // Add as proper date, if there is one
                 $sqlDate = Zotero_Date::multipartToSQL($val);
                 if (!$sqlDate || $sqlDate == '0000-00-00') {
                     continue 2;
                 }
                 $fieldName .= "_tdt";
                 $val = Zotero_Date::sqlToISO8601($sqlDate);
                 break;
             case 'accessDate':
                 if (!Zotero_Date::isSQLDateTime($val)) {
                     continue 2;
                 }
                 $fieldName .= "_tdt";
                 $val = Zotero_Date::sqlToISO8601($val);
                 break;
             default:
                 $fieldName .= "_t";
         }
         $doc->addField($fieldName, $val);
     }
     // Deleted item flag
     if ($this->getDeleted()) {
         $doc->addField('deleted', true);
     }
     if ($this->isNote() || $this->isAttachment()) {
         $sourceItemID = $this->getSource();
         if ($sourceItemID) {
             $sourceItem = Zotero_Items::get($this->libraryID, $sourceItemID);
             if (!$sourceItem) {
                 throw new Exception("Source item {$sourceItemID} not found");
             }
             $doc->addField('sourceItem', $sourceItem->key);
         }
     }
     // Group modification info
     $createdByUserID = null;
     $lastModifiedByUserID = null;
     switch (Zotero_Libraries::getType($this->libraryID)) {
         case 'group':
             $createdByUserID = $this->createdByUserID;
             $lastModifiedByUserID = $this->lastModifiedByUserID;
             break;
     }
     if ($createdByUserID) {
         $doc->addField('createdByUserID', $createdByUserID);
     }
     if ($lastModifiedByUserID) {
         $doc->addField('lastModifiedByUserID', $lastModifiedByUserID);
     }
     // Note
     if ($this->isNote()) {
         $doc->addField('note', $this->getNote());
     }
     if ($this->isAttachment()) {
         $doc->addField('linkMode', $this->attachmentLinkMode);
         $doc->addField('mimeType', $this->attachmentMIMEType);
         if ($this->attachmentCharset) {
             $doc->addField('charset', $this->attachmentCharset);
         }
         // TODO: get from a constant
         if ($this->attachmentLinkMode != 3) {
             $doc->addField('path', $this->attachmentPath);
         }
         $note = $this->getNote();
         if ($note) {
             $doc->addField('note', $note);
         }
     }
     // Creators
     $creators = $this->getCreators();
     if ($creators) {
         foreach ($creators as $index => $creator) {
             $c = $creator['ref'];
             $doc->addField('creatorKey', $c->key);
             if ($c->fieldMode == 0) {
                 $doc->addField('creatorFirstName', $c->firstName);
             }
             $doc->addField('creatorLastName', $c->lastName);
             $doc->addField('creatorType', Zotero_CreatorTypes::getName($creator['creatorTypeID']));
             $doc->addField('creatorIndex', $index);
         }
     }
     // Tags
     $tags = $this->getTags();
     if ($tags) {
         foreach ($tags as $tag) {
             $doc->addField('tagKey', $tag->key);
             $doc->addField('tag', $tag->name);
             $doc->addField('tagType', $tag->type);
         }
     }
     // Related items
     /*$related = $this->relatedItems;
     		if ($related) {
     			$related = Zotero_Items::get($this->libraryID, $related);
     			$keys = array();
     			foreach ($related as $item) {
     				$doc->addField('relatedItem', $item->key);
     			}
     		}*/
     return $doc;
 }
コード例 #7
0
 public static function notify($event, $type, $ids, $extraData)
 {
     if (!isset(Z_CONFIG::$SNS_TOPIC_STREAM_EVENTS)) {
         error_log('WARNING: Z_CONFIG::$SNS_TOPIC_STREAM_EVENTS not set ' . '-- skipping stream notifications');
         return;
     }
     if ($type == "library") {
         switch ($event) {
             case "modify":
                 $event = "topicUpdated";
                 break;
             case "delete":
                 $event = "topicDeleted";
                 break;
             default:
                 return;
         }
         $entries = [];
         foreach ($ids as $id) {
             $libraryID = $id;
             // For most libraries, get topic from URI
             if ($event != 'topicDeleted') {
                 // Convert 'http://zotero.org/users/...' to '/users/...'
                 $topic = str_replace(Zotero_URI::getBaseURI(), "/", Zotero_URI::getLibraryURI($libraryID));
             } else {
                 $topic = '/' . Zotero_Libraries::getType($libraryID) . "s/" . Zotero_Libraries::getLibraryTypeID($libraryID);
             }
             $message = ["event" => $event, "topic" => $topic];
             if (!empty($extraData[$id])) {
                 foreach ($extraData[$id] as $key => $val) {
                     $message[$key] = $val;
                 }
             }
             foreach (self::$messageReceivers as $receiver) {
                 $receiver(Z_CONFIG::$SNS_TOPIC_STREAM_EVENTS, json_encode($message, JSON_UNESCAPED_SLASHES));
             }
         }
     } else {
         if ($type == "apikey-library") {
             switch ($event) {
                 case "add":
                     $event = "topicAdded";
                     break;
                 case "remove":
                     $event = "topicRemoved";
                     break;
                 default:
                     return;
             }
             $entries = [];
             foreach ($ids as $id) {
                 list($apiKey, $libraryID) = explode("-", $id);
                 // Get topic from URI
                 $topic = str_replace(Zotero_URI::getBaseURI(), "/", Zotero_URI::getLibraryURI($libraryID));
                 $message = ["event" => $event, "apiKey" => $apiKey, "topic" => $topic];
                 if (!empty($extraData[$id])) {
                     foreach ($extraData[$id] as $key => $val) {
                         $message[$key] = $val;
                     }
                 }
                 self::send($message);
             }
         }
     }
 }
コード例 #8
0
ファイル: ApiController.php プロジェクト: ergo70/dataserver
 protected function getFeedNamePrefix($libraryID = false)
 {
     $prefix = "Zotero / ";
     if ($libraryID) {
         $type = Zotero_Libraries::getType($this->objectLibraryID);
     } else {
         $type = false;
     }
     switch ($type) {
         case "user":
             $title = $prefix . Zotero_Libraries::getName($this->objectLibraryID);
             break;
         case "group":
             $title = $prefix . "" . Zotero_Libraries::getName($this->objectLibraryID) . " Group";
             break;
         default:
             return $prefix;
     }
     return $title . " / ";
 }
コード例 #9
0
ファイル: Libraries.inc.php プロジェクト: ergo70/dataserver
 public static function toJSON($libraryID)
 {
     // TODO: cache
     $libraryType = Zotero_Libraries::getType($libraryID);
     if ($libraryType == 'user') {
         $objectUserID = Zotero_Users::getUserIDFromLibraryID($libraryID);
         $json = ['type' => $libraryType, 'id' => $objectUserID, 'name' => self::getName($libraryID), 'links' => ['alternate' => ['href' => Zotero_URI::getUserURI($objectUserID, true), 'type' => 'text/html']]];
     } else {
         if ($libraryType == 'publications') {
             $objectUserID = Zotero_Users::getUserIDFromLibraryID($libraryID);
             $json = ['type' => $libraryType, 'id' => $objectUserID, 'name' => self::getName($libraryID), 'links' => ['alternate' => ['href' => Zotero_URI::getUserURI($objectUserID, true) . "/publications", 'type' => 'text/html']]];
         } else {
             if ($libraryType == 'group') {
                 $objectGroupID = Zotero_Groups::getGroupIDFromLibraryID($libraryID);
                 $group = Zotero_Groups::get($objectGroupID);
                 $json = ['type' => $libraryType, 'id' => $objectGroupID, 'name' => self::getName($libraryID), 'links' => ['alternate' => ['href' => Zotero_URI::getGroupURI($group, true), 'type' => 'text/html']]];
             } else {
                 throw new Exception("Invalid library type '{$libraryType}'");
             }
         }
     }
     return $json;
 }
コード例 #10
0
 public static function isEditable($obj)
 {
     $type = static::field('object');
     // Only enforce for sync controller for now
     if (empty($GLOBALS['controller']) || !$GLOBALS['controller'] instanceof SyncController) {
         return true;
     }
     // Make sure user has access privileges to delete
     $userID = $GLOBALS['controller']->userID;
     if (!$userID) {
         return true;
     }
     $objectLibraryID = $obj->libraryID;
     $libraryType = Zotero_Libraries::getType($objectLibraryID);
     switch ($libraryType) {
         case 'user':
             if (!empty($GLOBALS['controller']->userLibraryID)) {
                 $userLibraryID = $GLOBALS['controller']->userLibraryID;
             } else {
                 $userLibraryID = Zotero_Users::getLibraryIDFromUserID($userID);
             }
             if ($objectLibraryID != $userLibraryID) {
                 return false;
             }
             return true;
         case 'group':
             $groupID = Zotero_Groups::getGroupIDFromLibraryID($objectLibraryID);
             $group = Zotero_Groups::get($groupID);
             if (!$group->hasUser($userID) || !$group->userCanEdit($userID)) {
                 return false;
             }
             if ($type == 'item' && $obj->isImportedAttachment() && !$group->userCanEditFiles($userID)) {
                 return false;
             }
             return true;
         default:
             throw new Exception("Unsupported library type '{$libraryType}'");
     }
 }
コード例 #11
0
 /**
  * This should be called after canAccess()
  */
 public function canWrite($libraryID)
 {
     if ($this->super) {
         return true;
     }
     if ($libraryID === 0) {
         return false;
     }
     if (!$libraryID) {
         throw new Exception('libraryID not provided');
     }
     if (!empty($this->permissions[$libraryID]['write'])) {
         return true;
     }
     $libraryType = Zotero_Libraries::getType($libraryID);
     switch ($libraryType) {
         case 'user':
             return false;
             // Write permissions match key's write access to user library
         // Write permissions match key's write access to user library
         case 'publications':
             $userLibraryID = Zotero_Users::getLibraryIDFromUserID($this->userID);
             return $this->canWrite($userLibraryID);
         case 'group':
             $groupID = Zotero_Groups::getGroupIDFromLibraryID($libraryID);
             // If key has write access to all groups, grant access if user
             // has write access to group
             if (!empty($this->permissions[0]['write'])) {
                 $group = Zotero_Groups::get($groupID);
                 return $group->userCanEdit($this->userID);
             }
             return false;
         default:
             throw new Exception("Unsupported library type '{$libraryType}'");
     }
 }
コード例 #12
0
ファイル: Items.inc.php プロジェクト: ergo70/dataserver
 private static function validateJSONItem($json, $libraryID, Zotero_Item $item = null, $isChild, $requestParams, $partialUpdate = false)
 {
     $isNew = !$item || !$item->version;
     if (!is_object($json)) {
         throw new Exception("Invalid item object (found " . gettype($json) . " '" . $json . "')", Z_ERROR_INVALID_INPUT);
     }
     if (isset($json->items) && is_array($json->items)) {
         throw new Exception("An 'items' array is not valid for single-item updates", Z_ERROR_INVALID_INPUT);
     }
     $apiVersion = $requestParams['v'];
     if ($partialUpdate) {
         $requiredProps = [];
     } else {
         if (isset($json->itemType) && $json->itemType == "attachment") {
             $requiredProps = array('linkMode', 'tags');
         } else {
             if (isset($json->itemType) && $json->itemType == "attachment") {
                 $requiredProps = array('tags');
             } else {
                 if ($isNew) {
                     $requiredProps = array('itemType');
                 } else {
                     if ($apiVersion < 2) {
                         $requiredProps = array('itemType', 'tags');
                     } else {
                         $requiredProps = array('itemType', 'tags', 'relations');
                         if (!$isChild) {
                             $requiredProps[] = 'collections';
                         }
                     }
                 }
             }
         }
     }
     foreach ($requiredProps as $prop) {
         if (!isset($json->{$prop})) {
             throw new Exception("'{$prop}' property not provided", Z_ERROR_INVALID_INPUT);
         }
     }
     // For partial updates where item type isn't provided, use the existing item type
     if (!isset($json->itemType) && $partialUpdate) {
         $itemType = Zotero_ItemTypes::getName($item->itemTypeID);
     } else {
         $itemType = $json->itemType;
     }
     foreach ($json as $key => $val) {
         switch ($key) {
             // Handled by Zotero_API::checkJSONObjectVersion()
             case 'key':
             case 'version':
                 if ($apiVersion < 3) {
                     throw new Exception("Invalid property '{$key}'", Z_ERROR_INVALID_INPUT);
                 }
                 break;
             case 'itemKey':
             case 'itemVersion':
                 if ($apiVersion != 2) {
                     throw new Exception("Invalid property '{$key}'", Z_ERROR_INVALID_INPUT);
                 }
                 break;
             case 'parentItem':
                 if ($apiVersion < 2) {
                     throw new Exception("Invalid property '{$key}'", Z_ERROR_INVALID_INPUT);
                 }
                 if (!Zotero_ID::isValidKey($val) && $val !== false) {
                     throw new Exception("'{$key}' must be a valid item key", Z_ERROR_INVALID_INPUT);
                 }
                 break;
             case 'itemType':
                 if (!is_string($val)) {
                     throw new Exception("'itemType' must be a string", Z_ERROR_INVALID_INPUT);
                 }
                 if ($isChild || !empty($json->parentItem)) {
                     switch ($val) {
                         case 'note':
                         case 'attachment':
                             break;
                         default:
                             throw new Exception("Child item must be note or attachment", Z_ERROR_INVALID_INPUT);
                     }
                 } else {
                     if ($val == 'attachment' && (!$item || !$item->getSource())) {
                         if ($json->linkMode == 'linked_url' || $json->linkMode == 'imported_url' && (empty($json->contentType) || $json->contentType != 'application/pdf')) {
                             throw new Exception("Only file attachments and PDFs can be top-level items", Z_ERROR_INVALID_INPUT);
                         }
                     }
                 }
                 if (!Zotero_ItemTypes::getID($val)) {
                     throw new Exception("'{$val}' is not a valid itemType", Z_ERROR_INVALID_INPUT);
                 }
                 break;
             case 'tags':
                 if (!is_array($val)) {
                     throw new Exception("'{$key}' property must be an array", Z_ERROR_INVALID_INPUT);
                 }
                 foreach ($val as $tag) {
                     $empty = true;
                     if (is_string($tag)) {
                         if ($tag === "") {
                             throw new Exception("Tag cannot be empty", Z_ERROR_INVALID_INPUT);
                         }
                         continue;
                     }
                     if (!is_object($tag)) {
                         throw new Exception("Tag must be an object", Z_ERROR_INVALID_INPUT);
                     }
                     foreach ($tag as $k => $v) {
                         switch ($k) {
                             case 'tag':
                                 if (!is_scalar($v)) {
                                     throw new Exception("Invalid tag name", Z_ERROR_INVALID_INPUT);
                                 }
                                 if ($v === "") {
                                     throw new Exception("Tag cannot be empty", Z_ERROR_INVALID_INPUT);
                                 }
                                 break;
                             case 'type':
                                 if (!is_numeric($v)) {
                                     throw new Exception("Invalid tag type '{$v}'", Z_ERROR_INVALID_INPUT);
                                 }
                                 break;
                             default:
                                 throw new Exception("Invalid tag property '{$k}'", Z_ERROR_INVALID_INPUT);
                         }
                         $empty = false;
                     }
                     if ($empty) {
                         throw new Exception("Tag object is empty", Z_ERROR_INVALID_INPUT);
                     }
                 }
                 break;
             case 'collections':
                 if (!is_array($val)) {
                     throw new Exception("'{$key}' property must be an array", Z_ERROR_INVALID_INPUT);
                 }
                 if ($isChild && $val) {
                     throw new Exception("Child items cannot be assigned to collections", Z_ERROR_INVALID_INPUT);
                 }
                 foreach ($val as $k) {
                     if (!Zotero_ID::isValidKey($k)) {
                         throw new Exception("'{$k}' is not a valid collection key", Z_ERROR_INVALID_INPUT);
                     }
                 }
                 break;
             case 'relations':
                 if ($apiVersion < 2) {
                     throw new Exception("Invalid property '{$key}'", Z_ERROR_INVALID_INPUT);
                 }
                 if (!is_object($val) && !(is_array($val) && empty($val))) {
                     throw new Exception("'{$key}' property must be an object", Z_ERROR_INVALID_INPUT);
                 }
                 foreach ($val as $predicate => $object) {
                     switch ($predicate) {
                         case 'owl:sameAs':
                         case 'dc:replaces':
                         case 'dc:relation':
                             break;
                         default:
                             throw new Exception("Unsupported predicate '{$predicate}'", Z_ERROR_INVALID_INPUT);
                     }
                     $arr = is_string($object) ? [$object] : $object;
                     foreach ($arr as $uri) {
                         if (!preg_match('/^http:\\/\\/zotero.org\\/(users|groups)\\/[0-9]+\\/(publications\\/)?items\\/[A-Z0-9]{8}$/', $uri)) {
                             throw new Exception("'{$key}' values currently must be Zotero item URIs", Z_ERROR_INVALID_INPUT);
                         }
                     }
                 }
                 break;
             case 'creators':
                 if (!is_array($val)) {
                     throw new Exception("'{$key}' property must be an array", Z_ERROR_INVALID_INPUT);
                 }
                 foreach ($val as $creator) {
                     $empty = true;
                     if (!isset($creator->creatorType)) {
                         throw new Exception("creator object must contain 'creatorType'", Z_ERROR_INVALID_INPUT);
                     }
                     if ((!isset($creator->name) || trim($creator->name) == "") && (!isset($creator->firstName) || trim($creator->firstName) == "") && (!isset($creator->lastName) || trim($creator->lastName) == "")) {
                         // On item creation, ignore single nameless creator,
                         // because that's in the item template that the API returns
                         if (sizeOf($val) == 1 && $isNew) {
                             continue;
                         } else {
                             throw new Exception("creator object must contain 'firstName'/'lastName' or 'name'", Z_ERROR_INVALID_INPUT);
                         }
                     }
                     foreach ($creator as $k => $v) {
                         switch ($k) {
                             case 'creatorType':
                                 $creatorTypeID = Zotero_CreatorTypes::getID($v);
                                 if (!$creatorTypeID) {
                                     throw new Exception("'{$v}' is not a valid creator type", Z_ERROR_INVALID_INPUT);
                                 }
                                 $itemTypeID = Zotero_ItemTypes::getID($itemType);
                                 if (!Zotero_CreatorTypes::isValidForItemType($creatorTypeID, $itemTypeID)) {
                                     // Allow 'author' in all item types, but reject other invalid creator types
                                     if ($creatorTypeID != Zotero_CreatorTypes::getID('author')) {
                                         throw new Exception("'{$v}' is not a valid creator type for item type '{$itemType}'", Z_ERROR_INVALID_INPUT);
                                     }
                                 }
                                 break;
                             case 'firstName':
                                 if (!isset($creator->lastName)) {
                                     throw new Exception("'lastName' creator field must be set if 'firstName' is set", Z_ERROR_INVALID_INPUT);
                                 }
                                 if (isset($creator->name)) {
                                     throw new Exception("'firstName' and 'name' creator fields are mutually exclusive", Z_ERROR_INVALID_INPUT);
                                 }
                                 break;
                             case 'lastName':
                                 if (!isset($creator->firstName)) {
                                     throw new Exception("'firstName' creator field must be set if 'lastName' is set", Z_ERROR_INVALID_INPUT);
                                 }
                                 if (isset($creator->name)) {
                                     throw new Exception("'lastName' and 'name' creator fields are mutually exclusive", Z_ERROR_INVALID_INPUT);
                                 }
                                 break;
                             case 'name':
                                 if (isset($creator->firstName)) {
                                     throw new Exception("'firstName' and 'name' creator fields are mutually exclusive", Z_ERROR_INVALID_INPUT);
                                 }
                                 if (isset($creator->lastName)) {
                                     throw new Exception("'lastName' and 'name' creator fields are mutually exclusive", Z_ERROR_INVALID_INPUT);
                                 }
                                 break;
                             default:
                                 throw new Exception("Invalid creator property '{$k}'", Z_ERROR_INVALID_INPUT);
                         }
                         $empty = false;
                     }
                     if ($empty) {
                         throw new Exception("Creator object is empty", Z_ERROR_INVALID_INPUT);
                     }
                 }
                 break;
             case 'note':
                 switch ($itemType) {
                     case 'note':
                     case 'attachment':
                         break;
                     default:
                         throw new Exception("'note' property is valid only for note and attachment items", Z_ERROR_INVALID_INPUT);
                 }
                 break;
             case 'attachments':
             case 'notes':
                 if ($apiVersion > 1) {
                     throw new Exception("'{$key}' property is no longer supported", Z_ERROR_INVALID_INPUT);
                 }
                 if (!$isNew) {
                     throw new Exception("'{$key}' property is valid only for new items", Z_ERROR_INVALID_INPUT);
                 }
                 if (!is_array($val)) {
                     throw new Exception("'{$key}' property must be an array", Z_ERROR_INVALID_INPUT);
                 }
                 foreach ($val as $child) {
                     // Check child item type ('attachment' or 'note')
                     $t = substr($key, 0, -1);
                     if (isset($child->itemType) && $child->itemType != $t) {
                         throw new Exception("Child {$t} must be of itemType '{$t}'", Z_ERROR_INVALID_INPUT);
                     }
                     if ($key == 'note') {
                         if (!isset($child->note)) {
                             throw new Exception("'note' property not provided for child note", Z_ERROR_INVALID_INPUT);
                         }
                     }
                 }
                 break;
             case 'deleted':
                 break;
                 // Attachment properties
             // Attachment properties
             case 'linkMode':
                 try {
                     $linkMode = Zotero_Attachments::linkModeNameToNumber($val, true);
                 } catch (Exception $e) {
                     throw new Exception("'{$val}' is not a valid linkMode", Z_ERROR_INVALID_INPUT);
                 }
                 // Don't allow changing of linkMode
                 if (!$isNew && $linkMode != $item->attachmentLinkMode) {
                     throw new Exception("Cannot change attachment linkMode", Z_ERROR_INVALID_INPUT);
                 }
                 break;
             case 'contentType':
             case 'charset':
             case 'filename':
             case 'md5':
             case 'mtime':
                 if ($itemType != 'attachment') {
                     throw new Exception("'{$key}' is valid only for attachment items", Z_ERROR_INVALID_INPUT);
                 }
                 switch ($key) {
                     case 'filename':
                     case 'md5':
                     case 'mtime':
                         $lm = isset($json->linkMode) ? $json->linkMode : Zotero_Attachments::linkModeNumberToName($item->attachmentLinkMode);
                         if (strpos(strtolower($lm), 'imported_') !== 0) {
                             throw new Exception("'{$key}' is valid only for imported attachment items", Z_ERROR_INVALID_INPUT);
                         }
                         break;
                 }
                 switch ($key) {
                     case 'contentType':
                     case 'charset':
                     case 'filename':
                         $propName = 'attachment' . ucwords($key);
                         break;
                     case 'md5':
                         $propName = 'attachmentStorageHash';
                         break;
                     case 'mtime':
                         $propName = 'attachmentStorageModTime';
                         break;
                 }
                 if (Zotero_Libraries::getType($libraryID) == 'group') {
                     if ($item && $item->{$propName} !== $val || !$item && $val !== null && $val !== "") {
                         throw new Exception("Cannot change '{$key}' directly in group library", Z_ERROR_INVALID_INPUT);
                     }
                 } else {
                     if ($key == 'md5') {
                         if ($val && !preg_match("/^[a-f0-9]{32}\$/", $val)) {
                             throw new Exception("'{$val}' is not a valid MD5 hash", Z_ERROR_INVALID_INPUT);
                         }
                     }
                 }
                 break;
             case 'accessDate':
                 if ($apiVersion >= 3 && $val !== '' && $val != 'CURRENT_TIMESTAMP' && !Zotero_Date::isSQLDate($val) && !Zotero_Date::isSQLDateTime($val) && !Zotero_Date::isISO8601($val)) {
                     throw new Exception("'{$key}' must be in ISO 8601 or UTC 'YYYY-MM-DD[ hh-mm-dd]' format or 'CURRENT_TIMESTAMP' ({$val})", Z_ERROR_INVALID_INPUT);
                 }
                 break;
             case 'dateAdded':
                 if (!Zotero_Date::isSQLDateTime($val) && !Zotero_Date::isISO8601($val)) {
                     throw new Exception("'{$key}' must be in ISO 8601 or UTC 'YYYY-MM-DD hh-mm-dd' format", Z_ERROR_INVALID_INPUT);
                 }
                 if (!$isNew) {
                     // Convert ISO date to SQL date for equality comparison
                     if (Zotero_Date::isISO8601($val)) {
                         $val = Zotero_Date::iso8601ToSQL($val);
                     }
                     if ($val != $item->{$key}) {
                         throw new Exception("'{$key}' cannot be modified for existing items", Z_ERROR_INVALID_INPUT);
                     }
                 }
                 break;
             case 'dateModified':
                 if (!Zotero_Date::isSQLDateTime($val) && !Zotero_Date::isISO8601($val)) {
                     throw new Exception("'{$key}' must be in ISO 8601 or UTC 'YYYY-MM-DD hh-mm-dd' format ({$val})", Z_ERROR_INVALID_INPUT);
                 }
                 break;
             default:
                 if (!Zotero_ItemFields::getID($key)) {
                     throw new Exception("Invalid property '{$key}'", Z_ERROR_INVALID_INPUT);
                 }
                 if (is_array($val)) {
                     throw new Exception("Unexpected array for property '{$key}'", Z_ERROR_INVALID_INPUT);
                 }
                 break;
         }
     }
     // Publications libraries have additional restrictions
     if (Zotero_Libraries::getType($libraryID) == 'publications') {
         Zotero_Publications::validateJSONItem($json);
     }
 }
コード例 #13
0
ファイル: SyncController.php プロジェクト: selenus/dataserver
 private function handleUploadError(Exception $e, $xmldata)
 {
     $msg = $e->getMessage();
     if ($msg[0] == '=') {
         $msg = substr($msg, 1);
         $explicit = true;
         // TODO: more specific error messages
     } else {
         $explicit = false;
     }
     switch ($e->getCode()) {
         case Z_ERROR_TAG_TOO_LONG:
         case Z_ERROR_COLLECTION_TOO_LONG:
             break;
         default:
             Z_Core::logError($msg);
     }
     if (!$explicit && Z_ENV_TESTING_SITE) {
         switch ($e->getCode()) {
             case Z_ERROR_COLLECTION_NOT_FOUND:
             case Z_ERROR_CREATOR_NOT_FOUND:
             case Z_ERROR_ITEM_NOT_FOUND:
             case Z_ERROR_TAG_TOO_LONG:
             case Z_ERROR_LIBRARY_ACCESS_DENIED:
             case Z_ERROR_TAG_LINKED_ITEM_NOT_FOUND:
                 break;
             default:
                 throw $e;
         }
         $id = 'N/A';
     } else {
         $id = substr(md5(uniqid(rand(), true)), 0, 8);
         $str = date("D M j G:i:s T Y") . "\n";
         $str .= "IP address: " . $_SERVER['REMOTE_ADDR'] . "\n";
         if (isset($_SERVER['HTTP_X_ZOTERO_VERSION'])) {
             $str .= "Version: " . $_SERVER['HTTP_X_ZOTERO_VERSION'] . "\n";
         }
         $str .= $msg;
         switch ($e->getCode()) {
             // Don't log uploaded data for some errors
             case Z_ERROR_TAG_TOO_LONG:
             case Z_ERROR_FIELD_TOO_LONG:
             case Z_ERROR_NOTE_TOO_LONG:
             case Z_ERROR_COLLECTION_TOO_LONG:
                 break;
             default:
                 $str .= "\n\n" . $xmldata;
         }
         if (!file_put_contents(Z_CONFIG::$SYNC_ERROR_PATH . $id, $str)) {
             error_log("Unable to save error report to " . Z_CONFIG::$SYNC_ERROR_PATH . $id);
         }
     }
     Zotero_DB::rollback(true);
     switch ($e->getCode()) {
         case Z_ERROR_LIBRARY_ACCESS_DENIED:
             preg_match('/[Ll]ibrary ([0-9]+)/', $e->getMessage(), $matches);
             $libraryID = $matches ? $matches[1] : null;
             $this->error(400, 'LIBRARY_ACCESS_DENIED', "Cannot make changes to library (Report ID: {$id})", array('libraryID' => $libraryID));
             break;
         case Z_ERROR_ITEM_NOT_FOUND:
         case Z_ERROR_COLLECTION_NOT_FOUND:
         case Z_ERROR_CREATOR_NOT_FOUND:
             error_log($e);
             $this->error(500, "FULL_SYNC_REQUIRED", "Please perform a full sync in the Sync->Reset pane of the Zotero preferences. (Report ID: {$id})");
             break;
         case Z_ERROR_TAG_TOO_LONG:
             $message = $e->getMessage();
             preg_match("/Tag '(.+)' too long/s", $message, $matches);
             if ($matches) {
                 $name = $matches[1];
                 $this->error(400, "TAG_TOO_LONG", "Tag '" . mb_substr($name, 0, 50) . "…' too long", array(), array("tag" => $name));
             }
             break;
         case Z_ERROR_COLLECTION_TOO_LONG:
             $message = $e->getMessage();
             preg_match("/Collection '(.+)' too long/s", $message, $matches);
             if ($matches) {
                 $name = $matches[1];
                 $this->error(400, "COLLECTION_TOO_LONG", "Collection '" . mb_substr($name, 0, 50) . "…' too long", array(), array("collection" => $name));
             }
             break;
         case Z_ERROR_NOTE_TOO_LONG:
             preg_match("/Note '(.+)' too long(?: for item '(.+)\\/(.+)')?/s", $msg, $matches);
             if ($matches) {
                 $name = $matches[1];
                 $libraryID = false;
                 if (isset($matches[2])) {
                     $libraryID = (int) $matches[2];
                     $itemKey = $matches[3];
                     if (Zotero_Libraries::getType($libraryID) == 'group') {
                         $groupID = Zotero_Groups::getGroupIDFromLibraryID($libraryID);
                         $group = Zotero_Groups::get($groupID);
                         $libraryName = $group->name;
                     } else {
                         $libraryName = false;
                     }
                 } else {
                     $itemKey = '';
                 }
                 $showNoteKey = false;
                 if (isset($_SERVER['HTTP_X_ZOTERO_VERSION'])) {
                     require_once '../model/ToolkitVersionComparator.inc.php';
                     $showNoteKey = ToolkitVersionComparator::compare($_SERVER['HTTP_X_ZOTERO_VERSION'], "4.0.27") < 0;
                 }
                 if ($showNoteKey) {
                     $this->error(400, "ERROR_PROCESSING_UPLOAD_DATA", "The note '" . mb_substr($name, 0, 50) . "…' in " . ($libraryName === false ? "your library " : "the group '{$libraryName}' ") . "is too long to sync to zotero.org.\n\n" . "Search for the excerpt above or copy and paste " . "'{$itemKey}' into the Zotero search bar. " . "Shorten the note, or delete it and empty the Zotero " . "trash, and then try syncing again.");
                 } else {
                     $this->error(400, "NOTE_TOO_LONG", "The note '" . mb_substr($name, 0, 50) . "…' in " . ($libraryName === false ? "your library " : "the group '{$libraryName}' ") . "is too long to sync to zotero.org.\n\n" . "Shorten the note, or delete it and empty the Zotero " . "trash, and then try syncing again.", [], $libraryID ? ["item" => $libraryID . "/" . $itemKey] : []);
                 }
             }
             break;
         case Z_ERROR_FIELD_TOO_LONG:
             preg_match("/(.+) field value '(.+)\\.\\.\\.' too long(?: for item '(.+)')?/s", $msg, $matches);
             if ($matches) {
                 $fieldName = $matches[1];
                 $value = $matches[2];
                 if (isset($matches[3])) {
                     $parts = explode("/", $matches[3]);
                     $libraryID = (int) $parts[0];
                     $itemKey = $parts[1];
                     if (Zotero_Libraries::getType($libraryID) == 'group') {
                         $groupID = Zotero_Groups::getGroupIDFromLibraryID($libraryID);
                         $group = Zotero_Groups::get($groupID);
                         $libraryName = "the group '" . $group->name . "'";
                     } else {
                         $libraryName = "your personal library";
                     }
                 } else {
                     $libraryName = "one of your libraries";
                     $itemKey = false;
                 }
                 $this->error(400, "ERROR_PROCESSING_UPLOAD_DATA", "The {$fieldName} field value '{$value}…' in {$libraryName} is " . "too long to sync to zotero.org.\n\n" . "Search for the excerpt above " . ($itemKey === false ? "using " : "or copy and paste " . "'{$itemKey}' into ") . "the Zotero search bar. " . "Shorten the field, or delete the item and empty the " . "Zotero trash, and then try syncing again.");
             }
             break;
         case Z_ERROR_ARRAY_SIZE_MISMATCH:
             $this->error(400, 'DATABASE_TOO_LARGE', "Databases of this size cannot yet be synced. Please check back soon. (Report ID: {$id})");
             break;
         case Z_ERROR_TAG_LINKED_ITEM_NOT_FOUND:
             $this->error(400, 'WRONG_LIBRARY_TAG_ITEM', "Error processing uploaded data (Report ID: {$id})");
             break;
         case Z_ERROR_SHARD_READ_ONLY:
         case Z_ERROR_SHARD_UNAVAILABLE:
             $this->error(503, 'SERVER_ERROR', Z_CONFIG::$MAINTENANCE_MESSAGE);
             break;
     }
     if (strpos($msg, "Lock wait timeout exceeded; try restarting transaction") !== false || strpos($msg, "MySQL error: Deadlock found when trying to get lock; try restarting transaction") !== false) {
         $this->error(500, 'TIMEOUT', "Sync upload timed out. Please try again in a few minutes. (Report ID: {$id})");
     }
     if (strpos($msg, "Data too long for column 'xmldata'") !== false) {
         $this->error(400, 'DATABASE_TOO_LARGE', "Databases of this size cannot yet be synced. Please check back soon. (Report ID: {$id})");
     }
     // On certain messages, send 400 to prevent auto-retry
     if (strpos($msg, " too long") !== false || strpos($msg, "First and last name are empty") !== false) {
         $this->error(400, 'ERROR_PROCESSING_UPLOAD_DATA', $explicit ? $msg : "Error processing uploaded data (Report ID: {$id})");
     }
     if (preg_match("/Incorrect datetime value: '([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2})' " . "for column 'date(Added|Modified)'/", $msg, $matches)) {
         if (isset($_SERVER['HTTP_X_ZOTERO_VERSION'])) {
             require_once '../model/ToolkitVersionComparator.inc.php';
             if (ToolkitVersionComparator::compare($_SERVER['HTTP_X_ZOTERO_VERSION'], "2.1rc1") < 0) {
                 $msg = "Invalid timestamp '{$matches[1]}' in uploaded data. Upgrade to Zotero 2.1rc1 when available to fix automatically.";
             } else {
                 $msg = "Invalid timestamp '{$matches[1]}' in uploaded data. Sync again to correct automatically.";
             }
         } else {
             $msg = "Invalid timestamp '{$matches[1]}' in uploaded data. Upgrade to Zotero 2.1rc1 when available to fix automatically.";
         }
         $this->error(400, 'INVALID_TIMESTAMP', $msg);
     }
     $this->error(500, 'ERROR_PROCESSING_UPLOAD_DATA', $explicit ? $msg : "Error processing uploaded data (Report ID: {$id})");
 }
コード例 #14
0
ファイル: ItemsController.php プロジェクト: ergo70/dataserver
 /**
  * Handle S3 request
  *
  * Permission-checking provided by items()
  */
 private function _handleFileRequest($item)
 {
     if (!$this->permissions->canAccess($this->objectLibraryID, 'files')) {
         $this->e403();
     }
     $this->allowMethods(array('HEAD', 'GET', 'POST', 'PATCH'));
     if (!$item->isAttachment()) {
         $this->e400("Item is not an attachment");
     }
     // File info for 4.0 client sync
     //
     // Use of HEAD method was discontinued after 2.0.8/2.1b1 due to
     // compatibility problems with proxies and security software
     if ($this->method == 'GET' && $this->fileMode == 'info') {
         $info = Zotero_Storage::getLocalFileItemInfo($item);
         if (!$info) {
             $this->e404();
         }
         StatsD::increment("storage.info", 1);
         /*
         header("Last-Modified: " . gmdate('r', $info['uploaded']));
         header("Content-Type: " . $info['type']);
         */
         header("Content-Length: " . $info['size']);
         header("ETag: " . $info['hash']);
         header("X-Zotero-Filename: " . $info['filename']);
         header("X-Zotero-Modification-Time: " . $info['mtime']);
         header("X-Zotero-Compressed: " . ($info['zip'] ? 'Yes' : 'No'));
         header_remove("X-Powered-By");
         $this->end();
     } else {
         if ($this->method == 'GET') {
             $info = Zotero_Storage::getLocalFileItemInfo($item);
             if (!$info) {
                 $this->e404();
             }
             // File viewing
             if ($this->fileView) {
                 $url = Zotero_Attachments::getTemporaryURL($item, !empty($_GET['int']));
                 if (!$url) {
                     $this->e500();
                 }
                 StatsD::increment("storage.view", 1);
                 $this->redirect($url);
                 exit;
             }
             // File download
             $url = Zotero_Storage::getDownloadURL($item, 60);
             if (!$url) {
                 $this->e404();
             }
             // Provide some headers to let 5.0 client skip download
             header("Zotero-File-Modification-Time: {$info['mtime']}");
             header("Zotero-File-MD5: {$info['hash']}");
             header("Zotero-File-Size: {$info['size']}");
             header("Zotero-File-Compressed: " . ($info['zip'] ? 'Yes' : 'No'));
             StatsD::increment("storage.download", 1);
             Zotero_Storage::logDownload($item, $this->userID, IPAddress::getIP());
             $this->redirect($url);
             exit;
         } else {
             if ($this->method == 'POST' || $this->method == 'PATCH') {
                 if (!$item->isImportedAttachment()) {
                     $this->e400("Cannot upload file for linked file/URL attachment item");
                 }
                 $libraryID = $item->libraryID;
                 $type = Zotero_Libraries::getType($libraryID);
                 if ($type == 'group') {
                     $groupID = Zotero_Groups::getGroupIDFromLibraryID($libraryID);
                     $group = Zotero_Groups::get($groupID);
                     if (!$group->userCanEditFiles($this->userID)) {
                         $this->e403("You do not have file editing access");
                     }
                 } else {
                     $group = null;
                 }
                 // If not the client, require If-Match or If-None-Match
                 if (!$this->httpAuth) {
                     if (empty($_SERVER['HTTP_IF_MATCH']) && empty($_SERVER['HTTP_IF_NONE_MATCH'])) {
                         $this->e428("If-Match/If-None-Match header not provided");
                     }
                     if (!empty($_SERVER['HTTP_IF_MATCH'])) {
                         if (!preg_match('/^"?([a-f0-9]{32})"?$/', $_SERVER['HTTP_IF_MATCH'], $matches)) {
                             $this->e400("Invalid ETag in If-Match header");
                         }
                         if (!$item->attachmentStorageHash) {
                             $this->e412("ETag set but file does not exist");
                         }
                         if ($item->attachmentStorageHash != $matches[1]) {
                             $this->libraryVersion = $item->version;
                             $this->libraryVersionOnFailure = true;
                             $this->e412("ETag does not match current version of file");
                         }
                     } else {
                         if ($_SERVER['HTTP_IF_NONE_MATCH'] != "*") {
                             $this->e400("Invalid value for If-None-Match header");
                         }
                         if (Zotero_Storage::getLocalFileItemInfo($item)) {
                             $this->libraryVersion = $item->version;
                             $this->libraryVersionOnFailure = true;
                             $this->e412("If-None-Match: * set but file exists");
                         }
                     }
                 }
                 //
                 // Upload authorization
                 //
                 if (!isset($_POST['update']) && !isset($_REQUEST['upload'])) {
                     $info = new Zotero_StorageFileInfo();
                     // Validate upload metadata
                     if (empty($_REQUEST['md5'])) {
                         $this->e400('MD5 hash not provided');
                     }
                     if (!preg_match('/[abcdefg0-9]{32}/', $_REQUEST['md5'])) {
                         $this->e400('Invalid MD5 hash');
                     }
                     if (!isset($_REQUEST['filename']) || $_REQUEST['filename'] === "") {
                         $this->e400('Filename not provided');
                     }
                     // Multi-file upload
                     //
                     // For ZIP files, the filename and hash of the ZIP file are different from those
                     // of the main file. We use the former for S3, and we store the latter in the
                     // upload log to set the attachment metadata with them on file registration.
                     if (!empty($_REQUEST['zipMD5'])) {
                         if (!preg_match('/[abcdefg0-9]{32}/', $_REQUEST['zipMD5'])) {
                             $this->e400('Invalid ZIP MD5 hash');
                         }
                         if (empty($_REQUEST['zipFilename'])) {
                             $this->e400('ZIP filename not provided');
                         }
                         $info->zip = true;
                         $info->hash = $_REQUEST['zipMD5'];
                         $info->filename = $_REQUEST['zipFilename'];
                         $info->itemFilename = $_REQUEST['filename'];
                         $info->itemHash = $_REQUEST['md5'];
                     } else {
                         if (!empty($_REQUEST['zipFilename'])) {
                             $this->e400('ZIP MD5 hash not provided');
                         } else {
                             $info->zip = !empty($_REQUEST['zip']);
                             $info->filename = $_REQUEST['filename'];
                             $info->hash = $_REQUEST['md5'];
                         }
                     }
                     if (empty($_REQUEST['mtime'])) {
                         $this->e400('File modification time not provided');
                     }
                     $info->mtime = $_REQUEST['mtime'];
                     if (!isset($_REQUEST['filesize'])) {
                         $this->e400('File size not provided');
                     }
                     $info->size = $_REQUEST['filesize'];
                     if (!is_numeric($info->size)) {
                         $this->e400("Invalid file size");
                     }
                     $info->contentType = isset($_REQUEST['contentType']) ? $_REQUEST['contentType'] : null;
                     if (!preg_match("/^[a-zA-Z0-9\\-\\/]+\$/", $info->contentType)) {
                         $info->contentType = null;
                     }
                     $info->charset = isset($_REQUEST['charset']) ? $_REQUEST['charset'] : null;
                     if (!preg_match("/^[a-zA-Z0-9\\-]+\$/", $info->charset)) {
                         $info->charset = null;
                     }
                     $contentTypeHeader = $info->contentType . ($info->contentType && $info->charset ? "; charset=" . $info->charset : "");
                     // Reject file if it would put account over quota
                     if ($group) {
                         $quota = Zotero_Storage::getEffectiveUserQuota($group->ownerUserID);
                         $usage = Zotero_Storage::getUserUsage($group->ownerUserID);
                     } else {
                         $quota = Zotero_Storage::getEffectiveUserQuota($this->objectUserID);
                         $usage = Zotero_Storage::getUserUsage($this->objectUserID);
                     }
                     $total = $usage['total'];
                     $fileSizeMB = round($info->size / 1024 / 1024, 1);
                     if ($total + $fileSizeMB > $quota) {
                         StatsD::increment("storage.upload.quota", 1);
                         $this->e413("File would exceed quota ({$total} + {$fileSizeMB} > {$quota})");
                     }
                     Zotero_DB::query("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
                     Zotero_DB::beginTransaction();
                     // See if file exists with this filename
                     $localInfo = Zotero_Storage::getLocalFileInfo($info);
                     if ($localInfo) {
                         $storageFileID = $localInfo['storageFileID'];
                         // Verify file size
                         if ($localInfo['size'] != $info->size) {
                             throw new Exception("Specified file size incorrect for existing file " . $info->hash . "/" . $info->filename . " ({$localInfo['size']} != {$info->size})");
                         }
                     } else {
                         $oldStorageFileID = Zotero_Storage::getFileByHash($info->hash, $info->zip);
                         if ($oldStorageFileID) {
                             // Verify file size
                             $localInfo = Zotero_Storage::getFileInfoByID($oldStorageFileID);
                             if ($localInfo['size'] != $info->size) {
                                 throw new Exception("Specified file size incorrect for duplicated file " . $info->hash . "/" . $info->filename . " ({$localInfo['size']} != {$info->size})");
                             }
                             // Create new file on S3 with new name
                             $storageFileID = Zotero_Storage::duplicateFile($oldStorageFileID, $info->filename, $info->zip, $contentTypeHeader);
                         }
                     }
                     // If we already have a file, add/update storageFileItems row and stop
                     if (!empty($storageFileID)) {
                         Zotero_Storage::updateFileItemInfo($item, $storageFileID, $info, $this->httpAuth);
                         Zotero_DB::commit();
                         StatsD::increment("storage.upload.existing", 1);
                         if ($this->httpAuth) {
                             $this->queryParams['format'] = null;
                             header('Content-Type: application/xml');
                             echo "<exists/>";
                         } else {
                             $this->queryParams['format'] = null;
                             header('Content-Type: application/json');
                             $this->libraryVersion = $item->version;
                             echo json_encode(array('exists' => 1));
                         }
                         $this->end();
                     }
                     Zotero_DB::commit();
                     // Add request to upload queue
                     $uploadKey = Zotero_Storage::queueUpload($this->userID, $info);
                     // User over queue limit
                     if (!$uploadKey) {
                         header('Retry-After: ' . Zotero_Storage::$uploadQueueTimeout);
                         if ($this->httpAuth) {
                             $this->e413("Too many queued uploads");
                         } else {
                             $this->e429("Too many queued uploads");
                         }
                     }
                     StatsD::increment("storage.upload.new", 1);
                     // Output XML for client requests (which use HTTP Auth)
                     if ($this->httpAuth) {
                         $params = Zotero_Storage::generateUploadPOSTParams($item, $info, true);
                         $this->queryParams['format'] = null;
                         header('Content-Type: application/xml');
                         $xml = new SimpleXMLElement('<upload/>');
                         $xml->url = Zotero_Storage::getUploadBaseURL();
                         $xml->key = $uploadKey;
                         foreach ($params as $key => $val) {
                             $xml->params->{$key} = $val;
                         }
                         echo $xml->asXML();
                     } else {
                         if (!empty($_REQUEST['params']) && $_REQUEST['params'] == "1") {
                             $params = array("url" => Zotero_Storage::getUploadBaseURL(), "params" => array());
                             foreach (Zotero_Storage::generateUploadPOSTParams($item, $info) as $key => $val) {
                                 $params['params'][$key] = $val;
                             }
                         } else {
                             $params = Zotero_Storage::getUploadPOSTData($item, $info);
                         }
                         $params['uploadKey'] = $uploadKey;
                         $this->queryParams['format'] = null;
                         header('Content-Type: application/json');
                         echo json_encode($params);
                     }
                     exit;
                 }
                 //
                 // API partial upload and post-upload file registration
                 //
                 if (isset($_REQUEST['upload'])) {
                     $uploadKey = $_REQUEST['upload'];
                     if (!$uploadKey) {
                         $this->e400("Upload key not provided");
                     }
                     $info = Zotero_Storage::getUploadInfo($uploadKey);
                     if (!$info) {
                         $this->e400("Upload key not found");
                     }
                     // Partial upload
                     if ($this->method == 'PATCH') {
                         if (empty($_REQUEST['algorithm'])) {
                             throw new Exception("Algorithm not specified", Z_ERROR_INVALID_INPUT);
                         }
                         $storageFileID = Zotero_Storage::patchFile($item, $info, $_REQUEST['algorithm'], $this->body);
                     } else {
                         $remoteInfo = Zotero_Storage::getRemoteFileInfo($info);
                         if (!$remoteInfo) {
                             error_log("Remote file {$info->hash}/{$info->filename} not found");
                             $this->e400("Remote file not found");
                         }
                         if ($remoteInfo->size != $info->size) {
                             error_log("Uploaded file size does not match " . "({$remoteInfo->size} != {$info->size}) " . "for file {$info->hash}/{$info->filename}");
                         }
                     }
                     // Set an automatic shared lock in getLocalFileInfo() to prevent
                     // two simultaneous transactions from adding a file
                     Zotero_DB::query("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
                     Zotero_DB::beginTransaction();
                     if (!isset($storageFileID)) {
                         // Check if file already exists, which can happen if two identical
                         // files are uploaded simultaneously
                         $fileInfo = Zotero_Storage::getLocalFileInfo($info);
                         if ($fileInfo) {
                             $storageFileID = $fileInfo['storageFileID'];
                         } else {
                             $storageFileID = Zotero_Storage::addFile($info);
                         }
                     }
                     Zotero_Storage::updateFileItemInfo($item, $storageFileID, $info);
                     Zotero_Storage::logUpload($this->userID, $item, $uploadKey, IPAddress::getIP());
                     Zotero_DB::commit();
                     header("HTTP/1.1 204 No Content");
                     header("Last-Modified-Version: " . $item->version);
                     exit;
                 }
                 //
                 // Client post-upload file registration
                 //
                 if (isset($_POST['update'])) {
                     $this->allowMethods(array('POST'));
                     if (empty($_POST['mtime'])) {
                         throw new Exception('File modification time not provided');
                     }
                     $uploadKey = $_POST['update'];
                     $info = Zotero_Storage::getUploadInfo($uploadKey);
                     if (!$info) {
                         $this->e400("Upload key not found");
                     }
                     $remoteInfo = Zotero_Storage::getRemoteFileInfo($info);
                     if (!$remoteInfo) {
                         $this->e400("Remote file not found");
                     }
                     if (!isset($info->size)) {
                         throw new Exception("Size information not available");
                     }
                     $info->mtime = $_POST['mtime'];
                     // Set an automatic shared lock in getLocalFileInfo() to prevent
                     // two simultaneous transactions from adding a file
                     Zotero_DB::query("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
                     Zotero_DB::beginTransaction();
                     // Check if file already exists, which can happen if two identical
                     // files are uploaded simultaneously
                     $fileInfo = Zotero_Storage::getLocalFileInfo($info);
                     if ($fileInfo) {
                         $storageFileID = $fileInfo['storageFileID'];
                     } else {
                         $storageFileID = Zotero_Storage::addFile($info);
                     }
                     Zotero_Storage::updateFileItemInfo($item, $storageFileID, $info, true);
                     Zotero_Storage::logUpload($this->userID, $item, $uploadKey, IPAddress::getIP());
                     Zotero_DB::commit();
                     header("HTTP/1.1 204 No Content");
                     exit;
                 }
                 throw new Exception("Invalid request", Z_ERROR_INVALID_INPUT);
             }
         }
     }
     exit;
 }
コード例 #15
0
ファイル: Users.inc.php プロジェクト: selenus/dataserver
 public static function getUserIDFromLibraryID($libraryID, $libraryType = null)
 {
     if (isset(self::$libraryUserIDs[$libraryID])) {
         return self::$libraryUserIDs[$libraryID];
     }
     $cacheKey = 'libraryUserID_' . $libraryID;
     $userID = Z_Core::$MC->get($cacheKey);
     if ($userID) {
         self::$libraryUserIDs[$libraryID] = $userID;
         return $userID;
     }
     if ($libraryType == null) {
         $libraryType = Zotero_Libraries::getType($libraryID);
     }
     switch ($libraryType) {
         case 'user':
             $sql = "SELECT userID FROM users WHERE libraryID=?";
             break;
         case 'publications':
             $sql = "SELECT userID FROM userPublications WHERE libraryID=?";
             break;
         case 'group':
             $sql = "SELECT userID FROM groupUsers JOIN groups USING (groupID) " . "WHERE libraryID=? AND role='owner'";
             break;
     }
     $userID = Zotero_DB::valueQuery($sql, $libraryID);
     if (!$userID) {
         if (!Zotero_Libraries::exists($libraryID)) {
             throw new Exception("Library {$libraryID} does not exist");
         }
         // Wrong library type passed
         error_log("Wrong library type passed for library {$libraryID} " . "in Zotero_Users::getUserIDFromLibraryID()");
         return self::getUserIDFromLibraryID($libraryID);
     }
     self::$libraryUserIDs[$libraryID] = $userID;
     Z_Core::$MC->set($cacheKey, $userID);
     return $userID;
 }
コード例 #16
0
ファイル: API.inc.php プロジェクト: robinpaulson/dataserver
 public static function getLibraryURI($libraryID)
 {
     $libraryType = Zotero_Libraries::getType($libraryID);
     switch ($libraryType) {
         case 'user':
             $id = Zotero_Users::getUserIDFromLibraryID($libraryID);
             return self::getBaseURI() . "users/{$id}";
         case 'group':
             $id = Zotero_Groups::getGroupIDFromLibraryID($libraryID);
             return self::getBaseURI() . "groups/{$id}";
     }
 }
コード例 #17
0
ファイル: Key.inc.php プロジェクト: ergo70/dataserver
 private function load()
 {
     if ($this->id) {
         $sql = "SELECT * FROM `keys` WHERE keyID=?";
         $row = Zotero_DB::rowQuery($sql, $this->id);
     } else {
         if ($this->key) {
             $sql = "SELECT * FROM `keys` WHERE `key`=?";
             $row = Zotero_DB::rowQuery($sql, $this->key);
         }
     }
     if (!$row) {
         return false;
     }
     $this->loadFromRow($row);
     $sql = "SELECT * FROM keyPermissions WHERE keyID=?";
     $rows = Zotero_DB::query($sql, $this->id);
     foreach ($rows as $row) {
         $this->permissions[$row['libraryID']][$row['permission']] = !!$row['granted'];
         if ($row['permission'] == 'library') {
             // Key-based access to library provides file access as well
             $this->permissions[$row['libraryID']]['files'] = !!$row['granted'];
             // Key-based access to group libraries provides note access as well
             if ($row['libraryID'] === 0 || Zotero_Libraries::getType($row['libraryID']) == 'group') {
                 $this->permissions[$row['libraryID']]['notes'] = !!$row['granted'];
             }
         }
     }
 }
コード例 #18
0
ファイル: API.inc.php プロジェクト: juego11/dataserver
 public static function getLibraryURI($libraryID)
 {
     $libraryType = Zotero_Libraries::getType($libraryID);
     switch ($libraryType) {
         case 'user':
             $id = Zotero_Users::getUserIDFromLibraryID($libraryID);
             return self::getBaseURI() . "users/{$id}";
         case 'publications':
             $id = Zotero_Users::getUserIDFromLibraryID($libraryID);
             return self::getBaseURI() . "users/{$id}/publications";
         case 'group':
             $id = Zotero_Groups::getGroupIDFromLibraryID($libraryID);
             return self::getBaseURI() . "groups/{$id}";
         default:
             throw new Exception("Invalid library type '{$libraryType}'");
     }
 }
コード例 #19
0
ファイル: Relation.inc.php プロジェクト: selenus/dataserver
 /**
  * Check if search exists in the database
  *
  * @return	bool			TRUE if the relation exists, FALSE if not
  */
 public function exists()
 {
     $shardID = Zotero_Shards::getByLibraryID($this->libraryID);
     if ($this->id) {
         $sql = "SELECT COUNT(*) FROM relations WHERE relationID=?";
         return !!Zotero_DB::valueQuery($sql, $this->id, $shardID);
     }
     if ($this->subject && $this->predicate && $this->object) {
         $sql = "SELECT COUNT(*) FROM relations WHERE libraryID=? AND `key`=?";
         $params = array($this->libraryID, $this->getKey());
         $exists = !!Zotero_DB::valueQuery($sql, $params, $shardID);
         // TEMP
         // For linked items, check reverse order too, since client can save in reverse
         // order when an item is dragged from a group to a personal library
         if (!$exists && $this->predicate == Zotero_Relations::$linkedObjectPredicate && Zotero_Libraries::getType($this->libraryID) == 'user') {
             $sql = "SELECT COUNT(*) FROM relations WHERE libraryID=? AND `key`=?";
             $params = [$this->libraryID, Zotero_Relations::makeKey($this->object, $this->predicate, $this->subject)];
             return !!Zotero_DB::valueQuery($sql, $params, $shardID);
         }
         return $exists;
     }
     throw new Exception("ID or subject/predicate/object not set");
 }