discuz_cron.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. <?php
  2. /**
  3. * [Discuz!] (C)2001-2099 Comsenz Inc.
  4. * This is NOT a freeware, use is subject to license terms
  5. *
  6. * $Id: discuz_cron.php 30314 2012-05-22 03:12:44Z monkey $
  7. */
  8. if(!defined('IN_DISCUZ')) {
  9. exit('Access Denied');
  10. }
  11. class discuz_cron
  12. {
  13. public static function run($cronid = 0) {
  14. global $_G;
  15. $cron = $cronid ? C::t('common_cron')->fetch($cronid) : C::t('common_cron')->fetch_nextrun(TIMESTAMP);
  16. $processname ='DZ_CRON_'.(empty($cron) ? 'CHECKER' : $cron['cronid']);
  17. if($cronid && !empty($cron)) {
  18. discuz_process::unlock($processname);
  19. }
  20. if(discuz_process::islocked($processname, 600)) {
  21. return false;
  22. }
  23. if($cron) {
  24. $cron['filename'] = str_replace(array('..', '/', '\\'), '', $cron['filename']);
  25. $efile = explode(':', $cron['filename']);
  26. if(count($efile) > 1) {
  27. $cronfile = in_array($efile[0], $_G['setting']['plugins']['available']) ? DISCUZ_ROOT.'./source/plugin/'.$efile[0].'/cron/'.$efile[1] : '';
  28. } else {
  29. $cronfile = DISCUZ_ROOT.'./source/include/cron/'.$cron['filename'];
  30. }
  31. if($cronfile) {
  32. $cron['minute'] = explode("\t", $cron['minute']);
  33. self::setnextime($cron);
  34. @set_time_limit(1000);
  35. @ignore_user_abort(TRUE);
  36. if(!@include $cronfile) {
  37. return false;
  38. }
  39. }
  40. }
  41. self::nextcron();
  42. discuz_process::unlock($processname);
  43. return true;
  44. }
  45. private static function nextcron() {
  46. $cron = C::t('common_cron')->fetch_nextcron();
  47. if($cron && isset($cron['nextrun'])) {
  48. savecache('cronnextrun', $cron['nextrun']);
  49. } else {
  50. savecache('cronnextrun', TIMESTAMP + 86400 * 365);
  51. }
  52. return true;
  53. }
  54. private static function setnextime($cron) {
  55. if(empty($cron)) return FALSE;
  56. list($yearnow, $monthnow, $daynow, $weekdaynow, $hournow, $minutenow) = explode('-', gmdate('Y-m-d-w-H-i', TIMESTAMP + getglobal('setting/timeoffset') * 3600));
  57. if($cron['weekday'] == -1) {
  58. if($cron['day'] == -1) {
  59. $firstday = $daynow;
  60. $secondday = $daynow + 1;
  61. } else {
  62. $firstday = $cron['day'];
  63. $secondday = $cron['day'] + gmdate('t', TIMESTAMP + getglobal('setting/timeoffset') * 3600);
  64. }
  65. } else {
  66. $firstday = $daynow + ($cron['weekday'] - $weekdaynow);
  67. $secondday = $firstday + 7;
  68. }
  69. if($firstday < $daynow) {
  70. $firstday = $secondday;
  71. }
  72. if($firstday == $daynow) {
  73. $todaytime = self::todaynextrun($cron);
  74. if($todaytime['hour'] == -1 && $todaytime['minute'] == -1) {
  75. $cron['day'] = $secondday;
  76. $nexttime = self::todaynextrun($cron, 0, -1);
  77. $cron['hour'] = $nexttime['hour'];
  78. $cron['minute'] = $nexttime['minute'];
  79. } else {
  80. $cron['day'] = $firstday;
  81. $cron['hour'] = $todaytime['hour'];
  82. $cron['minute'] = $todaytime['minute'];
  83. }
  84. } else {
  85. $cron['day'] = $firstday;
  86. $nexttime = self::todaynextrun($cron, 0, -1);
  87. $cron['hour'] = $nexttime['hour'];
  88. $cron['minute'] = $nexttime['minute'];
  89. }
  90. $nextrun = @gmmktime($cron['hour'], $cron['minute'] > 0 ? $cron['minute'] : 0, 0, $monthnow, $cron['day'], $yearnow) - getglobal('setting/timeoffset') * 3600;
  91. $data = array('lastrun' => TIMESTAMP, 'nextrun' => $nextrun);
  92. if(!($nextrun > TIMESTAMP)) {
  93. $data['available'] = '0';
  94. }
  95. C::t('common_cron')->update($cron['cronid'], $data);
  96. return true;
  97. }
  98. private static function todaynextrun($cron, $hour = -2, $minute = -2) {
  99. $hour = $hour == -2 ? gmdate('H', TIMESTAMP + getglobal('setting/timeoffset') * 3600) : $hour;
  100. $minute = $minute == -2 ? gmdate('i', TIMESTAMP + getglobal('setting/timeoffset') * 3600) : $minute;
  101. $nexttime = array();
  102. if($cron['hour'] == -1 && !$cron['minute']) {
  103. $nexttime['hour'] = $hour;
  104. $nexttime['minute'] = $minute + 1;
  105. } elseif($cron['hour'] == -1 && $cron['minute'] != '') {
  106. $nexttime['hour'] = $hour;
  107. if(($nextminute = self::nextminute($cron['minute'], $minute)) === false) {
  108. ++$nexttime['hour'];
  109. $nextminute = $cron['minute'][0];
  110. }
  111. $nexttime['minute'] = $nextminute;
  112. } elseif($cron['hour'] != -1 && $cron['minute'] == '') {
  113. if($cron['hour'] < $hour) {
  114. $nexttime['hour'] = $nexttime['minute'] = -1;
  115. } elseif($cron['hour'] == $hour) {
  116. $nexttime['hour'] = $cron['hour'];
  117. $nexttime['minute'] = $minute + 1;
  118. } else {
  119. $nexttime['hour'] = $cron['hour'];
  120. $nexttime['minute'] = 0;
  121. }
  122. } elseif($cron['hour'] != -1 && $cron['minute'] != '') {
  123. $nextminute = self::nextminute($cron['minute'], $minute);
  124. if($cron['hour'] < $hour || ($cron['hour'] == $hour && $nextminute === false)) {
  125. $nexttime['hour'] = -1;
  126. $nexttime['minute'] = -1;
  127. } else {
  128. $nexttime['hour'] = $cron['hour'];
  129. $nexttime['minute'] = $nextminute;
  130. }
  131. }
  132. return $nexttime;
  133. }
  134. private static function nextminute($nextminutes, $minutenow) {
  135. foreach($nextminutes as $nextminute) {
  136. if($nextminute > $minutenow) {
  137. return $nextminute;
  138. }
  139. }
  140. return false;
  141. }
  142. }
  143. ?>