Commit b02f01f6 by Alexander Makarov

More on advanced app template:

- Unified way to use Alert - Added link to restore password to login form - Refactored restore password
parent dacee193
...@@ -112,6 +112,7 @@ class User extends ActiveRecord implements Identity ...@@ -112,6 +112,7 @@ class User extends ActiveRecord implements Identity
array('email', 'required'), array('email', 'required'),
array('email', 'email'), array('email', 'email'),
array('email', 'unique', 'message' => 'This email address has already been taken.', 'on' => 'signup'), array('email', 'unique', 'message' => 'This email address has already been taken.', 'on' => 'signup'),
array('email', 'exist', 'message' => 'There is no user with such email.', 'on' => 'requestPasswordResetToken'),
array('password', 'required'), array('password', 'required'),
array('password', 'string', 'min' => 6), array('password', 'string', 'min' => 6),
...@@ -124,6 +125,7 @@ class User extends ActiveRecord implements Identity ...@@ -124,6 +125,7 @@ class User extends ActiveRecord implements Identity
'signup' => array('username', 'email', 'password'), 'signup' => array('username', 'email', 'password'),
'login' => array('username', 'password'), 'login' => array('username', 'password'),
'resetPassword' => array('password'), 'resetPassword' => array('password'),
'requestPasswordResetToken' => array('email'),
); );
} }
......
...@@ -8,7 +8,6 @@ use common\models\LoginForm; ...@@ -8,7 +8,6 @@ use common\models\LoginForm;
use frontend\models\ContactForm; use frontend\models\ContactForm;
use common\models\User; use common\models\User;
use yii\web\HttpException; use yii\web\HttpException;
use frontend\models\SendPasswordResetTokenForm;
class SiteController extends Controller class SiteController extends Controller
{ {
...@@ -48,7 +47,7 @@ class SiteController extends Controller ...@@ -48,7 +47,7 @@ class SiteController extends Controller
{ {
$model = new ContactForm; $model = new ContactForm;
if ($model->load($_POST) && $model->contact(Yii::$app->params['adminEmail'])) { if ($model->load($_POST) && $model->contact(Yii::$app->params['adminEmail'])) {
Yii::$app->session->setFlash('contactFormSubmitted'); Yii::$app->session->setFlash('success', 'Thank you for contacting us. We will respond to you as soon as possible.');
return $this->refresh(); return $this->refresh();
} else { } else {
return $this->render('contact', array( return $this->render('contact', array(
...@@ -77,37 +76,70 @@ class SiteController extends Controller ...@@ -77,37 +76,70 @@ class SiteController extends Controller
)); ));
} }
public function actionResetPassword($token = null) public function actionRequestPasswordReset()
{ {
if ($token) { $model = new User();
$model = User::find(array( $model->scenario = 'requestPasswordResetToken';
'password_reset_token' => $token, if ($model->load($_POST) && $model->validate()) {
'status' => User::STATUS_ACTIVE, if ($this->sendPasswordResetEmail($email)) {
)); Yii::$app->getSession()->setFlash('success', 'Check your email for further instructions.');
if (!$model) {
throw new HttpException(400, 'Wrong password reset token.');
}
$model->scenario = 'resetPassword';
if ($model->load($_POST) && $model->save()) {
// TODO: confirm that password was successfully saved
$this->redirect('index'); $this->redirect('index');
} else {
Yii::$app->getSession()->setFlash('error', 'There was an error sending email.');
} }
}
$this->render('requestPasswordResetToken', array(
'model' => $model,
));
}
$this->render('resetPassword', array( public function actionResetPassword($token)
'model' => $model, {
)); $model = User::find(array(
'password_reset_token' => $token,
'status' => User::STATUS_ACTIVE,
));
if (!$model) {
throw new HttpException(400, 'Wrong password reset token.');
} }
else {
$model = new SendPasswordResetTokenForm(); $model->scenario = 'resetPassword';
if ($model->load($_POST) && $model->sendEmail()) { if ($model->load($_POST) && $model->save()) {
// TODO: confirm that password reset token was sent Yii::$app->getSession()->setFlash('success', 'New password was saved.');
$this->redirect('index'); $this->redirect('index');
} }
$this->render('sendPasswordResetTokenForm', array(
'model' => $model, $this->render('resetPassword', array(
'model' => $model,
));
}
private function sendPasswordResetEmail($email)
{
$user = User::find(array(
'status' => User::STATUS_ACTIVE,
'email' => $email,
));
if (!$user) {
return false;
}
$user->password_reset_token = Security::generateRandomKey();
if ($user->save(false)) {
$fromEmail = \Yii::$app->params['supportEmail'];
$name = '=?UTF-8?B?' . base64_encode(\Yii::$app->name . ' robot') . '?=';
$subject = '=?UTF-8?B?' . base64_encode('Password reset for ' . \Yii::$app->name) . '?=';
$body = $this->renderPartial('/emails/passwordResetToken', array(
'user' => $this,
)); ));
$headers = "From: $name <{$fromEmail}>\r\n" .
"MIME-Version: 1.0\r\n" .
"Content-type: text/plain; charset=UTF-8";
return mail($fromEmail, $subject, $body, $headers);
} }
return false;
} }
} }
<?php
namespace frontend\models;
use yii\base\Model;
use common\models\User;
use yii\base\View;
use yii\helpers\Security;
/**
* SendPasswordResetTokenForm is the model behind requesting password reset token form.
*/
class SendPasswordResetTokenForm extends Model
{
public $email;
/**
* @return array the validation rules.
*/
public function rules()
{
return array(
array('email', 'required'),
array('email', 'email'),
);
}
public function sendEmail()
{
if($this->validate()) {
/** @var User $user */
$user = User::find(array(
'email' => $this->email,
'status' => User::STATUS_ACTIVE,
));
if ($user) {
$user->password_reset_token = Security::generateRandomKey();
if ($user->save(false)) {
$view = new View(array(
'context' => \Yii::$app->controller,
));
$fromEmail = \Yii::$app->params['supportEmail'];
$name = '=?UTF-8?B?' . base64_encode(\Yii::$app->name . ' robot') . '?=';
$subject = '=?UTF-8?B?' . base64_encode('Password reset for ' . \Yii::$app->name) . '?=';
$body = $view->render('/emails/passwordResetToken', array(
'user' => $user,
));
$headers = "From: $name <{$fromEmail}>\r\n" .
"MIME-Version: 1.0\r\n" .
"Content-type: text/plain; charset=UTF-8";
mail($fromEmail, $subject, $body, $headers);
return true;
}
}
}
return false;
}
}
...@@ -3,6 +3,7 @@ use frontend\config\AppAsset; ...@@ -3,6 +3,7 @@ use frontend\config\AppAsset;
use yii\helpers\Html; use yii\helpers\Html;
use yii\widgets\Menu; use yii\widgets\Menu;
use yii\widgets\Breadcrumbs; use yii\widgets\Breadcrumbs;
use frontend\widgets\Alert;
/** /**
* @var $this \yii\base\View * @var $this \yii\base\View
...@@ -54,6 +55,9 @@ AppAsset::register($this); ...@@ -54,6 +55,9 @@ AppAsset::register($this);
<?php echo Breadcrumbs::widget(array( <?php echo Breadcrumbs::widget(array(
'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : array(), 'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : array(),
)); ?> )); ?>
<?php echo Alert::widget()?>
<?php echo $content; ?> <?php echo $content; ?>
<hr> <hr>
......
...@@ -13,12 +13,6 @@ $this->params['breadcrumbs'][] = $this->title; ...@@ -13,12 +13,6 @@ $this->params['breadcrumbs'][] = $this->title;
?> ?>
<h1><?php echo Html::encode($this->title); ?></h1> <h1><?php echo Html::encode($this->title); ?></h1>
<?php if (Yii::$app->session->hasFlash('contactFormSubmitted')): ?>
<div class="alert alert-success">
Thank you for contacting us. We will respond to you as soon as possible.
</div>
<?php return; endif; ?>
<p> <p>
If you have business inquiries or other questions, please fill out the following form to contact us. Thank you. If you have business inquiries or other questions, please fill out the following form to contact us. Thank you.
</p> </p>
......
...@@ -22,3 +22,5 @@ $this->params['breadcrumbs'][] = $this->title; ...@@ -22,3 +22,5 @@ $this->params['breadcrumbs'][] = $this->title;
<?php echo Html::submitButton('Login', array('class' => 'btn btn-primary')); ?> <?php echo Html::submitButton('Login', array('class' => 'btn btn-primary')); ?>
</div> </div>
<?php ActiveForm::end(); ?> <?php ActiveForm::end(); ?>
<p>If you forgot your password you can <?php echo Html::a('reset it', array('site/requestPasswordReset'))?>.</p>
\ No newline at end of file
...@@ -5,7 +5,7 @@ use yii\widgets\ActiveForm; ...@@ -5,7 +5,7 @@ use yii\widgets\ActiveForm;
/** /**
* @var yii\base\View $this * @var yii\base\View $this
* @var yii\widgets\ActiveForm $form * @var yii\widgets\ActiveForm $form
* @var frontend\models\SendPasswordResetTokenForm $model * @var frontend\models\User $model
*/ */
$this->title = 'Request password reset'; $this->title = 'Request password reset';
$this->params['breadcrumbs'][] = $this->title; $this->params['breadcrumbs'][] = $this->title;
......
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace frontend\widgets;
use yii\helpers\Html;
/**
* Alert widget renders a message from session flash. You can set message as following:
*
* - \Yii::$app->getSession()->setFlash('error', 'This is the message');
* - \Yii::$app->getSession()->setFlash('success', 'This is the message');
* - \Yii::$app->getSession()->setFlash('info', 'This is the message');
*
* @author Alexander Makarov <sam@rmcerative.ru>
*/
class Alert extends \yii\bootstrap\Alert
{
public function init()
{
if ($this->body = \Yii::$app->getSession()->getFlash('error')) {
Html::addCssClass($this->options, 'alert-error');
} elseif ($this->body = \Yii::$app->getSession()->getFlash('success')) {
Html::addCssClass($this->options, 'alert-success');
} elseif ($this->body = \Yii::$app->getSession()->getFlash('info')) {
Html::addCssClass($this->options, 'alert-info');
} elseif ($this->body = \Yii::$app->getSession()->getFlash('warning')) {
} else {
// no message passed, no need to render widget
return;
}
parent::init();
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment