1<? 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 include_once("inc/format.php"); 10 11/** 12 * Convenience function to quickly build a wikilink 13 * 14 * @author Andreas Gohr <andi@splitbrain.org> 15 */ 16function html_wikilink($url,$name='',$search=''){ 17 global $conf; 18 $link = array(); 19 $link['url'] = $url; 20 $link['name'] = $name; 21 $link = format_link_wiki($link); 22 23 if($search){ 24 ($conf['userewrite']) ? $link['url'].='?s=' : $link['url'].='&s='; 25 $link['url'] .= urlencode($search); 26 } 27 28 return format_link_build($link); 29} 30 31/** 32 * The loginform 33 * 34 * @author Andreas Gohr <andi@splitbrain.org> 35 */ 36function html_login(){ 37 global $lang; 38 global $conf; 39 global $ID; 40 41 print parsedLocale('login'); 42 ?> 43 <div align="center"> 44 <form action="<?=script()?>" accept-charset="<?=$lang['encoding']?>" method="post"> 45 <fieldset> 46 <legend><?=$lang['btn_login']?></legend> 47 <input type="hidden" name="id" value="<?=$ID?>" /> 48 <input type="hidden" name="do" value="login" /> 49 <label> 50 <span><?=$lang['user']?></span> 51 <input type="text" name="u" value="<?=formText($_REQUEST['u'])?>" class="edit" /> 52 </label><br /> 53 <label> 54 <span><?=$lang['pass']?></span> 55 <input type="password" name="p" class="edit" /> 56 </label><br /> 57 <input type="submit" value="<?=$lang['btn_login']?>" class="button" /> 58 <label for="remember" class="simple"> 59 <input type="checkbox" name="r" id="remember" value="1" /> 60 <span><?=$lang['remember']?></span> 61 </label> 62 </fieldset> 63 </form> 64 <? 65 if($conf['openregister']){ 66 print '<p>'; 67 print $lang['reghere']; 68 print ': <a href="'.wl($ID,'do=register').'" class="wikilink1">'.$lang['register'].'</a>'; 69 print '</p>'; 70 } 71 ?> 72 </div> 73 <? 74 if(@file_exists('includes/login.txt')){ 75 print io_cacheParse('includes/login.txt'); 76 } 77} 78 79/** 80 * shows the edit/source/show button dependent on current mode 81 * 82 * @author Andreas Gohr <andi@splitbrain.org> 83 */ 84function html_editbutton(){ 85 global $ID; 86 global $REV; 87 global $ACT; 88 global $INFO; 89 90 if($ACT == 'show' || $ACT == 'search'){ 91 if($INFO['writable']){ 92 if($INFO['exists']){ 93 $r = html_btn('edit',$ID,'e',array('do' => 'edit','rev' => $REV),'post'); 94 }else{ 95 $r = html_btn('create',$ID,'e',array('do' => 'edit','rev' => $REV),'post'); 96 } 97 }else{ 98 $r = html_btn('source',$ID,'v',array('do' => 'edit','rev' => $REV),'post'); 99 } 100 }else{ 101 $r = html_btn('show',$ID,'v',array('do' => 'show')); 102 } 103 return $r; 104} 105 106/** 107 * prints a section editing button 108 * 109 * @author Andreas Gohr <andi@splitbrain.org> 110 */ 111function html_secedit_button($section,$p){ 112 global $ID; 113 global $lang; 114 $secedit = ''; 115 if($p) $secedit .= "</p>\n"; 116 $secedit .= '<div class="secedit">'; 117 $secedit .= html_btn('secedit',$ID,'', 118 array('do' => 'edit', 119 'lines' => "$section"), 120 'post'); 121 $secedit .= '</div>'; 122 if($p) $secedit .= "\n<p>"; 123 return $secedit; 124} 125 126/** 127 * inserts section edit buttons if wanted or removes the markers 128 * 129 * @author Andreas Gohr <andi@splitbrain.org> 130 */ 131function html_secedit($text,$show=true){ 132 global $INFO; 133 if($INFO['writable'] && $show){ 134 $text = preg_replace('#<!-- SECTION \[(\d+-\d+)\] -->#e', 135 "html_secedit_button('\\1',true)", 136 $text); 137 $text = preg_replace('#<!-- SECTION \[(\d+-)\] -->#e', 138 "html_secedit_button('\\1',false)", 139 $text); 140 }else{ 141 $text = preg_replace('#<!-- SECTION \[(\d*-\d*)\] -->#e','',$text); 142 } 143 return $text; 144} 145 146/** 147 * displays the breadcrumbs trace 148 * 149 * @author Andreas Gohr <andi@splitbrain.org> 150 */ 151function html_breadcrumbs(){ 152 global $lang; 153 global $conf; 154 155 //check if enabled 156 if(!$conf['breadcrumbs']) return; 157 158 $crumbs = breadcrumbs(); //setup crumb trace 159 print '<div class="breadcrumbs">'; 160 print $lang['breadcrumb'].':'; 161 foreach ($crumbs as $crumb){ 162 print ' » '; 163 print '<a href="'.wl($crumb).'" class="breadcrumbs" onclick="return svchk()" onkeypress="return svchk()" title="'.$crumb.'">'.noNS($crumb).'</a>'; 164 } 165 print '</div>'; 166} 167 168/** 169 * display the HTML head and metadata 170 * 171 * @author Andreas Gohr <andi@splitbrain.org> 172 */ 173function html_head(){ 174 global $ID; 175 global $ACT; 176 global $INFO; 177 global $conf; 178 global $lang; 179 180 print '<'.'?xml version="1.0"?'.">\n"; 181 print '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'; 182 print ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'; 183 print "\n"; 184?> 185 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?=$conf['lang']?>" lang="<?=$conf['lang']?>" dir="ltr"> 186 <head> 187 <title><?=$ID?> [<?=$conf['title']?>]</title> 188 <meta http-equiv="Content-Type" content="text/html; charset=<?=$lang['encoding']?>" /> 189 <meta name="generator" content="DokuWiki <?=DOKUWIKIVERSION?>" /> 190 <link rel="stylesheet" media="screen" type="text/css" href="<?=getBaseURL()?>style.css" /> 191 <link rel="stylesheet" media="print" type="text/css" href="<?=getBaseURL()?>print.css" /> 192 <link rel="shortcut icon" href="<?=getBaseURL()?>images/favicon.ico" /> 193 <link rel="start" href="<?=wl()?>" /> 194 <link rel="contents" href="<?=wl($ID,'do=index')?>" title="<?=$lang['index']?>" /> 195 <link rel="alternate" type="application/rss+xml" title="Recent Changes" href="<?=getBaseURL()?>feed.php" /> 196 <link rel="alternate" type="application/rss+xml" title="Current Namespace" href="<?=getBaseURL()?>feed.php?mode=list&ns=<?=$INFO['namespace']?>" /> 197 <link rel="alternate" type="text/html" title="Plain HTML" href="<?=wl($ID,'do=export_html')?>" /> 198 <link rel="alternate" type="text/plain" title="Wiki Markup" href="<?=wl($ID, 'do=export_raw')?>" /> 199<? 200 if($ACT=='show' || $ACT=='export_html'){ 201 if($INFO['exists']){ 202 print ' <meta name="robots" content="index,follow" />'."\n"; 203 print ' <meta name="date" content="'.date('Y-m-d\TH:i:sO',$INFO['lastmod']).'" />'."\n"; 204 }else{ 205 print ' <meta name="robots" content="noindex,follow" />'."\n"; 206 } 207 }else{ 208 print ' <meta name="robots" content="noindex,nofollow" />'."\n"; 209 } 210?> 211 212 <script language="JavaScript" type="text/javascript"> 213 var alertText = '<?=$lang['qb_alert']?>'; 214 var notSavedYet = '<?=$lang['notsavedyet']?>'; 215 var baseURL = '<?=getBaseURL()?>'; 216 </script> 217 <script language="JavaScript" type="text/javascript" src="<?=getBaseURL()?>script.js"></script> 218 219 <!--[if gte IE 5]> 220 <style type="text/css"> 221 /* that IE 5+ conditional comment makes this only visible in IE 5+ */ 222 img { behavior: url("<?=getBaseURL()?>pngbehavior.htc"); } /* IE bugfix for transparent PNGs */ 223 </style> 224 <![endif]--> 225 226 <?@include("includes/meta.html")?> 227 </head> 228<? 229} 230 231/** 232 * Displays a button (using it's own form) 233 * 234 * @author Andreas Gohr <andi@splitbrain.org> 235 */ 236function html_btn($name,$id,$akey,$params,$method='get'){ 237 global $conf; 238 global $lang; 239 240 $label = $lang['btn_'.$name]; 241 242 $ret = ''; 243 244 $id = idfilter($id); 245 246 //make nice URLs even for buttons 247 $link = getBaseURL().'/'; 248 $link = preg_replace('#//$#','/',$link); 249 if(!$conf['userewrite']){ 250 $script = $link.'doku.php'; 251 $params['id'] = $id; 252 }else{ 253 $script = $link.$id; 254 } 255 256 $ret .= '<form class="button" method="'.$method.'" action="'.$script.'" onsubmit="return svchk()">'; 257 258 reset($params); 259 while (list($key, $val) = each($params)) { 260 $ret .= '<input type="hidden" name="'.$key.'" '; 261 $ret .= 'value="'.htmlspecialchars($val).'" />'; 262 } 263 264 $ret .= '<input type="submit" value="'.htmlspecialchars($label).'" class="button" '; 265 if($akey){ 266 $ret .= 'title="ALT+'.strtoupper($akey).'" '; 267 $ret .= 'accesskey="'.$akey.'" '; 268 } 269 $ret .= '/>'; 270 $ret .= '</form>'; 271 272 return $ret; 273} 274 275/** 276 * Check for the given permission or prints an error 277 * 278 * @author Andreas Gohr <andi@splitbrain.org> 279 */ 280function html_acl($perm){ 281 global $INFO; 282 if($INFO['perm'] >= $perm) return true; 283 284 print parsedLocale('denied'); 285 return false; 286} 287 288/** 289 * Displays the overall page header and calls html_head() 290 * 291 * @author Andreas Gohr <andi@splitbrain.org> 292 */ 293function html_header(){ 294 global $ID; 295 global $REV; 296 global $lang; 297 global $conf; 298 html_head(); 299?> 300<body> 301 <div class="all"> 302 <? 303 @include("includes/topheader.html"); 304 html_msgarea(); 305 ?> 306 <div class="stylehead"> 307 <div class="header"> 308 <div class="pagename"> 309 [[<a href="<?=wl($ID,'do=backlink')?>" onclick="return svchk()" onkeypress="return svchk()"><?=$ID?></a>]] 310 </div> 311 <div class="logo"> 312 <a href="<?=wl()?>" name="top" accesskey="h" title="[ALT+H]" onclick="return svchk()" onkeypress="return svchk()"><?=$conf['title']?></a> 313 </div> 314 </div> 315 <?@include("includes/header.html")?> 316 317 <div class="bar" id="bar_top"> 318 <div class="bar-left" id="bar_topleft"> 319 <?=html_editbutton()?> 320 <?=html_btn(revs,$ID,'r',array('do' => 'revisions'))?> 321 </div> 322 323 <div class="bar-right" id="bar_topright"> 324 <?=html_btn(recent,'','r',array('do' => 'recent'))?> 325 <form action="<?=wl()?>" accept-charset="<?=$lang['encoding']?>"> 326 <input type="hidden" name="do" value="search" /> 327 <input type="text" name="id" class="edit" /> 328 <input type="submit" value="<?=$lang['btn_search']?>" class="button" /> 329 </form> 330 </div> 331 </div> 332 333 <? 334 flush(); 335 html_breadcrumbs(); 336 @include("includes/pageheader.html"); 337 ?> 338 </div> 339 <div class="page"> 340 <!-- wikipage start --> 341<? 342} 343 344/** 345 * display document and user info 346 * 347 * Displays some Metadata like who's logged in and the last modified 348 * date - do not confuse this with the HTML meta header. 349 * 350 * @author Andreas Gohr <andi@splitbrain.org> 351 */ 352function html_metainfo(){ 353 global $conf; 354 global $lang; 355 global $INFO; 356 global $REV; 357 358 $fn = $INFO['filepath']; 359 if(!$conf['fullpath']){ 360 if($REV){ 361 $fn = str_replace(realpath($conf['olddir']).DIRECTORY_SEPARATOR,'',$fn); 362 }else{ 363 $fn = str_replace(realpath($conf['datadir']).DIRECTORY_SEPARATOR,'',$fn); 364 } 365 } 366 $date = date($conf['dformat'],$INFO['lastmod']); 367 368 print '<div class="meta">'; 369 if($_SERVER['REMOTE_USER']){ 370 print '<div class="user">'; 371 print $lang['loggedinas'].': '.$_SERVER['REMOTE_USER']; 372 print '</div>'; 373 } 374 print ' '; 375 if($INFO['exists']){ 376 print $fn; 377 print ' · '; 378 print $lang['lastmod']; 379 print ': '; 380 print $date; 381 if($INFO['locked']){ 382 print ' · '; 383 print $lang['lockedby']; 384 print ': '; 385 print $INFO['locked']; 386 } 387 } 388 print '</div>'; 389} 390 391/** 392 * Diplay the overall footer 393 * 394 * @author Andreas Gohr <andi@splitbrain.org> 395 */ 396function html_footer(){ 397 global $ID; 398 global $REV; 399 global $INFO; 400 global $lang; 401 global $conf; 402?> 403 <!-- wikipage stop --> 404 </div> 405 <div class="clearer"> </div> 406 <div class="stylefoot"> 407 <? 408 flush(); 409 @include("includes/pagefooter.html"); 410 html_metainfo(); 411 ?> 412 <div class="bar" id="bar_bottom"> 413 <div class="bar-left" id="bar_bottomleft"> 414 <?=html_editbutton()?> 415 <?=html_btn(revs,$ID,'r',array('do' => 'revisions'))?> 416 </div> 417 418 <div class="bar-right" id="bar_bottomright"> 419 <? 420 if($conf['useacl']){ 421 if($_SERVER['REMOTE_USER']){ 422 print html_btn('logout',$ID,'',array('do' => 'logout',)); 423 }else{ 424 print html_btn('login',$ID,'',array('do' => 'login')); 425 } 426 } 427 ?> 428 <?=html_btn(index,$ID,'x',array('do' => 'index'))?> 429 <a href="#top"><input type="button" class="button" value="<?=$lang['btn_top']?>" /></a> 430 </div> 431 </div> 432 </div> 433 <?@include("includes/footer.html")?> 434 </div> 435 </body> 436 </html> 437<? 438} 439 440/** 441 * Print the table of contents 442 * 443 * @author Andreas Gohr <andi@splitbrain.org> 444 */ 445function html_toc($toc){ 446 global $lang; 447 $ret = ''; 448 $ret .= '<div class="toc">'; 449 $ret .= '<div class="tocheader">'; 450 $ret .= $lang['toc']; 451 $ret .= ' <script type="text/javascript">'; 452 $ret .= 'showTocToggle("+","-")'; 453 $ret .= '</script>'; 454 $ret .= '</div>'; 455 $ret .= '<div id="tocinside">'; 456 $ret .= html_buildlist($toc,'toc','html_list_toc'); 457 $ret .= '</div>'; 458 $ret .= '</div>'; 459 return $ret; 460} 461 462/** 463 * TOC item formatter 464 * 465 * User function for html_buildlist() 466 * 467 * @author Andreas Gohr <andi@splitbrain.org> 468 */ 469function html_list_toc($item){ 470 $ret = ''; 471 $ret .= '<a href="#'.$item['id'].'" class="toc">'; 472 $ret .= $item['name']; 473 $ret .= '</a>'; 474 return $ret; 475} 476 477/** 478 * show a wiki page 479 * 480 * @author Andreas Gohr <andi@splitbrain.org> 481 */ 482function html_show($text=''){ 483 global $ID; 484 global $REV; 485 global $HIGH; 486 //disable section editing for old revisions or in preview 487 if($text || $REV){ 488 global $parser; 489 $parser['secedit'] = false; 490 } 491 492 if ($text){ 493 //PreviewHeader 494 print parsedLocale('preview'); 495 print '<div class="preview">'; 496 print html_secedit(parse($text),false); 497 print '</div>'; 498 }else{ 499 if ($REV) print parsedLocale('showrev'); 500 $html = parsedWiki($ID,$REV,true); 501 $html = html_secedit($html); 502 print html_hilight($html,$HIGH); 503 } 504} 505 506/** 507 * Highlights searchqueries in HTML code 508 * 509 * @author Andreas Gohr <andi@splitbrain.org> 510 */ 511function html_hilight($html,$query){ 512 $queries = preg_split ("/\s/",$query,-1,PREG_SPLIT_NO_EMPTY); 513 foreach ($queries as $q){ 514 $q = preg_quote($q,'/'); 515 $html = preg_replace("/((<[^>]*)|$q)/ie", '"\2"=="\1"? "\1":"<span class=\"search_hit\">\1</span>"', $html); 516 } 517 return $html; 518} 519 520/** 521 * Run a search and display the result 522 * 523 * @author Andreas Gohr <andi@splitbrain.org> 524 */ 525function html_search(){ 526 require_once("inc/search.php"); 527 global $conf; 528 global $QUERY; 529 global $ID; 530 global $lang; 531 532 print parsedLocale('searchpage'); 533 flush(); 534 535 //do quick pagesearch 536 $data = array(); 537 search($data,$conf['datadir'],'search_pagename',array(query => $QUERY)); 538 if(count($data)){ 539 sort($data); 540 print '<div class="search_quickresult">'; 541 print '<b>'.$lang[quickhits].':</b><br />'; 542 foreach($data as $row){ 543 print '<div class="search_quickhits">'; 544 print html_wikilink(':'.$row['id'],$row['id']); 545 print '</div> '; 546 } 547 //clear float (see http://www.complexspiral.com/publications/containing-floats/) 548 print '<div class="clearer"> </div>'; 549 print '</div>'; 550 } 551 flush(); 552 553 //do fulltext search 554 $data = array(); 555 search($data,$conf['datadir'],'search_fulltext',array(query => $QUERY)); 556 if(count($data)){ 557 usort($data,'sort_search_fulltext'); 558 foreach($data as $row){ 559 print '<div class="search_result">'; 560 print html_wikilink(':'.$row['id'],$row['id'],$QUERY); 561 print ': <span class="search_cnt">'.$row['count'].' '.$lang['hits'].'</span><br />'; 562 print '<div class="search_snippet">'.$row['snippet'].'</div>'; 563 print '</div>'; 564 } 565 }else{ 566 print '<div align="center">'.$lang['nothingfound'].'</div>'; 567 } 568} 569 570/** 571 * Display error on locked pages 572 * 573 * @author Andreas Gohr <andi@splitbrain.org> 574 */ 575function html_locked($ip){ 576 global $ID; 577 global $conf; 578 global $lang; 579 580 $locktime = filemtime(wikiFN($ID).'.lock'); 581 $expire = @date($conf['dformat'], $locktime + $conf['locktime'] ); 582 $min = round(($conf['locktime'] - (time() - $locktime) )/60); 583 584 print parsedLocale('locked'); 585 print '<ul>'; 586 print '<li><b>'.$lang['lockedby'].':</b> '.$ip.'</li>'; 587 print '<li><b>'.$lang['lockexpire'].':</b> '.$expire.' ('.$min.' min)</li>'; 588 print '</ul>'; 589} 590 591/** 592 * list old revisions 593 * 594 * @author Andreas Gohr <andi@splitbrain.org> 595 */ 596function html_revisions(){ 597 global $ID; 598 global $INFO; 599 global $conf; 600 global $lang; 601 $revisions = getRevisions($ID); 602 $date = @date($conf['dformat'],$INFO['lastmod']); 603 604 print parsedLocale('revisions'); 605 print '<ul>'; 606 if($INFO['exists']){ 607 print '<li>'.$date.' <a class="wikilink1" href="'.wl($ID).'">'.$ID.'</a> ('.$lang['current'].')</li>'; 608 } 609 610 foreach($revisions as $rev){ 611 $date = date($conf['dformat'],$rev); 612 print '<li>'; 613 print $date.' <a class="wikilink1" href="'.wl($ID,"rev=$rev").'">'.$ID.'</a> '; 614 print '<a href="'.wl($ID,"rev=$rev,do=diff").'">['.$lang['diff'].']</a>'; 615 print '</li>'; 616 } 617 print '</ul>'; 618} 619 620/** 621 * display recent changes 622 * 623 * @author Andreas Gohr <andi@splitbrain.org> 624 */ 625function html_recent(){ 626 global $conf; 627 $recents = getRecents(0,true); 628 629 print parsedLocale('recent'); 630 print '<ul>'; 631 foreach(array_keys($recents) as $id){ 632 $date = date($conf['dformat'],$recents[$id]['date']); 633 print '<li>'; 634 print $date.' '.html_wikilink($id,$id); 635 print ' '.htmlspecialchars($recents[$id]['sum']); 636 print ' <span class="user">('; 637 print $recents[$id]['ip']; 638 if($recents[$id]['user']) print ' '.$recents[$id]['user']; 639 print ')</span>'; 640 print '</li>'; 641 } 642 print '</ul>'; 643} 644 645/** 646 * Display page index 647 * 648 * @author Andreas Gohr <andi@splitbrain.org> 649 */ 650function html_index($ns){ 651 require_once("inc/search.php"); 652 global $conf; 653 global $ID; 654 $dir = $conf['datadir']; 655 $ns = cleanID($ns); 656 if(empty($ns)){ 657 $ns = dirname(str_replace(':','/',$ID)); 658 if($ns == '.') $ns =''; 659 } 660 $ns = str_replace(':','/',$ns); 661 662 print parsedLocale('index'); 663 664 $data = array(); 665 search($data,$conf['datadir'],'search_index',array('ns' => $ns)); 666 print html_buildlist($data,'idx','html_list_index','html_li_index'); 667} 668 669/** 670 * Index item formatter 671 * 672 * User function for html_buildlist() 673 * 674 * @author Andreas Gohr <andi@splitbrain.org> 675 */ 676function html_list_index($item){ 677 $ret = ''; 678 $base = ':'.$item['id']; 679 $base = substr($base,strrpos($base,':')+1); 680 if($item['type']=='d'){ 681 $ret .= '<a href="'.wl($ID,'idx='.$item['id']).'" class="idx_dir">'; 682 $ret .= $base; 683 $ret .= '</a>'; 684 }else{ 685 $ret .= html_wikilink(':'.$item['id']); 686 } 687 return $ret; 688} 689 690/** 691 * Index List item 692 * 693 * This user function is used in html_build_lidt to build the 694 * <li> tags for namespaces when displaying the page index 695 * it gives different classes to opened or closed "folders" 696 * 697 * @author Andreas Gohr <andi@splitbrain.org> 698 */ 699function html_li_index($item){ 700 if($item['type'] == "f"){ 701 return '<li class="level'.$item['level'].'">'; 702 }elseif($item['open']){ 703 return '<li class="open">'; 704 }else{ 705 return '<li class="closed">'; 706 } 707} 708 709/** 710 * Default List item 711 * 712 * @author Andreas Gohr <andi@splitbrain.org> 713 */ 714function html_li_default($item){ 715 return '<li class="level'.$item['level'].'">'; 716} 717 718/** 719 * Build an unordered list 720 * 721 * Build an unordered list from the given $data array 722 * Each item in the array has to have a 'level' property 723 * the item itself gets printed by the given $func user 724 * function. The second and optional function is used to 725 * print the <li> tag. Both user function need to accept 726 * a single item. 727 * 728 * @author Andreas Gohr <andi@splitbrain.org> 729 */ 730function html_buildlist($data,$class,$func,$lifunc='html_li_default'){ 731 $level = 0; 732 $opens = 0; 733 $ret = ''; 734 735 foreach ($data as $item){ 736 737 if( $item['level'] > $level ){ 738 //open new list 739 $ret .= "\n<ul class=\"$class\">\n"; 740 }elseif( $item['level'] < $level ){ 741 //close last item 742 $ret .= "</li>\n"; 743 for ($i=0; $i<($level - $item['level']); $i++){ 744 //close higher lists 745 $ret .= "</ul>\n</li>\n"; 746 } 747 }else{ 748 //close last item 749 $ret .= "</li>\n"; 750 } 751 752 //remember current level 753 $level = $item['level']; 754 755 //print item 756 $ret .= $lifunc($item); //user function 757 $ret .= '<span class="li">'; 758 $ret .= $func($item); //user function 759 $ret .= '</span>'; 760 } 761 762 //close remaining items and lists 763 for ($i=0; $i < $level; $i++){ 764 $ret .= "</li></ul>\n"; 765 } 766 767 return $ret; 768} 769 770/** 771 * display backlinks 772 * 773 * @author Andreas Gohr <andi@splitbrain.org> 774 */ 775function html_backlinks(){ 776 require_once("inc/search.php"); 777 global $ID; 778 global $conf; 779 780 if(preg_match('#^(.*):(.*)$#',$ID,$matches)){ 781 $opts['ns'] = $matches[1]; 782 $opts['name'] = $matches[2]; 783 }else{ 784 $opts['ns'] = ''; 785 $opts['name'] = $ID; 786 } 787 788 print parsedLocale('backlinks'); 789 790 $data = array(); 791 search($data,$conf['datadir'],'search_backlinks',$opts); 792 sort($data); 793 794 print '<ul class="idx">'; 795 foreach($data as $row){ 796 print '<li>'; 797 print html_wikilink(':'.$row['id'],$row['id']); 798 print '</li>'; 799 } 800 print '</ul>'; 801} 802 803/** 804 * show diff 805 * 806 * @author Andreas Gohr <andi@splitbrain.org> 807 */ 808function html_diff($text='',$intro=true){ 809 require_once("inc/DifferenceEngine.php"); 810 global $ID; 811 global $REV; 812 global $lang; 813 global $conf; 814 if($text){ 815 $df = new Diff(split("\n",htmlspecialchars(rawWiki($ID,''))), 816 split("\n",htmlspecialchars(cleanText($text)))); 817 $left = '<a class="wikilink1" href="'.wl($ID).'">'. 818 $ID.' '.date($conf['dformat'],@filemtime(wikiFN($ID))).'</a>'. 819 $lang['current']; 820 $right = $lang['yours']; 821 }else{ 822 $df = new Diff(split("\n",htmlspecialchars(rawWiki($ID,$REV))), 823 split("\n",htmlspecialchars(rawWiki($ID,'')))); 824 $left = '<a class="wikilink1" href="'.wl($ID,"rev=$REV").'">'. 825 $ID.' '.date($conf['dformat'],$REV).'</a>'; 826 $right = '<a class="wikilink1" href="'.wl($ID).'">'. 827 $ID.' '.date($conf['dformat'],@filemtime(wikiFN($ID))).'</a> '. 828 $lang['current']; 829 } 830 $tdf = new TableDiffFormatter(); 831 if($intro) print parsedLocale('diff'); 832 ?> 833 <table class="diff" width="100%"> 834 <tr> 835 <td colspan="2" width="50%" class="diff-header"> 836 <?=$left?> 837 </td> 838 <td colspan="2" width="50%" class="diff-header"> 839 <?=$right?> 840 </td> 841 </tr> 842 <?=$tdf->format($df)?> 843 </table> 844 <? 845} 846 847/** 848 * show warning on conflict detection 849 * 850 * @author Andreas Gohr <andi@splitbrain.org> 851 */ 852function html_conflict($text,$summary){ 853 global $ID; 854 global $lang; 855 856 print parsedLocale('conflict'); 857 ?> 858 <form name="editform" method="post" action="<?=script()?>" accept-charset="<?=$lang['encoding']?>"> 859 <input type="hidden" name="id" value="<?=$ID?>" /> 860 <input type="hidden" name="wikitext" value="<?=formText($text)?>" /> 861 <input type="hidden" name="summary" value="<?=formText($summary)?>" /> 862 863 <div align="center"> 864 <input class="button" type="submit" name="do" value="<?=$lang['btn_save']?>" accesskey="s" title="[ALT+S]" /> 865 <input class="button" type="submit" name="do" value="<?=$lang['btn_cancel']?>" /> 866 </div> 867 </form> 868 <br /><br /><br /><br /> 869 <? 870} 871 872/** 873 * Prints the global message array 874 * 875 * @author Andreas Gohr <andi@splitbrain.org> 876 */ 877function html_msgarea(){ 878 global $MSG; 879 880 if(!isset($MSG)) return; 881 882 foreach($MSG as $msg){ 883 print '<div class="'.$msg['lvl'].'">'; 884 print $msg['msg']; 885 print '</div>'; 886 } 887} 888 889/** 890 * Prints the registration form 891 * 892 * @author Andreas Gohr <andi@splitbrain.org> 893 */ 894function html_register(){ 895 global $lang; 896 global $ID; 897 898 print parsedLocale('register'); 899?> 900 <div align="center"> 901 <form name="register" method="post" action="<?=wl($ID)?>" accept-charset="<?=$lang['encoding']?>"> 902 <input type="hidden" name="do" value="register" /> 903 <input type="hidden" name="save" value="1" /> 904 <fieldset> 905 <legend><?=$lang['register']?></legend> 906 <label> 907 <?=$lang['user']?> 908 <input type="text" name="login" class="edit" size="50" value="<?=formText($_POST['login'])?>" /> 909 </label><br /> 910 <label> 911 <?=$lang['fullname']?> 912 <input type="text" name="fullname" class="edit" size="50" value="<?=formText($_POST['fullname'])?>" /> 913 </label><br /> 914 <label> 915 <?=$lang['email']?> 916 <input type="text" name="email" class="edit" size="50" value="<?=formText($_POST['email'])?>" /> 917 </label><br /> 918 <input type="submit" class="button" value="<?=$lang['register']?>" /> 919 </fieldset> 920 </form> 921 </div> 922<? 923} 924 925/** 926 * This displays the edit form (lots of logic included) 927 * 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 //check for create permissions first 943 if(!$INFO['exists'] && !html_acl(AUTH_CREATE)) return; 944 945 //set summary default 946 if(!$SUM){ 947 if($REV){ 948 $SUM = $lang['restored']; 949 }elseif(!$INFO['exists']){ 950 $SUM = $lang['created']; 951 } 952 } 953 954 //no text? Load it! 955 if(!isset($text)){ 956 $pr = false; //no preview mode 957 if($RANGE){ 958 list($PRE,$text,$SUF) = rawWikiSlices($RANGE,$ID,$REV); 959 }else{ 960 $text = rawWiki($ID,$REV); 961 } 962 }else{ 963 $pr = true; //preview mode 964 } 965 966 $wr = $INFO['writable']; 967 if($wr){ 968 if ($REV) print parsedLocale('editrev'); 969 print parsedLocale($include); 970 }else{ 971 print parsedLocale('read'); 972 $ro='readonly="readonly"'; 973 } 974 if(!$DATE) $DATE = $INFO['lastmod']; 975?> 976 <form name="editform" method="post" action="<?=script()?>" accept-charset="<?=$lang['encoding']?>" onsubmit="return svchk()"> 977 <input type="hidden" name="id" value="<?=$ID?>" /> 978 <input type="hidden" name="rev" value="<?=$REV?>" /> 979 <input type="hidden" name="date" value="<?=$DATE?>" /> 980 <input type="hidden" name="prefix" value="<?=formText($PRE)?>" /> 981 <input type="hidden" name="suffix" value="<?=formText($SUF)?>" /> 982 <table style="width:99%"> 983 <tr> 984 <td class="toolbar" colspan="3"> 985 <?if($wr){?> 986 <script language="JavaScript" type="text/javascript"> 987 <?/* sets changed to true when previewed */?> 988 textChanged = <? ($pr) ? print 'true' : print 'false' ?>; 989 990 formatButton('images/bold.png','<?=$lang['qb_bold']?>','**','**','<?=$lang['qb_bold']?>','b'); 991 formatButton('images/italic.png','<?=$lang['qb_italic']?>',"\/\/","\/\/",'<?=$lang['qb_italic']?>','i'); 992 formatButton('images/underline.png','<?=$lang['qb_underl']?>','__','__','<?=$lang['qb_underl']?>','u'); 993 formatButton('images/code.png','<?=$lang['qb_code']?>','\'\'','\'\'','<?=$lang['qb_code']?>','c'); 994 995 formatButton('images/fonth1.png','<?=$lang['qb_h1']?>','====== ',' ======\n','<?=$lang['qb_h1']?>','1'); 996 formatButton('images/fonth2.png','<?=$lang['qb_h2']?>','===== ',' =====\n','<?=$lang['qb_h2']?>','2'); 997 formatButton('images/fonth3.png','<?=$lang['qb_h3']?>','==== ',' ====\n','<?=$lang['qb_h3']?>','3'); 998 formatButton('images/fonth4.png','<?=$lang['qb_h4']?>','=== ',' ===\n','<?=$lang['qb_h4']?>','4'); 999 formatButton('images/fonth5.png','<?=$lang['qb_h5']?>','== ',' ==\n','<?=$lang['qb_h5']?>','5'); 1000 1001 formatButton('images/link.png','<?=$lang['qb_link']?>','[[',']]','<?=$lang['qb_link']?>','l'); 1002 formatButton('images/extlink.png','<?=$lang['qb_extlink']?>','[[',']]','http://www.example.com|<?=$lang['qb_extlink']?>'); 1003 1004 formatButton('images/list.png','<?=$lang['qb_ol']?>',' - ','\n','<?=$lang['qb_ol']?>'); 1005 formatButton('images/list_ul.png','<?=$lang['qb_ul']?>',' * ','\n','<?=$lang['qb_ul']?>'); 1006 1007 insertButton('images/rule.png','<?=$lang['qb_hr']?>','----\n'); 1008 mediaButton('images/image.png','<?=$lang['qb_media']?>','m','<?=$INFO['namespace']?>'); 1009 1010 <? 1011 if($conf['useacl'] && $_SERVER['REMOTE_USER']){ 1012 echo "insertButton('images/sig.png','".$lang['qb_sig']."','".html_signature()."','y');"; 1013 } 1014 ?> 1015 </script> 1016 <?}?> 1017 </td> 1018 </tr> 1019 <tr> 1020 <td colspan="3"> 1021 <textarea name="wikitext" id="wikitext" <?=$ro?> cols="80" rows="10" class="edit" onchange="textChanged = true;" tabindex="1"><?="\n".formText($text)?></textarea> 1022 </td> 1023 </tr> 1024 <tr> 1025 <td> 1026 <?if($wr){?> 1027 <input class="button" type="submit" name="do" value="<?=$lang['btn_save']?>" accesskey="s" title="[ALT+S]" onclick="textChanged=false" onkeypress="textChanged=false" tabindex="3" /> 1028 <input class="button" type="submit" name="do" value="<?=$lang['btn_preview']?>" accesskey="p" title="[ALT+P]" onclick="textChanged=false" onkeypress="textChanged=false" tabindex="4" /> 1029 <input class="button" type="submit" name="do" value="<?=$lang['btn_cancel']?>" tabindex="5" /> 1030 <?}?> 1031 </td> 1032 <td> 1033 <?if($wr){?> 1034 <?=$lang['summary']?>: 1035 <input type="text" class="edit" name="summary" size="50" value="<?=formText($SUM)?>" tabindex="2" /> 1036 <?}?> 1037 </td> 1038 <td align="right"> 1039 <script type="text/javascript"> 1040 showSizeCtl(); 1041 <?if($wr){?> 1042 init_locktimer(<?=$conf['locktime']-60?>,'<?=$lang['willexpire']?>'); 1043 document.editform.wikitext.focus(); 1044 <?}?> 1045 </script> 1046 </td> 1047 </tr> 1048 </table> 1049 </form> 1050<? 1051} 1052 1053/** 1054 * prepares the signature string as configured in the config 1055 * 1056 * @author Andreas Gohr <andi@splitbrain.org> 1057 */ 1058function html_signature(){ 1059 global $conf; 1060 global $INFO; 1061 1062 $sig = $conf['signature']; 1063 $sig = strftime($sig); 1064 $sig = str_replace('@USER@',$_SERVER['REMOTE_USER'],$sig); 1065 $sig = str_replace('@NAME@',$INFO['userinfo']['name'],$sig); 1066 $sig = str_replace('@MAIL@',$INFO['userinfo']['mail'],$sig); 1067 $sig = str_replace('@DATE@',date($conf['dformat']),$sig); 1068 return $sig; 1069} 1070 1071/** 1072 * prints some debug info 1073 * 1074 * @author Andreas Gohr <andi@splitbrain.org> 1075 */ 1076function html_debug(){ 1077 global $conf; 1078 1079 print '<html><body>'; 1080 1081 print '<p>When reporting bugs please send all the following '; 1082 print 'output as a mail to andi@splitbrain.org '; 1083 print 'The best way to do this is to save this page in your browser</p>'; 1084 1085 print '<b>$_SERVER:</b><pre>'; 1086 print_r($_SERVER); 1087 print '</pre>'; 1088 1089 print '<b>$conf:</b><pre>'; 1090 print_r($conf); 1091 print '</pre>'; 1092 1093 print '<b>abs baseURL:</b><pre>'; 1094 print getBaseURL(true); 1095 print '</pre>'; 1096 1097 print '<b>rel baseURL:</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>Environment:</b><pre>'; 1110 print_r($_ENV); 1111 print '</pre>'; 1112 1113 print '<b>PHP settings:</b><pre>'; 1114 $inis = ini_get_all(); 1115 print_r($inis); 1116 print '</pre>'; 1117 1118 print '</body></html>'; 1119} 1120 1121?> 1122