Laravel: detect if running migrations - laravel

I have setup some event listeners in which I would like to detect if I'm runnnig database migrations or a normal request/command.
Is there some way of knowing this? Global flag? Environment?
Thanks in advance.

You can check if the console is being used with App::runningInConsole() ... that might be sufficient depending on how you are running the migrations.
Update:
OK, after doing some more digging, it looks like you can hack your way to the info you need using the follow example:
if(app()->runningInConsole()) {
// we are running in the console
$argv = \Request::server('argv', null);
// :$ php artisan migrate:refresh -v
//
// gives:
//
// $argv = array (
// 0 => 'artisan',
// 1 => 'migrate:refresh',
// 2 => '-v',
// )
if($argv[0] == 'artisan' && \Illuminate\Support\Str::contains($argv[1],'migrate')) {
// we are running the artisan migrate command
}
}
Source: How to get the current console command in Laravel

Actually, Laravel fires several events while running migrations:
Illuminate\Database\Events\MigrationsStarted : A batch of migrations is about to be executed.
Illuminate\Database\Events\MigrationsEnded : A batch of migrations has finished executing.
Illuminate\Database\Events\MigrationStarted : A single migration is about to be executed.
Illuminate\Database\Events\MigrationEnded : A single migration has finished executing.
You can utilize this to do anything you want. For example:
// change default Log channel when running migrations
Event::listen(function (MigrationsStarted $event) {
config()->set('logging.default', 'migration');
});
In your case, you can set a key in your app config files like app.running_migrations and set it to true in the event listener.

Related

Laravel: Send slack notification after a scheduled task finished

I need to schedule a few tasks on an application built using Laravel and I would like to send a slack notification after those tasks are finished with the output.
Laravel provides an "after" hook (https://laravel.com/docs/5.8/scheduling#task-hooks) so I can do something like this:
$schedule->command('mycommand')
->daily()
->after(function () {
// How can I access the command's name and output from here?
});
I've tried with $this->output but $this points to App\Console\Kernel and it says Undefined property: App\Console\Kernel::$output. I've also tried to pass a parameter to the closure, but I think I need to specify a type, but I have no idea and the documentation is not very clear.
Anyone has any idea on how to do this?
Thanks in advance!
Assuming you have this in your command
$this->info('hello');
In your kernel, you can send the output to a temporary file and then read the file and send it
/** #var \Illuminate\Console\Scheduling\Event $command */
$command = $schedule->command('mycommand')
->daily()
->sendOutputTo('storage/app/logs.txt');
$command->after(function () use ($command) {
\Log::debug([$command->command, $command->output]);
\Log::debug(file_get_contents($command->output));
});
You will get
[2019-10-11 13:03:38] local.DEBUG: array (
0 => '\'/usr/bin/php7.3\' \'artisan\' command:name',
1 => 'storage/app/logs.txt',
)
[2019-10-11 13:03:38] local.DEBUG: hello
Maybe it would be the time to re-open this proposal https://github.com/laravel/ideas/issues/122#issuecomment-228215251
What kind of output does your command generate? is it command line or is just a variable you're trying to pass to the after()?
Alternativly in your handle() method of the command you can call the desired command after all the code has been excuted, you can even pass a parameter to the command.
You can do that by using Artisan
Artisan::call('*command_name_here*');

Run scheduler using cron method in Laravel

I have an expires_at column in one of my models and I want to run a scheduler based on the timestamp of that.
I tried the following code :
$collection = Foo::first();
$schedule->call( function() {
// Do Something
})->cron( \Carbon\Carbon::parse( $collection->expires_at )->format( 'i h d m' ) . ' *' );
But when I run php artisan schedule:run at the expire date I get No scheduled commands are ready to run.
Instead of calling function you can do that by command. Make command for that cron job and than you can specify that schdeuler in schedule method of kernel.php
schedule->command('command Name')
->cron( \Carbon\Carbon::parse( $collection->expires_at )->format( 'i h d m' ) . ' *' );
Hope this helps :)

Scheduled task with parameter laravel

