1<?php
2/**
3 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
4 * @author     Esther Brunner <wikidesign@gmail.com>
5 */
6
7class action_plugin_task extends DokuWiki_Action_Plugin {
8
9    /**
10     * register the eventhandlers
11     */
12    function register(Doku_Event_Handler $contr) {
13        $contr->register_hook('ACTION_ACT_PREPROCESS',
14                            'BEFORE',
15                            $this,
16                            'handle_act_preprocess',
17                            array());
18    }
19
20    /**
21     * Checks if 'newentry' was given as action, if so we
22     * do handle the event our self and no further checking takes place
23     */
24    function handle_act_preprocess(&$event, $param) {
25        if ($event->data != 'newtask' && $event->data != 'changetask') return;
26
27        // we can handle it -> prevent others
28        $event->stopPropagation();
29
30        switch($event->data) {
31            case 'newtask':
32                $event->data = $this->_newTask();
33                break;
34            case 'changetask':
35                $event->data = $this->_changeTask();
36                break;
37        }
38    }
39
40    /**
41     * Creates a new task page
42     */
43    function _newTask() {
44        global $ID;
45        global $INFO;
46
47        $ns    = cleanID($_REQUEST['ns']);
48        $title = str_replace(':', '', $_REQUEST['title']);
49        $back  = $ID;
50        $ID    = ($ns ? $ns.':' : '').cleanID($title);
51        $INFO  = pageinfo();
52
53        // check if we are allowed to create this file
54        if ($INFO['perm'] >= AUTH_CREATE) {
55
56            //check if locked by anyone - if not lock for my self
57            if ($INFO['locked']) {
58                return 'locked';
59            } else {
60                lock($ID);
61            }
62
63            // prepare the new thread file with default stuff
64            if (!@file_exists($INFO['filepath'])) {
65                global $TEXT;
66
67                $user     = $_REQUEST['user'];
68                $date     = $_REQUEST['date'];
69                $priority = $_REQUEST['priority'];
70
71                // create wiki page
72                $data = array(
73                        'id'       => $ID,
74                        'ns'       => $ns,
75                        'title'    => $title,
76                        'back'     => $back,
77                        'priority' => $priority,
78                        'user'     => $user,
79                        'date'     => $date,
80                        );
81
82                $TEXT = $this->_pageTemplate($data);
83                return 'preview';
84            } else {
85                return 'edit';
86            }
87        } else {
88            return 'show';
89        }
90    }
91
92    /**
93     * Adapted version of pageTemplate() function
94     */
95    function _pageTemplate($data) {
96        global $INFO;
97
98        $id   = $data['id'];
99        $tpl  = io_readFile(DOKU_PLUGIN.'task/_template.txt');
100
101        // standard replacements
102        $replace = array(
103                '@ID@'   => $id,
104                '@NS@'   => $data['ns'],
105                '@PAGE@' => strtr(noNS($id),'_',' '),
106                '@USER@' => $data['user'],
107                '@NAME@' => $INFO['userinfo']['name'],
108                '@MAIL@' => $INFO['userinfo']['mail'],
109                '@DATE@' => $data['date'],
110                );
111
112        // additional replacements
113        $replace['@BACK@']     = $data['back'];
114        $replace['@TITLE@']    = $data['title'];
115        $replace['@PRIORITY@'] = $data['priority'];
116
117        // tag if tag plugin is available
118        if ((@file_exists(DOKU_PLUGIN.'tag/syntax/tag.php')) && (!plugin_isdisabled('tag'))) {
119            $replace['@TAG@'] = "\n\n{{tag>}}";
120        } else {
121            $replace['@TAG@'] = '';
122        }
123
124        // discussion if discussion plugin is available
125        if ((@file_exists(DOKU_PLUGIN.'discussion/syntax/comments.php')) && (!plugin_isdisabled('discussion'))) {
126            $replace['@DISCUSSION@'] = "~~DISCUSSION~~";
127        } else {
128            $replace['@DISCUSSION@'] = '';
129        }
130
131        // do the replace
132        $tpl = str_replace(array_keys($replace), array_values($replace), $tpl);
133        return $tpl;
134    }
135
136    /**
137     * Changes the status of a task
138     */
139    function _changeTask() {
140        global $ID;
141        global $INFO;
142
143        $status = $_REQUEST['status'];
144        $status = trim($status);
145        if (!is_numeric($status) || ($status < -1) || ($status > 4)) {
146            if ($this->getConf('show_error_msg')) {
147                $message = $this->getLang('msg_rcvd_invalid_status');
148                $message = str_replace('%status%', $status, $message);
149                msg($message, -1);
150            }
151            return 'show';
152        }
153
154        // load task data
155        if ($my =& plugin_load('helper', 'task')) {
156            $task = $my->readTask($ID);
157        } else {
158            if ($this->getConf('show_error_msg')) {
159                msg($this->getLang('msg_load_helper_failed'), -1);
160            }
161            return 'show';
162        }
163
164        if ($task['status'] == $status) {
165            // unchanged
166            if ($this->getConf('show_info_msg')) {
167                msg($this->getLang('msg_nothing_changed'));
168            }
169            return 'show';
170        }
171
172        $responsible = $my->_isResponsible($task['user']['name']);
173
174        // some additional checks if change not performed by an admin
175        // FIXME error messages?
176        if ($INFO['perm'] != AUTH_ADMIN) {
177
178            // responsible person can't verify her / his own tasks
179            if ($responsible && ($status == 4)) {
180                if ($this->getConf('show_info_msg')) {
181                    msg ($this->getLang('msg_responsible_no_verify'));
182                }
183                return 'show';
184            }
185
186            // other persons can only accept or verify tasks
187            if (!$responsible && $status != 1 && $status != 4) {
188                if ($this->getConf('show_info_msg')) {
189                    msg ($this->getLang('msg_other_accept_or_verify'));
190                }
191                return 'show';
192            }
193        }
194
195        // assign task to a user
196        if (!$task['user']['name']) {
197            // FIXME error message?
198            if (!$_SERVER['REMOTE_USER']) {
199                // no logged in user
200                if ($this->getConf('show_info_msg')) {
201                    msg($this->getLang('msg_not_logged_in'));
202                }
203                return 'show';
204            }
205
206            $wiki = rawWiki($ID);
207            $summary = $this->getLang('mail_changedtask').': '.$this->getLang('accepted');
208            $new = preg_replace('/~~TASK:?/', '~~TASK:'.$INFO['userinfo']['name'], $wiki);
209
210            if ($new != $wiki) {
211                saveWikiText($ID, $new, $summary, true); // save as minor edit
212            }
213
214            $task['user'] = array(
215                    'id'   => $_SERVER['REMOTE_USER'],
216                    'name' => $INFO['userinfo']['name'],
217                    'mail' => $INFO['userinfo']['mail'],
218                    );
219        }
220
221        // save .task meta file and clear xhtml cache
222        $oldstatus = $task['status'];
223        $task['status'] = $status;
224        $my->writeTask($ID, $task);
225        $_REQUEST['purge'] = true;
226
227        if ($this->getConf('show_success_msg')) {
228            $message = $this->getLang('msg_status_changed');
229            $message = str_replace('%status%', $my->statusLabel($status), $message);
230            $message = str_replace('%oldstatus%', $my->statusLabel($oldstatus), $message);
231            msg($message, 1);
232        }
233
234        return 'show';
235    }
236}
237// vim:ts=4:sw=4:et:enc=utf-8:
238