From e35182f6ba1d378f705036387f9e2b8cb1b8c256 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Thu, 15 Nov 2018 21:12:43 +0100 Subject: [PATCH] - added new hooks/actions/events for addons to hook into the core - TODO: the server services plugin is not capable of enabling and disabling addon plugins, yet --- install/install.php | 10 +- install/lib/installer_base.lib.php | 69 ++++-- install/lib/update.lib.php | 13 +- install/update.php | 12 +- interface/lib/classes/functions.inc.php | 6 + interface/lib/classes/listform.inc.php | 64 ++++++ interface/lib/classes/plugin.inc.php | 40 +++- interface/lib/classes/remote.d/server.inc.php | 18 +- interface/lib/classes/tform_base.inc.php | 60 +++++ .../admin/templates/server_edit_services.htm | 6 +- interface/web/admin/templates/server_list.htm | 5 +- interface/web/client/client_edit.php | 5 + .../client/templates/client_edit_limits.htm | 1 + .../templates/client_template_edit_limits.htm | 1 + .../client/templates/reseller_edit_limits.htm | 1 + interface/web/dashboard/ajax_get_json.php | 18 +- interface/web/nav.php | 4 + server/lib/classes/plugins.inc.php | 8 +- .../remoteaction_core_module.inc.php | 209 ------------------ .../server_services_plugin.inc.php | 2 + 20 files changed, 291 insertions(+), 261 deletions(-) delete mode 100644 server/mods-available/remoteaction_core_module.inc.php diff --git a/install/install.php b/install/install.php index 3061d34a73..e8e878ccd1 100644 --- a/install/install.php +++ b/install/install.php @@ -211,9 +211,9 @@ if(is_dir('/usr/local/ispconfig')) { } //** Detect the installed applications -$this->call_hook('find_installed_apps', false); +$inst->raiseEvent('find_installed_apps::before'); $inst->find_installed_apps(); -$this->call_hook('find_installed_apps', true); +$inst->raiseEvent('find_installed_apps::after'); //** Select the language and set default timezone $conf['language'] = $inst->simple_query('Select language', array('en', 'de'), 'en','language'); @@ -499,7 +499,7 @@ if($install_mode == 'standard' || strtolower($inst->simple_query('Configure Web } } -$inst->call_hook('configure_webserver_selection', true); +$inst->raiseEvent('configure_webserver_selection::after'); if($install_mode == 'standard' || strtolower($inst->simple_query('Configure Firewall Server', array('y', 'n'), 'y','configure_firewall')) == 'y') { //* Check for Firewall @@ -592,9 +592,9 @@ if($install_mode == 'standard' || strtolower($inst->simple_query('Install ISPCon $inst->install_ispconfig_interface = false; } -$inst->call_hook('install_ispconfig', false); +$inst->raiseEvent('install_ispconfig::before'); $inst->install_ispconfig(); -$inst->call_hook('install_ispconfig', true); +$inst->raiseEvent('install_ispconfig::after'); //* Configure DBServer swriteln('Configuring DBServer'); diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index ccdb074607..fa7a7d3e5e 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -2827,40 +2827,61 @@ class installer_base { return $tContents; } - public function call_hook($hook_name, $after = true) { - if(is_null($this->addon_classes)) { - // load addon libs - $this->addon_classes = array(); - $libpath = realpath(dirname(__FILE__).'/..') . '/lib.d'; - if(($dir = opendir($libpath))) { - while(false !== ($cur = readdir($dir))) { - if(strpos($cur, '..') !== false || !is_file($libpath . '/' . $cur) || substr($cur, -8) !== '.lib.php') { - continue; - } - $class_name = substr($cur, 0, -8) . '_addon_installer'; - include_once $libpath . '/' . $cur; - if(!class_exists($class_name)) { - continue; - } - - $this->addon_classes[] = new $class_name; + private function loadAddonClasses($path) { + $libpath = $conf['ispconfig_install_dir'] . '/addons'; + if(($dir = opendir($libpath))) { + while(false !== ($cur = readdir($dir))) { + if($cur === '.' || $cur === '..' || strpos($cur, '..') !== false || !is_dir($libpath . '/' . $cur)) { + continue; + } + $addon_file = $libpath . '/' . $cur . '/' . $cur . '.addon.php'; + if(!is_file($addon_file)) { + continue; + } + + $class_name = $cur . '_addon_installer'; + + if(isset($this->addon_classes[$class_name]) && is_object($this->addon_classes[$class_name])) { + // don't override + continue; + } + + include_once $addon_file; + if(!class_exists($class_name)) { + continue; + } + + if(!is_array($this->addon_classes)) { + $this->addon_classes = array(); } - closedir($dir); + + $this->addon_classes[$class_name] = new $class_name; } + closedir($dir); } + } + + public function raiseEvent($event_name) { + global $conf; - $call_method = 'onBefore'; - if($after === true) { - $call_method = 'onAfter'; + if(is_null($this->addon_classes)) { + // load addon libs + $this->addon_classes = array(); + $addonpath = $conf['ispconfig_install_dir'] . '/addons'; + $this->loadAddonClasses($addonpath); + + // check for addon libs in install dir + $addonpath = realpath(dirname(__FILE__) . '/..') . '/addons'; + $this->loadAddonClasses($addonpath); } + + $call_method = 'onRaisedEvent'; reset($this->addon_classes); foreach($this->addon_classes as $cl) { if(method_exists($cl, $call_method)) { - call_user_func(array($cl, $call_method), $hook_name); + call_user_func(array($cl, $call_method), $event_name); } } } } - -?> diff --git a/install/lib/update.lib.php b/install/lib/update.lib.php index 74b3b20637..8943aafdcb 100644 --- a/install/lib/update.lib.php +++ b/install/lib/update.lib.php @@ -434,11 +434,16 @@ function setDefaultServers(){ * @param $servicename string the name of the Database-Field in "servers" for this service * @param $detected_value boolean The result of service detection */ -function check_service_config_state($servicename, $detected_value) { - global $current_svc_config, $inst, $conf; +function check_service_config_state($servicename, $detected_value, $use_current_config = null) { + global $current_svc_config, $inst; - if ($current_svc_config[$servicename] == 1) $current_state = 1; - else $current_state = 0; + if(is_array($use_current_config)) { + if ($use_current_config[$servicename] == 1) $current_state = 1; + else $current_state = 0; + } else { + if ($current_svc_config[$servicename] == 1) $current_state = 1; + else $current_state = 0; + } if ($detected_value) $detected_value = 1; else $detected_value = 0; diff --git a/install/update.php b/install/update.php index 6bca068759..2fe3f6559f 100644 --- a/install/update.php +++ b/install/update.php @@ -340,9 +340,9 @@ checkDbHealth(); /* * dump the new Database and reconfigure the server.ini */ -$inst->call_hook('updateDbAndIni', false); +$inst->raiseEvent('updateDbAndIni::before'); updateDbAndIni(); -$inst->call_hook('updateDbAndIni', true); +$inst->raiseEvent('updateDbAndIni::after'); //** read server config from db into $conf['server_config'] $tmp = $inst->db->queryOneRecord("SELECT config FROM ?? WHERE server_id = ?", $conf["mysql"]["database"] . '.server', $conf['server_id']); @@ -364,11 +364,12 @@ if($reconfigure_master_database_rights_answer == 'yes') { //} //** Detect the installed applications -$this->call_hook('find_installed_apps', false); +$inst->raiseEvent('find_installed_apps::before'); $inst->find_installed_apps(); -$this->call_hook('find_installed_apps', true); +$inst->raiseEvent('find_installed_apps::after'); //** Check for current service config state and compare to our results +$inst->raiseEvent('check_service_config_state::before'); if ($conf['mysql']['master_slave_setup'] == 'y') $current_svc_config = $inst->dbmaster->queryOneRecord("SELECT mail_server,web_server,dns_server,firewall_server,db_server FROM ?? WHERE server_id=?", $conf['mysql']['master_database'] . '.server', $conf['server_id']); else $current_svc_config = $inst->db->queryOneRecord("SELECT mail_server,web_server,dns_server,firewall_server,db_server FROM ?? WHERE server_id=?", $conf["mysql"]["database"] . '.server', $conf['server_id']); $conf['services']['mail'] = check_service_config_state('mail_server', $conf['postfix']['installed']); @@ -377,6 +378,7 @@ $conf['services']['web'] = check_service_config_state('web_server', ($conf['apac $conf['services']['firewall'] = check_service_config_state('firewall_server', ($conf['ufw']['installed'] || $conf['firewall']['installed'])); $conf['services']['db'] = check_service_config_state('db_server', true); /* Will always offer as MySQL is of course installed on this host as it's a requirement for ISPC to work... */ unset($current_svc_config); +$inst->raiseEvent('check_service_config_state::after'); //** Write new decisions into DB $sql = "UPDATE ?? SET mail_server = '{$conf['services']['mail']}', web_server = '{$conf['services']['web']}', dns_server = '{$conf['services']['dns']}', file_server = '{$conf['services']['file']}', db_server = '{$conf['services']['db']}', proxy_server = '{$conf['services']['proxy']}', firewall_server = '$firewall_server_enabled' WHERE server_id = ?"; @@ -539,7 +541,9 @@ if ($inst->install_ispconfig_interface) { } } +$inst->raiseEvent('install_ispconfig::before'); $inst->install_ispconfig(); +$inst->raiseEvent('install_ispconfig::after'); // Cleanup $inst->cleanup_ispconfig(); diff --git a/interface/lib/classes/functions.inc.php b/interface/lib/classes/functions.inc.php index bace18f44c..25e8b4aa22 100644 --- a/interface/lib/classes/functions.inc.php +++ b/interface/lib/classes/functions.inc.php @@ -253,6 +253,12 @@ class functions { } } } + + $tmp_ips = $app->plugin->raiseEvent('get_server_ips', 0, true); + if(is_array($tmp_ips) && !empty($tmp_ips)) { + $ips = array_merge($ips, $tmp_ips); + } + $results = $groupid != 1 ? $app->db->queryAllRecords("SELECT database_name as name,remote_ips as ip FROM web_database WHERE remote_ips != '' AND sys_groupid = ?", $groupid) : $results = $app->db->queryAllRecords("SELECT database_name as name,remote_ips as ip FROM web_database WHERE remote_ips != ''"); diff --git a/interface/lib/classes/listform.inc.php b/interface/lib/classes/listform.inc.php index 4b92daa73c..665f2e457b 100644 --- a/interface/lib/classes/listform.inc.php +++ b/interface/lib/classes/listform.inc.php @@ -66,6 +66,70 @@ class listform { $this->wordbook = $wb; + $module = (isset($_SESSION['s']['module']['name']) ? $_SESSION['s']['module']['name'] : ''); + + // load wordbook/lang files from addons + if($module == '') { + $lng_path = 'lib/lang.d'; + } else { + $lng_path = '../' . $module . '/lib/lang.d'; + } + if(($dir = opendir($lng_path))) { + $fallback_files = array(); + $use_files = array(); + while(false !== ($cur = readdir($dir))) { + $lng_file = $lng_path . '/' . $cur; + if(is_file($lng_file) && substr($cur, -strlen('.'.$app->listform->listDef["name"].".lng")) === '.'.$app->listform->listDef["name"].".lng") { + if(substr($cur, 0, 3) === 'en_') { + $fallback_files[] = $cur; + } elseif(substr($cur, 0, 3) === $app->functions->check_language($_SESSION["s"]["language"]) . '_') { + $use_files[] = $cur; + } + } + } + closedir($dir); + + foreach($fallback_files as $cur) { + $cur_lng = $app->functions->check_language($_SESSION["s"]["language"]) . '_' . substr($cur, 3); + if(in_array($cur_lng, $use_files, true) == false) { + $use_files[] = $cur; + } + } + unset($fallback_files); + + reset($use_files); + foreach($use_files as $cur) { + $lng_file = $lng_path . '/' . $cur; + + include $lng_file; + if(isset($wb) && is_array($wb)) { + $this->wordbook = $app->functions->array_merge($this->wordbook, $wb); + } + } + unset($use_files); + } + + + if($module) { + // load list files from addons + $listform_path = '../' . $module . '/lib/form.d'; + if(($dir = opendir($listform_path))) { + $items = null; + while(false !== ($cur = readdir($dir))) { + $listform_file = $listform_path . '/' . $cur; + if(is_file($listform_file) && substr($cur, -strlen('.'.$app->listform->listDef["name"].".list.php")) === '.'.$app->listform->listDef["name"].".list.php") { + unset($items); // just in case someone does not create a new array in the list file + include($listform_file); + if(isset($items) && is_array($items) && !empty($items)) { + $this->listDef['item'] = array_merge($this->listDef['item'], $items); + } + } + } + closedir($dir); + } + } + + return true; } diff --git a/interface/lib/classes/plugin.inc.php b/interface/lib/classes/plugin.inc.php index 8a8ac20012..a01b2588cf 100644 --- a/interface/lib/classes/plugin.inc.php +++ b/interface/lib/classes/plugin.inc.php @@ -124,17 +124,35 @@ class plugin { $tmp_event = $sub_events[2]; if($this->debug) $app->log("Called Event '$tmp_event'", LOGLEVEL_DEBUG); $tmpresult = $this->callPluginEvent($tmp_event, $data, $return_data); - if($return_data == true && $tmpresult) $result .= $tmpresult; + if($return_data == true && $tmpresult) { + if(is_array($tmpresult) && (!$result || is_array($result))) { + $result = array_merge($result, $tmpresult); + } elseif(!is_array($tmpresult)) { + $result .= $tmpresult; + } + } $tmp_event = $sub_events[0].':'.$sub_events[2]; if($this->debug) $app->log("Called Event '$tmp_event'", LOGLEVEL_DEBUG); $tmpresult = $this->callPluginEvent($tmp_event, $data, $return_data); - if($return_data == true && $tmpresult) $result .= $tmpresult; + if($return_data == true && $tmpresult) { + if(is_array($tmpresult) && (!$result || is_array($result))) { + $result = array_merge($result, $tmpresult); + } elseif(!is_array($tmpresult)) { + $result .= $tmpresult; + } + } $tmp_event = $sub_events[0].':'.$sub_events[1].':'.$sub_events[2]; if($this->debug) $app->log("Called Event '$tmp_event'", LOGLEVEL_DEBUG); $tmpresult = $this->callPluginEvent($tmp_event, $data, $return_data); - if($return_data == true && $tmpresult) $result .= $tmpresult; + if($return_data == true && $tmpresult) { + if(is_array($tmpresult) && (!$result || is_array($result))) { + $result = array_merge($result, $tmpresult); + } elseif(!is_array($tmpresult)) { + $result .= $tmpresult; + } + } /*$sub_events = array_reverse($sub_events); $tmp_event = ''; @@ -147,7 +165,13 @@ class plugin { } else { if($this->debug) $app->log("Called Event '$sub_events[0]'", LOGLEVEL_DEBUG); $tmpresult = $this->callPluginEvent($sub_events[0], $data, $return_data); - if($return_data == true && $tmpresult) $result .= $tmpresult; + if($return_data == true && $tmpresult) { + if(is_array($tmpresult) && (!$result || is_array($result))) { + $result = array_merge($result, $tmpresult); + } elseif(!is_array($tmpresult)) { + $result .= $tmpresult; + } + } } } @@ -187,7 +211,13 @@ class plugin { // call_user_method($function_name,$app->loaded_plugins[$plugin_name],$event_name,$data); $tmpresult = call_user_func(array($app->loaded_plugins[$plugin_name], $function_name), $event_name, $data); - if($return_data == true && $tmpresult) $result .= $tmpresult; + if($return_data == true && $tmpresult) { + if(is_array($tmpresult) && (!$result || is_array($result))) { + $result = array_merge($result, $tmpresult); + } elseif(!is_array($tmpresult)) { + $result .= $tmpresult; + } + } } } diff --git a/interface/lib/classes/remote.d/server.inc.php b/interface/lib/classes/remote.d/server.inc.php index f1bf610afb..66684cf15f 100644 --- a/interface/lib/classes/remote.d/server.inc.php +++ b/interface/lib/classes/remote.d/server.inc.php @@ -203,7 +203,6 @@ class remoting_server extends remoting { global $app; if(!$this->checkPerm($session_id, 'server_get')) { throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; } if (!empty($session_id) && !empty($server_name)) { $sql = "SELECT server_id FROM server WHERE server_name = ?"; @@ -225,12 +224,22 @@ class remoting_server extends remoting { global $app; if(!$this->checkPerm($session_id, 'server_get')) { throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; } if (!empty($session_id) && !empty($server_id)) { - $sql = "SELECT mail_server, web_server, dns_server, file_server, db_server, proxy_server, firewall_server, mirror_server_id FROM server WHERE server_id = ?"; + $sql = "SELECT * FROM server WHERE server_id = ?"; $all = $app->db->queryOneRecord($sql, $server_id); - return $all; + if(empty($all)) return false; + + $func = array(); + foreach($all as $key => $value) { + if($key === 'mirror_server_id' || substr($key, -7) === '_server') { + if($value == 0 || $value == 1) { + $func[$key] = $value; + } + } + } + + return $func; } else { return false; } @@ -241,7 +250,6 @@ class remoting_server extends remoting { global $app; if(!$this->checkPerm($session_id, 'server_get')) { throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; } if (!empty($session_id)) { if($server_id == 0) $ispc_app_version = array('ispc_app_version' => ISPC_APP_VERSION); diff --git a/interface/lib/classes/tform_base.inc.php b/interface/lib/classes/tform_base.inc.php index 3b82b48376..0b8a73858b 100644 --- a/interface/lib/classes/tform_base.inc.php +++ b/interface/lib/classes/tform_base.inc.php @@ -155,6 +155,66 @@ class tform_base { $this->wordbook = $wb; + // load wordbook/lang files from addons + if($module == '') { + $lng_path = 'lib/lang.d'; + } else { + $lng_path = '../' . $module . '/lib/lang.d'; + } + if(($dir = opendir($lng_path))) { + $fallback_files = array(); + $use_files = array(); + while(false !== ($cur = readdir($dir))) { + $lng_file = $lng_path . '/' . $cur; + if(is_file($lng_file) && substr($cur, -strlen('.'.$this->formDef["name"].".lng")) === '.'.$this->formDef["name"].".lng") { + if(substr($cur, 0, 3) === 'en_') { + $fallback_files[] = $cur; + } elseif(substr($cur, 0, 3) === $app->functions->check_language($_SESSION["s"]["language"]) . '_') { + $use_files[] = $cur; + } + } + } + closedir($dir); + + foreach($fallback_files as $cur) { + $cur_lng = $app->functions->check_language($_SESSION["s"]["language"]) . '_' . substr($cur, 3); + if(in_array($cur_lng, $use_files, true) == false) { + $use_files[] = $cur; + } + } + unset($fallback_files); + + reset($use_files); + foreach($use_files as $cur) { + $lng_file = $lng_path . '/' . $cur; + + include $lng_file; + if(isset($wb) && is_array($wb)) { + $this->wordbook = $app->functions->array_merge($this->wordbook, $wb); + } + } + unset($use_files); + } + + if($module != '') { + // load tform files from addons + $tform_path = '../' . $module . '/lib/form.d'; + if(($dir = opendir($tform_path))) { + $tabs = null; + while(false !== ($cur = readdir($dir))) { + $tform_file = $tform_path . '/' . $cur; + if(is_file($tform_file) && substr($cur, -strlen('.'.$this->formDef["name"].".tform.php")) === '.'.$this->formDef["name"].".tform.php") { + unset($tabs); // just in case someone does not create a new array in the tform file + include($tform_file); + if(isset($tabs) && is_array($tabs) && !empty($tabs)) { + $this->tform['tabs'] = array_replace_recursive($this->tform['tabs'], $tabs); + } + } + } + closedir($dir); + } + } + $app->plugin->raiseEvent($_SESSION['s']['module']['name'].':'.$app->tform->formDef['name'] . ':on_after_formdef', $this); $this->dateformat = $app->lng('conf_format_dateshort'); diff --git a/interface/web/admin/templates/server_edit_services.htm b/interface/web/admin/templates/server_edit_services.htm index 22d4a26f10..cfcc2fb8b2 100644 --- a/interface/web/admin/templates/server_edit_services.htm +++ b/interface/web/admin/templates/server_edit_services.htm @@ -4,7 +4,7 @@

