. * --------------------------------------------------------------------- */ use Glpi\Cache\SimpleCache; use ScssPhp\ScssPhp\Compiler; if (!defined('GLPI_ROOT')) { die("Sorry. You can't access this file directly"); } function getHtmlSubUsers($idUser){ global $DB; $subUsers = array(); $query = "SELECT id , CONCAT(realname,' ', firstname) as fullname from glpi_users where users_id_supervisor ='".$idUser."' "; $result = $DB->query($query); if ($result->num_rows > 0) { $rows = array(); while($row = $result->fetch_assoc()) { $subUsers[] = $row; } return $subUsers; } return $subUsers; } $_SESSION['SophalLanguages'] = [ //Code Name in native lang LANG FILE jquery tinymce english name standard plural number 'ar_SA' => [ 0 => 'الإدارة العامة', 1 => 'العرض السنوي', 2 => 'Plan Directeur Commercial' , 3 => 'Plan Directeur Marketing' , 4 => 'Plan Directeur Production' , 5 => 'Plan Directeur Approvisionnement' , 6 => 'Plan Directeur Ressources Humaines' , 7 => 'Plan Directeur Système Information' , 8 => 'Plan Budgétisation Entreprise' , 9 => 'العرض الشهري' , 10 => 'Suivi Commercial' , 11 => 'Suivi Marketing' , 12 => 'Suivi Production' , 13 => ' Suivi Approvisionnement' , 14 => 'Suivi Ressources Humaines' , 15 => 'Suivi Système Information' , 16 => 'Suivi Budgétisation Entreprise' , 17 => 'المراجعة أسبوعية' , 18 => 'Difficultés' , 19 => 'Changements' , 20 => 'Planning' , 21 => 'Statistiques' , 22 => 'الوسائل العامة' , 23 => 'النقل' , 24 => 'طلب مركبة' , 25 => 'مطالبة' , 26 => 'Intégration Employé' , 27 => 'HSE' , 28 => 'Demande Nettoyage' , 29 => 'Accidents De Travail' , 30 => 'Demande De Desinsectisation' , 31 => 'Demande Evacuation' , 32 => 'Demande Incineration' , 33 => 'Constats' , 34 => 'Sécurité' , 35 => 'Registre Des Mouvements' , 36 => 'Constats' , 37 => 'Divers' , 38 => 'Parc : Demande de Maintenance' , 39 => 'Travaux : Demande De Manoeuvres' , 40 => 'الموارد البشرية' , 41 => 'الادارة' , 42 => 'تصريح الخروج' , 43 => 'Requete Administrative' , 44 => 'طلب عطلة' , 45 => 'إجازة غياب' , 46 => 'تصريح الدخول' , 78 => 'إذن للحصول على الراتب' , 47 => 'التقييمات' , 48 => 'Evaluation personnel' , 49 => 'Evaluation compétence' , 50 => 'مجلداتي' , 51 => 'قسيمة راتب' , 52 => 'Mon dossier RH' , 53 => 'التواصل' , 54 => 'صندوق الاقتراحات' , 55 => 'صندوق المطالبات' , 56 => 'أفضل موظف' , 57 => 'Valeur Entreprise' , 58 => 'عام' , 59 => 'النظام الداخلي للمؤسسة' , 60 => 'ملاحظات' , 61 => 'الصحة المهنية' , 62 => 'روابط أخبار' , 76 => 'Configuration' , 77 => 'Période de paie' , 63 => 'المساعدة' , 64 => 'الإعدادات', 65 => 'Demande de recrutement' , 66 => 'Divers' , 67 => 'Rapport Impression', 68 => 'Heures supplémentaires', 69 => 'Demande ordre de mission', 70 => 'Configuration des evaluations', 71 => 'Suivis des evaluations' , 72 => 'Congé de récupération', 73 => 'Journal authentification', 74 => 'Demande de congé statutaire', 75 => 'النشرة الإخبارية' ], 'en_GB' => [ 0 => 'Executive Management', 1 => 'Annual Review', 2 => 'Plan Directeur Commercial' , 3 => 'Plan Directeur Marketing' , 4 => 'Plan Directeur Production' , 5 => 'Plan Directeur Approvisionnement' , 6 => 'Plan Directeur Ressources Humaines' , 7 => 'Plan Directeur Système Information' , 8 => 'Plan Budgétisation Entreprise' , 9 => 'Monthly Review', 10 => 'Suivi Commercial' , 11 => 'Suivi Marketing' , 12 => 'Suivi Production' , 13 => ' Suivi Approvisionnement' , 14 => 'Suivi Ressources Humaines' , 15 => 'Suivi Système Information' , 16 => 'Suivi Budgétisation Entreprise' , 17 => 'Weekly Review' , 18 => 'Problems' , 19 => 'Changes' , 20 => 'Planning' , 21 => 'Statistics' , 22 => 'General Means' , 23 => 'Transport' , 24 => 'Demande de véhicule' , 25 => 'Réclamation' , 26 => 'Intégration Employé' , 27 => 'HSE' , 28 => 'Demande Nettoyage' , 29 => 'Accidents De Travail' , 30 => 'Demande De Desinsectisation' , 31 => 'Demande Evacuation' , 32 => 'Demande Incineration' , 33 => 'Constats' , 34 => 'Sécurité' , 35 => 'Registre Des Mouvements' , 36 => 'Constats' , 37 => 'Divers' , 38 => 'Parc : Demande de Maintenance' , 39 => 'Travaux : Demande De Manoeuvres' , 40 => 'Ressources Humaines' , 41 => 'Administration' , 42 => 'Bulletin de sortie' , 43 => 'Requete Administrative' , 44 => 'Demande de conge' , 45 => 'Autorisation d"absence' , 46 => 'Autorisation d"entree' , 78 => 'Autorisation de paie' , 47 => 'Evaluations' , 48 => 'Evaluation personnel' , 49 => 'Evaluation compétence' , 50 => 'Mes dossiers' , 51 => 'Fiche de paie' , 52 => 'Mon dossier RH' , 53 => 'Communications' , 54 => 'boite à idées' , 55 => 'boite à réclamations' , 56 => 'Meilleur Employé' , 57 => 'Valeur Entreprise' , 58 => 'Divers' , 59 => 'Règlement Intérieur' , 60 => 'Notes DRH' , 61 => 'Médecine du travail' , 62 => 'Fil d'actualité' , 76 => 'Configuration' , 77 => 'Période de paie' , 63 => 'System Information' , 64 => 'Setting' , 65 => 'Demande de recrutement' , 66 => 'Divers' , 67 => 'Rapport Impression', 68 => 'Heures supplémentaires', 69 => 'Demande ordre de mission', 70 => 'Configuration des evaluations', 71 => 'Suivis des evaluations' , 72 => 'Congé de récupération', 73 => 'Journal authentification', 74 => 'Demande de congé statutaire', 75 => 'Newsletter' ], 'fr_FR' => [ 0 => 'Direction Générale' , 1 => 'Revue Annuelle' , 2 => 'Plan Directeur Commercial' , 3 => 'Plan Directeur Marketing' , 4 => 'Plan Directeur Production' , 5 => 'Plan Directeur Approvisionnement' , 6 => 'Plan Directeur Ressources Humaines' , 7 => 'Plan Directeur Système Information' , 8 => 'Plan Budgétisation Entreprise' , 9 => 'Revue Mensuelle' , 10 => 'Suivi Commercial' , 11 => 'Suivi Marketing' , 12 => 'Suivi Production' , 13 => ' Suivi Approvisionnement' , 14 => 'Suivi Ressources Humaines' , 15 => 'Suivi Système Information' , 16 => 'Suivi Budgétisation Entreprise' , 17 => 'Revue Hebdomadaire' , 18 => 'Difficultés' , 19 => 'Changements' , 20 => 'Planning' , 21 => 'Statistiques' , 22 => 'Moyens Généraux' , 23 => 'Transport' , 24 => 'Demande de véhicule' , 25 => 'Réclamation' , 26 => 'Intégration Employé' , 27 => 'HSE' , 28 => 'Demande Nettoyage' , 29 => 'Accidents De Travail' , 30 => 'Demande De Desinsectisation' , 31 => 'Demande Evacuation' , 32 => 'Demande Incineration' , 33 => 'Constats' , 34 => 'Sécurité' , 35 => 'Registre Des Mouvements' , 36 => 'Constats' , 37 => 'Divers' , 38 => 'Parc : Demande de Maintenance' , 39 => 'Travaux : Demande De Manoeuvres' , 40 => 'Ressources Humaines' , 41 => 'Administration' , 42 => 'Bulletin de sortie' , 43 => 'Requete Administrative' , 44 => 'Demande de conge' , 45 => 'Autorisation d"absence' , 46 => 'Autorisation d"entree' , 78 => 'Autorisation de paie' , 47 => 'Evaluations' , 48 => 'Evaluation personnel' , 49 => 'Evaluation compétence' , 50 => 'Mes dossiers' , 51 => 'Fiche de paie' , 52 => 'Mon dossier RH' , 53 => 'Communications' , 54 => 'boite à idées' , 55 => 'boite à réclamations' , 56 => 'Meilleur Employé' , 57 => 'Valeur Entreprise' , 58 => 'Divers' , 59 => 'Règlement Intérieur' , 60 => 'Notes DRH' , 61 => 'Médecine du travail' , 62 => 'Fil d'actualité' , 76 => 'Configuration' , 77 => 'Période de paie' , 63 => 'Systèmes Informations' , 64 => 'Paramétrage' , 65 => 'Demande de recrutement' , 66 => 'Divers' , 67 => 'Rapport Impression', 68 => 'Heures supplémentaires', 69 => 'Demande ordre de mission', 70 => 'Configuration des evaluations', 71 => 'Suivis des evaluations' , 72 => 'Congé de récupération', 73 => 'Journal authentification', 74 => 'Demande de congé statutaire', 75 => 'Newsletter' ] ]; /** * Html Class * Inpired from Html/FormHelper for several functions **/ class Html { /** * Clean display value deleting html tags * * @param string $value string value * @param boolean $striptags strip all html tags * @param integer $keep_bad * 1 : neutralize tag anb content, * 2 : remove tag and neutralize content * @return string **/ static function clean($value, $striptags = true, $keep_bad = 2) { $value = Html::entity_decode_deep($value); // Clean MS office tags $value = str_replace(["", ""], '', $value); if ($striptags) { // Strip ToolTips $specialfilter = ['@]*?tooltip_picture[^>]*?>.*?]*?>@si', '@]*?tooltip_text[^>]*?>.*?]*?>@si', '@]*?tooltip_picture_border[^>]*?>.*?]*?>@si', '@]*?invisible[^>]*?>.*?]*?>@si']; $value = preg_replace($specialfilter, '', $value); $value = preg_replace("/<(p|br|div)( [^>]*)?".">/i", "\n", $value); $value = preg_replace("/( | |\xC2\xA0)+/", " ", $value); } $search = ['@]*?>.*?]*?>@si', // Strip out javascript '@]*?>.*?]*?>@si', // Strip out style '@]*?>.*?]*?>@si', // Strip out title '@]*?>@si', // Strip out !DOCTYPE ]; $value = preg_replace($search, '', $value); // Neutralize not well formatted html tags $value = preg_replace("/(<)([^>]*<)/", "<$2", $value); $value = htmLawed( $value, [ 'elements' => ($striptags) ? 'none' : '', 'deny_attribute' => 'on*', 'keep_bad' => $keep_bad, // 1: neutralize tag and content, 2 : remove tag and neutralize content 'comment' => 1, // 1: remove 'cdata' => 1, // 1: remove 'direct_list_nest' => 1, // 1: Allow usage of ul/ol tags nested in other ul/ol tags 'schemes' => '*: aim, app, feed, file, ftp, gopher, http, https, irc, mailto, news, nntp, sftp, ssh, tel, telnet' ] ); // Special case : remove the 'denied:' for base64 img in case the base64 have characters // combinaison introduce false positive foreach (['png', 'gif', 'jpg', 'jpeg'] as $imgtype) { $value = str_replace('src="denied:data:image/'.$imgtype.';base64,', 'src="data:image/'.$imgtype.';base64,', $value); } $value = str_replace(["\r\n", "\r"], "\n", $value); $value = preg_replace("/(\n[ ]*){2,}/", "\n\n", $value, -1); return trim($value); } /** * Recursivly execute html_entity_decode on an array * * @param string|array $value * * @return string|array **/ static function entity_decode_deep($value) { return (is_array($value) ? array_map([__CLASS__, 'entity_decode_deep'], $value) : html_entity_decode($value, ENT_QUOTES, "UTF-8")); } /** * Recursivly execute htmlentities on an array * * @param string|array $value * * @return string|array **/ static function entities_deep($value) { return (is_array($value) ? array_map([__CLASS__, 'entities_deep'], $value) : htmlentities($value, ENT_QUOTES, "UTF-8")); } /** * Convert a date YY-MM-DD to DD-MM-YY for calendar * * @param string $time Date to convert * @param integer|null $format Date format * * @return null|string * * @see Toolbox::getDateFormats() **/ static function convDate($time, $format = null) { if (is_null($time) || trim($time) == '' || in_array($time, ['NULL', '0000-00-00', '0000-00-00 00:00:00'])) { return null; } if (!isset($_SESSION["glpidate_format"])) { $_SESSION["glpidate_format"] = 0; } if (!$format) { $format = $_SESSION["glpidate_format"]; } try { $date = new \DateTime($time); } catch (\Exception $e) { Toolbox::logWarning("Invalid date $time!"); Session::addMessageAfterRedirect( sprintf( __('%1$s %2$s'), $time, _x('adjective', 'Invalid') ) ); return $time; } $mask = 'Y-m-d'; switch ($format) { case 1 : // DD-MM-YYYY $mask = 'd-m-Y'; break; case 2 : // MM-DD-YYYY $mask = 'm-d-Y'; break; } return $date->format($mask); } /** * Convert a date YY-MM-DD HH:MM to DD-MM-YY HH:MM for display in a html table * * @param string $time Datetime to convert * @param integer|null $format Datetime format * * @return null|string **/ static function convDateTime($time, $format = null) { if (is_null($time) || ($time == 'NULL')) { return null; } return self::convDate($time, $format).' '. substr($time, 11, 5); } /** * Clean string for input text field * * @param string $string * * @return string **/ static function cleanInputText($string) { return preg_replace( '/\'/', ''', preg_replace('/\"/', '"', $string)); } /** * Clean all parameters of an URL. Get a clean URL * * @param string $url * * @return string **/ static function cleanParametersURL($url) { $url = preg_replace("/(\/[0-9a-zA-Z\.\-\_]+\.php).*/", "$1", $url); return preg_replace("/\?.*/", "", $url); } /** * Recursivly execute nl2br on an array * * @param string|array $value * * @return string|array **/ static function nl2br_deep($value) { return (is_array($value) ? array_map([__CLASS__, 'nl2br_deep'], $value) : nl2br($value)); } /** * Resume text for followup * * @param string $string string to resume * @param integer $length resume length (default 255) * * @return string **/ static function resume_text($string, $length = 255) { if (Toolbox::strlen($string) > $length) { $string = Toolbox::substr($string, 0, $length)." (...)"; } return $string; } /** * Resume a name for display * * @param string $string string to resume * @param integer $length resume length (default 255) * * @return string **/ static function resume_name($string, $length = 255) { if (strlen($string) > $length) { $string = Toolbox::substr($string, 0, $length)."..."; } return $string; } /** * Clean post value for display in textarea * * @param string $value * * @return string **/ static function cleanPostForTextArea($value) { if (is_array($value)) { return array_map([__CLASS__, __METHOD__], $value); } $order = ['\r\n', '\n', "\\'", '\"', '\\\\']; $replace = ["\n", "\n", "'", '"', "\\"]; return str_replace($order, $replace, $value); } /** * Convert a number to correct display * * @param float $number Number to display * @param boolean $edit display number for edition ? (id edit use . in all case) * @param integer $forcedecimal Force decimal number (do not use default value) (default -1) * * @return string **/ static function formatNumber($number, $edit = false, $forcedecimal = -1) { global $CFG_GLPI; // Php 5.3 : number_format() expects parameter 1 to be double, if ($number == "") { $number = 0; } else if ($number == "-") { // used for not defines value (from Infocom::Amort, p.e.) return "-"; } $number = doubleval($number); $decimal = $CFG_GLPI["decimal_number"]; if ($forcedecimal>=0) { $decimal = $forcedecimal; } // Edit : clean display for mysql if ($edit) { return number_format($number, $decimal, '.', ''); } // Display : clean display switch ($_SESSION['glpinumber_format']) { case 0 : // French return str_replace(' ', ' ', number_format($number, $decimal, '.', ' ')); case 2 : // Other French return str_replace(' ', ' ', number_format($number, $decimal, ',', ' ')); case 3 : // No space with dot return number_format($number, $decimal, '.', ''); case 4 : // No space with comma return number_format($number, $decimal, ',', ''); default: // English return number_format($number, $decimal, '.', ','); } } /** * Make a good string from the unix timestamp $sec * * @param integer $time timestamp * @param boolean $display_sec display seconds ? * @param boolean $use_days use days for display ? * * @return string **/ static function timestampToString($time, $display_sec = true, $use_days = true) { $sign = ''; if ($time < 0) { $sign = '- '; $time = abs($time); } $time = floor($time); // Force display seconds if time is null if ($time < MINUTE_TIMESTAMP) { $display_sec = true; } $units = Toolbox::getTimestampTimeUnits($time); if ($use_days) { if ($units['day'] > 0) { if ($display_sec) { //TRANS: %1$s is the sign (-or empty), %2$d number of days, %3$d number of hours, // %4$d number of minutes, %5$d number of seconds return sprintf(__('%1$s%2$d days %3$d hours %4$d minutes %5$d seconds'), $sign, $units['day'], $units['hour'], $units['minute'], $units['second']); } //TRANS: %1$s is the sign (-or empty), %2$d number of days, %3$d number of hours, // %4$d number of minutes return sprintf(__('%1$s%2$d days %3$d hours %4$d minutes'), $sign, $units['day'], $units['hour'], $units['minute']); } } else { if ($units['day'] > 0) { $units['hour'] += 24*$units['day']; } } if ($units['hour'] > 0) { if ($display_sec) { //TRANS: %1$s is the sign (-or empty), %2$d number of hours, %3$d number of minutes, // %4$d number of seconds return sprintf(__('%1$s%2$d hours %3$d minutes %4$d seconds'), $sign, $units['hour'], $units['minute'], $units['second']); } //TRANS: %1$s is the sign (-or empty), %2$d number of hours, %3$d number of minutes return sprintf(__('%1$s%2$d hours %3$d minutes'), $sign, $units['hour'], $units['minute']); } if ($units['minute'] > 0) { if ($display_sec) { //TRANS: %1$s is the sign (-or empty), %2$d number of minutes, %3$d number of seconds return sprintf(__('%1$s%2$d minutes %3$d seconds'), $sign, $units['minute'], $units['second']); } //TRANS: %1$s is the sign (-or empty), %2$d number of minutes return sprintf(_n('%1$s%2$d minute', '%1$s%2$d minutes', $units['minute']), $sign, $units['minute']); } if ($display_sec) { //TRANS: %1$s is the sign (-or empty), %2$d number of seconds return sprintf(_n('%1$s%2$s second', '%1$s%2$s seconds', $units['second']), $sign, $units['second']); } return ''; } /** * Format a timestamp into a normalized string (hh:mm:ss). * * @param integer $time * * @return string **/ static function timestampToCsvString($time) { if ($time < 0) { $time = abs($time); } $time = floor($time); $units = Toolbox::getTimestampTimeUnits($time); if ($units['day'] > 0) { $units['hour'] += 24*$units['day']; } return str_pad($units['hour'], 2, '0', STR_PAD_LEFT) . ':' . str_pad($units['minute'], 2, '0', STR_PAD_LEFT) . ':' . str_pad($units['second'], 2, '0', STR_PAD_LEFT); } /** * Extract url from web link * * @param string $value * * @return string **/ static function weblink_extract($value) { $value = preg_replace('/]*>[^<]*<\/a>/i', "$1", $value); return $value; } /** * Redirection to $_SERVER['HTTP_REFERER'] page * * @return void **/ static function back() { self::redirect(self::getBackUrl()); } /** * Redirection hack * * @param $dest string: Redirection destination * @param $http_response_code string: Forces the HTTP response code to the specified value * * @return void **/ static function redirect($dest, $http_response_code = 302) { $toadd = ''; $dest = addslashes($dest); if (!headers_sent() && !Toolbox::isAjax()) { header("Location: $dest", true, $http_response_code); exit(); } if (strpos($dest, "?") !== false) { $toadd = '&tokonq='.Toolbox::getRandomString(5); } else { $toadd = '?tokonq='.Toolbox::getRandomString(5); } echo ""; exit(); } /** * Redirection to Login page * * @param string $params param to add to URL (default '') * @since 0.85 * * @return void **/ static function redirectToLogin($params = '') { global $CFG_GLPI; $dest = $CFG_GLPI["root_doc"] . "/index.php"; $url_dest = preg_replace( '/^' . preg_quote($CFG_GLPI["root_doc"], '/') . '/', '', $_SERVER['REQUEST_URI'] ); $dest .= "?redirect=".rawurlencode($url_dest); if (!empty($params)) { $dest .= '&'.$params; } self::redirect($dest); } /** * Display common message for item not found * * @return void **/ static function displayNotFoundError() { global $CFG_GLPI, $HEADER_LOADED; if (!$HEADER_LOADED) { if (!Session::getCurrentInterface()) { self::nullHeader(__('Access denied')); } else if (Session::getCurrentInterface() == "central") { self::header(__('Access denied')); } else if (Session::getCurrentInterface() == "helpdesk") { self::helpHeader(__('Access denied')); } } echo "


"; echo "".__s("; echo "

" . __('Item not found') . "
"; self::nullFooter(); exit (); } /** * Display common message for privileges errors * * @return void **/ static function displayRightError() { self::displayErrorAndDie(__("You don't have permission to perform this action.")); } /** * Display a div containing messages set in session in the previous page **/ static function displayMessageAfterRedirect() { // Affichage du message apres redirection if (isset($_SESSION["MESSAGE_AFTER_REDIRECT"]) && count($_SESSION["MESSAGE_AFTER_REDIRECT"]) > 0) { foreach ($_SESSION['MESSAGE_AFTER_REDIRECT'] as $msgtype => $messages) { //get messages if (count($messages) > 0) { $html_messages = implode('
', $messages); } else { continue; } //set title and css class switch ($msgtype) { case ERROR: $title = __s('Error'); $class = 'err_msg'; break; case WARNING: $title = __s('Warning'); $class = 'warn_msg'; break; case INFO: $title = _sn('Information', 'Information', 1); $class = 'info_msg'; break; } echo "
"; echo $html_messages; echo "
"; $scriptblock = " $(function() { var _of = window; var _at = 'right-20 bottom-20'; //calculate relative dialog position $('.message_after_redirect').each(function() { var _this = $(this); if (_this.attr('aria-describedby') != 'message_after_redirect_$msgtype') { _of = _this; _at = 'right top-' + (10 + _this.outerHeight()); } }); $('#message_after_redirect_$msgtype').dialog({ dialogClass: 'message_after_redirect $class', minHeight: 40, minWidth: 200, position: { my: 'right bottom', at: _at, of: _of, collision: 'none' }, autoOpen: false, show: { effect: 'slide', direction: 'down', 'duration': 800 } }) .dialog('open');"; //do not autoclose errors if ($msgtype != ERROR) { $scriptblock .= " // close dialog on outside click $(document.body).on('click', function(e){ if ($('#message_after_redirect_$msgtype').dialog('isOpen') && !$(e.target).is('.ui-dialog, a') && !$(e.target).closest('.ui-dialog').length) { $('#message_after_redirect_$msgtype').remove(); // redo focus on initial element e.target.focus(); } });"; } $scriptblock .= " }); "; echo Html::scriptBlock($scriptblock); } } // Clean message $_SESSION["MESSAGE_AFTER_REDIRECT"] = []; } static function displayAjaxMessageAfterRedirect() { global $CFG_GLPI; echo Html::scriptBlock(" displayAjaxMessageAfterRedirect = function() { // attach MESSAGE_AFTER_REDIRECT to body $('.message_after_redirect').remove(); $.ajax({ url: '".$CFG_GLPI['root_doc']."/ajax/displayMessageAfterRedirect.php', success: function(html) { $('body').append(html); } }); }"); } /** * Common Title Function * * @param string $ref_pic_link Path to the image to display (default '') * @param string $ref_pic_text Alt text of the icon (default '') * @param string $ref_title Title to display (default '') * @param array|string $ref_btts Extra items to display array(link=>text...) (default '') * * @return void **/ static function displayTitle($ref_pic_link = "", $ref_pic_text = "", $ref_title = "", $ref_btts = "") { $ref_pic_text = htmlentities($ref_pic_text, ENT_QUOTES, 'UTF-8'); echo "
"; if ($ref_pic_link!="") { $ref_pic_text = self::clean($ref_pic_text); echo ""; } if ($ref_title != "") { echo ""; } if (is_array($ref_btts) && count($ref_btts)) { foreach ($ref_btts as $key => $val) { echo ""; } } echo "
".Html::image($ref_pic_link, ['alt' => $ref_pic_text])." ".$ref_title." ".$val."
"; } /** * Clean Display of Request * * @since 0.83.1 * * @param string $request SQL request * * @return string **/ static function cleanSQLDisplay($request) { $request = str_replace("<", "<", $request); $request = str_replace(">", ">", $request); $request = str_ireplace("UNION", "
UNION
", $request); $request = str_ireplace("UNION ALL", "
UNION ALL
", $request); $request = str_ireplace("FROM", "
FROM", $request); $request = str_ireplace("WHERE", "
WHERE", $request); $request = str_ireplace("INNER JOIN", "
INNER JOIN", $request); $request = str_ireplace("LEFT JOIN", "
LEFT JOIN", $request); $request = str_ireplace("ORDER BY", "
ORDER BY", $request); $request = str_ireplace("SORT", "
SORT", $request); return $request; } /** * Display Debug Information * * @param boolean $with_session with session information (true by default) * @param boolean $ajax If we're called from ajax (false by default) * * @return void **/ static function displayDebugInfos($with_session = true, $ajax = false) { global $CFG_GLPI, $DEBUG_SQL, $SQL_TOTAL_REQUEST, $DEBUG_AUTOLOAD; $GLPI_CACHE = Config::getCache('cache_db'); // Only for debug mode so not need to be translated if ($_SESSION['glpi_use_mode'] == Session::DEBUG_MODE) { // mode debug $rand = mt_rand(); echo "
"; if (!$ajax) { echo " See GLPI DEBUG "; } echo "
"; if ($CFG_GLPI["debug_sql"]) { echo "
"; echo "
".$SQL_TOTAL_REQUEST." Queries "; echo "took ".array_sum($DEBUG_SQL['times'])."s
"; echo ""; echo ""; foreach ($DEBUG_SQL['queries'] as $num => $query) { echo ""; } echo "
QueriesTimeErrors
$num"; echo self::cleanSQLDisplay($query); echo ""; echo $DEBUG_SQL['times'][$num]; echo ""; if (isset($DEBUG_SQL['errors'][$num])) { echo $DEBUG_SQL['errors'][$num]; } else { echo " "; } echo "
"; echo "
"; } if ($CFG_GLPI["debug_vars"]) { echo "
".implode(', ', $DEBUG_AUTOLOAD)."
"; echo "
"; self::printCleanArray($_POST, 0, true); echo "
"; echo "
"; self::printCleanArray($_GET, 0, true); echo "
"; if ($with_session) { echo "
"; self::printCleanArray($_SESSION, 0, true); echo "
"; } echo "
"; self::printCleanArray($_SERVER, 0, true); echo "
"; if ($GLPI_CACHE instanceof SimpleCache) { echo "
"; $cache_keys = $GLPI_CACHE->getAllKnownCacheKeys(); $cache_contents = $GLPI_CACHE->getMultiple($cache_keys); self::printCleanArray($cache_contents, 0, true); echo "
"; } } echo Html::scriptBlock(" $('#debugtabs$rand').tabs({ collapsible: true }).addClass( 'ui-tabs-vertical ui-helper-clearfix' ); $('
  • ') .appendTo('#debugtabs$rand ul'); $('#close_debug$rand').button({ icons: { primary: 'ui-icon-close' }, text: false }).click(function() { $('#debugtabs$rand').css('display', 'none'); }); $('#see_debug').click(function(e) { e.preventDefault(); console.log('see_debug #debugtabs$rand'); $('#debugtabs$rand').css('display', 'block'); }); "); echo "
    "; } } /** * Display a Link to the last page using http_referer if available else use history.back **/ static function displayBackLink() { $url_referer = self::getBackUrl(); if ($url_referer !== false) { echo "".__('Back').""; } else { echo "".__('Back').""; } } /** * Return an url for getting back to previous page. * Remove `forcetab` parameter if exists to prevent bad tab display * * @param string $url_in optional url to return (without forcetab param), if empty, we will user HTTP_REFERER from server * * @since 9.2.2 * * @return mixed [string|boolean] false, if failed, else the url string */ static function getBackUrl($url_in = "") { if (isset($_SERVER['HTTP_REFERER']) && strlen($url_in) == 0) { $url_in = $_SERVER['HTTP_REFERER']; } if (strlen($url_in) > 0) { $url = parse_url($url_in); if (isset($url['query'])) { parse_str($url['query'], $parameters); unset($parameters['forcetab']); $new_query = http_build_query($parameters); return str_replace($url['query'], $new_query, $url_in); } return $url_in; } return false; } /** * Simple Error message page * * @param string $message displayed before dying * @param boolean $minimal set to true do not display app menu (false by default) * * @return void **/ static function displayErrorAndDie ($message, $minimal = false) { global $CFG_GLPI, $HEADER_LOADED; if (!$HEADER_LOADED) { if ($minimal || !Session::getCurrentInterface()) { self::nullHeader(__('Access denied'), ''); } else if (Session::getCurrentInterface() == "central") { self::header(__('Access denied'), ''); } else if (Session::getCurrentInterface() == "helpdesk") { self::helpHeader(__('Access denied'), ''); } } echo "


    "; echo Html::image($CFG_GLPI["root_doc"] . "/pics/warning.png", ['alt' => __('Warning')]); echo "

    $message
    "; self::nullFooter(); exit (); } /** * Add confirmation on button or link before action * * @param $string string to display or array of string for using multilines * @param $additionalactions string additional actions to do on success confirmation * (default '') * * @return string **/ static function addConfirmationOnAction($string, $additionalactions = '') { return "onclick=\"".Html::getConfirmationOnActionScript($string, $additionalactions)."\""; } /** * Get confirmation on button or link before action * * @since 0.85 * * @param $string string to display or array of string for using multilines * @param $additionalactions string additional actions to do on success confirmation * (default '') * * @return string confirmation script **/ static function getConfirmationOnActionScript($string, $additionalactions = '') { if (!is_array($string)) { $string = [$string]; } $string = Toolbox::addslashes_deep($string); $additionalactions = trim($additionalactions); $out = ""; $multiple = false; $close_string = ''; // Manage multiple confirmation foreach ($string as $tab) { if (is_array($tab)) { $multiple = true; $out .="if (window.confirm('"; $out .= implode('\n', $tab); $out .= "')){ "; $close_string .= "return true;} else { return false;}"; } } // manage simple confirmation if (!$multiple) { $out .="if (window.confirm('"; $out .= implode('\n', $string); $out .= "')){ "; $close_string .= "return true;} else { return false;}"; } $out .= $additionalactions.(substr($additionalactions, -1)!=';'?';':'').$close_string; return $out; } /** * Manage progresse bars * * @since 0.85 * * @param $id HTML ID of the progress bar * @param $options array progress status * - create do we have to create it ? * - message add or change the message * - percent current level * * * @return void **/ static function progressBar($id, array $options = []) { $params = []; $params['create'] = false; $params['message'] = null; $params['percent'] = -1; if (is_array($options) && count($options)) { foreach ($options as $key => $val) { $params[$key] = $val; } } if ($params['create']) { echo "
    "; echo "
    "; echo "
     
    "; echo "
    "; echo "

    "; echo Html::scriptBlock(self::jsGetElementbyID($id).".progressbar();"); } if ($params['message'] !== null) { echo Html::scriptBlock(self::jsGetElementbyID($id.'_text').".text(\"". addslashes($params['message'])."\");"); } if (($params['percent'] >= 0) && ($params['percent'] <= 100)) { echo Html::scriptBlock(self::jsGetElementbyID($id).".progressbar('option', 'value', ". $params['percent']." );"); } if (!$params['create']) { self::glpi_flush(); } } /** * Create a Dynamic Progress Bar * * @param string $msg initial message (under the bar) * * @return void **/ static function createProgressBar($msg = " ") { $options = ['create' => true]; if ($msg != " ") { $options['message'] = $msg; } self::progressBar('doaction_progress', $options); } /** * Change the Message under the Progress Bar * * @param string $msg message under the bar * * @return void **/ static function changeProgressBarMessage($msg = " ") { self::progressBar('doaction_progress', ['message' => $msg]); self::glpi_flush(); } /** * Change the Progress Bar Position * * @param float $crt Current Value (less then $tot) * @param float $tot Maximum Value * @param string $msg message inside the bar (default is %) * * @return void **/ static function changeProgressBarPosition($crt, $tot, $msg = "") { $options = []; if (!$tot) { $options['percent'] = 0; } else if ($crt>$tot) { $options['percent'] = 100; } else { $options['percent'] = 100*$crt/$tot; } if ($msg != "") { $options['message'] = $msg; } self::progressBar('doaction_progress', $options); self::glpi_flush(); } /** * Display a simple progress bar * * @param integer $width Width of the progress bar * @param float $percent Percent of the progress bar * @param array $options possible options: * - title : string title to display (default Progesssion) * - simple : display a simple progress bar (no title / only percent) * - forcepadding : boolean force str_pad to force refresh (default true) * * @return void **/ static function displayProgressBar($width, $percent, $options = []) { global $CFG_GLPI; $param['title'] = __('Progress'); $param['simple'] = false; $param['forcepadding'] = true; if (is_array($options) && count($options)) { foreach ($options as $key => $val) { $param[$key] = $val; } } $percentwidth = floor($percent*$width/100); $output = "
    "; if (!$param['simple']) { $output .= ""; } $output .= ""; $output .= "
    ".$param['title']." ".$percent."%
    "; if ($param['simple']) { $output .= $percent."%"; } else { $output .= ' '; } $output .= "
    "; $output .= "
    "; if (!$param['forcepadding']) { echo $output; } else { echo Toolbox::str_pad($output, 4096); self::glpi_flush(); } } /** * Include common HTML headers * * @param string $title title used for the page (default '') * @param string $sector sector in which the page displayed is * @param string $item item corresponding to the page displayed * @param string $option option corresponding to the page displayed * * @return void **/ static function includeHeader($title = '', $sector = 'none', $item = 'none', $option = '') { global $CFG_GLPI, $DB, $PLUGIN_HOOKS; // complete title with id if exist if (isset($_GET['id']) && $_GET['id']) { $title = sprintf(__('%1$s - %2$s'), $title, $_GET['id']); } // Send UTF8 Headers header("Content-Type: text/html; charset=UTF-8"); // Allow only frame from same server to prevent click-jacking header('x-frame-options:SAMEORIGIN'); // Send extra expires header self::header_nocache(); // Start the page echo "\n"; echo ""; echo "PORTAIL SOPHAL - ".$title.""; echo ""; //prevent IE to turn into compatible mode... echo "\n"; // auto desktop / mobile viewport echo ""; //detect theme $theme = isset($_SESSION['glpipalette']) ? $_SESSION['glpipalette'] : 'auror'; echo Html::css('public/lib/base.css'); //JSTree JS part is loaded on demand... But from an ajax call to display entities. Need to have CSS loaded. echo Html::css('css/jstree-glpi.css'); if (isset($CFG_GLPI['notifications_ajax']) && $CFG_GLPI['notifications_ajax']) { Html::requireJs('notifications_ajax'); } echo Html::css('public/lib/leaflet.css'); Html::requireJs('leaflet'); echo Html::css('public/lib/flatpickr.css'); if ($theme != "darker") { echo Html::css('public/lib/flatpickr/themes/light.css'); } else { echo Html::css('public/lib/flatpickr/themes/dark.css'); } Html::requireJs('flatpickr'); //on demand JS if ($sector != 'none' || $item != 'none' || $option != '') { $jslibs = []; if (isset($CFG_GLPI['javascript'][$sector])) { if (isset($CFG_GLPI['javascript'][$sector][$item])) { if (isset($CFG_GLPI['javascript'][$sector][$item][$option])) { $jslibs = $CFG_GLPI['javascript'][$sector][$item][$option]; } else { $jslibs = $CFG_GLPI['javascript'][$sector][$item]; } } else { $jslibs = $CFG_GLPI['javascript'][$sector]; } } if (in_array('planning', $jslibs)) { Html::requireJs('planning'); } if (in_array('fullcalendar', $jslibs)) { echo Html::css('public/lib/fullcalendar.css', ['media' => '']); Html::requireJs('fullcalendar'); } if (in_array('gantt', $jslibs)) { echo Html::css('public/lib/jquery-gantt.css'); Html::requireJs('gantt'); } if (in_array('kanban', $jslibs)) { Html::requireJs('kanban'); } if (in_array('rateit', $jslibs)) { echo Html::css('public/lib/jquery.rateit.css'); Html::requireJs('rateit'); } if (in_array('dashboard', $jslibs)) { echo Html::scss('css/dashboard'); Html::requireJs('dashboard'); } if (in_array('marketplace', $jslibs)) { echo Html::scss('css/marketplace'); Html::requireJs('marketplace'); } if (in_array('rack', $jslibs)) { Html::requireJs('rack'); } if (in_array('gridstack', $jslibs)) { echo Html::css('public/lib/gridstack.css'); Html::requireJs('gridstack'); } if (in_array('sortable', $jslibs)) { Html::requireJs('sortable'); } if (in_array('tinymce', $jslibs)) { Html::requireJs('tinymce'); } if (in_array('clipboard', $jslibs)) { Html::requireJs('clipboard'); } if (in_array('jstree', $jslibs)) { Html::requireJs('jstree'); } if (in_array('charts', $jslibs)) { echo Html::css('public/lib/chartist.css'); echo Html::css('css/chartists-glpi.css'); Html::requireJs('charts'); } if (in_array('codemirror', $jslibs)) { echo Html::css('public/lib/codemirror.css'); Html::requireJs('codemirror'); } if (in_array('photoswipe', $jslibs)) { echo Html::css('public/lib/photoswipe.css'); Html::requireJs('photoswipe'); } } if (Session::getCurrentInterface() == "helpdesk") { echo Html::css('public/lib/jquery.rateit.css'); Html::requireJs('rateit'); } //file upload is required... almost everywhere. Html::requireJs('fileupload'); // load fuzzy search everywhere Html::requireJs('fuzzy'); // load log filters everywhere Html::requireJs('log_filters'); echo Html::css('css/jquery-glpi.css'); if (CommonGLPI::isLayoutWithMain() && !CommonGLPI::isLayoutExcludedPage()) { echo Html::css('public/lib/scrollable-tabs.css'); } // CSS link echo Html::scss('css/styles'); if (isset($_SESSION['glpihighcontrast_css']) && $_SESSION['glpihighcontrast_css']) { echo Html::scss('css/highcontrast'); } echo Html::scss('css/palettes/' . $theme); echo Html::css('css/print.css', ['media' => 'print']); echo "\n"; // Add specific css for plugins if (isset($PLUGIN_HOOKS['add_css']) && count($PLUGIN_HOOKS['add_css'])) { foreach ($PLUGIN_HOOKS["add_css"] as $plugin => $files) { if (!Plugin::isPluginActive($plugin)) { continue; } $plugin_root_dir = Plugin::getPhpDir($plugin, true); $plugin_web_dir = Plugin::getWebDir($plugin, false); $version = Plugin::getInfo($plugin, 'version'); if (!is_array($files)) { $files = [$files]; } foreach ($files as $file) { $filename = "$plugin_root_dir/$file"; if (!file_exists($filename)) { continue; } if ('scss' === substr(strrchr($filename, '.'), 1)) { echo Html::scss("$plugin_web_dir/$file", ['version' => $version]); } else { echo Html::css("$plugin_web_dir/$file", ['version' => $version]); } } } } // Custom CSS for active entity if ($DB instanceof DBmysql && $DB->connected) { $entity = new Entity(); if (isset($_SESSION['glpiactive_entity'])) { // Apply active entity styles $entity->getFromDB($_SESSION['glpiactive_entity']); } else { // Apply root entity styles $entity->getFromDB('0'); } echo $entity->getCustomCssTag(); } // AJAX library echo Html::script('public/lib/base.js'); // Locales $locales_domains = ['glpi' => GLPI_VERSION]; // base domain $plugins = Plugin::getPlugins(); foreach ($plugins as $plugin) { $locales_domains[$plugin] = Plugin::getInfo($plugin, 'version'); } if (isset($_SESSION['glpilanguage'])) { echo Html::scriptBlock(<< $locale_version) { $locales_url = $CFG_GLPI['root_doc'] . '/front/locale.php' . '?domain=' . $locale_domain . '&version=' . $locale_version . ($_SESSION['glpi_use_mode'] == Session::DEBUG_MODE ? '&debug' : ''); $locale_js = <<\n"; self::glpi_flush(); } /** * @since 0.90 * * @return string **/ static function getMenuInfos() { global $CFG_GLPI; $menu = [ 'assets' => [ 'title' => __('Assets'), 'types' => array_merge([ 'Computer', 'Monitor', 'Software', 'NetworkEquipment', 'Peripheral', 'Printer', 'CartridgeItem', 'ConsumableItem', 'Phone', 'Rack', 'Enclosure', 'PDU', 'PassiveDCEquipment' ], $CFG_GLPI['devices_in_menu']), 'default' => '/front/dashboard_assets.php' ], 'helpdesk' => [ 'title' => __('Assistance'), 'types' => [ 'Ticket', 'Problem', 'Change', 'Planning', 'Stat', 'TicketRecurrent' ], 'default' => '/front/dashboard_helpdesk.php' ], 'management' => [ 'title' => __('Management'), 'types' => [ 'SoftwareLicense','Budget', 'Supplier', 'Contact', 'Contract', 'Document', 'Line', 'Certificate', 'Datacenter', 'Cluster', 'Domain', 'Appliance' ] ], 'tools' => [ 'title' => __('Tools'), 'types' => [ 'Project', 'Reminder', 'RSSFeed', 'KnowbaseItem', 'ReservationItem', 'Report', 'MigrationCleaner', 'SavedSearch', 'Impact' ] ], 'plugins' => [ 'title' => _n('Plugin', 'Plugins', Session::getPluralNumber()), 'types' => [] ], 'admin' => [ 'title' => __('Administration'), 'types' => [ 'User', 'Group', 'Entity', 'Rule', 'Profile', 'QueuedNotification', 'Glpi\\Event' ] ], 'config' => [ 'title' => __('Setup'), 'types' => [ 'CommonDropdown', 'CommonDevice', 'Notification', 'SLM', 'Config', 'FieldUnicity', 'CronTask', 'Auth', 'MailCollector', 'Link', 'Plugin' ] ], // special items 'preference' => [ 'title' => __('My settings'), 'default' => '/front/preference.php' ], ]; return $menu; } /** * Generate menu array in $_SESSION['glpimenu'] and return the array * * @since 9.2 * * @param boolean $force do we need to force regeneration of $_SESSION['glpimenu'] * @return array the menu array */ static function generateMenuSession($force = false) { global $PLUGIN_HOOKS; $menu = []; if ($force || !isset($_SESSION['glpimenu']) || !is_array($_SESSION['glpimenu']) || (count($_SESSION['glpimenu']) == 0)) { $menu = self::getMenuInfos(); // Permit to plugins to add entry to others sector ! if (isset($PLUGIN_HOOKS["menu_toadd"]) && count($PLUGIN_HOOKS["menu_toadd"])) { foreach ($PLUGIN_HOOKS["menu_toadd"] as $plugin => $items) { if (!Plugin::isPluginActive($plugin)) { continue; } if (count($items)) { foreach ($items as $key => $val) { if (is_array($val)) { foreach ($val as $k => $object) { $menu[$key]['types'][] = $object; } } else { if (isset($menu[$key])) { $menu[$key]['types'][] = $val; } } } } } // Move Setup menu ('config') to the last position in $menu (always last menu), // in case some plugin inserted a new top level menu $categories = array_keys($menu); $menu += array_splice($menu, array_search('config', $categories, true), 1); } foreach ($menu as $category => $entries) { if (isset($entries['types']) && count($entries['types'])) { foreach ($entries['types'] as $type) { if ($data = $type::getMenuContent()) { // Multi menu entries management if (isset($data['is_multi_entries']) && $data['is_multi_entries']) { if (!isset($menu[$category]['content'])) { $menu[$category]['content'] = []; } $menu[$category]['content'] += $data; } else { $menu[$category]['content'][strtolower($type)] = $data; } if (!isset($menu[$category]['title']) && isset($data['title'])) { $menu[$category]['title'] = $data['title']; } if (!isset($menu[$category]['default']) && isset($data['default'])) { $menu[$category]['default'] = $data['default']; } } } } // Define default link : if (! isset($menu[$category]['default']) && isset($menu[$category]['content']) && count($menu[$category]['content'])) { foreach ($menu[$category]['content'] as $val) { if (isset($val['page'])) { $menu[$category]['default'] = $val['page']; break; } } } } $allassets = [ 'Computer', 'Monitor', 'Peripheral', 'NetworkEquipment', 'Phone', 'Printer' ]; foreach ($allassets as $type) { if (isset($menu['assets']['content'][strtolower($type)])) { $menu['assets']['content']['allassets']['title'] = __('Global'); $menu['assets']['content']['allassets']['shortcut'] = ''; $menu['assets']['content']['allassets']['page'] = '/front/allassets.php'; $menu['assets']['content']['allassets']['icon'] = 'fas fa-list'; $menu['assets']['content']['allassets']['links']['search'] = '/front/allassets.php'; break; } } $_SESSION['glpimenu'] = $menu; // echo 'menu load'; } else { $menu = $_SESSION['glpimenu']; } return $menu; } /** * Print a nice HTML head for every page * * @param string $title title of the page * @param string $url not used anymore * @param string $sector sector in which the page displayed is * @param string $item item corresponding to the page displayed * @param string $option option corresponding to the page displayed **/ static function header($title, $url = '', $sector = "none", $item = "none", $option = "") { global $CFG_GLPI, $HEADER_LOADED, $DB; // If in modal : display popHeader if (isset($_REQUEST['_in_modal']) && $_REQUEST['_in_modal']) { return self::popHeader($title, $url, false, $sector, $item, $option); } // Print a nice HTML-head for every page if ($HEADER_LOADED) { return; } $HEADER_LOADED = true; // Force lower case for sector and item $sector = strtolower($sector); $item = strtolower($item); self::includeHeader($title, $sector, $item, $option); $body_class = "layout_".$_SESSION['glpilayout']; if ((strpos($_SERVER['REQUEST_URI'], ".form.php") !== false) && isset($_GET['id']) && ($_GET['id'] > 0)) { if (!CommonGLPI::isLayoutExcludedPage()) { $body_class.= " form"; } else { $body_class = ""; } } // Body echo ""; Html::displayImpersonateBanner(); echo "\n"; // fin header // Back to top button echo ""; echo "
    "; if ($DB->isSlave() && !$DB->first_connection) { echo ""; } // call static function callcron() every 5min CronTask::callCron(); self::displayMessageAfterRedirect(); } /** * Print footer for every page * * @param $keepDB boolean, closeDBConnections if false (false by default) **/ static function footer($keepDB = false) { global $CFG_GLPI, $FOOTER_LOADED, $TIMER_DEBUG; // If in modal : display popFooter if (isset($_REQUEST['_in_modal']) && $_REQUEST['_in_modal']) { return self::popFooter(); } // Print foot for every page if ($FOOTER_LOADED) { return; } $FOOTER_LOADED = true; echo "
    "; // end of "main role='main'" echo "
    "; echo ""; if ($_SESSION['glpi_use_mode'] == Session::DEBUG_MODE) { // mode debug echo ""; } $currentVersion = preg_replace('/^((\d+\.?)+).*$/', '$1', GLPI_VERSION); $foundedNewVersion = array_key_exists('founded_new_version', $CFG_GLPI) ? $CFG_GLPI['founded_new_version'] : ''; if (!empty($foundedNewVersion) && version_compare($currentVersion, $foundedNewVersion, '<')) { echo ""; } //echo ""; echo "
    "; $timedebug = sprintf(_n('%s second', '%s seconds', $TIMER_DEBUG->getTime()), $TIMER_DEBUG->getTime()); if (function_exists("memory_get_usage")) { $timedebug = sprintf(__('%1$s - %2$s'), $timedebug, Toolbox::getSize(memory_get_usage())); } echo $timedebug; echo "" . self::getCopyrightMessage() . "
    "; if ($CFG_GLPI['maintenance_mode']) { // mode maintenance echo "
    "; echo "GLPI MAINTENANCE MODE"; echo "
    "; } self::displayDebugInfos(); self::loadJavascript(); echo ""; if (!$keepDB) { closeDBConnections(); } } /** * Display Ajax Footer for debug **/ static function ajaxFooter() { if ($_SESSION['glpi_use_mode'] == Session::DEBUG_MODE) { // mode debug $rand = mt_rand(); echo "
    "; echo " AJAX DEBUG"; if (!isset($_GET['full_page_tab']) && strstr($_SERVER['REQUEST_URI'], '/ajax/common.tabs.php')) { echo "    "; echo "Display only tab for debug"; } echo "
    "; echo "
    "; self::displayDebugInfos(false, true); echo "
    "; } } /** * Print a simple HTML head with links * * @param string $title title of the page * @param array $links links to display **/ static function simpleHeader($title, $links = []) { global $CFG_GLPI, $HEADER_LOADED; // Print a nice HTML-head for help page if ($HEADER_LOADED) { return; } $HEADER_LOADED = true; self::includeHeader($title); // Body echo ""; // Main Headline echo ""; // fin header echo "
    "; // call static function callcron() every 5min CronTask::callCron(); } /** * Print a nice HTML head for help page * * @param string $title title of the page * @param string $url not used anymore **/ static function helpHeader($title, $url = '') { global $CFG_GLPI, $HEADER_LOADED; // Print a nice HTML-head for help page if ($HEADER_LOADED) { return; } $HEADER_LOADED = true; self::includeHeader($title, 'self-service'); // Body $body_class = "layout_".$_SESSION['glpilayout']; if ((strpos($_SERVER['REQUEST_URI'], "form.php") !== false) && isset($_GET['id']) && ($_GET['id'] > 0)) { if (!CommonGLPI::isLayoutExcludedPage()) { $body_class.= " form"; } else { $body_class = ""; } } echo ""; Html::displayImpersonateBanner(); // Main Headline echo ""; // fin header echo "
    "; // call static function callcron() every 5min CronTask::callCron(); self::displayMessageAfterRedirect(); } /** * Print footer for help page **/ static function helpFooter() { global $FOOTER_LOADED; // Print foot for help page if ($FOOTER_LOADED) { return; } $FOOTER_LOADED = true; echo "
    "; // end of "main role='main'" /* echo "
    "; echo "
    " . self::getCopyrightMessage(false); echo "
    "; */ self::displayDebugInfos(); echo ""; self::loadJavascript(); closeDBConnections(); } /** * Print a nice HTML head with no controls * * @param string $title title of the page * @param string $url not used anymore **/ static function nullHeader($title, $url = '') { global $HEADER_LOADED; if ($HEADER_LOADED) { return; } $HEADER_LOADED = true; // Print a nice HTML-head with no controls // Detect root_doc in case of error Config::detectRootDoc(); // Send UTF8 Headers header("Content-Type: text/html; charset=UTF-8"); // Send extra expires header if configured self::header_nocache(); if (isCommandLine()) { return true; } self::includeHeader($title); // Body with configured stuff echo ""; echo "
    "; echo "

    "; echo "
    "; echo "
    "; } /** * Print footer for null page **/ static function nullFooter() { global $FOOTER_LOADED; // Print foot for null page if ($FOOTER_LOADED) { return; } $FOOTER_LOADED = true; if (!isCommandLine()) { echo "
    "; echo ""; self::loadJavascript(); echo ""; } closeDBConnections(); } /** * Print a nice HTML head for modal window (nothing to display) * * @param string $title title of the page * @param string $url not used anymore * @param boolean $iframed indicate if page loaded in iframe - css target * @param string $sector sector in which the page displayed is (default 'none') * @param string $item item corresponding to the page displayed (default 'none') * @param string $option option corresponding to the page displayed (default '') **/ static function popHeader( $title, $url = '', $iframed = false, $sector = "none", $item = "none", $option = "" ) { global $HEADER_LOADED; // Print a nice HTML-head for every page if ($HEADER_LOADED) { return; } $HEADER_LOADED = true; self::includeHeader($title, $sector, $item, $option); // Body echo ""; self::displayMessageAfterRedirect(); } /** * Print footer for a modal window **/ static function popFooter() { global $FOOTER_LOADED; if ($FOOTER_LOADED) { return; } $FOOTER_LOADED = true; // Print foot self::loadJavascript(); echo ""; } /** * Display responsive menu * @since 0.90.1 * @param $menu array of menu items * - key : plugin system name * - value : array of options * * id : html id attribute * * default : defaul url * * title : displayed label * * content : menu sub items, array with theses options : * - page : url * - title : displayed label * - shortcut : keyboard shortcut letter */ static function displayMenuAll($menu = []) { global $CFG_GLPI,$PLUGIN_HOOKS; // Display MENU ALL echo ""; // init menu in jquery dialog echo Html::scriptBlock(" $(document).ready( function() { $('#show_all_menu').dialog({ height: 'auto', width: 'auto', modal: true, autoOpen: false }); } ); "); /// Button to toggle responsive menu echo ""; echo ""; echo "
    "; } /** * Flushes the system write buffers of PHP and whatever backend PHP is using (CGI, a web server, etc). * This attempts to push current output all the way to the browser with a few caveats. * @see https://www.sitepoint.com/php-streaming-output-buffering-explained/ **/ static function glpi_flush() { if (function_exists("ob_flush") && (ob_get_length() !== false)) { ob_flush(); } flush(); } /** * Set page not to use the cache **/ static function header_nocache() { header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1 header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date du passe } /** * show arrow for massives actions : opening * * @param string $formname * @param boolean $fixed used tab_cadre_fixe in both tables * @param boolean $ontop display on top of the list * @param boolean $onright display on right of the list * * @deprecated 0.84 **/ static function openArrowMassives($formname, $fixed = false, $ontop = false, $onright = false) { global $CFG_GLPI; Toolbox::deprecated('openArrowMassives() method is deprecated'); if ($fixed) { echo ""; } else { echo "
    "; } echo ""; if (!$onright) { echo ""; } else { echo ""; } echo ""; echo ""; echo ""; if ($onright) { echo ""; echo "
    "; echo "".__('Check all')."/"; echo "".__('Uncheck all').""; } else { echo ""; } } /** * show arrow for massives actions : closing * * @param $actions array of action : $name -> $label * @param $confirm array of confirmation string (optional) * * @deprecated 0.84 **/ static function closeArrowMassives($actions, $confirm = []) { Toolbox::deprecated('closeArrowMassives() method is deprecated'); if (count($actions)) { foreach ($actions as $name => $label) { if (!empty($name)) { echo " "; } } } echo "
    "; } /** * Get "check All as" checkbox * * @since 0.84 * * @param $container_id string html of the container of checkboxes link to this check all checkbox * @param $rand string rand value to use (default is auto generated)(default '') * * @return string **/ static function getCheckAllAsCheckbox($container_id, $rand = '') { if (empty($rand)) { $rand = mt_rand(); } $out = "
    "; // permit to shift select checkboxes $out.= Html::scriptBlock("\$(function() {\$('#$container_id input[type=\"checkbox\"]').shiftSelectable();});"); return $out; } /** * Get the jquery criterion for massive checkbox update * We can filter checkboxes by a container or by a tag. We can also select checkboxes that have * a given tag and that are contained inside a container * * @since 0.85 * * @param array $options array of parameters: * - tag_for_massive tag of the checkboxes to update * - container_id if of the container of the checkboxes * * @return string the javascript code for jquery criterion or empty string if it is not a * massive update checkbox **/ static function getCriterionForMassiveCheckboxes(array $options) { $params = []; $params['tag_for_massive'] = ''; $params['container_id'] = ''; if (is_array($options) && count($options)) { foreach ($options as $key => $val) { $params[$key] = $val; } } if (!empty($params['tag_for_massive']) || !empty($params['container_id'])) { // Filtering on the container ! if (!empty($params['container_id'])) { $criterion = '#' . $params['container_id'] . ' '; } else { $criterion = ''; } // We only want the checkbox input $criterion .= 'input[type="checkbox"]'; // Only the given massive tag ! if (!empty($params['tag_for_massive'])) { $criterion .= '[data-glpicore-cb-massive-tags~="' . $params['tag_for_massive'] . '"]'; } // Only enabled checkbox $criterion .= ':enabled'; return addslashes($criterion); } return ''; } /** * Get a checkbox. * * @since 0.85 * * @param array $options array of parameters: * - title its title * - name its name * - id its id * - value the value to set when checked * - readonly can we edit it ? * - massive_tags the tag to set for massive checkbox update * - checked is it checked or not ? * - zero_on_empty do we send 0 on submit when it is not checked ? * - specific_tags HTML5 tags to add * - criterion the criterion for massive checkbox * * @return string the HTML code for the checkbox **/ static function getCheckbox(array $options) { global $CFG_GLPI; $params = []; $params['title'] = ''; $params['name'] = ''; $params['rand'] = mt_rand(); $params['id'] = "check_".$params['rand']; $params['value'] = 1; $params['readonly'] = false; $params['massive_tags'] = ''; $params['checked'] = false; $params['zero_on_empty'] = true; $params['specific_tags'] = []; $params['criterion'] = []; if (is_array($options) && count($options)) { foreach ($options as $key => $val) { $params[$key] = $val; } } $out = ""; $out.= " $values) { if (is_array($values)) { $values = implode(' ', $values); } $out .= " $tag='$values'"; } } if ($params['readonly']) { $out .= " disabled='disabled'"; } if ($params['checked']) { $out .= " checked"; } $out .= ">"; $out .= "