Tuesday 6 February 2018

A Method for Separating Frontend / Backend Parts in Yii

If you're familiar with Yii, you should know that it implements the so-called behaviours , which allow you to change or add functionality and behaviour of the various components. They are most often used with conjunction with the models, but in our case, we propose to use the behaviour immediately to start the application.


Directory

First, let's define some directories. Get together on controllers that a user of the site (frontend) are stored in the "protected / controllers / frontend" . Logically, the admin controllers we will file in the folder "protected / controllers / backend" .
Same with maps. For the front-end - this is the folder "protected / views / frontend" , for the backend - "protected / views / backend" .
Actually, it looks like this:

Controllers

Obviously we do not want our controllers admin work as well as external controllers. For example, we want to put in the admin access filters only for certain user roles.
To raise noodle and not repeated in each controller with filters (DRY too!) - create the intermediate controllers - FrontEndController and BackEndController, which inherit from the base of the controller and put them in folder "protected / Components" . look of these controllers have something like this: 

FrontEndController.php:

class  FrontEndController  extends  BaseController
{
    / / layout
    Public  $ layout = 'Application' ;
         
    / / Menu
    Public  $ menu = array ();
     
    / / Crumbs
    Public  Breadcrumbs $ = array ();
}

BackEndController.php:

class  BackEndController  extends  BaseController
{
 
    / / Layout
    Public  $ layout = 'Application' ;
         
    / / Menu
    Public  $ menu = array ();
     
    / / Crumbs
    Public  Breadcrumbs $ = array ();
     
     
    / *
        Filters
    * /
    Public  function  Filters ()
    {
        return  array (
             'accessControl' ,
        );
    }
     
     
    / *
        Permissions
    * /
    Public  function  accessRules ()
    {
        return  array (
             / / give access only admins
            array (
                 'allow' ,
                 'roles' => array ( 'admin' ),
            )
                                    / / The rest are allowed to watch only the login page
            array (
                 'allow' ,
         'Actions' => array ( 'login' ),
         'users' => array ( '?' ),
      )
            / / Disable the rest
            array (
                 'deny' ,
                 'users' => array ( '*' ),
            )
        ); 
    }
}

In general, they are identical, except that BackEndController sells filters that are hidden from the prying eyes of our backend, allowing only try to get authorization. However, they may both have a common functionality and behavior, which if necessary can be created in BaseController, which they inherit. Personally, I do BaseController convenient shortcuts for different f-s, which are very often used: 

BaseController.php:

class  BaseController  extends  CController
{
    // Flash notice
    {
    }
     
    // Flash bug
    {
         
    }  
}

Well, after all is clear - all controllers that are in the "protected / controllers / backend" - inherit BackEndController . And those in the "protected / controllers / frontend" - FrontEndController .


Behavior

Now just tell how all this will work. To do this we create in the folder "protected / behaviors" new behavior -WebApplicationEndBehavior . Code it enough, as they say, straightforward. But in the comments yet, I will explain what and why. 

WebApplicationEndBehavior.php

class  WebApplicationEndBehavior  extends  CBehavior 
{
 
    / / Name of the desired part of the site to us
    Private  $ _endName ;
     
    / / Getter $ _endName;
    Public  function  getEndName ()
    {
        return  $ this -> _endName;
    }
     
    / / Run the application
    Public  function  runEnd ( $ name )
    {
        $ this -> _endName = $ name ;
         
        / / Process creation event module
        $ this -> onModuleCreate = array ( $ this , 'changeModulePaths' );
         $ this -> onModuleCreate ( New CEvent ( $ this -> Owner));
         
        $ This -> Owner-> run (); 
    }
     
    / / Event handler onModuleCreate
    Public  function  onModuleCreate ( $ Event )
    {
        $ this -> raiseEvent ( 'onModuleCreate' , $ Event ); 
    }
     
    / / Substitute the path to the files
    protected  function  changeModulePaths ( $ Event )
    {
        / / add the name of the site (frontend or backend) in the way in which framework will look for controllers and damper
        $ Event -> sender-> controllerPath. = DIRECTORY_SEPARATOR. $ this -> _endName;
         $ Event -> sender-> viewPath. = DIRECTORY_SEPARATOR. $ this -> _endName;
    }
         
}


Very simple. Call function runEnd ($ name) with the name of the site (frontend / backend) hangs handler onModuleCreate , then in the handler we substitute the path to the controllers and views after adding the needed "suffixes."
It remains only to add the component to the way in which framework will look for startup classes.
At «protected / config / main.php» add:
...
 / / used by the application

  )
)
...

Configuration

application configuration. To do this, create a separate configuration files in the folder "protected / config" - backend.php andfrontend.php .
They look something like this: backend.php

return CMap :: mergeArray (
 
    require_once (dirname (__FILE__). '/ main.php' ),
     
    array (
         
         
        / / Default controller
        'defaultController' => 'Posts' ,
         
        / / Components
        'Components' => array (
             
            / / User
            'User' => array (
                 'loginUrl' => array ( '/ users / login' ),
            )
 
    / /
     
    )
 
        )
    )
);

Bootstrap

Now we just have to adjust our input scripts. Here, I usually create two files in the root of the application - index.php andadmin.php . They contain the following code: index.php

// Path to the framework and necessary to us config
$ Yii = dirname (__FILE__). '/.. / Yii / framework / yii.php' ;
 $ config = dirname (__FILE__). '/ protected / config / frontend.php' ;
  
// Enable debug?
defined ( 'YII_DEBUG' ) or define ( 'YII_DEBUG' , true );
defined ( 'YII_TRACE_LEVEL' ) or define ( 'YII_TRACE_LEVEL' , 3 );
  
// Include the framework
require_once ( $ Yii );
// we start the application with the help of our WebApplicaitonEndBehavior, pointing out to him that you want to load the frontend
Yii :: createWebApplication ( $ config ) -> runEnd ( 'frontend' );

admin.php

// Path to the framework and necessary to us config
$ Yii = dirname (__FILE__). '/.. / Yii / framework / yii.php' ;
 $ config = dirname (__FILE__). '/ protected / config / backend.php' ;
  
// Enable debug?
defined ( 'YII_DEBUG' ) or define ( 'YII_DEBUG' , true );
defined ( 'YII_TRACE_LEVEL' ) or define ( 'YII_TRACE_LEVEL' , 3 );
  
// Include the framework
require_once ( $ Yii );
// we start the application with the help of our WebApplicaitonEndBehavior, pointing out to him that you want to load backend
Yii :: createWebApplication ( $ config ) -> runEnd ( 'backend' );

All are now turning to http://localhost/yourapp/index.php (or whatever your name is) - you'll be taken to the frontend website, referring to http://localhost/yourapp/admin.php - the application will load the administrative part. On my opinion, is very convenient - all clearly delineated, each part has its own settings, and keeps your controllers vyuha in separate folders without creating a hodgepodge of confusion and files. Actually, that's all I wanted to tell you about this very often occur in Many of the issues.Generally, Habré pretty no matter lit Yii. Although, for me personally - this is a clear issue number 1 of php-frameworks. So if you are interested in articles about Yii - hint in the comments.


No comments:

Yii Interview Question