{"action":"created","comment":{"url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/pulls/comments/81850347","pull_request_review_id":2800467,"id":81850347,"diff_hunk":"@@ -0,0 +1,954 @@\n+<?php\n+\n+/**\n+ * CodeIgniter\n+ *\n+ * An open source application development framework for PHP\n+ *\n+ * This content is released under the MIT License (MIT)\n+ *\n+ * Copyright (c) 2014 - 2016, British Columbia Institute of Technology\n+ *\n+ * Permission is hereby granted, free of charge, to any person obtaining a copy\n+ * of this software and associated documentation files (the \"Software\"), to deal\n+ * in the Software without restriction, including without limitation the rights\n+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n+ * copies of the Software, and to permit persons to whom the Software is\n+ * furnished to do so, subject to the following conditions:\n+ *\n+ * The above copyright notice and this permission notice shall be included in\n+ * all copies or substantial portions of the Software.\n+ *\n+ * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n+ * THE SOFTWARE.\n+ *\n+ * @package\tCodeIgniter\n+ * @author\tEllisLab Dev Team\n+ * @copyright\tCopyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)\n+ * @copyright\tCopyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/)\n+ * @license\thttp://opensource.org/licenses/MIT\tMIT License\n+ * @link\thttps://codeigniter.com\n+ * @since\tVersion 1.0.0\n+ * @filesource\n+ */\n+defined('BASEPATH') OR exit('No direct script access allowed');\n+\n+/**\n+ * CodeIgniter Form Helpers\n+ *\n+ * @package\t\tCodeIgniter\n+ * @subpackage\tHelpers\n+ * @category\tHelpers\n+ * @author\t\tEllisLab Dev Team\n+ * @link\t\thttps://codeigniter.com/user_guide/helpers/form_helper.html\n+ */\n+\n+// -------------------------------------------------------------------------------\n+\n+if ( ! function_exists('form_open'))\n+{\n+    /**\n+     * Form Declaration\n+     *\n+     * Creates the opening portion of the form.\n+     *\n+     * @param\tstring\tthe URI segments of the form destination\n+     * @param\tarray\ta key/value pair of attributes\n+     * @param\tarray\ta key/value pair hidden data\n+     * @return\tstring\n+     */\n+    function form_open(string $action = '', array $attributes = [], array $hidden = []): string\n+    {\n+        // If no action is provided then set to the current url\n+        if ( ! $action)\n+        {\n+            $action = current_url(true);\n+        }\n+        // If an action is not a full URL then turn it into one\n+        elseif (strpos($action, '://') === false)\n+        {\n+            $action = site_url($action);\n+        }\n+        \n+        $attributes = _attributes_to_string($attributes);\n+        if (stripos($attributes, 'method=') === false)\n+        {\n+            $attributes .= ' method=\"post\"';\n+        }\n+        if (stripos($attributes, 'accept-charset=') === false)\n+        {\n+            $attributes .= ' accept-charset=\"'.strtolower(config_item('charset')).'\"';\n+        }\n+        \n+        $form = '<form action=\"'.$action.'\"'.$attributes.\">\\n\";\n+        \n+        // Add CSRF field if enabled, but leave it out for GET requests and requests to external websites\n+        $getCsrf = new \\Config\\Filters();\n+        $before = $getCsrf->globals->before;\n+        \n+        if ((in_array('csrf', $before) || array_key_exists('csrf', $before)) &&\n+                strpos($action, base_url()) !== false && ! stripos($form, 'method=\"get\"'))\n+        {\n+            $security = \\Config\\Services::security();\n+            $hidden[$security->getCSRFTokenName()] = $security->getCSRFHash();\n+        }\n+        if (is_array($hidden))\n+        {\n+            foreach ($hidden as $name => $value)\n+            {\n+                $form .= '<input type=\"hidden\" name=\"'.$name.'\" value=\"'.esc($value, 'html').'\" style=\"display:none;\" />'.\"\\n\";\n+            }\n+        }\n+        return $form;\n+    }\n+}\n+\n+// -----------------------------------------------------------------------\n+\n+if ( ! function_exists('form_open_multipart'))\n+{  \n+    /**\n+     * Form Declaration - Multipart type\n+     *\n+     * Creates the opening portion of the form, but with \"multipart/form-data\".\n+     *\n+     * @param\tstring\tthe URI segments of the form destination\n+     * @param\tarray\ta key/value pair of attributes\n+     * @param\tarray\ta key/value pair hidden data\n+     * @return\tstring\n+     */\n+    function form_open_multipart(string $action = '', array $attributes = [], array $hidden = []): string\n+    {\n+        if (is_string($attributes))\n+        {\n+            $attributes .= ' enctype=\"multipart/form-data\"';\n+        }\n+        else\n+        {\n+            $attributes['enctype'] = 'multipart/form-data';\n+        }\n+        \n+        return form_open($action, $attributes, $hidden);\n+    }\n+}\n+\n+// ------------------------------------------------------------------------\n+\n+if ( ! function_exists('form_hidden'))\n+{\n+    /**\n+     * Hidden Input Field\n+     *\n+     * Generates hidden fields. You can pass a simple key/value string or\n+     * an associative array with multiple values.\n+     *\n+     * @param\tmixed\t$name\t\tField name\n+     * @param\tstring\t$value\t\tField value\n+     * @param\tbool\t$recursing\n+     * @return\tstring\n+     */\n+    function form_hidden($name, string $value = '', bool $recursing = false): string\n+    {\n+        static $form;\n+        if ($recursing === false)\n+        {\n+            $form = \"\\n\";\n+        }\n+        \n+        if (is_array($name))\n+        {\n+            foreach ($name as $key => $val)\n+            {\n+                form_hidden($key, $val, true);\n+            }\n+            return $form;\n+        }\n+        \n+        if ( ! is_array($value))\n+        {\n+            $form .= '<input type=\"hidden\" name=\"'.$name.'\" value=\"'.html_escape($value).\"\\\" />\\n\";\n+        }\n+        else\n+        {\n+            foreach ($value as $k => $v)\n+            {\n+                $k = is_int($k) ? '' : $k;\n+                form_hidden($name.'['.$k.']', $v, true);\n+            }\n+        }\n+        \n+        return $form;\n+    }\n+}\n+\n+// ------------------------------------------------------------------------\n+\n+if ( ! function_exists('form_input'))\n+{\n+    /**\n+     * Text Input Field\n+     *\n+     * @param\tmixed\n+     * @param\tstring\n+     * @param\tmixed\n+     * @return\tstring\n+     */\n+    function form_input($data = '', string $value = '', $extra = ''): string\n+    {\n+        $defaults = [\n+                'type' => 'text',\n+                'name' => is_array($data) ? '' : $data,\n+                'value' => $value\n+        ];\n+        \n+        return '<input '._parse_form_attributes($data, $defaults)._attributes_to_string($extra).\" />\\n\";\n+    }\n+}\n+\n+// ------------------------------------------------------------------------\n+\n+if ( ! function_exists('form_password'))\n+{\n+    /**\n+     * Password Field\n+     *\n+     * Identical to the input function but adds the \"password\" type\n+     *\n+     * @param\tmixed\n+     * @param\tstring\n+     * @param\tmixed\n+     * @return\tstring\n+     */\n+    function form_password($data = '', string $value = '', $extra = ''): string\n+    {\n+        is_array($data) OR $data = array('name' => $data);\n+        $data['type'] = 'password';\n+        \n+        return form_input($data, $value, $extra);\n+    }\n+}\n+\n+// ------------------------------------------------------------------------\n+\n+if ( ! function_exists('form_upload'))\n+{\n+    /**\n+     * Upload Field\n+     *\n+     * Identical to the input function but adds the \"file\" type\n+     *\n+     * @param\tmixed\n+     * @param\tstring\n+     * @param\tmixed\n+     * @return\tstring\n+     */\n+    function form_upload($data = '', string $value = '', $extra = ''): string\n+    {\n+        $defaults = ['type' => 'file', 'name' => ''];\n+        is_array($data) OR $data = ['name' => $data];\n+        $data['type'] = 'file';\n+        \n+        return '<input '._parse_form_attributes($data, $defaults)._attributes_to_string($extra).\" />\\n\";\n+    }\n+}\n+\n+// ------------------------------------------------------------------------\n+\n+if ( ! function_exists('form_textarea'))\n+{\n+    /**\n+     * Textarea field\n+     *\n+     * @param\tmixed\t$data\n+     * @param\tstring\t$value\n+     * @param\tmixed\t$extra\n+     * @return\tstring\n+     */\n+    function form_textarea($data = '', string $value = '', $extra = ''): string\n+    {\n+        $defaults = [\n+                'name' => is_array($data) ? '' : $data,\n+                'cols' => '40',\n+                'rows' => '10'\n+        ];\n+        if ( ! is_array($data) OR ! isset($data['value']))\n+        {\n+            $val = $value;\n+        }\n+        else\n+        {\n+            $val = $data['value'];\n+            unset($data['value']); // textareas don't use the value attribute\n+        }\n+        \n+        return '<textarea '._parse_form_attributes($data, $defaults)._attributes_to_string($extra).'>'\n+                .htmlspecialchars($val)\n+                .\"</textarea>\\n\";\n+    }\n+}\n+\n+// ------------------------------------------------------------------------\n+\n+if ( ! function_exists('form_multiselect'))\n+{\n+    /**\n+     * Multi-select menu\n+     *\n+     * @param\tstring\n+     * @param\tarray\n+     * @param\tmixed\n+     * @param\tmixed\n+     * @return\tstring\n+     */\n+    function form_multiselect(string $name = '', array $options = [], array $selected = [], $extra = ''): string\n+    {\n+        $extra = _attributes_to_string($extra);\n+        \n+        if (stripos($extra, 'multiple') === false)\n+        {\n+            $extra .= ' multiple=\"multiple\"';\n+        }\n+        \n+        return form_dropdown($name, $options, $selected, $extra);\n+    }\n+}\n+\n+// --------------------------------------------------------------------\n+\n+if ( ! function_exists('form_dropdown'))\n+{\n+    /**\n+     * Drop-down Menu\n+     *\n+     * @param\tmixed\t$data\n+     * @param\tmixed\t$options\n+     * @param\tmixed\t$selected\n+     * @param\tmixed\t$extra\n+     * @return\tstring\n+     */\n+    function form_dropdown($data = '', $options = [], $selected = [], $extra = ''): string\n+    {\n+        $defaults = [];\n+        if (is_array($data))\n+        {\n+            if (isset($data['selected']))\n+            {\n+                $selected = $data['selected'];\n+                unset($data['selected']); // select tags don't have a selected attribute\n+            }\n+            if (isset($data['options']))\n+            {\n+                $options = $data['options'];\n+                unset($data['options']); // select tags don't use an options attribute\n+            }\n+        }\n+        else\n+        {\n+            $defaults = ['name' => $data];\n+        }\n+        \n+        is_array($selected) OR $selected = [$selected];\n+        is_array($options) OR $options = [$options];\n+        \n+        // If no selected state was submitted we will attempt to set it automatically\n+        if (empty($selected))\n+        {\n+            if (is_array($data))\n+            {\n+                if (isset($data['name'], $_POST[$data['name']]))\n+                {\n+                    $selected = [$_POST[$data['name']]];\n+                }\n+            }\n+            elseif (isset($_POST[$data]))\n+            {\n+                $selected = [$_POST[$data]];\n+            }\n+        }\n+        \n+        $extra = _attributes_to_string($extra);\n+        $multiple = (count($selected) > 1 && stripos($extra, 'multiple') === false) ? ' multiple=\"multiple\"' : '';\n+        $form = '<select '.rtrim(_parse_form_attributes($data, $defaults)).$extra.$multiple.\">\\n\";\n+        foreach ($options as $key => $val)\n+        {\n+            $key = (string) $key;\n+            if (is_array($val))\n+            {\n+                if (empty($val))\n+                {\n+                    continue;\n+                }\n+                $form .= '<optgroup label=\"'.$key.\"\\\">\\n\";\n+                foreach ($val as $optgroup_key => $optgroup_val)\n+                {\n+                    $sel = in_array($optgroup_key, $selected) ? ' selected=\"selected\"' : '';\n+                    $form .= '<option value=\"'.htmlspecialchars($optgroup_key).'\"'.$sel.'>'\n+                            .(string) $optgroup_val.\"</option>\\n\";\n+                }\n+                $form .= \"</optgroup>\\n\";\n+            }\n+            else\n+            {\n+                $form .= '<option value=\"'.htmlspecialchars($key).'\"'\n+                        .(in_array($key, $selected) ? ' selected=\"selected\"' : '').'>'\n+                                .(string) $val.\"</option>\\n\";\n+            }\n+        }\n+        \n+        return $form.\"</select>\\n\";\n+    }\n+}\n+\n+// ------------------------------------------------------------------------\n+\n+if ( ! function_exists('form_checkbox'))\n+{\n+    /**\n+     * Checkbox Field\n+     *\n+     * @param\tmixed\n+     * @param\tstring\n+     * @param\tbool\n+     * @param\tmixed\n+     * @return\tstring\n+     */\n+    function form_checkbox($data = '', string $value = '', bool $checked = false, $extra = ''): string\n+    {\n+        $defaults = ['type' => 'checkbox', 'name' => ( ! is_array($data) ? $data : ''), 'value' => $value];\n+        \n+        if (is_array($data) && array_key_exists('checked', $data))\n+        {\n+            $checked = $data['checked'];\n+            if ($checked == false)\n+            {\n+                unset($data['checked']);\n+            }\n+            else\n+            {\n+                $data['checked'] = 'checked';\n+            }\n+        }\n+        \n+        if ($checked == true)\n+        {\n+            $defaults['checked'] = 'checked';\n+        }\n+        else\n+        {\n+            unset($defaults['checked']);\n+        }\n+        \n+        return '<input '._parse_form_attributes($data, $defaults)._attributes_to_string($extra).\" />\\n\";\n+    }\n+}\n+\n+// ------------------------------------------------------------------------\n+\n+if ( ! function_exists('form_radio'))\n+{\n+    /**\n+     * Radio Button\n+     *\n+     * @param\tmixed\n+     * @param\tstring\n+     * @param\tbool\n+     * @param\tmixed\n+     * @return\tstring\n+     */\n+    function form_radio($data = '', string $value = '', bool $checked = false, $extra = ''): string\n+    {\n+        is_array($data) OR $data = ['name' => $data];\n+        $data['type'] = 'radio';\n+        \n+        return form_checkbox($data, $value, $checked, $extra);\n+    }\n+}\n+\n+// ------------------------------------------------------------------------\n+\n+if ( ! function_exists('form_submit'))\n+{\n+    /**\n+     * Submit Button\n+     *\n+     * @param\tmixed\n+     * @param\tstring\n+     * @param\tmixed\n+     * @return\tstring\n+     */\n+    function form_submit($data = '', string $value = '', $extra = ''): string\n+    {\n+        $defaults = [\n+                'type' => 'submit',\n+                'name' => is_array($data) ? '' : $data,\n+                'value' => $value\n+        ];\n+        \n+        return '<input '._parse_form_attributes($data, $defaults)._attributes_to_string($extra).\" />\\n\";\n+    }\n+}\n+\n+// ------------------------------------------------------------------------\n+\n+if ( ! function_exists('form_reset'))\n+{\n+    /**\n+     * Reset Button\n+     *\n+     * @param\tmixed\n+     * @param\tstring\n+     * @param\tmixed\n+     * @return\tstring\n+     */\n+    function form_reset($data = '', string $value = '', $extra = ''): string\n+    {\n+        $defaults = [\n+                'type' => 'reset',\n+                'name' => is_array($data) ? '' : $data,\n+                'value' => $value\n+        ];\n+        \n+        return '<input '._parse_form_attributes($data, $defaults)._attributes_to_string($extra).\" />\\n\";\n+    }\n+}\n+\n+// ------------------------------------------------------------------------\n+\n+if ( ! function_exists('form_button'))\n+{\n+    /**\n+     * Form Button\n+     *\n+     * @param\tmixed\n+     * @param\tstring\n+     * @param\tmixed\n+     * @return\tstring\n+     */\n+    function form_button($data = '', string $content = '', $extra = ''): string\n+    {\n+        $defaults = [\n+                'name' => is_array($data) ? '' : $data,\n+                'type' => 'button'\n+        ];\n+        \n+        if (is_array($data) && isset($data['content']))\n+        {\n+            $content = $data['content'];\n+            unset($data['content']); // content is not an attribute\n+        }\n+        \n+        return '<button '._parse_form_attributes($data, $defaults)._attributes_to_string($extra).'>'\n+                .$content\n+                .\"</button>\\n\";\n+    }\n+}\n+\n+// ------------------------------------------------------------------------\n+\n+if ( ! function_exists('form_label'))\n+{\n+    /**\n+     * Form Label Tag\n+     *\n+     * @param\tstring\tThe text to appear onscreen\n+     * @param\tstring\tThe id the label applies to\n+     * @param\tarray\tAdditional attributes\n+     * @return\tstring\n+     */\n+    function form_label(string $label_text = '', string $id = '', array $attributes = []): string\n+    {\n+        $label = '<label';\n+        \n+        if ($id !== '')\n+        {\n+            $label .= ' for=\"'.$id.'\"';\n+        }\n+        \n+        if (is_array($attributes) && count($attributes) > 0)\n+        {\n+            foreach ($attributes as $key => $val)\n+            {\n+                $label .= ' '.$key.'=\"'.$val.'\"';\n+            }\n+        }\n+        \n+        return $label.'>'.$label_text.'</label>';\n+    }\n+}\n+\n+// ------------------------------------------------------------------------\n+\n+if ( ! function_exists('form_datalist'))\n+{\n+    /**\n+     * Datalist\n+     * \n+     * The <datalist> element specifies a list of pre-defined options for an <input> element.\n+     * Users will see a drop-down list of pre-defined options as they input data.\n+     * The list attribute of the <input> element, must refer to the id attribute of the <datalist> element.\n+     */\n+    function form_datalist($name, $value, $options)\n+    {\n+        $data = [\n+             'type' => 'text',\n+             'name' => $name,\n+             'list' => $name.'_list',\n+             'value' => $value\n+        ];\n+        \n+        $out = form_input($data).\"\\n\";\n+        $out .= \"<datalist id='\".$name.'_list'.\"'>\";\n+        \n+        foreach ($options as $option)\n+        {\n+            $out .= \"<option value='$option'>\".\"\\n\";\n+        }\n+        \n+        $out .= \"</datalist>\".\"\\n\";\n+        \n+        return $out;\n+    }\n+}\n+\n+// ------------------------------------------------------------------------\n+\n+if ( ! function_exists('form_keygen'))\n+{\n+    function form_keygen()\n+    {\n+        /* The purpose of the <keygen> element is to provide a secure way to authenticate users.\n+         The <keygen> element specifies a key-pair generator field in a form.\n+         When the form is submitted, two keys are generated, one private and one public.\n+         The private key is stored locally, and the public key is sent to the server.\n+         The public key could be used to generate a client certificate to authenticate the user in the future. */\n+    }\n+}\n+\n+// ------------------------------------------------------------------------\n+\n+if ( ! function_exists('form_output'))\n+{\n+    function form_output()\n+    {\n+        /* The <output> element represents the result of a calculation (like one performed by a script). */\n+    }\n+}\n+\n+// ------------------------------------------------------------------------\n+\n+if ( ! function_exists('form_fieldset'))\n+{\n+    /**\n+     * Fieldset Tag\n+     *\n+     * Used to produce <fieldset><legend>text</legend>.  To close fieldset\n+     * use form_fieldset_close()\n+     *\n+     * @param\tstring\tThe legend text\n+     * @param\tarray\tAdditional attributes\n+     * @return\tstring\n+     */\n+    function form_fieldset(string $legend_text = '', array $attributes = []): string\n+    {\n+        $fieldset = '<fieldset'._attributes_to_string($attributes).\">\\n\";\n+        \n+        if ($legend_text !== '')\n+        {\n+            return $fieldset.'<legend>'.$legend_text.\"</legend>\\n\";\n+        }\n+        \n+        return $fieldset;\n+    }\n+}\n+\n+// ------------------------------------------------------------------------\n+\n+if ( ! function_exists('form_fieldset_close'))\n+{\n+    /**\n+     * Fieldset Close Tag\n+     *\n+     * @param\tstring\n+     * @return\tstring\n+     */\n+    function form_fieldset_close(string $extra = ''): string\n+    {\n+        return '</fieldset>'.$extra;\n+    }\n+}\n+\n+// ------------------------------------------------------------------------\n+\n+if ( ! function_exists('form_close'))\n+{\n+    /**\n+     * Form Close Tag\n+     *\n+     * @param\tstring\n+     * @return\tstring\n+     */\n+    function form_close(string $extra = ''): string\n+    {\n+        return '</form>'.$extra;\n+    }\n+}\n+\n+// ------------------------------------------------------------------------\n+\n+if ( ! function_exists('set_value'))\n+{\n+    /**\n+     * Form Value\n+     *\n+     * Grabs a value from the POST array for the specified field so you can\n+     * re-populate an input field or textarea\n+     *\n+     * @param\tstring\t$field\t\tField name\n+     * @param\tstring\t$default\tDefault value\n+     * @param\tbool\t$html_escape\tWhether to escape HTML special characters or not\n+     * @return\tstring\n+     */\n+    function set_value(string $field, string $default = '', bool $html_escape = true): string\n+    {\n+        $value = $_POST[$field] ?? $default;\n+        \n+        return ($html_escape) ? html_escape($value) : $value;\n+    }\n+}\n+\n+// ------------------------------------------------------------------------\n+\n+if ( ! function_exists('set_select'))\n+{\n+    /**\n+     * Set Select\n+     *\n+     * Let's you set the selected value of a <select> menu via data in the POST array.\n+     * If Form Validation is active it retrieves the info from the validation class\n+     *\n+     * @param\tstring\n+     * @param\tstring\n+     * @param\tbool\n+     * @return\tstring\n+     */\n+    function set_select(string $field, string $value = '', bool $default = false): string\n+    {\n+        if (($input = $_POST[$field]) === NULL)\n+        {\n+            return ($default === TRUE) ? ' selected=\"selected\"' : '';\n+        }\n+        \n+        if (($input = $_POST[$field]) !== NULL)\n+        {\n+            if ( ! is_array($input))\n+            {\n+                return ' selected=\"selected\"';\n+            }\n+            \n+            if (is_array($input))\n+            {\n+                $value = (string) $value;\n+                \n+                // Note: in_array('', array(0)) returns TRUE, do not use it\n+                foreach ($input as &$v)\n+                {\n+                    if ($value === $v)\n+                    {\n+                        return ' selected=\"selected\"';\n+                    }\n+                }\n+                return '';\n+            }\n+        }\n+        \n+        return ($input === $value) ? ' selected=\"selected\"' : '';\n+    }\n+}\n+\n+// ------------------------------------------------------------------------\n+\n+if ( ! function_exists('set_checkbox'))\n+{\n+    /**\n+     * Set Checkbox\n+     *\n+     * Let's you set the selected value of a checkbox via the value in the POST array.\n+     * If Form Validation is active it retrieves the info from the validation class\n+     *\n+     * @param\tstring\n+     * @param\tstring\n+     * @param\tbool\n+     * @return\tstring\n+     */\n+    function set_checkbox(string $field, string $value = '', bool $default = false): string\n+    {\n+        // Form inputs are always strings ...\n+        $value = (string) $value;\n+        \n+        $input = $_POST[$field];\n+        \n+        if (is_array($input))\n+        {\n+            // Note: in_array('', array(0)) returns TRUE, do not use it\n+            foreach ($input as &$v)\n+            {\n+                if ($value === $v)\n+                {\n+                    return ' checked=\"checked\"';\n+                }\n+            }\n+            return '';\n+        }\n+        \n+        // Unchecked checkbox and radio inputs are not even submitted by browsers ...\n+        if ($_POST)\n+        {\n+            return ($input === $value) ? ' checked=\"checked\"' : '';\n+        }\n+        \n+        return ($default === TRUE) ? ' checked=\"checked\"' : '';\n+    }\n+}\n+\n+// ------------------------------------------------------------------------\n+\n+if ( ! function_exists('set_radio'))\n+{\n+    /**\n+     * Set Radio\n+     *\n+     * Let's you set the selected value of a radio field via info in the POST array.\n+     * If Form Validation is active it retrieves the info from the validation class\n+     *\n+     * @param\tstring\t$field\n+     * @param\tstring\t$value\n+     * @param\tbool\t$default\n+     * @return\tstring\n+     */\n+    function set_radio(string $field, string $value = '', bool $default = FALSE): string\n+    {\n+        // Form inputs are always strings ...\n+        $value = (string) $value;\n+        \n+        $input = $_POST[$field];\n+        \n+        if (is_array($input))\n+        {\n+            // Note: in_array('', array(0)) returns TRUE, do not use it\n+            foreach ($input as &$v)\n+            {\n+                if ($value === $v)\n+                {\n+                    return ' checked=\"checked\"';\n+                }\n+            }\n+            return '';\n+        }\n+        \n+        // Unchecked checkbox and radio inputs are not even submitted by browsers ...\n+        if ($_POST)\n+        {\n+            return ($input === $value) ? ' checked=\"checked\"' : '';\n+        }\n+        \n+        return ($default === TRUE) ? ' checked=\"checked\"' : '';\n+    }\n+}\n+\n+// ------------------------------------------------------------------------\n+\n+if ( ! function_exists('_parse_form_attributes'))","path":"system/Helpers/form_helper.php","position":865,"original_position":865,"commit_id":"bd49adefba1ef55c84d1e7a382bf6c913c5ce6d6","original_commit_id":"bd49adefba1ef55c84d1e7a382bf6c913c5ce6d6","user":{"login":"Portaflex","id":5394119,"avatar_url":"https://avatars.githubusercontent.com/u/5394119?v=3","gravatar_id":"","url":"https://api.github.com/users/Portaflex","html_url":"https://github.com/Portaflex","followers_url":"https://api.github.com/users/Portaflex/followers","following_url":"https://api.github.com/users/Portaflex/following{/other_user}","gists_url":"https://api.github.com/users/Portaflex/gists{/gist_id}","starred_url":"https://api.github.com/users/Portaflex/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Portaflex/subscriptions","organizations_url":"https://api.github.com/users/Portaflex/orgs","repos_url":"https://api.github.com/users/Portaflex/repos","events_url":"https://api.github.com/users/Portaflex/events{/privacy}","received_events_url":"https://api.github.com/users/Portaflex/received_events","type":"User","site_admin":false},"body":"Ok. Done.","created_at":"2016-10-04T20:48:38Z","updated_at":"2016-10-04T20:48:38Z","html_url":"https://github.com/bcit-ci/CodeIgniter4/pull/281#discussion_r81850347","pull_request_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/pulls/281","_links":{"self":{"href":"https://api.github.com/repos/bcit-ci/CodeIgniter4/pulls/comments/81850347"},"html":{"href":"https://github.com/bcit-ci/CodeIgniter4/pull/281#discussion_r81850347"},"pull_request":{"href":"https://api.github.com/repos/bcit-ci/CodeIgniter4/pulls/281"}}},"pull_request":{"url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/pulls/281","id":87520956,"html_url":"https://github.com/bcit-ci/CodeIgniter4/pull/281","diff_url":"https://github.com/bcit-ci/CodeIgniter4/pull/281.diff","patch_url":"https://github.com/bcit-ci/CodeIgniter4/pull/281.patch","issue_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/issues/281","number":281,"state":"open","locked":false,"title":"Form_helper","user":{"login":"Portaflex","id":5394119,"avatar_url":"https://avatars.githubusercontent.com/u/5394119?v=3","gravatar_id":"","url":"https://api.github.com/users/Portaflex","html_url":"https://github.com/Portaflex","followers_url":"https://api.github.com/users/Portaflex/followers","following_url":"https://api.github.com/users/Portaflex/following{/other_user}","gists_url":"https://api.github.com/users/Portaflex/gists{/gist_id}","starred_url":"https://api.github.com/users/Portaflex/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Portaflex/subscriptions","organizations_url":"https://api.github.com/users/Portaflex/orgs","repos_url":"https://api.github.com/users/Portaflex/repos","events_url":"https://api.github.com/users/Portaflex/events{/privacy}","received_events_url":"https://api.github.com/users/Portaflex/received_events","type":"User","site_admin":false},"body":"Form helper revisited.","created_at":"2016-09-30T16:01:52Z","updated_at":"2016-10-04T20:48:38Z","closed_at":null,"merged_at":null,"merge_commit_sha":"a4bd8fadd00e42654c04671e0ce9c20a2e1c3e3d","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/pulls/281/commits","review_comments_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/pulls/281/comments","review_comment_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/pulls/comments{/number}","comments_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/issues/281/comments","statuses_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/statuses/bd49adefba1ef55c84d1e7a382bf6c913c5ce6d6","head":{"label":"Portaflex:Form_helper","ref":"Form_helper","sha":"bd49adefba1ef55c84d1e7a382bf6c913c5ce6d6","user":{"login":"Portaflex","id":5394119,"avatar_url":"https://avatars.githubusercontent.com/u/5394119?v=3","gravatar_id":"","url":"https://api.github.com/users/Portaflex","html_url":"https://github.com/Portaflex","followers_url":"https://api.github.com/users/Portaflex/followers","following_url":"https://api.github.com/users/Portaflex/following{/other_user}","gists_url":"https://api.github.com/users/Portaflex/gists{/gist_id}","starred_url":"https://api.github.com/users/Portaflex/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Portaflex/subscriptions","organizations_url":"https://api.github.com/users/Portaflex/orgs","repos_url":"https://api.github.com/users/Portaflex/repos","events_url":"https://api.github.com/users/Portaflex/events{/privacy}","received_events_url":"https://api.github.com/users/Portaflex/received_events","type":"User","site_admin":false},"repo":{"id":69298266,"name":"CodeIgniter4","full_name":"Portaflex/CodeIgniter4","owner":{"login":"Portaflex","id":5394119,"avatar_url":"https://avatars.githubusercontent.com/u/5394119?v=3","gravatar_id":"","url":"https://api.github.com/users/Portaflex","html_url":"https://github.com/Portaflex","followers_url":"https://api.github.com/users/Portaflex/followers","following_url":"https://api.github.com/users/Portaflex/following{/other_user}","gists_url":"https://api.github.com/users/Portaflex/gists{/gist_id}","starred_url":"https://api.github.com/users/Portaflex/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Portaflex/subscriptions","organizations_url":"https://api.github.com/users/Portaflex/orgs","repos_url":"https://api.github.com/users/Portaflex/repos","events_url":"https://api.github.com/users/Portaflex/events{/privacy}","received_events_url":"https://api.github.com/users/Portaflex/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Portaflex/CodeIgniter4","description":"Open Source PHP Framework (originally from EllisLab)","fork":true,"url":"https://api.github.com/repos/Portaflex/CodeIgniter4","forks_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/forks","keys_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/teams","hooks_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/hooks","issue_events_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/issues/events{/number}","events_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/events","assignees_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/assignees{/user}","branches_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/branches{/branch}","tags_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/tags","blobs_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/git/refs{/sha}","trees_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/statuses/{sha}","languages_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/languages","stargazers_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/stargazers","contributors_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/contributors","subscribers_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/subscribers","subscription_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/subscription","commits_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/commits{/sha}","git_commits_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/git/commits{/sha}","comments_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/comments{/number}","issue_comment_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/issues/comments{/number}","contents_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/contents/{+path}","compare_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/merges","archive_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/downloads","issues_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/issues{/number}","pulls_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/pulls{/number}","milestones_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/milestones{/number}","notifications_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/labels{/name}","releases_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/releases{/id}","deployments_url":"https://api.github.com/repos/Portaflex/CodeIgniter4/deployments","created_at":"2016-09-26T22:31:58Z","updated_at":"2016-09-26T22:32:00Z","pushed_at":"2016-09-30T16:20:14Z","git_url":"git://github.com/Portaflex/CodeIgniter4.git","ssh_url":"git@github.com:Portaflex/CodeIgniter4.git","clone_url":"https://github.com/Portaflex/CodeIgniter4.git","svn_url":"https://github.com/Portaflex/CodeIgniter4","homepage":" https://codeigniter.com/","size":17173,"stargazers_count":0,"watchers_count":0,"language":"PHP","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"develop"}},"base":{"label":"bcit-ci:develop","ref":"develop","sha":"ff7b54203650bbd37509e3639f36b33651640916","user":{"login":"bcit-ci","id":8863432,"avatar_url":"https://avatars.githubusercontent.com/u/8863432?v=3","gravatar_id":"","url":"https://api.github.com/users/bcit-ci","html_url":"https://github.com/bcit-ci","followers_url":"https://api.github.com/users/bcit-ci/followers","following_url":"https://api.github.com/users/bcit-ci/following{/other_user}","gists_url":"https://api.github.com/users/bcit-ci/gists{/gist_id}","starred_url":"https://api.github.com/users/bcit-ci/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bcit-ci/subscriptions","organizations_url":"https://api.github.com/users/bcit-ci/orgs","repos_url":"https://api.github.com/users/bcit-ci/repos","events_url":"https://api.github.com/users/bcit-ci/events{/privacy}","received_events_url":"https://api.github.com/users/bcit-ci/received_events","type":"Organization","site_admin":false},"repo":{"id":41463886,"name":"CodeIgniter4","full_name":"bcit-ci/CodeIgniter4","owner":{"login":"bcit-ci","id":8863432,"avatar_url":"https://avatars.githubusercontent.com/u/8863432?v=3","gravatar_id":"","url":"https://api.github.com/users/bcit-ci","html_url":"https://github.com/bcit-ci","followers_url":"https://api.github.com/users/bcit-ci/followers","following_url":"https://api.github.com/users/bcit-ci/following{/other_user}","gists_url":"https://api.github.com/users/bcit-ci/gists{/gist_id}","starred_url":"https://api.github.com/users/bcit-ci/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bcit-ci/subscriptions","organizations_url":"https://api.github.com/users/bcit-ci/orgs","repos_url":"https://api.github.com/users/bcit-ci/repos","events_url":"https://api.github.com/users/bcit-ci/events{/privacy}","received_events_url":"https://api.github.com/users/bcit-ci/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/bcit-ci/CodeIgniter4","description":"Open Source PHP Framework (originally from EllisLab)","fork":false,"url":"https://api.github.com/repos/bcit-ci/CodeIgniter4","forks_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/forks","keys_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/teams","hooks_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/hooks","issue_events_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/issues/events{/number}","events_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/events","assignees_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/assignees{/user}","branches_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/branches{/branch}","tags_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/tags","blobs_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/git/refs{/sha}","trees_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/statuses/{sha}","languages_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/languages","stargazers_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/stargazers","contributors_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/contributors","subscribers_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/subscribers","subscription_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/subscription","commits_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/commits{/sha}","git_commits_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/git/commits{/sha}","comments_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/comments{/number}","issue_comment_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/issues/comments{/number}","contents_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/contents/{+path}","compare_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/merges","archive_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/downloads","issues_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/issues{/number}","pulls_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/pulls{/number}","milestones_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/milestones{/number}","notifications_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/labels{/name}","releases_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/releases{/id}","deployments_url":"https://api.github.com/repos/bcit-ci/CodeIgniter4/deployments","created_at":"2015-08-27T03:32:45Z","updated_at":"2016-10-04T19:57:22Z","pushed_at":"2016-10-04T09:17:05Z","git_url":"git://github.com/bcit-ci/CodeIgniter4.git","ssh_url":"git@github.com:bcit-ci/CodeIgniter4.git","clone_url":"https://github.com/bcit-ci/CodeIgniter4.git","svn_url":"https://github.com/bcit-ci/CodeIgniter4","homepage":" https://codeigniter.com/","size":18440,"stargazers_count":452,"watchers_count":452,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":162,"mirror_url":null,"open_issues_count":40,"forks":162,"open_issues":40,"watchers":452,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/bcit-ci/CodeIgniter4/pulls/281"},"html":{"href":"https://github.com/bcit-ci/CodeIgniter4/pull/281"},"issue":{"href":"https://api.github.com/repos/bcit-ci/CodeIgniter4/issues/281"},"comments":{"href":"https://api.github.com/repos/bcit-ci/CodeIgniter4/issues/281/comments"},"review_comments":{"href":"https://api.github.com/repos/bcit-ci/CodeIgniter4/pulls/281/comments"},"review_comment":{"href":"https://api.github.com/repos/bcit-ci/CodeIgniter4/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/bcit-ci/CodeIgniter4/pulls/281/commits"},"statuses":{"href":"https://api.github.com/repos/bcit-ci/CodeIgniter4/statuses/bd49adefba1ef55c84d1e7a382bf6c913c5ce6d6"}}}}
{"actor":{"display_login":"Portaflex"}}