1<?php
2/**
3* projects Action Plugin: hijack the ACTION_ACT_PREPROCESS events for admin action
4*
5* @author     Junling Ma <junlingm@gmail.com>
6*/
7
8require_once(dirname(__FILE__).'/../lib/project.php');
9require_once DOKU_PLUGIN.'action.php';
10
11class action_plugin_projects_action extends DokuWiki_Action_Plugin {
12
13    function getInfo(){
14    return array(
15        'author' => 'Junling Ma',
16        'email'  => 'junlingm@gmail.com',
17        'date'   => '2010-12-15',
18        'name'   => 'Projects',
19        'desc'   => 'hijack page write events',
20        'url'    => 'http://www.math.uvic.ca/~jma'
21        );
22    }
23
24    /**
25    * Register its handlers with the DokuWiki's event controller
26    */
27    function register(&$controller) {
28        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this,
29                'filter');
30        $controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this,
31                'render');
32    }
33
34    private function wikitext($type) {
35        $crosslink = "";
36        switch ($type) {
37            case SOURCE:
38                $content = '<' . CONTENT_TAG . '></' . CONTENT_TAG . '>';
39                break;
40            case TARGET:
41                $content = '<' . RECIPE_TAG . '></' . RECIPE_TAG . '>';
42                break;
43            case CROSSLINK:
44                $content = "";
45                $crosslink = " linkto=\"\"";
46                break;
47            default:
48                return NULL;
49        }
50        $tag = "<project-file type=\"$type\"$crosslink/>\n";
51        return $tag . $content;
52    }
53
54    /**
55    * render the manage_files action
56    *
57    */
58    function render(&$event, $param) {
59        global $ID;
60        $perm = auth_quickaclcheck($ID);
61        if ($event->data != 'manage_files') return;
62        $event->preventDefault();
63        if ($perm < AUTH_READ) {
64            echo '<h1>Error</h1><p>You do not have permission to view this page</p>';
65            return;
66        }
67        $project = Project::project();
68        if ($project == NULL) {
69            echo '<h1>Error</h1>';
70            $project = getNS($ID);
71            $path = explode(":", $project);
72            if (!$project || $path[0] != PROJECTS_NAMESPACE) {
73                echo "<p>Projects wiki has to work under the " . PROJECTS_NAMESPACE
74                    . " namespace</p>";
75                return;
76            }
77            $parent = getNS($project);
78            if (!$parent) {
79                echo "<p>The namespace " . PROJECTS_NAMESPACE .
80                    " has not been created yet!</p>";
81                return;
82            }
83            echo "<p>This project does not exist!</p>";
84            $name = noNS($parent);
85            $link = DOKU_URL . "/doku.php?id=$parent:$name&do=manage_files";
86            echo "<p>Go back to <a href=\"$link\">$parent</a>";
87            return;
88        }
89        echo '<h1>Manage Project ' . $project->name() . '</h1>';
90        $files = $project->files();
91    ksort($files);
92    echo "<h1>Manage Files</h1>";
93    echo "<table>";
94        foreach (array(SOURCE, TARGET, CROSSLINK) as $type) {
95            $count = 0;
96            $utype =ucfirst($type);
97            echo "<tr><td></td><td></td><td><h2>$utype Files</h2></td></tr>";
98        foreach ($files as $file) {
99            if ($file->type() != $type) continue;
100            echo "<tr>";
101                $name = $file->name();
102                echo "<td>";
103                if ($file->is_target() && $perm > AUTH_READ)
104                echo button_remake($project->id($name));
105                echo "</td>";
106                echo "<td>";
107                if ($perm >= AUTH_DELETE)
108                    echo button_delete($project->id($name));
109                echo "</td>";
110            echo "<td>";
111			echo html_wikilink($project->id($name));
112			if ($project->error($name) != NULL)
113                echo "<img src=\"" . DOKU_URL . "/lib/images/error.png\"></img>";
114                echo "</td>";
115            echo "</tr>";
116            $count++;
117        }
118        if ($count == 0)
119                echo "<tr><td></td><td></td><td>No $type files in this project</td></tr>";
120        }
121        $files = $project->subprojects();
122        if ($files) {
123            sort($files);
124            echo "<tr><td></td><td></td><td><h2>Subprojects</h2></td></tr>";
125            foreach ($files as $file) {
126                $id = $project->name() . ":$file";
127                $link = DOKU_URL . "/doku.php?id=$id:$file&do=manage_files";
128                echo "<tr><td></td><td></td><td>";
129                echo "<a href=\"$link\">$file</a>";
130                echo "</td>";
131                echo "</tr>";
132            }
133        }
134        echo "</table>";
135
136        $parent = $project->parent();
137        if ($parent != NULL) {
138            echo "<h1>Parent project</h1>";
139            $name = $parent->name();
140            $file = end(explode(":", $name));
141            $link = DOKU_URL . "/doku.php?id=$name:$file&do=manage_files";
142            echo "<a href=\"$link\">$name</a>";
143        }
144
145        if ($perm <= AUTH_READ) return;
146
147    echo "<p/><h1>Create Files</h1>";
148    $create = new Doku_Form("Create");
149
150    $create->addHidden("do", "create");
151    $create->addHidden("page", "projects_manage_files");
152    $create->addHidden("id", $ID);
153
154        $create->startFieldSet('Create a new file');
155    $create->addElement(form_makeOpenTag("p"));
156    $create->addElement(form_makeField('text', 'File name'));
157    $create->addElement(form_makeCloseTag("p"));
158
159    $create->addElement(form_makeOpenTag("p"));
160    $create->addElement(form_makeRadioField('Type', SOURCE, "Source", "", "", array('checked' => "true")));
161    $create->addElement(form_makeRadioField('Type', TARGET, 'Generated'));
162    $create->addElement(form_makeRadioField('Type', CROSSLINK, 'Crosslink'));
163    $create->addElement(form_makeCloseTag("p"));
164
165    $create->addElement(form_makeButton("submit", '', "Create"));
166    $create->endFieldSet();
167    echo $create->getForm();
168
169        echo "<h1>Create subproject</h1>";
170        $subproject = new Doku_Form("Subproject");
171
172        $subproject->addHidden("do", "create_subproject");
173        $subproject->addHidden("page", "projects_manage_files");
174        $subproject->addHidden("id", $ID);
175        $subproject->startFieldSet('Create a new subproject');
176        $subproject->addElement(form_makeOpenTag("p"));
177        $subproject->addElement(form_makeField('text', 'Project name'));
178        $subproject->addElement(form_makeCloseTag("p"));
179
180        $subproject->addElement(form_makeButton("submit", '', "Create sub-project"));
181        $subproject->endFieldSet();
182        echo $subproject->getForm();
183
184        echo "<h1>Clean up</h1>";
185    $clean = new Doku_Form("Clean");
186    $clean->addHidden("do", "clean");
187    $clean->addHidden("page", "projects_manage_files");
188    $clean->addHidden("id", $ID);
189        $clean->startFieldSet('Clean the project');
190    $clean->addElement(form_makeCheckboxField("Recursive"));
191    $clean->addElement(form_makeButton("submit", "", "Clean"));
192    $clean->endFieldSet();
193    echo $clean->getForm();
194
195    if ($perm < AUTH_ADMIN) return;
196
197    echo "<h1>Rebuild the project</h1>";
198    $rebuild = new Doku_Form("rebuild");
199    $rebuild->addHidden("do", "rebuild");
200    $rebuild->addHidden("page", "projects_manage_files");
201    $rebuild->addHidden("id", $ID);
202        $rebuild->startFieldSet('Rebuild the project');
203    $rebuild->addElement(form_makeButton("submit", '', "Rebuild"));
204    $rebuild->endFieldSet();
205    echo $rebuild->getForm();
206    }
207
208    /**
209    * an action has been called
210    *
211    */
212    function filter(&$event, $param) {
213        global $ACT;
214        global $ID;
215        global $TEXT;
216        global $PRE;
217        $perm = auth_quickaclcheck($ID);
218        if ($event->data == 'manage_files') {
219            $event->preventDefault();
220            return;
221        }
222        $project = Project::project();
223        if ($project == NULL) return;
224        switch ($event->data) {
225            case 'change_use' :
226                if ($perm <= AUTH_READ) {
227                    msg('You do not have permission to change this file', -1);
228                    $event->data = 'show';
229                }
230                else {
231                    $range = $_REQUEST['range'];
232                    $name = $_REQUEST['use'];
233                    $slices = rawWikiSlices($range, $ID);
234                    $TEXT = $slices[0] . '<use name="' . $name . '"/>' . $slices[2];
235                }
236                $event->data = 'save';
237                break;
238            case 'create' :
239                if ($perm < AUTH_CREATE) {
240                    msg('You do not have permission to create a file', -1);
241                    if ($perm < AUTH_READ) {
242                        $event->data = 'show';
243                        break;
244                    }
245                    $event->data = 'manage_files';
246                    $event->preventDefault();
247                    break;
248                }
249                $text = $this->wikitext($_REQUEST['Type']);
250                $name = $_REQUEST['File_name'];
251                $ID = $project->name() . ':' . $name;
252                if ($text == NULL) return;
253                $TEXT = $text;
254                $event->data = 'save';
255                break;
256            case 'remake' :
257                if ($perm <= AUTH_READ) {
258                    msg('You do not have permission to change this file', -1);
259                    if ($perm < AUTH_READ) {
260                        $event->data = 'show';
261                        break;
262                    }
263                    $event->data = 'manage_files';
264                    $event->preventDefault();
265                }
266                else {
267                    set_media_file_revision_limit($this->getConf('media file revision limit'));
268                    global $ID;
269                    $id = $_REQUEST['id'];
270                    if (getNS($name)) $ID = $id;
271                    $id = noNS($id);
272                    $project->remake(array($id));
273                    $ID = $project->id($id);
274                    $event->data = 'show';
275                }
276                $event->preventDefault();
277                break;
278            case "create_subproject" :
279                if ($perm < AUTH_CREATE) {
280                    msg('You do not have permission to create a subproject');
281                    if ($perm < AUTH_READ) {
282                        $event->data = 'show';
283                        break;
284                    }
285                }
286                else {
287                    $name = $_REQUEST['Project_name'];
288                    $project = Project::project($project->name() .':' . $name, true);
289                    $ID = $project->name() . ':' . $name . ':manage_files';
290                }
291                $event->data = 'manage_files';
292                $event->preventDefault();
293                break;
294            case 'clean' :
295                if ($perm <= AUTH_READ) {
296                    msg('You do not have permission to clean this project', -1);
297                    if ($perm < AUTH_READ) {
298                        $event->data = 'show';
299                        break;
300                    }
301                }
302                else {
303                    $recursive = $_REQUEST['Recursive'];
304                    if (!$project->clean($recursive))
305                        msg('Other users are updating the project. Please clean later.');
306                }
307                $event->data = 'manage_files';
308                $event->preventDefault();
309                break;
310            case 'rebuild' :
311                $event->preventDefault();
312                if ($perm <= AUTH_READ) {
313                    msg('You do not have permission to rebuild this project', -1);
314                    if ($perm < AUTH_READ) {
315                        $event->data = 'show';
316                        break;
317                    }
318                }
319                else {
320                    if ($project == NULL)
321                        $project = Project::project(NULL, true);
322                    if (!$project->rebuild())
323                        msg('Other users are updating the project. Please rebuild later.');
324                }
325                $event->data = 'manage_files';
326                $event->preventDefault();
327                break;
328            case 'media' :
329                $file_id = $_REQUEST['image'];
330                if (!$file_id) return;
331                $project = Project::project(getNS($file_id));
332                if ($project === NULL) return;
333                $file = $project->path() . noNS($file_id);
334                if (file_exists($file)) {
335                    $event->preventDefault();
336                    send_redirect(ml($file_id));
337                    break;
338                }
339                return;
340            case 'remove_tag' :
341                $tag = $_REQUEST['tag'];
342                if ($perm < AUTH_EDIT) {
343                    msg("You do not have permission to edit this file", -1);
344                    $event->data = 'show';
345                    $event->preventDefault();
346                    break;
347                }
348                $range = $_REQUEST['range'];
349                $slices = rawWikiSlices($range, $ID);
350                if (substr(strtoupper($slices[1]), 0, strlen($tag)+1)
351                    != '<' . strtoupper($tag)) {
352                    msg("Missing the $tag tag?", -1);
353                    $event->data = 'show';
354                    $event->preventDefault();
355                    break;
356                }
357                $text = $slices[0] .$slices[2];
358                saveWikiText($ID, $slices[0] . $slices[2], "Remove $tag", FALSE);
359                $event->data = 'show';
360                break;
361            case 'add_tag' :
362                if ($perm < AUTH_EDIT) {
363                    msg("You do not have permission to edit this file", -1);
364                    $event->data = 'show';
365                    $event->preventDefault();
366                    break;
367                }
368                $tag = $_REQUEST['tag'];
369                if (isset($_REQUEST['name'])) {
370                    $name = $_REQUEST['name'];
371                    $name = "name=\"$name\"";
372                }
373                else $name = '';
374                $text = rawWiki($ID) . "<$tag $name";
375                if (strtoupper($tag) == 'USE')
376                    $text .= '/>';
377                else $text = "></$tag>";
378                saveWikiText($ID, $text, "Add $tag", FALSE);
379                $event->data = 'show';
380                break;
381            default:
382                return;
383        }
384        $ACT = $event->data;
385    }
386
387}
388
389?>