cron_run_jobs.php 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. #!/usr/bin/env php
  2. <?php
  3. /*
  4. * Copyright (C) 2012 Nicolas Villa aka Boyquotes http://informetic.fr
  5. * Copyright (C) 2013 Florian Henry <forian.henry@open-concept.pro
  6. * Copyright (C) 2013-2015 Laurent Destailleur <eldy@users.sourceforge.net>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. */
  21. /**
  22. * \file scripts/cron/cron_run_jobs.php
  23. * \ingroup cron
  24. * \brief Execute pendings jobs
  25. */
  26. if (!defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); // Disables token renewal
  27. if (!defined('NOREQUIREMENU')) define('NOREQUIREMENU', '1');
  28. if (!defined('NOREQUIREHTML')) define('NOREQUIREHTML', '1');
  29. if (!defined('NOREQUIREAJAX')) define('NOREQUIREAJAX', '1');
  30. if (!defined('NOLOGIN')) define('NOLOGIN', '1');
  31. $sapi_type = php_sapi_name();
  32. $script_file = basename(__FILE__);
  33. $path = __DIR__.'/';
  34. // Error if Web mode
  35. if (substr($sapi_type, 0, 3) == 'cgi') {
  36. echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n";
  37. exit(-1);
  38. }
  39. require_once $path."../../htdocs/master.inc.php";
  40. require_once DOL_DOCUMENT_ROOT."/cron/class/cronjob.class.php";
  41. require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
  42. // Check parameters
  43. if (!isset($argv[1]) || !$argv[1]) {
  44. usage($path, $script_file);
  45. exit(-1);
  46. }
  47. $key = $argv[1];
  48. if (!isset($argv[2]) || !$argv[2]) {
  49. usage($path, $script_file);
  50. exit(-1);
  51. }
  52. $userlogin = $argv[2];
  53. // Global variables
  54. $version = DOL_VERSION;
  55. $error = 0;
  56. // Language Management
  57. $langs->loadLangs(array('main', 'admin', 'cron', 'dict'));
  58. /*
  59. * Main
  60. */
  61. // current date
  62. $now = dol_now();
  63. @set_time_limit(0);
  64. print "***** ".$script_file." (".$version.") pid=".dol_getmypid()." ***** userlogin=".$userlogin." ***** ".dol_print_date($now, 'dayhourrfc')." *****\n";
  65. // Check module cron is activated
  66. if (empty($conf->cron->enabled)) {
  67. print "Error: module Scheduled jobs (cron) not activated\n";
  68. exit(-1);
  69. }
  70. // Check module cron is activated
  71. if (empty($conf->cron->enabled)) {
  72. print "Error: module Scheduled jobs (cron) not activated\n";
  73. exit(-1);
  74. }
  75. // Check security key
  76. if ($key != $conf->global->CRON_KEY) {
  77. print "Error: securitykey is wrong\n";
  78. exit(-1);
  79. }
  80. // If param userlogin is reserved word 'firstadmin'
  81. if ($userlogin == 'firstadmin') {
  82. $sql = 'SELECT login, entity from '.MAIN_DB_PREFIX.'user WHERE admin = 1 and statut = 1 ORDER BY entity LIMIT 1';
  83. $resql = $db->query($sql);
  84. if ($resql) {
  85. $obj = $db->fetch_object($resql);
  86. if ($obj) {
  87. $userlogin = $obj->login;
  88. echo "First admin user found is login '".$userlogin."', entity ".$obj->entity."\n";
  89. }
  90. } else
  91. dol_print_error($db);
  92. }
  93. // Check user login
  94. $user = new User($db);
  95. $result = $user->fetch('', $userlogin);
  96. if ($result < 0) {
  97. echo "User Error: ".$user->error;
  98. dol_syslog("cron_run_jobs.php:: User Error:".$user->error, LOG_ERR);
  99. exit(-1);
  100. } else {
  101. if (empty($user->id)) {
  102. echo "User login: ".$userlogin." does not exists";
  103. dol_syslog("User login:".$userlogin." does not exists", LOG_ERR);
  104. exit(-1);
  105. }
  106. }
  107. $user->getrights();
  108. if (isset($argv[3]) || $argv[3]) {
  109. $id = $argv[3];
  110. }
  111. // create a jobs object
  112. $object = new Cronjob($db);
  113. $filter = array();
  114. if (!empty($id)) {
  115. if (!is_numeric($id)) {
  116. echo "Error: Bad value for parameter job id";
  117. dol_syslog("cron_run_jobs.php Bad value for parameter job id", LOG_WARNING);
  118. exit();
  119. }
  120. $filter['t.rowid'] = $id;
  121. }
  122. $result = $object->fetch_all('ASC,ASC,ASC', 't.priority,t.entity,t.rowid', 0, 0, 1, $filter, 0);
  123. if ($result < 0) {
  124. echo "Error: ".$object->error;
  125. dol_syslog("cron_run_jobs.php fetch Error ".$object->error, LOG_ERR);
  126. exit(-1);
  127. }
  128. $qualifiedjobs = array();
  129. foreach ($object->lines as $val) {
  130. if (!verifCond($val->test))
  131. {
  132. continue;
  133. }
  134. $qualifiedjobs[] = $val;
  135. }
  136. // TODO Duplicate code. This sequence of code must be shared with code into public/cron/cron_run_jobs.php php page.
  137. $nbofjobs = count($qualifiedjobs);
  138. $nbofjobslaunchedok = 0;
  139. $nbofjobslaunchedko = 0;
  140. if (is_array($qualifiedjobs) && (count($qualifiedjobs) > 0)) {
  141. $savconf = dol_clone($conf);
  142. // Loop over job
  143. foreach ($qualifiedjobs as $line) {
  144. dol_syslog("cron_run_jobs.php cronjobid: ".$line->id." priority=".$line->priority." entity=".$line->entity." label=".$line->label, LOG_DEBUG);
  145. echo "cron_run_jobs.php cronjobid: ".$line->id." priority=".$line->priority." entity=".$line->entity." label=".$line->label;
  146. // Force reload of setup for the current entity
  147. if ((empty($line->entity) ? 1 : $line->entity) != $conf->entity)
  148. {
  149. dol_syslog("cron_run_jobs.php we work on another entity conf than ".$conf->entity." so we reload user and conf", LOG_DEBUG);
  150. echo " -> we change entity so we reload user and conf";
  151. $conf->entity = (empty($line->entity) ? 1 : $line->entity);
  152. $conf->setValues($db); // This make also the $mc->setValues($conf); that reload $mc->sharings
  153. // Force recheck that user is ok for the entity to process and reload permission for entity
  154. if ($conf->entity != $user->entity && $user->entity != 0)
  155. {
  156. $result = $user->fetch('', $userlogin, '', 0, $conf->entity);
  157. if ($result < 0)
  158. {
  159. echo "\nUser Error: ".$user->error."\n";
  160. dol_syslog("cron_run_jobs.php:: User Error:".$user->error, LOG_ERR);
  161. exit(-1);
  162. }
  163. else
  164. {
  165. if ($result == 0)
  166. {
  167. echo "\nUser login: ".$userlogin." does not exists for entity ".$conf->entity."\n";
  168. dol_syslog("User login:".$userlogin." does not exists", LOG_ERR);
  169. exit(-1);
  170. }
  171. }
  172. $user->getrights();
  173. }
  174. }
  175. //If date_next_jobs is less of current date, execute the program, and store the execution time of the next execution in database
  176. if (($line->datenextrun < $now) && (empty($line->datestart) || $line->datestart <= $now) && (empty($line->dateend) || $line->dateend >= $now)) {
  177. echo " - qualified";
  178. dol_syslog("cron_run_jobs.php line->datenextrun:".dol_print_date($line->datenextrun, 'dayhourrfc')." line->datestart:".dol_print_date($line->datestart, 'dayhourrfc')." line->dateend:".dol_print_date($line->dateend, 'dayhourrfc')." now:".dol_print_date($now, 'dayhourrfc'));
  179. $cronjob = new Cronjob($db);
  180. $result = $cronjob->fetch($line->id);
  181. if ($result < 0) {
  182. echo "Error cronjobid: ".$line->id." cronjob->fetch: ".$cronjob->error."\n";
  183. echo "Failed to fetch job ".$line->id."\n";
  184. dol_syslog("cron_run_jobs.php::fetch Error ".$cronjob->error, LOG_ERR);
  185. exit(-1);
  186. }
  187. // Execute job
  188. $result = $cronjob->run_jobs($userlogin);
  189. if ($result < 0) {
  190. echo "Error cronjobid: ".$line->id." cronjob->run_job: ".$cronjob->error."\n";
  191. echo "At least one job failed. Go on menu Home-Setup-Admin tools to see result for each job.\n";
  192. echo "You can also enable module Log if not yet enabled, run again and take a look into dolibarr.log file\n";
  193. dol_syslog("cron_run_jobs.php::run_jobs Error ".$cronjob->error, LOG_ERR);
  194. $nbofjobslaunchedko++;
  195. $resultstring = 'KO';
  196. } else {
  197. $nbofjobslaunchedok++;
  198. $resultstring = 'OK';
  199. }
  200. echo " - run_jobs ".$resultstring." result = ".$result;
  201. // We re-program the next execution and stores the last execution time for this job
  202. $result = $cronjob->reprogram_jobs($userlogin, $now);
  203. if ($result < 0) {
  204. echo "Error cronjobid: ".$line->id." cronjob->reprogram_job: ".$cronjob->error."\n";
  205. echo "Enable module Log if not yet enabled, run again and take a look into dolibarr.log file\n";
  206. dol_syslog("cron_run_jobs.php::reprogram_jobs Error ".$cronjob->error, LOG_ERR);
  207. exit(-1);
  208. }
  209. echo " - reprogrammed\n";
  210. } else {
  211. echo " - not qualified\n";
  212. dol_syslog("cron_run_jobs.php job not qualified line->datenextrun:".dol_print_date($line->datenextrun, 'dayhourrfc')." line->datestart:".dol_print_date($line->datestart, 'dayhourrfc')." line->dateend:".dol_print_date($line->dateend, 'dayhourrfc')." now:".dol_print_date($now, 'dayhourrfc'));
  213. }
  214. }
  215. $conf = $savconf;
  216. }
  217. else
  218. {
  219. echo "cron_run_jobs.php no qualified job found\n";
  220. }
  221. $db->close();
  222. if ($nbofjobslaunchedko)
  223. exit(1);
  224. exit(0);
  225. /**
  226. * script cron usage
  227. *
  228. * @param string $path Path
  229. * @param string $script_file Filename
  230. * @return void
  231. */
  232. function usage($path, $script_file)
  233. {
  234. print "Usage: ".$script_file." securitykey userlogin|'firstadmin' [cronjobid]\n";
  235. print "The script return 0 when everything worked successfully.\n";
  236. print "\n";
  237. print "On Linux system, you can have cron jobs ran automatically by adding an entry into cron.\n";
  238. print "For example, to run pending tasks each day at 3:30, you can add this line:\n";
  239. print "30 3 * * * ".$path.$script_file." securitykey userlogin > ".DOL_DATA_ROOT."/".$script_file.".log\n";
  240. print "For example, to run pending tasks every 5mn, you can add this line:\n";
  241. print "*/5 * * * * ".$path.$script_file." securitykey userlogin > ".DOL_DATA_ROOT."/".$script_file.".log\n";
  242. }