[ Index ]

PHP Cross Reference of MyBB 1.8.37

title

Body

[close]

/inc/ -> functions_task.php (source)

   1  <?php
   2  /**
   3   * MyBB 1.8
   4   * Copyright 2014 MyBB Group, All Rights Reserved
   5   *
   6   * Website: http://www.mybb.com
   7   * License: http://www.mybb.com/about/license
   8   *
   9   */
  10  
  11  /**
  12   * Execute a scheduled task.
  13   *
  14   * @param int $tid The task ID. If none specified, the next task due to be ran is executed
  15   * @return boolean True if successful, false on failure
  16   */
  17  function run_task($tid=0)
  18  {
  19      global $db, $mybb, $cache, $plugins, $task, $lang;
  20  
  21      // Run a specific task
  22      if($tid > 0)
  23      {
  24          $query = $db->simple_select("tasks", "*", "tid='{$tid}'");
  25          $task = $db->fetch_array($query);
  26      }
  27  
  28      // Run the next task due to be run
  29      else
  30      {
  31          $query = $db->simple_select("tasks", "*", "enabled=1 AND nextrun<='".TIME_NOW."'", array("order_by" => "nextrun", "order_dir" => "asc", "limit" => 1));
  32          $task = $db->fetch_array($query);
  33      }
  34  
  35      // No task? Return
  36      if(!$task)
  37      {
  38          $cache->update_tasks();
  39          return false;
  40      }
  41  
  42      // Is this task still running and locked less than 5 minutes ago? Well don't run it now - clearly it isn't broken!
  43      if($task['locked'] != 0 && $task['locked'] > TIME_NOW-300)
  44      {
  45          $cache->update_tasks();
  46          return false;
  47      }
  48      // Lock it! It' mine, all mine!
  49      else
  50      {
  51          $db->update_query("tasks", array("locked" => TIME_NOW), "tid='{$task['tid']}'");
  52      }
  53  
  54      $file = basename($task['file'], '.php');
  55  
  56      // The task file does not exist
  57      if(!file_exists(MYBB_ROOT."inc/tasks/{$file}.php"))
  58      {
  59          if($task['logging'] == 1)
  60          {
  61              add_task_log($task, $lang->missing_task);
  62          }
  63  
  64          // If task file does not exist, disable task and inform the administrator
  65          $updated_task = array(
  66              "enabled" => 0,
  67              "locked" => 0
  68          );
  69          $db->update_query("tasks", $updated_task, "tid='{$task['tid']}'");
  70  
  71          $subject = $lang->sprintf($lang->email_broken_task_subject, $mybb->settings['bbname']);
  72          $message = $lang->sprintf($lang->email_broken_task, $mybb->settings['bbname'], $mybb->settings['bburl'], $task['title']);
  73  
  74          my_mail($mybb->settings['adminemail'], $subject, $message, $mybb->settings['adminemail']);
  75  
  76          $cache->update_tasks();
  77          return false;
  78      }
  79      // Run the task
  80      else
  81      {
  82          // Update the nextrun time now, so if the task causes a fatal error, it doesn't get stuck first in the queue
  83          $nextrun = fetch_next_run($task);
  84          $db->update_query("tasks", array("nextrun" => $nextrun), "tid='{$task['tid']}'");
  85          
  86          include_once MYBB_ROOT."inc/tasks/{$file}.php";
  87          $function = "task_{$task['file']}";
  88          if(function_exists($function))
  89          {
  90              $function($task);
  91          }
  92      }
  93  
  94      $updated_task = array(
  95          "lastrun" => TIME_NOW,
  96          "locked" => 0
  97      );
  98      $db->update_query("tasks", $updated_task, "tid='{$task['tid']}'");
  99  
 100      $cache->update_tasks();
 101  
 102      return true;
 103  }
 104  
 105  /**
 106   * Adds information to the scheduled task log.
 107   *
 108   * @param int $task The task array to create the log entry for
 109   * @param string $message The message to log
 110   */
 111  function add_task_log($task, $message)
 112  {
 113      global $db;
 114  
 115      if(!$task['logging'])
 116      {
 117          return;
 118      }
 119  
 120      $log_entry = array(
 121          "tid" => (int)$task['tid'],
 122          "dateline" => TIME_NOW,
 123          "data" => $db->escape_string($message)
 124      );
 125      $db->insert_query("tasklog", $log_entry);
 126  }
 127  
 128  /**
 129   * Generate the next run time for a particular task.
 130   *
 131   * @param array $task The task array as fetched from the database.
 132   * @return int The next run time as a UNIX timestamp
 133   */
 134  function fetch_next_run($task)
 135  {
 136      $time = TIME_NOW;
 137      $next_minute = $current_minute = date("i", $time);
 138      $next_hour = $current_hour = date("H", $time);
 139      $next_day = $current_day = date("d", $time);
 140      $next_weekday = $current_weekday = date("w", $time);
 141      $next_month = $current_month = date("m", $time);
 142      $next_year = $current_year = date("Y", $time);
 143      $reset_day = $reset_hour = $reset_month = $reset_year = 0;
 144  
 145      if($task['minute'] == "*")
 146      {
 147          ++$next_minute;
 148          if($next_minute > 59)
 149          {
 150              $reset_hour = 1;
 151              $next_minute = 0;
 152          }
 153      }
 154      else
 155      {
 156          if(build_next_run_bit($task['minute'], $current_minute) != false)
 157          {
 158              $next_minute = build_next_run_bit($task['minute'], $current_minute);
 159          }
 160          else
 161          {
 162              $next_minute = fetch_first_run_time($task['minute']);
 163          }
 164          if($next_minute <= $current_minute)
 165          {
 166              $reset_hour = 1;
 167          }
 168      }
 169  
 170      if($reset_hour || !run_time_exists($task['hour'], $current_hour))
 171      {
 172          if($task['hour'] == "*")
 173          {
 174              ++$next_hour;
 175              if($next_hour > 23)
 176              {
 177                  $reset_day = 1;
 178                  $next_hour = 0;
 179              }
 180          }
 181          else
 182          {
 183              if(build_next_run_bit($task['hour'], $current_hour) != false)
 184              {
 185                  $next_hour = build_next_run_bit($task['hour'], $current_hour);
 186              }
 187              else
 188              {
 189                  $next_hour = fetch_first_run_time($task['hour']);
 190                  $reset_day = 1;
 191              }
 192              if($next_hour < $current_hour)
 193              {
 194                  $reset_day = 1;
 195              }
 196          }
 197          $next_minute = fetch_first_run_time($task['minute']);
 198      }
 199  
 200      if($reset_day || ($task['weekday'] == "*" && !run_time_exists($task['day'], $current_day) || $task['day'] == "*" && !run_time_exists($task['weekday'], $current_weekday)))
 201      {
 202          if($task['weekday'] == "*")
 203          {
 204              if($task['day'] == "*")
 205              {
 206                  ++$next_day;
 207                  if($next_day > date("t", $time))
 208                  {
 209                      $reset_month = 1;
 210                      $next_day = 1;
 211                  }
 212              }
 213              else
 214              {
 215                  if(build_next_run_bit($task['day'], $current_day) != false)
 216                  {
 217                      $next_day = build_next_run_bit($task['day'], $current_day);
 218                  }
 219                  else
 220                  {
 221                      $next_day = fetch_first_run_time($task['day']);
 222                      $reset_month = 1;
 223                  }
 224                  if($next_day < $current_day)
 225                  {
 226                      $reset_month = 1;
 227                  }
 228              }
 229          }
 230          else
 231          {
 232              if(build_next_run_bit($task['weekday'], $current_weekday) != false)
 233              {
 234                  $next_weekday = build_next_run_bit($task['weekday'], $current_weekday);
 235              }
 236              else
 237              {
 238                  $next_weekday = fetch_first_run_time($task['weekday']);
 239              }
 240              $next_day = $current_day + ($next_weekday-$current_weekday);
 241              if($next_day <= $current_day)
 242              {
 243                  $next_day += 7;
 244              }
 245  
 246              if($next_day > date("t", $time))
 247              {
 248                  $reset_month = 1;
 249              }
 250          }
 251          $next_minute = fetch_first_run_time($task['minute']);
 252          $next_hour = fetch_first_run_time($task['hour']);
 253          if($next_day == $current_day && $next_hour < $current_hour)
 254          {
 255              $reset_month = 1;
 256          }
 257      }
 258  
 259      if($reset_month || !run_time_exists($task['month'], $current_month))
 260      {
 261          if($task['month'] == "*")
 262          {
 263              $next_month++;
 264              if($next_month > 12)
 265              {
 266                  $reset_year = 1;
 267                  $next_month = 1;
 268              }
 269          }
 270          else
 271          {
 272              if(build_next_run_bit($task['month'], $current_month) != false)
 273              {
 274                  $next_month = build_next_run_bit($task['month'], $current_month);
 275              }
 276              else
 277              {
 278                  $next_month = fetch_first_run_time($task['month']);
 279                  $reset_year = 1;
 280              }
 281              if($next_month < $current_month)
 282              {
 283                  $reset_year = 1;
 284              }
 285          }
 286          $next_minute = fetch_first_run_time($task['minute']);
 287          $next_hour = fetch_first_run_time($task['hour']);
 288          if($task['weekday'] == "*")
 289          {
 290              $next_day = fetch_first_run_time($task['day']);
 291              if($next_day == 0) $next_day = 1;
 292          }
 293          else
 294          {
 295              $next_weekday = fetch_first_run_time($task['weekday']);
 296              $new_weekday = date("w", mktime($next_hour, $next_minute, 0, $next_month, 1, $next_year));
 297              $next_day = 1 + ($next_weekday-$new_weekday);
 298              if($next_weekday < $new_weekday)
 299              {
 300                  $next_day += 7;
 301              }
 302          }
 303          if($next_month == $current_month && $next_day == $current_day && $next_hour < $current_hour)
 304          {
 305              $reset_year = 1;
 306          }
 307      }
 308  
 309      if($reset_year)
 310      {
 311          $next_year++;
 312          $next_minute = fetch_first_run_time($task['minute']);
 313          $next_hour = fetch_first_run_time($task['hour']);
 314          $next_month = fetch_first_run_time($task['month']);
 315          if($next_month == 0) $next_month = 1;
 316          if($task['weekday'] == "*")
 317          {
 318              $next_day = fetch_first_run_time($task['day']);
 319              if($next_day == 0) $next_day = 1;
 320          }
 321          else
 322          {
 323              $next_weekday = fetch_first_run_time($task['weekday']);
 324              $new_weekday = date("w", mktime($next_hour, $next_minute, 0, $next_month, 1, $next_year));
 325              $next_day = 1 + ($next_weekday-$new_weekday);
 326              if($next_weekday < $new_weekday)
 327              {
 328                  $next_day += 7;
 329              }
 330          }
 331      }
 332      return mktime($next_hour, $next_minute, 0, $next_month, $next_day, $next_year);
 333  }
 334  
 335  /**
 336   * Builds the next run time bit for a particular item (day, hour, month etc). Used by fetch_next_run().
 337   *
 338   * @param string $data A string containing the run times for this particular item
 339   * @param int $bit The current value (be it current day etc)
 340   * @return int|bool The new or found value or boolean if nothing is found
 341   */
 342  function build_next_run_bit($data, $bit)
 343  {
 344      if($data == "*") return $bit;
 345      $data = explode(",", $data);
 346      foreach($data as $thing)
 347      {
 348          if($thing > $bit)
 349          {
 350              return $thing;
 351          }
 352      }
 353      return false;
 354  }
 355  
 356  /**
 357   * Fetches the fist run bit for a particular item (day, hour, month etc). Used by fetch_next_run().
 358   *
 359   * @param string $data A string containing the run times for this particular item
 360   * @return int The first run time
 361   */
 362  function fetch_first_run_time($data)
 363  {
 364      if($data == "*") return "0";
 365      $data = explode(",", $data);
 366      return $data[0];
 367  }
 368  
 369  /**
 370   * Checks if a specific run time exists for a particular item (day, hour, month etc). Used by fetch_next_run().
 371   *
 372   * @param string $data A string containing the run times for this particular item
 373   * @param int $bit The bit we're checking for
 374   * @return boolean True if it exists, false if it does not
 375   */
 376  function run_time_exists($data, $bit)
 377  {
 378      if($data == "*") return true;
 379      $data = explode(",", $data);
 380      if(in_array($bit, $data))
 381      {
 382          return true;
 383      }
 384      return false;
 385  }


2005 - 2021 © MyBB.de | Alle Rechte vorbehalten! | Sponsor: netcup Cross-referenced by PHPXref