Yii Framework Forum: Separation of admin controllers from public controllers - Yii Framework Forum

Jump to content

  • (2 Pages)
  • +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic

Separation of admin controllers from public controllers Handy little technique Rate Topic: ***-- 1 Votes

#1 User is offline   mindplay 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 397
  • Joined: 03-September 09
  • Location:New York

Posted 03 August 2010 - 12:49 PM

We've started separating our admin controllers from our public controllers, for a couple of reasons:

  • Separation of concerns
  • Distinction: have our admin URLs display as "http://site.com/admin/..." by convention.
  • Security: separating admin controllers from public controllers simplifies access control.
  • Performance: admin controllers tend to be heavier than public controllers - by separating them, we avoid loading up a bunch of admin-actions when running a public action.


By following a naming convention for admin and public controllers, we end up with controller names like these:

  • UserController
  • UserAdminController
  • PageController
  • PageAdminController
  • etc.


Now for the clever bit. Rather than adding a route for each of the admin controllers, we simply do this:

'urlManager'=>array(
  'urlFormat'=>'path',     // use "path" format, e.g. "post/show?id=4" rather than "r=post/show&id=4"
  'showScriptName'=>false, // do not show "index.php" in URLs
  'appendParams' => false, // do not append parameters as name/value pairs (DO NOT CHANGE THIS)
  'rules'=>array(
    'admin/<controller:\w+>'=>'<controller>Admin/index',
    'admin/<controller:\w+>/<id:\d+>'=>'<controller>Admin/view',
    'admin/<controller:\w+>/<id:\d+>/<action:\w+>'=>'<controller>Admin/<action>',
    'admin/<controller:\w+>/<action:\w+>'=>'<controller>Admin/<action>',
    
    '<controller:\w+>'=>'<controller>/index',
    '<controller:\w+>/<id:\d+>'=>'<controller>/view',
    '<controller:\w+>/<id:\d+>/<action:\w+>'=>'<controller>/<action>',
    '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
  ),
),



I'm sure some of you had already figured this out, but this idea was new to me - thought I'd share it :-)
3

#2 User is offline   samdark 

  • Having fun
  • Yii
  • Group: Yii Dev Team
  • Posts: 3,781
  • Joined: 17-January 09
  • Location:Russia

Posted 03 August 2010 - 01:26 PM

There are other possible approaches.

Personally, I'm grouping admin controllers with the same names as non-admin ones into admin module of the same application.

Also you can separate application into frontend and backend applications.
Yii 1.1 Application Development Cookbook

Enjoying Yii? Star us at github: 1.1 and 2.0.
0

#3 User is offline   Kheang Hok Chin 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 53
  • Joined: 12-August 10
  • Location:Gatineau, Qc (CANADA)

Posted 12 August 2010 - 08:51 AM

What would be the other methods of seperating the controllers for public and backend?

What I would like to have would be all the public controllers in the controllers folder and maybe a sub folder for the admin controllers.

Here is what I would like to accomplish:

Right now by default when I go to the index.php page it loads the SiteController.php and renders the index view.

What I would like is when I type index.php/admin/ it would load views/admin/index.php

I have tried to add in the rules:

'admin'=>'admin/index',	


And I had to create an admin/IndexController.php

This is the path that I am returned:

echo $this->getViewPath().'<br />'.$this->getRoute(); echo '<br />'.dirname(__FILE__).DIRECTORY_SEPARATOR.'..';

\protected\views/admin/index
admin/index/index
\protected\controllers\admin\..



Is the route ok? I don't understand..
Is there any more documentation on how we can achieve this somewhere?

Oh I just understood your approach of creating an application for frontend and backend, meaning I could have say:

Root being the frontend and in a subfolder say admin/ would be the backend application?

Would this be the best way to go or can we achieve similar structure but having only 1 application with subfolders for controllers, themes, etc..

I was thinking of 1 application with the public controllers in the controllers root dir and having a sub dir for admin/.

Then having frontend/ backend/ with their own theme folders in the themes folder.
Example:

themes/frontend/classic themes/backend/classic

