Merge branch '5.2'
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / form / RegisterNewActivationCodeForm.class.php
1 <?php
2 namespace wcf\form;
3 use wcf\data\user\User;
4 use wcf\data\user\UserAction;
5 use wcf\system\email\mime\MimePartFacade;
6 use wcf\system\email\mime\RecipientAwareTextMimePart;
7 use wcf\system\email\Email;
8 use wcf\system\email\UserMailbox;
9 use wcf\system\exception\IllegalLinkException;
10 use wcf\system\exception\PermissionDeniedException;
11 use wcf\system\exception\UserInputException;
12 use wcf\system\request\LinkHandler;
13 use wcf\system\WCF;
14 use wcf\util\HeaderUtil;
15 use wcf\util\StringUtil;
16 use wcf\util\UserRegistrationUtil;
17 use wcf\util\UserUtil;
18
19 /**
20 * Shows the new activation code form.
21 *
22 * @author Marcel Werk
23 * @copyright 2001-2019 WoltLab GmbH
24 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
25 * @package WoltLabSuite\Core\Form
26 */
27 class RegisterNewActivationCodeForm extends AbstractForm {
28 /**
29 * username
30 * @var string
31 */
32 public $username = '';
33
34 /**
35 * password
36 * @var string
37 */
38 public $password = '';
39
40 /**
41 * email
42 * @var string
43 */
44 public $email = '';
45
46 /**
47 * user object
48 * @var User
49 */
50 public $user = null;
51
52 /**
53 * @inheritDoc
54 */
55 public function readFormParameters() {
56 parent::readFormParameters();
57
58 if (isset($_POST['username'])) $this->username = StringUtil::trim($_POST['username']);
59 if (isset($_POST['password'])) $this->password = $_POST['password'];
60 if (isset($_POST['email'])) $this->email = StringUtil::trim($_POST['email']);
61 }
62
63 /**
64 * @inheritDoc
65 */
66 public function validate() {
67 parent::validate();
68
69 // username
70 $this->validateUsername();
71
72 // password
73 $this->validatePassword();
74
75 // activation state
76 $this->validateActivationState();
77
78 // email
79 $this->validateEmail();
80 }
81
82 /**
83 * Validates the username.
84 */
85 public function validateUsername() {
86 if (empty($this->username)) {
87 throw new UserInputException('username');
88 }
89
90 $this->user = User::getUserByUsername($this->username);
91 if (!$this->user->userID) {
92 throw new UserInputException('username', 'notFound');
93 }
94
95 if (!empty($this->user->getBlacklistMatches())) {
96 throw new PermissionDeniedException();
97 }
98 }
99
100 /**
101 * Validates the password.
102 */
103 public function validatePassword() {
104 if (empty($this->password)) {
105 throw new UserInputException('password');
106 }
107
108 // check password
109 if (!$this->user->checkPassword($this->password)) {
110 throw new UserInputException('password', 'false');
111 }
112 }
113
114 /**
115 * Validates the activation state.
116 */
117 public function validateActivationState() {
118 // check if user is already enabled
119 if ($this->user->isEmailConfirmed()) {
120 throw new UserInputException('username', 'alreadyEnabled');
121 }
122 }
123 /**
124 * Validates the email address.
125 */
126 public function validateEmail() {
127 if (!empty($this->email)) {
128 // check whether user entered the same email, instead of leaving the input empty
129 if (mb_strtolower($this->email) != mb_strtolower($this->user->email)) {
130 if (!UserRegistrationUtil::isValidEmail($this->email)) {
131 throw new UserInputException('email', 'invalid');
132 }
133
134 // Check if email exists already.
135 if (!UserUtil::isAvailableEmail($this->email)) {
136 throw new UserInputException('email', 'notUnique');
137 }
138 }
139 else {
140 $this->email = '';
141 }
142 }
143 }
144
145 /**
146 * @inheritDoc
147 */
148 public function save() {
149 parent::save();
150
151 // save user
152 $parameters = ['emailConfirmed' => \bin2hex(\random_bytes(20))];
153 if (!empty($this->email)) $parameters['email'] = $this->email;
154 $this->objectAction = new UserAction([$this->user], 'update', [
155 'data' => array_merge($this->additionalFields, $parameters)
156 ]);
157 $this->objectAction->executeAction();
158
159 // reload user to reflect changes
160 $this->user = new User($this->user->userID);
161
162 // send activation mail
163 $email = new Email();
164 $email->addRecipient(new UserMailbox($this->user));
165 $email->setSubject(WCF::getLanguage()->getDynamicVariable('wcf.user.register.needActivation.mail.subject'));
166 $email->setBody(new MimePartFacade([
167 new RecipientAwareTextMimePart('text/html', 'email_registerNeedActivation'),
168 new RecipientAwareTextMimePart('text/plain', 'email_registerNeedActivation')
169 ]));
170 $email->send();
171 $this->saved();
172
173 // forward to index page
174 HeaderUtil::delayedRedirect(LinkHandler::getInstance()->getLink(), WCF::getLanguage()->getDynamicVariable('wcf.user.newActivationCode.success', ['email' => !empty($this->email) ? $this->email : $this->user->email]), 10);
175 exit;
176 }
177
178 /**
179 * @inheritDoc
180 */
181 public function readData() {
182 parent::readData();
183
184 if (empty($_POST) && WCF::getUser()->userID) {
185 $this->username = WCF::getUser()->username;
186 }
187 }
188
189 /**
190 * @inheritDoc
191 */
192 public function assignVariables() {
193 parent::assignVariables();
194
195 WCF::getTPL()->assign([
196 'username' => $this->username,
197 'password' => $this->password,
198 'email' => $this->email
199 ]);
200 }
201
202 /**
203 * @inheritDoc
204 */
205 public function show() {
206 if (!(REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_USER)) {
207 throw new IllegalLinkException();
208 }
209
210 if ($this->user === null && !empty(WCF::getUser()->getBlacklistMatches())) {
211 throw new PermissionDeniedException();
212 }
213
214 parent::show();
215 }
216 }