Location: PHPKode > projects > Blandware AtLeap Lite - CMS on PHP > atleaplite/include/util/smarty_ex.php
<?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);
}

?>
Return current item: Blandware AtLeap Lite - CMS on PHP