PageRenderTime 48ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/classes/crontab.php

https://github.com/ringmaster/system
PHP | 264 lines | 158 code | 22 blank | 84 comment | 16 complexity | 9e044cbeefbb683d6d65dc79c13edd11 MD5 | raw file
  1. <?php
  2. /**
  3. * @package Habari
  4. *
  5. */
  6. /**
  7. * Static class to build and read cron entries
  8. *
  9. */
  10. class CronTab extends ActionHandler
  11. {
  12. /**
  13. * Executes all cron jobs in the DB if there are any to run.
  14. *
  15. * @param boolean $async If true, allows execution to continue by making an asynchronous request to a cron URL
  16. */
  17. static function run_cron( $async = false )
  18. {
  19. // check if it's time to run crons, and if crons are already running.
  20. $next_cron = HabariDateTime::date_create( Options::get( 'next_cron' ) );
  21. $time = HabariDateTime::date_create();
  22. if ( ( $next_cron->int > $time->int )
  23. || ( Options::get( 'cron_running' ) && Options::get( 'cron_running' ) > microtime( true ) )
  24. ) {
  25. return;
  26. }
  27. // cron_running will timeout in 10 minutes
  28. // round cron_running to 4 decimals
  29. $run_time = microtime( true ) + 600;
  30. $run_time = sprintf( "%.4f", $run_time );
  31. Options::set( 'cron_running', $run_time );
  32. if ( $async ) {
  33. // Timeout is really low so that it doesn't wait for the request to finish
  34. $cronurl = URL::get( 'cron',
  35. array(
  36. 'time' => $run_time,
  37. 'asyncronous' => Utils::crypt( Options::get( 'GUID' ) ) )
  38. );
  39. $request = new RemoteRequest( $cronurl, 'GET', 1 );
  40. try {
  41. $request->execute();
  42. }
  43. catch ( RemoteRequest_Timeout $e ) {
  44. // the request timed out - we knew that would happen
  45. }
  46. catch ( Exception $e ) {
  47. // some other error occurred. we still don't care
  48. }
  49. }
  50. else {
  51. // @todo why do we usleep() and why don't we just call act_poll_cron()?
  52. usleep( 5000 );
  53. if ( Options::get( 'cron_running' ) != $run_time ) {
  54. return;
  55. }
  56. $time = HabariDateTime::date_create();
  57. $crons = DB::get_results(
  58. 'SELECT * FROM {crontab} WHERE start_time <= ? AND next_run <= ?',
  59. array( $time->sql, $time->sql ),
  60. 'CronJob'
  61. );
  62. if ( $crons ) {
  63. foreach ( $crons as $cron ) {
  64. $cron->execute();
  65. }
  66. }
  67. EventLog::log( _t( 'CronTab run completed.' ), 'debug', 'crontab', 'habari', $crons );
  68. // set the next run time to the lowest next_run OR a max of one day.
  69. $next_cron = DB::get_value( 'SELECT next_run FROM {crontab} ORDER BY next_run ASC LIMIT 1', array() );
  70. Options::set( 'next_cron', min( intval( $next_cron ), $time->modify( '+1 day' )->int ) );
  71. Options::set( 'cron_running', false );
  72. }
  73. }
  74. /**
  75. * Handles asyncronous cron calls.
  76. *
  77. * @todo next_cron should be the actual next run time and update it when new
  78. * crons are added instead of just maxing out at one day..
  79. */
  80. function act_poll_cron()
  81. {
  82. Utils::check_request_method( array( 'GET', 'HEAD', 'POST' ) );
  83. $time = doubleval( $this->handler_vars['time'] );
  84. if ( $time != Options::get( 'cron_running' ) ) {
  85. return;
  86. }
  87. // allow script to run for 10 minutes. This only works on host with safe mode DISABLED
  88. if ( !ini_get( 'safe_mode' ) ) {
  89. set_time_limit( 600 );
  90. }
  91. $time = HabariDateTime::date_create();
  92. $crons = DB::get_results(
  93. 'SELECT * FROM {crontab} WHERE start_time <= ? AND next_run <= ?',
  94. array( $time->sql, $time->sql ),
  95. 'CronJob'
  96. );
  97. if ( $crons ) {
  98. foreach ( $crons as $cron ) {
  99. $cron->execute();
  100. }
  101. }
  102. // set the next run time to the lowest next_run OR a max of one day.
  103. $next_cron = DB::get_value( 'SELECT next_run FROM {crontab} ORDER BY next_run ASC LIMIT 1', array() );
  104. Options::set( 'next_cron', min( intval( $next_cron ), $time->modify( '+1 day' )->int ) );
  105. Options::set( 'cron_running', false );
  106. }
  107. /**
  108. * Get a Cron Job by name or id from the Database.
  109. *
  110. * @param mixed $name The name or id of the cron job to retreive.
  111. * @return CronJob The cron job retreived from the DB
  112. */
  113. static function get_cronjob( $name )
  114. {
  115. if ( is_int( $name ) ) {
  116. $cron = DB::get_row( 'SELECT * FROM {crontab} WHERE cron_id = ?', array( $name ), 'CronJob' );
  117. }
  118. else {
  119. $cron = DB::get_row( 'SELECT * FROM {crontab} WHERE name = ?', array( $name ), 'CronJob' );
  120. }
  121. return $cron;
  122. }
  123. /**
  124. * Delete a Cron Job by name or id from the Database.
  125. *
  126. * @param mixed $name The name or id of the cron job to delete.
  127. * @return bool Wheather or not the delete was successfull
  128. */
  129. static function delete_cronjob( $name )
  130. {
  131. $cron = self::get_cronjob( $name );
  132. if ( $cron ) {
  133. return $cron->delete();
  134. }
  135. return false;
  136. }
  137. /**
  138. * Add a new cron job to the DB.
  139. *
  140. * @see CronJob
  141. * @param array $paramarray A paramarray of cron job feilds.
  142. */
  143. static function add_cron( $paramarray )
  144. {
  145. $cron = new CronJob( $paramarray );
  146. $result = $cron->insert();
  147. //If the new cron should run earlier than the others, rest next_cron to its strat time.
  148. $next_cron = DB::get_value( 'SELECT next_run FROM {crontab} ORDER BY next_run ASC LIMIT 1', array() );
  149. if ( intval( Options::get( 'next_cron' ) ) > intval( $next_cron ) ) {
  150. Options::set( 'next_cron', $next_cron );
  151. }
  152. return $result;
  153. }
  154. /**
  155. * Add a new cron job to the DB, that runs only once.
  156. *
  157. * @param string $name The name of the cron job.
  158. * @param mixed $callback The callback function or plugin action for the cron job to execute.
  159. * @param HabariDateTime $run_time The time to execute the cron.
  160. * @param string $description The description of the cron job.
  161. */
  162. static function add_single_cron( $name, $callback, $run_time, $description = '' )
  163. {
  164. $paramarray = array(
  165. 'name' => $name,
  166. 'callback' => $callback,
  167. 'start_time' => $run_time,
  168. 'end_time' => $run_time, // only run once
  169. 'description' => $description
  170. );
  171. return self::add_cron( $paramarray );
  172. }
  173. /**
  174. * Add a new cron job to the DB, that runs hourly.
  175. *
  176. * @param string $name The name of the cron job.
  177. * @param mixed $callback The callback function or plugin action for the cron job to execute.
  178. * @param string $description The description of the cron job.
  179. */
  180. static function add_hourly_cron( $name, $callback, $description = '' )
  181. {
  182. $paramarray = array(
  183. 'name' => $name,
  184. 'callback' => $callback,
  185. 'increment' => 3600, // one hour
  186. 'description' => $description
  187. );
  188. return self::add_cron( $paramarray );
  189. }
  190. /**
  191. * Add a new cron job to the DB, that runs daily.
  192. *
  193. * @param string $name The name of the cron job.
  194. * @param mixed $callback The callback function or plugin action for the cron job to execute.
  195. * @param string $description The description of the cron job.
  196. */
  197. static function add_daily_cron( $name, $callback, $description = '' )
  198. {
  199. $paramarray = array(
  200. 'name' => $name,
  201. 'callback' => $callback,
  202. 'increment' => 86400, // one day
  203. 'description' => $description
  204. );
  205. return self::add_cron( $paramarray );
  206. }
  207. /**
  208. * Add a new cron job to the DB, that runs weekly.
  209. *
  210. * @param string $name The name of the cron job.
  211. * @param mixed $callback The callback function or plugin action for the cron job to execute.
  212. * @param string $description The description of the cron job.
  213. */
  214. static function add_weekly_cron( $name, $callback, $description = '' )
  215. {
  216. $paramarray = array(
  217. 'name' => $name,
  218. 'callback' => $callback,
  219. 'increment' => 604800, // one week (7 days)
  220. 'description' => $description
  221. );
  222. return self::add_cron( $paramarray );
  223. }
  224. /**
  225. * Add a new cron job to the DB, that runs monthly.
  226. *
  227. * @param string $name The name of the cron job.
  228. * @param mixed $callback The callback function or plugin action for the cron job to execute.
  229. * @param string $description The description of the cron job.
  230. */
  231. static function add_monthly_cron( $name, $callback, $description = '' )
  232. {
  233. $paramarray = array(
  234. 'name' => $name,
  235. 'callback' => $callback,
  236. 'increment' => 2592000, // one month (30 days)
  237. 'description' => $description
  238. );
  239. return self::add_cron( $paramarray );
  240. }
  241. }
  242. ?>