When is laravel executing the yearly() function - laravel

When is laravel executing the yearly() function of it's task scheduling? Is it from the first time it was used or is it each year on 01.01.YYYY?
I checked up the laravel docs and several pages, but I wasn't able to find out the answer to this question.
$schedule->call(function () {
DB::table("invoice_settings")
->where("key", "invoice_number")
->update(["value" => 860001]);
})->yearly();
I expect that it's running on the 01.01.YYYY.

Laravel's yearly coresponds to crontab's yearly event. Described here:
https://crontab.guru/every-year

This is the cron produced:
0 0 1 1 *
Which runs:
At 00:00 on day-of-month 1 in January.

The yearly function is defined in:
vendor/laravel/framework/src/Illuminate/Console/Scheduling/ManagesFrequencies.php
Here you can find the daily, monthly and yearly, and other frequency functions.
public function daily()
{
return $this->spliceIntoPosition(1, 0)
->spliceIntoPosition(2, 0);
}
public function monthly()
{
return $this->spliceIntoPosition(1, 0)
->spliceIntoPosition(2, 0)
->spliceIntoPosition(3, 1);
}
public function yearly()
{
return $this->spliceIntoPosition(1, 0)
->spliceIntoPosition(2, 0)
->spliceIntoPosition(3, 1)
->spliceIntoPosition(4, 1);
}
As in the official Laravel documentation is written that the daily function runs daily at midnight, since the yearly function is defined in the same way it will run at the 1/1/YYYY at midnight.

Related

How to check if number is a decimal and run function laravel

I use Ajax to search my data and when it runs it removes price formatting from 49.99 to 4999. I can solve the problem by using ${{number_format($product->price / 100, 2)}} in the view file but the problem is if the price is displaying correctly as 49.99 and the function runs then it now displays as 0.50. How can I run a check so that this function only attempts to format price if it doesn't have decimal, only if its a int like 4999
I tried
if(is_float($product->price)){
echo $product->price;
} else {
echo number_format($product->price / 100, 2);
}
This worked for me
if (is_numeric($product->price) && floor($product->price) != $product->price) {
echo $product->price;
} else {
echo number_format($product->price / 100, 2);
}

Queue notifications delay in Laravel

I tried delaying each notification (or job) using Laravel queues. Still, instead of the notifications being delayed one after the other, the delay is applied to all the notifications at once. However, the delay is only applied to the first notification, and the rest are sent out simultaneously as the first message. Please, can anyone in this community help me?
This is part of the method that gets only the applicants whose admissions are accepted or rejected and then notify them individually. Unfortunately, the mail server we are using only allows sending a maximum of 30 emails per 1 minute; therefore, I need to use queuing to limit sending only (not more than) 1 email per 2 seconds.
foreach ($applications as $application)
{
$application_id = $application->id;
$admission = Admission::where('application_id', $application_id)->first();
if (empty($admission->admission_no) & $application->status === 5) {
$this->generateAdmissionNumber($application->id, $application->course_id);
$application->update(['done' => 1]);
$admissions = Admission::where('course_id', '=', $id)->get();
foreach ($admissions as $admission) {
$admission->update(['done' => 1]);
}
}
$application->done = 1;
$application->update();
$user = $application->users;
if ($user->notify_if_decision_is_made === 1)
{
$user->notify((new DecisionNotification($user))
->delay(Carbon::now()->addSeconds(2)));
}
}
I followed the guides but still have no solution. I looked at many solutions here but did not see any issues like this one.
I set QUEUE_CONNECTION=database in my .env file, added shouldQueue in the DecisionNotification file, and run php artisan queue:work from the terminal to execute the jobs. I appreciate any help.
The ->delay() only gives a delay to the running job. As your loop is running almost instantly, it won't delay put a delay of 2 seconds between each job.
One way to achieve what you want is:
foreach ($applications as $i => $application) {
// your code chunk
$user->notify((new DecisionNotification($user))->delay($i * 2)));
}
This results in delays as:
Job 1: 0s
Job 2: 2s
Job 3: 4s
Job 4: 6s
Job 5: 8s
...
By the way, ->delay() also accepts integer as second.
You can use sleep() function, which holds the loop for defined period, for example if you want to hold loop for 2 seconds, use sleep(2).
Your code should be:
foreach ($applications as $application) {
$application_id = $application->id;
$admission = Admission::where('application_id', $application_id)->first();
if (empty($admission->admission_no) & $application->status === 5) {
$this->generateAdmissionNumber($application->id, $application->course_id);
$application->update(['done' => 1]);
$admissions = Admission::where('course_id', '=', $id)->get();
foreach ($admissions as $admission) {
$admission->update(['done' => 1]);
}
}
$application->done = 1;
$application->update();
$user = $application->users;
if ($user->notify_if_decision_is_made === 1) {
$user->notify((new DecisionNotification($user))->delay(Carbon::now()->addSeconds(2)));
}
sleep(2);
}
Hope this will be useful.
Read More about sleep()

