how to hold all artisan command laravel - php

How to disable all artisan command?
i try with create parent class and extend that class to my artisan commands.
Parent
namespace App\Extenders;
use Illuminate\Console\Command AS BaseCommand;
class Command extends BaseCommand {
public function __construct()
{
parent::__construct();
dump('command disabled');
exit;
}
}
My artisan command:
namespace App\Console\Commands;
use App\Extenders\Command;
class HoldAllArtisanCommand extends Command
{
protected $signature = 'command';
protected $description = 'Command description';
public function __construct()
{
parent::__construct();
}
public function handle()
{
//
}
}
With this code the command not running but all command that not extend my custom parent command is not running as well

I don't know why you want to disable your commands entirely but here is how I would do it:
First I would create an environment variable called COMMANDS_DISABLED and then create a config for it inside config/app.php and call it commands_disabled. OR just create a setting on the database so that I you enable and disable commands as you like.
You can create a BaseCommand class that extends the Illuminate\Console\Command like so:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class BaseCommand extends Command
{
public function __construct()
{
if (config('app.commands_disabled')) {
dump('command disabled');
exit;
}
}
}
Then for all your custom commands inside app/Console/Commands you have to extend from this BaseCommand like so:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class TestCommand extends BaseCommand
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'testing';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Command description';
/**
* Execute the console command.
*
* #return int
*/
public function handle()
{
return 0;
}
}
now when you run php artisan testing it will show the message command disabled.
And if you want to enable your custom commands again you can remove the constructor code from the BaseCommand class.

Related

Passing a quantity or other arguments to a Laravel seeder

