diff --git a/cron.php b/cron.php index ae868c47a..2a6787d15 100644 --- a/cron.php +++ b/cron.php @@ -51,22 +51,40 @@ e107::getCache()->set('cronLastLoad',time(),TRUE,FALSE,TRUE); // from the plugin directory: // realpath(dirname(__FILE__)."/../../")."/"; + $list = array(); -if($pref['e_cron_pref']) // grab cron -{ - foreach($pref['e_cron_pref'] as $func=>$cron) + $sql = e107::getDb(); + if($sql->db_Select("cron",'cron_function,cron_tab','cron_active =1')) { - if($cron['active']==1) + while($row = $sql->db_Fetch(MYSQL_ASSOC)) { - $list[$func] = $cron; - } + list($class,$function) = explode("::",$row['cron_function'],2); + $key = $class."__".$function; + + $list[$key] = array( + 'path' => $class, + 'active' => 1, + 'tab' => $row['cron_tab'], + 'function' => $function, + 'class' => $class + ); + } } -} + + + // foreach($pref['e_cron_pref'] as $func=>$cron) + // { + // if($cron['active']==1) + // { + // $list[$func] = $cron; + // } + // } + if($_E107['debug'] && $_SERVER['QUERY_STRING']) { - echo "

Cron List

"; + echo "

Cron Lists

