public function findAll($paths) : array
    {
        if (is_string($paths)) {
            $paths = [$paths];
        }

        if (!is_array($paths)) {
            throw new InvalidArgumentException('Paths must be a string or array');
        }

        $allClassNames = [];

        foreach ($paths as $path) {
            if (!is_dir($path)) {
                throw new InvalidArgumentException("Path $path is not a directory");
            }

            $fileIter = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));

            foreach ($fileIter as $file) {
                if ($file->getExtension() !== 'php') {
                    continue;
                }

                $tokens = token_get_all(file_get_contents($file->getRealPath()));
                $allClassNames = array_merge($allClassNames, $this->getClassNamesFromTokens($tokens));
            }
        }

        // Filter out any non-concrete migration classes
        $migrationClassNames = array_filter($allClassNames, function ($className) {
            $reflectionClass = new ReflectionClass($className);

            return $reflectionClass->implementsInterface(IMigration::class) &&
                !$reflectionClass->isInterface() &&
                !$reflectionClass->isAbstract();
        });

        // Sort the migration classes by their creation dates
        usort($migrationClassNames, function (string $a, string $b) {
            return $a::getCreationDate() <=> $b::getCreationDate();
        });

        return $migrationClassNames;
    }
public function findAll($paths) : array
    {
        if (is_string($paths)) {
            $paths = [$paths];
        }

        if (!is_array($paths)) {
            throw new InvalidArgumentException('Paths must be a string or array');
        }

        $allClassNames = [];

        foreach ($paths as $path) {
            if (!is_dir($path)) {
                throw new InvalidArgumentException("Path $path is not a directory");
            }

            $fileIter = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));

            foreach ($fileIter as $file) {
                if ($file->getExtension() !== 'php') {
                    continue;
                }

                $tokens = token_get_all(file_get_contents($file->getRealPath()));
                $allClassNames = array_merge($allClassNames, $this->getClassNamesFromTokens($tokens));
            }
        }

        // Filter out any non-concrete migration classes
        $migrationClassNames = array_filter($allClassNames, function ($className) {
            $reflectionClass = new ReflectionClass($className);

            return $reflectionClass->implementsInterface(IMigration::class) &&
                !$reflectionClass->isInterface() &&
                !$reflectionClass->isAbstract();
        });

        // Sort the migration classes by their creation dates
        usort($migrationClassNames, function (string $a, string $b) {
            return $a::getCreationDate() <=> $b::getCreationDate();
        });

        return $migrationClassNames;
    }
public function findAll ( $ paths ) : array { if ( is_string ( $ paths ) ) { $ paths = [ $ paths ] ; } if ( ! is_array ( $ paths ) ) { throw new InvalidArgumentException ( 'Paths must be a string or array' ) ; } $ allClassNames = [ ] ; foreach ( $ paths as $ path ) { if ( ! is_dir ( $ path ) ) { throw new InvalidArgumentException ( "Path $path is not a directory" ) ; } $ fileIter = new RecursiveIteratorIterator ( new RecursiveDirectoryIterator ( $ path ) ) ; foreach ( $ fileIter as $ file ) { if ( $ file -> getExtension ( ) !== 'php' ) { continue ; } $ tokens = token_get_all ( file_get_contents ( $ file -> getRealPath ( ) ) ) ; $ allClassNames = array_merge ( $ allClassNames , $ this -> getClassNamesFromTokens ( $ tokens ) ) ; } } // Filter out any non-concrete migration classes $ migrationClassNames = array_filter ( $ allClassNames , function ( $ className ) { $ reflectionClass = new ReflectionClass ( $ className ) ; return $ reflectionClass -> implementsInterface ( IMigration :: class ) && ! $ reflectionClass -> isInterface ( ) && ! $ reflectionClass -> isAbstract ( ) ; } ) ; // Sort the migration classes by their creation dates usort ( $ migrationClassNames , function ( string $ a , string $ b ) { return $ a :: getCreationDate ( ) <=> $ b :: getCreationDate ( ) ; } ) ; return $ migrationClassNames ; }
Recursively finds all migration classes in the order they're to be run

@param string|array $paths The path or list of paths to search
@return string[] The list of all migration class names
@throws InvalidArgumentException Thrown if the paths are not a string or array
Recursively finds all migration classes in the order they re to be run