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