8

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@domain.com)
           ->from('no-reply@domain.com')
           ->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

bowlerae
  • 1,122
  • 1
  • 14
  • 36
  • Have you read [this](http://caky.de/en/console-and-shells/cron-jobs.html) and [that](http://stackoverflow.com/questions/3192070/cron-job-with-cakephp). – skywalker Apr 18 '14 at 14:16
  • The first (this) I was confused about the path. The second (that) just flat out didn't work. Also, that was for an older version of Cake so not sure if the paths were correct. I tried to adjust to Cake 2.X vendor paths but still did not work. I would like to avoid using the vendors directory as according to the doc, shells should be placed in Console/Command. – bowlerae Apr 18 '14 at 14:34
  • @slywalker that doc is terrible :|. [The official docs](http://book.cakephp.org/2.0/en/console-and-shells/cron-jobs.html) do not mislead users into thinking you need "something special" to run a cron job. bowlerae if you can run your command on the cli and it doesn't work via cron - you'll need to indicate how/why - as, except for e.g. environment variables, contrary to popular belief cron isn't any different to just running things normally. – AD7six Apr 18 '14 at 23:11
  • 1
    The script isn't running on PHP 5.4, but PHP 7.x. **https://book.cakephp.org/2.0/en/appendices/2-7-migration-guide.html#utility** | **https://www.google.com/search?q=Cannot+use+%27String%27+as+class+name+as+it+is+reserved** – ndm Oct 15 '17 at 03:04
  • @ndm thank you. I suspected that was the problem but I didn't think migration would be as easy as it was. If you submit an official answer I will accept it. – bowlerae Oct 15 '17 at 07:29

4 Answers4

2

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.

SidMalde
  • 45
  • 6
  • 1
    It's not a bad answer, but using a "corn" dispatcher is unnecessary, you could equally use `wget http://domain.com/routedUrl` in your cron job. In any case though: I advise to convert your cronjob controller to commands and run them as cli processes (`cd app && Console/cake cron etc.`). – AD7six Apr 28 '14 at 14:48
  • Agree with AD7six - Controllers are for handling HTTP requests, not triggering scheduled tasks. Try and move the logic to a model if it's used by both a controller action and required as a cron. – robmcvey Apr 28 '14 at 15:06
2

This method is the "vanilla" method, does not require you to edit or add any php files to dispatch your Cron jobs, it works out the box with CakePHP 2.x

So for CakePHP 2.x use this:

Settings:

  • You have a Shell called CustomShell.php located at /public_html/app/Console/Command/CustomShell.php

  • Inside this CustomShell.php you have several functions: functionThis() and functionThat()

How to call this Shell and how to call each function as I please?

You go to your cPanel (or whatever manage you're using), inside the Cron Job Manager, and this is what you would type in the command:

  • The syntax looks like this:

    cd /home/your_user/public_html/app && Console/cake shell_name function_name

  • This is how the cmd looks like with my example:

    cd /home/your_user/public_html/app && Console/cake custom functionThis

Notice that the function name is not CustomShell but custom. Also, notice how I call the functionThis(), you can leave this blank and it will automatically call your main() function inside the CustomShell.php file.

nullwriter
  • 785
  • 8
  • 31
2

I am running cake 2.5 on PHP 5.4

You maybe running php 5.4 but your php-cli maybe in different version for example could be php 7 check your cli version. In php 7 you can't create class with name String.

* @package       Cake.Utility
*/
class String {
vasillis
  • 332
  • 4
  • 9
1

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
robmcvey
  • 735
  • 7
  • 18