Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Instantiating all classes in directory

I'm using Laravel and creating artisan commands but I need to register each one in start/artisan.php by calling

Artisan::add(new MyCommand);

How can I take all files in a directory (app/commands/*), and instantiate every one of them in an array ? I'd like to get something like (pseudocode) :

$my_commands = [new Command1, new Command2, new Command3];
foreach($my_commands as $command){
    Artisan::add($command);
}
like image 274
Lukmo Avatar asked Jan 22 '14 11:01

Lukmo


1 Answers

Here is a way to auto-register artisan commands. (This code was adapted from the Symfony Bundle auto-loader.)

function registerArtisanCommands($namespace = '', $path = 'app/commands')
{
    $finder = new \Symfony\Component\Finder\Finder();
    $finder->files()->name('*Command.php')->in(base_path().'/'.$path);

    foreach ($finder as $file) {
        $ns = $namespace;
        if ($relativePath = $file->getRelativePath()) {
            $ns .= '\\'.strtr($relativePath, '/', '\\');
        }
        $class = $ns.'\\'.$file->getBasename('.php');

        $r = new \ReflectionClass($class);

        if ($r->isSubclassOf('Illuminate\\Console\\Command') && !$r->isAbstract() && !$r->getConstructor()->getNumberOfRequiredParameters()) {
            \Artisan::add($r->newInstance());
        }
    }
}

registerArtisanCommands();

If you put that in your start/artisan.php file, all commands found in app/commands will be automatically registered (assuming you follow Laravel's recommendations for command and file names). If you namespace your commands like I do, you can call the function like so:

registerArtisanCommands('App\\Commands');

(This does add a global function, and a better way to do this would probably be creating a package. But this works.)

like image 162
Joshua Jabbour Avatar answered Sep 23 '22 07:09

Joshua Jabbour