"; print_a($list); } diff --git a/e107_admin/cron.php b/e107_admin/cron.php index fbcc0ff1c..a98bc4107 100644 --- a/e107_admin/cron.php +++ b/e107_admin/cron.php @@ -30,11 +30,550 @@ if (!getperms('U')) include_lan(e_LANGUAGEDIR.e_LANGUAGE.'/admin/lan_'.e_PAGE); + + +class cron_admin extends e_admin_dispatcher +{ + + protected $modes = array( + 'main' => array( + 'controller' => 'cron_admin_ui', + 'path' => null, + 'ui' => 'cron_admin_form_ui', + 'uipath' => null + ) + ); + + + protected $adminMenu = array( + 'main/list' => array('caption'=> 'Manage', 'perm' => '0'), + // 'main/create' => array('caption'=> LAN_CREATE, 'perm' => '0'), + // 'main/prefs' => array('caption'=> 'Settings', 'perm' => '0'), + // 'main/custom' => array('caption'=> 'Custom Page', 'perm' => '0') + ); + + protected $adminMenuAliases = array( + 'main/edit' => 'main/list' + ); + + protected $menuTitle = 'Comments'; +} + +class cron_admin_ui extends e_admin_ui +{ + + protected $pluginTitle = PAGE_NAME; + protected $pluginName = 'core'; + protected $table = "cron"; + protected $pid = "cron_id"; + protected $perPage = 10; + protected $batchDelete = TRUE; + + protected $fields = array( + 'checkboxes' => array('title'=> '', 'type' => null, 'width' =>'5%', 'forced'=> TRUE, 'thclass'=>'center', 'class'=>'center'), + 'cron_id' => array('title'=> LAN_ID, 'type' => 'number', 'width' =>'5%', 'forced'=> TRUE), + 'cron_name' => array('title'=> "Name", 'type' => 'text', 'width' => 'auto', 'readonly' => 1), + 'cron_description' => array('title'=> "Description", 'type' => 'text', 'width' => '35%', 'readonly' => 1), + + 'cron_function' => array('title'=> "Function", 'type' => 'text', 'width' => 'auto', 'thclass' => 'left first', 'readonly' => 1), + 'cron_tab' => array('title'=> "Tab", 'type' => 'method', 'width' => 'auto'), // Display name + 'cron_lastrun' => array('title'=> "Last-run", 'type' => 'datestamp', 'data' => 'int', 'width' => 'auto', 'readonly' => 2), + 'cron_active' => array('title'=> "Active", 'type' => 'boolean', 'data'=> 'int', 'thclass' => 'center', 'class'=>'center', 'filter' => true, 'batch' => true, 'width' => 'auto'), + 'options' => array('title'=> LAN_OPTIONS, 'type' => 'method', 'data'=> null, 'noedit'=>TRUE, 'forced'=>TRUE, 'width' => '10%', 'thclass' => 'center last', 'class' => 'center') + ); + + + // public function beforeCreate($new_data) + // { + + // } + private $curCrons = array(); + private $activeCrons = 0; + + function init() + { + $pref = e107::getPref(); + $sql = e107::getDb(); + + if(vartrue($_POST['cron_execute'])) + { + $executeID = key($_POST['cron_execute']); + $this->cronExecute($executeID); + } + + // unset($this->_data_fields['options']); // FIX ME - this should be done automatically. + + if (!vartrue(e107::getPref('e_cron_pwd'))) + { + $pwd = $this->setCronPwd(); + } + + $sql->db_Select_gen("SELECT cron_function,cron_active FROM #cron "); + while($row = $sql->db_Fetch(MYSQL_ASSOC)) + { + $this->curCrons[] = $row['cron_function']; + if($row['cron_active']==1) + { + $this->activeCrons++; + } + } + + $this->lastRefresh(); + // Import Core and Plugin e_cron data + + $cronDefaults['_system'] = array( + 0 => array('name' => 'Test Email', 'function' => 'sendEmail', 'description' => 'Send a test email to '.$pref['siteadminemail'].'
Recommended to test the scheduling system.'), + 1 => array('name' => 'Mail Queue', 'function' => 'procEmailQueue', 'description' => 'Process mail queue'), + 2 => array('name' => 'Mail Bounce Check', 'function' => 'procEmailBounce', 'description' => 'Check for bounced emails', 'available' => vartrue($pref['mail_bounce_auto'])), + ); + + if(!$_GET['action']) + { + + $this->cronImport($cronDefaults); // import Core Crons (if missing) + $this->cronImport(e107::getAddonConfig('e_cron')); // Import plugin Crons + $this->cronImportLegacy(); // Import Legacy Cron Tab Settings + } + + } + + + + /** + * Import Cron Settings into Database. + */ + public function cronImport($new_cron = FALSE) + { + if(!$new_cron) + { + return; + } + + foreach($new_cron as $class => $ecron) + { + foreach($ecron as $val) + { + $insert = array( + 'cron_id' => 0, + 'cron_name' => $val['name'], + 'cron_description' => $val['description'], + 'cron_function' => $class."::".$val['function'], + 'cron_tab' => '* * * * *', + 'cron_active' => 0, + ); + + $this->cronInsert($insert); + } + } + } + + + + /** + * Import Legacy e_cron_pref settings. + */ + public function cronImportLegacy() + { + global $pref; + + $cronPref = e107::getPref('e_cron_pref'); + + + if(!is_array($cronPref)) + { + return; + } + + foreach($cronPref as $val) + { + $update = array( + 'cron_tab' => $val['tab'], + 'cron_active' => $val['active'], + 'cron_function' => $val['class']."::".$val['function'], + 'WHERE' => "cron_function = '".$val['class']."::".$val['function']."'" + ); + + $this->cronUpdate($update); + } + + e107::getConfig()->remove('e_cron_pref')->save(); + } + + + + + // Insert a Cron. + public function cronInsert($insert) + { + // print_a($insert); + // return; +// + $sql = e107::getDb(); + + if(in_array($insert['cron_function'],$this->curCrons)) + { + return; + } + + if(!$sql->db_Insert('cron',$insert)) + { + e107::getMessage()->add("Couldn't Import Prefs", E_MESSAGE_ERROR); + } + else + { + e107::getMessage()->add("Imported: ".$insert['cron_function'], E_MESSAGE_INFO); + } + } + + + + /** + * Update cron timing - from legacy Pref. + */ + public function cronUpdate($insert) + { + // print_a($insert); + // return; +// + $sql = e107::getDb(); + + $cron_function = $insert['cron_function']; + unset($insert['cron_function']); + + if($sql->db_Update('cron',$insert)===FALSE) + { + e107::getMessage()->add("Couldn't Import Timing Settings", E_MESSAGE_ERROR); + } + else + { + e107::getMessage()->add("Imported Timing Settings for: ".$cron_function, E_MESSAGE_INFO); + } + } + + + + + + // Process _POST before saving. + public function beforeUpdate($new_data, $old_data, $id) + { + $new_data['cron_tab'] = implode(" ", $new_data['tab']); + return $new_data; + } + + + function setCronPwd() + { + //global $pref; + $userMethods = e107::getUserSession(); + $newpwd = $userMethods->generateRandomString('*^*#.**^*'); + $newpwd = sha1($newpwd.time()); + + e107::getConfig()->set('e_cron_pwd', $newpwd)->save(false); + return true; + + } + + + + function lastRefresh() + { + $pref = e107::getPref(); + $mes = e107::getMessage(); + + e107::getCache()->CachePageMD5 = '_'; + $lastload = e107::getCache()->retrieve('cronLastLoad', FALSE, TRUE, TRUE); + + $ago = (time() - $lastload); + + $active = ($ago < 901) ? TRUE : FALSE; + $status = ($active) ? LAN_ENABLED : LAN_DISABLED; // "Enabled" : "Offline"; + + $mins = floor($ago / 60); + $secs = $ago % 60; + + $lastRun = ($mins) ? $mins." minutes and ".$secs." seconds ago." : $secs." seconds ago."; + + $lastRefresh = ($ago < 10000) ? $lastRun : 'Never'; + + $mes->add("Status: ".$status."", E_MESSAGE_INFO); + + + $mes->add("Active Crons: ".$this->activeCrons."", E_MESSAGE_INFO); + $mes->add("Last cron refresh: ".$lastRefresh, E_MESSAGE_INFO); + + //FIXME: for Windows, the is_executable() function only checks the file + // extensions of exe, com, bat and cmd. + + if (!is_executable(e_BASE."cron.php")) + { + $mes->add("Please CHMOD /cron.php to 755", E_MESSAGE_WARNING); + } + //elseif (!$active) - always show instructions + { + $setpwd_message = "Use the following Cron Command: ".$_SERVER['DOCUMENT_ROOT'].e_HTTP."cron.php ".$pref['e_cron_pwd']."
+ Using your server control panel (eg. cPanel,Plesk etc.) please create a crontab to run this command on your server every minute."; + $mes->add($setpwd_message, E_MESSAGE_INFO); + } + + } + + function cronExecute($cron_id) + { + $sql = e107::getDb(); + if($sql->db_Select("cron","cron_name,cron_function","cron_id = ".intval($cron_id))) + { + $row = $sql->db_Fetch(MYSQL_ASSOC); + $class_func = $row['cron_function']; + $cron_name = $row['cron_name']; + } + + if(!$class_func) + { + return; + } + + + list($class_name, $method_name) = explode("::", $class_func); + $mes = e107::getMessage(); + $taskName = $class_name; + + if ($class_name == '_system') + { + require_once(e_HANDLER.'cron_class.php'); + } + else + { + require_once(e_PLUGIN.$class_name.'/e_cron.php'); + } + $class_name .= '_cron'; + $status = $this->cronExecuteMethod($class_name, $method_name) ? E_MESSAGE_SUCCESS : E_MESSAGE_ERROR; + $mes->add("Running ".$cron_name."", $status); + } + + + + function cronExecuteMethod($class_name, $method_name, $return = 'boolean') + { + $mes = e107::getMessage(); + + if (class_exists($class_name)) + { + $obj = new $class_name; + if (method_exists($obj, $method_name)) + { + $mes->add("Executing config function ".$class_name." : ".$method_name."()", E_MESSAGE_DEBUG); + if ($return == 'boolean') + { + call_user_func(array($obj, $method_name)); + return TRUE; + } + else + { + return call_user_func(array($obj, $method_name)); + } + } + else + { + $mes->add("Config function ".$method_name."() NOT found.", E_MESSAGE_DEBUG); + } + } + return FALSE; + } + +} + +class cron_admin_form_ui extends e_admin_form_ui +{ + + function cron_tab($curVal,$mode) + { + if($mode == 'read') + { + return $curVal; + } + + if($mode == 'write') + { + return $this->editTab($curVal); + } + + if($mode == 'filter') // Custom Filter List + { + $list = array(); + return $list; + } + + if($mode == 'batch') + { + $types = array(); + asort($types); + + return $types; + } + } + + // Override the default Options field. + function options($field, $value, $attributes, $id) + { + + if($attributes['mode'] == 'read') + { + $text = $this->renderValue('options',$value,'',$id); + $text .= $this->submit_image('cron_execute['.$id.']', 1, 'execute', 'Execute'); + return $text; + } + } + + + function editTab($curVal) + { + $sep = array(); + list($sep['minute'], $sep['hour'], $sep['day'], $sep['month'], $sep['weekday']) = explode(" ", $curVal); + + foreach ($sep as $key => $value) + { + if ($value == "") + { + $sep[$key] = "*"; + } + } + + $minute = explode(",", $sep['minute']); + $hour = explode(",", $sep['hour']); + $day = explode(",", $sep['day']); + $month = explode(",", $sep['month']); + $weekday = explode(",", $sep['weekday']); + + $min_options = array( + "*" => LAN_CRON_11, + "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, + "0,5,10,15,20,25,30,35,40,45,50,55" => LAN_CRON_13, + "0,10,20,30,40,50" => LAN_CRON_14, + "0,15,30,45" => LAN_CRON_10, + "0,30" => LAN_CRON_15 + ); + + $hour_options = array( + "*" => LAN_CRON_16, + "0,2,4,6,8,10,12,14,16,18,20,22" => LAN_CRON_17, + "0,3,6,9,12,15,18,21" => LAN_CRON_18, + "0,6,12,18"=> LAN_CRON_19 + ); + + $text = " + + + + + + + + + "; + + return $text; + + } + + + + +} + +new cron_admin(); + + + $e_sub_cat = 'cron'; require_once('auth.php'); + +e107::getAdminUI()->runPage(); $frm = e107::getForm(); -$cron = new cron(); +// $cron = new cron(); require_once(e_ADMIN.'footer.php'); exit; diff --git a/e107_admin/sql/core_sql.php b/e107_admin/sql/core_sql.php index e58151a68..c9336b982 100644 --- a/e107_admin/sql/core_sql.php +++ b/e107_admin/sql/core_sql.php @@ -153,6 +153,18 @@ CREATE TABLE core_media_cat ( ) ENGINE=MyISAM; +CREATE TABLE cron ( + cron_id INT( 10 ) UNSIGNED NOT NULL AUTO_INCREMENT , + cron_name VARCHAR( 50 ) NOT NULL , + cron_description VARCHAR( 255 ) NOT NULL , + cron_function VARCHAR( 50 ) NOT NULL , + cron_tab VARCHAR( 255 ) NOT NULL , + cron_lastrun INT( 13 ) UNSIGNED NOT NULL , + cron_active INT( 1 ) UNSIGNED NOT NULL , + PRIMARY KEY (cron_id), + UNIQUE KEY cron_function (cron_function) +) ENGINE = MYISAM ; + diff --git a/e107_handlers/form_handler.php b/e107_handlers/form_handler.php index 4a52511df..3ebe5c42c 100644 --- a/e107_handlers/form_handler.php +++ b/e107_handlers/form_handler.php @@ -704,6 +704,16 @@ class e_form $image = ADMIN_DELETE_ICON_PATH; $options['class'] = vartrue($options['class'] , 'action delete'); break; + + case 'execute': + $image = ADMIN_EXECUTE_ICON_PATH; + $options['class'] = vartrue($options['class'] , 'action delete'); + break; + + case 'view': + $image = ADMIN_VIEW_ICON_PATH; + $options['class'] = vartrue($options['class'] , 'action delete'); + break; } $options['title'] = $title;//shorthand @@ -1205,12 +1215,23 @@ class e_form switch($field) // special fields { case 'options': + + if($attributes['type']=='method') // Allow override with 'options' function. + { + + $attributes['mode'] = "read"; + return $this->options($field, $value, $attributes, $id); + + } + if(!$value) { parse_str(str_replace('&', '&', e_QUERY), $query); //FIXME - FIX THIS // keep other vars in tact $query['action'] = 'edit'; $query['id'] = $id; + + //$edit_query = array('mode' => varset($query['mode']), 'action' => varset($query['action']), 'id' => $id); $query = http_build_query($query); @@ -1569,13 +1590,15 @@ class e_form */ function renderElement($key, $value, $attributes, $required_data = array()) { + $parms = vartrue($attributes['writeParms'], array()); $tp = e107::getParser(); if(is_string($parms)) parse_str($parms, $parms); - if(vartrue($attributes['readonly']) && vartrue($value)) // quick fix (maybe 'noedit'=>'readonly'?) - { + // Two modes of read-only. 1 = read-only, but only when there is a value, 2 = read-only regardless. + if(vartrue($attributes['readonly']) && (vartrue($value) || vartrue($attributes['readonly'])==2)) // quick fix (maybe 'noedit'=>'readonly'?) + { return $this->renderValue($key, $value, $attributes).$this->hidden($key, $value); // } diff --git a/e107_images/admin_images/execute_16.png b/e107_images/admin_images/execute_16.png new file mode 100644 index 000000000..1faf7d014 Binary files /dev/null and b/e107_images/admin_images/execute_16.png differ diff --git a/e107_images/admin_images/execute_32.png b/e107_images/admin_images/execute_32.png new file mode 100644 index 000000000..71bd8efba Binary files /dev/null and b/e107_images/admin_images/execute_32.png differ diff --git a/e107_plugins/gsitemap/e_cron.php b/e107_plugins/gsitemap/e_cron.php index 7bf69fd71..70c0e13ab 100644 --- a/e107_plugins/gsitemap/e_cron.php +++ b/e107_plugins/gsitemap/e_cron.php @@ -50,6 +50,8 @@ class gsitemap_cron // include plugin-folder in the name. function myfunction() { // Whatever code you wish. + e107::getMessage()->add("Executed dummy function within gsitemap/e_cron.php"); + return ; } diff --git a/e107_themes/_blank/admin_theme.php b/e107_themes/_blank/admin_theme.php index 59816c3c0..2583d2d27 100644 --- a/e107_themes/_blank/admin_theme.php +++ b/e107_themes/_blank/admin_theme.php @@ -67,6 +67,9 @@ $no_core_css = TRUE; define("ADMIN_DOWN_ICON", ""); define("ADMIN_DOWN_ICON_PATH", e_IMAGE."admin_images/down_32.png"); + + define("ADMIN_EXECUTE_ICON", ""); + define("ADMIN_EXECUTE_ICON_PATH", e_IMAGE."admin_images/execute_32.png"); diff --git a/e107_themes/templates/admin_icons_template.php b/e107_themes/templates/admin_icons_template.php index 180b70830..8610faa8d 100644 --- a/e107_themes/templates/admin_icons_template.php +++ b/e107_themes/templates/admin_icons_template.php @@ -58,3 +58,6 @@ define("ADMIN_UPGRADEPLUGIN_ICON", ""); define("ADMIN_UPGRADEPLUGIN_ICON_PATH", e_IMAGE_ABS."admin_images/up_16.png"); + + define("ADMIN_EXECUTE_ICON", ""); + define("ADMIN_EXECUTE_ICON_PATH", e_IMAGE."admin_images/execute_16.png");