I guess, we can add the setControllerMap() to all the 3 situations and
setModuleMap()/setControllerToModuleMap() to subdirectories/subdomain
situations to offer the maximum features to everyone.

Shekar



On 12/4/06, Shekar C Reddy <[EMAIL PROTECTED]> wrote:

 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