. * */ defined('APP_ROOT') || die(_('No es posible acceder directamente a este archivo')); /** * Esta clase es la encargada de mostrar el HTML */ class SP_Html { public static $htmlBodyOpts = ""; private static $htmlPage = array(); /** * Crear un elemento del tipo SELECT. * Esta función genera un elemento SELECT con las propiedades y valores pasados. * * @param array $arrValues con los valores del select * @param array $arrSelectProp con las propiedades del select * @param bool $useValue para usar el Id como valor * @return none */ public static function printSelect($arrValues, $arrSelectProp, $useValue = true) { if (!is_array($arrSelectProp)) { return; } $strAttrs = (is_array($arrSelectProp["attribs"])) ? implode(" ", $arrSelectProp["attribs"]) : ""; $strClass = ($arrSelectProp["class"]) ? 'class="' . $arrSelectProp["class"] . '"' : ""; if (!is_array($arrValues)) { echo ''; echo ''; return; } if ($arrSelectProp["label"]) { echo ''; } echo ''; } /** * Mostrar la página HTML. * Esta función es la encargada de devolver el código HTML al navegador. * * @param string $page opcional con la página a mostar * @param array $err con los errores generados * @return none */ public static function render($page = "main", $err = NULL) { $data['showlogo'] = 1; // UTF8 Headers header("Content-Type: text/html; charset=UTF-8"); // Cache Control header("Cache-Control: public, no-cache, max-age=0, must-revalidate"); header("Pragma: public; max-age=0"); if (!is_null($err) && is_array($err) && count($err) > 0) { $data['errors'] = $err; } // Start the page self::$htmlPage[] = ''; self::$htmlPage[] = ''; self::makeHeader(); self::makeBody($page); self::$htmlPage[] = ''; foreach (self::$htmlPage as $html) { if (is_array($html) && array_key_exists('include', $html)) { self::getTemplate($html['include'], $data); } else { echo $html . PHP_EOL; } } } /** * Crear el header en HTML. * Esta función crea la cabecera de una página HTML * * @return none */ private static function makeHeader() { $info = self::getAppInfo(); self::$htmlPage[] = ''; self::$htmlPage[] = '' . $info['appname'] . ' :: ' . $info['appdesc'] . ''; self::$htmlPage[] = ''; self::$htmlPage[] = ''; self::setCss(); self::setJs(); self::$htmlPage[] = ''; } /** * Devuelve información sobre la aplicación. * * @param string $index con la key a devolver * @return array con las propiedades de la aplicación */ public static function getAppInfo($index = NULL) { $appinfo = array( 'appname' => 'sysPass', 'appdesc' => 'Systems Password Manager', 'appwebsite' => 'http://www.syspass.org', 'appblog' => 'http://www.cygnux.org', 'appdoc' => 'http://wiki.syspass.org', 'appupdates' => 'http://sourceforge.net/api/file/index/project-id/775555/mtime/desc/limit/20/rss', 'apphelp' => 'help.syspass.org', 'appchangelog' => ''); if (!is_null($index) && array_key_exists($index, $appinfo)) { return $appinfo[$index]; } return $appinfo; } /** * Establece los enlaces CSS de la página HTML. * * @return none */ public static function setCss() { $visualStyle = SP_Util::resultsCardsIsEnabled(); $versionParameter = md5(implode(SP_Util::getVersion()) . $visualStyle); self::$htmlPage[] = ''; } /** * Establece los enlaces JAVASCRIPT de la página HTML. * * @return none */ public static function setJs() { $versionParameter = md5(implode(SP_Util::getVersion())); self::$htmlPage[] = ''; } /** * Crear el body en HTML. * Esta función crea el cuerpo de una página HTML * * @param string $page con la página a cargar * @return none */ private static function makeBody($page) { self::$htmlPage[] = ''; self::$htmlPage[] = '
'; self::$htmlPage[] = ''; self::$htmlPage[] = '
'; self::$htmlPage[] = array('include' => $page); self::$htmlPage[] = '
'; self::makeFooter($page); self::$htmlPage[] = '
'; self::$htmlPage[] = ''; } /** * Crear el pie de la página HTML. * * @param string $page opcional con la paǵina a mostrar * @return none */ public static function makeFooter($page = "main") { $info = self::getAppInfo(); self::$htmlPage[] = ' '; self::$htmlPage[] = ''; } /** * Cargar un archivo de plantilla. * * @param string $template con el nombre de la plantilla * @param array $tplvars con los datos a pasar a la plantilla * @return none */ public static function getTemplate($template, $tplvars = array()) { $tpl = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'tpl' . DIRECTORY_SEPARATOR . $template . '.php'; if (file_exists($tpl)) { $data = $tplvars; include_once $tpl; //self::$htmlPage[] = array('include' => $tpl); } } /** * Crea la barra de navegación para búsqueda de cuentas. * * @param int $intSortKey con el número de campo del filro * @param int $intCur con el número de página actual * @param int $intTotal con el número total de páginas * @param int $intLimit con el límite de registros a mostrar * @param int $intTime con el tiempo de carga de los resultados * @param bool $filterOn opcional con el estado del filtrado * @return none */ public static function printQuerySearchNavBar($intSortKey, $intCur, $intTotal, $intLimit, $intTime, $filterOn = false) { $firstPage = ceil(($intCur + 1) / $intLimit); $lastPage = ceil($intTotal / $intLimit); $globalOn = SP_Common::parseParams('p', 'gsearch', 0, false, 1); echo ''; } /** * Crea la barra de navegación para el registro de eventos. * * @param int $intCur con el número de página actual * @param int $intTotal con el número total de páginas * @param int $intTime con el tiempo de carga de los resultados * @return none */ public static function printQueryLogNavBar($intCur, $intTotal, $intTime = 0) { $intLimit = 50; $firstPage = ceil(($intCur + 1) / $intLimit); $lastPage = ceil($intTotal / $intLimit); echo ''; } /** * Limpia los datos recibidos de un formulario. * * @param string $data con los datos a limpiar * @return false|string con los datos limpiados */ public static function sanitize(&$data) { if (!$data) { return false; } if (is_array($data)) { array_walk_recursive($data, 'SP_Html::sanitize'); } else { $data = strip_tags($data); // Fix &entity\n; $data = str_replace(array('&', '<', '>'), array('&amp;', '&lt;', '&gt;'), $data); $data = preg_replace('/(&#*\w+)[\x00-\x20]+;/u', '$1;', $data); $data = preg_replace('/(&#x*[0-9A-F]+);*/iu', '$1;', $data); $data = html_entity_decode($data, ENT_COMPAT, 'UTF-8'); // Remove any attribute starting with "on" or xmlns $data = preg_replace('#(<[^>]+?[\x00-\x20"\'])(?:on|xmlns)[^>]*+>#iu', '$1>', $data); // Remove javascript: and vbscript: protocols $data = preg_replace('#([a-z]*)[\x00-\x20]*=[\x00-\x20]*([`\'"]*)[\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2nojavascript...', $data); $data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2novbscript...', $data); $data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#u', '$1=$2nomozbinding...', $data); // Only works in IE: $data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?expression[\x00-\x20]*\([^>]*+>#i', '$1>', $data); $data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?behaviour[\x00-\x20]*\([^>]*+>#i', '$1>', $data); $data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^>]*+>#iu', '$1>', $data); // Remove namespaced elements (we do not need them) $data = preg_replace('#]*+>#i', '', $data); do { // Remove really unwanted tags $old_data = $data; $data = preg_replace('#]*+>#i', '', $data); } while ($old_data !== $data); } return $data; } /** * Muestra una barra de información con los registros y tiempo de la consulta. * * @param int $intTotal con el total de registros devueltos * @param int $startTime con el tiempo de inicio de la consulta * @return none */ public static function printQueryInfoBar($intTotal, $startTime) { $endTime = microtime(); $totalTime = round($endTime - $startTime, 5); echo ''; } /** * Truncar un texto a una determinada longitud. * * @param string $str con la cadena a truncar * @param int $len con la longitud máxima de la cadena * @return string con el texto truncado */ public static function truncate($str, $len) { $tail = max(0, $len - 10); $truncate = substr($str, 0, $tail); $truncate .= strrev(preg_replace('~^..+?[\s,:]\b|^...~', '...', strrev(substr($str, $tail, $len - $tail)))); return $truncate; } /** * Devolver errores comunes. * Esta función muestra la página de error con el error indicado. * * @param string $code con el código de error a mostrar * @return none */ public static function showCommonError($code) { $commonErrors = array( 'unavailable' => array('txt' => _('Opción no disponible'), 'hint' => _('Consulte con el administrador')), 'noaccpermission' => array('txt' => _('No tiene permisos para acceder a esta cuenta'), 'hint' => _('Consulte con el administrador')), 'nopermission' => array('txt' => _('No tiene permisos para acceder a esta página'), 'hint' => _('Consulte con el administrador')), 'updatempass' => array('txt' => _('Clave maestra actualizada'), 'hint' => _('Reinicie la sesión para cambiarla')) ); $data['errors'][] = array( 'type' => 'critical', 'description' => $commonErrors[$code]['txt'], 'hint' => $commonErrors[$code]['hint']); self::getTemplate('error', $data); exit(); } /** * Convertir un color RGB a HEX * From: http://bavotasan.com/2011/convert-hex-color-to-rgb-using-php/ * * @param array $rgb con color en RGB * @return string */ public static function rgb2hex($rgb) { $hex = "#"; $hex .= str_pad(dechex($rgb[0]), 2, "0", STR_PAD_LEFT); $hex .= str_pad(dechex($rgb[1]), 2, "0", STR_PAD_LEFT); $hex .= str_pad(dechex($rgb[2]), 2, "0", STR_PAD_LEFT); return $hex; // returns the hex value including the number sign (#) } /** * Devolver una tabla con el resultado de una consulta y acciones. * * @param array $arrTableProp con las propiedades de la tabla * @param array $queryItems con los resultados de la consulta * @return none */ public static function getQueryTable($arrTableProp, $queryItems) { $sk = SP_Common::getSessionKey(true); $maxNumActions = 3; echo '
'; echo ''; echo '
'; if ($arrTableProp["header"]) { echo '
' . $arrTableProp["header"] . '
'; } echo '
'; echo '
'; echo ''; echo '
'; echo '
'; foreach ($queryItems as $item) { $intId = $item->$arrTableProp["tblRowSrcId"]; $action_check = array(); $numActions = count($arrTableProp["actions"]); $classActionsOptional = ($numActions > $maxNumActions) ? 'actions-optional' : ''; echo ''; } echo '
'; } /** * Devolver una cadena con el tag HTML strong. * * @param string $text con la cadena de texto * @return string */ public static function strongText($text) { return ('' . $text . ''); } /** * Devolver un link HTML. * * @param string $text con la cadena de texto * @param string $link con el destino del enlace * @param string $title con el título del enlace * @param string $attribs con atributos del enlace * @return string */ public static function anchorText($text, $link = '', $title = '', $attribs = '') { $alink = (!empty($link)) ? $link : $text; $atitle = (!empty($title)) ? $title : ''; $anchor = '' . $text . ''; return $anchor; } }