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='',$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($text || $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 print '<img src="'.DOKU_BASE.'images/blank.gif" border="0" width="15" height="11" alt="" /> '; 399 400 print $date.' <a class="wikilink1" href="'.wl($ID).'">'.$ID.'</a> '; 401 402 print $INFO['sum']; 403 print ' <span class="user">('; 404 print $INFO['ip']; 405 if($INFO['user']) print ' '.$INFO['user']; 406 print ')</span> '; 407 408 print '('.$lang['current'].')'; 409 print '</li>'; 410 } 411 412 foreach($revisions as $rev){ 413 $date = date($conf['dformat'],$rev); 414 $info = getRevisionInfo($ID,$rev); 415 416 print '<li>'; 417 print '<a href="'.wl($ID,"rev=$rev,do=diff").'">'; 418 print '<img src="'.DOKU_BASE.'images/diff.png" border="0" width="15" height="11" title="'.$lang['diff'].'" />'; 419 print '</a> '; 420 421 print $date.' <a class="wikilink1" href="'.wl($ID,"rev=$rev").'">'.$ID.'</a> '; 422 print $info['sum']; 423 print ' <span class="user">('; 424 print $info['ip']; 425 if($info['user']) print ' '.$info['user']; 426 print ')</span>'; 427 428 print '</li>'; 429 } 430 print '</ul>'; 431} 432 433/** 434 * display recent changes 435 * 436 * @author Andreas Gohr <andi@splitbrain.org> 437 */ 438function html_recent(){ 439 global $conf; 440 global $lang; 441 $recents = getRecents(0,true); 442 443 print p_locale_xhtml('recent'); 444 print '<ul>'; 445 foreach(array_keys($recents) as $id){ 446 $date = date($conf['dformat'],$recents[$id]['date']); 447 print '<li>'; 448 449 print '<a href="'.wl($id,"do=diff").'">'; 450 print '<img src="'.DOKU_BASE.'images/diff.png" border="0" width="15" height="11" title="'.$lang['diff'].'" />'; 451 print '</a> '; 452 453 print '<a href="'.wl($id,"do=revisions").'">'; 454 print '<img src="'.DOKU_BASE.'images/history.png" border="0" width="12" height="14" title="'.$lang['btn_revs'].'" />'; 455 print '</a> '; 456 457 458 print $date.' '.html_wikilink($id,$id); 459 print htmlspecialchars($recents[$id]['sum']); 460 print ' <span class="user">('; 461 print $recents[$id]['ip']; 462 if($recents[$id]['user']) print ' '.$recents[$id]['user']; 463 print ')</span>'; 464 465 print '</li>'; 466 } 467 print '</ul>'; 468} 469 470/** 471 * Display page index 472 * 473 * @author Andreas Gohr <andi@splitbrain.org> 474 */ 475function html_index($ns){ 476 require_once(DOKU_INC.'inc/search.php'); 477 global $conf; 478 global $ID; 479 $dir = $conf['datadir']; 480 $ns = cleanID($ns); 481 if(empty($ns)){ 482 $ns = dirname(str_replace(':','/',$ID)); 483 if($ns == '.') $ns =''; 484 } 485 $ns = utf8_encodeFN(str_replace(':','/',$ns)); 486 487 print p_locale_xhtml('index'); 488 489 $data = array(); 490 search($data,$conf['datadir'],'search_index',array('ns' => $ns)); 491 print html_buildlist($data,'idx','html_list_index','html_li_index'); 492} 493 494/** 495 * Index item formatter 496 * 497 * User function for html_buildlist() 498 * 499 * @author Andreas Gohr <andi@splitbrain.org> 500 */ 501function html_list_index($item){ 502 $ret = ''; 503 $base = ':'.$item['id']; 504 $base = substr($base,strrpos($base,':')+1); 505 if($item['type']=='d'){ 506 $ret .= '<a href="'.wl($ID,'idx='.$item['id']).'" class="idx_dir">'; 507 $ret .= $base; 508 $ret .= '</a>'; 509 }else{ 510 $ret .= html_wikilink(':'.$item['id']); 511 } 512 return $ret; 513} 514 515/** 516 * Index List item 517 * 518 * This user function is used in html_build_lidt to build the 519 * <li> tags for namespaces when displaying the page index 520 * it gives different classes to opened or closed "folders" 521 * 522 * @author Andreas Gohr <andi@splitbrain.org> 523 */ 524function html_li_index($item){ 525 if($item['type'] == "f"){ 526 return '<li class="level'.$item['level'].'">'; 527 }elseif($item['open']){ 528 return '<li class="open">'; 529 }else{ 530 return '<li class="closed">'; 531 } 532} 533 534/** 535 * Default List item 536 * 537 * @author Andreas Gohr <andi@splitbrain.org> 538 */ 539function html_li_default($item){ 540 return '<li class="level'.$item['level'].'">'; 541} 542 543/** 544 * Build an unordered list 545 * 546 * Build an unordered list from the given $data array 547 * Each item in the array has to have a 'level' property 548 * the item itself gets printed by the given $func user 549 * function. The second and optional function is used to 550 * print the <li> tag. Both user function need to accept 551 * a single item. 552 * 553 * @author Andreas Gohr <andi@splitbrain.org> 554 */ 555function html_buildlist($data,$class,$func,$lifunc='html_li_default'){ 556 $level = 0; 557 $opens = 0; 558 $ret = ''; 559 560 foreach ($data as $item){ 561 562 if( $item['level'] > $level ){ 563 //open new list 564 for($i=0; $i<($item['level'] - $level); $i++){ 565 if ($i) $ret .= "<li class=\"clear\">\n"; 566 $ret .= "\n<ul class=\"$class\">\n"; 567 } 568 }elseif( $item['level'] < $level ){ 569 //close last item 570 $ret .= "</li>\n"; 571 for ($i=0; $i<($level - $item['level']); $i++){ 572 //close higher lists 573 $ret .= "</ul>\n</li>\n"; 574 } 575 }else{ 576 //close last item 577 $ret .= "</li>\n"; 578 } 579 580 //remember current level 581 $level = $item['level']; 582 583 //print item 584 $ret .= $lifunc($item); //user function 585 $ret .= '<span class="li">'; 586 $ret .= $func($item); //user function 587 $ret .= '</span>'; 588 } 589 590 //close remaining items and lists 591 for ($i=0; $i < $level; $i++){ 592 $ret .= "</li></ul>\n"; 593 } 594 595 return $ret; 596} 597 598/** 599 * display backlinks 600 * 601 * @author Andreas Gohr <andi@splitbrain.org> 602 */ 603function html_backlinks(){ 604 require_once(DOKU_INC.'inc/search.php'); 605 global $ID; 606 global $conf; 607 608 if(preg_match('#^(.*):(.*)$#',$ID,$matches)){ 609 $opts['ns'] = $matches[1]; 610 $opts['name'] = $matches[2]; 611 }else{ 612 $opts['ns'] = ''; 613 $opts['name'] = $ID; 614 } 615 616 print p_locale_xhtml('backlinks'); 617 618 $data = array(); 619 search($data,$conf['datadir'],'search_backlinks',$opts); 620 sort($data); 621 622 print '<ul class="idx">'; 623 foreach($data as $row){ 624 print '<li>'; 625 print html_wikilink(':'.$row['id'],$row['id']); 626 print '</li>'; 627 } 628 print '</ul>'; 629} 630 631/** 632 * show diff 633 * 634 * @author Andreas Gohr <andi@splitbrain.org> 635 */ 636function html_diff($text='',$intro=true){ 637 require_once(DOKU_INC.'inc/DifferenceEngine.php'); 638 global $ID; 639 global $REV; 640 global $lang; 641 global $conf; 642 if($text){ 643 $df = new Diff(split("\n",htmlspecialchars(rawWiki($ID,''))), 644 split("\n",htmlspecialchars(cleanText($text)))); 645 $left = '<a class="wikilink1" href="'.wl($ID).'">'. 646 $ID.' '.date($conf['dformat'],@filemtime(wikiFN($ID))).'</a>'. 647 $lang['current']; 648 $right = $lang['yours']; 649 }else{ 650 if($REV){ 651 $r = $REV; 652 }else{ 653 //use last revision if none given 654 $revs = getRevisions($ID); 655 $r = $revs[0]; 656 } 657 658 $df = new Diff(split("\n",htmlspecialchars(rawWiki($ID,$r))), 659 split("\n",htmlspecialchars(rawWiki($ID,'')))); 660 $left = '<a class="wikilink1" href="'.wl($ID,"rev=$r").'">'. 661 $ID.' '.date($conf['dformat'],$r).'</a>'; 662 $right = '<a class="wikilink1" href="'.wl($ID).'">'. 663 $ID.' '.date($conf['dformat'],@filemtime(wikiFN($ID))).'</a> '. 664 $lang['current']; 665 } 666 $tdf = new TableDiffFormatter(); 667 if($intro) print p_locale_xhtml('diff'); 668 ?> 669 <table class="diff" width="100%"> 670 <tr> 671 <td colspan="2" width="50%" class="diff-header"> 672 <?=$left?> 673 </td> 674 <td colspan="2" width="50%" class="diff-header"> 675 <?=$right?> 676 </td> 677 </tr> 678 <?=$tdf->format($df)?> 679 </table> 680 <? 681} 682 683/** 684 * show warning on conflict detection 685 * 686 * @author Andreas Gohr <andi@splitbrain.org> 687 */ 688function html_conflict($text,$summary){ 689 global $ID; 690 global $lang; 691 692 print p_locale_xhtml('conflict'); 693 ?> 694 <form name="editform" method="post" action="<?=script()?>" accept-charset="<?=$lang['encoding']?>"> 695 <input type="hidden" name="id" value="<?=$ID?>" /> 696 <input type="hidden" name="wikitext" value="<?=formText($text)?>" /> 697 <input type="hidden" name="summary" value="<?=formText($summary)?>" /> 698 699 <div align="center"> 700 <input class="button" type="submit" name="do" value="<?=$lang['btn_save']?>" accesskey="s" title="[ALT+S]" /> 701 <input class="button" type="submit" name="do" value="<?=$lang['btn_cancel']?>" /> 702 </div> 703 </form> 704 <br /><br /><br /><br /> 705 <? 706} 707 708/** 709 * Prints the global message array 710 * 711 * @author Andreas Gohr <andi@splitbrain.org> 712 */ 713function html_msgarea(){ 714 global $MSG; 715 716 if(!isset($MSG)) return; 717 718 foreach($MSG as $msg){ 719 print '<div class="'.$msg['lvl'].'">'; 720 print $msg['msg']; 721 print '</div>'; 722 } 723} 724 725/** 726 * Prints the registration form 727 * 728 * @author Andreas Gohr <andi@splitbrain.org> 729 */ 730function html_register(){ 731 global $lang; 732 global $ID; 733 734 print p_locale_xhtml('register'); 735?> 736 <div align="center"> 737 <form name="register" method="post" action="<?=wl($ID)?>" accept-charset="<?=$lang['encoding']?>"> 738 <input type="hidden" name="do" value="register" /> 739 <input type="hidden" name="save" value="1" /> 740 <fieldset> 741 <legend><?=$lang['register']?></legend> 742 <label> 743 <?=$lang['user']?> 744 <input type="text" name="login" class="edit" size="50" value="<?=formText($_POST['login'])?>" /> 745 </label><br /> 746 <label> 747 <?=$lang['fullname']?> 748 <input type="text" name="fullname" class="edit" size="50" value="<?=formText($_POST['fullname'])?>" /> 749 </label><br /> 750 <label> 751 <?=$lang['email']?> 752 <input type="text" name="email" class="edit" size="50" value="<?=formText($_POST['email'])?>" /> 753 </label><br /> 754 <input type="submit" class="button" value="<?=$lang['register']?>" /> 755 </fieldset> 756 </form> 757 </div> 758<? 759} 760 761/** 762 * This displays the edit form (lots of logic included) 763 * 764 * @author Andreas Gohr <andi@splitbrain.org> 765 */ 766function html_edit($text=null,$include='edit'){ //FIXME: include needed? 767 global $ID; 768 global $REV; 769 global $DATE; 770 global $RANGE; 771 global $PRE; 772 global $SUF; 773 global $INFO; 774 global $SUM; 775 global $lang; 776 global $conf; 777 778 //set summary default 779 if(!$SUM){ 780 if($REV){ 781 $SUM = $lang['restored']; 782 }elseif(!$INFO['exists']){ 783 $SUM = $lang['created']; 784 } 785 } 786 787 //no text? Load it! 788 if(!isset($text)){ 789 $pr = false; //no preview mode 790 if($RANGE){ 791 list($PRE,$text,$SUF) = rawWikiSlices($RANGE,$ID,$REV); 792 }else{ 793 $text = rawWiki($ID,$REV); 794 } 795 }else{ 796 $pr = true; //preview mode 797 } 798 799 $wr = $INFO['writable']; 800 if($wr){ 801 if ($REV) print p_locale_xhtml('editrev'); 802 print p_locale_xhtml($include); 803 }else{ 804 print p_locale_xhtml('read'); 805 $ro='readonly="readonly"'; 806 } 807 if(!$DATE) $DATE = $INFO['lastmod']; 808?> 809 <form name="editform" method="post" action="<?=script()?>" accept-charset="<?=$lang['encoding']?>" onsubmit="return svchk()"> 810 <input type="hidden" name="id" value="<?=$ID?>" /> 811 <input type="hidden" name="rev" value="<?=$REV?>" /> 812 <input type="hidden" name="date" value="<?=$DATE?>" /> 813 <input type="hidden" name="prefix" value="<?=formText($PRE)?>" /> 814 <input type="hidden" name="suffix" value="<?=formText($SUF)?>" /> 815 <table style="width:99%"> 816 <tr> 817 <td class="toolbar" colspan="3"> 818 <?if($wr){?> 819 <script language="JavaScript" type="text/javascript"> 820 <?/* sets changed to true when previewed */?> 821 textChanged = <? ($pr) ? print 'true' : print 'false' ?>; 822 823 formatButton('images/bold.png','<?=$lang['qb_bold']?>','**','**','<?=$lang['qb_bold']?>','b'); 824 formatButton('images/italic.png','<?=$lang['qb_italic']?>',"\/\/","\/\/",'<?=$lang['qb_italic']?>','i'); 825 formatButton('images/underline.png','<?=$lang['qb_underl']?>','__','__','<?=$lang['qb_underl']?>','u'); 826 formatButton('images/code.png','<?=$lang['qb_code']?>','\'\'','\'\'','<?=$lang['qb_code']?>','c'); 827 828 formatButton('images/fonth1.png','<?=$lang['qb_h1']?>','====== ',' ======\n','<?=$lang['qb_h1']?>','1'); 829 formatButton('images/fonth2.png','<?=$lang['qb_h2']?>','===== ',' =====\n','<?=$lang['qb_h2']?>','2'); 830 formatButton('images/fonth3.png','<?=$lang['qb_h3']?>','==== ',' ====\n','<?=$lang['qb_h3']?>','3'); 831 formatButton('images/fonth4.png','<?=$lang['qb_h4']?>','=== ',' ===\n','<?=$lang['qb_h4']?>','4'); 832 formatButton('images/fonth5.png','<?=$lang['qb_h5']?>','== ',' ==\n','<?=$lang['qb_h5']?>','5'); 833 834 formatButton('images/link.png','<?=$lang['qb_link']?>','[[',']]','<?=$lang['qb_link']?>','l'); 835 formatButton('images/extlink.png','<?=$lang['qb_extlink']?>','[[',']]','http://www.example.com|<?=$lang['qb_extlink']?>'); 836 837 formatButton('images/list.png','<?=$lang['qb_ol']?>',' - ','\n','<?=$lang['qb_ol']?>'); 838 formatButton('images/list_ul.png','<?=$lang['qb_ul']?>',' * ','\n','<?=$lang['qb_ul']?>'); 839 840 insertButton('images/rule.png','<?=$lang['qb_hr']?>','----\n'); 841 mediaButton('images/image.png','<?=$lang['qb_media']?>','m','<?=$INFO['namespace']?>'); 842 843 <? 844 if($conf['useacl'] && $_SERVER['REMOTE_USER']){ 845 echo "insertButton('images/sig.png','".$lang['qb_sig']."','".html_signature()."','y');"; 846 } 847 ?> 848 </script> 849 <?}?> 850 </td> 851 </tr> 852 <tr> 853 <td colspan="3"> 854 <textarea name="wikitext" id="wikitext" <?=$ro?> cols="80" rows="10" class="edit" onchange="textChanged = true;" onkeyup="summaryCheck();" tabindex="1"><?="\n".formText($text)?></textarea> 855 </td> 856 </tr> 857 <tr> 858 <td> 859 <?if($wr){?> 860 <input class="button" type="submit" name="do" value="<?=$lang['btn_save']?>" accesskey="s" title="[ALT+S]" onclick="textChanged=false" onkeypress="textChanged=false" tabindex="3" /> 861 <input class="button" type="submit" name="do" value="<?=$lang['btn_preview']?>" accesskey="p" title="[ALT+P]" onclick="textChanged=false" onkeypress="textChanged=false" tabindex="4" /> 862 <input class="button" type="submit" name="do" value="<?=$lang['btn_cancel']?>" tabindex="5" /> 863 <?}?> 864 </td> 865 <td> 866 <?if($wr){?> 867 <?=$lang['summary']?>: 868 <input type="text" class="edit" name="summary" id="summary" size="50" onkeyup="summaryCheck();" value="<?=formText($SUM)?>" tabindex="2" /> 869 <?}?> 870 </td> 871 <td align="right"> 872 <script type="text/javascript"> 873 showSizeCtl(); 874 <?if($wr){?> 875 init_locktimer(<?=$conf['locktime']-60?>,'<?=$lang['willexpire']?>'); 876 document.editform.wikitext.focus(); 877 <?}?> 878 </script> 879 </td> 880 </tr> 881 </table> 882 </form> 883<? 884} 885 886/** 887 * prepares the signature string as configured in the config 888 * 889 * @author Andreas Gohr <andi@splitbrain.org> 890 */ 891function html_signature(){ 892 global $conf; 893 global $INFO; 894 895 $sig = $conf['signature']; 896 $sig = strftime($sig); 897 $sig = str_replace('@USER@',$_SERVER['REMOTE_USER'],$sig); 898 $sig = str_replace('@NAME@',$INFO['userinfo']['name'],$sig); 899 $sig = str_replace('@MAIL@',$INFO['userinfo']['mail'],$sig); 900 $sig = str_replace('@DATE@',date($conf['dformat']),$sig); 901 return $sig; 902} 903 904/** 905 * prints some debug info 906 * 907 * @author Andreas Gohr <andi@splitbrain.org> 908 */ 909function html_debug(){ 910 global $conf; 911 global $lang; 912 //remove sensitive data 913 $cnf = $conf; 914 $cnf['auth']='***'; 915 $cnf['notify']='***'; 916 $cnf['ftp']='***'; 917 918 print '<html><body>'; 919 920 print '<p>When reporting bugs please send all the following '; 921 print 'output as a mail to andi@splitbrain.org '; 922 print 'The best way to do this is to save this page in your browser</p>'; 923 924 print '<b>$_SERVER:</b><pre>'; 925 print_r($_SERVER); 926 print '</pre>'; 927 928 print '<b>$conf:</b><pre>'; 929 print_r($cnf); 930 print '</pre>'; 931 932 print '<b>DOKU_BASE:</b><pre>'; 933 print DOKU_BASE; 934 print '</pre>'; 935 936 print '<b>abs DOKU_BASE:</b><pre>'; 937 print DOKU_URL; 938 print '</pre>'; 939 940 print '<b>rel DOKU_BASE:</b><pre>'; 941 print dirname($_SERVER['PHP_SELF']).'/'; 942 print '</pre>'; 943 944 print '<b>PHP Version:</b><pre>'; 945 print phpversion(); 946 print '</pre>'; 947 948 print '<b>locale:</b><pre>'; 949 print setlocale(LC_ALL,0); 950 print '</pre>'; 951 952 print '<b>encoding:</b><pre>'; 953 print $lang['encoding']; 954 print '</pre>'; 955 956 print '<b>Environment:</b><pre>'; 957 print_r($_ENV); 958 print '</pre>'; 959 960 print '<b>PHP settings:</b><pre>'; 961 $inis = ini_get_all(); 962 print_r($inis); 963 print '</pre>'; 964 965 print '</body></html>'; 966} 967 968/** 969 * Print the admin overview page 970 * 971 * @author Andreas Gohr <andi@splitbrain.org> 972 */ 973function html_admin(){ 974 global $ID; 975 global $lang; 976 977 print p_locale_xhtml('admin'); 978 979 ptln('<ul class="admin">'); 980 981 // currently ACL only - more to come 982 ptln('<li><a href="'.wl($ID,'do=admin&page=acl').'">'.$lang['admin_acl'].'</a></li>'); 983 984 ptln('</ul>'); 985} 986 987 988//Setup VIM: ex: et ts=2 enc=utf-8 : 989