1<?php 2namespace dokuwiki\Form; 3 4/** 5 * Class LegacyForm 6 * 7 * Provides a compatibility layer to the old Doku_Form API 8 * 9 * This can be used to work with the modern API on forms provided by old events for 10 * example. When you start new forms, just use Form\Form 11 * 12 * @package dokuwiki\Form 13 */ 14class LegacyForm extends Form { 15 16 /** 17 * Creates a new modern form from an old legacy Doku_Form 18 * 19 * @param \Doku_Form $oldform 20 */ 21 public function __construct(\Doku_Form $oldform) { 22 parent::__construct($oldform->params); 23 24 $this->hidden = $oldform->_hidden; 25 26 foreach($oldform->_content as $element) { 27 list($ctl, $attr) = $this->parseLegacyAttr($element); 28 29 if(is_array($element)) { 30 switch($ctl['elem']) { 31 case 'wikitext': 32 $this->addTextarea('wikitext') 33 ->attrs($attr) 34 ->id('wiki__text') 35 ->val($ctl['text']) 36 ->addClass($ctl['class']); 37 break; 38 case 'textfield': 39 $this->addTextInput($ctl['name'], $ctl['text']) 40 ->attrs($attr) 41 ->id($ctl['id']) 42 ->addClass($ctl['class']); 43 break; 44 case 'passwordfield': 45 $this->addPasswordInput($ctl['name'], $ctl['text']) 46 ->attrs($attr) 47 ->id($ctl['id']) 48 ->addClass($ctl['class']); 49 break; 50 case 'checkboxfield': 51 $this->addCheckbox($ctl['name'], $ctl['text']) 52 ->attrs($attr) 53 ->id($ctl['id']) 54 ->addClass($ctl['class']); 55 break; 56 case 'radiofield': 57 $this->addRadioButton($ctl['name'], $ctl['text']) 58 ->attrs($attr) 59 ->id($ctl['id']) 60 ->addClass($ctl['class']); 61 break; 62 case 'tag': 63 $this->addTag($ctl['tag']) 64 ->attrs($attr) 65 ->attr('name', $ctl['name']) 66 ->id($ctl['id']) 67 ->addClass($ctl['class']); 68 break; 69 case 'opentag': 70 $this->addTagOpen($ctl['tag']) 71 ->attrs($attr) 72 ->attr('name', $ctl['name']) 73 ->id($ctl['id']) 74 ->addClass($ctl['class']); 75 break; 76 case 'closetag': 77 $this->addTagClose($ctl['tag']); 78 break; 79 case 'openfieldset': 80 $this->addFieldsetOpen($ctl['legend']) 81 ->attrs($attr) 82 ->attr('name', $ctl['name']) 83 ->id($ctl['id']) 84 ->addClass($ctl['class']); 85 break; 86 case 'closefieldset': 87 $this->addFieldsetClose(); 88 break; 89 case 'button': 90 case 'field': 91 case 'fieldright': 92 case 'filefield': 93 case 'menufield': 94 case 'listboxfield': 95 throw new \UnexpectedValueException('Unsupported legacy field ' . $ctl['elem']); 96 break; 97 default: 98 throw new \UnexpectedValueException('Unknown legacy field ' . $ctl['elem']); 99 100 } 101 } else { 102 $this->addHTML($element); 103 } 104 } 105 106 } 107 108 /** 109 * Parses out what is the elements attributes and what is control info 110 * 111 * @param array $legacy 112 * @return array 113 */ 114 protected function parseLegacyAttr($legacy) { 115 $attributes = array(); 116 $control = array(); 117 118 foreach($legacy as $key => $val) { 119 if($key{0} == '_') { 120 $control[substr($key, 1)] = $val; 121 } elseif($key == 'name') { 122 $control[$key] = $val; 123 } elseif($key == 'id') { 124 $control[$key] = $val; 125 } else { 126 $attributes[$key] = $val; 127 } 128 } 129 130 return array($control, $attributes); 131 } 132 133 /** 134 * Translates our types to the legacy types 135 * 136 * @param string $type 137 * @return string 138 */ 139 protected function legacyType($type) { 140 static $types = array( 141 'text' => 'textfield', 142 'password' => 'passwordfield', 143 'checkbox' => 'checkboxfield', 144 'radio' => 'radiofield', 145 'tagopen' => 'opentag', 146 'tagclose' => 'closetag', 147 'fieldsetopen' => 'openfieldset', 148 'fieldsetclose' => 'closefieldset', 149 ); 150 if(isset($types[$type])) return $types[$type]; 151 return $type; 152 } 153 154 /** 155 * Creates an old legacy form from this modern form's data 156 * 157 * @return \Doku_Form 158 */ 159 public function toLegacy() { 160 $this->balanceFieldsets(); 161 162 $legacy = new \Doku_Form($this->attrs()); 163 $legacy->_hidden = $this->hidden; 164 foreach($this->elements as $element) { 165 if(is_a($element, 'dokuwiki\Form\HTMLElement')) { 166 $legacy->_content[] = $element->toHTML(); 167 } elseif(is_a($element, 'dokuwiki\Form\InputElement')) { 168 /** @var InputElement $element */ 169 $data = $element->attrs(); 170 $data['_elem'] = $this->legacyType($element->getType()); 171 $label = $element->getLabel(); 172 if($label) { 173 $data['_class'] = $label->attr('class'); 174 } 175 $legacy->_content[] = $data; 176 } 177 } 178 179 return $legacy; 180 } 181} 182