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);
}
}
Related
Nova 3 and Laravel 8
In RouteServiceProvider I added
Route::prefix('nova-api')
->middleware(['nova'])
->domain(config('nova.domain'))
->namespace('App\Http\Controllers\Nova')
->group(base_path('routes/nova-api.php'));
And the file content is
Route::delete('/{resource}/{resourceId}/field/{field}', 'FieldDestroyController#handle');
Route::delete('/testing', 'FieldDestroyController#handle');
After restarting project I see testing route, but not nova overwritten.
Is it possible to overwrite routes and how ?
Solution that works!
Create new ServiceProvider
php artisan make:provider NovaServiceProvider (or php artisan make:provider NovaRouteServiceProvider)
And place overwrite code .
In my case it is
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Route;
use Laravel\Nova\NovaServiceProvider as ServiceProvider;
class NovaServiceProvider extends ServiceProvider
{
protected function registerRoutes()
{
parent::registerRoutes();
Route::prefix('nova-api')
->middleware(['nova'])
->domain(config('nova.domain'))
->namespace('App\Http\Controllers\Nova')
->group(base_path('routes/nova-api.php'));
}
}
trying to prevent queued job from passing by ViewComposer in laravel using pm2.
Problem : setCookie has not been applied because (i think ) there is no session from extern calls access (pm2).
let me explain:
also sharing with you this part of my app.
I have a queued job that sends dynamic emails (templates and mail params)
in my ServiceController,
also, am sharing needed data with all view when returning to any of them,
so I created a ViewComposer called by any view(*) in AppServiceProvider, inside this ViewComposer, am using a trait that uses many traits too, to collect data I need for views.
when I navigate in my application everything looks fine.
when implementing any task that uses queued jobs, in my case sending an email:
when I run php artisan queue:work everything works fine too and I receive emails.
BUT
when I use pm2 deamon which calls that queue it fires an exception :
(setCookie has not been applied) related to that trait I use in view composer.
I know it's hard for me to explain it, but I really need some help here.
here is my code :
pm2 path : / (server root)
app path :/prod
shared hosting with ssh.
1. AppServiceProvider
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Schema;
class AppServiceProvider extends ServiceProvider
{
public function register()
{
Schema::defaultStringLength(191);
}
public function boot()
{
view()->composer('*',
'App\Http\ViewComposers\MasterComposer');
}
}
2. WebsiteComposer:
namespace App\Http\ViewComposers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use App\Website;
use other_traits;
trait WebsiteComposer
{
use other_traits;
protected function Get_Website(Request $request)
{
//some code by calling other traits;
// $results= get client websitestuff;
$this->website= $results;
}
}
3. MasterComposer:
namespace App\Http\ViewComposers;
use Illuminate\View\View;
use Illuminate\Http\Request;
class MasterComposer
{
use WebsiteComposer;
public $web=[];
public function __construct()
{
}
public function compose(View $view)
{
//to prevent external views( email templates located in
//views/emails from passing by getting website process...
if(!starts_with($view->getName(), 'emails'))
{
//here where exception fired using pm2
$this->Get_Website(request());
$this->web=$this->website;
}
View::share('website', $this->web);
}
}
4. ServiceContorller:
(the Start of the process)
// POST PROCESS then Calling this function :
public function EmailDispatcher($data,Request $request)
{
//some code...
dispatch(function () use ($data) {
dispatch(new GuestMailerJob($data));
});
return redirect('somview');
}
5. GuestMailerJob:
namespace App\Jobs;
use App\Mail\GuestMailer;
// needed uses...
class GuestMailerJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable,
SerializesModels,GuestMailer;
protected $data;
public $tries = 3;
public $timeout = 10;
public function retryUntil()
{
return now()->addSeconds(12);
}
public function __construct(Array $data)
{
$this->data=$data;
}
public function handle()
{
$this->sendEmail($this->data);
}
}
6. GuestMailer:
namespace App\Mail;
use Illuminate\Http\Request;
use Mail;
trait GuestMailer
{
protected function sendEmail(array $all)
{
$toview = array(
'title' => $all["title"],
'other_attributes' => $all["other_attributes"]
);
Mail::send( [$all["template"]=> $all['view']],$toview,
function ($message) use($all)
{
$message->from( $all['from'],$all['nameFrom'] );
$message->subject( $all['subject'] );
//other params...
}
});
}
}
7. pm2 executed file : mail-worker.yml
//located in: (/prod)
//mail-worker.yml content:
apps:
- name: mail-worker
script: artisan
exec_mode: fork
interpreter: php
instances: 1
args:
- queue:work
- --tries=1
- --sleep=1
8 : artisan Cleaning
all php artisan cleaners are implemented
ex : php artisan clear-compiled
php artisan queue:restart
9 : pm2 Configuration :
pm2 start mail-worker.yml
pm2 monit
10 - pm2 state :
id name mode reload status cpu memory
0 mail-worker fork 1 online 0% 6.5mp
it's working with php artisan queue:work / listen
but with pm2 here is the exception.
pm2 Result :
Whoops\Run::handleError("Trait method setCookie has not been applied,
/app_base_path/PRODMAAN/vendor/filp/whoops/src/Whoops/Run.ph x
Whoops\Run::handleShutdown() [internal]:0
failed_Jobs result :
Illuminate\Queue\MaxAttemptsExceededException: App\Jobs\GuestMailerJob has been attempted too many times or run too long. The job may have previously timed out.
what is the problem ?
thank you for any advice about the code structure too.
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.
Maybe I'm not understanding on Laravel queue works, or maybe it itself is not working, my expected behaviour for Laravel Queue/Dispatch is that if a dispatch is initiated from the Controller, the code dispatched to queue should be executed silently and in the background. The end-user browser should not have to wait for the code to execute.
This is however what happens with my code, the dispatched code to queue leaves the browsers "Spinning..." whilst is executes.
Is this expected behavior? The code:
**Controller:**
public function make_eps_certs($tbl_eps)
{
//dd(Carbon::now()->addMinutes(10))
Log::info('Dispatching maeEPSCert to Queue');
$var_result=makeEPSCerts::dispatch($tbl_eps)->onQueue('eventadmin')
->delay(10);
return redirect()->back();
}
**Job:**
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use App\partSubs;
use Log;
use Image;
class makeEPSCerts implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*
* #return void
*/
protected $passdata;
public $timeout = 120;
public function __construct($passdata)
{
Log::info('Constructing makeEPSCert');
$this->passdata = $passdata;
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
try
{
Log::info('Beginning makeEPSCert');
$tbl_eps=$this->passdata;
.....
Change your LOG_DRIVERin your .env to database and create the needed migration files with php artisan queue:table, after that do a php artisan migrate.
After that you just need to run php artisan queue:work --queue="eventadmin"
and then you will recognize the expected behavior
A more detailed documentation can be found here: https://laravel.com/docs/5.5/queues
You can try again in the following way (I assume that you did instructions in Laravel docs but someday it's not working):
Step 1: drop table 'jobs' in your database.
Step 2: run command 'php artisan migrate' in console to create table 'jobs' again.
Step 3: run command 'php artisan queue:work' in console
Step 4: retry your app
Note that in .env file, you set up:
QUEUE_CONNECTION=database
QUEUE_DRIVER=database
P/s: It works for me!
I have a package for Laravel 5.5 and in the CommandsServiceProvider boot() method, I have:
if($this->app->runningInConsole()){
$this->commands([
MyCommandClass:class,
]);
}
Then, my MyCommandClass looks like:
<?php
namespace Testing\Commands;
use Illuminate\Console\Command;
class MyCommandClass extends Command
{
protected $signature = "execute:test";
protected $description = "Description of the command";
public function __construct()
{
parent::__construct();
}
public function handle()
{
$this->info('Command Executed');
}
}
The issue is that Artisan does not list the command when I run php artisan and when I try to run the command with php artisan execute:test it tells me the command is not defined.
What am I missing here? I followed the documentation for registering package commands in Laravel 5.5
It would appear that the Auto discovery only works when pulling a package from a Git Repo via Composer. When developing a package, the composer files within the package do not seem to auto load.