Laravel custom artisan command not listed - laravel

I have several artisan commands which I wrote.
All of them share common functionality, so instead of extending Command class, I wrote a MyBaseCommand class so all commands extend this one:
namespace App\Console\Commands;
use Illuminate\Console\Command;
class SomeCommand extends MyBaseCommand
{
protected $signature = 'mycommands:command1';
protected $description = 'Some description';
:
:
And the base class:
namespace App\Console\Commands;
class MyBaseCommand extends Command
{
:
:
The problem is that from some reason these commands are no longer listed with php artisan.
Any idea how can I force laravel to list these commands as well?

protected $signature = 'mycommands:command1'; //this is your command name
Open app\Console\kernel.php file.
protected $commands = [
\App\Console\Commands\SomeCommand::class,
]
then run
php artisan list

Laravel tries to register the commands for you automatically with:
/**
* Register the commands for the application.
*
* #return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
You can find this in the App\Console\Kernel.php
Make sure that your classes have a signature and description property.

It is quite stupid, anyway since it might happen to someone else I leave here the answer:
I wanted to hide the base class, so I had inside it this line:
protected $hidden = true;
Of-course, the value of this variable was propagated to the high-level class, what made the custom commands hidden.
The solution is simply to add to these files this line:
protected $hidden = false;
====================== UPDATE ======================
As #aken-roberts mentions, a better solution is simply making the base class abstract:
namespace App\Console\Commands;
abstract class MyBaseCommand extends Command
{
abstract public function handle();
:
:
In this case artisan doesn't list it, and it cannot be executed.

Related

Why does Intelephense dislike my custom helper class?

I am trying to write some custom helper functions for my Laravel 9 app using the advice given in the second answer (written by heisian) to this question. I think I've imitated everything faithfully but when I try to use the new function, intelephense says "Undefined type 'Helper'.
Here is my Helper.php (stored in app/Helpers/Helper.php):
<?php
namespace App\Helpers;
class Helper {
public static function hello() {
return "Hello!";
}
}
?>
Here is the only section I changed in config/app.php:
'aliases' => Facade::defaultAliases()->merge([
// 'ExampleClass' => App\Example\ExampleClass::class,
'Helper' => App\Helpers\Helper::class
])->toArray(),
Here is the part of my code where I actually use the new hello() function:
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
use Helper;
/**
* #extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Listing>
*/
class ListingFactory extends Factory
{
/**
* Define the model's default state.
*
* #return array<string, mixed>
*/
public function definition()
{
$this->faker = \Faker\Factory::create();
/* Choose a single job title at random from the collection of job titles. */
// $titlesCollection = collect(['Junior Laravel Developer', 'Intermediate Laravel Developer', 'Senior Laravel Developer', 'Laravel Project Leader']);
// $randomTitleString = $titlesCollection->random();
$randomTitleString = Helper::hello();
Intelephense highlights the final line of this excerpt by putting a red squiggly line under Helper. I can make the error go away by changing:
use Helper;
to
use app\Helpers\Helper;
However, if I then try to execute php artisan migrate:refresh --seed I get a different error. However, the refresh/seed WORKS with use Helper; despite the error and the hello() function does exactly what I've told it to do. (I should mention that I have done the composer dump-autoload on my terminal as per the instructions in the linked question.)
Ultimately, the only real problem here is that Intelephense doesn't recognize the Helper class for what it is. Short of uninstalling Intelephense from my copy of VS Code, is there anything I can do to make it recognize that Helper is a legitimate class?

Custom Laravel Artisan Make Controller command

I want to put my controller generated by the artisan command to a custom directory. I made own command
php artisan make:command ApiControllerMake
and extended it
class ApiControllerMake extends ControllerMakeCommand
then I removed everything from there and overridden method
protected function getDefaultNamespace($rootNamespace)
{
return $rootNamespace.'\Http\AppAPI\Controllers';
}
It's working OK.
Then I overridden
protected $signature = 'make:api-controller';
and after run
php artisan make:api-controller MyNewController
I got error
No arguments expected for "make:api-controller" command, got "MyNewController".
What is the problem?
Take a look at the ControllerMakeCommand, they use
protected $name = 'make:controller';
You probably have this:
protected $signature = 'make:api-controller';
So in your new class, replace $signature with $name.

Is there a way to disable artisan commands?

Is there a way to disable artisan commands from running at all?
For example, if I wanted to disable php artisan migrate:fresh from running, where would I go to remove/disable the command?
As far as I know, laravel does not have this feature by default. And this is still under laravel ideas.
I also had this problem before and could not find a solution, I am not sure why you want to disable a command. But my case was that in the production environment I never want to run php artisan migrate:fresh. So what I end up with is to override the default command.
For example, in the routes/console.php file:
if ('production' === App::environment()) {
Artisan::command('migrate:fresh', function () {
$this->comment('You are not allowed to do this in production!');
})->describe('Override default command in production.');
}
So, when you are in production, php artisan migrate:fresh will do nothing. You can change the condition based on your requirement, my example is just an idea of how you can override a laravel default command based on some variables in the .env file.
You can do a lot of things here as well, I am not sure why you want to disable the command, so this is the best I can help.
Create a command like the following
<?php
namespace App\Console\Commands\Utils;
use Illuminate\Console\Command;
use Illuminate\Console\Events\CommandStarting;
class PreCommand extends Command
{
protected $signature = 'precommand';
public function handle(CommandStarting $event) {
if (app()->environment(['production'])) {
logger('Trying to fresh database in production');
if ($event->command == 'migrate:fresh') {
$this->output = $event->output;
$this->info('You can not fresh database in the production');
die();
}
}
}
}
And register it in your EventServiceProvider's boot method
<?php
namespace App\Providers;
use App\Console\Commands\Utils\PreCommand;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Console\Events\CommandStarting;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Event;
class EventServiceProvider extends ServiceProvider
{
/**
* Register any events for your application.
*
* #return void
*/
public function boot() {
Event::listen(CommandStarting::class, PreCommand::class);
}
}

Generate files using custom artisan make command Laravel

I am trying to generate a class file using custom artisan make command.My command is showing under artisan make but I am not able to generate file
What i did
1.Use php artisan make:command CreateActionClass and implement GeneratorCommand
<?php
namespace App\Console\Commands;
use Illuminate\Console\GeneratorCommand;
use Symfony\Component\Console\Input\InputArgument;
class CreateActionClass extends GeneratorCommand
{
protected $signature = 'make:action {name}';
protected $description = 'Create New Action Single Responsibility';
protected $type = 'Action';
public function handle()
{
//
}
protected function getStub()
{
return app_path().'/Console/Stubs/MakeActionStub.stub';
}
protected function getDefaultNamespace($rootNamespace)
{
return $rootNamespace.'\Actions';
}
protected function getArguments()
{
return [
['name', InputArgument::REQUIRED, 'The name of the contract.'],
];
}}
2. Generate .stub file /Console/Stubs/MakeActionStub.stub
<?php
namespace DummyNamespace;
class DummyAction
{
}
Please Help
Remove the handle method. It is overriding the GeneratorCommand class's handle that's why its doing nothing. If you wish to extend the handle method, call parent::handle() before or after your statements

call a model from a command class in Laravel 5, and pass the command class itself

I have a laravel 5.5 artisan command working, so of course I can use methods like $this->info() and $this->arguments() etc.. it looks like this:
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Config;
use Compasspointmedia\Julietmenu\Model\Menu;
class MenuManagementCommand extends Command
{
/**
* The console command name.
*
* #var string
*/
protected $signature = 'julietmenu:menu
{action=list}';
protected $description = 'Manages menu elements per the Juliet CMS specification';
public function __construct() {
parent::__construct();
//trying to make this command methods available in Menu
$this->menu = new Menu($this);
}
/**
* Execute the console command.
*/
public function handle()
{
// this works just fine
$this->info('Calling ' . $this->argument('action'));
$action = $this->argument('action');
$this->menu->action();
}
}
Of course, I would like do the actual work in the Model, not the command, using the command like a controller. Here's the model class so far:
namespace Compasspointmedia\Julietmenu\Model;
use Illuminate\Database\Eloquent\Model;
class Menu extends Model {
//
public function __construct($command){
$this->command = $command;
// this says the `arguments` method is present:
print_r(get_class_methods($this->command));
// but, it does not work!
// error: "Call to a member function getArguments() on null"
$this->arguments = $this->command->arguments();
}
public function node(){
echo '--- it works! -----';
}
}
To the point, how do I pass the Command object to the Model so that I can use $this->command->arguments() or the other Command features inside the model?
P.S. I'd be very grateful to know if there's a native "Laravel way" to do this better than passing the entire $this to a constructor.

Resources