1<?php
2
3/**
4 * Class helper_plugin_data_aliastextbox
5 *
6 * Create a field with properties defined by given type alias
7 * Mostly this is a single line input field, but for enum type a select field.
8 */
9class helper_plugin_data_aliastextbox extends helper_plugin_bureaucracy_field
10{
11    private $args;
12    private $additional;
13
14    /**
15     * Arguments:
16     *  - cmd
17     *  - label
18     *  - _typealias (optional)
19     *  - ^ (optional)
20     *
21     * @param array $args The tokenized definition, only split at spaces
22     */
23    public function initialize($args)
24    {
25        $this->init($args);
26        $n_args = [];
27        $this->args = [];
28        foreach ($args as $arg) {
29            if ($arg[0] !== '_') {
30                $n_args[] = $arg;
31                continue;
32            }
33            $this->args[] = $arg;
34        }
35        $this->standardArgs($n_args);
36    }
37
38    /**
39     * Prepare
40     *
41     * @param array $args data plugin related field arguments
42     */
43    private function prepareColumns($args)
44    {
45        /** @var helper_plugin_data $dthlp */
46        $dthlp = plugin_load('helper', 'data');
47        if (!$dthlp) msg('Loading the data helper failed. Make sure the data plugin is installed.', -1);
48
49        foreach ($args as $arg) {
50            $arg = $this->replaceTranslation($arg);
51            $datatype = $dthlp->column($arg);
52            if (is_array($datatype['type'])) {
53                $datatype['basetype'] = $datatype['type']['type'];
54                $datatype['enum'] = $datatype['type']['enum'];
55                $datatype['type'] = $datatype['origtype'];
56            } else {
57                $datatype['basetype'] = $datatype['type'];
58            }
59        }
60        $datatype['title'] = '@@DISPLAY@@';
61        if (isset($datatype['enum'])) {
62            $values = preg_split('/\s*,\s*/', $datatype['enum']);
63            if (!$datatype['multi'] && $this->opt['optional']) array_unshift($values, '');
64            $this->opt['args'] = $values;
65            $this->additional = ($datatype['multi'] ? ['multiple' => 'multiple'] : []);
66        } else {
67            $classes = 'data_type_' . $datatype['type'] . ($datatype['multi'] ? 's' : '') . ' ' .
68                'data_type_' . $datatype['basetype'] . ($datatype['multi'] ? 's' : '');
69            $content = form_makeTextField('@@NAME@@', '@@VALUE@@', '@@DISPLAY@@', '@@ID@@', '@@CLASS@@ ' . $classes);
70
71            $this->tpl = $content;
72        }
73        if (!isset($this->opt['display'])) {
74            $this->opt['display'] = $this->opt['label'];
75        }
76    }
77
78    /**
79     * Render the field as XHTML
80     *
81     * Creates a single line input field or select field
82     *
83     * @params array     $params Additional HTML specific parameters
84     * @params Doku_Form $form   The target Doku_Form object
85     * @params int       $formid unique identifier of the form which contains this field
86     */
87    public function renderfield($params, Doku_Form $form, $formid)
88    {
89        $this->prepareColumns($this->args);
90
91        if (isset($this->tpl)) {
92            parent::renderfield($params, $form, $formid);
93        } else {
94            // Is an enum type, otherwise $this->tpl would be set in __construct
95            $this->_handlePreload();
96            if (!$form->_infieldset) {
97                $form->startFieldset('');
98            }
99            if ($this->error) {
100                $params['class'] = 'bureaucracy_error';
101            }
102            $params = array_merge($this->opt, $params);
103            $params['value'] = preg_split('/\s*,\s*/', $params['value'], -1, PREG_SPLIT_NO_EMPTY);
104            if (count($params['value']) === 0) {
105                $params['value'] = $params['args'][0];
106            }
107            if (!isset($this->opt['optional'])) {
108                $this->additional['required'] = 'required';
109            }
110
111            $form->addElement(call_user_func_array(
112                'form_makeListboxField',
113                $this->_parse_tpl(
114                    [
115                        '@@NAME@@[]',
116                        $params['args'],
117                        $params['value'],
118                        '@@DISPLAY@@',
119                        '',
120                        '@@CLASS@@',
121                        $this->additional
122                    ],
123                    $params
124                )
125            ));
126        }
127    }
128
129    /**
130     * Handle a post to the field
131     *
132     * Accepts and validates a posted value.
133     *
134     * @param string $value The passed value or array or null if none given
135     * @param helper_plugin_bureaucracy_field[] $fields (reference) form fields (POST handled upto $this field)
136     * @param int $index index number of field in form
137     * @param int $formid unique identifier of the form which contains this field
138     * @return bool Whether the passed value is valid
139     */
140    public function handlePost($value, &$fields, $index, $formid)
141    {
142        if (is_array($value)) {
143            $value = implode(', ', $value);
144        }
145
146        return parent::handlePost($value, $fields, $index, $formid);
147    }
148
149    /**
150     * Replace the translation placeholders
151     *
152     * @param string $string
153     * @return string parsed string
154     */
155    private function replaceTranslation($string)
156    {
157        global $ID;
158        global $conf;
159
160        $lang = $conf['lang'];
161        $trans = '';
162
163        /** @var helper_plugin_translation $translationPlugin */
164        $translationPlugin = plugin_load('helper', 'translation');
165        if ($translationPlugin) {
166            $trans = $translationPlugin->getLangPart($ID);
167            $lang = $translationPlugin->realLC('');
168        }
169
170        $string = str_replace('@LANG@', $lang, $string);
171        return str_replace('@TRANS@', $trans, $string);
172    }
173}
174