Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CakePHP 2.X Cron Jobs Not Working

EDITS FOR 2017 IN BOTTOM SECTION

I've read the following doc entries:

http://book.cakephp.org/2.0/en/console-and-shells.html

http://book.cakephp.org/2.0/en/console-and-shells/cron-jobs.html

As well as this question:

Creating Cron Jobs in CakePHP 2.x

I'm having trouble trying to implement two cron job functions, one being the exact same as the Stack Overflow question listed above to send a test email. The other to simply inset a new row in my "crons" table. Neither works and I believe it is the way in which I am trying to call the cron jobs. I don't believe I am using the correct path.

Console/Command/CronShell.php

class CronShell extends AppShell {
    public $uses = array('Cron');

    public function trigger() {
        $cron = array(
            'Cron' => array(
                'title' => 'Cron Test'
            )
        );

        $this->Cron->create();
        $this->Cron->save($cron);
    }
}

I have set up a CronsController.php with the above code as part of the index action. The code works fine when accessed via the controller so the issue is with the shell or cron job.

I used to following commands to call this method as a cron job, none worked...

***** cd /home1/bhndbrwn/public_html/cake2/app && Console/cake cron trigger
***** cd /home1/bhndbrwn/public_html/cake2/app && Console/cake cronshell trigger
***** cd /home1/bhndbrwn/public_html/cake2/app && Console/cake Cron trigger
***** cd /home1/bhndbrwn/public_html/cake2/app && Console/cake CronShell trigger
***** cd /home1/bhndbrwn/public_html/cake2/app/Console/cake cron trigger
***** cd /home1/bhndbrwn/public_html/cake2/app/Console/cake cronshell trigger
***** cd /home1/bhndbrwn/public_html/cake2/app/Console/cake Cron trigger
***** cd /home1/bhndbrwn/public_html/cake2/app/Console/cake CronShell trigger

Similarly I tried the following shell to send a test email

Console/Command/EmailShell.php

App::uses('CakeEmail', 'Network/Email');

class EmailShell extends Shell {

    public function main() {

       $Email = new CakeEmail();
       $Email->template('test', 'default')
           ->emailFormat('html')
           ->to([email protected])
           ->from('[email protected]')
           ->subject('Cron Email')
           ->send();
    } // END MAIN FUNCTION

}

Again I tried the following commands. For each of these commands I also tried removing the method name "main" per the doc's instructions.

***** cd /home1/bhndbrwn/public_html/cake2/app && Console/cake email main
***** cd /home1/bhndbrwn/public_html/cake2/app && Console/cake emailshell main
***** cd /home1/bhndbrwn/public_html/cake2/app && Console/cake Email main
***** cd /home1/bhndbrwn/public_html/cake2/app && Console/cake EmailShell main
***** cd /home1/bhndbrwn/public_html/cake2/app/Console/cake email main
***** cd /home1/bhndbrwn/public_html/cake2/app/Console/cake emailshell main
***** cd /home1/bhndbrwn/public_html/cake2/app/Console/cake Email main
***** cd /home1/bhndbrwn/public_html/cake2/app/Console/cake EmailShell main

2017 EDIT - STILL NOT WORKING

I have updated my cron to /home/allfan5/public_html/allfans/app/Console/cake.php -app /home/allfan5/public_html/allfans/app/ test action

I have a shell called TestShell and an function called "action". The action function is completely empty to test things (I was also trying a function where I was emailing users but I was getting errors so I created a new shell and a completely empty function and I'm getting the same error).

The error I am receiving now is

2017-10-14 21:34:02 Error: Fatal Error (64): Cannot use ‘String’ as class name as it is reserved in [/home/allfan5/public_html/allfans/lib/Cake/Utility/String.php, line 25]
2017-10-14 21:34:02 Error: [FatalErrorException] Cannot use ‘String’ as class name as it is reserved
Stack Trace:
#0 /home/allfan5/public_html/allfans/lib/Cake/Error/ErrorHandler.php(203): ErrorHandler::handleFatalError(64, ‘Cannot use ‘Str…’, ‘/home/allfan5/p…’, 25)
#1 /home/allfan5/public_html/allfans/lib/Cake/Core/App.php(929): ErrorHandler::handleError(64, ‘Cannot use ‘Str…’, ‘/home/allfan5/p…’, 25, Array)
#2 /home/allfan5/public_html/allfans/lib/Cake/Core/App.php(902): App::_checkFatalError()
#3 [internal function]: App::shutdown()
#4 {main}

I have no idea what could be causing this as the shell function is completely empty. Even the action when I tried emailing out users, I copied the code and ran it from a controller and it worked fine. So there's something wrong with how Cake is executing or calling the shell.

I am running cake 2.5 on PHP 5.4

like image 390
bowlerae Avatar asked Apr 18 '14 13:04

bowlerae


2 Answers

We use a different way of running crons:

in the webroot dir I have a file called corn_dispatcher.php which is a copy of the index.php file but with some modifications to the end of the file:

App::uses('Dispatcher', 'Routing');
define('CRON_DISPATCHER',true);
$Dispatcher = new Dispatcher();
$Dispatcher->dispatch(new CakeRequest($argv[1]), new CakeResponse());

Then I have a CronjobController.php file with the functions that are related to individual crons. Also added a beforeFilter function with $this->Auth->allow(); (so crons run without breaking due to ACL restrictions) as well as removing layouts and autorendering

Next set up routes to the crons.

Finally in my crontabs file I put:

1 6 * * * php -f /path-to-webroot/cron_dispatcher.php /routedUrl

Also few things to note:

  • you may need to run the php form the full path not as I have it above.
  • if files are being created you may need to run teh crontab as the www-data user or equivalent on your distro of linux
  • Also if you have a lot of stuff in the AppController.php 's beforeFilter function, you may need to put a condition to see if the HTTP_HOST value is empty so you keep the running of crons as light as possible

I hope that helps.

like image 73
SidMalde Avatar answered Nov 16 '22 22:11

SidMalde


Use the full path for the cake shell script (rather than using cd) then pass the full path of your app directory, as per console instructions:

Your working path should be the same as your application path to change your path use the '-app' param. Example: -app relative/path/to/myapp or -app /absolute/path/to/myapp

So your cron tab becomes:

 * * * * * /home1/bhndbrwn/public_html/cake2/app/Console/cake -app /home1/bhndbrwn/public_html/cake2/app/ cron trigger
like image 25
robmcvey Avatar answered Nov 16 '22 22:11

robmcvey