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