/**
 * Zikula_View function to display a drop down list of languages
 *
 * Available parameters:
 *   - assign:   If set, the results are assigned to the corresponding variable instead of printed out
 *   - name:     Name for the control
 *   - id:       ID for the control
 *   - selected: Selected value
 *   - installed: if set only show languages existing in languages folder
 *   - all:      show dummy entry '_ALL' on top of the list with empty value
 *
 * Example
 *   {html_select_languages name=language selected=en}
 *
 * @param array       $params All attributes passed to this function from the template.
 * @param Zikula_View $view   Reference to the Zikula_View object.
 *
 * @deprecated smarty_function_html_select_locales()
 * @return string The value of the last status message posted, or void if no status message exists.
 */
function smarty_function_html_select_languages($params, Zikula_View $view)
{
    if (!isset($params['name']) || empty($params['name'])) {
        $view->trigger_error(__f('Error! in %1$s: the %2$s parameter must be specified.', array('html_select_languages', 'name')));
        return false;
    }
    require_once $view->_get_plugin_filepath('function', 'html_options');
    $params['output'] = array();
    $params['values'] = array();
    if (isset($params['all']) && $params['all']) {
        $params['values'][] = '';
        $params['output'][] = DataUtil::formatForDisplay(__('All'));
        unset($params['all']);
    }
    if (isset($params['installed']) && $params['installed']) {
        $languagelist = ZLanguage::getInstalledLanguageNames();
        unset($params['installed']);
    } else {
        $languagelist = ZLanguage::languageMap();
    }
    $params['output'] = array_merge($params['output'], DataUtil::formatForDisplay(array_values($languagelist)));
    $params['values'] = array_merge($params['values'], DataUtil::formatForDisplay(array_keys($languagelist)));
    $assign = isset($params['assign']) ? $params['assign'] : null;
    unset($params['assign']);
    $html_result = smarty_function_html_options($params, $view);
    if (!empty($assign)) {
        $view->assign($assign, $html_result);
    } else {
        return $html_result;
    }
}
/**
 * Zikula_View function to display a drop down list of themes.
 *
 * Available parameters:
 *   - name:     Name for the control (optional) if not present then only the option tags are output
 *   - id:       ID for the control
 *   - selected: Selected value
 *   - filter:   Filter themes use (possible values: ThemeUtil::FILTER_ALL (default) ThemeUtil::FILTER_USER, ThemeUtil::FILTER_SYSTEM, ThemeUtil::FILTER_ADMIN
 *   - state:    Filter themes by state (possible values: ThemeUtil::STATE_ALL (default), ThemeUtil::STATE_ACTIVE, ThemeUtil::STATE_INACTIVE
 *   - type:     Filter themes by type (possible values: ThemeUtil::TYPE_ALL (default), ThemeUtil::TYPE_XANTHIA3
 *   - assign:   If set, the results are assigned to the corresponding variable instead of printed out
 *
 * Examples
 *
 *     {html_select_themes name=mytheme selected=mythemechoice}
 *
 *     <select name="mytheme">
 *         <option value="">{ml name=_DEFAULT}</option>
 *         {html_select_themes selected=$mythemechoice}
 *     </select>
 *
 * @param array       $params All attributes passed to this function from the template.
 * @param Zikula_View $view   Reference to the Zikula_View object.
 *
 * @return string The value of the last status message posted, or void if no status message exists.
 */
