--- /dev/null
+<?php
+/**
+ * Provides a generic pattern for different mapping types within the application
+ * directory.
+ *
+ * @author Bob Mckee <bmckee@bywires.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @category Horde
+ * @package Horde_Autoloader
+ */
+class Horde_Autoloader_ClassPathMapper_Application implements Horde_Autoloader_ClassPathMapper
+{
+ protected $_appDir;
+ protected $_mappings = array();
+
+ /**
+ * The following constants are for naming the positions in the regex for
+ * easy readability later.
+ */
+ const APPLICATION_POS = 1;
+ const ACTION_POS = 2;
+ const SUFFIX_POS = 3;
+
+ const NAME_SEGMENT = '([0-9A-Z][0-9A-Za-z]+)+';
+
+ public function __construct($appDir)
+ {
+ $this->_appDir = rtrim($appDir, '/') . '/';
+ }
+
+ public function addMapping($classSuffix, $subDir)
+ {
+ $this->_mappings[$classSuffix] = $subDir;
+ $this->_classMatchRegex = '/^' . self::NAME_SEGMENT . '_' . self::NAME_SEGMENT . '_' .
+ '(' . implode('|', array_keys($this->_mappings)) . ')$/';
+ }
+
+ public function mapToPath($className)
+ {
+ if (preg_match($this->_classMatchRegex, $className, $matches)) {
+ return $this->_appDir . $this->_mappings[$matches[self::SUFFIX_POS]] . '/' . $matches[self::ACTION_POS] . '.php';
+ }
+ }
+
+ public function __toString()
+ {
+ return get_class($this) . ' ' . $this->_classMatchRegex . ' [' . $this->_appDir . ']';
+ }
+}
--- /dev/null
+<?php
+/**
+ * @category Horde
+ * @package Horde_Autoloader
+ */
+class Horde_Autoloader_ClassPathMapper_ApplicationTest extends PHPUnit_Framework_TestCase
+{
+ private $_mapper;
+
+ public function setUp()
+ {
+ $this->_mapper = new Horde_Autoloader_ClassPathMapper_Application(
+ 'app' // directory to app dir
+ );
+ $this->_mapper->addMapping('Suffix', 'subdir');
+ }
+
+ public function providerValidClassNames()
+ {
+ return array(
+ array('Module_Action_Suffix', 'app/subdir/Action.php'),
+ array('MyModule_Action_Suffix', 'app/subdir/Action.php'),
+ array('Module_MyAction_Suffix', 'app/subdir/MyAction.php'),
+ array('MyModule_MyAction_Suffix', 'app/subdir/MyAction.php'),
+ );
+ }
+
+ /**
+ * @dataProvider providerValidClassNames
+ */
+ public function testShouldMapValidAppClassToAppPath($validClassName, $classPath)
+ {
+ $this->assertEquals(
+ $classPath,
+ $this->_mapper->mapToPath($validClassName)
+ );
+ }
+
+ public function providerInvalidClassNames()
+ {
+ return array(
+ array('Module_Action_BadSuffix'),
+ array('module_Action_Suffix'),
+ array('Module_action_Suffix'),
+ array('Module-Action-Suffix'),
+ array(''),
+ );
+ }
+
+ /**
+ * @dataProvider providerInvalidClassNames
+ */
+ public function testShouldIgnoreInvalidAppClassNames($invalidClassName)
+ {
+ $this->assertNull($this->_mapper->mapToPath($invalidClassName));
+ }
+}