コード例 #1
0
ファイル: Item.inc.php プロジェクト: kskod/dataserver
	public function toHTML($asSimpleXML=false) {
		$html = new SimpleXMLElement('<table/>');
		
		/*
		// Title
		$tr = $html->addChild('tr');
		$tr->addAttribute('class', 'title');
		$tr->addChild('th', Zotero_ItemFields::getLocalizedString(false, 'title'));
		$tr->addChild('td', htmlspecialchars($item->getDisplayTitle(true)));
		*/
		
		// Item type
		Zotero_Atom::addHTMLRow(
			$html,
			"itemType",
			Zotero_ItemFields::getLocalizedString(false, 'itemType'),
			Zotero_ItemTypes::getLocalizedString($this->itemTypeID)
		);
		
		// Creators
		$creators = $this->getCreators();
		if ($creators) {
			$displayText = '';
			foreach ($creators as $creator) {
				// Two fields
				if ($creator['ref']->fieldMode == 0) {
					$displayText = $creator['ref']->firstName . ' ' . $creator['ref']->lastName;
				}
				// Single field
				else if ($creator['ref']->fieldMode == 1) {
					$displayText = $creator['ref']->lastName;
				}
				else {
					// TODO
				}
				
				Zotero_Atom::addHTMLRow(
					$html,
					"creator",
					Zotero_CreatorTypes::getLocalizedString($creator['creatorTypeID']),
					trim($displayText)
				);
			}
		}
		
		$primaryFields = array();
		$fields = array_merge($primaryFields, $this->getUsedFields());
		
		foreach ($fields as $field) {
			if (Zotero_Items::isPrimaryField($field)) {
				$fieldName = $field;
			}
			else {
				$fieldName = Zotero_ItemFields::getName($field);
			}
			
			// Skip certain fields
			switch ($fieldName) {
				case '':
				case 'userID':
				case 'libraryID':
				case 'key':
				case 'itemTypeID':
				case 'itemID':
				case 'title':
				case 'serverDateModified':
				case 'version':
					continue 2;
			}
			
			if (Zotero_ItemFields::isFieldOfBase($fieldName, 'title')) {
				continue;
			}
			
			$localizedFieldName = Zotero_ItemFields::getLocalizedString(false, $field);
			
			$value = $this->getField($field);
			$value = trim($value);
			
			// Skip empty fields
			if (!$value) {
				continue;
			}
			
			$fieldText = '';
			
			// Shorten long URLs manually until Firefox wraps at ?
			// (like Safari) or supports the CSS3 word-wrap property
			if (false && preg_match("'https?://'", $value)) {
				$fieldText = $value;
				
				$firstSpace = strpos($value, ' ');
				// Break up long uninterrupted string
				if (($firstSpace === false && strlen($value) > 29) || $firstSpace > 29) {
					$stripped = false;
					
					/*
					// Strip query string for sites we know don't need it
					for each(var re in _noQueryStringSites) {
						if (re.test($field)){
							var pos = $field.indexOf('?');
							if (pos != -1) {
								fieldText = $field.substr(0, pos);
								stripped = true;
							}
							break;
						}
					}
					*/
					
					if (!$stripped) {
						// Add a line-break after the ? of long URLs
						//$fieldText = str_replace($field.replace('?', "?<ZOTEROBREAK/>");
						
						// Strip query string variables from the end while the
						// query string is longer than the main part
						$pos = strpos($fieldText, '?');
						if ($pos !== false) {
							while ($pos < (strlen($fieldText) / 2)) {
								$lastAmp = strrpos($fieldText, '&');
								if ($lastAmp === false) {
									break;
								}
								$fieldText = substr($fieldText, 0, $lastAmp);
								$shortened = true;
							}
							// Append '&...' to the end
							if ($shortened) {
								 $fieldText .= "&…";
							}
						}
					}
				}
				
				if ($field == 'url') {
					$linkContainer = new SimpleXMLElement("<container/>");
					$linkContainer->a = $value;
					$linkContainer->a['href'] = $fieldText;
				}
			}
			// Remove SQL date from multipart dates
			// (e.g. '2006-00-00 Summer 2006' becomes 'Summer 2006')
			else if ($fieldName == 'date') {
				$fieldText = $value;
			}
			// Convert dates to local format
			else if ($fieldName == 'accessDate' || $fieldName == 'dateAdded' || $fieldName == 'dateModified') {
				//$date = Zotero.Date.sqlToDate($field, true)
				$date = $value;
				//fieldText = escapeXML(date.toLocaleString());
				$fieldText = $date;
			}
			else {
				$fieldText = $value;
			}
			
			if (isset($linkContainer)) {
				$tr = Zotero_Atom::addHTMLRow($html, $fieldName, $localizedFieldName, "", true);
				
				$tdNode = dom_import_simplexml($tr->td);
				$linkNode = dom_import_simplexml($linkContainer->a);
				$importedNode = $tdNode->ownerDocument->importNode($linkNode, true);
				$tdNode->appendChild($importedNode);
				unset($linkContainer);
			}
			else {
				Zotero_Atom::addHTMLRow($html, $fieldName, $localizedFieldName, $fieldText);
			}
		}
		
		if ($this->isNote() || $this->isAttachment()) {
			$note = $this->getNote(true);
			if ($note) {
				$tr = Zotero_Atom::addHTMLRow($html, "note", "Note", "", true);
				
				try {
					$noteXML = @new SimpleXMLElement("<td>" . $note . "</td>");
					$trNode = dom_import_simplexml($tr);
					$tdNode = $trNode->getElementsByTagName("td")->item(0);
					$noteNode = dom_import_simplexml($noteXML);
					$importedNode = $trNode->ownerDocument->importNode($noteNode, true);
					$trNode->replaceChild($importedNode, $tdNode);
					unset($noteXML);
				}
				catch (Exception $e) {
					// Store non-HTML notes as <pre>
					$tr->td->pre = $note;
				}
			}
		}
		
		if ($this->isAttachment()) {
			Zotero_Atom::addHTMLRow($html, "linkMode", "Link Mode", $this->attachmentLinkMode);
			Zotero_Atom::addHTMLRow($html, "mimeType", "MIME Type", $this->attachmentMIMEType);
			Zotero_Atom::addHTMLRow($html, "charset", "Character Set", $this->attachmentCharset);
			
			// TODO: get from a constant
			/*if ($this->attachmentLinkMode != 3) {
				$doc->addField('path', $this->attachmentPath);
			}*/
		}
		
		if ($this->getDeleted()) {
			Zotero_Atom::addHTMLRow($html, "deleted", "Deleted", "Yes");
		}
		
		if ($asSimpleXML) {
			return $html;
		}
		
		return str_replace('<?xml version="1.0"?>', '', $html->asXML());
	}