function smarty_function_html_select_themes($params, Zikula_View $view)
{
    if (!isset($params['filter']) || !defined($params['filter'])) {
        $filter = ThemeUtil::FILTER_ALL;
    } else {
        $filter = constant($params['filter']);
    }
    if (!isset($params['state']) || !defined($params['state'])) {
        $state = ThemeUtil::STATE_ALL;
    } else {
        $state = constant($params['state']);
    }
    if (!isset($params['type']) || !defined($params['type'])) {
        $type = ThemeUtil::TYPE_ALL;
    } else {
        $type = constant($params['type']);
    }
    $themelist = array();
    $themes = ThemeUtil::getAllThemes($filter, $state, $type);
    if (!empty($themes)) {
        foreach ($themes as $theme) {
            $themelist[$theme['name']] = $theme['displayname'];
        }
    }
    natcasesort($themelist);
    require_once $view->_get_plugin_filepath('function', 'html_options');
    $output = smarty_function_html_options(array('options' => $themelist, 'selected' => isset($params['selected']) ? $params['selected'] : null, 'name' => isset($params['name']) ? $params['name'] : null, 'id' => isset($params['id']) ? $params['id'] : null), $view);
    if (isset($params['assign'])) {
        $view->assign($params['assign'], $output);
    } else {
        return $output;
    }
}
/**
 * Zikula_View function to display a drop down list of module stylesheets.
 *
 * Available parameters:
 *   - modname   The module name to show the styles for
 *   - assign:   If set, the results are assigned to the corresponding variable instead of printed out
 *   - id:       ID for the control
 *   - name:     Name for the control
 *   - exclude   Comma seperated list of files to exclude (optional)
 *   - selected: Selected value
 *
 * @param array       $params All attributes passed to this function from the template.
 * @param Zikula_View $view   Reference to the Zikula_View object.
 *
 * @return string The value of the last status message posted, or void if no status message exists.
 */
function smarty_function_html_select_modulestylesheets($params, Zikula_View $view)
{
    if (!isset($params['modname'])) {
        $view->trigger_error(__f('Error! in %1$s: the %2$s parameter must be specified.', array('html_select_modulestylesheets', 'modname')));
        return false;
    }
    if (isset($params['exclude'])) {
        $exclude = explode(',', trim($params['exclude']));
        unset($params['exclude']);
    } else {
        $exclude = array();
    }
    $params['values'] = ModUtil::apiFunc('ZikulaAdminModule', 'admin', 'getmodstyles', array('modname' => $params['modname'], 'exclude' => $exclude));
    unset($params['modname']);
    $params['output'] = $params['values'];
    $assign = isset($params['assign']) ? $params['assign'] : null;
    unset($params['assign']);
    require_once $view->_get_plugin_filepath('function', 'html_options');
    $output = smarty_function_html_options($params, $view);
    if (!empty($assign)) {
        $view->assign($assign, $output);
    } else {
        return $output;
    }
}
/**
 * Template plugin to display timezone list.
 *
 * Example {timezoneselect selected='Timezone'}.
 *
 * @param array       $params All attributes passed to this function from the template.
 * @param Zikula_View $view   The Zikula_View.
 *
 * @see   function.timezoneselect.php::smarty_function_timezoneselect().
 *
 * @return string The results of the module function.
 */
function smarty_function_timezoneselect($params, Zikula_View $view)
{
    require_once $view->_get_plugin_filepath('function', 'html_options');
    $timezones = DateUtil::getTimezones();
    if (!isset($params['selected']) || empty($params['selected']) || !isset($timezones[$params['selected']])) {
        $params['selected'] = System::getVar('timezone_offset');
    }
    return smarty_function_html_options(array('options' => $timezones, 'selected' => $params['selected'], 'print_result' => false), $view);
}
/**
 * Display an core image form submission button using either the <button> or the <input> HTML element.
 *
 * This tag calls the img tag to determine the full path of the image
 * for the src attribute of the img element within the button element, or
 * for the src attribute of the input element.
 *
 * <i>BEWARE: Internt Explorer 6.x does NOT work especially well with <button> tags!</i>
 *
 * Available attributes:
 *  - src       (string)    The file name of the image. The full path of the image
 *                          will be determined by the smarty_function_img function.
 *  - set       (string)    The name of the image set from which to retrieve the
 *                          image file (the name of a subdirectory under /images/icons).
 *  - mode      (string)    if set, the type of HTML element to be used (optional,
 *                          default: button). Values = [button|input]
 *  - type      (string)    if set, the type of button that will be generated
 *                          (optional, default: submit, used only if mode is set to 'button')
 *  - name      (string)    if set, the name of button that will be generated as
 *                          the name attribute on the button or input element
 *                          (optional, default: value of 'type' parameter)
 *  - value     (string)    if set, the value that will be generated as the
 *                          value attribute on the button or input element (optional,
 *                          however should be set if mode is input)
 *  - id        (string)    if set, the value of the id attribute on the button
 *                          or input element (optional)
 *  - class     (string)    if set, the value of the class attribute on the
 *                          button or input element (optional)
 *  - alt       (string)    if set, the value for the alt attribute. If mode is
 *                          'button' then the alt attribute is generated for
 *                          the img element embedded in the button element. If
 *                          mode is 'input' then the alt attribute is generated
 *                          for the input element. (optional)
 *  - title     (string)    if set, the value for the title attribute of the
 *                          button or input element. (optional)
 *  - text      (string)    if set, the button tag surrounds this string
 *  - assign    (string)    If set, the results are assigned to the corresponding
 *                          template variable instead of being returned to the template (optional)
 *
 * Examples:
 *
 * Display a submit button with button_ok.png (a green check mark) from the set of
 * small icons (/images/icons/small) with the <button ...> HTML element.
 *
 * <samp>{button src='button_ok.png' set='small'}</samp>
 *
 * Display a cancel button with button_cancel.png (a red 'X') from the set of
 * extra small icons (/images/icons/extrasmall) with the <button ...> HTML element.
 *
 * <samp>{button src='button_cancel.png' set='extrasmall' type='cancel'}</samp>
 *
 * Display a submit button with button_cancel.png (a red 'X') from the set of
 * medium icons (/images/icons/medium) and a value of
 * 'cancel' with the <input ...> HTML element. The id attribute of the input
 * element is set to 'cancelbutton'.
 *
 * <samp>{button src='button_cancel.png' set='medium' mode='input' value='cancel' id='cancelbutton'}</samp>
 *
 * @param array       $params All attributes passed to this function from the template.
 * @param Zikula_View $view   Reference to the {@link Zikula_View} object.
 *
 * @return string The rendered <button ...><img ...></button> or <input ...>
 *                element for the form button.
 */
