本文整理汇总了PHP中Zotero_DB::rollback方法的典型用法代码示例。如果您正苦于以下问题:PHP Zotero_DB::rollback方法的具体用法?PHP Zotero_DB::rollback怎么用?PHP Zotero_DB::rollback使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Zotero_DB
的用法示例。
在下文中一共展示了Zotero_DB::rollback方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的PHP代码示例。
示例1: save
//.........这里部分代码省略.........
if ($sourceItemID) {
$sql = "UPDATE OR REPLACE collectionItems " . "SET itemID=? WHERE itemID=?";
Zotero_DB::query($sql, array($sourceItemID, $this->id), $shardID);
} else {
$sql = "DELETE FROM collectionItems WHERE itemID=?";
Zotero_DB::query($sql, $this->id, $shardID);
}
}
}
$sql = "UPDATE item{$Type}s SET sourceItemID=?\n\t\t\t\t\t\t\t\tWHERE itemID=?";
$bindParams = array($sourceItemID ? $sourceItemID : null, $itemID);
Zotero_DB::query($sql, $bindParams, $shardID);
//Zotero.Notifier.trigger('modify', 'item', $this->id, notifierData);
// Update the counts of the previous and new sources
if ($oldItem) {
/*
switch ($type) {
case 'note':
$oldItem->decrementNoteCount();
break;
case 'attachment':
$oldItem->decrementAttachmentCount();
break;
}
*/
//Zotero.Notifier.trigger('modify', 'item', oldSourceItemID, oldItemNotifierData);
}
if ($newItem) {
/*
switch ($type) {
case 'note':
$newItem->incrementNoteCount();
break;
case 'attachment':
$newItem->incrementAttachmentCount();
break;
}
*/
//Zotero.Notifier.trigger('modify', 'item', sourceItemID, newItemNotifierData);
}
}
}
// Related items
if (!empty($this->changed['relatedItems'])) {
$removed = array();
$newids = array();
$currentIDs = $this->relatedItems;
if (!$currentIDs) {
$currentIDs = array();
}
foreach ($this->previousData['relatedItems'] as $id) {
if (!in_array($id, $currentIDs)) {
$removed[] = $id;
}
}
foreach ($currentIDs as $id) {
if (in_array($id, $this->previousData['relatedItems'])) {
continue;
}
$newids[] = $id;
}
if ($removed) {
$sql = "DELETE FROM itemRelated WHERE itemID=?\n\t\t\t\t\t\t\t\tAND linkedItemID IN (";
$q = array_fill(0, sizeOf($removed), '?');
$sql .= implode(', ', $q) . ")";
Zotero_DB::query($sql, array_merge(array($this->id), $removed), $shardID);
}
if ($newids) {
$sql = "INSERT INTO itemRelated (itemID, linkedItemID)\n\t\t\t\t\t\t\t\tVALUES (?,?)";
$insertStatement = Zotero_DB::getStatement($sql, false, $shardID);
foreach ($newids as $linkedItemID) {
$insertStatement->execute(array($this->id, $linkedItemID));
}
}
}
}
Zotero_DB::commit();
} catch (Exception $e) {
Zotero_DB::rollback();
throw $e;
}
if (!$this->id) {
$this->id = $itemID;
}
if (!$this->key) {
$this->key = $key;
}
if ($isNew) {
Zotero_Items::cache($this);
Zotero_Items::cacheLibraryKeyID($this->libraryID, $key, $itemID);
}
// TODO: invalidate memcache
Zotero_Items::reload($this->libraryID, $this->id);
if ($isNew) {
//Zotero.Notifier.trigger('add', 'item', $this->getID());
return $this->id;
}
//Zotero.Notifier.trigger('modify', 'item', $this->getID(), { old: $this->_preChangeArray });
return true;
}
示例2: copyLibrary
public static function copyLibrary($libraryID, $newShardID, $overrideLock = false)
{
$currentShardID = self::getByLibraryID($libraryID);
if ($currentShardID == $newShardID) {
throw new Exception("Library {$libraryID} is already on shard {$newShardID}");
}
if (!self::shardIsWriteable($newShardID)) {
throw new Exception("Shard {$newShardID} is not writeable");
}
if (!$overrideLock && Zotero_Libraries::isLocked($libraryID)) {
throw new Exception("Library {$libraryID} is locked");
}
// Make sure there's no stale data on the new shard
if (self::checkForLibrary($libraryID, $newShardID)) {
throw new Exception("Library {$libraryID} data already exists on shard {$newShardID}");
}
Zotero_DB::beginTransaction();
Zotero_DB::query("SET foreign_key_checks=0", false, $newShardID);
$tables = array('shardLibraries', 'collections', 'creators', 'items', 'relations', 'savedSearches', 'tags', 'collectionItems', 'deletedItems', 'groupItems', 'itemAttachments', 'itemCreators', 'itemData', 'itemNotes', 'itemRelated', 'itemSortFields', 'itemTags', 'savedSearchConditions', 'storageFileItems', 'syncDeleteLogIDs', 'syncDeleteLogKeys');
foreach ($tables as $table) {
if (!$overrideLock && Zotero_Libraries::isLocked($libraryID)) {
Zotero_DB::rollback();
throw new Exception("Aborted due to library lock");
}
switch ($table) {
case 'collections':
case 'creators':
case 'items':
case 'relations':
case 'savedSearches':
case 'shardLibraries':
case 'syncDeleteLogIDs':
case 'syncDeleteLogKeys':
case 'tags':
$sql = "SELECT * FROM {$table} WHERE libraryID=?";
break;
case 'collectionItems':
$sql = "SELECT CI.* FROM collectionItems CI\n\t\t\t\t\t\t\tJOIN collections USING (collectionID) WHERE libraryID=?";
break;
case 'deletedItems':
case 'groupItems':
case 'itemAttachments':
case 'itemCreators':
case 'itemData':
case 'itemNotes':
case 'itemRelated':
case 'itemSortFields':
case 'itemTags':
case 'storageFileItems':
$sql = "SELECT T.* FROM {$table} T JOIN items USING (itemID) WHERE libraryID=?";
break;
case 'savedSearchConditions':
$sql = "SELECT SSC.* FROM savedSearchConditions SSC\n\t\t\t\t\t\t\tJOIN savedSearches USING (searchID) WHERE libraryID=?";
break;
}
$rows = Zotero_DB::query($sql, $libraryID, $currentShardID);
if ($rows) {
$sets = array();
foreach ($rows as $row) {
$sets[] = array_values($row);
}
$sql = "INSERT INTO {$table} VALUES ";
Zotero_DB::bulkInsert($sql, $sets, 50, false, $newShardID);
}
}
Zotero_DB::query("SET foreign_key_checks=1", false, $newShardID);
if (!$overrideLock && Zotero_Libraries::isLocked($libraryID)) {
Zotero_DB::rollback();
throw new Exception("Aborted due to library lock");
}
Zotero_DB::commit();
if (!$overrideLock && Zotero_Libraries::isLocked($libraryID)) {
self::deleteLibrary($libraryID, $newShardID);
throw new Exception("Aborted due to library lock");
}
}
示例3: save
//.........这里部分代码省略.........
$sql = "UPDATE tags SET {$fields} WHERE tagID=?";
$stmt = Zotero_DB::getStatement($sql, true, Zotero_Shards::getByLibraryID($this->libraryID));
Zotero_DB::queryFromStatement($stmt, array_merge($params, array($tagID)));
}
} catch (Exception $e) {
// If an incoming tag is the same as an existing tag, but with a different key,
// then delete the old tag and add its linked items to the new tag
if (preg_match("/Duplicate entry .+ for key 'uniqueTags'/", $e->getMessage())) {
// GET existing tag
$existing = Zotero_Tags::getIDs($this->libraryID, $this->name);
if (!$existing) {
throw new Exception("Existing tag not found");
}
foreach ($existing as $id) {
$tag = Zotero_Tags::get($this->libraryID, $id, true);
if ($tag->__get('type') == $this->type) {
$linked = $tag->getLinkedItems(true);
Zotero_Tags::delete($this->libraryID, $tag->key);
break;
}
}
// Save again
if ($isNew) {
$sql = "INSERT INTO tags SET tagID=?, {$fields}";
$stmt = Zotero_DB::getStatement($sql, true, $shardID);
Zotero_DB::queryFromStatement($stmt, array_merge(array($tagID), $params));
// Remove from delete log if it's there
$sql = "DELETE FROM syncDeleteLogKeys WHERE libraryID=? AND objectType='tag' AND `key`=?";
Zotero_DB::query($sql, array($this->libraryID, $key), $shardID);
} else {
$sql = "UPDATE tags SET {$fields} WHERE tagID=?";
$stmt = Zotero_DB::getStatement($sql, true, Zotero_Shards::getByLibraryID($this->libraryID));
Zotero_DB::queryFromStatement($stmt, array_merge($params, array($tagID)));
}
$new = array_unique(array_merge($linked, $this->getLinkedItems(true)));
$this->setLinkedItems($new);
} else {
throw $e;
}
}
// Linked items
if ($full || !empty($this->changed['linkedItems'])) {
$removed = array();
$newids = array();
$currentIDs = $this->getLinkedItems(true);
if (!$currentIDs) {
$currentIDs = array();
}
if ($full) {
$sql = "SELECT itemID FROM itemTags WHERE tagID=?";
$stmt = Zotero_DB::getStatement($sql, true, $shardID);
$dbItemIDs = Zotero_DB::columnQueryFromStatement($stmt, $tagID);
if ($dbItemIDs) {
$removed = array_diff($dbItemIDs, $currentIDs);
$newids = array_diff($currentIDs, $dbItemIDs);
} else {
$newids = $currentIDs;
}
} else {
if ($this->previousData['linkedItems']) {
$removed = array_diff($this->previousData['linkedItems'], $currentIDs);
$newids = array_diff($currentIDs, $this->previousData['linkedItems']);
} else {
$newids = $currentIDs;
}
}
if ($removed) {
$sql = "DELETE FROM itemTags WHERE tagID=? AND itemID IN (";
$q = array_fill(0, sizeOf($removed), '?');
$sql .= implode(', ', $q) . ")";
Zotero_DB::query($sql, array_merge(array($this->id), $removed), $shardID);
}
if ($newids) {
$newids = array_values($newids);
$sql = "INSERT INTO itemTags (tagID, itemID) VALUES ";
$maxInsertGroups = 50;
Zotero_DB::bulkInsert($sql, $newids, $maxInsertGroups, $tagID, $shardID);
}
//Zotero.Notifier.trigger('add', 'collection-item', $this->id . '-' . $itemID);
}
Zotero_DB::commit();
Zotero_Tags::cachePrimaryData(array('id' => $tagID, 'libraryID' => $this->libraryID, 'key' => $key, 'name' => $this->name, 'type' => $this->type ? $this->type : 0, 'dateAdded' => $dateAdded, 'dateModified' => $dateModified));
} catch (Exception $e) {
Zotero_DB::rollback();
throw $e;
}
// If successful, set values in object
if (!$this->id) {
$this->id = $tagID;
}
if (!$this->key) {
$this->key = $key;
}
$this->init();
if ($isNew) {
Zotero_Tags::cache($this);
Zotero_Tags::cacheLibraryKeyID($this->libraryID, $key, $tagID);
}
return $this->id;
}
示例4: save
public function save($fixGaps = false)
{
if (!$this->libraryID) {
throw new Exception("Library ID must be set before saving");
}
Zotero_Searches::editCheck($this);
if (!$this->changed) {
Z_Core::debug("Search {$this->id} has not changed");
return false;
}
if (!isset($this->name) || $this->name === '') {
throw new Exception("Name not provided for saved search");
}
$shardID = Zotero_Shards::getByLibraryID($this->libraryID);
Zotero_DB::beginTransaction();
$isNew = !$this->id || !$this->exists();
try {
$searchID = $this->id ? $this->id : Zotero_ID::get('savedSearches');
Z_Core::debug("Saving search {$this->id}");
if (!$isNew) {
$sql = "DELETE FROM savedSearchConditions WHERE searchID=?";
Zotero_DB::query($sql, $searchID, $shardID);
}
$key = $this->key ? $this->key : $this->generateKey();
$fields = "searchName=?, libraryID=?, `key`=?, dateAdded=?, dateModified=?,\n\t\t\t\t\t\tserverDateModified=?";
$timestamp = Zotero_DB::getTransactionTimestamp();
$params = array($this->name, $this->libraryID, $key, $this->dateAdded ? $this->dateAdded : $timestamp, $this->dateModified ? $this->dateModified : $timestamp, $timestamp);
$shardID = Zotero_Shards::getByLibraryID($this->libraryID);
if ($isNew) {
$sql = "INSERT INTO savedSearches SET searchID=?, {$fields}";
$stmt = Zotero_DB::getStatement($sql, true, $shardID);
Zotero_DB::queryFromStatement($stmt, array_merge(array($searchID), $params));
Zotero_Searches::cacheLibraryKeyID($this->libraryID, $key, $searchID);
// Remove from delete log if it's there
$sql = "DELETE FROM syncDeleteLogKeys WHERE libraryID=? AND objectType='search' AND `key`=?";
Zotero_DB::query($sql, array($this->libraryID, $key), $shardID);
} else {
$sql = "UPDATE savedSearches SET {$fields} WHERE searchID=?";
$stmt = Zotero_DB::getStatement($sql, true, $shardID);
Zotero_DB::queryFromStatement($stmt, array_merge($params, array($searchID)));
}
// Close gaps in savedSearchIDs
$saveConditions = array();
$i = 1;
foreach ($this->conditions as $id => $condition) {
if (!$fixGaps && $id != $i) {
trigger_error('searchConditionIDs not contiguous and |fixGaps| not set in save() of saved search ' . $this->id, E_USER_ERROR);
}
$saveConditions[$i] = $condition;
$i++;
}
$this->conditions = $saveConditions;
// TODO: use proper bound parameters once DB class is updated
foreach ($this->conditions as $searchConditionID => $condition) {
$sql = "INSERT INTO savedSearchConditions (searchID,\n\t\t\t\t\t\tsearchConditionID, `condition`, mode, operator,\n\t\t\t\t\t\tvalue, required) VALUES (?,?,?,?,?,?,?)";
$sqlParams = array($searchID, $searchConditionID, $condition['condition'], $condition['mode'] ? $condition['mode'] : '', $condition['operator'] ? $condition['operator'] : '', $condition['value'] ? $condition['value'] : '', $condition['required'] ? 1 : 0);
try {
Zotero_DB::query($sql, $sqlParams, $shardID);
} catch (Exception $e) {
$msg = $e->getMessage();
if (strpos($msg, "Data too long for column 'value'") !== false) {
throw new Exception("=Value '" . mb_substr($condition['value'], 0, 75) . "…' too long in saved search '" . $this->name . "'");
}
throw $e;
}
}
Zotero_DB::commit();
} catch (Exception $e) {
Zotero_DB::rollback();
throw $e;
}
// If successful, set values in object
if (!$this->id) {
$this->id = $searchID;
}
if (!$this->key) {
$this->key = $key;
}
return $this->id;
}
示例5: __call
/**
* Handler for HTTP shortcut functions (e404(), e500())
*/
public function __call($name, $arguments)
{
if (!preg_match("/^e([1-5])([0-9]{2})\$/", $name, $matches)) {
throw new Exception("Invalid function {$name}");
}
$this->responseCode = (int) ($matches[1] . $matches[2]);
// On 4xx or 5xx errors, rollback all open transactions
// and don't send Last-Modified-Version
if ($matches[1] == "4" || $matches[1] == "5") {
if (!$this->libraryVersionOnFailure) {
$this->libraryVersion = null;
}
Zotero_DB::rollback(true);
}
if (isset($arguments[0])) {
echo htmlspecialchars($arguments[0]);
} else {
// Default messages for some codes
switch ($this->responseCode) {
case 401:
echo "Access denied";
break;
case 403:
echo "Forbidden";
break;
case 404:
echo "Not found";
break;
case 405:
echo "Method not allowed";
break;
case 429:
echo "Too many requests";
break;
case 500:
echo "An error occurred";
break;
case 501:
echo "Method is not implemented";
break;
case 503:
echo "Service unavailable";
break;
}
}
$this->end();
}
示例6: save
public function save()
{
if (!$this->libraryID) {
trigger_error("Library ID must be set before saving", E_USER_ERROR);
}
Zotero_Collections::editCheck($this);
if (!$this->changed) {
Z_Core::debug("Collection {$this->id} has not changed");
return false;
}
Zotero_DB::beginTransaction();
try {
$collectionID = $this->id ? $this->id : Zotero_ID::get('collections');
Z_Core::debug("Saving collection {$this->id}");
$key = $this->key ? $this->key : $this->generateKey();
$timestamp = Zotero_DB::getTransactionTimestamp();
$dateAdded = $this->dateAdded ? $this->dateAdded : $timestamp;
$dateModified = $this->dateModified ? $this->dateModified : $timestamp;
// Verify parent
if ($this->_parent) {
if (is_int($this->_parent)) {
$newParentCollection = Zotero_Collections::get($this->libraryID, $this->_parent);
} else {
$newParentCollection = Zotero_Collections::getByLibraryAndKey($this->libraryID, $this->_parent);
}
if (!$newParentCollection) {
// TODO: clear caches
throw new Exception("Cannot set parent to invalid collection {$this->_parent}");
}
if ($newParentCollection->id == $this->id) {
trigger_error("Cannot move collection {$this->id} into itself!", E_USER_ERROR);
}
// If the designated parent collection is already within this
// collection (which shouldn't happen), move it to the root
if ($this->id && $this->hasDescendent('collection', $newParentCollection->id)) {
$newParentCollection->parent = null;
$newParentCollection->save();
}
$parent = $newParentCollection->id;
} else {
$parent = null;
}
$fields = "collectionName=?, parentCollectionID=?, libraryID=?, `key`=?,\n\t\t\t\t\t\tdateAdded=?, dateModified=?, serverDateModified=?";
$params = array($this->name, $parent, $this->libraryID, $key, $dateAdded, $dateModified, $timestamp);
$params = array_merge(array($collectionID), $params, $params);
$shardID = Zotero_Shards::getByLibraryID($this->libraryID);
$sql = "INSERT INTO collections SET collectionID=?, {$fields}\n\t\t\t\t\tON DUPLICATE KEY UPDATE {$fields}";
$insertID = Zotero_DB::query($sql, $params, $shardID);
if (!$this->id) {
if (!$insertID) {
throw new Exception("Collection id not available after INSERT");
}
$collectionID = $insertID;
Zotero_Collections::cacheLibraryKeyID($this->libraryID, $key, $insertID);
}
// Remove from delete log if it's there
$sql = "DELETE FROM syncDeleteLogKeys WHERE libraryID=? AND objectType='collection' AND `key`=?";
Zotero_DB::query($sql, array($this->libraryID, $key), $shardID);
Zotero_DB::commit();
Zotero_Collections::cachePrimaryData(array('id' => $collectionID, 'libraryID' => $this->libraryID, 'key' => $key, 'name' => $this->name, 'dateAdded' => $dateAdded, 'dateModified' => $dateModified, 'parent' => $parent));
} catch (Exception $e) {
Zotero_DB::rollback();
throw $e;
}
// If successful, set values in object
if (!$this->id) {
$this->_id = $collectionID;
}
if (!$this->key) {
$this->_key = $key;
}
return $this->id;
}
示例7: processUploadInternal
//.........这里部分代码省略.........
if ($xml->deleted) {
// Delete collections
if ($xml->deleted->collections) {
Zotero_Collections::deleteFromXML($xml->deleted->collections, $userID);
}
// Delete items
if ($xml->deleted->items) {
Zotero_Items::deleteFromXML($xml->deleted->items, $userID);
}
// Delete creators
if ($xml->deleted->creators) {
Zotero_Creators::deleteFromXML($xml->deleted->creators, $userID);
}
// Delete saved searches
if ($xml->deleted->searches) {
Zotero_Searches::deleteFromXML($xml->deleted->searches, $userID);
}
// Delete tags
if ($xml->deleted->tags) {
$xmlElements = dom_import_simplexml($xml->deleted->tags);
$xmlElements = $xmlElements->getElementsByTagName('tag');
foreach ($xmlElements as $xmlElement) {
$libraryID = (int) $xmlElement->getAttribute('libraryID');
$key = $xmlElement->getAttribute('key');
$tagObj = Zotero_Tags::getByLibraryAndKey($libraryID, $key);
if (!$tagObj) {
continue;
}
// We need to update all items on the deleted tag
$modifiedItems = array_merge($modifiedItems, array_map(function ($key) use($libraryID) {
return $libraryID . "/" . $key;
}, $tagObj->getLinkedItems(true)));
}
Zotero_Tags::deleteFromXML($xml->deleted->tags, $userID);
}
// Delete relations
if ($xml->deleted->relations) {
Zotero_Relations::deleteFromXML($xml->deleted->relations, $userID);
}
// Delete relations
if ($xml->deleted->settings) {
Zotero_Settings::deleteFromXML($xml->deleted->settings, $userID);
}
}
$toUpdate = array();
foreach ($modifiedItems as $item) {
// libraryID/key string
if (is_string($item)) {
if (isset($savedItems[$item])) {
continue;
}
$savedItems[$item] = true;
list($libraryID, $key) = explode("/", $item);
$item = Zotero_Items::getByLibraryAndKey($libraryID, $key);
if (!$item) {
// Item was deleted
continue;
}
} else {
$lk = $item->libraryID . "/" . $item->key;
if (isset($savedItems[$lk])) {
continue;
}
$savedItems[$lk] = true;
}
$toUpdate[] = $item;
}
Zotero_Items::updateVersions($toUpdate, $userID);
unset($savedItems);
unset($modifiedItems);
try {
self::removeUploadProcess($processID);
} catch (Exception $e) {
if (strpos($e->getMessage(), 'MySQL server has gone away') !== false) {
// Reconnect
error_log("Reconnecting to MySQL master");
Zotero_DB::close();
self::removeUploadProcess($processID);
} else {
throw $e;
}
}
// Send notifications for changed libraries
foreach ($affectedLibraries as $libraryID) {
Zotero_Notifier::trigger('modify', 'library', $libraryID);
}
Zotero_DB::commit();
if ($profile) {
$shardID = Zotero_Shards::getByUserID($userID);
Zotero_DB::profileEnd($shardID);
}
// Return timestamp + 1, to keep the next /updated call
// (using >= timestamp) from returning this data
return $timestamp + 1;
} catch (Exception $e) {
Zotero_DB::rollback(true);
self::removeUploadProcess($processID);
throw $e;
}
}
示例8: save
public function save()
{
if (!$this->libraryID) {
trigger_error("Library ID must be set before saving", E_USER_ERROR);
}
Zotero_Creators::editCheck($this);
// If empty, move on
if ($this->firstName === '' && $this->lastName === '') {
throw new Exception('First and last name are empty');
}
if ($this->fieldMode == 1 && $this->firstName !== '') {
throw new Exception('First name must be empty in single-field mode');
}
if (!$this->hasChanged()) {
Z_Core::debug("Creator {$this->id} has not changed");
return false;
}
Zotero_DB::beginTransaction();
try {
$creatorID = $this->id ? $this->id : Zotero_ID::get('creators');
$isNew = !$this->id;
Z_Core::debug("Saving creator {$this->id}");
$key = $this->key ? $this->key : $this->generateKey();
$timestamp = Zotero_DB::getTransactionTimestamp();
$dateAdded = $this->dateAdded ? $this->dateAdded : $timestamp;
$dateModified = $this->changed['dateModified'] ? $this->dateModified : $timestamp;
$fields = "firstName=?, lastName=?, fieldMode=?,\n\t\t\t\t\t\tlibraryID=?, `key`=?, dateAdded=?, dateModified=?, serverDateModified=?";
$params = array($this->firstName, $this->lastName, $this->fieldMode, $this->libraryID, $key, $dateAdded, $dateModified, $timestamp);
$shardID = Zotero_Shards::getByLibraryID($this->libraryID);
try {
if ($isNew) {
$sql = "INSERT INTO creators SET creatorID=?, {$fields}";
$stmt = Zotero_DB::getStatement($sql, true, $shardID);
Zotero_DB::queryFromStatement($stmt, array_merge(array($creatorID), $params));
// Remove from delete log if it's there
$sql = "DELETE FROM syncDeleteLogKeys WHERE libraryID=? AND objectType='creator' AND `key`=?";
Zotero_DB::query($sql, array($this->libraryID, $key), $shardID);
} else {
$sql = "UPDATE creators SET {$fields} WHERE creatorID=?";
$stmt = Zotero_DB::getStatement($sql, true, $shardID);
Zotero_DB::queryFromStatement($stmt, array_merge($params, array($creatorID)));
}
} catch (Exception $e) {
if (strpos($e->getMessage(), " too long") !== false) {
if (strlen($this->firstName) > 255) {
throw new Exception("=First name '" . mb_substr($this->firstName, 0, 50) . "…' too long");
}
if (strlen($this->lastName) > 255) {
if ($this->fieldMode == 1) {
throw new Exception("=Last name '" . mb_substr($this->lastName, 0, 50) . "…' too long");
} else {
throw new Exception("=Name '" . mb_substr($this->lastName, 0, 50) . "…' too long");
}
}
}
throw $e;
}
// The client updates the mod time of associated items here, but
// we don't, because either A) this is from syncing, where appropriate
// mod times come from the client or B) the change is made through
// $item->setCreator(), which updates the mod time.
//
// If the server started to make other independent creator changes,
// linked items would need to be updated.
Zotero_DB::commit();
Zotero_Creators::cachePrimaryData(array('id' => $creatorID, 'libraryID' => $this->libraryID, 'key' => $key, 'dateAdded' => $dateAdded, 'dateModified' => $dateModified, 'firstName' => $this->firstName, 'lastName' => $this->lastName, 'fieldMode' => $this->fieldMode));
} catch (Exception $e) {
Zotero_DB::rollback();
throw $e;
}
// If successful, set values in object
if (!$this->id) {
$this->id = $creatorID;
}
if (!$this->key) {
$this->key = $key;
}
$this->init();
if ($isNew) {
Zotero_Creators::cache($this);
Zotero_Creators::cacheLibraryKeyID($this->libraryID, $key, $creatorID);
}
// TODO: invalidate memcache?
return $this->id;
}
示例9: save
public function save($userID = false)
{
if (!$this->_libraryID) {
trigger_error("Library ID must be set before saving", E_USER_ERROR);
}
Zotero_Collections::editCheck($this, $userID);
if (!$this->hasChanged()) {
Z_Core::debug("Collection {$this->_id} has not changed");
return false;
}
$env = [];
$isNew = $env['isNew'] = !$this->_id;
Zotero_DB::beginTransaction();
try {
$collectionID = $env['id'] = $this->_id = $this->_id ? $this->_id : Zotero_ID::get('collections');
Z_Core::debug("Saving collection {$this->_id}");
$key = $env['key'] = $this->_key = $this->_key ? $this->_key : Zotero_ID::getKey();
$timestamp = Zotero_DB::getTransactionTimestamp();
$dateAdded = $this->_dateAdded ? $this->_dateAdded : $timestamp;
$dateModified = $this->_dateModified ? $this->_dateModified : $timestamp;
$version = Zotero_Libraries::getUpdatedVersion($this->_libraryID);
// Verify parent
if ($this->_parentKey) {
$newParentCollection = Zotero_Collections::getByLibraryAndKey($this->_libraryID, $this->_parentKey);
if (!$newParentCollection) {
// TODO: clear caches
throw new Exception("Cannot set parent to invalid collection {$this->_parentKey}");
}
if (!$isNew) {
if ($newParentCollection->id == $collectionID) {
trigger_error("Cannot move collection {$this->_id} into itself!", E_USER_ERROR);
}
// If the designated parent collection is already within this
// collection (which shouldn't happen), move it to the root
if (!$isNew && $this->hasDescendent('collection', $newParentCollection->id)) {
$newParentCollection->parent = null;
$newParentCollection->save();
}
}
$parent = $newParentCollection->id;
} else {
$parent = null;
}
$fields = "collectionName=?, parentCollectionID=?, libraryID=?, `key`=?,\n\t\t\t\t\t\tdateAdded=?, dateModified=?, serverDateModified=?, version=?";
$params = array($this->_name, $parent, $this->_libraryID, $key, $dateAdded, $dateModified, $timestamp, $version);
$params = array_merge(array($collectionID), $params, $params);
$shardID = Zotero_Shards::getByLibraryID($this->_libraryID);
$sql = "INSERT INTO collections SET collectionID=?, {$fields}\n\t\t\t\t\tON DUPLICATE KEY UPDATE {$fields}";
Zotero_DB::query($sql, $params, $shardID);
// Remove from delete log if it's there
$sql = "DELETE FROM syncDeleteLogKeys WHERE libraryID=? AND objectType='collection' AND `key`=?";
Zotero_DB::query($sql, array($this->_libraryID, $key), $shardID);
Zotero_DB::commit();
if (!empty($this->changed['parentKey'])) {
$objectsClass = $this->objectsClass;
// Add this item to the parent's cached item lists after commit,
// if the parent was loaded
if ($this->_parentKey) {
$parentCollectionID = $objectsClass::getIDFromLibraryAndKey($this->_libraryID, $this->_parentKey);
$objectsClass::registerChildCollection($parentCollectionID, $collectionID);
} else {
if (!$isNew && !empty($this->previousData['parentKey'])) {
$parentCollectionID = $objectsClass::getIDFromLibraryAndKey($this->_libraryID, $this->previousData['parentKey']);
$objectsClass::unregisterChildCollection($parentCollectionID, $collectionID);
}
}
}
} catch (Exception $e) {
Zotero_DB::rollback();
throw $e;
}
$this->finalizeSave($env);
return $isNew ? $this->_id : true;
}
示例10: settings
public function settings()
{
if ($this->apiVersion < 2) {
$this->e404();
}
// Check for general library access
if (!$this->permissions->canAccess($this->objectLibraryID)) {
$this->e403();
}
if ($this->isWriteMethod()) {
Zotero_DB::beginTransaction();
// Check for library write access
if (!$this->permissions->canWrite($this->objectLibraryID)) {
$this->e403("Write access denied");
}
// Make sure library hasn't been modified
if (!$this->singleObject) {
$libraryTimestampChecked = $this->checkLibraryIfUnmodifiedSinceVersion();
}
Zotero_Libraries::updateVersionAndTimestamp($this->objectLibraryID);
}
// Single setting
if ($this->singleObject) {
$this->allowMethods(array('GET', 'PUT', 'DELETE'));
$setting = Zotero_Settings::getByLibraryAndKey($this->objectLibraryID, $this->objectKey);
if (!$setting) {
if ($this->method == 'PUT') {
$setting = new Zotero_Setting();
$setting->libraryID = $this->objectLibraryID;
$setting->name = $this->objectKey;
} else {
$this->e404("Setting not found");
}
}
if ($this->isWriteMethod()) {
if ($this->method == 'PUT') {
$json = $this->jsonDecode($this->body);
$objectVersionValidated = $this->checkSingleObjectWriteVersion('setting', $setting, $json);
}
$this->libraryVersion = Zotero_Libraries::getUpdatedVersion($this->objectLibraryID);
// Update setting
if ($this->method == 'PUT') {
$changed = Zotero_Settings::updateFromJSON($setting, $json, $this->queryParams, $this->userID, $objectVersionValidated ? 0 : 2);
// If not updated, return the original library version
if (!$changed) {
$this->libraryVersion = Zotero_Libraries::getOriginalVersion($this->objectLibraryID);
Zotero_DB::rollback();
$this->e204();
}
} else {
if ($this->method == 'DELETE') {
Zotero_Settings::delete($this->objectLibraryID, $this->objectKey);
} else {
throw new Exception("Unexpected method {$this->method}");
}
}
Zotero_DB::commit();
$this->e204();
} else {
$this->libraryVersion = $setting->version;
$json = $setting->toJSON(true, $this->queryParams);
echo Zotero_Utilities::formatJSON($json);
}
} else {
$this->allowMethods(array('GET', 'POST'));
$this->libraryVersion = Zotero_Libraries::getUpdatedVersion($this->objectLibraryID);
// Create a setting
if ($this->method == 'POST') {
$obj = $this->jsonDecode($this->body);
$changed = Zotero_Settings::updateMultipleFromJSON($obj, $this->queryParams, $this->objectLibraryID, $this->userID, $this->permissions, $libraryTimestampChecked ? 0 : 1, null);
// If not updated, return the original library version
if (!$changed) {
$this->libraryVersion = Zotero_Libraries::getOriginalVersion($this->objectLibraryID);
}
Zotero_DB::commit();
$this->e204();
} else {
$settings = Zotero_Settings::search($this->objectLibraryID, $this->queryParams);
$json = new stdClass();
foreach ($settings as $setting) {
$json->{$setting->name} = $setting->toJSON(true, $this->queryParams);
}
echo Zotero_Utilities::formatJSON($json);
}
}
$this->end();
}
示例11: processUploadInternal
//.........这里部分代码省略.........
}
$ids[] = $item->id;
}
$collection['obj']->setChildItems($ids);
}
}
unset($collectionSets);
}
// Add/update saved searches
if ($xml->searches) {
$searches = array();
$keys = array();
foreach ($xml->searches->search as $xmlElement) {
$key = (string) $xmlElement['key'];
if (isset($keys[$key])) {
throw new Exception("Search {$key} already processed");
}
$keys[$key] = true;
$searchObj = Zotero_Searches::convertXMLToSearch($xmlElement);
$searchObj->save();
}
unset($xml->searches);
}
// Add/update tags
if ($xml->tags) {
$keys = array();
// DOM
$xmlElements = dom_import_simplexml($xml->tags);
$xmlElements = $xmlElements->getElementsByTagName('tag');
foreach ($xmlElements as $xmlElement) {
$key = $xmlElement->getAttribute('key');
if (isset($keys[$key])) {
throw new Exception("Tag {$key} already processed");
}
$keys[$key] = true;
$tagObj = Zotero_Tags::convertXMLToTag($xmlElement);
$tagObj->save(true);
}
unset($keys);
unset($xml->tags);
}
// Add/update relations
if ($xml->relations) {
// DOM
$xmlElements = dom_import_simplexml($xml->relations);
$xmlElements = $xmlElements->getElementsByTagName('relation');
foreach ($xmlElements as $xmlElement) {
$relationObj = Zotero_Relations::convertXMLToRelation($xmlElement, $userLibraryID);
if ($relationObj->exists()) {
continue;
}
$relationObj->save();
}
unset($keys);
unset($xml->relations);
}
// TODO: loop
if ($xml->deleted) {
// Delete collections
if ($xml->deleted->collections) {
Zotero_Collections::deleteFromXML($xml->deleted->collections);
}
// Delete items
if ($xml->deleted->items) {
Zotero_Items::deleteFromXML($xml->deleted->items);
}
// Delete creators
if ($xml->deleted->creators) {
Zotero_Creators::deleteFromXML($xml->deleted->creators);
}
// Delete saved searches
if ($xml->deleted->searches) {
Zotero_Searches::deleteFromXML($xml->deleted->searches);
}
// Delete tags
if ($xml->deleted->tags) {
Zotero_Tags::deleteFromXML($xml->deleted->tags);
}
// Delete tags
if ($xml->deleted->relations) {
Zotero_Relations::deleteFromXML($xml->deleted->relations);
}
}
self::removeUploadProcess($processID);
Zotero_DB::commit();
Z_Core::$MC->commit();
if ($profile) {
$shardID = Zotero_Shards::getByUserID($userID);
Zotero_DB::profileEnd($shardID);
}
// Return timestamp + 1, to keep the next /updated call
// (using >= timestamp) from returning this data
return $timestamp + 1;
} catch (Exception $e) {
Z_Core::$MC->rollback();
Zotero_DB::rollback(true);
self::removeUploadProcess($processID);
throw $e;
}
}
示例12: handleUploadError
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;
//.........这里部分代码省略.........
示例13: save
/**
* Save the setting to the DB
*/
public function save($userID = false)
{
if (!$this->libraryID) {
throw new Exception("libraryID not set");
}
if (!isset($this->name) || $this->name === '') {
throw new Exception("Setting name not provided");
}
try {
Zotero_Settings::editCheck($this, $userID);
} catch (Exception $e) {
error_log("WARNING: " . $e);
return false;
}
if (!$this->changed) {
Z_Core::debug("Setting {$this->libraryID}/{$this->name} has not changed");
return false;
}
$shardID = Zotero_Shards::getByLibraryID($this->libraryID);
Zotero_DB::beginTransaction();
$isNew = !$this->exists();
try {
Z_Core::debug("Saving setting {$this->libraryID}/{$this->name}");
$params = array(json_encode($this->value), Zotero_Libraries::getUpdatedVersion($this->libraryID), Zotero_DB::getTransactionTimestamp());
$params = array_merge(array($this->libraryID, $this->name), $params, $params);
$shardID = Zotero_Shards::getByLibraryID($this->libraryID);
$sql = "INSERT INTO settings (libraryID, name, value, version, lastUpdated) " . "VALUES (?, ?, ?, ?, ?) " . "ON DUPLICATE KEY UPDATE value=?, version=?, lastUpdated=?";
Zotero_DB::query($sql, $params, $shardID);
// Remove from delete log if it's there
$sql = "DELETE FROM syncDeleteLogKeys WHERE libraryID=? AND objectType='setting' AND `key`=?";
Zotero_DB::query($sql, array($this->libraryID, $this->name), $shardID);
Zotero_DB::commit();
} catch (Exception $e) {
Zotero_DB::rollback();
throw $e;
}
return true;
}
示例14: save
public function save()
{
if (!$this->libraryID) {
trigger_error("Library ID must be set before saving", E_USER_ERROR);
}
Zotero_DB::beginTransaction();
try {
$shardID = Zotero_Shards::getByLibraryID($this->libraryID);
$relationID = $this->id ? $this->id : Zotero_ID::get('relations');
Z_Core::debug("Saving relation {$relationID}");
$sql = "INSERT INTO relations\n\t\t\t\t\t(relationID, libraryID, subject, predicate, object, serverDateModified)\n\t\t\t\t\tVALUES (?, ?, ?, ?, ?, ?)";
$timestamp = Zotero_DB::getTransactionTimestamp();
$params = array($relationID, $this->libraryID, $this->subject, $this->predicate, $this->object, $timestamp);
$insertID = Zotero_DB::query($sql, $params, $shardID);
if (!$this->id) {
if (!$insertID) {
throw new Exception("Relation id not available after INSERT");
}
$this->id = $insertID;
}
// Remove from delete log if it's there
$sql = "DELETE FROM syncDeleteLogKeys WHERE libraryID=? AND objectType='relation' AND `key`=?";
Zotero_DB::query($sql, array($this->libraryID, $this->getKey()), $shardID);
Zotero_DB::commit();
} catch (Exception $e) {
Zotero_DB::rollback();
throw $e;
}
return $this->id;
}
示例15: updateMultipleFromJSON
public static function updateMultipleFromJSON($json, $requestParams, $libraryID, $userID, Zotero_Permissions $permissions, $requireVersion, $parent = null)
{
$type = self::$objectType;
$types = self::$objectTypePlural;
$keyProp = $type . "Key";
switch ($type) {
case 'collection':
case 'search':
if ($parent) {
throw new Exception('$parent is not valid for ' . $type);
}
break;
case 'item':
break;
default:
throw new Exception("Function not valid for {$type}");
}
self::validateMultiObjectJSON($json, $requestParams);
$results = new Zotero_Results($requestParams);
if ($requestParams['v'] >= 2 && Zotero_DB::transactionInProgress()) {
throw new Exception("Transaction cannot be open when starting multi-object update");
}
// If single collection object, stuff in array
if ($requestParams['v'] < 2 && $type == 'collection' && !isset($json->collections)) {
$json = [$json];
} else {
if ($requestParams['v'] < 3) {
$json = $json->{$types};
}
}
$i = 0;
foreach ($json as $prop => $jsonObject) {
Zotero_DB::beginTransaction();
try {
if (!is_object($jsonObject)) {
throw new Exception("Invalid value for index {$prop} in uploaded data; expected JSON {$type} object", Z_ERROR_INVALID_INPUT);
}
$className = "Zotero_" . ucwords($type);
$obj = new $className();
$obj->libraryID = $libraryID;
if ($type == 'item') {
$changed = self::updateFromJSON($obj, $jsonObject, $parent, $requestParams, $userID, $requireVersion, true);
} else {
$changed = self::updateFromJSON($obj, $jsonObject, $requestParams, $userID, $requireVersion, true);
}
Zotero_DB::commit();
if ($changed) {
$results->addSuccessful($i, $obj->toResponseJSON($requestParams, $permissions));
} else {
$results->addUnchanged($i, $obj->key);
}
} catch (Exception $e) {
Zotero_DB::rollback();
if ($requestParams['v'] < 2) {
throw $e;
}
// If object key given, include that
$resultKey = isset($jsonObject->{$keyProp}) ? $jsonObject->{$keyProp} : '';
$results->addFailure($i, $resultKey, $e);
}
$i++;
}
return $results->generateReport();
}