⚝
One Hat Cyber Team
⚝
Your IP:
216.73.216.72
Server IP:
41.128.143.86
Server:
Linux host.raqmix.cloud 6.8.0-1025-azure #30~22.04.1-Ubuntu SMP Wed Mar 12 15:28:20 UTC 2025 x86_64
Server Software:
Apache
PHP Version:
8.3.23
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
usr
/
share
/
psa-pear
/
pear
/
php
/
Horde
/
Edit File: Template.php
<?php /** * Horde Template system. Adapted from bTemplate by Brian Lozier * <brian@massassi.net>. * * Horde_Template provides a basic template engine with tags, loops, * and if conditions. However, it is also a simple interface with * several essential functions: set(), fetch(), and * parse(). Subclasses or decorators can implement (or delegate) these * three methods, plus the options api, and easily implement other * template engines (PHP code, XSLT, etc.) without requiring usage * changes. * * Compilation code adapted from code written by Bruno Pedro <bpedro@ptm.pt>. * * Copyright 2002-2016 Horde LLC (http://www.horde.org/) * * See the enclosed file COPYING for license information (LGPL). If you * did not receive this file, see http://www.horde.org/licenses/lgpl21. * * @author Chuck Hagenbuch <chuck@horde.org> * @author Michael Slusarz <slusarz@horde.org> * @package Template */ class Horde_Template { /** The identifier to use for memory-only templates. */ const TEMPLATE_STRING = '**string'; /** * The Horde_Cache object to use. * * @var Horde_Cache */ protected $_cache; /** * Logger. * * @var Horde_Log_Logger */ protected $_logger; /** * Option values. * * @var array */ protected $_options = array(); /** * Directory that templates should be read from. * * @var string */ protected $_basepath = ''; /** * Tag (scalar) values. * * @var array */ protected $_scalars = array(); /** * Loop tag values. * * @var array */ protected $_arrays = array(); /** * Path to template source. * * @var string */ protected $_templateFile = null; /** * Template source. * * @var string */ protected $_template = null; /** * Foreach variable mappings. * * @var array */ protected $_foreachMap = array(); /** * Foreach variable incrementor. * * @var integer */ protected $_foreachVar = 0; /** * preg_match() cache. * * @var array */ protected $_pregcache = array(); /** * Constructor. * * @param array $params The following configuration options: * <pre> * 'basepath' - (string) The directory where templates are read from. * 'cacheob' - (Horde_Cache) A caching object used to cache the output. * 'logger' - (Horde_Log_Logger) A logger object. * </pre> */ public function __construct($params = array()) { if (isset($params['basepath'])) { $this->_basepath = $params['basepath']; } if (isset($params['cacheob'])) { $this->_cache = $params['cacheob']; } if (isset($params['logger'])) { $this->_logger = $params['logger']; } } /** * Sets an option. * Currently available options are: * <pre> * 'debug' - Output debugging information to screen * 'forcecompile' - Force a compilation on every page load * 'gettext' - Activate gettext detection * <pre> * * @param string $option The option name. * @param mixed $val The option's value. */ public function setOption($option, $val) { $this->_options[$option] = $val; } /** * Set the template contents to a string. * * @param string $template The template text. */ public function setTemplate($template) { $this->_template = $template; $this->_parse(); $this->_templateFile = self::TEMPLATE_STRING; } /** * Returns an option's value. * * @param string $option The option name. * * @return mixed The option's value. */ public function getOption($option) { return isset($this->_options[$option]) ? $this->_options[$option] : null; } /** * Sets a tag, loop, or if variable. * * @param string|array $tag Either the tag name or a hash with tag names * as keys and tag values as values. * @param mixed $var The value to replace the tag with. */ public function set($tag, $var) { if (is_array($tag)) { foreach ($tag as $tTag => $tVar) { $this->set($tTag, $tVar); } } elseif (is_array($var)) { $this->_arrays[$tag] = $var; } else { $this->_scalars[$tag] = (string) $var; } } /** * Returns the value of a tag or loop. * * @param string $tag The tag name. * * @return mixed The tag value or null if the tag hasn't been set yet. */ public function get($tag) { if (isset($this->_arrays[$tag])) { return $this->_arrays[$tag]; } if (isset($this->_scalars[$tag])) { return $this->_scalars[$tag]; } return null; } /** * Fetches a template from the specified file and return the parsed * contents. * * @param string $filename The file to fetch the template from. * * @return string The parsed template. */ public function fetch($filename = null) { $file = $this->_basepath . $filename; $force = $this->getOption('forcecompile'); if (!is_null($filename) && ($file != $this->_templateFile)) { $this->_template = $this->_templateFile = null; } /* First, check for a cached compiled version. */ $parts = array( 'horde_template', filemtime($file), $file ); if ($this->getOption('gettext')) { $parts[] = setlocale(LC_ALL, 0); } $cacheid = implode('|', $parts); if (!$force && is_null($this->_template) && $this->_cache) { $this->_template = $this->_cache->get($cacheid, 0); if ($this->_template === false) { $this->_template = null; } } /* Parse and compile the template. */ if ($force || is_null($this->_template)) { $this->_template = str_replace("\n", " \n", file_get_contents($file)); $this->_parse(); if ($this->_cache) { $this->_cache->set($cacheid, $this->_template); if ($this->_logger) { $this->_logger->log(sprintf('Saved compiled template file for "%s".', $file), 'DEBUG'); } } } $this->_templateFile = $file; /* Template debugging. */ if ($this->getOption('debug')) { echo '<pre>' . htmlspecialchars($this->_template) . '</pre>'; } return $this->parse(); } /** * Parses all variables/tags in the template. * * @param string $contents The unparsed template. * * @return string The parsed template. */ public function parse($contents = null) { if (!is_null($contents)) { $this->setTemplate(str_replace("\n", " \n", $contents)); } /* Evaluate the compiled template and return the output. */ ob_start(); eval('?>' . $this->_template); return is_null($contents) ? ob_get_clean() : str_replace(" \n", "\n", ob_get_clean()); } /** * Parses all variables/tags in the template. */ protected function _parse() { // Escape XML instructions. $this->_template = preg_replace('/\?>|<\?/', '<?php echo \'$0\' ?>', $this->_template); // Parse gettext tags, if the option is enabled. if ($this->getOption('gettext')) { $this->_parseGettext(); } // Process ifs. $this->_parseIf(); // Process loops and arrays. $this->_parseLoop(); // Process base scalar tags. Needs to be after _parseLoop() as we // rely on _foreachMap(). $this->_parseTags(); // Finally, process any associative array scalar tags. $this->_parseAssociativeTags(); } /** * Parses gettext tags. * * @todo Convert to use Horde_Translation. */ protected function _parseGettext() { if (preg_match_all("/<gettext>(.+?)<\/gettext>/s", $this->_template, $matches, PREG_SET_ORDER)) { $replace = array(); foreach ($matches as $val) { // eval gettext independently so we can embed tempate tags $code = 'echo _(\'' . str_replace("'", "\\'", $val[1]) . '\');'; ob_start(); eval($code); $replace[$val[0]] = ob_get_clean(); } $this->_doReplace($replace); } } /** * Parses 'if' statements. * * @param string $key The key prefix to parse. */ protected function _parseIf($key = null) { $replace = array(); foreach ($this->_doSearch('if', $key) as $val) { $replace[$val[0]] = '<?php if (!empty(' . $this->_generatePHPVar('scalars', $val[1]) . ') || !empty(' . $this->_generatePHPVar('arrays', $val[1]) . ')): ?>'; $replace[$val[2]] = '<?php endif; ?>'; // Check for else statement. foreach ($this->_doSearch('else', $key) as $val2) { $replace[$val2[0]] = '<?php else: ?>'; $replace[$val2[2]] = ''; } } $this->_doReplace($replace); } /** * Parses the given array for any loops or other uses of the array. * * @param string $key The key prefix to parse. */ protected function _parseLoop($key = null) { $replace = array(); foreach ($this->_doSearch('loop', $key) as $val) { $divider = null; // See if we have a divider. if (preg_match("/<divider:" . $val[1] . ">(.*)<\/divider:" . $val[1] . ">/sU", $this->_template, $m)) { $divider = $m[1]; $replace[$m[0]] = ''; } if (!isset($this->_foreachMap[$val[1]])) { $this->_foreachMap[$val[1]] = ++$this->_foreachVar; } $varId = $this->_foreachMap[$val[1]]; $var = $this->_generatePHPVar('arrays', $val[1]); $replace[$val[0]] = '<?php ' . (($divider) ? '$i' . $varId . ' = count(' . $var . '); ' : '') . 'foreach (' . $this->_generatePHPVar('arrays', $val[1]) . ' as $k' . $varId . ' => $v' . $varId . '): ?>'; $replace[$val[2]] = '<?php ' . (($divider) ? 'if (--$i' . $varId . ' != 0) { echo \'' . $divider . '\'; }; ' : '') . 'endforeach; ?>'; // Parse ifs. $this->_parseIf($val[1]); // Parse interior loops. $this->_parseLoop($val[1]); // Replace scalars. $this->_parseTags($val[1]); } $this->_doReplace($replace); } /** * Replaces 'tag' tags with their PHP equivalents. * * @param string $key The key prefix to parse. */ protected function _parseTags($key = null) { $replace = array(); foreach ($this->_doSearch('tag', $key, true) as $val) { $replace_text = '<?php '; if (isset($this->_foreachMap[$val[1]])) { $var = $this->_foreachMap[$val[1]]; $replace_text .= 'if (isset($v' . $var . ')) { echo is_array($v' . $var . ') ? $k' . $var . ' : $v' . $var . '; } else'; } $var = $this->_generatePHPVar('scalars', $val[1]); $replace[$val[0]] = $replace_text . 'if (isset(' . $var . ')) { echo ' . $var . '; } ?>'; } $this->_doReplace($replace); } /** * Parse associative tags (i.e. <tag:foo.bar />). */ protected function _parseAssociativeTags() { $replace = array(); foreach ($this->_pregcache['tag'] as $key => $val) { $parts = explode('.', $val[1]); $var = '$this->_arrays[\'' . $parts[0] . '\'][\'' . $parts[1] . '\']'; $replace[$val[0]] = '<?php if (isset(' . $var . ')) { echo ' . $var . '; } ?>'; unset($this->_pregcache['tag'][$key]); } $this->_doReplace($replace); } /** * Output the correct PHP variable string for use in template space. */ protected function _generatePHPVar($tag, $key) { $out = ''; $a = explode('.', $key); $a_count = count($a); if ($a_count == 1) { switch ($tag) { case 'arrays': $out = '$this->_arrays'; break; case 'scalars': $out = '$this->_scalars'; break; } } else { $out = '$v' . $this->_foreachMap[implode('.', array_slice($a, 0, -1))]; } return $out . '[\'' . end($a) . '\']'; } /** * TODO */ protected function _doSearch($tag, $key, $noclose = false) { $out = array(); $level = (is_null($key)) ? 0 : substr_count($key, '.') + 1; if (!isset($this->_pregcache[$key])) { $regex = ($noclose) ? "/<" . $tag . ":(.+?)\s\/>/" : "/<" . $tag . ":([^>]+)>/"; preg_match_all($regex, $this->_template, $this->_pregcache[$tag], PREG_SET_ORDER); } foreach ($this->_pregcache[$tag] as $pkey => $val) { $val_level = substr_count($val[1], '.'); $add = false; if (is_null($key)) { $add = !$val_level; } else { $add = (($val_level == $level) && (strpos($val[1], $key . '.') === 0)); } if ($add) { if (!$noclose) { $val[2] = '</' . $tag . ':' . $val[1] . '>'; } $out[] = $val; unset($this->_pregcache[$tag][$pkey]); } } return $out; } /** * TODO */ protected function _doReplace($replace) { if (empty($replace)) { return; } $search = array(); foreach (array_keys($replace) as $val) { $search[] = '/' . preg_quote($val, '/') . '/'; } $this->_template = preg_replace($search, array_values($replace), $this->_template); } }
Simpan