function smarty_function_button($params, Zikula_View $view)
{
    // we're going to make use of pnimg for path searching
    require_once $view->_get_plugin_filepath('function', 'img');
    if (!isset($params['src'])) {
        $view->trigger_error(__f('Error! in %1$s: the %2$s parameter must be specified.', array('smarty_function_button', 'src')));
        return false;
    }
    if (!isset($params['set'])) {
        $view->trigger_error(__f('Error! in %1$s: the %2$s parameter must be specified.', array('smarty_function_button', 'set')));
        return false;
    }
    $type = isset($params['type']) ? $params['type'] : 'submit';
    $mode = isset($params['mode']) ? $params['mode'] : 'button';
    if (isset($params['name'])) {
        $name = ' name="' . DataUtil::formatForDisplay($params['name']) . '"';
    } else {
        $name = ' name="' . DataUtil::formatForDisplay($type) . '"';
    }
    if (isset($params['value'])) {
        $value = ' value="' . DataUtil::formatForDisplay($params['value']) . '"';
    } else {
        $value = '';
    }
    if (isset($params['id'])) {
        $id = ' id="' . DataUtil::formatForDisplay($params['id']) . '"';
    } else {
        $id = '';
    }
    if (isset($params['class'])) {
        $class = ' class="' . DataUtil::formatForDisplay($params['class']) . '"';
    } else {
        $class = '';
    }
    if (isset($params['text'])) {
        $text = ' ' . DataUtil::formatForDisplay($params['text']);
    } else {
        $text = '';
    }
    $title = isset($params['title']) ? $params['title'] : '';
    $alt = isset($params['alt']) ? $params['alt'] : '';
    // call the pnimg plugin and work out the src from the assigned template vars
    smarty_function_img(array('assign' => 'buttonsrc', 'src' => $params['src'], 'set' => $params['set'], 'modname' => 'core'), $view);
    $imgvars = $view->get_template_vars('buttonsrc');
    $imgsrc = $imgvars['src'];
    // form the button html
    if ($mode == 'button') {
        $return = '<button' . $id . $class . ' type="' . DataUtil::formatForDisplay($type) . '"' . $name . $value . ' title="' . DataUtil::formatForDisplay($title) . '"><img src="' . DataUtil::formatForDisplay($imgsrc) . '" alt="' . DataUtil::formatForDisplay($alt) . '" />' . $text . '</button>';
    } else {
        $return = '<input' . $id . $class . ' type="image"' . $name . $value . ' title="' . DataUtil::formatForDisplay($title) . '" src="' . DataUtil::formatForDisplay($imgsrc) . '" alt="' . DataUtil::formatForDisplay($alt) . '" />';
    }
    if (isset($params['assign'])) {
        $view->assign($params['assign'], $return);
    } else {
        return $return;
    }
}
/**
 * Zikula_View function to display a list box with a list of active modules.
 *
 * Either user or admin capable or all modules.
 *
 * Available parameters:
 *   - name:       Name for the control (optional) if not present then only the option tags are output
 *   - id:         ID for the control
 *   - selected:   Selected value
 *   - capability: Show modules with this capability, all or $capability.
 *   - assign:     If set, the results are assigned to the corresponding variable instead of printed out
 *
 * Example
 *
 *     {html_select_modules name=mod selected=$mymod}
 *
 *     <select name="mod">
 *         <option value="">&bsp;</option>
 *         {html_select_modules selected=$mythemechoice}
 *     </select>
 *
 * @param array       $params All attributes passed to this function from the template.
 * @param Zikula_View $view   Reference to the Zikula_View object.
 *
 * @see    function.html_select_modules.php::smarty_function_html_select_modules()
 * @return string A drop down containing a list of modules.
 */
