[ PHPXref.com ] [ Generated: Sun Jul 20 20:58:52 2008 ] [ WackoWiki 4.2 ]
[ Index ]     [ Variables ]     [ Functions ]     [ Classes ]     [ Constants ]     [ Statistics ]

title

Body

[close]

/classes/ -> wacko.php (source)

   1  <?php
   2  // $Id: wacko.php 481 2005-03-07 14:18:45Z kukutz $

   3  
   4  // constants

   5  define("TRAN_DONTCHANGE", "0");
   6  define("TRAN_LOWERCASE", "1");
   7  define("TRAN_LOAD", "0");
   8  define("TRAN_DONTLOAD", "1");
   9  define("LOAD_NOCACHE", "0");
  10  define("LOAD_CACHE", "1");
  11  define("LOAD_ALL", "0");
  12  define("LOAD_META", "1");
  13  define("BM_AUTO", "0");
  14  define("BM_USER", "1");
  15  define("BM_DEFAULT", "2");
  16  
  17  
  18  class Wacko
  19  {
  20   var $dblink;
  21   var $page;
  22   var $tag;
  23   var $queryLog = array();
  24   var $interWiki = array();
  25   var $VERSION;
  26   var $WVERSION; //Wacko version

  27   var $context = array("");
  28   var $current_context = 0;
  29   var $pages_meta = "id, tag, time, owner, user, latest, handler, comment_on, super_comment_on, supertag, lang, keywords, description";
  30   var $first_inclusion = array(); // for backlinks

  31   // if you change this two symbols, settings for all users will be lost.

  32   var $optionSplitter = "\n";
  33   var $valueSplitter  = "=";
  34   var $format_safe = true; //for htmlspecialchars() in PreLink

  35   var $unicode_entities = array(); //common unicode array

  36   var $timer;
  37   var $toc_context = array();
  38   var $search_engines = array("bot", "rambler", "yandex", "crawl", "search", "archiver", "slurp", "aport", "crawler", "google", "inktomi", "spider", );
  39   var $_langlist = null;
  40   var $languages = null;
  41   var $resources = null;
  42   var $wantedCache = null;
  43   var $pageCache = null;
  44   var $_formatter_noautolinks = null;
  45   var $post_wacko_action = null;
  46   var $_userhost = null;
  47  
  48   // constructor

  49   function Wacko($config)
  50   {
  51     $this->timer = $this->GetMicroTime();
  52     $this->config = $config;
  53     $this->dblink = connect($this->config["mysql_host"], $this->config["mysql_user"], $this->config["mysql_password"], $this->config["mysql_database"], $this->config["db_collation"]);
  54     $this->VERSION = WAKKA_VERSION;
  55     $this->WVERSION = WACKO_VERSION;
  56   }
  57  
  58   // DATABASE

  59   function Query($query, $debug=0)
  60   {
  61     if ($debug) echo "((QUERY: $query))";
  62     if($this->GetConfigValue("debug")>=2) $start = $this->GetMicroTime();
  63     $result = query($query, $this->dblink);
  64     if($this->GetConfigValue("debug")>=2)
  65     {
  66       $time = $this->GetMicroTime() - $start;
  67       $this->queryLog[] = array(
  68         "query"   => $query,
  69         "time"    => $time);
  70     }
  71     return $result;
  72   }
  73  
  74   function LoadSingle($query) { if ($data = $this->LoadAll($query)) return $data[0]; }
  75  
  76   function LoadAll($query)
  77   {
  78     $data = array();
  79     if ($r = $this->Query($query))
  80     {
  81       while ($row = fetch_assoc($r)) $data[] = $row;
  82       free_result($r);
  83     }
  84     return $data;
  85   }
  86  
  87  
  88   // MISC

  89   function GetMicroTime() { list($usec, $sec) = explode(" ",microtime()); return ((float)$usec + (float)$sec); }
  90  
  91   function IncludeBuffered($filename, $notfoundText = "", $vars = "", $path = "")
  92   {
  93     if ($path) $dirs = explode(":", $path);
  94     else $dirs = array("");
  95  
  96     foreach($dirs as $dir)
  97     {
  98       if ($dir) $dir .= "/";
  99       $fullfilename = $dir.$filename;
 100       $fullfilename = trim($fullfilename, "./");
 101       if (@file_exists($fullfilename))
 102       {
 103         if (is_array($vars)) extract($vars, EXTR_SKIP);
 104  
 105         ob_start();
 106         include($fullfilename);
 107         $output = ob_get_contents();
 108         ob_end_clean();
 109         return $output;
 110       }
 111     }
 112     if ($notfoundText) return $notfoundText;
 113     else return false;
 114   }
 115  
 116   // VARIABLES

 117   function GetPageTag() { return $this->tag; }
 118   function GetPageSuperTag() { return $this->supertag; }
 119   function GetPageTime() { return $this->page["time"]; }
 120   function GetMethod() { return $this->method; }
 121   function GetConfigValue($name) { return isset( $this->config[$name] ) ? $this->config[$name] : ''; }
 122   function SetResource($lang) {$this->resource=&$this->resources[$lang];}
 123   
 124   function SetLanguage($lang) 
 125   {
 126  //   echo "<b>SetLanguage:</b> ".$lang."<br />";

 127     $this->LoadResource($lang);
 128     $this->language = &$this->languages[$lang];
 129     setlocale(LC_CTYPE,$this->language["locale"]);
 130     $this->language["locale"] = setlocale(LC_CTYPE,0);
 131     $this->language["UPPER"]     = "[".$this->language["UPPER_P"]."]";   
 132     $this->language["UPPERNUM"]  = "[0-9".$this->language["UPPER_P"]."]";
 133     $this->language["LOWER"]     = "[".$this->language["LOWER_P"]."]";   
 134     $this->language["ALPHA"]     = "[".$this->language["ALPHA_P"]."]";   
 135     $this->language["ALPHANUM"]  = "[0-9".$this->language["ALPHA_P"]."]";
 136     $this->language["ALPHANUM_P"]= "0-9".$this->language["ALPHA_P"];     
 137   }
 138   
 139   function LoadResource($lang)
 140   {
 141     if (!$this->resources[$lang])
 142     {
 143       $resourcefile = "lang/wakka.".$lang.".php";
 144       if (@file_exists($resourcefile)) include($resourcefile);
 145       // wakka.all

 146       $resourcefile = "lang/wakka.all.php";
 147       if (!$this->resources["all"])
 148       {
 149       if (@file_exists($resourcefile)) include($resourcefile);
 150         $this->resources["all"] =& $wackoAllResource; 
 151       }
 152       $wackoResource = array_merge($wakkaResource, $this->resources["all"]);
 153       // theme

 154       $resourcefile = "themes/".$this->config["theme"]."/lang/wakka.".$lang.".php";
 155       if (@file_exists($resourcefile)) include($resourcefile);
 156       $wackoResource = array_merge((array)$wackoResource, (array)$themeResource);
 157       // wakka.all theme

 158       $resourcefile = "themes/".$this->config["theme"]."/lang/wakka.all.php";
 159       if (@file_exists($resourcefile)) include($resourcefile);
 160       $wackoResource = array_merge((array)$wackoResource, (array)$themeResource);
 161  
 162       $this->resources[$lang] = $wackoResource;
 163  
 164       $this->LoadLang($lang);
 165     }
 166   }
 167   
 168   function LoadLang($lang)
 169   {
 170     if (!isset( $this->languages[$lang] ))
 171     {
 172       $resourcefile = "lang/lang.".$lang.".php";
 173       if (@file_exists($resourcefile)) include($resourcefile);
 174       $this->languages[$lang] = $wackoLanguage;
 175       $ue = @array_flip($wackoLanguage["unicode_entities"]);
 176       $this->unicode_entities = array_merge($this->unicode_entities, $ue);
 177       unset($this->unicode_entities[0]);
 178     }
 179   }
 180   
 181   function LoadAllLanguages()
 182   { 
 183     if (!$this->GetConfigValue("multilanguage")) return;
 184     $langs = $this->AvailableLanguages();
 185     foreach ($langs as $lang)
 186      $this->LoadLang($lang);
 187   }
 188   
 189   function AvailableLanguages()
 190   {
 191    if (!$this->_langlist)
 192    {
 193     $handle=opendir("lang");
 194     while (false!==($file = readdir($handle))) {
 195       if ($file != "." && $file != ".." && $file != "wakka.all.php" && !is_dir("lang/".$file) && 1==preg_match("/^wakka\.(.*?)\.php$/",$file,$match)) {
 196         $langlist[] = $match[1];
 197       }
 198     }
 199     closedir($handle);
 200     $this->_langlist = $langlist;
 201    }
 202    return $this->_langlist;
 203   }
 204   
 205   function GetResourceValue($name, $lang="", $dounicode=true) 
 206   { 
 207     if (!$this->GetConfigValue("multilanguage")) return $this->resource[$name];
 208  
 209     //echo "<b>GetResourceValue:</b> $lang + $name + $this->userlang + $this->pagelang<br />";

 210  
 211     if (!$lang && $this->userlang!=$this->pagelang) $lang = $this->userlang;
 212     if ($lang!="")
 213     {
 214       $this->LoadResource($lang);
 215       return (is_array($this->resources[$lang][$name]))?$this->resources[$lang][$name]:($dounicode?$this->DoUnicodeEntities($this->resources[$lang][$name], $lang):$this->resources[$lang][$name]);
 216     }
 217     return $this->resource[$name];
 218   }
 219   
 220   function FormatResourceValue($name, $lang="") 
 221   {
 222     $string = $this->GetResourceValue($name, $lang, false);
 223     $this->format_safe = false;
 224     $string = $this->Format($string);
 225     $this->format_safe = true;
 226     return $string;
 227   }
 228   
 229   function DetermineLang() 
 230   { 
 231     $langlist = $this->AvailableLanguages();
 232                                       //!!!! wrong code, maybe!

 233     if ($this->GetMethod()=="edit" && $_GET["add"]==1) 
 234       if ($_REQUEST["lang"] && in_array($_REQUEST["lang"], $langlist)) 
 235         $lang = $_REQUEST["lang"];
 236       else
 237         $lang = $this->userlang;
 238     else 
 239       $lang = $this->pagelang;
 240  
 241     return $lang;
 242   }
 243   
 244   function SetPageLang($lang)
 245   {
 246    if (!$lang) return false;
 247    $this->pagelang = $lang;
 248    $this->SetLanguage($lang);
 249    return true;
 250   }
 251   
 252   function GetCharset() 
 253   {
 254     $lang = $this->DetermineLang();
 255     $this->LoadResource($lang);
 256     return $this->languages[$lang]["charset"]; 
 257   }
 258   
 259   function DoUnicodeEntities($string, $lang)
 260   {
 261     if (!$this->GetConfigValue("multilanguage")) return $string;
 262     $_lang = $this->DetermineLang();
 263     if ($lang==$_lang) return $string;
 264  
 265  //    die("<h2>".$lang."<>".$_lang."</h2>");

 266  
 267     $this->LoadResource($lang);
 268     if (is_array($this->languages[$lang]["unicode_entities"]))
 269     {
 270      return @strtr($string, $this->languages[$lang]["unicode_entities"]);
 271     }
 272     else return $string;
 273   }
 274   
 275   function tryUtfDecode ($string) 
 276   {
 277     $t1 = $this->utf8ToUnicodeEntities($string);
 278     $t2 = @strtr($t1, $this->unicode_entities);
 279     //echo "<pre><h1>".$string."|".$t1."|".$t2."</h1></pre>";

 280     if (!preg_match("/\&\#[0-9]+\;/", $t2))
 281       $string = $t2;
 282     return $string;
 283   }
 284   
 285   function utf8ToUnicodeEntities ($source) 
 286   {
 287    // array used to figure what number to decrement from character order value

 288    // according to number of characters used to map unicode to ascii by utf-8

 289    $decrement[4] = 240; $decrement[3] = 224;
 290    $decrement[2] = 192; $decrement[1] = 0;
 291  
 292    // the number of bits to shift each charNum by

 293    $shift[1][0] = 0;  $shift[2][0] = 6;
 294    $shift[2][1] = 0;  $shift[3][0] = 12;
 295    $shift[3][1] = 6;  $shift[3][2] = 0;
 296    $shift[4][0] = 18; $shift[4][1] = 12;
 297    $shift[4][2] = 6;  $shift[4][3] = 0;
 298  
 299    $pos = 0;
 300    $len = strlen ($source);
 301    $encodedString = '';
 302    while ($pos < $len) 
 303    {
 304     $asciiPos = ord (substr ($source, $pos, 1));
 305     if (($asciiPos >= 240) && ($asciiPos <= 255)) 
 306     {// 4 chars representing one unicode character
 307      $thisLetter = substr ($source, $pos, 4);
 308      $pos += 4;
 309     }
 310     else if (($asciiPos >= 224) && ($asciiPos <= 239)) 
 311     {// 3 chars representing one unicode character
 312      $thisLetter = substr ($source, $pos, 3);
 313      $pos += 3;
 314     }
 315     else if (($asciiPos >= 192) && ($asciiPos <= 223)) 
 316     {// 2 chars representing one unicode character
 317      $thisLetter = substr ($source, $pos, 2);
 318      $pos += 2;
 319     }
 320     else 
 321     {// 1 char (lower ascii)
 322      $thisLetter = substr ($source, $pos, 1);
 323      $pos += 1;
 324     }
 325  
 326     // process the string representing the letter to a unicode entity

 327     $thisLen = strlen ($thisLetter);
 328     if ($thisLen>1)
 329     {
 330      $thisPos = 0;
 331      $decimalCode = 0;
 332      while ($thisPos < $thisLen) 
 333      {
 334       $thisCharOrd = ord (substr ($thisLetter, $thisPos, 1));
 335       if ($thisPos == 0) 
 336       {
 337        $charNum = intval ($thisCharOrd - $decrement[$thisLen]);
 338        $decimalCode += ($charNum << $shift[$thisLen][$thisPos]);
 339       }
 340       else 
 341       {
 342        $charNum = intval ($thisCharOrd - 128);
 343        $decimalCode += ($charNum << $shift[$thisLen][$thisPos]);
 344       }
 345       $thisPos++;
 346      }
 347      $encodedLetter = "&#". $decimalCode . ';';
 348     }
 349     else 
 350      $encodedLetter = $thisLetter;
 351     $encodedString .= $encodedLetter;
 352    }
 353    return $encodedString;
 354   }
 355  
 356   function GetWakkaName() { return $this->GetConfigValue("wakka_name"); }
 357   function GetWakkaVersion() { return $this->VERSION; }
 358   function GetWackoVersion() { return $this->WVERSION; }
 359  
 360   // PAGES

 361   // NpjTranslit

 362   var $NpjMacros = array( "вики" => "wiki", "вака" => "wacko", "швака" => "shwacko",
 363                           "веб" => "web", "ланс" => "lance", "кукуц" => "kukutz", "мендокуси" => "mendokusee",
 364                           "€ремко" => "iaremko", "николай" => "nikolai", "алексей" => "aleksey", "анатолий" => "anatoly"
 365                         );
 366   
 367   function NpjTranslit($tag, $strtolow = TRAN_LOWERCASE, $donotload=TRAN_LOAD)
 368   {
 369     $_lang = null;
 370     if (!$this->GetConfigValue("multilanguage")) $donotload = 1;
 371     if (!$donotload)
 372     if ($page = $this->LoadPage($tag, "", LOAD_CACHE, LOAD_META))
 373     {
 374        $_lang = $this->language["code"];
 375        if ($page["lang"]) $lang = $page["lang"];
 376        else $lang = $this->GetConfigValue("language");
 377  
 378        $this->SetLanguage($lang);
 379     }
 380  
 381     $tag = str_replace( "//", "/", $tag );
 382     $tag = str_replace( "-", "", $tag );
 383     $tag = str_replace( " ", "", $tag );
 384     $tag = str_replace( "'", "_", $tag );
 385     $_tag = strtolower( $tag ); 
 386     if ($strtolow) $tag = @strtr( $_tag, $this->NpjMacros ); 
 387     else 
 388      foreach( $this->NpjMacros as $macro=>$value ) 
 389       while (($pos = strpos($_tag, $macro)) !== false) 
 390       { 
 391         $_tag = substr_replace( $_tag, $value, $pos, strlen($macro) ); 
 392         $tag = substr_replace( $tag, ucfirst($value), $pos, strlen($macro) ); 
 393       } 
 394  
 395     $tag = @strtr( $tag, $this->language["NpjLettersFrom"], $this->language["NpjLettersTo"] ); 
 396     $tag = @strtr( $tag, $this->language["NpjBiLetters"] ); 
 397     if ($strtolow) $tag = strtolower( $tag ); 
 398  
 399     if ($_lang)
 400       $this->SetLanguage($_lang);
 401     return rtrim($tag, "/"); 
 402   }
 403  
 404   function Translit($tag, $direction=1) { //deprecated
 405    return $tag;
 406   }
 407  
 408   function LoadPage($tag, $time = "", $cache = LOAD_CACHE, $metadataonly = LOAD_ALL) 
 409   {
 410     $supertag = $this->NpjTranslit($tag, TRAN_LOWERCASE, TRAN_DONTLOAD);
 411  
 412     if ($this->GetCachedWantedPage($supertag)==1) return "";
 413  
 414     $page = $this->OldLoadPage($supertag,$time,$cache, true, $metadataonly);     // 1. search for supertag

 415     if (!$page)                                      // 2. if not found, search for tag 
 416  //    {

 417      $page = $this->OldLoadPage($tag,$time,$cache, false, $metadataonly);
 418  /*      if ($page)                                     // 3. if found, update supertag

 419        {

 420          $this->Query( "update ".$this->config["table_prefix"]."pages ".

 421                        "set supertag='".$supertag."' where tag = '".$tag."';" );

 422        }

 423      }

 424  */
 425     if (!$page) $this->CacheWantedPage($supertag);
 426     return $page;
 427   }
 428  
 429   function OldLoadPage($tag, $time = "", $cache = 1, $supertagged = false, $metadataonly = 0) 
 430   {
 431     $page = null;
 432     if (!$supertagged) $supertag = $this->NpjTranslit($tag, TRAN_LOWERCASE, TRAN_DONTLOAD);
 433     else $supertag=$tag;
 434     // retrieve from cache

 435     if (!$time && $cache && ($cachedPage = $this->GetCachedPage($supertag, $metadataonly))) $page = $cachedPage;
 436     // load page

 437     if ($metadataonly) $what = $this->pages_meta;
 438     else $what = "*";
 439     if (!$page)
 440     { 
 441       if ($supertagged) {
 442         $page = $this->LoadSingle("select ".$what." from ".$this->config["table_prefix"]."pages where supertag='".quote($tag)."' and latest = 'Y' limit 1");
 443         if ($time && $time!=$page["time"]) {
 444           $this->CachePage($page, $metadataonly);
 445           $page = $this->LoadSingle("select ".$what." from ".$this->config["table_prefix"]."revisions where supertag='".quote($tag)."' and time = '".quote($time)."' limit 1");
 446         }
 447       }
 448       else {
 449         $page = $this->LoadSingle("select ".$what." from ".$this->config["table_prefix"]."pages where tag='".quote($tag)."' and latest = 'Y' limit 1");
 450         if ($time && $time!=$page["time"]) {
 451           $this->CachePage($page, $metadataonly);
 452           $page = $this->LoadSingle("select ".$what." from ".$this->config["table_prefix"]."revisions where tag='".quote($tag)."' and time = '".quote($time)."' limit 1");
 453         }
 454       }
 455     }// cache result

 456     if (!$time && !$cachedPage) $this->CachePage($page, $metadataonly);
 457     return $page;
 458   }
 459   
 460   function GetCachedPage($tag, $metadataonly=0) { 
 461     if (isset( $this->pageCache[$tag] )) 
 462      if ($this->pageCache[$tag]["mdonly"]==0 || $metadataonly==$this->pageCache[$tag]["mdonly"])
 463        return $this->pageCache[$tag];
 464    return false;
 465   }
 466   
 467   function CachePage($page, $metadataonly=0) { 
 468    $page["supertag"] = $this->NpjTranslit($page["supertag"], TRAN_LOWERCASE, TRAN_DONTLOAD);
 469    $this->pageCache[$page["supertag"]] = $page;
 470    $this->pageCache[$page["supertag"]]["mdonly"] = $metadataonly;
 471   }
 472   
 473   function CacheWantedPage($tag, $check = 0) { 
 474    if ($check==0)
 475      $this->wantedCache[$this->language["code"]][$tag] = 1;  
 476    else if ($this->OldLoadPage($tag, "", 1, false, 1)=="")
 477      $this->wantedCache[$this->language["code"]][$tag] = 1;  
 478   }
 479   
 480   function ClearCacheWantedPage($tag){
 481     $this->wantedCache[$this->language["code"]][$tag] = 0;  
 482   }
 483   
 484   function GetCachedWantedPage($tag) 
 485   {
 486     if (isset( $this->wantedCache[$this->language["code"]][$tag] )) 
 487       return $this->wantedCache[$this->language["code"]][$tag];
 488     else 
 489       return '';
 490   }
 491   
 492   function GetCachedACL($tag, $privilege, $useDefaults) 
 493   {
 494     if (isset( $this->aclCache[$tag."#".$privilege."#".$useDefaults] ))
 495       return $this->aclCache[$tag."#".$privilege."#".$useDefaults];
 496     else
 497       return '';
 498   }
 499   function CacheACL($tag, $privilege, $useDefaults, $acl) { $this->aclCache[$tag."#".$privilege."#".$useDefaults] = $acl; }
 500   
 501   function CacheLinks() 
 502   { 
 503    if ($links = $this->LoadAll("select * from ".$this->config["table_prefix"]."links where from_tag='".quote($this->GetPageTag())."'")) 
 504    {
 505      $cl = count($links);
 506      for ($i=0; $i<$cl; $i++)
 507        $pages[$i] = $links[$i]["to_tag"];
 508    }
 509  
 510    $user = $this->GetUser();
 511    $pages[$cl] = $user["name"]; 
 512  
 513  
 514    $bookm = $this->GetDefaultBookmarks($user["lang"], "site")."\n".($user["bookmarks"] ? $user["bookmarks"] : $this->GetDefaultBookmarks($user["lang"]));
 515    $bookmarks = explode("\n", $bookm);
 516    for ($i=0; $i<=count($bookmarks); $i++)
 517      $pages[$cl+$i] = preg_replace("/^(.*?)\s.*$/","\\1",preg_replace("/[\[\]\(\)]/","",$bookmarks[$i]));
 518  
 519    $pages[]=$this->GetPageTag();
 520  
 521    $spages_str = ''; $pages_str = '';
 522    for ($i=0; $i<count($pages); $i++)
 523    {
 524      $spages[$i] = $this->NpjTranslit($pages[$i], TRAN_LOWERCASE, TRAN_DONTLOAD);
 525      $spages_str .= "'".quote($spages[$i])."', ";
 526      $pages_str .= "'".quote($pages[$i])."', ";
 527    }
 528    
 529    $spages_str=substr($spages_str,0,strlen($spages_str)-2);
 530    $pages_str=substr($pages_str,0,strlen($pages_str)-2);
 531  
 532    if ($links = $this->LoadAll("select ".$this->pages_meta." from ".$this->config["table_prefix"]."pages where supertag in (".$spages_str.")"))
 533      for ($i=0; $i<count($links); $i++) 
 534      {
 535        $this->CachePage($links[$i], 1);
 536        $exists[] = $links[$i]["supertag"];
 537      }
 538    $notexists = @array_values(@array_diff($spages, $exists));
 539    for ($i=0; $i<count($notexists); $i++) 
 540    {
 541      $this->CacheWantedPage($pages[array_search($notexists[$i],$spages)], 1);
 542      $this->CacheACL($notexists[$i], "read", 1, $acl);
 543    }
 544  
 545  //   unset($exists);

 546    if ($read_acls = $this->LoadAll("select * from ".$this->config["table_prefix"]."acls where BINARY page_tag in (".$pages_str.") and privilege = 'read'"))
 547      for ($i=0; $i<count($read_acls); $i++) 
 548      {
 549        $this->CacheACL($read_acls[$i]["supertag"], "read", 1, $read_acls[$i]);
 550  //       $exists[] = $read_acls[$i]["tag"];

 551      }
 552  /*

 553     $notexists = @array_values(@array_diff($pages, $exists));

 554     for ($i=0; $i<count($notexists); $i++) 

 555     {

 556       $acl = array("supertag" => $notexists[$i], "page_tag" => $notexists[$i], "privilege" => "read", "list" => "*", "time" => date("YmdHis"));

 557       $this->CacheACL($notexists[$i], "read", 1, $acl);

 558     }

 559  */
 560    $ddd = $this->GetMicroTime();
 561    $this->queryLog[] = array(
 562      "query"   => "<b>end caching links</b>",
 563      "time"    => $this->GetResourceValue("MeasuredTime").": ".(number_format(($ddd-$this->timer),3))." s");
 564   }
 565  
 566   function SetPage($page) 
 567   { 
 568    $langlist = $this->AvailableLanguages();
 569    $this->page = $page; 
 570    if ($this->page["tag"]) $this->tag = $this->page["tag"]; 
 571    if ($page["lang"])
 572      $this->pagelang = $page["lang"];
 573    else if ($_REQUEST["add"] && $_REQUEST["lang"] && in_array($_REQUEST["lang"], $langlist))
 574      $this->pagelang = $_REQUEST["lang"];
 575    else if ($_REQUEST["add"])
 576      $this->pagelang = $this->userlang;
 577    else 
 578      $this->pagelang = $this->GetConfigValue("language");
 579   }
 580   
 581   function LoadPageById($id) 
 582   { 
 583    if ($id!="-1")
 584     return $this->LoadSingle("select * from ".$this->config["table_prefix"]."revisions where id = '".quote($id)."' limit 1"); 
 585    else
 586     return $this->LoadSingle("select * from ".$this->config["table_prefix"]."pages where tag='".quote($this->GetPageTag())."' and latest='Y' limit 1"); 
 587   }
 588   
 589   function LoadRevisions($page) 
 590   { 
 591     $rev = $this->LoadAll("select ".$this->pages_meta." from ".$this->config["table_prefix"]."revisions where tag='".quote($page)."' order by time desc"); 
 592     if (is_array($rev)) array_unshift($rev, $this->LoadSingle("select ".$this->pages_meta." from ".$this->config["table_prefix"]."pages where tag='".quote($page)."' order by time desc  limit 1"));
 593     else $rev[] = $this->LoadSingle("select ".$this->pages_meta." from ".$this->config["table_prefix"]."pages where tag='".quote($page)."' order by time desc  limit 1");
 594     return $rev;
 595   }
 596   
 597   function LoadPagesLinkingTo($tag, $for="") 
 598   { 
 599    return $this->LoadAll("select from_tag as tag from ".$this->config["table_prefix"]."links where ".
 600     ($for?"from_tag like '".quote($for)."/%' and ":"").
 601     "((to_supertag='' AND to_tag='".quote($tag)."') OR to_supertag='".quote($this->NpJTranslit($tag))."')".
 602     " order by tag"); 
 603   }
 604   
 605   function LoadRecentlyChanged($limit=70, $for="", $from="")
 606   {
 607     $limit= (int) $limit;
 608     if ($pages = 
 609         $this->LoadAll("select ".$this->pages_meta." from ".$this->config["table_prefix"]."pages ".
 610         "where latest = 'Y' and comment_on = '' ".($from?"and time<='".quote($from)." 23:59:59'":"").
 611         ($for?"and supertag like '".quote($this->NpjTranslit($for))."/%' ":"").
 612         "order by time desc  limit ".$limit))
 613     {
 614       foreach ($pages as $page)
 615       {
 616         $this->CachePage($page, 1);
 617       }
 618  
 619       if ($read_acls = $this->LoadAll("select a.* "
 620                    ."from ".$this->config["table_prefix"]."acls a, ".$this->config["table_prefix"]."pages p "
 621                      ."where p.latest = 'Y' "
 622                      ."and p.comment_on = '' " 
 623                      ."and a.supertag = p.supertag "
 624                      .($for?"and p.supertag like '".quote($this->NpjTranslit($for))."/%' ":"")
 625                      ."and privilege = 'read' "
 626                      ."order by time desc limit ".$limit))
 627         for ($i=0; $i<count($read_acls); $i++) {
 628           $this->CacheACL($read_acls[$i]["supertag"], "read", 1,$read_acls[$i]);
 629         }
 630  
 631       return $pages;
 632     }
 633   }
 634   
 635   function LoadWantedPages($for="") 
 636   { 
 637     $pref = $this->config["table_prefix"];
 638     $sql = "select distinct ".$pref."links.to_tag as tag,count(".$pref."links.from_tag) as count ".
 639      "from ".$pref."links left join ".$pref."pages on ".
 640      "((".$pref."links.to_tag = ".$pref."pages.tag AND ".$pref."links.to_supertag='') ".
 641      " OR ".$pref."links.to_supertag=".$pref."pages.supertag) ".
 642      "where ".($for?$pref."links.to_tag like '".quote($for)."/%' and ":"").
 643      $pref."pages.tag is NULL group by tag order by count desc, tag asc limit 200";
 644     return $this->LoadAll($sql); 
 645   }
 646   
 647   function LoadOrphanedPages($for="") 
 648   { 
 649     $pref = $this->config["table_prefix"];
 650     $sql = "select distinct tag from ".$pref."pages left join ".$pref."links on ".
 651  //     $pref."pages.tag = ".$pref."links.to_tag where ".

 652      "((".$pref."links.to_tag = ".$pref."pages.tag AND ".$pref."links.to_supertag='') ".
 653      " OR ".$pref."links.to_supertag=".$pref."pages.supertag) where ".
 654      ($for?$pref."pages.tag like '".quote($for)."/%' and ":"").
 655      $pref."links.to_tag is NULL and ".$pref."pages.comment_on = '' ".
 656      "order by tag limit 200";
 657     return $this->LoadAll($sql); 
 658   }
 659   
 660   function LoadPageTitles() { return $this->LoadAll("select distinct tag from ".$this->config["table_prefix"]."pages order by tag"); }
 661   function LoadAllPages() { return $this->LoadAll("select ".$this->pages_meta." from ".$this->config["table_prefix"]."pages where latest = 'Y' and LEFT(supertag,7)!='comment' order by BINARY tag limit 1000"); }
 662   
 663   function FullTextSearch($phrase,$filter) 
 664   { 
 665    return $this->LoadAll("select ".$this->pages_meta." from ".$this->config["table_prefix"].
 666                          "pages where latest = 'Y' and (( match(body) against('".quote($phrase)."') ".
 667                          "or lower(tag) like lower('%".quote($phrase)."%')) ".($filter?"and comment_on=''":"")." )"); 
 668   }
 669  
 670   function TagSearch($phrase) { return $this->LoadAll("select ".$this->pages_meta." from ".$this->config["table_prefix"]."pages where latest = 'Y' and lower(tag) like binary lower('%".quote($phrase)."%') order by supertag"); }
 671  
 672   function SendMail($email,$subject, $message) {
 673     $headers = "From: \"".$this->GetConfigValue("wakka_name")."\"<".$this->GetConfigValue("admin_email").">\r\n";
 674     $headers .= "X-Mailer: PHP/".phpversion()."\r\n"; //mailer

 675     $headers .= "X-Priority: 3\r\n"; //1 UrgentMessage, 3 Normal

 676     $headers .= "Content-Type: text/html; charset=".$this->GetCharset()."\r\n";
 677     $subject =  "=?".$this->GetCharset()."?B?" . base64_encode($subject) . "?=";
 678     @mail($email, $subject, "<html><head></head><body>".$message."</body></html>", $headers);
 679   }
 680  
 681   function SavePage($tag, $body, $comment_on = "")
 682   {
 683     // get current user

 684     $user = $this->GetUserName();
 685  
 686     //ANTISPAM

 687     $this->spam = array(".cn/", "shop263", "haishun", "qenset-sh", "7766888.com", "xsjby", "asp169.com", "fm360.net", 
 688      "garrywa.com", "funasia", "sec66.com", "xhhj.com", "cndevi.com", "sinostrategy.com", "hdfix.com", 
 689      "voip99", "zhiliaotuofa", "shuangchuang", "9li.", "agreatserver.", "how-to-make-valances.", 
 690      "pop-the-question.", "m-shopping.de", "vitabig.com", "komusumeya.net", "ryohin.kir", "kir.jp", 
 691      "haru-ulala", "buy-cheap-", ".uni.cc", ".6x.to", ".qn.com", ".go.ro", "wiki.t35.com", "junyuan.com",
 692      "gad1ee.com", "0008888.com", "njlvtong.com", "shellbitumen.com", "njuyq.com", "searcher.cn",
 693      "51asa.com", "sooyi.com", "dlctc.com", "ganzao.", "68l.com", "tt33tt.com", "99bbcc.com", "88aabb.com",
 694      "5iu5iu.com", "tg123.net", "88118888.com", "dzdg007", "condyloma.net", "hpv.com", "17836.com", "hpv888.com",
 695      "bxmm.com", "hpv120.com", "d9d.net", "chinaoo.com", "vipwww", "fengxiong.net", "13788888888.com",
 696      "pc123.cn", "88558888.com", "3333888888.com");
 697  
 698     if (is_array($this->spam))
 699     foreach ($this->spam as $spam)
 700     {
 701      if (strpos($body, $spam)!==false) return "Error: couldn't connect to database.";
 702     }
 703  
 704  //   die ($this->userlang."|".$this->pagelang."|".$_REQUEST["lang"]."|".$_POST["tag"]."|".$this->tag."|".$this->supertag);

 705     if($_POST["tag"]) 
 706     {
 707       $this->tag = $tag = $_POST["tag"];
 708       $this->supertag = $this->NpjTranslit($tag);
 709     }
 710  
 711     if (!$this->NpjTranslit($tag)) return;
 712  
 713     if ($this->GetConfigValue("cache"))
 714     if ($comment_on) $this->cache->CacheInvalidate($comment_on);
 715     else 
 716     {
 717      $this->cache->CacheInvalidate($this->tag);
 718      $this->cache->CacheInvalidate($this->supertag);
 719     }
 720  
 721     if ($this->HasAccess("write", $tag) || ($comment_on && $this->HasAccess("comment", $comment_on)))
 722     {
 723       $body = $this->Format($body, "preformat");
 724       // is page new?

 725       if (!$oldPage = $this->LoadPage($tag))
 726       {
 727         $langlist = $this->AvailableLanguages();
 728         if ($_REQUEST["lang"] && in_array($_REQUEST["lang"], $langlist)) 
 729           $lang = $_REQUEST["lang"];
 730         else
 731           $lang = $this->userlang;
 732  
 733         if (!$lang) $lang = $this->GetConfigValue["language"];
 734  
 735         $this->SetLanguage($lang);
 736  
 737         $body_r = $this->Format($body, "wacko");
 738         if ($this->GetConfigValue("paragrafica") && !$comment_on)
 739         {
 740           $body_r = $this->Format($body_r, "paragrafica");
 741           $body_toc = $this->body_toc;
 742         }
 743         // create default write acl. store empty write ACL for comments.

 744         // get default acl for root.

 745         if (strstr($this->context[$this->current_context], "/")) 
 746         {
 747           $root = preg_replace( "/^(.*)\\/([^\\/]+)$/", "$1", $this->context[$this->current_context] );
 748           $write_acl = $this->LoadAcl($root, "write");
 749           while ($write_acl["default"]==1)
 750           {
 751             $_root = $root;
 752             $root = preg_replace( "/^(.*)\\/([^\\/]+)$/", "$1", $root );
 753             if ($root == $_root) break;
 754             $write_acl = $this->LoadAcl($root, "write");
 755           }
 756                                                                         $write_acl   = $write_acl["list"];
 757           $read_acl = $this->LoadAcl($root, "read");                    $read_acl    = $read_acl["list"];
 758           $comment_acl = $this->LoadAcl($root, "comment");              $comment_acl = $comment_acl["list"];
 759         }
 760         else 
 761         { $write_acl = $this->GetConfigValue("default_write_acl");      
 762           $read_acl  = $this->GetConfigValue("default_read_acl");       
 763           $comment_acl = $this->GetConfigValue("default_comment_acl");  
 764         }
 765  
 766         // current user is owner; if user is logged in! otherwise, no owner.

 767         if ($this->GetUser()) $owner = $user;
 768         
 769         $this->Query("insert into ".$this->config["table_prefix"]."pages set ".
 770           ($comment_on ? "comment_on = '".quote($comment_on)."', " : "").
 771           ($comment_on ? "super_comment_on = '".quote($this->NpjTranslit($comment_on))."', " : "").
 772           "time = now(), ".
 773           "owner = '".quote($owner)."', ".
 774           "user = '".quote($user)."', ".
 775           "latest = 'Y', ".
 776           "supertag = '".quote($this->NpjTranslit($tag))."', ".
 777           "body = '".quote($body)."', ".
 778           "body_r = '".quote($body_r)."', ".
 779           "body_toc = '".quote($body_toc)."', ".
 780           "lang = '".quote($lang)."', ".
 781           "tag = '".quote($tag)."'");
 782  
 783  
 784         $this->SaveAcl($tag, "write", ($comment_on ? "" : $write_acl));
 785         $this->SaveAcl($tag, "read", $read_acl);
 786         $this->SaveAcl($tag, "comment", ($comment_on ? "" : $comment_acl));
 787         
 788         if ($this->GetUser() && !$this->GetConfigValue("disable_autosubscribe")) 
 789           $this->SetWatch($this->GetUserName(), $this->GetPageTag());
 790  
 791         if ($comment_on) {
 792          $username = $this->GetUserName();
 793          $Watchers = $this->LoadAll("select distinct user from ".$this->config["table_prefix"]."pagewatches where tag = '".quote($comment_on)."'");
 794          foreach ($Watchers as $Watcher)
 795          if ($Watcher["user"] !=  $username)
 796          {
 797            $_user = $this->GetUser();
 798            $Watcher["name"] = $Watcher["user"];
 799            $this->SetUser($Watcher, 0);
 800  
 801            if ($this->HasAccess("read", $comment_on, $Watcher["user"]))
 802            {
 803             $User = $this->LoadSingle("select email, lang, more, email_confirm from " .$this->config["user_table"]." where name = '".quote($Watcher["user"])."'");
 804             $User["options"] = $this->DecomposeOptions($User["more"]);
 805             if ($User["email_confirm"]=="" && $User["options"]["send_watchmail"]!="N")
 806             {
 807              $lang = $User["lang"];
 808              $subject = $this->GetResourceValue("Comment for watched page",$lang)."'".$comment_on."'";
 809              $message = $this->GetResourceValue("MailHello",$lang). $Watcher["user"].".<br /> <br /> ";
 810              $message .=   $username.
 811                            $this->GetResourceValue("Someone commented",$lang)."<br />  * <a href=\"".$this->Href("",$comment_on,"")."\">".$this->Href("",$comment_on,"")."</a><br />";
 812              $message .= "<hr />".$this->Format($body_r, "post_wacko")."<hr />";
 813              $message .= "<br />".$this->GetResourceValue("MailGoodbye",$lang)." ".$this->GetConfigValue("wakka_name");
 814              $this->SendMail($User["email"], $subject, $message);
 815             }
 816            }
 817            $this->SetUser($_user, 0);
 818          }
 819         }
 820       }
 821       else
 822       {
 823         $this->SetLanguage($this->pagelang);
 824         $body_r = $this->Format($body, "wacko");
 825         if ($this->GetConfigValue("paragrafica"))
 826         {
 827           $body_r = $this->Format($body_r, "paragrafica");
 828           $body_toc = $this->body_toc;
 829         }
 830         // aha! page isn't new. keep owner!

 831         $owner = $oldPage["owner"];
 832         if ($oldPage['body'] != $body) 
 833         {
 834          // move revision

 835          $this->Query("insert into ".$this->config["table_prefix"]."revisions (tag, time, body, owner, user, latest, handler, comment_on, supertag, keywords, description) ".
 836              "select tag, time, body, owner, user, 'N', handler, comment_on, supertag, keywords, description from ".$this->config["table_prefix"]."pages WHERE tag = '".quote($tag)."' and latest='Y' LIMIT 1");
 837  
 838          // add new revision

 839          $this->Query("update ".$this->config["table_prefix"]."pages set ".
 840            ($comment_on ? "comment_on = '".quote($comment_on)."', " : "").
 841            ($comment_on ? "super_comment_on = '".quote($this->NpjTranslit($comment_on))."', " : "").
 842            "time = now(), ".
 843            "owner = '".quote($owner)."', ".
 844            "user = '".quote($user)."', ".
 845            "supertag = '".$this->NpjTranslit($tag)."', ".
 846            "body = '".quote($body)."', ".
 847            "body_toc = '".quote($body_toc)."', ".
 848            "body_r = '".quote($body_r)."' ".
 849            "where tag = '".quote($tag)."' and latest='Y' LIMIT 1");
 850         }
 851  
 852       $username = $this->GetUserName();
 853       $Watchers = $this->LoadAll("select distinct user from ".$this->config["table_prefix"]."pagewatches where tag = '".quote($tag)."'");
 854       if ($Watchers)
 855       {
 856        foreach ($Watchers as $Watcher)
 857         if ($Watcher["user"] !=  $username)
 858         {
 859          $_user = $this->GetUser();
 860          $Watcher["name"] = $Watcher["user"];
 861          $this->SetUser($Watcher, 0);
 862          $lang = $Watcher["lang"];
 863          if ($this->HasAccess("read", $tag, $Watcher["user"]))
 864          {
 865           $User = $this->LoadSingle("select email, lang, more, email_confirm from " .$this->config["user_table"]." where name = '".quote($Watcher["user"])."'");
 866           $User["options"] = $this->DecomposeOptions($User["more"]);
 867           if ($User["email_confirm"]=="" && $User["options"]["send_watchmail"]!="N")
 868           {
 869             $lang = $User["lang"];
 870             $subject = $this->GetResourceValue("A watched Page changed!",$lang)."'".$tag."'";
 871             $message = "<style>.additions {color: #008800;}\n.deletions {color: #880000;}</style>";
 872             $message .= $this->GetResourceValue("MailHello",$lang). $Watcher["user"].".<br /> <br /> ";
 873             $message .=   $username.
 874                           $this->GetResourceValue("Someone changed this page:",$lang)."<br />  ";//* <a href=\"".$this->Href("",$tag,"")."\">".$this->Href("",$tag,"")."</a><br />";

 875             $_GET["fastdiff"] = 1;

 876             $_GET["a"] = -1;

 877             $page = $this->LoadSingle("select ".$this->pages_meta." from ".$this->config["table_prefix"]."revisions where tag='".quote($tag)."' order by time desc"); 

 878             $_GET["b"] = $page["id"];

 879             $message .= "<hr />".$this->IncludeBuffered("handlers/page/diff.php", "oops")."<hr />";

 880             $message .= "<br />".$this->GetResourceValue("MailGoodbye",$lang)." ".$this->GetConfigValue("wakka_name");

 881             $this->SendMail($User["email"], $subject, $message);

 882           }

 883          }

 884          $this->SetUser( $_user, 0 ); 

 885         }

 886       }

 887       $this->SetLanguage($this->userlang);

 888     }

 889     }

 890     

 891     $this->WriteRecentChangesXML();

 892  

 893     return $body_r;

 894   }

 895  

 896   function SaveMeta($tag, $metadata)

 897   {

 898     if ($this->UserIsOwner($tag))

 899     {

 900        // update

 901        $this->Query("update ".$this->config["table_prefix"]."pages set ".

 902          "lang = '".quote($metadata["lang"])."', ".

 903          "keywords = '".quote($metadata["keywords"])."', ".

 904          "description = '".quote($metadata["description"])."' ".

 905          "where tag = '".quote($tag)."' and latest='Y' LIMIT 1");

 906     }

 907     return true;

 908   }

 909  

 910   // COOKIES

 911   function SetSessionCookie($name, $value) { SetCookie($this->config["cookie_prefix"].$name, $value, 0, "/"); $_COOKIE[$this->config["cookie_prefix"].$name] = $value; }

 912   function SetPersistentCookie($name, $value, $remember = 1) { SetCookie($this->config["cookie_prefix"].$name, $value, time() + ($remember ? 90*24*60*60 : 60 * 60), "/"); $_COOKIE[$this->config["cookie_prefix"].$name] = $value; }

 913   function DeleteCookie($name) { SetCookie($this->config["cookie_prefix"].$name, "", 1, "/"); $_COOKIE[$this->config["cookie_prefix"].$name] = ""; }

 914   function GetCookie($name) { return $_COOKIE[$this->config["cookie_prefix"].$name]; }

 915  

 916   // HTTP/REQUEST/LINK RELATED

 917   function SetMessage($message) { $_SESSION["message"] = $message; }

 918   function GetMessage() { $message = $_SESSION["message"]; $_SESSION["message"] = ""; return $message; }

 919   function Redirect($url) { header("Location: $url"); exit; }

 920   

 921   function UnwrapLink( $tag )

 922   {

 923     if ($tag=="/") return "";

 924     if ($tag=="!") return $this->tag;

 925  

 926     $newtag = $tag;

 927  

 928     if (strstr($this->context[$this->current_context], "/")) 

 929       $root = preg_replace( "/^(.*)\\/([^\\/]+)$/", "$1", $this->context[$this->current_context] );

 930                            else $root = "";

 931     if (preg_match("/^\.\/(.*)$/", $tag, $matches)) { $root=""; }

 932     else if (preg_match("/^\/(.*)$/", $tag, $matches)) { $root = ""; $newtag = $matches[1]; }

 933     else if (preg_match("/^\!\/(.*)$/", $tag, $matches)) 

 934     { 

 935      $root = $this->context[$this->current_context]; 

 936      $newtag = $matches[1]; 

 937     }

 938     else if (preg_match("/^\.\.\/(.*)$/", $tag, $matches)) 

 939     { 

 940      $newtag = $matches[1];  

 941      if (strstr($root, "/")) 

 942         $root = preg_replace( "/^(.*)\\/([^\\/]+)$/", "$1", $root );

 943      else $root = "";

 944     }

 945     if ($root != "") $newtag= "/".$newtag;

 946     $tag = $root.$newtag;

 947     $tag = str_replace( "//", "/", $tag );

 948     return $tag;

 949   }

 950   

 951   // returns just PageName[/method].

 952   function MiniHref($method = "", $tag = "", $addpage = "") 

 953   { 

 954    if (!$tag = trim($tag)) $tag = $this->tag;

 955    if (!$addpage) $tag=$this->SlimUrl($tag);

 956    //$tag = $this->Translit($tag, 0);

 957    $tag = trim( $tag, "/." );

 958    return $tag.($method ? "/".$method : ""); 

 959   }

 960   

 961   // returns the full url to a page/method.

 962   function Href($method = "", $tag = "", $params = "", $addpage=0)

 963   {

 964    $href = $this->config["base_url"].$this->MiniHref($method, $tag, $addpage);

 965    if ($addpage) $params="add=1".($params?"&amp;".$params:"");

 966    if ($params)

 967    {

 968     $href .= ($this->config["rewrite_mode"] ? "?" : "&amp;").$params;

 969    }

 970    return $href;

 971   }

 972   

 973   function ComposeLinkToPage($tag, $method = "", $text = "", $track = 1)

 974   {

 975     if (!$text) $text = $this->AddSpaces($tag);

 976     //$text = htmlentities($text);

 977     if ($_SESSION["linktracking"] && $track)

 978             $this->TrackLinkTo($tag);

 979     return '<a href="'.$this->href($method, $tag).'">'.$text.'</a>';

 980   }

 981   

 982   function PreLink($tag, $text = "", $track = 1) 

 983   {

 984  //    if (!$text) $text = $this->AddSpaces($tag);

 985  

 986     if (preg_match("/^[\!\.".$this->language["ALPHANUM_P"]."]+$/", $tag))

 987     {// it's a Wiki link!

 988       if ($_SESSION["linktracking"] && $track) $this->TrackLinkTo($this->UnwrapLink( $tag ));

 989     }

 990     return "\xA2\xA2".$tag." ==".($this->format_safe?str_replace(">", "&gt;", str_replace("<", "&lt;", $text)):$text)."\xAF\xAF";

 991   }

 992   

 993   // <? 

 994   function Link($tag, $method = "", $text = "", $track = 1, $safe=0, $linklang="") 

 995   {

 996     $class = '';   $title = '';  $lang = '';

 997  

 998     $text = str_replace('"', "&quot;", $text);

 999  

1000     if (!$safe)

1001       $text = htmlspecialchars($text, ENT_NOQUOTES);

1002  

1003     if ($linklang) 

1004       $this->SetLanguage($linklang);

1005  

1006     $imlink = false;

1007     if (preg_match("/^[\.\-".$this->language["ALPHANUM_P"]."]+\.(gif|jpg|jpe|jpeg|png)$/i", $text))

1008       $imlink = $this->GetConfigValue("root_url")."/images/".$text;

1009     else if (preg_match("/^(http|https|ftp):\/\/([^\\s\"<>]+)\.(gif|jpg|jpe|jpeg|png)$/i", preg_replace("/<\/?nobr>/", "" ,$text)))

1010       $imlink = $text = preg_replace("/(<|\&lt\;)\/?span( class\=\"nobr\")?(>|\&gt\;)/", "" ,$text);

1011     $url = '';

1012  

1013     if (preg_match("/^(mailto[:])?[^\\s\"<>&\:]+\@[^\\s\"<>&\:]+\.[^\\s\"<>&\:]+$/", $tag, $matches))

1014     {// this is a valid Email

1015       $url = ($matches[1]=="mailto:" ? $tag : "mailto:".$tag); 

1016       $title = $this->GetResourceValue("MailLink");

1017       $icon = $this->GetResourceValue("mailicon");

1018       $tpl = "email";

1019     }

1020     else if (preg_match("/^#/", $tag))

1021     {// html-anchor

1022       $url = $tag;

1023       $tpl = "anchor";

1024     }                         

1025     else if (preg_match("/^[\.\-".$this->language["ALPHANUM_P"]."]+\.(gif|jpg|jpe|jpeg|png)$/i", $tag))

1026     {// image

1027       $text = preg_replace("/(<|\&lt\;)\/?span( class\=\"nobr\")?(>|\&gt\;)/", "" ,$text);

1028       return "<img src=\"".$this->GetConfigValue("root_url")."/images/".$tag."\" ".($text?"alt=\"".$text."\" title=\"".$text."\"":"")." />";

1029     }

1030     else if (preg_match("/^(http|https|ftp|file):\/\/([^\\s\"<>]+)\.(gif|jpg|jpe|jpeg|png)$/i", $tag))

1031     {// external image 

1032       $text = preg_replace("/(<|\&lt\;)\/?span( class\=\"nobr\")?(>|\&gt\;)/", "" ,$text);

1033       return "<img src=\"".str_replace("&", "&amp;", str_replace("&amp;", "&", $tag))."\" ".($text?"alt=\"".$text."\" title=\"".$text."\"":"")." />";

1034     }

1035     else if (preg_match("/^(http|https|ftp|file):\/\/([^\\s\"<>]+)\.(rpm|gz|tgz|zip|rar|exe|doc|xls|ppt|tgz|pdf)$/", $tag))

1036     {// this is a file link

1037       $url = str_replace("&", "&amp;", str_replace("&amp;", "&", $tag)); 

1038       $title= $this->GetResourceValue("FileLink");

1039       $icon = $this->GetResourceValue("fileicon");

1040       $tpl = "file";

1041     } 

1042     else if (preg_match("/^(http|https|ftp|file|nntp|telnet):\/\/([^\\s\"<>]+)$/", $tag))

1043     {// this is a valid external URL

1044       $url = str_replace("&", "&amp;", str_replace("&amp;", "&", $tag));

1045       if (!stristr($tag,$this->config["base_url"])) 

1046       {

1047        $title= $this->GetResourceValue("OuterLink2");

1048        $icon = $this->GetResourceValue("outericon");

1049       }

1050       $tpl = "outerlink";

1051     } 

1052     else if (preg_match("/^(_?)file:([^\\s\"<>\(\)]+)$/", $tag, $matches))

1053     {// this is a file:

1054       $noimg = $matches[1];

1055       $thing = $matches[2];

1056       $arr = explode("/", $thing);

1057  //echo($thing."<br />");

1058       if (count($arr)==1)                // file:shit.zip

1059       {

1060  //    echo ($thing."<br />");

1061         //try to find in global storage and return if success

1062         $desc = $this->CheckFileExists($thing);

1063  //    print_r($desc);

1064         if (is_array($desc))

1065         {

1066           $title = $desc["description"]." (".ceil($desc["filesize"]/1024)."&nbsp;".$this->GetResourceValue("UploadKB").")";

1067           if ($desc["picture_w"] && !$noimg)

1068           {

1069             if (!$text) $text = $title;

1070             return "<img src=\"".$this->GetConfigValue("root_url").$this->config["upload_path"]."/".$thing."\" ".($text?"alt=\"".$text."\" title=\"".$text."\"":"")." width='".$desc["picture_w"]."' height='".$desc["picture_h"]."' />";

1071           }

1072           $url = $this->GetConfigValue("root_url").$this->config["upload_path"]."/".$thing;

1073           $icon = $this->GetResourceValue("fileicon");

1074           $imlink = false;

1075           $tpl = "localfile";

1076         }

1077       }

1078       if (count($arr)==2 && $arr[0]=="") // file:/shit.zip

1079       {

1080         //try to find in global storage and return if success

1081         $desc = $this->CheckFileExists($arr[1]);

1082         if (is_array($desc))

1083         {

1084           $title = $desc["description"]." (".ceil($desc["filesize"]/1024)."&nbsp;".$this->GetResourceValue("UploadKB").")";

1085           if ($desc["picture_w"] && !$noimg)

1086           {

1087             if (!$text) $text = $title;

1088             return "<img src=\"".$this->GetConfigValue("root_url").$this->config["upload_path"]."/".$thing."\" ".($text?"alt=\"".$text."\" title=\"".$text."\"":"")." width='".$desc["picture_w"]."' height='".$desc["picture_h"]."' />";

1089           }

1090           $url = $this->GetConfigValue("root_url").$this->config["upload_path"].$thing;

1091           $imlink = false;

1092           $icon = $this->GetResourceValue("fileicon");

1093           $tpl = "localfile";

1094         }

1095         else //404

1096         {

1097           $tpl = "wlocalfile";

1098           $title = "404: /".$this->config["upload_path"].$thing;

1099           $url = "404";

1100         }

1101           

1102       }

1103       if (!$url)

1104       {

1105         $file = $arr[count($arr)-1];

1106         unset($arr[count($arr)-1]);

1107         $_pagetag = implode("/", $arr);

1108         if ($_pagetag=="") $_pagetag = "!/";

1109         //unwrap tag (check !/, ../ cases)

1110         $pagetag = $this->UnwrapLink( $_pagetag );

1111         //try to find in local $tag storage

1112         $desc = $this->CheckFileExists($file, $pagetag);

1113         if (is_array($desc))

1114         {

1115          //check 403 here!

1116           if ($this->IsAdmin() || ($desc["id"] && ($this->GetPageOwner($this->tag) == $this->GetUserName())) ||

1117               ($this->HasAccess("read", $pagetag)) || ($desc["user"] == $this->GetUserName()) )

1118           {        

1119             $title = $desc["description"]." (".ceil($desc["filesize"]/1024)."&nbsp;".$this->GetResourceValue("UploadKB").")";

1120             if ($desc["picture_w"] && !$noimg)

1121             {

1122               if (!$text) $text = $title;

1123               return "<img src=\"".$this->config["base_url"].trim($pagetag,"/")."/files".($this->config["rewrite_mode"] ? "?" : "&amp;")."get=".$file."\" ".($text?"alt=\"".$text."\" title=\"".$text."\"":"")." width='".$desc["picture_w"]."' height='".$desc["picture_h"]."' />";

1124             }

1125             $url = $this->config["base_url"].trim($pagetag,"/")."/files".($this->config["rewrite_mode"] ? "?" : "&amp;")."get=".$file;

1126             $imlink = false;

1127             $icon = $this->GetResourceValue("fileicon");

1128             $tpl = "localfile";

1129           }

1130           else //403

1131           {

1132             $url = $this->config["base_url"].trim($pagetag,"/")."/files".($this->config["rewrite_mode"] ? "?" : "&amp;")."get=".$file;

1133             $imlink = false;

1134             $icon = $this->GetResourceValue("lockicon");

1135             $tpl = "localfile";

1136             $class = "denied";

1137           }

1138         }

1139         else //404

1140         { 

1141           $tpl = "wlocalfile";

1142           $title = "404: /".trim($pagetag,"/")."/files".($this->config["rewrite_mode"] ? "?" : "&amp;")."get=".$file;

1143           $url = "404";

1144         }

1145           

1146       }

1147       //forgot 'bout 403

1148     } 

1149     else if ($this->GetConfigValue("disable_tikilinks")!=1 && preg_match("/^(".$this->language["UPPER"].$this->language["LOWER"].$this->language["ALPHANUM"]."*)\.(".$this->language["ALPHA"].$this->language["ALPHANUM"]."+)$/s", $tag, $matches)) 

1150     {// it`s a Tiki link!

1151       if (!$text) $text = $this->AddSpaces($tag);

1152       $tag = "/".$matches[1]."/".$matches[2];

1153       return $this->Link( $tag, $method, $text, $track, 1);

1154     }

1155     else if (preg_match("/^([[:alnum:]]+)[:]([".$this->language["ALPHANUM_P"]."\-\_\.\+\&\=\#]*)$/", $tag, $matches))

1156     {// interwiki

1157       $parts = explode("/",$matches[2]);

1158       for ($i=0;$i<count($parts);$i++) $parts[$i] = str_replace("%23", "#", urlencode($parts[$i]));

1159       $url = $this->GetInterWikiUrl($matches[1], implode("/",$parts));

1160       $icon = $this->GetResourceValue("iwicon");

1161       $tpl = "interwiki";

1162       if ($linklang)

1163         $text = $this->DoUnicodeEntities($text, $linklang);

1164     }

1165     else if (preg_match("/^([\!\.".$this->language["ALPHANUM_P"]."]+)(\#[".$this->language["ALPHANUM_P"]."\_\-]+)?$/", $tag, $matches))

1166     {// it's a Wiki link!

1167       $tag = $otag = $matches[1];

1168       $untag = $unwtag = $this->UnwrapLink( $tag );

1169  

1170       $regex_handlers = '/^(.*?)\/('.$this->GetConfigValue("standart_handlers").')\/(.*)$/i';

1171       $ptag = $this->NpjTranslit($unwtag);

1172       $handler = null;

1173       if (preg_match( $regex_handlers, "/".$ptag."/", $match ))

1174       {

1175         $handler = $match[2];

1176         $ptag = $match[1];

1177         $unwtag = "/".$unwtag."/";

1178         $co = substr_count($_ptag, "/") - substr_count($ptag, "/");

1179         for ($i=0; $i<$co; $i++) $unwtag = substr($unwtag,0,strrpos($unwtag,"/"));

1180         if ($handler)

1181         {

1182          $opar = "/".$untag."/";

1183          for ($i=0; $i<substr_count($data, "/")+2; $i++) $opar = substr($opar,strpos($opar,"/")+1);

1184          $params = explode("/", $opar); //there're good params

1185         }

1186       }

1187       $unwtag = trim($unwtag, "/.");

1188       $unwtag = str_replace( "_", "", $unwtag );

1189       if ($handler) $method = $handler;

1190       //if ($tag=="!/edit") echo "{".$tag."|".$untag."|".$unwtag."|".$handler."}";

1191  

1192       $thispage = $this->LoadPage($unwtag, "", LOAD_CACHE, LOAD_META);

1193       if (!$thispage && $linklang) 

1194       {

1195         $this->SetLanguage($linklang);

1196         $lang = $linklang;

1197         $thispage = $this->LoadPage($unwtag, "", LOAD_CACHE, LOAD_META);

1198       }

1199       if ($thispage) 

1200       {

1201        $_lang = $this->language["code"];

1202        if ($thispage["lang"]) $lang = $thispage["lang"];

1203        else $lang = $this->GetConfigValue("language");

1204  

1205        $this->SetLanguage($lang);

1206        $supertag = $this->NpjTranslit($tag);

1207  //       echo "<h1>".$_lang."|".$lang."|".$supertag."</h1>";

1208       }

1209       else 

1210       {

1211        $supertag = $this->NpjTranslit($tag, TRAN_LOWERCASE, TRAN_DONTLOAD);

1212       }

1213  

1214  

1215       $aname="";

1216       if (substr($tag,0,2)=="!/")

1217       {

1218        $icon = $this->GetResourceValue("childicon");

1219        $page0 = substr($tag,2);

1220        $page = $this->AddSpaces($page0);

1221        $tpl = "childpage";

1222       }

1223       else if (substr($tag,0,3)=="../")

1224       {

1225        $icon = $this->GetResourceValue("parenticon");

1226        $page0 = substr($tag,3);

1227        $page = $this->AddSpaces($page0);

1228        $tpl = "parentpage";

1229       }

1230       else if (substr($tag,0,1)=="/")

1231       {

1232        $icon = $this->GetResourceValue("rooticon");

1233        $page0 = substr($tag,1);

1234        $page = $this->AddSpaces($page0);

1235        $tpl = "rootpage";

1236       }

1237       else 

1238       {

1239        $icon = $this->GetResourceValue("equalicon");

1240        $page0 = $tag;

1241        $page = $this->AddSpaces($page0);

1242        $tpl = "equalpage";

1243       }

1244       if ($imlink) $text="<img src=\"$imlink\" border=\"0\" title=\"$text\" />";

1245       if ($text)

1246       {

1247        $tpl = "descrpage";

1248        $icon = "";

1249       }

1250       $pagepath = substr($untag,0, strlen($untag) - strlen($page0));

1251       $anchor = isset( $matches[2] ) ? $matches[2] : '';

1252       $tag = $unwtag;

1253       if ($_SESSION["linktracking"] && $track) $this->TrackLinkTo($tag);

1254  

1255       if (!isset( $this->first_inclusion[ $supertag ] )) $aname = "name=\"".$supertag."\"";

1256       $this->first_inclusion[ $supertag ] = 1; 

1257  

1258       if ($thispage) 

1259       {

1260         $pagelink = $this->href($method, $thispage["tag"]).$this->AddDateTime($tag).($anchor?$anchor:"");

1261         if ($this->config["hide_locked"]) $access = $this->HasAccess("read",$tag);

1262         else 

1263         {

1264          $access = true;

1265          $this->_acl["list"]=="*";

1266         }

1267         if (!$access) 

1268         {

1269          $class="denied";

1270          $accicon = $this->GetResourceValue("lockicon");

1271         }

1272         else if ($this->_acl["list"]=="*") 

1273         {

1274          $class = "";

1275          $accicon = "";

1276         }

1277         else 

1278         {

1279          $class="customsec";

1280          $accicon = $this->GetResourceValue("keyicon");

1281         }

1282         // language

1283  //        echo "<< ".$lang.":".$_lang.":".$otag."|$linklang >>";

1284  //        if ($lang!=$this->pagelang)

1285  //        {

1286          if ($text==trim($otag,"/") || $linklang)

1287            $text = $this->DoUnicodeEntities($text, $lang);

1288  //         echo "< ".$text.":".$otag." >";

1289          $page = $this->DoUnicodeEntities($page, $lang);

1290  //        }

1291        if (isset($_lang)) $this->SetLanguage($_lang);

1292       }

1293       else

1294       {

1295        $tpl = ($this->method=="print" || $this->method=="msword"?"p":"")."w".$tpl;

1296        $pagelink = $this->href("edit", $tag, $lang?"lang=".$lang:"", 1);

1297        $accicon = $this->GetResourceValue("wantedicon");

1298        $title = $this->GetResourceValue("CreatePage");

1299        if ($linklang)

1300        {

1301          $text = $this->DoUnicodeEntities($text, $linklang);

1302          $page = $this->DoUnicodeEntities($page, $linklang);

1303        }

1304       }

1305  

1306       $icon = str_replace("{theme}", $this->GetConfigValue("theme_url"), $icon);

1307       $accicon = str_replace("{theme}", $this->GetConfigValue("theme_url"), $accicon);

1308       $res = $this->GetResourceValue("tpl.".$tpl);

1309       $text = trim($text);

1310       if ($res)

1311       {

1312       //todo: pagepath

1313        $aname = str_replace("/", ".", $aname);

1314        $res = str_replace("{aname}",  $aname,  $res);

1315        $res = str_replace("{icon}",   $icon,   $res);

1316        $res = str_replace("{accicon}",$accicon,$res);

1317        $res = str_replace("{class}",  $class,  $res);

1318        $res = str_replace("{title}",  $title,  $res);

1319        $res = str_replace("{pagelink}", $pagelink, $res);

1320        $res = str_replace("{pagepath}", $pagepath, $res);

1321        $res = str_replace("{page}",   $page,  $res);

1322        $res = str_replace("{text}",   $text,  $res);

1323  //      if ($linklang)  {echo("{aname}".  $aname);echo("{icon}".   $icon);echo("{accicon}".$accicon);echo("{class}".  $class);echo("{title}".  $title);echo("{pagelink}". $pagelink);echo("{pagepath}". $pagepath);echo("{page}".   $page);echo("{text}".   $text);}

1324  

1325        if (!$text) $text = htmlspecialchars($tag, ENT_NOQUOTES);

1326        if ($this->GetConfigValue("youarehere_text"))

1327        if ($this->NpjTranslit($tag) == $this->NpjTranslit($this->context[$this->current_context])) 

1328          $res = str_replace("####", $text, $this->GetConfigValue("youarehere_text"));

1329        return $res;

1330       }

1331       die ("ERROR: no tpl '$tpl'!");

1332     }

1333     if (!$text) $text = htmlspecialchars($tag, ENT_NOQUOTES);

1334     if ($url)

1335     {

1336      if ($imlink) $text="<img src=\"$imlink\" border=\"0\" title=\"$text\" />";

1337      $icon = str_replace("{theme}", $this->GetConfigValue("theme_url"), $icon);

1338      $res = $this->GetResourceValue("tpl.".$tpl);

1339      if ($res)

1340      {

1341       if (!$class) $class="outerlink";

1342       $res = str_replace("{icon}",  $icon,  $res);

1343       $res = str_replace("{class}", $class, $res);

1344       $res = str_replace("{title}", $title, $res);

1345       $res = str_replace("{url}",   $url,   $res);

1346       $res = str_replace("{text}",  $text,  $res);

1347       return $res;

1348      }

1349     }

1350     //echo ("<br>".$tag."<br>");

1351     //die("^([[:alnum:]]+)[:]([".$this->language["ALPHANUM_P"]."\-\_\.\+\&\=]*)$");

1352     return $text;

1353   }

1354   

1355   function AddDatetime($tag)

1356   {

1357     if ($user = $this->GetUser()) $show = $user["showdatetime"];

1358     if (!$show) $show=$this->GetConfigValue("show_datetime");

1359     if (!$show) $show = "Y";

1360     if ($show!="N" && $show!="0") 

1361     {

1362       $_page = $this->LoadPage($tag, "", LOAD_CACHE, LOAD_META); 

1363       return ($this->config["rewrite_mode"] ? "?" : "&amp;").

1364         "v=".base_convert($this->crc16(preg_replace("/[ :\-]/","",$_page["time"])),10,36);

1365     } else return "";

1366   }

1367   

1368   function crc16($string) { 

1369    $crc = 0xFFFF; 

1370    for ($x = 0; $x < strlen ($string); $x++) { 

1371      $crc = $crc ^ ord($string[$x]); 

1372      for ($y = 0; $y < 8; $y++) { 

1373        if (($crc & 0x0001) == 0x0001) { 

1374          $crc = (($crc >> 1) ^ 0xA001); 

1375        } else { $crc = $crc >> 1; } 

1376      } 

1377    } 

1378    return $crc; 

1379   } 

1380   

1381   function AddSpaces($text)

1382   {

1383    $show = "Y";

1384    if ($user = $this->GetUser()) $show = $user["show_spaces"];

1385    if (!$show) $show=$this->GetConfigValue("show_spaces");

1386    if ($show!="N") {

1387      $text = preg_replace("/(".$this->language["ALPHANUM"].")(".$this->language["UPPERNUM"].")/","\\1&nbsp;\\2",$text);

1388      $text = preg_replace("/(".$this->language["UPPERNUM"].")(".$this->language["UPPERNUM"].")/","\\1&nbsp;\\2",$text);

1389      $text = preg_replace("/(".$this->language["ALPHANUM"].")\//","\\1&nbsp;/",$text);

1390      $text = preg_replace("/(".$this->language["UPPER"].")&nbsp;(?=".$this->language["UPPER"]."&nbsp;".$this->language["UPPERNUM"].")/","\\1",$text);

1391      $text = preg_replace("/(".$this->language["UPPER"].")&nbsp;(?=".$this->language["UPPER"]."&nbsp;\/)/","\\1",$text);

1392      $text = preg_replace("/\/(".$this->language["ALPHANUM"].")/","/&nbsp;\\1",$text);

1393      $text = preg_replace("/(".$this->language["UPPERNUM"].")&nbsp;(".$this->language["UPPERNUM"].")($|\b)/","\\1\\2",$text);

1394      $text = preg_replace("/([0-9])(".$this->language["ALPHA"].")/","\\1&nbsp;\\2",$text);

1395      $text = preg_replace("/(".$this->language["ALPHA"].")([0-9])/","\\1&nbsp;\\2",$text);

1396      $text = preg_replace("/([0-9])&nbsp;(?=[0-9])/","\\1",$text);

1397    }

1398    if (strpos($text, "/")===0) $text = $this->GetResourceValue("RootLinkIcon").substr($text, 1);

1399    if (strpos($text, "!/")===0) $text = $this->GetResourceValue("SubLinkIcon").substr($text, 2);

1400    if (strpos($text, "../")===0) $text = $this->GetResourceValue("UpLinkIcon").substr($text, 3);

1401    return $text;

1402   }

1403   

1404   function SlimUrl($text)

1405   {

1406    $text = $this->NpjTranslit($text, TRAN_DONTCHANGE);

1407    $text = str_replace("_", "'", $text);

1408    if ($this->config["urls_underscores"]==1) 

1409    {

1410     $text = preg_replace("/(".$this->language["ALPHANUM"].")(".$this->language["UPPERNUM"].")/","\\1ґ\\2",$text);

1411     $text = preg_replace("/(".$this->language["UPPERNUM"].")(".$this->language["UPPERNUM"].")/","\\1ґ\\2",$text);

1412     $text = preg_replace("/(".$this->language["UPPER"].")ґ(?=".$this->language["UPPER"]."ґ".$this->language["UPPERNUM"].")/","\\1",$text);

1413     $text = preg_replace("/(".$this->language["UPPER"].")ґ(?=".$this->language["UPPER"]."ґ\/)/","\\1",$text);

1414     $text = preg_replace("/(".$this->language["UPPERNUM"].")ґ(".$this->language["UPPERNUM"].")($|\b)/","\\1\\2",$text);

1415     $text = preg_replace("/\/ґ(".$this->language["UPPERNUM"].")/","/\\1",$text);

1416     $text = str_replace("ґ", "_", $text);

1417    }

1418    return $text;

1419   }

1420   

1421   function IsWikiName($text) { return preg_match("/^".$this->language["UPPER"].$this->language["LOWER"]."+".$this->language["UPPERNUM"].$this->language["ALPHANUM"]."*$/", $text); }

1422   function TrackLinkTo($tag) { $this->linktable[] = $tag; }

1423   function GetLinkTable() { return $this->linktable; }

1424   function ClearLinkTable() { $this->linktable = array(); }

1425   function StartLinkTracking() { $_SESSION["linktracking"] = 1; }

1426   function StopLinkTracking() { $_SESSION["linktracking"] = 0; }

1427   

1428   function WriteLinkTable()

1429   {

1430     // delete old link table

1431     $this->Query("delete from ".$this->config["table_prefix"]."links where from_tag = '".quote($this->GetPageTag())."'");

1432     if ($linktable = $this->GetLinkTable())

1433     {

1434       $from_tag = quote($this->GetPageTag());

1435       foreach ($linktable as $to_tag)

1436       {

1437         $lower_to_tag = strtolower($to_tag);

1438         if (!$written[$lower_to_tag])

1439         {

1440           $query.="('".$from_tag."', '".quote($to_tag)."', '".quote($this->NpjTranslit($to_tag))."'),";

1441           $written[$lower_to_tag] = 1;

1442         }

1443       }

1444       $this->Query("insert into ".$this->config["table_prefix"]."links (from_tag, to_tag, to_supertag) VALUES ".rtrim($query,","));

1445     }

1446   }

1447   

1448   function Header($mod="") {

1449  //    $this->StopLinkTracking();

1450     $result = $this->IncludeBuffered("header".$mod.".php", "Theme is corrupt: ".$this->GetConfigValue("theme"), "", "themes/".$this->GetConfigValue("theme")."/appearance");

1451  //    $this->StartLinkTracking();

1452     return $result;

1453    }

1454   

1455   function Footer($mod="") {

1456  //    $this->StopLinkTracking();

1457     $result = $this->IncludeBuffered("footer".$mod.".php", "Theme is corrupt: ".$this->GetConfigValue("theme"), "", "themes/".$this->GetConfigValue("theme")."/appearance");

1458  //    $this->StartLinkTracking();

1459     return $result;

1460   }

1461  

1462   function UseClass($class_name, $class_dir="", $file_name="" )

1463   {

1464     if(!class_exists($class_name))

1465     {

1466       if ($file_name == "") $file_name=$class_name;

1467       if ($class_dir == "") $class_dir=$this->classes_dir;

1468       $class_file = $class_dir.$file_name.".php";

1469       $class_file = trim($class_file, "./");

1470  

1471       if (!@is_readable($class_file)) 

1472        die("Cannot load class ".$class_name."  from ". $class_file. " (".$class_dir.")");

1473       else require_once($class_file);

1474     } 

1475   }

1476  

1477   // tabbed theme output routine

1478   function EchoTab( $link, $hint, $text, $selected=false, $bonus="" )

1479   {

1480     $xsize = $selected?7:8;

1481     $ysize = $selected?25:30;

1482     if ($text == "") return; // no tab;

1483     if ($selected) $text = "<a href=\"$link\" title=\"$hint\">".$text."</a>";

1484     if (!$selected) echo "<div class='TabSelected$bonus' style='background-image:url(".$this->GetConfigValue("theme_url")."icons/tabbg.gif);' >";

1485     else echo "<div class='Tab$bonus' style='background-image:url(".$this->GetConfigValue("theme_url")."icons/tabbg".($bonus=="2a"?"del":"1").".gif);'>";

1486     $bonus2 = $bonus=="2a"?"del":"";

1487  

1488     echo '<table cellspacing="0" cellpadding="0" border="0" ><tr>';

1489       echo "<td><img src='".

1490             $this->GetConfigValue("theme_url").

1491             "icons/tabr$selected".$bonus2.".gif' width='$xsize' align='top' hspace='0' vspace='0' height='$ysize' alt='' border='0' /></td>";

1492       if (!$selected) echo "<td>"; else echo "<td valign='top'>";

1493         echo "<div class='TabText'>".$text."</div>";

1494       echo "</td>";

1495       echo "<td><img src='".

1496             $this->GetConfigValue("theme_url").

1497             "icons/tabl$selected".$bonus2.".gif' width='$xsize' align='top' hspace='0' vspace='0' height='$ysize' alt='' border='0' /></td>";

1498     echo '</tr></table>';

1499     echo "</div>";

1500   }

1501  

1502   // FORMS

1503   function FormOpen($method = "", $tag = "", $formMethod = "post", $formname="", $formMore="")

1504   {

1505     $add = isset( $_REQUEST["add"] ) ? $_REQUEST["add"] : '';

1506     $result = "<form action=\"".$this->href($method, $tag, "", $add)."\" ".$formMore." method=\"".$formMethod."\" ".($formname?"name=\"".$formname."\" ":"").">\n";

1507     if (!$this->config["rewrite_mode"]) $result .= "<input type=\"hidden\" name=\"wakka\" value=\"".$this->MiniHref($method, $tag, $add)."\" />\n";

1508     return $result;

1509   }

1510   

1511   function FormClose()

1512   {

1513     return "</form>\n";

1514   }

1515   

1516   function NoCache()

1517   {

1518    header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");    // Date in the past 

1519    header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // always modified 

1520    header("Cache-Control: no-store, no-cache, must-revalidate");  // HTTP/1.1 

1521    header("Cache-Control: post-check=0, pre-check=0", false); 

1522    header("Pragma: no-cache");                          // HTTP/1.0 

1523   }

1524  

1525   // INTERWIKI STUFF

1526   function ReadInterWikiConfig()

1527   {

1528     if ($lines = file("interwiki.conf"))

1529     {

1530       foreach ($lines as $line)

1531       {

1532         if ($line = trim($line))

1533         {

1534           list($wikiName, $wikiUrl) = explode(" ", trim($line));

1535           $this->AddInterWiki($wikiName, $wikiUrl);

1536         }

1537       }

1538     }

1539   }

1540   

1541   function AddInterWiki($name, $url)

1542   {

1543     $this->interWiki[strtolower($name)] = $url;

1544   }

1545   

1546   function GetInterWikiUrl($name, $tag)

1547   {

1548     if ($url = $this->interWiki[strtolower($name)])

1549     {

1550       $url = str_replace("&", "&amp;", $url); //xhtmlisation

1551       if (strpos($url, "%s")) {

1552         return str_replace("%s", $tag, $url);

1553       } else {

1554         return $url.$tag;

1555       }

1556     }

1557   }

1558  

1559   // REFERRERS

1560   function LogReferrer($tag = "", $referrer = "")

1561   {

1562     // fill values

1563     if (!$tag = trim($tag)) $tag = $this->GetPageTag();

1564     if (!$referrer = trim($referrer)) $referrer = isset( $_SERVER["HTTP_REFERER"] ) ? $_SERVER["HTTP_REFERER"] : '';

1565  

1566     // check if it's coming from another site

1567     if ($referrer && !preg_match("/^".preg_quote($this->GetConfigValue("base_url"), "/")."/", $referrer))

1568     {

1569       $this->Query("insert into ".$this->config["table_prefix"]."referrers set ".

1570         "page_tag = '".quote($tag)."', ".

1571         "referrer = '".quote($referrer)."', ".

1572         "time = now()");

1573     }

1574   }

1575   

1576   function LoadReferrers($tag = "")

1577   {

1578     return $this->LoadAll("select referrer, count(referrer) as num from ".$this->config["table_prefix"]."referrers ".($tag = trim($tag) ? "where page_tag = '".quote($tag)."'" : "")." group by referrer order by num desc");

1579   }

1580  

1581   // PLUGINS

1582   function Action($action, $params, $forceLinkTracking = 0)

1583   {

1584     $action = trim($action);

1585  

1586     if (!$forceLinkTracking) $this->StopLinkTracking();

1587     $result = $this->IncludeBuffered(strtolower($action).".php", "<i>Unknown action \"$action\"</i>", $params, $this->config["action_path"]);

1588     $this->StartLinkTracking();

1589     $this->NoCache();

1590     return $result;

1591   }

1592   

1593   function Method($method)

1594   {

1595     if ($method=="show") $this->CacheLinks();

1596     if (!$handler = $this->page["handler"]) $handler = "page";

1597     $methodLocation = $handler."/".$method.".php";

1598     return $this->IncludeBuffered($methodLocation, "<i>Unknown method \"$methodLocation\"</i>", "", $this->config["handler_path"]);

1599   }

1600   

1601   function Format($text, $formatter = "wakka", $options = "") 

1602   { 

1603     return $this->_Format($text, $formatter, $options);

1604   }

1605  

1606   function _Format($text, $formatter, &$options) 

1607   { 

1608     $text = $this->IncludeBuffered("formatters/".$formatter.".php", 

1609       "<i>Formatter \"$formatter\" not found</i>", compact("text", "options")); 

1610     if ($formatter == "wacko" && $this->GetConfigValue("default_typografica"))

1611        $text = $this->IncludeBuffered("formatters/typografica.php", "<i>Formatter \"$formatter\" not found</i>", compact("text")); 

1612     return $text; 

1613   }

1614  

1615   // USERS

1616   function LoadUser($name, $password = 0) 

1617   { 

1618     $user = $this->LoadSingle("select * from ".$this->config["user_table"]." where name = '".

1619             quote($name)."' ".($password === 0 ? "" : "and password = '".quote($password)."'")." limit 1"); 

1620     if ($user) $user["options"] = $this->DecomposeOptions($user["more"]);

1621     return $user;

1622   }

1623   

1624   function LoadUsers() { return $this->LoadAll("select * from ".$this->config["user_table"]." order by binary name"); }

1625   

1626   function GetUserName() 

1627   { 

1628     if ($user = $this->GetUser()) $name = $user["name"]; 

1629     else if ($this->_userhost) $name = $this->_userhost; 

1630     else 

1631     {

1632      if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') $name = $_SERVER["REMOTE_ADDR"];

1633      else if (!$name = $this->_gethostbyaddr($_SERVER["REMOTE_ADDR"])) $name = $_SERVER["REMOTE_ADDR"];

1634      $this->_userhost = $name;

1635     }

1636     return $name; 

1637   }

1638   

1639   function _gethostbyaddr($ip) {if ($this->GetConfigValue("allow_gethostbyaddr")) return gethostbyaddr($ip); else return false;}

1640   function GetUser() 

1641   {

1642     if (isset( $_SESSION[$this->config["cookie_prefix"]."user"] )) 

1643       return $_SESSION[$this->config["cookie_prefix"]."user"];

1644     else 

1645       return null;

1646   }

1647   

1648   function SetUser($user, $setcookie=1) 

1649   { 

1650    $_SESSION[$this->config["cookie_prefix"]."user"] = $user; 

1651    if ($setcookie) $this->SetPersistentCookie("name", $user["name"], 1); 

1652   }

1653   

1654   function LogUserIn($user) 

1655   { 

1656    $this->SetPersistentCookie("name", $user["name"], 1); 

1657    $this->SetPersistentCookie("password", $user["password"]); 

1658   }

1659   

1660   function LogoutUser() { $_SESSION[$this->config["cookie_prefix"]."user"] = ""; $this->DeleteCookie("name"); $this->DeleteCookie("password"); }

1661   function UserWantsComments() { if (!$user = $this->GetUser()) return false; return ($user["show_comments"] == "Y"); }

1662   function UserWantsFiles()    { if (!$user = $this->GetUser()) return false; return ($user["options"]["show_files"] == "Y"); }

1663   

1664   function DecomposeOptions( $more )

1665   {

1666     $b = array();

1667     $opts = explode( $this->optionSplitter, $more );

1668     foreach( $opts as $o )

1669     {

1670       $params = explode( $this->valueSplitter, trim($o) );

1671       $b[ $params[0] ] = $params[1];

1672     }

1673     return $b;

1674   }

1675   

1676   function ComposeOptions( $options )

1677   {

1678     $opts = array();

1679     foreach ($options as $k=>$v)

1680       $opts[] = $k.$this->valueSplitter.$v;

1681     return implode( $this->optionSplitter, $opts );

1682   }

1683  

1684  

1685   // COMMENTS

1686   function LoadComments($tag) { return $this->LoadAll("select * from ".$this->config["table_prefix"]."pages where comment_on = '".quote($tag)."' and latest = 'Y' order by time"); }

1687  

1688   // ACCESS CONTROL

1689   function IsAdmin() 

1690   {

1691    if (is_array($this->config['aliases'])) 

1692    {

1693     $al = $this->config['aliases'];

1694     $adm = explode("\n", $al['Admins']);

1695     if (in_array($this->GetUserName(),$adm))

1696      return true;

1697    }

1698    return false;

1699   }

1700   

1701   // returns true if logged in user is owner of current page, or page specified in $tag

1702   function UserIsOwner($tag = "")

1703   {

1704     // check if user is logged in

1705     if (!$this->GetUser()) return false;

1706  

1707     // set default tag

1708     if (!$tag = trim($tag)) $tag = $this->GetPageTag();

1709  

1710     // check if user is owner

1711     if ($this->GetPageOwner($tag) == $this->GetUserName()) return true;

1712   }

1713   

1714   function GetPageOwnerFromComment()  {  if($this->page["comment_on"]) return $this->GetPageOwner($this->page["comment_on"]); return false; }

1715   function GetPageOwner($tag = "", $time = "") { if (!$tag = trim($tag)) $tag = $this->GetPageTag(); if ($page = $this->LoadPage($tag, $time, LOAD_CACHE, LOAD_META)) return $page["owner"]; }

1716   

1717   function SetPageOwner($tag, $user)

1718   {

1719     // check if user exists

1720     if (!$this->LoadUser($user)) return;

1721  

1722     // updated latest revision with new owner

1723     $this->Query("update ".$this->config["table_prefix"]."pages set owner = '".quote($user)."' where tag = '".quote($tag)."' and latest = 'Y' limit 1");

1724   }

1725   

1726   function LoadAcl($tag, $privilege, $useDefaults = 1)

1727   {

1728     $supertag = $this->NpjTranslit($tag);

1729     if ($cachedACL = $this->GetCachedACL($supertag, $privilege, $useDefaults)) $acl = $cachedACL;

1730     if (!$acl)

1731     {

1732       if ($cachedACL = $this->GetCachedACL($tag, $privilege, $useDefaults)) $acl = $cachedACL;

1733  

1734       if (!$acl)

1735       {

1736  

1737         $acl = $this->LoadSingle("select * from ".$this->config["table_prefix"]."acls where ".

1738                                  "supertag = '".quote($supertag)."' ".

1739                                  "and privilege = '".quote($privilege)."' limit 1");

1740         if (!$acl) 

1741         {

1742           $acl = $this->LoadSingle("select * from ".$this->config["table_prefix"]."acls where ".

1743                                    "page_tag = '".quote($tag)."' ".

1744                                    "and privilege = '".quote($privilege)."' limit 1");

1745  /*        if ($acl)

1746           {

1747             $this->Query( "update ".$this->config["table_prefix"]."acls ".

1748                           "set supertag='".$supertag."' where page_tag = '".$tag."';" );

1749             $acl["supertag"]=$supertag;

1750           }

1751  */      }
1752         if (!$acl && $useDefaults)
1753         {
1754           $acl = array("supertag" => $supertag, "page_tag" => $tag, 
1755                        "privilege" => $privilege, 
1756                        "list" => $this->GetConfigValue("default_".$privilege."_acl"),
1757                        "time" => date("YmdHis"),
1758                        "default" => "1"
1759                       );
1760         }
1761         $this->CacheACL($supertag, $privilege, $useDefaults,$acl);
1762       }
1763     }
1764     return $acl;
1765   }
1766  
1767   function SaveAcl($tag, $privilege, $list) {
1768   
1769     $supertag = $this->NpjTranslit($tag);
1770     if ($this->LoadAcl($tag, $privilege, 0)) 
1771      $this->Query("update ".$this->config["table_prefix"]."acls set list = '".
1772           quote(trim(str_replace("\r", "", $list)))."' where supertag = '".quote($supertag)."' and privilege = '".quote($privilege)."' ");
1773     else 
1774      $this->Query("insert into ".$this->config["table_prefix"]."acls set list = '".
1775           quote(trim(str_replace("\r", "", $list)))."', ".
1776           "supertag = '".quote($supertag)."', ".
1777           "page_tag = '".quote($tag)."', ".
1778           "privilege = '".quote($privilege)."'");
1779    
1780   }
1781   
1782   function RemoveAcls($tag) {
1783     return $this->Query("delete from ".$this->config["table_prefix"]."acls  where page_tag = '".quote($tag)."' ");
1784   }
1785   
1786   function RemovePage($tag) {
1787     return $this->Query("delete from ".$this->config["table_prefix"]."revisions  where tag = '".quote($tag)."' ") &&
1788     $this->Query("delete from ".$this->config["table_prefix"]."pages  where tag = '".quote($tag)."' ");
1789   }
1790   
1791   function RemoveComments($tag) {
1792     return $this->Query("delete from ".$this->config["table_prefix"]."pages  where comment_on = '".quote($tag)."' ");
1793   }
1794   
1795   function RemoveWatches($tag) {
1796     return $this->Query("delete from ".$this->config["table_prefix"]."pagewatches  where tag = '".quote($tag)."' ");
1797   }
1798   
1799   function RemoveLinks($tag) {
1800     return $this->Query("delete from ".$this->config["table_prefix"]."links  where from_tag = '".quote($tag)."' ");
1801   }
1802   
1803   function RemoveReferrers($tag) {
1804     return $this->Query("delete from ".$this->config["table_prefix"]."referrers where page_tag = '".quote($tag)."' ");
1805   }
1806   
1807   // WATCHES 

1808   function IsWatched($user, $tag) { 
1809     return $this->LoadSingle("select * from ".$this->config["table_prefix"]."pagewatches where user = '".quote($user)."' and tag = '".quote($tag)."'"); 
1810   } 
1811   
1812   function SetWatch($user, $tag) { 
1813     return $this->Query( "insert into ".$this->config["table_prefix"]."pagewatches (user,tag) values ( '".quote($user)."', '".quote($tag)."')" ); 
1814     // TIMESTAMP type is filled automatically by MySQL 

1815   } 
1816   
1817   function ClearWatch($user, $tag){ 
1818     return $this->Query( "delete from ".$this->config["table_prefix"]."pagewatches where user = '".quote($user)."' and tag = '".quote($tag)."'"); 
1819   }
1820  
1821   //aliases stuff

1822   function ReplaceAliases ($acl)
1823   {
1824     if (!is_array($this->config['aliases'])) return $acl;
1825  
1826     foreach ($this->config['aliases'] as $key => $val) $aliases[strtolower($key)]=$val;
1827  
1828     do 
1829     {
1830       $list = array();
1831       $replaced = 0;
1832       $lines = explode("\n", $acl);
1833       foreach ($lines as $line)
1834       {
1835         $linel = $line;
1836         // check for inversion character "!"

1837         if (preg_match("/^\!(.*)$/", $line, $matches))
1838         {
1839           $negate = 1;
1840           $linel = $matches[1];
1841         }
1842         else
1843           $negate = 0;
1844  
1845         $linel = strtolower(trim($linel));
1846  
1847         if (isset( $aliases[$linel] ))
1848         {
1849           foreach (explode("\n", $aliases[$linel]) as $item)
1850           {
1851             $item = trim($item);
1852             $list[] = ($negate) ? "!".$item : $item;
1853           }
1854           $replaced++;
1855         }
1856         else
1857           $list[] = $line;
1858       }
1859       $acl = join("\n", $list);
1860     } while ($replaced > 0);
1861     return $acl;
1862   }
1863  
1864   // returns true if $user (defaults to current user) has access to $privilege on $page_tag (defaults to current page)

1865   function HasAccess($privilege, $tag = "", $user = "")
1866   {
1867    $registered = false;
1868    // see whether user is registered and logged in

1869    if ($user!="guest@wacko")
1870    {
1871     if ($user = $this->GetUser()) $registered = true;
1872     $user = strtolower($this->GetUserName());
1873     if (!$registered) $user="guest@wacko";
1874    }
1875    if (!$tag = trim($tag)) $tag = $this->GetPageTag();
1876  
1877    // load acl

1878    $acl = $this->LoadAcl($tag, $privilege);
1879    $this->_acl = $acl;
1880  
1881     // if current user is owner, return true. owner can do anything!

1882    if ($user!="guest@wacko") if ($this->UserIsOwner($tag)) 
1883     return true;
1884  
1885    return $this->CheckACL($user, $acl['list'], true);
1886   }
1887  
1888   function CheckACL($user, $acl_list, $copy_to_this_acl = false, $debug=0)
1889   {
1890    if (is_array($user)) $user = $user["name"];
1891    $user = strtolower($user);
1892  
1893    // replace groups

1894    $acl = str_replace(" ", "", strtolower($this->ReplaceAliases($acl_list)));
1895    if ($copy_to_this_acl) $this->_acl['list'] = $acl;
1896    $acls = "\n".$acl."\n";
1897  
1898    if ($user=="guest@wacko" || $user=="")
1899    {
1900     if (($pos=strpos($acls, '*'))===false) return false;
1901     if ($acls{$pos-1}!="!") return true;
1902     return false;
1903    }
1904  
1905    $upos =strpos($acls, "\n".$user."\n"); 
1906    $aupos=strpos($acls, "\n!".$user."\n");
1907    $spos =strpos($acls, '*');
1908    $bpos =strpos($acls, '$');
1909    $bpos2=strpos($acls, 'І'); //deprecate it!!

1910  
1911    if ($aupos!==false) return false;
1912  
1913    if ($upos!==false)  return true;
1914  
1915    if ($spos!==false)
1916     if ($acls{$spos-1}=="!") return false;
1917  
1918    if ($bpos!==false)
1919     if ($acls{$bpos-1}=="!") return false;
1920  
1921    if ($bpos2!==false)
1922     if ($acls{$bpos2-1}=="!") return false;
1923  
1924    if ($spos!==false) return true;
1925    if ($bpos!==false) if ($user=="guest@wacko" || $user=="") return false;
1926    else return true;
1927    if ($bpos2!==false) if ($user=="guest@wacko" || $user=="") return false;
1928    else return true;
1929  
1930    return false;
1931   }
1932  
1933   // XML

1934   function WriteRecentChangesXML()
1935   {
1936     $xml = "<?xml version=\"1.0\" encoding=\"windows-1251\"?>\n";
1937     $xml .= "<rss version=\"0.92\">\n";
1938     $xml .= "<channel>\n";
1939     $xml .= "<title>".$this->GetConfigValue("wakka_name")." - RecentChanges</title>\n";
1940     $xml .= "<link>".$this->GetConfigValue("root_url")."</link>\n";
1941     $xml .= "<description>Recent changes to the ".$this->GetConfigValue("wakka_name")." WackoWiki</description>\n";
1942     $xml .= "<language>en-us</language>\n";
1943     
1944     if ($pages = $this->LoadRecentlyChanged())
1945     {
1946       foreach ($pages as $i => $page)
1947       {
1948         if ($this->config["hide_locked"]) $access =$this->HasAccess("read",$page["tag"],"guest@wacko");
1949         if ($access && ($count < 30)) 
1950         {
1951           $count++;
1952           $xml .= "<item>\n";
1953           $xml .= "<title>".$page["tag"]."</title>\n";
1954           $xml .= "<link>".$this->href("show", $page["tag"], "time=".urlencode($page["time"]))."</link>\n";
1955           $xml .= "<description>".$page["time"]." by ".$page["user"]."</description>\n";
1956           $xml .= "</item>\n";
1957         }
1958       }
1959     }
1960  
1961     $xml .= "</channel>\n";
1962     $xml .= "</rss>\n";
1963  
1964     $filename = "xml/recentchanges_".preg_replace("/[^a-zA-Z0-9]/", "", strtolower($this->GetConfigValue("wakka_name"))).".xml";
1965  
1966     $fp = @fopen($filename, "w");
1967     if ($fp)
1968     {
1969       fwrite($fp, $xml);
1970       fclose($fp);
1971     }
1972   }
1973  
1974   // MAINTENANCE

1975   function Maintenance()
1976   {
1977     // purge referrers

1978     if ($days = $this->GetConfigValue("referrers_purge_time")) {
1979       $this->Query("delete from ".$this->config["table_prefix"]."referrers where time < date_sub(now(), interval '".quote($days)."' day)");
1980     }
1981  
1982     // purge old page revisions

1983     if ($days = $this->GetConfigValue("pages_purge_time")) {
1984       $this->Query("delete from ".$this->config["table_prefix"]."revisions where time < date_sub(now(), interval '".quote($days)."' day) and latest = 'N'");
1985     }
1986   }
1987  
1988   function GetDefaultBookmarks($lang, $what="default")
1989   {
1990    if (!$lang) $lang = $this->config["language"];
1991  
1992    if (isset($this->config[$what."_bookmarks"]) && is_array($this->config[$what."_bookmarks"]) && isset($this->config[$what."_bookmarks"][$lang]))
1993      return $this->config[$what."_bookmarks"][$lang];
1994    else if (isset($this->config[$what."_bookmarks"]) && !is_array($this->config[$what."_bookmarks"]) && ($this->config["language"]==$lang))
1995      return $this->config[$what."_bookmarks"];
1996    else
1997      return $this->GetResourceValue($what."_bookmarks", $lang, false);
1998   }
1999  
2000   function SetBookmarks($set=BM_AUTO)
2001   {
2002    $user = $this->GetUser();
2003   
2004    if ($set || !($bookmarks=$this->GetBookmarks()))
2005    {
2006      $bookmarks = $user["bookmarks"] ? $user["bookmarks"] : $this->GetDefaultBookmarks($user["lang"]);
2007      if ($set==BM_DEFAULT) $bookmarks = $this->GetDefaultBookmarks($user["lang"]);
2008      $dummy = $this->Format($bookmarks, "wacko");
2009      $this->ClearLinkTable();
2010      $this->StartLinkTracking();
2011      $dummy = $this->Format($dummy, "post_wacko");
2012      $this->StopLinkTracking();
2013      $bmlinks = $this->GetLinkTable();
2014      $bookmarks = explode("\n", $bookmarks);
2015      for ($i=0;$i<count($bmlinks);$i++) $bmlinks[$i] = $this->NpjTranslit($bmlinks[$i]);
2016      $_SESSION["bookmarks"] = $bookmarks;
2017      $_SESSION["bookmarklinks"] = $bmlinks;
2018      $_SESSION["bookmarksfmt"] = $this->Format(implode(" | ", $bookmarks), "wacko");
2019    }
2020  
2021    if (!empty( $_REQUEST["addbookmark"] ) && $user)
2022    {
2023      $bookmark="((".$this->GetPageTag().($user["lang"]!=$this->pagelang?" @@".$this->pagelang:"")."))";
2024      if (!in_array($bookmark,$bookmarks)) 
2025      {
2026       $bookmarks[] = $bookmark;
2027      
2028       $this->Query("update ".$this->config["user_table"]." set ".
2029              "bookmarks = '".quote(implode("\n", $bookmarks))."' ".
2030              "where name = '".quote($user["name"])."' limit 1");
2031  
2032       $this->SetUser($this->LoadUser($user["name"]));
2033      }
2034      $_SESSION["bookmarks"] = $bookmarks;
2035      //$_SESSION["bookmarksfmt"] = $this->Format($this->Format(implode(" | ", $bookmarks), "wacko"), "post_wacko");

2036      $_SESSION["bookmarksfmt"] = $this->Format(implode(" | ", $bookmarks), "wacko");
2037      $bmlinks = $bookmarks; 
2038      for ($i=0;$i<count($bmlinks);$i++) $bmlinks[$i] = trim($this->NpjTranslit($bmlinks[$i]),"()"); 
2039      $_SESSION["bookmarklinks"] = $bmlinks; 
2040    }
2041  
2042    if (!empty( $_REQUEST["removebookmark"] ) && $user)
2043    {
2044     foreach ($bookmarks as $bm)
2045     {
2046      $dummy = $this->Format($bm, "wacko");
2047      $this->ClearLinkTable();
2048      $this->StartLinkTracking();
2049      $dummy = $this->Format($dummy, "post_wacko");
2050      $this->StopLinkTracking();
2051      $bml = $this->GetLinkTable();
2052      if ($this->GetPageSuperTag()!=$this->NpjTranslit($bml[0])) $newbm[] = $bm;
2053     }
2054     $bookmarks = $newbm;
2055     $this->Query("update ".$this->config["user_table"]." set ".
2056            "bookmarks = '".quote(implode("\n", $bookmarks))."' ".
2057            "where name = '".quote($user["name"])."' limit 1");
2058  
2059     $this->SetUser($this->LoadUser($user["name"]));
2060     $_SESSION["bookmarks"] = $bookmarks;
2061  //    $_SESSION["bookmarksfmt"] = $this->Format($this->Format(implode(" | ", $bookmarks), "wacko"), "post_wacko");

2062      $_SESSION["bookmarksfmt"] = $this->Format(implode(" | ", $bookmarks), "wacko");
2063    }
2064   }
2065   
2066   function GetBookmarks()  { return $_SESSION["bookmarks"]; }
2067   function GetBookmarksFormatted() { return $_SESSION["bookmarksfmt"]; }
2068   function GetBookmarkLinks()  { return $_SESSION["bookmarklinks"]; }
2069  
2070   // THE BIG EVIL NASTY ONE!

2071   function Run($tag, $method = "")
2072   {
2073     if(!($this->GetMicroTime()%3)) $this->Maintenance(); 
2074     $this->ReadInterWikiConfig();
2075  
2076     foreach ($this->search_engines as $engine)
2077     {
2078      if (stristr($_SERVER["HTTP_USER_AGENT"], $engine)) 
2079      {
2080        $this->config["default_showdatetime"] = 0;
2081        $this->config["show_datetime"] = "N";
2082      }
2083     }
2084  
2085     // do our stuff!

2086     if ((!$this->GetUser() && isset( $_COOKIE[$this->config["cookie_prefix"]."name"] )) && ($user = $this->LoadUser($_COOKIE[$this->config["cookie_prefix"]."name"], $_COOKIE[$this->config["cookie_prefix"]."password"]))) $this->SetUser($user);
2087     $user = $this->GetUser();
2088     $this->userlang = ($user["lang"]?$user["lang"]:$this->GetConfigValue("language"));
2089     if (!($this->userlang)) $this->userlang="en";
2090     if (is_array($user) && $user["options"]["theme"])
2091     {
2092      $this->config["theme"] = $user["options"]["theme"];
2093      $this->config["theme_url"]=$this->config["root_url"]."themes/".$this->config["theme"]."/";
2094     }
2095  
2096     if (!$this->GetConfigValue("multilanguage")) $this->SetLanguage($this->GetConfigValue("language"));
2097  
2098     $this->LoadAllLanguages();
2099     $this->LoadResource($this->userlang);
2100     $this->SetResource($this->userlang);
2101     $this->SetLanguage($this->userlang);
2102  
2103     $wacko = &$this;
2104  
2105     if (!$this->method = trim($method)) $this->method = "show";
2106     if (!$this->tag = trim($tag)) $this->Redirect($this->href("", $this->config["root_page"]));
2107  
2108     if (!preg_match("/^[".$this->language["ALPHANUM_P"]."\!]+$/", $tag))
2109      $tag = $this->tryUtfDecode($tag);
2110  //    if (!$_REQUEST["add"]=="1" || $this->method=="watch" ) 

2111     $tag = str_replace("'", "_", str_replace("\\", "", str_replace("_", "", $tag)));
2112     $tag = preg_replace("/[^".$this->language["ALPHANUM_P"]."\_\-]/", "", $tag);
2113  
2114     //$this->tag=$this->Translit($tag, 1);

2115     $this->tag = $tag;
2116     $this->supertag = $this->NpjTranslit($tag);
2117     $time = isset( $_GET["time"] ) ? $_GET["time"] : "";
2118     $page = $this->LoadPage($this->tag, $time);
2119     if ($this->GetConfigValue("outlook_workaround") && !$page) 
2120     {
2121      $page = $this->LoadPage($this->supertag."'", $time);
2122     }
2123     $this->SetPage($page);
2124     $this->LogReferrer();
2125     $this->SetBookmarks();
2126  
2127     if (!$this->GetUser() && $this->page["time"])
2128       header("Last-Modified: ".gmdate("D, d M Y H:i:s", strtotime($this->page["time"])+120)." GMT");;
2129     if (preg_match("/(\.xml)$/", $this->method))
2130     {
2131       print($this->Method($this->method));
2132     }
2133     else if (preg_match("/print$/", $this->method))
2134     {
2135       print($this->Header("print").$this->Method($this->method).$this->Footer("print"));
2136     }
2137     else if (preg_match("/msword$/", $this->method))
2138     {
2139       print($this->Header("msword").$this->Method($this->method).$this->Footer("print"));
2140     }
2141     else
2142     {
2143       $this->current_context++;
2144       $this->context[$this->current_context] = $this->tag;
2145       $data = $this->Method($this->method);
2146       $this->current_context--;
2147       print($this->Header().$data.$this->Footer());
2148     }
2149    return $this->tag;
2150   }
2151  
2152   function AvailableThemes()
2153   {
2154    $handle=opendir("themes");
2155    while (false!==($file = readdir($handle))) {
2156      if ($file != "." && $file != "CVS" && $file != ".." && is_dir("themes/".$file)) 
2157        $themelist[] = $file;
2158    }
2159    closedir($handle);
2160    if ($allow = $this->GetConfigValue("allow_themes"))
2161    {
2162     $ath = explode(",",$allow);
2163     if (is_array($ath) && $ath[0])
2164       $themelist = array_intersect ($ath, $themelist);
2165    }
2166    return $themelist;
2167   }
2168  
2169   // TOC manipulations

2170   function SetTocArray( $toc )
2171   {
2172     $this->body_toc = "";
2173     foreach($toc as $k=>$v)
2174      $toc[$k] = implode("<poloskuns,col>", $v);
2175     $this->body_toc = implode("<poloskuns,row>", $toc);
2176   }
2177   
2178   function BuildToc( $tag, $from, $to, $num, $link=-1 )
2179   {
2180     if (isset($this->tocs[ $tag ])) return $this->tocs[ $tag ];
2181     $page = $this->LoadPage( $tag );
2182     if ($link === -1) 
2183      $_link = ($this->page["tag"] != $page["tag"])?$this->Href("",$page["tag"]):"";
2184      else $_link = $link;
2185     $toc = explode( "<poloskuns,row>", $page["body_toc"] );
2186     foreach($toc as $k=>$v)
2187      $toc[$k] = explode("<poloskuns,col>", $v);
2188     $_toc = array();
2189     foreach($toc as $k=>$v)
2190      if ($v[2] == 99999)
2191      { 
2192        if (!in_array($v[0],$this->toc_context)) 
2193         if (!($v[0] == $this->tag)) 
2194         {
2195           array_push($this->toc_context, $v[0]);
2196           $_toc = array_merge( $_toc, $this->BuildToc( $v[0], $from, $to, $num, $link ) );
2197           array_pop($this->toc_context);
2198         }
2199      }
2200      else
2201      if ($v[2] == 77777)
2202      {
2203        $toc[$k][3] = $_link;
2204        $_toc[] = &$toc[$k];
2205      }
2206      else
2207      if (($v[2] >= $from) && ($v[2] <= $to))
2208      {
2209        $toc[$k][3] = $_link;
2210        $_toc[] = &$toc[$k];
2211        $toc[$k][1] = $this->Format($toc[$k][1], "post_wacko");
2212      }
2213     $this->tocs[ $tag ] = $_toc;
2214     return $_toc;
2215   }
2216   
2217   function NumerateToc( $what ) // numerating toc using prepared "$this->post_wacko_toc"
2218   { if (!is_array($this->post_wacko_action)) return $what;
2219     // #1. hash toc 

2220     $hash = array();
2221     foreach( $this->post_wacko_toc as $v )
2222      $hash[ $v[0] ] = $v;
2223     $this->post_wacko_toc_hash = &$hash;
2224     if ($this->post_wacko_action["toc"])
2225     {
2226       // #2. find all <a></a><hX> & guide them in subroutine

2227       //     notice that complex regexp is copied & duplicated in formatters/paragrafica (subject to refactor)

2228       $what = preg_replace_callback( "!(<a name=\"(h[0-9]+-[0-9]+)\"></a><h([0-9])>(.*?)</h\\3>)!i", 
2229               array( &$this, "NumerateTocCallbackToc"), $what );
2230     }
2231     if ($this->post_wacko_action["p"])
2232     {
2233       // #2. find all <a></a><p...> & guide them in subroutine

2234       //     notice that complex regexp is copied & duplicated in formatters/paragrafica (subject to refactor)

2235       $what = preg_replace_callback( "!(<a name=\"(p[0-9]+-[0-9]+)\"></a><p([^>]+)>(.+?)</p>)!is", 
2236               array( &$this, "NumerateTocCallbackP"), $what );
2237     }
2238     return $what;
2239   }
2240   
2241   function NumerateTocCallbackToc( $matches )
2242   {
2243     return '<a name="'.$matches[2].'"></a><h'.$matches[3].'>'.
2244            ($this->post_wacko_toc_hash[$matches[2]][1]?$this->post_wacko_toc_hash[$matches[2]][1]:$matches[4]).
2245            '</h'.$matches[3].'>';
2246   }
2247   
2248   var $paragrafica_styles = array( 
2249      "before"  => 
2250       array( "_before"=>"", "_after"=>"", "before"=> "<span class='pmark'>[##]</span><br />", "after"=>"" ),
2251      "after"  => 
2252       array( "_before"=>"", "_after"=>"", "before"=> "", "after"=>" <span class='pmark'>[##]</span>" ),
2253      "right" =>
2254       array( "_before"=>"<div class='pright'><div class='p-'>&nbsp;<span class='pmark'>[##]</span></div><div class='pbody-'>", "_after"=>"</div></div>", "before"=> "", "after"=>"" ),
2255      "left" =>
2256       array( "_before"=>"<div class='pleft'><div class='p-'><span class='pmark'>[##]</span>&nbsp;</div><div class='pbody-'>", "_after"=>"</div></div>", "before"=> "", "after"=>"" ),
2257                                 );                
2258   var $paragrafica_patches = array(
2259      "before" => array("before"),
2260      "after"  => array("after"),
2261      "right"  => array("_before"),
2262      "left"  => array("_before"),
2263                                  );
2264   function NumerateTocCallbackP( $matches )
2265   {
2266     $before=""; $after="";
2267     if (!($style = $this->paragrafica_styles[ $this->post_wacko_action["p"] ]))
2268     { $this->post_wacko_action["p"] = "before";
2269       $style = $this->paragrafica_styles[ "before" ];
2270     }
2271     $len = strlen("".$this->post_wacko_maxp);
2272     $link = '<a href="#'.$matches[2].'">'.
2273             str_pad($this->post_wacko_toc_hash[$matches[2]][66],$len,"0",STR_PAD_LEFT).
2274             '</a>';
2275     foreach ( $this->paragrafica_patches[ $this->post_wacko_action["p"] ] as $v )
2276      $style[$v] = str_replace( "##", $link, $style[$v] );
2277  
2278     return $style["_before"].'<a name="'.$matches[2].'"></a><p'.$matches[3].'>'.
2279            $style["before"].$matches[4].$style["after"].
2280            '</p>'.$style["_after"];
2281   }
2282  
2283   // BREADCRUMBS -- additional navigation added with WackoClusters

2284   function GetPagePath()
2285   {
2286     $steps = explode("/", $this->tag);
2287     $result = "";
2288     $links = array();
2289     $_links = array();
2290     for ($i=0;$i<count($steps)-1;$i++)
2291     {
2292       if ($i==0) $prev=""; else $prev=$links[$i-1]."/"; 
2293       $links[] =  $prev.$steps[$i];
2294     }
2295     for ($i=0;$i<count($steps)-1;$i++)
2296       $result.= $this->Link( $links[$i], "", $steps[$i] )."/";
2297     $result.=$steps[count($steps)-1];
2298     return $result;
2299   }
2300  
2301   function RenamePage($tag, $NewTag, $NewSuperTag="")
2302   {
2303     if ($NewSuperTag=="")
2304       $NewSuperTag = $this->NpjTranslit($NewTag);
2305  
2306     return $this->Query("update ".$this->config["table_prefix"]."revisions set tag = '".quote($NewTag)."', supertag = '".quote($NewSuperTag)."' where tag = '".quote($tag)."' ") &&
2307     $this->Query("update ".$this->config["table_prefix"]."pages  set tag = '".quote($NewTag)."', supertag = '".quote($NewSuperTag)."' where tag = '".quote($tag)."' ");
2308   } 
2309   
2310   function RenameAcls($tag, $NewTag, $NewSuperTag="") {
2311     if ($NewSuperTag=="")
2312       $NewSuperTag = $this->NpjTranslit($NewTag);
2313     return $this->Query("update ".$this->config["table_prefix"]."acls set page_tag = '".quote($NewTag)."', supertag = '".quote($NewSuperTag)."' where page_tag = '".quote($tag)."' ");
2314   }
2315   
2316   function RenameComments($tag, $NewTag, $NewSuperTag="") {
2317     return $this->Query("update ".$this->config["table_prefix"]."pages set comment_on = '".quote($NewTag)."'  where comment_on = '".quote($tag)."' ");
2318   }
2319   
2320   function RenameWatches($tag, $NewTag, $NewSuperTag="") {
2321     return $this->Query("update ".$this->config["table_prefix"]."pagewatches set tag = '".quote($NewTag)."' where tag = '".quote($tag)."' ");
2322   }
2323   
2324   function RenameLinks($tag) {
2325     return $this->Query("update ".$this->config["table_prefix"]."links set from_tag = '".quote($NewTag)."' where from_tag = '".quote($tag)."' ");
2326   }
2327  
2328   function CheckFileExists( $filename, $unwrapped_tag = "" )
2329   {
2330     if ($unwrapped_tag == "") $page_id=0;
2331     else
2332     { $page = $this->LoadPage($unwrapped_tag, "", LOAD_CACHE, LOAD_META);
2333       $page_id=$page["id"];
2334       if (!$page_id) return false;
2335     }
2336     if (!($file = $this->filesCache[$page_id][$filename]))
2337     {
2338      $what = $this->LoadAll( "select id, filename, filesize, description, picture_w, picture_h, file_ext from ".$this->config["table_prefix"]."upload where ".
2339                              "page_id = '".quote($page_id)."' and filename='".quote($filename)."'");
2340      if (sizeof($what) == 0) return false;
2341      $file = $what[0];
2342      $this->filesCache[$page_id][$filename] = $file;
2343     }
2344     return $file;
2345   }
2346  
2347   function GetKeywords()
2348   {      
2349     if ($this->page["keywords"]) return $this->page["keywords"];
2350     else return $this->GetConfigValue("meta_keywords");
2351   }
2352  
2353   function GetDescription()
2354   {      
2355     if ($this->page["description"]) return $this->page["description"];
2356     else return $this->GetConfigValue("meta_description");
2357   }
2358  
2359  }
2360  ?>


[ Powered by PHPXref - Served by Debian GNU/Linux ]