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