function smarty_function_html_select_modules($params, Zikula_View $view)
{
    // we'll make use of the html_options plugin to simplfiy this plugin
    require_once $view->_get_plugin_filepath('function', 'html_options');
    // set some defaults
    if (isset($params['type'])) {
        // bc
        $params['capability'] = $params['type'];
    }
    if (!isset($params['capability'])) {
        $params['capability'] = 'all';
    }
    // get the modules
    switch ($params['capability']) {
        case 'all':
            $modules = ModUtil::getAllMods();
            break;
        default:
            $modules = ModUtil::getModulesCapableOf($params['capability']);
            break;
    }
    // process our list of modules for input to the html_options plugin
    $moduleslist = array();
    $installerArray = array('ZikulaBlocksModule', 'ZikulaErrorsModule', 'ZikulaPermissionsModule', 'ZikulaCategoriesModule', 'ZikulaGroupsModule', 'ZikulaThemeModule', 'ZikulaUsersModule', 'ZikulaSearchModule');
    if (!empty($modules)) {
        foreach ($modules as $module) {
            if (!(System::isInstalling() && in_array($module['name'], $installerArray))) {
                $moduleslist[$module['name']] = $module['displayname'];
            }
        }
    }
    natcasesort($moduleslist);
    // get the formatted list
    $output = smarty_function_html_options(array('options' => $moduleslist, 'selected' => isset($params['selected']) ? $params['selected'] : null, 'name' => isset($params['name']) ? $params['name'] : null, 'id' => isset($params['id']) ? $params['id'] : null), $view);
    if (isset($params['assign']) && !empty($params['assign'])) {
        $view->assign($params['assign'], $output);
    } else {
        return $output;
    }
}
/**
 * Zikula_View function to display a drop down list of languages
 *
 * Available parameters:
 *   - assign:   If set, the results are assigned to the corresponding variable instead of printed out
 *   - name:     Name for the control
 *   - id:       ID for the control
 *   - selected: Selected value
 *   - installed: if set only show languages existing in languages folder
 *   - all:      show dummy entry '_ALL' on top of the list with empty value
 *
 * Example
 *   {html_select_locales name=locale selected=en}
 *
 * @param array       $params All attributes passed to this function from the template.
 * @param Zikula_View $view   Reference to the Zikula_View object.
 *
 * @return string The value of the last status message posted, or void if no status message exists.
 */
