xref: /dokuwiki/inc/actions.php (revision e795ba4d07c9ccc85ddbb61f86a36d83829ccf8f)
1<?php
2/**
3 * DokuWiki Actions
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     Andreas Gohr <andi@splitbrain.org>
7 */
8
9if(!defined('DOKU_INC')) die('meh.');
10
11
12function act_dispatch(){
13    $router = \dokuwiki\ActionRouter::getInstance(); // is this needed here or could we delegate it to tpl_content() later?
14
15    $headers = array('Content-Type: text/html; charset=utf-8');
16    trigger_event('ACTION_HEADERS_SEND',$headers,'act_sendheaders');
17
18    // clear internal variables
19    unset($router);
20    unset($headers);
21    // make all globals available to the template
22    extract($GLOBALS);
23
24    include(template('main.php'));
25    // output for the commands is now handled in inc/templates.php
26    // in function tpl_content()
27}
28
29/**
30 * Send the given headers using header()
31 *
32 * @param array $headers The headers that shall be sent
33 */
34function act_sendheaders($headers) {
35    foreach ($headers as $hdr) header($hdr);
36}
37
38/**
39 * Sanitize the action command
40 *
41 * @author Andreas Gohr <andi@splitbrain.org>
42 *
43 * @param array|string $act
44 * @return string
45 */
46function act_clean($act){
47    // check if the action was given as array key
48    if(is_array($act)){
49        list($act) = array_keys($act);
50    }
51
52    //remove all bad chars
53    $act = strtolower($act);
54    $act = preg_replace('/[^1-9a-z_]+/','',$act);
55
56    if($act == 'export_html') $act = 'export_xhtml';
57    if($act == 'export_htmlbody') $act = 'export_xhtmlbody';
58
59    if($act === '') $act = 'show';
60    return $act;
61}
62
63
64/**
65 * Handle 'draftdel'
66 *
67 * Deletes the draft for the current page and user
68 *
69 * @param string $act action command
70 * @return string action command
71 */
72function act_draftdel($act){
73    global $INFO;
74    @unlink($INFO['draft']);
75    $INFO['draft'] = null;
76    return 'show';
77}
78
79/**
80 * Saves a draft on preview
81 *
82 * @todo this currently duplicates code from ajax.php :-/
83 *
84 * @param string $act action command
85 * @return string action command
86 */
87function act_draftsave($act){
88    global $INFO;
89    global $ID;
90    global $INPUT;
91    global $conf;
92    if($conf['usedraft'] && $INPUT->post->has('wikitext')) {
93        $draft = array('id'     => $ID,
94                'prefix' => substr($INPUT->post->str('prefix'), 0, -1),
95                'text'   => $INPUT->post->str('wikitext'),
96                'suffix' => $INPUT->post->str('suffix'),
97                'date'   => $INPUT->post->int('date'),
98                'client' => $INFO['client'],
99                );
100        $cname = getCacheName($draft['client'].$ID,'.draft');
101        if(io_saveFile($cname,serialize($draft))){
102            $INFO['draft'] = $cname;
103        }
104    }
105    return $act;
106}
107
108
109
110/**
111 * Do a redirect after receiving post data
112 *
113 * Tries to add the section id as hash mark after section editing
114 *
115 * @param string $id page id
116 * @param string $preact action command before redirect
117 */
118function act_redirect($id,$preact){
119    global $PRE;
120    global $TEXT;
121
122    $opts = array(
123            'id'       => $id,
124            'preact'   => $preact
125            );
126    //get section name when coming from section edit
127    if($PRE && preg_match('/^\s*==+([^=\n]+)/',$TEXT,$match)){
128        $check = false; //Byref
129        $opts['fragment'] = sectionID($match[0], $check);
130    }
131
132    trigger_event('ACTION_SHOW_REDIRECT',$opts,'act_redirect_execute');
133}
134
135/**
136 * Execute the redirect
137 *
138 * @param array $opts id and fragment for the redirect and the preact
139 */
140function act_redirect_execute($opts){
141    $go = wl($opts['id'],'',true);
142    if(isset($opts['fragment'])) $go .= '#'.$opts['fragment'];
143
144    //show it
145    send_redirect($go);
146}
147
148/**
149 * Validate POST data
150 *
151 * Validates POST data for a subscribe or unsubscribe request. This is the
152 * default action for the event ACTION_HANDLE_SUBSCRIBE.
153 *
154 * @author Adrian Lang <lang@cosmocode.de>
155 *
156 * @param array &$params the parameters: target, style and action
157 * @throws Exception
158 */
159function subscription_handle_post(&$params) {
160    global $INFO;
161    global $lang;
162    /* @var Input $INPUT */
163    global $INPUT;
164
165    // Get and validate parameters.
166    if (!isset($params['target'])) {
167        throw new Exception('no subscription target given');
168    }
169    $target = $params['target'];
170    $valid_styles = array('every', 'digest');
171    if (substr($target, -1, 1) === ':') {
172        // Allow “list” subscribe style since the target is a namespace.
173        $valid_styles[] = 'list';
174    }
175    $style  = valid_input_set('style', $valid_styles, $params,
176                              'invalid subscription style given');
177    $action = valid_input_set('action', array('subscribe', 'unsubscribe'),
178                              $params, 'invalid subscription action given');
179
180    // Check other conditions.
181    if ($action === 'subscribe') {
182        if ($INFO['userinfo']['mail'] === '') {
183            throw new Exception($lang['subscr_subscribe_noaddress']);
184        }
185    } elseif ($action === 'unsubscribe') {
186        $is = false;
187        foreach($INFO['subscribed'] as $subscr) {
188            if ($subscr['target'] === $target) {
189                $is = true;
190            }
191        }
192        if ($is === false) {
193            throw new Exception(sprintf($lang['subscr_not_subscribed'],
194                                        $INPUT->server->str('REMOTE_USER'),
195                                        prettyprint_id($target)));
196        }
197        // subscription_set deletes a subscription if style = null.
198        $style = null;
199    }
200
201    $params = compact('target', 'style', 'action');
202}
203
204//Setup VIM: ex: et ts=2 :
205