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