Back-trace:
http://www.nabble.com/Controllers-in-subdirectories-tf2746071s16154.html
http://www.nabble.com/Controllers-in-subdirectories-tf2746071s16154.html
I've hacked the Front, Dispatcher and Router classes of the standard
dispatcher/router to accomplish mapping subdomains to modules but it is too
messy because I had to extend 3 classes. Please sync the old router along
with the RewriteRouter when controllers-in-subdirectories changes are
incorporated in order to be able to over-ride the part of the code that
returns the module name in a clean way in the standard router. Here are some
ideas that are *generic* enough to not break backwards compatibility:
If the _subdirectories variable is set to true, the first parameter in the
basic router would be 'module', followed by controller and action
parameters. Or, if the set _domain variable is subtracted from the
HTTP_HOST, the remainder would be the subdomain which - in turn - would be
the module. Otherwise, the code would behave as it is now - controller
first, action next:
if ( $request->isSubdirectories())
{
$module = $path[0];
$controller = $path[1];
//
if ( $module )
$controller = $module . '_' . $controller;
//
$action = isset($path[2]) ? $path[2] : null;
}
else
{
$domain = $request->getDomain();
//
if ( $domain ) // Subdomain matching to module - more options
here
{
$module = remainder from subtracting $domain from
strtolower(HTTP_HOST) and the '.' separator
$controller = $path[0];
//
//////////////////////////////////
// THIS ARE VERY, VERY IMPORTANT!!
$moduleMap = $request->getModuleMap(); // Default:
'www' => ''
//
// Invokes a different controller
// Useful for eg: developing/testing a new controller (copy), etc.
$controllerMap = $request->getControllerMap();
//
// Exceptional controllers that 'modify' the $module
$controllerToModuleMap = $request->getControllerToModuleMap();
//////////////////////////////////
//
if ( isset( $controllerMap[ $controller ] )
$controller = $controllerMap[ $controller ]; // A different
controller
//
if ( isset( $moduleMap[ $module ] )
$module = $moduleMap[ $module ]; // Maybe the 'www', no
subdomain specified, etc.
elseif ( isset( $controllerToModuleMap[ $controller ] )
$module = $controllerToModuleMap[ $controller ]; // A different
module
//
if ( $module )
$controller = $module . '_' . $controller;
//
$action = isset($path[1]) ? $path[1] : null;
}
else // Old fashioned - no subdirectories or subdomains
{
$controller = $path[0];
$action = isset($path[1]) ? $path[1] : null;
}
}
The formatControllerName method should be ehnanced to ignore
directory-separators in the controller name:
public function formatControllerName($unformatted)
{
if ( $this->_subdirectories || $this->_domain )
{
$unformatted = str_replace(array('-', '_', '.'), ' ',
strtolower($unformatted));
$unformatted = preg_replace('[^a-z0-9 ]', ' ', $unformatted);
$unformatted = str_replace(' ', DIRECTORY_SEPARATOR,
ucwords($unformatted));
//
return $unformatted . 'Controller';
}
//
return ucfirst($this->_formatName($unformatted)) . 'Controller';
}
Further, the Zend::loadClass/loadFile methods could be duplicated in the
Zend_Controller_Dispatcher class that would ignore directory-separators in
controller names:
if ( $this->_subdirectories || $this->_domain )
{
self::loadClass($className, $this->_directory);
$className = str_replace( DIRECTORY_SEPARATOR, '_', $className );
}
else
Zend::loadClass($className, $this->_directory);
Here is another enhancement to improve performance in
Zend_Controller_Dispatcher::_dispatch() method that gets invoked twice
(regex) - once with $performDispatch false and the next time with true:
if ( $this->_className )
{
$className = $this->_className; // Second pass - $performDispatch
= true
$this->_className = '';
}
else // First pass - $performDispatch = false
{
$className = $this->formatControllerName($action->getControllerName());
$this->_className = $className; // *Store it to improve
performance by re-using this var next-time when $performDispatch is true! *
}
//
...
...
Maybe, there are better ways and ideas (refer to Rob's suggestion, too) in
this regard.
Excuse me if I referred to any obsolete classes.
http://framework.zend.com/issues/browse/ZF-617
Regards,
Shekar