Merge branch '2.0'
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / acp / form / UserEditForm.class.php
1 <?php
2 namespace wcf\acp\form;
3 use wcf\data\user\avatar\Gravatar;
4 use wcf\data\user\avatar\UserAvatar;
5 use wcf\data\user\avatar\UserAvatarAction;
6 use wcf\data\user\group\UserGroup;
7 use wcf\data\user\User;
8 use wcf\data\user\UserAction;
9 use wcf\data\user\UserEditor;
10 use wcf\data\user\UserProfileAction;
11 use wcf\form\AbstractForm;
12 use wcf\system\exception\IllegalLinkException;
13 use wcf\system\exception\PermissionDeniedException;
14 use wcf\system\exception\UserInputException;
15 use wcf\system\moderation\queue\ModerationQueueManager;
16 use wcf\system\WCF;
17 use wcf\util\StringUtil;
18
19 /**
20 * Shows the user edit form.
21 *
22 * @author Marcel Werk
23 * @copyright 2001-2014 WoltLab GmbH
24 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
25 * @package com.woltlab.wcf
26 * @subpackage acp.form
27 * @category Community Framework
28 */
29 class UserEditForm extends UserAddForm {
30 /**
31 * @see \wcf\page\AbstractPage::$activeMenuItem
32 */
33 public $activeMenuItem = 'wcf.acp.menu.link.user.management';
34
35 /**
36 * @see \wcf\page\AbstractPage::$neededPermissions
37 */
38 public $neededPermissions = array('admin.user.canEditUser');
39
40 /**
41 * user id
42 * @var integer
43 */
44 public $userID = 0;
45
46 /**
47 * user editor object
48 * @var \wcf\data\user\UserEditor
49 */
50 public $user = null;
51
52 /**
53 * ban status
54 * @var boolean
55 */
56 public $banned = 0;
57
58 /**
59 * ban reason
60 * @var string
61 */
62 public $banReason = '';
63
64 /**
65 * user avatar object
66 * @var \wcf\data\user\avatar\UserAvatar
67 */
68 public $userAvatar = null;
69
70 /**
71 * avatar type
72 * @var string
73 */
74 public $avatarType = 'none';
75
76 /**
77 * true to disable this avatar
78 * @var boolean
79 */
80 public $disableAvatar = 0;
81
82 /**
83 * reason
84 * @var string
85 */
86 public $disableAvatarReason = '';
87
88 /**
89 * @see \wcf\page\IPage::readParameters()
90 */
91 public function readParameters() {
92 if (isset($_REQUEST['id'])) $this->userID = intval($_REQUEST['id']);
93 $user = new User($this->userID);
94 if (!$user->userID) {
95 throw new IllegalLinkException();
96 }
97
98 $this->user = new UserEditor($user);
99 if (!UserGroup::isAccessibleGroup($this->user->getGroupIDs())) {
100 throw new PermissionDeniedException();
101 }
102
103 parent::readParameters();
104 }
105
106 /**
107 * wcf\acp\form\AbstractOptionListForm::initOptionHandler()
108 */
109 protected function initOptionHandler() {
110 $this->optionHandler->setUser($this->user->getDecoratedObject());
111 }
112
113 /**
114 * @see \wcf\page\IPage::readFormParameters()
115 */
116 public function readFormParameters() {
117 parent::readFormParameters();
118
119 if (!WCF::getSession()->getPermission('admin.user.canEditPassword')) $this->password = $this->confirmPassword = '';
120 if (!WCF::getSession()->getPermission('admin.user.canEditMailAddress')) $this->email = $this->confirmEmail = $this->user->email;
121
122 if (!empty($_POST['banned'])) $this->banned = 1;
123 if (isset($_POST['banReason'])) $this->banReason = StringUtil::trim($_POST['banReason']);
124 if (isset($_POST['avatarType'])) $this->avatarType = $_POST['avatarType'];
125
126 if (WCF::getSession()->getPermission('admin.user.canDisableAvatar')) {
127 if (!empty($_POST['disableAvatar'])) $this->disableAvatar = 1;
128 if (isset($_POST['disableAvatarReason'])) $this->disableAvatarReason = StringUtil::trim($_POST['disableAvatarReason']);
129 }
130 }
131
132 /**
133 * @see \wcf\page\IPage::readData()
134 */
135 public function readData() {
136 if (empty($_POST)) {
137 // get visible languages
138 $this->readVisibleLanguages();
139
140 // default values
141 $this->readDefaultValues();
142 }
143
144 parent::readData();
145
146 // get avatar object
147 if ($this->avatarType == 'custom') {
148 $this->userAvatar = new UserAvatar($this->user->avatarID);
149 }
150 }
151
152 /**
153 * Gets the selected languages.
154 */
155 protected function readVisibleLanguages() {
156 $this->visibleLanguages = $this->user->getLanguageIDs();
157 }
158
159 /**
160 * Gets the default values.
161 */
162 protected function readDefaultValues() {
163 $this->username = $this->user->username;
164 $this->email = $this->confirmEmail = $this->user->email;
165 $this->groupIDs = $this->user->getGroupIDs(true);
166 $this->languageID = $this->user->languageID;
167 $this->banned = $this->user->banned;
168 $this->banReason = $this->user->banReason;
169 $this->userTitle = $this->user->userTitle;
170
171 $this->signature = $this->user->signature;
172 $this->signatureEnableBBCodes = $this->user->signatureEnableBBCodes;
173 $this->signatureEnableSmilies = $this->user->signatureEnableSmilies;
174 $this->signatureEnableHtml = $this->user->signatureEnableHtml;
175 $this->disableSignature = $this->user->disableSignature;
176 $this->disableSignatureReason = $this->user->disableSignatureReason;
177 $this->disableAvatar = $this->user->disableAvatar;
178 $this->disableAvatarReason = $this->user->disableAvatarReason;
179
180 if ($this->user->avatarID) $this->avatarType = 'custom';
181 else if (MODULE_GRAVATAR && $this->user->enableGravatar) $this->avatarType = 'gravatar';
182 }
183
184 /**
185 * @see \wcf\page\IPage::assignVariables()
186 */
187 public function assignVariables() {
188 parent::assignVariables();
189
190 WCF::getTPL()->assign(array(
191 'userID' => $this->user->userID,
192 'action' => 'edit',
193 'url' => '',
194 'markedUsers' => 0,
195 'user' => $this->user,
196 'banned' => $this->banned,
197 'banReason' => $this->banReason,
198 'avatarType' => $this->avatarType,
199 'disableAvatar' => $this->disableAvatar,
200 'disableAvatarReason' => $this->disableAvatarReason,
201 'userAvatar' => $this->userAvatar
202 ));
203 }
204
205 /**
206 * @see \wcf\form\IForm::save()
207 */
208 public function save() {
209 AbstractForm::save();
210
211 // handle avatar
212 if ($this->avatarType != 'custom') {
213 // delete custom avatar
214 if ($this->user->avatarID) {
215 $action = new UserAvatarAction(array($this->user->avatarID), 'delete');
216 $action->executeAction();
217 }
218 }
219 switch ($this->avatarType) {
220 case 'none':
221 $avatarData = array(
222 'avatarID' => null,
223 'enableGravatar' => 0
224 );
225 break;
226
227 case 'custom':
228 $avatarData = array(
229 'enableGravatar' => 0
230 );
231 break;
232
233 case 'gravatar':
234 $avatarData = array(
235 'avatarID' => null,
236 'enableGravatar' => 1
237 );
238 break;
239 }
240
241 if (WCF::getSession()->getPermission('admin.user.canDisableAvatar')) {
242 $avatarData['disableAvatar'] = $this->disableAvatar;
243 $avatarData['disableAvatarReason'] = $this->disableAvatarReason;
244 }
245
246 $this->additionalFields = array_merge($this->additionalFields, $avatarData);
247
248 // add default groups
249 $defaultGroups = UserGroup::getAccessibleGroups(array(UserGroup::GUESTS, UserGroup::EVERYONE, UserGroup::USERS));
250 $oldGroupIDs = $this->user->getGroupIDs();
251 foreach ($oldGroupIDs as $oldGroupID) {
252 if (isset($defaultGroups[$oldGroupID])) {
253 $this->groupIDs[] = $oldGroupID;
254 }
255 }
256 $this->groupIDs = array_unique($this->groupIDs);
257
258 // save user
259 $saveOptions = $this->optionHandler->save();
260 $this->additionalFields['languageID'] = $this->languageID;
261 if (WCF::getSession()->getPermission('admin.user.canBanUser')) {
262 $this->additionalFields['banned'] = $this->banned;
263 $this->additionalFields['banReason'] = $this->banReason;
264 }
265 $data = array(
266 'data' => array_merge($this->additionalFields, array(
267 'username' => $this->username,
268 'email' => $this->email,
269 'password' => $this->password,
270 'banned' => $this->banned,
271 'banReason' => $this->banReason,
272 'userTitle' => $this->userTitle,
273 'signature' => $this->signature,
274 'signatureEnableBBCodes' => $this->signatureEnableBBCodes,
275 'signatureEnableSmilies' => $this->signatureEnableSmilies,
276 'signatureEnableHtml' => $this->signatureEnableHtml
277 )),
278 'groups' => $this->groupIDs,
279 'languageIDs' => $this->visibleLanguages,
280 'options' => $saveOptions
281 );
282
283 if (WCF::getSession()->getPermission('admin.user.canDisableSignature')) {
284 $data['data']['disableSignature'] = $this->disableSignature;
285 $data['data']['disableSignatureReason'] = $this->disableSignatureReason;
286 }
287
288 $this->objectAction = new UserAction(array($this->userID), 'update', $data);
289 $this->objectAction->executeAction();
290
291 // update user rank
292 $editor = new UserEditor(new User($this->userID));
293 if (MODULE_USER_RANK) {
294 $action = new UserProfileAction(array($editor), 'updateUserRank');
295 $action->executeAction();
296 }
297 if (MODULE_USERS_ONLINE) {
298 $action = new UserProfileAction(array($editor), 'updateUserOnlineMarking');
299 $action->executeAction();
300 }
301
302 // remove assignments
303 $sql = "DELETE FROM wcf".WCF_N."_moderation_queue_to_user
304 WHERE userID = ?";
305 $statement = WCF::getDB()->prepareStatement($sql);
306 $statement->execute(array($this->user->userID));
307
308 // reset moderation count
309 ModerationQueueManager::getInstance()->resetModerationCount($this->user->userID);
310 $this->saved();
311
312 // reset password
313 $this->password = $this->confirmPassword = '';
314
315 // show success message
316 WCF::getTPL()->assign('success', true);
317 }
318
319 /**
320 * @see \wcf\acp\form\UserAddForm::validateUsername()
321 */
322 protected function validateUsername($username) {
323 if (mb_strtolower($this->user->username) != mb_strtolower($username)) {
324 parent::validateUsername($username);
325 }
326 }
327
328 /**
329 * @see \wcf\acp\form\UserAddForm::validateEmail()
330 */
331 protected function validateEmail($email, $confirmEmail) {
332 if (mb_strtolower($this->user->email) != mb_strtolower($email)) {
333 parent::validateEmail($email, $this->confirmEmail);
334 }
335 }
336
337 /**
338 * @see \wcf\acp\form\UserAddForm::validatePassword()
339 */
340 protected function validatePassword($password, $confirmPassword) {
341 if (!empty($password) || !empty($confirmPassword)) {
342 parent::validatePassword($password, $confirmPassword);
343 }
344 }
345
346 /**
347 * Validates the user avatar.
348 */
349 protected function validateAvatar() {
350 if ($this->avatarType != 'custom' && $this->avatarType != 'gravatar') $this->avatarType = 'none';
351
352 try {
353 switch ($this->avatarType) {
354 case 'custom':
355 if (!$this->user->avatarID) {
356 throw new UserInputException('customAvatar');
357 }
358 break;
359
360 case 'gravatar':
361 if (!MODULE_GRAVATAR) {
362 $this->avatarType = 'none';
363 break;
364 }
365
366 // test gravatar
367 if (!Gravatar::test($this->user->email)) {
368 throw new UserInputException('gravatar', 'notFound');
369 }
370 }
371 }
372 catch (UserInputException $e) {
373 $this->errorType[$e->getField()] = $e->getType();
374 }
375 }
376
377 /**
378 * @see \wcf\form\IForm::validate()
379 */
380 public function validate() {
381 $this->validateAvatar();
382
383 parent::validate();
384 }
385 }