Creating Cron Jobs in CakePHP 2.x - php

I have attempted to create a cron job in my CakePHP 2.x application. But all of the resources I have read online seem to be either doing it completely different to one another with little consistency or explain it in very complex terminology.
Basically I have created the following file MyShell.php in /app/Console/Command
<?php
class MyShell extends Shell {
public function sendEmail() {
App::uses('CakeEmail', 'Network/Email');
$email = new CakeEmail();
$email->from('cameron#driz.co.uk');
$email->to('cameron#driz.co.uk');
$email->subject('Test Email from Cron');
$result = $email->send('Hello from Cron');
}
}
?>
And I want to say run this code at midnight every night.
What do I do next? As the next part really confuses me! I have read on the Book at: http://book.cakephp.org/2.0/en/console-and-shells/cron-jobs.html that I should run some code in the terminal to make it do it at a certain time etc. And I can set these up using my hosting provider rather easily it seems.
But I'm rather confused about the Console directory. What should go in what folder in here: https://github.com/cakephp/cakephp/tree/master/app/Console
/Console/Command
/Console/Command/Tasks
/Console/Templates
Also noticed that many of the files are .php (e.g. my Shell file is also .php), but according to documentation I've read for Cron jobs, the executed files should be .sh?
Can anyone shed more light on this?
And what would the code be to call that command?
e.g. would presume this is incorrect: 0 0 * * * cd /domains/driz.co.uk/html/App && cake/Console MyShell sendEmail
Thanks

No. There is no way to do it just in PHP. But that doesn't matter, because crons are easy to set up.
In that article you linked to, you still have to set up a cron - the difference is just that you set up a single cron, that runs all your other crons - as opposed to setting up one cron per job. So, either way, you have to learn to create a cron.
The instructions depend on your server's operating system and also what host you're with. Some hosts will have a way to set up cron jobs through a GUI interface like cPanel or something, without you having to touch the terminal.
It's usually pretty easy to find instructions online for how to set up cron jobs with your host or server OS, but if you're having trouble, update your question with your host's name, and your server OS and version.
Also ---------------------------------
Often in cron jobs you'll be running a shell script (.sh). But don't worry about that for this case; your's will end in .php.
Re: the directory structure:
/Console/Command is where your new file should go.
If you're doing a lot of shell stuff, you may want to abstract common code out into the /Console/Command/Task folder. Read more about that here. This probably won't be needed in your case.
/Console/Command/Templates is where you can put custom templates for the Cake bake console - don't worry about that for now.
If I've only got a couple of cron jobs to run, then I create just one file called CronJobsShell.php, and put them all in there.
Really, you should read Cake's documentation on shells from start to end. It will give you a nice picture of how it all hangs together.

This can be done very easily by the following steps -:
1) Create a shell let's say HelloShell.php in Console/Command
<?php
class HelloShell extends AppShell
{
public function main()
{
//Your functionality here...
}
}
?>
This shell can be called by Console/cake hello
2) Write the command crontab-e .This will open up the default editor or the editor which you select Now as we want that our shell should run after at midnight write:-
0 0 * * * /PATH TO APP/Console/cake hello
For better understanding refer https://www.youtube.com/watch?v=ljgvo2jM234
Thanks!

Related

How Execute PHP File Using a Cron Job

