PageRenderTime 45ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/e107_admin/cron.php

https://github.com/CasperGemini/e107
PHP | 1270 lines | 507 code | 153 blank | 610 comment | 64 complexity | 44169028282d9b63fdda27ab13f49824 MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. /*
  3. * e107 website system
  4. *
  5. * Copyright (C) 2008-2012 e107 Inc (e107.org)
  6. * Released under the terms and conditions of the
  7. * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
  8. *
  9. * Cron Administration
  10. *
  11. * $URL$
  12. * $Id$
  13. *
  14. */
  15. /**
  16. *
  17. * @package e107
  18. * @subpackage admin
  19. * @version $Id$
  20. * Admin-related functions for cron (Scheduler) management
  21. */
  22. require_once('../class2.php');
  23. if (!getperms('U'))
  24. {
  25. header('location:'.e_BASE.'index.php');
  26. exit;
  27. }
  28. include_lan(e_LANGUAGEDIR.e_LANGUAGE.'/admin/lan_'.e_PAGE);
  29. class cron_admin extends e_admin_dispatcher
  30. {
  31. protected $modes = array(
  32. 'main' => array(
  33. 'controller' => 'cron_admin_ui',
  34. 'path' => null,
  35. 'ui' => 'cron_admin_form_ui',
  36. 'uipath' => null
  37. )
  38. );
  39. protected $adminMenu = array(
  40. 'main/list' => array('caption'=> LAN_CRON_M_01, 'perm' => '0'),
  41. 'main/refresh' => array('caption'=> LAN_CRON_M_02, 'perm' => '0','url'=>'cron.php'),
  42. // 'main/prefs' => array('caption'=> 'Settings', 'perm' => '0'),
  43. // 'main/custom' => array('caption'=> 'Custom Page', 'perm' => '0')
  44. );
  45. protected $adminMenuAliases = array(
  46. 'main/edit' => 'main/list'
  47. );
  48. protected $menuTitle = PAGE_NAME;
  49. }
  50. class cron_admin_ui extends e_admin_ui
  51. {
  52. protected $pluginTitle = PAGE_NAME;
  53. protected $pluginName = 'core';
  54. protected $table = "cron";
  55. protected $pid = "cron_id";
  56. protected $listOrder = 'cron_category desc'; // Show 'upgrades' on first page.
  57. protected $perPage = 10;
  58. protected $batchDelete = TRUE;
  59. protected $fields = array(
  60. 'checkboxes' => array('title'=> '', 'type' => null, 'width' =>'5%', 'forced'=> TRUE, 'thclass'=>'center', 'class'=>'center'),
  61. 'cron_id' => array('title'=> LAN_ID, 'type' => 'number', 'width' =>'5%', 'forced'=> FALSE, 'nolist'=>TRUE),
  62. 'cron_category' => array('title'=> LAN_CATEGORY, 'type' => 'method', 'data' => 'str', 'width'=>'auto','readonly' => 1, 'thclass' => '', 'batch' => TRUE, 'filter'=>TRUE),
  63. 'cron_name' => array('title'=> LAN_CRON_1, 'type' => 'text', 'width' => 'auto', 'readonly' => 1),
  64. 'cron_description' => array('title'=> LAN_DESCRIPTION, 'type' => 'text', 'width' => '35%', 'readonly' => 1),
  65. 'cron_function' => array('title'=> LAN_CRON_2, 'type' => 'text', 'width' => 'auto', 'thclass' => 'left first', 'readonly' => 1),
  66. 'cron_tab' => array('title'=> LAN_CRON_3, 'type' => 'method', 'width' => 'auto'), // Display name
  67. 'cron_lastrun' => array('title'=> LAN_CRON_4, 'type' => 'datestamp', 'data' => 'int', 'width' => 'auto', 'readonly' => 2),
  68. 'cron_active' => array('title'=> LAN_CRON_5, 'type' => 'boolean', 'data'=> 'int', 'thclass' => 'center', 'class'=>'center', 'filter' => true, 'batch' => true, 'width' => 'auto'),
  69. 'options' => array('title'=> LAN_OPTIONS, 'type' => 'method', 'data'=> null, 'noedit'=>TRUE, 'forced'=>TRUE, 'width' => '10%', 'thclass' => 'center last', 'class' => 'center')
  70. );
  71. // public function beforeCreate($new_data)
  72. // {
  73. // }
  74. private $curCrons = array();
  75. private $activeCrons = 0;
  76. function init()
  77. {
  78. $pref = e107::getPref();
  79. $sql = e107::getDb();
  80. if(vartrue($_POST['cron_execute']))
  81. {
  82. $executeID = key($_POST['cron_execute']);
  83. $this->cronExecute($executeID);
  84. }
  85. if (!vartrue(e107::getPref('e_cron_pwd')) || varset($_POST['generate_pwd']))
  86. {
  87. $pwd = $this->setCronPwd();
  88. }
  89. $sql->gen("SELECT cron_function,cron_active FROM #cron ");
  90. while($row = $sql->fetch(MYSQL_ASSOC))
  91. {
  92. $this->curCrons[] = $row['cron_function'];
  93. if($row['cron_active']==1)
  94. {
  95. $this->activeCrons++;
  96. }
  97. }
  98. $this->lastRefresh();
  99. // Import Core and Plugin e_cron data
  100. $cronDefaults['_system'] = array(
  101. 0 => array(
  102. 'name' => LAN_CRON_01_1,
  103. 'function' => 'sendEmail',
  104. 'category' => 'mail',
  105. 'description' => str_replace("[eml]",$pref['siteadminemail'],LAN_CRON_01_2) ."<br />". LAN_CRON_01_3
  106. ),
  107. 1 => array(
  108. 'name' => LAN_CRON_02_1,
  109. 'category' => 'mail',
  110. 'function' => 'procEmailQueue',
  111. 'description' => LAN_CRON_02_2
  112. ),
  113. 2 => array(
  114. 'name' => LAN_CRON_03_1,
  115. 'category' => 'mail',
  116. 'function' => 'procEmailBounce',
  117. 'description' => LAN_CRON_03_2
  118. // 'available' => vartrue($pref['mail_bounce_auto'])
  119. ),
  120. 3 => array(
  121. 'name' => LAN_CRON_04_1,
  122. 'category' => 'user',
  123. 'function' => 'procBanRetrigger',
  124. 'description' => LAN_CRON_04_2 ."<br />". LAN_CRON_04_3,
  125. 'available' => e107::getPref('ban_retrigger')
  126. ),
  127. 4 => array(
  128. 'name' => LAN_CRON_05_1,
  129. 'category' => 'backup',
  130. 'function' => 'dbBackup',
  131. 'description' => LAN_CRON_05_2 .' '.e_SYSTEM.'backups/'
  132. // 'available' => e107::getPref('ban_retrigger')
  133. ),
  134. 5 => array(
  135. 'name' => LAN_CRON_06_1,
  136. 'category' => 'user',
  137. 'function' => 'procBanRetrigger',
  138. 'description' => LAN_CRON_06_2 ."<br />". LAN_CRON_06_3,
  139. // 'available' => e107::getPref('ban_retrigger')
  140. ),
  141. 6 => array(
  142. 'name' => LAN_CRON_20_1,
  143. 'category' => 'update',
  144. 'function' => 'checkCoreUpdate',
  145. 'description' => LAN_CRON_20_2 ."<br />". LAN_CRON_20_3,
  146. // 'available' => e107::getPref('ban_retrigger')
  147. ),
  148. );
  149. if(is_dir(e_BASE.".git"))
  150. {
  151. $cronDefaults['_system'][7] = array(
  152. 'name' => "Update this Git repository", //TODO LAN
  153. 'category' => 'update',
  154. 'function' => 'gitrepo',
  155. 'description' => "Update this e107 installation with the very latest files from github.<br />Recommended for developers only.<br /><span class='label label-warning'>Warning!</span> May cause site instability!", //TODO LAN
  156. // 'available' => e107::getPref('ban_retrigger')
  157. );
  158. }
  159. if(!vartrue($_GET['action']) || $_GET['action'] == 'refresh')
  160. {
  161. $this->cronImport($cronDefaults); // import Core Crons (if missing)
  162. $this->cronImport(e107::getAddonConfig('e_cron')); // Import plugin Crons
  163. $this->cronImportLegacy(); // Import Legacy Cron Tab Settings
  164. }
  165. }
  166. /**
  167. * Import Cron Settings into Database.
  168. */
  169. public function cronImport($new_cron = FALSE)
  170. {
  171. if(!$new_cron)
  172. {
  173. return;
  174. }
  175. foreach($new_cron as $class => $ecron)
  176. {
  177. foreach($ecron as $val)
  178. {
  179. $insert = array(
  180. 'cron_id' => 0,
  181. 'cron_name' => $val['name'],
  182. 'cron_category' => $val['category'],
  183. 'cron_description' => $val['description'],
  184. 'cron_function' => $class."::".$val['function'],
  185. 'cron_tab' => '* * * * *',
  186. 'cron_active' => 0,
  187. );
  188. $this->cronInsert($insert);
  189. }
  190. }
  191. }
  192. /**
  193. * Import Legacy e_cron_pref settings.
  194. */
  195. public function cronImportLegacy()
  196. {
  197. global $pref;
  198. $cronPref = e107::getPref('e_cron_pref');
  199. if(!is_array($cronPref))
  200. {
  201. return;
  202. }
  203. foreach($cronPref as $val)
  204. {
  205. $update = array(
  206. 'cron_tab' => $val['tab'],
  207. 'cron_active' => $val['active'],
  208. 'cron_function' => $val['class']."::".$val['function'],
  209. 'WHERE' => "cron_function = '".$val['class']."::".$val['function']."'"
  210. );
  211. $this->cronUpdate($update);
  212. }
  213. e107::getConfig()->remove('e_cron_pref')->save();
  214. }
  215. // Insert a Cron.
  216. public function cronInsert($insert)
  217. {
  218. // print_a($insert);
  219. // return;
  220. //
  221. $sql = e107::getDb();
  222. if(in_array($insert['cron_function'],$this->curCrons))
  223. {
  224. return;
  225. }
  226. if(!$sql->insert('cron',$insert))
  227. {
  228. e107::getMessage()->add(LAN_CRON_6, E_MESSAGE_ERROR);
  229. }
  230. else
  231. {
  232. e107::getMessage()->add(LAN_CRON_8.": ".$insert['cron_function'], E_MESSAGE_INFO);
  233. }
  234. }
  235. /**
  236. * Update cron timing - from legacy Pref.
  237. */
  238. public function cronUpdate($insert)
  239. {
  240. // print_a($insert);
  241. // return;
  242. $sql = e107::getDb();
  243. $cron_function = $insert['cron_function'];
  244. unset($insert['cron_function']);
  245. if($sql->update('cron',$insert)===FALSE)
  246. {
  247. e107::getMessage()->add(LAN_CRON_7, E_MESSAGE_ERROR);
  248. }
  249. else
  250. {
  251. e107::getMessage()->add(LAN_CRON_8.$cron_function, E_MESSAGE_INFO);
  252. }
  253. }
  254. // Process _POST before saving.
  255. public function beforeUpdate($new_data, $old_data, $id)
  256. {
  257. $new_data['cron_tab'] = implode(" ", $new_data['tab']);
  258. return $new_data;
  259. }
  260. function setCronPwd()
  261. {
  262. //global $pref;
  263. $userMethods = e107::getUserSession();
  264. $newpwd = $userMethods->generateRandomString('*^*#.**^*');
  265. $newpwd = sha1($newpwd.time());
  266. e107::getConfig()->set('e_cron_pwd', $newpwd)->save(false);
  267. return true;
  268. }
  269. function lastRefresh()
  270. {
  271. $pref = e107::getPref();
  272. $mes = e107::getMessage();
  273. $frm = e107::getForm();
  274. e107::getCache()->CachePageMD5 = '_';
  275. $lastload = e107::getCache()->retrieve('cronLastLoad', FALSE, TRUE, TRUE);
  276. $ago = (time() - $lastload);
  277. $active = ($ago < 901) ? TRUE : FALSE;
  278. $status = ($active) ? LAN_ENABLED : LAN_DISABLED; // "Enabled" : "Offline";
  279. $mins = floor($ago / 60);
  280. $secs = $ago % 60;
  281. $srch = array("[x]","[y]");
  282. $repl = array($mins,$secs);
  283. $lastRun = ($mins) ? str_replace($srch,$repl,LAN_CRON_9) : str_replace($srch,$repl,LAN_CRON_10); // FIX: check syntax
  284. $lastRefresh = ($ago < 10000) ? $lastRun : LAN_NEVER;
  285. $mes->addInfo(LAN_STATUS.": <b>".$status."</b>");
  286. $mes->addInfo(LAN_CRON_11.": <b>".$this->activeCrons."</b>");
  287. $mes->addInfo(LAN_CRON_12.": ".$lastRefresh."<br /><br />");
  288. //FIXME: for Windows, the is_executable() function only checks the file
  289. // extensions of exe, com, bat and cmd.
  290. $isWin = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
  291. $actualPerm = substr(decoct(fileperms(e_BASE."cron.php")),3);
  292. if($isWin)
  293. {
  294. $mes->addWarning(LAN_CRON_13);
  295. }
  296. if (!$isWin && $actualPerm != 755) // is_executable() is not reliable.
  297. {
  298. $mes->addWarning(LAN_CRON_14);
  299. }
  300. elseif (!$active) // show instructions
  301. {
  302. $setpwd_message = $frm->open("generate")."<small>"
  303. .LAN_CRON_15.":</small><br /><pre style='color:black'>".rtrim($_SERVER['DOCUMENT_ROOT'], '/').e_HTTP."cron.php ".$pref['e_cron_pwd'];
  304. $setpwd_message .= "</pre><small>". LAN_CRON_16."</small>";
  305. if(e_DOMAIN && file_exists("/usr/local/cpanel/version"))
  306. {
  307. $setpwd_message .= "<div style='margin-top:10px'><a rel='external' class='btn btn-primary' href='".e_HTTP."cpanel'>Go to cPanel</a></div>";
  308. }
  309. $setpwd_message .= "<br /><br />".$frm->admin_button('generate_pwd', 1, 'delete', 'Generate new cron password',array('class'=>'btn btn-small'));
  310. $setpwd_message .= $frm->close();
  311. $mes->add($setpwd_message, E_MESSAGE_INFO);
  312. }
  313. }
  314. function cronExecute($cron_id)
  315. {
  316. $sql = e107::getDb();
  317. if($sql->db_Select("cron","cron_name,cron_function","cron_id = ".intval($cron_id)))
  318. {
  319. $row = $sql->db_Fetch(MYSQL_ASSOC);
  320. $class_func = $row['cron_function'];
  321. $cron_name = $row['cron_name'];
  322. }
  323. if(!$class_func)
  324. {
  325. return;
  326. }
  327. list($class_name, $method_name) = explode("::", $class_func);
  328. $mes = e107::getMessage();
  329. $taskName = $class_name;
  330. if ($class_name == '_system')
  331. {
  332. require_once(e_HANDLER.'cron_class.php');
  333. }
  334. else
  335. {
  336. require_once(e_PLUGIN.$class_name.'/e_cron.php');
  337. }
  338. $class_name .= '_cron';
  339. $status = $this->cronExecuteMethod($class_name, $method_name) ? E_MESSAGE_SUCCESS : E_MESSAGE_ERROR;
  340. $mes->add(LAN_CRON_RUNNING.":<b>".$cron_name."</b>", $status);
  341. }
  342. function cronExecuteMethod($class_name, $method_name, $return = 'boolean')
  343. {
  344. $mes = e107::getMessage();
  345. if (class_exists($class_name))
  346. {
  347. $obj = new $class_name;
  348. if (method_exists($obj, $method_name))
  349. {
  350. $mes->add("Executing config function <b>".$class_name." : ".$method_name."()</b>", E_MESSAGE_DEBUG);
  351. if ($return == 'boolean')
  352. {
  353. call_user_func(array($obj, $method_name));
  354. return TRUE;
  355. }
  356. else
  357. {
  358. return call_user_func(array($obj, $method_name));
  359. }
  360. }
  361. else
  362. {
  363. $mes->add("Config function <b>".$method_name."()</b> NOT found.", E_MESSAGE_DEBUG);
  364. }
  365. }
  366. return FALSE;
  367. }
  368. }
  369. class cron_admin_form_ui extends e_admin_form_ui
  370. {
  371. var $min_options = array(
  372. "*" => LAN_CRON_30,
  373. "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58" => LAN_CRON_31,
  374. "0,5,10,15,20,25,30,35,40,45,50,55" => LAN_CRON_32,
  375. "0,10,20,30,40,50" => LAN_CRON_33,
  376. "0,15,30,45" => LAN_CRON_34,
  377. "0,30" => LAN_CRON_35
  378. );
  379. var $hour_options = array(
  380. "*" => LAN_CRON_36,
  381. "0,2,4,6,8,10,12,14,16,18,20,22" => LAN_CRON_37,
  382. "0,3,6,9,12,15,18,21" => LAN_CRON_38,
  383. "0,6,12,18" => LAN_CRON_39
  384. );
  385. var $cronCategories = array(
  386. 'backup' => LAN_CRON_BACKUP,
  387. 'content' => ADLAN_CL_3,
  388. 'log' => LAN_CRON_LOGGING,
  389. 'mail' => ADLAN_136,
  390. 'notify' => ADLAN_149,
  391. 'user' => LAN_USER,
  392. 'plugin' => ADLAN_CL_7,
  393. 'update' => LAN_UPDATE
  394. );
  395. /**
  396. * Render cron_tab field
  397. */
  398. function cron_tab($curVal,$mode)
  399. {
  400. if($mode == 'read')
  401. {
  402. $sep = array();
  403. list($min, $hour, $day, $month, $weekday) = explode(" ", $curVal);
  404. $text = (isset($this->min_options[$min])) ? $this->min_options[$min] : LAN_CRON_50 ." ". $min; // Minute(s)
  405. $text .= "<br />";
  406. $text .= (isset($this->hour_options[$hour])) ? $this->hour_options[$hour] : LAN_CRON_51 ." ". $hour; // Hour(s)
  407. $text .= "<br />";
  408. $text .= ($day != '*') ? LAN_CRON_52 ." ". $day : LAN_CRON_40; // Day(s)
  409. $text .= "<br />";
  410. $text .= ($month != '*') ? LAN_CRON_53 ." ". strftime("%B", mktime(00, 00, 00, $month, 1, 2000)) : LAN_CRON_41; // Month(s)
  411. $text .= "<br />";
  412. $text .= ($weekday != '*') ? LAN_CRON_54 ." ". strftime("%A", mktime(00, 00, 00, 5, $weekday, 2000)) : LAN_CRON_42; // Weekday(s)
  413. return "<a class='e-tip' href=''>".ADMIN_INFO_ICON."</a>
  414. <div class='field-help'>".$text."</div>";
  415. return $text;
  416. }
  417. if($mode == 'write')
  418. {
  419. return $this->editTab($curVal);
  420. }
  421. if($mode == 'filter') // Custom Filter List
  422. {
  423. return;
  424. }
  425. if($mode == 'batch')
  426. {
  427. return;
  428. }
  429. }
  430. function cron_category($curVal,$mode)
  431. {
  432. if($mode == 'read')
  433. {
  434. return isset($this->cronCategories[$curVal]) ? $this->cronCategories[$curVal] : "";
  435. }
  436. if($mode == 'write')
  437. {
  438. return isset($this->cronCategories[$curVal]) ? $this->cronCategories[$curVal] : "";
  439. }
  440. if($mode == 'filter')
  441. {
  442. return $this->cronCategories;
  443. }
  444. if($mode == 'batch')
  445. {
  446. return;
  447. }
  448. }
  449. // Override the default Options field.
  450. function options($parms, $value, $id, $attributes)
  451. {
  452. if($attributes['mode'] == 'read')
  453. {
  454. $text = $this->renderValue('options',$value,'',$id);
  455. $text .= $this->submit_image('cron_execute['.$id.']', 1, 'execute', 'Execute');
  456. return $text;
  457. }
  458. }
  459. function editTab($curVal)
  460. {
  461. $sep = array();
  462. list($sep['minute'], $sep['hour'], $sep['day'], $sep['month'], $sep['weekday']) = explode(" ", $curVal);
  463. foreach ($sep as $key => $value)
  464. {
  465. if ($value == "")
  466. {
  467. $sep[$key] = "*";
  468. }
  469. }
  470. $minute = explode(",", $sep['minute']);
  471. $hour = explode(",", $sep['hour']);
  472. $day = explode(",", $sep['day']);
  473. $month = explode(",", $sep['month']);
  474. $weekday = explode(",", $sep['weekday']);
  475. $text = "
  476. <select style='height:120px' multiple='multiple' name='tab[minute]'>
  477. \n";
  478. foreach ($this->min_options as $key => $val)
  479. {
  480. if ($sep['minute'] == $key)
  481. {
  482. $sel = "selected='selected'";
  483. $minute = array();
  484. }
  485. else
  486. {
  487. $sel = "";
  488. }
  489. $text .= "
  490. <option value='$key' $sel>".$val."</option>\n";
  491. }
  492. for ($i = 0; $i <= 59; $i++)
  493. {
  494. $sel = (in_array(strval($i), $minute)) ? "selected='selected'" : "";
  495. $text .= "
  496. <option value='$i' $sel>".$i."</option>\n";
  497. }
  498. $text .= "
  499. </select>
  500. <select style='height:120px' multiple='multiple' name='tab[hour]'>
  501. \n";
  502. foreach ($this->hour_options as $key => $val)
  503. {
  504. if ($sep['hour'] == $key)
  505. {
  506. $sel = "selected='selected'";
  507. $hour = array();
  508. }
  509. else
  510. {
  511. $sel ="";
  512. }
  513. $text .= "<option value='$key' $sel>".$val."</option>\n";
  514. }
  515. for ($i = 0; $i <= 23; $i++)
  516. {
  517. $sel = (in_array(strval($i), $hour)) ? "selected='selected'" : "";
  518. $diz = mktime($i, 00, 00, 1, 1, 2000);
  519. $text .= "<option value='$i' $sel>".$i." - ".date("g A", $diz)."</option>\n";
  520. }
  521. $text .= "</select>
  522. <select style='height:120px' multiple='multiple' name='tab[day]'>\n";
  523. $sel_day = ($day[0] == "*") ? "selected='selected'" : "";
  524. $text .= "<option value='*' {$sel_day}>".LAN_CRON_40."</option>\n"; // Every Day
  525. for ($i = 1; $i <= 31; $i++)
  526. {
  527. $sel = (in_array($i, $day)) ? "selected='selected'" : "";
  528. $text .= "<option value='$i' $sel>".$i."</option>\n";
  529. }
  530. $text .= "</select>
  531. <select style='height:120px' multiple='multiple' name='tab[month]'>\n";
  532. $sel_month = ($month[0] == "*") ? "selected='selected'" : "";
  533. $text .= "<option value='*' $sel_month>".LAN_CRON_41."</option>\n"; // Every Month
  534. for ($i = 1; $i <= 12; $i++)
  535. {
  536. $sel = (in_array($i, $month)) ? "selected='selected'" : "";
  537. $diz = mktime(00, 00, 00, $i, 1, 2000);
  538. $text .= "<option value='$i' $sel>".strftime("%B", $diz)."</option>\n";
  539. }
  540. $text .= "</select>
  541. <select style='height:120px' multiple='multiple' name='tab[weekday]'>\n";
  542. $sel_weekday = ($weekday[0] == "*") ? "selected='selected'" : "";
  543. $text .= "<option value='*' $sel_weekday>".LAN_CRON_42."</option>\n"; // Every Week Day.
  544. for ($i = 0; $i <= 6; $i++)
  545. {
  546. $sel = (in_array(strval($i), $weekday)) ? "selected='selected'" : "";
  547. $text .= "<option value='$i' $sel>".strftime("%A", mktime(00, 00, 00, 5, $i, 2000))."</option>\n";
  548. }
  549. $text .= "</select>
  550. ";
  551. return $text;
  552. }
  553. }
  554. new cron_admin();
  555. $e_sub_cat = 'cron';
  556. require_once('auth.php');
  557. e107::getAdminUI()->runPage();
  558. $frm = e107::getForm();
  559. // $cron = new cron();
  560. require_once(e_ADMIN.'footer.php');
  561. exit;
  562. /*
  563. class cron
  564. {
  565. protected $coreCrons = array();
  566. protected $cronAction;
  567. protected $e_cron = array();
  568. public function __construct()
  569. {
  570. $pref = e107::getPref();
  571. $mes = e107::getMessage();
  572. $this->cronAction = e_QUERY;
  573. // The 'available' flag only gives the option to configure the cron if the underlying feature is enabled
  574. $this->coreCrons['_system'] = array(
  575. 0 => array('name' => 'Test Email', 'function' => 'sendEmail', 'description' => 'Send a test email to '.$pref['siteadminemail'].'<br />Recommended to test the scheduling system.'),
  576. 1 => array('name' => 'Mail Queue', 'function' => 'procEmailQueue', 'description' => 'Process mail queue'),
  577. 2 => array('name' => 'Mail Bounce Check', 'function' => 'procEmailBounce', 'description' => 'Check for bounced emails', 'available' => vartrue($pref['mail_bounce_auto'])),
  578. // 1 => array('name'=>'User Purge', 'function' => 'userPurge', 'description'=>'Purge Unactivated Users'),
  579. // 2 => array('name'=>'User UnActivated', 'function' => 'userUnactivated', 'description'=>'Resend activation email to unactivated users.'),
  580. // 3 => array('name'=>'News Sticky', 'function' => 'newsPurge', 'description'=>'Remove Sticky News Items')
  581. );
  582. if (!vartrue($pref['e_cron_pwd']))
  583. {
  584. $pwd = $this->setCronPwd();
  585. }
  586. if (isset($_POST['submit']))
  587. {
  588. $this->cronSave();
  589. }
  590. $this->lastRefresh();
  591. $this->cronLoad();
  592. if (isset($_POST['save_prefs']))
  593. {
  594. $this->cronSavePrefs();
  595. }
  596. if (isset($_POST['execute']))
  597. {
  598. $class_func = key($_POST['execute']);
  599. $this->cronExecute($class_func);
  600. }
  601. // Set Core Cron Options.
  602. // These core functions need to be put into e_BASE/cron.php ie. news_purge()
  603. if ($this->cronAction == "" || $this->cronAction == "main")
  604. {
  605. $this->cronRenderPage();
  606. }
  607. if ($this->cronAction == "pref")
  608. {
  609. $this->cronRenderPrefs();
  610. }
  611. }
  612. function lastRefresh()
  613. {
  614. $pref = e107::getPref();
  615. e107::getCache()->CachePageMD5 = '_';
  616. $lastload = e107::getCache()->retrieve('cronLastLoad', FALSE, TRUE, TRUE);
  617. $mes = e107::getMessage();
  618. $ago = (time() - $lastload);
  619. $active = ($ago < 901) ? TRUE : FALSE;
  620. $status = ($active) ? LAN_ENABLED : LAN_DISABLED; // "Enabled" : "Offline";
  621. $mins = floor($ago / 60);
  622. $secs = $ago % 60;
  623. $lastRun = ($mins) ? $mins." minutes and ".$secs." seconds ago." : $secs." seconds ago.";
  624. $lastRefresh = ($ago < 10000) ? $lastRun : 'Never';
  625. $mes->add("Status: <b>".$status."</b>", E_MESSAGE_INFO);
  626. // print_a($pref['e_cron_pref']);
  627. if ($pref['e_cron_pref']) // grab cron
  628. {
  629. foreach ($pref['e_cron_pref'] as $func => $cron)
  630. {
  631. if ($cron['active'] == 1)
  632. {
  633. $list[$func] = $cron;
  634. }
  635. }
  636. }
  637. $mes->add("Active Crons: <b>".count($list)."</b>", E_MESSAGE_INFO);
  638. $mes->add("Last cron refresh: ".$lastRefresh, E_MESSAGE_INFO);
  639. //FIXME: for Windows, the is_executable() function only checks the file
  640. // extensions of exe, com, bat and cmd.
  641. $actualPerms = fileperms(e_BASE."cron.php");
  642. if (!is_executable(realpath(e_BASE."cron.php")))
  643. {
  644. $mes->add("Please CHMOD /cron.php to 755 ", E_MESSAGE_WARNING);
  645. }
  646. //elseif (!$active) - always show instructions
  647. {
  648. $setpwd_message = "Use the following Cron Command: <b style='color:black'>".$_SERVER['DOCUMENT_ROOT'].e_HTTP."cron.php ".$pref['e_cron_pwd']."</b><br />
  649. Using your server control panel (eg. cPanel,Plesk etc.) please create a crontab to run this command on your server every minute.";
  650. $mes->add($setpwd_message, E_MESSAGE_INFO);
  651. }
  652. }
  653. function cronName($classname, $method)
  654. {
  655. $tp = e107::getParser();
  656. foreach ($this->e_cron as $class => $val)
  657. {
  658. if ($class == $classname)
  659. {
  660. foreach ($val as $func)
  661. {
  662. if ($func['function'] == $method)
  663. {
  664. return $tp->toHtml($func['name']);
  665. }
  666. }
  667. }
  668. }
  669. }
  670. function cronExecute($class_func)
  671. {
  672. //TODO LANs
  673. list($class_name, $method_name) = explode("__", $class_func);
  674. $mes = e107::getMessage();
  675. $taskName = $class_name;
  676. if ($class_name == '_system')
  677. {
  678. require_once(e_HANDLER.'cron_class.php');
  679. }
  680. else
  681. {
  682. require_once(e_PLUGIN.$class_name.'/e_cron.php');
  683. }
  684. $class_name .= '_cron';
  685. $status = $this->cronExecuteMethod($class_name, $method_name) ? E_MESSAGE_SUCCESS : E_MESSAGE_ERROR;
  686. $mes->add("Running <b>".$this->cronName($taskName, $method_name)."</b>", $status);
  687. }
  688. function cronSavePref()
  689. {
  690. // Store the USERID with the password.
  691. // This way only the one password is needed, and the user login can be looked up in e_base/cron.php
  692. }
  693. function cronSave()
  694. {
  695. global $pref;
  696. $mes = e107::getMessage();
  697. $activeCount = 0;
  698. foreach ($_POST['cron'] as $key => $val)
  699. {
  700. if (!$val['active'])
  701. {
  702. $val['active'] = 0;
  703. }
  704. else
  705. {
  706. $activeCount++;
  707. }
  708. $t['minute'] = implode(",", $_POST['tab'][$key]['minute']);
  709. $t['hour'] = implode(",", $_POST['tab'][$key]['hour']);
  710. $t['day'] = implode(",", $_POST['tab'][$key]['day']);
  711. $t['month'] = implode(",", $_POST['tab'][$key]['month']);
  712. $t['weekday'] = implode(",", $_POST['tab'][$key]['weekday']);
  713. $val['tab'] = implode(" ", $t);
  714. $tabs .= $val['tab']."<br />";
  715. list($class, $func) = explode("__", $key);
  716. $val['function'] = $func;
  717. $val['class'] = $class;
  718. $val['path'] = $class;
  719. $cron[$key] = $val;
  720. }
  721. $pref['e_cron_pref'] = $cron;
  722. if (!vartrue($pref['e_cron_pwd']) || varset($_POST['generate_pwd']))
  723. {
  724. $pwd = $this->setCronPwd();
  725. $setpwd_message = "Use the following Cron Command:<br /><b style='color:black'>".$_SERVER['DOCUMENT_ROOT'].e_HTTP."cron.php ".$pwd."</b><br />
  726. This cron command is unique and will not be displayed again. Please copy and paste it into your webserver cron area to be run every minute (or 15 minutes) of every day.";
  727. $mes->add($setpwd_message, E_MESSAGE_WARNING);
  728. }
  729. // print_a($pref['e_cron_pref']);
  730. if (save_prefs())
  731. {
  732. $mes->add(LAN_SETSAVED, E_MESSAGE_SUCCESS);
  733. $mes->add($activeCount." Cron(s) Active", E_MESSAGE_SUCCESS);
  734. }
  735. else
  736. {
  737. $mes->add("There was a problem saving your settings.", E_MESSAGE_ERROR);
  738. }
  739. }
  740. function setCronPwd()
  741. {
  742. //global $pref;
  743. $userMethods = e107::getUserSession();
  744. $newpwd = $userMethods->generateRandomString('*^*#.**^*');
  745. $newpwd = sha1($newpwd.time());
  746. //$pref['e_cron_pwd'] = $newpwd;
  747. e107::getConfig()->set('e_cron_pwd', $newpwd)->save(false);
  748. return true;
  749. }
  750. // --------------------------------------------------------------------------
  751. function cronRenderPrefs()
  752. {
  753. //global $frm,$ns;
  754. $frm = e107::getForm();
  755. $text = "<div style='text-align:center'>
  756. <form method='post' action='"
  757. .e_SELF."' id='linkform'>
  758. <table class='table adminlist'>
  759. <tr>
  760. <td style='width:30%'>Cron Password</td>
  761. <td style='width:70%'>
  762. "
  763. .$frm->password('cron_password', '', 100)."
  764. </td>
  765. </tr>
  766. <tr style='vertical-align:top'>
  767. <td colspan='2' class='center buttons-bar'>";
  768. $text .= $frm->admin_button('save_prefs', LAN_SAVE, 'update');
  769. $text .= "</td>
  770. </tr>
  771. </table>
  772. </form>
  773. </div>";
  774. e107::getRender()->tablerender(LAN_PREFS, $text);
  775. }
  776. function cronLoad() //TODO Make a generic function to work with e_cron, e_sitelink, e_url etc.
  777. {
  778. $pref = e107::getPref();
  779. $core_cron = $this->coreCrons; // May need to check 'available' flag here
  780. $new_cron = e107::getAddonConfig('e_cron');
  781. $this->e_cron = array_merge($core_cron, $new_cron);
  782. return;
  783. }
  784. // ----------- Grab All e_cron parameters -----------------------------------
  785. function cronRenderPage()
  786. {
  787. $pref = e107::getPref();
  788. $cronpref = $pref['e_cron_pref'];
  789. $ns = e107::getRender();
  790. $frm = e107::getForm();
  791. $mes = e107::getMessage();
  792. $e_cron = $this->e_cron;
  793. // ---------------------- List All Functions -----------------------------
  794. $text = "<div style='text-align:center'>
  795. <form method='post' action='"
  796. .e_SELF."' id='cronform'>
  797. <table class='table adminlist'>
  798. <colgroup>
  799. <col />
  800. <col />
  801. <col />
  802. <col />
  803. <col />
  804. <col />
  805. <col />
  806. <col />
  807. </colgroup>
  808. <thead>
  809. <tr>
  810. <th>"
  811. .LAN_CRON_1."</th>
  812. <th>"
  813. .LAN_CRON_2."</th>
  814. <th>"
  815. .LAN_CRON_3."</th>
  816. <th>"
  817. .LAN_CRON_4."</th>
  818. <th>"
  819. .LAN_CRON_5."</th>
  820. <th>"
  821. .LAN_CRON_6."</th>
  822. <th>"
  823. .LAN_CRON_7."</th>
  824. <th>"
  825. .LAN_CRON_8."</th>
  826. <th>Run Now</th>
  827. </tr>
  828. </thead>
  829. <tbody>";
  830. foreach ($e_cron as $plug => $cfg)
  831. {
  832. foreach ($cfg as $class => $cron)
  833. {
  834. if (!isset($cron['available']) || $cron['available']) // Only display cron functions which are available
  835. {
  836. $c = $plug.'__'.$cron['function']; // class and function.
  837. $sep = array();
  838. list($sep['minute'], $sep['hour'], $sep['day'], $sep['month'], $sep['weekday']) = explode(" ", $cronpref[$c]['tab']);
  839. foreach ($sep as $key => $value)
  840. {
  841. if ($value == "")
  842. {
  843. $sep[$key] = "*";
  844. }
  845. }
  846. $minute = explode(",", $sep['minute']);
  847. $hour = explode(",", $sep['hour']);
  848. $day = explode(",", $sep['day']);
  849. $month = explode(",", $sep['month']);
  850. $weekday = explode(",", $sep['weekday']);
  851. $min_options = array(
  852. "*" => LAN_CRON_11,
  853. "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58" => LAN_CRON_12,
  854. "0,5,10,15,20,25,30,35,40,45,50,55" => LAN_CRON_13,
  855. "0,10,20,30,40,50" => LAN_CRON_14,
  856. "0,15,30,45" => LAN_CRON_10,
  857. "0,30" => LAN_CRON_15
  858. );
  859. $hour_options = array(
  860. "*" => LAN_CRON_16,
  861. "0,2,4,6,8,10,12,14,16,18,20,22" => LAN_CRON_17,
  862. "0,3,6,9,12,15,18,21" => LAN_CRON_18,
  863. "0,6,12,18" => LAN_CRON_19
  864. );
  865. $text .= "<tr>
  866. <td>"
  867. .$cron['name']."</td>
  868. <td>"
  869. .$cron['description']."</td>
  870. <td>
  871. <input type='hidden' name='cron[$c][path]' value='".$cron['path']."' />
  872. <select class='tbox' style='height:70px' multiple='multiple' name='tab[$c][minute][]'>\n";
  873. foreach ($min_options as $key => $val)
  874. {
  875. if ($sep['minute'] == $key)
  876. {
  877. $sel = "selected='selected'";
  878. $minute = array();
  879. }
  880. else
  881. {
  882. $sel = "";
  883. }
  884. $text .= "<option value='$key' $sel>".$val."</option>\n";
  885. }
  886. for ($i = 0; $i <= 59; $i++)
  887. {
  888. $sel = (in_array(strval($i), $minute)) ? "selected='selected'" : "";
  889. $text .= "<option value='$i' $sel>".$i."</option>\n";
  890. }
  891. $text .= "</select>
  892. </td>
  893. <td>
  894. <select class='tbox' style='height:70px' multiple='multiple' name='tab[$c][hour][]'>
  895. \n";
  896. foreach ($hour_options as $key => $val)
  897. {
  898. if ($sep['hour'] == $key)
  899. {
  900. $sel = "selected='selected'";
  901. $hour = array();
  902. }
  903. else
  904. {
  905. $sel = "";
  906. }
  907. $text .= "<option value='$key' $sel>".$val."</option>\n";
  908. }
  909. for ($i = 0; $i <= 23; $i++)
  910. {
  911. $sel = (in_array(strval($i), $hour)) ? "selected='selected'" : "";
  912. $diz = mktime($i, 00, 00, 1, 1, 2000);
  913. $text .= "<option value='$i' $sel>".$i." - ".date("g A", $diz)."</option>\n";
  914. }
  915. $text .= "</select>
  916. </td>
  917. <td>
  918. <select class='tbox' style='height:70px' multiple='multiple' name='tab[$c][day][]'>\n";
  919. $sel_day = ($day[0] == "*") ? "selected='selected'" : "";
  920. $text .= "<option value='*' {$sel_day}>".LAN_CRON_20."</option>\n"; // Every Day
  921. for ($i = 1; $i <= 31; $i++)
  922. {
  923. $sel = (in_array($i, $day)) ? "selected='selected'" : "";
  924. $text .= "<option value='$i' $sel>".$i."</option>\n";
  925. }
  926. $text .= "</select>
  927. </td>
  928. <td>
  929. <select class='tbox' style='height:70px' multiple='multiple' name='tab[$c][month][]'>\n";
  930. $sel_month = ($month[0] == "*") ? "selected='selected'" : "";
  931. $text .= "<option value='*' $sel_month>".LAN_CRON_21."</option>\n"; // Every Month
  932. for ($i = 1; $i <= 12; $i++)
  933. {
  934. $sel = (in_array($i, $month)) ? "selected='selected'" : "";
  935. $diz = mktime(00, 00, 00, $i, 1, 2000);
  936. $text .= "<option value='$i' $sel>".strftime("%B", $diz)."</option>\n";
  937. }
  938. $text .= "</select>
  939. </td>
  940. <td>
  941. <select class='tbox' style='height:70px' multiple='multiple' name='tab[$c][weekday][]'>\n";
  942. $sel_weekday = ($weekday[0] == "*") ? "selected='selected'" : "";
  943. $text .= "<option value='*' $sel_weekday>".LAN_CRON_22."</option>\n"; // Every Week Day.
  944. $days = array(LAN_SUN, LAN_MON, LAN_TUE, LAN_WED, LAN_THU, LAN_FRI, LAN_SAT);
  945. for ($i = 0; $i <= 6; $i++)
  946. {
  947. $sel = (in_array(strval($i), $weekday)) ? "selected='selected'" : "";
  948. $text .= "<option value='$i' $sel>".$days[$i]."</option>\n";
  949. }
  950. $text .= "</select>
  951. </td>
  952. <td class='center'>";
  953. $checked = ($cronpref[$c]['active'] == 1) ? "checked='checked'" : "";
  954. $text .= "<input type='checkbox' name='cron[$c][active]' value='1' $checked />
  955. </td>
  956. <td class='center'>".$frm->admin_button('execute['.$c.']', 'Run Now')."</td>
  957. </tr>";
  958. }
  959. }
  960. }
  961. $text .= "
  962. <tr >
  963. <td colspan='9' class='center'>
  964. <div class='center buttons-bar'>";
  965. // $text .= "<input class='btn' type='submit' name='submit' value='".LAN_SAVE."' />";
  966. $text .= $frm->admin_button('submit', LAN_SAVE, $action = 'update');
  967. $text .= $frm->checkbox_switch('generate_pwd', 1, '', 'Generate new cron command');
  968. $text .= "</div></td>
  969. </tr>
  970. </tbody>
  971. </table>
  972. </form>
  973. </div>";
  974. $ns->tablerender(PAGE_NAME, $mes->render().$text);
  975. }
  976. function cronOptions()
  977. {
  978. $e107 = e107::getInstance();
  979. $var['main']['text'] = PAGE_NAME;
  980. $var['main']['link'] = e_SELF;
  981. // $var['pref']['text'] = LAN_PREFS;
  982. // $var['pref']['link'] = e_SELF."?pref";
  983. // $var['pref']['perm'] = "N";
  984. $action = ($this->cronAction) ? $this->cronAction : 'main';
  985. e107::getNav()->admin(PAGE_NAME, $action, $var);
  986. }
  987. function cronExecuteMethod($class_name, $method_name, $return = 'boolean')
  988. {
  989. $mes = e107::getMessage();
  990. if (class_exists($class_name))
  991. {
  992. $obj = new $class_name;
  993. if (method_exists($obj, $method_name))
  994. {
  995. $mes->add("Executing config function <b>".$class_name." : ".$method_name."()</b>", E_MESSAGE_DEBUG);
  996. if ($return == 'boolean')
  997. {
  998. call_user_func(array($obj, $method_name));
  999. return TRUE;
  1000. }
  1001. else
  1002. {
  1003. return call_user_func(array($obj, $method_name));
  1004. }
  1005. }
  1006. else
  1007. {
  1008. $mes->add("Config function <b>".$method_name."()</b> NOT found.", E_MESSAGE_DEBUG);
  1009. }
  1010. }
  1011. return FALSE;
  1012. }
  1013. }
  1014. function cron_adminmenu()
  1015. {
  1016. global $cron;
  1017. $cron->cronOptions();
  1018. }
  1019. */
  1020. ?>