Merge branch '2.0'
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / acp / form / UserAddForm.class.php
1 <?php
2 namespace wcf\acp\form;
3 use wcf\data\user\group\UserGroup;
4 use wcf\data\user\UserAction;
5 use wcf\form\AbstractForm;
6 use wcf\system\database\util\PreparedStatementConditionBuilder;
7 use wcf\system\exception\UserInputException;
8 use wcf\system\language\LanguageFactory;
9 use wcf\system\WCF;
10 use wcf\util\ArrayUtil;
11 use wcf\util\StringUtil;
12 use wcf\util\UserUtil;
13
14 /**
15 * Shows the user add form.
16 *
17 * @author Marcel Werk
18 * @copyright 2001-2014 WoltLab GmbH
19 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
20 * @package com.woltlab.wcf
21 * @subpackage acp.form
22 * @category Community Framework
23 */
24 class UserAddForm extends UserOptionListForm {
25 /**
26 * @see \wcf\page\AbstractPage::$activeMenuItem
27 */
28 public $activeMenuItem = 'wcf.acp.menu.link.user.add';
29
30 /**
31 * @see \wcf\page\AbstractPage::$neededPermissions
32 */
33 public $neededPermissions = array('admin.user.canAddUser');
34
35 /**
36 * username
37 * @var string
38 */
39 public $username = '';
40
41 /**
42 * email address
43 * @var string
44 */
45 public $email = '';
46
47 /**
48 * confirmed email address
49 * @var string
50 */
51 public $confirmEmail = '';
52
53 /**
54 * user password
55 * @var string
56 */
57 public $password = '';
58
59 /**
60 * confirmed user password
61 * @var string
62 */
63 public $confirmPassword = '';
64
65 /**
66 * user group ids
67 * @var array<integer>
68 */
69 public $groupIDs = array();
70
71 /**
72 * language id
73 * @var integer
74 */
75 public $languageID = 0;
76
77 /**
78 * visible languages
79 * @var array<integer>
80 */
81 public $visibleLanguages = array();
82
83 /**
84 * title of the user
85 * @var string
86 */
87 protected $userTitle = '';
88
89 /**
90 * signature text
91 * @var string
92 */
93 public $signature = '';
94
95 /**
96 * enables smilies
97 * @var boolean
98 */
99 public $signatureEnableSmilies = 1;
100
101 /**
102 * enables bbcodes
103 * @var boolean
104 */
105 public $signatureEnableBBCodes = 1;
106
107 /**
108 * enables html
109 * @var boolean
110 */
111 public $signatureEnableHtml = 0;
112
113 /**
114 * true to disable this signature
115 * @var boolean
116 */
117 public $disableSignature = 0;
118
119 /**
120 * reason
121 * @var string
122 */
123 public $disableSignatureReason = '';
124
125 /**
126 * date when the signature will be enabled again
127 * @var string
128 */
129 public $disableSignatureExpires = '';
130
131 /**
132 * @see \wcf\form\IForm::readFormParameters()
133 */
134 public function readFormParameters() {
135 parent::readFormParameters();
136
137 if (isset($_POST['username'])) $this->username = StringUtil::trim($_POST['username']);
138 if (isset($_POST['email'])) $this->email = StringUtil::trim($_POST['email']);
139 if (isset($_POST['confirmEmail'])) $this->confirmEmail = StringUtil::trim($_POST['confirmEmail']);
140 if (isset($_POST['password'])) $this->password = $_POST['password'];
141 if (isset($_POST['confirmPassword'])) $this->confirmPassword = $_POST['confirmPassword'];
142 if (isset($_POST['groupIDs']) && is_array($_POST['groupIDs'])) $this->groupIDs = ArrayUtil::toIntegerArray($_POST['groupIDs']);
143 if (isset($_POST['visibleLanguages']) && is_array($_POST['visibleLanguages'])) $this->visibleLanguages = ArrayUtil::toIntegerArray($_POST['visibleLanguages']);
144 if (isset($_POST['languageID'])) $this->languageID = intval($_POST['languageID']);
145 if (isset($_POST['userTitle'])) $this->userTitle = $_POST['userTitle'];
146
147 if (isset($_POST['signature'])) $this->signature = StringUtil::trim($_POST['signature']);
148
149 $this->signatureEnableBBCodes = $this->signatureEnableSmilies = 0;
150 if (!empty($_POST['signatureEnableBBCodes'])) $this->signatureEnableBBCodes = 1;
151 if (!empty($_POST['signatureEnableSmilies'])) $this->signatureEnableSmilies = 1;
152 if (!empty($_POST['signatureEnableHtml'])) $this->signatureEnableHtml = 1;
153
154 if (WCF::getSession()->getPermission('admin.user.canDisableSignature')) {
155 if (isset($_POST['disableSignatureReason'])) $this->disableSignatureReason = StringUtil::trim($_POST['disableSignatureReason']);
156 if (!empty($_POST['disableSignature'])) $this->disableSignature = 1;
157 if ($this->disableSignature && !isset($_POST['disableSignatureNeverExpires'])) {
158 if (isset($_POST['disableSignatureExpires'])) $this->disableSignatureExpires = StringUtil::trim($_POST['disableSignatureExpires']);
159 }
160 else {
161 $this->disableSignatureExpires = '';
162 }
163 }
164 }
165
166 /**
167 * @see \wcf\form\IForm::validate()
168 */
169 public function validate() {
170 // validate static user options
171 try {
172 $this->validateUsername($this->username);
173 }
174 catch (UserInputException $e) {
175 $this->errorType[$e->getField()] = $e->getType();
176 }
177
178 try {
179 $this->validateEmail($this->email, $this->confirmEmail);
180 }
181 catch (UserInputException $e) {
182 $this->errorType[$e->getField()] = $e->getType();
183 }
184
185 try {
186 $this->validatePassword($this->password, $this->confirmPassword);
187 }
188 catch (UserInputException $e) {
189 $this->errorType[$e->getField()] = $e->getType();
190 }
191
192 // validate user groups
193 if (!empty($this->groupIDs)) {
194 $conditions = new PreparedStatementConditionBuilder();
195 $conditions->add("groupID IN (?)", array($this->groupIDs));
196 $conditions->add("groupType NOT IN (?)", array(array(UserGroup::GUESTS, UserGroup::EVERYONE, UserGroup::USERS)));
197
198 $sql = "SELECT groupID
199 FROM wcf".WCF_N."_user_group
200 ".$conditions;
201 $statement = WCF::getDB()->prepareStatement($sql);
202 $statement->execute($conditions->getParameters());
203 $this->groupIDs = array();
204 while ($row = $statement->fetchArray()) {
205 if (UserGroup::isAccessibleGroup(array($row['groupID']))) {
206 $this->groupIDs[] = $row['groupID'];
207 }
208 }
209 }
210
211 // validate user language
212 $language = LanguageFactory::getInstance()->getLanguage($this->languageID);
213 if ($language === null || !$language->languageID) {
214 // use default language
215 $this->languageID = LanguageFactory::getInstance()->getDefaultLanguageID();
216 }
217
218 // validate visible languages
219 foreach ($this->visibleLanguages as $key => $visibleLanguage) {
220 $language = LanguageFactory::getInstance()->getLanguage($visibleLanguage);
221 if (!$language->languageID || !$language->hasContent) {
222 unset($this->visibleLanguages[$key]);
223 }
224 }
225 if (empty($this->visibleLanguages) && ($language = LanguageFactory::getInstance()->getLanguage($this->languageID)) && $language->hasContent) {
226 $this->visibleLanguages[] = $this->languageID;
227 }
228
229 // validate user title
230 try {
231 if (mb_strlen($this->userTitle) > USER_TITLE_MAX_LENGTH) {
232 throw new UserInputException('userTitle', 'tooLong');
233 }
234 if (!StringUtil::executeWordFilter($this->userTitle, USER_FORBIDDEN_TITLES)) {
235 throw new UserInputException('userTitle', 'forbidden');
236 }
237 }
238 catch (UserInputException $e) {
239 $this->errorType[$e->getField()] = $e->getType();
240 }
241
242 // validate dynamic options
243 parent::validate();
244 }
245
246 /**
247 * @see \wcf\form\IForm::save()
248 */
249 public function save() {
250 AbstractForm::save();
251
252 // create
253 $saveOptions = $this->optionHandler->save();
254 $this->additionalFields['languageID'] = $this->languageID;
255 $data = array(
256 'data' => array_merge($this->additionalFields, array(
257 'username' => $this->username,
258 'email' => $this->email,
259 'password' => $this->password,
260 'userTitle' => $this->userTitle,
261 'signature' => $this->signature,
262 'signatureEnableBBCodes' => $this->signatureEnableBBCodes,
263 'signatureEnableSmilies' => $this->signatureEnableSmilies,
264 'signatureEnableHtml' => $this->signatureEnableHtml
265 )),
266 'groups' => $this->groupIDs,
267 'languageIDs' => $this->visibleLanguages,
268 'options' => $saveOptions
269 );
270
271 if (WCF::getSession()->getPermission('admin.user.canDisableSignature')) {
272 $disableSignatureExpires = 0;
273 if ($this->disableSignatureExpires) {
274 $disableSignatureExpires = strtotime($this->disableSignatureExpires);
275 }
276
277 $data['data']['disableSignature'] = $this->disableSignature;
278 $data['data']['disableSignatureReason'] = $this->disableSignatureReason;
279 $data['data']['disableSignatureExpires'] = $disableSignatureExpires;
280 }
281
282 $this->objectAction = new UserAction(array(), 'create', $data);
283 $this->objectAction->executeAction();
284 $this->saved();
285
286 // show empty add form
287 WCF::getTPL()->assign(array(
288 'success' => true
289 ));
290
291 // reset values
292 $this->signatureEnableHtml = $this->disableSignature = 0;
293 $this->signatureEnableSmilies = $this->signatureEnableBBCodes = 1;
294 $this->username = $this->email = $this->confirmEmail = $this->password = $this->confirmPassword = $this->userTitle = '';
295 $this->signature = $this->disableSignatureReason = $this->disableSignatureExpires = '';
296 $this->groupIDs = array();
297 $this->languageID = $this->getDefaultFormLanguageID();
298 $this->optionHandler->resetOptionValues();
299 }
300
301 /**
302 * Throws a UserInputException if the username is not unique or not valid.
303 *
304 * @param string $username
305 */
306 protected function validateUsername($username) {
307 if (empty($username)) {
308 throw new UserInputException('username');
309 }
310
311 // check for forbidden chars (e.g. the ",")
312 if (!UserUtil::isValidUsername($username)) {
313 throw new UserInputException('username', 'notValid');
314 }
315
316 // Check if username exists already.
317 if (!UserUtil::isAvailableUsername($username)) {
318 throw new UserInputException('username', 'notUnique');
319 }
320 }
321
322 /**
323 * Throws a UserInputException if the email is not unique or not valid.
324 *
325 * @param string $email
326 * @param string $confirmEmail
327 */
328 protected function validateEmail($email, $confirmEmail) {
329 if (empty($email)) {
330 throw new UserInputException('email');
331 }
332
333 // check for valid email (one @ etc.)
334 if (!UserUtil::isValidEmail($email)) {
335 throw new UserInputException('email', 'notValid');
336 }
337
338 // Check if email exists already.
339 if (!UserUtil::isAvailableEmail($email)) {
340 throw new UserInputException('email', 'notUnique');
341 }
342
343 // check confirm input
344 if (mb_strtolower($email) != mb_strtolower($confirmEmail)) {
345 throw new UserInputException('confirmEmail', 'notEqual');
346 }
347 }
348
349 /**
350 * Throws a UserInputException if the password is not valid.
351 *
352 * @param string $password
353 * @param string $confirmPassword
354 */
355 protected function validatePassword($password, $confirmPassword) {
356 if (empty($password)) {
357 throw new UserInputException('password');
358 }
359
360 // check confirm input
361 if ($password != $confirmPassword) {
362 throw new UserInputException('confirmPassword', 'notEqual');
363 }
364 }
365
366 /**
367 * @see \wcf\page\IPage::readData()
368 */
369 public function readData() {
370 parent::readData();
371
372 $this->readOptionTree();
373 }
374
375 /**
376 * Reads option tree on page init.
377 */
378 protected function readOptionTree() {
379 $this->optionTree = $this->optionHandler->getOptionTree();
380 }
381
382 /**
383 * @see \wcf\page\IPage::assignVariables()
384 */
385 public function assignVariables() {
386 parent::assignVariables();
387
388 WCF::getTPL()->assign(array(
389 'username' => $this->username,
390 'email' => $this->email,
391 'confirmEmail' => $this->confirmEmail,
392 'password' => $this->password,
393 'confirmPassword' => $this->confirmPassword,
394 'groupIDs' => $this->groupIDs,
395 'optionTree' => $this->optionTree,
396 'availableGroups' => $this->getAvailableGroups(),
397 'availableLanguages' => LanguageFactory::getInstance()->getLanguages(),
398 'languageID' => $this->languageID,
399 'visibleLanguages' => $this->visibleLanguages,
400 'availableContentLanguages' => LanguageFactory::getInstance()->getContentLanguages(),
401 'action' => 'add',
402 'userTitle' => $this->userTitle,
403 'signature' => $this->signature,
404 'signatureEnableBBCodes' => $this->signatureEnableBBCodes,
405 'signatureEnableSmilies' => $this->signatureEnableSmilies,
406 'signatureEnableHtml' => $this->signatureEnableHtml,
407 'disableSignature' => $this->disableSignature,
408 'disableSignatureReason' => $this->disableSignatureReason,
409 'disableSignatureExpires' => $this->disableSignatureExpires
410 ));
411 }
412
413 /**
414 * @see \wcf\page\IPage::show()
415 */
416 public function show() {
417 // get the default language id
418 $this->languageID = $this->getDefaultFormLanguageID();
419
420 // show form
421 parent::show();
422 }
423 }