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 //draft deletion 66 if($ACT == 'draftdel') 67 $ACT = act_draftdel($ACT); 68 69 //draft saving on preview 70 if($ACT == 'preview') 71 $ACT = act_draftsave($ACT); 72 73 //edit 74 if(($ACT == 'edit' || $ACT == 'preview') && $INFO['editable']){ 75 $ACT = act_edit($ACT); 76 }else{ 77 unlock($ID); //try to unlock 78 } 79 80 //handle export 81 if(substr($ACT,0,7) == 'export_') 82 $ACT = act_export($ACT); 83 84 //display some infos 85 if($ACT == 'check'){ 86 check(); 87 $ACT = 'show'; 88 } 89 90 //handle admin tasks 91 if($ACT == 'admin'){ 92 // retrieve admin plugin name from $_REQUEST['page'] 93 if ($_REQUEST['page']) { 94 $pluginlist = plugin_list('admin'); 95 if (in_array($_REQUEST['page'], $pluginlist)) { 96 // attempt to load the plugin 97 if ($plugin =& plugin_load('admin',$_REQUEST['page']) !== NULL) 98 $plugin->handle(); 99 } 100 } 101/* 102 if($_REQUEST['page'] == 'acl'){ 103 require_once(DOKU_INC.'inc/admin_acl.php'); 104 admin_acl_handler(); 105 } 106*/ 107 } 108 109 //call template FIXME: all needed vars available? 110 header('Content-Type: text/html; charset=utf-8'); 111 include(template('main.php')); 112 // output for the commands is now handled in inc/templates.php 113 // in function tpl_content() 114} 115 116/** 117 * Sanitize the action command 118 * 119 * Add all allowed commands here. 120 * 121 * @author Andreas Gohr <andi@splitbrain.org> 122 */ 123function act_clean($act){ 124 global $lang; 125 global $conf; 126 127 // check if the action was given as array key 128 if(is_array($act)){ 129 list($act) = array_keys($act); 130 } 131 132 //handle localized buttons 133 if($act == $lang['btn_save']) $act = 'save'; 134 if($act == $lang['btn_preview']) $act = 'preview'; 135 if($act == $lang['btn_cancel']) $act = 'show'; 136 if($act == $lang['btn_recover']) $act = 'recover'; 137 if($act == $lang['btn_draftdel']) $act = 'draftdel'; 138 139 140 //remove all bad chars 141 $act = strtolower($act); 142 $act = preg_replace('/[^a-z_]+/','',$act); 143 144 if($act == 'export_html') $act = 'export_xhtml'; 145 if($act == 'export_htmlbody') $act = 'export_xhtmlbody'; 146 147 //disable all acl related commands if ACL is disabled 148 if(!$conf['useacl'] && in_array($act,array('login','logout','register','admin', 149 'subscribe','unsubscribe','profile', 150 'resendpwd',))){ 151 msg('Command unavailable: '.htmlspecialchars($act),-1); 152 return 'show'; 153 } 154 155 if(!in_array($act,array('login','logout','register','save','edit','draft', 156 'preview','search','show','check','index','revisions', 157 'diff','recent','backlink','admin','subscribe', 158 'unsubscribe','profile','resendpwd','recover', 159 'draftdel',)) && substr($act,0,7) != 'export_' ) { 160 msg('Command unknown: '.htmlspecialchars($act),-1); 161 return 'show'; 162 } 163 return $act; 164} 165 166/** 167 * Run permissionchecks 168 * 169 * @author Andreas Gohr <andi@splitbrain.org> 170 */ 171function act_permcheck($act){ 172 global $INFO; 173 global $conf; 174 175 if(in_array($act,array('save','preview','edit','recover'))){ 176 if($INFO['exists']){ 177 if($act == 'edit'){ 178 //the edit function will check again and do a source show 179 //when no AUTH_EDIT available 180 $permneed = AUTH_READ; 181 }else{ 182 $permneed = AUTH_EDIT; 183 } 184 }else{ 185 $permneed = AUTH_CREATE; 186 } 187 }elseif(in_array($act,array('login','search','recent','profile'))){ 188 $permneed = AUTH_NONE; 189 }elseif($act == 'register'){ 190 if ($conf['openregister']){ 191 $permneed = AUTH_NONE; 192 }else{ 193 $permneed = AUTH_ADMIN; 194 } 195 }elseif($act == 'admin'){ 196 $permneed = AUTH_ADMIN; 197 }else{ 198 $permneed = AUTH_READ; 199 } 200 if($INFO['perm'] >= $permneed) return $act; 201 202 return 'denied'; 203} 204 205/** 206 * Handle 'draftdel' 207 * 208 * Deletes the draft for the current page and user 209 */ 210function act_draftdel($act){ 211 global $INFO; 212 @unlink($INFO['draft']); 213 $INFO['draft'] = null; 214 return 'show'; 215} 216 217/** 218 * Saves a draft on preview 219 * 220 * @todo this currently duplicates code from ajax.php :-/ 221 */ 222function act_draftsave($act){ 223 global $INFO; 224 global $ID; 225 global $conf; 226 if($conf['usedraft'] && $_POST['wikitext']){ 227 $draft = array('id' => $ID, 228 'prefix' => $_POST['prefix'], 229 'text' => $_POST['wikitext'], 230 'suffix' => $_POST['suffix'], 231 'date' => $_POST['date'], 232 'client' => $INFO['client'], 233 ); 234 $cname = getCacheName($draft['client'].$ID,'.draft'); 235 if(io_saveFile($cname,serialize($draft))){ 236 $INFO['draft'] = $cname; 237 } 238 } 239 return $act; 240} 241 242/** 243 * Handle 'save' 244 * 245 * Checks for spam and conflicts and saves the page. 246 * Does a redirect to show the page afterwards or 247 * returns a new action. 248 * 249 * @author Andreas Gohr <andi@splitbrain.org> 250 */ 251function act_save($act){ 252 global $ID; 253 global $DATE; 254 global $PRE; 255 global $TEXT; 256 global $SUF; 257 global $SUM; 258 259 //spam check 260 if(checkwordblock()) 261 return 'wordblock'; 262 //conflict check //FIXME use INFO 263 if($DATE != 0 && @filemtime(wikiFN($ID)) > $DATE ) 264 return 'conflict'; 265 266 //save it 267 saveWikiText($ID,con($PRE,$TEXT,$SUF,1),$SUM,$_REQUEST['minor']); //use pretty mode for con 268 //unlock it 269 unlock($ID); 270 271 //delete draft 272 act_draftdel($act); 273 274 //show it 275 session_write_close(); 276 header("Location: ".wl($ID,'',true)); 277 exit(); 278} 279 280/** 281 * Handle 'login', 'logout' 282 * 283 * @author Andreas Gohr <andi@splitbrain.org> 284 */ 285function act_auth($act){ 286 global $ID; 287 global $INFO; 288 289 //already logged in? 290 if($_SERVER['REMOTE_USER'] && $act=='login') 291 return 'show'; 292 293 //handle logout 294 if($act=='logout'){ 295 $lockedby = checklock($ID); //page still locked? 296 if($lockedby == $_SERVER['REMOTE_USER']) 297 unlock($ID); //try to unlock 298 299 // do the logout stuff 300 auth_logoff(); 301 302 // rebuild info array 303 $INFO = pageinfo(); 304 305 return 'login'; 306 } 307 308 return $act; 309} 310 311/** 312 * Handle 'edit', 'preview' 313 * 314 * @author Andreas Gohr <andi@splitbrain.org> 315 */ 316function act_edit($act){ 317 global $ID; 318 global $INFO; 319 320 //check if locked by anyone - if not lock for my self 321 $lockedby = checklock($ID); 322 if($lockedby) return 'locked'; 323 324 lock($ID); 325 return $act; 326} 327 328/** 329 * Handle 'edit', 'preview' 330 * 331 * @author Andreas Gohr <andi@splitbrain.org> 332 */ 333function act_export($act){ 334 global $ID; 335 global $REV; 336 337 // no renderer for this 338 if($act == 'export_raw'){ 339 header('Content-Type: text/plain; charset=utf-8'); 340 print rawWiki($ID,$REV); 341 exit; 342 } 343 344 // html export #FIXME what about the template's style? 345 if($act == 'export_xhtml'){ 346 global $conf; 347 global $lang; 348 header('Content-Type: text/html; charset=utf-8'); 349 ptln('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'); 350 ptln(' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'); 351 ptln('<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="'.$conf['lang'].'"'); 352 ptln(' lang="'.$conf['lang'].'" dir="'.$lang['direction'].'">'); 353 ptln('<head>'); 354 ptln(' <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />'); 355 ptln(' <title>'.$ID.'</title>'); 356 tpl_metaheaders(); 357 ptln('</head>'); 358 ptln('<body>'); 359 ptln('<div class="dokuwiki export">'); 360 print p_wiki_xhtml($ID,$REV,false); 361 ptln('</div>'); 362 ptln('</body>'); 363 ptln('</html>'); 364 exit; 365 } 366 367 // html body only 368 if($act == 'export_xhtmlbody'){ 369 print p_wiki_xhtml($ID,$REV,false); 370 exit; 371 } 372 373 // try to run renderer #FIXME use cached instructions 374 $mode = substr($act,7); 375 $text = p_render($mode,p_get_instructions(rawWiki($ID,$REV)),$info); 376 if(!is_null($text)){ 377 print $text; 378 exit; 379 } 380 381 382 383 return 'show'; 384} 385 386/** 387 * Handle 'subscribe', 'unsubscribe' 388 * 389 * @author Steven Danz <steven-danz@kc.rr.com> 390 * @todo localize 391 */ 392function act_subscription($act){ 393 global $ID; 394 global $INFO; 395 global $lang; 396 397 $file=metaFN($ID,'.mlist'); 398 if ($act=='subscribe' && !$INFO['subscribed']){ 399 if ($INFO['userinfo']['mail']){ 400 if (io_saveFile($file,$_SERVER['REMOTE_USER']."\n",true)) { 401 $INFO['subscribed'] = true; 402 msg(sprintf($lang[$act.'_success'], $INFO['userinfo']['name'], $ID),1); 403 } else { 404 msg(sprintf($lang[$act.'_error'], $INFO['userinfo']['name'], $ID),1); 405 } 406 } else { 407 msg($lang['subscribe_noaddress']); 408 } 409 } elseif ($act=='unsubscribe' && $INFO['subscribed']){ 410 if (io_deleteFromFile($file,$_SERVER['REMOTE_USER']."\n")) { 411 $INFO['subscribed'] = false; 412 msg(sprintf($lang[$act.'_success'], $INFO['userinfo']['name'], $ID),1); 413 } else { 414 msg(sprintf($lang[$act.'_error'], $INFO['userinfo']['name'], $ID),1); 415 } 416 } 417 418 return 'show'; 419} 420 421//Setup VIM: ex: et ts=2 enc=utf-8 : 422