cron.func.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <?php
  2. /**
  3. * [WeEngine System] Copyright (c) 2014 WE7.CC
  4. * WeEngine is NOT a free software, it under the license terms, visited http://www.we7.cc/ for more details.
  5. */
  6. defined('IN_IA') or exit('Access Denied');
  7. function cron_check($cronid = 0) {
  8. global $_W;
  9. $cron = pdo_get('core_cron', array('cloudid' => $cronid));
  10. $_W['uniacid'] = $cron['uniacid'];
  11. if (empty($cron)) {
  12. return error(-1000, '任务不存在或已删除');
  13. }
  14. if (!$cron['status']) {
  15. return error(-1001, '任务已关闭');
  16. }
  17. if ('sms' != $cron['filename']) {
  18. if (!$cron['uniacid']) {
  19. return error(-1002, '任务uniacid错误1');
  20. }
  21. }
  22. if (empty($cron['module'])) {
  23. return error(-1003, '任务所属模块为空');
  24. } else {
  25. if ('task' != $cron['module']) {
  26. $modules = array_keys(uni_modules());
  27. if (!in_array($cron['module'], $modules)) {
  28. return error(-1004, "公众号没有操作模块{$cron['module']}的权限");
  29. }
  30. }
  31. }
  32. if (empty($cron['filename'])) {
  33. return error(-1005, '任务脚本名称为空');
  34. }
  35. return $cron;
  36. }
  37. function cron_run($id) {
  38. global $_W;
  39. $cron = pdo_get('core_cron', array('uniacid' => $_W['uniacid'], 'id' => $id));
  40. if (empty($cron)) {
  41. return false;
  42. }
  43. $extra = array();
  44. $extra['Host'] = $_SERVER['HTTP_HOST'];
  45. load()->func('communication');
  46. $urlset = parse_url($_W['siteurl']);
  47. $urlset = pathinfo($urlset['path']);
  48. $response = ihttp_request($_W['sitescheme'] . '127.0.0.1/' . $urlset['dirname'] . '/' . url('cron/entry', array('id' => $cron['cloudid'])), array(), $extra);
  49. $response = json_decode($response['content'], true);
  50. if (is_error($response['message'])) {
  51. return $response['message'];
  52. } else {
  53. cron_setnexttime($cron);
  54. $cron_new = pdo_get('core_cron', array('uniacid' => $_W['uniacid'], 'id' => $id));
  55. if (empty($cron_new)) {
  56. return true;
  57. }
  58. if ($cron_new['status'] != $cron['status'] || $cron_new['lastruntime'] != $cron['lastruntime'] || $cron_new['nextruntime'] != $cron['nextruntime']) {
  59. load()->model('cloud');
  60. $cron_new['id'] = $cron_new['cloudid'];
  61. $status = cloud_cron_update($cron_new);
  62. if (is_error($status)) {
  63. return $status;
  64. }
  65. }
  66. }
  67. return true;
  68. }
  69. function cron_setnexttime($cron) {
  70. if (empty($cron)) {
  71. return false;
  72. }
  73. if (1 == $cron['type']) {
  74. pdo_update('core_cron', array('status' => 0, 'lastruntime' => TIMESTAMP, 'nextruntime' => TIMESTAMP), array('id' => $cron['id']));
  75. return true;
  76. }
  77. if (!empty($cron['minute'])) {
  78. $cron['minute'] = explode("\t", $cron['minute']);
  79. }
  80. list($yearnow, $monthnow, $daynow, $weekdaynow, $hournow, $minutenow) = explode('-', date('Y-m-d-w-H-i', TIMESTAMP));
  81. if ($cron['weekday'] == -1) {
  82. if ($cron['day'] == -1) {
  83. $firstday = $daynow;
  84. $secondday = $daynow + 1;
  85. } else {
  86. $firstday = $cron['day'];
  87. $secondday = $cron['day'] + date('t', TIMESTAMP);
  88. }
  89. } else {
  90. $firstday = $daynow + ($cron['weekday'] - $weekdaynow);
  91. $secondday = $firstday + 7;
  92. }
  93. if ($firstday < $daynow) {
  94. $firstday = $secondday;
  95. }
  96. if ($firstday == $daynow) {
  97. $todaytime = cron_todaynextrun($cron);
  98. if ($todaytime['hour'] == -1 && $todaytime['minute'] == -1) {
  99. $cron['day'] = $secondday;
  100. $nexttime = cron_todaynextrun($cron, 0, -1);
  101. $cron['hour'] = $nexttime['hour'];
  102. $cron['minute'] = $nexttime['minute'];
  103. } else {
  104. $cron['day'] = $firstday;
  105. $cron['hour'] = $todaytime['hour'];
  106. $cron['minute'] = $todaytime['minute'];
  107. }
  108. } else {
  109. $cron['day'] = $firstday;
  110. $nexttime = cron_todaynextrun($cron, 0, -1);
  111. $cron['hour'] = $nexttime['hour'];
  112. $cron['minute'] = $nexttime['minute'];
  113. }
  114. $nextrun = mktime($cron['hour'], $cron['minute'] > 0 ? $cron['minute'] : 0, 0, $monthnow, $cron['day'], $yearnow);
  115. $data = array('lastruntime' => TIMESTAMP, 'nextruntime' => $nextrun);
  116. if ($nextrun <= TIMESTAMP) {
  117. $data['status'] = 0;
  118. }
  119. pdo_update('core_cron', $data, array('id' => $cron['id']));
  120. return true;
  121. }
  122. function cron_todaynextrun($cron, $hour = -2, $minute = -2) {
  123. $hour = $hour == -2 ? date('H', TIMESTAMP) : $hour;
  124. $minute = $minute == -2 ? date('i', TIMESTAMP) : $minute;
  125. $nexttime = array();
  126. if ($cron['hour'] == -1 && !$cron['minute']) {
  127. $nexttime['hour'] = $hour + 1;
  128. $nexttime['minute'] = 0;
  129. } elseif ($cron['hour'] == -1 && '' != $cron['minute']) {
  130. $nexttime['hour'] = $hour;
  131. if (false === ($nextminute = cron_nextminute($cron['minute'], $minute))) {
  132. ++$nexttime['hour'];
  133. $nextminute = $cron['minute'][0];
  134. }
  135. $nexttime['minute'] = $nextminute;
  136. } elseif ($cron['hour'] != -1 && !$cron['minute']) {
  137. if ($cron['hour'] <= $hour) {
  138. $nexttime['hour'] = $nexttime['minute'] = -1;
  139. } else {
  140. $nexttime['hour'] = $cron['hour'];
  141. $nexttime['minute'] = 0;
  142. }
  143. } elseif ($cron['hour'] != -1 && '' != $cron['minute']) {
  144. $nextminute = cron_nextminute($cron['minute'], $minute);
  145. if ($cron['hour'] < $hour || ($cron['hour'] == $hour && false === $nextminute)) {
  146. $nexttime['hour'] = -1;
  147. $nexttime['minute'] = -1;
  148. } else {
  149. $nexttime['hour'] = $cron['hour'];
  150. $nexttime['minute'] = $nextminute;
  151. }
  152. }
  153. return $nexttime;
  154. }
  155. function cron_nextminute($nextminutes, $minutenow) {
  156. foreach ($nextminutes as $nextminute) {
  157. if ($nextminute > $minutenow) {
  158. return $nextminute;
  159. }
  160. }
  161. return false;
  162. }
  163. function cron_add($data) {
  164. global $_W;
  165. load()->model('cloud');
  166. if (empty($data['uniacid'])) {
  167. $data['uniacid'] = $_W['uniacid'];
  168. }
  169. if (empty($data['name'])) {
  170. return error(-1, '任务名称不能为空');
  171. }
  172. if (empty($data['filename'])) {
  173. return error(-1, '任务脚本不能为空');
  174. }
  175. if (empty($data['module'])) {
  176. return error(-1, '任务所属模块不能为空');
  177. }
  178. if (empty($data['type']) || !in_array($data['type'], array(1, 2))) {
  179. return error(-1, '任务的类型不能为空');
  180. }
  181. if (1 == $data['type'] && $data['lastruntime'] <= TIMESTAMP) {
  182. return error(-1, '定时任务的执行时间不能小于当前时间');
  183. } else {
  184. $data['nextruntime'] = $data['lastruntime'];
  185. }
  186. $data['day'] = intval($data['weekday']) == -1 ? intval($data['day']) : -1;
  187. $data['weekday'] = intval($data['weekday']);
  188. $data['hour'] = intval($data['hour']);
  189. $data['module'] = trim($data['module']);
  190. $data['minute'] = str_replace(',', ',', $data['minute']);
  191. if (false !== strpos($data['minute'], ',')) {
  192. $minutenew = explode(',', $data['minute']);
  193. foreach ($minutenew as $key => $val) {
  194. $minutenew[$key] = $val = intval($val);
  195. if ($val < 0 || $val > 59) {
  196. unset($minutenew[$key]);
  197. }
  198. }
  199. $minutenew = array_slice(array_unique($minutenew), 0, 2);
  200. $minutenew = implode("\t", $minutenew);
  201. } else {
  202. $minutenew = intval($data['minute']);
  203. $minutenew = $minutenew >= 0 && $minutenew < 60 ? $minutenew : '';
  204. }
  205. $data['minute'] = $minutenew;
  206. $data['createtime'] = TIMESTAMP;
  207. $data = array_elements(array('uniacid', 'name', 'filename', 'module', 'type', 'status', 'day', 'weekday', 'hour', 'minute', 'status', 'lastruntime', 'nextruntime', 'createtime', 'extra'), $data);
  208. $status = cloud_cron_create($data);
  209. if (is_error($status)) {
  210. return $status;
  211. }
  212. $data['cloudid'] = $status['cron_id'];
  213. pdo_insert('core_cron', $data);
  214. return pdo_insertid();
  215. }
  216. function cron_delete($ids) {
  217. global $_W;
  218. load()->model('cloud');
  219. if (empty($ids) || !is_array($ids)) {
  220. return true;
  221. }
  222. $ids = safe_gpc_array($ids);
  223. $corns = pdo_getall('core_cron', array('uniacid' => $_W['uniacid'], 'id' => $ids), array(), 'cloudid');
  224. $cloudid = array_keys($corns);
  225. if (!empty($cloudid)) {
  226. $status = cloud_cron_remove($cloudid);
  227. if (is_error($status)) {
  228. return $status;
  229. }
  230. pdo_delete('core_cron', array('uniacid' => $_W['uniacid'], 'id' => $ids));
  231. }
  232. return true;
  233. }