[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/inc/ -> actions.php (source)

   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')) die('meh.');
  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   * @triggers ACTION_ACT_PREPROCESS
  18   * @triggers ACTION_HEADERS_SEND
  19   */
  20  function act_dispatch(){
  21    global $INFO;
  22    global $ACT;
  23    global $ID;
  24    global $QUERY;
  25    global $lang;
  26    global $conf;
  27    global $license;
  28  
  29    $preact = $ACT;
  30  
  31    // give plugins an opportunity to process the action
  32    $evt = new Doku_Event('ACTION_ACT_PREPROCESS',$ACT);
  33    if ($evt->advise_before()) {
  34  
  35      //sanitize $ACT
  36      $ACT = act_clean($ACT);
  37  
  38      //check if searchword was given - else just show
  39      $s = cleanID($QUERY);
  40      if($ACT == 'search' && empty($s)){
  41        $ACT = 'show';
  42      }
  43  
  44      //login stuff
  45      if(in_array($ACT,array('login','logout'))){
  46          $ACT = act_auth($ACT);
  47      }
  48  
  49      //check if user is asking to (un)subscribe a page
  50      if($ACT == 'subscribe' || $ACT == 'unsubscribe')
  51        $ACT = act_subscription($ACT);
  52  
  53      //check if user is asking to (un)subscribe a namespace
  54      if($ACT == 'subscribens' || $ACT == 'unsubscribens')
  55        $ACT = act_subscriptionns($ACT);
  56  
  57      //check permissions
  58      $ACT = act_permcheck($ACT);
  59  
  60      //register
  61      $nil = array();
  62      if($ACT == 'register' && $_POST['save'] && register()){
  63        $ACT = 'login';
  64      }
  65  
  66      if ($ACT == 'resendpwd' && act_resendpwd()) {
  67        $ACT = 'login';
  68      }
  69  
  70      //update user profile
  71      if ($ACT == 'profile') {
  72        if(!$_SERVER['REMOTE_USER']) {
  73          $ACT = 'login';
  74        } else {
  75          if(updateprofile()) {
  76            msg($lang['profchanged'],1);
  77            $ACT = 'show';
  78          }
  79        }
  80      }
  81  
  82      //revert
  83      if($ACT == 'revert'){
  84        if(checkSecurityToken()){
  85          $ACT = act_revert($ACT);
  86        }else{
  87          $ACT = 'show';
  88        }
  89      }
  90  
  91      //save
  92      if($ACT == 'save'){
  93        if(checkSecurityToken()){
  94          $ACT = act_save($ACT);
  95        }else{
  96          $ACT = 'show';
  97        }
  98      }
  99  
 100      //cancel conflicting edit
 101      if($ACT == 'cancel')
 102        $ACT = 'show';
 103  
 104      //draft deletion
 105      if($ACT == 'draftdel')
 106        $ACT = act_draftdel($ACT);
 107  
 108      //draft saving on preview
 109      if($ACT == 'preview')
 110        $ACT = act_draftsave($ACT);
 111  
 112      //edit
 113      if(($ACT == 'edit' || $ACT == 'preview') && $INFO['editable']){
 114        $ACT = act_edit($ACT);
 115      }else{
 116        unlock($ID); //try to unlock
 117      }
 118  
 119      //handle export
 120      if(substr($ACT,0,7) == 'export_')
 121        $ACT = act_export($ACT);
 122  
 123      //display some infos
 124      if($ACT == 'check'){
 125        check();
 126        $ACT = 'show';
 127      }
 128  
 129      //handle admin tasks
 130      if($ACT == 'admin'){
 131        // retrieve admin plugin name from $_REQUEST['page']
 132        if (!empty($_REQUEST['page'])) {
 133            $pluginlist = plugin_list('admin');
 134            if (in_array($_REQUEST['page'], $pluginlist)) {
 135              // attempt to load the plugin
 136              if ($plugin =& plugin_load('admin',$_REQUEST['page']) !== NULL)
 137                  $plugin->handle();
 138            }
 139        }
 140      }
 141  
 142      // check permissions again - the action may have changed
 143      $ACT = act_permcheck($ACT);
 144    }  // end event ACTION_ACT_PREPROCESS default action
 145    $evt->advise_after();
 146    unset($evt);
 147  
 148    // when action 'show', the intial not 'show' and POST, do a redirect
 149    if($ACT == 'show' && $preact != 'show' && strtolower($_SERVER['REQUEST_METHOD']) == 'post'){
 150      act_redirect($ID,$preact);
 151    }
 152  
 153    //call template FIXME: all needed vars available?
 154    $headers[] = 'Content-Type: text/html; charset=utf-8';
 155    trigger_event('ACTION_HEADERS_SEND',$headers,'act_sendheaders');
 156  
 157    include(template('main.php'));
 158    // output for the commands is now handled in inc/templates.php
 159    // in function tpl_content()
 160  }
 161  
 162  function act_sendheaders($headers) {
 163    foreach ($headers as $hdr) header($hdr);
 164  }
 165  
 166  /**
 167   * Sanitize the action command
 168   *
 169   * Add all allowed commands here.
 170   *
 171   * @author Andreas Gohr <andi@splitbrain.org>
 172   */
 173  function act_clean($act){
 174    global $lang;
 175    global $conf;
 176  
 177    // check if the action was given as array key
 178    if(is_array($act)){
 179      list($act) = array_keys($act);
 180    }
 181  
 182    //remove all bad chars
 183    $act = strtolower($act);
 184    $act = preg_replace('/[^1-9a-z_]+/','',$act);
 185  
 186    if($act == 'export_html') $act = 'export_xhtml';
 187    if($act == 'export_htmlbody') $act = 'export_xhtmlbody';
 188  
 189    // check if action is disabled
 190    if(!actionOK($act)){
 191      msg('Command disabled: '.htmlspecialchars($act),-1);
 192      return 'show';
 193    }
 194  
 195    //disable all acl related commands if ACL is disabled
 196    if(!$conf['useacl'] && in_array($act,array('login','logout','register','admin',
 197                                               'subscribe','unsubscribe','profile','revert',
 198                                               'resendpwd','subscribens','unsubscribens',))){
 199      msg('Command unavailable: '.htmlspecialchars($act),-1);
 200      return 'show';
 201    }
 202  
 203    if(!in_array($act,array('login','logout','register','save','cancel','edit','draft',
 204                            'preview','search','show','check','index','revisions',
 205                            'diff','recent','backlink','admin','subscribe','revert',
 206                            'unsubscribe','profile','resendpwd','recover','wordblock',
 207                            'draftdel','subscribens','unsubscribens',)) && substr($act,0,7) != 'export_' ) {
 208      msg('Command unknown: '.htmlspecialchars($act),-1);
 209      return 'show';
 210    }
 211    return $act;
 212  }
 213  
 214  /**
 215   * Run permissionchecks
 216   *
 217   * @author Andreas Gohr <andi@splitbrain.org>
 218   */
 219  function act_permcheck($act){
 220    global $INFO;
 221    global $conf;
 222  
 223    if(in_array($act,array('save','preview','edit','recover'))){
 224      if($INFO['exists']){
 225        if($act == 'edit'){
 226          //the edit function will check again and do a source show
 227          //when no AUTH_EDIT available
 228          $permneed = AUTH_READ;
 229        }else{
 230          $permneed = AUTH_EDIT;
 231        }
 232      }else{
 233        $permneed = AUTH_CREATE;
 234      }
 235    }elseif(in_array($act,array('login','search','recent','profile'))){
 236      $permneed = AUTH_NONE;
 237    }elseif($act == 'revert'){
 238      $permneed = AUTH_ADMIN;
 239      if($INFO['ismanager']) $permneed = AUTH_EDIT;
 240    }elseif($act == 'register'){
 241      $permneed = AUTH_NONE;
 242    }elseif($act == 'resendpwd'){
 243      $permneed = AUTH_NONE;
 244    }elseif($act == 'admin'){
 245      if($INFO['ismanager']){
 246        // if the manager has the needed permissions for a certain admin
 247        // action is checked later
 248        $permneed = AUTH_READ;
 249      }else{
 250        $permneed = AUTH_ADMIN;
 251      }
 252    }else{
 253      $permneed = AUTH_READ;
 254    }
 255    if($INFO['perm'] >= $permneed) return $act;
 256  
 257    return 'denied';
 258  }
 259  
 260  /**
 261   * Handle 'draftdel'
 262   *
 263   * Deletes the draft for the current page and user
 264   */
 265  function act_draftdel($act){
 266    global $INFO;
 267    @unlink($INFO['draft']);
 268    $INFO['draft'] = null;
 269    return 'show';
 270  }
 271  
 272  /**
 273   * Saves a draft on preview
 274   *
 275   * @todo this currently duplicates code from ajax.php :-/
 276   */
 277  function act_draftsave($act){
 278    global $INFO;
 279    global $ID;
 280    global $conf;
 281    if($conf['usedraft'] && $_POST['wikitext']){
 282      $draft = array('id'     => $ID,
 283                     'prefix' => $_POST['prefix'],
 284                     'text'   => $_POST['wikitext'],
 285                     'suffix' => $_POST['suffix'],
 286                     'date'   => $_POST['date'],
 287                     'client' => $INFO['client'],
 288                    );
 289      $cname = getCacheName($draft['client'].$ID,'.draft');
 290      if(io_saveFile($cname,serialize($draft))){
 291        $INFO['draft'] = $cname;
 292      }
 293    }
 294    return $act;
 295  }
 296  
 297  /**
 298   * Handle 'save'
 299   *
 300   * Checks for spam and conflicts and saves the page.
 301   * Does a redirect to show the page afterwards or
 302   * returns a new action.
 303   *
 304   * @author Andreas Gohr <andi@splitbrain.org>
 305   */
 306  function act_save($act){
 307    global $ID;
 308    global $DATE;
 309    global $PRE;
 310    global $TEXT;
 311    global $SUF;
 312    global $SUM;
 313  
 314    //spam check
 315    if(checkwordblock())
 316      return 'wordblock';
 317    //conflict check //FIXME use INFO
 318    if($DATE != 0 && @filemtime(wikiFN($ID)) > $DATE )
 319      return 'conflict';
 320  
 321    //save it
 322    saveWikiText($ID,con($PRE,$TEXT,$SUF,1),$SUM,$_REQUEST['minor']); //use pretty mode for con
 323    //unlock it
 324    unlock($ID);
 325  
 326    //delete draft
 327    act_draftdel($act);
 328    session_write_close();
 329  
 330    // when done, show page
 331    return 'show';
 332  }
 333  
 334  /**
 335   * Revert to a certain revision
 336   *
 337   * @author Andreas Gohr <andi@splitbrain.org>
 338   */
 339  function act_revert($act){
 340      global $ID;
 341      global $REV;
 342      global $lang;
 343  
 344      // when no revision is given, delete current one
 345      // FIXME this feature is not exposed in the GUI currently
 346      $text = '';
 347      $sum  = $lang['deleted'];
 348      if($REV){
 349          $text = rawWiki($ID,$REV);
 350          if(!$text) return 'show'; //something went wrong
 351          $sum  = $lang['restored'];
 352      }
 353  
 354      // spam check
 355      if(checkwordblock($Text))
 356          return 'wordblock';
 357  
 358      saveWikiText($ID,$text,$sum,false);
 359      msg($sum,1);
 360  
 361      //delete any draft
 362      act_draftdel($act);
 363      session_write_close();
 364  
 365      // when done, show current page
 366      $_SERVER['REQUEST_METHOD'] = 'post'; //should force a redirect
 367      $REV = '';
 368      return 'show';
 369  }
 370  
 371  /**
 372   * Do a redirect after receiving post data
 373   *
 374   * Tries to add the section id as hash mark after section editing
 375   */
 376  function act_redirect($id,$preact){
 377    global $PRE;
 378    global $TEXT;
 379    global $MSG;
 380  
 381    //are there any undisplayed messages? keep them in session for display
 382    //on the next page
 383    if(isset($MSG) && count($MSG)){
 384      //reopen session, store data and close session again
 385      @session_start();
 386      $_SESSION[DOKU_COOKIE]['msg'] = $MSG;
 387      session_write_close();
 388    }
 389  
 390    $opts = array(
 391      'id'       => $id,
 392      'preact'   => $preact
 393    );
 394    //get section name when coming from section edit
 395    if($PRE && preg_match('/^\s*==+([^=\n]+)/',$TEXT,$match)){
 396      $check = false; //Byref
 397      $opts['fragment'] = sectionID($match[0], $check);
 398    }
 399  
 400    trigger_event('ACTION_SHOW_REDIRECT',$opts,'act_redirect_execute');
 401  }
 402  
 403  function act_redirect_execute($opts){
 404    $go = wl($opts['id'],'',true);
 405    if(isset($opts['fragment'])) $go .= '#'.$opts['fragment'];
 406  
 407    //show it
 408    send_redirect($go);
 409  }
 410  
 411  /**
 412   * Handle 'login', 'logout'
 413   *
 414   * @author Andreas Gohr <andi@splitbrain.org>
 415   */
 416  function act_auth($act){
 417    global $ID;
 418    global $INFO;
 419  
 420    //already logged in?
 421    if(isset($_SERVER['REMOTE_USER']) && $act=='login'){
 422      return 'show';
 423    }
 424  
 425    //handle logout
 426    if($act=='logout'){
 427      $lockedby = checklock($ID); //page still locked?
 428      if($lockedby == $_SERVER['REMOTE_USER'])
 429        unlock($ID); //try to unlock
 430  
 431      // do the logout stuff
 432      auth_logoff();
 433  
 434      // rebuild info array
 435      $INFO = pageinfo();
 436  
 437      act_redirect($ID,'login');
 438    }
 439  
 440    return $act;
 441  }
 442  
 443  /**
 444   * Handle 'edit', 'preview'
 445   *
 446   * @author Andreas Gohr <andi@splitbrain.org>
 447   */
 448  function act_edit($act){
 449    global $ID;
 450    global $INFO;
 451  
 452    //check if locked by anyone - if not lock for my self
 453    $lockedby = checklock($ID);
 454    if($lockedby) return 'locked';
 455  
 456    lock($ID);
 457    return $act;
 458  }
 459  
 460  /**
 461   * Export a wiki page for various formats
 462   *
 463   * Triggers ACTION_EXPORT_POSTPROCESS
 464   *
 465   *  Event data:
 466   *    data['id']      -- page id
 467   *    data['mode']    -- requested export mode
 468   *    data['headers'] -- export headers
 469   *    data['output']  -- export output
 470   *
 471   * @author Andreas Gohr <andi@splitbrain.org>
 472   * @author Michael Klier <chi@chimeric.de>
 473   */
 474  function act_export($act){
 475    global $ID;
 476    global $REV;
 477    global $conf;
 478    global $lang;
 479  
 480    $pre = '';
 481    $post = '';
 482    $output = '';
 483    $headers = array();
 484  
 485    // search engines: never cache exported docs! (Google only currently)
 486    $headers['X-Robots-Tag'] = 'noindex';
 487  
 488    $mode = substr($act,7);
 489    switch($mode) {
 490      case 'raw':
 491        $headers['Content-Type'] = 'text/plain; charset=utf-8';
 492        $headers['Content-Disposition'] = 'attachment; filename='.noNS($ID).'.txt';
 493        $output = rawWiki($ID,$REV);
 494        break;
 495      case 'xhtml':
 496        $pre .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"' . DOKU_LF;
 497        $pre .= ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' . DOKU_LF;
 498        $pre .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="'.$conf['lang'].'"' . DOKU_LF;
 499        $pre .= ' lang="'.$conf['lang'].'" dir="'.$lang['direction'].'">' . DOKU_LF;
 500        $pre .= '<head>' . DOKU_LF;
 501        $pre .= '  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />' . DOKU_LF;
 502        $pre .= '  <title>'.$ID.'</title>' . DOKU_LF;
 503  
 504        // get metaheaders
 505        ob_start();
 506        tpl_metaheaders();
 507        $pre .= ob_get_clean();
 508  
 509        $pre .= '</head>' . DOKU_LF;
 510        $pre .= '<body>' . DOKU_LF;
 511        $pre .= '<div class="dokuwiki export">' . DOKU_LF;
 512  
 513        // get toc
 514        $pre .= tpl_toc(true);
 515  
 516        $headers['Content-Type'] = 'text/html; charset=utf-8';
 517        $output = p_wiki_xhtml($ID,$REV,false);
 518  
 519        $post .= '</div>' . DOKU_LF;
 520        $post .= '</body>' . DOKU_LF;
 521        $post .= '</html>' . DOKU_LF;
 522        break;
 523      case 'xhtmlbody':
 524        $headers['Content-Type'] = 'text/html; charset=utf-8';
 525        $output = p_wiki_xhtml($ID,$REV,false);
 526        break;
 527      default:
 528        $output = p_cached_output(wikiFN($ID,$REV), $mode);
 529        $headers = p_get_metadata($ID,"format $mode");
 530        break;
 531    }
 532  
 533    // prepare event data
 534    $data = array();
 535    $data['id'] = $ID;
 536    $data['mode'] = $mode;
 537    $data['headers'] = $headers;
 538    $data['output'] =& $output;
 539  
 540    trigger_event('ACTION_EXPORT_POSTPROCESS', $data);
 541  
 542    if(!empty($data['output'])){
 543      if(is_array($data['headers'])) foreach($data['headers'] as $key => $val){
 544        header("$key: $val");
 545      }
 546      print $pre.$data['output'].$post;
 547      exit;
 548    }
 549    return 'show';
 550  }
 551  
 552  /**
 553   * Handle page 'subscribe', 'unsubscribe'
 554   *
 555   * @author Steven Danz <steven-danz@kc.rr.com>
 556   * @todo   localize
 557   */
 558  function act_subscription($act){
 559    global $ID;
 560    global $INFO;
 561    global $lang;
 562  
 563    $file=metaFN($ID,'.mlist');
 564    if ($act=='subscribe' && !$INFO['subscribed']){
 565      if ($INFO['userinfo']['mail']){
 566        if (io_saveFile($file,$_SERVER['REMOTE_USER']."\n",true)) {
 567          $INFO['subscribed'] = true;
 568          msg(sprintf($lang[$act.'_success'], $INFO['userinfo']['name'], $ID),1);
 569        } else {
 570          msg(sprintf($lang[$act.'_error'], $INFO['userinfo']['name'], $ID),1);
 571        }
 572      } else {
 573        msg($lang['subscribe_noaddress']);
 574      }
 575    } elseif ($act=='unsubscribe' && $INFO['subscribed']){
 576      if (io_deleteFromFile($file,$_SERVER['REMOTE_USER']."\n")) {
 577        $INFO['subscribed'] = false;
 578        msg(sprintf($lang[$act.'_success'], $INFO['userinfo']['name'], $ID),1);
 579      } else {
 580        msg(sprintf($lang[$act.'_error'], $INFO['userinfo']['name'], $ID),1);
 581      }
 582    }
 583  
 584    return 'show';
 585  }
 586  
 587  /**
 588   * Handle namespace 'subscribe', 'unsubscribe'
 589   *
 590   */
 591  function act_subscriptionns($act){
 592    global $ID;
 593    global $INFO;
 594    global $lang;
 595  
 596    if(!getNS($ID)) {
 597      $file = metaFN(getNS($ID),'.mlist');
 598      $ns = "root";
 599    } else {
 600      $file = metaFN(getNS($ID),'/.mlist');
 601      $ns = getNS($ID);
 602    }
 603  
 604    // reuse strings used to display the status of the subscribe action
 605    $act_msg = rtrim($act, 'ns');
 606  
 607    if ($act=='subscribens' && !$INFO['subscribedns']){
 608      if ($INFO['userinfo']['mail']){
 609        if (io_saveFile($file,$_SERVER['REMOTE_USER']."\n",true)) {
 610          $INFO['subscribedns'] = true;
 611          msg(sprintf($lang[$act_msg.'_success'], $INFO['userinfo']['name'], $ns),1);
 612        } else {
 613          msg(sprintf($lang[$act_msg.'_error'], $INFO['userinfo']['name'], $ns),1);
 614        }
 615      } else {
 616        msg($lang['subscribe_noaddress']);
 617      }
 618    } elseif ($act=='unsubscribens' && $INFO['subscribedns']){
 619      if (io_deleteFromFile($file,$_SERVER['REMOTE_USER']."\n")) {
 620        $INFO['subscribedns'] = false;
 621        msg(sprintf($lang[$act_msg.'_success'], $INFO['userinfo']['name'], $ns),1);
 622      } else {
 623        msg(sprintf($lang[$act_msg.'_error'], $INFO['userinfo']['name'], $ns),1);
 624      }
 625    }
 626  
 627    return 'show';
 628  }
 629  
 630  //Setup VIM: ex: et ts=2 enc=utf-8 :


Generated: Fri Mar 19 03:00:35 2010 Cross-referenced by PHPXref 0.7
WikiForumIRCBugsGitXRefTranslate