コード例 #2
0
 /**
  * JSON type/field data
  */
 public function mappings()
 {
     if (!empty($_GET['locale']) && $_GET['locale'] != 'en-US') {
         $this->e400("Non-English locales are not yet supported");
     }
     $locale = empty($_GET['locale']) ? 'en-US' : $_GET['locale'];
     if ($this->subset == 'itemTypeFields') {
         if (empty($_GET['itemType'])) {
             $this->e400("'itemType' not provided");
         }
         $itemType = $_GET['itemType'];
         $itemTypeID = Zotero_ItemTypes::getID($itemType);
         if (!$itemTypeID) {
             $this->e400("Invalid item type '{$itemType}'");
         }
     } else {
         if ($this->subset == 'itemTypeCreatorTypes') {
             if (empty($_GET['itemType'])) {
                 $this->e400("'itemType' not provided");
             }
             $itemType = $_GET['itemType'];
             $itemTypeID = Zotero_ItemTypes::getID($itemType);
             if (!$itemTypeID) {
                 $this->e400("Invalid item type '{$itemType}'");
             }
             // Notes and attachments don't have creators
             if ($itemType == 'note' || $itemType == 'attachment') {
                 echo "[]";
                 exit;
             }
         }
     }
     // TODO: check If-Modified-Since and return 304 if not changed
     $cacheKey = $this->subset . "JSON";
     if (isset($itemTypeID)) {
         $cacheKey .= "_" . $itemTypeID;
     }
     $ttl = 60;
     if ($this->queryParams['pprint']) {
         $cacheKey .= "_pprint";
     }
     $json = Z_Core::$MC->get($cacheKey);
     if ($json) {
         if ($this->queryParams['pprint']) {
             header("Content-Type: text/plain");
         } else {
             header("Content-Type: application/json");
         }
         echo $json;
         exit;
     }
     switch ($this->subset) {
         case 'itemTypes':
             $rows = Zotero_ItemTypes::getAll($locale);
             $propName = 'itemType';
             break;
         case 'itemTypeFields':
             $fieldIDs = Zotero_ItemFields::getItemTypeFields($itemTypeID);
             $rows = array();
             foreach ($fieldIDs as $fieldID) {
                 $fieldName = Zotero_ItemFields::getName($fieldID);
                 $rows[] = array('name' => $fieldName, 'localized' => Zotero_ItemFields::getLocalizedString($itemTypeID, $fieldName, $locale));
             }
             $propName = 'field';
             break;
         case 'itemFields':
             $rows = Zotero_ItemFields::getAll($locale);
             $propName = 'field';
             break;
         case 'itemTypeCreatorTypes':
             $rows = Zotero_CreatorTypes::getTypesForItemType($itemTypeID, $locale);
             $propName = 'creatorType';
             break;
         case 'creatorFields':
             $rows = Zotero_Creators::getLocalizedFieldNames();
             $propName = 'field';
             break;
     }
     $json = array();
     foreach ($rows as $row) {
         $json[] = array($propName => $row['name'], 'localized' => $row['localized']);
     }
     if ($this->queryParams['pprint']) {
         header("Content-Type: text/plain");
         $json = Zotero_Utilities::json_encode_pretty($json);
         Z_Core::$MC->set($cacheKey, $json, $ttl);
     } else {
         header("Content-Type: application/json");
         $json = json_encode($json);
         Z_Core::$MC->set($cacheKey, $json, $ttl);
     }
     echo $json;
     exit;
 }