And being able to tell the group of controllers say admin/* all controllers of admin use admin.php config instead of main.php.

Can this be achieved?

Any help is appreciated.
0

#4 User is offline   mindplay 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 397
  • Joined: 03-September 09
  • Location:New York

Posted 12 August 2010 - 06:37 PM

View Postsamdark, on 03 August 2010 - 01:26 PM, said:

There are other possible approaches.

Personally, I'm grouping admin controllers with the same names as non-admin ones into admin module of the same application.

Also you can separate application into frontend and backend applications.


Ahh, because controllers don't autoload, this is actually possible - never thought of that. So you have, say, a ProductController class in your main app, but then you have an admin module with a different ProductController as well?

The only downside to that, is it could get kind of confusing if you have both ProductController classes open in two tabs (in your editor/IDE) at the same time...
0

#5 User is offline   samdark 

  • Having fun
  • Yii
  • Group: Yii Dev Team
  • Posts: 3,781
  • Joined: 17-January 09
  • Location:Russia

Posted 13 August 2010 - 03:23 AM

I do have paths in my IDE ;)
Yii 1.1 Application Development Cookbook

Enjoying Yii? Star us at github: 1.1 and 2.0.
0

#6 User is offline   mindplay 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 397
  • Joined: 03-September 09
  • Location:New York

Posted 14 August 2010 - 08:40 AM

View Postsamdark, on 13 August 2010 - 03:23 AM, said:

I do have paths in my IDE ;)


On the tab headers? What IDE?
0

#7 User is offline   samdark 

  • Having fun
  • Yii
  • Group: Yii Dev Team
  • Posts: 3,781
  • Joined: 17-January 09
  • Location:Russia

Posted 14 August 2010 - 08:57 AM

On hovering tabs. IDE is PhpStorm.
Yii 1.1 Application Development Cookbook

Enjoying Yii? Star us at github: 1.1 and 2.0.
0

#8 User is offline   mbi 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 608
  • Joined: 08-May 09

Posted 14 August 2010 - 02:35 PM

my approach is to create a submodule for every module that needs an admin area
0

#9 User is offline   jonah 

  • Advanced Member
  • Yii
  • Group: Yii Dev Team
  • Posts: 733
  • Joined: 27-November 08
  • Location:California (US)

Posted 14 August 2010 - 02:54 PM

For a client I am doing something similar to this: http://www.yiiframew...oc/cookbook/33/

Only my folder structure is more like this:

	index.php
	assets/
	protected/
		config/
			main.php
		components/
		controllers/
		models/
		views/
	backend/
		index.php
		assets/
		protected/
			config/
				main.php
			components/
			controllers/
			models/
			views/


I have it so my backend can "see" (load classes from) the front-end, while the front-end can NOT see the backend. The top of my backend config file looks like this:

//points to front end.
$frontend = dirname(dirname(dirname(dirname(__FILE__)))).DIRECTORY_SEPARATOR.'protected';
Yii::setPathOfAlias('frontend',$frontend);

define('IS_FRONTEND',false);


And the import config option looks like this:

	// autoloading model and component classes
	'import'=>array(
		'application.models.*',
		'frontend.models.',
		'application.components.*',
		'frontend.components.*',
	),

http://php-thoughts.cubedwater.com - my bloggings about Yii
4

#10 User is offline   mindplay 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 397
  • Joined: 03-September 09
  • Location:New York

Posted 14 August 2010 - 03:05 PM

Jonah, I like that approach - gives a nice insulation between the back-end and front-end. Good thinking.
0

#11 User is offline   Y!! 

  • Advanced Member
  • Yii
  • Group: Yii Dev Team
  • Posts: 978
  • Joined: 18-June 09

Posted 14 August 2010 - 03:18 PM

I use modules only. I use the 1st level of the protected folder for all the shared data/components.

- components
   - Controller.php
- modules
   - backend
      - components
         - BackendController.php
   - frontend
      - components
         - FrontendController.php

0

#12 User is offline   Samuel K. 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 7
  • Joined: 28-November 10

Posted 15 December 2010 - 02:47 PM

View PostY!!, on 14 August 2010 - 03:18 PM, said:

I use modules only. I use the 1st level of the protected folder for all the shared data/components.

- components
   - Controller.php
- modules
   - backend
      - components
         - BackendController.php
   - frontend
      - components
         - FrontendController.php



What is the advantage of this approach? and over an above what jonah's approach.

How would be the 'outside' module Controller.php configured to communicate with backend and frontend?
...
I changed a moment ago
0

#13 User is offline   Y!! 

  • Advanced Member
  • Yii
  • Group: Yii Dev Team
  • Posts: 978
  • Joined: 18-June 09

Posted 15 December 2010 - 03:33 PM

View PostSamuel K., on 15 December 2010 - 02:47 PM, said:

What is the advantage of this approach? and over an above what jonah's approach.

How would be the 'outside' module Controller.php configured to communicate with backend and frontend?


I guess it's just a personal preference rather than real advantage. When you go with that approach you can call $this->getModule() within the controller of the main module (e.g. frontend module). This is not possible when you go with the traditional approach (because CWebApplication is the parent of a controller, not a CWebModule). Also you can override beforeControllerAction() within the frontend module. CWebApplication offers this method as well, but you would've to extend CWebApplication.

The Controller.php is considered shared and will be imported within the main config file. So the idea behind this approach is:

- The traditional main application does only exist now to share components, views, etc. across the modules. It won't have any actual Controller which users can access.

- frontend & backend are seperated - each module can set it's own special config within CWebModule::init() if needed.

But this approach also leads to some problems. For example if you're within the frontend and you want to create a backend url, you may do

Yii::app()->getModule('backend')->urlManager->createUrl();


But as soon as you access another module, the CWebModule::init() method of that module will run. Means if you set a global app component just for the backend module within init(), it may now overwrite a global app component previously set by the frontend module. Though it's possible to set application components for each module directly, but this is not fully supported.

I hope we see enhanced module system in Yii 2.
1

#14 User is offline   Samuel K. 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 7
  • Joined: 28-November 10

Posted 19 December 2010 - 05:09 AM

View PostY!!, on 15 December 2010 - 03:33 PM, said:

I guess it's just a personal preference rather than real advantage. When you go with that approach you can call $this->getModule() within the controller of the main module (e.g. frontend module). This is not possible when you go with the traditional approach (because CWebApplication is the parent of a controller, not a CWebModule). Also you can override beforeControllerAction() within the frontend module. CWebApplication offers this method as well, but you would've to extend CWebApplication.

The Controller.php is considered shared and will be imported within the main config file. So the idea behind this approach is:

- The traditional main application does only exist now to share components, views, etc. across the modules. It won't have any actual Controller which users can access.

- frontend & backend are seperated - each module can set it's own special config within CWebModule::init() if needed.

But this approach also leads to some problems. For example if you're within the frontend and you want to create a backend url, you may do

Yii::app()->getModule('backend')->urlManager->createUrl();


But as soon as you access another module, the CWebModule::init() method of that module will run. Means if you set a global app component just for the backend module within init(), it may now overwrite a global app component previously set by the frontend module. Though it's possible to set application components for each module directly, but this is not fully supported.

I hope we see enhanced module system in Yii 2.

Thanks I will try the approach.
...
I changed a moment ago
0

#15 User is offline   pcs2112 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 79
  • Joined: 31-July 10

Posted 04 February 2011 - 12:59 AM

View Postsamdark, on 14 August 2010 - 08:57 AM, said:

On hovering tabs. IDE is PhpStorm.


awesome IDE, i guess no more eclipse for me.
0

#16 User is offline   rAWTAZ 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 102
  • Joined: 08-January 10

Posted 14 March 2011 - 01:07 PM

View Postmbi, on 14 August 2010 - 02:35 PM, said:

my approach is to create a submodule for every module that needs an admin area

I'm a little confused. Did you mean to write "a submodule for every model that needs an admin area"?
0

#17 User is offline   samdark 

  • Having fun
  • Yii
  • Group: Yii Dev Team
  • Posts: 3,781
  • Joined: 17-January 09
  • Location:Russia

Posted 14 March 2011 - 01:34 PM

rAWTAZ, a module can have a submodule.
Yii 1.1 Application Development Cookbook

Enjoying Yii? Star us at github: 1.1 and 2.0.
0

#18 User is offline   alisherdavronov 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 3
  • Joined: 14-August 11

Posted 21 September 2011 - 08:40 AM

Hi guys!

What about real modules?
For example module news, or articles or whatever.
Module must have all its contents in one folder, including admin part.
And to implement features of that module a man must only copy that folder to any project.

thanks to any reply
0

#19 User is offline   kunalroy85 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 5
  • Joined: 16-November 11

Posted 28 January 2012 - 07:34 AM

View Postjonah, on 14 August 2010 - 02:54 PM, said:

For a client I am doing something similar to this: http://www.yiiframew...oc/cookbook/33/

Only my folder structure is more like this:

	index.php
	assets/
	protected/
		config/
			main.php
		components/
		controllers/
		models/
		views/
	backend/
		index.php
		assets/
		protected/
			config/
				main.php
			components/
			controllers/
			models/
			views/


I have it so my backend can "see" (load classes from) the front-end, while the front-end can NOT see the backend. The top of my backend config file looks like this:



I have been looking out for the approaches to create and encapsulate admin section separately. This is probably the nicest way to do it. But how would I be able to use the same modules in the frontend here? Lets say if I want to use the same gii module, is that possible using the url like:
www.site.com/backend/gii/controller
I tried this and it shows 404.

I have merged the config file for the backend like follows:
CMap::mergeArray(
    require( $frontend .'/config/main.php'),
    array(
        
        'name' => 'Administration',
        'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..',
        'theme' => 'newtheme',
        'import'=>array(
                'frontend.models.',
                'frontend.components.*',
        ),
    )
);


Thanks!

EDIT::
I figured out why gii was not working. It was because there was no htaccess file placed inside the backend folder. So all the requests were going to the frontend for anything that said /backend/<controller>
I am trying out further to see what else can or cannot be used. Thank you all for the tips in this post!!

This post has been edited by kunalroy85: 28 January 2012 - 08:38 AM

0

#20 User is offline   mmx 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 64
  • Joined: 20-June 11
  • Location:Virginia Beach, VA USA

Posted 30 January 2012 - 08:27 PM

View Postkunalroy85, on 28 January 2012 - 07:34 AM, said:

I have been looking out for the approaches to create and encapsulate admin section separately.


Some time back, Qiang posted a nice tutorial on the wiki to show how he created the directory structure for larger applications as well as the Yii site. As I recall, something like this.

/<application name>/
     /admin/
     /common/
     /console/
     /public/


The tutorial describes how to move files from a standard install into the console and common directories. It also provides tips of configuring your main.php files to handle the directory structure, assuming you already read the Yii docs.

I use a variant of this:

/<applicationname>/
      /admin/
      /common/
      /console/
      /public/
      /www/
          /admin/
              /assets/
              /css/
              /images/
              /js/
              /themes/
                  /default/
                  /classic/
              index.php
              .htaccess
          /public/
              (same structure as admin)


What the tutorial does not mention is creating .htaccess files to convert those four directories to the equivalent of the old /protected/ directory (just move the /protected/ .htaccess to /admin/, /console/, /common/, and /public/. /www/admin/ and /www/public/ above need their own web accessible .htaccess.

I found this to be the best solution of all of my own projects. Many of my projects tend to start off small or intermediate in size and gradually grow into monsters over time as customer wants to add more and more bells and whistles.

A lot of my customers want their admin installed either on separate domains with access to the same database server, so the above works really well.

The other advantage of the above structure allows the creation of a development site that can be removed when putting your site online. I use this for handling some profiling requirements, setting public site constants, temporary file related constants, etc. It's basically an Admin interface with some additional modules.

Still another advantage if you need to support Apache's mod_rewrite module, additional directory structures can be created for individual subdomains.

I found Qiang's solution to be very extensible for my own needs as well as the needs of customers because it leaves room to grow. You lose nothing by setting your directory structure up to handle needs you or your customer might not know about immediately.
0

Share this topic:


  • (2 Pages)
  • +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users