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