vendor/csoft/autoinvoker/src/ClassFinder/ClassFinder.php line 104

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Csoft\AutoInvoker\ClassFinder;
  4. use Csoft\AutoInvoker\AutoInvokeRule\AutoInvokeRuleInterface;
  5. use Generator;
  6. use ReflectionClass;
  7. use ReflectionException;
  8. use Symfony\Component\Finder\Finder;
  9. class ClassFinder implements ClassFinderInterface
  10. {
  11.     /** @var array */
  12.     protected $classes;
  13.     /**
  14.      * @inheritDoc
  15.      */
  16.     public function getMatchingClasses(AutoInvokeRuleInterface $rule): array
  17.     {
  18.         // Preloads the available classes for the rule.
  19.         $this->fetchClasses($rule);
  20.         $matchingClasses = [];
  21.         foreach ($rule->getSourcePaths() as $path) {
  22.             foreach ($this->classes[$path] as $fqn => $interfaces) {
  23.                 // If the rule presents all class or we matched the class.
  24.                 if ($rule->getInvokableInterface() === '' || in_array(
  25.                         $rule->getInvokableInterface(),
  26.                         $interfaces,
  27.                         true
  28.                     )) {
  29.                     $matchingClasses[] = $fqn;
  30.                 }
  31.             }
  32.         }
  33.         return $matchingClasses;
  34.     }
  35.     /**
  36.      * Fetches all available and autoloadable classes from the given paths.
  37.      *
  38.      * @param AutoInvokeRuleInterface $rule
  39.      */
  40.     protected function fetchClasses(AutoInvokeRuleInterface $rule)
  41.     {
  42.         foreach ($rule->getSourcePaths() as $path) {
  43.             if (empty($this->classes[$path])) {
  44.                 $this->classes[$path] = [];
  45.                 foreach ($this->fetchClassesFromPath($path) as $fqn => $interfaces) {
  46.                     $this->classes[$path][$fqn] = $interfaces;
  47.                 }
  48.             }
  49.         }
  50.     }
  51.     /**
  52.      * Fetches all available and autoloadable classes from the given path.
  53.      *
  54.      * @param string $path
  55.      *
  56.      * @return Generator
  57.      */
  58.     protected function fetchClassesFromPath(string $path): Generator
  59.     {
  60.         foreach ($this->getFinder()->files()->name('*.php')->in($path) as $file) {
  61.             foreach ($this->fetchClassesFromContent($file->getContents()) as $fqn => $interfaces) {
  62.                 yield $fqn => $interfaces;
  63.             }
  64.         }
  65.     }
  66.     /**
  67.      * Returns a Finder instance.
  68.      *
  69.      * @return Finder
  70.      */
  71.     protected function getFinder(): Finder
  72.     {
  73.         return new Finder();
  74.     }
  75.     /**
  76.      * Fetches all available and autoloadable classes from the given content.
  77.      *
  78.      * @param string $content
  79.      *
  80.      * @return Generator
  81.      */
  82.     protected function fetchClassesFromContent(string $content): Generator
  83.     {
  84.         $namespace ClassParser::getNameSpaceFromContent($content);
  85.         $className ClassParser::getClassNameFromContent($content);
  86.         if (empty($className) === false) {
  87.             foreach ($className as $currentClassName) {
  88.                 $fqn $namespace '\\' $currentClassName;
  89.                 try {
  90.                     $reflectionClass = new ReflectionClass($fqn);
  91.                     if ($reflectionClass->isAbstract() === false) {
  92.                         yield $fqn => $reflectionClass->getInterfaceNames();
  93.                     }
  94.                 } catch (ReflectionException $e) {
  95.                     //echo $e->getMessage() . PHP_EOL;
  96.                 }
  97.             }
  98.         }
  99.     }
  100. }