コード例 #3
0
ファイル: Sync.inc.php プロジェクト: robinpaulson/dataserver
 public static function checkUploadForErrors($syncProcessID)
 {
     Zotero_DB::beginTransaction();
     if (Z_Core::probability(30)) {
         $sql = "UPDATE syncUploadQueue SET started=NULL, errorCheck=0 WHERE started IS NOT NULL AND errorCheck=1 AND\n\t\t\t\t\t\tstarted < (NOW() - INTERVAL 15 MINUTE) AND finished IS NULL";
         Zotero_DB::query($sql);
     }
     // Get a queued process that hasn't been error-checked and is large enough to warrant it
     $sql = "SELECT * FROM syncUploadQueue WHERE started IS NULL AND errorCheck=0\n\t\t\t\tAND dataLength>=" . self::$minErrorCheckSize . " ORDER BY added LIMIT 1 FOR UPDATE";
     $row = Zotero_DB::rowQuery($sql);
     // No pending processes
     if (!$row) {
         Zotero_DB::commit();
         return 0;
     }
     $sql = "UPDATE syncUploadQueue SET started=NOW(), errorCheck=1 WHERE syncUploadQueueID=?";
     Zotero_DB::query($sql, array($row['syncUploadQueueID']));
     // We track error processes as upload processes that just get reset back to
     // started=NULL on completion (but with errorCheck=2)
     self::addUploadProcess($row['userID'], null, $row['syncUploadQueueID'], $syncProcessID);
     Zotero_DB::commit();
     try {
         $doc = new DOMDocument();
         $doc->loadXML($row['xmldata']);
         // Get long tags
         $value = Zotero_Tags::getLongDataValueFromXML($doc);
         if ($value) {
             throw new Exception("Tag '" . $value . "' too long", Z_ERROR_TAG_TOO_LONG);
         }
         // Get long collection names
         $value = Zotero_Collections::getLongDataValueFromXML($doc);
         if ($value) {
             throw new Exception("Collection '" . $value . "' too long", Z_ERROR_COLLECTION_TOO_LONG);
         }
         // Get long creator names
         $node = Zotero_Creators::getLongDataValueFromXML($doc);
         // returns DOMNode rather than value
         if ($node) {
             if ($node->nodeName == 'firstName') {
                 throw new Exception("=First name '" . mb_substr($node->nodeValue, 0, 50) . "…' too long");
             }
             if ($node->nodeName == 'lastName') {
                 throw new Exception("=Last name '" . mb_substr($node->nodeValue, 0, 50) . "…' too long");
             }
             if ($node->nodeName == 'name') {
                 throw new Exception("=Name '" . mb_substr($node->nodeValue, 0, 50) . "…' too long");
             }
         }
         $node = Zotero_Items::getLongDataValueFromXML($doc);
         // returns DOMNode rather than value
         if ($node) {
             $fieldName = $node->getAttribute('name');
             $fieldName = Zotero_ItemFields::getLocalizedString(null, $fieldName);
             if ($fieldName) {
                 $start = "'{$fieldName}' field";
             } else {
                 $start = "Field";
             }
             throw new Exception("={$start} value '" . mb_substr($node->nodeValue, 0, 50) . "...' too long");
         }
     } catch (Exception $e) {
         //Z_Core::logError($e);
         Zotero_DB::beginTransaction();
         $sql = "UPDATE syncUploadQueue SET syncProcessID=NULL, finished=?,\n\t\t\t\t\t\terrorCode=?, errorMessage=? WHERE syncUploadQueueID=?";
         Zotero_DB::query($sql, array(Zotero_DB::getTransactionTimestamp(), $e->getCode(), serialize($e), $row['syncUploadQueueID']));
         $sql = "DELETE FROM syncUploadQueueLocks WHERE syncUploadQueueID=?";
         Zotero_DB::query($sql, $row['syncUploadQueueID']);
         self::removeUploadProcess($syncProcessID);
         Zotero_DB::commit();
         return -2;
     }
     Zotero_DB::beginTransaction();
     $sql = "UPDATE syncUploadQueue SET syncProcessID=NULL, started=NULL, errorCheck=2 WHERE syncUploadQueueID=?";
     Zotero_DB::query($sql, $row['syncUploadQueueID']);
     self::removeUploadProcess($syncProcessID);
     Zotero_DB::commit();
     return 1;
 }
