From 16977ca6207490927c5c9f54297ace35caa57eff Mon Sep 17 00:00:00 2001 From: =?utf8?q?Joshua=20R=C3=BCsweg?= Date: Sun, 9 Jul 2017 15:48:49 +0200 Subject: [PATCH] Add userTrophy DBO See #2315 --- .../lib/data/user/trophy/UserTrophy.class.php | 101 ++++++++++++++++++ .../user/trophy/UserTrophyAction.class.php | 60 +++++++++++ .../user/trophy/UserTrophyEditor.class.php | 20 ++++ .../data/user/trophy/UserTrophyList.class.php | 62 +++++++++++ wcfsetup/setup/db/install.sql | 18 +++- 5 files changed, 260 insertions(+), 1 deletion(-) create mode 100644 wcfsetup/install/files/lib/data/user/trophy/UserTrophy.class.php create mode 100644 wcfsetup/install/files/lib/data/user/trophy/UserTrophyAction.class.php create mode 100644 wcfsetup/install/files/lib/data/user/trophy/UserTrophyEditor.class.php create mode 100644 wcfsetup/install/files/lib/data/user/trophy/UserTrophyList.class.php diff --git a/wcfsetup/install/files/lib/data/user/trophy/UserTrophy.class.php b/wcfsetup/install/files/lib/data/user/trophy/UserTrophy.class.php new file mode 100644 index 0000000000..6dcc147497 --- /dev/null +++ b/wcfsetup/install/files/lib/data/user/trophy/UserTrophy.class.php @@ -0,0 +1,101 @@ + + * @package WoltLabSuite\Core\Data\User\Trophy + * @since 3.1 + * + * @property-read integer $userTrophyID unique id of the user trophy + * @property-read integer $trophyID trophy id + * @property-read integer $userID user id + * @property-read integer $time the time when the trophy was rewarded + * @property-read string $description the custom trophy description + * @property-read string $useCustomDescription `1`, iif the trophy use a custom description + */ +class UserTrophy extends DatabaseObject { + /** + * Returns the trophy for the user trophy. + * + * @return Trophy + */ + public function getTrophy() { + return TrophyCache::getInstance()->getTrophyByID($this->trophyID); + } + + /** + * Returns the user profile for the user trophy. + * + * @return UserProfile + */ + public function getUserProfile() { + return UserProfileRuntimeCache::getInstance()->getObject($this->userID); + } + + /** + * Returns the parsed description. + * + * @return string + */ + public function getDescription() { + if (!$this->useCustomDescription) { + return $this->getTrophy()->getDescription(); + } + + $replacements = [ + '{$username}' => $this->getUserProfile()->username + ]; + + $parameters = ['replacements' => $replacements]; + + EventHandler::getInstance()->fireAction($this, 'getDescription', $parameters); + + $replacements = $parameters['replacements']; + + return nl2br(StringUtil::encodeHTML(strtr($this->description, $replacements))); + } + + /** + * Returns true, if the given user can see this user trophy. + * + * @param User $user + * @return bool + * @throws SystemException + */ + public function canSee(User $user = null) { + if ($user === null) { + $user = WCF::getUser(); + } + + if (!$user->userID) { + $userProfile = new UserProfile(new User(null, [])); + } else { + $userProfile = UserProfileRuntimeCache::getInstance()->getObject($user->userID); + } + + if (!$userProfile->getPermission('user.profile.trophy.canSeeTrophies')) { + return false; + } + + if ($this->getTrophy()->isDisabled()) { + return false; + } + + // @TODO check user option canViewTrophies + return true; + } +} diff --git a/wcfsetup/install/files/lib/data/user/trophy/UserTrophyAction.class.php b/wcfsetup/install/files/lib/data/user/trophy/UserTrophyAction.class.php new file mode 100644 index 0000000000..16f0092edd --- /dev/null +++ b/wcfsetup/install/files/lib/data/user/trophy/UserTrophyAction.class.php @@ -0,0 +1,60 @@ + + * @package WoltLabSuite\Core\Data\User\Trophy + * @since 3.1 + */ +class UserTrophyAction extends AbstractDatabaseObjectAction { + /** + * @inheritDoc + */ + protected $permissionsDelete = ['admin.trophy.canAwardTrophy']; + + /** + * @inheritDoc + */ + public function create() { + $returnValues = parent::create(); + + (new UserAction([$returnValues->userID], 'update', [ + 'counters' => [ + 'trophyPoints' => 1 + ] + ]))->executeAction(); + + return $returnValues; + } + + /** + * @inheritDoc + */ + public function delete() { + $returnValues = parent::delete(); + + $updateUserTrophies = []; + + /** @var $object UserTrophyEditor */ + foreach ($this->objects as $object) { + if (!isset($updateUserTrophies[$object->userID])) $updateUserTrophies[$object->userID] = 0; + $updateUserTrophies[$object->userID]--; + } + + foreach ($updateUserTrophies as $userID => $count) { + (new UserAction([$userID], 'update', [ + 'counters' => [ + 'trophies' => $count + ] + ]))->executeAction(); + } + + return $returnValues; + } +} diff --git a/wcfsetup/install/files/lib/data/user/trophy/UserTrophyEditor.class.php b/wcfsetup/install/files/lib/data/user/trophy/UserTrophyEditor.class.php new file mode 100644 index 0000000000..798c4fd9e9 --- /dev/null +++ b/wcfsetup/install/files/lib/data/user/trophy/UserTrophyEditor.class.php @@ -0,0 +1,20 @@ + + * @package WoltLabSuite\Core\Data\User\Trophy + * @since 3.1 + * @mixin UserTrophy + */ +class UserTrophyEditor extends DatabaseObjectEditor { + /** + * @inheritDoc + */ + protected static $baseClass = UserTrophy::class; +} diff --git a/wcfsetup/install/files/lib/data/user/trophy/UserTrophyList.class.php b/wcfsetup/install/files/lib/data/user/trophy/UserTrophyList.class.php new file mode 100644 index 0000000000..94f9a65b71 --- /dev/null +++ b/wcfsetup/install/files/lib/data/user/trophy/UserTrophyList.class.php @@ -0,0 +1,62 @@ + + * @package WoltLabSuite\Core\Data\User\Trophy + * @since 3.1 + * + * @method UserTrophy current() + * @method UserTrophy[] getObjects() + * @method UserTrophy|null search($objectID) + * @property UserTrophy[] $objects + */ +class UserTrophyList extends DatabaseObjectList { + /** + * Returns a user trophy list for a certain users. + * + * @param integer[] $userIDs + * @param boolean $includeDisabled + * @return UserTrophy[][] + */ + public static function getUserTrophies(array $userIDs, $includeDisabled = false) { + if (empty($userIDs)) { + throw new \InvalidArgumentException('UserIDs cannot be empty.'); + } + + $trophyList = new self(); + $trophyList->getConditionBuilder()->add('user_trophy.userID IN (?)', [$userIDs]); + + if (!$includeDisabled) { + if (!empty($trophyList->sqlJoins)) $trophyList->sqlJoins .= ' '; + if (!empty($trophyList->sqlConditionJoins)) $trophyList->sqlConditionJoins .= ' '; + $trophyList->sqlJoins .= 'LEFT JOIN wcf'. WCF_N . '_trophy trophy ON user_trophy.trophyID = trophy.trophyID'; + $trophyList->sqlConditionJoins .= 'LEFT JOIN wcf'. WCF_N . '_trophy trophy ON user_trophy.trophyID = trophy.trophyID'; + + // trophy category join + $trophyList->sqlJoins .= ' LEFT JOIN wcf'. WCF_N . '_category category ON trophy.categoryID = category.categoryID'; + $trophyList->sqlConditionJoins .= ' LEFT JOIN wcf'. WCF_N . '_category category ON trophy.categoryID = category.categoryID'; + + $trophyList->getConditionBuilder()->add('trophy.isDisabled = ?', [0]); + $trophyList->getConditionBuilder()->add('category.isDisabled = ?', [0]); + } + + $trophyList->readObjects(); + + $returnValues = []; + foreach ($userIDs as $userID) { + $returnValues[$userID] = []; + } + + foreach ($trophyList as $trophy) { + $returnValues[$trophy->userID][$trophy->getObjectID()] = $trophy; + } + + return $returnValues; + } +} diff --git a/wcfsetup/setup/db/install.sql b/wcfsetup/setup/db/install.sql index fd46701326..e3a9dc04f1 100644 --- a/wcfsetup/setup/db/install.sql +++ b/wcfsetup/setup/db/install.sql @@ -1374,6 +1374,7 @@ CREATE TABLE wcf1_user ( notificationMailToken VARCHAR(20) NOT NULL DEFAULT '', authData VARCHAR(191) NOT NULL DEFAULT '', likesReceived MEDIUMINT(7) NOT NULL DEFAULT 0, + trophyPoints INT(10) NOT NULL DEFAULT 0, KEY username (username), KEY email (email), @@ -1383,7 +1384,8 @@ CREATE TABLE wcf1_user ( KEY registrationData (registrationIpAddress, registrationDate), KEY activityPoints (activityPoints), KEY likesReceived (likesReceived), - KEY authData (authData) + KEY authData (authData), + KEY trophyPoints (trophyPoints) ); DROP TABLE IF EXISTS wcf1_user_activity_event; @@ -1518,6 +1520,17 @@ CREATE TABLE wcf1_user_ignore ( UNIQUE KEY (userID, ignoreUserID) ); +DROP TABLE IF EXISTS wcf1_user_trophy; +CREATE TABLE wcf1_user_trophy( + userTrophyID INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY, + trophyID INT(10) NOT NULL, + userID INT(10) NOT NULL, + time INT(10) NOT NULL DEFAULT 0, + description MEDIUMTEXT, + useCustomDescription TINYINT(1) NOT NULL DEFAULT 0, + KEY(trophyID, time) +); + DROP TABLE IF EXISTS wcf1_user_menu_item; CREATE TABLE wcf1_user_menu_item ( menuItemID INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY, @@ -1937,6 +1950,9 @@ ALTER TABLE wcf1_user_to_group ADD FOREIGN KEY (groupID) REFERENCES wcf1_user_gr ALTER TABLE wcf1_user_to_language ADD FOREIGN KEY (userID) REFERENCES wcf1_user (userID) ON DELETE CASCADE; ALTER TABLE wcf1_user_to_language ADD FOREIGN KEY (languageID) REFERENCES wcf1_language (languageID) ON DELETE CASCADE; +ALTER TABLE wcf1_user_trophy ADD FOREIGN KEY (trophyID) REFERENCES wcf1_trophy (trophyID) ON DELETE CASCADE; +ALTER TABLE wcf1_user_trophy ADD FOREIGN KEY (userID) REFERENCES wcf1_user (userID) ON DELETE CASCADE; + ALTER TABLE wcf1_import_mapping ADD FOREIGN KEY (objectTypeID) REFERENCES wcf1_object_type (objectTypeID) ON DELETE CASCADE; ALTER TABLE wcf1_tracked_visit ADD FOREIGN KEY (objectTypeID) REFERENCES wcf1_object_type (objectTypeID) ON DELETE CASCADE; -- 2.20.1