/resources/admin/forum/MyBB/inc/functions_task.php

https://github.com/canercandan/agat-engine · PHP · 371 lines · 293 code · 23 blank · 55 comment · 80 complexity · 79ab905f2eb2297aa2f902df6f8677af MD5 · raw file

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