2
class  SendLostwillEmailsController extends Controller
{
    public function runCommand()
    {
        return $this->getAllLostWill();
    }

    protected function getAllLostWill()
    {
        try {
            $status = false;
            $newMailSetting = new ChangeMailSettings();

            $getToday = Carbon::now()->format('Y-m-d');
            $getLast7day = Carbon::now()->subDays(7)->format('Y-m-d');
            $lostwill = LostWill::select('id', 'lost_first_name', 'lost_last_name', 'lost_dod', 'user_id')->whereBetween('created_at', [$getLast7day, $getToday])->get();

            if (!$lostwill->isEmpty()) {
                $listOfEmails = $this->getEmailList($lostwill->pluck('user_id'));

                $newMailSetting->sendMail();
                $listChunkEmail = array_chunk($listOfEmails['emails'], 550, false);
                $i = 0;
                $countSentMail = 0;
                while ($i < count($listChunkEmail)) {
                    Notification::route('mail', 'info@lostwillregister.com.au')->notify(new SendLostwillMarketingEmail($listChunkEmail[$i], $lostwill));
                    $countSentMail = ($countSentMail + count($listChunkEmail[$i]));
                    $i++;
                }
                //$listChunkEmail[$i]
                Log::channel('marketing_mail')->info('total email sent:' . $countSentMail);
                $newMailSetting->setDefault();
                $status = true;
            } else {
                $status = false;
                Log::channel('marketing_mail')->info("lost will not registers for yesterday's date");
            }

            return $status;
        } catch (Exception $e) {
            return false;
            Log::channel('marketing_mail')->info($e->getMessage());
        }
    }

I want to run getAllLostWill() in crontab. This function get all the lost will for the past 7 days and sends a mail. The file path of SendLostwillEmailsController class is lost-will-register\app\Http\Controllers Currently, in my crontab I have this:

 GNU nano 4.8                                                                                /tmp/crontab.qrUExv/crontab                                                                                          
# Edit this file to introduce tasks to be run by cron.
# 
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
# 
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').
# 
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
# 
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
# 
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
# 
# For more information see the manual pages of crontab(5) and cron(8)
# 
# m h  dom mon dow   command
25 10 * * * cd /var/www/lost-will-register && php artisan marketing:startCampaign >> /dev/null 2>&1
00 16 * * * cd /var/www/lost-will-register && php artisan delete:files >> /dev/null 2>&1
25 10 * * * cd /var/www/australian-will-register && php artisan reminder:annualwillregistration >> /dev/null 2>&1
00 00 * * 4 cd /var/www/lost-will-register-nz && php artisan marketing:startCampaign >> /dev/null 2>&1
00 16 * * * cd /var/www/lost-will-register-nz && php artisan delete:files >> /dev/null 2>&1

would this be right command to run the function getAllLostWill() 00 01 1 1 * cd /var/www/lost-will-register && php artisan reminder:getAllLostWill >> /dev/null 2>&1?

I am new to crontab, so I don't know much; however, I assume you need to put the command first, as in time 00 00 ** **, and then the path to the file I mentioned above. I am not sure how to put it all together to send a mail every week on Thursday at 1 pm, so by running the getAllLostWill() function, which sends the mail

Karl Hill
  • 12,937
  • 5
  • 58
  • 95
user022yufjb
  • 157
  • 1
  • 3
  • 11
  • 4
    why dont you use the actual laravel [scheduler](https://laravel.com/docs/10.x/scheduling) then you can simply run it like `->weeklyOn(4, '13:00');` or `->weekly()->thursdays()->at('13:00');` – silver Jun 21 '23 at 07:29

3 Answers3

3

Laravel recommended way to schedule command jobs is to use their Task Scheduling feature.

You should not define all your command lines manually in your server crontab. Instead, you should only add a job to run Laravel scheduler:

* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

Regarding you case, you should create a command and move your code in that command instead of using a Controller.

Then, you can define your command schedules in your app/Console/Kernel.php file:

protected function schedule(Schedule $schedule): void
{
    $schedule->command('your:command-name')->weeklyOn(4, '13:00');

}
Seb33300
  • 7,464
  • 2
  • 40
  • 57
2

To schedule the execution of the getAllLostWill() function every Thursday at 1 PM using crontab, you can update your crontab file with the following entry.

0 13 * * 4 cd /var/www/lost-will-register && php artisan reminder:getAllLostWill >> /dev/null 2>&1
  • 0: Specifies the minute (0 represents the hour's start). Using 00 is valid and represents the same thing.
  • 13: Specifies the hour in 24-hour format (13 represents 1 PM).
  • *: Indicates that any day of the month is acceptable.
  • *: Indicates that any month is acceptable.
  • 4: Specifies the day of the week (4 represents Thursday).
Karl Hill
  • 12,937
  • 5
  • 58
  • 95
  • And if I wanna schedule for Wednesday would it be `0 13 * * 4 `? – user022yufjb Jun 21 '23 at 01:48
  • It would be 0 13 * * 3 for Wednesday. – Karl Hill Jun 21 '23 at 01:55
  • Ah I see. Also what does reminder: means before the function name? How can I know where this is in my code? – user022yufjb Jun 21 '23 at 02:12
  • It will run the command reminder:getAllLostWill as defined by its signature. You can search your codebase for reminder:getAllLostWill. – Karl Hill Jun 21 '23 at 02:36
  • You can also run "php artisan list" and locate the reminder:getAllLostWill command. – Karl Hill Jun 21 '23 at 03:29
  • When I do php artisan list I cannot see the reminder:getAllLostWill. I also did a quyick search in my code but its not there and neither the mail got sent. So I was wondering where can I add the reminder:getLostWill in my code? – user022yufjb Jun 21 '23 at 03:58
  • If you run "php artisan make:command getAllLostWill" it will create the command file in app/Console/Commands/. From there you can change the new file's signature to: protected $signature = 'reminder:getAllLostWill'; – Karl Hill Jun 21 '23 at 04:25
  • After doing that it has an handle function in the command class it created so what would go in handle class? – user022yufjb Jun 22 '23 at 01:32
  • $lostWills = new SendLostwillEmailsController(); $getLostWills = $lostWills->getAllLostWill(); – Karl Hill Jun 22 '23 at 01:37
0

You've got two components here: learning the syntax for cron, which there are many online resources for, and constructing the PHP/Laravel code.

For sanity's sake, I'd recommend having a self-contained PHP page that deals with all the code stuff and set the cron to call that page (as opposed to having PHP code in the crontab).

25 10 * * * php -d safe_mode=off -f /var/www/lost-will-register/my-schedule.php > /dev/null

Aside from separating the code from the cron, this will allow you to maintain and troubleshoot things a bit easier. Ideally, you should store such scripts in their own folder outside of the webroot for security purposes. It's also worth mentioning that you can set up crons for different Linux users (so www-data for web stuff), and that the correct permissions need to be in place on the target PHP script.

Morris
  • 218
  • 1
  • 10