📜 ⬆️ ⬇️

Method of separating frontend / backend parts in Yii

What am I talking about?


I want to tell you a little about how I divide the front-end / back-end parts of the site in all my projects on Yii. I do not pretend to authorship of this method, I just want to explain a little what is organized and how it works.

Actually, almost always the project cannot consist only of a frontend (that is, what the visitor sees). It is often necessary to organize the administrative part, while having painless access to all components of the project (models, extensions, etc.).

There are several ways to achieve this. I will not go into the details of each of them, if you are interested - you can search the forum yiiframework.com .
The most elegant and convenient option seemed to me using my “behavior” of launching the application. It makes it very convenient to separate the application in terms of a directory, use different configs for each part of the site, etc.

')
If you are familiar with Yii, you should know that it implements so-called behaviors that allow you to change or supplement the functionality and behavior of different components. Most often they are used in conjunction with models, but in our case it is proposed to use behaviors directly to start the application.

Directories


First, let's define the directories. Let's agree on the fact that the controllers of the user part of the site (frontend) are stored in the folder “protected / controllers / frontend” . It is logical that we will store admin controllers in the “protected / controllers / backend” folder.
The same with mappings. For the frontend, this is the “protected / views / frontend” folder, for the backend it is the “protected / views / backend” folder.
In fact, it looks like this:
image

Controllers


Obviously, we do not want our admin controllers to work as well as external controllers. For example, we want to put in the admin access filters only for certain user roles.
In order not to breed noodles and not to repeat in each controller with filters (DRY is the same!) - create intermediate controllers - FrontEndController and BackEndController, which we will inherit from the base controller and place them in the “protected / components” folder.

These controllers should look like this:

FrontEndController.php:
class FrontEndController extends BaseController { //  public $layout = 'application'; //  public $menu = array(); //  public $breadcrumbs = array(); } 


BackEndController.php:
 class BackEndController extends BaseController { //  public $layout = 'application'; //  public $menu = array(); //  public $breadcrumbs = array(); /*  */ public function filters() { return array( 'accessControl', ); } /*   */ public function accessRules() { return array( //     array( 'allow', 'roles'=>array('admin'), ), //         array( 'allow', 'actions'=>array('login'), 'users'=>array('?'), ), //    array( 'deny', 'users'=>array('*'), ), ); } } 


In general, they are identical, except that BackEndController implements filters that hide our backend from prying eyes, allowing only to try to pass authorization. At the same time, they both can have common functionality and behavior, which, if necessary, can be created in BaseController, which they inherit.

Personally, I in BaseController make convenient shortcuts for various functions, which are very often used:

BaseController.php:
 class BaseController extends CController { // -  public function setNotice($message) { return Yii::app()->user->setFlash('notice', $message); } // -  public function setError($message) { return Yii::app()->user->setFlash('error', $message); } } 


Well, then everything is clear - all controllers that are in the “protected / controllers / backend” inherit BackEndController . Those that are “protected / controllers / frontend” are FrontEndController .

Behavior


Now I’ll tell you directly how it will work. To do this, we create a new behavior in the “protected / behaviors” folder - WebApplicationEndBehavior . Its code is enough, as they say, straightforward. But in the comments still explain what and why.

WebApplicationEndBehavior.php
 class WebApplicationEndBehavior extends CBehavior { //      private $_endName; //  $_endName; public function getEndName() { return $this->_endName; } //   public function runEnd($name) { $this->_endName = $name; //     $this->onModuleCreate = array($this, 'changeModulePaths'); $this->onModuleCreate(new CEvent ($this->owner)); $this->owner->run(); } //   onModuleCreate public function onModuleCreate($event) { $this->raiseEvent('onModuleCreate', $event); } //     protected function changeModulePaths($event) { //     (frontend  backend)  ,         $event->sender->controllerPath .= DIRECTORY_SEPARATOR.$this->_endName; $event->sender->viewPath .= DIRECTORY_SEPARATOR.$this->_endName; } } 


Very simple. Calling the runEnd function ($ name) with the name of a part of the site (frontend / backend) hangs the onModuleCreate event handler , then in the handler we change the path to the controllers and mappings, adding the “suffixes” we need.
It remains only to add this component to the path that the framework will look for classes for autoloading.
In "protected / config / main.php" add:
 ... //    'behaviors'=>array( 'runEnd'=>array( 'class'=>'application.behaviors.WebApplicationEndBehavior', ), ), ... 


Configuration


It will be very useful to separate our parts of the site not only at the folder location level, but also at the application configuration level. To do this, we create separate configuration files in the “protected / config” folder - backend.php and frontend.php .
They look like this:
backend.php
 return CMap::mergeArray( require_once(dirname(__FILE__).'/main.php'), array( //   'defaultController' => 'posts', //  'components'=>array( //  'user'=>array( 'loginUrl'=>array('/users/login'), ), // mailer 'mailer'=>array( 'pathViews' => 'application.views.backend.email', 'pathLayouts' => 'application.views.email.backend.layouts' ), ), ) ); 


With the front end as well.
For example, this is how my configs folder looks like:
image

Bootstrap


Now we just need to customize our input scripts. Here I usually create two files in the application root - index.php and admin.php . The code they contain is as follows:

index.php
 //        $yii = dirname(__FILE__).'/../yii/framework/yii.php'; $config = dirname(__FILE__).'/protected/config/frontend.php'; //  ? defined('YII_DEBUG') or define('YII_DEBUG', true); defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL', 3); //   require_once($yii); //      WebApplicaitonEndBehavior,  ,     Yii::createWebApplication($config)->runEnd('frontend'); 


admin.php
 //        $yii = dirname(__FILE__).'/../yii/framework/yii.php'; $config = dirname(__FILE__).'/protected/config/backend.php'; //  ? defined('YII_DEBUG') or define('YII_DEBUG', true); defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL', 3); //   require_once($yii); //      WebApplicaitonEndBehavior,  ,     Yii::createWebApplication($config)->runEnd('backend'); 


Everything, now referring to http: //localhost/yourapp/index.php (or whatever you are there) - you will be taken to the front end of the site, referring to http: //localhost/yourapp/admin.php - the application will load the administrative part.

In my opinion, it comes out very conveniently - everything is clearly demarcated, each part has its own settings, stores its controllers and views in separate folders, without creating confusion and confusion in the files.

Actually, this is all that I wanted to tell you on this very common question for many.

In general, the Habré is quite not important illuminated Yii. Although, for me personally, this is the clear number 1 among php frameworks. So if you are interested in articles about Yii - hint in the comments.

Source: https://habr.com/ru/post/117457/


All Articles