3 namespace wcf\data\user\trophy
;
5 use wcf\data\AbstractDatabaseObjectAction
;
6 use wcf\data\user\UserAction
;
7 use wcf\data\user\UserProfile
;
8 use wcf\data\user\UserProfileAction
;
9 use wcf\system\cache\runtime\UserProfileRuntimeCache
;
10 use wcf\system\database\util\PreparedStatementConditionBuilder
;
11 use wcf\system\exception\IllegalLinkException
;
12 use wcf\system\exception\PermissionDeniedException
;
13 use wcf\system\user\activity\event\UserActivityEventHandler
;
14 use wcf\system\user\notification\
object\UserTrophyNotificationObject
;
15 use wcf\system\user\notification\UserNotificationHandler
;
16 use wcf\system\user\storage\UserStorageHandler
;
20 * Provides user trophy actions.
22 * @author Joshua Ruesweg
23 * @copyright 2001-2019 WoltLab GmbH
24 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
25 * @package WoltLabSuite\Core\Data\User\Trophy
28 * @method UserTrophyEditor[] getObjects()
29 * @method UserTrophyEditor getSingleObject()
31 class UserTrophyAction
extends AbstractDatabaseObjectAction
36 protected $permissionsDelete = ['admin.trophy.canAwardTrophy'];
41 protected $allowGuestAccess = ['getGroupedUserTrophyList'];
51 public function create()
53 /** @var UserTrophy $userTrophy */
54 $userTrophy = parent
::create();
56 if (!$userTrophy->getTrophy()->isDisabled()) {
57 $userAction = new UserAction([$userTrophy->userID
], 'update', [
62 $userAction->executeAction();
64 // checks if the user still has space to add special trophies
65 if (\
count($userTrophy->getUserProfile()->getSpecialTrophies()) < $userTrophy->getUserProfile()->getPermission('user.profile.trophy.maxUserSpecialTrophies')) {
67 foreach (UserTrophyList
::getUserTrophies([$userTrophy->getUserProfile()->userID
])[$userTrophy->getUserProfile()->userID
] as $trophy) {
68 if ($trophy->trophyID
== $userTrophy->trophyID
&& $trophy->userTrophyID
!== $userTrophy->userTrophyID
) {
75 $userProfileAction = new UserProfileAction(
76 [$userTrophy->getUserProfile()->getDecoratedObject()],
77 'updateSpecialTrophies',
79 'trophyIDs' => \array_unique
(\array_merge
(\array_map
(static function ($trophy) {
80 return $trophy->trophyID
;
81 }, $userTrophy->getUserProfile()->getSpecialTrophies()), [$userTrophy->trophyID
])),
84 $userProfileAction->executeAction();
89 UserActivityEventHandler
::getInstance()->fireEvent(
90 'com.woltlab.wcf.userTrophy.recentActivityEvent.trophyReceived',
91 $userTrophy->getObjectID(),
96 UserNotificationHandler
::getInstance()->fireEvent(
98 'com.woltlab.wcf.userTrophy.notification',
99 new UserTrophyNotificationObject($userTrophy),
111 public function validateDelete()
113 parent
::validateDelete();
115 /** @var UserTrophy $object */
116 foreach ($this->objects
as $object) {
117 if ($object->getTrophy()->awardAutomatically
) {
118 throw new PermissionDeniedException();
126 public function delete()
128 if (empty($this->objects
)) {
129 $this->readObjects();
132 $trophyIDs = $userIDs = [];
133 foreach ($this->getObjects() as $object) {
134 $trophyIDs[] = $object->trophyID
;
135 $userIDs[] = $object->userID
;
138 $returnValues = parent
::delete();
140 if (!empty($this->objects
)) {
141 // update user special trophies trophies
142 $userTrophies = UserTrophyList
::getUserTrophies($userIDs);
144 foreach ($userTrophies as $userID => $trophies) {
146 foreach ($trophies as $trophy) {
147 $userTrophyIDs[] = $trophy->trophyID
;
150 $conditionBuilder = new PreparedStatementConditionBuilder();
151 if (!empty($userTrophyIDs)) {
152 $conditionBuilder->add('trophyID NOT IN (?)', [\array_unique
($userTrophyIDs)]);
154 $conditionBuilder->add('userID = ?', [$userID]);
156 $sql = "DELETE FROM wcf" . WCF_N
. "_user_special_trophy
157 " . $conditionBuilder;
158 $statement = WCF
::getDB()->prepareStatement($sql);
159 $statement->execute($conditionBuilder->getParameters());
161 UserStorageHandler
::getInstance()->reset([$userID], 'specialTrophies');
164 $updateUserTrophies = [];
165 foreach ($this->getObjects() as $object) {
166 if (!$object->getTrophy()->isDisabled()) {
167 if (!isset($updateUserTrophies[$object->userID
])) {
168 $updateUserTrophies[$object->userID
] = 0;
170 $updateUserTrophies[$object->userID
]--;
174 foreach ($updateUserTrophies as $userID => $count) {
175 $userAction = new UserAction([$userID], 'update', [
177 'trophyPoints' => $count,
180 $userAction->executeAction();
184 return $returnValues;
188 * Validates the getGroupedUserTrophyList method.
190 public function validateGetGroupedUserTrophyList()
192 if (!MODULE_TROPHY
) {
193 throw new IllegalLinkException();
196 WCF
::getSession()->checkPermissions(['user.profile.trophy.canSeeTrophies']);
198 $this->readInteger('pageNo');
199 $this->readInteger('userID');
201 $this->userProfile
= UserProfileRuntimeCache
::getInstance()->getObject($this->parameters
['userID']);
202 if (!$this->userProfile
->isAccessible('canViewTrophies') && !($this->userProfile
->userID
== WCF
::getSession()->userID
)) {
203 throw new PermissionDeniedException();
208 * Returns a viewable user trophy list for a specific user.
210 public function getGroupedUserTrophyList()
212 $userTrophyList = new UserTrophyList();
213 $userTrophyList->getConditionBuilder()->add('userID = ?', [$this->parameters
['userID']]);
214 if (!empty($userTrophyList->sqlJoins
)) {
215 $userTrophyList->sqlJoins
.= ' ';
217 if (!empty($userTrophyList->sqlConditionJoins
)) {
218 $userTrophyList->sqlConditionJoins
.= ' ';
220 $userTrophyList->sqlJoins
.= '
221 LEFT JOIN wcf' . WCF_N
. '_trophy trophy
222 ON user_trophy.trophyID = trophy.trophyID';
223 $userTrophyList->sqlConditionJoins
.= '
224 LEFT JOIN wcf' . WCF_N
. '_trophy trophy
225 ON user_trophy.trophyID = trophy.trophyID';
227 // trophy category join
228 $userTrophyList->sqlJoins
.= '
229 LEFT JOIN wcf' . WCF_N
. '_category category
230 ON trophy.categoryID = category.categoryID';
231 $userTrophyList->sqlConditionJoins
.= '
232 LEFT JOIN wcf' . WCF_N
. '_category category
233 ON trophy.categoryID = category.categoryID';
235 $userTrophyList->getConditionBuilder()->add('trophy.isDisabled = ?', [0]);
236 $userTrophyList->getConditionBuilder()->add('category.isDisabled = ?', [0]);
237 $userTrophyList->sqlLimit
= 10;
238 $userTrophyList->sqlOffset
= ($this->parameters
['pageNo'] - 1) * 10;
239 $userTrophyList->sqlOrderBy
= 'time DESC';
240 $pageCount = \
ceil($userTrophyList->countObjects() / 10);
241 $userTrophyList->readObjects();
244 'pageCount' => $pageCount,
245 'title' => WCF
::getLanguage()->getDynamicVariable(
246 'wcf.user.trophy.dialogTitle',
247 ['username' => $this->userProfile
->username
]
249 'template' => WCF
::getTPL()->fetch('groupedUserTrophyList', 'wcf', [
250 'userTrophyList' => $userTrophyList,