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; }
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; }