/** * Saves user's information into the database. If user's id is not known, it will try to create a new user. * If user's id is known, it will try to edit information in database to make it identical to information in * this class. If you want to change user's login, load user's information before doing so. If the user with * selected id does not exist, it will throw an exception with code self::ERROR_NOTFOUND_ID. If the function * tries to create a user with taken login, an exception with code self::ERROR_TAKEN_LOGIN will be thrown. * If the user tries to take somebody else's UUID, an exception with code self::ERROR_TAKEN_UUID will be * thrown. */ public function save() { // id lookup key $userLoginKey = new Rediska_Key('user_login_' . $this->login); // id is known - we are going to edit user's information if ($this->id !== null) { // user with selected id must exist if (!$this->application->rediska->exists('user_' . $this->id)) { throw new ApplicationModelException_User('User with id ' . $this->id . ' does not exist in the database.', self::ERROR_NOTFOUND_ID); } } else { // new login must not be taken by someone else if ($userLoginKey->getValue() !== null) { throw new ApplicationModelException_User('User with login ' . $this->login . ' already exists in the database.', self::ERROR_TAKEN_LOGIN); } } // make sure that the user does not want to take somebody else's uuid foreach ($this->uuids as $time => $uuid) { $userUuidKey = new Rediska_Key('user_uuid_' . $uuid); if ($userUuidKey->getValue() !== null && $userUuidKey->getValue() != $this->id) { throw new ApplicationModelException_User('UUID ' . $uuid . ' is taken by somebody else.', self::ERROR_TAKEN_UUID); } } // if we are creating a new user - get the new id for him if ($this->id === null) { $this->id = $this->incrementRedisCounter('users_count'); } // if user's login needs to be changed (for new users, this will not be active) if ($this->loginOld !== null && $this->loginOld != $this->login) { // new login must not be taken by someone else if ($userLoginKey->getValue() !== null) { throw new ApplicationModelException_User('User with login ' . $this->login . ' already exists in the database.', self::ERROR_TAKEN_LOGIN); } // remove old id lookup key $userLoginOldKey = new Rediska_Key('user_login_' . $this->loginOld); $userLoginOldKey->delete(); } // save user's login and password hash $userKeyHash = new Rediska_Key_Hash('user_' . $this->id); $userKeyHash->login = $this->login; $this->loginOld = $this->login; $userKeyHash->password = $this->passwordHash; // save id lookup key $userLoginKey->setValue($this->id); // for every old uuid of the user: $uuidsKeySet = new Rediska_Key_SortedSet('user_' . $this->id . '_uuids'); foreach ($uuidsKeySet as $uuid) { // cut off uuid_ prefix $uuid = substr($uuid, strlen('uuid_')); // remove old id lookup key $userUuidOldKey = new Rediska_Key('user_uuid_' . $uuid); $userUuidOldKey->delete(); // remove uuid from the list $uuidsKeySet->remove('uuid_' . $uuid); } // for every new uuid for this user: foreach ($this->uuids as $time => $uuid) { // create a new id lookup key $userUuidKey = new Rediska_Key('user_uuid_' . $uuid); $userUuidKey->setValue($this->id); // add it to the list $uuidsKeySet[$time] = 'uuid_' . $uuid; } }
/** * Deletes the file from the database and disk. The file's id or path of the file must be set before this function is * called. If the id is unknown, but the path is known, this function will try to find the file's id first. * Then it will try to delete the information for the file from the database. If file with selected path or * id does not exist, an exception with code self::ERROR_NOTFOUND_PATH or self::ERROR_NOTFOUND_ID will be * thrown. If both path and file id were not set when this function is called, an exception with code * self::ERROR_UNDEFINED_ID will be thrown. */ public function delete() { // id lookup hash $path = $this->path; $filePathHash = new Rediska_Key_Hash('file_path'); // if the id is unknown, but the path is - use id lookup key to get the id of the file. if ($this->id === null && $this->path !== null) { if ($filePathHash->{$path} === null) { throw new ApplicationModelException_File('File with path ' . $this->path . ' does not exist in the database.', self::ERROR_NOTFOUND_PATH); } $this->id = (int) $filePathHash->{$path}; } // if the id is known, delete the information from the database if ($this->id !== null) { if (!$this->application->rediska->exists('file_' . $this->id)) { throw new ApplicationModelException_File('File with id ' . $this->id . ' does not exist in the database.', self::ERROR_NOTFOUND_ID); } // delete file's information $fileKeyHash = new Rediska_Key_Hash('file_' . $this->id); if ($this->path == null) { $this->path = $fileKeyHash->path; } // Remove file from disk unlink($this->path); $fileKeyHash->delete(); // remove id lookup field unset($filePathHash->{$path}); // remove file from user's upload list $filesUuidKeySet = new Rediska_Key_SortedSet('uuid_' . $this->uploader); // dirty hack for saving "uuid_HASH" in redis after removing last user file if ($filesUuidKeySet->getLength() < 2) { $filesUuidKeySet->add('virtual', 0); } $filesUuidKeySet->remove('file_' . $this->id); } else { throw new ApplicationModelException_File('Not enough information was given to delete the file\'s information.', self::ERROR_UNDEFINED_ID); } }