112a4e4d1SAndreas Gohr<?php 212a4e4d1SAndreas Gohrnamespace dokuwiki\Form; 312a4e4d1SAndreas Gohr 412a4e4d1SAndreas Gohr/** 512a4e4d1SAndreas Gohr * Class InputElement 612a4e4d1SAndreas Gohr * 7*de19515fSAndreas Gohr * Base class for all input elements. Uses a wrapping label when label 8*de19515fSAndreas Gohr * text is given. 912a4e4d1SAndreas Gohr * 1012a4e4d1SAndreas Gohr * @todo figure out how to make wrapping or related label configurable 1112a4e4d1SAndreas Gohr * @package dokuwiki\Form 1212a4e4d1SAndreas Gohr */ 1312a4e4d1SAndreas Gohrclass InputElement extends Element { 1412a4e4d1SAndreas Gohr /** 1512a4e4d1SAndreas Gohr * @var Label 1612a4e4d1SAndreas Gohr */ 17*de19515fSAndreas Gohr protected $label = null; 1812a4e4d1SAndreas Gohr 1912a4e4d1SAndreas Gohr /** 2012a4e4d1SAndreas Gohr * @var bool if the element should reflect posted values 2112a4e4d1SAndreas Gohr */ 2212a4e4d1SAndreas Gohr protected $useInput = true; 2312a4e4d1SAndreas Gohr 2412a4e4d1SAndreas Gohr /** 2512a4e4d1SAndreas Gohr * @param string $type The type of this element 2612a4e4d1SAndreas Gohr * @param string $name The name of this form element 2712a4e4d1SAndreas Gohr * @param string $label The label text for this element 2812a4e4d1SAndreas Gohr */ 29*de19515fSAndreas Gohr public function __construct($type, $name, $label = '') { 3012a4e4d1SAndreas Gohr parent::__construct($type, array('name' => $name)); 3112a4e4d1SAndreas Gohr $this->attr('name', $name); 32*de19515fSAndreas Gohr if($label) $this->label = new Label($label); 33*de19515fSAndreas Gohr } 34*de19515fSAndreas Gohr 35*de19515fSAndreas Gohr /** 36*de19515fSAndreas Gohr * Returns the label element if there's one set 37*de19515fSAndreas Gohr * 38*de19515fSAndreas Gohr * @return Label|null 39*de19515fSAndreas Gohr */ 40*de19515fSAndreas Gohr public function getLabel() { 41*de19515fSAndreas Gohr return $this->label; 4212a4e4d1SAndreas Gohr } 4312a4e4d1SAndreas Gohr 4412a4e4d1SAndreas Gohr /** 4512a4e4d1SAndreas Gohr * Should the user sent input be used to initialize the input field 4612a4e4d1SAndreas Gohr * 4712a4e4d1SAndreas Gohr * The default is true. Any set values will be overwritten by the INPUT 4812a4e4d1SAndreas Gohr * provided values. 4912a4e4d1SAndreas Gohr * 5012a4e4d1SAndreas Gohr * @param bool $useinput 5112a4e4d1SAndreas Gohr * @return $this 5212a4e4d1SAndreas Gohr */ 5312a4e4d1SAndreas Gohr public function useInput($useinput) { 5412a4e4d1SAndreas Gohr $this->useInput = (bool) $useinput; 5512a4e4d1SAndreas Gohr return $this; 5612a4e4d1SAndreas Gohr } 5712a4e4d1SAndreas Gohr 5812a4e4d1SAndreas Gohr /** 5912a4e4d1SAndreas Gohr * Get or set the element's ID 6012a4e4d1SAndreas Gohr * 6112a4e4d1SAndreas Gohr * @param null|string $id 6212a4e4d1SAndreas Gohr * @return string|$this 6312a4e4d1SAndreas Gohr */ 6412a4e4d1SAndreas Gohr public function id($id = null) { 65*de19515fSAndreas Gohr if($this->label) $this->label->attr('for', $id); 6612a4e4d1SAndreas Gohr return parent::id($id); 6712a4e4d1SAndreas Gohr } 6812a4e4d1SAndreas Gohr 6912a4e4d1SAndreas Gohr /** 7012a4e4d1SAndreas Gohr * Adds a class to the class attribute 7112a4e4d1SAndreas Gohr * 7212a4e4d1SAndreas Gohr * This is the preferred method of setting the element's class 7312a4e4d1SAndreas Gohr * 7412a4e4d1SAndreas Gohr * @param string $class the new class to add 7512a4e4d1SAndreas Gohr * @return $this 7612a4e4d1SAndreas Gohr */ 7712a4e4d1SAndreas Gohr public function addClass($class) { 78*de19515fSAndreas Gohr if($this->label) $this->label->addClass($class); 7912a4e4d1SAndreas Gohr return parent::addClass($class); 8012a4e4d1SAndreas Gohr } 8112a4e4d1SAndreas Gohr 8212a4e4d1SAndreas Gohr /** 8312a4e4d1SAndreas Gohr * Figures out how to access the value for this field from INPUT data 8412a4e4d1SAndreas Gohr * 8512a4e4d1SAndreas Gohr * The element's name could have been given as a simple string ('foo') 8612a4e4d1SAndreas Gohr * or in array notation ('foo[bar]'). 8712a4e4d1SAndreas Gohr * 8812a4e4d1SAndreas Gohr * Note: this function only handles one level of arrays. If your data 8912a4e4d1SAndreas Gohr * is nested deeper, you should call useInput(false) and set the 9012a4e4d1SAndreas Gohr * correct value yourself 9112a4e4d1SAndreas Gohr * 9212a4e4d1SAndreas Gohr * @return array name and array key (null if not an array) 9312a4e4d1SAndreas Gohr */ 9412a4e4d1SAndreas Gohr protected function getInputName() { 9512a4e4d1SAndreas Gohr $name = $this->attr('name'); 9612a4e4d1SAndreas Gohr parse_str("$name=1", $parsed); 9712a4e4d1SAndreas Gohr 9812a4e4d1SAndreas Gohr $name = array_keys($parsed); 9912a4e4d1SAndreas Gohr $name = array_shift($name); 10012a4e4d1SAndreas Gohr 10112a4e4d1SAndreas Gohr if(is_array($parsed[$name])) { 10212a4e4d1SAndreas Gohr $key = array_keys($parsed[$name]); 10312a4e4d1SAndreas Gohr $key = array_shift($key); 10412a4e4d1SAndreas Gohr } else { 10512a4e4d1SAndreas Gohr $key = null; 10612a4e4d1SAndreas Gohr } 10712a4e4d1SAndreas Gohr 10812a4e4d1SAndreas Gohr return array($name, $key); 10912a4e4d1SAndreas Gohr } 11012a4e4d1SAndreas Gohr 11112a4e4d1SAndreas Gohr /** 11212a4e4d1SAndreas Gohr * Handles the useInput flag and set the value attribute accordingly 11312a4e4d1SAndreas Gohr */ 11412a4e4d1SAndreas Gohr protected function prefillInput() { 11512a4e4d1SAndreas Gohr global $INPUT; 11612a4e4d1SAndreas Gohr 11712a4e4d1SAndreas Gohr list($name, $key) = $this->getInputName(); 11812a4e4d1SAndreas Gohr if(!$INPUT->has($name)) return; 11912a4e4d1SAndreas Gohr 12012a4e4d1SAndreas Gohr if($key === null) { 12112a4e4d1SAndreas Gohr $value = $INPUT->str($name); 12212a4e4d1SAndreas Gohr } else { 12312a4e4d1SAndreas Gohr $value = $INPUT->arr($name); 12412a4e4d1SAndreas Gohr if(isset($value[$key])) { 12512a4e4d1SAndreas Gohr $value = $value[$key]; 12612a4e4d1SAndreas Gohr } else { 12712a4e4d1SAndreas Gohr $value = ''; 12812a4e4d1SAndreas Gohr } 12912a4e4d1SAndreas Gohr } 13012a4e4d1SAndreas Gohr if($value !== '') { 13112a4e4d1SAndreas Gohr $this->val($value); 13212a4e4d1SAndreas Gohr } 13312a4e4d1SAndreas Gohr } 13412a4e4d1SAndreas Gohr 13512a4e4d1SAndreas Gohr /** 13612a4e4d1SAndreas Gohr * The HTML representation of this element 13712a4e4d1SAndreas Gohr * 13812a4e4d1SAndreas Gohr * @return string 13912a4e4d1SAndreas Gohr */ 14012a4e4d1SAndreas Gohr protected function mainElementHTML() { 14112a4e4d1SAndreas Gohr if($this->useInput) $this->prefillInput(); 14212a4e4d1SAndreas Gohr return '<input ' . buildAttributes($this->attrs()) . ' />'; 14312a4e4d1SAndreas Gohr } 14412a4e4d1SAndreas Gohr 14512a4e4d1SAndreas Gohr /** 14612a4e4d1SAndreas Gohr * The HTML representation of this element wrapped in a label 14712a4e4d1SAndreas Gohr * 14812a4e4d1SAndreas Gohr * @return string 14912a4e4d1SAndreas Gohr */ 15012a4e4d1SAndreas Gohr public function toHTML() { 151*de19515fSAndreas Gohr if($this->label) { 15212a4e4d1SAndreas Gohr return '<label ' . buildAttributes($this->label->attrs()) . '>' . DOKU_LF . 15312a4e4d1SAndreas Gohr '<span>' . hsc($this->label->label) . '</span>' . DOKU_LF . 15412a4e4d1SAndreas Gohr $this->mainElementHTML() . DOKU_LF . 15512a4e4d1SAndreas Gohr '</label>'; 156*de19515fSAndreas Gohr } else { 157*de19515fSAndreas Gohr return $this->mainElementHTML(); 158*de19515fSAndreas Gohr } 15912a4e4d1SAndreas Gohr } 16012a4e4d1SAndreas Gohr} 161