I am using a WordPress site hosted on a DigitalOcean WordPress Litespeed droplet. I am attempting to run a php file in my theme every five minutes using a Cron Job. I don't want to use the default WordPress cron job system.
So far I have connected to the sever through ssh. Then entered the crontab using "crontab -e" then entered the following code then saved / exit
*/5 * * * * php /var/www/html/wp-content/themes/my_theme/cron.php
And inside the cron.php I put a simple mailing function for testing purposes:
<?php
/*template name: Cron*/
$content = date("h:i:sa");
wp_mail( 'reece.r.barrett#gmail.com', 'Cron Test', $content, array());
?>
But I never receive an email so I assume its not working. Is there something wrong with the way I am declaring my cron job? Also I haven't disabled the WordPress Cron system like I have seen a lot of tutorials doing. Is this required to get my own cron to work?
This is how I've seen some tutorials disabling the WordPress cron in wp-config
define('DISABLE_WP_CRON', true);
Your problem is that even if your file physically live inside your theme folder it is actually run "outside" wp core ENV since you are calling it directly. If you ask me, the best, simpliest and cleanest way to use external cron system inside WP ecosystem is to do something like this:
add_action( 'wp_ajax_nopriv_my_cron_action', array( 'myCronAction' ) );
function myCronAction(){
//...your code
}
In that way you make use of WP ajax endpoint to enter the WP ecosystem. Be careful with security since in that way you are exposing a cron url to do your stuff. Securing that is up to you, but that's the easiest way to achieve that.
To use that from your cron you just need to make something that fetches an URL built like this: https://yourdomain.com/wp-admin/admin-ajax.php?action=my_cron_action
If you don't want to make it like that, then you have to bootstrap WP core yourself inside your .php file see https://wordpress.stackexchange.com/questions/47049/what-is-the-correct-way-to-use-wordpress-functions-outside-wordpress-files
First check if your script run from cli/webhook. Then please check for cli execution, since there could be the case that php is not in server's PATH and you have to call full path to php, e.g.:
/usr/local/bin/php /home/your_username/public_html/path/to/cron/script.php

call php script from cron job only - deny all other ips

Is there a way to call a script from a cron job only and make it so no other ips can run that script?
I have a script that sends notifications to phones. It is supposed to be called by a cron job once day, but sometimes something triggers it and everyone gets notified when they shouldn't. I would like to limit it to be called from my server only.
In other words to make it not to be able to be called from a browser or a spider etc..
Thanks
I'd suggest that you don't make this file available publicly.
But to answer your question directly; A way to do this is to add the following check:
if (php_sapi_name() === 'cli') {...}
More info: https://secure.php.net/manual/en/function.php-sapi-name.php
Your script seems to be available via public URL. Move it somewhere else. For example, if the script is within /www/site.com/public/script.php, and /www/site.com/public is the public directory of the Web server, move it to some /www/site.com/cron/script.php. Make sure that the Web server is not configured to fetch files from the cron directory.
As others have written, there may be other setups you could use, (permissions and file locations) however, I've never been someone who tells someone to re-engineer their whole process to meet a single need. That feels too much like the tail wagging the dog. Therefore, if you wish to have a script that can only be executed by your cron job and not mistakenly by another process, I would offer you this solution
The php_sapi solution has been noted to provide inconsistent behavior and is system configuration specific (for example echo it's output when calling your script from the command line, and again when calling from a cron). This can lead to tracking down other bugs. The best solution I have seen and used, is to pass a command line argument to your script and evaluate the existence of that argument.
your cron job would look something like:
* * * * * * php /path/to/script --cron
Then, inside your script you would perform an if check, that when not satisfied, stops the script.
if( $argv[0] != 'cron')
{
//NO CRON ARGUMENT SUPPLIED, SOMETHING ELSE MUST BE CALLING THIS
exit;
}
Take not that some systems may use the first argument as the script name, so based on your individual system configuration, you may need to check $argv[1]
Hope this helps, let me know if you have any questions, I'm happy to respond or edit if needed.

set up Cron job to run PHP script

I know this question has been asked before, but none of the answers are working for me.
I'm trying to run a simple PHP script every night at midnight. I created a file called "autoDelete.php" that contains just this code:
<?php
include 'my-database-connection.php';
mysql_query("DELETE FROM meetings WHERE indexDate < NOW()");
?>
I know this script is working because if I navigate to it in a browser, it does what it should.
I then set up the Cron job (via GoDaddy cPanel) to run every minute, with a command to run the script using this:
* * * * /usr/bin/php -q /home/username/public_html/autoDelete.php
However, this is not working. I suspect this has something to do with whatever precedes the "/home" in the command.
Some things to check:
1) cron jobs' default "working directory" is the home directory of the user ID they're running under. That'd most likely be /home/username in this case. That means if you have any relative-pathed include/require commands, they're going to be relative to /home/username, NOT /home/username/public_html. Make SURE that all necessary files are accessible.
2) You're simply assuming the query call succeeded. That's exactly the wrong the thing to do. Calls to external resources (DBs in particular) have exactly ONE way to succeed, and a near infinite number of ways to fail. ALWAYS check for failure, and treat success as a pleasant surprise.
Combining these two (failing to include your connection script, and failing to check for failure), and you end up with what you've got: "nothing" happening. At least try something like
mysql_query(...) or die(mysql_error());
^^^^^^^^^^^^^^^^^^^^^^
The error message will become your script's output, and get emailed to the controlling account's mailbox.
I've had issues in the past with running PHP scripts in a cron job when trying to invoke the PHP binary directly. My solution was to use wget in the cron job since the script was servable by Apache anyway (0 0 * * * wget url/of/script.php). Apache already has the right PHP environment set up so might as well just ask it to handle the job.

