smarty-php / smarty-php/smarty

Support enclosure elements at html_checkboxes function

Open
#886 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
PHP
Stars
2.3k
Forks
709
PR merge metrics
No merged PRs in 30d

Description

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;
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in libs/plugins/function.html_checkboxes.php and compare the current html_checkboxes implementation with the proposed separator_ini and separator_end behavior. Done means the function accepts these optional parameters and wraps each generated checkbox with the requested opening and closing elements while preserving the existing separator behavior; exercise the documented example to verify the output.

Written by the indexing model from the issue text.

Assessment

Tech stack
php
Domain
frontend
Issue type
Feature
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.