b2evolution PHP Cross Reference Blogging Systems

Source: /cron/cron_exec.php - 244 lines - 7598 bytes - Text - Print

Description: Execute cron jobs. Example to use CLI: >c:\php4\php cron_exec.php >c:\php4\php-cli cron_exec.php

   1  <?php
   2  /**
   3   * Execute cron jobs.
   4   *
   5   * Example to use CLI:
   6   * >c:\php4\php cron_exec.php
   7   * >c:\php4\php-cli cron_exec.php
   8   *
   9   * @version $Id: cron_exec.php 5874 2014-02-03 13:37:01Z attila $
  10   */
  11  
  12  
  13  /**
  14   * Include config
  15   */
  16  require_once dirname(__FILE__).'/../conf/_config.php';
  17  
  18  /**
  19   * Include main initialization
  20   * Note: This will initialize only the required objects ( e.g. $Session or $Hit objects will NOT be initialized in cli mode ).
  21   */
  22  require_once $inc_path .'_main.inc.php';
  23  
  24  if( $Settings->get( 'system_lock' ) )
  25  { // System is locked down for maintenance, Stop cron execution
  26      echo 'The site is locked for maintenance. All scheduled jobs are postponed. No job was executed.';
  27      exit(0);
  28  }
  29  
  30  /**
  31   * Cron support functions
  32   */
  33  load_funcs( 'cron/_cron.funcs.php' );
  34  
  35  /**
  36   * @global integer Quietness.
  37   *         1 suppresses trivial/informative messages,
  38   *         2 suppresses success messages,
  39   *         3 suppresses errors.
  40   */
  41  $quiet = 0;
  42  if( $is_cli )
  43  { // called through Command Line Interface, handle args:
  44  
  45      // Load required functions ( we need to load here, because in CLI mode it is not loaded )
  46      load_funcs( '_core/_url.funcs.php' );
  47  
  48      if( isset( $_SERVER['argc'], $_SERVER['argv'] ) )
  49      {
  50          $argc = $_SERVER['argc'];
  51          $argv = $_SERVER['argv'];
  52      }
  53  
  54      if( isset($argv) )
  55      { // may not be set for CGI
  56          foreach( array_slice($argv, 1) as $v )
  57          {
  58              switch( $v )
  59              {
  60                  case '-h':
  61                  case '--help':
  62                      // display help:
  63                      echo $argv[0]." - Execute cron jobs for b2evolution\n";
  64                      echo "\n";
  65                      echo "Options:\n";
  66                      echo " -q --quiet: Be quiet (do not output a message, if there are no jobs).\n";
  67                      echo "             This is especially useful, when running as a cron job.\n";
  68                      echo "             You can use this up to three times to increase quietness.\n";
  69                      echo "             Successful runs can be made silent with \"-q -q\".\n";
  70                      exit(0);
  71                      break;
  72  
  73                  case '-q':
  74                  case '--quiet':
  75                      // increase quietness:
  76                      $quiet++;
  77                      break;
  78  
  79                  default:
  80                      echo 'Invalid option "'.$v.'". Use "-h" or "--help" for a list of options.'."\n";
  81                      die(1);
  82              }
  83          }
  84      }
  85  
  86      global $default_locale, $current_charset;
  87  
  88      // We don't load _init_session.inc.php in CLI mode, so we set locale and DB connection charset here
  89      locale_overwritefromDB();
  90      locale_activate( $default_locale );
  91  
  92      // Init charset handling - this will also set the encoding for MySQL connection
  93      init_charsets( $current_charset );
  94  }
  95  else
  96  { // This is a web request: (for testing purposes only. Not designed for production)
  97  
  98      // Make sure the response is never cached:
  99      header_nocache();
 100      header_content_type();
 101  
 102      // Add CSS:
 103      require_css( 'basic_styles.css', 'rsc_url' ); // the REAL basic styles
 104      require_css( 'basic.css', 'rsc_url' ); // Basic styles
 105      ?>
 106      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 107      <html>
 108      <head>
 109          <title>Cron exec</title>
 110          <?php include_headlines() /* Add javascript and css files included by plugins and skin */ ?>
 111      </head>
 112      <body>
 113          <h1>Cron exec</h1>
 114          <p>This script will execute the next task in the cron queue.
 115          You should normally call it with the CLI (command line interface) version of PHP
 116          and automate that call through a cron.</p>
 117      <?php
 118  }
 119  
 120  /*
 121   * The following will feel a little bloated...
 122   * BUT it is actually a pretty nifty design to prevent double execution of tasks without any transaction!
 123   * The trick is to rely on the primary key of the cron__log table.
 124   */
 125  
 126  // Get next task to run in queue which has not started execution yet:
 127  $sql = 'SELECT *
 128                      FROM T_cron__task LEFT JOIN T_cron__log ON ctsk_ID = clog_ctsk_ID
 129                   WHERE clog_ctsk_ID IS NULL
 130                       AND ctsk_start_datetime <= '.$DB->quote( date2mysql($localtimenow) ).'
 131                   ORDER BY ctsk_start_datetime ASC, ctsk_ID ASC
 132                   LIMIT 1';
 133  $task = $DB->get_row( $sql, OBJECT, 0, 'Get next task to run in queue which has not started execution yet' );
 134  $error_task = NULL;
 135  
 136  if( empty( $task ) )
 137  {
 138      cron_log( 'There is no task to execute yet.', 0 );
 139  }
 140  else
 141  {
 142      $ctsk_ID = $task->ctsk_ID;
 143      $ctsk_name = $task->ctsk_name;
 144  
 145      cron_log( 'Requesting lock on task #'.$ctsk_ID.' ['.$ctsk_name.']', 0 );
 146  
 147      $DB->halt_on_error = false;
 148      $DB->show_errors = false;
 149      $sql = 'INSERT INTO T_cron__log( clog_ctsk_ID, clog_realstart_datetime, clog_status)
 150                      VALUES( '.$ctsk_ID.', '.$DB->quote( date2mysql($localtimenow) ).', "started" )';
 151      // Duplicate query for tests!
 152      // $DB->query( $sql, 'Request lock' );
 153      if( $DB->query( $sql, 'Request lock' ) != 1 )
 154      { // This has no affected exactly ONE row: error! (probably locked -- duplicate key -- by a concurrent process)
 155          $DB->show_errors = true;
 156          $DB->halt_on_error = true;
 157          cron_log( 'Could not lock. Task is probably handled by another process.', 2 );
 158      }
 159      else
 160      {
 161          if( !empty( $task->ctsk_repeat_after ) )
 162          {    // This task wants to be repeated:
 163              // Note: we use the current time for 2 reasons: 1) prevent scheduling something in the past AND 2) introduce variety so that everyone doesn't run his repeated tasks at the same exact time, especially pings, pollings...
 164              if( $task->ctsk_controller == 'cron/_antispam_poll.job.php' )
 165              {    // THIS IS A HACK. Guess why we need that!? :P  Please do not override or you'll kill our server :(
 166                  $new_start_datetime = $localtimenow + rand( 43200, 86400 ); // 12 to 24 hours
 167              }
 168              else
 169              {    // Normal
 170                  $new_start_datetime = $localtimenow + $task->ctsk_repeat_after;
 171              }
 172              $sql = 'INSERT INTO T_cron__task( ctsk_start_datetime, ctsk_repeat_after, ctsk_name, ctsk_controller, ctsk_params )
 173                              VALUES( '.$DB->quote(date2mysql($new_start_datetime)).', '.$DB->quote($task->ctsk_repeat_after).', '
 174                                                  .$DB->quote($ctsk_name).', '.$DB->quote($task->ctsk_controller).', '.$DB->quote($task->ctsk_params).' )';
 175              $DB->query( $sql, 'Schedule repeated task.' );
 176          }
 177  
 178          $DB->show_errors = true;
 179          $DB->halt_on_error = true;
 180          cron_log( 'Starting task #'.$ctsk_ID.' ['.$ctsk_name.'] at '.date( 'H:i:s', $localtimenow ).'.', 1 );
 181  
 182          if( empty($task->ctsk_params) )
 183          {
 184              $cron_params = array();
 185          }
 186          else
 187          {
 188              $cron_params = unserialize( $task->ctsk_params );
 189          }
 190  
 191          // The job may need to know its ID and name (to set logical locks for example):
 192          $cron_params['ctsk_ID'] = $ctsk_ID;
 193  
 194          // EXECUTE
 195          $error_message = call_job( $task->ctsk_controller, $cron_params );
 196          if( !empty( $error_message ) )
 197          {
 198              $error_task = array(
 199                      'ID'      => $ctsk_ID,
 200                      'name'    => $ctsk_name,
 201                      'message' => $error_message,
 202                  );
 203          }
 204  
 205          // Record task as finished:
 206          if( empty($timestop) )
 207          {
 208              $timestop = time() + $time_difference;
 209          }
 210  
 211          if( is_array( $result_message ) )
 212          {    // If result is array we should store it as serialized data
 213              $result_message = serialize( $result_message );
 214          }
 215  
 216          $sql = ' UPDATE T_cron__log
 217                                  SET clog_status = '.$DB->quote($result_status).',
 218                                          clog_realstop_datetime = '.$DB->quote( date2mysql( $timestop ) ).',
 219                                          clog_messages = '.$DB->quote( $result_message ) /* May be NULL */.'
 220                              WHERE clog_ctsk_ID = '.$ctsk_ID;
 221          $DB->query( $sql, 'Record task as finished.' );
 222      }
 223  }
 224  
 225  
 226  //echo 'detecting timeouts...';
 227  // Detect timed out tasks:
 228  detect_timeout_cron_jobs( $error_task );
 229  
 230  
 231  
 232  if( ! $is_cli )
 233  { // This is a web request:
 234      echo '<p><a href="cron_exec.php">Refresh Now!</a></p>';
 235      echo '<p>This page should refresh automatically in 15 seconds...</p>';
 236      echo '<!-- This is invalid HTML but it is SOOOOOO helpful! (Delay will be triggered when we reach that point -->';
 237      echo '<meta http-equiv="Refresh" content="15" />';
 238      ?>
 239      </body>
 240      </html>
 241      <?php
 242  }
 243  
 244  ?>

title

Description

title

Description

title

Description

title

title

Body