How to run a cron job on a CodeIgniter controller that the entire URL executes a request from an API, update a DB, and send emails (from CI)?

I have a web application that launches a request for api, receives new information, changes the variables in the database and sends emails if necessary (compares old and new variables).

I work with Ubuntu Server and I have tried several options for this.

my controller is as follows:

class Cli_only extends CI_Controller { public function __construct() { parent::__construct(); is_cli() OR show_404(); // If cronjob ! $this->load->model('kas_model'); // Sets the server not to have a time out. ini_set('max_execution_time', 0); ini_set('memory_limit', '-1'); // Expand the array displays ini_set('xdebug.var_display_max_depth', 5); ini_set('xdebug.var_display_max_children', 256); ini_set('xdebug.var_display_max_data', 1024); } // This function has to run every day using a corn job. public function cron_job(){ // does stuff... } 

So, first I tried using the regular curl command on my cronjob:

15 15 * * * http://10.0.1.666/tools/Cli_only/cron_job

and I got this error in the log file:

 Dec 6 15:30:01 MYserver CRON[1134]: (root) CMD (curl http://10.0.1.66/tools/Cli_only/cron_job) Dec 6 15:30:02 MYserver CRON[1133]: (CRON) info (No MTA installed, discarding output) 

running fast google and I noticed that I need to install "postfix" on my server and I did it. I restarted cron and got:

 Dec 6 16:26:01 MYserver cron[2663]: (root) RELOAD (crontabs/root) Dec 6 16:26:01 MYserver CRON[2703]: (root) CMD (curl http://10.0.1.666/tools/Cli_only/cron_job) Dec 6 16:26:01 MYserver postfix/pickup[2479]: 23430102E11: uid=0 from=<root> Dec 6 16:26:01 MYserver postfix/cleanup[2707]: 23430102E11: message-id=< 20151206142601.23430102E11@MYserver > Dec 6 16:26:01 MYserver postfix/qmgr[2480]: 23430102E11: from=< root@MYserver >, size=2058, nrcpt=1 (queue active) Dec 6 16:26:01 MYserver postfix/local[2709]: 23430102E11: to=< root@MYserver >, orig_to=<root>, relay=local, delay=0.02, delays=0.01/0/0/0, dsn=2.0.0, status=sent (delivered to mailbox) Dec 6 16:26:01 MYserver postfix/qmgr[2480]: 23430102E11: removed 

However, no changes to the database — and if they were — CodeIgniter has working mailing list configurations that should only work with URL triggering.

I tried to run things like this:

 14 16 * * * wget -O - http://10.0.1.666/tools/Cli_only/cron_job >/dev/null 2>&1 14 16 * * * curl -O - http://10.0.1.666/tools/Cli_only/cron_job >/dev/null 2>&1 14 16 * * * GET -O - http://10.0.1.666/tools/Cli_only/cron_job >/dev/null 2>&1 

which I really don’t know what they are doing, and still do not work.

EDIT:

Just to be clear, if I run the controller in my browser, everything works fine!

This is all my code in the controller, the cron_job () function immediately after the __construct () function:

 <?php class Cli_only extends CI_Controller { public function __construct() { parent::__construct(); is_cli() OR show_404(); // If cronjob ! //if (!$this->input->is_cli_request()) show_error('Direct access is not allowed'); $this->load->model('kas_model'); // Sets the server not to have a time out. ini_set('max_execution_time', 0); ini_set('memory_limit', '-1'); // Expand the array displays ini_set('xdebug.var_display_max_depth', 5); ini_set('xdebug.var_display_max_children', 256); ini_set('xdebug.var_display_max_data', 1024); } // This function has to run every day using a corn job. public function cron_job(){ // 1. Run the query that gets the table data from the DB('from kas table') $data['table'] = $this->kas_model->get_kas_table(); // 2. Go through each row. foreach ( $data['table'] as $row ) { // 3.1. But first, get vars! $kas_id = $row->kas_id; $kas_key = $row->kas_key; $kas_id_aaa = $row->kas_id_aaa; $kas_id_bbb = $row->kas_id_bbb; $kas_rank1_aaa = $row->kas_rank1_aaa; $kas_rank2_aaa = $row->kas_rank2_aaa; $kas_rank1_bbb = $row->kas_rank1_bbb; $kas_rank2_bbb = $row->kas_rank2_bbb; // 3.2. move to yesterday to make place for a new query result. $this->kas_model->move_tod_to_yes($kas_id, $kas_rank2_aaa, $kas_rank2_bbb); // 3.3. Run the key query again for today on each one of the keys and insert to DB. if ( ($kas_id_aaa != 0) || ( !empty($kas_id_aaa) ) ) { $aaa_rank_today = $this->get_rank_aaa_by_id_and_kw($kas_id_aaa, $kas_key); } if ( ($kas_id_bbb != 0) || ( !empty($kas_id_bbb) ) ) { $bbb_rank_today = $this->get_rank_bbb_by_id_and_kw($kas_id_bbb, $kas_key); } // 3.4. Add the new rank to rank2 in the DB. $this->kas_model->add_new_today($kas_id, $aaa_rank_today, $bbb_rank_today); // 4. Check difference as Sag described : $msg = ''; $send = FALSE; // First if: aaa if ( ($aaa_rank_today > 10 ) && ( $kas_rank2_aaa < 30 ) && ( ( abs( $aaa_rank_today - $kas_rank2_aaa ) ) > 10) ) { $msg .= 'aaa:<br> ( (Today > 10 ) && ( Yesterday < 30 ) && ( ( |Today - Yesterday| > 10) ) ==> True. <br><br>'; $send = TRUE; } // Second if: aaa if ( ( ($kas_rank2_aaa < 5) && ($aaa_rank_today > 10) ) || ( ($aaa_rank_today < 5) && ($kas_rank2_aaa > 10) ) ) { $msg .= 'aaa: <br> ( ( (Yesterday < 5) && (Today > 10) ) || ( (Today < 5) && (Yesterday > 10) ) ) ==> True. <br> <br>'; $send = TRUE; } // First if: bbb if ( ($bbb_rank_today > 10 ) && ( $kas_rank2_bbb < 30 ) && ( ( abs( $bbb_rank_today - $kas_rank2_bbb ) ) > 10) ) { $msg .= 'bbb: <br> ( (Today > 10 ) && ( Yesterday < 30 ) && ( ( |Today - Yesterday| > 10) ) ==> True. <br><br>'; $send = TRUE; } // Second if: bbb if ( ( ($kas_rank2_bbb < 5) && ($bbb_rank_today > 10) ) || ( ($bbb_rank_today < 5) && ($kas_rank2_bbb > 10) ) ) { $msg .= 'bbb: <br> ( ( (Yesterday < 5) && (Today > 10) ) || ( (Today < 5) && (Yesterday > 10) ) ) ==> True. <br> <br>'; $send = TRUE; } $this->send_mail($kas_id_aaa, $kas_id_bbb, $msg, $send, $aaa_rank_today, $bbb_rank_today, $kas_rank2_aaa, $kas_rank2_bbb, $kas_key); } } // Gets aaa categorys Ranking by ID. public function get_rank_aaa_by_id_and_kw($id, $key, $query_country){ $key_for_url = rawurlencode($key); $found = FALSE; $i = 0; // Create a stream for Json. That how the code knows what to expect to get. $context_opts = array( 'http' => array( 'method' => "GET", 'header' => "Accepts: categorylication/json\r\n" )); $context = stream_context_create($context_opts); while ($found == FALSE) { // aaa Query $json_query_aaa = "https://api.example.com:666/aaa/ajax/research_key?category_id=$id&term=$key_for_url&page_index=$i&country=$query_country&auth_token=tokentokentoken"; // Get the Json $json_query_aaa = file_get_contents($json_query_aaa, false, $context); // Turn Json to a PHP array $json_query_aaa = json_decode($json_query_aaa, true); // Finally, the main categorys array. $json_query_aaa = $json_query_aaa['key']['phone_categorys']['category_list']; if ( count($json_query_aaa) > 2 ) { for ( $j=0; $j<count($json_query_aaa); $j++ ) { if ( $json_query_aaa[$j]['id'] == $id ) { $found = TRUE; $rank = $json_query_aaa[$j]['rank'] + 1; break; } if ($found == TRUE){ break; } } $i++; } else { $rank = "none"; break; } } return $rank; } // Gets bbb categorys Ranking by ID. public function get_rank_bbb_by_id_and_kw($id, $key, $query_country){ $key_for_url = rawurlencode($key); $found = FALSE; $i = 0; // Create a stream for Json. That how the code knows what to expect to get. $context_opts = array( 'http' => array( 'method' => "GET", 'header' => "Accepts: categorylication/json\r\n" )); $context = stream_context_create($context_opts); while ($found == FALSE) { // aaa Query $json_query_bbb = "https://api.example.com:666/bbb/research_key?category_id=$id&term=$key_for_url&page_index=$i&country=$query_country&auth_token=tokentokentoken"; // Get the Json $json_query_bbb = file_get_contents($json_query_bbb, false, $context); // Turn Json to a PHP array $json_query_bbb = json_decode($json_query_bbb, true); // Finally, the main categorys array. $json_query_bbb = $json_query_bbb['key']['phone_categorys']['category_list']; if ( count($json_query_bbb) > 2 ) { for ( $j=0; $j<count($json_query_bbb); $j++ ) { if ( $json_query_bbb[$j]['id'] == $id ) { $found = TRUE; $rank = $json_query_bbb[$j]['rank']+1; } } $i++; } else { $rank = "none"; break; } } return $rank; } // Sends to email the results public function send_mail($id_aaa, $id_bbb, $msg, $send, $aaa_rank_today, $bbb_rank_today, $aaa_rank_yesterday, $bbb_rank_yesterday, $kas_key){ if ($send) { $ci = get_instance(); $config['protocol'] = "smtp"; $config['smtp_host'] = "ssl://smtp.gmail.com"; $config['smtp_port'] = "465"; $config['smtp_user'] = " myEmail@example.pro "; $config['smtp_pass'] = "assword"; $config['charset'] = "utf-8"; $config['mailtype'] = "html"; $config['newline'] = "\r\n"; $config['crlf'] = "\r\n"; $config['validate'] = FALSE; $ci->load->library('email'); $ci->email->initialize($config); $ci->email->from(' myEmail@example.pro ', 'key Alerting System (KAS)'); $list = array(' myEmail.do@gmail.com ', ' sag@example.pro '); $ci->email->to($list); $this->email->reply_to(' no-reply@example.pro ', 'KAS Alert'); $ci->email->subject('KAS Alert!'); $ci->email->message("key: $kas_key <br/><br/> aaa ID:$id_aaa <br> bbb ID: $id_bbb <br><br><br> $msg<br><br> aaa Rank Today: $aaa_rank_today<br> aaa Rank Yesterday: $aaa_rank_yesterday<br><br> bbb Rank Today: $bbb_rank_today<br> bbb Rank Yesterday: $bbb_rank_yesterday"); $ci->email->send(); } } function test(){ echo 'banana'; } } 

EDIT # 2:

This works great when is_cli() OR show_404(); does not exist in the build function is_cli() OR show_404(); . But I want this controller to work only from cronjob

I get the same result:

if (!$this->input->is_cli_request()) show_error('Direct access is not allowed');

+6
source share
2 answers

curl -O - http://10.0.1.666/tools/Cli_only/cron_job >/dev/null 2>&1 not cli. Curl makes a normal HTTP request for your web server, and cli stands for the command line PHP script.

To run it as cli:

 $ cd /path/to/your/web/root $ php index.php tools Cli_only cron_job 

For your pairing, this should be:

 14 16 * * * cd /path/to/project; php tools Cli_only cron_job >/dev/null 2>&1 

EDIT

In normal mode, you can run curl requests from the cron job it has. For example, it allows you to run a cron job like any user and ensure that the job is performed by a web server user. Using cli, you must set the cron job for the correct user, for example. crontab -u www-data -e if the user of your web server is www-data . Otherwise, you run the risk of having permissions for temporary files, such as caches, logs, etc.

If you are unsure of the internal functions, it might be better to use curl in your cron job, but restrict access to the controller for specific IP addresses. For example, instead of

 is_cli() OR show_404(); 

use something like

 $this->input->ip_address() == '127.0.0.1' OR show_404(); 
+4
source

At first I don’t understand why you are running crotab through an HTTP request. You can fully run crontab on your server, which is 10.0.1.666, which can also go on if something is wrong with the Internet. Also, you said: “This works fine if it does not have is_cli () OR show_404 (); because you send an HTTP request in a crontab letter. Suppose you are a client and the server is 10.0.1.666. Anytime when crontab is running, the “client” sends an HTTP request. And server 666 receives the request, then issues the controller you wrote. This is not a cli script. If you insist on this by sending an HTTP request. I have 2 adivices (not better, but it can work)

Secondly, I highly recommend you run bash on the server.

+1
source

All Articles