From 8be966d0bbe2cb9f498b31e6c340536674f60e99 Mon Sep 17 00:00:00 2001 From: David Goodwin Date: Sun, 27 Sep 2020 10:52:19 +0100 Subject: [PATCH] allow the template to be destroyed --- model/PFASmarty.php | 137 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 model/PFASmarty.php diff --git a/model/PFASmarty.php b/model/PFASmarty.php new file mode 100644 index 00000000..efe7596b --- /dev/null +++ b/model/PFASmarty.php @@ -0,0 +1,137 @@ +getAll(); + + if (isset($CONF['theme']) && is_dir(dirname(__FILE__) . "/../templates/" . $CONF['theme'])) { + $smarty = new PFASmarty($CONF['theme']); + } else { + $smarty = new PFASmarty(); + } + + $smarty->configureTheme('');// default to something. + + $smarty->assign('CONF', $CONF); + $smarty->assign('PALANG', $CONF['__PALANG'] ?? []); + $smarty->assign('url_domain', ''); + + $smarty->assign('version', $CONF['version'] ?? 'unknown'); + + $smarty->assign('boolconf_alias_domain', Config::bool('alias_domain')); + $smarty->assign('authentication_has_role', array('global_admin' => authentication_has_role('global-admin'), 'admin' => authentication_has_role('admin'), 'user' => authentication_has_role('user'))); + + return $smarty; + } + + /** + * @param string $rel_path - relative path for referenced css etc dependencies - e.g. users/edit.php needs '../' else, it's ''. + */ + public function configureTheme(string $rel_path = '') { + $CONF = Config::getInstance()->getAll(); + + $CONF['theme_css'] = $rel_path . htmlentities($CONF['theme_css']); + if (!empty($CONF['theme_custom_css'])) { + $CONF['theme_custom_css'] = $rel_path . htmlentities($CONF['theme_custom_css']); + } + $CONF['theme_favicon'] = $rel_path . htmlentities($CONF['theme_favicon']); + $CONF['theme_logo'] = $rel_path . htmlentities($CONF['theme_logo']); + + $this->assign('CONF', $CONF); + } + + /** + * @var Smarty + */ + protected $template; + + /** + * @param string $template_theme + */ + public function __construct($template_theme = 'default') { + $this->template = new Smarty(); + + //$this->template->debugging = true; + if ($template_theme == 'default') { + $this->template->setTemplateDir(dirname(__FILE__) . '/../templates'); + } else { + $this->template->setTemplateDir(dirname(__FILE__) . '/../templates/' . $template_theme); + } + + // if it's not present or writeable, smarty should just not cache. + $templates_c = dirname(__FILE__) . '/../templates_c'; + if (is_dir($templates_c) && is_writeable($templates_c)) { + $this->template->setCompileDir($templates_c); + } else { + # unfortunately there's no sane way to just disable compiling of templates + clearstatcache(); // just incase someone just fixed it; on their next refresh it should work. + error_log("ERROR: directory $templates_c doesn't exist or isn't writeable for the webserver"); + die("ERROR: the templates_c directory doesn't exist or isn't writeable for the webserver"); + } + + $this->template->setConfigDir(dirname(__FILE__) . '/../configs'); + } + + /** + * @param string $key + * @param mixed $value + * @param bool $sanitise + */ + public function assign($key, $value, $sanitise = true) { + $this->template->assign("RAW_$key", $value); + if ($sanitise == false) { + return $this->template->assign($key, $value); + } + $clean = $this->sanitise($value); + /* we won't run the key through sanitise() here... some might argue we should */ + return $this->template->assign($key, $clean); + } + + /** + * @param string $template + * @return void + */ + public function display($template) { + header("Expires: Sun, 16 Mar 2003 05:00:00 GMT"); + header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); + header("Cache-Control: no-store, no-cache, must-revalidate"); + header("Cache-Control: post-check=0, pre-check=0", false); + header("Pragma: no-cache"); + header("Content-Type: text/html; charset=UTF-8"); + + $this->template->display($template); + unset($_SESSION['flash']); # cleanup flash messages + } + + /** + * Recursive cleaning of data, using htmlentities - this assumes we only ever output to HTML and we're outputting in UTF-8 charset + * + * @param mixed $data - array or primitive type; objects not supported. + * @return mixed $data + * */ + public function sanitise($data) { + if (!is_array($data)) { + return htmlentities($data, ENT_QUOTES, 'UTF-8', false); + } + $clean = array(); + foreach ($data as $key => $value) { + /* as this is a nested data structure it's more likely we'll output the key too (at least in my opinion, so we'll sanitise it too */ + $clean[$this->sanitise($key)] = $this->sanitise($value); + } + return $clean; + } +}