Exemplo n.º 1
0
 /**
  * Converts a Zotero_Item object to a SimpleXMLElement item
  *
  * @param	object				$item		Zotero_Item object
  * @param	array				$data
  * @return	SimpleXMLElement					Item data as SimpleXML element
  */
 public static function convertItemToXML(Zotero_Item $item, $data = array())
 {
     $t = microtime(true);
     // Check cache for all items except imported attachments,
     // which don't have their versions updated when the client
     // updates their file metadata
     if (!$item->isImportedAttachment()) {
         $cacheVersion = 1;
         $cacheKey = "syncXMLItem_" . $item->libraryID . "/" . $item->id . "_" . $item->version . "_" . md5(json_encode($data)) . "_" . $cacheVersion . (isset(Z_CONFIG::$CACHE_VERSION_SYNC_XML_ITEM) ? "_" . Z_CONFIG::$CACHE_VERSION_SYNC_XML_ITEM : "");
         $xmlstr = Z_Core::$MC->get($cacheKey);
     } else {
         $cacheKey = false;
         $xmlstr = false;
     }
     if ($xmlstr) {
         $xml = new SimpleXMLElement($xmlstr);
         StatsD::timing("api.items.itemToSyncXML.cached", (microtime(true) - $t) * 1000);
         StatsD::increment("memcached.items.itemToSyncXML.hit");
         // Skip the cache every 10 times for now, to ensure cache sanity
         if (Z_Core::probability(10)) {
             //$xmlstr = $xml->saveXML();
         } else {
             Z_Core::debug("Using cached sync XML item");
             return $xml;
         }
     }
     $xml = new SimpleXMLElement('<item/>');
     // Primary fields
     foreach (self::$primaryFields as $field) {
         switch ($field) {
             case 'id':
             case 'serverDateModified':
             case 'version':
                 continue 2;
             case 'itemTypeID':
                 $xmlField = 'itemType';
                 $xmlValue = Zotero_ItemTypes::getName($item->{$field});
                 break;
             default:
                 $xmlField = $field;
                 $xmlValue = $item->{$field};
         }
         $xml[$xmlField] = $xmlValue;
     }
     // Item data
     $itemTypeID = $item->itemTypeID;
     $fieldIDs = $item->getUsedFields();
     foreach ($fieldIDs as $fieldID) {
         $val = $item->getField($fieldID);
         if ($val == '') {
             continue;
         }
         $f = $xml->addChild('field', htmlspecialchars($val));
         $fieldName = Zotero_ItemFields::getName($fieldID);
         // Special handling for renamed computerProgram 'version' field
         if ($itemTypeID == 32 && $fieldName == 'versionNumber') {
             $fieldName = 'version';
         }
         $f['name'] = htmlspecialchars($fieldName);
     }
     // Deleted item flag
     if ($item->deleted) {
         $xml['deleted'] = '1';
     }
     if ($item->isNote() || $item->isAttachment()) {
         $sourceItemID = $item->getSource();
         if ($sourceItemID) {
             $sourceItem = Zotero_Items::get($item->libraryID, $sourceItemID);
             if (!$sourceItem) {
                 throw new Exception("Source item {$sourceItemID} not found");
             }
             $xml['sourceItem'] = $sourceItem->key;
         }
     }
     // Group modification info
     $createdByUserID = null;
     $lastModifiedByUserID = null;
     switch (Zotero_Libraries::getType($item->libraryID)) {
         case 'group':
             $createdByUserID = $item->createdByUserID;
             $lastModifiedByUserID = $item->lastModifiedByUserID;
             break;
     }
     if ($createdByUserID) {
         $xml['createdByUserID'] = $createdByUserID;
     }
     if ($lastModifiedByUserID) {
         $xml['lastModifiedByUserID'] = $lastModifiedByUserID;
     }
     if ($item->isAttachment()) {
         $xml['linkMode'] = $item->attachmentLinkMode;
         $xml['mimeType'] = $item->attachmentMIMEType;
         if ($item->attachmentCharset) {
             $xml['charset'] = $item->attachmentCharset;
         }
         $storageModTime = $item->attachmentStorageModTime;
         if ($storageModTime) {
             $xml['storageModTime'] = $storageModTime;
         }
         $storageHash = $item->attachmentStorageHash;
         if ($storageHash) {
             $xml['storageHash'] = $storageHash;
         }
         // TODO: get from a constant
         if ($item->attachmentLinkMode != 3) {
             $xml->addChild('path', htmlspecialchars($item->attachmentPath));
         }
     }
     // Note
     if ($item->isNote() || $item->isAttachment()) {
         // Get htmlspecialchars'ed note
         $note = $item->getNote(false, true);
         if ($note !== '') {
             $xml->addChild('note', $note);
         } else {
             if ($item->isNote()) {
                 $xml->addChild('note', '');
             }
         }
     }
     // Creators
     $creators = $item->getCreators();
     if ($creators) {
         foreach ($creators as $index => $creator) {
             $c = $xml->addChild('creator');
             $c['key'] = $creator['ref']->key;
             $c['creatorType'] = htmlspecialchars(Zotero_CreatorTypes::getName($creator['creatorTypeID']));
             $c['index'] = $index;
             if (empty($data['updatedCreators']) || !in_array($creator['ref']->id, $data['updatedCreators'])) {
                 $cNode = dom_import_simplexml($c);
                 $creatorXML = Zotero_Creators::convertCreatorToXML($creator['ref'], $cNode->ownerDocument);
                 $cNode->appendChild($creatorXML);
             }
         }
     }
     // Related items
     $relatedKeys = $item->relatedItems;
     $keys = array();
     foreach ($relatedKeys as $relatedKey) {
         if (Zotero_Items::getByLibraryAndKey($item->libraryID, $relatedKey)) {
             $keys[] = $relatedKey;
         }
     }
     if ($keys) {
         $xml->related = implode(' ', $keys);
     }
     if ($xmlstr) {
         $uncached = $xml->saveXML();
         if ($xmlstr != $uncached) {
             error_log("Cached sync XML item does not match");
             error_log("  Cached: " . $xmlstr);
             error_log("Uncached: " . $uncached);
         }
     } else {
         $xmlstr = $xml->saveXML();
         if ($cacheKey) {
             Z_Core::$MC->set($cacheKey, $xmlstr, 3600);
             // 1 hour for now
         }
         StatsD::timing("api.items.itemToSyncXML.uncached", (microtime(true) - $t) * 1000);
         StatsD::increment("memcached.items.itemToSyncXML.miss");
     }
     return $xml;
 }
