ZF-55: Zend_Controller only works at "root-level": Zend_Controller_Front::setdispatcherBaseUri(); missing? (TRAC#79)

Description

http://framework.zend.com/developer/ticket/79

FILES AVAILABLE

hi guys,

tried out the controller and could not get it to work in a subdirectory on my webroot. (e.g. "/testing/") Zend_Controller thinks "testing" is my controller. i fixed it locally by adding:


2 Methodes: ============================================================================================================================ Zend_Controller_Front::setdispatcherBaseUri() & Zend_Controller_Dispatcher::setdispatcherBaseUri() /* just sets the given base-uri */ ============================================================================================================================

and adding 4 lines to: ============================================================================================================================ Zend_Controller_Router::route() /* takes the given (if any) base-uri and cuts the base-uri */ /* off the path, so controller & action work well */

(..) if ($dispatcher->getDispatcherBaseUri()) {

    $expr = "/" . preg_replace("/\//", "\\\/", $dispatcher->getDispatcherBaseUri() ) . "(.*)/"; $path = preg_replace($expr, "$1", $path); } (..)

============================================================================================================================

this is just a quick&dirty solution, but the feature of setting a base-uri for the controller/dispatcher is essential i think!

greets,

falk pauser

Comments

05/28/06 03:14:18: Modified by bruno.couleau@the-phocea-experiment.net

Hello,

I was a bit worried about this point two. After trying to fix this my self by writing my own Zend_Controller_Router class, I found an article by Rob Allen at http://akrabat.com/2006/03/… which include the source code to address this issue.

The changes over ZF code are minor, and it would be nice if the team could integrate them in the future.

Thanks you guys for all your efforts.

Bruno 06/12/06 06:40:23: Modified by Link stretch boots skechers shoes motorcycle boots sale buy phentermine keen shoes replica watches vintage luggage free shipping ugg boots stretch boots personalized luggage tag phentermine on line magnum boots pink motorcycle boots luggage locks work shoes citizens watches dansko shoes wholesale coach brand shoes and handbags cartier watches christian dior sunglasses 06/17/06 08:00:57: Modified by tolmi@lazycat.hu

* attachment Router.php.patch.htm added.

The patch solving the issue. I have tested it on 2 different webservers. 06/17/06 08:05:09: Modified by tolmi@lazycat.hu

I just now posted a patch against library/Controller/Router.php. It fixes the "root-level" requirement. Please apply this patch to the HEAD. Thanks for the great work, ZF devs!

-- Mark Tolmacs

With a RewriteRouter located in the incubator you should be able to use the module from within a subdirectory. Please, give it a try.

Zend Framework demos in subdirs!

This directory contains Web based, portable, Zend Framework demos I found on the Net and made work in any subdir below docroot!

IMPORTANT - Modify .htaccess in this directory

To make the demos work in subdirs below docroot, I first put my own quick'n'dirty fix in, but have since replaced this after discovering the RewriteRouter in the incubator of ZendFramework-0.1.4 which addresses this very issue!

The only pain I found in modifying the demos was, every internal link in a demo needs prepending with the baseUrl value and causes a bit of code clutter to bring the value in where needed.

In the index.php file I took the following approach:

// Register the controller because it is the only way I know to get at the RewriteRouter's GetRewriteBase() method from within my controllers Zend::register('controller', $controller);

// Use the new RewriteRouter from the incubator (ZendFramework-0.1.4) which allows us to run demos in subdirs below the webserver's docroot. require_once 'Zend/Controller/RewriteRouter.php'; $router = new Zend_Controller_RewriteRouter(); $controller->setRouter($router);

$controller->dispatch();

I then access the baseUrl value in my controllers with (or similar): $baseUrl = Zend::registry('controller')->getRouter()->getRewriteBase();

Is there a better way?

Mark Maynereid 5th July 2006

P.S.

This subdir below docroot feature is common amongst other frameworks. I've looked at plenty, and my interest in ZF nearly timed out when I found this wasn't supported already.

Surely, for a framework to gain and sustain popularity, you need to showcase what it can do with a whole bunch of 'real-world' ready-to-run demos? I know it's early days for ZF but still! I guess also, there should be some QA on them, before you know it ZF morphs into a CMS, errr... perhaps I shouldn't have said that.

Hi,

I've had a go at using the RewriteRouter. Don't know if I have done right but basically did as follows:

index.php:

// Register the controller because it is the only way I know to get at the RewriteRouter's GetRewriteBase() method from within my controllers Zend::register('controller', $controller);

// Use the new RewriteRouter from the incubator (ZendFramework-0.1.4) which allows us to run demos in subdirs below the webserver's docroot. require_once 'Zend/Controller/RewriteRouter.php'; $router = new Zend_Controller_RewriteRouter(); $controller->setRouter($router); $controller->dispatch();

I then access the baseUrl value in my controllers with (or similar): $baseUrl = Zend::registry('controller')->getRouter()->getRewriteBase();

Is there a better way?

I have made a my_demos directory of subdir-portable ZF demos that uses RewriteRouter (in ZendFramework-0.1.4 incubator) and attached it as a tar file to this Issue. Please download and inspect/comment on it.

Thanks, Mark Maynereid

For you to take a peek at and see if rewrite router solves it.

With the new RewriteRouter it's already possible to run the code from within webserver subdirectory. Subdirectory is automaticaly detected at object construction time so it should work out of the box.

Should the rewriteBase be detected incorrectly, you can override it with your own string by the means of setRewriteBase method of the RewriteRouter object.

Fixed in 0.1.5 with the new RewriteRouter moving to core. Old router will not allow this and will be replaced by the new router in a future release.

0.1.5 released

FYI I just installed 0.1.5, moved Zend.php and Zend/ over to a test application (replacing the 0.1.4 versions) and this did not work out of the box.

Trying to load in a subdirectory, brought me to IndexController::noRouteAction still. Unless I'm missing a setting, the above states "out of the box should work".

I'm using

$controller = Zend_Controller_Front::getInstance(); $controller->setControllerDirectory('./app/controllers'); $controller->dispatch();

You're not using a RewriteRouter, Mark. You're using the same router as before with that code.

Michael,

Thanks for the nudge in the right direction.

It took some serious grokage of the Zend_Controller_RewriteRouter document to figure out how to do multiple arguments in the URL. For those who need the info, this is what I finally came up with:

URL: http://example.com/test/view/… test = subdir view = controller foo = action id = name of var1 12 = value of var1 color= name of var2 blue = value of var2 name = name of var3 me = value of var3

In my case I wanted to create param variables $id, $name, $color ($color = $this->_getParam('color') etc...)

$router = new Zend_Controller_RewriteRouter(); $router->addRoute('view', 'view/foo/id/:id/color/:color/name/:name', array('controller' => 'view', 'action' => 'foo'));

So, essentially defining the entire possible path, and the parameters to assign values to. This then enables:

URL: http://example.com/test/view/ (controller = 'view', action = 'foo', $id is not set, $color is not set, $name is not set) URL: http://example.com/test/view/foo (controller = 'view', action = 'foo', $id is not set, $color is not set, $name is not set) URL: http://example.com/test/view/foo/id/12 (controller = 'view', action = 'foo', $id = 12, $color is not set, $name is not set) URL: http://example.com/test/view/foo/id/12/color (controller = 'view', action = 'foo', $id = 12, $color is not set, $name is not set) URL: http://example.com/test/view/foo/id/12/color/blue (controller = 'view', action = 'foo', $id = 12, $color = 'blue', $name is not set) URL: http://example.com/test/view/… (controller = 'view', action = 'foo', $id = 12, $color = 'blue', $name is not set) URL: http://example.com/test/view/… (controller = 'view', action = 'foo', $id = 12, $color = 'blue', $name = 'me')

Leaving out variables in the middle of the url will cause routing back to noRouteAction: URL: http://example.com/test/view/… (controller = 'index', action = 'noRoute', $id is not set, $color is not set, $name is not set)

Hopefully that's useful to others