diff --git a/e107_handlers/form_handler.php b/e107_handlers/form_handler.php index 399189d31..632a6ab8f 100644 --- a/e107_handlers/form_handler.php +++ b/e107_handlers/form_handler.php @@ -848,7 +848,7 @@ class e_form //never allow id in format name-value for text fields - return "get_attributes($options, $name). ' />'; + return "get_attributes($options, $name). ' />'; } @@ -3901,6 +3901,27 @@ var_dump($select_options);*/ $this->_tabindex_counter = $reset; } + /** + * Build a series of HTML attributes from the provided array + * + * @param array $attributes Key-value pairs of HTML attributes. The value must not be HTML-encoded. If the value is + * boolean true, the value will be set to the key (e.g. `['required' => true]` becomes + * "required='required'"). + * @return string The HTML attributes to concatenate inside an HTML tag + */ + private function attributes($attributes) + { + $stringifiedAttributes = []; + + foreach ($attributes as $key => $value) + { + if ($value === true) $value = $key; + if (!empty($value)) $stringifiedAttributes[] = $key . "='" . htmlspecialchars($value) . "'"; + } + + return count($stringifiedAttributes) > 0 ? " ".implode(" ", $stringifiedAttributes) : ""; + } + public function get_attributes($options, $name = '', $value = '') { $ret = ''; @@ -3909,7 +3930,7 @@ var_dump($select_options);*/ { if ($option !== 'other') { - $optval = htmlspecialchars(trim((string) $optval), ENT_COMPAT | ENT_HTML401, 'UTF-8', false); + $optval = html_entity_decode(trim((string) $optval)); } switch ($option) { @@ -3919,30 +3940,30 @@ var_dump($select_options);*/ break; case 'class': - if(!empty($optval)) - { - $ret .= " class='{$optval}'"; - } - break; - case 'size': - if($optval) - { - $ret .= " size='{$optval}'"; - } - break; - case 'title': - if($optval) - { - $ret .= " title='{$optval}'"; - } + case 'label': + case 'maxlength': + case 'wrap': + case 'autocomplete': + case 'pattern': + $ret .= $this->attributes([$option => $optval]); break; - case 'label': - if($optval) - { - $ret .= " label='{$optval}'"; + case 'readonly': + case 'multiple': + case 'selected': + case 'checked': + case 'disabled': + case 'required': + case 'autofocus': + $ret .= $this->attributes([$option => (bool) $optval]); + break; + + case 'placeholder': + if($optval) { + $optval = deftrue($optval, $optval); + $ret .= $this->attributes([$option => $optval]); } break; @@ -3958,91 +3979,7 @@ var_dump($select_options);*/ else { ++$this->_tabindex_counter; - $ret .= " tabindex='".$this->_tabindex_counter."'"; - } - break; - - case 'readonly': - if($optval) - { - $ret .= " readonly='readonly'"; - } - break; - - case 'multiple': - if($optval) - { - $ret .= " multiple='multiple'"; - } - break; - - case 'selected': - if($optval) - { - $ret .= " selected='selected'"; - } - break; - - case 'maxlength': - if($optval) - { - $ret .= " maxlength='{$optval}'"; - } - break; - - case 'checked': - if($optval) - { - $ret .= " checked='checked'"; - } - break; - - case 'disabled': - if($optval) - { - $ret .= " disabled='disabled'"; - } - break; - - case 'required': - if($optval) - { - $ret .= " required='required'"; - } - break; - - case 'autofocus': - if($optval) - { - $ret .= " autofocus='autofocus'"; - } - break; - - case 'placeholder': - if($optval) { - $optval = deftrue($optval, $optval); - $ret .= " placeholder='{$optval}'"; - } - break; - - case 'wrap': - if($optval) - { - $ret .= " wrap='{$optval}'"; - } - break; - - case 'autocomplete': - if($optval) - { - $ret .= " autocomplete='{$optval}'"; - } - break; - - case 'pattern': - if($optval) - { - $ret .= " pattern='{$optval}'"; + $ret .= $this->attributes([$option => $this->_tabindex_counter]); } break; @@ -4056,7 +3993,7 @@ var_dump($select_options);*/ default: if(strpos($option,'data-') === 0) { - $ret .= ' ' .$option."='{$optval}'"; + $ret .= $this->attributes([$option => $optval]); } break; }