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