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
