'Invalid Access Code', 'msgCodeExpired' => 'Access Code Expired', 'msgPassActivated' => 'New password was set', ]; protected $_settingsPrefix = 'forgotPasswordEmail'; public function exec() { if (Auth::getInstance()->hasIdentity()) { Qs_Http::redirect(BASE_URL . '/' . Qs_SiteMap::getAliasByItem('User\\')); } $this->_defaultAction = $this->getConfig('defaultAction'); return parent::exec(); } protected function _doInsert() { $form = $this->_getNewForm(); if ($form->validate()) { $this->_getDataObj()->setPrimaryKeyByEmail($form->getValue('email')); $data = $this->_getDataObj()->getData(); $expirationTime = time() + 86400; // 24 hours $recoverCode = md5('code' . rand(0, 100) . time()); $this->_getDataObj()->setRecoverCode($recoverCode, date('Y-m-d H:i:s', $expirationTime)); $data['expirationTime'] = $expirationTime; $data['recoverCode'] = $recoverCode; $this->_sendMail2User($data); $this->redirect($this->url() . '/sent.html'); } else { $this->_addFormItem($form); } return $this; } protected function _sendMail2User($data) { $subject = SettingsObj::get($this->_settingsPrefix . 'Subject'); $from = SettingsObj::getEmailFrom($this->_settingsPrefix . 'From'); $to = $data['email']; $body = SettingsObj::get($this->_settingsPrefix . 'Body'); $mailData = [ 'firstName' => htmlspecialchars($data['firstName']), 'lastName' => htmlspecialchars($data['lastName']), 'email' => htmlspecialchars($data['email']), ]; $mailData['recoverCodeExpirationDate'] = date('m/d/Y g:i A', $data['expirationTime']); $pageUrl = Qs_SiteMap::findFirst( null, ['type' => 'User\\ForgotPassword\\'], ['defaultAction' => 'edit'], 'url' ); $mailData['link'] = $pageUrl . '?action=edit&code=' . rawurlencode($data['recoverCode']); foreach ($mailData as $field => $value) { $body = str_replace('{' . $field . '}', $value, $body); } $this->_sendMail(compact('subject', 'from', 'to', 'body')); return $this; } /** * Verify recover code * @param string $recoverCode * @return bool|array */ protected function _validateRecoverCode($recoverCode = null) { $errors = []; if (null === $recoverCode) { $recoverCode = Qs_Request::getRequestValue('code'); } if (!$recoverCode) { $errors[] = $this->_createMessage(self::MSG_CODE_ERROR); } else { $this->_getDataObj()->setPrimaryKeyByRecoverCode($recoverCode); if (null === ($data = $this->_getDataObj()->getData())) { $errors[] = $this->_createMessage(self::MSG_CODE_ERROR); } else if (strtotime($data['recoverCodeExpirationDate']) < time()) { $errors[] = $this->_createMessage(self::MSG_CODE_EXPIRED); } } return (empty($errors)) ? true : $errors; } protected function _doEdit() { $backUrl = Qs_SiteMap::findFirst( null, ['type' => 'User\\ForgotPassword\\'], ['defaultAction' => 'new'], 'url' ); $this->_setBackUrl($backUrl); $recoverCode = Qs_Request::getGetValue('code'); /** * Якщо ми на прев’юві сторінки то не треба валідувати "$recoverCode" і показати форму. */ if (!$this->_doc->isPagePreviewMode() && true !== ($errors = $this->_validateRecoverCode($recoverCode))) { $this->_setBackErrors($errors); $this->_doBack(); } $form = $this->_getEditForm(['defaults' => ['code' => $recoverCode]]); $form->setDefaults(); $this->_addFormItem($form); $this->_postEdit(); return $this; } protected function _getFormOptions($type = null) { $options = parent::_getFormOptions($type); $options['attribs']['id'] = strtolower($this->getApplicationName()) . '-forgot-form'; return $options; } protected function _doUpdateAjax() { if (true !== ($errors = $this->_validateRecoverCode())) { $data = ['isValid' => false, 'formErrors' => $errors]; } else { $form = $this->_getEditForm(); $data = $form->validateAjax(); } $this->_displayJson($data); } protected function _doUpdate() { $this->_setBackUrl(BASE_URL_LANGUAGE . '/' . Qs_SiteMap::getAliasByItem('User\\Login\\')); if (true !== ($errors = $this->_validateRecoverCode())) { $this->_setBackErrors($errors); $this->_doBack(); } if (null === $this->_getDataObj()->getData()) { $this->_setBackError(static::MSG_DATA_UNAVAILABLE); $this->_doBack(); } $form = $this->_getEditForm(); if ($form->validate()) { $this->_initFromForm($form); if (false === $this->_getDataObj()->update()) { $this->_setBackErrors($this->_getDataObj()->getErrors()); } else { $this->_postUpdate(); $this->_setBackMessage(static::MSG_ACTIVATED); } $this->_doBack(); } else { $this->_addFormItem($form); } return $this; } protected function _initFromForm(\Qs_Form $form) { $data = $form->getValues(); if ($this->_action == 'update') { $data['recoverCode'] = null; $data['recoverCodeExpirationDate'] = null; } $this->_getDataObj()->initFromForm($data); return $this; } }