function smarty_function_html_select_locales($params, Zikula_View $view)
{
    if (!isset($params['name']) || empty($params['name'])) {
        $view->trigger_error(__f('Error! in %1$s: the %2$s parameter must be specified.', array('html_select_locales', 'name')));
        return false;
    }
    require_once $view->_get_plugin_filepath('function', 'html_options');
    $values = $output = array();
    if (isset($params['all']) && $params['all']) {
        $values[] = '';
        $output[] = DataUtil::formatForDisplay(__('All'));
    }
    $installed = ZLanguage::getInstalledLanguageNames();
    $output = array_merge($output, DataUtil::formatForDisplay(array_values($installed)));
    $values = array_merge($values, DataUtil::formatForDisplay(array_keys($installed)));
    $html_result = smarty_function_html_options(array('output' => $output, 'values' => $values, 'selected' => isset($params['selected']) ? $params['selected'] : null, 'id' => isset($params['id']) ? $params['id'] : null, 'name' => $params['name']), $view);
    if (isset($params['assign']) && !empty($params['assign'])) {
        $view->assign($params['assign'], $html_result);
    } else {
        return $html_result;
    }
}
/**
 * Zikula_View function to create help link.
 *
 * This function creates a help link.
 * 
 * To make the link appear as a button, wrap it in a div or span with a class
 * of z-buttons.
 *
 * Available parameters:
 *   - filename:     name of file, defaults to 'help.txt'.
 *   - anchor:       anchor marker.
 *   - popup:        opens the help file in a new window using javascript.
 *   - width:        width of the window if newwindow is set, default 600.
 *   - height:       height of the window if newwindow is set, default 400.
 *   - title:        name of the new window if new window is set, default is 'Help'.
 *   - link_contents the text for the link (between the <a> and </a> tags); optional, if not specified, then the title is used.
 *   - icon_type      an optional icon type to include in the link, separated from the link_contents (or title) by a non-breaking space; equivalent to the type parameter from the {icon} template function
 *   - icon_size      the size of the icon (e.g., extrasmall); optional if link_icon_type is specified, defaults to 'extrasmall', otherwise ignored; 
 *                      equivalent to the size parameter of the {icon} template function
 *   - icon_width    the width of the icon in pixels; optional if link_icon_type is specified, if not specified, then obtained from size, otherwise ignored; 
 *                      equivalent to the width parameter of the {icon} template function
 *   - icon_height   the height of the icon in pixels; optional if link_icon_type is specified, if not specified, then obtained from size, otherwise ignored; 
 *                      equivalent to the height parameter of the {icon} template function
 *   - icon_alt      the alternate text for the icon, used for the alt param of the {icon} template function; optional if link_icon_type is specified, 
 *                      defaults to an empty string, otherwise ignored
 *   - icon_title    the title text for the icon, used for the title param of the {icon} template function; optional if link_icon_type is specified, 
 *                      defaults to an empty string, otherwise ignored
 *   - icon_optional if true and the icon image is not found then an error will not be returned, used for the optinal param of the {icon} template 
 *                      function; optional if link_icon_type is specified, defaults to false, otherwise ignored
 *   - icon_default  the full path to an image file to use if the icon is not found, used for the default param of the {icon} template 
 *                      function; optional if link_icon_type is specified, defaults to an empty string, otherwise ignored
 *   - icon_right    if true, then the icon is placed on the right side of the link text (the text from either link_contents or title); optional, 
 *                      defaults to false (placing the icon on the left side of the text)
 *   - icon_*        all remaining parameters with a "icon_" prefix are passed to the {icon} function and subsequently to the <img> tag, except for
 *                      'icon_assign' which is completely ignored; optional if link_icon_type is specified, otherwise ignored
 *   - class:        class for use in the <a> tag.
 *   - assign:       if set, the results (array('url', 'link') are assigned to the corresponding variable instead of printed out.
 *
 * Example: A pop-up help window with a width of 400 and a height of 300, containing the contents of help.txt, and a title of 'Help'
 * {helplink popup='1' width='400' height='300' filename='help.txt' title='Help'}
 *
 * Example: The same as above, except displayed as a button with an icon image placed on the left side of the text 'Help' separated by a non-breaking space.
 *          The image does not have either alternate text nor a title.
 * <div class="z-buttons">
 *     {helplink popup='1' width='400' height='300' filename='help.txt' title='Help' icon_type='help' icon_size='extrasmall'}
 * </div>
 *
 * Example: The same as above, except the icon's <img> tag will contain a class attrbute with the value "my_class"
 * <div class="z-buttons">
 *     {helplink popup='1' width='400' height='300' filename='help.txt' title='Help' icon_type='help' icon_size='extrasmall' icon_class='my_class'}
 * </div>
 *
 * @param array       $params All attributes passed to this function from the template.
 * @param Zikula_View $view   Reference to the Zikula_View object.
 *
 * @return string|void
 */
