Zend Framework - How routing is done in ZF 1.12? - zend-framework

I was going through the Zend document but I didn't get clear idea how routing is done in Zend framework 1.12.
What I understand from the document is when we hit the URL in the browser then request is going the index.php in public folder.
But I am not getting how Zend framework decomposes the URL and calls the particular controller and action.
Eg.
consider the URL: http://zendtutorial.local/blog/new
How Zend evaluates newAction from BlogController

When We hit the URL First following things happens:
Very first index.php in public directory gets called.
In Index.php the constants like APPLICATION_PATH, APPLICATION_ENV are defined and Application object gets created.
The settings in the application.ini file get initialized.
application.ini contains all the information like the default controller, default modules, database settings, etc.
Then the bootstrap function of Zend_Application gets called.
This function calls the Bootstrap class from bootstrap.php.
Then run() method of Zend_Application_Bootstrap_Bootstrap gets called.
Zend_Application_Bootstrap_Bootstrap :: run() method gets called.
Finally, dispatch() method of Zend_Controller_Front gets called.
dispatch() method routes the requested URL to specific controller and action.

Related

Zend_Application issue with extending Frontcontroller and using extended Frontcontroller application resource

I extended the Zend Frontcontroller with a personal one and also extended the frontcontroller application resource to use my personal front controller. All it basically does for the moment is assign the front variable within the application resource method getFrontController to my personal front controller. Lastly, I added the pluginpaths variable within application.ini to use my personal Application Resources. In any case, I'm getting the Zend Frontcontroller returned to me instead of my personal one. Anybody know why my personal application frontcontroller resource
isnt being used?
`
Since Zend_Controller_Front is a singleton, you will also need to override the getInstance() method to ensure it creates an instance of your class instead of the base class. You can just cut and paste the method to do this:
public static function getInstance()
{
if (null === self::$_instance) {
self::$_instance = new self();
}
return self::$_instance;
}

url not found in zend framework though working for index page

i am trying to develop website using zend framework so i had created one index.php file where all my requests goes and c.reated two controller one is IndexController and other is TestController
Class IndexController extends Zend_Controller_Action{
public function indexAction(){
echo "Index Index Jamla";
}
public function displayAction(){
echo "Index Display Jamla";
}
}
now when i access the url http://test/
it correctly calls IndexController and its IndexAction function
but when i access the url http://test/index/index
it displays the message url /index/index was not found on this server same it does when i access http://test/test/index
though http://test/ is equivalent to http://test/index/index
The rewrite rules for Zend Framework are not working.
http://test works because Apache is defaulting to run index.php which will run your application. The router will see no URL parameters so it routes to index controller index action. When you attempt to access anything else, Apache is handling the request and is not rewriting it to index.php so you are getting a 404 not found.
Make sure the .htaccess containing the rewrite rules is in your public folder. Also check that Apache allows processing of .htaccess files for your document root by setting AllowOverride All in httpd.conf and/or httpd-vhosts.conf.
Make sure that you have set AllowOverride to All in your Apache configuration and have enabled the mod_rewrite extension
Silly but can you recheck again either index.phtml file exists under views/scripts/index/

An explanation of the Zend Redirector Action Helper

Is there a comprehensive explanation of how the Zend Redirector Action Helper works? I've read the reference guide, but am still not 100% clear. For example:
Apparently the goToSimple() is more like a forward(), than a redirect. Does this mean that it won't send a redirect message back to the browser?
If I want to send a redirect message back to the browser, which Redirector method should I be using?
Is there a way to get the forward() type of behaviour, without re-executing the init() method of Action Helpers?
This problem cropped up when I was implementing an ACL. I have an ACL Action Helper and its init() method adds the role 'current'. When I use the redirector's goToSimple() I get an error saying that the role is already registered. I can use if (!$acl->hasRole('current')) however I think it would be preferable not to be re-executing the helper's init() in the first place.
Not too comprehensive just a few quick notes about the redirector.
The redirector does a little bit more than a regular PHP redirect which you would use with header('Location: www.domain.com/new/location') in your script--following by an exit().
If you look at Zend_Controller_Action_Helper_Redirector it ultimately does exactly the same; if $_exit==true (default) everything leads to redirectAndExit() which calls header() and ends with an exit() call. However it terminates the framework properly, mainly the session if any.
The redirector does not forward internally it sends a default 302 code back unless you have set another code with setCode().
Methods gotoRoute() and gotoSimple() assemble the destination URL for you and call redirectAndExit() but only if $_exit==true. Or you can use their brethren gotoRouteAndExit() and gotoSimpleAndExit() which will exit immediately. The gotoSimple methods pass on to setGotoSimple which uses some methods to assemble the URL for you.
In your case I can only assume that the setGotoSimple method and one of the methods in it call the destination controller and fire up the init() method; however, only for checking but not forwarding.

Zend Framework: Module Name in Bootstrap

I need to know how to get the current module name in the bootstrap file of my zend application. On the load of the page I'm doing a request to a webservice to get the current user information by sending a hashed cookie and a token. The problem is that I only need to do this in two of my 3 modules so i need to be able to ask for example.
if ($moduleName !== "filteredmodule"){
// do the request
}
Thanks.
Bootstrap is for getting the application ready. I suggest you do this kind of call in a Controller Plugin (which you can use to get the current called module) or in the init() function of your controller.
This is how to get the current module via controller plugin:
<?php
final class YourApp_Controller_Plugin_YourPluginName extends Zend_Controller_Plugin_Abstract {
public function preDispatch(Zend_Controller_Request_Abstract $request) {
$module = $request->getModuleName(); //This is the module
Docs: http://framework.zend.com/manual/en/zend.controller.plugins.html
One thing regarding Ashley's answer:
If you want to do
$module = $request->getModuleName();
as soon as possible, then do it in routeShutdown().
As the documentation states, "routeStartup() is called before Zend_Controller_Front calls on the router to evaluate the request against the registered routes. routeShutdown() is called after the router finishes routing the request."
So router dependant request parameters like module, controller, action or any other parameters specified in the route will be accessible in routeShutdown() and later functions.

Zend Controller Plugins vs Subclassing Action Controller

I've got a pretty standard ACL system in my application. There's a Login controller and a bunch of other controllers redirecting back to Login if user is not authorized. I use a Controller Plugin for checking the ID and redirecting and I obviously don't want Login controller and Error controller to perform such a redirect.
Now I've read several times that using Controller Plugins is a better practice than subclassing the Action Controller. Yet what I see is it's much easier to extend all my controllers from this abstract base controller class which performs the necessary checking in its init method, except for the Login controller which extends Zend_Controller_Action directly.
So the question is, is there a way to attach the plugin to the controllers selectively? Of course I can always make an array out of certain controllers, send it to a plugin through a setter method and do something like:
$controller = $request->getParam('controller');
if (count($this->exceptions))
if (in_array($controller, $this->exceptions)) return;
//...check ID, perform redirect, etc...
Yet something tells me it's not the best way doing it.
And advices?
EDIT 1: #Billy ONeal
Thank you for your reply, but I don't quite catch. I can do
public function init()
{
$this->getRequest()->setParam('dropProtection', true);
}
(or run some method that sets some private variable of the plugin) in my login controller, and then say if 'dropProtection' is not true then check the user ID. But the actual dispatch process looks like this:
Plugin::dispatchLoopStartup
Plugin::preDispatch
Controller::init
Plugin::postDispatch
Plugin::preDispatch
Plugin::postDispatch
Plugin::dispatchLoopShutdown
So I cannot check this 'dropProtection' param earlier than in Plugin::postDispatch and that's a bit late. (by the way, why the preDispatch and postDispatch are being called twice?)
If you want to do it earlier, I think you can use the first method (passing an array of exceptions to the plugin) and test the module name or the controller name in routeShutdown.
Personnaly I use an action helper to check the auth in all my actions. It's more flexible and give me more control. It's only one line for each private action.
And DON'T SUBCLASS your action controller. I did it on one of my project and now my base class is a piece of shit. Use action helper instead.
is there a way to attach the plugin to the controllers selectively?
Of course. Just don't register the plugin if the request doesn't contain the parameters you're looking for. Alternately, assume all pages are protected, and have those pages which should not be protected call some method on your plugin during the init stage.
If you want to protect just a single controller, you could reverse that -- have the plugin only take action if there's some method called during the init stage.
Finally, you could make the entire logged-in section of the page it's own module, which would allow you to have the plugin check for that module before checking credentials and redirecting.