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