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