quickstrap/quickstrap

View on GitHub
src/BundleFinder.php

Summary

Maintainability
C
1 day
Test Coverage
<?php
/**
 * Created by PhpStorm.
 * User: Jeremy
 * Date: 8/20/2016
 * Time: 11:38 AM
 */

namespace Quickstrap;


use Symfony\Component\Finder\Finder;
use Symfony\Component\HttpKernel\Bundle\Bundle;

class BundleFinder
{
    public function find($bundlesDirectory)
    {
        $bundles = [];
        // iterate through vendor folders
        foreach(new \DirectoryIterator($bundlesDirectory) as $vendorIterator) {
            if ( (!$vendorIterator->isDir()) || $vendorIterator->isDot()) {
                continue;
            }

            // iterate through project folders
            foreach(new \DirectoryIterator($vendorIterator->getPathname()) as $projectIterator) {
                if ( (!$projectIterator->isDir()) || $projectIterator->isDot()) {
                    continue;
                }

                if (($bundle = $this->findBundle($projectIterator->getPathname())) !== null) {
                    $bundles[] = $bundle;
                }
            }
        }

        return $bundles;
    }

    protected function findBundle($dir) {
        if (!is_dir($dir)) {
            return null;
        }

        if (!class_exists('Symfony\Component\Finder\Finder')) {
            throw new \RuntimeException('You need the symfony/finder component to register bundle commands.');
        }

        $finder = new Finder();
        $finder->files()->name('*Bundle.php')->in($dir);


        foreach ($finder as $file) {
            $reflection = $this->getClassReflection($file->getPathname());
            if(!$reflection) {
                continue;
            }

            if ($reflection->isSubclassOf(Bundle::class)
                && !$reflection->isAbstract()
                && (!$reflection->getConstructor() || !$reflection->getConstructor()->getNumberOfRequiredParameters())
            ) {
                return $reflection->getName();
            }
        }
        return null;
    }

    protected function getClassReflection($file)
    {
        $fp = fopen($file, 'r');
        if (!$fp) {
            return null;
        }
        $class = $namespace = $buffer = '';
        $i = 0;
        while (!$class) {
            if (feof($fp)) break;

            $buffer .= fread($fp, 512);
            $tokens = token_get_all($buffer);

            if (strpos($buffer, '{') === false) continue;

            for (;$i<count($tokens);$i++) {
                if ($tokens[$i][0] === T_NAMESPACE) {
                    for ($j=$i+1;$j<count($tokens); $j++) {
                        if ($tokens[$j][0] === T_STRING) {
                            $namespace .= '\\'.$tokens[$j][1];
                        } else if ($tokens[$j] === '{' || $tokens[$j] === ';') {
                            break;
                        }
                    }
                }

                if ($tokens[$i][0] === T_CLASS) {
                    for ($j=$i+1;$j<count($tokens);$j++) {
                        if ($tokens[$j] === '{') {
                            $class = $tokens[$i+2][1];
                        }
                    }
                }
            }
        }
        return new \ReflectionClass("$namespace\\$class");
    }

}