root/trunk/wiki/wakka.php

Revision 1, 27.8 KB (checked in by anonymous, 7 years ago)

initial import

Line 
1<?php
2/*
3    Yes, most of the formatting used in this file is HORRIBLY BAD STYLE. However,
4    most of the action happens outside of this file, and I really wanted the code
5    to look as small as what it does. Basically. Oh, I just suck. :)
6*/
7
8// do not change this line, you fool. In fact, don't change anything! Ever!
9define("WAKKA_VERSION", "0.1.1");
10define("WIKINI_VERSION", "0.3");
11// start the compute time
12list($g_usec, $g_sec) = explode(" ",microtime());
13define ("t_start", (float)$g_usec + (float)$g_sec);
14$t_SQL=0;
15
16function retreive_url_info($url)
17{
18        $url = ereg_replace("^/", "", $url);
19        return split('/', $url);
20}
21
22
23class Wiki
24{
25    var $dblink;
26    var $page;
27    var $lang;
28    var $tag;
29    var $parameter = array();
30    var $queryLog = array();
31    var $interWiki = array();
32    var $VERSION;
33   
34    // constructor
35    function Wiki($config, $lang='fr')
36    {
37        $this->lang = $lang;
38        $this->config = $config;
39/* might be a good idea to change this to mysql_connect */
40        $this->dblink = mysql_pconnect (
41            $this->config["mysql_host"],
42            $this->config["mysql_user"],
43            $this->config["mysql_password"]);
44        mysql_select_db($this->config["mysql_database"], $this->dblink);
45        $this->VERSION = WAKKA_VERSION;
46    }
47
48    // DATABASE
49    function Query($query)
50    {
51        if($this->GetConfigValue("debug")) $start = $this->GetMicroTime();
52        if (!$result = mysql_query($query, $this->dblink))
53        {
54            ob_end_clean();
55            die("Query failed: ".$query." (".mysql_error().")");
56        }
57        if($this->GetConfigValue("debug"))
58        {
59            $time = $this->GetMicroTime() - $start;
60            $this->queryLog[] = array(
61                "query"        => $query,
62                "time"        => $time);
63        }
64        return $result;
65    }
66    function LoadSingle($query) { if ($data = $this->LoadAll($query)) return $data[0]; }
67    function LoadAll($query)
68    {
69        $data=array();
70        if ($r = $this->Query($query))
71        {
72            while ($row = mysql_fetch_assoc($r)) $data[] = $row;
73            mysql_free_result($r);
74        }
75        return $data;
76    }
77   
78
79    // MISC
80    function GetMicroTime() { list($usec, $sec) = explode(" ",microtime()); return ((float)$usec + (float)$sec); }
81    function IncludeBuffered($filename, $notfoundText = "", $vars = "", $path = "")
82    {
83        if ($path) $dirs = explode(":", $path);
84        else $dirs = array("");
85
86        foreach($dirs as $dir)
87        {
88            if ($dir) $dir .= "/";
89            $fullfilename = $dir.$filename;
90            if (file_exists($fullfilename))
91            {
92                if (is_array($vars)) extract($vars);
93
94                ob_start();
95                include($fullfilename);
96                $output = ob_get_contents();
97                ob_end_clean();
98                return $output;
99            }
100        }
101        if ($notfoundText) return $notfoundText;
102        else return false;
103    }
104
105    // VARIABLES
106    function GetPageTag() { return $this->tag; }
107    function GetPageTime() { return $this->page["time"]; }
108    function GetMethod() { return $this->method; }
109    function GetConfigValue($name) { return $this->config[$name]; }
110    function GetWakkaName() { return $this->GetConfigValue("wakka_name"); }
111    function GetWakkaVersion() { return $this->VERSION; }
112    function GetWikiNiVersion() { $ver=$this->GetWakkaVersion().'.'.WIKINI_VERSION; return $ver; }
113    // PAGES
114    function LoadPage($tag, $time = "", $cache = 1) {
115        // retrieve from cache
116        if (!$time && $cache && ($cachedPage = $this->GetCachedPage($tag))) { $page = $cachedPage;}
117        // load page
118        if (!isset($page)) $page = $this->LoadSingle("select * from ".$this->config["table_prefix"]."pages where tag = '".mysql_escape_string($tag)."' and lang = '".mysql_escape_string($this->lang)."' ".($time ? "and time = '".mysql_escape_string($time)."'" : "and latest = 'Y'")." limit 1");
119        // cache result
120        if (!$time) $this->CachePage($page);
121        return $page;
122    }
123    function GetCachedPage($tag) {return (isset($this->pageCache[$tag]) ? $this->pageCache[$tag] : ''); }
124    function CachePage($page) { $this->pageCache[$page["tag"]] = $page; }
125    function SetPage($page) { $this->page = $page; if ($this->page["tag"]) $this->tag = $this->page["tag"]; }
126    function LoadPageById($id) { return $this->LoadSingle("select * from ".$this->config["table_prefix"]."pages where id = '".mysql_escape_string($id)."' limit 1"); }
127    function LoadRevisions($page) { return $this->LoadAll("select * from ".$this->config["table_prefix"]."pages where tag = '".mysql_escape_string($page)."' and lang = '".mysql_escape_string($this->lang)."' order by time desc"); }
128    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"); }
129    function LoadRecentlyChanged($limit=50, $lang='%')
130    {
131        $limit= (int) $limit;
132        if ($pages = $this->LoadAll("select tag, time, user, owner, lang from ".$this->config["table_prefix"]."pages where latest = 'Y' and comment_on = '' and lang like '$lang' order by time desc limit $limit"))
133        {
134            foreach ($pages as $page)
135            {
136                $this->CachePage($page);
137            }
138            return $pages;
139        }
140    }
141    function LoadAllPages() { return $this->LoadAll("select * from ".$this->config["table_prefix"]."pages where latest = 'Y' order by tag"); }
142    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)."')"); }
143    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"); }
144    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"); }
145    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)."'"); }
146    function DeleteOrphanedPage($tag)
147    {
148        $this->Query("delete from ".$this->config["table_prefix"]."pages where tag='".mysql_escape_string($tag)."' ");
149        $this->Query("delete from ".$this->config["table_prefix"]."links where from_tag='".mysql_escape_string($tag)."' ");
150        $this->Query("delete from ".$this->config["table_prefix"]."acls where page_tag='".mysql_escape_string($tag)."' ");
151        $this->Query("delete from ".$this->config["table_prefix"]."referrers where page_tag='".mysql_escape_string($tag)."' ");
152    }
153    function SavePage($tag, $body, $comment_on = "", $language)
154    {
155        // get current user
156        $user = $this->GetUserName();
157        if($language)
158            $lang = $language;
159        else
160            $lang = $this->lang;
161        //die($tag);
162
163        // TODO: check write privilege
164        if ($this->HasAccess("write", $tag))
165        {
166            // is page new?
167            if (!$oldPage = $this->LoadPage($tag))
168            {
169                // create default write acl. store empty write ACL for comments.
170                $this->SaveAcl($tag, "write", ($comment_on ? "" : $this->GetConfigValue("default_write_acl")));
171
172                // create default read acl
173                $this->SaveAcl($tag, "read", $this->GetConfigValue("default_read_acl"));
174
175                // create default comment acl.
176                $this->SaveAcl($tag, "comment", $this->GetConfigValue("default_comment_acl"));
177
178                // current user is owner; if user is logged in! otherwise, no owner.
179                if ($this->GetUser()) $owner = $user;
180            }
181            else
182            {
183                // aha! page isn't new. keep owner!
184                $owner = $oldPage["owner"];
185            }
186
187
188            // set all other revisions to old
189            $this->Query("update ".$this->config["table_prefix"]."pages set latest = 'N' where tag = '".mysql_Escape_string($tag)."' and lang = '".mysql_Escape_string($lang)."'");
190
191            // add new revision
192            $this->Query("insert into ".$this->config["table_prefix"]."pages set ".
193                "tag = '".mysql_escape_string($tag)."', ".
194                ($comment_on ? "comment_on = '".mysql_escape_string($comment_on)."', " : "").
195                "time = now(), ".
196                "owner = '".mysql_escape_string($owner)."', ".
197                "user = '".mysql_escape_string($user)."', ".
198                "lang = '".mysql_escape_string($lang)."', ".
199                "latest = 'Y', ".
200                "body = '".mysql_escape_string(trim($body))."'");
201        }
202    }
203
204    // COOKIES
205    function SetSessionCookie($name, $value) { SetCookie($name, $value, 0, "/"); $_COOKIE[$name] = $value; }
206    function SetPersistentCookie($name, $value, $remember = 0) { SetCookie($name, $value, time() + ($remember ? 90*24*60*60 : 60 * 60), "/"); $_COOKIE[$name] = $value; }
207    function DeleteCookie($name) { SetCookie($name, "", 1, "/"); $_COOKIE[$name] = ""; }
208    function GetCookie($name) { return $_COOKIE[$name]; }
209
210    // HTTP/REQUEST/LINK RELATED
211    function SetMessage($message) { $_SESSION["message"] = $message; }
212    function GetMessage() { $message = $_SESSION["message"]; $_SESSION["message"] = ""; return $message; }
213    function Redirect($url) { header("Location: $url"); exit; }
214    // returns just PageName[/method].
215    function MiniHref($method = "", $tag = "") { if (!$tag = trim($tag)) $tag = $this->tag; return $tag.($method ? "/".$method : ""); }
216    // returns the full url to a page/method.
217    function Href($method = "", $tag = "", $params = "", $lang="")
218    {
219        if(!$lang)
220            $href = $this->config["base_url"].$this->MiniHref($method, $tag);
221        else
222            $href = '/'.$lang.'/'.$this->MiniHref($method, $tag);
223
224        if ($params)
225            $href .= ($this->config["rewrite_mode"] ? "?" : "&amp;").$params;
226        return $href;
227    }
228    function Link($tag, $method = "", $text = "", $track = 1) {
229        $tag=htmlspecialchars($tag, ENT_COMPAT, 'UTF-8');//avoid xss
230        $text=htmlspecialchars($text, ENT_COMPAT, 'UTF-8');//paranoiac again
231        if (!$text) $text = $tag;
232
233        // is this an interwiki link?
234        if (preg_match("/^([A-Z][A-Z,a-z]+)[:]([A-Z,a-z,0-9]*)$/s", $tag, $matches))
235        {
236            $tag = $this->GetInterWikiUrl($matches[1], $matches[2]);
237            return "<a href=\"$tag\">".$matches[2]." <img src='/img/flags/".strtolower($matches[1]).".png' alt='(".$matches[1].")' /></a>";
238        }
239        // is this a full link? ie, does it contain alpha-numeric characters?
240        else if (preg_match("/[^[:alnum:]]/", $tag))
241        {
242            // check for email addresses
243            if (preg_match("/^.+\@.+$/", $tag))
244            {
245                $tag = "mailto:".$tag;
246            }
247            // check for protocol-less URLs
248            else if (!preg_match("/:\/\//", $tag))
249            {
250                $tag = "http://".$tag;   //Very important for xss (avoid javascript:() hacking)
251            }
252            // is this an inline image (text!=tag and url ends png,gif,jpeg)
253            if($text!=$tag and preg_match("/.(gif|jpeg|png|jpg)$/i",$tag)){
254                 return "<img src=\"$tag\" alt=\"$text\" \\>";
255            }else{
256                 return "<a href=\"$tag\">$text</a>";
257            }
258        }
259        else
260        {
261            // it's a Wiki link!
262            if ($_SESSION["linktracking"] && $track) $this->TrackLinkTo($tag);
263            return ($this->LoadPage($tag) ? "<a href=\"".$this->href($method, $tag)."\">".$text."</a>" : "<span class=\"missingpage\">".$text."</span><a href=\"".$this->href("edit", $tag)."\">?</a>");
264        }
265    }
266    function ComposeLinkToPage($tag, $method = "", $text = "", $track = 1, $lang='')
267    {
268        if (!$text) $text = $tag;
269        if (!$lang) $lang = $this->lang;
270        $text = htmlentities($text, ENT_COMPAT, 'UTF-8');
271        if ($_SESSION["linktracking"] && $track)
272            $this->TrackLinkTo($tag);
273        return '<a href="'.$this->href($method, $tag, "", $lang).'">'.$text.'</a>';
274    }
275
276    // function PregPageLink($matches) { return $this->Link($matches[1]); }
277   
278
279    function IsWikiName($text) { return preg_match("/^[A-Z][a-z]+[A-Z,0-9][A-Z,a-z,0-9]*$/", $text); }
280    function TrackLinkTo($tag) { $_SESSION["linktable"][] = $tag; }
281    function GetLinkTable() { return $_SESSION["linktable"]; }
282    function ClearLinkTable() { $_SESSION["linktable"] = array(); }
283    function StartLinkTracking() { $_SESSION["linktracking"] = 1; }
284    function StopLinkTracking() { $_SESSION["linktracking"] = 0; }
285    function WriteLinkTable()
286    {
287        // delete old link table
288        $this->Query("delete from ".$this->config["table_prefix"]."links where from_tag = '".mysql_escape_string($this->GetPageTag())."'");
289        if ($linktable = $this->GetLinkTable())
290        {
291            $from_tag = mysql_escape_string($this->GetPageTag());
292            foreach ($linktable as $to_tag)
293            {
294                $lower_to_tag = strtolower($to_tag);
295                if (!$written[$lower_to_tag])
296                {
297                    $this->Query("insert into ".$this->config["table_prefix"]."links set from_tag = '".$from_tag."', to_tag = '".mysql_escape_string($to_tag)."'");
298                    $written[$lower_to_tag] = 1;
299                }
300            }
301        }
302    }
303    function Header() { return $this->Action($this->GetConfigValue("header_action"), 1); }
304    function Footer() { return $this->Action($this->GetConfigValue("footer_action"), 1); }
305   
306    // FORMS
307    function FormOpen($method = "", $tag = "", $formMethod = "post")
308    {
309        $result = "<form action=\"".$this->href($method, $tag)."\" method=\"".$formMethod."\">\n";
310        if (!$this->config["rewrite_mode"]) $result .= "<input type=\"hidden\" name=\"wiki\" value=\"".$this->MiniHref($method, $tag)."\" />\n";
311        return $result;
312    }
313    function FormClose()
314    {
315        return "</form>\n";
316    }
317   
318    // INTERWIKI STUFF
319    function ReadInterWikiConfig()
320    {
321        if ($lines = file("interwiki.conf"))
322        {
323            foreach ($lines as $line)
324            {
325                if ($line = trim($line))
326                {
327                    list($wikiName, $wikiUrl) = explode(" ", trim($line));
328                    $this->AddInterWiki($wikiName, $wikiUrl);
329                }
330            }
331        }
332    }
333    function AddInterWiki($name, $url)
334    {
335        $this->interWiki[$name] = $url;
336    }
337    function GetInterWikiUrl($name, $tag)
338    {
339        if (isset($this->interWiki[$name]))
340        {
341            return $this->interWiki[$name].$tag;
342        }else{
343            return 'http://'.$tag; //avoid xss by putting http:// in front of JavaScript:()
344        }
345    }
346
347    // REFERRERS
348    function LogReferrer($tag = "", $referrer = "")
349    {
350        // fill values
351        if (!$tag = trim($tag)) $tag = $this->GetPageTag();
352        if (!$referrer = trim($referrer) AND isset($_SERVER["HTTP_REFERER"])) $referrer = $_SERVER["HTTP_REFERER"];
353       
354        // check if it's coming from another site
355        if ($referrer && !preg_match("/^".preg_quote($this->GetConfigValue("base_url"), "/")."/", $referrer))
356        {
357            $this->Query("insert into ".$this->config["table_prefix"]."referrers set ".
358                "page_tag = '".mysql_escape_string($tag)."', ".
359                "referrer = '".mysql_escape_string($referrer)."', ".
360                "time = now()");
361        }
362    }
363    function LoadReferrers($tag = "")
364    {
365        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");
366    }
367   
368    // PLUGINS
369    function Action($action, $forceLinkTracking = 0)
370    {
371        $action = trim($action); $vars=array();
372        // stupid attributes check
373        if ((stristr($action, "=\"")) || (stristr($action, "/")))
374        {
375            // extract $action and $vars_temp ("raw" attributes)
376            preg_match("/^([A-Za-z0-9]*)\/?(.*)$/", $action, $matches);
377            list(, $action, $vars_temp) = $matches;
378            // match all attributes (key and value)
379            $this->parameter[$vars_temp]=$vars_temp;
380            preg_match_all("/([A-Za-z0-9]*)=\"(.*)\"/U", $vars_temp, $matches);
381
382            // prepare an array for extract() to work with (in $this->IncludeBuffered())
383            if (is_array($matches))
384            {
385                for ($a = 0; $a < count($matches); $a++)
386                {
387                    $vars[$matches[1][$a]] = $matches[2][$a];
388                    $this->parameter[$matches[1][$a]]=$matches[2][$a];
389                }
390            }
391        }
392                if (!$forceLinkTracking) $this->StopLinkTracking();
393        $result = $this->IncludeBuffered(strtolower($action).".php", "<i>Action inconnue \"$action\"</i>", $vars, $this->config["action_path"]);
394        $this->StartLinkTracking();
395        if (isset($parameter)) unset($this->parameter[$parameter]);
396        unset($this->parameter);
397        return $result;
398    }
399    function Method($method)
400    {
401        if (!$handler = $this->page["handler"]) $handler = "page";
402        $methodLocation = $handler."/".$method.".php";
403        return $this->IncludeBuffered($methodLocation, "<i>Méthode inconue \"$methodLocation\"</i>", "", $this->config["handler_path"]);
404    }
405    function Format($text, $formatter = "wakka")
406    {
407        return $this->IncludeBuffered("formatters/".$formatter.".php", "<i>Impossible de trouver le formateur \"$formatter\"</i>", compact("text"));
408    }   
409
410    // USERS
411    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"); }
412    function LoadUsers() { return $this->LoadAll("select * from ".$this->config["table_prefix"]."users order by name"); }
413    function GetUserName() { if ($user = $this->GetUser()) $name = $user["name"]; else if (!$name = gethostbyaddr($_SERVER["REMOTE_ADDR"])) $name = $_SERVER["REMOTE_ADDR"]; return $name; }
414    function UserName() { /* deprecated! */ return $this->GetUserName(); }
415    function GetUser() { return (isset($_SESSION["user"]) ? $_SESSION["user"] : '');}
416    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); }
417    function LogoutUser() { $_SESSION["user"] = ""; $this->DeleteCookie("name"); $this->DeleteCookie("password"); }
418    function UserWantsComments() { if (!$user = $this->GetUser()) return false; return ($user["show_comments"] == "Y"); }
419    function GetParameter($parameter) { return (isset($this->parameter[$parameter]) ? $this->parameter[$parameter] :''); }
420   
421   
422    // COMMENTS
423    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"); }
424    function LoadRecentComments() { return $this->LoadAll("select * from ".$this->config["table_prefix"]."pages where comment_on != '' and latest = 'Y' order by time desc"); }
425    function LoadRecentlyCommented($limit = 50)
426    {
427        // NOTE: this is really stupid. Maybe my SQL-Fu is too weak, but apparently there is no easier way to simply select
428        //       all comment pages sorted by their first revision's (!) time. ugh!
429       
430        // load ids of the first revisions of latest comments. err, huh?
431        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"))
432        {
433            // load complete comments
434            foreach ($ids as $id)
435            {
436                $comment = $this->LoadSingle("select * from ".$this->config["table_prefix"]."pages where id = '".$id["id"]."' limit 1");
437                if (!$comments[$comment["comment_on"]] && $num < $limit)
438                {
439                    $comments[$comment["comment_on"]] = $comment;
440                    $num++;
441                }
442            }
443       
444            // now load pages
445            if ($comments)
446            {
447                // now using these ids, load the actual pages
448                foreach ($comments as $comment)
449                {
450                    $page = $this->LoadPage($comment["comment_on"]);
451                    $page["comment_user"] = $comment["user"];
452                    $page["comment_time"] = $comment["time"];
453                    $page["comment_tag"] = $comment["tag"];
454                    $pages[] = $page;
455                }
456            }
457        }
458        // load tags of pages
459        //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");
460        return $pages;
461    }
462   
463    // ACCESS CONTROL
464    // returns true if logged in user is owner of current page, or page specified in $tag
465    function UserIsOwner($tag = "")
466    {
467        // check if user is logged in
468        if (!$this->GetUser()) return false;
469
470        // set default tag
471        if (!$tag = trim($tag)) $tag = $this->GetPageTag();
472       
473        // check if user is owner
474        if ($this->GetPageOwner($tag) == $this->GetUserName()) return true;
475    }
476    function GetPageOwner($tag = "", $time = "") { if (!$tag = trim($tag)) $tag = $this->GetPageTag(); if ($page = $this->LoadPage($tag, $time)) return $page["owner"]; }
477    function SetPageOwner($tag, $user)
478    {
479        // check if user exists
480        if (!$this->LoadUser($user)) return;
481       
482        // updated latest revision with new owner
483        $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");
484    }
485    function LoadAcl($tag, $privilege, $useDefaults = 1)
486    {
487        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)
488        {
489            $acl = array("page_tag" => $tag, "privilege" => $privilege, "list" => $this->GetConfigValue("default_".$privilege."_acl"));
490        }
491        return $acl;
492    }
493    function SaveAcl($tag, $privilege, $list) {
494        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");
495        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)."'");
496    }
497    // returns true if $user (defaults to current user) has access to $privilege on $page_tag (defaults to current page)
498    function HasAccess($privilege, $tag = "", $user = "")
499    {
500        // set defaults
501        if (!$tag = trim($tag)) $tag = $this->GetPageTag();
502        if (!$user = $this->GetUserName());
503       
504        // load acl
505        $acl = $this->LoadAcl($tag, $privilege);
506       
507        // if current user is owner, return true. owner can do anything!
508        if ($this->UserIsOwner($tag)) return true;
509       
510        // fine fine... now go through acl
511        foreach (explode("\n", $acl["list"]) as $line)
512        {
513            $line = trim($line);
514
515            // check for inversion character "!"
516            if (preg_match("/^[!](.*)$/", $line, $matches))
517            {
518                $negate = 1;
519                $line = $matches[1];
520            }
521            else
522            {
523                $negate = 0;
524            }
525
526            // if there's still anything left... lines with just a "!" don't count!
527            if ($line)
528            {
529                switch ($line[0])
530                {
531                // comments
532                case "#":
533                    break;
534                // everyone
535                case "*":
536                    return !$negate;
537                // aha! a user entry.
538                case "+":
539                    if (!$this->LoadUser($user))
540                    {
541                        return $negate;
542                    }
543                    else
544                    {
545                        return !$negate;
546                    }
547                default:
548                    if ($line == $user)
549                    {
550                        return !$negate;
551                    }
552                }
553            }
554        }
555       
556        // tough luck.
557        return false;
558    }
559   
560    // MAINTENANCE
561    function Maintenance()
562    {
563        // purge referrers
564        if ($days = $this->GetConfigValue("referrers_purge_time")) {
565            $this->Query("delete from ".$this->config["table_prefix"]."referrers where time < date_sub(now(), interval '".mysql_escape_string($days)."' day)");
566        }
567       
568        // purge old page revisions
569        if ($days = $this->GetConfigValue("pages_purge_time")) {
570            $this->Query("delete from ".$this->config["table_prefix"]."pages where time < date_sub(now(), interval '".mysql_escape_string($days)."' day) and latest = 'N'");
571        }
572    }
573   
574    // THE BIG EVIL NASTY ONE!
575    function Run($tag, $method = "")
576    {
577                if(!($this->GetMicroTime()%3)) $this->Maintenance();
578
579        $this->ReadInterWikiConfig();
580
581        // do our stuff!
582        if (!$this->method = trim($method)) $this->method = "show";
583        if (!$this->tag = trim($tag)) $this->Redirect($this->href("", $this->config["root_page"]));
584        if ((!$this->GetUser() && isset($_COOKIE["name"])) && ($user = $this->LoadUser($_COOKIE["name"], $_COOKIE["password"]))) $this->SetUser($user, $_COOKIE["remember"]);
585        $this->SetPage($this->LoadPage($tag, (isset($_REQUEST["time"]) ? $_REQUEST["time"] :'')));
586        $this->LogReferrer();
587        switch ($this->method)
588        {
589            case "xml":
590                  header("Content-type: text/xml");   
591            case "raw":
592                print($this->Method($this->method));
593                break;
594            default:
595                print($this->Header().$this->Method($this->method).$this->Footer());
596        }
597
598    }
599}
600// stupid version check
601if (!isset($_REQUEST)) die('$_REQUEST[] not found. Wakka requires PHP 4.1.0 or higher!');
602
603$token = retreive_url_info($_SERVER['PHP_SELF']);
604
605// workaround for the amazingly annoying magic quotes.
606function magicQuotesSuck(&$a)
607{
608    if (is_array($a))
609    {
610        foreach ($a as $k => $v)
611        {
612            if (is_array($v))
613                magicQuotesSuck($a[$k]);
614            else
615                $a[$k] = stripslashes($v);
616        }
617    }
618}
619set_magic_quotes_runtime(0);
620if (get_magic_quotes_gpc())
621{
622    magicQuotesSuck($_POST);
623    magicQuotesSuck($_GET);
624    magicQuotesSuck($_COOKIE);
625}
626
627
628// default configuration values
629$wakkaConfig= array();
630$wakkaDefaultConfig = array(
631    'wakka_version'         => '',
632    'debug'                 => 'no',
633    "mysql_host"            => "localhost",
634    "mysql_database"        => "wikini",
635    "mysql_user"            => "wikini",
636    "mysql_password"        => '',
637    "table_prefix"            => "wikini_",
638
639    "root_page"                => "PagePrincipale",
640    "wakka_name"            => "MonSiteWikiNi",
641    "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=" : ""),
642    "rewrite_mode"            => (preg_match("/".preg_quote("wakka.php")."$/", $_SERVER["REQUEST_URI"]) ? "0" : "1"),
643   
644    'meta_keywords'         => '',
645    'meta_description'      => '',
646    "action_path"            => "actions",
647    "handler_path"            => "handlers",
648   
649    "header_action"            => "header",
650    "footer_action"            => "footer",
651   
652    "navigation_links"        => "DerniersChangements :: DerniersCommentaires :: ParametresUtilisateur",
653   
654    "referrers_purge_time"    => 24,
655    "pages_purge_time"    => 90,
656   
657    "default_write_acl"        => "*",
658    "default_read_acl"        => "*",
659    "default_comment_acl"    => "*",
660      "preview_before_save"    => "0");
661
662// load config
663if (!$configfile = GetEnv("WAKKA_CONFIG")) $configfile = "wakka.config.php";
664if (file_exists($configfile)) include($configfile);
665$wakkaConfigLocation = $configfile;
666$wakkaConfig = array_merge($wakkaDefaultConfig, $wakkaConfig);
667
668// check for locking
669if (file_exists("locked")) {
670    // read password from lockfile
671    $lines = file("locked");
672    $lockpw = trim($lines[0]);
673   
674    // is authentification given?
675    if (isset($_SERVER["PHP_AUTH_USER"])) {
676        if (!(($_SERVER["PHP_AUTH_USER"] == "admin") && ($_SERVER["PHP_AUTH_PW"] == $lockpw))) {
677            $ask = 1;
678        }
679    } else {
680        $ask = 1;
681    }
682   
683    if ($ask) {
684        header("WWW-Authenticate: Basic realm=\"".$wakkaConfig["wakka_name"]." Install/Upgrade Interface\"");
685        header("HTTP/1.0 401 Unauthorized");
686        print("This site is currently being upgraded. Please try again later.");
687        exit;
688        }
689}
690
691
692// compare versions, start installer if necessary
693if ($wakkaConfig["wakka_version"] != WAKKA_VERSION)
694{
695    // start installer
696    if (!isset($_REQUEST["installAction"]) OR !$installAction = trim($_REQUEST["installAction"])) $installAction = "default";
697    include("setup/header.php");
698    if (file_exists("setup/".$installAction.".php")) include("setup/".$installAction.".php"); else print("<i>Invalid action</i>");
699    include("setup/footer.php");
700    exit;
701}
702
703
704// start session
705session_start();
706
707// fetch wakka location
708$wiki = $_REQUEST["wiki"];
709
710
711$wiki_lang = $token[0];
712$wiki = $token[1];
713
714// remove leading slash
715$wiki = preg_replace("/^\//", "", $wiki);
716
717// split into page/method
718if (preg_match("#^(.+?)/(.*)$#", $wiki, $matches)) list(, $page, $method) = $matches;
719else if (preg_match("#^(.*)$#", $wiki, $matches)) list(, $page) = $matches;
720
721// create wiki object
722$wiki = new Wiki($wakkaConfig, $wiki_lang);
723/*
724function compress_output($output)
725{
726    return gzencode($output);
727}
728
729// Check if the browser supports gzip encoding, HTTP_ACCEPT_ENCODING
730if (strstr ($HTTP_SERVER_VARS['HTTP_ACCEPT_ENCODING'], 'gzip') && function_exists('gzencode') )
731{
732    // Start output buffering, and register compress_output() (see
733    // below)
734    ob_start ("compress_output");
735
736    // Tell the browser the content is compressed with gzip
737    header ("Content-Encoding: gzip");
738}
739*/
740header('Content-type: text/html; charset=UTF-8');
741# ob_start("ob_gzhandler");
742
743
744// go!
745if (!isset($method)) $method='';
746$method = $token[2];
747$wiki->Run($page, $method);
748?>
Note: See TracBrowser for help on using the browser.