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