xref: /plugin/approve/admin.php (revision 086ec97f464da60e465e4d1f9e8067fcfcf13f2a)
1<?php
2/**
3 * DokuWiki Plugin watchcycle (Admin Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  Szymon Olewniczak <dokuwiki@cosmocode.de>
7 */
8
9// must be run within Dokuwiki
10if (!defined('DOKU_INC')) {
11    die();
12}
13
14class admin_plugin_approve extends DokuWiki_Admin_Plugin
15{
16
17    /** @var helper_plugin_sqlite */
18    protected $sqlite;
19
20    /** @var helper_plugin_approve */
21    protected $helper;
22
23    /**
24     * @return helper_plugin_sqlite
25     */
26    protected function sqlite() {
27        if (!$this->sqlite) {
28            /** @var helper_plugin_approve_db $db_helper */
29            $db_helper = plugin_load('helper', 'approve_db');
30            $this->sqlite = $db_helper->getDB();
31        }
32        return $this->sqlite;
33    }
34
35    /**
36     * @return helper_plugin_approve
37     */
38    protected function helper() {
39        if (!$this->helper) {
40            $helper = plugin_load('helper', 'approve');
41            $this->helper = $helper;
42        }
43        return $this->helper;
44    }
45
46    /**
47     * @return int sort number in admin menu
48     */
49    public function getMenuSort()
50    {
51        return 1;
52    }
53
54    protected function getPages() {
55        global $conf;
56        $datadir = $conf['datadir'];
57        if (substr($datadir, -1) != '/') {
58            $datadir .= '/';
59        }
60
61        $directory = new RecursiveDirectoryIterator($datadir, FilesystemIterator::SKIP_DOTS);
62        $iterator = new RecursiveIteratorIterator($directory);
63
64        $pages = [];
65        foreach ($iterator as $fileinfo) {
66            if (!$fileinfo->isFile()) continue;
67
68            $path = $fileinfo->getPath();
69            $ns = str_replace('/', ':', substr($path, strlen($datadir)));
70
71            if (!isset($pages[$ns])) {
72                $pages[$ns] = [];
73            }
74
75            //remove .txt
76            $pages[$ns][] = substr($fileinfo->getFilename(), 0, -4);
77        }
78
79
80        return $pages;
81    }
82
83    protected function updatePage()
84    {
85        $res = $this->sqlite()->query('SELECT * FROM maintainer');
86        $assignments = $this->sqlite()->res2arr($res);
87
88        $weighted_assigments = [];
89        foreach ($assignments as $assignment) {
90            $ns = $assignment['namespace'];
91            //more general namespaces are overridden by more specific ones.
92            if (substr($ns, -1) == '*') {
93                $weight = substr_count($ns, ':');
94            } else {
95                $weight = PHP_INT_MAX;
96            }
97
98            $assignment['weight'] = $weight;
99            $weighted_assigments[] = $assignment;
100        }
101        array_multisort(array_column($weighted_assigments, 'weight'), $weighted_assigments);
102
103        $pages = [];
104        $wikiPages = $this->getPages();
105        foreach ($weighted_assigments as $assignment) {
106            $ns = $assignment['namespace'];
107            $maintainer = $assignment['maintainer'];
108            if (substr($ns, -2) == '**') {
109                //remove '**'
110                $ns = substr($ns, 0, -2);
111                $ns = trim($ns, ':');
112                foreach ($wikiPages as $page) {
113//                    if (substr($page, 0, strlen($ns)) === $ns) {
114//
115//                    }
116                }
117
118            } elseif (substr($ns, -2) == '*') {
119                //remove '*'
120                $ns = substr($ns, 0, -2);
121                $ns = trim($ns, ':');
122            } else {
123                $ns = trim($ns, ':');
124                $pages[$ns] = $maintainer;
125            }
126        }
127
128        return true;
129    }
130
131    /**
132     * Should carry out any processing required by the plugin.
133     */
134    public function handle()
135    {
136        global $ID;
137
138        /* @var Input */
139        global $INPUT;
140
141        if($INPUT->str('action') && $INPUT->arr('assignment') && checkSecurityToken()) {
142            $assignment = $INPUT->arr('assignment');
143            //insert empty string as NULL
144            if ($INPUT->str('action') === 'delete') {
145                $ok = $this->sqlite()->query('DELETE FROM maintainer WHERE id=?', $assignment['id']);
146                if (!$ok) msg('failed to remove pattern', -1);
147
148                $this->updatePage();
149            } else if ($INPUT->str('action') === 'add' && !blank($assignment['assign'])) {
150                if (blank($assignment['maintainer'])) {
151                    $q = 'INSERT INTO maintainer(namespace) VALUES (?)';
152                    $ok = $this->sqlite()->query($q, $assignment['assign']);
153                } else {
154                    $q = 'INSERT INTO maintainer(namespace,maintainer) VALUES (?,?)';
155                    $ok = $this->sqlite()->query($q, $assignment['assign'], $assignment['maintainer']);
156                }
157
158                if (!$ok) msg('failed to add pattern', -1);
159
160                $this->updatePage();
161            }
162
163            send_redirect(wl($ID, array('do' => 'admin', 'page' => 'approve'), true, '&'));
164        }
165    }
166
167    /**
168     * Render HTML output, e.g. helpful text and a form
169     */
170    public function html()
171    {
172        global $lang;
173
174        global $ID;
175        /* @var DokuWiki_Auth_Plugin */
176        global $auth;
177
178        $res = $this->sqlite()->query('SELECT * FROM maintainer');
179        $assignments = $this->sqlite()->res2arr($res);
180
181        echo $this->locale_xhtml('assignments_intro');
182
183        echo '<form action="' . wl($ID) . '" action="post">';
184        echo '<input type="hidden" name="do" value="admin" />';
185        echo '<input type="hidden" name="page" value="approve" />';
186        echo '<input type="hidden" name="sectok" value="' . getSecurityToken() . '" />';
187        echo '<table class="inline">';
188
189        // header
190        echo '<tr>';
191        echo '<th>'.$this->getLang('admin h_assignment_namespace').'</th>';
192        echo '<th>'.$this->getLang('admin h_assignment_maintainer').'</th>';
193        echo '<th></th>';
194        echo '</tr>';
195
196        // existing assignments
197        foreach($assignments as $assignment) {
198            $id = $assignment['id'];
199            $namespace = $assignment['namespace'];
200            $maintainer = $assignment['maintainer'] ? $assignment['maintainer'] : '---';
201
202            $link = wl(
203                $ID, array(
204                    'do' => 'admin',
205                    'page' => 'approve',
206                    'action' => 'delete',
207                    'sectok' => getSecurityToken(),
208                    'assignment[id]' => $id
209                )
210            );
211
212            echo '<tr>';
213            echo '<td>' . hsc($namespace) . '</td>';
214            echo '<td>' . hsc($maintainer) . '</td>';
215            echo '<td><a href="' . $link . '">'.$this->getLang('admin btn_delete').'</a></td>';
216            echo '</tr>';
217        }
218
219        // new assignment form
220        echo '<tr>';
221        echo '<td><input type="text" name="assignment[assign]" /></td>';
222        echo '<td>';
223        echo '<select name="assignment[maintainer]">';
224        echo '<option value="">---</option>';
225        foreach($auth->retrieveUsers() as $login => $data) {
226            echo '<option value="' . hsc($login) . '">' . hsc($data['name']) . '</option>';
227        }
228        echo '</select>';
229        echo '</td>';
230        echo '<td><button type="submit" name="action" value="add">'.$this->getLang('admin btn_add').'</button></td>';
231        echo '</tr>';
232
233        echo '</table>';
234    }
235}
236
237// vim:ts=4:sw=4:et:
238