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