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

Reply via email to