I answer to myself :)
So, matthew, i have followed your recommandations, and here is my new
"Widget" view helper implementation :
// I have noticed that i can prefix my class name as i want. Anyway.
class Zend_View_Helper_Widget
{
public function Widget($module=NULL, $controller=NULL, $action=NULL)
{
// Create a trash request, and set params
$request = new Zend_Controller_Request_Http();
$request->setParams(array('module'=>$module,
'controller'=>$controller, 'action'=>$action));
// Create a trash response
$response = new Zend_Controller_Response_Http();
//Create a new module dispatcher
$dispatcher = new Zend_Controller_ModuleDispatcher();
// I need that, because i dynamically add my controller
directories from database, in my dispatchLoopStartup plugin method.
// Tried in predispatch method, but did'nt work.
// It's pity that we have to manually add a controller directory
for each module we use...
$plugin = new My_Controller_Plugin();
$plugin->dispatchLoopStartup($request);
// Now that my controller directories are in my main controller
instance, i have to add them to my new module dispatcher
$controller = Zend_Controller_Front::getInstance();
foreach($controller->getControllerDirectory() as $module =>
$directory)
if ( $module != '0' )
$dispatcher->addControllerDirectory($directory, $module);
//Call the dispatch method
$dispatcher->dispatch($request, $response);
// Return response
return (string) $response;
}
}
I still don't want to subclass anything, as ZF mvc implementation is
still a "preview".
If you have few minutes (matthew, or anybody) to show us a
cleaner/proper/simpler way to call a module->controller->action in a
view context.
And also, why not, in an another action context.
Thanks !
i was also looking for such functionnality, plus, i wanted that particular
action could be called in a view context.
As it is not seems to be (yet ?) included, here is my temporary solution :
let's define a "Widget.php" helper :
class Zend_View_Helper_Widget
{
public function Widget($module=NULL, $controller=NULL, $action=NULL)
{
Zend::loadClass('Zend_Controller_Request_Http');
$Request = new Zend_Controller_Request_Http();
$Request->setModuleName($module);
$Request->setControllerName($controller);
$Request->setActionName($action);
$controller = Zend_Controller_Front::getInstance();
$controller->dispatch($Request);
}
}
I wouldn't do it this way. First off, you're possibly altering the state
of the current front controller instance and response object, which
could lead to unintended consequences. All you need is the dispatcher in
this case -- you've already set the module, controller, and action.
Change the internals to this:
$response = new Zend_Controller_Response_Http();
$dispatcher = new Zend_Controller_Dispatcher();
$dispatcher->dispatch($Request, $response);
return (string) $response;
(You need a response object to pass to the dispatcher's dispatch
method. Alternatively, you could subclass the dispatcher and provided a
convenience method that creates the response object and returns the
rendered output.)
My intention was to avoid subclassing at this time, waiting for the
framework is finished.
Anyway, i have already defined my controllers directories in the main
front controller instance ( $front->setControllerDirectory, and
$front->addControllerDirectory).
Correct me if i'm wrong, but if i instantiate a new dispatcher, as you do,
i lost all of these controller directories. And there not seem to be a
method to "grab" all of of them in a new dispatcher object.
So i got a beautiful "Fatal error: Uncaught exception 'Zend_Exception'
with message 'File "WidgetController.php" was not found." :)
I have also tried with the dispatcher object i use in the main front
controller. Same result.
$dispatcher = new Zend_Controller_ModuleDispatcher();
$front->setDispatcher($dispatcher);
...
$dispatcher->dispatch($Request, $Response);
(note : i'm using moduledispatcher an modulerouter, rev. 3009)
Behind all of this mess, as you say, and as i clearly realize, my approach
is not the good one. From far.
Instead of trying to make it works step by step, i'm really curious to see
how would you do to make a "pretty easy" implementation of partials in
zend_view (and, why not, in action context).
(really) Thanks for your job, and your answers.
PS : what do you need by "OP" ? Other Points ?
I'll reply to the OP in a separate response; it's pretty easy to
implement partials using Zend_View.
(Note : contrary to the reference manual, custom helpers MUST begin by
"Zend_View_Helper". Is it a bug ?)
The test suite indicates that you should be able to prefix helpers with
your own class prefix. You can do so with the following construct:
$view->addHelperPath($path, $classPrefix);
If this doesn't work for you, please report the issue on JIRA with the
minimum amount of code required to show it doesn't work.
I didn't know the parameter $classPrefix :) Now it's Ok.
But as far as i can see in the source, its not implemented in the
"__construct" method of "Zend_View_Abstract" :
// user-defined helper path
if (array_key_exists('helperPath', $config)) {
$this->addHelperPath($config['helperPath']);
}
maybe something like that :
// user-defined helper path
if (array_key_exists('helperPath', $config)) {
if (array_key_exists('helperclassPrefix', $config))
$this->addHelperPath($config['helperPath'],
$config['helperclassPrefix']);
else
$this->addHelperPath($config['helperPath']);
}
(and same for filter)