Содержание
- Yii2 basic авторизация через БД во всплывающем (модальном) окне
- Yii2 basic, авторизация из коробки во всплывающем (модальном) окне
- Yii2 advanced. Авторизация во всплывающем (модальном) окне
Yii2 basic авторизация через БД во всплывающем (модальном) окне
Шаг 1
Для реализации авторизации Yii2 basic во всплывающем окне я возьму ранее написанный пример с авторизацией из БД: Yii2 basic, авторизация и регистрация через БД. Для этого клонируем его и подготавливаем:
mkdir yii2-auth-in-modal.local cd yii2-auth-in-modal.local git clone https://github.com/egor/yii2-basic-auth-through-db.git . composer update
Настраиваем соединение с БД и запускаем миграцию:
yii migrate
Шаг 2
Создаем каталог для хранения виджтов app/widgets и каталог для представлений (view) виджетов app/widgets/views.
Создаем виджет LoginFormWidget для отображения модального окна с формой авторизации, app/widgets/LoginFormWidget.php:
<?php namespace app\widgets; use Yii; use yii\base\Widget; use app\models\LoginForm; class LoginFormWidget extends Widget { public function run() { if (Yii::$app->user->isGuest) { $model = new LoginForm(); return $this->render('loginFormWidget', [ 'model' => $model, ]); } else { return ; } } }
В представление (view) виджета LoginFormWidget добавляем модально окно с формой авторизации, app/widgets/views/loginFormWidget.php:
<?php use yii\helpers\Html; use yii\bootstrap\ActiveForm; use yii\bootstrap\Modal; Modal::begin([ 'header'=>'<h4>Login</h4>', 'id'=>'login-modal', ]); ?> <p>Please fill out the following fields to login:</p> <?php $form = ActiveForm::begin([ 'id' => 'login-form', 'enableAjaxValidation' => true, 'action' => ['site/ajax-login'] ]); echo $form->field($model, 'email')->textInput(); echo $form->field($model, 'password')->passwordInput(); echo $form->field($model, 'rememberMe')->checkbox(); ?> <div> If you forgot your password you can <?= Html::a('reset it', ['site/request-password-reset']) ?>. </div> <div class="form-group"> <div class="text-right"> <?php echo Html::button('Cancel', ['class' => 'btn btn-default', 'data-dismiss' => 'modal']); echo Html::submitButton('Login', ['class' => 'btn btn-primary', 'name' => 'login-button']); ?> </div> </div> <?php ActiveForm::end(); Modal::end();
Шаг 3
Добавляем ajax действие проверки и авторизации пользователя в контроллер Site, app/controllers/SiteController.php:
public function actionAjaxLogin() { if (Yii::$app->request->isAjax) { $model = new LoginForm(); if ($model->load(Yii::$app->request->post())) { if ($model->login()) { return $this->goBack(); } else { Yii::$app->response->format = yii\web\Response::FORMAT_JSON; return \yii\widgets\ActiveForm::validate($model); } } } else { throw new HttpException(404 ,'Page not found'); } }
Шаг 4
В главном макете app/views/layouts/main.php в блок use
добавляем виджет LoginFormWidget:
use app\widgets\LoginFormWidget;
Вызов виджета LoginFormWidget, вставляем после <?php $this->beginBody() ?>
:
<?= (Yii::$app->user->isGuest ? LoginFormWidget::widget([]) : ''); ?>
Заменим ссылку ведущую на страницу авторизации для вызов модального окна, с:
$menuItems[] = ['label' => 'Login', 'url' => ['/site/login']];
Меняем на:
$menuItems[] = ['label' => 'Login', 'url' => '#', 'options' => ['data-toggle' => 'modal', 'data-target' => '#login-modal']];
В итоге app/views/layouts/main.php примет вид:
<?php /* @var $this \yii\web\View */ /* @var $content string */ use yii\helpers\Html; use yii\bootstrap\Nav; use yii\bootstrap\NavBar; use yii\widgets\Breadcrumbs; use app\assets\AppAsset; use app\widgets\LoginFormWidget; AppAsset::register($this); ?> <?php $this->beginPage() ?> <!DOCTYPE html> <html lang="<?= Yii::$app->language ?>"> <head> <meta charset="<?= Yii::$app->charset ?>"> <meta name="viewport" content="width=device-width, initial-scale=1"> <?= Html::csrfMetaTags() ?> <title><?= Html::encode($this->title) ?></title> <?php $this->head() ?> </head> <body> <?php $this->beginBody() ?> <?php if (Yii::$app->user->isGuest) { echo LoginFormWidget::widget([]); } ?> <div class="wrap"> <?php NavBar::begin([ 'brandLabel' => 'My Company', 'brandUrl' => Yii::$app->homeUrl, 'options' => [ 'class' => 'navbar-inverse navbar-fixed-top', ], ]); $menuItems = [ ['label' => 'Home', 'url' => ['/site/index']], ['label' => 'About', 'url' => ['/site/about']], ['label' => 'Contact', 'url' => ['/site/contact']], ]; if (Yii::$app->user->isGuest) { $menuItems[] = ['label' => 'Signup', 'url' => ['/site/signup']]; $menuItems[] = ['label' => 'Login', 'url' => '#', 'options' => ['data-toggle' => 'modal', 'data-target' => '#login-modal']]; } else { $menuItems[] = '<li>' . Html::beginForm(['/site/logout'], 'post') . Html::submitButton( 'Logout (' . Yii::$app->user->identity->username . ')', ['class' => 'btn btn-link logout'] ) . Html::endForm() . '</li>'; } echo Nav::widget([ 'options' => ['class' => 'navbar-nav navbar-right'], 'items' => $menuItems, ]); NavBar::end(); ?> <div class="container"> <?= Breadcrumbs::widget([ 'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [], ]) ?> <?= $content ?> </div> </div> <footer class="footer"> <div class="container"> <p class="pull-left">© My Company <?= date('Y') ?></p> <p class="pull-right"><?= Yii::powered() ?></p> </div> </footer> <?php $this->endBody() ?> </body> </html> <?php $this->endPage() ?>
Сохраняем и запускаем.
Yii2 basic, авторизация из коробки во всплывающем (модальном) окне
Пример описанный выше подойдет и для авторизации имеющейся в Yii2 basic из коробки с небольшими правками.
Шаг 1
Шаг 1 из предыдущего примера пропускаем, вместо него устанавливаем yii2 basic (Как установить Yii 2 basic, краткая инструкция) или открываем существующий проект с авторизацией из коробки.
Шаг 2
Выполняем шаг 2 из предыдущего примера с некоторыми изменениями. В представлении виджета app/widgets/views/loginFormWidget.php заменяем:
echo $form->field($model, 'email')->textInput();
на:
echo $form->field($model, 'username')->textInput();
Т.к. по умолчанию логин это username
. Далее убираем блок отвечающий за сброс пароля, т.к. из коробки он не реализован. Все остальное остается как есть.
В итоге app/widgets/LoginFormWidget.php примет вид:
<?php namespace app\widgets; use Yii; use yii\base\Widget; use app\models\LoginForm; class LoginFormWidget extends Widget { public function run() { if (Yii::$app->user->isGuest) { $model = new LoginForm(); return $this->render('loginFormWidget', [ 'model' => $model, ]); } else { return ; } } }
Представление виджета LoginFormWidget примет вид, app/widgets/views/loginFormWidget.php:
<?php use yii\helpers\Html; use yii\bootstrap\ActiveForm; use yii\bootstrap\Modal; Modal::begin([ 'header'=>'<h4>Login</h4>', 'id'=>'login-modal', ]); ?> <p>Please fill out the following fields to login:</p> <?php $form = ActiveForm::begin([ 'id' => 'login-form', 'enableAjaxValidation' => true, 'action' => ['site/ajax-login'] ]); echo $form->field($model, 'username')->textInput(); echo $form->field($model, 'password')->passwordInput(); echo $form->field($model, 'rememberMe')->checkbox(); ?> <div class="form-group"> <div class="text-right"> <?php echo Html::button('Cancel', ['class' => 'btn btn-default', 'data-dismiss' => 'modal']); echo Html::submitButton('Login', ['class' => 'btn btn-primary', 'name' => 'login-button']); ?> </div> </div> <?php ActiveForm::end(); Modal::end();
Шаг 3
Шаг 3 из предыдущего примера выполняем полностью.
В итоге actionAjaxLogin в app/controllers/SiteController.php примет вид:
public function actionAjaxLogin() { if (Yii::$app->request->isAjax) { $model = new LoginForm(); if ($model->load(Yii::$app->request->post())) { if ($model->login()) { return $this->goBack(); } else { Yii::$app->response->format = yii\web\Response::FORMAT_JSON; return \yii\widgets\ActiveForm::validate($model); } } } else { throw new HttpException(404 ,'Page not found'); } }
Шаг 4
Шаг 4 из предыдущего примера подвергнется небольшим изменениям. А именно в главном макете app/views/layouts/main.php заменяем ссылку вызова страницы авторизации с:
['label' => 'Login', 'url' => ['/site/login']]
на:
['label' => 'Login', 'url' => '#', 'options' => ['data-toggle' => 'modal', 'data-target' => '#login-modal']]
Остальное делаем как написано. В итоге app/views/layouts/main.php примет вид:
<?php /* @var $this \yii\web\View */ /* @var $content string */ use yii\helpers\Html; use yii\bootstrap\Nav; use yii\bootstrap\NavBar; use yii\widgets\Breadcrumbs; use app\assets\AppAsset; use app\widgets\LoginFormWidget; AppAsset::register($this); ?> <?php $this->beginPage() ?> <!DOCTYPE html> <html lang="<?= Yii::$app->language ?>"> <head> <meta charset="<?= Yii::$app->charset ?>"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <?= Html::csrfMetaTags() ?> <title><?= Html::encode($this->title) ?></title> <?php $this->head() ?> </head> <body> <?php $this->beginBody() ?> <?= (Yii::$app->user->isGuest ? LoginFormWidget::widget([]) : ''); ?> <div class="wrap"> <?php NavBar::begin([ 'brandLabel' => 'My Company', 'brandUrl' => Yii::$app->homeUrl, 'options' => [ 'class' => 'navbar-inverse navbar-fixed-top', ], ]); echo Nav::widget([ 'options' => ['class' => 'navbar-nav navbar-right'], 'items' => [ ['label' => 'Home', 'url' => ['/site/index']], ['label' => 'About', 'url' => ['/site/about']], ['label' => 'Contact', 'url' => ['/site/contact']], Yii::$app->user->isGuest ? ( ['label' => 'Login', 'url' => '#', 'options' => ['data-toggle' => 'modal', 'data-target' => '#login-modal']] ) : ( '<li>' . Html::beginForm(['/site/logout'], 'post') . Html::submitButton( 'Logout (' . Yii::$app->user->identity->username . ')', ['class' => 'btn btn-link logout'] ) . Html::endForm() . '</li>' ) ], ]); NavBar::end(); ?> <div class="container"> <?= Breadcrumbs::widget([ 'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [], ]) ?> <?= $content ?> </div> </div> <footer class="footer"> <div class="container"> <p class="pull-left">© My Company <?= date('Y') ?></p> <p class="pull-right"><?= Yii::powered() ?></p> </div> </footer> <?php $this->endBody() ?> </body> </html> <?php $this->endPage() ?>
По окончанию жмем на Login, вводим логин и пароль (admin, admin).
Yii2 advanced. Авторизация во всплывающем (модальном) окне
Шаг 1
Открываем существующий проект на Yii2 advanced или устанавливаем новый (Как установить Yii 2 advanced, краткая инструкция). И используем инструкцию описанную выше с некоторыми изменениями.
Шаг 1 пропускаем из основного примера.
Шаг 2
Для шага 2 из основного примера, меняем путь к каталогу хранения виджета и его представления на frontend/widgets и frontend/widgets/views соответственно.
В классе виджета frontend/widgets/LoginFormWidget.php меняем namespace
c:
namespace app\widgets;
на:
namespace frontend\widgets;
Также меняем путь к LoginForm c:
use app\models\LoginForm;
на:
use common\models\LoginForm;
В представление виджета frontend/widgets/views/loginFormWidget.php заменяем:
echo $form->field($model, 'email')->textInput();
на:
echo $form->field($model, 'username')->textInput();
Т.к. по умолчанию логин это username
.
Остальное в шаге 2 из основного примера оставляем как есть.
Виджет frontend/widgets/LoginFormWidget.php примет вид:
<?php namespace frontend\widgets; use Yii; use yii\base\Widget; use common\models\LoginForm; class LoginFormWidget extends Widget { public function run() { if (Yii::$app->user->isGuest) { $model = new LoginForm(); return $this->render('loginFormWidget', [ 'model' => $model, ]); } else { return ; } } }
Представление виджета LoginFormWidget примет вид, frontend/widgets/views/loginFormWidget.php:
<?php use yii\helpers\Html; use yii\bootstrap\ActiveForm; use yii\bootstrap\Modal; Modal::begin([ 'header'=>'<h4>Login</h4>', 'id'=>'login-modal', ]); ?> <p>Please fill out the following fields to login:</p> <?php $form = ActiveForm::begin([ 'id' => 'login-form', 'enableAjaxValidation' => true, 'action' => ['site/ajax-login'], ]); echo $form->field($model, 'username')->textInput(); echo $form->field($model, 'password')->passwordInput(); echo $form->field($model, 'rememberMe')->checkbox(); ?> <div> If you forgot your password you can <?= Html::a('reset it', ['site/request-password-reset']) ?>. </div> <div class="form-group"> <div class="text-right"> <?php echo Html::button('Cancel', ['class' => 'btn btn-default', 'data-dismiss' => 'modal']); echo Html::submitButton('Login', ['class' => 'btn btn-primary', 'name' => 'login-button']); ?> </div> </div> <?php ActiveForm::end(); Modal::end();
Шаг 3
Шаг 3 из основного примера делаем полностью.
В итоге actionAjaxLogin в frontend/controllers/SiteController.php примет вид:
public function actionAjaxLogin() { if (Yii::$app->request->isAjax) { $model = new LoginForm(); if ($model->load(Yii::$app->request->post())) { if ($model->login()) { return $this->goBack(); } else { Yii::$app->response->format = yii\web\Response::FORMAT_JSON; return \yii\widgets\ActiveForm::validate($model); } } } else { throw new HttpException(404 ,'Page not found'); } }
Шаг 4
Шаг 4 из основного примера имеет небольшие отличия. Открываем основной макет frontend/views/layouts/main.php, в блок use
добавляем виджет с модальным окном и формой авторизации:
use frontend\widgets\LoginFormWidget;
Остальное остается как описано в шаге 4 из основного примера.
В итоге frontend/views/layouts/main.php примет вид:
<?php /* @var $this \yii\web\View */ /* @var $content string */ use yii\helpers\Html; use yii\bootstrap\Nav; use yii\bootstrap\NavBar; use yii\widgets\Breadcrumbs; use frontend\assets\AppAsset; use common\widgets\Alert; use frontend\widgets\LoginFormWidget; AppAsset::register($this); ?> <?php $this->beginPage() ?> <!DOCTYPE html> <html lang="<?= Yii::$app->language ?>"> <head> <meta charset="<?= Yii::$app->charset ?>"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <?= Html::csrfMetaTags() ?> <title><?= Html::encode($this->title) ?></title> <?php $this->head() ?> </head> <body> <?php $this->beginBody() ?> <?= (Yii::$app->user->isGuest ? LoginFormWidget::widget([]) : ''); ?> <div class="wrap"> <?php NavBar::begin([ 'brandLabel' => 'My Company', 'brandUrl' => Yii::$app->homeUrl, 'options' => [ 'class' => 'navbar-inverse navbar-fixed-top', ], ]); $menuItems = [ ['label' => 'Home', 'url' => ['/site/index']], ['label' => 'About', 'url' => ['/site/about']], ['label' => 'Contact', 'url' => ['/site/contact']], ]; if (Yii::$app->user->isGuest) { $menuItems[] = ['label' => 'Signup', 'url' => ['/site/signup']]; $menuItems[] = ['label' => 'Login', 'url' => '#', 'options' => ['data-toggle' => 'modal', 'data-target' => '#login-modal']]; } else { $menuItems[] = '<li>' . Html::beginForm(['/site/logout'], 'post') . Html::submitButton( 'Logout (' . Yii::$app->user->identity->username . ')', ['class' => 'btn btn-link logout'] ) . Html::endForm() . '</li>'; } echo Nav::widget([ 'options' => ['class' => 'navbar-nav navbar-right'], 'items' => $menuItems, ]); NavBar::end(); ?> <div class="container"> <?= Breadcrumbs::widget([ 'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [], ]) ?> <?= Alert::widget() ?> <?= $content ?> </div> </div> <footer class="footer"> <div class="container"> <p class="pull-left">© My Company <?= date('Y') ?></p> <p class="pull-right"><?= Yii::powered() ?></p> </div> </footer> <?php $this->endBody() ?> </body> </html> <?php $this->endPage() ?>
Добавляем нового пользователя в БД. И пробуем.
Комментарии
Я думал статья будет раза в 4 короче)))
Ответитьа у меня все равно ошибка Unable to find 'app\components\LoginFormWidget' in file: /home/*****/components/LoginFormWidget.php.
ОтветитьNamespace missing?
use app\widgets\LoginFormWidget
ОтветитьОткуда взялся components?
В именно в этой папке у меня находятся все виджеты включая виждет из этой статье. ктому же везде пишут что они там должны лежать
ОтветитьПроверьте все namespace и use, а так по описанию ошибки ничего не понятно
Ответить$this->asJson(), вместо Yii::$app->response->format = yii\web\Response::FORMAT_JSON; Выглядит красевее
ОтветитьА какой ввиду для ссылки? Если вставлять в другом месте
ОтветитьСсылка просто на "#"
ОтветитьА у родительскому элементу ссылки нужно добавить атрибуты data-toggle="modal" data-target="#login-modal"
Исследуйте получившийся HTML код, который получается при использовании NavBar
Блог умер?
ОтветитьНадеюсь нет. Видно человек работает.
ОтветитьСпасибо, работает
ОтветитьПочему-то не все стили подключились к форме.
ОтветитьВзял шаблон basic
скопировал файл login.php а не все отрабатывает как надо :(