From: Chuck Hagenbuch Date: Sat, 24 Jan 2009 20:19:46 +0000 (-0500) Subject: add Horde_Controller_Scanner for processing controller directories in a way compatibl... X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=f2d82b66a546f56bb49b651c287ac325f5389f7f;p=horde.git add Horde_Controller_Scanner for processing controller directories in a way compatible with Horde_Controller_Dispatcher --- diff --git a/framework/Controller/lib/Horde/Controller/Dispatcher.php b/framework/Controller/lib/Horde/Controller/Dispatcher.php index 294b23e1e..46249a444 100644 --- a/framework/Controller/lib/Horde/Controller/Dispatcher.php +++ b/framework/Controller/lib/Horde/Controller/Dispatcher.php @@ -74,6 +74,13 @@ class Horde_Controller_Dispatcher $this->_controllerDir .= '/'; } + // Set the mapper's controller directory and controllerScan + if ($this->_controllerDir && !$this->_mapper->directory) { + $this->_mapper->directory = $this->_controllerDir; + } + $scanner = new Horde_Controller_Scanner($this->_mapper); + $this->_mapper->controllerScan = $scanner->getCallback(); + // Make sure views directory, if set, ends in a /. if ($this->_viewsDir && substr($this->_viewsDir, -1) != '/') { $this->_viewsDir .= '/'; diff --git a/framework/Controller/lib/Horde/Controller/Scanner.php b/framework/Controller/lib/Horde/Controller/Scanner.php new file mode 100644 index 000000000..57a2cf6ed --- /dev/null +++ b/framework/Controller/lib/Horde/Controller/Scanner.php @@ -0,0 +1,170 @@ + + * @author Derek DeVries + * @author Chuck Hagenbuch + * @license http://opensource.org/licenses/bsd-license.php + * @category Horde + * @package Horde_Controller + */ + +/** + * Horde_Routes_Mapper requires a list of all possible controller names + * in order to build the regular expressions it uses for matching routes. + * It uses a callback, controllerScan, to get this list. + * + * Depending on the routes connected to the mapper, it may be possible to + * determine all of the controller names from the routes themselves. If + * not, the filesystem must be scanned to determine the controller names. + * + * This class contains two controllerScan strategies, one that scans the + * filesystem and one that doesn't, and can determine the most efficient + * strategy to use for a given mapper. + * + * @author Mike Naberezny + * @author Derek DeVries + * @author Chuck Hagenbuch + * @license http://opensource.org/licenses/bsd-license.php + * @category Horde + * @package Horde_Controller + */ +class Horde_Controller_Scanner +{ + /** + * @var Horde_Routes_Mapper + */ + protected $_mapper; + + /** + * controllerScan strategy selected for this mapper. + * @var callback + */ + protected $_callback; + + /** + * Array of controller names collected from route hardcodes + * @var array + */ + protected $_controllers; + + + /** + * Constructor. Analyze the routes connected to this mapper to + * select a controllerScan strategy. + * + * @param Horde_Routes_Mapper + */ + public function __construct($mapper) + { + $this->_mapper = $mapper; + $this->analyze(); + } + + /** + * Analyze the routes connected to the mapper. If all of the possible + * controller names can be determined from the routes themselves, select + * the scanHardcodes() strategy that returns them collected from the + * routes. If the possible controller names cannot be determined this + * way, select the scanFilesystem() strategy. + */ + public function analyze() + { + $needScan = false; + $controllers = array(); + foreach ($this->_mapper->matchList as $route) { + if (in_array('controller', $route->hardCoded)) { + $controllers[ $route->defaults['controller'] ] = true; + } else { + $needScan = true; + break; + } + } + $this->_controllers = array_keys($controllers); + + if ($needScan || empty($this->_controllers)) { + $this->_callback = array($this, 'scanFilesystem'); + } else { + $this->_callback = array($this, 'scanHardcodes'); + } + } + + /** + * Get the controllerScan callback stategy selected for this mapper. + * + * @return callback + */ + public function getCallback() + { + return $this->_callback; + } + + /** + * Scan a directory and return an array of the controllers it contains. + * The array is used by Horde_Routes to build its matching regexps. + * + * @param string $dirname Controller directory + * @param string $prefix Prefix controllers found with string + * @return array Controller names + */ + public function scanFilesystem($dirname = null, $prefix = '') + { + $controllers = array(); + + if ($dirname === null) { + return $controllers; + } + + $baseregexp = preg_quote($dirname, '/'); + + foreach (new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($dirname)) as $entry) { + + if ($entry->isFile()) { + // match .php files that don't start with an underscore + if (preg_match('/^[^_]{1,1}.*\.php$/', basename($entry->getFilename())) != 0) { + // strip off base path: dirname/admin/users.php -> admin/users.php + $controller = preg_replace("/^$baseregexp(.*)\.php/", '\\1', $entry->getPathname()); + + // PrepareController -> prepare_controller -> prepare + $controller = strtolower(preg_replace('/([a-z])([A-Z])/', "\${1}_\${2}", $controller)); + $controller = substr($controller, 0, -(strlen('_controller'))); + + // add to controller list + $controllers[] = $prefix . $controller; + } + } + } + + $callback = array('Horde_Routes_Utils', 'longestFirst'); + usort($controllers, $callback); + + return $controllers; + } + + /** + * Return an array of controller names that were collected from the + * hardcodes of the routes connected to this mapper. + * + * @param string $dirname For method signature compatibility only + * @param string $prefix Prefix controllers found with string + * @return array Controller names + */ + public function scanHardcodes($dirname = null, $prefix = null) + { + if ($prefix === null) { + $controllers = $this->_controllers; + } else { + $controllers = array(); + foreach ($this->_controllers as $controller) { + $controllers[] = $prefix . $controller; + } + } + + usort($controllers, 'Horde_Routes_Utils::longestFirst'); + return $controllers; + } + +} \ No newline at end of file diff --git a/framework/Controller/package.xml b/framework/Controller/package.xml index 37cf42005..b2cc149ad 100644 --- a/framework/Controller/package.xml +++ b/framework/Controller/package.xml @@ -52,8 +52,9 @@ http://pear.php.net/dtd/package-2.0.xsd"> - + + @@ -74,8 +75,9 @@ http://pear.php.net/dtd/package-2.0.xsd"> - + +