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