Advertisement
Guest User

Untitled

a guest
May 13th, 2018
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.37 KB | None | 0 0
  1. <?php
  2. namespace wcf\form;
  3. use wcf\acp\form\UserAddForm;
  4. use wcf\data\user\avatar\Gravatar;
  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\UserProfile;
  11. use wcf\system\captcha\CaptchaHandler;
  12. use wcf\system\exception\NamedUserException;
  13. use wcf\system\exception\PermissionDeniedException;
  14. use wcf\system\exception\SystemException;
  15. use wcf\system\exception\UserInputException;
  16. use wcf\system\language\LanguageFactory;
  17. use wcf\system\mail\Mail;
  18. use wcf\system\request\LinkHandler;
  19. use wcf\system\user\authentication\UserAuthenticationFactory;
  20. use wcf\system\Regex;
  21. use wcf\system\WCF;
  22. use wcf\util\HeaderUtil;
  23. use wcf\util\StringUtil;
  24. use wcf\util\UserRegistrationUtil;
  25.  
  26. /**
  27. * Shows the user registration form.
  28. *
  29. * @author Marcel Werk
  30. * @copyright 2001-2015 WoltLab GmbH
  31. * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  32. * @package com.woltlab.wcf
  33. * @subpackage form
  34. * @category Community Framework
  35. */
  36. class RegisterForm extends UserAddForm {
  37. /**
  38. * @see \wcf\page\AbstractPage::$enableTracking
  39. */
  40. public $enableTracking = true;
  41.  
  42. /**
  43. * true if external authentication is used
  44. * @var boolean
  45. */
  46. public $isExternalAuthentication = false;
  47.  
  48. /**
  49. * @see \wcf\page\AbstractPage::$neededPermissions
  50. */
  51. public $neededPermissions = array();
  52.  
  53. /**
  54. * holds a language variable with information about the registration process
  55. * e.g. if you need to activate your account
  56. * @var string
  57. */
  58. public $message = '';
  59.  
  60. /**
  61. * @see \wcf\form\AbstractCaptchaForm::$captchaObjectType
  62. */
  63. public $captchaObjectType = null;
  64.  
  65. /**
  66. * @see \wcf\form\AbstractCaptchaForm::$useCaptcha
  67. */
  68. public $captchaObjectTypeName = CAPTCHA_TYPE;
  69.  
  70. /**
  71. * @see \wcf\form\AbstractCaptchaForm::$useCaptcha
  72. */
  73. public $useCaptcha = REGISTER_USE_CAPTCHA;
  74.  
  75. /**
  76. * field names
  77. * @var array
  78. */
  79. public $randomFieldNames = array();
  80.  
  81. /**
  82. * min number of seconds between form request and submit
  83. * @var integer
  84. */
  85. public static $minRegistrationTime = 10;
  86.  
  87. /**
  88. * @see \wcf\page\IPage::readParameters()
  89. */
  90. public function readParameters() {
  91. parent::readParameters();
  92.  
  93. // user is already registered
  94. if (WCF::getUser()->userID) {
  95. throw new PermissionDeniedException();
  96. }
  97.  
  98. // registration disabled
  99. if (REGISTER_DISABLED) {
  100. throw new NamedUserException(WCF::getLanguage()->get('wcf.user.register.error.disabled'));
  101. }
  102.  
  103. // check disclaimer
  104. if (REGISTER_ENABLE_DISCLAIMER && !WCF::getSession()->getVar('disclaimerAccepted')) {
  105. HeaderUtil::redirect(LinkHandler::getInstance()->getLink('Disclaimer'));
  106. exit;
  107. }
  108.  
  109. if (WCF::getSession()->getVar('__3rdPartyProvider')) {
  110. $this->isExternalAuthentication = true;
  111. }
  112. }
  113.  
  114. /**
  115. * @see \wcf\form\IForm::readFormParameters()
  116. */
  117. public function readFormParameters() {
  118. parent::readFormParameters();
  119.  
  120. if (!empty($this->username) || !empty($this->email)) {
  121. throw new PermissionDeniedException();
  122. }
  123.  
  124. $this->randomFieldNames = WCF::getSession()->getVar('registrationRandomFieldNames');
  125. if ($this->randomFieldNames === null) {
  126. throw new PermissionDeniedException();
  127. }
  128.  
  129. if (isset($_POST[$this->randomFieldNames['username']])) $this->username = StringUtil::trim($_POST[$this->randomFieldNames['username']]);
  130. if (isset($_POST[$this->randomFieldNames['email']])) $this->email = StringUtil::trim($_POST[$this->randomFieldNames['email']]);
  131. if (isset($_POST[$this->randomFieldNames['confirmEmail']])) $this->confirmEmail = StringUtil::trim($_POST[$this->randomFieldNames['confirmEmail']]);
  132. if (isset($_POST[$this->randomFieldNames['password']])) $this->password = $_POST[$this->randomFieldNames['password']];
  133. if (isset($_POST[$this->randomFieldNames['confirmPassword']])) $this->confirmPassword = $_POST[$this->randomFieldNames['confirmPassword']];
  134.  
  135. $this->groupIDs = array();
  136.  
  137. if ($this->captchaObjectType) {
  138. $this->captchaObjectType->getProcessor()->readFormParameters();
  139. }
  140. }
  141.  
  142. /**
  143. * wcf\acp\form\AbstractOptionListForm::initOptionHandler()
  144. */
  145. protected function initOptionHandler() {
  146. $this->optionHandler->setInRegistration();
  147. parent::initOptionHandler();
  148. }
  149.  
  150. /**
  151. * @see \wcf\form\IForm::validate()
  152. */
  153. public function validate() {
  154. // validate captcha first
  155. $this->validateCaptcha();
  156.  
  157. parent::validate();
  158.  
  159. // validate registration time
  160. if (!$this->isExternalAuthentication && (!WCF::getSession()->getVar('registrationStartTime') || (TIME_NOW - WCF::getSession()->getVar('registrationStartTime')) < self::$minRegistrationTime)) {
  161. throw new UserInputException('registrationStartTime', array());
  162. }
  163. }
  164.  
  165. /**
  166. * @see \wcf\page\IPage::readData()
  167. */
  168. public function readData() {
  169. if ($this->useCaptcha && $this->captchaObjectTypeName) {
  170. $this->captchaObjectType = CaptchaHandler::getInstance()->getObjectTypeByName($this->captchaObjectTypeName);
  171. if ($this->captchaObjectType === null) {
  172. throw new SystemException("Unknown captcha object type with id '".$this->captchaObjectTypeName."'");
  173. }
  174.  
  175. if (!$this->captchaObjectType->getProcessor()->isAvailable()) {
  176. $this->captchaObjectType = null;
  177. }
  178.  
  179. if (WCF::getSession()->getVar('noRegistrationCaptcha')) {
  180. $this->captchaObjectType = null;
  181. }
  182. }
  183.  
  184. parent::readData();
  185.  
  186. if (empty($_POST)) {
  187. $this->languageID = WCF::getLanguage()->languageID;
  188.  
  189. if (WCF::getSession()->getVar('__username')) {
  190. $this->username = WCF::getSession()->getVar('__username');
  191. WCF::getSession()->unregister('__username');
  192. }
  193. if (WCF::getSession()->getVar('__email')) {
  194. $this->email = $this->confirmEmail = WCF::getSession()->getVar('__email');
  195. WCF::getSession()->unregister('__email');
  196. }
  197.  
  198. WCF::getSession()->register('registrationStartTime', TIME_NOW);
  199.  
  200. // generate random field names
  201. $this->randomFieldNames = array(
  202. 'username' => UserRegistrationUtil::getRandomFieldName('username'),
  203. 'email' => UserRegistrationUtil::getRandomFieldName('email'),
  204. 'confirmEmail' => UserRegistrationUtil::getRandomFieldName('confirmEmail'),
  205. 'password' => UserRegistrationUtil::getRandomFieldName('password'),
  206. 'confirmPassword' => UserRegistrationUtil::getRandomFieldName('confirmPassword')
  207. );
  208.  
  209. WCF::getSession()->register('registrationRandomFieldNames', $this->randomFieldNames);
  210. }
  211. }
  212.  
  213. /**
  214. * Reads option tree on page init.
  215. */
  216. protected function readOptionTree() {
  217. $this->optionTree = $this->optionHandler->getOptionTree('profile');
  218. }
  219.  
  220. /**
  221. * @see \wcf\page\IPage::assignVariables()
  222. */
  223. public function assignVariables() {
  224. parent::assignVariables();
  225.  
  226. WCF::getTPL()->assign(array(
  227. 'captchaObjectType' => $this->captchaObjectType,
  228. 'isExternalAuthentication' => $this->isExternalAuthentication,
  229. 'randomFieldNames' => $this->randomFieldNames
  230. ));
  231. }
  232.  
  233. /**
  234. * @see \wcf\page\IPage::show()
  235. */
  236. public function show() {
  237. AbstractForm::show();
  238. }
  239.  
  240. /**
  241. * Validates the captcha.
  242. */
  243. protected function validateCaptcha() {
  244. if ($this->captchaObjectType) {
  245. try {
  246. $this->captchaObjectType->getProcessor()->validate();
  247. }
  248. catch (UserInputException $e) {
  249. $this->errorType[$e->getField()] = $e->getType();
  250. }
  251. }
  252. }
  253.  
  254. /**
  255. * @see \wcf\acp\form\UserAddForm::validateUsername()
  256. */
  257. protected function validateUsername($username) {
  258. parent::validateUsername($username);
  259.  
  260. // check for min-max length
  261. if (!UserRegistrationUtil::isValidUsername($username)) {
  262. throw new UserInputException('username', 'notValid');
  263. }
  264. }
  265.  
  266. /**
  267. * @see \wcf\acp\form\UserAddForm::validatePassword()
  268. */
  269. protected function validatePassword($password, $confirmPassword) {
  270. if (!$this->isExternalAuthentication) {
  271. parent::validatePassword($password, $confirmPassword);
  272.  
  273. // check security of the given password
  274. if (!UserRegistrationUtil::isSecurePassword($password)) {
  275. throw new UserInputException('password', 'notSecure');
  276. }
  277. }
  278. }
  279.  
  280. /**
  281. * @see \wcf\acp\form\UserAddForm::validateEmail()
  282. */
  283. protected function validateEmail($email, $confirmEmail) {
  284. parent::validateEmail($email, $confirmEmail);
  285.  
  286. if (!UserRegistrationUtil::isValidEmail($email)) {
  287. throw new UserInputException('email', 'notValid');
  288. }
  289. }
  290.  
  291. /**
  292. * @see \wcf\form\IForm::save()
  293. */
  294. public function save() {
  295. AbstractForm::save();
  296.  
  297. // get options
  298. $saveOptions = $this->optionHandler->save();
  299. $registerVia3rdParty = false;
  300.  
  301. $avatarURL = '';
  302. if ($this->isExternalAuthentication) {
  303. switch (WCF::getSession()->getVar('__3rdPartyProvider')) {
  304. case 'github':
  305. // GitHub
  306. if (WCF::getSession()->getVar('__githubData')) {
  307. $githubData = WCF::getSession()->getVar('__githubData');
  308.  
  309. $this->additionalFields['authData'] = 'github:'.$githubData['id'];
  310.  
  311. WCF::getSession()->unregister('__githubData');
  312. WCF::getSession()->unregister('__githubToken');
  313.  
  314. if (WCF::getSession()->getVar('__email') && WCF::getSession()->getVar('__email') == $this->email) {
  315. $registerVia3rdParty = true;
  316. }
  317.  
  318. if (isset($githubData['bio']) && User::getUserOptionID('aboutMe') !== null) $saveOptions[User::getUserOptionID('aboutMe')] = $githubData['bio'];
  319. if (isset($githubData['location']) && User::getUserOptionID('location') !== null) $saveOptions[User::getUserOptionID('location')] = $githubData['location'];
  320. }
  321. break;
  322. case 'twitter':
  323. // Twitter
  324. if (WCF::getSession()->getVar('__twitterData')) {
  325. $twitterData = WCF::getSession()->getVar('__twitterData');
  326. $this->additionalFields['authData'] = 'twitter:'.$twitterData['user_id'];
  327.  
  328. WCF::getSession()->unregister('__twitterData');
  329.  
  330. if (isset($twitterData['description']) && User::getUserOptionID('aboutMe') !== null) $saveOptions[User::getUserOptionID('aboutMe')] = $twitterData['description'];
  331. if (isset($twitterData['location']) && User::getUserOptionID('location') !== null) $saveOptions[User::getUserOptionID('location')] = $twitterData['location'];
  332. }
  333. break;
  334. case 'facebook':
  335. // Facebook
  336. if (WCF::getSession()->getVar('__facebookData')) {
  337. $facebookData = WCF::getSession()->getVar('__facebookData');
  338. $this->additionalFields['authData'] = 'facebook:'.$facebookData['id'];
  339.  
  340. WCF::getSession()->unregister('__facebookData');
  341.  
  342. if (isset($facebookData['email']) && $facebookData['email'] == $this->email) {
  343. $registerVia3rdParty = true;
  344. }
  345.  
  346. if (isset($facebookData['gender']) && User::getUserOptionID('gender') !== null) $saveOptions[User::getUserOptionID('gender')] = ($facebookData['gender'] == 'male' ? UserProfile::GENDER_MALE : UserProfile::GENDER_FEMALE);
  347.  
  348. if (isset($facebookData['birthday']) && User::getUserOptionID('birthday') !== null) {
  349. list($month, $day, $year) = explode('/', $facebookData['birthday']);
  350. $saveOptions[User::getUserOptionID('birthday')] = $year.'-'.$month.'-'.$day;
  351. }
  352. if (isset($facebookData['bio']) && User::getUserOptionID('bio') !== null) $saveOptions[User::getUserOptionID('aboutMe')] = $facebookData['bio'];
  353. if (isset($facebookData['location']) && User::getUserOptionID('location') !== null) $saveOptions[User::getUserOptionID('location')] = $facebookData['location']['name'];
  354. if (isset($facebookData['website']) && User::getUserOptionID('website') !== null) {
  355. $urls = preg_split('/[\s,;]/', $facebookData['website'], -1, PREG_SPLIT_NO_EMPTY);
  356. if (!empty($urls)) {
  357. if (!Regex::compile('^https?://')->match($urls[0])) {
  358. $urls[0] = 'http://' . $urls[0];
  359. }
  360.  
  361. $saveOptions[User::getUserOptionID('homepage')] = $urls[0];
  362. }
  363. }
  364.  
  365. // avatar
  366. if (isset($facebookData['picture']) && !$facebookData['picture']['data']['is_silhouette']) {
  367. $avatarURL = $facebookData['picture']['data']['url'];
  368. }
  369. }
  370. break;
  371. case 'google':
  372. // Google Plus
  373. if (WCF::getSession()->getVar('__googleData')) {
  374. $googleData = WCF::getSession()->getVar('__googleData');
  375. $this->additionalFields['authData'] = 'google:'.$googleData['id'];
  376.  
  377. WCF::getSession()->unregister('__googleData');
  378.  
  379. if (isset($googleData['emails'][0]['value']) && $googleData['emails'][0]['value'] == $this->email) {
  380. $registerVia3rdParty = true;
  381. }
  382.  
  383. if (isset($googleData['gender']) && User::getUserOptionID('gender') !== null) {
  384. switch ($googleData['gender']) {
  385. case 'male':
  386. $saveOptions[User::getUserOptionID('gender')] = UserProfile::GENDER_MALE;
  387. break;
  388. case 'female':
  389. $saveOptions[User::getUserOptionID('gender')] = UserProfile::GENDER_FEMALE;
  390. break;
  391. }
  392. }
  393. if (isset($googleData['birthday']) && User::getUserOptionID('birthday') !== null) $saveOptions[User::getUserOptionID('birthday')] = $googleData['birthday'];
  394. if (isset($googleData['placesLived']) && User::getUserOptionID('location') !== null) {
  395. // save primary location
  396. $saveOptions[User::getUserOptionID('location')] = current(array_map(
  397. function ($element) { return $element['value']; },
  398. array_filter($googleData['placesLived'], function ($element) { return isset($element['primary']) && $element['primary']; })
  399. ));
  400. }
  401.  
  402. // avatar
  403. if (isset($googleData['image']['url'])) {
  404. $avatarURL = $googleData['image']['url'];
  405. }
  406. }
  407. break;
  408. }
  409.  
  410. // create fake password
  411. $this->password = StringUtil::getRandomID();
  412. }
  413.  
  414. $this->additionalFields['languageID'] = $this->languageID;
  415. if (LOG_IP_ADDRESS) $this->additionalFields['registrationIpAddress'] = WCF::getSession()->ipAddress;
  416.  
  417. // generate activation code
  418. $addDefaultGroups = true;
  419. if ((REGISTER_ACTIVATION_METHOD == 1 && !$registerVia3rdParty) || REGISTER_ACTIVATION_METHOD == 2) {
  420. $activationCode = UserRegistrationUtil::getActivationCode();
  421. $this->additionalFields['activationCode'] = $activationCode;
  422. $addDefaultGroups = false;
  423. $this->groupIDs = UserGroup::getGroupIDsByType(array(UserGroup::EVERYONE, UserGroup::GUESTS));
  424. }
  425.  
  426. // check gravatar support
  427. if (MODULE_GRAVATAR && Gravatar::test($this->email)) {
  428. $this->additionalFields['enableGravatar'] = 1;
  429. }
  430.  
  431. // create user
  432. $data = array(
  433. 'data' => array_merge($this->additionalFields, array(
  434. 'username' => $this->username,
  435. 'email' => $this->email,
  436. 'password' => $this->password,
  437. )),
  438. 'groups' => $this->groupIDs,
  439. 'languageIDs' => $this->visibleLanguages,
  440. 'options' => $saveOptions,
  441. 'addDefaultGroups' => $addDefaultGroups
  442. );
  443. $this->objectAction = new UserAction(array(), 'create', $data);
  444. $result = $this->objectAction->executeAction();
  445. $user = $result['returnValues'];
  446. $userEditor = new UserEditor($user);
  447.  
  448. // update session
  449. WCF::getSession()->changeUser($user);
  450.  
  451. // set avatar if provided
  452. if (!empty($avatarURL)) {
  453. $userAvatarAction = new UserAvatarAction(array(), 'fetchRemoteAvatar', array(
  454. 'url' => $avatarURL,
  455. 'userEditor' => $userEditor
  456. ));
  457. $userAvatarAction->executeAction();
  458. }
  459.  
  460. // activation management
  461. if (REGISTER_ACTIVATION_METHOD == 0) {
  462. $this->message = 'wcf.user.register.success';
  463. }
  464. else if (REGISTER_ACTIVATION_METHOD == 1) {
  465. // registering via 3rdParty leads to instant activation
  466. if ($registerVia3rdParty) {
  467. $this->message = 'wcf.user.register.success';
  468. }
  469. else {
  470. $mail = new Mail(array($this->username => $this->email),
  471. WCF::getLanguage()->getDynamicVariable('wcf.user.register.needActivation.mail.subject'),
  472. WCF::getLanguage()->getDynamicVariable('wcf.user.register.needActivation.mail', array('user' => $user))
  473. );
  474. $mail->send();
  475. $this->message = 'wcf.user.register.needActivation';
  476. }
  477. }
  478. else if (REGISTER_ACTIVATION_METHOD == 2) {
  479. $this->message = 'wcf.user.register.awaitActivation';
  480. }
  481.  
  482. // notify admin
  483. if (REGISTER_ADMIN_NOTIFICATION) {
  484. // get default language
  485. $language = LanguageFactory::getInstance()->getLanguage(LanguageFactory::getInstance()->getDefaultLanguageID());
  486.  
  487. // send mail
  488. $mail = new Mail(MAIL_ADMIN_ADDRESS,
  489. $language->getDynamicVariable('wcf.user.register.notification.mail.subject'),
  490. $language->getDynamicVariable('wcf.user.register.notification.mail', array('user' => $user))
  491. );
  492. $mail->setLanguage($language);
  493. $mail->send();
  494. }
  495.  
  496. if ($this->captchaObjectType) {
  497. $this->captchaObjectType->getProcessor()->reset();
  498. }
  499.  
  500. if (WCF::getSession()->getVar('noRegistrationCaptcha')) {
  501. WCF::getSession()->unregister('noRegistrationCaptcha');
  502. }
  503.  
  504. // login user
  505. UserAuthenticationFactory::getInstance()->getUserAuthentication()->storeAccessData($user, $this->username, $this->password);
  506. WCF::getSession()->unregister('registrationRandomFieldNames');
  507. WCF::getSession()->unregister('registrationStartTime');
  508. $this->saved();
  509.  
  510. // forward to index page
  511. HeaderUtil::delayedRedirect(LinkHandler::getInstance()->getLink(), WCF::getLanguage()->getDynamicVariable($this->message, array('user' => $user)), 15);
  512. exit;
  513. }
  514. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement