Commit | Line | Data |
---|---|---|
e3667539 MW |
1 | <?php |
2 | namespace wcf\system\worker; | |
557115b5 | 3 | use wcf\data\reaction\type\ReactionTypeCache; |
2772d4eb MW |
4 | use wcf\data\user\avatar\UserAvatar; |
5 | use wcf\data\user\avatar\UserAvatarEditor; | |
6 | use wcf\data\user\avatar\UserAvatarList; | |
8a413435 | 7 | use wcf\data\user\User; |
e3667539 | 8 | use wcf\data\user\UserEditor; |
157054c9 | 9 | use wcf\data\user\UserList; |
e3667539 | 10 | use wcf\data\user\UserProfileAction; |
7e058783 | 11 | use wcf\system\bbcode\BBCodeHandler; |
e3667539 | 12 | use wcf\system\database\util\PreparedStatementConditionBuilder; |
c5c9e424 | 13 | use wcf\system\exception\SystemException; |
b8c48208 | 14 | use wcf\system\html\input\HtmlInputProcessor; |
2772d4eb | 15 | use wcf\system\image\ImageHandler; |
e3667539 MW |
16 | use wcf\system\WCF; |
17 | ||
18 | /** | |
19 | * Worker implementation for updating users. | |
20 | * | |
21 | * @author Marcel Werk | |
7b7b9764 | 22 | * @copyright 2001-2019 WoltLab GmbH |
e3667539 | 23 | * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php> |
e71525e4 | 24 | * @package WoltLabSuite\Core\System\Worker |
bbd89532 MS |
25 | * |
26 | * @method UserList getObjectList() | |
e3667539 MW |
27 | */ |
28 | class UserRebuildDataWorker extends AbstractRebuildDataWorker { | |
29 | /** | |
0fcfe5f6 | 30 | * @inheritDoc |
e3667539 | 31 | */ |
157054c9 | 32 | protected $objectListClassName = UserList::class; |
e3667539 MW |
33 | |
34 | /** | |
0fcfe5f6 | 35 | * @inheritDoc |
e3667539 MW |
36 | */ |
37 | protected $limit = 50; | |
38 | ||
39 | /** | |
0fcfe5f6 | 40 | * @inheritDoc |
e3667539 MW |
41 | */ |
42 | protected function initObjectList() { | |
43 | parent::initObjectList(); | |
44 | ||
8a413435 AE |
45 | $this->objectList->sqlSelects = 'user_option_value.userOption' . User::getUserOptionID('aboutMe') . ' AS aboutMe'; |
46 | $this->objectList->sqlJoins = "LEFT JOIN wcf".WCF_N."_user_option_value user_option_value ON (user_option_value.userID = user_table.userID)"; | |
e3667539 MW |
47 | $this->objectList->sqlOrderBy = 'user_table.userID'; |
48 | } | |
49 | ||
50 | /** | |
0fcfe5f6 | 51 | * @inheritDoc |
e3667539 MW |
52 | */ |
53 | public function execute() { | |
54 | parent::execute(); | |
55 | ||
058cbd6a | 56 | $users = $userIDs = []; |
e3667539 MW |
57 | foreach ($this->getObjectList() as $user) { |
58 | $users[] = new UserEditor($user); | |
59 | $userIDs[] = $user->userID; | |
60 | } | |
61 | ||
62 | // update user ranks | |
63 | if (!empty($users)) { | |
64 | $action = new UserProfileAction($users, 'updateUserOnlineMarking'); | |
65 | $action->executeAction(); | |
66 | } | |
67 | ||
68 | if (!empty($userIDs)) { | |
bd1067ab AE |
69 | // update article counter |
70 | $conditionBuilder = new PreparedStatementConditionBuilder(); | |
71 | $conditionBuilder->add('user_table.userID IN (?)', [$userIDs]); | |
72 | $sql = "UPDATE wcf".WCF_N."_user user_table | |
73 | SET articles = ( | |
74 | SELECT COUNT(*) | |
75 | FROM wcf".WCF_N."_article | |
76 | WHERE userID = user_table.userID | |
77 | ) | |
78 | ".$conditionBuilder; | |
79 | $statement = WCF::getDB()->prepareStatement($sql); | |
80 | $statement->execute($conditionBuilder->getParameters()); | |
81 | ||
e3667539 MW |
82 | // update like counter |
83 | if (MODULE_LIKE) { | |
557115b5 | 84 | $sql = "UPDATE wcf".WCF_N."_user user_table SET"; |
25f91a2f | 85 | |
1626fe3e | 86 | $reactionTypeIDs = array_keys(ReactionTypeCache::getInstance()->getReactionTypes()); |
25f91a2f | 87 | if (!empty($reactionTypeIDs)) { |
557115b5 | 88 | $sql .= " likesReceived = ( |
e3667539 MW |
89 | SELECT COUNT(*) |
90 | FROM wcf".WCF_N."_like | |
91 | WHERE objectUserID = user_table.userID | |
25f91a2f AE |
92 | AND reactionTypeID IN (". implode(',', $reactionTypeIDs) .") |
93 | )"; | |
557115b5 JR |
94 | } |
95 | else { | |
25f91a2f | 96 | $sql .= " likesReceived = 0"; |
557115b5 JR |
97 | } |
98 | ||
557115b5 | 99 | $sql .= " ".$conditionBuilder; |
e3667539 MW |
100 | $statement = WCF::getDB()->prepareStatement($sql); |
101 | $statement->execute($conditionBuilder->getParameters()); | |
102 | } | |
2772d4eb | 103 | |
85f59bb3 JR |
104 | // update trophy points |
105 | if (MODULE_TROPHY) { | |
85f59bb3 JR |
106 | $sql = "UPDATE wcf".WCF_N."_user user_table |
107 | SET trophyPoints = ( | |
108 | SELECT COUNT(*) | |
109 | FROM wcf".WCF_N."_user_trophy user_trophy | |
110 | LEFT JOIN wcf".WCF_N."_trophy trophy ON user_trophy.trophyID = trophy.trophyID | |
111 | LEFT JOIN wcf".WCF_N."_category trophy_category ON trophy.categoryID = trophy_category.categoryID | |
112 | WHERE user_trophy.userID = user_table.userID | |
113 | AND trophy.isDisabled = 0 | |
114 | AND trophy_category.isDisabled = 0 | |
115 | ) | |
116 | ".$conditionBuilder; | |
117 | $statement = WCF::getDB()->prepareStatement($sql); | |
118 | $statement->execute($conditionBuilder->getParameters()); | |
119 | } | |
120 | ||
8a413435 AE |
121 | // update signatures and about me |
122 | $sql = "UPDATE wcf".WCF_N."_user_option_value | |
123 | SET userOption" . User::getUserOptionID('aboutMe') . " = ? | |
124 | WHERE userID = ?"; | |
125 | $statement = WCF::getDB()->prepareStatement($sql); | |
126 | ||
7e058783 AE |
127 | // retrieve permissions |
128 | $userIDs = []; | |
129 | foreach ($users as $user) { | |
130 | $userIDs[] = $user->userID; | |
131 | } | |
132 | $userPermissions = $this->getBulkUserPermissions($userIDs, ['user.message.disallowedBBCodes', 'user.signature.disallowedBBCodes']); | |
133 | ||
b8c48208 AE |
134 | $htmlInputProcessor = new HtmlInputProcessor(); |
135 | WCF::getDB()->beginTransaction(); | |
136 | /** @var UserEditor $user */ | |
137 | foreach ($users as $user) { | |
7e058783 AE |
138 | BBCodeHandler::getInstance()->setDisallowedBBCodes(explode(',', $this->getBulkUserPermissionValue($userPermissions, $user->userID, 'user.signature.disallowedBBCodes'))); |
139 | ||
b8c48208 AE |
140 | if (!$user->signatureEnableHtml) { |
141 | $htmlInputProcessor->process($user->signature, 'com.woltlab.wcf.user.signature', $user->userID, true); | |
142 | ||
143 | $user->update([ | |
144 | 'signature' => $htmlInputProcessor->getHtml(), | |
145 | 'signatureEnableHtml' => 1 | |
146 | ]); | |
13825b39 AE |
147 | } |
148 | else { | |
149 | $htmlInputProcessor->reprocess($user->signature, 'com.woltlab.wcf.user.signature', $user->userID); | |
150 | $user->update(['signature' => $htmlInputProcessor->getHtml()]); | |
151 | } | |
152 | ||
153 | if ($user->aboutMe) { | |
7e058783 AE |
154 | BBCodeHandler::getInstance()->setDisallowedBBCodes(explode(',', $this->getBulkUserPermissionValue($userPermissions, $user->userID, 'user.message.disallowedBBCodes'))); |
155 | ||
13825b39 | 156 | if (!$user->signatureEnableHtml) { |
8a413435 | 157 | $htmlInputProcessor->process($user->aboutMe, 'com.woltlab.wcf.user.aboutMe', $user->userID, true); |
8a413435 | 158 | } |
13825b39 AE |
159 | else { |
160 | $htmlInputProcessor->reprocess($user->aboutMe, 'com.woltlab.wcf.user.aboutMe', $user->userID); | |
161 | } | |
162 | ||
163 | $html = $htmlInputProcessor->getHtml(); | |
164 | // MySQL's TEXT type allows for 65,535 bytes, hence we need to count | |
165 | // the bytes rather than the actual amount of characters | |
166 | if (strlen($html) > 65535) { | |
167 | // content does not fit the available space, and any | |
168 | // attempts to truncate it will yield awkward results | |
169 | $html = ''; | |
170 | } | |
171 | ||
172 | $statement->execute([$html, $user->userID]); | |
b8c48208 AE |
173 | } |
174 | } | |
175 | WCF::getDB()->commitTransaction(); | |
176 | ||
bbabc452 | 177 | // update old/imported avatars |
2772d4eb MW |
178 | $avatarList = new UserAvatarList(); |
179 | $avatarList->getConditionBuilder()->add('user_avatar.userID IN (?)', [$userIDs]); | |
180 | $avatarList->getConditionBuilder()->add('(user_avatar.width <> ? OR user_avatar.height <> ?)', [UserAvatar::AVATAR_SIZE, UserAvatar::AVATAR_SIZE]); | |
181 | $avatarList->readObjects(); | |
182 | foreach ($avatarList as $avatar) { | |
1fe8a30f AE |
183 | $editor = new UserAvatarEditor($avatar); |
184 | if (!file_exists($avatar->getLocation()) || @getimagesize($avatar->getLocation()) === false) { | |
185 | // delete avatars that are missing or broken | |
186 | $editor->delete(); | |
187 | continue; | |
188 | } | |
189 | ||
2772d4eb MW |
190 | $width = $avatar->width; |
191 | $height = $avatar->height; | |
192 | if ($width != $height) { | |
bbabc452 | 193 | // make avatar quadratic |
2772d4eb MW |
194 | $width = $height = min($width, $height, UserAvatar::AVATAR_SIZE); |
195 | $adapter = ImageHandler::getInstance()->getAdapter(); | |
c5c9e424 AE |
196 | |
197 | try { | |
198 | $adapter->loadFile($avatar->getLocation()); | |
199 | } | |
200 | catch (SystemException $e) { | |
201 | // broken image | |
202 | $editor->delete(); | |
203 | continue; | |
204 | } | |
205 | ||
2772d4eb MW |
206 | $thumbnail = $adapter->createThumbnail($width, $height, false); |
207 | $adapter->writeImage($thumbnail, $avatar->getLocation()); | |
99397679 TD |
208 | // Clear thumbnail as soon as possible to free up the memory. |
209 | $thumbnail = null; | |
2772d4eb MW |
210 | } |
211 | ||
bbabc452 MW |
212 | if ($width != UserAvatar::AVATAR_SIZE || $height != UserAvatar::AVATAR_SIZE) { |
213 | // resize avatar | |
3461e167 | 214 | $adapter = ImageHandler::getInstance()->getAdapter(); |
c5c9e424 AE |
215 | |
216 | try { | |
217 | $adapter->loadFile($avatar->getLocation()); | |
218 | } | |
219 | catch (SystemException $e) { | |
220 | // broken image | |
221 | $editor->delete(); | |
222 | continue; | |
223 | } | |
224 | ||
3461e167 MW |
225 | $adapter->resize(0, 0, $width, $height, UserAvatar::AVATAR_SIZE, UserAvatar::AVATAR_SIZE); |
226 | $adapter->writeImage($adapter->getImage(), $avatar->getLocation()); | |
227 | $width = $height = UserAvatar::AVATAR_SIZE; | |
2772d4eb MW |
228 | } |
229 | ||
2772d4eb | 230 | $editor->update([ |
3461e167 MW |
231 | 'width' => $width, |
232 | 'height' => $height | |
2772d4eb MW |
233 | ]); |
234 | } | |
e3667539 MW |
235 | } |
236 | } | |
237 | } |