Laravel-modules: Artisan commands declared in modules not working

Created on 8 Nov 2017  路  9Comments  路  Source: nWidart/laravel-modules

Hi,

I trying to create a custom artisan command inside a module, first of all I try using:
php artisan module:make-command TestCommand MyModule.

Inside the generated file I change the protected $name property in "test:test"

class TestCommand extends Command
{
    /**
     * The console command name.
     *
     * @var string
     */
    protected $name = 'test:test';

but when I try to exec it I receiving an error:
There are no commands defined in the "test" namespace.

I also try to clear the composer autoload and laravel cache but I still receive the same errore, seems the commands are not loaded.

I noticed that the laravel artisan make:command create a different property name:

class TestCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'command:name';

using signature instead of name it does not give results.

Am I doing something wrong?
Thank you.

Most helpful comment

I use a similar solution adding this method in the service provider:

   /**
     * Register commands
     *
     * @param string $namespace
     */
    protected function registerCommands($namespace = '')
    {
        $finder = new Finder(); // from Symfony\Component\Finder;
        $finder->files()->name('*Command.php')->in(__DIR__ . '/../Console');

        $classes = [];
        foreach ($finder as $file) {
            $class = $namespace.'\\'.$file->getBasename('.php');
            array_push($classes, $class);
        }

        $this->commands($classes);
    }

and in boot method adding:

  $this->registerCommands('\My\Module\Console');

this seems working, even if is little bit "quick and dirty".

All 9 comments

Hello,

You're on a good path, but just forgot to register this command with laravel.
Use $this->commands([TestCommand::class]) inside your service provider.

Hi, many thanks for the prompt reply,

so the commands are not registered automatically from the path?
Registering it "manual" in the service provider, like this:

   /**
     * Register commands.
     *
     * @return void
     */
    protected function registerCommands()
    {
        $this->commands([
            \Modules\MyModule\Console\TestCommand::class
        ]);
    }

and adding on boot the function $this->registerCommands(); it works, thx.

Not automatic is a choice of laravel sadly: https://twitter.com/themsaid/status/888041249780924416

I use a similar solution adding this method in the service provider:

   /**
     * Register commands
     *
     * @param string $namespace
     */
    protected function registerCommands($namespace = '')
    {
        $finder = new Finder(); // from Symfony\Component\Finder;
        $finder->files()->name('*Command.php')->in(__DIR__ . '/../Console');

        $classes = [];
        foreach ($finder as $file) {
            $class = $namespace.'\\'.$file->getBasename('.php');
            array_push($classes, $class);
        }

        $this->commands($classes);
    }

and in boot method adding:

  $this->registerCommands('\My\Module\Console');

this seems working, even if is little bit "quick and dirty".

yeah why not 馃憤

(I'll close this issue as it has been resolved :) )

Thanks for the support.

In Laravel 5.6 Registering Commands section:

Because of the load method call in your console kernel's commands method, all commands within the app/Console/Commands directory will automatically be registered with Artisan. In fact, you are free to make additional calls to the load method to scan other directories for Artisan commands:

/**
 * Register the commands for the application.
 *
 * @return void
 */
protected function commands()
{
    $this->load(__DIR__.'/Commands');
    $this->load(__DIR__.'/MoreCommands');

    // ...
}

@ahlechandre @daaru00 @nWidart

  /**
     * Register commands.
     *
     * @return void
     */
    protected function registerCommands()
    {
        $commands = collect(glob(base_path(sprintf('%s/*/Console/*.php', config('modules.namespace')))))
            ->map(function ($item) {
                preg_match(sprintf("/%s.*/", config('modules.namespace')), $item, $matches);
                return str_replace(['/', '.php'], ["\\", ''], $matches[0]);
            })->toArray();

        $this->commands($commands);
    }

...

public function boot() { $this->registerTranslations(); $this->registerConfig(); $this->registerViews(); $this->registerCommands(); $this->loadMigrationsFrom(module_path($this->moduleName, 'Database/Migrations')); }

On this way i have all commands from my modules registreds

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sandeepk2304 picture sandeepk2304  路  3Comments

djoudi picture djoudi  路  4Comments

firebed picture firebed  路  3Comments

vdjkelly picture vdjkelly  路  4Comments

pawlox picture pawlox  路  4Comments