function smarty_function_helplink($params, Zikula_View $view)
{
    $userLang = ZLanguage::transformFS(ZLanguage::getLanguageCode());
    $systemLang = System::getVar('language_i18n');
    $iconParams = array();
    if (!empty($params) && is_array($params)) {
        foreach ($params as $key => $value) {
            if (strpos($key, 'icon_') === 0 && strlen($key) > 5) {
                $iconParams[substr($key, 5)] = $value;
                unset($params[$key]);
            }
        }
    }
    if (!empty($iconParams) && isset($iconParams['type'])) {
        // We need to make sure the icon template function is available so we can call it.
        require_once $view->_get_plugin_filepath('function', 'icon');
        $iconRightSide = false;
        if (isset($iconParams['right'])) {
            $iconRightSide = (bool) $iconParams['right'];
            unset($iconParams['right']);
        }
        if (isset($iconParams['assign'])) {
            // We cannot use the assign parameter with the icon function in this context.
            unset($iconParams['assign']);
        }
    } else {
        $iconParams = false;
        $iconRightSide = false;
    }
    $title = isset($params['title']) ? $params['title'] : 'Help';
    $linkContents = isset($params['link_contents']) ? $params['link_contents'] : $title;
    $fileName = isset($params['filename']) ? $params['filename'] : 'help.txt';
    $chapter = isset($params['anchor']) ? '#' . $params['anchor'] : '';
    $class = isset($params['class']) ? $params['class'] : null;
    $width = isset($params['width']) ? $params['width'] : 600;
    $height = isset($params['height']) ? $params['height'] : 400;
    $popup = isset($params['popup']) ? true : false;
    $modname = $view->getModuleName();
    $linkID = isset($params['linkid']) ? $params['linkid'] : DataUtil::formatForDisplay(strtolower('manuallink_' . $modname . '_' . hash('md5', serialize($params))));
    $base = ModUtil::getModuleBaseDir($modname) . "/{$modname}/docs";
    $paths = array("{$base}/{$userLang}/{$fileName}", "{$base}/{$systemLang}/{$fileName}", "{$base}/en/{$fileName}");
    $found = false;
    foreach ($paths as $path) {
        if (is_readable($path)) {
            $found = true;
            $contents = StringUtil::getMarkdownExtraParser()->transform(file_get_contents($path));
            $url = $path . $chapter;
            break;
        }
    }
    if (!$found) {
        //$view->trigger_error(__f('Helpfile %s not found', $fileName));
        return;
    }
    $linkContents = DataUtil::formatForDisplayHTML($linkContents);
    if ($iconParams) {
        $iconContents = smarty_function_icon($iconParams, $view);
        if (isset($iconContents) && is_string($iconContents) && !empty($iconContents)) {
            if ($iconRightSide) {
                $linkContents = $linkContents . '&nbsp;' . $iconContents;
            } else {
                $linkContents = $iconContents . '&nbsp;' . $linkContents;
            }
        } else {
            //$view->trigger_error(__f('Icon for type '%s' not found', $iconParams['type']));
            return;
        }
    }
    $class = !empty($class) ? "class=\"{$class}\"" : '';
    if ($popup) {
        PageUtil::addVar('javascript', 'zikula.ui');
        $link = array();
        $link[] = "<a id=\"{$linkID}\" {$class} href=\"#{$linkID}_content\" title=\"{$title}\">" . $linkContents . "</a>";
        $link[] = "<div id=\"{$linkID}_content\" style=\"display: none;\">{$contents}</div>";
        $link[] = "<script type=\"text/javascript\">var {$linkID} = new Zikula.UI.Window(\$('{$linkID}'),{resizable: true, width: {$width}, height: {$height}})</script>";
        $link = implode("\n", $link);
    } else {
        $link = "<a id=\"{$linkID}\" {$class} href=\"" . DataUtil::formatForDisplay($url) . "\" title=\"{$title}\">" . $linkContents . "</a>";
    }
    if (isset($params['assign'])) {
        $ret = array('url' => $url, 'link' => $link);
        $view->assign($params['assign'], $ret);
        return;
    } else {
        return $link;
    }
}
Exemple #9
0
/**
 * Zikula_View function to create help link.
 *
 * This function creates a help link.
 *
 * To make the link appear as a button, wrap it in a div or span with a class
 * of z-buttons.
 *
 * Available parameters:
 *   - filename:     name of file, defaults to 'help.txt'.
 *   - anchor:       anchor marker.
 *   - popup:        opens the help file in a new window using javascript.
 *   - width:        width of the window if newwindow is set, default 600.
 *   - height:       height of the window if newwindow is set, default 400.
 *   - title:        name of the new window if new window is set, default is 'Help'.
 *   - link_contents the text for the link (between the <a> and </a> tags); optional, if not specified, then the title is used.
 *   - icon_type      an optional icon type to include in the link, separated from the link_contents (or title) by a non-breaking space; equivalent to the type parameter from the {icon} template function
 *   - icon_size      the size of the icon (e.g., extrasmall); optional if link_icon_type is specified, defaults to 'extrasmall', otherwise ignored;
 *                      equivalent to the size parameter of the {icon} template function
 *   - icon_width    the width of the icon in pixels; optional if link_icon_type is specified, if not specified, then obtained from size, otherwise ignored;
 *                      equivalent to the width parameter of the {icon} template function
 *   - icon_height   the height of the icon in pixels; optional if link_icon_type is specified, if not specified, then obtained from size, otherwise ignored;
 *                      equivalent to the height parameter of the {icon} template function
 *   - icon_alt      the alternate text for the icon, used for the alt param of the {icon} template function; optional if link_icon_type is specified,
 *                      defaults to an empty string, otherwise ignored
 *   - icon_title    the title text for the icon, used for the title param of the {icon} template function; optional if link_icon_type is specified,
 *                      defaults to an empty string, otherwise ignored
 *   - icon_optional if true and the icon image is not found then an error will not be returned, used for the optinal param of the {icon} template
 *                      function; optional if link_icon_type is specified, defaults to false, otherwise ignored
 *   - icon_default  the full path to an image file to use if the icon is not found, used for the default param of the {icon} template
 *                      function; optional if link_icon_type is specified, defaults to an empty string, otherwise ignored
 *   - icon_right    if true, then the icon is placed on the right side of the link text (the text from either link_contents or title); optional,
 *                      defaults to false (placing the icon on the left side of the text)
 *   - icon_*        all remaining parameters with a "icon_" prefix are passed to the {icon} function and subsequently to the <img> tag, except for
 *                      'icon_assign' which is completely ignored; optional if link_icon_type is specified, otherwise ignored
 *   - class:        class for use in the <a> tag.
 *   - assign:       if set, the results (array('url', 'link') are assigned to the corresponding variable instead of printed out.
 *
 * Example: A pop-up help window with a width of 400 and a height of 300, containing the contents of help.txt, and a title of 'Help'
 * {helplink popup='1' width='400' height='300' filename='help.txt' title='Help'}
 *
 * Example: The same as above, except displayed as a button with an icon image placed on the left side of the text 'Help' separated by a non-breaking space.
 *          The image does not have either alternate text nor a title.
 * <div class="z-buttons">
 *     {helplink popup='1' width='400' height='300' filename='help.txt' title='Help' icon_type='help' icon_size='extrasmall'}
 * </div>
 *
 * Example: The same as above, except the icon's <img> tag will contain a class attrbute with the value "my_class"
 * <div class="z-buttons">
 *     {helplink popup='1' width='400' height='300' filename='help.txt' title='Help' icon_type='help' icon_size='extrasmall' icon_class='my_class'}
 * </div>
 *
 * @param array       $params All attributes passed to this function from the template.
 * @param Zikula_View $view   Reference to the Zikula_View object.
 *
 * @return string|void
 */
