xref: /plugin/approve/admin.php (revision d8ede06043d02e5697f43d6d5bd3619b9ec26549)
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        /** @var SplFileInfo $fileinfo */
66        foreach ($iterator as $fileinfo) {
67            if (!$fileinfo->isFile()) continue;
68
69            $path = $fileinfo->getPathname();
70            //remove .txt
71            $id = str_replace('/', ':', substr($path, strlen($datadir), -4));
72            $pages[] = $id;
73        }
74
75        return $pages;
76    }
77
78    protected function updatePage()
79    {
80        $res = $this->sqlite()->query('SELECT * FROM maintainer');
81        $assignments = $this->sqlite()->res2arr($res);
82
83        $weighted_assigments = [];
84        foreach ($assignments as $assignment) {
85            $ns = $assignment['namespace'];
86            //more general namespaces are overridden by more specific ones.
87            if (substr($ns, -1) == '*') {
88                $weight = substr_count($ns, ':');
89            } else {
90                $weight = PHP_INT_MAX;
91            }
92
93            $assignment['weight'] = $weight;
94            $weighted_assigments[] = $assignment;
95        }
96        array_multisort(array_column($weighted_assigments, 'weight'), $weighted_assigments);
97
98        $approvePages = [];
99        $wikiPages = $this->getPages();
100        foreach ($weighted_assigments as $assignment) {
101            $ns = ltrim($assignment['namespace'], ':');
102            $maintainer = $assignment['maintainer'];
103            if (substr($ns, -2) == '**') {
104                //remove '**'
105                $ns = substr($ns, 0, -2);
106                foreach ($wikiPages as $id) {
107                    if (substr($id, 0, strlen($ns)) == $ns) {
108                        $approvePages[$id] = $maintainer;
109                    }
110                }
111            } elseif (substr($ns, -1) == '*') {
112                //remove '*'
113                $ns = substr($ns, 0, -1);
114                foreach ($wikiPages as $id) {
115                    $noNS = substr($id, strlen($id));
116                    if (strpos($noNS, ':') === FALSE &&
117                        substr($id, 0, strlen($ns)) == $ns) {
118                        $approvePages[$id] = $maintainer;
119                    }
120                }
121            } else {
122                $approvePages[$ns] = $maintainer;
123            }
124        }
125
126        //clean current settings
127        $this->sqlite()->query('DELETE FROM page');
128        $no_apr_namespace = $this->helper()->no_apr_namespace();
129        foreach ($approvePages as $id => $maintainer) {
130            $in_hidden_namespace = $this->helper()->in_hidden_namespace($id, $no_apr_namespace);
131            $hidden = $in_hidden_namespace ? '1' : '0';
132            if (blank($maintainer)) {
133                $q = 'INSERT INTO page(page,hidden) VALUES (?,?)';
134                $this->sqlite()->query($q, $id, $hidden);
135            } else {
136                $q = 'INSERT INTO page(page,maintainer,hidden) VALUES (?,?,?)';
137                $this->sqlite()->query($q, $id, $maintainer, $hidden);
138            }
139        }
140
141    }
142
143    /**
144     * Should carry out any processing required by the plugin.
145     */
146    public function handle()
147    {
148        global $ID;
149
150        /* @var Input */
151        global $INPUT;
152
153        if($INPUT->str('action') && $INPUT->arr('assignment') && checkSecurityToken()) {
154            $assignment = $INPUT->arr('assignment');
155            //insert empty string as NULL
156            if ($INPUT->str('action') === 'delete') {
157                $this->sqlite()->query('DELETE FROM maintainer WHERE id=?', $assignment['id']);
158                $this->updatePage();
159            } else if ($INPUT->str('action') === 'add' && !blank($assignment['assign'])) {
160                if (blank($assignment['maintainer'])) {
161                    $q = 'INSERT INTO maintainer(namespace) VALUES (?)';
162                    $this->sqlite()->query($q, $assignment['assign']);
163                } else {
164                    $q = 'INSERT INTO maintainer(namespace,maintainer) VALUES (?,?)';
165                    $this->sqlite()->query($q, $assignment['assign'], $assignment['maintainer']);
166                }
167                $this->updatePage();
168            }
169
170            send_redirect(wl($ID, array('do' => 'admin', 'page' => 'approve'), true, '&'));
171        }
172    }
173
174    /**
175     * Render HTML output, e.g. helpful text and a form
176     */
177    public function html()
178    {
179        global $ID;
180        /* @var DokuWiki_Auth_Plugin $auth */
181        global $auth;
182
183        $res = $this->sqlite()->query('SELECT * FROM maintainer');
184        $assignments = $this->sqlite()->res2arr($res);
185
186        echo $this->locale_xhtml('assignments_intro');
187
188        echo '<form action="' . wl($ID) . '" action="post">';
189        echo '<input type="hidden" name="do" value="admin" />';
190        echo '<input type="hidden" name="page" value="approve" />';
191        echo '<input type="hidden" name="sectok" value="' . getSecurityToken() . '" />';
192        echo '<table class="inline">';
193
194        // header
195        echo '<tr>';
196        echo '<th>'.$this->getLang('admin h_assignment_namespace').'</th>';
197        echo '<th>'.$this->getLang('admin h_assignment_maintainer').'</th>';
198        echo '<th></th>';
199        echo '</tr>';
200
201        // existing assignments
202        foreach($assignments as $assignment) {
203            $id = $assignment['id'];
204            $namespace = $assignment['namespace'];
205            $maintainer = $assignment['maintainer'] ? $assignment['maintainer'] : '---';
206
207            $link = wl(
208                $ID, array(
209                    'do' => 'admin',
210                    'page' => 'approve',
211                    'action' => 'delete',
212                    'sectok' => getSecurityToken(),
213                    'assignment[id]' => $id
214                )
215            );
216
217            echo '<tr>';
218            echo '<td>' . hsc($namespace) . '</td>';
219            $user = $auth->getUserData($maintainer);
220            if ($user) {
221                echo '<td>' . hsc($user['name']) . '</td>';
222            } else {
223                echo '<td>' . hsc($maintainer) . '</td>';
224            }
225            echo '<td><a href="' . $link . '">'.$this->getLang('admin btn_delete').'</a></td>';
226            echo '</tr>';
227        }
228
229        // new assignment form
230        echo '<tr>';
231        echo '<td><input type="text" name="assignment[assign]" /></td>';
232        echo '<td>';
233        echo '<select name="assignment[maintainer]">';
234        echo '<option value="">---</option>';
235        foreach($auth->retrieveUsers() as $login => $data) {
236            echo '<option value="' . hsc($login) . '">' . hsc($data['name']) . '</option>';
237        }
238        echo '</select>';
239        echo '</td>';
240        echo '<td><button type="submit" name="action" value="add">'.$this->getLang('admin btn_add').'</button></td>';
241        echo '</tr>';
242
243        echo '</table>';
244    }
245}
246
247// vim:ts=4:sw=4:et:
248