Skip to content
Browse files

Fix #236: Add support for class name prefixes when autoloading classe…

…s. With this, one can have class A_B_Class loaded from the file 'folder/Class.php' (using prefix 'A_B_') instead of as previously only 'folder/A/B/Class.php'.
  • Loading branch information...
1 parent 1bfce97 commit 92b489f73a4584d40f39064a8cf4f8c8d45f1402 @rawtaz rawtaz committed
View
28 Phergie/Autoload.php
@@ -31,6 +31,15 @@
class Phergie_Autoload
{
/**
+ * Prefixes to trim off of class names before trying to load their corresponding files.
+ * Using this, Autoload can support loading class A_B_C from file folder/C.php (using prefix 'A_B_') instead of just
+ * looking for it in the file folder/A/B/C.php.
+ *
+ * @var array
+ */
+ protected static $prefixes;
+
+ /**
* Constructor to add the base Phergie path to the include_path.
*
* @return void
@@ -52,11 +61,16 @@ public function load($class)
$paths = explode(PATH_SEPARATOR, get_include_path());
foreach ($paths as $path) {
- $fileName = $path . DIRECTORY_SEPARATOR
- . str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php';
+ $fileName = "$class.php";
+ if(isset(static::$prefixes[$path])) {
+ $prefix = preg_quote(static::$prefixes[$path]);
+ $fileName = preg_replace("{^$prefix}", '', $fileName);
+ }
+ $fileName = str_replace('_', DIRECTORY_SEPARATOR, $fileName);
- if (file_exists($fileName)) {
- include $fileName;
+ $filePath = $path . DIRECTORY_SEPARATOR . $fileName;
+ if (file_exists($filePath)) {
+ include $filePath;
if (class_exists($class, false)
|| interface_exists($class, false)
@@ -66,7 +80,7 @@ public function load($class)
throw new Phergie_Exception(
'Expected class ' . $class
- . ' in ' . $fileName . ' not found'
+ . ' in ' . $filePath . ' not found'
);
}
}
@@ -86,15 +100,17 @@ public static function registerAutoloader()
* Add a path to the include path.
*
* @param string $path Path to add
+ * @param string $prefix Prefix to trim off of the requested class name before trying to load the corresponding file
*
* @return void
*/
- public static function addPath($path)
+ public static function addPath($path, $prefix = null)
{
$includePath = get_include_path();
$includePathList = explode(PATH_SEPARATOR, $includePath);
if (!in_array($path, $includePathList)) {
set_include_path($path . PATH_SEPARATOR . get_include_path());
+ static::$prefixes[$path] = $prefix;
}
}
}
View
1 Phergie/Plugin/Handler.php
@@ -101,6 +101,7 @@ public function __construct(
if (!empty($config['plugins.paths'])) {
foreach ($config['plugins.paths'] as $dir => $prefix) {
$this->addPath($dir, $prefix);
+ Phergie_Autoload::addPath($dir, $prefix);
}
}
View
5 Tests/Phergie/Autoload/_PrefixRemovedFromClassFileNameTest/Class.php
@@ -0,0 +1,5 @@
+<?php
+
+class Phergie_Prefixed_Class
+{
+}
View
17 Tests/Phergie/AutoloadTest.php
@@ -199,6 +199,23 @@ class_exists('Phergie_Missing_Class', true);
}
/**
+ * Tests that the autoloader strips off prefixes given to addPath() from class names before trying to find their
+ * corresponding files. If it fails to do that, the class in this test shouldn't be loaded.
+ *
+ * @return void
+ */
+ public function testRemovesPrefixFromClassFileName()
+ {
+ // Fake environment and register autoloader
+ $path = dirname(__FILE__) . '/Autoload/_PrefixRemovedFromClassFileNameTest';
+ Phergie_Autoload::registerAutoloader();
+
+ Phergie_Autoload::addPath($path, 'Phergie_Prefixed_');
+
+ $this->assertTrue(class_exists('Phergie_Prefixed_Class', true));
+ }
+
+ /**
* Prevents preservation of global state in cases where test methods
* must be run in separate processes.
*

0 comments on commit 92b489f

Please sign in to comment.
Something went wrong with that request. Please try again.