Source for file pnRender.class.php
Documentation is available at pnRender.class.php
* $Id: pnRender.class.php 24339 2008-06-05 18:06:52Z markwest $
* Zikula wrapper class for Smarty
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License (GPL)
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* @author Zikula development team
* @link http://www.post-nuke.net Zikula home page
* @link http://smarty.php.net Smarty home page
* @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
// keeping track if Smarty is loaded somewhere else!
* The directory of Smarty
define('SMARTY_DIR', 'includes/classes/Smarty/');
* The module in which the current template will be located
* The primary module for this page
* The full module info for wich the object is for
* The current theme used by the site/user
* The full theme info for the theme used by the site/user
* The current language used by the site/user
* The base URL of the site
* The base URI of the site
* The cache ID of the object
* Set if Xanthia is an active module and templates stored in database
* true if admins wants to expose the template folder, needs admin rights for pnRender too
* @param string $module The module for which this object is for
* @param bool $caching (optional) Value for the caching class var -
* default is void (i.e. use admin configured value
function pnRender($module = '', $caching = null)
// first, get a native Smarty object
// set the error reporting level
$this->error_reporting = isset ($GLOBALS['PNConfig']['Debug']['error_reporting']) ? $GLOBALS['PNConfig']['Debug']['error_reporting'] : E_ALL;
// Initialize the module property with the name of
// the topmost module. Foor Hooks, Blocks, API Functions and others
// you need to set this property to the name of the respective module!
// initialise other PN environment vars
// begin holder tag (be nice to others)
//---- Plugins handling -----------------------------------------------
//$this->modinfo = $modinfo = pnModGetInfo(pnModGetIDFromName($module));
$modpath = ($this->module[$module]['type'] == 3) ? 'system' : 'modules';
// plugin paths are ordered so that we find the vast majority of plugins with as few path
$pluginpaths = array('system/pnRender/plugins',
"themes/$theme/templates/modules/$module/plugins",
"$modpath/" . $this->module[$module]['directory'] . "/pntemplates/plugins");
foreach ($pluginpaths as $pluginpath) {
// check if the recent 'type' parameter in the URL is admin and if yes,
// include (modules|system)/Admin/pntemplates/plugins to the plugins_dir array
/* // add the plugin directory for all available modules
// TODO evaluate performance issues
$modules = pnModGetAllMods();
foreach ($modules as $module) {
if ($module['type'] == 3) {
array_push($this->plugins_dir, "system/$module[directory]/pntemplates/plugins");
array_push($this->plugins_dir, "modules/$module[directory]/pntemplates/plugins");
// build the path to the config file for usemodules needed later
$usemod_conf = "$modpath/". $this->module[$module]['directory']. "/pntemplates/config/usemodules";
$additionalmodules = file($usemod_conf);
foreach ($additionalmodules as $addmod) {
$this->_add_plugins_dir(trim($addmod));
//---- Cache handling -------------------------------------------------
// use HTML cache system?
if (isset ($caching) && is_bool($caching)) {
//---- Compilation handling -------------------------------------------
// check for updated templates?
// force compile template always?
// don't use subdirectories when creating compiled/cached templates
// this works better in a hosted environment
// cache directory (compiled templates)
// initialize the cache ID
// register resource type 'pn'
// this defines the way templates are searched during
// <!--[ include file='my_template.html' ]-->
// this enables us to store selected module templates in the
// theme while others can be kept in the module itself.
// set 'pn' as default resource type
// For ajax requests we use the short urls filter to 'fix' relative paths
// Assign some useful theme settings
// firstly all theme variables
// secondly the base paths
// lastly the theme paths
$this->assign('stylepath', $this->baseurl . 'themes/' . $theme . '/style');
$this->assign('scriptpath', $this->baseurl . 'themes/' . $theme . '/javascript');
$this->assign('imagepath', $this->baseurl . 'themes/' . $theme . '/images');
* setup the current instance of the pnRender class and return it back to the module
function getInstance($module = null, $caching = null, $cache_id = null, $add_core_data = false)
* static variable to hold the instance of this object when called in a singleton pattern
$instance = new pnRender($module, $caching);
$instance->caching = $caching;
$instance->cache_id = $cache_id;
$module = $instance->toplevelmodule;
//$instance->modinfo = pnModGetInfo(pnModGetIDFromName($module));
$instance->_add_plugins_dir($module);
$instance->add_core_data();
* Checks whether requested template exists.
* @param string $template
* Checks which path to use for required template
* @param string $template
if (isset ($cache[$template])) {
return $cache[$template];
foreach ($this->module as $module => $modinfo) {
// prepare the values for OS
$os_pnmodgetname = DataUtil::formatForOS($pnmodgetname);
$os_module = DataUtil::formatForOS($module);
$os_modpath = DataUtil::formatForOS($modinfo['directory']);
// Define the locations in which we will look for templates
// Note: Paths 1, 3, 5 and 7 - This allows for the hook or block functions
// (such as ratings and comments) to use different templates depending
// on the top level module. e.g. the comments dialog can be different
// They are only evaluated when the calling module is not the current one.
// 1. The top level module directory in the requested module folder
// in the theme directory.
$themehookpath = "themes/ $os_theme/templates/modules/ $os_module/ $os_pnmodgetname";
// 2. The module directory in the current theme.
$themepath = "themes/ $os_theme/templates/modules/ $os_module";
// 3. The global template directory for the current top level module
$globalhookpath = "config/templates/ $os_module/ $os_pnmodgetname";
// 4. The global template directory
$globalpath = "config/templates/ $os_module";
// 5. The top level module directory in the requested module folder
// in the modules sub folder.
$modhookpath = "modules/ $os_module/pntemplates/ $os_pnmodgetname";
// 6. The module directory in the modules sub folder.
$modpath = "modules/ $os_module/pntemplates ";
// 7. The top level module directory in the requested module folder
// in the system sub folder.
$syshookpath = "system/ $os_module/pntemplates/ $os_pnmodgetname";
// 8. The module directory in the system sub folder.
$syspath = "system/ $os_module/pntemplates ";
$ostemplate = DataUtil::formatForOS($template); //.'.htm';
// check the module for which we're looking for a template is the
// same as the top level mods. This limits the places to look for
if ($module == $pnmodgetname) {
$search_path = array($themepath,
$search_path = array($themehookpath,
foreach ($search_path as $path) {
$cache[$template] = $path;
// when we arrive here, no path was found
* executes & returns the template results
* This returns the template output instead of displaying it.
* Supply a valid template name.
* As an optional second parameter, you can pass a cache id.
* As an optional third parameter, you can pass a compile id.
* @param string $template the name of the template
* @param string $cache_id (optional) the cache ID
* @param string $compile_id (optional) the compile ID
* @param boolean $display
* @param boolean $reset (optional) reset singleton defaults
* @return string the template output
function fetch($template, $cache_id= null, $compile_id= null, $display = false, $reset = true)
$this->_setup_template($template);
$output = parent::fetch($template, $cache_id, $compile_id, $display);
$output = "\n<!-- Start ". $this->template_dir. "/$template -->\n"
// now we've got our output from this module reset our instance
// $this->module = $this->toplevelmodule;
* executes & displays the template results
* This displays the template.
* Supply a valid template name.
* As an optional second parameter, you can pass a cache id.
* As an optional third parameter, you can pass a compile id.
* @param string $template the name of the template
* @param string $cache_id (optional) the cache ID
* @param string $compile_id (optional) the compile ID
function display($template, $cache_id= null, $compile_id= null)
echo $this->fetch($template, $cache_id, $compile_id);
* finds out if a template is already cached
* This returns true if there is a valid cache for this template.
* Right now, we are just passing it to the original Smarty function.
* We might introduce a function to decide if the cache is in need
* @param string $template the name of the template
* @param string $cache_id (optional) the cache ID
function is_cached($template, $cache_id= null, $compile_id= null)
// insert the condition to check the cache here!
// if (functioncheckdb($this -> module)) {
// return parent :: clear_cache($template, $this -> cache_id);
$this->_setup_template($template);
if (!isset ($compile_id)) {
return parent::is_cached($template, $cache_id, $compile_id);
* clears the cache for a specific template
* This returns true if there is a valid cache for this template.
* Right now, we are just passing it to the original Smarty function.
* We might introduce a function to decide if the cache is in need
* @param string $template the name of the template
* @param string $cache_id (optional) the cache ID
* @param string $compile_id (optional) the compile ID
* @param string $expire (optional) minimum age in sec. the cache file must be before it will get cleared.
function clear_cache($template= null, $cache_id= null, $compile_id= null, $expire= null)
return parent::clear_cache($template, $cache_id, $compile_id, $expire);
* clear the entire contents of cache (all templates)
* Smarty's original clear_all_cache function calls the subclasse's
* clear_cache function. As we always prepend the module name, this
* @param string $exp_time expire time
* @return boolean results of {@link smarty_core_rm_auto()}
$res = parent::clear_cache(null, null, null, $exp_time);
// recreate index.html file
* set up paths for the template
* This function sets the template and the config path according
* to where the template is found (Theme or Module directory)
* @param string $template the template name
function _setup_template($template)
// default directory for templates
//echo $this->template_dir . '<br>';
* add a plugins dir to _plugin_dir array
* This function takes module name and adds two path two the plugins_dir array
* @param string $module well known module name
function _add_plugins_dir($module)
$modpath = ($modinfo['type'] == 3) ? 'system' : 'modules';
$mod_plugs = "$modpath/$modinfo[directory]/pntemplates/plugins";
* add core data to the template
* This function adds some basic data to the template depending on the
* current user and the PN settings.
* @param list of module names. all mod vars of these modules will be included too
* The mod vars of the current module will always be included
* @return boolean true if ok, otherwise false
// add modvars of current modules
foreach ($this->module as $module => $dummy) {
// add mod vars of all modules supplied as parameter
foreach ($modulenames as $modulename) {
// if the modulename is empty do nothing
// check if user wants to have /PNConfig
foreach($pnconfig as $key => $value) {
// gather all config vars
$pncore['pnconfig'][$key] = $value;
$this->assign('pncore', $pncore);
* Smarty block function to prevent template parts from being cached
* Smarty resource function to determine correct path for template inclusion
* For more information about parameters see http://smarty.php.net/manual/en/template.resources.php
function pn_get_template($tpl_name, &$tpl_source, &$smarty)
// determine the template path and store the template source
// get path, checks also if tpl_name file_exists and is_readable
if ($tpl_path !== false) {
if ($tpl_source !== false ) {
// get the timestamp of the last change of the $tpl_name file
// get path, checks also if tpl_name file_exists and is_readable
if ($tpl_path !== false) {
if ($tpl_timestamp !== false) {
// assume all templates are secure
// not used for templates
|