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 51 print p_locale_xhtml('login'); 52 ?> 53 <div align="center"> 54 <form action="<?=script()?>" accept-charset="<?=$lang['encoding']?>" method="post"> 55 <fieldset> 56 <legend><?=$lang['btn_login']?></legend> 57 <input type="hidden" name="id" value="<?=$ID?>" /> 58 <input type="hidden" name="do" value="login" /> 59 <label> 60 <span><?=$lang['user']?></span> 61 <input type="text" name="u" value="<?=formText($_REQUEST['u'])?>" class="edit" /> 62 </label><br /> 63 <label> 64 <span><?=$lang['pass']?></span> 65 <input type="password" name="p" class="edit" /> 66 </label><br /> 67 <input type="submit" value="<?=$lang['btn_login']?>" class="button" /> 68 <label for="remember" class="simple"> 69 <input type="checkbox" name="r" id="remember" value="1" /> 70 <span><?=$lang['remember']?></span> 71 </label> 72 </fieldset> 73 </form> 74 <? 75 if($conf['openregister']){ 76 print '<p>'; 77 print $lang['reghere']; 78 print ': <a href="'.wl($ID,'do=register').'" class="wikilink1">'.$lang['register'].'</a>'; 79 print '</p>'; 80 } 81 ?> 82 </div> 83 <? 84/* 85 FIXME provide new hook 86 if(@file_exists('includes/login.txt')){ 87 print io_cacheParse('includes/login.txt'); 88 } 89*/ 90} 91 92/** 93 * shows the edit/source/show button dependent on current mode 94 * 95 * @author Andreas Gohr <andi@splitbrain.org> 96 */ 97function html_editbutton(){ 98 global $ID; 99 global $REV; 100 global $ACT; 101 global $INFO; 102 103 if($ACT == 'show' || $ACT == 'search'){ 104 if($INFO['writable']){ 105 if($INFO['exists']){ 106 $r = html_btn('edit',$ID,'e',array('do' => 'edit','rev' => $REV),'post'); 107 }else{ 108 $r = html_btn('create',$ID,'e',array('do' => 'edit','rev' => $REV),'post'); 109 } 110 }else{ 111 $r = html_btn('source',$ID,'v',array('do' => 'edit','rev' => $REV),'post'); 112 } 113 }else{ 114 $r = html_btn('show',$ID,'v',array('do' => 'show')); 115 } 116 return $r; 117} 118 119/** 120 * prints a section editing button 121 * 122 * @author Andreas Gohr <andi@splitbrain.org> 123 */ 124function html_secedit_button($section,$p){ 125 global $ID; 126 global $lang; 127 $secedit = ''; 128# if($p) $secedit .= "</p>\n"; 129 $secedit .= '<div class="secedit">'; 130 $secedit .= html_btn('secedit',$ID,'', 131 array('do' => 'edit', 132 'lines' => "$section"), 133 'post'); 134 $secedit .= '</div>'; 135# if($p) $secedit .= "\n<p>"; 136 return $secedit; 137} 138 139/** 140 * inserts section edit buttons if wanted or removes the markers 141 * 142 * @author Andreas Gohr <andi@splitbrain.org> 143 */ 144function html_secedit($text,$show=true){ 145 global $INFO; 146 if($INFO['writable'] && $show && !$INFO['rev']){ 147 $text = preg_replace('#<!-- SECTION \[(\d+-\d+)\] -->#e', 148 "html_secedit_button('\\1',true)", 149 $text); 150 $text = preg_replace('#<!-- SECTION \[(\d+-)\] -->#e', 151 "html_secedit_button('\\1',false)", 152 $text); 153 }else{ 154 $text = preg_replace('#<!-- SECTION \[(\d*-\d*)\] -->#e','',$text); 155 } 156 return $text; 157} 158 159/** 160 * Just the back to top button (in it's own form) 161 * 162 * @author Andreas Gohr <andi@splitbrain.org> 163 */ 164function html_topbtn(){ 165 global $lang; 166 167 $ret = ''; 168 $ret = '<a href="#top"><input type="button" class="button" value="Back to top" onclick="window.scrollTo(0, 0)" /></a>'; 169 170 return $ret; 171} 172 173/** 174 * Displays a button (using it's own form) 175 * 176 * @author Andreas Gohr <andi@splitbrain.org> 177 */ 178function html_btn($name,$id,$akey,$params,$method='get'){ 179 global $conf; 180 global $lang; 181 182 $label = $lang['btn_'.$name]; 183 184 $ret = ''; 185 186 //filter id (without urlencoding) 187 $id = idfilter($id,false); 188 189 //make nice URLs even for buttons 190 if(!$conf['userewrite']){ 191 $script = DOKU_BASE.DOKU_SCRIPT; 192 $params['id'] = $id; 193 }else{ 194 $script = DOKU_BASE.$id; 195 } 196 197 $ret .= '<form class="button" method="'.$method.'" action="'.$script.'" onsubmit="return svchk()">'; 198 199 reset($params); 200 while (list($key, $val) = each($params)) { 201 $ret .= '<input type="hidden" name="'.$key.'" '; 202 $ret .= 'value="'.htmlspecialchars($val).'" />'; 203 } 204 205 $ret .= '<input type="submit" value="'.htmlspecialchars($label).'" class="button" '; 206 if($akey){ 207 $ret .= 'title="ALT+'.strtoupper($akey).'" '; 208 $ret .= 'accesskey="'.$akey.'" '; 209 } 210 $ret .= '/>'; 211 $ret .= '</form>'; 212 213 return $ret; 214} 215 216/** 217 * Print the table of contents 218 * 219 * @author Andreas Gohr <andi@splitbrain.org> 220 */ 221function html_toc($toc){ 222 global $lang; 223 $ret = ''; 224 $ret .= '<div class="toc">'; 225 $ret .= '<div class="tocheader">'; 226 $ret .= $lang['toc']; 227 $ret .= ' <script type="text/javascript">'; 228 $ret .= 'showTocToggle("+","-")'; 229 $ret .= '</script>'; 230 $ret .= '</div>'; 231 $ret .= '<div id="tocinside">'; 232 $ret .= html_buildlist($toc,'toc','html_list_toc'); 233 $ret .= '</div>'; 234 $ret .= '</div>'; 235 return $ret; 236} 237 238/** 239 * TOC item formatter 240 * 241 * User function for html_buildlist() 242 * 243 * @author Andreas Gohr <andi@splitbrain.org> 244 */ 245function html_list_toc($item){ 246 $ret = ''; 247 $ret .= '<a href="#'.$item['id'].'" class="toc">'; 248 $ret .= $item['name']; 249 $ret .= '</a>'; 250 return $ret; 251} 252 253/** 254 * show a wiki page 255 * 256 * @author Andreas Gohr <andi@splitbrain.org> 257 */ 258function html_show($txt=''){ 259 global $ID; 260 global $REV; 261 global $HIGH; 262 //disable section editing for old revisions or in preview 263 if($txt || $REV){ 264 $secedit = false; 265 }else{ 266 $secedit = true; 267 } 268 269 if ($txt){ 270 //PreviewHeader 271 print p_locale_xhtml('preview'); 272 print '<div class="preview">'; 273 print html_secedit(p_render('xhtml',p_get_instructions($txt)),$secedit); 274 print '</div>'; 275 276 }else{ 277 if ($REV) print p_locale_xhtml('showrev'); 278 $html = p_wiki_xhtml($ID,$REV,true); 279 $html = html_secedit($html,$secedit); 280 print html_hilight($html,$HIGH); 281 } 282} 283 284/** 285 * Highlights searchqueries in HTML code 286 * 287 * @author Andreas Gohr <andi@splitbrain.org> 288 */ 289function html_hilight($html,$query){ 290 $queries = preg_split ("/\s/",$query,-1,PREG_SPLIT_NO_EMPTY); 291 foreach ($queries as $q){ 292 $q = preg_quote($q,'/'); 293 $html = preg_replace("/((<[^>]*)|$q)/ie", '"\2"=="\1"? "\1":"<span class=\"search_hit\">\1</span>"', $html); 294 } 295 return $html; 296} 297 298/** 299 * Run a search and display the result 300 * 301 * @author Andreas Gohr <andi@splitbrain.org> 302 */ 303function html_search(){ 304 require_once(DOKU_INC.'inc/search.php'); 305 global $conf; 306 global $QUERY; 307 global $ID; 308 global $lang; 309 310 print p_locale_xhtml('searchpage'); 311 flush(); 312 313 //show progressbar 314 print '<div align="center">'; 315 print '<script language="JavaScript" type="text/javascript">'; 316 print 'showLoadBar();'; 317 print '</script>'; 318 print '<br /></div>'; 319 320 //do quick pagesearch 321 $data = array(); 322 search($data,$conf['datadir'],'search_pagename',array(query => cleanID($QUERY))); 323 if(count($data)){ 324 sort($data); 325 print '<div class="search_quickresult">'; 326 print '<b>'.$lang[quickhits].':</b><br />'; 327 foreach($data as $row){ 328 print '<div class="search_quickhits">'; 329 print html_wikilink(':'.$row['id'],$row['id']); 330 print '</div> '; 331 } 332 //clear float (see http://www.complexspiral.com/publications/containing-floats/) 333 print '<div class="clearer"> </div>'; 334 print '</div>'; 335 } 336 flush(); 337 338 //do fulltext search 339 $data = array(); 340 search($data,$conf['datadir'],'search_fulltext',array(query => utf8_strtolower($QUERY))); 341 if(count($data)){ 342 usort($data,'sort_search_fulltext'); 343 foreach($data as $row){ 344 print '<div class="search_result">'; 345 print html_wikilink(':'.$row['id'],$row['id'],$QUERY); 346 print ': <span class="search_cnt">'.$row['count'].' '.$lang['hits'].'</span><br />'; 347 print '<div class="search_snippet">'.$row['snippet'].'</div>'; 348 print '</div>'; 349 } 350 }else{ 351 print '<div class="nothing">'.$lang['nothingfound'].'</div>'; 352 } 353 354 //hide progressbar 355 print '<script language="JavaScript" type="text/javascript">'; 356 print 'hideLoadBar();'; 357 print '</script>'; 358} 359 360/** 361 * Display error on locked pages 362 * 363 * @author Andreas Gohr <andi@splitbrain.org> 364 */ 365function html_locked($ip){ 366 global $ID; 367 global $conf; 368 global $lang; 369 370 $locktime = filemtime(wikiFN($ID).'.lock'); 371 $expire = @date($conf['dformat'], $locktime + $conf['locktime'] ); 372 $min = round(($conf['locktime'] - (time() - $locktime) )/60); 373 374 print p_locale_xhtml('locked'); 375 print '<ul>'; 376 print '<li><b>'.$lang['lockedby'].':</b> '.$ip.'</li>'; 377 print '<li><b>'.$lang['lockexpire'].':</b> '.$expire.' ('.$min.' min)</li>'; 378 print '</ul>'; 379} 380 381/** 382 * list old revisions 383 * 384 * @author Andreas Gohr <andi@splitbrain.org> 385 */ 386function html_revisions(){ 387 global $ID; 388 global $INFO; 389 global $conf; 390 global $lang; 391 $revisions = getRevisions($ID); 392 $date = @date($conf['dformat'],$INFO['lastmod']); 393 394 print p_locale_xhtml('revisions'); 395 print '<ul>'; 396 if($INFO['exists']){ 397 print '<li>'; 398 399 print $date; 400 401 print ' <img src="'.DOKU_BASE.'images/blank.gif" border="0" width="15" height="11" alt="" /> '; 402 403 print '<a class="wikilink1" href="'.wl($ID).'">'.$ID.'</a> '; 404 405 print $INFO['sum']; 406 print ' <span class="user">('; 407 print $INFO['ip']; 408 if($INFO['user']) print ' '.$INFO['user']; 409 print ')</span> '; 410 411 print '('.$lang['current'].')'; 412 print '</li>'; 413 } 414 415 foreach($revisions as $rev){ 416 $date = date($conf['dformat'],$rev); 417 $info = getRevisionInfo($ID,$rev); 418 419 print '<li>'; 420 421 print $date; 422 423 print ' <a href="'.wl($ID,"rev=$rev,do=diff").'">'; 424 print '<img src="'.DOKU_BASE.'images/diff.png" border="0" width="15" height="11" title="'.$lang['diff'].'" />'; 425 print '</a> '; 426 427 print '<a class="wikilink1" href="'.wl($ID,"rev=$rev").'">'.$ID.'</a> '; 428 429 print htmlspecialchars($info['sum']); 430 print ' <span class="user">('; 431 print $info['ip']; 432 if($info['user']) print ' '.$info['user']; 433 print ')</span>'; 434 435 print '</li>'; 436 } 437 print '</ul>'; 438} 439 440/** 441 * display recent changes 442 * 443 * @author Andreas Gohr <andi@splitbrain.org> 444 */ 445function html_recent(){ 446 global $conf; 447 global $lang; 448 $recents = getRecents(0,true); 449 450 print p_locale_xhtml('recent'); 451 print '<ul>'; 452 foreach(array_keys($recents) as $id){ 453 $date = date($conf['dformat'],$recents[$id]['date']); 454 print '<li>'; 455 456 print $date.' '; 457 458 print '<a href="'.wl($id,"do=diff").'">'; 459 print '<img src="'.DOKU_BASE.'images/diff.png" border="0" width="15" height="11" title="'.$lang['diff'].'" />'; 460 print '</a> '; 461 462 print '<a href="'.wl($id,"do=revisions").'">'; 463 print '<img src="'.DOKU_BASE.'images/history.png" border="0" width="12" height="14" title="'.$lang['btn_revs'].'" />'; 464 print '</a> '; 465 466 print html_wikilink($id,$id); 467 468 print ' '.htmlspecialchars($recents[$id]['sum']); 469 print ' <span class="user">('; 470 print $recents[$id]['ip']; 471 if($recents[$id]['user']) print ' '.$recents[$id]['user']; 472 print ')</span>'; 473 474 print '</li>'; 475 } 476 print '</ul>'; 477} 478 479/** 480 * Display page index 481 * 482 * @author Andreas Gohr <andi@splitbrain.org> 483 */ 484function html_index($ns){ 485 require_once(DOKU_INC.'inc/search.php'); 486 global $conf; 487 global $ID; 488 $dir = $conf['datadir']; 489 $ns = cleanID($ns); 490 #fixme use appropriate function 491 if(empty($ns)){ 492 $ns = dirname(str_replace(':','/',$ID)); 493 if($ns == '.') $ns =''; 494 } 495 $ns = utf8_encodeFN(str_replace(':','/',$ns)); 496 497 print p_locale_xhtml('index'); 498 499 $data = array(); 500 search($data,$conf['datadir'],'search_index',array('ns' => $ns)); 501 print html_buildlist($data,'idx','html_list_index','html_li_index'); 502} 503 504/** 505 * Index item formatter 506 * 507 * User function for html_buildlist() 508 * 509 * @author Andreas Gohr <andi@splitbrain.org> 510 */ 511function html_list_index($item){ 512 $ret = ''; 513 $base = ':'.$item['id']; 514 $base = substr($base,strrpos($base,':')+1); 515 if($item['type']=='d'){ 516 $ret .= '<a href="'.wl($ID,'idx='.$item['id']).'" class="idx_dir">'; 517 $ret .= $base; 518 $ret .= '</a>'; 519 }else{ 520 $ret .= html_wikilink(':'.$item['id']); 521 } 522 return $ret; 523} 524 525/** 526 * Index List item 527 * 528 * This user function is used in html_build_lidt to build the 529 * <li> tags for namespaces when displaying the page index 530 * it gives different classes to opened or closed "folders" 531 * 532 * @author Andreas Gohr <andi@splitbrain.org> 533 */ 534function html_li_index($item){ 535 if($item['type'] == "f"){ 536 return '<li class="level'.$item['level'].'">'; 537 }elseif($item['open']){ 538 return '<li class="open">'; 539 }else{ 540 return '<li class="closed">'; 541 } 542} 543 544/** 545 * Default List item 546 * 547 * @author Andreas Gohr <andi@splitbrain.org> 548 */ 549function html_li_default($item){ 550 return '<li class="level'.$item['level'].'">'; 551} 552 553/** 554 * Build an unordered list 555 * 556 * Build an unordered list from the given $data array 557 * Each item in the array has to have a 'level' property 558 * the item itself gets printed by the given $func user 559 * function. The second and optional function is used to 560 * print the <li> tag. Both user function need to accept 561 * a single item. 562 * 563 * @author Andreas Gohr <andi@splitbrain.org> 564 */ 565function html_buildlist($data,$class,$func,$lifunc='html_li_default'){ 566 $level = 0; 567 $opens = 0; 568 $ret = ''; 569 570 foreach ($data as $item){ 571 572 if( $item['level'] > $level ){ 573 //open new list 574 for($i=0; $i<($item['level'] - $level); $i++){ 575 if ($i) $ret .= "<li class=\"clear\">\n"; 576 $ret .= "\n<ul class=\"$class\">\n"; 577 } 578 }elseif( $item['level'] < $level ){ 579 //close last item 580 $ret .= "</li>\n"; 581 for ($i=0; $i<($level - $item['level']); $i++){ 582 //close higher lists 583 $ret .= "</ul>\n</li>\n"; 584 } 585 }else{ 586 //close last item 587 $ret .= "</li>\n"; 588 } 589 590 //remember current level 591 $level = $item['level']; 592 593 //print item 594 $ret .= $lifunc($item); //user function 595 $ret .= '<span class="li">'; 596 $ret .= $func($item); //user function 597 $ret .= '</span>'; 598 } 599 600 //close remaining items and lists 601 for ($i=0; $i < $level; $i++){ 602 $ret .= "</li></ul>\n"; 603 } 604 605 return $ret; 606} 607 608/** 609 * display backlinks 610 * 611 * @author Andreas Gohr <andi@splitbrain.org> 612 */ 613function html_backlinks(){ 614 require_once(DOKU_INC.'inc/search.php'); 615 global $ID; 616 global $conf; 617 618 if(preg_match('#^(.*):(.*)$#',$ID,$matches)){ 619 $opts['ns'] = $matches[1]; 620 $opts['name'] = $matches[2]; 621 }else{ 622 $opts['ns'] = ''; 623 $opts['name'] = $ID; 624 } 625 626 print p_locale_xhtml('backlinks'); 627 628 $data = array(); 629 search($data,$conf['datadir'],'search_backlinks',$opts); 630 sort($data); 631 632 print '<ul class="idx">'; 633 foreach($data as $row){ 634 print '<li>'; 635 print html_wikilink(':'.$row['id'],$row['id']); 636 print '</li>'; 637 } 638 print '</ul>'; 639} 640 641/** 642 * show diff 643 * 644 * @author Andreas Gohr <andi@splitbrain.org> 645 */ 646function html_diff($text='',$intro=true){ 647 require_once(DOKU_INC.'inc/DifferenceEngine.php'); 648 global $ID; 649 global $REV; 650 global $lang; 651 global $conf; 652 if($text){ 653 $df = new Diff(split("\n",htmlspecialchars(rawWiki($ID,''))), 654 split("\n",htmlspecialchars(cleanText($text)))); 655 $left = '<a class="wikilink1" href="'.wl($ID).'">'. 656 $ID.' '.date($conf['dformat'],@filemtime(wikiFN($ID))).'</a>'. 657 $lang['current']; 658 $right = $lang['yours']; 659 }else{ 660 if($REV){ 661 $r = $REV; 662 }else{ 663 //use last revision if none given 664 $revs = getRevisions($ID); 665 $r = $revs[0]; 666 } 667 668 $df = new Diff(split("\n",htmlspecialchars(rawWiki($ID,$r))), 669 split("\n",htmlspecialchars(rawWiki($ID,'')))); 670 $left = '<a class="wikilink1" href="'.wl($ID,"rev=$r").'">'. 671 $ID.' '.date($conf['dformat'],$r).'</a>'; 672 $right = '<a class="wikilink1" href="'.wl($ID).'">'. 673 $ID.' '.date($conf['dformat'],@filemtime(wikiFN($ID))).'</a> '. 674 $lang['current']; 675 } 676 $tdf = new TableDiffFormatter(); 677 if($intro) print p_locale_xhtml('diff'); 678 ?> 679 <table class="diff" width="100%"> 680 <tr> 681 <td colspan="2" width="50%" class="diff-header"> 682 <?=$left?> 683 </td> 684 <td colspan="2" width="50%" class="diff-header"> 685 <?=$right?> 686 </td> 687 </tr> 688 <?=$tdf->format($df)?> 689 </table> 690 <? 691} 692 693/** 694 * show warning on conflict detection 695 * 696 * @author Andreas Gohr <andi@splitbrain.org> 697 */ 698function html_conflict($text,$summary){ 699 global $ID; 700 global $lang; 701 702 print p_locale_xhtml('conflict'); 703 ?> 704 <form name="editform" method="post" action="<?=script()?>" accept-charset="<?=$lang['encoding']?>"> 705 <input type="hidden" name="id" value="<?=$ID?>" /> 706 <input type="hidden" name="wikitext" value="<?=formText($text)?>" /> 707 <input type="hidden" name="summary" value="<?=formText($summary)?>" /> 708 709 <div align="center"> 710 <input class="button" type="submit" name="do" value="<?=$lang['btn_save']?>" accesskey="s" title="[ALT+S]" /> 711 <input class="button" type="submit" name="do" value="<?=$lang['btn_cancel']?>" /> 712 </div> 713 </form> 714 <br /><br /><br /><br /> 715 <? 716} 717 718/** 719 * Prints the global message array 720 * 721 * @author Andreas Gohr <andi@splitbrain.org> 722 */ 723function html_msgarea(){ 724 global $MSG; 725 726 if(!isset($MSG)) return; 727 728 foreach($MSG as $msg){ 729 print '<div class="'.$msg['lvl'].'">'; 730 print $msg['msg']; 731 print '</div>'; 732 } 733} 734 735/** 736 * Prints the registration form 737 * 738 * @author Andreas Gohr <andi@splitbrain.org> 739 */ 740function html_register(){ 741 global $lang; 742 global $ID; 743 744 print p_locale_xhtml('register'); 745?> 746 <div align="center"> 747 <form name="register" method="post" action="<?=wl($ID)?>" accept-charset="<?=$lang['encoding']?>"> 748 <input type="hidden" name="do" value="register" /> 749 <input type="hidden" name="save" value="1" /> 750 <fieldset> 751 <legend><?=$lang['register']?></legend> 752 <label> 753 <?=$lang['user']?> 754 <input type="text" name="login" class="edit" size="50" value="<?=formText($_POST['login'])?>" /> 755 </label><br /> 756 <label> 757 <?=$lang['fullname']?> 758 <input type="text" name="fullname" class="edit" size="50" value="<?=formText($_POST['fullname'])?>" /> 759 </label><br /> 760 <label> 761 <?=$lang['email']?> 762 <input type="text" name="email" class="edit" size="50" value="<?=formText($_POST['email'])?>" /> 763 </label><br /> 764 <input type="submit" class="button" value="<?=$lang['register']?>" /> 765 </fieldset> 766 </form> 767 </div> 768<? 769} 770 771/** 772 * This displays the edit form (lots of logic included) 773 * 774 * @author Andreas Gohr <andi@splitbrain.org> 775 */ 776function html_edit($text=null,$include='edit'){ //FIXME: include needed? 777 global $ID; 778 global $REV; 779 global $DATE; 780 global $RANGE; 781 global $PRE; 782 global $SUF; 783 global $INFO; 784 global $SUM; 785 global $lang; 786 global $conf; 787 788 //set summary default 789 if(!$SUM){ 790 if($REV){ 791 $SUM = $lang['restored']; 792 }elseif(!$INFO['exists']){ 793 $SUM = $lang['created']; 794 } 795 } 796 797 //no text? Load it! 798 if(!isset($text)){ 799 $pr = false; //no preview mode 800 if($RANGE){ 801 list($PRE,$text,$SUF) = rawWikiSlices($RANGE,$ID,$REV); 802 }else{ 803 $text = rawWiki($ID,$REV); 804 } 805 }else{ 806 $pr = true; //preview mode 807 } 808 809 $wr = $INFO['writable']; 810 if($wr){ 811 if ($REV) print p_locale_xhtml('editrev'); 812 print p_locale_xhtml($include); 813 }else{ 814 print p_locale_xhtml('read'); 815 $ro='readonly="readonly"'; 816 } 817 if(!$DATE) $DATE = $INFO['lastmod']; 818?> 819 <form name="editform" method="post" action="<?=script()?>" accept-charset="<?=$lang['encoding']?>" onsubmit="return svchk()"> 820 <input type="hidden" name="id" value="<?=$ID?>" /> 821 <input type="hidden" name="rev" value="<?=$REV?>" /> 822 <input type="hidden" name="date" value="<?=$DATE?>" /> 823 <input type="hidden" name="prefix" value="<?=formText($PRE)?>" /> 824 <input type="hidden" name="suffix" value="<?=formText($SUF)?>" /> 825 <table style="width:99%"> 826 <tr> 827 <td class="toolbar" colspan="3"> 828 <?if($wr){?> 829 <script language="JavaScript" type="text/javascript"> 830 <?/* sets changed to true when previewed */?> 831 textChanged = <? ($pr) ? print 'true' : print 'false' ?>; 832 833 formatButton('images/bold.png','<?=$lang['qb_bold']?>','**','**','<?=$lang['qb_bold']?>','b'); 834 formatButton('images/italic.png','<?=$lang['qb_italic']?>',"\/\/","\/\/",'<?=$lang['qb_italic']?>','i'); 835 formatButton('images/underline.png','<?=$lang['qb_underl']?>','__','__','<?=$lang['qb_underl']?>','u'); 836 formatButton('images/code.png','<?=$lang['qb_code']?>','\'\'','\'\'','<?=$lang['qb_code']?>','c'); 837 838 formatButton('images/fonth1.png','<?=$lang['qb_h1']?>','====== ',' ======\n','<?=$lang['qb_h1']?>','1'); 839 formatButton('images/fonth2.png','<?=$lang['qb_h2']?>','===== ',' =====\n','<?=$lang['qb_h2']?>','2'); 840 formatButton('images/fonth3.png','<?=$lang['qb_h3']?>','==== ',' ====\n','<?=$lang['qb_h3']?>','3'); 841 formatButton('images/fonth4.png','<?=$lang['qb_h4']?>','=== ',' ===\n','<?=$lang['qb_h4']?>','4'); 842 formatButton('images/fonth5.png','<?=$lang['qb_h5']?>','== ',' ==\n','<?=$lang['qb_h5']?>','5'); 843 844 formatButton('images/link.png','<?=$lang['qb_link']?>','[[',']]','<?=$lang['qb_link']?>','l'); 845 formatButton('images/extlink.png','<?=$lang['qb_extlink']?>','[[',']]','http://www.example.com|<?=$lang['qb_extlink']?>'); 846 847 formatButton('images/list.png','<?=$lang['qb_ol']?>',' - ','\n','<?=$lang['qb_ol']?>'); 848 formatButton('images/list_ul.png','<?=$lang['qb_ul']?>',' * ','\n','<?=$lang['qb_ul']?>'); 849 850 insertButton('images/rule.png','<?=$lang['qb_hr']?>','----\n'); 851 mediaButton('images/image.png','<?=$lang['qb_media']?>','m','<?=$INFO['namespace']?>'); 852 853 <? 854 if($conf['useacl'] && $_SERVER['REMOTE_USER']){ 855 echo "insertButton('images/sig.png','".$lang['qb_sig']."','".html_signature()."','y');"; 856 } 857 ?> 858 </script> 859 <?}?> 860 </td> 861 </tr> 862 <tr> 863 <td colspan="3"> 864 <textarea name="wikitext" id="wikitext" <?=$ro?> cols="80" rows="10" class="edit" onchange="textChanged = true;" onkeyup="summaryCheck();" tabindex="1"><?="\n".formText($text)?></textarea> 865 </td> 866 </tr> 867 <tr> 868 <td> 869 <?if($wr){?> 870 <input class="button" type="submit" name="do" value="<?=$lang['btn_save']?>" accesskey="s" title="[ALT+S]" onclick="textChanged=false" onkeypress="textChanged=false" tabindex="3" /> 871 <input class="button" type="submit" name="do" value="<?=$lang['btn_preview']?>" accesskey="p" title="[ALT+P]" onclick="textChanged=false" onkeypress="textChanged=false" tabindex="4" /> 872 <input class="button" type="submit" name="do" value="<?=$lang['btn_cancel']?>" tabindex="5" /> 873 <?}?> 874 </td> 875 <td> 876 <?if($wr){?> 877 <?=$lang['summary']?>: 878 <input type="text" class="edit" name="summary" id="summary" size="50" onkeyup="summaryCheck();" value="<?=formText($SUM)?>" tabindex="2" /> 879 <?}?> 880 </td> 881 <td align="right"> 882 <script type="text/javascript"> 883 showSizeCtl(); 884 <?if($wr){?> 885 init_locktimer(<?=$conf['locktime']-60?>,'<?=$lang['willexpire']?>'); 886 document.editform.wikitext.focus(); 887 <?}?> 888 </script> 889 </td> 890 </tr> 891 </table> 892 </form> 893<? 894} 895 896/** 897 * prepares the signature string as configured in the config 898 * 899 * @author Andreas Gohr <andi@splitbrain.org> 900 */ 901function html_signature(){ 902 global $conf; 903 global $INFO; 904 905 $sig = $conf['signature']; 906 $sig = strftime($sig); 907 $sig = str_replace('@USER@',$_SERVER['REMOTE_USER'],$sig); 908 $sig = str_replace('@NAME@',$INFO['userinfo']['name'],$sig); 909 $sig = str_replace('@MAIL@',$INFO['userinfo']['mail'],$sig); 910 $sig = str_replace('@DATE@',date($conf['dformat']),$sig); 911 return $sig; 912} 913 914/** 915 * prints some debug info 916 * 917 * @author Andreas Gohr <andi@splitbrain.org> 918 */ 919function html_debug(){ 920 global $conf; 921 global $lang; 922 //remove sensitive data 923 $cnf = $conf; 924 $cnf['auth']='***'; 925 $cnf['notify']='***'; 926 $cnf['ftp']='***'; 927 928 print '<html><body>'; 929 930 print '<p>When reporting bugs please send all the following '; 931 print 'output as a mail to andi@splitbrain.org '; 932 print 'The best way to do this is to save this page in your browser</p>'; 933 934 print '<b>$_SERVER:</b><pre>'; 935 print_r($_SERVER); 936 print '</pre>'; 937 938 print '<b>$conf:</b><pre>'; 939 print_r($cnf); 940 print '</pre>'; 941 942 print '<b>DOKU_BASE:</b><pre>'; 943 print DOKU_BASE; 944 print '</pre>'; 945 946 print '<b>abs DOKU_BASE:</b><pre>'; 947 print DOKU_URL; 948 print '</pre>'; 949 950 print '<b>rel DOKU_BASE:</b><pre>'; 951 print dirname($_SERVER['PHP_SELF']).'/'; 952 print '</pre>'; 953 954 print '<b>PHP Version:</b><pre>'; 955 print phpversion(); 956 print '</pre>'; 957 958 print '<b>locale:</b><pre>'; 959 print setlocale(LC_ALL,0); 960 print '</pre>'; 961 962 print '<b>encoding:</b><pre>'; 963 print $lang['encoding']; 964 print '</pre>'; 965 966 print '<b>Environment:</b><pre>'; 967 print_r($_ENV); 968 print '</pre>'; 969 970 print '<b>PHP settings:</b><pre>'; 971 $inis = ini_get_all(); 972 print_r($inis); 973 print '</pre>'; 974 975 print '</body></html>'; 976} 977 978/** 979 * Print the admin overview page 980 * 981 * @author Andreas Gohr <andi@splitbrain.org> 982 */ 983function html_admin(){ 984 global $ID; 985 global $lang; 986 987 print p_locale_xhtml('admin'); 988 989 ptln('<ul class="admin">'); 990 991 // currently ACL only - more to come 992 ptln('<li><a href="'.wl($ID,'do=admin&page=acl').'">'.$lang['admin_acl'].'</a></li>'); 993 994 ptln('</ul>'); 995} 996 997 998//Setup VIM: ex: et ts=2 enc=utf-8 : 999