Dingle Dork
Dingle Dork

Reputation: 21

Zend Controller Path with Sub Dirs

I'm Using Zend Framework 1.11.x

I'm using the standard directory layout... What I would like to do is have subdiretories in my controllers

controller
 --- MemberController.php

to be instead

controller
 --Member
    ---MemberController.php

When I add this directory structure, and then try to access the controller by doing something like this:

$this-url(array(controller=>'member'....)

it can not find the controller to create the url

How do i map this subdirectory? Do i have to put each and every sub directory path in the application.ini?

If so Is there a way to do it generically so that I can just put (which i currently have) the base path in the application.ini?

thanks

Upvotes: 2

Views: 2661

Answers (4)

Raghav Rach
Raghav Rach

Reputation: 4935

When you place a controller in a subdirectory, then you should change controller class name appended with FOLDER_NAME and _.

In your case the member controller class name would turn to

Member_MemberController

Then url to access this controller will be

SITE_PATH/Member_Member

Upvotes: 0

jmbertucci
jmbertucci

Reputation: 8234

I've just been dealing with this very question but I ran into a few problems. David Weinraub's answer leads to more information which had a comment then lead to page that had a credit that had the basic / simple way to doing this.

To avoid all that wrangling and to throw in some notes about Windows vs Linux, here's what I learned.

I want to simply organized some Admin controllers/actions in a sub-directory in my controllers directory such as this:

/application/controllers/
/application/controllers/admin/MyActionController.php

I didn't want to get involved with Modules. This isn't a huge project that will have all kinds of modules, I just want to organize Admin files a little better.

First, my development machine is Win7 with Apache. Our staging / Production machines are Linux (Debian-based).

The easiest solution is to simply create a custom route (I'll go over the route a little more below as to what it's doing for those unfamiliar with them). I do this in the bootstrap as such:

->addRoute('AdminRoute',
    new Zend_Controller_Router_Route('/admin/:action/*', array('controller'=>'Admin_Index', 'action'=>'index'))
)

NOTE

  • 'controller' => 'Admin_Index' uses capitol letters. While this works in this example, I found that this was a misunderstanding of how to properly declare router controller names. My next example will explain this.

I would then have this file in this directory:

/application/controllers/Admin/IndexController.php

and the Controller file would need the class name like this:

class Admin_IndexController extends Zend_Controller_Action
{
    ...
}

That's pretty straight forward.

Here's some issues I ran into. Windows and Linux are known for having case-sensitive issues. I believe Windows treats things as case-insensitive while Linux is case-sensitive.

Also, while my example above uses an Admin Controller class called "index", I actually had a Camel-Case class name such as "AdminIndexController.php".

This worked on Windows but caused problems on Linux. I'm still not 100% sure where this occurs but went through and debug-output some of the Standard Router processes and discovered that the Custom Router setup needed a specific format when setting up routes.

I believe when declaring your controller in the standard router, you use the URL naming convention for parsing, instead of the ZF class name convention. In other words, it would appear that the Router is case-insensitive so camel-casing wasn't properly telling the router where to find the router. Instead, I needed to use dashes (I was already using underscores).

So, if you want to have a file named like this:

/application/controllers/Admin/FooIndexController.php

you should declare your custom router like this:

->addRoute('AdminRoute',
    new Zend_Controller_Router_Route('/admin/:action/*', array('controller'=>'admin_foo-index', 'action'=>'index'))
)

and your controller class name name will be:

class Admin_FooIndexController extends Zend_Controller_Action
{
    ...
}

Custom router

To explain the customer router, it basically says that for any URL that starts with:

"/admin/"

Use the defined controller and action. I set the default controller to "admin_index" or "admin_foo-index" in the later example.

The part of the controller ":action/" is like a variable that tells ZF that something should be there are part of the URL. However, we can give it a default value, if it's left blank. Sort of like default arguments in programming functions.

In this case, I set 'action' => 'index'. By default, it will use the 'index' Action, if none is declared.

If a value is given, it will use that value instead. So, if someone uses the URL (assuming we're using the second example above):

/admin/users/

The router will use the controller/action

/application/controllers/Admin/FooIndexController.php
...
/* inside controller*/
function usersAction(){
    ...
}

Hopefully that helps a little. I just went though this troubleshooting processes and this is what I discovered and solved the issues I was having.

Cheers!

Upvotes: 1

David Weinraub
David Weinraub

Reputation: 14184

Robert Basic has written about this:

Grouping Zend Framework controllers in subdirectories

Upvotes: 1

aporat
aporat

Reputation: 5932

if you're considering grouping controllers together, you might be better off using the standard zend modular structure:

In the bootstrap you add the directory for each module:

 $frontController = Zend_Controller_Front::getInstance();

 $frontController->setControllerDirectory(array(
   'default' => APPLICATION_PATH . '/controllers',
  'blog'    => APPLICATION_PATH . '/blog/controllers'
  'api'    =>   APPLICATION_PATH . '/api/controllers'

));

It's easy to manage and maintain, because the modules are self contained and separated from each another. http://framework.zend.com/manual/en/zend.controller.modular.html

Upvotes: 2

Related Questions