1<?php 2namespace dokuwiki\Form; 3 4/** 5 * Class InputElement 6 * 7 * Base class for all input elements. Uses a wrapping label. 8 * 9 * @todo figure out how to make wrapping or related label configurable 10 * @package dokuwiki\Form 11 */ 12class InputElement extends Element { 13 /** 14 * @var Label 15 */ 16 protected $label; 17 18 /** 19 * @var bool if the element should reflect posted values 20 */ 21 protected $useInput = true; 22 23 /** 24 * @param string $type The type of this element 25 * @param string $name The name of this form element 26 * @param string $label The label text for this element 27 */ 28 public function __construct($type, $name, $label) { 29 parent::__construct($type, array('name' => $name)); 30 $this->attr('name', $name); 31 } 32 33 /** 34 * Should the user sent input be used to initialize the input field 35 * 36 * The default is true. Any set values will be overwritten by the INPUT 37 * provided values. 38 * 39 * @param bool $useinput 40 * @return $this 41 */ 42 public function useInput($useinput) { 43 $this->useInput = (bool) $useinput; 44 return $this; 45 } 46 47 /** 48 * Get or set the element's ID 49 * 50 * @param null|string $id 51 * @return string|$this 52 */ 53 public function id($id = null) { 54 $this->label->attr('for', $id); 55 return parent::id($id); 56 } 57 58 /** 59 * Adds a class to the class attribute 60 * 61 * This is the preferred method of setting the element's class 62 * 63 * @param string $class the new class to add 64 * @return $this 65 */ 66 public function addClass($class) { 67 $this->label->addClass($class); 68 return parent::addClass($class); 69 } 70 71 /** 72 * Figures out how to access the value for this field from INPUT data 73 * 74 * The element's name could have been given as a simple string ('foo') 75 * or in array notation ('foo[bar]'). 76 * 77 * Note: this function only handles one level of arrays. If your data 78 * is nested deeper, you should call useInput(false) and set the 79 * correct value yourself 80 * 81 * @return array name and array key (null if not an array) 82 */ 83 protected function getInputName() { 84 $name = $this->attr('name'); 85 parse_str("$name=1", $parsed); 86 87 $name = array_keys($parsed); 88 $name = array_shift($name); 89 90 if(is_array($parsed[$name])) { 91 $key = array_keys($parsed[$name]); 92 $key = array_shift($key); 93 } else { 94 $key = null; 95 } 96 97 return array($name, $key); 98 } 99 100 /** 101 * Handles the useInput flag and set the value attribute accordingly 102 */ 103 protected function prefillInput() { 104 global $INPUT; 105 106 list($name, $key) = $this->getInputName(); 107 if(!$INPUT->has($name)) return; 108 109 if($key === null) { 110 $value = $INPUT->str($name); 111 } else { 112 $value = $INPUT->arr($name); 113 if(isset($value[$key])) { 114 $value = $value[$key]; 115 } else { 116 $value = ''; 117 } 118 } 119 if($value !== '') { 120 $this->val($value); 121 } 122 } 123 124 /** 125 * The HTML representation of this element 126 * 127 * @return string 128 */ 129 protected function mainElementHTML() { 130 if($this->useInput) $this->prefillInput(); 131 return '<input ' . buildAttributes($this->attrs()) . ' />'; 132 } 133 134 /** 135 * The HTML representation of this element wrapped in a label 136 * 137 * @return string 138 */ 139 public function toHTML() { 140 return '<label ' . buildAttributes($this->label->attrs()) . '>' . DOKU_LF . 141 '<span>' . hsc($this->label->label) . '</span>' . DOKU_LF . 142 $this->mainElementHTML() . DOKU_LF . 143 '</label>'; 144 } 145} 146