I would like to pass an argument as to define how many records I want to create during database seeding, without having to edit the factory manually.
I have tried different variations on php artisan db:seed --class=UsersTableSeeder [using different args here]
I can't seem to find any documentation, so I don't know if that functionally exists. Does something like that exist?
class UsersTableSeeder extends Seeder
{
public $limit = null;
public function __construct($limit = 1) {
$this->limit = $limit;
}
public function run()
{
echo $this->limit;
}
}
There is no way to directly specify an argument.
If you want to specify a parameter via the command line, you could use an environment variable.
class UsersTableSeeder extends Seeder
{
public function run()
{
$limit = env('SEEDER_LIMIT', 1);
echo $this->limit;
}
}
Call like this:
SEEDER_LIMIT=10 php artisan db:seed --class=UsersTableSeeder
You can set it up this way:
public function run($count = 1)
And then you can pass the argument this way:
$this->call(ClientSeeder::class, false, ['count' => 500]);
From what I know there's no such thing as parameters for seeders, but you could implement it yourself. You could create a new command which accepts parameters and calls a seeder programmatically with those additional parameters.
Something like this should do the trick:
use Illuminate\Database\Seeder;
class UsersTableSeeder extends Seeder
{
public function run(int $limit)
{
echo $limit;
// Seed some stuff
}
}
namespace App\Console\Commands;
use Illuminate\Console\Command;
use UsersTableSeeder;
class SeedCommand extends Command
{
protected $signature = 'app:seed {limit}';
public function handle(UsersTableSeeder $seeder)
{
$limit = $this->argument('limit');
$seeder->run($limit);
}
}
you can ask for that limit before call any other seeders using
// DatabaseSeeder.php
$limit = $this->command->ask('Please enter the limit for creating something !!');
and then you can pass that limit to any additional seeders from 'DatabaseSeeder' like this
//DatabaseSeeder.php
$this->call(AnyAdditionalSeeder::class, false, compact('limit'));
then in 'AnyAdditionalSeeder' you can add parameter and name it $limit to the run() method like this
public function run($limit)
{
// you can access limit variable here
}
then when you run the command php artisan db:seed it will ask you for the limit :)
my solution:
// MemberSeeder.php (example for Members Table)
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\Member as ModelsMember;
class MemberSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
static function run(int $nRec=1) {
ModelsMember::factory()->times($nRec)->create();
}
}
Call from a .php file
// Members.php
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\Member;
use Database\Seeders\MemberSeeder;
class Members extends Component
{
public $members, $name, $email, $phone_number, $status, $member_id;
public $bldModal = '';
...
...
public function generaRecords() {
MemberSeeder::run(2);
}
}
Schema for to create table
Schema::create('members', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->string('phone_number');
$table->char('status',1);
$table->timestamps();
});
Shortly: to change
public function run() {
To
static function run(int $nRec=1) {
As of Laravel 8 you can use callWith to pass parameters to the run method of your seeders. Something like this:
class UsersTableSeeder extends Seeder
{
public function run($count = 1)
{
User::factory()->count($count)->create();
}
}
And then your could use those seeders in other seeders like this:
class DatabaseSeeder extends Seeder
{
public function run()
{
$this->callWith(UsersTableSeeder::class, ['count' => 10]);
}
}
Note that the parameter array you give to callWith is associative, and its keys should match the run method's parameters, because the call will ordinarily be resolved through the Laravel's application container.
you can pass a parameter as quantity to a seeder like this:
First, create a custom command
php artisan make:command generateFakeCompanyData
generateFakeCompanyData.php
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Database\Seeders\CreateFakeCompanySeeder;
class generateFakeCompanyData extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'create:fake-comapnies {count}';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Command description';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return int
*/
public function handle(CreateFakeCompanySeeder $seeder)
{
$limit = $this->argument('count');
$seeder->run($limit);
}
}
create seeder file:
php artisan make:seeder CreateFakeCompanySeeder
CreateFakeCompanySeeder.php
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class CreateFakeCompanySeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run(int $limit)
{
\App\Models\Company\Company::factory($limit)->create();
}
}
create factory file
php artisan make:factory Company\CompanyFactory --model=Company
CompanyFactory.php
<?php
namespace Database\Factories\Company;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
use App\Models\Blog;
/**
* #extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Company\Company>
*/
class CompanyFactory extends Factory
{
/**
* Define the model's default state.
*
* #return array<string, mixed>
*/
public function definition()
{
return [
'name' => $this->faker->company,
'email' => $this->faker->unique()->email,
'logo' => $this->faker->imageUrl(640,480),
'website' => Str::slug($this->faker->name).'.com',
// 'website' => $this->faker->text(),
];
}
}
in route: web.php
Route::controller(CompanyController::class)->group(function() {
Route::prefix('company')->group(function () {
Route::post('/store', 'companyInsert')->name('company.add');
});
});
in controller: CompanyController.php
class CompanyController extends Controller{
public function companyInsert(Request $request){
$limit = $request->no_of_company;
\Artisan::call('create:fake-comapnies '.$limit);
return redirect()->back()->with('crudMsg','Total of '.$limit.' Company
Successfully Added');
}
}

Laravel $schedule to read/send email

I´m trying to create $schedule job in Laravel to read Email with PHP IMAP package. If I go to route, package read email and does all correctly, but need to do this every 5 minutes.
I create a new command class and add this
use Illuminate\Http\Request;
class ReadMail extends Command implements SelfHandling {
protected $name = 'read:mail';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the command.
*
* #return void
*/
public function fire()
{
$request = Request::create($this->option('App\Http\Controllers\MailController#index'), 'GET');
$this->info(app()['Illuminate\Contracts\Http\Kernel']->handle($request));
}
In kernel
protected $commands = [
'App\Console\Commands\ReadMail',
];
protected function schedule(Schedule $schedule)
{
$schedule->call('read:mail')
->everyFiveMinutes();
}
I'm not sure if this code it´is correct, but does not work properly. Any idea about it?
Thank in advance for your help.
UPDATE
I launch this
php artisan read:mail and return
Argument 1 passed to Illuminate\Console\Application::add() must be an instance of Symfony\Component\Console\Command\Command, instance of App\Commands\ReadMail given
The code of ReadMail class
<?php namespace App\Commands;
use App\Commands\Command;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Http\Request;
class ReadMail extends Command implements SelfHandling {
protected $signature = 'read:mail';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Execute the command.
*
* #return void
*/
public function fire()
{
$request = Request::create($this->option('App\Http\Controllers\MailController#index'), 'GET');
$this->info(app()['Illuminate\Contracts\Http\Kernel']->handle($request));
}
}
UPDATE 2: SOLVED - ALL CODE
Kernel
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel {
/**
* The Artisan commands provided by your application.
*
* #var array
*/
protected $commands = [
'App\Commands\ReadMail',
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command('read:mail')
->everyFiveMinutes();
}
}
ReadMail
<?php namespace App\Commands;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Http\Request;
use Illuminate\Console\Command;
use App\Http\Controllers\MailController;
class ReadMail extends Command implements SelfHandling {
protected $name = 'read:mail';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the command.
*
* #return void
*/
public function handle()
{
MailController::index();
}
}
MailController
<?php namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use PhpImap\Mailbox as ImapMailbox;
use App\Models\Escalas;
class MailController extends Controller {
public static function index()
{
$mailbox = new ImapMailbox('{imap.gmail.com:993/imap/ssl}INBOX', '', '','');
$mailsIds = $mailbox->searchMailbox('UNSEEN');
if(!$mailsIds) {
die('Mailbox is empty');
}
$mail=[];
foreach ($mailsIds as $index=>$data){
$mail[]=$mailbox->getMail($mailsIds[$index]);
Escalas::insert([
['' => $mail[$index]->textPlain,
'' => $mail[$index]->date,
''=>$mail[$index]->subject,
''=>$mail[$index]->fromName,
''=>$mail[$index]->fromAddress,
''=>$mail[$index]->toString],
]);
}
}
}
Try changing
protected $name = 'read:mail';
with protected $signature= 'read:mail';
in your ReadMail class and then run in Kernel like this
$schedule->command('read:mail')->everyFiveMinutes();
Check whether your scheduled tasks are set up properly (see docs for Laravel 5.0) Make sure you've added a cronjob to trigger Laravel's scheduled commands. To check you cronjobs are running, look for a file like /logs/crond.log. When opening this file, you should see lines showing at what times this ran. This is the command that triggers Laravel's scheduled jobs.
If all that is correct, then try running your command via your terminal on localhost to check the command is all set. This should reveal any problems with the command setup. Your functionality itself seems allright, since you mentioned everything works when triggered via a route.

Laravel 5.1 - Get artisan arguments from internal call

I do
when I run artisan queue:work or artisan queue:listen it runs the current commands with their corresponding Arguments. Now my question is, how can I Access those Arguments?
As you can see in the following Picture, the Arguments are there but I have no clue how to Access them?
In a project which follow a "standard project structure"
You must have a class in app/Console named Kernel which extends Illuminate\Foundation\Console\Kernel, an example of how to implement it is as follows:
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* {#inheritdoc}
*/
protected $commands = [
//here you have to put your commands class
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule): void
{
}
/**
* Register the Closure based commands for the application.
*
* #return void
*/
protected function commands(): void
{
require base_path('routes/console.php');
}
}
so now let's create a new command, call it "print" and it will accept a parameter called text, here is the implementation :
<?
namespace App\Console\Commands;
use Illuminate\Console\Command;
class TestCommand extends Command
{
/**
* {#inheritdoc}
*/
protected $signature = 'test {text}';
/**
* {#inheritdoc}
*/
protected $description = 'Test command.';
/**
* {#inheritdoc}
*/
public function handle()
{
$this->info($this->argument('text'));
}
}
as you can see, the new command accept a parameter called text and print it in console.
So to retrieve the parameter sent to an command call, you have to use the argument method in the follow way:
$commandInstance->argument('key_of_parameter');
To get more info read the docs

Calling php artisan db:seed does not work without providing a class name

I have a seeder class in the database folder
class UsersTableSeeder extends Seeder
{
public function run()
{
$user = new User();
$user->name = 'Name';
$user->email = 'email#gmail.com';
$user->password = bcrypt('secret');
$user->save();
}
}
When I run php artisan db:seed nothing happens, the seeder is only called when I run php artisan db:seed --class=UsersTableSeeder
This means I have to call each seeder class separately, any idea why db:seed doesn't work by it self?
Take a look at database/seeds/DatabaseSeeder.php
You will need to add the calls to your other seeders in there.
Then db:seed will function as expected
Example:
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
$this->call(UsersTableSeeder::class);
$this->call(SecondSeedClass::class);
$this->call(ThirdSeedClass::class);
}
}
You have to register the seed classes in DatabaseSeeder class in seeds folder.
All the classes in run method will be seed on php artisab db:seed command
class DatabaseSeeder extends Seeder {
/**
* Run the database seeds.
*
* #return void
*/
public function run() {
$this->call(UsersTableSeeder::class);
$this->call(AnotherSeeder::class);
}
}
You need to add it to the DatabaseSeeder class:
public function run()
{
$this->call(UsersTableSeeder::class);
}

Testing/Mocking Custom Console commands

I constructed my own simple command, that I want to test.
which basically looks like this:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class NeatCommand extends Command
{
protected $signature = 'my:neat:command {input_file : path for a json-formatted file to analyze}';
protected $description = 'analyze an array of values';
public function __construct()
{
parent::__construct();
}
public function handle()
{
$inputFile=$this->argument('input_file');
echo $inputFile;
}
}
So I wrote this simple test:
/**
* #test
* #group neat
*/
public function commandShowsHelloWorld()
{
$defaultCommand=Artisan::call('my:neat:command');
}
I simple want to test at this stage: there are arguments missing. But when I run it right now, phpunit brings it as an error:
There was 1 error:
1) App\Console\Commands\NeatCommandTest::commandShowsHelloWorld
RuntimeException: Not enough arguments.
So my question is. How can i mock the whole thing...or say something like $this->shouldReturn('RuntimeException: Not enough arguments.'); ?
Got it working but adding the #annotation of expected exceptions.
/**
* #test
* #group neat
* #expectedException RuntimeException
* #expectedExceptionMessage Not enough arguments.
*/
public function commandWithoutArgumentsCausesError()
{
$defaultCommand=Artisan::call('my:neat:command');
}

Categories