elysia_cron_scheduler_old.inc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. <?php
  2. function elysia_cron_should_run($conf, $now = -1) {
  3. if ($conf['disabled']) {
  4. return false;
  5. }
  6. if ($now < 0) {
  7. $now = time();
  8. }
  9. if ((!$conf['last_run']) || ($now - $conf['last_run'] > 365 * 86400)) {
  10. return true;
  11. }
  12. if (!preg_match('/^([0-9*,\/-]+)[ ]+([0-9*,\/-]+)[ ]+([0-9*,\/-]+)[ ]+([0-9*,\/-]+)[ ]+([0-9*,\/-]+)$/', $conf['rule'], $rules)) {
  13. elysia_cron_warning('Invalid rule found: %rule', array('%rule' => $conf['rule']));
  14. return false;
  15. }
  16. $weekdayspec = ($rules[5] != '*');
  17. $mondayspec = ($rules[3] != '*');
  18. $rules[5] = _cronDecodeRule($rules[5], 0, 6);
  19. $rules[4] = _cronDecodeRule($rules[4], 1, 12);
  20. $rules[3] = _cronDecodeRule($rules[3], 1, 31);
  21. $rules[2] = _cronDecodeRule($rules[2], 0, 23);
  22. $rules[1] = _cronDecodeRule($rules[1], 0, 59);
  23. $lastT = _cronT($conf['last_run'] + 30);
  24. $nowT = _cronT($now);
  25. $nowTDelta = $nowT - $lastT + ($lastT > $nowT ? 12 * 31 * 24 * 60 : 0);
  26. $year = date('Y', $conf['last_run']);
  27. if ($mondayspec || (!$mondayspec && !$weekdayspec)) {
  28. $first = -1;
  29. foreach ($rules[4] as $mon) {
  30. foreach ($rules[3] as $d) {
  31. if (checkdate($mon, $d, $year)) {
  32. foreach ($rules[2] as $h) {
  33. foreach ($rules[1] as $m) {
  34. $t = _cronT($mon, $d, $h, $m);
  35. //dprint("* ".$t." L:".$lastT);
  36. if ($first < 0) {
  37. $first = $t;
  38. }
  39. if ($t > $lastT) {
  40. $nextT = $t;
  41. break 4;
  42. }
  43. }
  44. }
  45. }
  46. }
  47. }
  48. //dprint("R: ".$nextT);
  49. if (!$nextT) {
  50. $nextT = $first;
  51. }
  52. $nextTDelta = $nextT - $lastT + ($lastT > $nextT ? 12 * 31 * 24 * 60 : 0);
  53. //dprint($nowT.' '.$nowTDelta.' '.$nextT.' '.$nextTDelta);
  54. if ($nowTDelta >= $nextTDelta) {
  55. return true;
  56. }
  57. }
  58. if ($weekdayspec) {
  59. foreach ($rules[4] as $mon) {
  60. foreach (_cronMonDaysFromWeekDays($year, $mon, $rules[5]) as $d) {
  61. foreach ($rules[2] as $h) {
  62. foreach ($rules[1] as $m) {
  63. $t = _cronT($mon, $d, $h, $m);
  64. //dprint("* ".$t." L:".$lastT);
  65. if ($t > $lastT) {
  66. $nextT = $t;
  67. break 4;
  68. }
  69. }
  70. }
  71. }
  72. }
  73. //dprint("R: ".$nextT);
  74. if (!$nextT) {
  75. //Must get the first of following year (if day_of_week is specified it's not the same of previous one)
  76. foreach ($rules[4] as $mon) {
  77. foreach (_cronMonDaysFromWeekDays($year + 1, $mon, $rules[5]) as $d) {
  78. foreach ($rules[2] as $h) {
  79. foreach ($rules[1] as $m) {
  80. $nextT = _cronT($mon, $d, $h, $m);
  81. break 4;
  82. }
  83. }
  84. }
  85. }
  86. }
  87. $nextTDelta = $nextT - $lastT + ($lastT > $nextT ? 12 * 31 * 24 * 60 : 0);
  88. //dprint($nowT.' '.$nowTDelta.' '.$nextT.' '.$nextTDelta);
  89. if ($nowTDelta >= $nextTDelta) {
  90. return true;
  91. }
  92. }
  93. return false;
  94. }
  95. // Used by elysia_cron_should_run
  96. function _cronT($time, $d = -1, $h = -1, $m = -1) {
  97. if ($d < 0) {
  98. return date('n', $time) * 31 * 24 * 60 + date('j', $time) * 24 * 60 + date('H', $time) * 60 + date('i', $time);
  99. }
  100. else {
  101. return $time * 31 * 24 * 60 + $d * 24 * 60 + $h * 60 + $m;
  102. }
  103. }
  104. // Used by elysia_cron_should_run
  105. function _cronMonDaysFromWeekDays($year, $mon, $weekdays) {
  106. $result = array();
  107. for ($i = 1; checkdate($mon, $i, $year); $i++) {
  108. $w = date('w', mktime(12, 00, 00, $mon, $i, $year));
  109. if (in_array($w, $weekdays)) {
  110. $result[] = $i;
  111. }
  112. }
  113. return $result;
  114. }
  115. // Used by elysia_cron_should_run
  116. function _cronDecodeRule($rule, $min, $max) {
  117. if ($rule == '*') {
  118. return range($min, $max);
  119. }
  120. $result = array();
  121. foreach (explode(',', $rule) as $token) {
  122. if (preg_match('/^([0-9]+)-([0-9]+)$/', $token, $r)) {
  123. $result = array_merge($result, range($r[1], $r[2]));
  124. }
  125. elseif (preg_match('/^\*\/([0-9]+)$/', $token, $r)) {
  126. for ($i = $min; $i <= $max; $i++) {
  127. if ($i % $r[1] == 0) {
  128. $result[] = $i;
  129. }
  130. }
  131. }
  132. elseif (is_numeric($token)) {
  133. $result[] = $token;
  134. }
  135. }
  136. return $result;
  137. }
  138. /*******************************************************************************
  139. * TESTS
  140. ******************************************************************************/
  141. function test_elysia_cron_should_run() {
  142. dprint("Start test");
  143. $start = microtime(true);
  144. //mktime: hr min sec mon day yr
  145. dprint(" 1." . (false == elysia_cron_should_run(array('rule' => '0 12 * * *', 'last_run' => mktime(12, 0, 0, 1, 2, 2008)), mktime(12, 01, 0, 1, 2, 2008))));
  146. dprint(" 2." . (false == elysia_cron_should_run(array('rule' => '0 12 * * *', 'last_run' => mktime(12, 0, 0, 1, 2, 2008)), mktime(15, 00, 0, 1, 2, 2008))));
  147. dprint(" 3." . (false == elysia_cron_should_run(array('rule' => '0 12 * * *', 'last_run' => mktime(12, 0, 0, 1, 2, 2008)), mktime(11, 59, 0, 1, 3, 2008))));
  148. dprint(" 4." . (true == elysia_cron_should_run(array('rule' => '0 12 * * *', 'last_run' => mktime(12, 0, 0, 1, 2, 2008)), mktime(12, 00, 0, 1, 3, 2008))));
  149. dprint(" 5." . (false == elysia_cron_should_run(array('rule' => '59 23 * * *', 'last_run' => mktime(23, 59, 0, 1, 2, 2008)), mktime(0, 00, 0, 1, 3, 2008))));
  150. dprint(" 6." . (true == elysia_cron_should_run(array('rule' => '59 23 * * *', 'last_run' => mktime(23, 59, 0, 1, 2, 2008)), mktime(23, 59, 0, 1, 3, 2008))));
  151. dprint(" 7." . (true == elysia_cron_should_run(array('rule' => '59 23 * * *', 'last_run' => mktime(23, 59, 0, 1, 2, 2008)), mktime(0, 00, 0, 1, 4, 2008))));
  152. dprint(" 8." . (true == elysia_cron_should_run(array('rule' => '59 23 * * *', 'last_run' => mktime(23, 58, 0, 1, 2, 2008)), mktime(23, 59, 0, 1, 2, 2008))));
  153. dprint(" 9." . (true == elysia_cron_should_run(array('rule' => '59 23 * * *', 'last_run' => mktime(23, 58, 0, 1, 2, 2008)), mktime(0, 0, 0, 1, 3, 2008))));
  154. dprint("10." . (false == elysia_cron_should_run(array('rule' => '59 23 * * 0', 'last_run' => mktime(23, 58, 0, 1, 5, 2008)), mktime(23, 59, 0, 1, 5, 2008))));
  155. dprint("11." . (false == elysia_cron_should_run(array('rule' => '59 23 * * 0', 'last_run' => mktime(23, 58, 0, 1, 5, 2008)), mktime(0, 0, 0, 1, 6, 2008))));
  156. dprint("12." . (true == elysia_cron_should_run(array('rule' => '59 23 * * 0', 'last_run' => mktime(23, 58, 0, 1, 5, 2008)), mktime(23, 59, 0, 1, 6, 2008))));
  157. dprint("13." . (true == elysia_cron_should_run(array('rule' => '59 23 * * 0', 'last_run' => mktime(23, 58, 0, 1, 5, 2008)), mktime(00, 00, 0, 1, 7, 2008))));
  158. dprint("14." . (true == elysia_cron_should_run(array('rule' => '29,59 23 * * 0', 'last_run' => mktime(23, 58, 0, 1, 5, 2008)), mktime(23, 29, 0, 1, 6, 2008))));
  159. dprint("15." . (true == elysia_cron_should_run(array('rule' => '29,59 23 * * 0', 'last_run' => mktime(23, 58, 0, 1, 5, 2008)), mktime(23, 59, 0, 1, 6, 2008))));
  160. dprint("16." . (false == elysia_cron_should_run(array('rule' => '29,59 23 * * 0', 'last_run' => mktime(23, 58, 0, 1, 5, 2008)), mktime(23, 59, 0, 1, 5, 2008))));
  161. dprint("17." . (true == elysia_cron_should_run(array('rule' => '29,59 23 * * 0', 'last_run' => mktime(23, 58, 0, 1, 5, 2008)), mktime(23, 58, 0, 1, 6, 2008))));
  162. dprint("18." . (false == elysia_cron_should_run(array('rule' => '29,59 23 * * 0', 'last_run' => mktime(23, 58, 0, 1, 5, 2008)), mktime(23, 28, 0, 1, 6, 2008))));
  163. dprint("19." . (false == elysia_cron_should_run(array('rule' => '29,59 23 * * 0', 'last_run' => mktime(23, 28, 0, 1, 5, 2008)), mktime(23, 29, 0, 1, 5, 2008))));
  164. dprint("20." . (false == elysia_cron_should_run(array('rule' => '29,59 23 * * 0', 'last_run' => mktime(23, 28, 0, 1, 5, 2008)), mktime(23, 30, 0, 1, 5, 2008))));
  165. dprint("21." . (false == elysia_cron_should_run(array('rule' => '29,59 23 * * 0', 'last_run' => mktime(23, 28, 0, 1, 5, 2008)), mktime(23, 59, 0, 1, 5, 2008))));
  166. dprint("22." . (true == elysia_cron_should_run(array('rule' => '29,59 23 * * 0', 'last_run' => mktime(23, 28, 0, 1, 5, 2008)), mktime(23, 29, 0, 1, 6, 2008))));
  167. dprint("23." . (false == elysia_cron_should_run(array('rule' => '29,59 23 * * 5', 'last_run' => mktime(23, 59, 0, 2, 22, 2008)), mktime(23, 59, 0, 2, 28, 2008))));
  168. dprint("24." . (true == elysia_cron_should_run(array('rule' => '29,59 23 * * 5', 'last_run' => mktime(23, 59, 0, 2, 22, 2008)), mktime(23, 59, 0, 2, 29, 2008))));
  169. dprint("25." . (true == elysia_cron_should_run(array('rule' => '29,59 23 * * 5', 'last_run' => mktime(23, 59, 0, 2, 22, 2008)), mktime(0, 0, 0, 3, 1, 2008))));
  170. dprint("26." . (false == elysia_cron_should_run(array('rule' => '59 23 * * 3', 'last_run' => mktime(23, 59, 0, 12, 31, 2008)), mktime(0, 0, 0, 1, 1, 2009))));
  171. dprint("27." . (false == elysia_cron_should_run(array('rule' => '59 23 * * 3', 'last_run' => mktime(23, 59, 0, 12, 31, 2008)), mktime(0, 0, 0, 1, 7, 2009))));
  172. dprint("28." . (true == elysia_cron_should_run(array('rule' => '59 23 * * 3', 'last_run' => mktime(23, 59, 0, 12, 31, 2008)), mktime(23, 59, 0, 1, 7, 2009))));
  173. dprint("29." . (true == elysia_cron_should_run(array('rule' => '59 23 * 2 5', 'last_run' => mktime(23, 59, 0, 2, 22, 2008)), mktime(23, 59, 0, 2, 29, 2008))));
  174. dprint("30." . (true == elysia_cron_should_run(array('rule' => '59 23 * 2 5', 'last_run' => mktime(23, 59, 0, 2, 22, 2008)), mktime(0, 0, 0, 3, 1, 2008))));
  175. dprint("31." . (false == elysia_cron_should_run(array('rule' => '59 23 * 2 5', 'last_run' => mktime(23, 59, 0, 2, 29, 2008)), mktime(23, 59, 0, 3, 7, 2008))));
  176. dprint("32." . (false == elysia_cron_should_run(array('rule' => '59 23 * 2 5', 'last_run' => mktime(23, 59, 0, 2, 29, 2008)), mktime(23, 58, 0, 2, 6, 2009))));
  177. dprint("33." . (true == elysia_cron_should_run(array('rule' => '59 23 * 2 5', 'last_run' => mktime(23, 59, 0, 2, 29, 2008)), mktime(23, 59, 0, 2, 6, 2009))));
  178. dprint("34." . (true == elysia_cron_should_run(array('rule' => '59 23 *' . '/10 * *', 'last_run' => mktime(23, 58, 0, 1, 10, 2008)), mktime(23, 59, 0, 1, 10, 2008))));
  179. dprint("35." . (false == elysia_cron_should_run(array('rule' => '59 23 *' . '/10 * *', 'last_run' => mktime(23, 59, 0, 1, 10, 2008)), mktime(23, 59, 0, 1, 11, 2008))));
  180. dprint("36." . (true == elysia_cron_should_run(array('rule' => '59 23 *' . '/10 * *', 'last_run' => mktime(23, 59, 0, 1, 10, 2008)), mktime(23, 59, 0, 1, 20, 2008))));
  181. dprint("37." . (true == elysia_cron_should_run(array('rule' => '59 23 1-5,10-15 * *', 'last_run' => mktime(23, 59, 0, 1, 4, 2008)), mktime(23, 59, 0, 1, 5, 2008))));
  182. dprint("38." . (true == elysia_cron_should_run(array('rule' => '59 23 1-5,10-15 * *', 'last_run' => mktime(23, 59, 0, 1, 4, 2008)), mktime(23, 59, 0, 1, 6, 2008))));
  183. dprint("39." . (false == elysia_cron_should_run(array('rule' => '59 23 1-5,10-15 * *', 'last_run' => mktime(23, 59, 0, 1, 5, 2008)), mktime(23, 59, 0, 1, 6, 2008))));
  184. dprint("40." . (false == elysia_cron_should_run(array('rule' => '59 23 1-5,10-15 * *', 'last_run' => mktime(23, 59, 0, 1, 5, 2008)), mktime(23, 58, 0, 1, 10, 2008))));
  185. dprint("41." . (true == elysia_cron_should_run(array('rule' => '59 23 1-5,10-15 * *', 'last_run' => mktime(23, 59, 0, 1, 5, 2008)), mktime(23, 59, 0, 1, 10, 2008))));
  186. dprint("42." . (true == elysia_cron_should_run(array('rule' => '59 23 1-5,10-15 * *', 'last_run' => mktime(23, 59, 0, 1, 5, 2008)), mktime(23, 59, 0, 1, 16, 2008))));
  187. dprint("43." . (true == elysia_cron_should_run(array('rule' => '59 23 1-5 1 0', 'last_run' => mktime(23, 59, 0, 1, 4, 2008)), mktime(23, 59, 0, 1, 5, 2008))));
  188. dprint("44." . (true == elysia_cron_should_run(array('rule' => '59 23 1-5 1 0', 'last_run' => mktime(23, 59, 0, 1, 5, 2008)), mktime(23, 59, 0, 1, 6, 2008))));
  189. dprint("45." . (false == elysia_cron_should_run(array('rule' => '59 23 1-5 1 0', 'last_run' => mktime(23, 59, 0, 1, 6, 2008)), mktime(23, 59, 0, 1, 7, 2008))));
  190. dprint("46." . (true == elysia_cron_should_run(array('rule' => '59 23 1-5 1 0', 'last_run' => mktime(23, 59, 0, 1, 6, 2008)), mktime(23, 59, 0, 1, 13, 2008))));
  191. dprint("47." . (false == elysia_cron_should_run(array('rule' => '59 23 1-5 1 0', 'last_run' => mktime(23, 59, 0, 2, 4, 2008)), mktime(23, 59, 0, 2, 5, 2008))));
  192. dprint("48." . (false == elysia_cron_should_run(array('rule' => '59 23 1-5 1 0', 'last_run' => mktime(23, 59, 0, 2, 5, 2008)), mktime(23, 59, 0, 2, 10, 2008))));
  193. dprint("49." . (false == elysia_cron_should_run(array('rule' => '59 23 1-5 1 0', 'last_run' => mktime(23, 59, 0, 2, 10, 2008)), mktime(23, 59, 0, 2, 17, 2008))));
  194. dprint("49." . (true == elysia_cron_should_run(array('rule' => '* 0,1,2,3,4,5,6,7,8,18,19,20,21,22,23 * * *', 'last_run' => mktime(8, 58, 0, 2, 10, 2008)), mktime(8, 59, 0, 2, 10, 2008))));
  195. dprint("50." . (false == elysia_cron_should_run(array('rule' => '* 0,1,2,3,4,5,6,7,8,18,19,20,21,22,23 * * *', 'last_run' => mktime(8, 59, 0, 2, 10, 2008)), mktime(9, 00, 0, 2, 10, 2008))));
  196. dprint("51." . (false == elysia_cron_should_run(array('rule' => '* 0,1,2,3,4,5,6,7,8,18,19,20,21,22,23 * * *', 'last_run' => mktime(8, 59, 0, 2, 10, 2008)), mktime(17, 59, 0, 2, 10, 2008))));
  197. dprint("52." . (true == elysia_cron_should_run(array('rule' => '* 0,1,2,3,4,5,6,7,8,18,19,20,21,22,23 * * *', 'last_run' => mktime(8, 59, 0, 2, 10, 2008)), mktime(18, 00, 0, 2, 10, 2008))));
  198. dprint("53." . (true == elysia_cron_should_run(array('rule' => '* 0,1,2,3,4,5,6,7,8,18,19,20,21,22,23 * * *', 'last_run' => mktime(18, 00, 0, 2, 10, 2008)), mktime(18, 01, 0, 2, 10, 2008))));
  199. dprint("54." . (true == elysia_cron_should_run(array('rule' => '* 0,1,2,3,4,5,6,7,8,18,19,20,21,22,23 * * *', 'last_run' => mktime(18, 00, 0, 2, 10, 2008)), mktime(19, 0, 0, 2, 10, 2008))));
  200. dprint("55." . (true == elysia_cron_should_run(array('rule' => '* 0,1,2,3,4,5,6,7,8,18,19,20,21,22,23 * * *', 'last_run' => mktime(18, 00, 0, 2, 10, 2008)), mktime(9, 0, 0, 3, 10, 2008))));
  201. dprint("End test (" . (microtime(true) - $start) . ")");
  202. }
  203. // Remove comment to run tests
  204. //test_elysia_cron_should_run();die();