/** * Get the text of an item note **/ public function getNote($sanitized = false, $htmlspecialchars = false) { if (!$this->isNote() && !$this->isAttachment()) { throw new Exception("getNote() can only be called on notes and attachments"); } if (!$this->id) { return ''; } // Store access time for later garbage collection //$this->noteAccessTime = new Date(); if ($sanitized) { if ($htmlspecialchars) { throw new Exception('$sanitized and $htmlspecialchars cannot currently be used together'); } if (is_null($this->noteText)) { $sql = "SELECT note, noteSanitized FROM itemNotes WHERE itemID=?"; $row = Zotero_DB::rowQuery($sql, $this->id, Zotero_Shards::getByLibraryID($this->libraryID)); if (!$row) { $row = array('note' => '', 'noteSanitized' => ''); } // Empty string means the note is sanitized // Null means not yet processed if ($row['noteSanitized'] === '') { $this->noteText = $row['note']; $this->noteTextSanitized =& $this->noteText; } else { $this->noteText = $row['note']; if (!is_null($row['noteSanitized'])) { $this->noteTextSanitized = $row['noteSanitized']; } } } // DEBUG: Shouldn't be necessary anymore if (is_null($this->noteTextSanitized)) { $sanitized = Zotero_Notes::sanitize($this->noteText); // If sanitized version is the same, use reference if ($this->noteText == $sanitized) { $this->noteTextSanitized =& $this->noteText; } else { $this->noteTextSanitized = $sanitized; } } return $this->noteTextSanitized; } if (is_null($this->noteText)) { $note = Zotero_Notes::getCachedNote($this->libraryID, $this->id); if ($note === false) { $sql = "SELECT note FROM itemNotes WHERE itemID=?"; $note = Zotero_DB::valueQuery($sql, $this->id, Zotero_Shards::getByLibraryID($this->libraryID)); } $this->noteText = $note ? $note : ''; } if ($this->noteText !== '' && $htmlspecialchars) { $noteHash = $this->getNoteHash(); if (!$noteHash) { throw new Exception("Note hash is empty"); } $cacheKey = "htmlspecialcharsNote_{$noteHash}"; $note = Z_Core::$MC->get($cacheKey); if ($note === false) { $note = htmlspecialchars($this->noteText); Z_Core::$MC->set($cacheKey, $note); } return $note; } return $this->noteText; }
/** * Set an item note * * Note: This can only be called on notes and attachments **/ public function setNote($text) { if (!$this->isNote() && !$this->isAttachment()) { trigger_error("setNote() can only be called on notes and attachments", E_USER_ERROR); } if (!is_string($text)) { $text = ''; } if (mb_strlen($text) > Zotero_Notes::$MAX_NOTE_LENGTH) { // UTF-8 (0xC2 0xA0) isn't trimmed by default $whitespace = chr(0x20) . chr(0x09) . chr(0x0A) . chr(0x0D) . chr(0x00) . chr(0x0B) . chr(0xC2) . chr(0xA0); $excerpt = iconv( "UTF-8", "UTF-8//IGNORE", Zotero_Notes::noteToTitle(trim($text), true) ); $excerpt = trim($excerpt, $whitespace); // If tag-stripped version is empty, just return raw HTML if ($excerpt == '') { $excerpt = iconv( "UTF-8", "UTF-8//IGNORE", preg_replace( '/\s+/', ' ', mb_substr(trim($text), 0, Zotero_Notes::$MAX_TITLE_LENGTH) ) ); $excerpt = html_entity_decode($excerpt); $excerpt = trim($excerpt, $whitespace); } $msg = "=Note '" . $excerpt . "...' too long"; if ($this->key) { $msg .= " for item '" . $this->libraryID . "/" . $this->key . "'"; } throw new Exception($msg, Z_ERROR_NOTE_TOO_LONG); } $sanitizedText = Zotero_Notes::sanitize($text); if ($sanitizedText === $this->getNote(true)) { Z_Core::debug("Note text hasn't changed in setNote()"); return; } $this->noteText = $text; // If sanitized version is the same as original, store empty string if ($text === $sanitizedText) { $this->noteTextSanitized = ''; } else { $this->noteTextSanitized = $sanitizedText; } $this->changed['note'] = true; }
public function itemToAtom($itemID) { if (!is_int($itemID)) { throw new Exception("itemID must be an integer (was " . gettype($itemID) . ")"); } if (!$this->loaded) { $this->load(); } //$groupUserData = $this->getUserData($itemID); $item = Zotero_Items::get($this->libraryID, $itemID); if (!$item) { throw new Exception("Item {$itemID} doesn't exist"); } $xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?>' . '<entry xmlns="' . Zotero_Atom::$nsAtom . '" ' . 'xmlns:zapi="' . Zotero_Atom::$nsZoteroAPI . '" ' . 'xmlns:xfer="' . Zotero_Atom::$nsZoteroTransfer . '"/>'); $title = $item->getDisplayTitle(true); $title = $title ? $title : '[Untitled]'; // Strip HTML from note titles if ($item->isNote()) { // Clean and strip HTML, giving us an HTML-encoded plaintext string $title = strip_tags(Zotero_Notes::sanitize($title)); // Unencode plaintext string $title = html_entity_decode($title); } $xml->title = $title; $author = $xml->addChild('author'); $author->name = Zotero_Libraries::getName($item->libraryID); $author->uri = Zotero_URI::getLibraryURI($item->libraryID); $xml->id = Zotero_URI::getItemURI($item); $xml->published = Zotero_Date::sqlToISO8601($item->dateAdded); $xml->updated = Zotero_Date::sqlToISO8601($item->dateModified); $link = $xml->addChild("link"); $link['rel'] = "self"; $link['type'] = "application/atom+xml"; $link['href'] = Zotero_API::getItemURI($item); $link = $xml->addChild('link'); $link['rel'] = 'alternate'; $link['type'] = 'text/html'; $link['href'] = Zotero_URI::getItemURI($item, true); $xml->content['type'] = 'application/xml'; $itemXML = new SimpleXMLElement('<item xmlns="' . Zotero_Atom::$nsZoteroTransfer . '"/>'); // This method of adding the element seems to be necessary to get the // namespace prefix to show up $fNode = dom_import_simplexml($xml->content); $subNode = dom_import_simplexml($itemXML); $importedNode = $fNode->ownerDocument->importNode($subNode, true); $fNode->appendChild($importedNode); $xml->content->item['id'] = $itemID; return $xml; }