[ Index ]
 

Code source de WikiNi 0.4.4

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/ -> wakka.php (source)

   1  <?php
   2  /* encoding: iso-8859-1
   3  wakka.php
   4  Copyright (c) 2002, Hendrik Mans <hendrik@mans.de>
   5  Copyright  2003 Carlo Zottmann
   6  Copyright 2002, 2003 David DELON
   7  Copyright 2002, 2003, 2004 Charles NÉPOTE
   8  Copyright 2002, 2003 Patrick PAUL
   9  Copyright 2003 Éric DELORD
  10  Copyright 2003 Éric FELDSTEIN
  11  Copyright 2004 Jean-Christophe ANDRÉ
  12  Copyrught 2005-2006 Didier LOISEAU
  13  All rights reserved.
  14  Redistribution and use in source and binary forms, with or without
  15  modification, are permitted provided that the following conditions
  16  are met:
  17  1. Redistributions of source code must retain the above copyright
  18  notice, this list of conditions and the following disclaimer.
  19  2. Redistributions in binary form must reproduce the above copyright
  20  notice, this list of conditions and the following disclaimer in the
  21  documentation and/or other materials provided with the distribution.
  22  3. The name of the author may not be used to endorse or promote products
  23  derived from this software without specific prior written permission.
  24  
  25  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  26  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  27  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  28  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  29  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  30  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  31  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  32  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  33  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  34  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35  */
  36  
  37  /*
  38      Yes, most of the formatting used in this file is HORRIBLY BAD STYLE. However,
  39      most of the action happens outside of this file, and I really wanted the code
  40      to look as small as what it does. Basically. Oh, I just suck. :)
  41  */
  42  
  43  
  44  
  45  // do not change this line, you fool. In fact, don't change anything! Ever!
  46  define("WAKKA_VERSION", "0.1.1");
  47  define("WIKINI_VERSION", "0.4.4");
  48  // start the compute time
  49  list($g_usec, $g_sec) = explode(" ",microtime());
  50  define ("t_start", (float)$g_usec + (float)$g_sec);
  51  $t_SQL=0;
  52  
  53  
  54  
  55  class Wiki
  56  {
  57      var $dblink;
  58      var $page;
  59      var $tag;
  60      var $parameter = array();
  61      var $queryLog = array();
  62      var $interWiki = array();
  63      var $VERSION;
  64      var $CookiePath = '/';
  65  
  66  
  67      // constructor
  68  	function Wiki($config)
  69      {
  70          $this->config = $config;
  71          // some host do not allow mysql_pconnect
  72          $this->dblink = @mysql_connect (
  73              $this->config["mysql_host"],
  74              $this->config["mysql_user"],
  75              $this->config["mysql_password"]);
  76          if ($this->dblink)
  77          {
  78              if (!@mysql_select_db($this->config["mysql_database"], $this->dblink))
  79              {
  80                  @mysql_close($this->dblink);
  81                  $this->dblink = false;
  82              }
  83          }
  84          $this->VERSION = WAKKA_VERSION;
  85  
  86          //determine le chemin pour le cookie
  87          $a = parse_url($this->GetConfigValue('base_url'));
  88          $this->CookiePath = dirname($a['path']);
  89          if ($this->CookiePath != '/') $this->CookiePath .= '/';
  90      }
  91  
  92  
  93  
  94      // DATABASE
  95  	function Query($query)
  96      {
  97          if($this->GetConfigValue("debug")) $start = $this->GetMicroTime();
  98          if (!$result = mysql_query($query, $this->dblink))
  99          {
 100              ob_end_clean();
 101              die("Query failed: ".$query." (".mysql_error().")");
 102          }
 103          if($this->GetConfigValue("debug"))
 104          {
 105              $time = $this->GetMicroTime() - $start;
 106              $this->queryLog[] = array(
 107                  "query"        => $query,
 108                  "time"        => $time);
 109          }
 110          return $result;
 111      }
 112  	function LoadSingle($query) { if ($data = $this->LoadAll($query)) return $data[0]; }
 113  	function LoadAll($query)
 114      {
 115      $data=array();
 116      if ($r = $this->Query($query))
 117          {
 118              while ($row = mysql_fetch_assoc($r)) $data[] = $row;
 119              mysql_free_result($r);
 120          }
 121          return $data;
 122      }
 123  
 124  
 125  
 126      // MISC
 127  	function GetMicroTime() { list($usec, $sec) = explode(" ",microtime()); return ((float)$usec + (float)$sec); }
 128  	function IncludeBuffered($filename, $notfoundText = "", $vars = "", $path = "")
 129      {
 130          if ($path) $dirs = explode(":", $path);
 131          else $dirs = array("");
 132  
 133          foreach($dirs as $dir)
 134          {
 135              if ($dir) $dir .= "/";
 136              $fullfilename = $dir.$filename;
 137              if (file_exists($fullfilename))
 138              {
 139                  if (is_array($vars)) extract($vars);
 140  
 141                  ob_start();
 142                  include($fullfilename);
 143                  $output = ob_get_contents();
 144                  ob_end_clean();
 145                  return $output;
 146              }
 147          }
 148          if ($notfoundText) return $notfoundText;
 149          else return false;
 150      }
 151  
 152  
 153  
 154      // VARIABLES
 155  	function GetPageTag() { return $this->tag; }
 156  	function GetPageTime() { return $this->page["time"]; }
 157  	function GetMethod() { return $this->method; }
 158  	function GetConfigValue($name) { return $this->config[$name]; }
 159  	function GetWakkaName() { return $this->GetConfigValue("wakka_name"); }
 160  	function GetWakkaVersion() { return $this->VERSION; }
 161  	function GetWikiNiVersion() { return WIKINI_VERSION; } 
 162  
 163  
 164  
 165      // PAGES
 166  	function LoadPage($tag, $time = "", $cache = 1) {
 167          // retrieve from cache
 168          if (!$time && $cache && ($cachedPage = $this->GetCachedPage($tag))) { $page = $cachedPage;}
 169          // load page
 170          if (!isset($page)) $page = $this->LoadSingle("select * from ".$this->config["table_prefix"]."pages where tag = '".mysql_escape_string($tag)."' ".($time ? "and time = '".mysql_escape_string($time)."'" : "and latest = 'Y'")." limit 1");
 171          // cache result
 172          if (!$time) $this->CachePage($page);
 173          return $page;
 174      }
 175  	function GetCachedPage($tag) {return (isset($this->pageCache[$tag]) ? $this->pageCache[$tag] : ''); }
 176  	function CachePage($page) { $this->pageCache[$page["tag"]] = $page; }
 177  	function SetPage($page) { $this->page = $page; if ($this->page["tag"]) $this->tag = $this->page["tag"]; }
 178  	function LoadPageById($id) { return $this->LoadSingle("select * from ".$this->config["table_prefix"]."pages where id = '".mysql_escape_string($id)."' limit 1"); }
 179  	function LoadRevisions($page) { return $this->LoadAll("select * from ".$this->config["table_prefix"]."pages where tag = '".mysql_escape_string($page)."' order by time desc"); }
 180  	function LoadPagesLinkingTo($tag) { return $this->LoadAll("select from_tag as tag from ".$this->config["table_prefix"]."links where to_tag = '".mysql_escape_string($tag)."' order by tag"); }
 181  	function LoadRecentlyChanged($limit=50) {
 182          $limit= (int) $limit;
 183          if ($pages = $this->LoadAll("select tag, time, user, owner from ".$this->config["table_prefix"]."pages where latest = 'Y' and comment_on = '' order by time desc limit $limit"))
 184          {
 185              foreach ($pages as $page)
 186              {
 187                  $this->CachePage($page);
 188              }
 189              return $pages;
 190          }
 191      }
 192  	function LoadAllPages() { return $this->LoadAll("select * from ".$this->config["table_prefix"]."pages where latest = 'Y' order by tag"); }
 193  	function FullTextSearch($phrase) { return $this->LoadAll("select * from ".$this->config["table_prefix"]."pages where latest = 'Y' and match(tag, body) against('".mysql_escape_string($phrase)."')"); }
 194  	function LoadWantedPages() { return $this->LoadAll("select distinct ".$this->config["table_prefix"]."links.to_tag as tag,count(".$this->config["table_prefix"]."links.from_tag) as count from ".$this->config["table_prefix"]."links left join ".$this->config["table_prefix"]."pages on ".$this->config["table_prefix"]."links.to_tag = ".$this->config["table_prefix"]."pages.tag where ".$this->config["table_prefix"]."pages.tag is NULL group by tag order by count desc"); }
 195  	function LoadOrphanedPages() { return $this->LoadAll("select distinct tag from ".$this->config["table_prefix"]."pages left join ".$this->config["table_prefix"]."links on ".$this->config["table_prefix"]."pages.tag = ".$this->config["table_prefix"]."links.to_tag where ".$this->config["table_prefix"]."links.to_tag is NULL and ".$this->config["table_prefix"]."pages.comment_on = '' order by tag"); }
 196  	function IsOrphanedPage($tag) { return $this->LoadAll("select distinct tag from ".$this->config["table_prefix"]."pages left join ".$this->config["table_prefix"]."links on ".$this->config["table_prefix"]."pages.tag = ".$this->config["table_prefix"]."links.to_tag where ".$this->config["table_prefix"]."links.to_tag is NULL and ".$this->config["table_prefix"]."pages.comment_on ='' and tag='".mysql_escape_string($tag)."'"); }
 197  	function DeleteOrphanedPage($tag) {
 198          $this->Query("delete from ".$this->config["table_prefix"]."pages where tag='".mysql_escape_string($tag)."' ");
 199          $this->Query("delete from ".$this->config["table_prefix"]."links where from_tag='".mysql_escape_string($tag)."' ");
 200          $this->Query("delete from ".$this->config["table_prefix"]."acls where page_tag='".mysql_escape_string($tag)."' ");
 201          $this->Query("delete from ".$this->config["table_prefix"]."referrers where page_tag='".mysql_escape_string($tag)."' ");
 202      }
 203  	function SavePage($tag, $body, $comment_on = "") {
 204          // get current user
 205          $user = $this->GetUserName();
 206  
 207          //die($tag);
 208  
 209          // TODO: check write privilege
 210          if ($comment_on ? $this->HasAccess("comment", $comment_on)
 211                          : $this->HasAccess("write", $tag))
 212          {
 213              // is page new?
 214              if (!$oldPage = $this->LoadPage($tag))
 215              {
 216                  // create default write acl. store empty write ACL for comments.
 217                  $this->SaveAcl($tag, "write", ($comment_on ? "" : $this->GetConfigValue("default_write_acl")));
 218  
 219                  // create default read acl
 220                  $this->SaveAcl($tag, "read", $this->GetConfigValue("default_read_acl"));
 221  
 222                  // create default comment acl.
 223                  $this->SaveAcl($tag, "comment", $this->GetConfigValue("default_comment_acl"));
 224  
 225                  // current user is owner; if user is logged in! otherwise, no owner.
 226                  if ($this->GetUser()) $owner = $user;
 227                  else $owner = '';
 228              }
 229              else
 230              {
 231                  // aha! page isn't new. keep owner!
 232                  $owner = $oldPage["owner"];
 233              }
 234  
 235  
 236              // set all other revisions to old
 237              $this->Query("update ".$this->config["table_prefix"]."pages set latest = 'N' where tag = '".mysql_Escape_string($tag)."'");
 238  
 239              // add new revision
 240              $this->Query("insert into ".$this->config["table_prefix"]."pages set ".
 241                  "tag = '".mysql_escape_string($tag)."', ".
 242                  ($comment_on ? "comment_on = '".mysql_escape_string($comment_on)."', " : "").
 243                  "time = now(), ".
 244                  "owner = '".mysql_escape_string($owner)."', ".
 245                  "user = '".mysql_escape_string($user)."', ".
 246                  "latest = 'Y', ".
 247                  "body = '".mysql_escape_string(chop($body))."'");
 248          }
 249      }
 250  	function PurgePages() {
 251          if ($days = $this->GetConfigValue("pages_purge_time")) {
 252              // Selection of pages which can be deleted 
 253              $pages = $this->LoadAll("select distinct tag, time from ".$this->config["table_prefix"]."pages where time < date_sub(now(), interval '".mysql_escape_string($days)."' day) and latest = 'N' order by time asc");
 254              foreach ($pages as $page) {
 255                  // Deletion if there are more than 2 versions avalaible (TODO : parameter ?)
 256                  $tags=$this->LoadAll("select distinct tag from ".$this->config["table_prefix"]."pages where tag = '".mysql_escape_string($page['tag'])."' group by tag having count(*) > 2 order by tag");
 257                  foreach ($tags as $tag) {
 258                      $this->Query("delete from ".$this->config["table_prefix"]."pages where time = '".mysql_escape_string($page['time'])."' and tag = '".mysql_escape_string($tag['tag'])."'");
 259                  }
 260              }
 261          }
 262      }
 263  
 264  
 265  
 266      // COOKIES
 267  	function SetSessionCookie($name, $value) { SetCookie($name, $value, 0, $this->CookiePath); $_COOKIE[$name] = $value; }
 268  	function SetPersistentCookie($name, $value, $remember = 0) { SetCookie($name, $value, time() + ($remember ? 90*24*60*60 : 60 * 60), $this->CookiePath); $_COOKIE[$name] = $value; }
 269  	function DeleteCookie($name) { SetCookie($name, "", 1, $this->CookiePath); $_COOKIE[$name] = ""; }
 270  	function GetCookie($name) { return $_COOKIE[$name]; }
 271  
 272  
 273  
 274      // HTTP/REQUEST/LINK RELATED
 275  	function SetMessage($message) { $_SESSION["message"] = $message; }
 276  	function GetMessage()
 277      {
 278          if (isset($_SESSION["message"])) $message = $_SESSION["message"];
 279          else $message = "";
 280          $_SESSION["message"] = "";
 281          return $message;
 282      }
 283  	function Redirect($url)
 284      {
 285          header("Location: $url");
 286          exit;
 287      }
 288      // returns just PageName[/method].
 289  	function MiniHref($method = "", $tag = "")
 290      {
 291          if (!$tag = trim($tag)) $tag = $this->tag;
 292          return $tag.($method ? "/".$method : "");
 293      }
 294      // returns the full url to a page/method.
 295  	function Href($method = "", $tag = "", $params = "")
 296      {
 297          $href = $this->config["base_url"].$this->MiniHref($method, $tag);
 298          if ($params)
 299          {
 300              $href .= ($this->config["rewrite_mode"] ? "?" : "&amp;").$params;
 301          }
 302          return $href;
 303      }
 304  	function Link($tag, $method = "", $text = "", $track = 1)
 305      {
 306          $tag=htmlspecialchars($tag); //avoid xss
 307          $text=htmlspecialchars($text); //paranoiac again
 308          $text = preg_replace('/&amp;(\\#[xX][a-fA-F0-9]+|\\#[0-9]+|[a-zA-Z0-9]+);/', '&$1;', $text);
 309          if (!$text) $text = $tag;
 310  
 311          // is this an interwiki link?
 312          if (preg_match("/^([A-Z][A-Z,a-z]+)[:]([A-Z,a-z,0-9]*)$/s", $tag, $matches))
 313          {
 314              $tag = $this->GetInterWikiUrl($matches[1], $matches[2]);
 315              return "<a href=\"$tag\">$text (interwiki)</a>";
 316          }
 317          // is this a full link? ie, does it contain non alpha-numeric characters?
 318          // Note : [:alnum:] is equivalent [0-9A-Za-z]
 319          //        [^[:alnum:]] means : some caracters other than [0-9A-Za-z]
 320          // For example : "www.adress.com", "mailto:adress@domain.com", "http://www.adress.com"
 321          else if (preg_match("/[^[:alnum:]]/", $tag))
 322          {
 323              // check for email addresses
 324              if (preg_match("/^[\w.-]+\@[\w.-]+$/", $tag))
 325              {
 326                  $tag = "mailto:".$tag;
 327              }
 328              // check for protocol-less URLs
 329              else if (!preg_match("/:\/\//", $tag))
 330              {
 331                  $tag = "http://".$tag;    //Very important for xss (avoid javascript:() hacking)
 332              }
 333              // is this an inline image (text!=tag and url ends png,gif,jpeg)
 334              if ($text!=$tag and preg_match("/.(gif|jpeg|png|jpg)$/i",$tag))
 335              {
 336                  return "<img src=\"$tag\" alt=\"$text\" />";
 337              }
 338              else
 339              {
 340                  return "<a href=\"$tag\">$text</a>";
 341              }
 342          }
 343          else
 344          {
 345              // it's a Wiki link!
 346              if (isset($_SESSION["linktracking"]) && $track) $this->TrackLinkTo($tag);
 347              return ($this->LoadPage($tag) ? "<a href=\"".$this->href($method, $tag)."\">".$text."</a>" : "<span class=\"missingpage\">".$text."</span><a href=\"".$this->href("edit", $tag)."\">?</a>");
 348          }
 349      }
 350  	function ComposeLinkToPage($tag, $method = "", $text = "", $track = 1) {
 351          if (!$text) $text = $tag;
 352          $text = htmlentities($text);
 353          if (isset($_SESSION["linktracking"]) && $track)
 354              $this->TrackLinkTo($tag);
 355          return '<a href="'.$this->href($method, $tag).'">'.$text.'</a>';
 356      }
 357      // function PregPageLink($matches) { return $this->Link($matches[1]); }
 358  	function IsWikiName($text) { return preg_match("/^[A-Z][a-z]+[A-Z,0-9][A-Z,a-z,0-9]*$/", $text); }
 359  	function TrackLinkTo($tag) { $_SESSION["linktable"][] = $tag; }
 360  	function GetLinkTable() { return $_SESSION["linktable"]; }
 361  	function ClearLinkTable() { $_SESSION["linktable"] = array(); }
 362  	function StartLinkTracking() { $_SESSION["linktracking"] = 1; }
 363  	function StopLinkTracking() { $_SESSION["linktracking"] = 0; }
 364  	function WriteLinkTable() {
 365          // delete old link table
 366          $this->Query("delete from ".$this->config["table_prefix"]."links where from_tag = '".mysql_escape_string($this->GetPageTag())."'");
 367          if ($linktable = $this->GetLinkTable())
 368          {
 369              $from_tag = mysql_escape_string($this->GetPageTag());
 370              foreach ($linktable as $to_tag)
 371              {
 372                  $lower_to_tag = strtolower($to_tag);
 373                  if (!isset($written[$lower_to_tag]))
 374                  {
 375                      $this->Query("insert into ".$this->config["table_prefix"]."links set from_tag = '".$from_tag."', to_tag = '".mysql_escape_string($to_tag)."'");
 376                      $written[$lower_to_tag] = 1;
 377                  }
 378              }
 379          }
 380      }
 381  	function Header() { return $this->Action($this->GetConfigValue("header_action"), 1); }
 382  	function Footer() { return $this->Action($this->GetConfigValue("footer_action"), 1); }
 383  
 384  
 385  
 386      // FORMS
 387  	function FormOpen($method = "", $tag = "", $formMethod = "post") {
 388          $result = "<form action=\"".$this->href($method, $tag)."\" method=\"".$formMethod."\">\n";
 389          if (!$this->config["rewrite_mode"]) $result .= "<input type=\"hidden\" name=\"wiki\" value=\"".$this->MiniHref($method, $tag)."\" />\n";
 390          return $result;
 391      }
 392  	function FormClose() {
 393          return "</form>\n";
 394      }
 395  
 396  
 397  
 398      // INTERWIKI STUFF
 399  	function ReadInterWikiConfig() {
 400          if ($lines = file("interwiki.conf"))
 401          {
 402              foreach ($lines as $line)
 403              {
 404                  if ($line = trim($line))
 405                  {
 406                      list($wikiName, $wikiUrl) = explode(" ", trim($line));
 407                      $this->AddInterWiki($wikiName, $wikiUrl);
 408                  }
 409              }
 410          }
 411      }
 412  	function AddInterWiki($name, $url) {
 413          $this->interWiki[$name] = $url;
 414      }
 415  	function GetInterWikiUrl($name, $tag) {
 416          if (isset($this->interWiki[$name]))
 417          {
 418              return $this->interWiki[$name].$tag;
 419          } else {
 420          return 'http://'.$tag; //avoid xss by putting http:// in front of JavaScript:()
 421          }
 422      }
 423  
 424  
 425  
 426      // REFERRERS
 427  	function LogReferrer($tag = "", $referrer = "") {
 428          // fill values
 429          if (!$tag = trim($tag)) $tag = $this->GetPageTag();
 430          if (!$referrer = trim($referrer) AND isset($_SERVER["HTTP_REFERER"])) $referrer = $_SERVER["HTTP_REFERER"];
 431          
 432          // check if it's coming from another site
 433          if ($referrer && !preg_match("/^".preg_quote($this->GetConfigValue("base_url"), "/")."/", $referrer))
 434          {
 435              // avoid XSS (with urls like "javascript:alert()" and co)
 436              // by forcing http/https prefix
 437              // NB.: this does NOT exempt to htmlspecialchars() the collected URIs !
 438              if (!preg_match('`^https?://`', $referrer)) return;
 439              
 440              $this->Query("insert into ".$this->config["table_prefix"]."referrers set ".
 441                  "page_tag = '".mysql_escape_string($tag)."', ".
 442                  "referrer = '".mysql_escape_string($referrer)."', ".
 443                  "time = now()");
 444          }
 445      }
 446  	function LoadReferrers($tag = "") {
 447          return $this->LoadAll("select referrer, count(referrer) as num from ".$this->config["table_prefix"]."referrers ".($tag = trim($tag) ? "where page_tag = '".mysql_escape_string($tag)."'" : "")." group by referrer order by num desc");
 448      }
 449  	function PurgeReferrers() {
 450          if ($days = $this->GetConfigValue("referrers_purge_time")) {
 451              $this->Query("delete from ".$this->config["table_prefix"]."referrers where time < date_sub(now(), interval '".mysql_escape_string($days)."' day)");
 452          }
 453      }
 454  
 455  
 456  
 457      // PLUGINS
 458  	function Action($action, $forceLinkTracking = 0)
 459      {
 460          $action = trim($action); $vars=array();
 461          // stupid attributes check
 462          if ((stristr($action, "=\"")) || (stristr($action, "/")))
 463          {
 464              // extract $action and $vars_temp ("raw" attributes)
 465              preg_match("/^([A-Za-z0-9]*)\/?(.*)$/", $action, $matches);
 466              list(, $action, $vars_temp) = $matches;
 467              // match all attributes (key and value)
 468              $this->parameter[$vars_temp]=$vars_temp;
 469              preg_match_all("/([A-Za-z0-9]*)=\"(.*)\"/U", $vars_temp, $matches);
 470  
 471          // prepare an array for extract() to work with (in $this->IncludeBuffered())
 472          if (is_array($matches))
 473              {
 474                  for ($a = 0; $a < count($matches[1]); $a++)
 475                  {
 476                      $vars[$matches[1][$a]] = $matches[2][$a];
 477                      $this->parameter[$matches[1][$a]]=$matches[2][$a];
 478                  }
 479              }
 480          }
 481          if (!$forceLinkTracking) $this->StopLinkTracking();
 482          $result = $this->IncludeBuffered(strtolower($action).".php", "<i>Action inconnue \"$action\"</i>", $vars, $this->config["action_path"]);
 483          $this->StartLinkTracking();
 484          if (isset($parameter)) unset($this->parameter[$parameter]);
 485          unset($this->parameter);
 486          return $result;
 487      }
 488  	function Method($method) {
 489          if (!$handler = $this->page["handler"]) $handler = "page";
 490          $methodLocation = $handler."/".$method.".php";
 491          return $this->IncludeBuffered($methodLocation, "<i>M&eacute;thode inconnue \"$methodLocation\"</i>", "", $this->config["handler_path"]);
 492      }
 493  	function Format($text, $formatter = "wakka") {
 494          return $this->IncludeBuffered("formatters/".$formatter.".php", "<i>Impossible de trouver le formateur \"$formatter\"</i>", compact("text")); 
 495      }
 496  
 497  
 498  
 499      // USERS
 500  	function LoadUser($name, $password = 0) { return $this->LoadSingle("select * from ".$this->config["table_prefix"]."users where name = '".mysql_escape_string($name)."' ".($password === 0 ? "" : "and password = '".mysql_escape_string($password)."'")." limit 1"); }
 501  	function LoadUsers() { return $this->LoadAll("select * from ".$this->config["table_prefix"]."users order by name"); }
 502  	function GetUserName() { if ($user = $this->GetUser()) $name = $user["name"]; else if (!$name = gethostbyaddr($_SERVER["REMOTE_ADDR"])) $name = $_SERVER["REMOTE_ADDR"]; return $name; }
 503  	function UserName() { /* deprecated! */ return $this->GetUserName(); }
 504  	function GetUser() { return (isset($_SESSION["user"]) ? $_SESSION["user"] : '');}
 505  	function SetUser($user, $remember=0) { $_SESSION["user"] = $user; $this->SetPersistentCookie("name", $user["name"], $remember); $this->SetPersistentCookie("password", $user["password"], $remember); $this->SetPersistentCookie("remember", $remember, $remember); }
 506  	function LogoutUser() { $_SESSION["user"] = ""; $this->DeleteCookie("name"); $this->DeleteCookie("password"); }
 507  	function UserWantsComments() { if (!$user = $this->GetUser()) return false; return ($user["show_comments"] == "Y"); }
 508  	function GetParameter($parameter, $default = '') { return (isset($this->parameter[$parameter]) ? $this->parameter[$parameter] : $default); }
 509  
 510  
 511      
 512      // COMMENTS
 513  	function LoadComments($tag) { return $this->LoadAll("select * from ".$this->config["table_prefix"]."pages where comment_on = '".mysql_escape_string($tag)."' and latest = 'Y' order by time"); }
 514  	function LoadRecentComments() { return $this->LoadAll("select * from ".$this->config["table_prefix"]."pages where comment_on != '' and latest = 'Y' order by time desc"); }
 515  	function LoadRecentlyCommented($limit = 50) {
 516          $pages = array();
 517          
 518          // NOTE: this is really stupid. Maybe my SQL-Fu is too weak, but apparently there is no easier way to simply select
 519          //       all comment pages sorted by their first revision's (!) time. ugh!
 520          
 521          // load ids of the first revisions of latest comments. err, huh?
 522          $pages=array();
 523          $comments=array();
 524          if ($ids = $this->LoadAll("select min(id) as id from ".$this->config["table_prefix"]."pages where comment_on != '' group by tag order by id desc"))
 525          {
 526              // load complete comments
 527              $num=0;
 528              foreach ($ids as $id)
 529              {
 530                  $comment = $this->LoadSingle("select * from ".$this->config["table_prefix"]."pages where id = '".$id["id"]."' limit 1");
 531                  if (!isset($comments[$comment["comment_on"]]) && $num < $limit)
 532                  {
 533                      $comments[$comment["comment_on"]] = $comment;
 534                      $num++;
 535                  }
 536              }
 537          
 538              // now load pages
 539              if ($comments)
 540              {
 541                  // now using these ids, load the actual pages
 542                  foreach ($comments as $comment)
 543                  {
 544                      $page = $this->LoadPage($comment["comment_on"]);
 545                      $page["comment_user"] = $comment["user"];
 546                      $page["comment_time"] = $comment["time"];
 547                      $page["comment_tag"] = $comment["tag"];
 548                      $pages[] = $page;
 549                  }
 550              }
 551          }
 552          // load tags of pages 
 553          //return $this->LoadAll("select comment_on as tag, max(time) as time, tag as comment_tag, user from ".$this->config["table_prefix"]."pages where comment_on != '' group by comment_on order by time desc");
 554          return $pages;
 555      }
 556  
 557  
 558  
 559      // ACCESS CONTROL
 560      // returns true if logged in user is owner of current page, or page specified in $tag
 561  	function UserIsOwner($tag = "") {
 562          // check if user is logged in
 563          if (!$this->GetUser()) return false;
 564  
 565          // set default tag
 566          if (!$tag = trim($tag)) $tag = $this->GetPageTag();
 567          
 568          // check if user is owner
 569          if ($this->GetPageOwner($tag) == $this->GetUserName()) return true;
 570      }
 571  	function GetPageOwner($tag = "", $time = "") { if (!$tag = trim($tag)) $tag = $this->GetPageTag(); if ($page = $this->LoadPage($tag, $time)) return $page["owner"]; }
 572  	function SetPageOwner($tag, $user) {
 573          // check if user exists
 574          if (!$this->LoadUser($user)) return;
 575          
 576          // updated latest revision with new owner
 577          $this->Query("update ".$this->config["table_prefix"]."pages set owner = '".mysql_escape_string($user)."' where tag = '".mysql_escape_string($tag)."' and latest = 'Y' limit 1");
 578      }
 579  	function LoadAcl($tag, $privilege, $useDefaults = 1) {
 580          if ((!$acl = $this->LoadSingle("select * from ".$this->config["table_prefix"]."acls where page_tag = '".mysql_escape_string($tag)."' and privilege = '".mysql_escape_string($privilege)."' limit 1")) && $useDefaults)
 581          {
 582              $acl = array("page_tag" => $tag, "privilege" => $privilege, "list" => $this->GetConfigValue("default_".$privilege."_acl"));
 583          }
 584          return $acl;
 585      }
 586  	function SaveAcl($tag, $privilege, $list) {
 587          if ($this->LoadAcl($tag, $privilege, 0)) $this->Query("update ".$this->config["table_prefix"]."acls set list = '".mysql_escape_string(trim(str_replace("\r", "", $list)))."' where page_tag = '".mysql_escape_string($tag)."' and privilege = '".mysql_escape_string($privilege)."' limit 1");
 588          else $this->Query("insert into ".$this->config["table_prefix"]."acls set list = '".mysql_escape_string(trim(str_replace("\r", "", $list)))."', page_tag = '".mysql_escape_string($tag)."', privilege = '".mysql_escape_string($privilege)."'");
 589      }
 590      // returns true if $user (defaults to current user) has access to $privilege on $page_tag (defaults to current page)
 591  	function HasAccess($privilege, $tag = "", $user = "") {
 592          // set defaults
 593          if (!$tag = trim($tag)) $tag = $this->GetPageTag();
 594          if (!$user = $this->GetUserName());
 595          
 596          // load acl
 597          $acl = $this->LoadAcl($tag, $privilege);
 598          
 599          // if current user is owner, return true. owner can do anything!
 600          if ($this->UserIsOwner($tag)) return true;
 601          
 602          // fine fine... now go through acl
 603          foreach (explode("\n", $acl["list"]) as $line)
 604          {
 605              $line = trim($line);
 606  
 607              // check for inversion character "!"
 608              if (preg_match("/^[!](.*)$/", $line, $matches))
 609              {
 610                  $negate = 1;
 611                  $line = $matches[1];
 612              }
 613              else
 614              {
 615                  $negate = 0;
 616              }
 617  
 618              // if there's still anything left... lines with just a "!" don't count!
 619              if ($line)
 620              {
 621                  switch ($line[0])
 622                  {
 623                  // comments
 624                  case "#":
 625                      break;
 626                  // everyone
 627                  case "*":
 628                      return !$negate;
 629                  // aha! a user entry.
 630                  case "+":
 631                      if (!$this->LoadUser($user)) 
 632                      {
 633                          return $negate;
 634                      }
 635                      else
 636                      {
 637                          return !$negate;
 638                      }
 639                  default:
 640                      if ($line == $user)
 641                      {
 642                          return !$negate;
 643                      }
 644                  }
 645              }
 646          }
 647          
 648          // tough luck.
 649          return false;
 650      }
 651  
 652  
 653  
 654      // MAINTENANCE
 655  	function Maintenance() {
 656          // purge referrers
 657          $this->PurgeReferrers();
 658          // purge old page revisions
 659          $this->PurgePages();
 660      }
 661  
 662  
 663  
 664      // THE BIG EVIL NASTY ONE!
 665  	function Run($tag, $method = "") {
 666          if(!($this->GetMicroTime()%3)) $this->Maintenance(); 
 667  
 668          $this->ReadInterWikiConfig();
 669  
 670          // do our stuff!
 671          if (!$this->method = trim($method)) $this->method = "show";
 672          if (!$this->tag = trim($tag)) $this->Redirect($this->href("", $this->config["root_page"]));
 673          if ((!$this->GetUser() && isset($_COOKIE["name"])) && ($user = $this->LoadUser($_COOKIE["name"], $_COOKIE["password"]))) $this->SetUser($user, $_COOKIE["remember"]);
 674          $this->SetPage($this->LoadPage($tag, (isset($_REQUEST["time"]) ? $_REQUEST["time"] :'')));
 675          $this->LogReferrer();
 676  
 677        //correction pour un support plus facile de nouveaux handlers
 678        print($this->Method($this->method));
 679      }
 680  }
 681  
 682  
 683  
 684  // stupid version check
 685  if (!isset($_REQUEST)) die('$_REQUEST[] not found. Wakka requires PHP 4.1.0 or higher!');
 686  
 687  // workaround for the amazingly annoying magic quotes.
 688  function magicQuotesSuck(&$a)
 689  {
 690      if (is_array($a))
 691      {
 692          foreach ($a as $k => $v)
 693          {
 694              if (is_array($v))
 695                  magicQuotesSuck($a[$k]);
 696              else
 697                  $a[$k] = stripslashes($v);
 698          }
 699      }
 700  }
 701  set_magic_quotes_runtime(0);
 702  if (get_magic_quotes_gpc())
 703  {
 704      magicQuotesSuck($_POST);
 705      magicQuotesSuck($_GET);
 706      magicQuotesSuck($_COOKIE);
 707  }
 708  
 709  
 710  // default configuration values
 711  $wakkaConfig= array();
 712  $wakkaDefaultConfig = array(
 713      'wakka_version'        => '',
 714      'wikini_version'    => '',
 715      'debug'            => 'no',
 716      "mysql_host"        => "localhost",
 717      "mysql_database"        => "wikini",
 718      "mysql_user"        => "wikini",
 719      "mysql_password"        => '',
 720      "table_prefix"        => "wikini_",
 721      "root_page"            => "PagePrincipale",
 722      "wakka_name"        => "MonSiteWikiNi",
 723      "base_url"            => "http://".$_SERVER["SERVER_NAME"].($_SERVER["SERVER_PORT"] != 80 ? ":".$_SERVER["SERVER_PORT"] : "").$_SERVER["REQUEST_URI"].(preg_match("/".preg_quote("wakka.php")."$/", $_SERVER["REQUEST_URI"]) ? "?wiki=" : ""),
 724      "rewrite_mode"        => (preg_match("/".preg_quote("wakka.php")."$/", $_SERVER["REQUEST_URI"]) ? "0" : "1"),
 725      'meta_keywords'        => '',
 726      'meta_description'    => '',
 727      "action_path"        => "actions",
 728      "handler_path"        => "handlers",
 729      "header_action"        => "header",
 730      "footer_action"        => "footer",
 731      "navigation_links"        => "DerniersChangements :: DerniersCommentaires :: ParametresUtilisateur",
 732      "referrers_purge_time"    => 24,
 733      "pages_purge_time"    => 90,
 734      "default_write_acl"    => "*",
 735      "default_read_acl"    => "*",
 736      "default_comment_acl"    => "*",
 737      "preview_before_save"    => "0",
 738      'allow_raw_html'    => false);
 739  
 740  // load config
 741  if (!$configfile = GetEnv("WAKKA_CONFIG")) $configfile = "wakka.config.php";
 742  if (file_exists($configfile)) include($configfile);
 743  $wakkaConfigLocation = $configfile;
 744  $wakkaConfig = array_merge($wakkaDefaultConfig, $wakkaConfig);
 745  
 746  // check for locking
 747  if (file_exists("locked")) {
 748      // read password from lockfile
 749      $lines = file("locked");
 750      $lockpw = trim($lines[0]);
 751      
 752      // is authentification given?
 753      if (isset($_SERVER["PHP_AUTH_USER"])) {
 754          if (!(($_SERVER["PHP_AUTH_USER"] == "admin") && ($_SERVER["PHP_AUTH_PW"] == $lockpw))) {
 755              $ask = 1;
 756          }
 757      } else {
 758          $ask = 1;
 759      }
 760      
 761      if ($ask) {
 762          header("WWW-Authenticate: Basic realm=\"".$wakkaConfig["wakka_name"]." Install/Upgrade Interface\"");
 763          header("HTTP/1.0 401 Unauthorized");
 764          echo "Ce site est en cours de mise &agrave; jour. Veuillez essayer plus tard." ;
 765          exit;
 766      }
 767  }
 768  
 769  
 770  // compare versions, start installer if necessary
 771  if ($wakkaConfig["wakka_version"] && (!$wakkaConfig["wikini_version"])) { $wakkaConfig["wikini_version"]=$wakkaConfig["wakka_version"]; }
 772  if (($wakkaConfig["wakka_version"] != WAKKA_VERSION) || ($wakkaConfig["wikini_version"] != WIKINI_VERSION)) {
 773      // start installer
 774      if (!isset($_REQUEST["installAction"]) OR !$installAction = trim($_REQUEST["installAction"])) $installAction = "default";
 775      include ("setup/header.php");
 776      if (file_exists("setup/".$installAction.".php")) include("setup/".$installAction.".php"); else echo "<i>Invalid action</i>" ;
 777      include ("setup/footer.php");
 778      exit;
 779  }
 780  
 781  
 782  // configuration du cookie de session
 783  //determine le chemin pour le cookie
 784  $a = parse_url($wakkaConfig['base_url']);
 785  $CookiePath = dirname($a['path']);
 786  if ($CookiePath != '/') $CookiePath .= '/';
 787  $a = session_get_cookie_params();
 788  session_set_cookie_params($a['lifetime'],$CookiePath);
 789  unset($a);
 790  unset($CookiePath);
 791  
 792  // start session
 793  session_start();
 794  
 795  // fetch wakka location
 796  if (!isset($_REQUEST["wiki"])) $_REQUEST["wiki"] = '';
 797   
 798  $wiki = $_REQUEST["wiki"];
 799  
 800  // remove leading slash
 801  $wiki = preg_replace("/^\//", "", $wiki);
 802  
 803  // split into page/method
 804  if (preg_match("#^(.+?)/([A-Za-z0-9_]*)$#", $wiki, $matches)) list(, $page, $method) = $matches;
 805  else if (preg_match("#^(.*)$#", $wiki, $matches)) list(, $page) = $matches;
 806  
 807  // create wiki object
 808  $wiki = new Wiki($wakkaConfig);
 809  // check for database access
 810  if (!$wiki->dblink)
 811  {
 812      echo "<p>Pour des raisons ind&eacute;pendantes de notre volont&eacute;, le contenu de ce Wiki est temporairement inaccessible. Veuillez r&eacute;essayer ult&eacute;rieurement, merci de votre compr&eacute;hension.</p>";
 813      exit;
 814  }
 815  
 816  // Check if the server is configured to automatically compress the output
 817  if (!ini_get('zlib.output_compression') && !ini_get('zlib.output_handler'))
 818  { 
 819      // Check if we can use ob_gzhandler (requires the zlib extension)
 820      if (function_exists('ob_gzhandler'))
 821      {
 822          // let ob_gzhandler do the dirty job
 823          ob_start('ob_gzhandler');
 824      }
 825      // else let do the dirty job ourselves...
 826      elseif (!empty($_SERVER['HTTP_ACCEPT_ENCODING']) && strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') && function_exists('gzencode'))
 827      {
 828          ob_start ('gzencode');
 829          // Tell the browser the content is compressed with gzip 
 830          header ("Content-Encoding: gzip"); 
 831      }
 832  } 
 833  
 834  
 835  // go!
 836  if (!isset($method)) $method='';
 837  
 838  // Security (quick hack)  : Check method syntax
 839  if (!(preg_match('#^[A-Za-z0-9_]*$#',$method))) {
 840      $method='';
 841  }
 842  
 843  $wiki->Run($page, $method);
 844  ?>


Généré le : Mon Nov 26 12:05:46 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics