smarty-php / smarty

Smarty is a template engine for PHP, facilitating the separation of presentation (HTML/CSS) from application logic.
Other
2.25k stars 709 forks source link

Support enclosure elements at html_checkboxes function #886

Open cirofeitosa opened 1 year ago

cirofeitosa commented 1 year ago

We implement an small feature at "html_checkboxes" function, adding support for enclosure elements into a HTML tag (before and after checkbox tag). This is helpful when use some css grids, that needs an addition tag to organize the checkboxes in columns for example.

Could the team include this change on next Smarty version as default?

See below the /libs/plugins/function.html_checkboxes.php file changed. The changes is only envolving "separator_ini" and "separator_end" parameters. You can change the parameter name, it's just an example.

<?php
/**
 * Smarty plugin
 *
 * @package    Smarty
 * @subpackage PluginsFunction
 */
/**
 * Smarty {html_checkboxes} function plugin
 * File:       function.html_checkboxes.php
 * Type:       function
 * Name:       html_checkboxes
 * Date:       24.Feb.2003
 * Purpose:    Prints out a list of checkbox input types
 * Examples:
 *
 * {html_checkboxes values=$ids output=$names}
 * {html_checkboxes values=$ids name='box' separator='<br>' output=$names}
 * {html_checkboxes values=$ids checked=$checked separator='<br>' output=$names}
 * {html_checkboxes values=$ids checked=$checked separator='<br>' separator_ini='<div class="col-6">' separator_end='</div>' output=$names}
 *
 * Params:
 *
 * - name           (optional) - string default "checkbox"
 * - values         (required) - array
 * - options        (optional) - associative array
 * - checked        (optional) - array default not set
 * - separator      (optional) - ie <br> or &nbsp;
 * - separator_ini  (optional) - ie <div class="col-6">
 * - separator_end  (optional) - ie </div>
 * - output         (optional) - the output next to each checkbox
 * - assign         (optional) - assign the output as an array to this variable
 * - escape         (optional) - escape the content (not value), defaults to true
 *
 * @link    https://www.smarty.net/manual/en/language.function.html.checkboxes.php {html_checkboxes}
 *             (Smarty online manual)
 * @author  Christopher Kvarme <christopher.kvarme@flashjab.com>
 * @author  credits to Monte Ohrt <monte at ohrt dot com>
 * @version 1.0
 *
 * @param array                    $params   parameters
 * @param Smarty_Internal_Template $template template object
 *
 * @return string
 * @uses    smarty_function_escape_special_chars()
 * @throws \SmartyException
 */
function smarty_function_html_checkboxes($params, Smarty_Internal_Template $template)
{
    $template->_checkPlugins(
        array(
            array(
                'function' => 'smarty_function_escape_special_chars',
                'file'     => SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php'
            )
        )
    );
    $name = 'checkbox';
    $values = null;
    $options = null;
    $selected = array();
    $separator = $separator_ini = $separator_end = '';
    $escape = true;
    $labels = true;
    $label_ids = false;
    $output = null;
    $extra = '';
    foreach ($params as $_key => $_val) {
        switch ($_key) {
            case 'name':
            case 'separator':
            case 'separator_ini':
            case 'separator_end':
                $$_key = (string)$_val;
                break;
            case 'escape':
            case 'labels':
            case 'label_ids':
                $$_key = (bool)$_val;
                break;
            case 'options':
                $$_key = (array)$_val;
                break;
            case 'values':
            case 'output':
                $$_key = array_values((array)$_val);
                break;
            case 'checked':
            case 'selected':
                if (is_array($_val)) {
                    $selected = array();
                    foreach ($_val as $_sel) {
                        if (is_object($_sel)) {
                            if (method_exists($_sel, '__toString')) {
                                $_sel = smarty_function_escape_special_chars((string)$_sel->__toString());
                            } else {
                                trigger_error(
                                    'html_checkboxes: selected attribute contains an object of class \'' .
                                    get_class($_sel) . '\' without __toString() method',
                                    E_USER_NOTICE
                                );
                                continue;
                            }
                        } else {
                            $_sel = smarty_function_escape_special_chars((string)$_sel);
                        }
                        $selected[ $_sel ] = true;
                    }
                } elseif (is_object($_val)) {
                    if (method_exists($_val, '__toString')) {
                        $selected = smarty_function_escape_special_chars((string)$_val->__toString());
                    } else {
                        trigger_error(
                            'html_checkboxes: selected attribute is an object of class \'' . get_class($_val) .
                            '\' without __toString() method',
                            E_USER_NOTICE
                        );
                    }
                } else {
                    $selected = smarty_function_escape_special_chars((string)$_val);
                }
                break;
            case 'checkboxes':
                trigger_error(
                    'html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead',
                    E_USER_WARNING
                );
                $options = (array)$_val;
                break;
            case 'assign':
                break;
            case 'strict':
                break;
            case 'disabled':
            case 'readonly':
                if (!empty($params[ 'strict' ])) {
                    if (!is_scalar($_val)) {
                        trigger_error(
                            "html_options: {$_key} attribute must be a scalar, only boolean true or string '{$_key}' will actually add the attribute",
                            E_USER_NOTICE
                        );
                    }
                    if ($_val === true || $_val === $_key) {
                        $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"';
                    }
                    break;
                }
            // omit break; to fall through!
            // no break
            default:
                if (!is_array($_val)) {
                    $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
                } else {
                    trigger_error("html_checkboxes: extra attribute '{$_key}' cannot be an array", E_USER_NOTICE);
                }
                break;
        }
    }
    if (!isset($options) && !isset($values)) {
        return '';
    } /* raise error here? */
    $_html_result = array();
    if (isset($options)) {
        foreach ($options as $_key => $_val) {
            $_html_result[] =
                smarty_function_html_checkboxes_output(
                    $name,
                    $_key,
                    $_val,
                    $selected,
                    $extra,
                    $separator,
                    $labels,
                    $label_ids,
                    $escape,
                    $separator_ini, 
                    $separator_end
                );
        }
    } else {
        foreach ($values as $_i => $_key) {
            $_val = isset($output[ $_i ]) ? $output[ $_i ] : '';
            $_html_result[] =
                smarty_function_html_checkboxes_output(
                    $name,
                    $_key,
                    $_val,
                    $selected,
                    $extra,
                    $separator,
                    $labels,
                    $label_ids,
                    $escape,
                    $separator_ini, 
                    $separator_end
                );
        }
    }
    if (!empty($params[ 'assign' ])) {
        $template->assign($params[ 'assign' ], $_html_result);
    } else {
        return implode("\n", $_html_result);
    }
}

/**
 * @param      $name
 * @param      $value
 * @param      $output
 * @param      $selected
 * @param      $extra
 * @param      $separator
 * @param      $separator_ini
 * @param      $separator_end
 * @param      $labels
 * @param      $label_ids
 * @param bool $escape
 *
 * @return string
 */
function smarty_function_html_checkboxes_output(
    $name,
    $value,
    $output,
    $selected,
    $extra,
    $separator,
    $labels,
    $label_ids,
    $escape = true,
    $separator_ini = '', 
    $separator_end = ''
) {
    $_output = '';
    if (is_object($value)) {
        if (method_exists($value, '__toString')) {
            $value = (string)$value->__toString();
        } else {
            trigger_error(
                'html_options: value is an object of class \'' . get_class($value) .
                '\' without __toString() method',
                E_USER_NOTICE
            );
            return '';
        }
    } else {
        $value = (string)$value;
    }
    if (is_object($output)) {
        if (method_exists($output, '__toString')) {
            $output = (string)$output->__toString();
        } else {
            trigger_error(
                'html_options: output is an object of class \'' . get_class($output) .
                '\' without __toString() method',
                E_USER_NOTICE
            );
            return '';
        }
    } else {
        $output = (string)$output;
    }
    $_output .= $separator_ini;
    if ($labels) {
        if ($label_ids) {
            $_id = smarty_function_escape_special_chars(
                preg_replace(
                    '![^\w\-\.]!' . Smarty::$_UTF8_MODIFIER,
                    '_',
                    $name . '_' . $value
                )
            );
            $_output .= '<label for="' . $_id . '">';
        } else {
            $_output .= '<label>';
        }
    }
    $name = smarty_function_escape_special_chars($name);
    $value = smarty_function_escape_special_chars($value);
    if ($escape) {
        $output = smarty_function_escape_special_chars($output);
    }
    $_output .= '<input type="checkbox" name="' . $name . '[]" value="' . $value . '"';
    if ($labels && $label_ids) {
        $_output .= ' id="' . $_id . '"';
    }
    if (is_array($selected)) {
        if (isset($selected[ $value ])) {
            $_output .= ' checked="checked"';
        }
    } elseif ($value === $selected) {
        $_output .= ' checked="checked"';
    }
    $_output .= $extra . ' />' . $output;
    if ($labels) {
        $_output .= '</label>';
    }
    $_output .= $separator;
    $_output .= $separator_end;
    return $_output;
}