- * This file contains an abstract (PHP 4, so "abstract" is relative)
- * class meant to define the basic template interface for the
+ * This file contains an abstract (PHP 4, so "abstract" is relative)
+ * class meant to define the basic template interface for the
* SquirrelMail core application. Subclasses should extend this
* class with any custom functionality needed to interface a target
* templating engine with SquirrelMail.
* SquirrelMail core application. Subclasses should extend this
* class with any custom functionality needed to interface a target
* templating engine with SquirrelMail.
* @copyright © 2003-2006 The SquirrelMail Project Team
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
* @version $Id$
* @copyright © 2003-2006 The SquirrelMail Project Team
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
* @version $Id$
/**
* Template file cache. Structured as an array, whose keys
* are all the template file names (with path information relative
/**
* Template file cache. Structured as an array, whose keys
* are all the template file names (with path information relative
- * to the template set's base directory, e.g., "css/style.css")
- * found in all parent template sets including the ultimate fall-back
- * template set. Array values are sub-arrays with the
+ * to the template set's base directory, e.g., "css/style.css")
+ * found in all parent template sets including the ultimate fall-back
+ * template set. Array values are sub-arrays with the
* following key-value pairs:
*
* PATH -- file path, relative to SM_PATH
* following key-value pairs:
*
* PATH -- file path, relative to SM_PATH
// from the construct_template() method (I doubt it
// is worth the trouble to parse the current stack trace)
// if (???)
// from the construct_template() method (I doubt it
// is worth the trouble to parse the current stack trace)
// if (???)
// values are in main SM config file
//
global $templateset_fallback, $aTemplateSet;
// values are in main SM config file
//
global $templateset_fallback, $aTemplateSet;
? $default : $templateset_fallback);
// iterate through all template sets, is this a valid skin ID?
? $default : $templateset_fallback);
// iterate through all template sets, is this a valid skin ID?
global $templateset_default, $aTemplateSet;
$aTemplateSet = (!isset($aTemplateSet) || !is_array($aTemplateSet)
? array() : $aTemplateSet);
global $templateset_default, $aTemplateSet;
$aTemplateSet = (!isset($aTemplateSet) || !is_array($aTemplateSet)
? array() : $aTemplateSet);
? $default : $templateset_default);
// iterate through all template sets, is this a valid skin ID?
? $default : $templateset_default);
// iterate through all template sets, is this a valid skin ID?
+ * NOTE: due to when this code executes, plugins activated here
+ * do not have access to the config_override and loading_prefs
+ * hooks; instead, such plugins can use the
+ * "template_plugins_override_after" hook defined below.
+ *
- global $disable_plugins, $plugins, $squirrelmail_plugin_hooks;
+ global $disable_plugins, $plugins, $squirrelmail_plugin_hooks, $null;
'remove_plugins', array());
//FIXME (?) we assume $add_plugins and $remove_plugins are arrays -- we could
'remove_plugins', array());
//FIXME (?) we assume $add_plugins and $remove_plugins are arrays -- we could
- * is to be used as an override
- * (if not given, this template
+ * is to be used as an override
+ * (if not given, this template
* set's engine is used) (optional).
*
* @return object The Template subclass object for the template engine.
* set's engine is used) (optional).
*
* @return object The Template subclass object for the template engine.
if (empty($template_set_id)) $template_set_id = $this->template_set_id;
// FIXME: assuming PHP template engine may not necessarily be a good thing
if (empty($template_set_id)) $template_set_id = $this->template_set_id;
// FIXME: assuming PHP template engine may not necessarily be a good thing
- * @return string The relative path to the fallback template
- * directory based from the main SquirrelMail
+ * @return string The relative path to the fallback template
+ * directory based from the main SquirrelMail
- * Given a template set ID and setting name, returns the
- * setting's value. Note that settings are cached in
+ * Given a template set ID and setting name, returns the
+ * setting's value. Note that settings are cached in
* session, so "live" changes to template configuration
* won't be reflected until the user logs out and back
* in again.
* session, so "live" changes to template configuration
* won't be reflected until the user logs out and back
* in again.
* @param string $template_set_id The template set for which
* to look up the setting.
* @param string $setting The name of the setting to
* @param string $template_set_id The template set for which
* to look up the setting.
* @param string $setting The name of the setting to
* @param mixed $default When the requested setting
* is not found, the contents
* of this value are returned
* @param mixed $default When the requested setting
* is not found, the contents
* of this value are returned
* is NULL).
* NOTE that unlike sqGetGlobalVar(),
* this function will also return
* is NULL).
* NOTE that unlike sqGetGlobalVar(),
* this function will also return
* but is empty.
* @param boolean $live_config When TRUE, the target template
* set's configuration file is
* but is empty.
* @param boolean $live_config When TRUE, the target template
* set's configuration file is
* method is called. Default
* behavior is to only load the
* configuration file if it had
* method is called. Default
* behavior is to only load the
* configuration file if it had
- sqGetGlobalVar('template_configuration_settings',
- $template_configuration_settings,
- SQ_SESSION,
+ sqGetGlobalVar('template_configuration_settings',
+ $template_configuration_settings,
+ SQ_SESSION,
// setting is not known, return $default
//
if (!empty($template_configuration_settings[$template_set_id]))
return $default;
// setting is not known, return $default
//
if (!empty($template_configuration_settings[$template_set_id]))
return $default;
. Template::calculate_template_file_directory($template_set_id)
. 'config.php';
if (!file_exists($template_config_file)) {
. Template::calculate_template_file_directory($template_set_id)
. 'config.php';
if (!file_exists($template_config_file)) {
. $template_config_file . '")', E_USER_ERROR);
} else {
// we require() the file to let PHP do the variable value
// parsing for us, and read the file in manually so we can
. $template_config_file . '")', E_USER_ERROR);
} else {
// we require() the file to let PHP do the variable value
// parsing for us, and read the file in manually so we can
// (settings can be different depending on specific requirements
// of different template engines)... the other way this may
// (settings can be different depending on specific requirements
// of different template engines)... the other way this may
// before/after the require(), but anyway, this code should
// only run once for this template set...
//
// before/after the require(), but anyway, this code should
// only run once for this template set...
//
preg_match_all('/\$(\w+)/', $file_contents, $variables, PREG_PATTERN_ORDER);
foreach ($variables[1] as $variable) {
if (isset($$variable))
preg_match_all('/\$(\w+)/', $file_contents, $variables, PREG_PATTERN_ORDER);
foreach ($variables[1] as $variable) {
if (isset($$variable))
'template_configuration_settings');
// NOTE: could use isset() instead of empty() below, but
'template_configuration_settings');
// NOTE: could use isset() instead of empty() below, but
* Obtain template file hierarchy from cache.
*
* If the file hierarchy does not exist in session, it is
* Obtain template file hierarchy from cache.
*
* If the file hierarchy does not exist in session, it is
* empty - no additional files).
*
* @return array Template file hierarchy array, whose keys
* empty - no additional files).
*
* @return array Template file hierarchy array, whose keys
- * are all the template file names (with path
- * information relative to the template set's
- * base directory, e.g., "css/style.css")
- * found in all parent template sets including
- * the ultimate fall-back template set.
- * Array values are sub-arrays with the
+ * are all the template file names (with path
+ * information relative to the template set's
+ * base directory, e.g., "css/style.css")
+ * found in all parent template sets including
+ * the ultimate fall-back template set.
+ * Array values are sub-arrays with the
* following key-value pairs:
*
* PATH -- file path, relative to SM_PATH
* following key-value pairs:
*
* PATH -- file path, relative to SM_PATH
function cache_template_file_hierarchy($regenerate_cache=FALSE,
$additional_files=array()) {
function cache_template_file_hierarchy($regenerate_cache=FALSE,
$additional_files=array()) {
$additional_files);
sqsession_register($template_file_hierarchy,
'template_file_hierarchy');
$additional_files);
sqsession_register($template_file_hierarchy,
'template_file_hierarchy');
// this could be called when $sTemplateID has
// yet to be defined... throw error for now,
// but if the error occurs, it's a coding error
// this could be called when $sTemplateID has
// yet to be defined... throw error for now,
// but if the error occurs, it's a coding error
// additional files, if any
//
if (!empty($additional_files)) {
// additional files, if any
//
if (!empty($additional_files)) {
- *
- * Paths to all files in all parent, grand-parent, great grand
- * parent, etc. template sets (including the fallback template)
- * are catalogued; for identically named files, the file earlier
+ *
+ * Paths to all files in all parent, grand-parent, great grand
+ * parent, etc. template sets (including the fallback template)
+ * are catalogued; for identically named files, the file earlier
* @param string $template_set_id The template set in which to
* search for files
* @param array $file_list The file list so far to be added
* to (allows recursive behavior)
* (optional; default empty array).
* @param string $template_set_id The template set in which to
* search for files
* @param array $file_list The file list so far to be added
* to (allows recursive behavior)
* (optional; default empty array).
* files (must be given as full path).
* If empty, starts at top-level template
* set directory (optional; default empty).
* NOTE! Use with care, as behavior is
* unpredictable if directory given is not
* part of correct template set.
* files (must be given as full path).
* If empty, starts at top-level template
* set directory (optional; default empty).
* NOTE! Use with care, as behavior is
* unpredictable if directory given is not
* part of correct template set.
* @return mixed The top-level caller will have an array of template
* files returned to it; recursive calls to this function
* do not receive any return value at all. The format
* @return mixed The top-level caller will have an array of template
* files returned to it; recursive calls to this function
* do not receive any return value at all. The format
// place all found files in the cache
// FIXME: assuming PHP template engine may not necessarily be a good thing
//
// place all found files in the cache
// FIXME: assuming PHP template engine may not necessarily be a good thing
//
'template_engine', SQ_PHP_TEMPLATE);
foreach ($files_and_dirs['FILES'] as $file) {
'template_engine', SQ_PHP_TEMPLATE);
foreach ($files_and_dirs['FILES'] as $file) {
* @param string $plugin The name of the plugin
* @param string $file The name of the template file
* @param string $template_set_id The ID of the template for which
* @param string $plugin The name of the plugin
* @param string $file The name of the template file
* @param string $template_set_id The ID of the template for which
. $file;
if (file_exists($file_path)) {
// FIXME: assuming PHP template engine may not necessarily be a good thing
. $file;
if (file_exists($file_path)) {
// FIXME: assuming PHP template engine may not necessarily be a good thing
'template_engine', SQ_PHP_TEMPLATE);
$file_list = array('plugins/' . $plugin . '/' . $file => array(
'PATH' => substr($file_path, strlen(SM_PATH)),
'template_engine', SQ_PHP_TEMPLATE);
$file_list = array('plugins/' . $plugin . '/' . $file => array(
'PATH' => substr($file_path, strlen(SM_PATH)),
* Find the right template file.
*
* The template file is taken from the template file cache, thus
* Find the right template file.
*
* The template file is taken from the template file cache, thus
* ancestors or the fallback template.
*
* Note that it is perfectly acceptable to load template files from
* ancestors or the fallback template.
*
* Note that it is perfectly acceptable to load template files from
- * template subdirectories. For example, JavaScript templates found
- * in the js/ subdirectory would be loaded by passing
+ * template subdirectories. For example, JavaScript templates found
+ * in the js/ subdirectory would be loaded by passing
* "js/<javascript file name>" as the $filename.
*
* Note that the caller can also ask for ALL files in a directory
* "js/<javascript file name>" as the $filename.
*
* Note that the caller can also ask for ALL files in a directory
* slash, indicating that all files
* for that directory name should
* be returned.
* slash, indicating that all files
* for that directory name should
* be returned.
* directory contents, sub-directory
* names will also be included
* (optional; default FALSE).
* directory contents, sub-directory
* names will also be included
* (optional; default FALSE).
* are NOT included in the cache!
* @param boolean $directories_only When TRUE, only directory names
* are included in the returned
* are NOT included in the cache!
* @param boolean $directories_only When TRUE, only directory names
* are included in the returned
* are NOT included in the cache!
*
* @return mixed The full path to the template file or a list
* of all files in the given directory if $filename
* ends with a slash; if not found, an empty string
* are NOT included in the cache!
*
* @return mixed The full path to the template file or a list
* of all files in the given directory if $filename
* ends with a slash; if not found, an empty string
&& strpos($file, '/', strlen($filename)) === FALSE)
$return_array[] = SM_PATH . $file_info['PATH'];
&& strpos($file, '/', strlen($filename)) === FALSE)
$return_array[] = SM_PATH . $file_info['PATH'];
if ($directories_ok && strpos($file, $filename) === 0
&& ($pos = strpos($file, '/', strlen($filename))) !== FALSE
&& strpos($file, '/', $pos + 1) === FALSE) {
if ($directories_ok && strpos($file, $filename) === 0
&& ($pos = strpos($file, '/', strlen($filename))) !== FALSE
&& strpos($file, '/', $pos + 1) === FALSE) {
- $directory_name = SM_PATH
- . substr($file_info['PATH'],
- 0,
+ $directory_name = SM_PATH
+ . substr($file_info['PATH'],
+ 0,
strrpos($file_info['PATH'], '/'));
if (!in_array($directory_name, $return_array))
$return_array[] = $directory_name;
strrpos($file_info['PATH'], '/'));
if (!in_array($directory_name, $return_array))
$return_array[] = $directory_name;
if (strpos($file, $filename) === 0
&& ($pos = strpos($file, '/', strlen($filename))) !== FALSE
&& strpos($file, '/', $pos + 1) === FALSE) {
if (strpos($file, $filename) === 0
&& ($pos = strpos($file, '/', strlen($filename))) !== FALSE
&& strpos($file, '/', $pos + 1) === FALSE) {
* @param string $filename The name of the template file,
*
* @return object The needed template object to render the template.
* @param string $filename The name of the template file,
*
* @return object The needed template object to render the template.
// otherwise, compare $this' engine to the file's engine
//
$engine = $this->template_file_cache[$filename]['ENGINE'];
// otherwise, compare $this' engine to the file's engine
//
$engine = $this->template_file_cache[$filename]['ENGINE'];
// need to load another engine... if already instantiated,
// and stored herein, return that
// need to load another engine... if already instantiated,
// and stored herein, return that
// set config files that have same engine in common
// (but keeping a separate class object for every
// set config files that have same engine in common
// (but keeping a separate class object for every
// won't do that unless it becomes a problem)
//
if (!empty($this->other_template_engine_objects[$engine])) {
// won't do that unless it becomes a problem)
//
if (!empty($this->other_template_engine_objects[$engine])) {
* that of its ancestors) with the extension ".js" are returned.
*
* @param boolean $full_path When FALSE, only the file names
* that of its ancestors) with the extension ".js" are returned.
*
* @param boolean $full_path When FALSE, only the file names
* otherwise, path information is
* included (relative to SM_PATH)
* (OPTIONAL; default only file names)
* otherwise, path information is
* included (relative to SM_PATH)
* (OPTIONAL; default only file names)
// could end up being loaded, we have to load
// all js files from ancestor template sets,
// not just this set
// could end up being loaded, we have to load
// all js files from ancestor template sets,
// not just this set
//$js_files = list_files($directory, '.js', !$full_path);
//
$js_files = $this->get_template_file_path('js/');
//$js_files = list_files($directory, '.js', !$full_path);
//
$js_files = $this->get_template_file_path('js/');
- * All (non-empty) directories found in the template set's
- * "css/alternates" directory (and that of its ancestors)
+ * All (non-empty) directories found in the template set's
+ * "css/alternates" directory (and that of its ancestors)
* (OPTIONAL; default only file names)
*
* @return array A list of the available alternate stylesheets,
* (OPTIONAL; default only file names)
*
* @return array A list of the available alternate stylesheets,
- * where the keys are the file names (formatted
- * according to $full_path) for the stylesheets,
- * and the values are the prettified version of
+ * where the keys are the file names (formatted
+ * according to $full_path) for the stylesheets,
+ * and the values are the prettified version of
*/
function get_alternative_stylesheets($full_path=FALSE) {
// since any page from a parent template set
// could end up being loaded, we will load
*/
function get_alternative_stylesheets($full_path=FALSE) {
// since any page from a parent template set
// could end up being loaded, we will load
// template sets, not just this set
//
$css_directories = $this->get_template_file_path('css/alternates/', TRUE, TRUE);
// template sets, not just this set
//
$css_directories = $this->get_template_file_path('css/alternates/', TRUE, TRUE);
* "rtl.css" (which is dealt with separately) are returned.
*
* @param boolean $full_path When FALSE, only the file names
* "rtl.css" (which is dealt with separately) are returned.
*
* @param boolean $full_path When FALSE, only the file names
// could end up being loaded, we have to load
// all css files from ancestor template sets,
// not just this set
// could end up being loaded, we have to load
// all css files from ancestor template sets,
// not just this set
also contain the other parameters for create_css_link()
such as $name, $alt, $mtype, and $xhtml_end
But do we need to?
also contain the other parameters for create_css_link()
such as $name, $alt, $mtype, and $xhtml_end
But do we need to?
* this template set by getting the "rtl.css" file from
* this template set, its parent (or grandparent, etc.)
* this template set by getting the "rtl.css" file from
* this template set, its parent (or grandparent, etc.)
- * template set, the fall-back template set, or finally,
+ * template set, the fall-back template set, or finally,
- $aPluginOutput = concat_hook_function('template_construct_' . $file,
+ // At this moment concat_hook_function can return string and arrays.
+ // In php 4.3.x a notice will be raised when a string is passed as $aPluginOutput
+ // TODO, only return an arrays by concat_hook_function.
+ $mixedOutput = concat_hook_function('template_construct_' . $file,
$this->assign('plugin_output', $aPluginOutput);
//$output = $this->apply_template($template);
$this->assign('plugin_output', $aPluginOutput);
//$output = $this->apply_template($template);
* Note: this is an abstract method that must be implemented by subclass.
*
* @param string $filepath The full file path to the template to be applied
* Note: this is an abstract method that must be implemented by subclass.
*
* @param string $filepath The full file path to the template to be applied