Skip to content

Commit

Permalink
Added composer.json parsing support
Browse files Browse the repository at this point in the history
  • Loading branch information
theseer committed Aug 8, 2014
1 parent 93db58c commit beda4a7
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 0 deletions.
156 changes: 156 additions & 0 deletions src/ComposerIterator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
<?php
namespace TheSeer\Autoload {

class ComposerIterator implements \Iterator {

/**
* @var array
*/
private $directories = array();

private $pos = 0;

public function __construct(\SplFileInfo $composerFile) {
if (!$composerFile->isFile() && $composerFile->isReadable()) {
throw new ComposerIteratorException(
sprintf('Composer file "%s" not found or not readable', $composerFile->getPathname()),
ComposerIteratorException::InvalidComposerJsonFile
);
}
$composerDir = dirname($composerFile->getRealPath());
$composerData = json_decode(file_get_contents($composerFile->getRealPath()), true);
if (isset($composerData['require'])) {
foreach($composerData['require'] as $require => $version) {
if ($require == 'php' || strpos($require, 'ext-') === 0) {
continue;
}
$this->processRequire($composerDir, $require);
}
}
if (isset($composerData['autoload'])) {
$this->processAutoload($composerDir, $composerData['autoload']);
} else {
$this->addDirectory($composerDir);
}
}

private function processAutoload($baseDir, array $map) {
if (isset($map['classmap'])) {
foreach($map['classmap'] as $dir) {
$this->addDirectory($baseDir . '/' . $dir);
}
}
if (isset($map['psr-0'])) {
foreach($map['psr-0'] as $node => $dir) {
if ($dir === '') {
$this->addDirectory($baseDir);
continue;
}
$this->addDirectory($baseDir . '/' . $dir);
}
}
}

private function processRequire($basedir, $require) {
$requireDir = $basedir . '/vendor/' . $require;
$jsonFile = $this->findComposerJson($requireDir);
$jsonData = json_decode(file_get_contents($jsonFile), true);

if (isset($jsonData['require'])) {
foreach($jsonData['require'] as $require => $version) {
if ($require == 'php' || strpos($require, 'ext-') === 0) {
continue;
}
$this->processRequire($basedir, $require);
}
}

if (isset($jsonData['autoload'])) {
$this->processAutoload($requireDir, $jsonData['autoload']);
return;
}
$this->addDirectory($requireDir);
}

private function findComposerJson($dir) {
if (file_exists($dir . '/composer.json')) {
return $dir . '/composer.json';
}
foreach(glob($dir . '/*', GLOB_ONLYDIR) as $subDir) {
$result = $this->findComposerJson($subDir);
if ($result !== NULL) {
return $result;
}
}
}

private function addDirectory($dir) {
$dir = rtrim($dir, '/');
if (!in_array($dir, $this->directories)) {
$this->directories[] = $dir;
}
}

/**
* (PHP 5 &gt;= 5.0.0)<br/>
* Return the current element
*
* @link http://php.net/manual/en/iterator.current.php
* @return mixed Can return any type.
*/
public function current() {
return $this->directories[$this->pos];
}

/**
* (PHP 5 &gt;= 5.0.0)<br/>
* Move forward to next element
*
* @link http://php.net/manual/en/iterator.next.php
* @return void Any returned value is ignored.
*/
public function next() {
$this->pos++;
}

/**
* (PHP 5 &gt;= 5.0.0)<br/>
* Return the key of the current element
*
* @link http://php.net/manual/en/iterator.key.php
* @return mixed scalar on success, or null on failure.
*/
public function key() {
return $this->pos;
}

/**
* (PHP 5 &gt;= 5.0.0)<br/>
* Checks if current position is valid
*
* @link http://php.net/manual/en/iterator.valid.php
* @return boolean The return value will be casted to boolean and then evaluated.
* Returns true on success or false on failure.
*/
public function valid() {
return $this->pos < count($this->directories);
}

/**
* (PHP 5 &gt;= 5.0.0)<br/>
* Rewind the Iterator to the first element
*
* @link http://php.net/manual/en/iterator.rewind.php
* @return void Any returned value is ignored.
*/
public function rewind() {
$this->pos = 0;
}

}

class ComposerIteratorException extends \Exception {
const InvalidComposerJsonFile = 1;
}

}
5 changes: 5 additions & 0 deletions src/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,11 @@ public function getDirectories() {
if (is_dir($match)) {
$list[] = $match;
}
if (is_file($dir) && basename($dir) == 'composer.json') {
foreach(new ComposerIterator(new \SplFileInfo($dir)) as $d) {
$list[] = $d;
}
}
}
}
return $list;
Expand Down
2 changes: 2 additions & 0 deletions src/autoload.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ function($class) {
'theseer\\autoload\\collectorexception' => '/Collector.php',
'theseer\\autoload\\collectorresult' => '/CollectorResult.php',
'theseer\\autoload\\collectorresultexception' => '/CollectorResult.php',
'theseer\\autoload\\composeriterator' => '/ComposerIterator.php',
'theseer\\autoload\\composeriteratorexception' => '/ComposerIterator.php',
'theseer\\autoload\\config' => '/Config.php',
'theseer\\autoload\\factory' => '/Factory.php',
'theseer\\autoload\\logger' => '/Logger.php',
Expand Down

0 comments on commit beda4a7

Please sign in to comment.