xref: /dokuwiki/inc/Form/LegacyForm.php (revision 920904359a7088e3cf3885a96c03c453aa9e4095)
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