public function save() { if (!$this->loaded) { Z_Core::debug("Not saving unloaded group {$this->id}"); return; } if (empty($this->changed)) { Z_Core::debug("Group {$this->id} has not changed", 4); return; } if (!$this->ownerUserID) { throw new Exception("Cannot save group without owner"); } if (!$this->name) { throw new Exception("Cannot save group without name"); } if (mb_strlen($this->description) > 1024) { throw new Exception("Group description too long", Z_ERROR_GROUP_DESCRIPTION_TOO_LONG); } Zotero_DB::beginTransaction(); $libraryID = $this->libraryID; if (!$libraryID) { $shardID = Zotero_Shards::getNextShard(); $libraryID = Zotero_Libraries::add('group', $shardID); if (!$libraryID) { throw new Exception('libraryID not available after Zotero_Libraries::add()'); } } $fields = array('name', 'slug', 'type', 'description', 'url', 'hasImage'); if ($this->isPublic()) { $existing = Zotero_Groups::publicNameExists($this->name); if ($existing && $existing != $this->id) { throw new Exception("Public group with name '{$this->name}' already exists", Z_ERROR_PUBLIC_GROUP_EXISTS); } } $fields = array_merge($fields, array('libraryEditing', 'libraryReading', 'fileEditing')); $sql = "INSERT INTO groups\n\t\t\t\t\t(groupID, libraryID, " . implode(", ", $fields) . ", dateModified)\n\t\t\t\t\tVALUES (?, ?, " . implode(", ", array_fill(0, sizeOf($fields), "?")) . ", CURRENT_TIMESTAMP)"; $params = array($this->id, $libraryID); foreach ($fields as $field) { if (is_bool($this->{$field})) { $params[] = (int) $this->{$field}; } else { $params[] = $this->{$field}; } } $sql .= " ON DUPLICATE KEY UPDATE "; $q = array(); foreach ($fields as $field) { $q[] = "{$field}=?"; if (is_bool($this->{$field})) { $params[] = (int) $this->{$field}; } else { $params[] = $this->{$field}; } } $sql .= implode(", ", $q) . ", " . "dateModified=CURRENT_TIMESTAMP, " . "version=IF(version = 255, 1, version + 1)"; $insertID = Zotero_DB::query($sql, $params); if (!$this->id) { if (!$insertID) { throw new Exception("Group id not available after INSERT"); } $this->id = $insertID; } if (!$this->libraryID) { $this->libraryID = $libraryID; } // If creating group or changing owner if (!empty($this->changed['ownerUserID'])) { $sql = "SELECT userID FROM groupUsers WHERE groupID=? AND role='owner'"; $currentOwner = Zotero_DB::valueQuery($sql, $this->id); $newOwner = $this->ownerUserID; // Move existing owner out of the way, if there is one if ($currentOwner) { $sql = "UPDATE groupUsers SET role='admin' WHERE groupID=? AND userID=?"; Zotero_DB::query($sql, array($this->id, $currentOwner)); } // Make sure new owner exists in DB if (!Zotero_Users::exists($newOwner)) { Zotero_Users::addFromWWW($newOwner); } // Add new owner to group $sql = "INSERT INTO groupUsers (groupID, userID, role, joined) VALUES\n\t\t\t\t\t(?, ?, 'owner', CURRENT_TIMESTAMP) ON DUPLICATE KEY UPDATE\n\t\t\t\t\trole='owner', lastUpdated=CURRENT_TIMESTAMP"; Zotero_DB::query($sql, array($this->id, $newOwner)); // Delete any record of this user losing access to the group $libraryID = Zotero_Users::getLibraryIDFromUserID($this->ownerUserID); $sql = "DELETE FROM syncDeleteLogIDs WHERE libraryID=? AND objectType='group' AND id=?"; Zotero_DB::query($sql, array($libraryID, $this->id), Zotero_Shards::getByLibraryID($this->libraryID)); // Send library removal notification for all API keys belonging to the former owner // with access to this group $apiKeys = Zotero_Keys::getUserKeysWithLibrary($currentOwner, $this->libraryID); Zotero_Notifier::trigger('remove', 'apikey-library', array_map(function ($key) { return $key->key . "-" . $this->libraryID; }, $apiKeys)); // Send library add notification for all API keys belonging to the new owner // with access to this group $apiKeys = Zotero_Keys::getUserKeysWithLibrary($newOwner, $this->libraryID); Zotero_Notifier::trigger('add', 'apikey-library', array_map(function ($key) { return $key->key . "-" . $this->libraryID; }, $apiKeys)); } // If any of the group's users have a queued upload, flag group for a timestamp // update once the sync is done so that the uploading user gets the change try { $userIDs = self::getUsers(); foreach ($userIDs as $userID) { if ($syncUploadQueueID = Zotero_Sync::getUploadQueueIDByUserID($userID)) { Zotero_Sync::postWriteLog($syncUploadQueueID, 'group', $this->id, 'update'); } } } catch (Exception $e) { Z_Core::logError($e); } Zotero_DB::commit(); $this->load(); return $libraryID; }
public static function add($userID, $username = '') { Zotero_DB::beginTransaction(); $shardID = Zotero_Shards::getNextShard(); $libraryID = Zotero_Libraries::add('user', $shardID); $sql = "INSERT INTO users (userID, libraryID, username) VALUES (?, ?, ?)"; Zotero_DB::query($sql, array($userID, $libraryID, $username)); Zotero_DB::commit(); return $libraryID; }