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; |
7f379ade | 8 | use wcf\system\clipboard\ClipboardHandler; |
97247661 | 9 | use wcf\system\comment\CommentHandler; |
11ade432 | 10 | use wcf\system\database\util\PreparedStatementConditionBuilder; |
781fe402 | 11 | use wcf\system\event\EventHandler; |
a79cfb56 | 12 | use wcf\system\exception\PermissionDeniedException; |
3631f7bd | 13 | use wcf\system\exception\UserInputException; |
11dccf1c | 14 | use wcf\system\mail\Mail; |
bae8dd1e | 15 | use wcf\system\request\RequestHandler; |
2bc9f31d | 16 | use wcf\system\WCF; |
2fe45e04 | 17 | use 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 | 29 | class 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 | } |