本文整理汇总了PHP中Zotero_DB::getTransactionTimestamp方法的典型用法代码示例。如果您正苦于以下问题:PHP Zotero_DB::getTransactionTimestamp方法的具体用法?PHP Zotero_DB::getTransactionTimestamp怎么用?PHP Zotero_DB::getTransactionTimestamp使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Zotero_DB
的用法示例。
在下文中一共展示了Zotero_DB::getTransactionTimestamp方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的PHP代码示例。
示例1: indexItem
public static function indexItem(Zotero_Item $item, $content, $stats = array())
{
if (!$item->isAttachment()) {
throw new Exception("Full-text content can only be added for attachments", Z_ERROR_INVALID_INPUT);
}
Zotero_DB::beginTransaction();
$libraryID = $item->libraryID;
$key = $item->key;
$version = Zotero_Libraries::getUpdatedVersion($item->libraryID);
$timestamp = Zotero_DB::transactionInProgress() ? Zotero_DB::getTransactionTimestamp() : date("Y-m-d H:i:s");
// Add to MySQL for syncing, since Elasticsearch doesn't refresh immediately
$sql = "REPLACE INTO itemFulltext (";
$fields = ["itemID", "version", "timestamp"];
$params = [$item->id, $version, $timestamp];
$sql .= implode(", ", $fields) . ") VALUES (" . implode(', ', array_fill(0, sizeOf($params), '?')) . ")";
Zotero_DB::query($sql, $params, Zotero_Shards::getByLibraryID($libraryID));
// Add to Elasticsearch
self::indexItemInElasticsearch($libraryID, $key, $version, $timestamp, $content, $stats);
Zotero_DB::commit();
}
示例2: delete
public static function delete($libraryID, $key)
{
$table = self::$table;
$type = self::$objectType;
$types = self::$objectTypePlural;
if (!$key) {
throw new Exception("Invalid key {$key}");
}
// Get object (and trigger caching)
$obj = self::getByLibraryAndKey($libraryID, $key);
if (!$obj) {
return;
}
self::editCheck($obj);
Z_Core::debug("Deleting {$type} {$libraryID}/{$key}", 4);
$shardID = Zotero_Shards::getByLibraryID($libraryID);
Zotero_DB::beginTransaction();
// Delete child items
if ($type == 'item') {
if ($obj->isRegularItem()) {
$children = array_merge($obj->getNotes(), $obj->getAttachments());
if ($children) {
$children = Zotero_Items::get($libraryID, $children);
foreach ($children as $child) {
self::delete($child->libraryID, $child->key);
}
}
}
// Remove relations (except for merge tracker)
$uri = Zotero_URI::getItemURI($obj);
Zotero_Relations::eraseByURI($libraryID, $uri, array(Zotero_Relations::$deletedItemPredicate));
} else {
if ($type == 'tag') {
$tagName = $obj->name;
}
}
if ($type == 'item' && $obj->isAttachment()) {
Zotero_FullText::deleteItemContent($obj);
}
$sql = "DELETE FROM {$table} WHERE libraryID=? AND `key`=?";
$deleted = Zotero_DB::query($sql, array($libraryID, $key), $shardID);
self::unload($obj->id);
if ($deleted) {
$sql = "INSERT INTO syncDeleteLogKeys\n\t\t\t\t\t\t(libraryID, objectType, `key`, timestamp, version)\n\t\t\t\t\t\tVALUES (?, '{$type}', ?, ?, ?)\n\t\t\t\t\t\tON DUPLICATE KEY UPDATE timestamp=?, version=?";
$timestamp = Zotero_DB::getTransactionTimestamp();
$version = Zotero_Libraries::getUpdatedVersion($libraryID);
$params = array($libraryID, $key, $timestamp, $version, $timestamp, $version);
Zotero_DB::query($sql, $params, $shardID);
if ($type == 'tag') {
$sql = "INSERT INTO syncDeleteLogKeys\n\t\t\t\t\t\t\t(libraryID, objectType, `key`, timestamp, version)\n\t\t\t\t\t\t\tVALUES (?, 'tagName', ?, ?, ?)\n\t\t\t\t\t\t\tON DUPLICATE KEY UPDATE timestamp=?, version=?";
$params = array($libraryID, $tagName, $timestamp, $version, $timestamp, $version);
Zotero_DB::query($sql, $params, $shardID);
}
}
Zotero_DB::commit();
}
示例3: save
public function save($userID = false)
{
if (!$this->libraryID) {
trigger_error("Library ID must be set before saving", E_USER_ERROR);
}
Zotero_Items::editCheck($this);
if (!$this->hasChanged()) {
Z_Core::debug("Item {$this->id} has not changed");
return false;
}
// Make sure there are no gaps in the creator indexes
$creators = $this->getCreators();
$lastPos = -1;
foreach ($creators as $pos => $creator) {
if ($pos != $lastPos + 1) {
trigger_error("Creator index {$pos} out of sequence for item {$this->id}", E_USER_ERROR);
}
$lastPos++;
}
$shardID = Zotero_Shards::getByLibraryID($this->libraryID);
Zotero_DB::beginTransaction();
try {
//
// New item, insert and return id
//
if (!$this->id || !$this->exists()) {
Z_Core::debug('Saving data for new item to database');
$isNew = true;
$sqlColumns = array();
$sqlValues = array();
//
// Primary fields
//
$itemID = $this->id ? $this->id : Zotero_ID::get('items');
$key = $this->key ? $this->key : $this->generateKey();
$sqlColumns = array('itemID', 'itemTypeID', 'libraryID', 'key', 'dateAdded', 'dateModified', 'serverDateModified');
$timestamp = Zotero_DB::getTransactionTimestamp();
$sqlValues = array($itemID, $this->itemTypeID, $this->libraryID, $key, $this->dateAdded ? $this->dateAdded : $timestamp, $this->dateModified ? $this->dateModified : $timestamp, $timestamp);
//
// Primary fields
//
$sql = 'INSERT INTO items (`' . implode('`, `', $sqlColumns) . '`) VALUES (';
// Insert placeholders for bind parameters
for ($i = 0; $i < sizeOf($sqlValues); $i++) {
$sql .= '?, ';
}
$sql = substr($sql, 0, -2) . ')';
// Save basic data to items table
$insertID = Zotero_DB::query($sql, $sqlValues, $shardID);
if (!$this->id) {
if (!$insertID) {
throw new Exception("Item id not available after INSERT");
}
$itemID = $insertID;
$this->serverDateModified = $timestamp;
}
// Group item data
if (Zotero_Libraries::getType($this->libraryID) == 'group' && $userID) {
$sql = "INSERT INTO groupItems VALUES (?, ?, ?)";
Zotero_DB::query($sql, array($itemID, $userID, null), $shardID);
}
//
// ItemData
//
if ($this->changed['itemData']) {
// Use manual bound parameters to speed things up
$origInsertSQL = "INSERT INTO itemData (itemID, fieldID, value) VALUES ";
$insertSQL = $origInsertSQL;
$insertParams = array();
$insertCounter = 0;
$maxInsertGroups = 40;
$max = Zotero_Items::$maxDataValueLength;
$fieldIDs = array_keys($this->changed['itemData']);
foreach ($fieldIDs as $fieldID) {
$value = $this->getField($fieldID, true, false, true);
if ($value == 'CURRENT_TIMESTAMP' && Zotero_ItemFields::getID('accessDate') == $fieldID) {
$value = Zotero_DB::getTransactionTimestamp();
}
// Check length
if (strlen($value) > $max) {
$fieldName = Zotero_ItemFields::getLocalizedString($this->itemTypeID, $fieldID);
throw new Exception("={$fieldName} field " . "'" . substr($value, 0, 50) . "...' too long");
}
if ($insertCounter < $maxInsertGroups) {
$insertSQL .= "(?,?,?),";
$insertParams = array_merge($insertParams, array($itemID, $fieldID, $value));
}
if ($insertCounter == $maxInsertGroups - 1) {
$insertSQL = substr($insertSQL, 0, -1);
$stmt = Zotero_DB::getStatement($insertSQL, true, $shardID);
Zotero_DB::queryFromStatement($stmt, $insertParams);
$insertSQL = $origInsertSQL;
$insertParams = array();
$insertCounter = -1;
}
$insertCounter++;
}
if ($insertCounter > 0 && $insertCounter < $maxInsertGroups) {
$insertSQL = substr($insertSQL, 0, -1);
$stmt = Zotero_DB::getStatement($insertSQL, true, $shardID);
//.........这里部分代码省略.........
示例4: save
public function save($full = false)
{
if (!$this->libraryID) {
trigger_error("Library ID must be set before saving", E_USER_ERROR);
}
Zotero_Tags::editCheck($this);
if (!$this->changed) {
Z_Core::debug("Tag {$this->id} has not changed");
return false;
}
$shardID = Zotero_Shards::getByLibraryID($this->libraryID);
Zotero_DB::beginTransaction();
try {
$tagID = $this->id ? $this->id : Zotero_ID::get('tags');
$isNew = !$this->id;
Z_Core::debug("Saving tag {$tagID}");
$key = $this->key ? $this->key : $this->generateKey();
$timestamp = Zotero_DB::getTransactionTimestamp();
$dateAdded = $this->dateAdded ? $this->dateAdded : $timestamp;
$dateModified = $this->dateModified ? $this->dateModified : $timestamp;
$fields = "name=?, `type`=?, dateAdded=?, dateModified=?,\n\t\t\t\tlibraryID=?, `key`=?, serverDateModified=?";
$params = array($this->name, $this->type ? $this->type : 0, $dateAdded, $dateModified, $this->libraryID, $key, $timestamp);
try {
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)));
}
} 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), '?');
//.........这里部分代码省略.........
示例5: checkUploadForErrors
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;
}
示例6: 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;
}
示例7: delete
public static function delete($libraryID, $key, $updateLibrary = false)
{
$table = static::field('table');
$id = static::field('id');
$type = static::field('object');
$types = static::field('objects');
if (!$key) {
throw new Exception("Invalid key {$key}");
}
// Get object (and trigger caching)
$obj = static::getByLibraryAndKey($libraryID, $key);
if (!$obj) {
return;
}
static::editCheck($obj);
Z_Core::debug("Deleting {$type} {$libraryID}/{$key}", 4);
$shardID = Zotero_Shards::getByLibraryID($libraryID);
Zotero_DB::beginTransaction();
// Needed for API deletes to get propagated via sync
if ($updateLibrary) {
$timestamp = Zotero_Libraries::updateTimestamps($obj->libraryID);
Zotero_DB::registerTransactionTimestamp($timestamp);
}
// Delete child items
if ($type == 'item') {
if ($obj->isRegularItem()) {
$children = array_merge($obj->getNotes(), $obj->getAttachments());
if ($children) {
$children = Zotero_Items::get($libraryID, $children);
foreach ($children as $child) {
static::delete($child->libraryID, $child->key);
}
}
}
}
if ($type == 'relation') {
// TODO: add key column to relations to speed this up
$sql = "DELETE FROM {$table} WHERE libraryID=? AND MD5(CONCAT(subject, '_', predicate, '_', object))=?";
$deleted = Zotero_DB::query($sql, array($libraryID, $key), $shardID);
} else {
$sql = "DELETE FROM {$table} WHERE libraryID=? AND `key`=?";
$deleted = Zotero_DB::query($sql, array($libraryID, $key), $shardID);
}
unset(self::$idCache[$type][$libraryID][$key]);
static::uncachePrimaryData($libraryID, $key);
if ($deleted) {
$sql = "INSERT INTO syncDeleteLogKeys (libraryID, objectType, `key`, timestamp)\n\t\t\t\t\t\tVALUES (?, '{$type}', ?, ?) ON DUPLICATE KEY UPDATE timestamp=?";
$timestamp = Zotero_DB::getTransactionTimestamp();
$params = array($libraryID, $key, $timestamp, $timestamp);
Zotero_DB::query($sql, $params, $shardID);
}
Zotero_DB::commit();
}
示例8: 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;
}
示例9: 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;
}
示例10: setItems
public function setItems($itemIDs)
{
$shardID = Zotero_Shards::getByLibraryID($this->libraryID);
Zotero_DB::beginTransaction();
$this->loadChildItems();
$current = $this->childItems;
$removed = array_diff($current, $itemIDs);
$new = array_diff($itemIDs, $current);
if ($removed) {
$arr = $removed;
$sql = "DELETE FROM collectionItems WHERE collectionID=? AND itemID IN (";
while ($chunk = array_splice($arr, 0, 500)) {
array_unshift($chunk, $this->id);
Zotero_DB::query($sql . implode(', ', array_fill(0, sizeOf($chunk) - 1, '?')) . ")", $chunk, $shardID);
}
}
if ($new) {
$arr = $new;
$sql = "INSERT INTO collectionItems (collectionID, itemID) VALUES ";
while ($chunk = array_splice($arr, 0, 250)) {
Zotero_DB::query($sql . implode(',', array_fill(0, sizeOf($chunk), '(?,?)')), call_user_func_array('array_merge', array_map(function ($itemID) {
return [$this->id, $itemID];
}, $chunk)), $shardID);
}
}
$this->childItems = array_values(array_unique($itemIDs));
//
// TODO: remove UPDATE statements below once classic syncing is removed
//
// Update timestamp of collection
$sql = "UPDATE collections SET serverDateModified=? WHERE collectionID=?";
$ts = Zotero_DB::getTransactionTimestamp();
Zotero_DB::query($sql, array($ts, $this->id), $shardID);
// Update version of new and removed items
if ($new || $removed) {
$sql = "UPDATE items SET version=? WHERE itemID IN (" . implode(', ', array_fill(0, sizeOf($new) + sizeOf($removed), '?')) . ")";
Zotero_DB::query($sql, array_merge(array(Zotero_Libraries::getUpdatedVersion($this->libraryID)), $new, $removed), $shardID);
}
Zotero_DB::commit();
}
示例11: checkUploadForErrors
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;
}
示例12: updateFromJSON
//.........这里部分代码省略.........
while ($i > $orderIndex) {
$item->removeCreator($i);
$i--;
}
}
break;
case 'tags':
// If item isn't yet saved, add tags below
if (!$item->id) {
$twoStage = true;
break;
}
if ($item->setTags($val)) {
$forceChange = true;
}
break;
case 'attachments':
case 'notes':
if (!$val) {
continue;
}
$twoStage = true;
break;
case 'note':
$item->setNote($val);
break;
// Attachment properties
// Attachment properties
case 'linkMode':
$item->attachmentLinkMode = Zotero_Attachments::linkModeNameToNumber($val, true);
break;
case 'contentType':
case 'charset':
case 'filename':
$k = "attachment" . ucwords($key);
$item->{$k} = $val;
break;
case 'md5':
$item->attachmentStorageHash = $val;
break;
case 'mtime':
$item->attachmentStorageModTime = $val;
break;
default:
$item->setField($key, $val);
break;
}
}
if ($parentItem) {
$item->setSource($parentItem->id);
}
$item->deleted = !empty($json->deleted);
// For changes that don't register as changes internally, force a dateModified update
if ($forceChange) {
$item->setField('dateModified', Zotero_DB::getTransactionTimestamp());
}
$item->save($userID);
// Additional steps that have to be performed on a saved object
if ($twoStage) {
foreach ($json as $key => $val) {
switch ($key) {
case 'attachments':
if (!$val) {
continue;
}
foreach ($val as $attachment) {
$childItem = new Zotero_Item();
$childItem->libraryID = $item->libraryID;
self::updateFromJSON($childItem, $attachment, true, $item, $userID);
}
break;
case 'notes':
if (!$val) {
continue;
}
$noteItemTypeID = Zotero_ItemTypes::getID("note");
foreach ($val as $note) {
$childItem = new Zotero_Item();
$childItem->libraryID = $item->libraryID;
$childItem->itemTypeID = $noteItemTypeID;
$childItem->setSource($item->id);
$childItem->setNote($note->note);
$childItem->save();
}
break;
case 'tags':
if ($item->setTags($val)) {
$forceChange = true;
}
break;
}
}
// For changes that don't register as changes internally, force a dateModified update
if ($forceChange) {
$item->setField('dateModified', Zotero_DB::getTransactionTimestamp());
}
$item->save($userID);
}
Zotero_DB::commit();
}
示例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($userID=false) {
if (!$this->_libraryID) {
trigger_error("Library ID must be set before saving", E_USER_ERROR);
}
Zotero_Items::editCheck($this, $userID);
if (!$this->hasChanged()) {
Z_Core::debug("Item $this->id has not changed");
return false;
}
$this->cacheEnabled = false;
// Make sure there are no gaps in the creator indexes
$creators = $this->getCreators();
$lastPos = -1;
foreach ($creators as $pos=>$creator) {
if ($pos != $lastPos + 1) {
trigger_error("Creator index $pos out of sequence for item $this->id", E_USER_ERROR);
}
$lastPos++;
}
$shardID = Zotero_Shards::getByLibraryID($this->_libraryID);
$env = [];
Zotero_DB::beginTransaction();
try {
//
// New item, insert and return id
//
if (!$this->id || (empty($this->changed['version']) && !$this->exists())) {
Z_Core::debug('Saving data for new item to database');
$isNew = $env['isNew'] = true;
$sqlColumns = array();
$sqlValues = array();
//
// Primary fields
//
$itemID = $this->_id = $this->_id ? $this->_id : Zotero_ID::get('items');
$key = $this->_key = $this->_key ? $this->_key : Zotero_ID::getKey();
$sqlColumns = array(
'itemID',
'itemTypeID',
'libraryID',
'key',
'dateAdded',
'dateModified',
'serverDateModified',
'version'
);
$timestamp = Zotero_DB::getTransactionTimestamp();
$dateAdded = $this->_dateAdded ? $this->_dateAdded : $timestamp;
$dateModified = $this->_dateModified ? $this->_dateModified : $timestamp;
$version = Zotero_Libraries::getUpdatedVersion($this->_libraryID);
$sqlValues = array(
$itemID,
$this->_itemTypeID,
$this->_libraryID,
$key,
$dateAdded,
$dateModified,
$timestamp,
$version
);
$sql = 'INSERT INTO items (`' . implode('`, `', $sqlColumns) . '`) VALUES (';
// Insert placeholders for bind parameters
for ($i=0; $i<sizeOf($sqlValues); $i++) {
$sql .= '?, ';
}
$sql = substr($sql, 0, -2) . ')';
// Save basic data to items table
try {
$insertID = Zotero_DB::query($sql, $sqlValues, $shardID);
}
catch (Exception $e) {
if (strpos($e->getMessage(), "Incorrect datetime value") !== false) {
preg_match("/Incorrect datetime value: '([^']+)'/", $e->getMessage(), $matches);
throw new Exception("=Invalid date value '{$matches[1]}' for item $key", Z_ERROR_INVALID_INPUT);
}
throw $e;
}
if (!$this->_id) {
if (!$insertID) {
throw new Exception("Item id not available after INSERT");
}
$itemID = $insertID;
$this->_serverDateModified = $timestamp;
}
// Group item data
if (Zotero_Libraries::getType($this->_libraryID) == 'group' && $userID) {
//.........这里部分代码省略.........
示例15: save
public function save($userID = false)
{
if (!$this->libraryID) {
throw new Exception("Library ID must be set before saving");
}
Zotero_Searches::editCheck($this, $userID);
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 : Zotero_ID::getKey();
$fields = "searchName=?, libraryID=?, `key`=?, dateAdded=?, dateModified=?,\n\t\t\t\t\t\tserverDateModified=?, version=?";
$timestamp = Zotero_DB::getTransactionTimestamp();
$params = array($this->name, $this->libraryID, $key, $this->dateAdded ? $this->dateAdded : $timestamp, $this->dateModified ? $this->dateModified : $timestamp, $timestamp, Zotero_Libraries::getUpdatedVersion($this->libraryID));
$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));
// 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)));
}
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 + 1, $condition['condition'], $condition['mode'] ? $condition['mode'] : '', $condition['operator'] ? $condition['operator'] : '', $condition['value'] ? $condition['value'] : '', !empty($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 (!$this->id) {
$this->id = $searchID;
}
if (!$this->key) {
$this->key = $key;
}
return $this->id;
}