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