In trying to use Artisan::call($command, $arguments)
to execute a command exposed by my Laravel package—Folio—I was running into this issue.
The command "folio:clone" does not exist.
My commands were working on the terminal, by calling php artisan folio:clone
, for instance, but they were not working programmatically, calling something like this.
Artisan::call('folio:clone 123 "New Title"');
Artisan::command
was not a solution as it serves to register commands and not to execute them.
By looking into the FolioServiceProvider.php (the service provider of my own package) I noticed the $this->app->runningInConsole()
check. My commands were being registered in the console but were not exposed elsewhere (that is, in the application itself).
I'd guess this is a security and performance measure. Commands that don't need to be available to the Laravel app are not registered for it.
The solution was simply registering the commands I want to be callable from my Laravel sites outside of the if
statement that checks for $this->app->runningInConsole()
.
While eight commands are only available to run on the console, there's one available to both the console and the application's runtime.
if ($this->app->runningInConsole()) {
$this->commands([
\Nonoesp\Folio\Commands\GenerateSitemap::class,
\Nonoesp\Folio\Commands\MigrateTemplate::class,
\Nonoesp\Folio\Commands\TextAndTitleToJSON::class,
\Nonoesp\Folio\Commands\ItemPropertiesExport::class,
\Nonoesp\Folio\Commands\ItemPropertiesImport::class,
\Nonoesp\Folio\Commands\ItemRetag::class,
\Nonoesp\Folio\Commands\InstallCommand::class,
\Nonoesp\Folio\Commands\CreateUserCommand::class,
]);
}
$this->commands([
\Nonoesp\Folio\Commands\ItemClone::class,
]);
In my case, I'm the maintainer of the package and could easily work around this limitation by taking the command I want to use in Laravel out of the if
statement.
But you can register commands yourself in your app's $commands
array in app/Console/Kernel.php
. See the following example.
// app/Console/Kernel.php
protected $commands = [
\Nonoesp\Folio\Commands\CreateUserCommand::class,
];
While the CreateUserCommand
is only registered to the console by the package, I can explicitly make it available for my entire application calling it with Artisan::call('folio:user {email} {password}')
(which is this command's signature).
I hope you found this useful. Feel free to ping me at @nonoesp, join the mailing list, or check out other Laravel posts and code-related publications.