Yii - Добавление формы авторизации на каждую страницу

16.08.2011

Форма авторизации

Добавление формы авторизации на каждую страницу

перевод - http://www.yiiframework.com/wiki/43/adding-login-form-to-each-page

Добавить форму авторизации в макет можно следующим образом:

 

echo "Tmp";
...
if(Yii::app()->user->isGuest)
 echo CHtml::beginForm(array('site/login'));
 

 

Но пользователь не увидит нужную форму, потому что СWebUser::loginRequired() не вызывается и его состояние не сохраняется во время авторизации.
Для сохранения состояния нужно добавить обработчик события onEndRequest следующим образом:

 

$app=Yii::app();
if($app->createUrl($app->user->loginUrl[0])!=$app->request->getUrl())
   $app->user->setReturnUrl($app->request->getUrl());

 

Этот код делает следующее: если пользователь находится на странице авторизации, данные не сохраняются для дальнейшего использования(в противном случае он будет перенаправлен на страницу авторизации, сразу после самой авторизации, что не правильно).
В любых других случаях страница с формой перезагружается. Это происходит потому что в экшене, где происходит авторизация есть следующая строка:

$this->redirect(Yii::app()->user->returnUrl);

Соответственно процесс выхода может использовать эту же возможность и не отправлять пользователя на главную страницу.
Для подключения обработчика событий к приложению в файл конфигурации нужно добавить следующий код(в самом начале файла, перед return array(....)):

 

function endRequest($event)
    {
       $app=Yii::app();
       if($app->createUrl($app->user->loginUrl[0])!=$app->request->getUrl())
           $app->user->setReturnUrl($app->request->getUrl());
    }

 

И далее подключаем обработчик в самой конфигурации:

 

return array(
...
   'onEndRequest'=>'endRequest',
...

 

Перевод

А теперь свой метод...что-то после перевода понятнее не стало, но ниже я приведу свой метод подключения формы авторизации для любой страницы:
Сначала напишем вспомогательные классы для контроллера и портлета, и поместим их в папку components:

1) MyController:

 

<?php
class MyCController extends CController {
  public $pageKeywords;
  public $pageDescription;
  public $pageLoginForm = false;
}
?>

 

В контроллере я добавил несколько свойств, для нас важно только pageLoginForm, по умолчанию форма авторизации не отображается.

2) Portlet:

 

class Portlet extends CWidget {
public $title;
public $visible = true;
  
public $specCssClass = '';
public $mainCssClass = 'portlet';
  
public $headerCssClass = 'header';
public $contentCssClass = 'content';
  
  
 
public function init() {
  if(!$this->visible) return;
    
  echo '<div class="' . $this->mainCssClass . ' ' . $this->specCssClass . '">';
  if($this->title !== null)
   echo '<p class="' . $this->headerCssClass . '">' . $this->title . '</p>';
    
  echo '<div class="' . $this->contentCssClass . '">';
}
 
public function run() {
  if(!$this->visible) return;
  $this->renderContent();
  echo "</div>";
  echo "</div>";
}
 
protected function renderContent() {
   
}
}

 

Так же добавил нужные мне свойства и отображение самого портлета с указанием CSS классов.

Теперь сам компонент, отображающий форму авторизации: UserLogin

 

<?php
class UserLogin extends Portlet
{
    public $title = 'Личный кабинет';
    public $specCssClass = 'portlet_login';
 
    protected function renderContent()
    {
        $form = new LoginForm;
        
        if (isset($_POST['LoginForm']))
        {
            $form->attributes = $_POST['LoginForm'];
            
            if ($form->validate())
                $this->controller->refresh();
        }
        $this->render('userLogin', array('form' => $form));
    }
}
?>

 

И сама форма(папка components/views): userLogin

 

<div class="yiiForm login">
<?php echo CHtml::beginForm(); ?>
<?php echo CHtml::errorSummary($form); ?>
  
<div class="simple">
  <?php echo CHtml::activeLabel($form, 'username'); ?>
  <?php echo CHtml::activeTextField($form, 'username') ?>
</div>
  
<div class="simple">
  <?php echo CHtml::activeLabel($form, 'password'); ?>
  <?php echo CHtml::activePasswordField($form, 'password') ?>
</div>
  
<div class="action">
  <?php echo CHtml::link('Регистрация', 'registration'); ?> <br /><br />
  <?php echo CHtml::link('Забыли пароль?!', 'users/recovery'); ?>
  <?php echo CHtml::submitButton('Войти'); ?>
</div>
  
<?php echo CHtml::endForm(); ?>
</div>

 

Модель LoginForm — стандартная.

Подключим виджет в макете(views/layouts/main.php) в том месте, где нам надо:

$this->widget('UserLogin', array('visible' => $this->pageLoginForm && Yii::app()->user->isGuest));

blog comments powered by Disqus
Наверх