I am using windows.
My code on \app\Console\Kernel.php is like this:
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
protected $commands = [
Commands\CustomCommand::class,
];
protected function schedule(Schedule $schedule)
{
$schedule->command('custom:command')
->everyMinute();
}
protected function commands()
{
require base_path('routes/console.php');
}
}
My code on \app\Console\Commands\CustomCommand.php is like this:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use DB;
class CustomCommand extends Command
{
protected $signature = 'custom:command';
protected $description = 'test cron job to update status on table order';
public function __construct()
{
parent::__construct();
}
public function handle()
{
$id = 1;
DB::table('orders')
->where('id', $id)
->update(['status' => 2, 'canceled_at' => date("Y-m-d H:i:s")]);
}
}
I run php artisan list to see my cron job
After find my cron job (custom:command), then I run my cron job with like this : php artisan custom:command
It's successful update status = 2. After that I change the status manually again become 1, and then I wait one minute, it does not update status again
Is there anyone can help me?
You should also set cron on your local web server to run cron jobs.
How you change the status manually?
You change it in the database?
maybe the cron is running but 'id' int the database is equal to '2' and maybe this is why you dont see any change!
If you look for a better way to check if the Cron job is working
just add Log that will wroth to the log file
public function handle()
{
Log::info('Cron job working'); // you can also print variables
$id = 1;
DB::table('orders')
->where('id', $id)
->update(['status' => 2, 'canceled_at' => date("Y-m-d H:i:s")]);
}
Don't forget to had the Log to your source:
namespace App\Console\Commands;
use Illuminate\Console\Command;
use DB;
use Log; // Here
class CustomCommand extends Command
Related
We are running on Laravel 6 and we have got the following problem. A job we execute, that counts the number of impressions and clics of certain images triggers the following error, due to a high number of calls to the function:
method_exists(): The script tried to execute a method or access a
property of an incomplete object. Please ensure that the class
definition "App\Jobs\RegisterHouseLog" of the object you are trying to
operate on was loaded before unserialize() gets called or provide an
autoloader to load the class definition
We already increased the number of tries so it executes after sometime, so it's not the actual problem, but it sends an error to our error logs (Slack Channel) and causes a lot of "spam".
I was trying to fix the above error but I wasn't able to fix it, so at least I tried to "mute" the notification through an "failed job exception" but still to it fails.
The best would be to resolve the actual problem, the second best would be to mute it.
Anyone could help?
The Job:
<?php
namespace App\Jobs;
use App\HouseLog;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use Exception;
class RegisterHouseLog implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $tries = 20;
public $house_id;
public $user_id;
public $date;
public $type;
/**
* Create a new job instance.
*
* #return void
*/
public function __construct($house_id,$user_id,$type, $date)
{
$this->house_id = $house_id;
$this->user_id = $user_id;
$this->type = $type;
$this->date = $date;
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
$log = new HouseLog();
$log->user_id = $this->user_id;
$log->house_id = $this->house_id;
$log->type = $this->type;
$log->date = $this->date;
$log->save();
}
public function failed(Exception $exception)
{
Log::critical('Failed Register House');
}
}
And the call:
<?php
namespace App\Http\Controllers\api;
use App\HouseLog;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Jobs\RegisterHouseLog;
use Carbon\Carbon;
class HouseLogController extends Controller
{
public function registerLog(Request $request)
{
$date = Carbon::now();
RegisterHouseLog::dispatch($request->house_id, $request->user_id, $request->type, $date);
}
}
Thanks a lot!!
This error is likely due to the job dispatcher not being able to resolve \App\Jobs\RegisterHouseLog when it pulls from the job queue to kick off a job.
Try clearing the class loader cache:
artisan cache:clear
Also try restarting your job dispatcher process.
artisan queue:restart
It may not be the best solution, but you could also fix this by removing implements ShouldQueue from your job class definition; it would make the job kick off right away without going through the queue.
in db i have column visit_clear i want it 0 after one day so i used this code
in kernal.php
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
protected $commands = [
];
protected function schedule(Schedule $schedule)
{
$schedule->command('cron:update-user-not-new')->daily();
}
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}
and in command/UpdateUserNotNew.php
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class UpdateUserNotNew extends Command
{
protected $signature = 'cron:update-user-not-new';
protected $description = 'Command description';
public function __construct()
{
parent::__construct();
}
public function handle()
{
$dayAgo = 1; // Days ago
$dayToCheck = \Carbon\Carbon::now()->subDays($dayAgo)->format('Y-m-d');
Customer::whereDate('visit_date', '<=', $dayToCheck)
->update([
'visit_clear' => 0
]);
}
}
i am sheduling commnd like this as u can see cron:update-user-not-new should i use crone:UpdateUserNotNew?
You need to register your command in Kernel.php like this:
protected $commands = [
'App\Console\Commands\UpdateUserNotNew',
];
You should then be able to run the command manually with php artisan cron:update-user-not-new
In order for the automatic running of the command to work, you need to add an entry to your system's task scheduler, as this is what Laravel uses to run commands on a schedule.
Assuming you are using Linux, you need to add an entry to your crontab. To do this, in a command prompt enter crontab -e, hit enter, and add this line:
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
Don't forget to replace /path-to-your-project with the root folder of your project
Once done editing the crontab, save and close the editor and the new entries should be installed, and your command should now run on the schedule.
All this info came from https://laravel.com/docs/7.x/scheduling so if you need more info take a look there
I've made CRON Job using Laravel's task scheduling. But what I need is to store somewhere when that task was last ran,
Does anyone have any methods of how they store that and also, If Laravel outputs anything that can tell you when it was last ran?
Thanks
Not possible directly, however it is possible if you cache a date-time string on each run (either at the beginning or end of your script).
Cache::rememberForever('name_of_artisan_task', function () {
return now()->toDateTimeString();
});
The example shows using the Cache facade's ::rememberForever method to create a key/value of the last time the task was ran. As the name suggests, this is saved forever.
You can easily retrieve this date and time using the cache() helper:
cache('name_of_artisan_task');
The con with this method is that if your cache is cleared, you will not longer have this stored.
Using a cache is not a safe way to do this, as #thisiskelvin hinted, clearing the cache will remove the data (which should happen on each deployment) but he didn't provide an alternative
So here is one if you need this date reliably (if you use it to know the interval to run an export for instance)
In which case I recommend creating a model php artisan make:model ScheduleRuns -m
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
/**
* #property string $task
*/
class ScheduleRuns extends Model
{
public const UPDATED_AT = false;
public $timestamps = true;
protected $attributes = [
'task' => '',
];
protected $fillable = [
'task',
'created_at',
];
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('schedule_runs', function (Blueprint $table) {
$table->id();
$table->string('task');
$table->timestamp('created_at')->nullable();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('schedule_runs');
}
};
Then use schedule hooks to create it (or do it within the task if you want to avoid possible seconds differences)
$schedule->command('export:users')
->weekly()->onSuccess(fn () => ScheduleRuns::create(['task' => 'export:users']))
And to retrieve the latest run
ScheduleRuns::query()->where('task', 'export:users')->latest();
Just write log each time the task was run, or you can push it into database.
<?php
namespace App\Console\Commands\Tasks;
use Illuminate\Console\Command;
class ScheduledTask extends Command
{
public function handle()
{
//
// ...handle you task
//
$file = 'logs/jobs/' . __CLASS__ . '.log';
$message = 'Executed at: ' . date('Y-m-d H:i:s', time());
file_put_contents(storage_path($file), $message, FILE_APPEND);
}
}
I have a problem when I use
php artisan schedule:run
And that command returns
No scheduled commands are ready to run.
My server allows to call CRON above each 5 minutes.
So I think my server setting is the reason not to work schedule:run.
So I need to try CRON without Task Scheduler, and check if the CRON return correct response or not.
So please tell me how can I use CRON without Task Scheduler.
As information, I put my codes below.
These codes work correctly to send E-mail and make log when I use
php artisan command:notice_expired_date
Kernel.php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
protected $commands = [
'\App\Console\Commands\NoticeExpiredDateCommand',
];
protected function schedule(Schedule $schedule)
{
$schedule->command('command:notice_expired_date')
->daily()
->at(config('const.OPEN_TIME.FROM'))
->appendOutputTo(storage_path('logs/schedule/notice_expired_date.log'));
}
protected function commands()
{
$this->load(__DIR__ . '/Commands');
require base_path('routes/console.php');
}
}
ExpiredDateNotification.php
namespace App\Console\Commands;
use App\Ticket;
use App\User;
use Carbon\Carbon;
use Illuminate\Console\Command;
use App\Notifications\ExpiredDateNotification;
class NoticeExpiredDateCommand extends Command
{
protected $signature = 'command:notice_expired_date';
protected $description = 'send email to user to notice the expired date of his tickets.';
public function __construct()
{
parent::__construct();
}
public function handle()
{
$this->checkBefore1Week();
Common::makeLog($this->getName());
}
protected function checkBefore1Week()
{
$from = Carbon::today()->copy()->addDays(7)->format('Y-m-d H:i:s'); //ex. 2019-03-01 00:00:00
$to = Carbon::tomorrow()->copy()->addDays(7)->subSecond()->format('Y-m-d H:i:s');
$tickets = Ticket::whereBetween('expired_date', [$from, $to])->get();
$noticing_users = [];
foreach ($tickets as $i => $ticket) {
$noticing_users[$i] = $ticket['user_id'];
}
if ($noticing_users != []):
$users = User::find($noticing_users);
foreach ($users as $user) :
$user->notify(new ExpiredDateNotification($user, $expired_date = $from));
endforeach;
endif;
}
}
Common.php
namespace App\Console\Commands;
class Common
{
public static function makeLog($command_name)
{
$param = [
'command_name' => $command_name,
];
\Log::info('command executed', $param);
}
}
I solved this by my self.
I wrote cron like this but not work.
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
Now, I write cron like this and it works.
*/5 * * * * cd /{project directory} && /usr/local/bin/php artisan schedule:run >> /dev/null 2>&1
The directory of php may depend on the server.
And about I type below on the terminal.
php artisan schedule:run
The ones place of the minutes of the time is 5,
the command returns
Running scheduled command
If the ones place of the minutes of the time is except of 5, it returns
No scheduled commands are ready to run.
I'm creating a command for sending an email automatically daily.
I'm creating the command like this:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Mail;
class SendEmail extends Command
{
protected $signature = 'emails:send';
protected $description = 'Sending emails to the users.';
public function __construct()
{
parent::__construct();
}
public function handle()
{
$data = array(
'name' => "МГ 'Константин Величков', гр. Пазарджик",
);
Mail::send('emails.test', $data, function ($message) {
$message->from('mg.kvelichkov#gmail.com', 'МГ "Константин Величков"');
$message->to('yoannam1502#gmail.com')->subject('Оценки');
});
$this->info('The emails are send successfully!');
}
}
And then register it in Kernel like this:
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
protected $commands = [
Commands\Inspire::class,
Commands\SendEmail::class,
];
protected function schedule(Schedule $schedule)
{
$schedule->command('emails:send')->daily();
}
}
I'm listing all artisan commands and i can see my new comand emails:send - therefore its created, but when i try to run it (php artisan emails:send) i got this:
[Swift_TransportException] Process could not be started [The system
cannot find the path specified. ]
What is the problem?
It seems Gmail is blocking sending emails or your environment blocks connection.
Go to this address to unlock your Gmail account. Also, check firewall settings on your server.