File: D:/HostingSpaces/PvdBoogaard/indoorski.nl/backup/oude-site/cms/api/class.template.php
<?php
/**
* This file contains the iwp_template class.
*
* @author Jordie <jordie+code@interspire.com>
*
* @package IWP
* @subpackage IWP_API
*/
// require the base class
IWP::GetLib('template/class.template');
/**
* This class extends upon the base InterspireTemplate class.
* It makes a few changes and adds a few functions specific for Website Publisher.
* It is the template class used by both the control panel and the front end.
*
* @package IWP
* @subpackage IWP_API
*/
class iwp_template extends InterspireTemplate {
/**
* This static variable holds the current instance of this object being loaded.
* So using the getInstance function anywhere will return the very same instance.
*
* @var object Instance
*/
public static $Instance;
public $TemplateLocation = 'frontend';
public $config = null;
public static $PermissionOptions;
public static $OutputBlocks = array();
protected $AllowedFunctions = array('addslashes', 'stripnewlines', 'stripslashes', 'number_format', 'dateformat', 'errorimg', 'sprintf', 'round','math', 'ceil', 'is_checked', 'is_selected', 'iwp_strtoupper', 'iwp_strtolower' ,'strlen', 'ucfirst', 'strreplace', 'stripspaces', 'implode', 'nicesize', 'iwp_filterjavascriptstring', 'iwp_js', 'iwp_htmlspecialchars', 'iwp_htmlentities', 'iwp_shortdate', 'iwp_longdate', 'strtotime', 'var_dump', 'print_r', 'elipsize', 'iwp_redirect', 'json_encode');
protected $GetHelptipFunction = 'GetAdminHelpTip';
/**
* This is a list of required CSS files. This is handy if you're passing a lot of templates dynamically (like we are in Website Publisher)
* and each section may or may not need a CSS file AND multiple sections may need the same CSS file as another. Using this method we can make sure that
* there are no duplicate calls to CSS files.
*
* @var array
*/
public $CSSfiles = array();
/**
* This contains an array of if statements for the javascript files.
* e.g. It can be used if a JS file is only required if you're using Internet Explorer.
*
* Example: $tpl->JSfilesIF[] = 'IE';
*
* Then in the template you could have code similar to:
*
* {if $tpl.JSfilesIF.$key !== false}
* <!--[if {$tpl.JSfilesIF.$key}]><script type="text/javascript" src="{$file}"></script><![endif]-->
* {else}
* <script type="text/javascript" src="{$file}"></script>
* {/if}
*
* @var array $JSfilesIF
*/
public $JSfilesIF = array();
/**
* This is a list of required javascript files. This is handy if you're passing a lot of templates dynamically (like we are in website publisher)
* and each section may or may not need a javascript file AND multiple section may need the same JS file as another. Using this method we can make sure that
* there are no duplicate calls to javascript files.
*
* @example (This extends on the code example used by $JSFilesIF
*
* {if sizeof($tpl.JSfiles) > 0}
* {foreach from=$tpl.JSfiles key=key item=file id=jsFileLoop}
* {if $tpl.JSfilesIF.$key !== false}
* <!--[if {$tpl.JSfilesIF.$key}]><script type="text/javascript" src="{$file}"></script><![endif]-->
* {else}
* <script type="text/javascript" src="{$file}"></script>
* {/if}
* {/foreach}
* {/if}
*
* @var array $JSfiles
*/
public $JSfiles = array();
public $onPageLoadJs = array();
/**
* This is the object prefix that is used on all objects called in the template
* Example:
* {foreach from=%my_obj etc.}
* {/foreach}
* This will call $ObjectPrefix.'my_obj'
* e.g. If the prefix is 'iwp_' it will call on an object called 'iwp_my_obj'
*
* @var string $ObjectPrefix
*/
protected $ObjectPrefix = 'iwp_';
/**
* getInstance
* This is a static function that sets up the class instance and stores it to the static variable. It will then return that instantiation in the future.
*
* @return iwp_template Returns the instantiated object
**/
public static function getInstance(){
if(!isset(self::$Instance)){
self::$Instance = new self();
}
if(class_exists('IWP')){
self::$Instance->Assign('DemoMode', IWP::$DemoMode);
}
return self::$Instance;
}
public static function GetPermissionOptions () {
return self::$PermissionOptions;
}
/**
* The class constructor
*
* Calls the parent constructor
*/
public function __construct(){
parent::__construct();
$this->Assign('now', time());
$this->LoadSiteVariables();
}
/**
* This function takes a iwp_paging object and outputs the template code for it, makes it easier to work with paging in the control panel.
*
* @param object $paging The iwp_paging object being used
* @return string The resulting paging HTML from the template being parsed
*/
public function GetAdminPaging(&$paging){
$return = '';
$file = $this->TemplatePath . '/paging.html';
if(file_exists($file)){
ob_start();
include($file);
$return = ob_get_contents();
ob_end_clean();
}
return $return;
}
private $languageForJs = array();
public function GetLanguageForJS () {
return $this->languageForJs;
}
/**
* This function allows language variables to be added from any source to the Javascript output.
*
* @param array $lang This is an array of strings which are language variable names that can be used directly with the language class
* @param iwp_language $langInstance This should be an instance of the iwp_language class, pass this in if the language variable is elsewhere, e.g. in a module.
*/
public function AddLanguageForJS($lang = null, $langInstance = null, $prefix = '') {
if(empty($lang) || is_null($lang) || (is_array($lang) && sizeof($lang) < 1)){
return;
}
$outputArray = array();
if(!is_array($lang)) {
$lang = array($lang);
}
foreach($lang as $langVar){
if(!is_null($langInstance) && $langInstance instanceof iwp_language) {
$this->languageForJs[$prefix . $langVar] = $langInstance->Get($langVar);
} else {
$this->languageForJs[$prefix . $langVar] = iwp_language::getInstance()->Get($langVar);
}
}
$this->Assign('languageForJS', $this->languageForJs);
}
/**
* This function assigns all the site variables to be used in the template
*
* @return void Doesn't return anything
*/
private function LoadSiteVariables(){
$site = array();
$site['templateUrl'] = iwp_config::GetPublic('CurrentTemplateUrl');
$site['url'] = iwp_config::GetPublic('siteURL');
$site['metaTitle'] = iwp_config::GetPublic('siteName');
$site['metaDescription']= iwp_config::GetPublic('siteDesc');
$site['metaKeywords'] = iwp_config::GetPublic('siteKeywords');
$site['charset'] = iwp_config::GetPublic('charset');
$site['headerAppend'] = iwp_config::GetPublic('headerAppend');
$site['adminPath'] = IWP_ADMIN_PATH;
$site['maxUploadFileSize'] = getMaxUploadSize();
$this->Assign('site', $site);
}
/**
* This is a helper function that will load a section file, parse it and return the HTML content
*
* @param string $tplFile The name of the section file to parse
* @param boolean $returnCode Whether or not to return the code or to output it -- by default it returns.
*
* @return string The parsed HTML content of the section
*/
public function ParseSection($tplFile, $returnCode=true){
$dir = $this->TemplatePath;
$this->SetTemplatePath(IWP_CACHE_SECTION_HTML_PATH);
$return = '';
$return = $this->ParseTemplate($tplFile,$returnCode);
$this->SetTemplatePath($dir);
return $return;
}
/**
* This is the primary function that outputs a block. Blocks are created in the Site Layout section and can be just pure or a Title and content combo.
* This function gets the data from the database and parses the template file to return the final processed data.
*
* @return string The final HTML output of the block
*/
public function OutputBlock($type, $id, $section, $outputCounter){
$fileName = '';
// if(!isset(self::$OutputBlocks[$section])){
// self::$OutputBlocks[$section] = array();
// }
$subSection = $section . '_' . $type;
if(!isset(self::$OutputBlocks[$subSection])){
self::$OutputBlocks[$subSection] = array();
}
// $position = count(self::$OutputBlocks[$section]);
$typePosition = count(self::$OutputBlocks[$subSection]);
//self::$OutputBlocks[$section][$position] = $type . '_' . $id;
self::$OutputBlocks[$subSection][$typePosition] = $type . '_' . $id;
$typePosition++; $outputCounter++;
$this->Assign('blockNumberClass', ' Block' . $outputCounter .' ');
$this->Append('blockNumberClass', ' ' .$type . 'Block' . $typePosition .' ');
if(!iwp_IsId($id)){ // IsId casts to an integer for us
// @todo - when we implement error logging, insert an error message saying block not found
return '';
}
$baseClass = iwp_base::getInstance();
$baseClass->cache->SetDir('blocks');
if(!$baseClass->cache->HasExpired('block'.$section.$id)){
return $baseClass->cache->ReadCache('block'.$id);
}
// block types can only have letters in their names
$type = preg_replace('#[^a-zA-Z]#', '', $type);
// checking for what section files exist
// by default it looks for a 'standard' template file for the sesction (i.e. left, right, top, bottom or middle)
// if that doesn't exist it checks for a generic standard that should work anywhere
if(is_file(IWP_CACHE_SECTION_HTML_PATH .'/'.iwp_strtolower($type).'_'.$section.'_standard.html')){
$fileName = iwp_strtolower($type).'_'.$section.'_standard';
}elseif(is_file(IWP_CACHE_SECTION_HTML_PATH .'/'.iwp_strtolower($type).'_standard_'.$section.'.html')){
$fileName = iwp_strtolower($type).'_standard_'.$section;
}elseif(is_file(IWP_CACHE_SECTION_HTML_PATH .'/'.iwp_strtolower($type).'_standard.html')){
$fileName = iwp_strtolower($type).'_standard';
}else{
return ''; // no section template file found
}
$data = $baseClass->db->FetchQuery('select * from ' . IWP_TABLE_TEMPLATE_DATA .' where blockid='.$id);
if(!is_array($data) || empty($data)){
// @todo - when we implement error logging, insert an error message saying block not found
return '';
}
if(iwp_strtolower($type) == "customimage"){
// Its an image block, so lets check the image exists. If it doesn't, return a error in a html comment for debugging purposes
if(!file_exists(IWP_BLOCK_IMAGES_PATH . '/'. $data['content'])){
return $baseClass->output->HTMLComment("Image doesn't exist " . htmlspecialchars($data['content']));
}
$this->Assign('imageURI',IWP_BLOCK_IMAGES_URI . '/'. $data['content']);
$this->Assign('imageAlt', $data['title']);
if(trim($data['uri']) == '' || $data['uri'] == 'http://'){
$this->Assign('imageIsLinked', false);
}else{
$this->Assign('imageIsLinked', true);
}
$this->Assign('imageLinkURI', $data['uri']);
if(trim($data['newwindow']) == 1){
$this->Assign('imageLinkTarget', '_blank');
}else{
$this->Assign('imageLinkTarget', '');
}
if($baseClass->valid->IsImageFileExtension($data['content'])){
list($width, $height) = getimagesize(IWP_BLOCK_IMAGES_PATH . '/' . $data['content']);
$this->Assign('imageWidth', $width);
$this->Assign('imageHeight', $height);
}
}else{
// its html block of some sort, set up the template variables with the data
if(strlen(strip_tags($data['content'])) == strlen($data['content'])){
$data['content'] = nl2br($data['content']);
}
$this->Assign('blockTitle', $data['title']);
$this->Assign('blockContent', $data['content'], false);
$this->Assign('blockId', $data['blockid']);
$this->Assign('blockName', $data['name']);
$this->Assign('blockType', $data['type']);
}
$tplData = '';
if (iwp_event::trigger(new iwp_event_template_outputblockbeforeparsesection($this, $fileName, $type, (int)$id, $section, $tplData))) {
$tplData .= $this->ParseSection($fileName);
}
$baseClass->cache->WriteCache('block'.$id, $tplData);
return $tplData;
}
/**
* This function adds in the full path to the templates for the style sheets
* It doesn't use the DOM object because IE specific style sheets are hidden in a comment tag, so they wouldn't get replaced
*
* @param string $code This is the HTML code to have the urls replaced on
*
* @return string This is the HTML with the paths replaced
*/
private function ParseHeaderHref($code){
$code = str_replace('href="styles', 'href="'.iwp_config::GetPublic('CurrentTemplateUrl').'/styles', $code);
$code = str_replace('href=\'styles', 'href=\''.iwp_config::GetPublic('CurrentTemplateUrl').'/styles', $code);
$code = str_replace('src="images/', 'src="'.iwp_config::GetPublic('CurrentTemplateUrl').'/images/', $code);
$code = str_replace('src=\'images/', 'src=\''.iwp_config::GetPublic('CurrentTemplateUrl').'/images/', $code);
return $code;
}
/**
* This overrides the parent class because we might need to use the modules directory to parse a template
* If we're passing a module template it needs to change the tempalte directory temporarily then run the parent ParseTemplate function
* then revert the template directory back to what it was.
*
* @param string $file
* @param boolean $return Whether to echo it out directly or return it as a string
* @param string $module If its not null it means it needs to parse a module template
* @return mixed
*/
public function ParseTemplate($file=null, $return=false, $module=null){
iwp_cache::ConfirmDir('templates');
$output = '';
if($module === null){
$output = parent::ParseTemplate($file, true);
if(!defined('IN_CONTROL_PANEL') || !IN_CONTROL_PANEL){
$output = $this->ParseHeaderHref($output);
}
if($return){
return $output;
}else{
echo $output;
}
}else{
$dir = $this->TemplatePath;
$this->appendToParseTemplateForIncluded = ', false, "'.$module.'"';
if(file_exists(IWP_BASE_PATH . '/templates/' . iwp_config::Get('template') . '/modules/' . $module . '/templates/' . $file . '.' . $this->GetExtension())){
$this->SetTemplatePath(IWP_BASE_PATH . '/templates/' . iwp_config::Get('template') . '/modules/' . $module . '/templates/');
}else{
$this->SetTemplatePath(IWP_MODULES_PATH .'/'.$module .'/templates/');
}
if($return){
$output = parent::ParseTemplate($file, $return);
$this->SetTemplatePath($dir);
$this->appendToParseTemplateForIncluded = '';
return $output;
}
parent::ParseTemplate($file, $return);
$this->SetTemplatePath($dir);
$this->appendToParseTemplateForIncluded = '';
}
return '';
}
public function SetTemplatePathForBackEnd(){
$this->SetTemplatePath(IWP_BASE_PATH .'/'.IWP_ADMIN_PATH .'/templates/', 'tpl');
$this->DefaultHtmlEscape = false;
$this->TemplateLocation = 'backend';
}
public function SetTemplatePathForFrontEnd(){
$this->SetTemplatePath(dirname(dirname(__FILE__)) . "/templates/" . iwp_config::Get('template'), 'html');
$this->DefaultHtmlEscape = true;
$this->TemplateLocation = 'frontend';
}
/**
* This is a wrapper function that allows for direct input of template code to be parsed, rather than parsing a file on the filesystem
*
* @param string $input The template code to be parsed
*
* @return string Returns the final parsed code, ready for output
*/
public function ParseInput($input){
iwp_cache::ConfirmDir('templates');
return parent::ParseTemplate(null, true, $input);
}
/**
* This function loads the current template's config file and sets the instance of the template_config it created as a member variable of this class
*
* @return void
*
* @see $TemplatePath
* @see $config
*/
public function LoadTemplateConfigFile($path=null){
$reloadBackEnd = false;
if($this->TemplateLocation == 'backend') {
$this->SetTemplatePathForFrontEnd();
$reloadBackEnd = true;
}
if(is_null($this->config)){
$config = null;
if(is_null($path)){
$path = $this->TemplatePath;
}
if(file_exists($path.'/config.php')){
include_once($path.'/config.php');
}
$this->config = &$config;
}
if($reloadBackEnd) {
$this->SetTemplatePathForBackEnd();
}
return is_object($this->config);
}
/**
* Checks to see if the passed in name of a section is a real file.
*
* @param string $sectionName The name of the section to check if it exists.
*
* @return boolean True if the section file exists, false otherwise
*/
public function IsSection($sectionName){
return file_exists(IWP_CACHE_SECTION_HTML_PATH. '/'. $sectionName . ".html");
}
/**
* Adds a javascript source block that will be output in the page html
*
* @param mixed $script
*/
public function AddOnLoadJS ($script) {
if(!in_array($script, $this->onPageLoadJs)){
$this->onPageLoadJs[] = $script;
}
}
/**
* This function adds new elements to the beginning of the $JSfiles and $JSfilesIF member variables.
* It checks if an elements already exists, if it does, it won't add in a duplicate.
*
* @param string $file The full path to the javascript file to include
* @param string $if The browser to show this file for. If null, show to all.
*/
public function PrependRequiredJS($file, $if = null, $addVersion = true){
if($addVersion){
$file .= '?v='. urlencode(PRODUCT_VERSION_INTERNAL);
}
if(!in_array($file, $this->JSfiles)){
array_unshift($this->JSfiles, $file);
if($if !== null){
array_unshift($this->JSfilesIF, $if);
}else{
array_unshift($this->JSfilesIF, false);
}
}
}
/**
* This function adds new elements to the $JSfiles and $JSfilesIF member variables.
* It checks if an elements already exists, if it does, it won't add in a duplicate.
*
* @param string $file The full path to the javascript file to include
* @param string $if The browser to show this file for. If null, show to all.
*/
public function AddRequiredJS($file, $if = null, $addVersion = true){
if($addVersion){
$file .= '?v='. urlencode(PRODUCT_VERSION_INTERNAL);
}
if(!in_array($file, $this->JSfiles)){
$pos = sizeof($this->JSfiles);
$this->JSfiles[$pos] = $file;
if($if !== null){
$this->JSfilesIF[$pos] = $if;
}else{
$this->JSfilesIF[$pos] = false;
}
}
}
/**
* This function adds a new element to the $CSSfiles member variable.
* It checks if an element already exists, if it does, it won't add in a duplicate.
*
* @param string $file The full path to the CSS file to include
*/
public function AddRequiredCSS ($file, $addVersion = true)
{
if ($addVersion) {
if (strpos($file, '?') === false) {
$file .= '?v='. urlencode(PRODUCT_VERSION_INTERNAL);
} else {
$file .= '&v='. urlencode(PRODUCT_VERSION_INTERNAL);
}
}
if (!in_array($file, $this->CSSfiles)) {
$this->CSSfiles[] = $file;
}
}
public function ParseConfig() {
}
}
iwp_template::$PermissionOptions = array(
'full' => new iwp_permissionoption(false, false, false),
'choosetemplate' => new iwp_permissionoption(false, false, false),
'websitelayout' => new iwp_permissionoption(false, false, false),
'logo' => new iwp_permissionoption(false, false, false),
'downloadtemplate' => new iwp_permissionoption(false, false, false),
'addeditphpblock' => new iwp_permissionoption(false, false, false),
);