Skip to content
This repository has been archived by the owner on Jan 30, 2020. It is now read-only.

Commit

Permalink
Merge branch 'feature/module-explicit-paths' of https://github.com/Ev…
Browse files Browse the repository at this point in the history
…anDotPro/zf2 into hotfix/pr-482
  • Loading branch information
weierophinney committed Oct 10, 2011
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 33 deletions.
125 changes: 92 additions & 33 deletions src/ModuleAutoloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ class ModuleAutoloader implements SplAutoloader
*/
protected $paths = array();

/**
* @var array An array of modulename => path
*/
protected $explicitPaths = array();

/**
* Constructor
*
Expand Down Expand Up @@ -56,50 +61,95 @@ public function autoload($class)
if (substr($class, -7) !== '\Module') {
return false;
}
$moduleClassPath = str_replace('\\', DIRECTORY_SEPARATOR, $class) . '.php';
$moduleName = substr($class, 0, -7);
if (isset($this->explicitPaths[$moduleName])) {
if ($classLoaded = $this->loadModuleFromDir($this->explicitPaths[$moduleName], $class)) {
return $classLoaded;
} elseif ($classLoaded = $this->loadModuleFromPhar($this->explicitPaths[$moduleName], $class)) {
return $classLoaded;
}
}

$moduleClassPath = str_replace('\\', DIRECTORY_SEPARATOR, $moduleName);

foreach ($this->paths as $path) {
$file = new SplFileInfo($path . $moduleClassPath);
if ($file->isReadable()) {
// Found directory with Module.php in it
require_once $file->getRealPath();
return $class;
$path = $path . $moduleClassPath;
if ($classLoaded = $this->loadModuleFromDir($path, $class)) {
return $classLoaded;
}
// No directory with Module.php, searching for phars
$moduleName = substr($class, 0, strpos($class, '\\'));
//$moduleName = substr($class, 0, strpos($class, '\\'));

// Find executable phars
$matches = glob($path . $moduleName . '.{phar,phar.gz,phar.bz2,phar.tar,phar.tar.gz,phar.tar.bz2,phar.zip}', GLOB_BRACE);
$executable = true;
$matches = glob($path . '.{phar,phar.gz,phar.bz2,phar.tar,phar.tar.gz,phar.tar.bz2,phar.zip,tar,tar.gz,tar.bz2,zip}', GLOB_BRACE);
if (count($matches) == 0) {
$matches = glob($path . $moduleName . '.{tar,tar.gz,tar.bz2,zip}', GLOB_BRACE);
$executable = false;
return false;
}
foreach ($matches as $phar) {
$file = new SplFileInfo($phar);
if ($file->isReadable() && $file->isFile()) {
if ($executable) {
// First see if the stub makes the Module class available
require_once $file->getRealPath();
if (class_exists($class)) {
return $class;
}
}
// No stub, or stub did not provide Module class; try Module.php directly
$moduleClassFile = 'phar://' . $file->getRealPath() . '/Module.php';
$file = new SplFileInfo($moduleClassFile);
if ($file->isReadable() && $file->isFile()) {
require_once $moduleClassFile;
if (class_exists($class)) {
return $class;
}
}
if ($classLoaded = $this->loadModuleFromPhar($phar, $class)) {
return $classLoaded;
}
}
}
return false;
}

/**
* loadModuleFromDir
*
* @param string $dirPath
* @param string $class
* @return mixed
* False [if unable to load $class]
* get_class($class) [if $class is successfully loaded]
*/
protected function loadModuleFromDir($dirPath, $class)
{
$file = new SplFileInfo($dirPath . '/Module.php');
if ($file->isReadable() && $file->isFile()) {
// Found directory with Module.php in it
require_once $file->getRealPath();
if (class_exists($class)) {
return $class;
}
}
return false;
}

/**
* loadModuleFromPhar
*
* @param string $pharPath
* @param string $class
* @return mixed
* False [if unable to load $class]
* get_class($class) [if $class is successfully loaded]
*/
protected function loadModuleFromPhar($pharPath, $class)
{
$file = new SplFileInfo($pharPath);
if (!$file->isReadable() || !$file->isFile()) {
return false;
}
if (strpos($file->getRealPath(), '.phar') !== false) {
// First see if the stub makes the Module class available
require_once $file->getRealPath();
if (class_exists($class)) {
return $class;
}
}
// No stub, or stub did not provide Module class; try Module.php directly
$moduleClassFile = 'phar://' . $file->getRealPath() . '/Module.php';
$file = new SplFileInfo($moduleClassFile);
if ($file->isReadable() && $file->isFile()) {
require_once $moduleClassFile;
if (class_exists($class)) {
return $class;
}
}
return false;
}

/**
* Register the autoloader with spl_autoload registry
*
Expand Down Expand Up @@ -129,8 +179,12 @@ public function unregister()
public function registerPaths($paths)
{
if (is_array($paths) || $paths instanceof Traversable) {
foreach ($paths as $path) {
$this->registerPath($path);
foreach ($paths as $module => $path) {
if (is_string($module)) {
$this->registerPath($path, $module);
} else {
$this->registerPath($path);
}
}
} else {
throw new \InvalidArgumentException(
Expand All @@ -146,17 +200,22 @@ public function registerPaths($paths)
* registerPath
*
* @param string $path
* @param string $moduleName
* @return ModuleLoader
*/
public function registerPath($path)
public function registerPath($path, $moduleName = false)
{
if (!is_string($path)) {
throw new \InvalidArgumentException(sprintf(
'Invalid path provided; must be a string, received %s',
gettype($path)
));
}
$this->paths[] = static::normalizePath($path);
if ($moduleName) {
$this->explicitPaths[$moduleName] = static::normalizePath($path);
} else {
$this->paths[] = static::normalizePath($path);
}
return $this;
}

Expand Down
11 changes: 11 additions & 0 deletions test/ModuleAutoloaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,15 @@ public function testInvalidPathsThrowsException()
$this->setExpectedException('InvalidArgumentException');
$loader->registerPaths(123);
}

public function testCanLoadModulesFromExplicitLocation()
{
$loader = new ModuleAutoloader(array(
'My\NonmatchingModule' => __DIR__ . '/_files/NonmatchingModule',
'PharModule' => __DIR__ . '/_files/PharModule.phar',
));
$loader->register();
$this->assertTrue(class_exists('My\NonmatchingModule\Module'));
$this->assertTrue(class_exists('PharModule\Module'));
}
}
7 changes: 7 additions & 0 deletions test/_files/NonmatchingModule/Module.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace My\NonmatchingModule;

class Module
{
}

0 comments on commit b8d20ea

Please sign in to comment.