From de4d58cb7fdcda16e5129a26db1a6a3d46d6594f Mon Sep 17 00:00:00 2001 From: pdontthink Date: Thu, 28 Sep 2006 14:02:11 +0000 Subject: [PATCH 1/1] New Template class implementation git-svn-id: https://svn.code.sf.net/p/squirrelmail/code/trunk/squirrelmail@11745 7612ce4b-ef26-0410-bec9-ea0150e637f0 --- class/template/PHP_Template.class.php | 226 +++++++ class/template/Smarty_Template.class.php | 199 ++++++ class/template/Template.class.php | 749 +++++++++++++++++++++++ 3 files changed, 1174 insertions(+) create mode 100644 class/template/PHP_Template.class.php create mode 100644 class/template/Smarty_Template.class.php create mode 100644 class/template/Template.class.php diff --git a/class/template/PHP_Template.class.php b/class/template/PHP_Template.class.php new file mode 100644 index 00000000..7bc8ad62 --- /dev/null +++ b/class/template/PHP_Template.class.php @@ -0,0 +1,226 @@ + and Andrei Zmievski . + * + * The SquirrelMail (Foowd) template implementation. + * Derived from the foowd template implementation and adapted + * for squirrelmail + * @copyright © 2005-2006 The SquirrelMail Project Team + * @license http://opensource.org/licenses/gpl-license.php GNU Public License + * @version $Id$ + * @package squirrelmail + * + */ + +/** + * The SquirrelMail PHP Template class. Extends the base + * Template class for use with PHP template pages. + * + * @author Paul James + * @author Monte Ohrt + * @author Andrei Zmievski + * @author Paul Lesniewski + * @package squirrelmail + * + */ +class PHP_Template extends Template +{ + + /** + * The templates values array + * + * @var array + * + */ + var $values = array(); + + + /** + * Constructor + * + * Please do not call directly. Use Template::construct_template(). + * + * @param string $template_id the template ID + * + */ + function PHP_Template($template_id) { +//FIXME: find a way to test that this is ONLY ever called +// from parent's construct_template() method (I doubt it +// is worth the trouble to parse the current stack trace) +// if (???) +// trigger_error('Please do not use default PHP_Template() constructor. Instead, use Template::construct_template().', E_USER_ERROR); + + parent::Template($template_id); + + } + + /** + * Assigns values to template variables + * + * @param array|string $tpl_var the template variable name(s) + * @param mixed $value the value to assign +FIXME: Proposed idea to add a parameter here that turns variable + encoding on, so that we can make sure output is always + run through something like htmlspecialchars() (maybe even nl2br()?) + * + */ + function assign($tpl_var, $value = NULL) { + + if (is_array($tpl_var)) + { + foreach ($tpl_var as $key => $val) + { + if ($key != '') + $this->values[$key] = $val; + } + } + else + { + if ($tpl_var != '') + $this->values[$tpl_var] = $value; + } + + } + + /** + * Assigns values to template variables by reference + * + * @param string $tpl_var the template variable name + * @param mixed $value the referenced value to assign +FIXME: Proposed idea to add a parameter here that turns variable + encoding on, so that we can make sure output is always + run through something like htmlspecialchars() (maybe even nl2br()?) + * + */ + function assign_by_ref($tpl_var, &$value) { + + if ($tpl_var != '') + $this->values[$tpl_var] = &$value; + + } + + /** + * Appends values to template variables + * + * @param array|string $tpl_var the template variable name(s) + * @param mixed $value the value to append + * @param boolean $merge when $value is given as an array, + * this indicates whether or not that + * array itself should be appended as + * a new template variable value or if + * that array's values should be merged + * into the existing array of template + * variable values +FIXME: Proposed idea to add a parameter here that turns variable + encoding on, so that we can make sure output is always + run through something like htmlspecialchars() (maybe even nl2br()?) + * + */ + function append($tpl_var, $value = NULL, $merge = FALSE) + { + if (is_array($tpl_var)) + { + foreach ($tpl_var as $_key => $_val) + { + if ($_key != '') + { + if(isset($this->values[$_key]) && !is_array($this->values[$_key])) + settype($this->values[$_key],'array'); + + if($merge && is_array($_val)) + { + // FIXME: Tentative testing seems to indicate that + // this does not mirror Smarty behavior; Smarty + // seems to append the full array as a new element + // instead of merging, so this behavior is technically + // more "correct", but Smarty seems to differ + foreach($_val as $_mkey => $_mval) + $this->values[$_key][$_mkey] = $_mval; + } + else + $this->values[$_key][] = $_val; + } + } + } + else + { + if ($tpl_var != '' && isset($value)) + { + if(isset($this->values[$tpl_var]) && !is_array($this->values[$tpl_var])) + settype($this->values[$tpl_var],'array'); + + if($merge && is_array($value)) + { + foreach($value as $_mkey => $_mval) + $this->values[$tpl_var][$_mkey] = $_mval; + } + else + $this->values[$tpl_var][] = $value; + } + } + } + + /** + * Appends values to template variables by reference + * + * @param string $tpl_var the template variable name + * @param mixed $value the referenced value to append + * @param boolean $merge when $value is given as an array, + * this indicates whether or not that + * array itself should be appended as + * a new template variable value or if + * that array's values should be merged + * into the existing array of template + * variable values +FIXME: Proposed idea to add a parameter here that turns variable + encoding on, so that we can make sure output is always + run through something like htmlspecialchars() (maybe even nl2br()?) + * + */ + function append_by_ref($tpl_var, &$value, $merge = FALSE) + { + if ($tpl_var != '' && isset($value)) + { + if(!@is_array($this->values[$tpl_var])) + settype($this->values[$tpl_var],'array'); + + if ($merge && is_array($value)) + { + foreach($value as $_key => $_val) + $this->values[$tpl_var][$_key] = &$value[$_key]; + } + else + $this->values[$tpl_var][] = &$value; + } + } + + /** + * Applys the template and generates final output destined + * for the user's browser + * + * @param string $filepath The full file path to the template to be applied + * + * @return string The output for the given template + * + */ + function apply_template($filepath) { + + // place values array directly in scope + // ($t? let's try to be more verbose please :-) ) + // + $t = &$this->values; + + ob_start(); + include($filepath); + $contents = ob_get_contents(); + ob_end_clean(); + return $contents; + + } + +} + diff --git a/class/template/Smarty_Template.class.php b/class/template/Smarty_Template.class.php new file mode 100644 index 00000000..1e4dde88 --- /dev/null +++ b/class/template/Smarty_Template.class.php @@ -0,0 +1,199 @@ +get_template_file_directory() + . 'config.php'; + if (!file_exists($template_config_file)) { + + trigger_error('No template configuration file was found where expected: ("' + . $template_config_file . '")', E_USER_ERROR); + + } else { + + require($template_config_file); + + + // instantiate and set up Smarty object + // +//LEFT OFF HERE - check for this as empty or not + require($smarty_path); + $this->smarty_template = new Smarty(); +//LEFT OFF HERE - check for these as empty or not.... I think we at least need compile dir? + $this->smarty_template->compile_dir = $smarty_compile_dir; + $this->smarty_template->cache_dir = $smarty_cache_dir; + $this->smarty_template->config_dir = $smarty_config_dir; + + // note that we do not use Smarty's template_dir + // because SquirrelMail has its own method of + // determining template file paths + // + //$this->smarty_template->template_dir = + + } + + } + + /** + * Assigns values to template variables + * + * @param array|string $tpl_var the template variable name(s) + * @param mixed $value the value to assign +FIXME: Proposed idea to add a parameter here that turns variable + encoding on, so that we can make sure output is always + run through something like htmlspecialchars() (maybe even nl2br()?) + * + */ + function assign($tpl_var, $value = NULL) { + + $this->smarty_template->assign($tpl_var, $value); + + } + + /** + * Assigns values to template variables by reference + * + * @param string $tpl_var the template variable name + * @param mixed $value the referenced value to assign +FIXME: Proposed idea to add a parameter here that turns variable + encoding on, so that we can make sure output is always + run through something like htmlspecialchars() (maybe even nl2br()?) + * + */ + function assign_by_ref($tpl_var, &$value) { + + $this->smarty_template->assign_by_ref($tpl_var, $value); + + } + + /** + * Appends values to template variables + * + * @param array|string $tpl_var the template variable name(s) + * @param mixed $value the value to append + * @param boolean $merge when $value is given as an array, + * this indicates whether or not that + * array itself should be appended as + * a new template variable value or if + * that array's values should be merged + * into the existing array of template + * variable values +FIXME: Proposed idea to add a parameter here that turns variable + encoding on, so that we can make sure output is always + run through something like htmlspecialchars() (maybe even nl2br()?) + * + */ + function append($tpl_var, $value = NULL, $merge = FALSE) { + + $this->smarty_template->append($tpl_var, $value, $merge); + + } + + /** + * Appends values to template variables by reference + * + * @param string $tpl_var the template variable name + * @param mixed $value the referenced value to append + * @param boolean $merge when $value is given as an array, + * this indicates whether or not that + * array itself should be appended as + * a new template variable value or if + * that array's values should be merged + * into the existing array of template + * variable values +FIXME: Proposed idea to add a parameter here that turns variable + encoding on, so that we can make sure output is always + run through something like htmlspecialchars() (maybe even nl2br()?) + * + */ + function append_by_ref($tpl_var, &$value, $merge = FALSE) { + + $this->smarty_template->append_by_ref($tpl_var, $value, $merge); + + } + + /** + * Applys the template and generates final output destined + * for the user's browser + * + * @param string $filepath The full file path to the template to be applied + * + * @return string The output for the given template + * + */ + function apply_template($filepath) { + + // if being passed a raw .css or .js file, default + // Smarty delimiters will cause errors + // + if (strrpos($filepath, '.css') === (strlen($filepath) - 4) + || strrpos($filepath, '.js') === (strlen($filepath) - 3)) { + $this->smarty_template->left_delimiter = '{='; + $this->smarty_template->right_delimiter = '=}'; + } + + // Smarty wants absolute paths + // + if (strpos($filepath, '/') === 0) + return $this->smarty_template->fetch('file:' . $filepath); + else + return $this->smarty_template->fetch('file:' . getcwd() . '/' . $filepath); + + } + +} + diff --git a/class/template/Template.class.php b/class/template/Template.class.php new file mode 100644 index 00000000..d4ce0d8f --- /dev/null +++ b/class/template/Template.class.php @@ -0,0 +1,749 @@ +set_up_template($template_id); + + } + + /** + * Construct Template + * + * This method should always be called instead of trying + * to get a Template object from the normal/default constructor, + * and is necessary in order to control the return value. + * + * @param string $template_id the template ID + * + * @return object The correct Template object for the given template set + * + */ + function construct_template($template_id) { + + $template = new Template($template_id); + return $template->get_template_engine_subclass(); + + } + + /** + * Set up internal attributes + * + * This method does most of the work for setting up + * newly constructed objects. + * + * @param string $template_id the template ID + * + */ + function set_up_template($template_id) { + + // FIXME: do we want to place any restrictions on the ID like + // making sure no slashes included? + // get template ID + // + $this->template_id = $template_id; + + + // FIXME: do we want to place any restrictions on the ID like + // making sure no slashes included? + // get default template ID + // + global $templateset_default, $aTemplateSet; + $aTemplateSet = (!isset($aTemplateSet) || !is_array($aTemplateSet) + ? array() : $aTemplateSet); + $templateset_default = (!isset($templateset_default) ? 0 : $templateset_default); + $this->default_template_id = (!empty($aTemplateSet[$templateset_default]['ID']) + ? $aTemplateSet[$templateset_default]['ID'] + : 'default'); + + + // set up template directories + // + $this->template_dir + = Template::calculate_template_file_directory($this->template_id); + $this->default_template_dir + = Template::calculate_template_file_directory($this->default_template_id); + + + // pull in the template config file and load javascript and + // css files needed for this template set + // + $template_config_file = SM_PATH . $this->get_template_file_directory() + . 'config.php'; + if (!file_exists($template_config_file)) { + + trigger_error('No template configuration file was found where expected: ("' + . $template_config_file . '")', E_USER_ERROR); + + } else { + + require($template_config_file); + $this->required_js_files = is_array($required_js_files) + ? $required_js_files : array(); + + } + + + // determine template engine + // + if (empty($template_engine)) { + trigger_error('No template engine ($template_engine) was specified in template configuration file: ("' + . $template_config_file . '")', E_USER_ERROR); + } else { + $this->template_engine = $template_engine; + } + + } + + /** + * Instantiate and return correct subclass for this template + * set's templating engine. + * + * @return object The Template subclass object for the template engine. + * + */ + function get_template_engine_subclass() { + + $engine_class_file = SM_PATH . 'class/template/' + . $this->template_engine . 'Template.class.php'; + + if (!file_exists($engine_class_file)) { + trigger_error('Unknown template engine (' . $this->template_engine + . ') was specified in template configuration file', + E_USER_ERROR); + } + + $engine_class = $this->template_engine . 'Template'; + require($engine_class_file); + return new $engine_class($this->template_id); + + } + + /** + * Determine the relative template directory path for + * the given template ID. + * + * @param string $template_id The template ID from which to build + * the directory path + * + * @return string The relative template path (based off of SM_PATH) + * + */ + function calculate_template_file_directory($template_id) { + + return 'templates/' . $template_id . '/'; + + } + + /** + * Determine the relative images directory path for + * the given template ID. + * + * @param string $template_id The template ID from which to build + * the directory path + * + * @return string The relative images path (based off of SM_PATH) + * + */ + function calculate_template_images_directory($template_id) { + + return 'templates/' . $template_id . '/images/'; + + } + + /** + * Return the relative template directory path for this template set. + * + * @return string The relative path to the template directory based + * from the main SquirrelMail directory (SM_PATH). + * + */ + function get_template_file_directory() { + + return $this->template_dir; + + } + + + /** + * Return the relative template directory path for the DEFAULT template set. + * + * @return string The relative path to the default template directory based + * from the main SquirrelMail directory (SM_PATH). + * + */ + function get_default_template_file_directory() { + + return $this->default_template_dir; + + } + + + /** + * Find the right template file. + * + * Templates are expected to be found in the template set directory, + * for example: + * SM_PATH/templates/