Commit | Line | Data |
---|---|---|
11ade432 AE |
1 | <?php |
2 | namespace wcf\data\user; | |
0dd6ea0c | 3 | use wcf\data\user\avatar\UserAvatarAction; |
11ade432 | 4 | use wcf\data\user\group\UserGroup; |
931f6597 | 5 | use wcf\data\AbstractDatabaseObjectAction; |
7918ddba | 6 | use wcf\data\IClipboardAction; |
a427a8c8 | 7 | use wcf\data\ISearchAction; |
b0dc9618 | 8 | use wcf\system\attachment\AttachmentHandler; |
7f379ade | 9 | use wcf\system\clipboard\ClipboardHandler; |
97247661 | 10 | use wcf\system\comment\CommentHandler; |
11ade432 | 11 | use wcf\system\database\util\PreparedStatementConditionBuilder; |
bde0e3dc TD |
12 | use wcf\system\email\mime\MimePartFacade; |
13 | use wcf\system\email\mime\RecipientAwareTextMimePart; | |
14 | use wcf\system\email\Email; | |
15 | use wcf\system\email\UserMailbox; | |
dd900ec4 AE |
16 | use wcf\system\event\EventHandler; |
17 | use wcf\system\exception\PermissionDeniedException; | |
18 | use wcf\system\exception\UserInputException; | |
bae8dd1e | 19 | use wcf\system\request\RequestHandler; |
2bc9f31d | 20 | use wcf\system\WCF; |
2fe45e04 | 21 | use wcf\util\UserRegistrationUtil; |
11ade432 AE |
22 | |
23 | /** | |
24 | * Executes user-related actions. | |
25 | * | |
26 | * @author Alexander Ebert | |
c839bd49 | 27 | * @copyright 2001-2018 WoltLab GmbH |
11ade432 | 28 | * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php> |
e71525e4 | 29 | * @package WoltLabSuite\Core\Data\User |
0e8867ac MS |
30 | * |
31 | * @method UserEditor[] getObjects() | |
32 | * @method UserEditor getSingleObject() | |
11ade432 | 33 | */ |
7918ddba | 34 | class UserAction extends AbstractDatabaseObjectAction implements IClipboardAction, ISearchAction { |
11ade432 | 35 | /** |
b35f63d6 | 36 | * @inheritDoc |
11ade432 | 37 | */ |
b35f63d6 | 38 | public $className = UserEditor::class; |
11ade432 | 39 | |
8eb8876b | 40 | /** |
b35f63d6 | 41 | * @inheritDoc |
8eb8876b | 42 | */ |
b35f63d6 | 43 | protected $allowGuestAccess = ['getSearchResultList']; |
8eb8876b | 44 | |
11ade432 | 45 | /** |
b35f63d6 | 46 | * @inheritDoc |
11ade432 | 47 | */ |
b35f63d6 | 48 | protected $permissionsCreate = ['admin.user.canAddUser']; |
11ade432 AE |
49 | |
50 | /** | |
b35f63d6 | 51 | * @inheritDoc |
11ade432 | 52 | */ |
b35f63d6 | 53 | protected $permissionsDelete = ['admin.user.canDeleteUser']; |
11ade432 AE |
54 | |
55 | /** | |
b35f63d6 | 56 | * @inheritDoc |
11ade432 | 57 | */ |
b35f63d6 | 58 | protected $permissionsUpdate = ['admin.user.canEditUser']; |
11ade432 | 59 | |
bae8dd1e | 60 | /** |
b35f63d6 | 61 | * @inheritDoc |
bae8dd1e | 62 | */ |
efed4643 | 63 | protected $requireACP = ['create', 'delete']; |
bae8dd1e | 64 | |
11ade432 AE |
65 | /** |
66 | * Validates permissions and parameters. | |
67 | */ | |
68 | public function validateCreate() { | |
a54f8d8f | 69 | $this->readString('password', false, 'data'); |
11ade432 AE |
70 | } |
71 | ||
72 | /** | |
11cf19be MW |
73 | * Validates accessible groups. |
74 | * | |
75 | * @param boolean $ignoreOwnUser | |
2b770bdd MS |
76 | * @throws PermissionDeniedException |
77 | * @throws UserInputException | |
11ade432 | 78 | */ |
11cf19be MW |
79 | protected function __validateAccessibleGroups($ignoreOwnUser = true) { |
80 | if ($ignoreOwnUser) { | |
81 | if (in_array(WCF::getUser()->userID, $this->objectIDs)) { | |
82 | unset($this->objectIDs[array_search(WCF::getUser()->userID, $this->objectIDs)]); | |
83 | if (isset($this->objects[WCF::getUser()->userID])) { | |
84 | unset($this->objects[WCF::getUser()->userID]); | |
85 | } | |
a7fd745e | 86 | } |
48f9369a | 87 | } |
11ade432 | 88 | |
a7fd745e | 89 | // list might be empty because only our own user id was given |
11cf19be | 90 | if (empty($this->objectIDs)) { |
3631f7bd | 91 | throw new UserInputException('objectIDs'); |
a7fd745e AE |
92 | } |
93 | ||
11ade432 AE |
94 | // validate groups |
95 | $conditions = new PreparedStatementConditionBuilder(); | |
b35f63d6 | 96 | $conditions->add("userID IN (?)", [$this->objectIDs]); |
11ade432 AE |
97 | |
98 | $sql = "SELECT DISTINCT groupID | |
99 | FROM wcf".WCF_N."_user_to_group | |
100 | ".$conditions; | |
101 | $statement = WCF::getDB()->prepareStatement($sql); | |
102 | $statement->execute($conditions->getParameters()); | |
cd975610 | 103 | $groupIDs = $statement->fetchAll(\PDO::FETCH_COLUMN); |
11ade432 AE |
104 | |
105 | if (!UserGroup::isAccessibleGroup($groupIDs)) { | |
3631f7bd | 106 | throw new PermissionDeniedException(); |
11ade432 AE |
107 | } |
108 | } | |
109 | ||
11cf19be MW |
110 | /** |
111 | * Validates permissions and parameters. | |
112 | */ | |
113 | public function validateDelete() { | |
114 | // read and validate user objects | |
115 | parent::validateDelete(); | |
116 | ||
117 | $this->__validateAccessibleGroups(); | |
118 | } | |
119 | ||
0dd6ea0c | 120 | /** |
b35f63d6 | 121 | * @inheritDoc |
0dd6ea0c MW |
122 | */ |
123 | public function delete() { | |
124 | if (empty($this->objects)) { | |
125 | $this->readObjects(); | |
126 | } | |
127 | ||
128 | // delete avatars | |
b35f63d6 | 129 | $avatarIDs = []; |
4a130a51 | 130 | foreach ($this->getObjects() as $user) { |
0dd6ea0c MW |
131 | if ($user->avatarID) $avatarIDs[] = $user->avatarID; |
132 | } | |
133 | if (!empty($avatarIDs)) { | |
134 | $action = new UserAvatarAction($avatarIDs, 'delete'); | |
135 | $action->executeAction(); | |
136 | } | |
137 | ||
b0dc9618 | 138 | // delete profile comments and signature attachments |
0dd6ea0c | 139 | if (!empty($this->objectIDs)) { |
97247661 | 140 | CommentHandler::getInstance()->deleteObjects('com.woltlab.wcf.user.profileComment', $this->objectIDs); |
b0dc9618 | 141 | AttachmentHandler::removeAttachments('com.woltlab.wcf.user.signature', $this->objectIDs); |
0dd6ea0c MW |
142 | } |
143 | ||
241627da | 144 | return parent::delete(); |
0dd6ea0c MW |
145 | } |
146 | ||
11ade432 AE |
147 | /** |
148 | * Validates permissions and parameters. | |
11ade432 AE |
149 | */ |
150 | public function validateUpdate() { | |
a79cfb56 | 151 | // read objects |
15fa2802 | 152 | if (empty($this->objects)) { |
a79cfb56 | 153 | $this->readObjects(); |
15fa2802 MS |
154 | |
155 | if (empty($this->objects)) { | |
3631f7bd | 156 | throw new UserInputException('objectIDs'); |
15fa2802 | 157 | } |
a79cfb56 | 158 | } |
11ade432 | 159 | |
bae8dd1e AE |
160 | // disallow updating of anything except for options outside of ACP |
161 | if (RequestHandler::getInstance()->isACPRequest() && (count($this->parameters) != 1 || !isset($this->parameters['options']))) { | |
162 | throw new PermissionDeniedException(); | |
163 | } | |
164 | ||
a79cfb56 AE |
165 | try { |
166 | WCF::getSession()->checkPermissions($this->permissionsUpdate); | |
167 | } | |
168 | catch (PermissionDeniedException $e) { | |
169 | // check if we're editing ourselves | |
170 | if (count($this->objects) == 1 && ($this->objects[0]->userID == WCF::getUser()->userID)) { | |
67ca3261 AE |
171 | $count = count($this->parameters); |
172 | if ($count > 1 || ($count == 1 && !isset($this->parameters['options']))) { | |
3631f7bd | 173 | throw new PermissionDeniedException(); |
a79cfb56 AE |
174 | } |
175 | } | |
85f591f6 AE |
176 | else { |
177 | throw new PermissionDeniedException(); | |
178 | } | |
a79cfb56 | 179 | } |
11ade432 AE |
180 | } |
181 | ||
11cf19be MW |
182 | /** |
183 | * Validates the ban action. | |
184 | */ | |
185 | public function validateBan() { | |
f034d0ec | 186 | $this->validateUnban(); |
11cf19be | 187 | |
f034d0ec MS |
188 | $this->readString('banReason', true); |
189 | $this->readString('banExpires', true); | |
11cf19be MW |
190 | } |
191 | ||
192 | /** | |
193 | * Validates the unban action. | |
194 | */ | |
195 | public function validateUnban() { | |
b35f63d6 | 196 | WCF::getSession()->checkPermissions(['admin.user.canBanUser']); |
f034d0ec MS |
197 | |
198 | $this->__validateAccessibleGroups(); | |
11cf19be MW |
199 | } |
200 | ||
201 | /** | |
202 | * Bans users. | |
203 | */ | |
204 | public function ban() { | |
f034d0ec MS |
205 | $banExpires = $this->parameters['banExpires']; |
206 | if ($banExpires) { | |
207 | $banExpires = strtotime($banExpires); | |
a5888364 | 208 | if ($banExpires > 2147483647) $banExpires = 2147483647; |
f034d0ec MS |
209 | } |
210 | else { | |
211 | $banExpires = 0; | |
212 | } | |
213 | ||
11cf19be | 214 | $conditionBuilder = new PreparedStatementConditionBuilder(); |
b35f63d6 | 215 | $conditionBuilder->add('userID IN (?)', [$this->objectIDs]); |
f034d0ec | 216 | |
11cf19be MW |
217 | $sql = "UPDATE wcf".WCF_N."_user |
218 | SET banned = ?, | |
f034d0ec MS |
219 | banReason = ?, |
220 | banExpires = ? | |
11cf19be MW |
221 | ".$conditionBuilder; |
222 | $statement = WCF::getDB()->prepareStatement($sql); | |
223 | $statement->execute( | |
b35f63d6 | 224 | array_merge([ |
f034d0ec MS |
225 | 1, |
226 | $this->parameters['banReason'], | |
227 | $banExpires | |
b35f63d6 | 228 | ], $conditionBuilder->getParameters()) |
11cf19be | 229 | ); |
bbef7ed8 MW |
230 | |
231 | $this->unmarkItems(); | |
17bf3ee5 MW |
232 | |
233 | $firstUser = new User(reset($this->objectIDs)); | |
234 | return WCF::getLanguage()->getDynamicVariable('wcf.user.banned', ['user' => $firstUser]); | |
11cf19be MW |
235 | } |
236 | ||
237 | /** | |
238 | * Unbans users. | |
239 | */ | |
240 | public function unban() { | |
241 | $conditionBuilder = new PreparedStatementConditionBuilder(); | |
b35f63d6 | 242 | $conditionBuilder->add('userID IN (?)', [$this->objectIDs]); |
f034d0ec | 243 | |
11cf19be | 244 | $sql = "UPDATE wcf".WCF_N."_user |
f034d0ec MS |
245 | SET banned = ?, |
246 | banExpires = ? | |
11cf19be MW |
247 | ".$conditionBuilder; |
248 | $statement = WCF::getDB()->prepareStatement($sql); | |
f034d0ec | 249 | $statement->execute( |
b35f63d6 | 250 | array_merge([ |
f034d0ec MS |
251 | 0, |
252 | 0 | |
b35f63d6 | 253 | ], $conditionBuilder->getParameters()) |
f034d0ec | 254 | ); |
11cf19be MW |
255 | } |
256 | ||
11ade432 | 257 | /** |
0e8867ac | 258 | * @inheritDoc |
11ade432 AE |
259 | * @return User |
260 | */ | |
261 | public function create() { | |
0e8867ac | 262 | /** @var User $user */ |
11ade432 AE |
263 | $user = parent::create(); |
264 | $userEditor = new UserEditor($user); | |
265 | ||
266 | // updates user options | |
267 | if (isset($this->parameters['options'])) { | |
268 | $userEditor->updateUserOptions($this->parameters['options']); | |
269 | } | |
270 | ||
271 | // insert user groups | |
63b9817b MS |
272 | $addDefaultGroups = isset($this->parameters['addDefaultGroups']) ? $this->parameters['addDefaultGroups'] : true; |
273 | $groupIDs = isset($this->parameters['groups']) ? $this->parameters['groups'] : []; | |
2bb10466 | 274 | $userEditor->addToGroups($groupIDs, false, $addDefaultGroups); |
11ade432 AE |
275 | |
276 | // insert visible languages | |
7623b12f AE |
277 | if (!isset($this->parameters['languageIDs'])) { |
278 | // using the 'languages' key is deprecated since WCF 2.1, please use 'languageIDs' instead | |
b35f63d6 | 279 | $this->parameters['languageIDs'] = (!empty($this->parameters['languages'])) ? $this->parameters['languages'] : []; |
7623b12f AE |
280 | } |
281 | $userEditor->addToLanguages($this->parameters['languageIDs'], false); | |
11ade432 | 282 | |
320f4a6d MW |
283 | if (PACKAGE_ID) { |
284 | // set default notifications | |
285 | $sql = "INSERT INTO wcf".WCF_N."_user_notification_event_to_user | |
0ceb9e95 MW |
286 | (userID, eventID, mailNotificationType) |
287 | SELECT ?, eventID, presetMailNotificationType | |
695780d7 MW |
288 | FROM wcf".WCF_N."_user_notification_event |
289 | WHERE preset = ?"; | |
320f4a6d | 290 | $statement = WCF::getDB()->prepareStatement($sql); |
b35f63d6 | 291 | $statement->execute([$user->userID, 1]); |
c9d91afc MW |
292 | |
293 | // update user rank | |
294 | if (MODULE_USER_RANK) { | |
b35f63d6 | 295 | $action = new UserProfileAction([$userEditor], 'updateUserRank'); |
c9d91afc MW |
296 | $action->executeAction(); |
297 | } | |
298 | // update user online marking | |
b35f63d6 | 299 | $action = new UserProfileAction([$userEditor], 'updateUserOnlineMarking'); |
c9d91afc | 300 | $action->executeAction(); |
320f4a6d MW |
301 | } |
302 | ||
11ade432 AE |
303 | return $user; |
304 | } | |
835fa8c2 AE |
305 | |
306 | /** | |
b35f63d6 | 307 | * @inheritDoc |
835fa8c2 AE |
308 | */ |
309 | public function update() { | |
de7f211d | 310 | if (isset($this->parameters['data']) || isset($this->parameters['counters'])) { |
881246d6 | 311 | parent::update(); |
8a3258f5 MS |
312 | |
313 | if (isset($this->parameters['data']['languageID'])) { | |
4a130a51 | 314 | foreach ($this->getObjects() as $object) { |
8a3258f5 MS |
315 | if ($object->userID == WCF::getUser()->userID) { |
316 | if ($this->parameters['data']['languageID'] != WCF::getUser()->languageID) { | |
317 | WCF::setLanguage($this->parameters['data']['languageID']); | |
318 | } | |
319 | ||
320 | break; | |
321 | } | |
322 | } | |
323 | } | |
881246d6 AE |
324 | } |
325 | else { | |
15fa2802 | 326 | if (empty($this->objects)) { |
881246d6 AE |
327 | $this->readObjects(); |
328 | } | |
329 | } | |
835fa8c2 | 330 | |
63b9817b MS |
331 | $groupIDs = isset($this->parameters['groups']) ? $this->parameters['groups'] : []; |
332 | $languageIDs = isset($this->parameters['languageIDs']) ? $this->parameters['languageIDs'] : []; | |
333 | $removeGroups = isset($this->parameters['removeGroups']) ? $this->parameters['removeGroups'] : []; | |
334 | $userOptions = isset($this->parameters['options']) ? $this->parameters['options'] : []; | |
835fa8c2 | 335 | |
c2000c5d | 336 | if (!empty($groupIDs)) { |
b35f63d6 | 337 | $action = new UserAction($this->objects, 'addToGroups', [ |
12f80a9d MW |
338 | 'groups' => $groupIDs, |
339 | 'addDefaultGroups' => false | |
b35f63d6 | 340 | ]); |
c2000c5d MW |
341 | $action->executeAction(); |
342 | } | |
343 | ||
cc27b414 | 344 | if (!empty($removeGroups)) { |
b35f63d6 | 345 | $action = new UserAction($this->objects, 'removeFromGroups', [ |
3ffea5e3 | 346 | 'groups' => $removeGroups |
b35f63d6 | 347 | ]); |
cc27b414 JR |
348 | $action->executeAction(); |
349 | } | |
350 | ||
4a130a51 | 351 | foreach ($this->getObjects() as $userEditor) { |
f277d540 AE |
352 | if (!empty($userOptions)) { |
353 | $userEditor->updateUserOptions($userOptions); | |
354 | } | |
44adccf6 AE |
355 | |
356 | if (!empty($languageIDs)) { | |
357 | $userEditor->addToLanguages($languageIDs); | |
358 | } | |
835fa8c2 | 359 | } |
83f2404b AE |
360 | |
361 | // handle user rename | |
362 | if (count($this->objects) == 1 && !empty($this->parameters['data']['username'])) { | |
363 | if ($this->objects[0]->username != $this->parameters['data']['username']) { | |
364 | $userID = $this->objects[0]->userID; | |
365 | $username = $this->parameters['data']['username']; | |
366 | ||
367 | WCF::getDB()->beginTransaction(); | |
368 | ||
e06bab73 MW |
369 | // update article |
370 | $sql = "UPDATE wcf".WCF_N."_article | |
371 | SET username = ? | |
372 | WHERE userID = ?"; | |
373 | $statement = WCF::getDB()->prepareStatement($sql); | |
374 | $statement->execute([$username, $userID]); | |
375 | ||
83f2404b AE |
376 | // update comments |
377 | $sql = "UPDATE wcf".WCF_N."_comment | |
378 | SET username = ? | |
379 | WHERE userID = ?"; | |
380 | $statement = WCF::getDB()->prepareStatement($sql); | |
b35f63d6 | 381 | $statement->execute([$username, $userID]); |
83f2404b | 382 | |
b35f63d6 | 383 | // update comment responses |
83f2404b AE |
384 | $sql = "UPDATE wcf".WCF_N."_comment_response |
385 | SET username = ? | |
386 | WHERE userID = ?"; | |
387 | $statement = WCF::getDB()->prepareStatement($sql); | |
b35f63d6 | 388 | $statement->execute([$username, $userID]); |
83f2404b | 389 | |
b35f63d6 MS |
390 | // update media |
391 | $sql = "UPDATE wcf".WCF_N."_media | |
392 | SET username = ? | |
393 | WHERE userID = ?"; | |
394 | $statement = WCF::getDB()->prepareStatement($sql); | |
395 | $statement->execute([$username, $userID]); | |
396 | ||
397 | // update modification log | |
83f2404b AE |
398 | $sql = "UPDATE wcf".WCF_N."_modification_log |
399 | SET username = ? | |
400 | WHERE userID = ?"; | |
401 | $statement = WCF::getDB()->prepareStatement($sql); | |
b35f63d6 | 402 | $statement->execute([$username, $userID]); |
83f2404b AE |
403 | |
404 | WCF::getDB()->commitTransaction(); | |
405 | ||
406 | // fire event to handle other database tables | |
407 | EventHandler::getInstance()->fireAction($this, 'rename'); | |
408 | } | |
409 | } | |
835fa8c2 | 410 | } |
d5cab442 | 411 | |
fe6d199c | 412 | /** |
cc27b414 | 413 | * Remove users from given groups. |
fe6d199c JR |
414 | */ |
415 | public function removeFromGroups() { | |
416 | if (empty($this->objects)) { | |
417 | $this->readObjects(); | |
418 | } | |
419 | ||
420 | $groupIDs = $this->parameters['groups']; | |
421 | ||
4a130a51 | 422 | foreach ($this->getObjects() as $userEditor) { |
fe6d199c JR |
423 | $userEditor->removeFromGroups($groupIDs); |
424 | } | |
425 | ||
426 | //reread objects | |
b35f63d6 | 427 | $this->objects = []; |
fe6d199c JR |
428 | UserEditor::resetCache(); |
429 | $this->readObjects(); | |
430 | ||
431 | if (MODULE_USER_RANK) { | |
432 | $action = new UserProfileAction($this->objects, 'updateUserRank'); | |
433 | $action->executeAction(); | |
434 | } | |
435 | if (MODULE_USERS_ONLINE) { | |
436 | $action = new UserProfileAction($this->objects, 'updateUserOnlineMarking'); | |
437 | $action->executeAction(); | |
438 | } | |
439 | } | |
440 | ||
0dd6ea0c MW |
441 | /** |
442 | * Add users to given groups. | |
443 | */ | |
c2000c5d MW |
444 | public function addToGroups() { |
445 | if (empty($this->objects)) { | |
446 | $this->readObjects(); | |
447 | } | |
448 | ||
449 | $groupIDs = $this->parameters['groups']; | |
450 | $deleteOldGroups = $addDefaultGroups = true; | |
451 | if (isset($this->parameters['deleteOldGroups'])) $deleteOldGroups = $this->parameters['deleteOldGroups']; | |
452 | if (isset($this->parameters['addDefaultGroups'])) $addDefaultGroups = $this->parameters['addDefaultGroups']; | |
453 | ||
4a130a51 | 454 | foreach ($this->getObjects() as $userEditor) { |
c2000c5d MW |
455 | $userEditor->addToGroups($groupIDs, $deleteOldGroups, $addDefaultGroups); |
456 | } | |
320f4a6d | 457 | |
6374f974 | 458 | //reread objects |
b35f63d6 | 459 | $this->objects = []; |
6374f974 JR |
460 | UserEditor::resetCache(); |
461 | $this->readObjects(); | |
462 | ||
320f4a6d MW |
463 | if (MODULE_USER_RANK) { |
464 | $action = new UserProfileAction($this->objects, 'updateUserRank'); | |
465 | $action->executeAction(); | |
466 | } | |
467 | if (MODULE_USERS_ONLINE) { | |
468 | $action = new UserProfileAction($this->objects, 'updateUserOnlineMarking'); | |
469 | $action->executeAction(); | |
470 | } | |
c2000c5d MW |
471 | } |
472 | ||
a7fd745e | 473 | /** |
b35f63d6 | 474 | * @inheritDoc |
a7fd745e | 475 | */ |
a427a8c8 | 476 | public function validateGetSearchResultList() { |
a54f8d8f AE |
477 | $this->readBoolean('includeUserGroups', false, 'data'); |
478 | $this->readString('searchString', false, 'data'); | |
a7fd745e AE |
479 | |
480 | if (isset($this->parameters['data']['excludedSearchValues']) && !is_array($this->parameters['data']['excludedSearchValues'])) { | |
3631f7bd | 481 | throw new UserInputException('excludedSearchValues'); |
a7fd745e | 482 | } |
d5cab442 AE |
483 | } |
484 | ||
a7fd745e | 485 | /** |
b35f63d6 | 486 | * @inheritDoc |
a7fd745e | 487 | */ |
a427a8c8 | 488 | public function getSearchResultList() { |
d5cab442 | 489 | $searchString = $this->parameters['data']['searchString']; |
b35f63d6 | 490 | $excludedSearchValues = []; |
c000b08a MS |
491 | if (isset($this->parameters['data']['excludedSearchValues'])) { |
492 | $excludedSearchValues = $this->parameters['data']['excludedSearchValues']; | |
493 | } | |
b35f63d6 | 494 | $list = []; |
9f959ced | 495 | |
d5cab442 AE |
496 | if ($this->parameters['data']['includeUserGroups']) { |
497 | $accessibleGroups = UserGroup::getAccessibleGroups(); | |
498 | foreach ($accessibleGroups as $group) { | |
18c05238 | 499 | $groupName = $group->getName(); |
c000b08a | 500 | if (!in_array($groupName, $excludedSearchValues)) { |
838e315b | 501 | $pos = mb_strripos($groupName, $searchString); |
c000b08a | 502 | if ($pos !== false && $pos == 0) { |
b35f63d6 | 503 | $list[] = [ |
c000b08a MS |
504 | 'label' => $groupName, |
505 | 'objectID' => $group->groupID, | |
506 | 'type' => 'group' | |
b35f63d6 | 507 | ]; |
c000b08a | 508 | } |
d5cab442 AE |
509 | } |
510 | } | |
511 | } | |
c000b08a | 512 | |
c2d0b2d6 | 513 | // find users |
1f92bb4a MW |
514 | $searchString = addcslashes($searchString, '_%'); |
515 | $parameters = [ | |
516 | 'searchString' => $searchString | |
517 | ]; | |
518 | EventHandler::getInstance()->fireAction($this, 'beforeFindUsers', $parameters); | |
c2d0b2d6 | 519 | $userProfileList = new UserProfileList(); |
1f92bb4a | 520 | $userProfileList->getConditionBuilder()->add("username LIKE ?", [$parameters['searchString'].'%']); |
15fa2802 | 521 | if (!empty($excludedSearchValues)) { |
b35f63d6 | 522 | $userProfileList->getConditionBuilder()->add("username NOT IN (?)", [$excludedSearchValues]); |
c000b08a | 523 | } |
c2d0b2d6 MS |
524 | $userProfileList->sqlLimit = 10; |
525 | $userProfileList->readObjects(); | |
9f959ced | 526 | |
c2d0b2d6 | 527 | foreach ($userProfileList as $userProfile) { |
b35f63d6 | 528 | $list[] = [ |
c2d0b2d6 MS |
529 | 'icon' => $userProfile->getAvatar()->getImageTag(16), |
530 | 'label' => $userProfile->username, | |
531 | 'objectID' => $userProfile->userID, | |
d5cab442 | 532 | 'type' => 'user' |
b35f63d6 | 533 | ]; |
d5cab442 | 534 | } |
9f959ced | 535 | |
d5cab442 AE |
536 | return $list; |
537 | } | |
49c164a8 AE |
538 | |
539 | /** | |
b35f63d6 | 540 | * @inheritDoc |
49c164a8 | 541 | */ |
fbb077d4 MS |
542 | public function validateUnmarkAll() { |
543 | // does nothing | |
544 | } | |
49c164a8 AE |
545 | |
546 | /** | |
b35f63d6 | 547 | * @inheritDoc |
49c164a8 AE |
548 | */ |
549 | public function unmarkAll() { | |
550 | ClipboardHandler::getInstance()->removeItems(ClipboardHandler::getInstance()->getObjectTypeID('com.woltlab.wcf.user')); | |
551 | } | |
bbef7ed8 MW |
552 | |
553 | /** | |
554 | * Unmarks users. | |
59dc0db6 | 555 | * |
b35f63d6 | 556 | * @param integer[] $userIDs |
bbef7ed8 | 557 | */ |
b35f63d6 | 558 | protected function unmarkItems(array $userIDs = []) { |
bbef7ed8 MW |
559 | if (empty($userIDs)) { |
560 | $userIDs = $this->objectIDs; | |
561 | } | |
e3369fd2 | 562 | |
bbef7ed8 MW |
563 | if (!empty($userIDs)) { |
564 | ClipboardHandler::getInstance()->unmark($userIDs, ClipboardHandler::getInstance()->getObjectTypeID('com.woltlab.wcf.user')); | |
565 | } | |
566 | } | |
2fe45e04 MW |
567 | |
568 | /** | |
569 | * Validates the enable action. | |
570 | */ | |
571 | public function validateEnable() { | |
b35f63d6 | 572 | WCF::getSession()->checkPermissions(['admin.user.canEnableUser']); |
9927f711 MS |
573 | |
574 | $this->__validateAccessibleGroups(); | |
2fe45e04 MW |
575 | } |
576 | ||
577 | /** | |
578 | * Validates the disable action. | |
579 | */ | |
580 | public function validateDisable() { | |
581 | $this->validateEnable(); | |
582 | } | |
583 | ||
584 | /** | |
585 | * Enables users. | |
586 | */ | |
587 | public function enable() { | |
588 | if (empty($this->objects)) $this->readObjects(); | |
9927f711 | 589 | |
b35f63d6 MS |
590 | $action = new UserAction($this->objects, 'update', [ |
591 | 'data' => [ | |
2fe45e04 | 592 | 'activationCode' => 0 |
b35f63d6 MS |
593 | ], |
594 | 'removeGroups' => UserGroup::getGroupIDsByType([UserGroup::GUESTS]) | |
595 | ]); | |
2fe45e04 | 596 | $action->executeAction(); |
b35f63d6 MS |
597 | $action = new UserAction($this->objects, 'addToGroups', [ |
598 | 'groups' => UserGroup::getGroupIDsByType([UserGroup::USERS]), | |
2818981f | 599 | 'deleteOldGroups' => false, |
9927f711 | 600 | 'addDefaultGroups' => false |
b35f63d6 | 601 | ]); |
2fe45e04 | 602 | $action->executeAction(); |
00ce5cf8 | 603 | |
11dccf1c | 604 | // send e-mail notification |
723b4553 | 605 | if (empty($this->parameters['skipNotification'])) { |
4a130a51 | 606 | foreach ($this->getObjects() as $user) { |
bde0e3dc TD |
607 | $email = new Email(); |
608 | $email->addRecipient(new UserMailbox($user->getDecoratedObject())); | |
609 | $email->setSubject($user->getLanguage()->getDynamicVariable('wcf.acp.user.activation.mail.subject')); | |
610 | $email->setBody(new MimePartFacade([ | |
611 | new RecipientAwareTextMimePart('text/html', 'email_adminActivation'), | |
612 | new RecipientAwareTextMimePart('text/plain', 'email_adminActivation') | |
b35f63d6 | 613 | ])); |
bde0e3dc | 614 | $email->send(); |
11dccf1c MW |
615 | } |
616 | } | |
617 | ||
00ce5cf8 | 618 | $this->unmarkItems(); |
2fe45e04 MW |
619 | } |
620 | ||
621 | /** | |
622 | * Disables users. | |
623 | */ | |
624 | public function disable() { | |
625 | if (empty($this->objects)) $this->readObjects(); | |
9927f711 | 626 | |
b35f63d6 MS |
627 | $action = new UserAction($this->objects, 'update', [ |
628 | 'data' => [ | |
2fe45e04 | 629 | 'activationCode' => UserRegistrationUtil::getActivationCode() |
b35f63d6 | 630 | ], |
3728a6bd | 631 | 'removeGroups' => UserGroup::getGroupIDsByType([UserGroup::USERS]) |
b35f63d6 | 632 | ]); |
2fe45e04 | 633 | $action->executeAction(); |
b35f63d6 MS |
634 | $action = new UserAction($this->objects, 'addToGroups', [ |
635 | 'groups' => UserGroup::getGroupIDsByType([UserGroup::GUESTS]), | |
2818981f MW |
636 | 'deleteOldGroups' => false, |
637 | 'addDefaultGroups' => false | |
b35f63d6 | 638 | ]); |
2fe45e04 | 639 | $action->executeAction(); |
00ce5cf8 AE |
640 | |
641 | $this->unmarkItems(); | |
2fe45e04 | 642 | } |
2ce24640 MW |
643 | |
644 | /** | |
b35f63d6 | 645 | * @inheritDoc |
2ce24640 MW |
646 | */ |
647 | protected function readObjects() { | |
648 | if (empty($this->objectIDs)) { | |
649 | return; | |
650 | } | |
57f097e8 | 651 | |
2ce24640 | 652 | // get base class |
b35f63d6 | 653 | $baseClass = call_user_func([$this->className, 'getBaseClass']); |
57f097e8 | 654 | |
2ce24640 MW |
655 | // get objects |
656 | $sql = "SELECT user_option_value.*, user_table.* | |
657 | FROM wcf".WCF_N."_user user_table | |
658 | LEFT JOIN wcf".WCF_N."_user_option_value user_option_value | |
659 | ON (user_option_value.userID = user_table.userID) | |
660 | WHERE user_table.userID IN (".str_repeat('?,', count($this->objectIDs) - 1)."?)"; | |
661 | $statement = WCF::getDB()->prepareStatement($sql); | |
662 | $statement->execute($this->objectIDs); | |
663 | while ($object = $statement->fetchObject($baseClass)) { | |
664 | $this->objects[] = new $this->className($object); | |
665 | } | |
666 | } | |
57f097e8 MS |
667 | |
668 | /** | |
669 | * Validates the 'disableSignature' action. | |
670 | */ | |
671 | public function validateDisableSignature() { | |
3696fe93 | 672 | $this->validateEnableSignature(); |
57f097e8 MS |
673 | |
674 | $this->readString('disableSignatureReason', true); | |
f034d0ec | 675 | $this->readString('disableSignatureExpires', true); |
57f097e8 MS |
676 | } |
677 | ||
678 | /** | |
679 | * Disables the signature of the handled users. | |
680 | */ | |
681 | public function disableSignature() { | |
682 | if (empty($this->objects)) { | |
683 | $this->readObjects(); | |
684 | } | |
685 | ||
f034d0ec MS |
686 | $disableSignatureExpires = $this->parameters['disableSignatureExpires']; |
687 | if ($disableSignatureExpires) { | |
688 | $disableSignatureExpires = strtotime($disableSignatureExpires); | |
689 | } | |
690 | else { | |
691 | $disableSignatureExpires = 0; | |
692 | } | |
693 | ||
4a130a51 | 694 | foreach ($this->getObjects() as $userEditor) { |
b35f63d6 | 695 | $userEditor->update([ |
57f097e8 | 696 | 'disableSignature' => 1, |
f034d0ec MS |
697 | 'disableSignatureReason' => $this->parameters['disableSignatureReason'], |
698 | 'disableSignatureExpires' => $disableSignatureExpires | |
b35f63d6 | 699 | ]); |
57f097e8 MS |
700 | } |
701 | } | |
702 | ||
703 | /** | |
704 | * Validates the 'enableSignature' action. | |
705 | */ | |
706 | public function validateEnableSignature() { | |
b35f63d6 | 707 | WCF::getSession()->checkPermissions(['admin.user.canDisableSignature']); |
57f097e8 MS |
708 | |
709 | $this->__validateAccessibleGroups(); | |
710 | ||
711 | if (empty($this->objects)) { | |
712 | $this->readObjects(); | |
713 | ||
714 | if (empty($this->objects)) { | |
715 | throw new UserInputException('objectIDs'); | |
716 | } | |
717 | } | |
718 | } | |
719 | ||
720 | /** | |
721 | * Enables the signature of the handled users. | |
722 | */ | |
723 | public function enableSignature() { | |
724 | if (empty($this->objects)) { | |
725 | $this->readObjects(); | |
726 | } | |
727 | ||
4a130a51 | 728 | foreach ($this->getObjects() as $userEditor) { |
b35f63d6 | 729 | $userEditor->update([ |
57f097e8 | 730 | 'disableSignature' => 0 |
b35f63d6 | 731 | ]); |
57f097e8 MS |
732 | } |
733 | } | |
734 | ||
735 | /** | |
736 | * Validates the 'disableAvatar' action. | |
737 | */ | |
738 | public function validateDisableAvatar() { | |
3696fe93 | 739 | $this->validateEnableAvatar(); |
57f097e8 MS |
740 | |
741 | $this->readString('disableAvatarReason', true); | |
f034d0ec | 742 | $this->readString('disableAvatarExpires', true); |
57f097e8 MS |
743 | } |
744 | ||
745 | /** | |
746 | * Disables the avatar of the handled users. | |
747 | */ | |
748 | public function disableAvatar() { | |
749 | if (empty($this->objects)) { | |
750 | $this->readObjects(); | |
751 | } | |
1a6e8c52 | 752 | |
f034d0ec MS |
753 | $disableAvatarExpires = $this->parameters['disableAvatarExpires']; |
754 | if ($disableAvatarExpires) { | |
755 | $disableAvatarExpires = strtotime($disableAvatarExpires); | |
756 | } | |
757 | else { | |
758 | $disableAvatarExpires = 0; | |
759 | } | |
57f097e8 | 760 | |
4a130a51 | 761 | foreach ($this->getObjects() as $userEditor) { |
b35f63d6 | 762 | $userEditor->update([ |
57f097e8 | 763 | 'disableAvatar' => 1, |
f034d0ec MS |
764 | 'disableAvatarReason' => $this->parameters['disableAvatarReason'], |
765 | 'disableAvatarExpires' => $disableAvatarExpires | |
b35f63d6 | 766 | ]); |
57f097e8 MS |
767 | } |
768 | } | |
769 | ||
770 | /** | |
771 | * Validates the 'enableAvatar' action. | |
772 | */ | |
773 | public function validateEnableAvatar() { | |
b35f63d6 | 774 | WCF::getSession()->checkPermissions(['admin.user.canDisableAvatar']); |
57f097e8 MS |
775 | |
776 | $this->__validateAccessibleGroups(); | |
777 | ||
778 | if (empty($this->objects)) { | |
779 | $this->readObjects(); | |
780 | ||
781 | if (empty($this->objects)) { | |
782 | throw new UserInputException('objectIDs'); | |
783 | } | |
784 | } | |
785 | } | |
786 | ||
787 | /** | |
788 | * Enables the avatar of the handled users. | |
789 | */ | |
790 | public function enableAvatar() { | |
791 | if (empty($this->objects)) { | |
792 | $this->readObjects(); | |
793 | } | |
794 | ||
4a130a51 | 795 | foreach ($this->getObjects() as $userEditor) { |
b35f63d6 | 796 | $userEditor->update([ |
57f097e8 | 797 | 'disableAvatar' => 0 |
b35f63d6 | 798 | ]); |
57f097e8 MS |
799 | } |
800 | } | |
9ed42d00 AE |
801 | |
802 | /** | |
803 | * Validates parameters to retrieve the social network privacy settings. | |
527a8fc6 | 804 | * @deprecated 3.0 |
9ed42d00 | 805 | */ |
b35f63d6 MS |
806 | public function validateGetSocialNetworkPrivacySettings() { |
807 | // does nothing | |
808 | } | |
9ed42d00 AE |
809 | |
810 | /** | |
811 | * Returns the social network privacy settings. | |
527a8fc6 | 812 | * @deprecated 3.0 |
9ed42d00 AE |
813 | */ |
814 | public function getSocialNetworkPrivacySettings() { | |
527a8fc6 | 815 | // does nothing |
9ed42d00 AE |
816 | } |
817 | ||
b35f63d6 MS |
818 | /** |
819 | * Validates the 'saveSocialNetworkPrivacySettings' action. | |
527a8fc6 | 820 | * @deprecated 3.0 |
b35f63d6 | 821 | */ |
9ed42d00 | 822 | public function validateSaveSocialNetworkPrivacySettings() { |
527a8fc6 | 823 | // does nothing |
9ed42d00 AE |
824 | } |
825 | ||
b35f63d6 MS |
826 | /** |
827 | * Saves the social network privacy settings. | |
527a8fc6 | 828 | * @deprecated 3.0 |
b35f63d6 | 829 | */ |
9ed42d00 | 830 | public function saveSocialNetworkPrivacySettings() { |
527a8fc6 | 831 | // does nothing |
9ed42d00 | 832 | } |
11ade432 | 833 | } |