コード例 #4
0
ファイル: Sync.inc.php プロジェクト: selenus/dataserver
 public static function checkUploadForErrors($syncProcessID)
 {
     Zotero_DB::beginTransaction();
     if (Z_Core::probability(30)) {
         $sql = "UPDATE syncUploadQueue SET started=NULL, errorCheck=0 WHERE started IS NOT NULL AND errorCheck=1 AND\n\t\t\t\t\t\tstarted < (NOW() - INTERVAL 15 MINUTE) AND finished IS NULL";
         Zotero_DB::query($sql);
     }
     // Get a queued process that hasn't been error-checked and is large enough to warrant it
     $sql = "SELECT * FROM syncUploadQueue WHERE started IS NULL AND errorCheck=0\n\t\t\t\tAND dataLength>=" . self::$minErrorCheckSize . " ORDER BY added LIMIT 1 FOR UPDATE";
     $row = Zotero_DB::rowQuery($sql);
     // No pending processes
     if (!$row) {
         Zotero_DB::commit();
         return 0;
     }
     $sql = "UPDATE syncUploadQueue SET started=NOW(), errorCheck=1 WHERE syncUploadQueueID=?";
     Zotero_DB::query($sql, array($row['syncUploadQueueID']));
     // We track error processes as upload processes that just get reset back to
     // started=NULL on completion (but with errorCheck=2)
     self::addUploadProcess($row['userID'], null, $row['syncUploadQueueID'], $syncProcessID);
     Zotero_DB::commit();
     try {
         $doc = new DOMDocument();
         $doc->loadXML($row['xmldata'], LIBXML_COMPACT | LIBXML_PARSEHUGE);
         // Get long tags
         $value = Zotero_Tags::getLongDataValueFromXML($doc);
         if ($value) {
             throw new Exception("Tag '" . $value . "' too long", Z_ERROR_TAG_TOO_LONG);
         }
         // Get long collection names
         $value = Zotero_Collections::getLongDataValueFromXML($doc);
         if ($value) {
             throw new Exception("Collection '" . $value . "' too long", Z_ERROR_COLLECTION_TOO_LONG);
         }
         // Get long creator names
         $node = Zotero_Creators::getLongDataValueFromXML($doc);
         // returns DOMNode rather than value
         if ($node) {
             $name = mb_substr($node->nodeValue, 0, 50);
             throw new Exception("=The name ‘{$name}…’ is too long to sync.\n\n" . "Search for the item with this name and shorten it. " . "Note that the item may be in the trash or in a group library.\n\n" . "If you receive this message repeatedly for items saved from a " . "particular site, you can report this issue in the Zotero Forums.", Z_ERROR_CREATOR_TOO_LONG);
         }
         // Get long item data fields
         $node = Zotero_Items::getLongDataValueFromXML($doc);
         // returns DOMNode rather than value
         if ($node) {
             $libraryID = $node->parentNode->getAttribute('libraryID');
             $key = $node->parentNode->getAttribute('key');
             if ($libraryID) {
                 $key = $libraryID . "/" . $key;
             }
             $fieldName = $node->getAttribute('name');
             $fieldName = Zotero_ItemFields::getLocalizedString(null, $fieldName);
             if ($fieldName) {
                 $start = "{$fieldName} field";
             } else {
                 $start = "Field";
             }
             throw new Exception("={$start} value '" . mb_substr($node->nodeValue, 0, 75) . "...' too long for item '{$key}'", Z_ERROR_FIELD_TOO_LONG);
         }
     } catch (Exception $e) {
         //Z_Core::logError($e);
         Zotero_DB::beginTransaction();
         $sql = "UPDATE syncUploadQueue SET syncProcessID=NULL, finished=?,\n\t\t\t\t\t\terrorCode=?, errorMessage=? WHERE syncUploadQueueID=?";
         Zotero_DB::query($sql, array(Zotero_DB::getTransactionTimestamp(), $e->getCode(), serialize($e), $row['syncUploadQueueID']));
         $sql = "DELETE FROM syncUploadQueueLocks WHERE syncUploadQueueID=?";
         Zotero_DB::query($sql, $row['syncUploadQueueID']);
         self::removeUploadProcess($syncProcessID);
         Zotero_DB::commit();
         return -2;
     }
     Zotero_DB::beginTransaction();
     $sql = "UPDATE syncUploadQueue SET syncProcessID=NULL, started=NULL, errorCheck=2 WHERE syncUploadQueueID=?";
     Zotero_DB::query($sql, $row['syncUploadQueueID']);
     self::removeUploadProcess($syncProcessID);
     Zotero_DB::commit();
     return 1;
 }
