EPESI BIM • Business Information Manager • Cloud CRM/ERP http://epe.si/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

cron.php 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. <?php
  2. /**
  3. * This file provides cron functionality... Add it to your cron.
  4. * @author Paul Bukowski <pbukowski@telaxus.com>
  5. * @copyright Copyright &copy; 2006, Telaxus LLC
  6. * @license MIT
  7. * @version 1.0
  8. * @package epesi-base
  9. */
  10. define('CID',false);
  11. define('SET_SESSION',false);
  12. if (php_sapi_name() == 'cli') {
  13. define('EPESI_DIR', '/');
  14. if (isset($argv[1])) {
  15. define('DATA_DIR', $argv[1]);
  16. }
  17. } elseif (!isset($_GET['token'])) {
  18. die('Missing token in URL - please go to Administrator Panel->Cron and copy valid cron URL.');
  19. } else {
  20. defined("_VALID_ACCESS") || define("_VALID_ACCESS", true);
  21. require_once('include/include_path.php');
  22. require_once('include/data_dir.php');
  23. if(!file_exists(DATA_DIR.'/cron_token.php'))
  24. die('Invalid token in URL - please go to Administrator Panel->Cron and copy valid cron URL.');
  25. require_once(DATA_DIR.'/cron_token.php');
  26. if(CRON_TOKEN!=$_GET['token'])
  27. die('Invalid token in URL - please go to Administrator Panel->Cron and copy valid cron URL.');
  28. }
  29. require_once('include.php');
  30. if (file_exists(DATA_DIR . '/maintenance_mode.php')) die();
  31. $lock = DATA_DIR.'/cron.lock';
  32. if(file_exists($lock) && filemtime($lock)>time()-6*3600) die();
  33. register_shutdown_function(create_function('','@unlink("'.$lock.'");'));
  34. file_put_contents($lock,'');
  35. set_time_limit(0);
  36. ini_set('memory_limit', '512M');
  37. ModuleManager::load_modules();
  38. Base_AclCommon::set_sa_user();
  39. $ret = ModuleManager::call_common_methods('cron');
  40. $cron_last = DB::GetAssoc('SELECT func,last,running FROM cron ORDER BY last');
  41. $cron_funcs_prior = array(); //array of outdated cron callbacks
  42. $t = time();
  43. foreach($ret as $name=>$obj) {
  44. if(!$obj) continue;
  45. if(is_array($obj)) {
  46. foreach($obj as $func=>$every) {
  47. if(!strpos($func,'::')) $func = $name.'Common::'.$func;
  48. $func_md5 = md5($func);
  49. //if first cron run exists and it was executed in specified time or it keep running less then 24h - skip
  50. if(isset($cron_last[$func_md5]) && ($cron_last[$func_md5]['last']>$t-$every*60 || ($cron_last[$func_md5]['running'] && $cron_last[$func_md5]['last']>$t-min($every*60*30,24*60*60)))) continue;
  51. if(!isset($cron_last[$func_md5])) {
  52. DB::Execute('INSERT INTO cron(func,last,running,description) VALUES (%s,%d,%b,%s)',array($func_md5,0,0,$func));
  53. $cron_last = array_merge(array($func_md5 => array('last'=>0,'running'=>0)),$cron_last);
  54. }
  55. $cron_funcs_prior[$func_md5] = $func;
  56. }
  57. }
  58. }
  59. //print_r($cron_last);
  60. //print_r($cron_funcs_prior);
  61. function adodb_error() {}
  62. class CronErrorObserver extends ErrorObserver {
  63. private $func_md5;
  64. public function __construct($func_md5) {
  65. $this->func_md5 = $func_md5;
  66. }
  67. public function update_observer($type, $message, $errfile, $errline, $errcontext, $backtrace) {
  68. global $cron_funcs_prior;
  69. $backtrace = htmlspecialchars_decode(str_replace(array('<br />','&nbsp;'),array("\n",' '),$backtrace));
  70. $x = $cron_funcs_prior[$this->func_md5].":\ntype=".$type."\nmessage=".$message."\nerror file=".$errfile."\nerror line=".$errline."\n".$backtrace;
  71. epesi_log($x."\n", 'cron.log');
  72. DB::IgnoreErrors(array('adodb_error',null)); //ignore adodb errors
  73. $query_args = array(time(),$this->func_md5);
  74. $query = DB::TypeControl('UPDATE cron SET last=%d,running=0 WHERE func=%s',$query_args);
  75. if(!DB::Execute($query,$query_args)) { //if not - probably server gone away - retry every 10 seconds for 1h
  76. for($i=0; $i<360; $i++) {
  77. sleep(10);
  78. $connection = null;
  79. try {
  80. $connection = DB::Connect(); //reconnect database as new connection
  81. } catch(Exception $e) {
  82. continue; //no connection - wait
  83. }
  84. if($connection->Execute($query,$query_args)) { //if ok then break and exit
  85. $connection->Close();
  86. break;
  87. }
  88. $connection->Close();
  89. }
  90. }
  91. return true;
  92. }
  93. }
  94. //call oldest executed callback
  95. foreach($cron_last as $func_md5=>$last) {
  96. if(!isset($cron_funcs_prior[$func_md5])) continue;
  97. DB::Execute('UPDATE cron SET last=%d,running=1 WHERE func=%s',array($t,$func_md5));
  98. @unlink($lock);
  99. // print('call '.$cron_funcs_prior[$func_md5]."\n");
  100. $error_handler = new CronErrorObserver($func_md5);
  101. ErrorHandler::add_observer($error_handler);
  102. ob_start();
  103. $output = array();
  104. try {
  105. $output[0] = call_user_func(explode('::',$cron_funcs_prior[$func_md5]));
  106. } catch(Exception $e) {
  107. $output[0] = 'Cron Exception: '.$e->getMessage();
  108. }
  109. $output[1] = ob_get_clean();
  110. $output = array_filter($output);
  111. if($output) {
  112. $output = implode("<br />\n",$output);
  113. $stripped = $cron_funcs_prior[$func_md5].":\n".strip_tags($output)."\n\n";
  114. if(isset($argv))
  115. print($stripped);
  116. else
  117. print($cron_funcs_prior[$func_md5].":<br>".$output."<hr>");
  118. epesi_log($stripped, 'cron.log');
  119. }
  120. DB::Execute('UPDATE cron SET last=%d,running=0 WHERE func=%s',array(time(),$func_md5));
  121. break;
  122. }
  123. @unlink($lock);