Run trigger in partiuclar time interval only

I use this part of the code (and also time trigger) to run script every 5 minutes on "working hours" but now I need some adjustments
function officeHours(){
var nowH=new Date().getHours();
var nowD=new Date().getDay();
Logger.log('day : '+nowD+' Hours : '+nowH)
if(nowH>17||nowH<8||nowD==6||nowD==0){return}
Browser.msgBox('time to work !');//normally your real function should begin here...
}
Reference: Working hours only trigger
But how be more specific? e.g. set working hours from 8:30 to 17:30 or another e.g. when shift (working hours) starts at one day and ends next day (from 22:30 at day one to 06:30 at next day)?
You can check if the current hour is between the shift hours as in this example.
function officeHours(startShift, endShift){
startShift = startShift || 23;
endShift = endShift || 7;
var currentHour = new Date().getHours();
if (startShift > endShift) {
if (currentHour >= startShift || currentHour <= endShift) {
// run the trigger function
}
} else {
if (currentHour >= startShift && currentHour <= endShift) {
// run the trigger function
}
}
}

Cronjob in Laravel 5

I have the job table contains post_at,day_open,block properties
The post_at property is the day when user post the job (Ex:2015-11-24)
The day_open property is the day that job is open (Ex:10)
The block property can contain 2 values 0 or 1. If post_at + day_open > right now the block value will change from 0 to 1
So how can I do that using cronjob?
First check wheather the post_at,day_open are edit in current date
$date = date('Y-m-d');
$job= DB::table('job') ->select('post_at','day_open','block')->where('updated_at',$date) -first();
$id=$job->id;
if(isset($job) && !empty($job))
{
$finding=CronJobCotroller::pushNotify($id);
}
if it's true it go to function pushNotify under the CronJobCotroller,here we write the coding for changing block field value 0 to 1.
public function pushNotify($id) {
$job= DB::table('job') ->select('block')->where('id',$id) ->get();
if(isset($job) && !empty($job))
{
foreach ($job as $cb)
{
$job= DB::table('job')->update('block',1)->where('block',0);
}
}
}

laravel schedule command at random time

I've got a strange issue.
I use a custom command to share, via FB api, some url.
Now this command is scheduled to a fixed cron configuration but I would like this to be randomic, maybe between time ranges.
I tried using a random sleep function inside command, but I got strange behavior.
Did anyone already have to face this problem?
One solution is to put the code you want to run into a Queued Job, and then delay that job a random amount. For example, this code will run at a random time every hour (the same can easily be extrapolated to random time every day or on some other interval):
$schedule
->call(function () {
$job = new SomeQueuedJob();
// Do it at some random time in the next hour.
$job->delay(rand(0, 60 * 59));
dispatch($job);
})
->hourly();
You can generate random time at beginning.
protected function schedule(Schedule $schedule)
{
$expression = \Cache::get('schedule:expressions:inspire');
if (!$expression) {
$randomMinute = random_int(0, 59);
// hour between 8:00 and 19:00
$hourRange = range(8, 19);
shuffle($hourRange);
// execute twice a day
$randomHours = array_slice($hourRange, 0, 2);
$expression = $randomMinute . ' ' . implode($randomHours, ',') . ' * * * *';
\Cache::put('schedule:expressions:inspire', $expression, Carbon::now()->endOfDay());
}
$schedule->command('inspire')->cron($expression);
}

Resources