コード例 #5
0
 /**
  * JSON type/field data
  */
 public function mappings()
 {
     if (!empty($_GET['locale']) && $_GET['locale'] != 'en-US') {
         $this->e400("Non-English locales are not yet supported");
     }
     $locale = empty($_GET['locale']) ? 'en-US' : $_GET['locale'];
     if ($this->subset == 'itemTypeFields') {
         if (empty($_GET['itemType'])) {
             $this->e400("'itemType' not provided");
         }
         $itemType = $_GET['itemType'];
         $itemTypeID = Zotero_ItemTypes::getID($itemType);
         if (!$itemTypeID) {
             $this->e400("Invalid item type '{$itemType}'");
         }
     } else {
         if ($this->subset == 'itemTypeCreatorTypes') {
             if (empty($_GET['itemType'])) {
                 $this->e400("'itemType' not provided");
             }
             $itemType = $_GET['itemType'];
             $itemTypeID = Zotero_ItemTypes::getID($itemType);
             if (!$itemTypeID) {
                 $this->e400("Invalid item type '{$itemType}'");
             }
             // Notes and attachments don't have creators
             if ($itemType == 'note' || $itemType == 'attachment') {
                 echo "[]";
                 exit;
             }
         }
     }
     // TODO: check If-Modified-Since and return 304 if not changed
     $cacheKey = $this->subset . "JSON";
     if (isset($itemTypeID)) {
         $cacheKey .= "_" . $itemTypeID;
     }
     $cacheKey .= '_' . $this->apiVersion;
     $ttl = 60;
     $json = Z_Core::$MC->get($cacheKey);
     if ($json) {
         header("Content-Type: application/json");
         echo $json;
         exit;
     }
     switch ($this->subset) {
         case 'itemTypes':
             $rows = Zotero_ItemTypes::getAll($locale);
             $propName = 'itemType';
             break;
         case 'itemTypeFields':
             $fieldIDs = Zotero_ItemFields::getItemTypeFields($itemTypeID);
             $rows = array();
             foreach ($fieldIDs as $fieldID) {
                 $fieldName = Zotero_ItemFields::getName($fieldID);
                 $rows[] = array('id' => $fieldID, 'name' => $fieldName, 'localized' => Zotero_ItemFields::getLocalizedString($itemTypeID, $fieldName, $locale));
             }
             $propName = 'field';
             break;
         case 'itemFields':
             $rows = Zotero_ItemFields::getAll($locale);
             $propName = 'field';
             break;
         case 'itemTypeCreatorTypes':
             $rows = Zotero_CreatorTypes::getTypesForItemType($itemTypeID, $locale);
             $propName = 'creatorType';
             break;
         case 'creatorFields':
             $rows = Zotero_Creators::getLocalizedFieldNames();
             $propName = 'field';
             break;
     }
     $json = array();
     foreach ($rows as $row) {
         // Before v3, computerProgram's 'versionNumber' was just 'version'
         if ($this->apiVersion < 3 && ($this->subset == 'itemTypeFields' || $this->subset == 'itemFields') && $row['id'] == 81) {
             $row['name'] = 'version';
         }
         $json[] = array($propName => $row['name'], 'localized' => $row['localized']);
     }
     header("Content-Type: application/json");
     $json = Zotero_Utilities::formatJSON($json);
     Z_Core::$MC->set($cacheKey, $json, $ttl);
     echo $json;
     exit;
 }