Exemplo n.º 2
0
 /**
  * Converts a Zotero_Item object to a SimpleXMLElement item
  *
  * @param	object				$item		Zotero_Item object
  * @param	array				$data
  * @return	SimpleXMLElement					Item data as SimpleXML element
  */
 public static function convertItemToXML(Zotero_Item $item, $data = array(), $apiVersion = null)
 {
     $xml = new SimpleXMLElement('<item/>');
     // Primary fields
     foreach (Zotero_Items::$primaryFields as $field) {
         switch ($field) {
             case 'itemID':
             case 'serverDateModified':
             case 'itemVersion':
             case 'numAttachments':
             case 'numNotes':
                 continue 2;
             case 'itemTypeID':
                 $xmlField = 'itemType';
                 $xmlValue = Zotero_ItemTypes::getName($item->{$field});
                 break;
             default:
                 $xmlField = $field;
                 $xmlValue = $item->{$field};
         }
         $xml[$xmlField] = $xmlValue;
     }
     // Item data
     $fieldIDs = $item->getUsedFields();
     foreach ($fieldIDs as $fieldID) {
         $val = $item->getField($fieldID);
         if ($val == '') {
             continue;
         }
         $f = $xml->addChild('field', htmlspecialchars($val));
         $f['name'] = htmlspecialchars(Zotero_ItemFields::getName($fieldID));
     }
     // Deleted item flag
     if ($item->deleted) {
         $xml['deleted'] = '1';
     }
     if ($item->isNote() || $item->isAttachment()) {
         $sourceItemID = $item->getSource();
         if ($sourceItemID) {
             $sourceItem = Zotero_Items::get($item->libraryID, $sourceItemID);
             if (!$sourceItem) {
                 throw new Exception("Source item {$sourceItemID} not found");
             }
             $xml['sourceItem'] = $sourceItem->key;
         }
     }
     // Group modification info
     $createdByUserID = null;
     $lastModifiedByUserID = null;
     switch (Zotero_Libraries::getType($item->libraryID)) {
         case 'group':
             $createdByUserID = $item->createdByUserID;
             $lastModifiedByUserID = $item->lastModifiedByUserID;
             break;
     }
     if ($createdByUserID) {
         $xml['createdByUserID'] = $createdByUserID;
     }
     if ($lastModifiedByUserID) {
         $xml['lastModifiedByUserID'] = $lastModifiedByUserID;
     }
     if ($item->isAttachment()) {
         $xml['linkMode'] = $item->attachmentLinkMode;
         $xml['mimeType'] = $item->attachmentMIMEType;
         if ($apiVersion == 1 || $item->attachmentCharset) {
             $xml['charset'] = $item->attachmentCharset;
         }
         $storageModTime = $item->attachmentStorageModTime;
         if ($apiVersion > 1 && $storageModTime) {
             $xml['storageModTime'] = $storageModTime;
         }
         $storageHash = $item->attachmentStorageHash;
         if ($apiVersion > 1 && $storageHash) {
             $xml['storageHash'] = $storageHash;
         }
         // TODO: get from a constant
         if ($item->attachmentLinkMode != 3) {
             $xml->addChild('path', htmlspecialchars($item->attachmentPath));
         }
     }
     // Note
     if ($item->isNote() || $item->isAttachment()) {
         // Get htmlspecialchars'ed note
         $note = $item->getNote(false, true);
         if ($note !== '') {
             $xml->addChild('note', $note);
         } else {
             if ($item->isNote()) {
                 $xml->addChild('note', '');
             }
         }
     }
     // Creators
     $creators = $item->getCreators();
     if ($creators) {
         foreach ($creators as $index => $creator) {
             $c = $xml->addChild('creator');
             $c['key'] = $creator['ref']->key;
             $c['creatorType'] = htmlspecialchars(Zotero_CreatorTypes::getName($creator['creatorTypeID']));
             $c['index'] = $index;
             if (empty($data['updatedCreators']) || !in_array($creator['ref']->id, $data['updatedCreators'])) {
                 $cNode = dom_import_simplexml($c);
                 $creatorXML = Zotero_Creators::convertCreatorToXML($creator['ref'], $cNode->ownerDocument);
                 $cNode->appendChild($creatorXML);
             }
         }
     }
     // Related items
     $related = $item->relatedItems;
     if ($related) {
         $related = Zotero_Items::get($item->libraryID, $related);
         $keys = array();
         foreach ($related as $item) {
             $keys[] = $item->key;
         }
         if ($keys) {
             $xml->related = implode(' ', $keys);
         }
     }
     return $xml;
 }