- <?php
- /**
- * Zend Framework (http://framework.zend.com/)
- *
- * @link http://github.com/zendframework/zf2 for the canonical source repository
- * @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
- namespace Zend\Code\Scanner;
- use RecursiveDirectoryIterator;
- use RecursiveIteratorIterator;
- use Zend\Code\Exception;
- class DirectoryScanner implements ScannerInterface
- {
- /**
- * @var bool
- */
- protected $isScanned = false;
- /**
- * @var string[]|DirectoryScanner[]
- */
- protected $directories = array();
- /**
- * @var FileScanner[]
- */
- protected $fileScanners = array();
- /**
- * @var array
- */
- protected $classToFileScanner = null;
- /**
- * @param null|string|array $directory
- */
- public function __construct($directory = null)
- {
- if ($directory) {
- if (is_string($directory)) {
- $this->addDirectory($directory);
- } elseif (is_array($directory)) {
- foreach ($directory as $d) {
- $this->addDirectory($d);
- }
- }
- }
- }
- /**
- * @param DirectoryScanner|string $directory
- * @return void
- * @throws Exception\InvalidArgumentException
- */
- public function addDirectory($directory)
- {
- if ($directory instanceof DirectoryScanner) {
- $this->directories[] = $directory;
- } elseif (is_string($directory)) {
- $realDir = realpath($directory);
- if (!$realDir || !is_dir($realDir)) {
- throw new Exception\InvalidArgumentException(sprintf(
- 'Directory "%s" does not exist',
- $realDir
- ));
- }
- $this->directories[] = $realDir;
- } else {
- throw new Exception\InvalidArgumentException(
- 'The argument provided was neither a DirectoryScanner or directory path'
- );
- }
- }
- /**
- * @param DirectoryScanner $directoryScanner
- * @return void
- */
- public function addDirectoryScanner(DirectoryScanner $directoryScanner)
- {
- $this->addDirectory($directoryScanner);
- }
- /**
- * @param FileScanner $fileScanner
- * @return void
- */
- public function addFileScanner(FileScanner $fileScanner)
- {
- $this->fileScanners[] = $fileScanner;
- }
- /**
- * @return void
- */
- protected function scan()
- {
- if ($this->isScanned) {
- return;
- }
- // iterate directories creating file scanners
- foreach ($this->directories as $directory) {
- if ($directory instanceof DirectoryScanner) {
- $directory->scan();
- if ($directory->fileScanners) {
- $this->fileScanners = array_merge($this->fileScanners, $directory->fileScanners);
- }
- } else {
- $rdi = new RecursiveDirectoryIterator($directory);
- foreach (new RecursiveIteratorIterator($rdi) as $item) {
- if ($item->isFile() && pathinfo($item->getRealPath(), PATHINFO_EXTENSION) == 'php') {
- $this->fileScanners[] = new FileScanner($item->getRealPath());
- }
- }
- }
- }
- $this->isScanned = true;
- }
- /**
- * @todo implement method
- */
- public function getNamespaces()
- {
- // @todo
- }
- /**
- * @param bool $returnFileScanners
- * @return array
- */
- public function getFiles($returnFileScanners = false)
- {
- $this->scan();
- $return = array();
- foreach ($this->fileScanners as $fileScanner) {
- $return[] = ($returnFileScanners) ? $fileScanner : $fileScanner->getFile();
- }
- return $return;
- }
- /**
- * @return array
- */
- public function getClassNames()
- {
- $this->scan();
- if ($this->classToFileScanner === null) {
- $this->createClassToFileScannerCache();
- }
- return array_keys($this->classToFileScanner);
- }
- /**
- * @param bool $returnDerivedScannerClass
- * @return array
- */
- public function getClasses($returnDerivedScannerClass = false)
- {
- $this->scan();
- if ($this->classToFileScanner === null) {
- $this->createClassToFileScannerCache();
- }
- $returnClasses = array();
- foreach ($this->classToFileScanner as $className => $fsIndex) {
- $classScanner = $this->fileScanners[$fsIndex]->getClass($className);
- if ($returnDerivedScannerClass) {
- $classScanner = new DerivedClassScanner($classScanner, $this);
- }
- $returnClasses[] = $classScanner;
- }
- return $returnClasses;
- }
- /**
- * @param string $class
- * @return bool
- */
- public function hasClass($class)
- {
- $this->scan();
- if ($this->classToFileScanner === null) {
- $this->createClassToFileScannerCache();
- }
- return (isset($this->classToFileScanner[$class]));
- }
- /**
- * @param string $class
- * @param bool $returnDerivedScannerClass
- * @return ClassScanner|DerivedClassScanner
- * @throws Exception\InvalidArgumentException
- */
- public function getClass($class, $returnDerivedScannerClass = false)
- {
- $this->scan();
- if ($this->classToFileScanner === null) {
- $this->createClassToFileScannerCache();
- }
- if (!isset($this->classToFileScanner[$class])) {
- throw new Exception\InvalidArgumentException('Class not found.');
- }
- /** @var FileScanner $fs */
- $fs = $this->fileScanners[$this->classToFileScanner[$class]];
- $returnClass = $fs->getClass($class);
- if (($returnClass instanceof ClassScanner) && $returnDerivedScannerClass) {
- return new DerivedClassScanner($returnClass, $this);
- }
- return $returnClass;
- }
- /**
- * Create class to file scanner cache
- *
- * @return void
- */
- protected function createClassToFileScannerCache()
- {
- if ($this->classToFileScanner !== null) {
- return;
- }
- $this->classToFileScanner = array();
- /** @var FileScanner $fileScanner */
- foreach ($this->fileScanners as $fsIndex => $fileScanner) {
- $fsClasses = $fileScanner->getClassNames();
- foreach ($fsClasses as $fsClassName) {
- $this->classToFileScanner[$fsClassName] = $fsIndex;
- }
- }
- }
- /**
- * Export
- *
- * @todo implement method
- */
- public static function export()
- {
- // @todo
- }
- /**
- * __ToString
- *
- * @todo implement method
- */
- public function __toString()
- {
- // @todo
- }
- }