function smarty_function_helplink($params, Zikula_View $view)
{
    $userLang = ZLanguage::transformFS(ZLanguage::getLanguageCode());
    $systemLang = System::getVar('language_i18n');
    $iconParams = array();
    if (!empty($params) && is_array($params)) {
        foreach ($params as $key => $value) {
            if (strpos($key, 'icon_') === 0 && strlen($key) > 5) {
                $iconParams[substr($key, 5)] = $value;
                unset($params[$key]);
            }
        }
    }
    if (!empty($iconParams) && isset($iconParams['type'])) {
        // We need to make sure the icon template function is available so we can call it.
        require_once $view->_get_plugin_filepath('function', 'icon');
        $iconRightSide = false;
        if (isset($iconParams['right'])) {
            $iconRightSide = (bool) $iconParams['right'];
            unset($iconParams['right']);
        }
        if (isset($iconParams['assign'])) {
            // We cannot use the assign parameter with the icon function in this context.
            unset($iconParams['assign']);
        }
    } else {
        $iconParams = false;
        $iconRightSide = false;
    }
    $title = isset($params['title']) ? $params['title'] : 'Help';
    $linkContents = isset($params['link_contents']) ? $params['link_contents'] : $title;
    $fileName = isset($params['filename']) ? $params['filename'] : 'help.txt';
    $chapter = isset($params['anchor']) ? '#' . $params['anchor'] : '';
    $class = isset($params['class']) ? $params['class'] : null;
    $width = isset($params['width']) ? $params['width'] : 600;
    $height = isset($params['height']) ? $params['height'] : 400;
    $popup = isset($params['popup']) ? true : false;
    $modname = $view->getModuleName();
    $linkID = isset($params['linkid']) ? $params['linkid'] : DataUtil::formatForDisplay(strtolower('manuallink_' . $modname . '_' . hash('md5', serialize($params))));
    $paths = array();
    $module = ModUtil::getModule($modname);
    if ($module) {
        $base = $module->getPath();
        $paths[] = "{$base}/Resources/docs/{$userLang}/{$fileName}";
        $paths[] = "{$base}/Resources/docs/{$systemLang}/{$fileName}";
        $paths[] = "{$base}/Resources/docs/en/{$fileName}";
    }
    $base = ModUtil::getModuleBaseDir($modname) . "/{$modname}/docs";
    $paths[] = "{$base}/{$userLang}/{$fileName}";
    $paths[] = "{$base}/docs/{$systemLang}/{$fileName}";
    $paths[] = "{$base}/en/{$fileName}";
    $found = false;
    foreach ($paths as $path) {
        if (is_readable($path)) {
            $found = true;
            $contents = StringUtil::getMarkdownExtraParser()->transform(file_get_contents($path));
            $url = $path . $chapter;
            break;
        }
    }
    if (!$found) {
        //$view->trigger_error(__f('Helpfile %s not found', $fileName));
        return;
    }
    $linkContents = DataUtil::formatForDisplayHTML($linkContents);
    if ($iconParams) {
        $iconContents = smarty_function_icon($iconParams, $view);
        if (isset($iconContents) && is_string($iconContents) && !empty($iconContents)) {
            if ($iconRightSide) {
                $linkContents = $linkContents . '&nbsp;' . $iconContents;
            } else {
                $linkContents = $iconContents . '&nbsp;' . $linkContents;
            }
        } else {
            //$view->trigger_error(__f('Icon for type '%s' not found', $iconParams['type']));
            return;
        }
    }
    $class = !empty($class) ? "class=\"{$class}\"" : '';
    if ($popup) {
        PageUtil::addVar('javascript', 'zikula.ui');
        $link = array();
        $link[] = "<a id=\"{$linkID}\" {$class} data-toggle=\"modal\" data-target=\"#{$linkID}_content\" title=\"{$title}\">" . $linkContents . "</a>";
        $link[] = '<div class="modal fade" id="' . $linkID . '_content" tabindex="-1" role="dialog" aria-labelledby="' . $linkID . '_label" aria-hidden="true">';
        $link[] = '<div class="modal-dialog">';
        $link[] = '<div class="modal-content">';
        $link[] = '<div class="modal-header">';
        $link[] = '<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>';
        $link[] = '<h4 class="modal-title" id="' . $linkID . '_label">' . $title . '</h4>';
        $link[] = '</div>';
        $link[] = '<div class="modal-body">';
        $link[] = $contents;
        $link[] = '</div>';
        $link[] = '</div>';
        $link[] = '</div>';
        $link[] = '</div>';
        $link = implode("\n", $link);
    } else {
        $link = "<a id=\"{$linkID}\" {$class} href=\"" . DataUtil::formatForDisplay($url) . "\" title=\"{$title}\">" . $linkContents . "</a>";
    }
    if (isset($params['assign'])) {
        $ret = array('url' => $url, 'link' => $link);
        $view->assign($params['assign'], $ret);
        return;
    } else {
        return $link;
    }
}