- + {tmpl_hook name="begin_form"}
@@ -38,6 +38,8 @@ {tmpl_var name='db_server'} + {tmpl_hook name="field_db_server"} + {tmpl_hook name="end_service_fields"}
@@ -52,7 +54,7 @@ {tmpl_var name='active'}
- + {tmpl_hook name="end_form"} diff --git a/interface/web/admin/templates/server_list.htm b/interface/web/admin/templates/server_list.htm index 2f527af170..25c18c01f0 100644 --- a/interface/web/admin/templates/server_list.htm +++ b/interface/web/admin/templates/server_list.htm @@ -15,6 +15,7 @@ + {tmpl_hook name="end_table_headers"} {tmpl_var name='search_limit'} @@ -24,9 +25,10 @@ + {tmpl_hook name="end_table_filters"} - + "} @@ -38,6 +40,7 @@ {tmpl_var name="dns_server"} {tmpl_var name="file_server"} {tmpl_var name="db_server"} + {tmpl_hook name="end_table_columns"} diff --git a/interface/web/client/client_edit.php b/interface/web/client/client_edit.php index c405386032..0d06a42fe2 100644 --- a/interface/web/client/client_edit.php +++ b/interface/web/client/client_edit.php @@ -445,6 +445,11 @@ class page_action extends tform_actions { 'web_folder' => 'web_folder_id', 'web_folder_user' => 'web_folder_user_id' ); + + $addons_disable = $app->plugin->raiseEvent('client::get_lockable_data', $this->id, true); + if(is_array($addons_disable) && !empty($addons_disable)) { + $to_disable = array_merge($to_disable, $addons_disable); + } $udata = $app->db->queryOneRecord('SELECT `userid` FROM `sys_user` WHERE `client_id` = ?', $this->id); $gdata = $app->db->queryOneRecord('SELECT `groupid` FROM `sys_group` WHERE `client_id` = ?', $this->id); diff --git a/interface/web/client/templates/client_edit_limits.htm b/interface/web/client/templates/client_edit_limits.htm index 7ebb331221..16cd1fc201 100644 --- a/interface/web/client/templates/client_edit_limits.htm +++ b/interface/web/client/templates/client_edit_limits.htm @@ -349,6 +349,7 @@ + {tmpl_hook name="end_form"} diff --git a/interface/web/client/templates/client_template_edit_limits.htm b/interface/web/client/templates/client_template_edit_limits.htm index 6c63829f03..abaf65aad7 100644 --- a/interface/web/client/templates/client_template_edit_limits.htm +++ b/interface/web/client/templates/client_template_edit_limits.htm @@ -307,6 +307,7 @@ + {tmpl_hook name="end_form"}
diff --git a/interface/web/client/templates/reseller_edit_limits.htm b/interface/web/client/templates/reseller_edit_limits.htm index 4ca3d33b92..539b7d5e41 100644 --- a/interface/web/client/templates/reseller_edit_limits.htm +++ b/interface/web/client/templates/reseller_edit_limits.htm @@ -352,6 +352,7 @@
+ {tmpl_hook name="end_form"}