Merge branch next
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / data / user / UserAction.class.php
CommitLineData
11ade432
AE
1<?php
2namespace wcf\data\user;
0dd6ea0c 3use wcf\data\user\avatar\UserAvatarAction;
11ade432 4use wcf\data\user\group\UserGroup;
931f6597 5use wcf\data\AbstractDatabaseObjectAction;
7918ddba 6use wcf\data\IClipboardAction;
a427a8c8 7use wcf\data\ISearchAction;
b0dc9618 8use wcf\system\attachment\AttachmentHandler;
7f379ade 9use wcf\system\clipboard\ClipboardHandler;
97247661 10use wcf\system\comment\CommentHandler;
11ade432 11use wcf\system\database\util\PreparedStatementConditionBuilder;
bde0e3dc
TD
12use wcf\system\email\mime\MimePartFacade;
13use wcf\system\email\mime\RecipientAwareTextMimePart;
14use wcf\system\email\Email;
15use wcf\system\email\UserMailbox;
dd900ec4
AE
16use wcf\system\event\EventHandler;
17use wcf\system\exception\PermissionDeniedException;
18use wcf\system\exception\UserInputException;
bae8dd1e 19use wcf\system\request\RequestHandler;
2bc9f31d 20use wcf\system\WCF;
2fe45e04 21use 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 34class 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}