Authorization through fancybox in yii

    An article on how to fasten fancybox authorization to a yii project in win-1251 encoding. If you happen to be a happier developer, and your project is in utf, you can simply skip the items related to encoding hell, the rest is the same. Although, maybe then you do not need this article.

    The article assumes that you already have all the classes responsible for authorizing users, and you only need to make them work through fancybox.



    We connect fancybox

    Download the fancybox extension , put it in the extensions folder.
    We connect in the template:

    widget('application.extensions.fancybox.EFancyBox', array());
    ?>


    We make a link in the template where our fancybox will be called:

    'fancy_auth'));                        
    ?>
    


    For the fancy_auth link class, we are attaching an event:

    $(document).ready(function(){
    	$(".fancy_auth").fancybox({
            'transitionIn'      : 'elastic',
            'transitionOut'     : 'elastic',
            'width'             : 345,
            'height'            : 360,
            'autoDimensions': false,
            'autoSize': false,
            'speedIn'           : '500',
            'speedOut'          : '500',
            'type'              : 'ajax',
            'closeBtn' : false
    });
    


    Basically, the parameters are given as an example. The only thing worth paying attention to is 'type': 'ajax'. If you make 'type': 'iframe', the processing code for a successful request, which I will provide below, will not work, namely, the page reload code. If after authorization you do not need a reboot, select the type of your choice.

    Controller

    As you can see from the link parameters, the view containing the authorization form is submitted by the fancy method of some_controller controller. My method looks like this:

    
    public function actionFancy()
    {
      $model=new UserLogin; 
      $this->performAjaxValidation($model);
      echo $this->renderPartial('_login_utf',array('model'=>$model),true,true);
    }
    


    By default, the value of the last parameter for renderPartial is false. In this case, it is important for us to set it to true, because it is responsible for processing by the processOutput () method, which is also called by default in the render method and connects all the necessary scripts and other dynamic content. Without this, error processing during registration will not work for us.

    Template and a little encoding hell

    If you are lucky and you have a project on utf-8, just create the desired view. For example, like this:

    
    beginWidget('CActiveForm', array(
            'id'=>'user-login',
            //отправляем данные экшену, отвечающему за авторизацию
            'action' => Yii::app()->createUrl('/user/login'),
            //включаем ajax-валидацию ошибок
            'enableAjaxValidation'=>true,
            'clientOptions'=>array(
                'validateOnSubmit'=>true,
                //назначаем js функцию, которой нужно передать управление после того, как пришел ответ. 
                //более подробные пояснения и код функции будут приведены ниже
                'afterValidate' => 'js:afterValidate',
            ),
        )); ?
            labelEx($model,'username'); ?>
            textField($model,'username'); ?>
            error($model,'username'); ?>
            labelEx($model,'password'); ?>
            passwordField($model,'password'); ?>
            error($model,'password'); ?>
             'POST',
                        // Результат запроса записываем в элемент, найденный
                        // по CSS-селектору #msg.
                        'update' => '#msg',
                        'class'=>'journalFancySubmit',
                        )); ?>
    endWidget(); ?>
    


    If everything is very sad, and your project on win-1251, like mine, then your template will be displayed in squares, that is, in the wrong encoding. Hollywood workers will say - redo urgently in utf, and they will be right, but unfortunately, the realities are often such that for one reason or another it is impossible to transfer the entire project to a religiously correct encoding, but to work it is necessary. The simplest crutch seemed to me to just make the utf-8 encoded template file itself. Then everything is given correctly.

    Processing ajax validation in the controller, again encoding problems

    In order for the controller to work correctly with the ajax validation installed by you, you need to add the processing of the ajax request in the controller, usually this is done like this:

    
    if (isset($_POST['ajax']) && $_POST['ajax'] === 'login-form') {
            echo CActiveForm::validate($model);
            Yii::app()->end;
          }
    


    But in the case of win-1251, we get an error, because json_encode, called at the end to return the validation result, does not want to work with this encoding. We need to rewrite the validate method:

    
    protected function validate($models, $attributes=null, $loadInput=true)
        {
            $result=array();
            if(!is_array($models))
                $models=array($models);
            foreach($models as $model)
            {
                if($loadInput && isset($_POST[get_class($model)]))
                    $model->attributes=$_POST[get_class($model)];
                $model->validate($attributes);
                foreach($model->getErrors() as $attribute=>$errors)
                    $result[CHtml::activeId($model,$attribute)]=$errors;
            }
            if (empty($result)) {
                $utf_result = array();
            }
            foreach ($result as $key => $value) {
                if (is_array($value)) {
                    foreach ($value as $inner_key => $inner_value) {
                        $utf_result[$key][$inner_key] = iconv('windows-1251', 'UTF-8', $inner_value);
                    }
                } else {
                        $utf_result[$key] = iconv('windows-1251', 'UTF-8', $value);    
                }
            }
            return function_exists('json_encode') ? json_encode($utf_result) : CJSON::encode($utf_result);
        }
    


    The CActiveForm :: validate method is copied here and $ result transcoding is added at the end.

    Accordingly, we change the call

    
    echo CActiveForm::validate($model);
    

    on the

    
    echo $this->validate($model);
    


    Now standard error handling will work correctly.

    After successful authorization

    Authorization was successful, now it's time to think about the afterValidate js function, which we connected to clientOptions when creating the authorization form widget:

    
    'clientOptions'=>array(
                'validateOnSubmit'=>true,           
                'afterValidate' => 'js:afterValidate',
    


    afterValidate is a function that will be called after performing an ajax check.

    Incoming parameters - (data, hasError), form - JQuery representation of the form object, data - json response from the server, HasError - Boolean value indicating whether there were errors during validation.
    Keep in mind afterValidate is only available if validateOnSubmit is set to true.

    In this function, you can do everything you need after the user has successfully logged in.

    For example, it looks something like this for me:

    function afterValidate(form, data, hasError) {
      if (hasError == false) {
        window.location.reload();
        parent.$.fancybox.close();
      }
    }
    


    Sources

    All decisions are taken from the yii forum and stackoverflow.com and are simply summarized in the article.

    Instead of a conclusion

    I wish you and yourself to work only with projects in utf-8 and enjoy life.

    Also popular now: