xref: /dokuwiki/inc/actions.php (revision e08860f378b1f7c64b7a3b664d7ba33bb894684e)
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
9  if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
10  require_once(DOKU_INC.'inc/template.php');
11
12
13/**
14 * Call the needed action handlers
15 *
16 * @author Andreas Gohr <andi@splitbrain.org>
17 */
18function act_dispatch(){
19  global $INFO;
20  global $ACT;
21  global $ID;
22  global $QUERY;
23  global $lang;
24  global $conf;
25
26  //sanitize $ACT
27  $ACT = act_clean($ACT);
28
29  //check if searchword was given - else just show
30  $s = cleanID($QUERY);
31  if($ACT == 'search' && empty($s)){
32    $ACT = 'show';
33  }
34
35  //login stuff
36  if(in_array($ACT,array('login','logout')))
37    $ACT = act_auth($ACT);
38
39  //check if user is asking to (un)subscribe a page
40  if($ACT == 'subscribe' || $ACT == 'unsubscribe')
41    $ACT = act_subscription($ACT);
42
43  //check permissions
44  $ACT = act_permcheck($ACT);
45
46  //register
47  if($ACT == 'register' && register()){
48    $ACT = 'login';
49  }
50
51  if ($ACT == 'resendpwd' && act_resendpwd()) {
52    $ACT = 'login';
53  }
54
55  //update user profile
56  if (($ACT == 'profile') && updateprofile()) {
57    msg($lang['profchanged'],1);
58    $ACT = 'show';
59  }
60
61  //save
62  if($ACT == 'save')
63    $ACT = act_save($ACT);
64
65  //edit
66  if(($ACT == 'edit' || $ACT == 'preview') && $INFO['editable']){
67    $ACT = act_edit($ACT);
68  }else{
69    unlock($ID); //try to unlock
70  }
71
72  //handle export
73  if(substr($ACT,0,7) == 'export_')
74    $ACT = act_export($ACT);
75
76  //display some infos
77  if($ACT == 'check'){
78    check();
79    $ACT = 'show';
80  }
81
82  //handle admin tasks
83  if($ACT == 'admin'){
84    // retrieve admin plugin name from $_REQUEST['page']
85    if ($_REQUEST['page']) {
86        $pluginlist = plugin_list('admin');
87        if (in_array($_REQUEST['page'], $pluginlist)) {
88          // attempt to load the plugin
89          if ($plugin =& plugin_load('admin',$_REQUEST['page']) !== NULL)
90              $plugin->handle();
91        }
92    }
93/*
94        if($_REQUEST['page'] == 'acl'){
95            require_once(DOKU_INC.'inc/admin_acl.php');
96            admin_acl_handler();
97    }
98*/
99  }
100
101  //call template FIXME: all needed vars available?
102  header('Content-Type: text/html; charset=utf-8');
103  include(template('main.php'));
104  // output for the commands is now handled in inc/templates.php
105  // in function tpl_content()
106}
107
108/**
109 * Sanitize the action command
110 *
111 * Add all allowed commands here.
112 *
113 * @author Andreas Gohr <andi@splitbrain.org>
114 */
115function act_clean($act){
116  global $lang;
117  global $conf;
118
119  //handle localized buttons
120  if($act == $lang['btn_save']) $act = 'save';
121  if($act == $lang['btn_preview']) $act = 'preview';
122  if($act == $lang['btn_cancel']) $act = 'show';
123
124  //remove all bad chars
125  $act = strtolower($act);
126  $act = preg_replace('/[^a-z_]+/','',$act);
127
128  if($act == 'export_html') $act = 'export_xhtml';
129  if($act == 'export_htmlbody') $act = 'export_xhtmlbody';
130
131  //disable all acl related commands if ACL is disabled
132  if(!$conf['useacl'] && in_array($act,array('login','logout','register','admin',
133                                             'subscribe','unsubscribe','profile',
134                                             'resendpwd',))){
135    msg('Command unavailable: '.htmlspecialchars($act),-1);
136    return 'show';
137  }
138
139  if(array_search($act,array('login','logout','register','save','edit',
140                             'preview','search','show','check','index','revisions',
141                             'diff','recent','backlink','admin','subscribe',
142                             'unsubscribe','profile','resendpwd',)) === false
143     && substr($act,0,7) != 'export_' ) {
144    msg('Unknown command: '.htmlspecialchars($act),-1);
145    return 'show';
146  }
147  return $act;
148}
149
150/**
151 * Run permissionchecks
152 *
153 * @author Andreas Gohr <andi@splitbrain.org>
154 */
155function act_permcheck($act){
156  global $INFO;
157  global $conf;
158
159  if(in_array($act,array('save','preview','edit'))){
160    if($INFO['exists']){
161      if($act == 'edit'){
162        //the edit function will check again and do a source show
163        //when no AUTH_EDIT available
164        $permneed = AUTH_READ;
165      }else{
166        $permneed = AUTH_EDIT;
167      }
168    }else{
169      $permneed = AUTH_CREATE;
170    }
171  }elseif(in_array($act,array('login','search','recent','profile'))){
172    $permneed = AUTH_NONE;
173  }elseif($act == 'register'){
174    if ($conf['openregister']){
175      $permneed = AUTH_NONE;
176    }else{
177      $permneed = AUTH_ADMIN;
178    }
179  }elseif($act == 'admin'){
180    $permneed = AUTH_ADMIN;
181  }else{
182    $permneed = AUTH_READ;
183  }
184  if($INFO['perm'] >= $permneed) return $act;
185
186  return 'denied';
187}
188
189/**
190 * Handle 'save'
191 *
192 * Checks for spam and conflicts and saves the page.
193 * Does a redirect to show the page afterwards or
194 * returns a new action.
195 *
196 * @author Andreas Gohr <andi@splitbrain.org>
197 */
198function act_save($act){
199  global $ID;
200  global $DATE;
201  global $PRE;
202  global $TEXT;
203  global $SUF;
204  global $SUM;
205
206  //spam check
207  if(checkwordblock())
208    return 'wordblock';
209  //conflict check //FIXME use INFO
210  if($DATE != 0 && @filemtime(wikiFN($ID)) > $DATE )
211    return 'conflict';
212
213  //save it
214  saveWikiText($ID,con($PRE,$TEXT,$SUF,1),$SUM,$_REQUEST['minor']); //use pretty mode for con
215  //unlock it
216  unlock($ID);
217
218  //show it
219  session_write_close();
220  header("Location: ".wl($ID,'',true));
221  exit();
222}
223
224/**
225 * Handle 'login', 'logout'
226 *
227 * @author Andreas Gohr <andi@splitbrain.org>
228 */
229function act_auth($act){
230  global $ID;
231  global $INFO;
232
233  //already logged in?
234  if($_SERVER['REMOTE_USER'] && $act=='login')
235    return 'show';
236
237  //handle logout
238  if($act=='logout'){
239    $lockedby = checklock($ID); //page still locked?
240    if($lockedby == $_SERVER['REMOTE_USER'])
241      unlock($ID); //try to unlock
242
243    // do the logout stuff
244    auth_logoff();
245
246    // rebuild info array
247    $INFO = pageinfo();
248
249    return 'login';
250  }
251
252  return $act;
253}
254
255/**
256 * Handle 'edit', 'preview'
257 *
258 * @author Andreas Gohr <andi@splitbrain.org>
259 */
260function act_edit($act){
261  global $ID;
262
263  //check if locked by anyone - if not lock for my self
264  $lockedby = checklock($ID);
265  if($lockedby) return 'locked';
266
267  lock($ID);
268  return $act;
269}
270
271/**
272 * Handle 'edit', 'preview'
273 *
274 * @author Andreas Gohr <andi@splitbrain.org>
275 */
276function act_export($act){
277  global $ID;
278  global $REV;
279
280  // no renderer for this
281  if($act == 'export_raw'){
282    header('Content-Type: text/plain; charset=utf-8');
283    print rawWiki($ID,$REV);
284    exit;
285  }
286
287  // html export #FIXME what about the template's style?
288  if($act == 'export_xhtml'){
289    global $conf;
290    global $lang;
291    header('Content-Type: text/html; charset=utf-8');
292    ptln('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"');
293    ptln(' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">');
294    ptln('<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="'.$conf['lang'].'"');
295    ptln(' lang="'.$conf['lang'].'" dir="'.$lang['direction'].'">');
296    ptln('<head>');
297    ptln('  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />');
298    ptln('  <title>'.$ID.'</title>');
299    tpl_metaheaders();
300    ptln('</head>');
301    ptln('<body>');
302    ptln('<div class="dokuwiki export">');
303    print p_wiki_xhtml($ID,$REV,false);
304    ptln('</div>');
305    ptln('</body>');
306    ptln('</html>');
307    exit;
308  }
309
310  // html body only
311  if($act == 'export_xhtmlbody'){
312    print p_wiki_xhtml($ID,$REV,false);
313    exit;
314  }
315
316  // try to run renderer #FIXME use cached instructions
317  $mode = substr($act,7);
318  $text = p_render($mode,p_get_instructions(rawWiki($ID,$REV)),$info);
319  if(!is_null($text)){
320    print $text;
321    exit;
322  }
323
324
325
326  return 'show';
327}
328
329/**
330 * Handle 'subscribe', 'unsubscribe'
331 *
332 * @author Steven Danz <steven-danz@kc.rr.com>
333 * @todo   localize
334 */
335function act_subscription($act){
336  global $ID;
337  global $INFO;
338  global $lang;
339
340  $file=metaFN($ID,'.mlist');
341  if ($act=='subscribe' && !$INFO['subscribed']){
342    if ($INFO['userinfo']['mail']){
343      if (io_saveFile($file,$_SERVER['REMOTE_USER']."\n",true)) {
344        $INFO['subscribed'] = true;
345        msg(sprintf($lang[$act.'_success'], $INFO['userinfo']['name'], $ID),1);
346      } else {
347        msg(sprintf($lang[$act.'_error'], $INFO['userinfo']['name'], $ID),1);
348      }
349    } else {
350      msg($lang['subscribe_noaddress']);
351    }
352  } elseif ($act=='unsubscribe' && $INFO['subscribed']){
353    if (io_deleteFromFile($file,$_SERVER['REMOTE_USER']."\n")) {
354      $INFO['subscribed'] = false;
355      msg(sprintf($lang[$act.'_success'], $INFO['userinfo']['name'], $ID),1);
356    } else {
357      msg(sprintf($lang[$act.'_error'], $INFO['userinfo']['name'], $ID),1);
358    }
359  }
360
361  return 'show';
362}
363
364//Setup VIM: ex: et ts=2 enc=utf-8 :
365