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',realpath(dirname(__FILE__).'/../').'/'); 10 11 require_once(DOKU_INC.'inc/parserutils.php'); 12 13/** 14 * Convenience function to quickly build a wikilink 15 * 16 * @author Andreas Gohr <andi@splitbrain.org> 17 */ 18function html_wikilink($id,$name=NULL,$search=''){ 19 require_once(DOKU_INC.'inc/parser/xhtml.php'); 20 static $xhtml_renderer = NULL; 21 if(is_null($xhtml_renderer)){ 22 $xhtml_renderer = new Doku_Renderer_xhtml(); 23 } 24 25 return $xhtml_renderer->internallink($id,$name,$search,true); 26} 27 28/** 29 * Helps building long attribute lists 30 * 31 * @author Andreas Gohr <andi@splitbrain.org> 32 */ 33function html_attbuild($attributes){ 34 $ret = ''; 35 foreach ( $attributes as $key => $value ) { 36 $ret .= $key.'="'.formtext($value).'" '; 37 } 38 return trim($ret); 39} 40 41/** 42 * The loginform 43 * 44 * @author Andreas Gohr <andi@splitbrain.org> 45 */ 46function html_login(){ 47 global $lang; 48 global $conf; 49 global $ID; 50 global $auth; 51 52 print p_locale_xhtml('login'); 53 ?> 54 <div class="centeralign"> 55 <form action="<?php echo script()?>" accept-charset="<?php echo $lang['encoding']?>" method="post"> 56 <fieldset> 57 <legend><?php echo $lang['btn_login']?></legend> 58 <input type="hidden" name="id" value="<?php echo $ID?>" /> 59 <input type="hidden" name="do" value="login" /> 60 <label class="block"> 61 <span><?php echo $lang['user']?></span> 62 <input type="text" name="u" value="<?php echo formText($_REQUEST['u'])?>" class="edit" /> 63 </label><br /> 64 <label class="block"> 65 <span><?php echo $lang['pass']?></span> 66 <input type="password" name="p" class="edit" /> 67 </label><br /> 68 <input type="submit" value="<?php echo $lang['btn_login']?>" class="button" /> 69 <label for="remember" class="simple"> 70 <input type="checkbox" name="r" id="remember" value="1" /> 71 <span><?php echo $lang['remember']?></span> 72 </label> 73 </fieldset> 74 </form> 75 <?php 76 if($conf['openregister']){ 77 print '<p>'; 78 print $lang['reghere']; 79 print ': <a href="'.wl($ID,'do=register').'" class="wikilink1">'.$lang['register'].'</a>'; 80 print '</p>'; 81 } 82 83 if ($auth->canDo('modifyUser')) { 84 print '<p>'; 85 print $lang['pwdforget']; 86 print ': <a href="'.wl($ID,'do=resendpwd').'" class="wikilink1">'.$lang['btn_resendpwd'].'</a>'; 87 print '</p>'; 88 } 89 ?> 90 </div> 91 <?php 92/* 93 FIXME provide new hook 94 if(@file_exists('includes/login.txt')){ 95 print io_cacheParse('includes/login.txt'); 96 } 97*/ 98} 99 100/** 101 * shows the edit/source/show button dependent on current mode 102 * 103 * @author Andreas Gohr <andi@splitbrain.org> 104 */ 105function html_editbutton(){ 106 global $ID; 107 global $REV; 108 global $ACT; 109 global $INFO; 110 111 if($ACT == 'show' || $ACT == 'search'){ 112 if($INFO['writable']){ 113 if($INFO['exists']){ 114 $r = html_btn('edit',$ID,'e',array('do' => 'edit','rev' => $REV),'post'); 115 }else{ 116 $r = html_btn('create',$ID,'e',array('do' => 'edit','rev' => $REV),'post'); 117 } 118 }else{ 119 $r = html_btn('source',$ID,'v',array('do' => 'edit','rev' => $REV),'post'); 120 } 121 }else{ 122 $r = html_btn('show',$ID,'v',array('do' => 'show')); 123 } 124 return $r; 125} 126 127/** 128 * prints a section editing button 129 * 130 * @author Andreas Gohr <andi@splitbrain.org> 131 */ 132function html_secedit_button($section,$p){ 133 global $ID; 134 global $lang; 135 $secedit = ''; 136# if($p) $secedit .= "</p>\n"; 137 $secedit .= '<div class="secedit">'; 138 $secedit .= html_btn('secedit',$ID,'', 139 array('do' => 'edit', 140 'lines' => "$section"), 141 'post'); 142 $secedit .= '</div>'; 143# if($p) $secedit .= "\n<p>"; 144 return $secedit; 145} 146 147/** 148 * inserts section edit buttons if wanted or removes the markers 149 * 150 * @author Andreas Gohr <andi@splitbrain.org> 151 */ 152function html_secedit($text,$show=true){ 153 global $INFO; 154 if($INFO['writable'] && $show && !$INFO['rev']){ 155 $text = preg_replace('#<!-- SECTION \[(\d+-\d+)\] -->#e', 156 "html_secedit_button('\\1',true)", 157 $text); 158 $text = preg_replace('#<!-- SECTION \[(\d+-)\] -->#e', 159 "html_secedit_button('\\1',false)", 160 $text); 161 }else{ 162 $text = preg_replace('#<!-- SECTION \[(\d*-\d*)\] -->#e','',$text); 163 } 164 return $text; 165} 166 167/** 168 * Just the back to top button (in its own form) 169 * 170 * @author Andreas Gohr <andi@splitbrain.org> 171 */ 172function html_topbtn(){ 173 global $lang; 174 175 $ret = ''; 176 $ret = '<a href="#top"><input type="button" class="button" value="'.$lang['btn_top'].'" onclick="window.scrollTo(0, 0)" /></a>'; 177 178 return $ret; 179} 180 181/** 182 * Just the back to media window button in its own form 183 * 184 * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net> 185 */ 186function html_backtomedia_button($params,$akey=''){ 187 global $conf; 188 global $lang; 189 190 $ret = '<form class="button" method="get" action="'.DOKU_BASE.'lib/exe/media.php"><div class="no">'; 191 192 reset($params); 193 while (list($key, $val) = each($params)) { 194 $ret .= '<input type="hidden" name="'.$key.'" '; 195 $ret .= 'value="'.htmlspecialchars($val).'" />'; 196 } 197 198 $ret .= '<input type="submit" value="'.htmlspecialchars($lang['btn_backtomedia']).'" class="button" '; 199 if($akey){ 200 $ret .= 'title="ALT+'.strtoupper($akey).'" '; 201 $ret .= 'accesskey="'.$akey.'" '; 202 } 203 $ret .= '/>'; 204 $ret .= '</div></form>'; 205 206 return $ret; 207} 208 209/** 210 * Displays a button (using its own form) 211 * 212 * @author Andreas Gohr <andi@splitbrain.org> 213 */ 214function html_btn($name,$id,$akey,$params,$method='get'){ 215 global $conf; 216 global $lang; 217 218 $label = $lang['btn_'.$name]; 219 220 $ret = ''; 221 222 //filter id (without urlencoding) 223 $id = idfilter($id,false); 224 225 //make nice URLs even for buttons 226 if($conf['userewrite'] == 2){ 227 $script = DOKU_BASE.DOKU_SCRIPT.'/'.$id; 228 }elseif($conf['userewrite']){ 229 $script = DOKU_BASE.$id; 230 }else{ 231 $script = DOKU_BASE.DOKU_SCRIPT; 232 $params['id'] = $id; 233 } 234 235 $ret .= '<form class="button" method="'.$method.'" action="'.$script.'"><div class="no">'; 236 237 reset($params); 238 while (list($key, $val) = each($params)) { 239 $ret .= '<input type="hidden" name="'.$key.'" '; 240 $ret .= 'value="'.htmlspecialchars($val).'" />'; 241 } 242 243 $ret .= '<input type="submit" value="'.htmlspecialchars($label).'" class="button" '; 244 if($akey){ 245 $ret .= 'title="ALT+'.strtoupper($akey).'" '; 246 $ret .= 'accesskey="'.$akey.'" '; 247 } 248 $ret .= '/>'; 249 $ret .= '</div></form>'; 250 251 return $ret; 252} 253 254/** 255 * show a wiki page 256 * 257 * @author Andreas Gohr <andi@splitbrain.org> 258 */ 259function html_show($txt=''){ 260 global $ID; 261 global $REV; 262 global $HIGH; 263 //disable section editing for old revisions or in preview 264 if($txt || $REV){ 265 $secedit = false; 266 }else{ 267 $secedit = true; 268 } 269 270 if ($txt){ 271 //PreviewHeader 272 print p_locale_xhtml('preview'); 273 print '<div class="preview">'; 274 print html_secedit(p_render('xhtml',p_get_instructions($txt),$info),$secedit); 275 print '<div class="clearer"></div>'; 276 print '</div>'; 277 278 }else{ 279 if ($REV) print p_locale_xhtml('showrev'); 280 $html = p_wiki_xhtml($ID,$REV,true); 281 $html = html_secedit($html,$secedit); 282 print html_hilight($html,$HIGH); 283 } 284} 285 286/** 287 * Highlights searchqueries in HTML code 288 * 289 * @author Andreas Gohr <andi@splitbrain.org> 290 * @author Harry Fuecks <hfuecks@gmail.com> 291 */ 292function html_hilight($html,$query){ 293 //split at common delimiters 294 $queries = preg_split ('/[\s\'"\\\\`()\]\[?:!\.{};,#+*<>\\/]+/',$query,-1,PREG_SPLIT_NO_EMPTY); 295 foreach ($queries as $q){ 296 $q = preg_quote($q,'/'); 297 $html = preg_replace_callback("/((<[^>]*)|$q)/i",'html_hilight_callback',$html); 298 } 299 return $html; 300} 301 302/** 303 * Callback used by html_hilight() 304 * 305 * @author Harry Fuecks <hfuecks@gmail.com> 306 */ 307function html_hilight_callback($m) { 308 $hlight = unslash($m[0]); 309 if ( !isset($m[2])) { 310 $hlight = '<span class="search_hit">'.$hlight.'</span>'; 311 } 312 return $hlight; 313} 314 315/** 316 * Run a search and display the result 317 * 318 * @author Andreas Gohr <andi@splitbrain.org> 319 */ 320function html_search(){ 321 require_once(DOKU_INC.'inc/search.php'); 322 require_once(DOKU_INC.'inc/fulltext.php'); 323 global $conf; 324 global $QUERY; 325 global $ID; 326 global $lang; 327 328 print p_locale_xhtml('searchpage'); 329 flush(); 330 331 //show progressbar 332 print '<div class="centeralign">'; 333 print '<script type="text/javascript" charset="utf-8">'; 334 print 'showLoadBar();'; 335 print '</script>'; 336 print '<br /></div>'; 337 338 //do quick pagesearch 339 $data = array(); 340 $data = ft_pageLookup(cleanID($QUERY)); 341 if(count($data)){ 342 sort($data); 343 print '<div class="search_quickresult">'; 344 print '<strong>'.$lang[quickhits].':</strong><br />'; 345 foreach($data as $id){ 346 print '<div class="search_quickhits">'; 347 print html_wikilink(':'.$id,$conf['useheading']?NULL:$id); 348 print '</div> '; 349 } 350 //clear float (see http://www.complexspiral.com/publications/containing-floats/) 351 print '<div class="clearer"> </div>'; 352 print '</div>'; 353 } 354 flush(); 355 356 //do fulltext search 357 $data = ft_pageSearch($QUERY,$poswords); 358 if(count($data)){ 359 $num = 1; 360 foreach($data as $id => $cnt){ 361 print '<div class="search_result">'; 362 print html_wikilink(':'.$id,$conf['useheading']?NULL:$id,$poswords); 363 print ': <span class="search_cnt">'.$cnt.' '.$lang['hits'].'</span><br />'; 364 if($num < 15){ // create snippets for the first number of matches only #FIXME add to conf ? 365 print '<div class="search_snippet">'.ft_snippet($id,$poswords).'</div>'; 366 } 367 print '</div>'; 368 flush(); 369 $num++; 370 } 371 }else{ 372 print '<div class="nothing">'.$lang['nothingfound'].'</div>'; 373 } 374 375 //hide progressbar 376 print '<script type="text/javascript" charset="utf-8">'; 377 print 'hideLoadBar();'; 378 print '</script>'; 379} 380 381/** 382 * Display error on locked pages 383 * 384 * @author Andreas Gohr <andi@splitbrain.org> 385 */ 386function html_locked(){ 387 global $ID; 388 global $conf; 389 global $lang; 390 global $INFO; 391 392 $locktime = filemtime(wikiFN($ID).'.lock'); 393 $expire = @date($conf['dformat'], $locktime + $conf['locktime'] ); 394 $min = round(($conf['locktime'] - (time() - $locktime) )/60); 395 396 print p_locale_xhtml('locked'); 397 print '<ul>'; 398 print '<li><div class="li"><strong>'.$lang['lockedby'].':</strong> '.$INFO['locked'].'</li>'; 399 print '<li><div class="li"><strong>'.$lang['lockexpire'].':</strong> '.$expire.' ('.$min.' min)</div></li>'; 400 print '</ul>'; 401} 402 403/** 404 * list old revisions 405 * 406 * @author Andreas Gohr <andi@splitbrain.org> 407 */ 408function html_revisions(){ 409 global $ID; 410 global $INFO; 411 global $conf; 412 global $lang; 413 $revisions = getRevisions($ID); 414 $date = @date($conf['dformat'],$INFO['lastmod']); 415 416 print p_locale_xhtml('revisions'); 417 print '<ul>'; 418 if($INFO['exists']){ 419 print ($INFO['minor']) ? '<li class="minor">' : '<li>'; 420 print '<div class="li">'; 421 422 print $date; 423 424 print ' <img src="'.DOKU_BASE.'lib/images/blank.gif" border="0" width="15" height="11" alt="" /> '; 425 426 print '<a class="wikilink1" href="'.wl($ID).'">'.$ID.'</a> '; 427 428 print $INFO['sum']; 429 print ' <span class="user">'; 430 print $INFO['editor']; 431 print '</span> '; 432 433 print '('.$lang['current'].')'; 434 print '</div>'; 435 print '</li>'; 436 } 437 438 foreach($revisions as $rev){ 439 $date = date($conf['dformat'],$rev); 440 $info = getRevisionInfo($ID,$rev); 441 442 print ($info['minor']) ? '<li class="minor">' : '<li>'; 443 print '<div class="li">'; 444 print $date; 445 446 print ' <a href="'.wl($ID,"rev=$rev,do=diff").'">'; 447 $p = array(); 448 $p['src'] = DOKU_BASE.'lib/images/diff.png'; 449 $p['border'] = 0; 450 $p['width'] = 15; 451 $p['height'] = 11; 452 $p['title'] = $lang['diff']; 453 $p['alt'] = $lang['diff']; 454 $att = buildAttributes($p); 455 print "<img $att />"; 456 print '</a> '; 457 458 print '<a class="wikilink1" href="'.wl($ID,"rev=$rev").'">'.$ID.'</a> '; 459 460 print htmlspecialchars($info['sum']); 461 print ' <span class="user">'; 462 if($info['user']){ 463 print $info['user']; 464 }else{ 465 print $info['ip']; 466 } 467 print '</span>'; 468 469 print '</div>'; 470 print '</li>'; 471 } 472 print '</ul>'; 473} 474 475/** 476 * display recent changes 477 * 478 * @author Andreas Gohr <andi@splitbrain.org> 479 * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net> 480 */ 481function html_recent($first=0){ 482 global $conf; 483 global $lang; 484 global $ID; 485 /* we need to get one additionally log entry to be able to 486 * decide if this is the last page or is there another one. 487 * This is the cheapest solution to get this information. 488 */ 489 $recents = getRecents($first,$conf['recent'] + 1,getNS($ID)); 490 if(count($recents) == 0 && $first != 0){ 491 $first=0; 492 $recents = getRecents(0,$conf['recent'] + 1,getNS($ID)); 493 } 494 $cnt = count($recents) <= $conf['recent'] ? count($recents) : $conf['recent']; 495 496 print p_locale_xhtml('recent'); 497 print '<ul>'; 498 499 foreach($recents as $recent){ 500 $date = date($conf['dformat'],$recent['date']); 501 print ($recent['minor']) ? '<li class="minor">' : '<li>'; 502 print '<div class="li">'; 503 504 print $date.' '; 505 506 print '<a href="'.wl($recent['id'],"do=diff").'">'; 507 $p = array(); 508 $p['src'] = DOKU_BASE.'lib/images/diff.png'; 509 $p['border'] = 0; 510 $p['width'] = 15; 511 $p['height'] = 11; 512 $p['title'] = $lang['diff']; 513 $p['alt'] = $lang['diff']; 514 $att = buildAttributes($p); 515 print "<img $att />"; 516 print '</a> '; 517 518 print '<a href="'.wl($recent['id'],"do=revisions").'">'; 519 $p = array(); 520 $p['src'] = DOKU_BASE.'lib/images/history.png'; 521 $p['border'] = 0; 522 $p['width'] = 12; 523 $p['height'] = 14; 524 $p['title'] = $lang['btn_revs']; 525 $p['alt'] = $lang['btn_revs']; 526 $att = buildAttributes($p); 527 print "<img $att />"; 528 print '</a> '; 529 530 print html_wikilink(':'.$recent['id'],$conf['useheading']?NULL:$recent['id']); 531 print ' '.htmlspecialchars($recent['sum']); 532 533 print ' <span class="user">'; 534 if($recent['user']){ 535 print $recent['user']; 536 }else{ 537 print $recent['ip']; 538 } 539 print '</span>'; 540 541 print '</div>'; 542 print '</li>'; 543 } 544 print '</ul>'; 545 546 print '<div class="pagenav">'; 547 $last = $first + $conf['recent']; 548 if ($first > 0) { 549 $first -= $conf['recent']; 550 if ($first < 0) $first = 0; 551 print '<div class="pagenav-prev">'; 552 print html_btn('newer','',"p",array('do' => 'recent', 'first' => $first)); 553 print '</div>'; 554 } 555 if ($conf['recent'] < count($recents)) { 556 print '<div class="pagenav-next">'; 557 print html_btn('older','',"n",array('do' => 'recent', 'first' => $last)); 558 print '</div>'; 559 } 560 print '</div>'; 561} 562 563/** 564 * Display page index 565 * 566 * @author Andreas Gohr <andi@splitbrain.org> 567 */ 568function html_index($ns){ 569 require_once(DOKU_INC.'inc/search.php'); 570 global $conf; 571 global $ID; 572 $dir = $conf['datadir']; 573 $ns = cleanID($ns); 574 #fixme use appropriate function 575 if(empty($ns)){ 576 $ns = dirname(str_replace(':','/',$ID)); 577 if($ns == '.') $ns =''; 578 } 579 $ns = utf8_encodeFN(str_replace(':','/',$ns)); 580 581 print p_locale_xhtml('index'); 582 583 $data = array(); 584 search($data,$conf['datadir'],'search_index',array('ns' => $ns)); 585 print html_buildlist($data,'idx','html_list_index','html_li_index'); 586} 587 588/** 589 * Index item formatter 590 * 591 * User function for html_buildlist() 592 * 593 * @author Andreas Gohr <andi@splitbrain.org> 594 */ 595function html_list_index($item){ 596 $ret = ''; 597 $base = ':'.$item['id']; 598 $base = substr($base,strrpos($base,':')+1); 599 if($item['type']=='d'){ 600 $ret .= '<a href="'.wl($ID,'idx='.$item['id']).'" class="idx_dir">'; 601 $ret .= $base; 602 $ret .= '</a>'; 603 }else{ 604 $ret .= html_wikilink(':'.$item['id']); 605 } 606 return $ret; 607} 608 609/** 610 * Index List item 611 * 612 * This user function is used in html_build_lidt to build the 613 * <li> tags for namespaces when displaying the page index 614 * it gives different classes to opened or closed "folders" 615 * 616 * @author Andreas Gohr <andi@splitbrain.org> 617 */ 618function html_li_index($item){ 619 if($item['type'] == "f"){ 620 return '<li class="level'.$item['level'].'">'; 621 }elseif($item['open']){ 622 return '<li class="open">'; 623 }else{ 624 return '<li class="closed">'; 625 } 626} 627 628/** 629 * Default List item 630 * 631 * @author Andreas Gohr <andi@splitbrain.org> 632 */ 633function html_li_default($item){ 634 return '<li class="level'.$item['level'].'">'; 635} 636 637/** 638 * Build an unordered list 639 * 640 * Build an unordered list from the given $data array 641 * Each item in the array has to have a 'level' property 642 * the item itself gets printed by the given $func user 643 * function. The second and optional function is used to 644 * print the <li> tag. Both user function need to accept 645 * a single item. 646 * 647 * @author Andreas Gohr <andi@splitbrain.org> 648 */ 649function html_buildlist($data,$class,$func,$lifunc='html_li_default'){ 650 $level = 0; 651 $opens = 0; 652 $ret = ''; 653 654 foreach ($data as $item){ 655 656 if( $item['level'] > $level ){ 657 //open new list 658 for($i=0; $i<($item['level'] - $level); $i++){ 659 if ($i) $ret .= "<li class=\"clear\">\n"; 660 $ret .= "\n<ul class=\"$class\">\n"; 661 } 662 }elseif( $item['level'] < $level ){ 663 //close last item 664 $ret .= "</li>\n"; 665 for ($i=0; $i<($level - $item['level']); $i++){ 666 //close higher lists 667 $ret .= "</ul>\n</li>\n"; 668 } 669 }else{ 670 //close last item 671 $ret .= "</li>\n"; 672 } 673 674 //remember current level 675 $level = $item['level']; 676 677 //print item 678 $ret .= $lifunc($item); //user function 679 $ret .= '<div class="li">'; 680 $ret .= $func($item); //user function 681 $ret .= '</div>'; 682 } 683 684 //close remaining items and lists 685 for ($i=0; $i < $level; $i++){ 686 $ret .= "</li></ul>\n"; 687 } 688 689 return $ret; 690} 691 692/** 693 * display backlinks 694 * 695 * @author Andreas Gohr <andi@splitbrain.org> 696 */ 697function html_backlinks(){ 698 require_once(DOKU_INC.'inc/fulltext.php'); 699 global $ID; 700 global $conf; 701 702 print p_locale_xhtml('backlinks'); 703 704 $data = ft_backlinks($ID); 705 706 print '<ul class="idx">'; 707 foreach($data as $blink){ 708 print '<li><div class="li">'; 709 print html_wikilink(':'.$blink,$conf['useheading']?NULL:$blink); 710 print '</div></li>'; 711 } 712 print '</ul>'; 713} 714 715/** 716 * show diff 717 * 718 * @author Andreas Gohr <andi@splitbrain.org> 719 */ 720function html_diff($text='',$intro=true){ 721 require_once(DOKU_INC.'inc/DifferenceEngine.php'); 722 global $ID; 723 global $REV; 724 global $lang; 725 global $conf; 726 if($text){ 727 $df = new Diff(split("\n",htmlspecialchars(rawWiki($ID,''))), 728 split("\n",htmlspecialchars(cleanText($text)))); 729 $left = '<a class="wikilink1" href="'.wl($ID).'">'. 730 $ID.' '.date($conf['dformat'],@filemtime(wikiFN($ID))).'</a>'. 731 $lang['current']; 732 $right = $lang['yours']; 733 }else{ 734 if($REV){ 735 $r = $REV; 736 }else{ 737 //use last revision if none given 738 $revs = getRevisions($ID); 739 $r = $revs[0]; 740 } 741 742 $df = new Diff(split("\n",htmlspecialchars(rawWiki($ID,$r))), 743 split("\n",htmlspecialchars(rawWiki($ID,'')))); 744 $left = '<a class="wikilink1" href="'.wl($ID,"rev=$r").'">'. 745 $ID.' '.date($conf['dformat'],$r).'</a>'; 746 $right = '<a class="wikilink1" href="'.wl($ID).'">'. 747 $ID.' '.date($conf['dformat'],@filemtime(wikiFN($ID))).'</a> '. 748 $lang['current']; 749 } 750 $tdf = new TableDiffFormatter(); 751 if($intro) print p_locale_xhtml('diff'); 752 ?> 753 <table class="diff" width="100%"> 754 <tr> 755 <td colspan="2" width="50%" class="diff-header"> 756 <?php echo $left?> 757 </td> 758 <td colspan="2" width="50%" class="diff-header"> 759 <?php echo $right?> 760 </td> 761 </tr> 762 <?php echo $tdf->format($df)?> 763 </table> 764 <?php 765} 766 767/** 768 * show warning on conflict detection 769 * 770 * @author Andreas Gohr <andi@splitbrain.org> 771 */ 772function html_conflict($text,$summary){ 773 global $ID; 774 global $lang; 775 776 print p_locale_xhtml('conflict'); 777 ?> 778 <form id="dw__editform" method="post" action="<?php echo script()?>" accept-charset="<?php echo $lang['encoding']?>"> 779 <div class="centeralign"> 780 <input type="hidden" name="id" value="<?php echo $ID?>" /> 781 <input type="hidden" name="wikitext" value="<?php echo formText($text)?>" /> 782 <input type="hidden" name="summary" value="<?php echo formText($summary)?>" /> 783 784 <input class="button" type="submit" name="do" value="<?php echo $lang['btn_save']?>" accesskey="s" title="[ALT+S]" /> 785 <input class="button" type="submit" name="do" value="<?php echo $lang['btn_cancel']?>" /> 786 </div> 787 </form> 788 <br /><br /><br /><br /> 789 <?php 790} 791 792/** 793 * Prints the global message array 794 * 795 * @author Andreas Gohr <andi@splitbrain.org> 796 */ 797function html_msgarea(){ 798 global $MSG; 799 800 if(!isset($MSG)) return; 801 802 foreach($MSG as $msg){ 803 print '<div class="'.$msg['lvl'].'">'; 804 print $msg['msg']; 805 print '</div>'; 806 } 807} 808 809/** 810 * Prints the registration form 811 * 812 * @author Andreas Gohr <andi@splitbrain.org> 813 */ 814function html_register(){ 815 global $lang; 816 global $conf; 817 global $ID; 818 819 print p_locale_xhtml('register'); 820?> 821 <div class="centeralign"> 822 <form id="dw__register" method="post" action="<?php echo wl($ID)?>" accept-charset="<?php echo $lang['encoding']?>"> 823 <fieldset> 824 <input type="hidden" name="do" value="register" /> 825 <input type="hidden" name="save" value="1" /> 826 827 <legend><?php echo $lang['register']?></legend> 828 <label class="block"> 829 <?php echo $lang['user']?> 830 <input type="text" name="login" class="edit" size="50" value="<?php echo formText($_POST['login'])?>" /> 831 </label><br /> 832 833 <?php 834 if (!$conf['autopasswd']) { 835 ?> 836 <label class="block"> 837 <?php echo $lang['pass']?> 838 <input type="password" name="pass" class="edit" size="50" /> 839 </label><br /> 840 <label class="block"> 841 <?php echo $lang['passchk']?> 842 <input type="password" name="passchk" class="edit" size="50" /> 843 </label><br /> 844 <?php 845 } 846 ?> 847 848 <label class="block"> 849 <?php echo $lang['fullname']?> 850 <input type="text" name="fullname" class="edit" size="50" value="<?php echo formText($_POST['fullname'])?>" /> 851 </label><br /> 852 <label class="block"> 853 <?php echo $lang['email']?> 854 <input type="text" name="email" class="edit" size="50" value="<?php echo formText($_POST['email'])?>" /> 855 </label><br /> 856 <input type="submit" class="button" value="<?php echo $lang['register']?>" /> 857 </fieldset> 858 </form> 859 </div> 860<?php 861} 862 863/** 864 * Print the update profile form 865 * 866 * @author Christopher Smith <chris@jalakai.co.uk> 867 * @author Andreas Gohr <andi@splitbrain.org> 868 */ 869function html_updateprofile(){ 870 global $lang; 871 global $conf; 872 global $ID; 873 global $INFO; 874 875 print p_locale_xhtml('updateprofile'); 876 877 if (empty($_POST['fullname'])) $_POST['fullname'] = $INFO['userinfo']['name']; 878 if (empty($_POST['email'])) $_POST['email'] = $INFO['userinfo']['mail']; 879?> 880 <div class="centeralign"> 881 <form id="dw__register" method="post" action="<?php echo wl($ID)?>" accept-charset="<?php echo $lang['encoding']?>"> 882 <fieldset style="width: 80%;"> 883 <input type="hidden" name="do" value="profile" /> 884 <input type="hidden" name="save" value="1" /> 885 886 <legend><?php echo $lang['profile']?></legend> 887 <label class="block"> 888 <?php echo $lang['user']?> 889 <input type="text" name="fullname" disabled="disabled" class="edit" size="50" value="<?php echo formText($_SERVER['REMOTE_USER'])?>" /> 890 </label><br /> 891 <label class="block"> 892 <?php echo $lang['fullname']?> 893 <input type="text" name="fullname" class="edit" size="50" value="<?php echo formText($_POST['fullname'])?>" /> 894 </label><br /> 895 <label class="block"> 896 <?php echo $lang['email']?> 897 <input type="text" name="email" class="edit" size="50" value="<?php echo formText($_POST['email'])?>" /> 898 </label><br /><br /> 899 <label class="block"> 900 <?php echo $lang['newpass']?> 901 <input type="password" name="newpass" class="edit" size="50" /> 902 </label><br /> 903 <label class="block"> 904 <?php echo $lang['passchk']?> 905 <input type="password" name="passchk" class="edit" size="50" /> 906 </label><br /> 907 908 <?php if ($conf['profileconfirm']) { ?> 909 <br /> 910 <label class="block"> 911 <?php echo $lang['oldpass']?> 912 <input type="password" name="oldpass" class="edit" size="50" /> 913 </label><br /> 914 <?php } ?> 915 916 <input type="submit" class="button" value="<?php echo $lang['btn_save']?>" /> 917 <input type="reset" class="button" value="<?php echo $lang['btn_reset']?>" /> 918 </fieldset> 919 </form> 920 </div> 921<?php 922} 923 924/** 925 * This displays the edit form (lots of logic included) 926 * 927 * @fixme this is a huge lump of code and should be modularized 928 * @author Andreas Gohr <andi@splitbrain.org> 929 */ 930function html_edit($text=null,$include='edit'){ //FIXME: include needed? 931 global $ID; 932 global $REV; 933 global $DATE; 934 global $RANGE; 935 global $PRE; 936 global $SUF; 937 global $INFO; 938 global $SUM; 939 global $lang; 940 global $conf; 941 942 //set summary default 943 if(!$SUM){ 944 if($REV){ 945 $SUM = $lang['restored']; 946 }elseif(!$INFO['exists']){ 947 $SUM = $lang['created']; 948 } 949 } 950 951 //no text? Load it! 952 if(!isset($text)){ 953 $pr = false; //no preview mode 954 if($INFO['exists']){ 955 if($RANGE){ 956 list($PRE,$text,$SUF) = rawWikiSlices($RANGE,$ID,$REV); 957 }else{ 958 $text = rawWiki($ID,$REV); 959 } 960 }else{ 961 //try to load a pagetemplate 962 $text = pageTemplate($ID); 963 } 964 }else{ 965 $pr = true; //preview mode 966 } 967 968 $wr = $INFO['writable']; 969 if($wr){ 970 if ($REV) print p_locale_xhtml('editrev'); 971 print p_locale_xhtml($include); 972 }else{ 973 print p_locale_xhtml('read'); 974 $ro='readonly="readonly"'; 975 } 976 if(!$DATE) $DATE = $INFO['lastmod']; 977 978 979?> 980 <form id="dw__editform" method="post" action="<?php echo script()?>" accept-charset="<?php echo $lang['encoding']?>"> 981 <table style="width:99%"> 982 <tr> 983 <td class="toolbar" colspan="2"> 984 <div id="toolbar"></div> 985 <input type="hidden" name="id" value="<?php echo $ID?>" /> 986 <input type="hidden" name="rev" value="<?php echo $REV?>" /> 987 <input type="hidden" name="date" value="<?php echo $DATE?>" /> 988 <input type="hidden" name="prefix" value="<?php echo formText($PRE)?>" /> 989 <input type="hidden" name="suffix" value="<?php echo formText($SUF)?>" /> 990 991 <?php if($wr){?> 992 <script type="text/javascript" charset="utf-8"> 993 <?php /* sets changed to true when previewed */?> 994 textChanged = <?php ($pr) ? print 'true' : print 'false' ?>; 995 </script> 996 <span id="spell_action"></span> 997 <?php } ?> 998 </td> 999 <td> 1000 <div id="spell_suggest"></div> 1001 </td> 1002 </tr> 1003 <tr> 1004 <td colspan="3"> 1005 <div id="spell_result"></div> 1006 <textarea name="wikitext" id="wikitext" <?php echo $ro?> cols="80" rows="10" class="edit" tabindex="1"><?php echo "\n".formText($text)?></textarea> 1007 </td> 1008 </tr> 1009 <tr id="wikieditbar"> 1010 <td> 1011 <?php if($wr){?> 1012 <input class="button" id="edbtn_save" type="submit" name="do" value="<?php echo $lang['btn_save']?>" accesskey="s" title="[ALT+S]" tabindex="4" /> 1013 <input class="button" id="edbtn_preview" type="submit" name="do" value="<?php echo $lang['btn_preview']?>" accesskey="p" title="[ALT+P]" tabindex="5" /> 1014 <input class="button" type="submit" name="do" value="<?php echo $lang['btn_cancel']?>" tabindex="5" /> 1015 <?php } ?> 1016 </td> 1017 <td> 1018 <?php if($wr){ ?> 1019 <?php echo $lang['summary']?>: 1020 <input type="text" class="edit" name="summary" id="summary" size="50" value="<?php echo formText($SUM)?>" tabindex="2" /> 1021 <?php html_minoredit()?> 1022 <?php }?> 1023 </td> 1024 <td class="rightalign"> 1025 <div id="sizectl"></div> 1026 </td> 1027 </tr> 1028 </table> 1029 </form> 1030<?php 1031} 1032 1033/** 1034 * Adds a checkbox for minor edits for logged in users 1035 * 1036 * @author Andrea Gohr <andi@splitbrain.org> 1037 */ 1038function html_minoredit(){ 1039 global $conf; 1040 global $lang; 1041 // minor edits are for logged in users only 1042 if(!$conf['useacl'] || !$_SERVER['REMOTE_USER']){ 1043 return; 1044 } 1045 1046 $p = array(); 1047 $p['name'] = 'minor'; 1048 $p['type'] = 'checkbox'; 1049 $p['id'] = 'minoredit'; 1050 $p['tabindex'] = 3; 1051 $p['value'] = '1'; 1052 if($_REQUEST['minor']) $p['checked']='checked'; 1053 $att = buildAttributes($p); 1054 1055 print "<input $att />"; 1056 print '<label for="minoredit">'; 1057 print $lang['minoredit']; 1058 print '</label>'; 1059} 1060 1061/** 1062 * prints some debug info 1063 * 1064 * @author Andreas Gohr <andi@splitbrain.org> 1065 */ 1066function html_debug(){ 1067 global $conf; 1068 global $lang; 1069 //remove sensitive data 1070 $cnf = $conf; 1071 $cnf['auth']='***'; 1072 $cnf['notify']='***'; 1073 $cnf['ftp']='***'; 1074 1075 print '<html><body>'; 1076 1077 print '<p>When reporting bugs please send all the following '; 1078 print 'output as a mail to andi@splitbrain.org '; 1079 print 'The best way to do this is to save this page in your browser</p>'; 1080 1081 print '<b>$_SERVER:</b><pre>'; 1082 print_r($_SERVER); 1083 print '</pre>'; 1084 1085 print '<b>$conf:</b><pre>'; 1086 print_r($cnf); 1087 print '</pre>'; 1088 1089 print '<b>DOKU_BASE:</b><pre>'; 1090 print DOKU_BASE; 1091 print '</pre>'; 1092 1093 print '<b>abs DOKU_BASE:</b><pre>'; 1094 print DOKU_URL; 1095 print '</pre>'; 1096 1097 print '<b>rel DOKU_BASE:</b><pre>'; 1098 print dirname($_SERVER['PHP_SELF']).'/'; 1099 print '</pre>'; 1100 1101 print '<b>PHP Version:</b><pre>'; 1102 print phpversion(); 1103 print '</pre>'; 1104 1105 print '<b>locale:</b><pre>'; 1106 print setlocale(LC_ALL,0); 1107 print '</pre>'; 1108 1109 print '<b>encoding:</b><pre>'; 1110 print $lang['encoding']; 1111 print '</pre>'; 1112 1113 print '<b>$_SESSION:</b><pre>'; 1114 print_r($_SESSION); 1115 print '</pre>'; 1116 1117 print '<b>Environment:</b><pre>'; 1118 print_r($_ENV); 1119 print '</pre>'; 1120 1121 print '<b>PHP settings:</b><pre>'; 1122 $inis = ini_get_all(); 1123 print_r($inis); 1124 print '</pre>'; 1125 1126 print '</body></html>'; 1127} 1128 1129function html_admin(){ 1130 global $ID; 1131 global $lang; 1132 global $conf; 1133 1134 print p_locale_xhtml('admin'); 1135 1136 // build menu of admin functions from the plugins that handle them 1137 $pluginlist = plugin_list('admin'); 1138 $menu = array(); 1139 foreach ($pluginlist as $p) { 1140 if($obj =& plugin_load('admin',$p) === NULL) continue; 1141 $menu[] = array('plugin' => $p, 1142 'prompt' => $obj->getMenuText($conf['lang']), 1143 'sort' => $obj->getMenuSort() 1144 ); 1145 } 1146 1147 usort($menu, p_sort_modes); 1148 1149 // output the menu 1150 ptln('<ul>'); 1151 1152 foreach ($menu as $item) { 1153 if (!$item['prompt']) continue; 1154 ptln(' <li><div class="li"><a href="'.wl($ID, 'do=admin&page='.$item['plugin']).'">'.$item['prompt'].'</a></div></li>'); 1155 } 1156 1157 // add in non-plugin functions 1158 if (!$conf['openregister']){ 1159 ptln('<li><div class="li"><a href="'.wl($ID,'do=register').'">'.$lang['admin_register'].'</a></div></li>'); 1160 } 1161 1162 ptln('</ul>'); 1163} 1164 1165/** 1166 * Form to request a new password for an existing account 1167 * 1168 * @author Benoit Chesneau <benoit@bchesneau.info> 1169 */ 1170function html_resendpwd() { 1171 global $lang; 1172 global $conf; 1173 global $ID; 1174 1175 print p_locale_xhtml('resendpwd'); 1176?> 1177 <div class="centeralign"> 1178 <form id="dw__resendpwd" action="<?php echo wl($ID)?>" accept-charset="<?php echo $lang['encoding']?>" method="post"> 1179 <fieldset> 1180 <br /> 1181 <legend><?php echo $lang['resendpwd']?></legend> 1182 <input type="hidden" name="do" value="resendpwd" /> 1183 <input type="hidden" name="save" value="1" /> 1184 <label class="block"> 1185 <span><?php echo $lang['user']?></span> 1186 <input type="text" name="login" value="<?php echo formText($_POST['login'])?>" class="edit" /><br /><br /> 1187 </label><br /> 1188 <input type="submit" value="<?php echo $lang['btn_resendpwd']?>" class="button" /> 1189 </fieldset> 1190 </form> 1191 </div> 1192<?php 1193} 1194 1195//Setup VIM: ex: et ts=2 enc=utf-8 : 1196