PHP simple parser to run only once a day

I am using the simple_html_dom script to parse a value from a website.
My code:
<?php
include('simpleparser/simple_html_dom.php');
$html = file_get_html('http://www.example.com');
foreach($html->find('strong') as $e) // the tag that I am fetching
echo $e->innertext ;
?>
Now, I'd like to run this only once per day as the data, I am parsing updates only once every day.
I've read a couple of articles about the cron task, but can not get it to work. The examples seem to overcomplicate things and are not relevant to my case.
My hosting plan has the cron scheduler disabled and no shell access and I don't know how else to set it up.
To create cronjob from the command line use:
#write out current crontab
crontab -l > mycron
# echo new cron into cron file | runs everyday at 22h
echo "* 22 * * * php /full/path/to/script.php" >> mycron
#install new cron file
crontab mycron
rm mycron
To create a cronjob using Parallels Plesk Panel, take a look at this answer
UPDATE:
I have no shell access and cronjob disabled in my Plesk Panel.
Use a online cronjob https://www.setcronjob.com/
If there's really no way for you to setup a cron job on your hosting - you could also use some online service to trigger your script once in a while.
For example https://cron-job.org seems to do what you need
Attaching a sample of settings they provide
You can contact with your hosting server but temporary solution for this kind of problem is to use cronjob service there are lot of free cronjob service out there in web. you can try those service .
I used this kind of service while creating a DDoS bot .. :p ..
You can use these cronjob service but there are more ...
https://www.setcronjob.com/
https://www.easycron.com/
search in google with "Cron job service" you'll find thousands of service like this
Happy coding :)
I use windows task-schedule. To execute a .php script you can either insert it like this or create a .bat file and execute it through there.

Cakephp 2.0, CPanel and Shell scripts

I have cPanel on a shared server and I need to run a shell script everyday.
This script has to call a controller function that scraps a webpage everyday.
My problem is that I don't know how to do a shell script that calls this function and add it at cron jobs in cpanel. How do I do all of this?
Thanks in advance!
I'm going to extend my question.
I have this code "TestTask.php":
class TestTask extends Shell {
function main() {
$this->out('Hello world.');
}
function execute() {
$this->out('Hello world 2.');
}
}
It's located in: /home/myuser/public_html/app/Console/Command/Task
And then, my cronjob is like this:
* * * * * php /home/myuser/public_html/app/Console/cake.php test -app /home/myuser/public_html/app >> /home/myuser/public_html/file.log
The last part it's to log the output in a file.
It doesn't work at all.
Help please!!!
Here's the command for a cron job I am using on my server:
/home/path-to-cake/lib/Cake/Console/cake -app /home/path-to-cake/app time
where time is my shell, located in /app/Console/Command/TimeShell.php. This is how you run shells.
Now, on the other part of your question, a task must be called from within a shell. From the code you posted, it seems that you are confusing a bit shells with tasks. A shell can contain tasks, just like controllers can have components. main(); is required for a shell when it is called without any arguments. It is not necessary for a task to implement it. On the other hand, a task must implement an execute(); method.
In order to run a task from your shell, be sure to add public $tasks = array('Test'); in the TestShell class; You can use this task in your shell just like you use a component in a controller: $this->Test->whatever();
For more info on CakePHP 2.0 shells and tasks, have a look here
Hope this helped!

Categories