Fixed time zone calculation issue
[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 if (!empty($_POST['disableAvatar'])) $this->disableAvatar = 1;
126 if (isset($_POST['disableAvatarReason'])) $this->disableAvatarReason = StringUtil::trim($_POST['disableAvatarReason']);
127 }
128
129 /**
130 * @see \wcf\page\IPage::readData()
131 */
132 public function readData() {
133 if (empty($_POST)) {
134 // get visible languages
135 $this->readVisibleLanguages();
136
137 // default values
138 $this->readDefaultValues();
139 }
140
141 parent::readData();
142
143 // get avatar object
144 if ($this->avatarType == 'custom') {
145 $this->userAvatar = new UserAvatar($this->user->avatarID);
146 }
147 }
148
149 /**
150 * Gets the selected languages.
151 */
152 protected function readVisibleLanguages() {
153 $this->visibleLanguages = $this->user->getLanguageIDs();
154 }
155
156 /**
157 * Gets the default values.
158 */
159 protected function readDefaultValues() {
160 $this->username = $this->user->username;
161 $this->email = $this->confirmEmail = $this->user->email;
162 $this->groupIDs = $this->user->getGroupIDs(true);
163 $this->languageID = $this->user->languageID;
164 $this->banned = $this->user->banned;
165 $this->banReason = $this->user->banReason;
166 $this->userTitle = $this->user->userTitle;
167
168 $this->signature = $this->user->signature;
169 $this->signatureEnableBBCodes = $this->user->signatureEnableBBCodes;
170 $this->signatureEnableSmilies = $this->user->signatureEnableSmilies;
171 $this->signatureEnableHtml = $this->user->signatureEnableHtml;
172 $this->disableSignature = $this->user->disableSignature;
173 $this->disableSignatureReason = $this->user->disableSignatureReason;
174 $this->disableAvatar = $this->user->disableAvatar;
175 $this->disableAvatarReason = $this->user->disableAvatarReason;
176
177 if ($this->user->avatarID) $this->avatarType = 'custom';
178 else if (MODULE_GRAVATAR && $this->user->enableGravatar) $this->avatarType = 'gravatar';
179 }
180
181 /**
182 * @see \wcf\page\IPage::assignVariables()
183 */
184 public function assignVariables() {
185 parent::assignVariables();
186
187 WCF::getTPL()->assign(array(
188 'userID' => $this->user->userID,
189 'action' => 'edit',
190 'url' => '',
191 'markedUsers' => 0,
192 'user' => $this->user,
193 'banned' => $this->banned,
194 'banReason' => $this->banReason,
195 'avatarType' => $this->avatarType,
196 'disableAvatar' => $this->disableAvatar,
197 'disableAvatarReason' => $this->disableAvatarReason,
198 'userAvatar' => $this->userAvatar
199 ));
200 }
201
202 /**
203 * @see \wcf\form\IForm::save()
204 */
205 public function save() {
206 AbstractForm::save();
207
208 // handle avatar
209 if ($this->avatarType != 'custom') {
210 // delete custom avatar
211 if ($this->user->avatarID) {
212 $action = new UserAvatarAction(array($this->user->avatarID), 'delete');
213 $action->executeAction();
214 }
215 }
216 switch ($this->avatarType) {
217 case 'none':
218 $avatarData = array(
219 'avatarID' => null,
220 'enableGravatar' => 0
221 );
222 break;
223
224 case 'custom':
225 $avatarData = array(
226 'enableGravatar' => 0
227 );
228 break;
229
230 case 'gravatar':
231 $avatarData = array(
232 'avatarID' => null,
233 'enableGravatar' => 1
234 );
235 break;
236 }
237 $avatarData['disableAvatar'] = $this->disableAvatar;
238 $avatarData['disableAvatarReason'] = $this->disableAvatarReason;
239 $this->additionalFields = array_merge($this->additionalFields, $avatarData);
240
241 // add default groups
242 $defaultGroups = UserGroup::getAccessibleGroups(array(UserGroup::GUESTS, UserGroup::EVERYONE, UserGroup::USERS));
243 $oldGroupIDs = $this->user->getGroupIDs();
244 foreach ($oldGroupIDs as $oldGroupID) {
245 if (isset($defaultGroups[$oldGroupID])) {
246 $this->groupIDs[] = $oldGroupID;
247 }
248 }
249 $this->groupIDs = array_unique($this->groupIDs);
250
251 // save user
252 $saveOptions = $this->optionHandler->save();
253 $this->additionalFields['languageID'] = $this->languageID;
254 if (WCF::getSession()->getPermission('admin.user.canBanUser')) {
255 $this->additionalFields['banned'] = $this->banned;
256 $this->additionalFields['banReason'] = $this->banReason;
257 }
258 $data = array(
259 'data' => array_merge($this->additionalFields, array(
260 'username' => $this->username,
261 'email' => $this->email,
262 'password' => $this->password,
263 'banned' => $this->banned,
264 'banReason' => $this->banReason,
265 'userTitle' => $this->userTitle,
266 'signature' => $this->signature,
267 'signatureEnableBBCodes' => $this->signatureEnableBBCodes,
268 'signatureEnableSmilies' => $this->signatureEnableSmilies,
269 'signatureEnableHtml' => $this->signatureEnableHtml,
270 'disableSignature' => $this->disableSignature,
271 'disableSignatureReason' => $this->disableSignatureReason
272 )),
273 'groups' => $this->groupIDs,
274 'languageIDs' => $this->visibleLanguages,
275 'options' => $saveOptions
276 );
277 $this->objectAction = new UserAction(array($this->userID), 'update', $data);
278 $this->objectAction->executeAction();
279
280 // update user rank
281 $editor = new UserEditor(new User($this->userID));
282 if (MODULE_USER_RANK) {
283 $action = new UserProfileAction(array($editor), 'updateUserRank');
284 $action->executeAction();
285 }
286 if (MODULE_USERS_ONLINE) {
287 $action = new UserProfileAction(array($editor), 'updateUserOnlineMarking');
288 $action->executeAction();
289 }
290
291 // remove assignments
292 $sql = "DELETE FROM wcf".WCF_N."_moderation_queue_to_user
293 WHERE userID = ?";
294 $statement = WCF::getDB()->prepareStatement($sql);
295 $statement->execute(array($this->user->userID));
296
297 // reset moderation count
298 ModerationQueueManager::getInstance()->resetModerationCount($this->user->userID);
299 $this->saved();
300
301 // reset password
302 $this->password = $this->confirmPassword = '';
303
304 // show success message
305 WCF::getTPL()->assign('success', true);
306 }
307
308 /**
309 * @see \wcf\acp\form\UserAddForm::validateUsername()
310 */
311 protected function validateUsername($username) {
312 if (mb_strtolower($this->user->username) != mb_strtolower($username)) {
313 parent::validateUsername($username);
314 }
315 }
316
317 /**
318 * @see \wcf\acp\form\UserAddForm::validateEmail()
319 */
320 protected function validateEmail($email, $confirmEmail) {
321 if (mb_strtolower($this->user->email) != mb_strtolower($email)) {
322 parent::validateEmail($email, $this->confirmEmail);
323 }
324 }
325
326 /**
327 * @see \wcf\acp\form\UserAddForm::validatePassword()
328 */
329 protected function validatePassword($password, $confirmPassword) {
330 if (!empty($password) || !empty($confirmPassword)) {
331 parent::validatePassword($password, $confirmPassword);
332 }
333 }
334
335 /**
336 * Validates the user avatar.
337 */
338 protected function validateAvatar() {
339 if ($this->avatarType != 'custom' && $this->avatarType != 'gravatar') $this->avatarType = 'none';
340
341 try {
342 switch ($this->avatarType) {
343 case 'custom':
344 if (!$this->user->avatarID) {
345 throw new UserInputException('customAvatar');
346 }
347 break;
348
349 case 'gravatar':
350 if (!MODULE_GRAVATAR) {
351 $this->avatarType = 'none';
352 break;
353 }
354
355 // test gravatar
356 if (!Gravatar::test($this->user->email)) {
357 throw new UserInputException('gravatar', 'notFound');
358 }
359 }
360 }
361 catch (UserInputException $e) {
362 $this->errorType[$e->getField()] = $e->getType();
363 }
364 }
365
366 /**
367 * @see \wcf\form\IForm::validate()
368 */
369 public function validate() {
370 $this->validateAvatar();
371
372 parent::validate();
373 }
374 }