<?php
/*
* Copyright 2008 Blandware (http://www.blandware.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Smarty extensions.
*
* @package AtleapLite
* @author Roman Puchkovskiy
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
*/
/**
*/
require 'Smarty.class.php';
require 'server_options.php';
/**
* Main smarty extension class.
*
* @package AtleapLite
*/
class Smarty_Base extends Smarty {
/**
* The display layout, if set
*
* @var string
* @access private
*/
var $_displayLayout = null;
/**
* Whether admin layout should be used to render page.
*
* @var bool
* @access private
*/
var $_adminLayout = true;
/**
* Whether nothing should be output by this Smarty instance
*/
var $_noOutput = false;
/**
* Array of named counters
*
* @var array
* @access private
*/
var $_counters = array();
/**
* Constructor. Does all smarty configuration.
*/
function Smarty_Base()
{
global $smartyCompiledTemplatesDir;
$this->Smarty();
$dir = 'smarty';
$this->template_dir = "$dir/templates/";
$this->compile_dir = $smartyCompiledTemplatesDir;
$this->config_dir = "$dir/configs/";
$this->cashing = false;
$this->force_compile = true;
$this->register_function('buildUrl', 'smarty_function_buildUrl');
$this->register_function('rewriteUrl', 'smarty_function_rewriteUrl');
$this->register_function('initFilters', 'smarty_function_initFilters');
$this->register_function('filterName', 'smarty_function_filterName');
$this->register_function('filterValue', 'smarty_function_filterValue');
$this->register_function('textFilter', 'smarty_function_textFilter');
//$this->register_function('dateFilter', 'smarty_function_dateFilter');
$this->register_function('sortLink', 'smarty_function_sortLink');
$this->register_function('sortLinkTitle', 'smarty_function_sortLinkTitle');
$this->register_function('getPages', 'smarty_function_getPages');
$this->register_function('field', 'smarty_function_field');
$this->register_function('base', 'smarty_function_base');
$this->register_function('loadTopNews', 'smarty_function_loadTopNews');
$this->register_function('formatDate', 'smarty_function_formatDate');
$this->register_function('resourceIcon', 'smarty_function_resourceIcon');
$this->register_function('button', 'smarty_function_button');
$this->register_function('random', 'smarty_function_random');
$this->register_function('getFreeCategories', 'smarty_function_getFreeCategories');
$this->register_function('message', 'smarty_function_message');
$this->register_function('smartFileSize', 'smarty_function_smartFileSize');
$this->register_function('count', 'smarty_function_count');
$this->register_function('hiddenFields', 'smarty_function_hiddenFields');
$this->register_function('fieldValue', 'smarty_function_fieldValue');
$this->register_block('contextMenu', 'smarty_block_contextMenu');
$this->register_block('ifEditMode', 'smarty_block_ifEditMode');
$this->register_function('allowed', 'smarty_function_allowed');
}
/**
* Assigns some variables for grid.
*
* @param string $gridName name of grid
* @param object $descriptor descriptor
* @param string $action action name
*/
function initGrid($gridName, &$descriptor, $action) {
$this->assign('gridName', $gridName);
$this->assign('gridDescriptor', $descriptor);
$this->assign('gridAction', $action);
}
/**
* Returns grid name.
*
* @return string name of grid
*/
function getGridName() {
return $this->get_template_vars('gridName');
}
/**
* Returns filters name.
*
* @return string name of filters
*/
function getFiltersName() {
return 'filters';
}
/**
* Returns descriptor.
*
* @return object $descriptor
*/
function getDescriptor() {
return $this->get_template_vars('gridDescriptor');
}
/**
* Returns action.
*
* @return string action
*/
function getAction() {
return $this->get_template_vars('gridAction');
}
/**
* Sets display layout (i.e. the layout which will be used for displaying).
*
* @param string $layout layout
*/
function setDisplayLayout($layout) {
$this->_displayLayout = $layout;
}
/**
* Returns display layout (i.e. the layout which will be used for displaying).
*
* @return string display layout
*/
function getDisplayLayout() {
return $this->_displayLayout;
}
/**
* Returns whether display layout is set.
*
* @return bool true if set
*/
function isDisplayLayoutSet() {
return !empty($this->_displayLayout);
}
/**
* Returns whether admin layout should be used to render a result.
*
* @return bool true if admin layout will be used
*/
function isAdminLayout() {
return $this->_adminLayout;
}
/**
* Sets whether admin layout should be used to render a result.
*
* @param bool $val true if admin layout will be used
*/
function setAdminLayout($val) {
$this->_adminLayout = $val;
}
/**
* Sets flag which suppresses any output from this Smarty instance.
*/
function setNoOutput() {
$this->_noOutput = true;
}
/**
* Returns true if this should not output anything.
*
* @return true if should not output
*/
function isNoOutput() {
return $this->_noOutput;
}
/**
* Increments a named counter.
*
* @param string $name counter name
*/
function incrementCounter($name) {
if (!isset($this->_counters[$name])) {
$this->_counters[$name] = 0;
}
$this->_counters[$name]++;
}
/**
* Returns a named counter value.
*
* @param string $name counter name
* @return integer counter value
*/
function getCounter($name) {
if (!isset($this->_counters[$name])) {
$this->_counters[$name] = 0;
}
return $this->_counters[$name];
}
}
/**
* Smarty function that builds an URL.
* Following parameters are supported:
* <ul>
* <li>assign - if set, result will be stored to variable with given name,
* else it will be written to page</li>
* <li>absolute - if true, URL will contain context path</li>
* <li>friendly - 'friendliness' type</li>
* <li>language - language to set</li>
* <li>... other parameters... - passed to buildUrl() function</li>
* </ul>
*
* @see buildUrl()
*/
function smarty_function_buildUrl($params, &$smarty) {
$assign = $params['assign'];
unset($params['assign']);
$absolute = $params['absolute'];
unset($params['absolute']);
$friendly = $params['friendly'];
if ($friendly) {
unset($params['friendly']);
}
$language = $params['language'];
unset($params['language']);
$result = buildUrl(null, $params, $friendly, $absolute, $language);
if (empty($assign)) {
return $result;
} else {
$smarty->assign($assign, $result);
}
}
function smarty_function_rewriteUrl($params, &$smarty) {
$assign = $params['assign'];
unset($params['assign']);
$url = $params['url'];
unset($params['url']);
$absolute = $params['absolute'];
unset($params['absolute']);
$friendly = $params['friendly'];
if ($friendly) {
unset($params['friendly']);
}
$language = $params['language'];
unset($params['language']);
$result = rewriteUrl($url, $params, $friendly, $absolute, $language);
if (empty($assign)) {
return $result;
} else {
$smarty->assign($assign, $result);
}
}
/**
* Initializes filters for a given grid.
*/
function smarty_function_initFilters($params, &$smarty) {
$gridAction = $smarty->getAction();
$result = "<input type=\"hidden\" name=\"action\" value=\"$gridAction\">";
// $result .= "<input type=\"hidden\" name=\"resetPageId\" value=\"yes\">";
return $result;
}
/**
* Renders filter name for a given colon.
* <ul>
* <li>colon - name of colon</li>
* </ul>
*/
function smarty_function_filterName($params, &$smarty) {
$colon = $params['colon'];
$descriptor = $smarty->getDescriptor();
$dbColon = $descriptor->objToDb($colon);
$filtersName = $smarty->getFiltersName();
return $filtersName . '[' . $dbColon . ']';
}
/**
* Calculates filter value.
* <ul>
* <li>assign - if set, result will be stored to variable with given name,
* else it will be written to page</li>
* <li>colon - colon name</li>
* <li>escape - whether result should be HTML-escaped</li>
* </ul>
*/
function smarty_function_filterValue($params, &$smarty) {
$colon = $params['colon'];
$descriptor = $smarty->getDescriptor();
$dbColon = $descriptor->objToDb($colon);
$assign = $params['assign'];
$escape = $params['escape'];
if ($escape === null || $escape === '') {
$escape = true;
}
$filtersName = $smarty->getFiltersName();
$filters = $smarty->get_template_vars($filtersName);
$result = $filters[$dbColon];
if ($escape === true) {
$result = htmlspecialchars($result, ENT_QUOTES);
}
if (empty($assign)) {
return $result;
} else {
$smarty->assign($assign, $result);
}
}
/**
* Renders a text filter.
* <ul>
* <li>maxlength - max length in characters</li>
* <li>size - text input size in characters</li>
* <li>class - HTML class of element; if not set, 'form_filter' will be used</li>
* </ul>
*/
function smarty_function_textFilter($params, &$smarty) {
$name = smarty_function_filterName($params, $smarty);
$value = smarty_function_filterValue($params, $smarty);
$maxlength = isset($params['maxlength']) ? $params['maxlength'] : 255;
$size = isset($params['size']) ? $params['size'] : 10;
$clazz = isset($params['class']) ? $params['class'] : 'form_filter';
return "<input type=\"text\" name=\"$name\" value=\"$value\" maxlength=\"$maxlength\" size=\"$size\" class=\"$clazz\">";
}
/*function smarty_function_dateFilter($params, &$smarty) {
$name = smarty_function_filterName($params, $smarty);
$value = smarty_function_filterValue($params, $smarty);
$maxlength = isset($params['maxlength']) ? $params['maxlength'] : 20;
$size = isset($params['size']) ? $params['size'] : 10;
$clazz = isset($params['class']) ? $params['class'] : 'form_filter';
return "<input type=\"text\" name=\"$name\" value=\"$value\" maxlength=\"$maxlength\" size=\"$size\" class=\"$clazz\"";
}*/
/**
* Renders a sort link.
* <ul>
* <li>colon - colon name</li>
* </ul>
*/
function smarty_function_sortLink($params, &$smarty) {
$colon = $params['colon'];
$descriptor = $smarty->getDescriptor();
$dbColon = $descriptor->objToDb($colon);
$sortDir = 'sortDir' . ucfirst($colon);
$linkParams = array('sortColon' => $dbColon, 'sortDir' => $smarty->get_template_vars($sortDir));
$action = $smarty->getAction();
return buildUrl($action, $linkParams);
}
/**
* Renders a sort link title.
* <ul>
* <li>colon - colon name</li>
* <li>prefix - prefix before main message (which is defined by asc or desc)</li>
* <li>asc - message for ascending order</li>
* <li>desc - message for descending order</li>
* </ul>
*/
function smarty_function_sortLinkTitle($params, &$smarty) {
$colon = $params['colon'];
$prefix = $params['prefix'];
$asc = $params['asc'];
$desc = $params['desc'];
$descriptor = $smarty->getDescriptor();
$sortDir = 'sortDir' . ucfirst($colon);
$sortDirValue = $smarty->get_template_vars($sortDir);
$result = $prefix;
$result .= ($sortDirValue == 'asc' ? $asc : $desc);
return $result;
}
/**
* Gets pages for a given menu and assigns them to some variable.
* <ul>
* <li>menu - menu identifier</li>
* <li>assign - variable to which to put array of pages</li>
* </ul>
*/
function smarty_function_getPages($params, &$smarty) {
$menu = $params['menu'];
$assign = $params['assign'];
$cacheManager = new CacheManager();
$pages = $cacheManager->getMenuPages($menu, getCurrentLanguage());
if ($pages == null) {
// cache miss
$dao =& getDao('page');
$pages = $dao->findActiveByMenuAndLanguage($menu, getCurrentLanguage());
$cacheManager->putMenuPages($menu, getCurrentLanguage(), $pages);
}
$smarty->assign($assign, $pages);
}
/**
* Renders field; if user has updatePage permission, field content will be
* highlighted when mouse enters its area; also, double-click will cause
* page to be edited or created (the latter is for case when there's no page
* with such identifier in the current language and page with the same
* identifier in default language is displayed).
* <ul>
* <li>pageId - ID of page to which field belongs</li>
* <li>identifier - field identifier</li>
* <li>pageIdentifier - identifier of page to which field belongs</li>
* <li>pageLanguage - language of page to which field belongs</li>
* </ul>
*/
function smarty_function_field($params, &$smarty) {
$wrap = allowed('updatePage');
$pageId = $params['pageId'];
$identifier = $params['identifier'];
$pageIdentifier = $params['pageIdentifier'];
$pageLanguage = $params['pageLanguage'];
$result = '';
$cacheManager = new CacheManager();
$field = $cacheManager->getField($pageId, $identifier);
if ($field == null) {
// cache miss
$field =& getDao('field');
if ($field->findByPageIdAndIdentifier($pageId, $identifier) > 0) {
$result = $field->data;
$cacheManager->putField($field);
}
} else {
// cache hit
$result = $field->data;
}
if ($wrap) {
$currentLanguage = getCurrentLanguage();
if (!empty($pageLanguage) && $pageLanguage != $currentLanguage) {
$result = "<div id=\"fieldWrapperCreate.{$pageIdentifier}.{$currentLanguage}.$identifier\" class=\"fieldWrapper\">$result</div>";
} else {
$result = "<div id=\"fieldWrapper.{$pageId}.$identifier\" class=\"fieldWrapper\">$result</div>";
}
}
return $result;
}
/**
* Renders a base tag.
*
* @global string context path
*/
function smarty_function_base($params, &$smarty) {
$url = defaultBaseHref();
return "<base href=\"$url\">";
}
/**
* Loads top news and saves them to variable.
* <ul>
* <li>assign - variable to which to put array of news items</li>
* </ul>
*/
function smarty_function_loadTopNews($params, &$smarty) {
$assign = $params['assign'];
$smarty->assign($assign, loadTopNews());
}
/**
* Formats a date.
* <ul>
* <li>assign - if set, result will be stored to variable with given name,
* else it will be written to page</li>
* <li>date - date to format (in DB format)</li>
* </ul>
*/
function smarty_function_formatDate($params, &$smarty) {
$assign = $params['assign'];
$date = $params['date'];
$result = dateFromDbFormat($date);
if (empty($assign)) {
return $result;
} else {
$smarty->assign($assign, $result);
}
}
/**
* Calculates a resource icon URL by file name.
* <ul>
* <li>assign - if set, result will be stored to variable with given name,
* else it will be written to page</li>
* <li>fileName - name of file</li>
* </ul>
*/
function smarty_function_resourceIcon($params, &$smarty) {
$assign = $params['assign'];
$fileName = $params['fileName'];
$resourceIcon = getResourceIconByMimeType($fileName);
if (!empty($resourceIcon)) {
$resourceIcon = "fileicons/$resourceIcon.gif";
}
if (empty($assign)) {
return $resourceIcon;
} else {
$smarty->assign($assign, $resourceIcon);
}
}
/**
* Renders a button.
* <ul>
* <li>url - button URL (ignored if onClick is not empty)</li>
* <li>title - button title</li>
* <li>onClick - onclick handler (if empty, url is used)</li>
* <li>class - HTML class (if empty, no class is rendered)</li>
* </ul>
*/
function smarty_function_button($params, &$smarty) {
$url = $params['url'];
$title = $params['title'];
$onClick = $params['onClick'];
$clazz = $params['class'];
$classCode = empty($clazz) ? '' : " class=\"$clazz\" ";
$onClick = empty($onClick) ? "document.location.href = '$url';" : $onClick;
return "<input type=\"button\" value=\"$title\" onclick=\"$onClick\" $classCode>";
}
/**
* Renders a random number (same as produced by rand()).
*/
function smarty_function_random($params, &$smarty) {
return rand();
}
/**
* Obtains categories with no parents and assigns them to variable.
* <ul>
* <li>assign - variable to which to put array of categories</li>
* </ul>
*/
function smarty_function_getFreeCategories($params, &$smarty) {
$assign = $params['assign'];
$dao =& getDao('category');
$result = $dao->getFreeCategories();
$smarty->assign($assign, $result);
}
/**
* Obtains a message.
* <ul>
* <li>assign - if set, result will be stored to variable with given name,
* else it will be written to page</li>
* <li>key - message key</li>
* </ul>
*/
function smarty_function_message($params, &$smarty) {
$assign = $params['assign'];
$key = $params['key'];
$escapeSingleQuotes = $params['escapeSingleQuotes'];
$result = getMessage($key);
if ($escapeSingleQuotes) {
$result = str_replace("'", "\\'", $result);
}
if (empty($assign)) {
return $result;
} else {
$smarty->assign($assign, $result);
}
}
/**
* Formats a file size in human-friendly format (with kb, mb if needed).
* <ul>
* <li>assign - if set, result will be stored to variable with given name,
* else it will be written to page</li>
* <li>size - file size</li>
* <li>b - text for 'bytes'</li>
* <li>kb - text for 'kilobytes'</li>
* <li>mb - text for 'megabytes'</li>
* </ul>
*/
function smarty_function_smartFileSize($params, &$smarty) {
$assign = $params['assign'];
$size = $params['size'];
$b = $params['b'];
$kb = $params['kb'];
$mb = $params['mb'];
$result = smartFileSize($size, $b, $kb, $mb);
if (empty($assign)) {
return $result;
} else {
$smarty->assign($assign, $result);
}
}
/**
* Calculates number of elements in array.
* <ul>
* <li>assign - if set, result will be stored to variable with given name,
* else it will be written to page</li>
* <li>array - the array</li>
* </ul>
*/
function smarty_function_count($params, &$smarty) {
$assign = $params['assign'];
$array = $params['array'];
$result = count($array);
if (empty($assign)) {
return $result;
} else {
$smarty->assign($assign, $result);
}
}
/**
* Renders hidden fields (all at once) which exist in the given form.
* <ul>
* <li>form - the form</li>
* </ul>
*/
function smarty_function_hiddenFields($params, &$smarty) {
$form = $params['form'];
return $form['hidden'];
}
/**
* Obtains a field value for some language. The precedence is as follows:
* <ul>
* <li>current language is tried</li>
* <li>default language is tried</li>
* <li>if some values exist in the map, any of them is returned</li>
* <li>null is returned</li>
* </ul>
* Parameters:
* <ul>
* <li>valueMap - mapping from the language codes to values</li>
* <li>assign - if set, result will be stored to variable with given name,
* else it will be written to page</li>
* <li>escape - whether result should be HTML-escaped</li>
* </ul>
*/
function smarty_function_fieldValue($params, &$smarty) {
$valueMap = $params['valueMap'];
$assign = $params['assign'];
$escape = $params['escape'];
if ($escape === null || $escape === '') {
$escape = true;
}
$currentLanguage = getCurrentLanguage();
$defaultLanguage = getDefaultLanguage();
if (isset($valueMap[$currentLanguage])) {
$result = $valueMap[$currentLanguage];
} elseif (isset($valueMap[$defaultLanguage])) {
$result = $valueMap[$defaultLanguage];
} elseif (count($valueMap > 0)) {
foreach ($valueMap as $value) {
$result = $value;
break;
}
} else {
$result = null;
}
if ($escape === true) {
$result = htmlspecialchars($result, ENT_QUOTES);
}
if (empty($assign)) {
return $result;
} else {
$smarty->assign($assign, $result);
}
}
/**
* Prepares a context menu, draws a block to which the context menu will be
* attached. The content of this will be put to this block.
* Parameters:
* <ul>
* <li>editModeOnly - if true, context menu will be prepared only when edit
* mode is ON.</li>
* <li>link_N - link of Nth item</li>
* <li>text_N - text of Nth item</li>
* <li>confirm_N - if true, then confirm() call will be made before following
* the link for Nth item</li>
* <li>permId_N - permission for Nth item</li>
* </ul>
* ID of context menu is assigned to 'contextMenuId' variable, and context menu
* is assigned to 'contextMenu' variable.
*/
function smarty_block_contextMenu($params, $content, &$smarty) {
if ($content === null) {
// opening tag
return null;
}
$editModeOnly = $params['editModeOnly'];
if ($editModeOnly === null) {
$editModeOnly = false;
}
$smarty->incrementCounter('block_contextMenu');
$number = $smarty->getCounter('block_contextMenu');
$editModeEnabled = !isAnonymous();
$wrap = !$editModeOnly || $editModeEnabled;
if ($wrap) {
$contextMenu = array();
foreach ($params as $k => $v) {
if (startsWith($k, 'link_')) {
$len = strlen('link_');
$index = substr($k, $len, strlen($k) - $len);
$contextMenu[$index]['link'] = $v;
} elseif (startsWith($k, 'text_')) {
$len = strlen('text_');
$index = substr($k, $len, strlen($k) - $len);
$contextMenu[$index]['text'] = $v;
} elseif (startsWith($k, 'confirm_')) {
$len = strlen('confirm_');
$index = substr($k, $len, strlen($k) - $len);
$contextMenu[$index]['confirm'] = $v;
} elseif (startsWith($k, 'permId_')) {
$len = strlen('permId_');
$index = substr($k, $len, strlen($k) - $len);
$contextMenu[$index]['permId'] = $v;
}
}
foreach ($contextMenu as $k => $v) {
if ((!empty($v['permId']) && !allowed($v['permId'])) || empty($v['link'])) {
unset($contextMenu[$k]);
}
}
$contextMenuId = 'cm_' . $number;
$smarty->assign('contextMenuId', $contextMenuId);
$smarty->assign('contextMenu', $contextMenu);
$content = '<div id="contextMenuInvokerWrapper_' . $number . '" class="contentWrapper" oncontextmenu="return showDropdownMenu(\'' . $contextMenuId . "', '" . $contextMenuId . '\', null, event);">' . $content . '</div>';
}
return $content;
}
/**
* Renders its content only if edit mode is ON.
*/
function smarty_block_ifEditMode($params, $content, &$smarty) {
if ($content === null) {
// opening tag
return null;
}
$editModeEnabled = !isAnonymous();
return $editModeEnabled ? $content : null;
}
/**
* Determines whether a given permission is allowed for the current user.
* Parameters:
* <ul>
* <li>permId - identifier of permission.</li>
* <li>assign - name of variable to which to save boolean result</li>
*/
function smarty_function_allowed($params, &$smarty) {
$permId = $params['permId'];
$allowed = allowed($permId);
$assign = $params['assign'];
$smarty->assign($assign, $allowed);
}
?>