xref: /dokuwiki/inc/Form/LegacyForm.php (revision de19515f04567db78bd41d5bff68a88bfb8c2a22)
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
63                    case 'tag':
64                    case 'opentag':
65                    case 'closetag':
66                    case 'openfieldset':
67                    case 'closefieldset':
68                    case 'button':
69                    case 'field':
70                    case 'fieldright':
71                    case 'filefield':
72                    case 'menufield':
73                    case 'listboxfield':
74                        throw new \UnexpectedValueException('Unsupported legacy field ' . $ctl['elem']);
75                        break;
76                    default:
77                        throw new \UnexpectedValueException('Unknown legacy field ' . $ctl['elem']);
78
79                }
80            } else {
81                $this->addHTML($element);
82            }
83        }
84
85    }
86
87    /**
88     * Parses out what is the elements attributes and what is control info
89     *
90     * @param array $legacy
91     * @return array
92     */
93    protected function parseLegacyAttr($legacy) {
94        $attributes = array();
95        $control = array();
96
97        foreach($legacy as $key => $val) {
98            if($key{0} == '_') {
99                $control[substr($key, 1)] = $val;
100            } elseif($key == 'name') {
101                $control[$key] = $val;
102            } elseif($key == 'id') {
103                $control[$key] = $val;
104            } else {
105                $attributes[$key] = $val;
106            }
107        }
108
109        return array($control, $attributes);
110    }
111
112    /**
113     * Translates our types to the legacy types
114     *
115     * @param string $type
116     * @return string
117     */
118    protected function legacyType($type) {
119        static $types = array(
120            'text' => 'textfield',
121            'password' => 'passwordfield',
122            'checkbox' => 'checkboxfield',
123            'radio' => 'radiofield',
124        );
125        if(isset($types[$type])) return $types[$type];
126        return $type;
127    }
128
129    /**
130     * Creates an old legacy form from this modern form's data
131     *
132     * @return \Doku_Form
133     */
134    public function toLegacy() {
135        $this->balanceFieldsets();
136
137        $legacy = new \Doku_Form($this->attrs());
138        $legacy->_hidden = $this->hidden;
139        foreach($this->elements as $element) {
140            if(is_a($element, 'dokuwiki\Form\HTMLElement')) {
141                $legacy->_content[] = $element->toHTML();
142            } elseif(is_a($element, 'dokuwiki\Form\InputElement')) {
143                /** @var InputElement $element */
144                $data = $element->attrs();
145                $data['_elem'] = $this->legacyType($element->getType());
146                $label = $element->getLabel();
147                if($label) {
148                    $data['_class'] = $label->attr('class');
149                }
150                $legacy->_content[] = $data;
151            }
152        }
153
154        return $legacy;
155    }
156}
157