grthtrhthjhtyjytjytkergtrhtrjytjerhrfh4:24 29/09/2026. -------------------------------------------------------------------------- */ // Based on cacti plugin system /** @file * @brief */ if (!defined('GLPI_ROOT')) { die("Sorry. You can't access this file directly"); } class Plugin extends CommonDBTM { // Class constant : Plugin state const ANEW = 0; const ACTIVATED = 1; const NOTINSTALLED = 2; const TOBECONFIGURED = 3; const NOTACTIVATED = 4; const TOBECLEANED = 5; const NOTUPDATED = 6; static $rightname = 'config'; /** * @since version 0.85 * * @param $nb **/ static function getTypeName($nb=0) { return _n('Plugin', 'Plugins', $nb); } /** * @see CommonGLPI::getMenuName() * * @since version 0.85 **/ static function getMenuName() { return static::getTypeName(Session::getPluralNumber()); } /** * @see CommonGLPI::getMenuContent() * * @since version 0.85 **/ static function getMenuContent() { global $CFG_GLPI; $menu = array(); if (static::canView()) { $menu['title'] = self::getMenuName(); $menu['page'] = '/front/plugin.php'; } if (count($menu)) { return $menu; } return false; } /** * Retrieve an item from the database using its directory * * @param $dir directory of the plugin * * @return true if succeed else false **/ function getFromDBbyDir($dir) { return $this->getFromDBByQuery("WHERE `".$this->getTable()."`.`directory` = '$dir'"); } /** * Init plugins list reading plugins directory * * @return nothing **/ function init() { $this->checkStates(); $plugins = $this->find('state='.self::ACTIVATED); $_SESSION["glpi_plugins"] = array(); if (count($plugins)) { foreach ($plugins as $ID => $plug) { $_SESSION["glpi_plugins"][$ID] = $plug['directory']; } } } /** * Init a plugin including setup.php file * launching plugin_init_NAME function after checking compatibility * * @param $name Name of hook to use * @param $withhook boolean to load hook functions (false by default) * * @return nothing **/ static function load($name, $withhook=false) { global $LOADED_PLUGINS; if (file_exists(GLPI_ROOT . "/plugins/$name/setup.php")) { include_once(GLPI_ROOT . "/plugins/$name/setup.php"); if (!isset($LOADED_PLUGINS[$name])) { self::loadLang($name); $function = "plugin_init_$name"; if (function_exists($function)) { $function(); $LOADED_PLUGINS[$name] = $name; } } } if ($withhook && file_exists(GLPI_ROOT . "/plugins/$name/hook.php")) { include_once(GLPI_ROOT . "/plugins/$name/hook.php"); } } /** * Load lang file for a plugin * * @param $name Name of hook to use * @param $forcelang force a specific lang (default '') * @param $coretrytoload lang trying to be load from core (default '') * * @return nothing **/ static function loadLang($name, $forcelang='', $coretrytoload='') { // $LANG needed : used when include lang file global $CFG_GLPI, $LANG, $TRANSLATE; // For compatibility for plugins using $LANG $trytoload = 'en_GB'; if (isset($_SESSION['glpilanguage'])) { $trytoload = $_SESSION["glpilanguage"]; } // Force to load a specific lang if (!empty($forcelang)) { $trytoload = $forcelang; } // If not set try default lang file if (empty($trytoload)) { $trytoload = $CFG_GLPI["language"]; } if (empty($coretrytoload)) { $coretrytoload = $trytoload; } $dir = GLPI_ROOT . "/plugins/$name/locales/"; $translation_included = false; // New localisation system if (file_exists($dir.$CFG_GLPI["languages"][$trytoload][1])) { $TRANSLATE->addTranslationFile('gettext', $dir.$CFG_GLPI["languages"][$trytoload][1], $name, $coretrytoload); $translation_included = true; } else if (!empty($CFG_GLPI["language"]) && file_exists($dir.$CFG_GLPI["languages"][$CFG_GLPI["language"]][1])) { $TRANSLATE->addTranslationFile('gettext', $dir.$CFG_GLPI["languages"][$CFG_GLPI["language"]][1], $name, $coretrytoload); $translation_included = true; } else if (file_exists($dir."en_GB.mo")) { $TRANSLATE->addTranslationFile('gettext', $dir."en_GB.mo", $name, $coretrytoload); $translation_included = true; } if (!$translation_included) { if (file_exists($dir.$trytoload.'.php')) { include ($dir.$trytoload.'.php'); } else if (file_exists($dir.$CFG_GLPI["language"].'.php')) { include ($dir.$CFG_GLPI["language"].'.php'); } else if (file_exists($dir . "en_GB.php")) { include ($dir . "en_GB.php"); } else if (file_exists($dir . "fr_FR.php")) { include ($dir . "fr_FR.php"); } } } /** * Check plugins states and detect new plugins **/ function checkStates() { //// Get all plugins // Get all from DBs $pluglist = $this->find("","name, directory"); $db_plugins = array(); if (count($pluglist)) { foreach ($pluglist as $plug) { $db_plugins[$plug['directory']] = $plug['id']; } } // Parse plugin dir $file_plugins = array(); $error_plugins = array(); $dirplug = GLPI_ROOT."/plugins"; $dh = opendir($dirplug); while (false !== ($filename = readdir($dh))) { if (($filename != ".svn") && ($filename != ".") && ($filename != "..") && is_dir($dirplug."/".$filename)) { // Find version if (file_exists($dirplug."/".$filename."/setup.php")) { self::loadLang($filename); include_once($dirplug."/".$filename."/setup.php"); $info = self::getInfo($filename); if (count($info)) { $file_plugins[$filename] = Toolbox::addslashes_deep($info); } } } } // check plugin state foreach ($db_plugins as $plug => $ID) { $install_ok = true; // Check file if (!isset($file_plugins[$plug])) { $this->update(array('id' => $ID, 'state' => self::TOBECLEANED)); $install_ok = false; } else { // Check version if ($file_plugins[$plug]['version'] != $pluglist[$ID]['version']) { $input = $file_plugins[$plug]; $input['id'] = $ID; if ($pluglist[$ID]['version']) { $input['state'] = self::NOTUPDATED; } $this->update($input); $install_ok = false; } } // Check install is ok for activated plugins if ($install_ok && ($pluglist[$ID]['state'] == self::ACTIVATED)) { $usage_ok = true; $function = "plugin_".$plug."_check_prerequisites"; if (function_exists($function)) { if (!$function()) { $usage_ok = false; } } $function = "plugin_".$plug."_check_config"; if (function_exists($function)) { if (!$function()) { $usage_ok = false; } } else { $usage_ok = false; } if (!$usage_ok) { $input = $file_plugins[$plug]; $this->unactivate($ID); } } // Delete plugin for file list if (isset($file_plugins[$plug])) { unset($file_plugins[$plug]); } } if (count($file_plugins)) { foreach ($file_plugins as $plug => $data) { if (isset($data['oldname'])) { $checking = $pluglist; foreach ($checking as $check) { if (isset($check['directory']) && ($check['directory'] == $data['oldname'])) { $data['state'] = self::NOTUPDATED; $this->delete(array('id' => $check['id'])); } } } else { $data['state'] = self::NOTINSTALLED; } $data['directory'] = $plug; $this->add($data); } } } /** * Check if all plugins are CSRF compliant * * @since version 0.83.3 **/ static function isAllPluginsCSRFCompliant() { global $PLUGIN_HOOKS; if (isset($_SESSION['glpi_plugins']) && is_array($_SESSION['glpi_plugins']) && count($_SESSION['glpi_plugins'])) { foreach ($_SESSION['glpi_plugins'] as $plug) { if (!isset($PLUGIN_HOOKS['csrf_compliant'][$plug]) || !$PLUGIN_HOOKS['csrf_compliant'][$plug]) { return false; } } } return true; } /** * List availabled plugins **/ function listPlugins() { global $CFG_GLPI, $PLUGIN_HOOKS; $this->checkStates(); echo "
| ".__('Plugins list')." | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ".__('Name')." | "._n('Version', 'Versions',1)." | "; echo "".__('License')." | "; echo "".__('Status')." | "._n('Author', 'Authors', Session::getPluralNumber())." | "; echo "".__('Website')." | "; echo "".__('CSRF compliant')." | "; echo "||||||||||
| "; $name = trim($plug['name']); if (empty($name)) { $plug['name'] = $plug['directory']; } // Only config for install plugins if (in_array($plug['state'], array(self::ACTIVATED, self::TOBECONFIGURED, self::NOTACTIVATED)) && isset($PLUGIN_HOOKS['config_page'][$plug['directory']])) { echo " ".$plug['name'].""; } else { echo $plug['name']; } echo " | "; echo "".$plug['version']." | "; if ($plug['license']) { $link = ''; if (file_exists(GLPI_ROOT.'/plugins/'.$plug['directory'].'/LICENSE')) { $link = $CFG_GLPI['root_doc'].'/plugins/'.$plug['directory'].'/LICENSE'; } else if (file_exists(GLPI_ROOT.'/plugins/'.$plug['directory'].'/COPYING.txt')) { $link = $CFG_GLPI['root_doc'].'/plugins/'.$plug['directory'].'/COPYING.txt'; } if ($link) { echo "".$plug['license'].""; } else { echo $plug['license']; } } else { echo " "; } echo " | "; switch ($plug['state']) { case self::ANEW : echo _x('status', 'New'); break; case self::ACTIVATED : echo _x('plugin', 'Enabled'); break; case self::NOTINSTALLED : echo _x('plugin', 'Not installed'); break; case self::NOTUPDATED : _e('To update'); break; case self::TOBECONFIGURED : echo _x('plugin', 'Installed / not configured'); break; case self::NOTACTIVATED : echo _x('plugin', 'Installed / not activated'); break; case self::TOBECLEANED : default: _e('Error / to clean'); break; } echo " | "; echo "".$plug['author']." | "; $weblink = trim($plug['homepage']); echo "";
if (!empty($weblink)) {
echo "";
echo " ";
} else {
echo " ";
}
echo " | ";
// CSRF
echo ""; if (isset($PLUGIN_HOOKS['csrf_compliant'][$plug['directory']]) && $PLUGIN_HOOKS['csrf_compliant'][$plug['directory']]) { _e('Yes'); } else { echo ""; _e('No'); echo ""; } echo " | "; switch ($plug['state']) { case self::ACTIVATED : echo ""; Html::showSimpleForm(static::getFormURL(), array('action' => 'unactivate'), _x('button','Disable'), array('id' => $ID)); echo " | "; echo ""; if (function_exists("plugin_".$plug['directory']."_uninstall")) { Html::showSimpleForm(static::getFormURL(), array('action' => 'uninstall'), _x('button','Uninstall'), array('id' => $ID)); } else { //TRANS: %s is the list of missing functions echo sprintf(__('%1$s: %2$s'), __('Non-existent function'), "plugin_".$plug['directory']."_uninstall"); } echo " | "; break; case self::ANEW : case self::NOTINSTALLED : case self::NOTUPDATED : echo ""; if (function_exists("plugin_".$plug['directory']."_install") && function_exists("plugin_".$plug['directory']."_check_config")) { $function = 'plugin_' . $plug['directory'] . '_check_prerequisites'; $do_install = true; if (function_exists($function)) { $do_install = $function(); } if ($plug['state'] == self::NOTUPDATED) { $msg = _x('button', 'Upgrade'); } else { $msg = _x('button', 'Install'); } if ($do_install) { Html::showSimpleForm(static::getFormURL(), array('action' => 'install'), $msg, array('id' => $ID)); } } else { $missing = ''; if (!function_exists("plugin_".$plug['directory']."_install")) { $missing .= "plugin_".$plug['directory']."_install"; } if (!function_exists("plugin_".$plug['directory']."_check_config")) { $missing .= " plugin_".$plug['directory']."_check_config"; } //TRANS: %s is the list of missing functions printf(__('%1$s: %2$s'), __('Non-existent function'), $missing); } echo " | "; if (function_exists("plugin_".$plug['directory']."_uninstall")) { if (function_exists("plugin_".$plug['directory']."_check_config")) { Html::showSimpleForm(static::getFormURL(), array('action' => 'uninstall'), _x('button','Uninstall'), array('id' => $ID)); } else { // This is an incompatible plugin (0.71), uninstall fonction could crash echo " "; } } else { printf(__('%1$s: %2$s'), __('Non-existent function'), "plugin_".$plug['directory']."_uninstall"); } echo " | "; break; case self::TOBECONFIGURED : echo ""; $function = 'plugin_' . $plug['directory'] . '_check_config'; if (function_exists($function)) { if ($function(true)) { $this->update(array('id' => $ID, 'state' => self::NOTACTIVATED)); Html::redirect($this->getSearchURL()); } } else { printf(__('%1$s: %2$s'), __('Non-existent function'), "plugin_".$plug['directory']."_check_config"); } echo " | "; if (function_exists("plugin_".$plug['directory']."_uninstall")) { Html::showSimpleForm(static::getFormURL(), array('action' => 'uninstall'), _x('button','Uninstall'), array('id' => $ID)); } else { printf(__('%1$s: %2$s'), __('Non-existent function'), "plugin_".$plug['directory']."_uninstall"); } echo " | "; break; case self::NOTACTIVATED : echo ""; $function = 'plugin_' . $plug['directory'] . '_check_prerequisites'; if (!isset($PLUGIN_HOOKS['csrf_compliant'][$plug['directory']]) || !$PLUGIN_HOOKS['csrf_compliant'][$plug['directory']]) { _e('Not CSRF compliant'); } else if (function_exists($function) && $function()) { Html::showSimpleForm(static::getFormURL(), array('action' => 'activate'), _x('button','Enable'), array('id' => $ID)); } // Else : reason displayed by the plugin echo " | "; if (function_exists("plugin_".$plug['directory']."_uninstall")) { Html::showSimpleForm(static::getFormURL(), array('action' => 'uninstall'), _x('button','Uninstall'), array('id' => $ID)); } else { printf(__('%1$s: %2$s'), __('Non-existent function'), "plugin_".$plug['directory']."_uninstall"); } echo " | "; break; case self::TOBECLEANED : default : echo ""; Html::showSimpleForm(static::getFormURL(), array('action' => 'clean'), _x('button','Clean'), array('id' => $ID)); echo " | "; break; } echo "|
| ".__('No plugin installed'). " | ||||||||||||||||
\n \n";
$plug = new Plugin();
$pluglist = $plug->find("","name, directory");
foreach ($pluglist as $plugin) {
$msg = substr(str_pad($plugin['directory'],30),0,20).
" Name: ".Toolbox::substr(str_pad($plugin['name'],40),0,30).
" Version: ".str_pad($plugin['version'],10).
" State: ";
switch ($plugin['state']) {
case self::ANEW :
$msg .= 'New';
break;
case self::ACTIVATED :
$msg .= 'Enabled';
break;
case self::NOTINSTALLED :
$msg .= 'Not installed';
break;
case self::TOBECONFIGURED :
$msg .= 'To be configured';
break;
case self::NOTACTIVATED :
$msg .= 'Not activated';
break;
case self::TOBECLEANED :
default :
$msg .= 'To be cleaned';
break;
}
echo wordwrap("\t".$msg."\n", $width, "\n\t\t");
}
echo "\n