1<?php
2
3use dokuwiki\Extension\AdminPlugin;
4use dokuwiki\Form\Form;
5
6/**
7 * DokuWiki Plugin structnotification (Admin Component)
8 *
9 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
10 * @author  Szymon Olewniczak <it@rid.pl>
11 */
12class admin_plugin_structnotification extends AdminPlugin
13{
14    protected $headers = ['schema', 'field', 'operator', 'value', 'filters', 'users_and_groups', 'message'];
15    protected $operators = ['before', 'after', 'at'];
16
17    /**
18     * @return int sort number in admin menu
19     */
20    public function getMenuSort()
21    {
22        return 499;
23    }
24
25    /**
26     * @return bool true if only access for superuser, false is for superusers and moderators
27     */
28    public function forAdminOnly()
29    {
30        return false;
31    }
32
33    /**
34     * Should carry out any processing required by the plugin.
35     */
36    public function handle()
37    {
38        global $INPUT;
39        global $ID;
40
41        try {
42            /** @var \helper_plugin_structnotification_db$db_helper */
43            $db_helper = plugin_load('helper', 'structnotification_db');
44            $sqlite = $db_helper->getDB();
45        } catch (Exception $e) {
46            msg($e->getMessage(), -1);
47            return;
48        }
49
50        if ($INPUT->str('action') && $INPUT->arr('predicate') && checkSecurityToken()) {
51            $predicate = $INPUT->arr('predicate');
52            if ($INPUT->str('action') === 'add') {
53                $errors = $this->validate($predicate);
54                if ($errors) {
55                    $this->displayErrors($errors);
56                    return;
57                }
58                $ok = $sqlite->storeEntry('predicate', $predicate);
59                if (!$ok) msg('failed to add predicate', -1);
60            } elseif ($INPUT->str('action') === 'delete') {
61                $ok = $sqlite->query('DELETE FROM predicate WHERE id=?', $predicate['id']);
62                if (!$ok) msg('failed to delete predicate', -1);
63            } elseif ($INPUT->str('action') === 'update') {
64                $errors = $this->validate($predicate);
65                if ($errors) {
66                    $this->displayErrors($errors);
67                    return;
68                }
69
70                $set = implode(',', array_map(static fn($header) => "$header=?", $this->headers));
71                $predicate['id'] = $INPUT->str('edit');
72                $ok = $sqlite->query("UPDATE predicate SET $set WHERE id=?", $predicate);
73                if (!$ok) msg('failed to update predicate', -1);
74            }
75
76            if ($ok) send_redirect(wl($ID, ['do' => 'admin', 'page' => 'structnotification'], true, '&'));
77        }
78    }
79
80    /**
81     * Render HTML output, e.g. helpful text and a form
82     */
83    public function html()
84    {
85        global $INPUT;
86        global $ID;
87
88        try {
89            /** @var \helper_plugin_structnotification_db$db_helper */
90            $db_helper = plugin_load('helper', 'structnotification_db');
91            $sqlite = $db_helper->getDB();
92        } catch (Exception $e) {
93            msg($e->getMessage(), -1);
94            return;
95        }
96
97        echo '<h1>' . $this->getLang('menu') . '</h1>';
98        echo '<div class="table"><table>';
99
100        echo $this->locale_xhtml('intro');
101
102        echo '<tr>';
103        foreach ($this->headers as $header) {
104            echo '<th>' . $this->getLang('admin header ' . $header) . '</th>';
105        }
106        echo '<th></th>';
107        echo '</tr>';
108
109        $q = 'SELECT * FROM predicate';
110        $res = $sqlite->query($q);
111
112        $predicates = $sqlite->res2arr($res);
113
114        foreach ($predicates as $predicate) {
115            if ($INPUT->str('edit') == $predicate['id']) {
116                if (!$INPUT->has('predicate')) {
117                    $INPUT->set('predicate', $predicate);
118                }
119
120                echo $this->form('update');
121                continue;
122            }
123
124            echo '<tr>';
125            foreach ($this->headers as $header) {
126                $value = $predicate[$header];
127                if ($header == 'message') {
128                    $html = p_render('xhtml', p_get_instructions($value), $info);
129                    echo '<td>' . $html . '</td>';
130                } else {
131                    echo '<td>' . $value . '</td>';
132                }
133            }
134
135            echo '<td>';
136            $link = wl(
137                $ID,
138                ['do' => 'admin', 'page' => 'structnotification', 'edit' => $predicate['id']]
139            );
140            echo '<a href="' . $link . '">' . $this->getLang('edit') . '</a> | ';
141
142            $link = wl(
143                $ID,
144                [
145                    'do' => 'admin',
146                    'page' => 'structnotification',
147                    'action' => 'delete',
148                    'sectok' => getSecurityToken(),
149                    'predicate[id]' => $predicate['id']
150                ]
151            );
152            echo '<a class="plugin__structnotification_delete" href="' . $link . '">' .
153                $this->getLang('delete') . '</a>';
154
155            echo '</td>';
156            echo '</tr>';
157        }
158        if (!$INPUT->has('edit')) {
159            echo $this->form();
160        }
161        echo '</table></div>';
162    }
163
164    protected function form($action = 'add')
165    {
166        global $ID;
167
168        $form = new Form();
169        $form->addTagOpen('tr');
170
171        $form->addTagOpen('td');
172        $form->addTextInput('predicate[schema]')->attr('size', 10);
173        $form->addTagClose('td');
174
175        $form->addTagOpen('td');
176        $form->addTextInput('predicate[field]')->attr('size', 10);
177        $form->addTagClose('td');
178
179        $form->addTagOpen('td');
180        $form->addDropdown('predicate[operator]', $this->operators);
181        $form->addTagClose('td');
182
183        $form->addTagOpen('td');
184        $form->addTextInput('predicate[value]')->attr('size', 10);
185        $form->addTagClose('td');
186
187        $form->addTagOpen('td');
188        $form->addTextarea('predicate[filters]')
189            ->attrs([
190                'cols' => '12',
191                'rows' => '5'
192            ]);
193        $form->addTagClose('td');
194
195        $form->addTagOpen('td');
196        $form->addTextInput('predicate[users_and_groups]')->attr('size', 10);
197        $form->addTagClose('td');
198
199        $form->addTagOpen('td');
200        $form->addHTML('<div id="tool__bar"></div>');
201        $form->setHiddenField('id', $ID); //for linkwiz
202        $form->addTextarea('predicate[message]')
203            ->id('wiki__text')
204            ->attr('style', 'width: 100%; height: 10em;');
205        $form->addTagClose('td');
206
207        $form->addTagOpen('td');
208        $form->addButton('action', $this->getLang($action))->val($action);
209        $link = wl(
210            $ID,
211            [
212                'do' => 'admin',
213                'page' => 'structnotification',
214            ]
215        );
216        $cancel_link = '<a href="' . $link . '" style="margin-left:1em" id="plugin__structnotification_cancel">' .
217            $this->getLang('cancel') . '</a>';
218        $form->addHTML($cancel_link);
219        $form->addTagClose('td');
220
221
222        $form->addTagClose('tr');
223
224        return $form->toHTML();
225    }
226
227    protected function validate($predicate)
228    {
229        $errors = [];
230        if (blank($predicate['schema'])) {
231            $errors[] = 'val schema blank';
232        }
233
234        if (blank($predicate['field'])) {
235            $errors[] = 'val field blank';
236        }
237
238        if (blank($predicate['operator'])) {
239            $errors[] = 'val operator blank';
240        }
241
242        if (blank($predicate['value'])) {
243            $errors[] = 'val value blank';
244        }
245
246        if (blank($predicate['users_and_groups'])) {
247            $errors[] = 'val users_and_groups blank';
248        }
249
250        if (blank($predicate['message'])) {
251            $errors[] = 'val message blank';
252        }
253
254        return $errors;
255    }
256
257    protected function displayErrors($errors)
258    {
259        foreach ($errors as $error) {
260            $msg = $this->getLang($error);
261            if (!$msg) $msg = $error;
262            msg($error, -1);
263        }
264    }
265}
266