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