in Laravel 5.6 i have a controller that invokes a command through a Process component.
The command run fine, is about a compression of a folder with the name the user gives.
$command = 'tar -czvf '.$nameFile.' storage/images/';
$process = new Process($command);
$process->setTimeout(1800);
$process->run();
I need to schedule that job 3 times a day. I saw task scheduling with file app/Console/Kernel.php; the problem is to execute the process with the file name the user gives.
How can i programm a Schedule task in this situation?
Thanks
Assume you run the schedule tasks three times a day, per each user input. You can create a eloquent model for such purpose, says ProcessTask, and save the required data in Controller:
ProcessTask::create(['user_id' => $userId, 'name_file' => $nameFile]);
Then, you can make scheduling task as:
$schedule->call(function () {
$tasks = ProcessTask::all();
foreach ($tasks as $task) {
$command = 'tar -czvf '.$task->name_file.' storage/images/';
....
}
})->hourly()
->when(function() { return date('H') % 8 == 0; }) // run tasks at 00:00, 08:00, 16:00
->name('processTask')
->withoutOverlapping();
If the scheduling tasks are time-consuming, the best practice is to dispatch tasks to queue and let workers consume it.

How to disable all visitors cookies in Joomla 3.x

I'm trying to disable all visitor cookies for my Joomla website.
I found some tutorials, but they are for Joomla version:1.x
Any suggestions?
The solution is very similar to solution to remove cookies in Joomla version 1.x and 2.x. So we will use the same condition and principle.
If you change this two files then maybe something other will not work. Change this only if you know what are you doing and if you know that will everyting else work. Because you can break the whole website!
You must edit two files /libraries/src/Application/CMSApplication.php and libraries/joomla/session/handler/native.php
In libraries/src/Application/CMSApplication.php change code around line 166 and add if condition for whole code in method if (substr($_SERVER['SCRIPT_NAME'] , 0 , 14) == "/administrator"){
public function checkSession()
{
if (substr($_SERVER['SCRIPT_NAME'] , 0 , 14) == "/administrator"){ // added condition
$db = \JFactory::getDbo();
$session = \JFactory::getSession();
$user = \JFactory::getUser();
// ... rest of code
}
}
In libraries/joomla/session/handler/native.php change code around line 229 add if condition for whole code in method like in previous file
private function doSessionStart()
{
if (substr($_SERVER['SCRIPT_NAME'] , 0 , 14) == "/administrator"){ // added condition
// Register our function as shutdown method, so we can manipulate it
register_shutdown_function(array($this, 'save'));
// ... rest of code
}
}
This works in Joomla 3.8.2
Note: after every Joomla update you must edit this two files again and test if this solution still works.
Set the cookie-path "/administrator" in the Admin Joomla Settings (System => Configuration).
Then the session cookies are created only for the admin area.
To avoid all cookies for normal visitors, you need to follow the below steps.
First of all: Deactivate site statistics! Global configuration -> Statistics -> Statistics: No. This will stop the "mosvisitor" cookie.
Don't use the Template Chooser module, because it uses a cookie named "jos_user_template".
Be careful with components: Some might start their own PHP session.
Now to the main point: comment out line 697 of /includes/joomla.php like this:
// setcookie( $sessionCookieName, '-', false, '/' );
Additional: Comment out line 25 in /offline.php:
// session_start();
This seams to be an artifact of old versions.

Laravel Cron not auto run (Windows)

I use Cron (https://github.com/liebig/cron) for Laravel 4 to run specific task in specific time
I have this code in my Global.php
Event::listen('cron.collectJobs', function() {
Cron::add('example1', '* * * * *', function() {
$trip = new TripReminder();
$trip->checkDateAndSendEmail();
});
Cron::setRunInterval(1);
$report = Cron::run();
print_r ($report);
});
=>This Code use to Send an email to the customers in every minute (just demo and check)
in cmd, i run this command "php artisan cron:run"
It can run well, the email was sent also, but, it only run 1 times.
I don't know what i'm missing.
Please help !
Thank you !

Resources