[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/inc/ -> html.php (source)

   1  <?php
   2  /**
   3   * HTML output functions
   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',fullpath(dirname(__FILE__).'/../').'/');
  10  if(!defined('NL')) define('NL',"\n");
  11  require_once (DOKU_INC.'inc/parserutils.php');
  12  require_once (DOKU_INC.'inc/form.php');
  13  
  14  /**
  15   * Convenience function to quickly build a wikilink
  16   *
  17   * @author Andreas Gohr <andi@splitbrain.org>
  18   */
  19  function html_wikilink($id,$name=NULL,$search=''){
  20    static $xhtml_renderer = NULL;
  21    if(is_null($xhtml_renderer)){
  22      require_once (DOKU_INC.'inc/parser/xhtml.php');
  23      $xhtml_renderer = new Doku_Renderer_xhtml();
  24    }
  25  
  26    return $xhtml_renderer->internallink($id,$name,$search,true,'navigation');
  27  }
  28  
  29  /**
  30   * Helps building long attribute lists
  31   *
  32   * @author Andreas Gohr <andi@splitbrain.org>
  33   */
  34  function html_attbuild($attributes){
  35    $ret = '';
  36    foreach ( $attributes as $key => $value ) {
  37      $ret .= $key.'="'.formtext($value).'" ';
  38    }
  39    return trim($ret);
  40  }
  41  
  42  /**
  43   * The loginform
  44   *
  45   * @author   Andreas Gohr <andi@splitbrain.org>
  46   */
  47  function html_login(){
  48    global $lang;
  49    global $conf;
  50    global $ID;
  51    global $auth;
  52  
  53    print p_locale_xhtml('login');
  54    print '<div class="centeralign">'.NL;
  55    $form = new Doku_Form('dw__login');
  56    $form->startFieldset($lang['btn_login']);
  57    $form->addHidden('id', $ID);
  58    $form->addHidden('do', 'login');
  59    $form->addElement(form_makeTextField('u', ((!$_REQUEST['http_credentials']) ? $_REQUEST['u'] : ''), $lang['user'], 'focus__this', 'block'));
  60    $form->addElement(form_makePasswordField('p', $lang['pass'], '', 'block'));
  61    if($conf['rememberme']) {
  62        $form->addElement(form_makeCheckboxField('r', '1', $lang['remember'], 'remember__me', 'simple'));
  63    }
  64    $form->addElement(form_makeButton('submit', '', $lang['btn_login']));
  65    $form->endFieldset();
  66    html_form('login', $form);
  67  
  68    if($auth && $auth->canDo('addUser') && actionOK('register')){
  69      print '<p>';
  70      print $lang['reghere'];
  71      print ': <a href="'.wl($ID,'do=register').'" rel="nofollow" class="wikilink1">'.$lang['register'].'</a>';
  72      print '</p>';
  73    }
  74  
  75    if ($auth && $auth->canDo('modPass') && actionOK('resendpwd')) {
  76      print '<p>';
  77      print $lang['pwdforget'];
  78      print ': <a href="'.wl($ID,'do=resendpwd').'" rel="nofollow" class="wikilink1">'.$lang['btn_resendpwd'].'</a>';
  79      print '</p>';
  80    }
  81    print '</div>'.NL;
  82  }
  83  
  84  /**
  85   * prints a section editing button
  86   * used as a callback in html_secedit
  87   *
  88   * @author Andreas Gohr <andi@splitbrain.org>
  89   */
  90  function html_secedit_button($matches){
  91    global $ID;
  92    global $INFO;
  93  
  94    $section = $matches[2];
  95    $name = $matches[1];
  96  
  97    $secedit  = '';
  98    $secedit .= '<div class="secedit">';
  99    $secedit .= html_btn('secedit',$ID,'',
 100                          array('do'      => 'edit',
 101                                'lines'   => "$section",
 102                                'rev' => $INFO['lastmod']),
 103                                'post', $name);
 104    $secedit .= '</div>';
 105    return $secedit;
 106  }
 107  
 108  /**
 109   * inserts section edit buttons if wanted or removes the markers
 110   *
 111   * @author Andreas Gohr <andi@splitbrain.org>
 112   */
 113  function html_secedit($text,$show=true){
 114    global $INFO;
 115  
 116    if($INFO['writable'] && $show && !$INFO['rev']){
 117      $text = preg_replace_callback('#<!-- SECTION "(.*?)" \[(\d+-\d*)\] -->#',
 118                           'html_secedit_button', $text);
 119    }else{
 120      $text = preg_replace('#<!-- SECTION "(.*?)" \[(\d+-\d*)\] -->#','',$text);
 121    }
 122  
 123    return $text;
 124  }
 125  
 126  /**
 127   * Just the back to top button (in its own form)
 128   *
 129   * @author Andreas Gohr <andi@splitbrain.org>
 130   */
 131  function html_topbtn(){
 132    global $lang;
 133  
 134    $ret  = '';
 135    $ret  = '<a class="nolink" href="#dokuwiki__top"><input type="button" class="button" value="'.$lang['btn_top'].'" onclick="window.scrollTo(0, 0)" title="'.$lang['btn_top'].'" /></a>';
 136  
 137    return $ret;
 138  }
 139  
 140  /**
 141   * Displays a button (using its own form)
 142   * If tooltip exists, the access key tooltip is replaced.
 143   *
 144   * @author Andreas Gohr <andi@splitbrain.org>
 145   */
 146  function html_btn($name,$id,$akey,$params,$method='get',$tooltip=''){
 147    global $conf;
 148    global $lang;
 149  
 150    $label = $lang['btn_'.$name];
 151  
 152    $ret = '';
 153    $tip = '';
 154  
 155    //filter id (without urlencoding)
 156    $id = idfilter($id,false);
 157  
 158    //make nice URLs even for buttons
 159    if($conf['userewrite'] == 2){
 160      $script = DOKU_BASE.DOKU_SCRIPT.'/'.$id;
 161    }elseif($conf['userewrite']){
 162      $script = DOKU_BASE.$id;
 163    }else{
 164      $script = DOKU_BASE.DOKU_SCRIPT;
 165      $params['id'] = $id;
 166    }
 167  
 168    $ret .= '<form class="button btn_'.$name.'" method="'.$method.'" action="'.$script.'"><div class="no">';
 169  
 170    if(is_array($params)){
 171      reset($params);
 172      while (list($key, $val) = each($params)) {
 173        $ret .= '<input type="hidden" name="'.$key.'" ';
 174        $ret .= 'value="'.htmlspecialchars($val).'" />';
 175      }
 176    }
 177  
 178    if ($tooltip!='') {
 179        $tip = htmlspecialchars($tooltip);
 180    }else{
 181        $tip = htmlspecialchars($label);
 182    }
 183  
 184    $ret .= '<input type="submit" value="'.htmlspecialchars($label).'" class="button" ';
 185    if($akey){
 186      $tip .= ' ['.strtoupper($akey).']';
 187      $ret .= 'accesskey="'.htmlspecialchars($label).' '.$akey.'" ';
 188    }
 189    $ret .= 'title="'.$tip.'" ';
 190    $ret .= '/>';
 191    $ret .= '</div></form>';
 192  
 193    return $ret;
 194  }
 195  
 196  /**
 197   * show a wiki page
 198   *
 199   * @author Andreas Gohr <andi@splitbrain.org>
 200   */
 201  function html_show($txt=''){
 202    global $ID;
 203    global $REV;
 204    global $HIGH;
 205    global $INFO;
 206    //disable section editing for old revisions or in preview
 207    if($txt || $REV){
 208      $secedit = false;
 209    }else{
 210      $secedit = true;
 211    }
 212  
 213    if ($txt){
 214      //PreviewHeader
 215      echo '<br id="scroll__here" />';
 216      echo p_locale_xhtml('preview');
 217      echo '<div class="preview">';
 218      $html = html_secedit(p_render('xhtml',p_get_instructions($txt),$info),$secedit);
 219      if($INFO['prependTOC']) $html = tpl_toc(true).$html;
 220      echo $html;
 221      echo '<div class="clearer"></div>';
 222      echo '</div>';
 223  
 224    }else{
 225      if ($REV) print p_locale_xhtml('showrev');
 226      $html = p_wiki_xhtml($ID,$REV,true);
 227      $html = html_secedit($html,$secedit);
 228      if($INFO['prependTOC']) $html = tpl_toc(true).$html;
 229      $html = html_hilight($html,$HIGH);
 230      echo $html;
 231    }
 232  }
 233  
 234  /**
 235   * ask the user about how to handle an exisiting draft
 236   *
 237   * @author Andreas Gohr <andi@splitbrain.org>
 238   */
 239  function html_draft(){
 240    global $INFO;
 241    global $ID;
 242    global $lang;
 243    global $conf;
 244    $draft = unserialize(io_readFile($INFO['draft'],false));
 245    $text  = cleanText(con($draft['prefix'],$draft['text'],$draft['suffix'],true));
 246  
 247    print p_locale_xhtml('draft');
 248    $form = new Doku_Form('dw__editform');
 249    $form->addHidden('id', $ID);
 250    $form->addHidden('date', $draft['date']);
 251    $form->addElement(form_makeWikiText($text, array('readonly'=>'readonly')));
 252    $form->addElement(form_makeOpenTag('div', array('id'=>'draft__status')));
 253    $form->addElement($lang['draftdate'].' '. strftime($conf['dformat'],filemtime($INFO['draft'])));
 254    $form->addElement(form_makeCloseTag('div'));
 255    $form->addElement(form_makeButton('submit', 'recover', $lang['btn_recover'], array('tabindex'=>'1')));
 256    $form->addElement(form_makeButton('submit', 'draftdel', $lang['btn_draftdel'], array('tabindex'=>'2')));
 257    $form->addElement(form_makeButton('submit', 'show', $lang['btn_cancel'], array('tabindex'=>'3')));
 258    html_form('draft', $form);
 259  }
 260  
 261  /**
 262   * Highlights searchqueries in HTML code
 263   *
 264   * @author Andreas Gohr <andi@splitbrain.org>
 265   * @author Harry Fuecks <hfuecks@gmail.com>
 266   */
 267  function html_hilight($html,$phrases){
 268    $regex = join('|',array_map('preg_quote_cb',array_filter((array) $phrases)));
 269  
 270    if ($regex === '') return $html;
 271    $html = preg_replace_callback("/((<[^>]*)|$regex)/ui",'html_hilight_callback',$html);
 272    return $html;
 273  }
 274  
 275  /**
 276   * Callback used by html_hilight()
 277   *
 278   * @author Harry Fuecks <hfuecks@gmail.com>
 279   */
 280  function html_hilight_callback($m) {
 281    $hlight = unslash($m[0]);
 282    if ( !isset($m[2])) {
 283      $hlight = '<span class="search_hit">'.$hlight.'</span>';
 284    }
 285    return $hlight;
 286  }
 287  
 288  /**
 289   * Run a search and display the result
 290   *
 291   * @author Andreas Gohr <andi@splitbrain.org>
 292   */
 293  function html_search(){
 294    require_once (DOKU_INC.'inc/search.php');
 295    require_once (DOKU_INC.'inc/fulltext.php');
 296    global $conf;
 297    global $QUERY;
 298    global $ID;
 299    global $lang;
 300  
 301    print p_locale_xhtml('searchpage');
 302    flush();
 303  
 304    //check if search is restricted to namespace
 305    if(preg_match('/([^@]*)@([^@]*)/',$QUERY,$match)) {
 306        $id = cleanID($match[1]);
 307        if(empty($id)) {
 308          print '<div class="nothing">'.$lang['nothingfound'].'</div>';
 309          flush();
 310          return;
 311        }
 312    } else {
 313        $id = cleanID($QUERY);
 314    }
 315  
 316    //show progressbar
 317    print '<div class="centeralign" id="dw__loading">'.NL;
 318    print '<script type="text/javascript" charset="utf-8"><!--//--><![CDATA[//><!--'.NL;
 319    print 'showLoadBar();'.NL;
 320    print '//--><!]]></script>'.NL;
 321    print '<br /></div>'.NL;
 322    flush();
 323  
 324    //do quick pagesearch
 325    $data = array();
 326  
 327    $data = ft_pageLookup($id);
 328    if(count($data)){
 329      print '<div class="search_quickresult">';
 330      print '<h3>'.$lang['quickhits'].':</h3>';
 331      print '<ul class="search_quickhits">';
 332      foreach($data as $id){
 333        print '<li> ';
 334        $ns = getNS($id);
 335        if($ns){
 336          $name = shorten(noNS($id), ' ('.$ns.')',30);
 337        }else{
 338          $name = $id;
 339        }
 340        print html_wikilink(':'.$id,$name);
 341        print '</li> ';
 342      }
 343      print '</ul> ';
 344      //clear float (see http://www.complexspiral.com/publications/containing-floats/)
 345      print '<div class="clearer">&nbsp;</div>';
 346      print '</div>';
 347    }
 348    flush();
 349  
 350    //do fulltext search
 351    $data = ft_pageSearch($QUERY,$regex);
 352    if(count($data)){
 353      $num = 1;
 354      foreach($data as $id => $cnt){
 355        print '<div class="search_result">';
 356        print html_wikilink(':'.$id,useHeading('navigation')?NULL:$id,$regex);
 357        print ': <span class="search_cnt">'.$cnt.' '.$lang['hits'].'</span><br />';
 358        if($num < 15){ // create snippets for the first number of matches only #FIXME add to conf ?
 359          print '<div class="search_snippet">'.ft_snippet($id,$regex).'</div>';
 360        }
 361        print '</div>';
 362        flush();
 363        $num++;
 364      }
 365    }else{
 366      print '<div class="nothing">'.$lang['nothingfound'].'</div>';
 367    }
 368  
 369    //hide progressbar
 370    print '<script type="text/javascript" charset="utf-8"><!--//--><![CDATA[//><!--'.NL;
 371    print 'hideLoadBar("dw__loading");'.NL;
 372    print '//--><!]]></script>'.NL;
 373    flush();
 374  }
 375  
 376  /**
 377   * Display error on locked pages
 378   *
 379   * @author Andreas Gohr <andi@splitbrain.org>
 380   */
 381  function html_locked(){
 382    global $ID;
 383    global $conf;
 384    global $lang;
 385    global $INFO;
 386  
 387    $locktime = filemtime(wikiLockFN($ID));
 388    $expire = @strftime($conf['dformat'], $locktime + $conf['locktime'] );
 389    $min    = round(($conf['locktime'] - (time() - $locktime) )/60);
 390  
 391    print p_locale_xhtml('locked');
 392    print '<ul>';
 393    print '<li><div class="li"><strong>'.$lang['lockedby'].':</strong> '.$INFO['locked'].'</div></li>';
 394    print '<li><div class="li"><strong>'.$lang['lockexpire'].':</strong> '.$expire.' ('.$min.' min)</div></li>';
 395    print '</ul>';
 396  }
 397  
 398  /**
 399   * list old revisions
 400   *
 401   * @author Andreas Gohr <andi@splitbrain.org>
 402   * @author Ben Coburn <btcoburn@silicodon.net>
 403   */
 404  function html_revisions($first=0){
 405    global $ID;
 406    global $INFO;
 407    global $conf;
 408    global $lang;
 409    /* we need to get one additionally log entry to be able to
 410     * decide if this is the last page or is there another one.
 411     * see html_recent()
 412     */
 413    $revisions = getRevisions($ID, $first, $conf['recent']+1);
 414    if(count($revisions)==0 && $first!=0){
 415      $first=0;
 416      $revisions = getRevisions($ID, $first, $conf['recent']+1);;
 417    }
 418    $hasNext = false;
 419    if (count($revisions)>$conf['recent']) {
 420      $hasNext = true;
 421      array_pop($revisions); // remove extra log entry
 422    }
 423  
 424    $date = @strftime($conf['dformat'],$INFO['lastmod']);
 425  
 426    print p_locale_xhtml('revisions');
 427  
 428    $form = new Doku_Form('page__revisions', wl($ID));
 429    $form->addElement(form_makeOpenTag('ul'));
 430    if($INFO['exists'] && $first==0){
 431      if (isset($INFO['meta']) && isset($INFO['meta']['last_change']) && $INFO['meta']['last_change']['type']===DOKU_CHANGE_TYPE_MINOR_EDIT)
 432        $form->addElement(form_makeOpenTag('li', array('class' => 'minor')));
 433      else
 434        $form->addElement(form_makeOpenTag('li'));
 435      $form->addElement(form_makeOpenTag('div', array('class' => 'li')));
 436      $form->addElement(form_makeTag('input', array(
 437        'type' => 'checkbox',
 438        'name' => 'rev2[]',
 439        'value' => 'current')));
 440  
 441      $form->addElement(form_makeOpenTag('span', array('class' => 'date')));
 442      $form->addElement($date);
 443      $form->addElement(form_makeCloseTag('span'));
 444  
 445      $form->addElement(form_makeTag('img', array(
 446        'src' =>  DOKU_BASE.'lib/images/blank.gif',
 447        'width' => '15',
 448        'height' => '11',
 449        'alt'    => '')));
 450  
 451      $form->addElement(form_makeOpenTag('a', array(
 452        'class' => 'wikilink1',
 453        'href'  => wl($ID))));
 454      $form->addElement($ID);
 455      $form->addElement(form_makeCloseTag('a'));
 456  
 457      $form->addElement(form_makeOpenTag('span', array('class' => 'sum')));
 458      $form->addElement(' &ndash; ');
 459      $form->addElement(htmlspecialchars($INFO['sum']));
 460      $form->addElement(form_makeCloseTag('span'));
 461  
 462      $form->addElement(form_makeOpenTag('span', array('class' => 'user')));
 463      $form->addElement((empty($INFO['editor']))?('('.$lang['external_edit'].')'):editorinfo($INFO['editor']));
 464      $form->addElement(form_makeCloseTag('span'));
 465  
 466      $form->addElement('('.$lang['current'].')');
 467      $form->addElement(form_makeCloseTag('div'));
 468      $form->addElement(form_makeCloseTag('li'));
 469    }
 470  
 471    foreach($revisions as $rev){
 472      $date   = strftime($conf['dformat'],$rev);
 473      $info   = getRevisionInfo($ID,$rev,true);
 474      $exists = page_exists($ID,$rev);
 475  
 476      if ($info['type']===DOKU_CHANGE_TYPE_MINOR_EDIT)
 477        $form->addElement(form_makeOpenTag('li', array('class' => 'minor')));
 478      else
 479        $form->addElement(form_makeOpenTag('li'));
 480      $form->addElement(form_makeOpenTag('div', array('class' => 'li')));
 481      if($exists){
 482        $form->addElement(form_makeTag('input', array(
 483          'type' => 'checkbox',
 484          'name' => 'rev2[]',
 485          'value' => $rev)));
 486      }else{
 487        $form->addElement(form_makeTag('img', array(
 488          'src' => DOKU_BASE.'lib/images/blank.gif',
 489          'width' => 14,
 490          'height' => 11,
 491          'alt' => '')));
 492      }
 493  
 494      $form->addElement(form_makeOpenTag('span', array('class' => 'date')));
 495      $form->addElement($date);
 496      $form->addElement(form_makeCloseTag('span'));
 497  
 498      if($exists){
 499        $form->addElement(form_makeOpenTag('a', array('href' => wl(