Subversion Repositories Applications.wikini

Rev

Rev 43 | Rev 54 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 43 Rev 45
1
<?php
1
<?php
2
/* encoding: iso-8859-1
2
/*
3
wakka.php
3
$Id: wakka.php 864 2007-11-28 12:44:52Z nepote $
4
Copyright (c) 2002, Hendrik Mans <hendrik@mans.de>
4
Copyright (c) 2002, Hendrik Mans <hendrik@mans.de>
5
Copyright  2003 Carlo Zottmann
5
Copyright 2003 Carlo Zottmann
6
Copyright 2002, 2003 David DELON
6
Copyright 2002, 2003, 2005 David DELON
7
Copyright 2002, 2003, 2004 Charles NÉPOTE
7
Copyright 2002, 2003, 2004, 2006 Charles N?POTE
8
Copyright 2002, 2003 Patrick PAUL
8
Copyright 2002, 2003 Patrick PAUL
9
Copyright 2003 Éric DELORD
9
Copyright 2003 Eric DELORD
10
Copyright 2003 Éric FELDSTEIN
10
Copyright 2003 Eric FELDSTEIN
11
Copyright 2004 Jean-Christophe ANDRÉ
11
Copyright 2004-2006 Jean-Christophe ANDR?
-
 
12
Copyright 2005-2006 Didier LOISEAU
12
All rights reserved.
13
All rights reserved.
13
Redistribution and use in source and binary forms, with or without
14
Redistribution and use in source and binary forms, with or without
14
modification, are permitted provided that the following conditions
15
modification, are permitted provided that the following conditions
15
are met:
16
are met:
16
1. Redistributions of source code must retain the above copyright
17
1. Redistributions of source code must retain the above copyright
17
notice, this list of conditions and the following disclaimer.
18
notice, this list of conditions and the following disclaimer.
18
2. Redistributions in binary form must reproduce the above copyright
19
2. Redistributions in binary form must reproduce the above copyright
19
notice, this list of conditions and the following disclaimer in the
20
notice, this list of conditions and the following disclaimer in the
20
documentation and/or other materials provided with the distribution.
21
documentation and/or other materials provided with the distribution.
21
3. The name of the author may not be used to endorse or promote products
22
3. The name of the author may not be used to endorse or promote products
22
derived from this software without specific prior written permission.
23
derived from this software without specific prior written permission.
23
 
24
 
24
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
*/
35
 */
35
 
36
 
36
/*
37
/*
37
    Yes, most of the formatting used in this file is HORRIBLY BAD STYLE. However,
38
	Yes, most of the formatting used in this file is HORRIBLY BAD STYLE. However,
38
    most of the action happens outside of this file, and I really wanted the code
39
	most of the action happens outside of this file, and I really wanted the code
39
    to look as small as what it does. Basically. Oh, I just suck. :)
40
	to look as small as what it does. Basically. Oh, I just suck. :)
40
*/
41
 */
41
 
42
 
42
 
43
 
43
 
44
 
44
// do not change this line, you fool. In fact, don't change anything! Ever!
45
// do not change this line, you fool. In fact, don't change anything! Ever!
45
define("WAKKA_VERSION", "0.1.1");
46
define("WAKKA_VERSION", "0.1.1");
46
define("WIKINI_VERSION", "0.4.3");
47
define("WIKINI_VERSION", "0.5.0");
-
 
48
require 'includes/constants.php';
-
 
49
include 'includes/urlutils.inc.php';
-
 
50
 
47
// start the compute time
51
// start the compute time
48
list($g_usec, $g_sec) = explode(" ",microtime());
52
list($g_usec, $g_sec) = explode(" ",microtime());
49
define ("t_start", (float)$g_usec + (float)$g_sec);
53
define ("t_start", (float)$g_usec + (float)$g_sec);
50
$t_SQL=0;
54
$t_SQL=0;
51
 
55
 
52
 
56
 
53
 
57
 
54
class Wiki
58
class Wiki
55
{
59
{
56
	var $dblink;
60
	var $dblink;
57
	var $page;
61
	var $page;
58
	var $tag;
62
	var $tag;
59
	var $parameter = array();
63
	var $parameter = array();
60
	var $queryLog = array();
64
	var $queryLog = array();
61
	var $interWiki = array();
65
	var $interWiki = array();
62
	var $VERSION;
66
	var $VERSION;
63
	var $CookiePath = '/';
67
	var $CookiePath = '/';
-
 
68
	var $inclusions = array();
-
 
69
	/**
-
 
70
	 * an array containing all the actions that are implemented by an object
-
 
71
	 * @access private
-
 
72
	 */
-
 
73
	var $actionObjects;
-
 
74
 
-
 
75
	// LinkTrackink
-
 
76
	var $isTrackingLinks = false;
-
 
77
	var $linktable = array();
-
 
78
 
-
 
79
	var $pageCache = array();
-
 
80
	var $_groupsCache = array();
64
 
81
	var $_actionsAclsCache = array();
65
 
82
 
66
	// constructor
83
	// constructor
67
	function Wiki($config)
84
	function Wiki($config)
68
	{
85
	{
69
		$this->config = $config;
86
		$this->config = $config;
70
		// some host do not allow mysql_pconnect
87
		// some host do not allow mysql_pconnect
71
		$this->dblink = @mysql_connect (
88
		$this->dblink = @mysql_connect (
72
			$this->config["mysql_host"],
89
			$this->config["mysql_host"],
73
			$this->config["mysql_user"],
90
			$this->config["mysql_user"],
74
			$this->config["mysql_password"]);
91
			$this->config["mysql_password"]);
75
		if ($this->dblink)
92
		if ($this->dblink)
76
		{
93
		{
77
			if (!@mysql_select_db($this->config["mysql_database"], $this->dblink))
94
			if (!@mysql_select_db($this->config["mysql_database"], $this->dblink))
78
			{
95
			{
79
				@mysql_close($this->dblink);
96
				@mysql_close($this->dblink);
80
				$this->dblink = false;
97
				$this->dblink = false;
81
			}
98
			}
82
		}
99
		}
83
		$this->VERSION = WAKKA_VERSION;
100
		$this->VERSION = WAKKA_VERSION;
84
 
101
 
85
		//determine le chemin pour le cookie
102
		// determine le chemin pour les cookies
86
		$a = parse_url($this->GetConfigValue('base_url'));
103
		$a = parse_url($this->GetConfigValue('base_url'));
-
 
104
		$this->CookiePath = dirname($a['path']);
-
 
105
		// Fixe la gestion des cookie sous les OS utilisant le \ comme s?parteur de chemin
-
 
106
		$this->CookiePath = str_replace("\\","/",$this->CookiePath);
87
		$this->CookiePath = dirname($a['path']);
107
		// ajoute un '/' terminal sauf si on est ? la racine web
88
		if ($this->CookiePath != '/') $this->CookiePath .= '/';
108
		if ($this->CookiePath != '/') $this->CookiePath .= '/';
89
	}
109
	}
90
 
110
 
91
 
111
 
92
 
112
 
93
	// DATABASE
113
	// DATABASE
94
	function Query($query)
114
	function Query($query)
95
	{
115
	{
96
		if($this->GetConfigValue("debug")) $start = $this->GetMicroTime();
116
		if($this->GetConfigValue("debug")) $start = $this->GetMicroTime();
97
		if (!$result = mysql_query($query, $this->dblink))
117
		if (!$result = mysql_query($query, $this->dblink))
98
		{
118
		{
99
			ob_end_clean();
119
			ob_end_clean();
100
			die("Query failed: ".$query." (".mysql_error().")");
120
			die("Query failed: ".$query." (".mysql_error().")");
101
		}
121
		}
102
		if($this->GetConfigValue("debug"))
122
		if($this->GetConfigValue("debug"))
103
		{
123
		{
104
			$time = $this->GetMicroTime() - $start;
124
			$time = $this->GetMicroTime() - $start;
105
			$this->queryLog[] = array(
125
			$this->queryLog[] = array(
106
				"query"		=> $query,
126
				"query"		=> $query,
107
				"time"		=> $time);
127
				"time"		=> $time);
108
		}
128
		}
109
		return $result;
129
		return $result;
110
	}
130
	}
-
 
131
	function LoadSingle($query) {
111
	function LoadSingle($query) { if ($data = $this->LoadAll($query)) return $data[0]; }
132
		if ($data = $this->LoadAll($query)) return $data[0];
-
 
133
		return null;
-
 
134
	}
112
	function LoadAll($query)
135
	function LoadAll($query)
113
	{
136
	{
114
	$data=array();
137
		$data=array();
115
	if ($r = $this->Query($query))
138
		if ($r = $this->Query($query))
116
		{
139
		{
117
			while ($row = mysql_fetch_assoc($r)) $data[] = $row;
140
			while ($row = mysql_fetch_assoc($r)) $data[] = $row;
118
			mysql_free_result($r);
141
			mysql_free_result($r);
119
		}
142
		}
120
		return $data;
143
		return $data;
121
	}
144
	}
122
 
145
 
123
 
146
 
124
 
147
 
125
	// MISC
148
	// MISC
-
 
149
	function GetMicroTime()
-
 
150
	{
126
	function GetMicroTime() { list($usec, $sec) = explode(" ",microtime()); return ((float)$usec + (float)$sec); }
151
		list($usec, $sec) = explode(" ",microtime()); return ((float)$usec + (float)$sec);
-
 
152
	}
127
	function IncludeBuffered($filename, $notfoundText = "", $vars = "", $path = "")
153
	function IncludeBuffered($filename, $notfoundText = "", $vars = "", $path = "")
128
	{
154
	{
129
		if ($path) $dirs = explode(":", $path);
155
		if ($path) $dirs = explode(":", $path);
130
		else $dirs = array("");
156
		else $dirs = array("");
131
 
157
 
132
		foreach($dirs as $dir)
158
		foreach($dirs as $dir)
133
		{
159
		{
134
			if ($dir) $dir .= "/";
160
			if ($dir) $dir .= "/";
135
			$fullfilename = $dir.$filename;
161
			$fullfilename = $dir.$filename;
136
			if (file_exists($fullfilename))
162
			if (file_exists($fullfilename))
137
			{
163
			{
138
				if (is_array($vars)) extract($vars);
164
				if (is_array($vars)) extract($vars);
139
 
165
 
140
				ob_start();
166
				ob_start();
141
				include($fullfilename);
167
				include($fullfilename);
142
				$output = ob_get_contents();
168
				$output = ob_get_contents();
143
				ob_end_clean();
169
				ob_end_clean();
144
				return $output;
170
				return $output;
145
			}
171
			}
146
		}
172
		}
147
		if ($notfoundText) return $notfoundText;
173
		if ($notfoundText) return $notfoundText;
148
		else return false;
174
		else return false;
149
	}
175
	}
150
 
176
 
151
 
177
 
152
 
178
 
153
	// VARIABLES
179
	// VARIABLES
154
	function GetPageTag() { return $this->tag; }
180
	function GetPageTag() { return $this->tag; }
155
	function GetPageTime() { return $this->page["time"]; }
181
	function GetPageTime() { return $this->page["time"]; }
156
	function GetMethod() { return $this->method; }
182
	function GetMethod() { return $this->method; }
157
	function GetConfigValue($name) { return $this->config[$name]; }
183
	function GetConfigValue($name) { return isset($this->config[$name]) ? trim($this->config[$name]) : ''; }
158
	function GetWakkaName() { return $this->GetConfigValue("wakka_name"); }
184
	function GetWakkaName() { return $this->GetConfigValue("wakka_name"); }
159
	function GetWakkaVersion() { return $this->VERSION; }
185
	function GetWakkaVersion() { return $this->VERSION; }
160
	function GetWikiNiVersion() { return WIKINI_VERSION; } 
186
	function GetWikiNiVersion() { return WIKINI_VERSION; }
-
 
187
 
-
 
188
	/**
-
 
189
	 * Retrieves all the triples that match some criteria.
-
 
190
	 * This allows to search triples by their approximate resource or property names.
-
 
191
	 * The allowed operators are the sql LIKE and the sql =
-
 
192
	 * @param string $resource The resource of the triples
-
 
193
	 * @param string $property The property of the triple to retrieve or null
-
 
194
	 * @param string $res_op The operator of comparison between the effective resource and $resource (default: 'LIKE')
-
 
195
	 * @param string $prop_op The operator of comparison between the effective property and $property (default: '=')
-
 
196
	 * @return array The list of all the triples that match the asked criteria 
-
 
197
	 */
-
 
198
	function GetMatchingTriples($resource, $property = null, $res_op = 'LIKE', $prop_op = '=')
-
 
199
	{
-
 
200
		static $operators = array('=', 'LIKE'); // we might want to add other operators later
-
 
201
		$res_op = strtoupper($res_op);
-
 
202
		if (!in_array($res_op, $operators)) $res_op = '=';
-
 
203
		$sql = 'SELECT * FROM ' . $this->GetConfigValue('table_prefix') . 'triples '
-
 
204
			. 'WHERE resource ' . $res_op . ' "' . addslashes($resource) . '"';
-
 
205
		if ($property !== null)
-
 
206
		{
-
 
207
			$prop_op = strtoupper($prop_op);
-
 
208
			if (!in_array($prop_op, $operators)) $prop_op = '=';
-
 
209
			$sql .= ' AND property ' . $prop_op . ' "' . addslashes($property) . '"';
-
 
210
		}
-
 
211
		return $this->LoadAll($sql);
-
 
212
	}
-
 
213
 
-
 
214
	/**
-
 
215
	 * Retrieves all the values for a given couple (resource, property)
-
 
216
	 * @param string $resource The resource of the triples
-
 
217
	 * @param string $property The property of the triple to retrieve
-
 
218
	 * @param string $re_prefix The prefix to add to $resource (defaults to THISWIKI_PREFIX)
-
 
219
	 * @param string $prop_prefix The prefix to add to $property (defaults to WIKINI_VOC_PREFIX)
-
 
220
	 * @return array An array of the retrieved values, in the form
-
 
221
	 * array(
-
 
222
	 * 	0 => array(id = 7 , 'value' => $value1),
-
 
223
	 * 	1 => array(id = 34, 'value' => $value2),
-
 
224
	 * 	...
-
 
225
	 * )
-
 
226
	 */
-
 
227
	function GetAllTriplesValues($resource, $property, $re_prefix = THISWIKI_PREFIX, $prop_prefix = WIKINI_VOC_PREFIX)
-
 
228
	{
-
 
229
		$sql = 'SELECT id, value FROM ' . $this->GetConfigValue('table_prefix') . 'triples '
-
 
230
			. 'WHERE resource = "' . addslashes($re_prefix . $resource) . '" '
-
 
231
			. 'AND property = "' . addslashes($prop_prefix . $property) . '" ';
-
 
232
		return $this->LoadAll($sql);
-
 
233
	} 
-
 
234
 
-
 
235
	/**
-
 
236
	 * Retrieves a single value for a given couple (resource, property)
-
 
237
	 * @param string $resource The resource of the triples
-
 
238
	 * @param string $property The property of the triple to retrieve
-
 
239
	 * @param string $re_prefix The prefix to add to $resource (defaults to <tt>THISWIKI_PREFIX</tt>)
-
 
240
	 * @param string $prop_prefix The prefix to add to $property (defaults to <tt>WIKINI_VOC_PREFIX</tt>)
-
 
241
	 * @return string The value corresponding to ($resource, $property) or null if
-
 
242
	 * there is no such couple in the triples table.
-
 
243
	 */
-
 
244
	function GetTripleValue($resource, $property, $re_prefix = THISWIKI_PREFIX, $prop_prefix = WIKINI_VOC_PREFIX)
-
 
245
	{
-
 
246
		$res = $this->GetAllTriplesValues($resource, $property, $re_prefix, $prop_prefix);
-
 
247
		if ($res) return $res[0]['value'];
-
 
248
		return null;
-
 
249
	}
-
 
250
 
-
 
251
	/**
-
 
252
	 * Checks whether a triple exists or not
-
 
253
	 * @param string $resource The resource of the triple to find
-
 
254
	 * @param string $property The property of the triple to find
-
 
255
	 * @param string $value The value of the triple to find
-
 
256
	 * @param string $re_prefix The prefix to add to $resource (defaults to <tt>THISWIKI_PREFIX</tt>)
-
 
257
	 * @param string $prop_prefix The prefix to add to $property (defaults to <tt>WIKINI_VOC_PREFIX</tt>)
-
 
258
	 * @param int The id of the found triple or 0 if there is no such triple. 
-
 
259
	 */
-
 
260
	function TripleExists($resource, $property, $value, $re_prefix = THISWIKI_PREFIX, $prop_prefix = WIKINI_VOC_PREFIX)
-
 
261
	{
-
 
262
		$sql = 'SELECT id FROM ' . $this->GetConfigValue('table_prefix') . 'triples '
-
 
263
			. 'WHERE resource = "' . addslashes($re_prefix . $resource) . '" '
-
 
264
			. 'AND property = "' . addslashes($prop_prefix . $property) . '" '
-
 
265
			. 'AND value = "' . addslashes($value) . '"';
-
 
266
		$res = $this->LoadSingle($sql);
-
 
267
		if (!$res) return 0;
-
 
268
		return $res['id'];
-
 
269
	}
-
 
270
 
-
 
271
	/**
-
 
272
	 * Inserts a new triple ($resource, $property, $value) in the triples' table
-
 
273
	 * @param string $resource The resource of the triple to insert
-
 
274
	 * @param string $property The property of the triple to insert
-
 
275
	 * @param string $value The value of the triple to insert
-
 
276
	 * @param string $re_prefix The prefix to add to $resource (defaults to <tt>THISWIKI_PREFIX</tt>)
-
 
277
	 * @param string $prop_prefix The prefix to add to $property (defaults to <tt>WIKINI_VOC_PREFIX</tt>)
-
 
278
	 * @return int An error code: 0 (success), 1 (failure) or 3 (already exists)
-
 
279
	 */
-
 
280
	function InsertTriple($resource, $property, $value, $re_prefix = THISWIKI_PREFIX, $prop_prefix = WIKINI_VOC_PREFIX)
-
 
281
	{
-
 
282
		if ($this->TripleExists($resource, $property, $value, $re_prefix, $prop_prefix))
-
 
283
		{
-
 
284
			return 3;
-
 
285
		}
-
 
286
		$sql = 'INSERT INTO ' . $this->GetConfigValue('table_prefix') . 'triples (resource, property, value)'
-
 
287
			. 'VALUES ("' . addslashes($re_prefix . $resource) . '", "'
-
 
288
				. addslashes($prop_prefix . $property) . '", "'
-
 
289
				. addslashes($value) . '")';
-
 
290
		return $this->Query($sql) ? 0 : 1;
-
 
291
	}
-
 
292
 
-
 
293
	/**
-
 
294
	 * Updates a triple ($resource, $property, $value) in the triples' table
-
 
295
	 * @param string $resource The resource of the triple to update
-
 
296
	 * @param string $property The property of the triple to update
-
 
297
	 * @param string $oldvalue The old value of the triple to update
-
 
298
	 * @param string $newvalue The new value of the triple to update
-
 
299
	 * @param string $re_prefix The prefix to add to $resource (defaults to <tt>THISWIKI_PREFIX</tt>)
-
 
300
	 * @param string $prop_prefix The prefix to add to $property (defaults to <tt>WIKINI_VOC_PREFIX</tt>)
-
 
301
	 * @return int An error code: 0 (succ?s), 1 (?chec),
-
 
302
	 * 		2 ($resource, $property, $oldvalue does not exist)
-
 
303
	 * 		or 3 ($resource, $property, $newvalue already exists)
-
 
304
	 */
-
 
305
	function UpdateTriple($resource, $property, $oldvalue, $newvalue, $re_prefix = THISWIKI_PREFIX, $prop_prefix = WIKINI_VOC_PREFIX)
-
 
306
	{
-
 
307
		$id = $this->TripleExists($resource, $property, $oldvalue, $re_prefix, $prop_prefix);
-
 
308
		if (!$id) return 2;
-
 
309
		if ($this->TripleExists($resource, $property, $newvalue, $re_prefix, $prop_prefix))
-
 
310
		{
-
 
311
			return 3;
-
 
312
		}
-
 
313
		$sql = 'UPDATE ' . $this->GetConfigValue('table_prefix') . 'triples '
-
 
314
			. 'SET value = "' . addslashes($newvalue) . '" '
-
 
315
			. 'WHERE id = ' . $id;
-
 
316
		return $this->Query($sql) ? 0 : 1;
-
 
317
	}
-
 
318
 
-
 
319
	/**
-
 
320
	 * Deletes a triple ($resource, $property, $value) from the triples' table
-
 
321
	 * @param string $resource The resource of the triple to delete
-
 
322
	 * @param string $property The property of the triple to delete
-
 
323
	 * @param string $value The value of the triple to delete. If set to <tt>null</tt>,
-
 
324
	 * deletes all the triples corresponding to ($resource, $property). (defaults to <tt>null</tt>)
-
 
325
	 * @param string $re_prefix The prefix to add to $resource (defaults to <tt>THISWIKI_PREFIX</tt>)
-
 
326
	 * @param string $prop_prefix The prefix to add to $property (defaults to <tt>WIKINI_VOC_PREFIX</tt>)
-
 
327
	 */
-
 
328
	function DeleteTriple($resource, $property, $value = null, $re_prefix = THISWIKI_PREFIX, $prop_prefix = WIKINI_VOC_PREFIX)
-
 
329
	{
-
 
330
		$sql = 'DELETE FROM ' . $this->GetConfigValue('table_prefix') . 'triples '
-
 
331
			. 'WHERE resource = "' . addslashes($re_prefix . $resource) . '" '
-
 
332
			. 'AND property = "' . addslashes($prop_prefix . $property) . '" ';
-
 
333
		if ($value !== null) $sql .= 'AND value = "' . addslashes($value) . '"';
-
 
334
		$this->Query($sql);
-
 
335
	}
-
 
336
 
-
 
337
	// inclusions
-
 
338
	/**
-
 
339
	 * Enr?gistre une nouvelle inclusion dans la pile d'inclusions.
-
 
340
	 * 
-
 
341
	 * @param string $pageTag Le nom de la page qui va ?tre inclue
-
 
342
	 * @return int Le nombre d'?l?ments dans la pile
-
 
343
	 */
-
 
344
	function RegisterInclusion($pageTag)
-
 
345
	{
-
 
346
		return array_unshift($this->inclusions, strtolower(trim($pageTag)));
-
 
347
	} 
-
 
348
	/**
-
 
349
	 * Retire le dernier ?l?ment de la pile d'inclusions.
-
 
350
	 * 
-
 
351
	 * @return string Le nom de la page dont l'inclusion devrait se terminer.
-
 
352
	 * null s'il n'y a plus d'inclusion dans la pile.
-
 
353
	 */
-
 
354
	function UnregisterLastInclusion()
-
 
355
	{
-
 
356
		return array_shift($this->inclusions);
-
 
357
	} 
-
 
358
	/**
-
 
359
	 * Renvoie le nom de la page en cours d'inclusion.
-
 
360
	 * 
-
 
361
	 * @example // dans le cas d'une action comme l'ActionEcrivezMoi
-
 
362
	 * if($inc = $this->CurrentInclusion() && strtolower($this->GetPageTag()) != $inc)
-
 
363
	 * 	echo 'Cette action ne peut ?tre appel?e depuis une page inclue';
-
 
364
	 * @return string Le nom (tag) de la page (en minuscules)
-
 
365
	 * false si la pile est vide.
-
 
366
	 */
-
 
367
	function GetCurrentInclusion()
-
 
368
	{
-
 
369
		return isset($this->inclusions[0]) ? $this->inclusions[0]: false ;
-
 
370
	} 
-
 
371
	/**
-
 
372
	 * V?rifie si on est ? l'int?rieur d'une inclusion par $pageTag (sans tenir compte de la casse)
-
 
373
	 * 
-
 
374
	 * @param string $pageTag Le nom de la page ? v?rifier
-
 
375
	 * @return bool True si on est ? l'int?rieur d'une inclusion par $pageTag (false sinon)
-
 
376
	 */
-
 
377
	function IsIncludedBy($pageTag)
-
 
378
	{
-
 
379
		return in_array(strtolower($pageTag), $this->inclusions);
-
 
380
	} 
-
 
381
	/**
-
 
382
	 * 
-
 
383
	 * @return array La pile d'inclusions
-
 
384
	 * L'?l?ment 0 sera la derni?re inclusion, l'?l?ment 1 sera son parent et ainsi de suite.
-
 
385
	 */
-
 
386
	function GetAllInclusions()
-
 
387
	{
-
 
388
		return $this->inclusions;
-
 
389
	} 
-
 
390
	/**
-
 
391
	 * Remplace la pile des inclusions par une nouvelle pile (par d?faut une pile vide)
-
 
392
	 * Permet de formatter une page sans tenir compte des inclusions pr?c?dentes.
-
 
393
	 * 
-
 
394
	 * @param array $ La nouvelle pile d'inclusions.
-
 
395
	 * L'?l?ment 0 doit repr?senter la derni?re inclusion, l'?l?ment 1 son parent et ainsi de suite.
-
 
396
	 * @return array L'ancienne pile d'inclusions, avec les noms des pages en minuscules.
-
 
397
	 */
-
 
398
	function SetInclusions($pile = array())
-
 
399
	{
-
 
400
		$temp = $this->inclusions;
-
 
401
		$this->inclusions = $pile;
161
 
402
		return $temp;
162
 
403
	} 
-
 
404
 
163
 
405
	// PAGES
164
	// PAGES
406
	function LoadPage($tag, $time = "", $cache = 1)
-
 
407
	{
-
 
408
		// retrieve from cache
-
 
409
		if (!$time && $cache && (($cachedPage = $this->GetCachedPage($tag)) !== false))
165
	function LoadPage($tag, $time = "", $cache = 1) {
410
		{
-
 
411
			$page = $cachedPage;
-
 
412
		}
-
 
413
		else // load page
166
		// retrieve from cache
414
		{
-
 
415
			$sql = "SELECT * FROM ".$this->config["table_prefix"]."pages"
167
		if (!$time && $cache && ($cachedPage = $this->GetCachedPage($tag))) { $page = $cachedPage;}
416
				. " WHERE tag = '".mysql_real_escape_string($tag)."' AND "
168
		// load page
417
				. ($time ? "time = '".mysql_real_escape_string($time)."'" : "latest = 'Y'") . " LIMIT 1";
-
 
418
			$page = $this->LoadSingle($sql);
169
		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");
419
			// cache result
170
		// cache result
420
			if (!$time) $this->CachePage($page, $tag);
-
 
421
		}
-
 
422
		return $page;
-
 
423
	}
-
 
424
	/**
-
 
425
	 * Retrieves the cached version of a page.
-
 
426
	 *
-
 
427
	 * Notice that this method null or false, use
-
 
428
	 * 	$this->GetCachedPage($tag) === false
-
 
429
	 * to check if a page is not in the cache.
-
 
430
	 * @return mixed The cached version of a page:
-
 
431
	 * 	- the page DB line if the page exists and is in cache
171
		if (!$time) $this->CachePage($page);
432
	 * 	- null if the cache knows that the page does not exists
-
 
433
	 * 	- false is the cache does not know the page
-
 
434
	 */
-
 
435
	function GetCachedPage($tag) {return (array_key_exists($tag, $this->pageCache) ? $this->pageCache[$tag] : false); }
-
 
436
	/**
-
 
437
	 * Caches a page's DB line.
-
 
438
	 *
172
		return $page;
439
	 * @param array $page The page (full) DB line or null if the page does not exists
-
 
440
	 * @param string $pageTag The tag of the page to cache. Defaults to $page['tag'] but is mendatory when $page === null
-
 
441
	 */
-
 
442
	function CachePage($page, $pageTag = null) {
-
 
443
		if ($pageTag === null)
-
 
444
		{
-
 
445
			$pageTag = $page["tag"];
173
	}
446
		}
174
	function GetCachedPage($tag) {return (isset($this->pageCache[$tag]) ? $this->pageCache[$tag] : ''); }
447
		$this->pageCache[$pageTag] = $page;
175
	function CachePage($page) { $this->pageCache[$page["tag"]] = $page; }
448
	}
176
	function SetPage($page) { $this->page = $page; if ($this->page["tag"]) $this->tag = $this->page["tag"]; }
449
	function SetPage($page) { $this->page = $page; if ($this->page["tag"]) $this->tag = $this->page["tag"]; }
177
	function LoadPageById($id) { return $this->LoadSingle("select * from ".$this->config["table_prefix"]."pages where id = '".mysql_escape_string($id)."' limit 1"); }
450
	function LoadPageById($id) { return $this->LoadSingle("select * from ".$this->config["table_prefix"]."pages where id = '".mysql_real_escape_string($id)."' limit 1"); }
-
 
451
	function LoadRevisions($page) { return $this->LoadAll("select * from ".$this->config["table_prefix"]."pages where tag = '".mysql_real_escape_string($page)."' order by time desc"); }
178
	function LoadRevisions($page) { return $this->LoadAll("select * from ".$this->config["table_prefix"]."pages where tag = '".mysql_escape_string($page)."' order by time desc"); }
452
	function LoadPagesLinkingTo($tag) { return $this->LoadAll("select from_tag as tag from ".$this->config["table_prefix"]."links where to_tag = '".mysql_real_escape_string($tag)."' order by tag"); }
179
	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"); }
453
	function LoadRecentlyChanged($limit=50)
180
	function LoadRecentlyChanged($limit=50) {
454
	{
181
		$limit= (int) $limit;
455
		$limit= (int) $limit;
182
		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"))
456
		if ($pages = $this->LoadAll("select id, tag, time, user, owner from ".$this->config["table_prefix"]."pages where latest = 'Y' and comment_on = '' order by time desc limit $limit"))
183
		{
457
		{
184
			foreach ($pages as $page)
458
			foreach ($pages as $page)
185
			{
459
			{
186
				$this->CachePage($page);
460
				$this->CachePage($page);
187
			}
461
			}
188
			return $pages;
462
			return $pages;
189
		}
463
		}
190
	}
464
	}
191
	function LoadAllPages() { return $this->LoadAll("select * from ".$this->config["table_prefix"]."pages where latest = 'Y' order by tag"); }
465
	function LoadAllPages() { return $this->LoadAll("select * from ".$this->config["table_prefix"]."pages where latest = 'Y' order by tag"); }
192
	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)."')"); }
466
	function FullTextSearch($phrase) { return $this->LoadAll("select * from ".$this->config["table_prefix"]."pages where latest = 'Y' and match(tag, body) against('".mysql_real_escape_string($phrase)."')"); }
193
	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"); }
467
	function LoadWantedPages() {
194
	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"); }
468
		$p = $this->config["table_prefix"];
195
	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)."'"); }
469
		$r = "SELECT ${p}links.to_tag AS tag, COUNT(${p}links.from_tag) AS count "
196
	function DeleteOrphanedPage($tag) {
-
 
197
		$this->Query("delete from ".$this->config["table_prefix"]."pages where tag='".mysql_escape_string($tag)."' ");
470
			. "FROM ${p}links LEFT JOIN ${p}pages ON ${p}links.to_tag = ${p}pages.tag "
198
		$this->Query("delete from ".$this->config["table_prefix"]."links where from_tag='".mysql_escape_string($tag)."' ");
471
			. "WHERE ${p}pages.tag IS NULL GROUP BY ${p}links.to_tag ORDER BY count DESC, tag ASC";
199
		$this->Query("delete from ".$this->config["table_prefix"]."acls where page_tag='".mysql_escape_string($tag)."' ");
472
		return $this->LoadAll($r);
200
		$this->Query("delete from ".$this->config["table_prefix"]."referrers where page_tag='".mysql_escape_string($tag)."' ");
-
 
201
	}
473
	}
-
 
474
	function LoadOrphanedPages() { return $this->LoadAll("select distinct tag from ".$this->config["table_prefix"]."pages as p left join ".$this->config["table_prefix"]."links as l on p.tag = l.to_tag where l.to_tag is NULL and p.comment_on = '' and p.latest = 'Y' order by tag"); }
202
	function SavePage($tag, $body, $comment_on = "") {
475
	function IsOrphanedPage($tag) { return $this->LoadAll("select distinct tag from ".$this->config['table_prefix']."pages as p left join ".$this->config['table_prefix']."links as l on p.tag = l.to_tag where l.to_tag is NULL and p.latest = 'Y' and tag = '".mysql_real_escape_string($tag)."'"); }
-
 
476
	function DeleteOrphanedPage($tag) {
-
 
477
		$p = $this->config["table_prefix"];
-
 
478
		$this->Query("DELETE FROM ${p}pages WHERE tag='".mysql_real_escape_string($tag)."' OR comment_on='".mysql_real_escape_string($tag)."'");
-
 
479
		$this->Query("DELETE FROM ${p}links WHERE from_tag='".mysql_real_escape_string($tag)."' ");
-
 
480
		$this->Query("DELETE FROM ${p}acls WHERE page_tag='".mysql_real_escape_string($tag)."' ");
-
 
481
		$this->Query("DELETE FROM ${p}referrers WHERE page_tag='".mysql_real_escape_string($tag)."' ");
-
 
482
	}
-
 
483
 
-
 
484
	/**
-
 
485
	 * SavePage
-
 
486
	 * Sauvegarde un contenu dans une page donn?e
-
 
487
	 *
-
 
488
	 * @param string $body Contenu ? sauvegarder dans la page
-
 
489
	 * @param string $tag Nom de la page
-
 
490
	 * @param string $comment_on Indication si c'est un commentaire
-
 
491
	 * @param boolean $bypass_acls Indication si on bypasse les droits d'?criture
-
 
492
	 * @return int Code d'erreur : 0 (succ?s), 1 (l'utilisateur n'a pas les droits)
-
 
493
	 */	
-
 
494
	function SavePage($tag, $body, $comment_on = "", $bypass_acls = false)
-
 
495
	{
203
		// get current user
496
		// get current user
204
		$user = $this->GetUserName();
497
		$user = $this->GetUserName();
205
 
498
 
-
 
499
		// check bypass of rights or write privilege
206
		//die($tag);
-
 
207
 
500
		$rights = $bypass_acls || ($comment_on ? $this->HasAccess("comment", $comment_on) : $this->HasAccess("write", $tag));
208
		// TODO: check write privilege
501
			
209
		if ($this->HasAccess("write", $tag))
502
		if ($rights)
210
		{
503
		{
211
			// is page new?
504
			// is page new?
212
			if (!$oldPage = $this->LoadPage($tag))
505
			if (!$oldPage = $this->LoadPage($tag))
213
			{
506
			{
214
				// create default write acl. store empty write ACL for comments.
507
				// create default write acl. store empty write ACL for comments.
215
				$this->SaveAcl($tag, "write", ($comment_on ? "" : $this->GetConfigValue("default_write_acl")));
508
				$this->SaveAcl($tag, "write", ($comment_on ? $user : $this->GetConfigValue("default_write_acl")));
216
 
509
 
217
				// create default read acl
510
				// create default read acl
218
				$this->SaveAcl($tag, "read", $this->GetConfigValue("default_read_acl"));
511
				$this->SaveAcl($tag, "read", $this->GetConfigValue("default_read_acl"));
219
 
512
 
220
				// create default comment acl.
513
				// create default comment acl.
221
				$this->SaveAcl($tag, "comment", $this->GetConfigValue("default_comment_acl"));
514
				$this->SaveAcl($tag, "comment", ($comment_on ? "" : $this->GetConfigValue("default_comment_acl")));
222
 
515
 
223
				// current user is owner; if user is logged in! otherwise, no owner.
516
				// current user is owner; if user is logged in! otherwise, no owner.
224
				if ($this->GetUser()) $owner = $user;
517
				if ($this->GetUser()) $owner = $user;
-
 
518
				else $owner = '';
225
			}
519
			}
226
			else
520
			else
227
			{
521
			{
228
				// aha! page isn't new. keep owner!
522
				// aha! page isn't new. keep owner!
229
				$owner = $oldPage["owner"];
523
				$owner = $oldPage["owner"];
-
 
524
 
-
 
525
				// ...and comment_on, eventualy?
-
 
526
				if ($comment_on == '') $comment_on = $oldPage['comment_on'];
230
			}
527
			}
231
 
528
 
232
 
529
 
233
			// set all other revisions to old
530
			// set all other revisions to old
234
			$this->Query("update ".$this->config["table_prefix"]."pages set latest = 'N' where tag = '".mysql_Escape_string($tag)."'");
531
			$this->Query("update ".$this->config["table_prefix"]."pages set latest = 'N' where tag = '".mysql_real_escape_string($tag)."'");
235
 
532
 
236
			// add new revision
533
			// add new revision
237
			$this->Query("insert into ".$this->config["table_prefix"]."pages set ".
534
			$this->Query("insert into ".$this->config["table_prefix"]."pages set ".
238
				"tag = '".mysql_escape_string($tag)."', ".
535
				"tag = '".mysql_real_escape_string($tag)."', ".
239
				($comment_on ? "comment_on = '".mysql_escape_string($comment_on)."', " : "").
536
				($comment_on ? "comment_on = '".mysql_real_escape_string($comment_on)."', " : "").
240
				"time = now(), ".
537
				"time = now(), ".
241
				"owner = '".mysql_escape_string($owner)."', ".
538
				"owner = '".mysql_real_escape_string($owner)."', ".
242
				"user = '".mysql_escape_string($user)."', ".
539
				"user = '".mysql_real_escape_string($user)."', ".
243
				"latest = 'Y', ".
540
				"latest = 'Y', ".
244
				"body = '".mysql_escape_string(chop($body))."'");
541
				"body = '".mysql_real_escape_string(chop($body))."'");
-
 
542
 
-
 
543
			unset($this->pageCache[$tag]);
-
 
544
			return 0;
245
		}
545
		}
-
 
546
		else return 1;
246
	}
547
	}
-
 
548
 
-
 
549
	
-
 
550
	/**
-
 
551
	 * AppendContentToPage
-
 
552
	 * Ajoute du contenu ? la fin d'une page
-
 
553
	 *
-
 
554
	 * @param string $content Contenu ? ajouter ? la page
-
 
555
	 * @param string $page Nom de la page
-
 
556
	 * @param boolean $bypass_acls Boul?en pour savoir s'il faut bypasser les ACLs
-
 
557
	 * @return int Code d'erreur : 0 (succ?s), 1 (pas de contenu sp?cifi?)
-
 
558
	 */
-
 
559
	function AppendContentToPage($content, $page, $bypass_acls = false)
-
 
560
	{
-
 
561
		// Si un contenu est sp?cifi?
-
 
562
		if (isset($content))
-
 
563
		{
-
 
564
			// -- D?termine quelle est la page :
-
 
565
			//    -- pass?e en param?tre (que se passe-t'il si elle n'existe pas ?)
-
 
566
			//    -- ou la page en cours par d?faut
-
 
567
			$page = isset($page) ? $page : $this->GetPageTag();
-
 
568
 
-
 
569
			// -- Chargement de la page
-
 
570
			$result = $this->LoadPage($page);
-
 
571
			$body = $result['body'];
-
 
572
			// -- Ajout du contenu ? la fin de la page
-
 
573
			$body .= $content;
-
 
574
 
-
 
575
			// -- Sauvegarde de la page
-
 
576
			// TODO : que se passe-t-il si la page est pleine ou si l'utilisateur n'a pas les droits ?
-
 
577
			$this->SavePage($page, $body, "", $bypass_acls);
-
 
578
			
-
 
579
			// now we render it internally so we can write the updated link table.
-
 
580
			$this->ClearLinkTable();
-
 
581
			$this->StartLinkTracking();
-
 
582
			$temp = $this->SetInclusions();
-
 
583
			$this->RegisterInclusion($this->GetPageTag()); // on simule totalement un affichage normal
-
 
584
			$this->Format($body);
-
 
585
			$this->SetInclusions($temp);
-
 
586
			if($user = $this->GetUser())
-
 
587
			{
-
 
588
				$this->TrackLinkTo($user['name']);
-
 
589
			}
-
 
590
			if($owner = $this->GetPageOwner())
-
 
591
			{
-
 
592
				$this->TrackLinkTo($owner);
-
 
593
			}
-
 
594
			$this->StopLinkTracking();
-
 
595
			$this->WriteLinkTable();
-
 
596
			$this->ClearLinkTable();/**/
-
 
597
 
-
 
598
			// Retourne 0 seulement si tout c'est bien pass?
-
 
599
			return 0;
-
 
600
		}
-
 
601
		else return 1;
-
 
602
	}
-
 
603
	
-
 
604
	/**
-
 
605
	 * LogAdministrativeAction($user, $content, $page = "")
-
 
606
	 * 
-
 
607
	 * @param string $user Utilisateur
-
 
608
	 * @param string $content Contenu de l'enregistrement
-
 
609
	 * @param string $page Page de log
-
 
610
	 * 
-
 
611
	 * @return int Code d'erreur : 0 (succ?s), 1 (pas de contenu sp?cifi?)
-
 
612
	 */
-
 
613
	function LogAdministrativeAction($user, $content, $page = "")
-
 
614
	{
-
 
615
		$order   = array("\r\n", "\n", "\r");
-
 
616
		$replace = '\\n';
-
 
617
		$content = str_replace($order, $replace, $content);
-
 
618
		$contentToAppend = "\n" . date("Y-m-d H:i:s") . " . . . . " . $user . " . . . . " . $content . "\n";
-
 
619
		$page = $page ? $page : "LogDesActionsAdministratives" . date("Ymd");
-
 
620
		return $this->AppendContentToPage($contentToAppend, $page, true);
-
 
621
	}
-
 
622
 
-
 
623
	
-
 
624
	/**
-
 
625
	 * Make the purge of page versions that are older than the last version older than 3 "pages_purge_time"
-
 
626
	 * This method permits to allways keep a version that is older than that period.
-
 
627
	 */
247
	function PurgePages() {
628
	function PurgePages() {
248
		if ($days = $this->GetConfigValue("pages_purge_time")) {
629
		if ($days = $this->GetConfigValue("pages_purge_time")) { // is purge active ?
249
			// Selection of pages which can be deleted 
630
			// let's search which pages versions we have to remove
-
 
631
			// this is necessary beacause even MySQL does not handel multi-tables deletes before version 4.0
-
 
632
			$wnPages = $this->GetConfigValue('table_prefix') . 'pages';
250
			$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");
633
			$sql = 'SELECT DISTINCT a.id FROM ' . $wnPages . ' a,' . $wnPages . ' b WHERE a.latest = \'N\' AND a.time < date_sub(now(), INTERVAL \'' . addslashes($days) . '\' DAY) AND a.tag = b.tag AND a.time < b.time AND b.time < date_sub(now(), INTERVAL \'' . addslashes($days) . '\' DAY)';
251
			foreach ($pages as $page) {
634
			$ids = $this->LoadAll($sql);
-
 
635
 
252
				// Deletion if there are more than 2 versions avalaible (TODO : parameter ?)
636
			if (count($ids)) { // there are some versions to remove from DB
253
				$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");
637
				// let's build one big request, that's better...
-
 
638
				$sql = 'DELETE FROM ' . $wnPages . ' WHERE id IN (';
254
				foreach ($tags as $tag) {
639
				foreach($ids as $key => $line){
255
					$this->Query("delete from ".$this->config["table_prefix"]."pages where time = '".mysql_escape_string($page[time])."' and tag = '".mysql_escape_string($tag[tag])."'");
640
					$sql .= ($key ? ', ':'') . $line['id']; // NB.: id is an int, no need of quotes
256
				}
641
				}
-
 
642
				$sql .= ')';
-
 
643
 
-
 
644
				// ... and send it !
-
 
645
				$this->Query($sql);
257
			}
646
			}
258
		}
647
		}
259
	}
648
	}
260
 
649
 
261
 
650
 
262
 
651
 
263
	// COOKIES
652
	// COOKIES
-
 
653
	function SetSessionCookie($name, $value)
-
 
654
	{
-
 
655
		SetCookie($name, $value, 0, $this->CookiePath);
-
 
656
		$_COOKIE[$name] = $value;
-
 
657
	}
264
	function SetSessionCookie($name, $value) { SetCookie($name, $value, 0, $this->CookiePath); $_COOKIE[$name] = $value; }
658
	function SetPersistentCookie($name, $value, $remember = 0)
-
 
659
	{
265
	function SetPersistentCookie($name, $value, $remember = 0) { SetCookie($name, $value, time() + ($remember ? 90*24*60*60 : 60 * 60), $this->CookiePath); $_COOKIE[$name] = $value; }
660
		SetCookie($name, $value, time() + ($remember ? 90*24*60*60 : 60 * 60), $this->CookiePath);
-
 
661
		$_COOKIE[$name] = $value;
-
 
662
	}
-
 
663
	function DeleteCookie($name)
-
 
664
	{
266
	function DeleteCookie($name) { SetCookie($name, "", 1, $this->CookiePath); $_COOKIE[$name] = ""; }
665
		SetCookie($name, "", 1, $this->CookiePath);
-
 
666
		$_COOKIE[$name] = "";
-
 
667
	}
267
	function GetCookie($name) { return $_COOKIE[$name]; }
668
	function GetCookie($name) { return $_COOKIE[$name]; }
268
 
669
 
269
 
670
 
270
 
671
 
271
	// HTTP/REQUEST/LINK RELATED
672
	// HTTP/REQUEST/LINK RELATED
272
	function SetMessage($message) { $_SESSION["message"] = $message; }
673
	function SetMessage($message) { $_SESSION["message"] = $message; }
273
	function GetMessage()
674
	function GetMessage()
274
	{
675
	{
275
		if (isset($_SESSION["message"])) $message = $_SESSION["message"];
676
		if (isset($_SESSION["message"])) $message = $_SESSION["message"];
276
		else $message = "";
677
		else $message = "";
277
		$_SESSION["message"] = "";
678
		$_SESSION["message"] = "";
278
		return $message;
679
		return $message;
279
	}
680
	}
280
	function Redirect($url)
681
	function Redirect($url)
281
	{
682
	{
282
		header("Location: $url");
683
		header("Location: $url");
283
		exit;
684
		exit;
284
	}
685
	}
285
	// returns just PageName[/method].
686
	// returns just PageName[/method].
286
	function MiniHref($method = "", $tag = "")
687
	function MiniHref($method = "", $tag = "")
287
	{
688
	{
288
		if (!$tag = trim($tag)) $tag = $this->tag;
689
		if (!$tag = trim($tag)) $tag = $this->tag;
289
		return $tag.($method ? "/".$method : "");
690
		return $tag.($method ? "/".$method : "");
290
	}
691
	}
291
	// returns the full url to a page/method.
692
	// returns the full url to a page/method.
292
	function Href($method = "", $tag = "", $params = "")
693
	function Href($method = "", $tag = "", $params = "", $htmlspchars = true)
293
	{
694
	{
294
		$href = $this->config["base_url"].$this->MiniHref($method, $tag);
695
		$href = $this->config["base_url"].$this->MiniHref($method, $tag);
295
		if ($params)
696
		if ($params)
296
		{
697
		{
297
			$href .= ($this->config["rewrite_mode"] ? "?" : "&amp;").$params;
698
			$href .= ($this->config["rewrite_mode"] ? "?" : ($htmlspchars ? "&amp;" : '&')).$params;
298
		}
699
		}
299
		return $href;
700
		return $href;
300
	}
701
	}
301
	function Link($tag, $method = "", $text = "", $track = 1) {
702
	function Link($tag, $method = "", $text = "", $track = 1)
302
		$tag=htmlspecialchars($tag); //avoid xss
-
 
303
		$text=htmlspecialchars($text); //paranoiac again
-
 
-
 
703
	{
304
		if (!$text) $text = $tag;
704
		$displayText = $text ? $text : $tag;
305
 
-
 
306
		// is this an interwiki link?
705
		// is this an interwiki link?
307
		if (preg_match("/^([A-Z][A-Z,a-z]+)[:]([A-Z,a-z,0-9]*)$/s", $tag, $matches))
706
		if (preg_match('/^' . WN_INTERWIKI_CAPTURE . '$/', $tag, $matches))
308
		{
707
		{
309
			$tag = $this->GetInterWikiUrl($matches[1], $matches[2]);
708
			if ($tagInterWiki = $this->GetInterWikiUrl($matches[1], $matches[2])) {
310
			return "<a href=\"$tag\">$text (interwiki)</a>";
709
				return '<a href="'.htmlspecialchars($tagInterWiki).'">'
-
 
710
					.htmlspecialchars($displayText).' (interwiki)</a>';
-
 
711
			}
-
 
712
			else return '<a href="'.htmlspecialchars($tag).'">'
-
 
713
				.htmlspecialchars($displayText).' (interwiki inconnu)</a>';
311
		}
714
		}
312
		// is this a full link? ie, does it contain non alpha-numeric characters?
715
		// is this a full link? ie, does it contain non alpha-numeric characters?
313
		// Note : [:alnum:] is equivalent [0-9A-Za-z]
716
		// Note : [:alnum:] is equivalent [0-9A-Za-z]
314
		//        [^[:alnum:]] means : some caracters other than [0-9A-Za-z]
717
		//		  [^[:alnum:]] means : some caracters other than [0-9A-Za-z]
315
		// For example : "www.adress.com", "mailto:adress@domain.com", "http://www.adress.com"
718
		// For example : "www.adress.com", "mailto:adress@domain.com", "http://www.adress.com"
316
		else if (preg_match("/[^[:alnum:]]/", $tag))
719
		else if (preg_match("/[^[:alnum:]]/", $tag))
317
		{
720
		{
318
			// check for email addresses
721
			// check for various modifications to perform on $tag
319
			if (preg_match("/^.+\@.+$/", $tag))
722
			if (preg_match("/^[\w.-]+\@[\w.-]+$/", $tag))
-
 
723
			{ // email addresses
-
 
724
				$tag = 'mailto:'.$tag;
320
			{
725
			}
-
 
726
			// Note : in Perl regexp, (?: ... ) is a non-catching cluster
-
 
727
			else if (preg_match('/^[[:alnum:]][[:alnum:].-]*(?:\/|$)/', $tag))
-
 
728
			{ // protocol-less URLs
321
				$tag = "mailto:".$tag;
729
				$tag = 'http://'.$tag;
-
 
730
			}
-
 
731
			// Finally, block script schemes (see RFC 3986 about
-
 
732
			// schemes) and allow relative link & protocol-full URLs
-
 
733
			else if (preg_match('/^[a-z0-9.+-]*script[a-z0-9.+-]*:/i', $tag)
-
 
734
				|| !(preg_match('/^\.?\.?\//', $tag)
-
 
735
					|| preg_match('/^[a-z0-9.+-]+:\/\//i', $tag)))
-
 
736
			{
-
 
737
				// If does't fit, we can't qualify $tag as an URL.
-
 
738
				// There is a high risk that $tag is just XSS (bad
-
 
739
				// javascript: code) or anything nasty. So we must not
-
 
740
				// produce any link at all.
-
 
741
				return htmlspecialchars($tag.($text ? ' '.$text : ''));
322
			}
742
			}
323
			// check for protocol-less URLs
743
			// Important: Here, we know that $tag is not something bad
324
			else if (!preg_match("/:\/\//", $tag))
744
			// and that we must produce a link with it
325
			{
-
 
326
				$tag = "http://".$tag;	//Very important for xss (avoid javascript:() hacking)
-
 
327
			}
745
 
328
			// is this an inline image (text!=tag and url ends png,gif,jpeg)
746
			// An inline image? (text!=tag and url ends by png,gif,jpeg)
329
			if ($text!=$tag and preg_match("/.(gif|jpeg|png|jpg)$/i",$tag))
747
			if ($text and preg_match("/\.(gif|jpeg|png|jpg)$/i",$tag))
330
			{
748
			{
331
				return "<img src=\"$tag\" alt=\"$text\" />";
749
				return '<img src="'.htmlspecialchars($tag)
-
 
750
					.'" alt="'.htmlspecialchars($displayText).'"/>';
332
			}
751
			}
333
			else
752
			else
334
			{
753
			{
-
 
754
				// Even if we know $tag is harmless, we MUST encode it
-
 
755
				// in HTML with htmlspecialchars() before echoing it.
-
 
756
				// This is not about being paranoiac. This is about
-
 
757
				// being compliant to the HTML standard.
335
				return "<a href=\"$tag\">$text</a>";
758
				return '<a href="'.htmlspecialchars($tag).'">'
-
 
759
					.htmlspecialchars($displayText).'</a>';
336
			}
760
			}
337
		}
761
		}
338
		else
762
		else
339
		{
763
		{
340
			// it's a Wiki link!
764
			// it's a Wiki link!
341
			if (isset($_SESSION["linktracking"]) && $track) $this->TrackLinkTo($tag);
765
			if (!empty($track)) $this->TrackLinkTo($tag);
-
 
766
			if ($this->LoadPage($tag))
-
 
767
				return '<a href="'.htmlspecialchars($this->href($method, $tag)).'">'
-
 
768
					.htmlspecialchars($displayText).'</a>';
-
 
769
			else
-
 
770
				return '<span class="missingpage">'.htmlspecialchars($displayText)
342
			return ($this->LoadPage($tag) ? "<a href=\"".$this->href($method, $tag)."\">".$text."</a>" : "<span class=\"missingpage\">".$text."</span><a href=\"".$this->href("edit", $tag)."\">?</a>");
771
				.'</span><a href="'.htmlspecialchars($this->href("edit", $tag)).'">?</a>';
343
		}
772
		}
344
	}
773
	}
345
	function ComposeLinkToPage($tag, $method = "", $text = "", $track = 1) {
774
	function ComposeLinkToPage($tag, $method = "", $text = "", $track = 1) {
346
		if (!$text) $text = $tag;
775
		if (!$text) $text = $tag;
347
		$text = htmlentities($text);
776
		$text = htmlspecialchars($text);
348
		if (isset($_SESSION["linktracking"]) && $track)
777
		if ($track)
349
			$this->TrackLinkTo($tag);
778
			$this->TrackLinkTo($tag);
350
		return '<a href="'.$this->href($method, $tag).'">'.$text.'</a>';
779
		return '<a href="'.$this->href($method, $tag).'">'.$text.'</a>';
351
	}
780
	}
-
 
781
	function IsWikiName($text) {
352
	// function PregPageLink($matches) { return $this->Link($matches[1]); }
782
		return preg_match('/^' . WN_CAMEL_CASE . '$/', $text);
-
 
783
	}
-
 
784
 
-
 
785
	// LinkTracking management
-
 
786
	/**
353
	function IsWikiName($text) { return preg_match("/^[A-Z][a-z]+[A-Z,0-9][A-Z,a-z,0-9]*$/", $text); }
787
	 * Tracks the link to a given page (only if the LinkTracking is activated)
-
 
788
	 * @param string $tag The tag (name) of the page to track a link to.
-
 
789
	 */
-
 
790
	function TrackLinkTo($tag) {
354
	function TrackLinkTo($tag) { $_SESSION["linktable"][] = $tag; }
791
		if ($this->LinkTracking()) $this->linktable[] = $tag;
-
 
792
	}
-
 
793
	/**
-
 
794
	 * @return array The current link tracking table
-
 
795
	 */
355
	function GetLinkTable() { return $_SESSION["linktable"]; }
796
	function GetLinkTable() { return $this->linktable; }
-
 
797
	/**
-
 
798
	 * Clears the link tracking table
-
 
799
	 */
356
	function ClearLinkTable() { $_SESSION["linktable"] = array(); }
800
	function ClearLinkTable() { $this->linktable = array(); }
-
 
801
	/**
-
 
802
	 * Starts the LinkTracking
-
 
803
	 * @return bool The previous state of the link tracking
-
 
804
	 */
357
	function StartLinkTracking() { $_SESSION["linktracking"] = 1; }
805
	function StartLinkTracking() {
-
 
806
		return $this->LinkTracking(true);
-
 
807
	}
-
 
808
	/**
-
 
809
	 * Stops the LinkTracking
-
 
810
	 * @return bool The previous state of the link tracking
-
 
811
	 */
-
 
812
	function StopLinkTracking() {
-
 
813
		return $this->LinkTracking(false);
-
 
814
	}
-
 
815
	/**
-
 
816
	 * Sets and/or retrieve the state of the LinkTracking
-
 
817
	 * @param bool $newStatus The new status of the LinkTracking
-
 
818
	 * (defaults to <tt>null</tt> which lets it unchanged)
-
 
819
	 * @return bool The previous state of the link tracking
-
 
820
	 */
358
	function StopLinkTracking() { $_SESSION["linktracking"] = 0; }
821
	function LinkTracking($newStatus = null)
-
 
822
	{
-
 
823
		$old = $this->isTrackingLinks;
-
 
824
		if ($newStatus !== null) $this->isTrackingLinks = $newStatus;
-
 
825
		return $old;
-
 
826
	}
359
	function WriteLinkTable() {
827
	function WriteLinkTable() {
360
		// delete old link table
828
		// delete old link table
361
		$this->Query("delete from ".$this->config["table_prefix"]."links where from_tag = '".mysql_escape_string($this->GetPageTag())."'");
829
		$this->Query("delete from ".$this->config["table_prefix"]."links where from_tag = '".mysql_real_escape_string($this->GetPageTag())."'");
362
		if ($linktable = $this->GetLinkTable())
830
		if ($linktable = $this->GetLinkTable())
363
		{
831
		{
364
			$from_tag = mysql_escape_string($this->GetPageTag());
832
			$from_tag = mysql_real_escape_string($this->GetPageTag());
365
			foreach ($linktable as $to_tag)
833
			foreach ($linktable as $to_tag)
366
			{
834
			{
367
				$lower_to_tag = strtolower($to_tag);
835
				$lower_to_tag = strtolower($to_tag);
368
				if (!$written[$lower_to_tag])
836
				if (!isset($written[$lower_to_tag]))
369
				{
837
				{
370
					$this->Query("insert into ".$this->config["table_prefix"]."links set from_tag = '".$from_tag."', to_tag = '".mysql_escape_string($to_tag)."'");
838
					$this->Query("insert into ".$this->config["table_prefix"]."links set from_tag = '".$from_tag."', to_tag = '".mysql_real_escape_string($to_tag)."'");
371
					$written[$lower_to_tag] = 1;
839
					$written[$lower_to_tag] = 1;
372
				}
840
				}
373
			}
841
			}
374
		}
842
		}
375
	}
843
	}
376
	function Header() { return $this->Action($this->GetConfigValue("header_action"), 1); }
-
 
377
	function Footer() { return $this->Action($this->GetConfigValue("footer_action"), 1); }
-
 
-
 
844
 
-
 
845
	function Header() {
-
 
846
		$action = $this->GetConfigValue("header_action");
-
 
847
		if (($actionObj = &$this->GetActionObject($action)) && is_object($actionObj))
-
 
848
		{
-
 
849
			return $actionObj->GenerateHeader();
-
 
850
		}
-
 
851
		return $this->Action($action, 1);
-
 
852
	}
-
 
853
 
-
 
854
	function Footer() {
-
 
855
		$action = $this->GetConfigValue("footer_action");
-
 
856
		if (($actionObj = &$this->GetActionObject($action)) && is_object($actionObj))
-
 
857
		{
-
 
858
			return $actionObj->GenerateFooter();
-
 
859
		}
378
 
860
		return $this->Action($action, 1);
379
 
861
	}
380
 
862
 
381
	// FORMS
863
	// FORMS
382
	function FormOpen($method = "", $tag = "", $formMethod = "post") {
864
	function FormOpen($method = "", $tag = "", $formMethod = "post") {
383
	/* Debut de la modif ACeditor */
-
 
384
	// ACEditor: id=\"ACEditor\" name=\"ACEditor\" ci-dessous le if a été ajouté (initialement, seule la ligne du else existait)
-
 
385
	// si l'url se termine par edit (expression régulière edit$), on est en mode édition et dans ce cas on donne les id et name au formulaire
-
 
386
	// Sinon surtout pas car ça marche plus dans la mesure ou plusieurs formulaires auraient ces ID et name et dans ce cas
-
 
387
	// il semble que le dernier soit considéré, c'est à dire pas le bon :o(
-
 
388
 
-
 
389
		if (ereg('edit$', $this->href($method, $tag))) {
-
 
390
			$result = "<form id=\"ACEditor\" name=\"ACEditor\" action=\"".$this->href($method, $tag)."\" method=\"".$formMethod."\">\n";
-
 
391
		} else {
-
 
392
		$result = "<form action=\"".$this->href($method, $tag)."\" method=\"".$formMethod."\">\n";
865
		$result = "<form action=\"".$this->href($method, $tag)."\" method=\"".$formMethod."\">\n";
393
		}
-
 
394
 
-
 
395
/* fin de la modif ACeditor */
-
 
396
		if (!$this->config["rewrite_mode"]) $result .= "<input type=\"hidden\" name=\"wiki\" value=\"".$this->MiniHref($method, $tag)."\" />\n";
866
		if (!$this->config["rewrite_mode"]) $result .= "<input type=\"hidden\" name=\"wiki\" value=\"".$this->MiniHref($method, $tag)."\" />\n";
397
		return $result;
867
		return $result;
398
	}
868
	}
399
	function FormClose() {
869
	function FormClose() {
400
		return "</form>\n";
870
		return "</form>\n";
401
	}
871
	}
402
 
872
 
403
 
873
 
404
 
874
 
405
	// INTERWIKI STUFF
875
	// INTERWIKI STUFF
406
	function ReadInterWikiConfig() {
876
	function ReadInterWikiConfig() {
407
		if ($lines = file("interwiki.conf"))
877
		if ($lines = file("interwiki.conf"))
408
		{
878
		{
409
			foreach ($lines as $line)
879
			foreach ($lines as $line)
410
			{
880
			{
411
				if ($line = trim($line))
881
				if ($line = trim($line))
412
				{
882
				{
413
					list($wikiName, $wikiUrl) = explode(" ", trim($line));
883
					list($wikiName, $wikiUrl) = explode(" ", trim($line));
414
					$this->AddInterWiki($wikiName, $wikiUrl);
884
					$this->AddInterWiki($wikiName, $wikiUrl);
415
				}
885
				}
416
			}
886
			}
417
		}
887
		}
418
	}
888
	}
419
	function AddInterWiki($name, $url) {
889
	function AddInterWiki($name, $url) {
420
		$this->interWiki[$name] = $url;
890
		$this->interWiki[strtolower($name)] = $url;
421
	}
891
	}
422
	function GetInterWikiUrl($name, $tag) {
892
	function GetInterWikiUrl($name, $tag)
423
		if (isset($this->interWiki[$name]))
-
 
424
		{
893
	{
425
			return $this->interWiki[$name].$tag;
894
		if (isset($this->interWiki[strtolower($name)])) return $this->interWiki[strtolower($name)].$tag;
426
		} else {
895
		else return FALSE;
427
		return 'http://'.$tag; //avoid xss by putting http:// in front of JavaScript:()
-
 
428
		}
-
 
429
	}
896
	}
430
 
897
 
431
 
898
 
432
 
899
 
433
	// REFERRERS
900
	// REFERRERS
434
	function LogReferrer($tag = "", $referrer = "") {
901
	function LogReferrer($tag = "", $referrer = "") {
435
		// fill values
902
		// fill values
436
		if (!$tag = trim($tag)) $tag = $this->GetPageTag();
903
		if (!$tag = trim($tag)) $tag = $this->GetPageTag();
437
		if (!$referrer = trim($referrer) AND isset($_SERVER["HTTP_REFERER"])) $referrer = $_SERVER["HTTP_REFERER"];
904
		if (!$referrer = trim($referrer) AND isset($_SERVER["HTTP_REFERER"])) $referrer = $_SERVER["HTTP_REFERER"];
438
		
905
 
439
		// check if it's coming from another site
906
		// check if it's coming from another site
440
		if ($referrer && !preg_match("/^".preg_quote($this->GetConfigValue("base_url"), "/")."/", $referrer))
907
		if ($referrer && !preg_match("/^".preg_quote($this->GetConfigValue("base_url"), "/")."/", $referrer))
441
		{
908
		{
-
 
909
			// avoid XSS (with urls like "javascript:alert()" and co)
-
 
910
			// by forcing http/https prefix
-
 
911
			// NB.: this does NOT exempt to htmlspecialchars() the collected URIs !
-
 
912
			if (!preg_match('`^https?://`', $referrer)) return;
-
 
913
 
442
			$this->Query("insert into ".$this->config["table_prefix"]."referrers set ".
914
			$this->Query("insert into ".$this->config["table_prefix"]."referrers set ".
443
				"page_tag = '".mysql_escape_string($tag)."', ".
915
				"page_tag = '".mysql_real_escape_string($tag)."', ".
444
				"referrer = '".mysql_escape_string($referrer)."', ".
916
				"referrer = '".mysql_real_escape_string($referrer)."', ".
445
				"time = now()");
917
				"time = now()");
446
		}
918
		}
447
	}
919
	}
448
	function LoadReferrers($tag = "") {
920
	function LoadReferrers($tag = "") {
449
		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");
921
		return $this->LoadAll("select referrer, count(referrer) as num from ".$this->config["table_prefix"]."referrers ".($tag = trim($tag) ? "where page_tag = '".mysql_real_escape_string($tag)."'" : "")." group by referrer order by num desc");
450
	}
922
	}
451
	function PurgeReferrers() {
923
	function PurgeReferrers() {
452
		if ($days = $this->GetConfigValue("referrers_purge_time")) {
924
		if ($days = $this->GetConfigValue("referrers_purge_time")) {
453
			$this->Query("delete from ".$this->config["table_prefix"]."referrers where time < date_sub(now(), interval '".mysql_escape_string($days)."' day)");
925
			$this->Query("delete from ".$this->config["table_prefix"]."referrers where time < date_sub(now(), interval '".mysql_real_escape_string($days)."' day)");
454
		}
926
		}
455
	}
927
	}
456
 
928
 
457
 
929
 
458
 
930
 
459
	// PLUGINS
931
	// PLUGINS
460
	function Action($action, $forceLinkTracking = 0)
-
 
461
	{
932
	/**
-
 
933
	 * Exacutes an "action" module and returns the generated output
-
 
934
	 * @param string $action The name of the action and its eventual parameters,
462
		$action = trim($action); $vars=array();
935
	 * as it appears in the page between "{{" and "}}"
-
 
936
	 * @param boolean $forceLinkTracking By default, the link tracking will be disabled
-
 
937
	 * during the call of an action. Set this value to <code>true</code> to allow it.
-
 
938
	 * @param array $vars An array of additionnal parameters to give to the action, in the form
463
		// stupid attributes check
939
	 * array( 'param' => 'value').
-
 
940
	 * This allows you to call Action() internally, setting $action to the name of the action
-
 
941
	 * you want to call and it's parameters in an array, wich is more efficient than
-
 
942
	 * the pattern-matching algorithm used to extract the parameters from $action.
-
 
943
	 * @return The output generated by the action.
-
 
944
	 */
464
		if ((stristr($action, "=\"")) || (stristr($action, "/")))
945
	function Action($action, $forceLinkTracking = 0, $vars = array())
465
		{
946
	{
-
 
947
		$cmd = trim($action);
466
			// extract $action and $vars_temp ("raw" attributes)
948
		// extract $action and $vars_temp ("raw" attributes)
467
			preg_match("/^([A-Za-z0-9]*)\/?(.*)$/", $action, $matches);
949
		if (!preg_match("/^([a-zA-Z-0-9]+)\/?(.*)$/", $cmd, $matches))
-
 
950
		{
-
 
951
			return '<i>Action invalide &quot;' . htmlspecialchars($cmd) . '&quot;</i>';
-
 
952
		}
468
			list(, $action, $vars_temp) = $matches;
953
		list(, $action, $vars_temp) = $matches;
469
			// match all attributes (key and value)
954
		$vars[$vars_temp] = $vars_temp; // usefull for {{action/vars_temp}}
-
 
955
 
-
 
956
		// now that we have the action's name, we can check if the user satisfies the ACLs
470
			$this->parameter[$vars_temp]=$vars_temp;
957
		if (!$this->CheckModuleACL($action, 'action'))
-
 
958
		{
471
			preg_match_all("/([A-Za-z0-9]*)=\"(.*)\"/U", $vars_temp, $matches);
959
			return 'Erreur: vous n\'avez pas acc&egrave;s &agrave; l\'action ' . $action . '.';
-
 
960
		}
-
 
961
 
472
 
962
		// match all attributes (key and value)
473
		// prepare an array for extract() to work with (in $this->IncludeBuffered())
963
		// prepare an array for extract() to work with (in $this->IncludeBuffered())
474
		if (is_array($matches))
964
		if (preg_match_all("/([a-zA-Z0-9]*)=\"(.*)\"/U", $vars_temp, $matches))
475
			{
965
		{
476
				for ($a = 0; $a < count($matches[1]); $a++)
966
			for ($a = 0; $a < count($matches[1]); $a++)
477
				{
967
			{
478
					$vars[$matches[1][$a]] = $matches[2][$a];
968
				$vars[$matches[1][$a]] = $matches[2][$a];
479
					$this->parameter[$matches[1][$a]]=$matches[2][$a];
-
 
480
				}
-
 
481
			}
969
			}
482
		}
970
		}
-
 
971
 
483
		if (!$forceLinkTracking) $this->StopLinkTracking();
972
		if (!$forceLinkTracking) $this->StopLinkTracking();
-
 
973
		if ($actionObj = &$this->GetActionObject($action))
-
 
974
		{
-
 
975
			if (is_object($actionObj))
-
 
976
			{
484
		$result = $this->IncludeBuffered(strtolower($action).".php", "<i>Action inconnue \"$action\"</i>", $vars, $this->config["action_path"]);
977
				$result = $actionObj->PerformAction($vars, $cmd);
-
 
978
			}
-
 
979
			else // $actionObj is an error message
-
 
980
			{
485
		$this->StartLinkTracking();
981
				$result = $actionObj;
-
 
982
			}
-
 
983
		}
486
		if (isset($parameter)) unset($this->parameter[$parameter]);
984
		else // $actionObj == null (not found, no error message)
-
 
985
		{
-
 
986
			$this->parameter = &$vars;
-
 
987
			$result = $this->IncludeBuffered(strtolower($action).".php", "<i>Action inconnue &quot;$action&quot;</i>", $vars, $this->config["action_path"]);
487
		unset($this->parameter);
988
			unset($this->parameter);
-
 
989
		}
-
 
990
		$this->StartLinkTracking(); // shouldn't we restore the previous status ?
488
		return $result;
991
		return $result;
489
	}
992
	}
-
 
993
 
-
 
994
	/**
-
 
995
	 * Finds the object corresponding to an action, if it exists.
-
 
996
	 * @param string $name The name of an action (should be alphanumeric)
-
 
997
	 * @return mixed
-
 
998
	 * 	- null if the corresponding file was not found or the corresponding class didn't exist after inclusion
-
 
999
	 *  - an error string if the corresponding file was found but an error append while loading it
-
 
1000
	 *  - the object corresponding to this action if no problem happend
-
 
1001
	 * To check the result, you should use is_object() on it.
-
 
1002
	 * You should always assign the result of this method by referrence
-
 
1003
	 * to avoid copying the object, which is the default beheviour in PHP4.
-
 
1004
	 * @example
-
 
1005
	 * $var = &$wiki->GetActionObject('actionname');
-
 
1006
	 * if (is_object($var))
-
 
1007
	 * {
-
 
1008
	 * 		// normal behaviour
-
 
1009
	 * }
-
 
1010
	 * elseif ($var) // $var is not an object but an error string
-
 
1011
	 * {
-
 
1012
	 * 		// threat error
-
 
1013
	 * }
-
 
1014
	 * else // action was not found
-
 
1015
	 * {
-
 
1016
	 * 		// rescue from inexising action or sth
-
 
1017
	 * } 
-
 
1018
	 */
-
 
1019
	function &GetActionObject($name)
-
 
1020
	{
-
 
1021
		$name = strtolower($name);
-
 
1022
		$actionObj = null; // the generated object
-
 
1023
		if (!preg_match('/^[a-z0-9]+$/', $name)) // paranoiac
-
 
1024
		{
-
 
1025
			return $actionObj;
-
 
1026
		}
-
 
1027
 
-
 
1028
		// already tried to load this object ? (may be null)
-
 
1029
		if (isset($this->actionObjects[$name]))
-
 
1030
		{
-
 
1031
			return $this->actionObjects[$name];
-
 
1032
		}
-
 
1033
 
-
 
1034
		// object not loaded, try to load it
-
 
1035
		$filename = $name . '.class.php';
-
 
1036
		// load parent class for all action objects (only once)
-
 
1037
		require_once 'includes/action.class.php';
-
 
1038
		// include the action file, this should return an empty string
-
 
1039
		$result = $this->IncludeBuffered($filename, null, null, $this->GetConfigValue('action_path'));
-
 
1040
		if ($result) // the result was not an empty string, certainly an error message
-
 
1041
		{
-
 
1042
			$actionObj = $result;
-
 
1043
		}
-
 
1044
		elseif ($result !== false) // the result was empty but the file was found
-
 
1045
		{
-
 
1046
			$class = 'Action' . ucfirst($name);
-
 
1047
			if (class_exists($class))
-
 
1048
			{
-
 
1049
				$actionObj = new $class($this);
-
 
1050
				if (!is_a($actionObj, 'WikiniAction'))
-
 
1051
				{
-
 
1052
					die("Action invalide '$name': classe incorrecte");
-
 
1053
				}
-
 
1054
			}
-
 
1055
		}
-
 
1056
		$this->actionObjects[$name] = &$actionObj;
-
 
1057
		return $actionObj;
-
 
1058
	}
-
 
1059
 
-
 
1060
	/**
-
 
1061
	 * Retrieves the list of existing actions
-
 
1062
	 * @return array An unordered array of all the available actions.
-
 
1063
	 */
-
 
1064
	function GetActionsList()
-
 
1065
	{
-
 
1066
		$action_path = $this->GetConfigValue('action_path');
-
 
1067
		$list = array();
-
 
1068
		if ($dh = opendir($action_path))
-
 
1069
		{
-
 
1070
			while (($file = readdir($dh)) !== false)
-
 
1071
			{
-
 
1072
				if (preg_match('/^([a-zA-Z-0-9]+)(.class)?.php$/', $file, $matches))
-
 
1073
				{
-
 
1074
					$list[] = $matches[1];
-
 
1075
				}
-
 
1076
			}
-
 
1077
		}
-
 
1078
		return $list;
-
 
1079
	}
-
 
1080
 
-
 
1081
	/**
-
 
1082
	 * Retrieves the list of existing handlers
-
 
1083
	 * @return array An unordered array of all the available handlers.
-
 
1084
	 */
-
 
1085
	function GetHandlersList()
-
 
1086
	{
-
 
1087
		$handler_path = $this->GetConfigValue('handler_path') . '/page/';
-
 
1088
		$list = array();
-
 
1089
		if ($dh = opendir($handler_path))
-
 
1090
		{
-
 
1091
			while (($file = readdir($dh)) !== false)
-
 
1092
			{
-
 
1093
				if (preg_match('/^([a-zA-Z-0-9]+)(.class)?.php$/', $file, $matches))
-
 
1094
				{
-
 
1095
					$list[] = $matches[1];
-
 
1096
				}
-
 
1097
			}
-
 
1098
		}
-
 
1099
		return $list;
-
 
1100
	}
-
 
1101
 
490
	function Method($method) {
1102
	function Method($method) {
491
		if (!$handler = $this->page["handler"]) $handler = "page";
1103
		if (!$handler = $this->page["handler"]) $handler = "page";
492
		$methodLocation = $handler."/".$method.".php";
1104
		$methodLocation = $handler."/".$method.".php";
493
		return $this->IncludeBuffered($methodLocation, "<i>M&eacute;thode inconnue \"$methodLocation\"</i>", "", $this->config["handler_path"]);
1105
		return $this->IncludeBuffered($methodLocation, "<i>M&eacute;thode inconnue \"$methodLocation\"</i>", "", $this->config["handler_path"]);
494
	}
1106
	}
495
	function Format($text, $formatter = "wakka") {
1107
	function Format($text, $formatter = "wakka") {
496
		return $this->IncludeBuffered("formatters/".$formatter.".php", "<i>Impossible de trouver le formateur \"$formatter\"</i>", compact("text")); 
1108
		return $this->IncludeBuffered("formatters/".$formatter.".php", "<i>Impossible de trouver le formateur \"$formatter\"</i>", compact("text")); 
497
	}
1109
	}
498
 
1110
 
499
 
1111
 
500
 
1112
 
501
	// USERS
1113
	// USERS
502
	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"); }
1114
	function LoadUser($name, $password = 0) { return $this->LoadSingle("select * from ".$this->config["table_prefix"]."users where name = '".mysql_real_escape_string($name)."' ".($password === 0 ? "" : "and password = '".mysql_real_escape_string($password)."'")." limit 1"); }
503
	function LoadUsers() { return $this->LoadAll("select * from ".$this->config["table_prefix"]."users order by name"); }
1115
	function LoadUsers() { return $this->LoadAll("select * from ".$this->config["table_prefix"]."users order by name"); }
504
	function GetUserName() { if ($user = $this->GetUser()) $name = $user["name"]; else if (!$name = gethostbyaddr($_SERVER["REMOTE_ADDR"])) $name = $_SERVER["REMOTE_ADDR"]; return $name; }
1116
	function GetUserName() { if ($user = $this->GetUser()) $name = $user["name"]; else if (!$name = gethostbyaddr($_SERVER["REMOTE_ADDR"])) $name = $_SERVER["REMOTE_ADDR"]; return $name; }
505
	function UserName() { /* deprecated! */ return $this->GetUserName(); }
-
 
506
	function GetUser() { return (isset($_SESSION["user"]) ? $_SESSION["user"] : '');}
1117
	function GetUser() { return (isset($_SESSION["user"]) ? $_SESSION["user"] : '');}
507
	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); }
1118
	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); }
508
	function LogoutUser() { $_SESSION["user"] = ""; $this->DeleteCookie("name"); $this->DeleteCookie("password"); }
1119
	function LogoutUser() { $_SESSION["user"] = ""; $this->DeleteCookie("name"); $this->DeleteCookie("password"); }
509
	function UserWantsComments() { if (!$user = $this->GetUser()) return false; return ($user["show_comments"] == "Y"); }
1120
	function UserWantsComments() { if (!$user = $this->GetUser()) return false; return ($user["show_comments"] == "Y"); }
510
	function GetParameter($parameter, $default = '') { return (isset($this->parameter[$parameter]) ? $this->parameter[$parameter] : $default); }
1121
	function GetParameter($parameter, $default = '') { return (isset($this->parameter[$parameter]) ? $this->parameter[$parameter] : $default); }
511
 
1122
 
512
 
-
 
513
	
1123
 
-
 
1124
	// COMMENTS
-
 
1125
	/**
-
 
1126
	 * Charge les commentaires relatifs ? une page.
-
 
1127
	 * 
-
 
1128
	 * @param string $tag Nom de la page. Ex : "PagePrincipale"
-
 
1129
	 * @return array Tableau contenant tous les commentaires et leurs
-
 
1130
	 * propri?t?s correspondantes.
-
 
1131
	 */
-
 
1132
	function LoadComments($tag)
-
 
1133
	{
-
 
1134
		return $this->LoadAll(
-
 
1135
			"select * " .
514
	// COMMENTS
1136
			"from ".$this->config["table_prefix"]."pages " .
-
 
1137
			"where comment_on = '".mysql_real_escape_string($tag)."' " .
-
 
1138
			"and latest = 'Y' " .
-
 
1139
			"order by substring(tag, 8) + 0");
-
 
1140
	}
-
 
1141
	/**
-
 
1142
	 * Charge les derniers commentaires de toutes les pages.
-
 
1143
	 * 
-
 
1144
	 * @param int $limit Nombre de commentaires charg?s.
-
 
1145
	 *                   0 par d?faut (ie tous les commentaires).
-
 
1146
	 * @return array Tableau contenant chaque commentaire et ses
-
 
1147
	 *               propri?t?s associ?es.
-
 
1148
	 * @todo Ajouter le param?tre $start pour permettre une pagination
-
 
1149
	 *       des commentaires : ->LoadRecentComments(10, 10)
-
 
1150
	 */
-
 
1151
	function LoadRecentComments($limit = 0)
-
 
1152
	{
-
 
1153
		// The part of the query which limit the number of comments  
-
 
1154
		if(is_numeric($limit) && $limit > 0) $lim = " limit ".$limit;
-
 
1155
		else $lim = "";
-
 
1156
 
-
 
1157
		// Query
-
 
1158
		return $this->LoadAll(
515
	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"); }
1159
			"select * " .
-
 
1160
			"from " . $this->config["table_prefix"] . "pages " .
-
 
1161
			"where comment_on != '' " .
-
 
1162
			"and latest = 'Y' " .
-
 
1163
			"order by time desc " .
-
 
1164
			$lim);
516
	function LoadRecentComments() { return $this->LoadAll("select * from ".$this->config["table_prefix"]."pages where comment_on != '' and latest = 'Y' order by time desc"); }
1165
	}
-
 
1166
	function LoadRecentlyCommented($limit = 50)
-
 
1167
	{
-
 
1168
		$pages = array();
517
	function LoadRecentlyCommented($limit = 50) {
1169
 
518
		// NOTE: this is really stupid. Maybe my SQL-Fu is too weak, but apparently there is no easier way to simply select
1170
		// 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!
1171
		//       all comment pages sorted by their first revision's (!) time. ugh!
520
		
1172
 
521
		// load ids of the first revisions of latest comments. err, huh?
1173
		// 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"))
1174
		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
		{
1175
		{
526
			// load complete comments
1176
			// load complete comments
-
 
1177
			$num=0;
527
			foreach ($ids as $id)
1178
			foreach ($ids as $id)
528
			{
1179
			{
529
				$comment = $this->LoadSingle("select * from ".$this->config["table_prefix"]."pages where id = '".$id["id"]."' limit 1");
1180
				$comment = $this->LoadSingle("select * from ".$this->config["table_prefix"]."pages where id = '".$id["id"]."' limit 1");
530
				$num=0;
-
 
531
				if (!isset($comments[$comment["comment_on"]])) $comments[$comment["comment_on"]]='';
-
 
532
				if (!$comments[$comment["comment_on"]] && $num < $limit)
1181
				if (!isset($comments[$comment["comment_on"]]) && $num < $limit)
533
				{
1182
				{
534
					$comments[$comment["comment_on"]] = $comment;
1183
					$comments[$comment["comment_on"]] = $comment;
535
					$num++;
1184
					$num++;
536
				}
1185
				}
537
			}
1186
			}
538
		
1187
 
539
			// now load pages
1188
			// now load pages
540
			if ($comments)
1189
			if ($comments)
541
			{
1190
			{
542
				// now using these ids, load the actual pages
1191
				// now using these ids, load the actual pages
543
				foreach ($comments as $comment)
1192
				foreach ($comments as $comment)
544
				{
1193
				{
545
					$page = $this->LoadPage($comment["comment_on"]);
1194
					$page = $this->LoadPage($comment["comment_on"]);
546
					$page["comment_user"] = $comment["user"];
1195
					$page["comment_user"] = $comment["user"];
547
					$page["comment_time"] = $comment["time"];
1196
					$page["comment_time"] = $comment["time"];
548
					$page["comment_tag"] = $comment["tag"];
1197
					$page["comment_tag"] = $comment["tag"];
549
					$pages[] = $page;
1198
					$pages[] = $page;
550
				}
1199
				}
551
			}
1200
			}
552
		}
1201
		}
553
		// load tags of pages 
1202
		// load tags of pages 
554
		//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");
1203
		//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");
555
		return $pages;
1204
		return $pages;
556
	}
1205
	}
557
 
1206
 
558
 
1207
 
559
 
1208
 
560
	// ACCESS CONTROL
1209
	// ACCESS CONTROL
561
	// returns true if logged in user is owner of current page, or page specified in $tag
1210
	// returns true if logged in user is owner of current page, or page specified in $tag
562
	function UserIsOwner($tag = "") {
1211
	function UserIsOwner($tag = "") {
563
		// check if user is logged in
1212
		// check if user is logged in
564
		if (!$this->GetUser()) return false;
1213
		if (!$this->GetUser()) return false;
565
 
1214
 
566
		// set default tag
1215
		// set default tag
567
		if (!$tag = trim($tag)) $tag = $this->GetPageTag();
1216
		if (!$tag = trim($tag)) $tag = $this->GetPageTag();
568
		
1217
 
569
		// check if user is owner
1218
		// check if user is owner
570
		if ($this->GetPageOwner($tag) == $this->GetUserName()) return true;
1219
		if ($this->GetPageOwner($tag) == $this->GetUserName()) return true;
571
	}
1220
	}
-
 
1221
 
-
 
1222
	/**
-
 
1223
	 * @param string $group The name of a group
-
 
1224
	 * @return string the ACL associated with the group $gname
-
 
1225
	 * @see UserIsInGroup to check if a user belongs to some group
-
 
1226
	 */
-
 
1227
	function GetGroupACL($group)
-
 
1228
	{
-
 
1229
		if (array_key_exists($group, $this->_groupsCache))
-
 
1230
		{
-
 
1231
			return $this->_groupsCache[$group];
-
 
1232
		}
-
 
1233
		return $this->_groupsCache[$group] = $this->GetTripleValue($group, WIKINI_VOC_ACLS, GROUP_PREFIX);
-
 
1234
	}
-
 
1235
 
-
 
1236
	/**
-
 
1237
	 * Checks if a new group acl is not defined recursively
-
 
1238
	 * (this method expects that groups that are already defined are not themselves defined recursively...)
-
 
1239
	 * @param string $gname The name of the group
-
 
1240
	 * @param string $acl The new acl for that group
-
 
1241
	 * @return boolean True iff the new acl defines the group recursively
-
 
1242
	 */
-
 
1243
	function MakesGroupRecursive($gname, $acl, $origin = null, $checked = array())
-
 
1244
	{
-
 
1245
		$gname = strtolower($gname);
-
 
1246
		if ($origin === null)
-
 
1247
		{
-
 
1248
			$origin = $gname;
-
 
1249
		}
-
 
1250
		elseif ($gname === $origin)
-
 
1251
		{
-
 
1252
			return true;
-
 
1253
		}
-
 
1254
		foreach (explode("\n", $acl) as $line)
-
 
1255
		{
-
 
1256
			if (!$line) continue;
-
 
1257
			if ($line[0] == '!')
-
 
1258
			{
-
 
1259
				$line = substr($line, 1);
-
 
1260
			}
-
 
1261
			if (!$line) continue;
-
 
1262
			if ($line[0] == '@')
-
 
1263
			{
-
 
1264
				$line = substr($line, 1);
-
 
1265
				if (!in_array($line, $checked))
-
 
1266
				{
-
 
1267
					if ($this->MakesGroupRecursive($line, $this->GetGroupACL($line), $origin, $checked))
-
 
1268
					{
-
 
1269
						return true;
-
 
1270
					}
-
 
1271
				}
-
 
1272
			}
-
 
1273
		}
-
 
1274
		$checked[] = $gname;
-
 
1275
		return false;
-
 
1276
	}
-
 
1277
 
-
 
1278
	/**
-
 
1279
	 * Sets a new ACL to a given group
-
 
1280
	 * @param string $gname The name of a group
-
 
1281
	 * @param string $acl The new ACL to associate with the group $gname
-
 
1282
	 * @return int 0 if successful, a triple error code or a specific error code:
-
 
1283
	 * 	1000 if the new value would define the group recursively
-
 
1284
	 * 	1001 if $gname is not named with alphanumeric chars
-
 
1285
	 * @see GetGroupACL
-
 
1286
	 */
-
 
1287
	function SetGroupACL($gname, $acl)
-
 
1288
	{
-
 
1289
		if (preg_match('/[^A-Za-z0-9]/', $gname))
-
 
1290
		{
-
 
1291
			return 1001;
-
 
1292
		}
-
 
1293
		$old = $this->GetGroupACL($gname);
-
 
1294
		if ($this->MakesGroupRecursive($gname, $acl))
-
 
1295
		{
-
 
1296
			return 1000;
-
 
1297
		}
-
 
1298
		$this->_groupsCache[$gname] = $acl;
-
 
1299
		if ($old === null)
-
 
1300
		{
-
 
1301
			return $this->InsertTriple($gname, WIKINI_VOC_ACLS, $acl, GROUP_PREFIX);
-
 
1302
		}
-
 
1303
		elseif ($old === $acl)
-
 
1304
		{
-
 
1305
			return 0; // nothing has changed
-
 
1306
		}
-
 
1307
		else
-
 
1308
		{
-
 
1309
			return $this->UpdateTriple($gname, WIKINI_VOC_ACLS, $old, $acl, GROUP_PREFIX);
-
 
1310
		}
-
 
1311
	}
-
 
1312
	/**
-
 
1313
	 * @return array The list of all group names
-
 
1314
	 */
-
 
1315
	function GetGroupsList()
-
 
1316
	{
-
 
1317
		$res = $this->GetMatchingTriples(GROUP_PREFIX . '%', WIKINI_VOC_ACLS_URI);
-
 
1318
		$prefix_len = strlen(GROUP_PREFIX);
-
 
1319
		$list = array();
-
 
1320
		foreach ($res as $line)
-
 
1321
		{
-
 
1322
			$list[] = substr($line['resource'], $prefix_len);
-
 
1323
		}
-
 
1324
		return $list;
-
 
1325
	}
-
 
1326
 
-
 
1327
	/**
-
 
1328
	 * @param string $group The name of a group
-
 
1329
	 * @return boolean true iff the user is in the given $group 
-
 
1330
	 */
-
 
1331
	function UserIsInGroup($group, $user = null, $admincheck = true)
-
 
1332
	{
-
 
1333
		return $this->CheckACL($this->GetGroupACL($group), $user, $admincheck);
-
 
1334
	}
-
 
1335
 
-
 
1336
	/**
-
 
1337
	 * Checks if a given user is andministrator
-
 
1338
	 * @param string $user The name of the user (defaults to the current user if not given)
-
 
1339
	 * @return boolean true iff the user is an administrator
-
 
1340
	 */
-
 
1341
	function UserIsAdmin($user = null)
-
 
1342
	{
-
 
1343
		return $this->UserIsInGroup(ADMIN_GROUP, $user, false);
-
 
1344
	}
-
 
1345
 
572
	function GetPageOwner($tag = "", $time = "") { if (!$tag = trim($tag)) $tag = $this->GetPageTag(); if ($page = $this->LoadPage($tag, $time)) return $page["owner"]; }
1346
	function GetPageOwner($tag = "", $time = "") { if (!$tag = trim($tag)) $tag = $this->GetPageTag(); if ($page = $this->LoadPage($tag, $time)) return $page["owner"]; }
573
	function SetPageOwner($tag, $user) {
1347
	function SetPageOwner($tag, $user) {
574
		// check if user exists
1348
		// check if user exists
575
		if (!$this->LoadUser($user)) return;
1349
		if (!$this->LoadUser($user)) return;
576
		
1350
 
577
		// updated latest revision with new owner
1351
		// updated latest revision with new owner
578
		$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");
1352
		$this->Query("update ".$this->config["table_prefix"]."pages set owner = '".mysql_real_escape_string($user)."' where tag = '".mysql_real_escape_string($tag)."' and latest = 'Y' limit 1");
579
	}
1353
	}
580
	function LoadAcl($tag, $privilege, $useDefaults = 1) {
1354
	function LoadAcl($tag, $privilege, $useDefaults = 1) {
581
		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)
1355
		if ((!$acl = $this->LoadSingle("select * from ".$this->config["table_prefix"]."acls where page_tag = '".mysql_real_escape_string($tag)."' and privilege = '".mysql_real_escape_string($privilege)."' limit 1")) && $useDefaults)
582
		{
1356
		{
583
			$acl = array("page_tag" => $tag, "privilege" => $privilege, "list" => $this->GetConfigValue("default_".$privilege."_acl"));
1357
			$acl = array("page_tag" => $tag, "privilege" => $privilege, "list" => $this->GetConfigValue("default_".$privilege."_acl"));
584
		}
1358
		}
585
		return $acl;
1359
		return $acl;
586
	}
1360
	}
587
	function SaveAcl($tag, $privilege, $list) {
1361
	function SaveAcl($tag, $privilege, $list) {
588
		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");
1362
		if ($this->LoadAcl($tag, $privilege, 0)) $this->Query("update ".$this->config["table_prefix"]."acls set list = '".mysql_real_escape_string(trim(str_replace("\r", "", $list)))."' where page_tag = '".mysql_real_escape_string($tag)."' and privilege = '".mysql_real_escape_string($privilege)."' limit 1");
589
		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)."'");
1363
		else $this->Query("insert into ".$this->config["table_prefix"]."acls set list = '".mysql_real_escape_string(trim(str_replace("\r", "", $list)))."', page_tag = '".mysql_real_escape_string($tag)."', privilege = '".mysql_real_escape_string($privilege)."'");
590
	}
1364
	}
591
	// returns true if $user (defaults to current user) has access to $privilege on $page_tag (defaults to current page)
1365
	// returns true if $user (defaults to current user) has access to $privilege on $page_tag (defaults to current page)
592
	function HasAccess($privilege, $tag = "", $user = "") {
1366
	function HasAccess($privilege, $tag = "", $user = "") {
593
		// set defaults
1367
		// set defaults
594
		if (!$tag = trim($tag)) $tag = $this->GetPageTag();
1368
		if (!$tag = trim($tag)) $tag = $this->GetPageTag();
-
 
1369
		if (!$user)
-
 
1370
		{
-
 
1371
			// if current user is owner, return true. owner can do anything!
-
 
1372
			if ($this->UserIsOwner($tag)) return true;
595
		if (!$user = $this->GetUserName());
1373
			$user = $this->GetUserName();
-
 
1374
		}
-
 
1375
 
-
 
1376
		// TODO: we might want to check if a given $user (other than the current user)
-
 
1377
		// has access to a given page. If the $user is the owner of that page,
-
 
1378
		// this method might give a wrong result (because we can't check that)
596
		
1379
 
597
		// load acl
1380
		// load acl
598
		$acl = $this->LoadAcl($tag, $privilege);
1381
		$acl = $this->LoadAcl($tag, $privilege);
599
		
-
 
600
		// if current user is owner, return true. owner can do anything!
-
 
601
		if ($this->UserIsOwner($tag)) return true;
-
 
602
		
1382
 
-
 
1383
		// fine fine... now go through acl
-
 
1384
		return $this->CheckACL($acl["list"], $user);
-
 
1385
	}
-
 
1386
 
-
 
1387
	/**
-
 
1388
	 * Checks if some $user satisfies the given $acl
-
 
1389
	 * @param string $acl The acl to check, in the same format than for pages ACL's
-
 
1390
	 * @param string $user The name of the user that must satisfy the ACL. By default
-
 
1391
	 * the current remote user.
-
 
1392
	 * @return bool True if the $user satisfies the $acl, false otherwise
-
 
1393
	 */
-
 
1394
	function CheckACL($acl, $user = null, $admincheck = true)
-
 
1395
	{
-
 
1396
		if (!$user)
-
 
1397
		{
-
 
1398
			$user = $this->GetUserName();
-
 
1399
		}
-
 
1400
 
-
 
1401
		if ($admincheck && $this->UserIsAdmin($user))
-
 
1402
		{
-
 
1403
			return true;
-
 
1404
		}
-
 
1405
 
603
		// fine fine... now go through acl
1406
 
604
		foreach (explode("\n", $acl["list"]) as $line)
1407
		foreach (explode("\n", $acl) as $line)
605
		{
1408
		{
606
			$line = trim($line);
1409
			$line = trim($line);
607
 
1410
 
608
			// check for inversion character "!"
1411
			// check for inversion character "!"
609
			if (preg_match("/^[!](.*)$/", $line, $matches))
1412
			if (preg_match("/^[!](.*)$/", $line, $matches))
610
			{
1413
			{
611
				$negate = 1;
1414
				$negate = 1;
612
				$line = $matches[1];
1415
				$line = $matches[1];
613
			}
1416
			}
614
			else
1417
			else
615
			{
1418
			{
616
				$negate = 0;
1419
				$negate = 0;
617
			}
1420
			}
618
 
1421
 
619
			// if there's still anything left... lines with just a "!" don't count!
1422
			// if there's still anything left... lines with just a "!" don't count!
620
			if ($line)
1423
			if ($line)
621
			{
1424
			{
622
				switch ($line[0])
1425
				switch ($line[0])
623
				{
1426
				{
624
				// comments
1427
				case "#": // comments
625
				case "#":
-
 
626
					break;
1428
					break;
627
				// everyone
1429
				case "*": // everyone
628
				case "*":
-
 
629
					return !$negate;
1430
					return !$negate;
630
				// aha! a user entry.
1431
				case "+": // registered users
631
				case "+":
-
 
632
					if (!$this->LoadUser($user)) 
1432
					if (!$this->LoadUser($user)) 
633
					{
1433
					{
634
						return $negate;
1434
						return $negate;
635
					}
1435
					}
636
					else
1436
					else
637
					{
1437
					{
638
						return !$negate;
1438
						return !$negate;
639
					}
1439
					}
-
 
1440
				case '@': // groups
-
 
1441
					$gname = substr($line, 1);
-
 
1442
					// paranoiac: avoid line = '@'
-
 
1443
					if ($gname && $this->UserIsInGroup($gname, $user, false /* we have allready checked if user was an admin */))
-
 
1444
					{
-
 
1445
						return !$negate;
-
 
1446
					}
640
				default:
1447
					break;
-
 
1448
				default: // simple user entry
641
					if ($line == $user)
1449
					if ($line == $user)
642
					{
1450
					{
643
						return !$negate;
1451
						return !$negate;
644
					}
1452
					}
645
				}
1453
				}
646
			}
1454
			}
647
		}
1455
		}
648
		
1456
 
649
		// tough luck.
1457
		// tough luck.
650
		return false;
1458
		return false;
651
	}
1459
	}
-
 
1460
 
-
 
1461
	/**
-
 
1462
	 * Loads the module ACL for a certain module
-
 
1463
	 * @param string $module The name of the module
-
 
1464
	 * @param string $module_type The type of module: 'action' or 'handler'
-
 
1465
	 * @return mixed The ACL for the given module or <tt>null</tt> if no such
-
 
1466
	 * ACL was found (which should probably be interpreted as '*'). 
-
 
1467
	 */
-
 
1468
	function GetModuleACL($module, $module_type)
-
 
1469
	{
-
 
1470
		$module = strtolower($module);
-
 
1471
		switch ($module_type)
-
 
1472
		{
-
 
1473
		case 'action':
-
 
1474
			if (array_key_exists($module, $this->_actionsAclsCache))
-
 
1475
			{
-
 
1476
				$acl = $this->_actionsAclsCache[$module];
-
 
1477
				break;
-
 
1478
			}
-
 
1479
			$this->_actionsAclsCache[$module] = $acl = $this->GetTripleValue($module, WIKINI_VOC_ACLS, WIKINI_VOC_ACTIONS_PREFIX);
-
 
1480
			if ($acl === null)
-
 
1481
			{
-
 
1482
				$action = &$this->GetActionObject($module);
-
 
1483
				if (is_object($action))
-
 
1484
				{
-
 
1485
					return $this->_actionsAclsCache[$module] = $action->GetDefaultACL();
-
 
1486
				}
-
 
1487
			}
-
 
1488
			break;
-
 
1489
		case 'handler':
-
 
1490
			$acl = $this->GetTripleValue($module, WIKINI_VOC_ACLS, WIKINI_VOC_HANDLERS_PREFIX);
-
 
1491
			break;
-
 
1492
		default:
-
 
1493
			return null; // TODO error msg ?
-
 
1494
		}
-
 
1495
		return $acl === null ? '*' : $acl;
-
 
1496
	}
-
 
1497
 
-
 
1498
	/**
-
 
1499
	 * Sets the $acl for a given $module
-
 
1500
	 * @param string $module The name of the module
-
 
1501
	 * @param string $module_type The type of module ('action' or 'handler')
-
 
1502
	 * @param string $acl The new ACL for that module
-
 
1503
	 * @return 0 on success, > 0 on error (see InsertTriple and UpdateTriple)
-
 
1504
	 */
-
 
1505
	function SetModuleACL($module, $module_type, $acl)
-
 
1506
	{
-
 
1507
		$module = strtolower($module);
-
 
1508
		$voc_prefix = $module_type == 'action' ? WIKINI_VOC_ACTIONS_PREFIX : WIKINI_VOC_HANDLERS_PREFIX;
-
 
1509
		$old = $this->GetTripleValue($module, WIKINI_VOC_ACLS, $voc_prefix);
-
 
1510
		if ($module_type == 'action')
-
 
1511
		{
-
 
1512
			$this->_actionsAclsCache[$module] = $acl;
-
 
1513
		}
-
 
1514
		if ($old === null)
-
 
1515
		{
-
 
1516
			return $this->InsertTriple($module, WIKINI_VOC_ACLS, $acl, $voc_prefix);
-
 
1517
		}
-
 
1518
		elseif ($old === $acl)
-
 
1519
		{
-
 
1520
			return 0; // nothing has changed
-
 
1521
		}
-
 
1522
		else
-
 
1523
		{
-
 
1524
			return $this->UpdateTriple($module, WIKINI_VOC_ACLS, $old, $acl, $voc_prefix);
-
 
1525
		}
-
 
1526
	}
-
 
1527
 
-
 
1528
	/**
-
 
1529
	 * Checks if a $user satisfies the ACL to access a certain $module
-
 
1530
	 * @param string $module The name of the module to access
-
 
1531
	 * @param string $module_type The type of the module ('action' or 'handler')
-
 
1532
	 * @param string $user The name of the user. By default
-
 
1533
	 * the current remote user.
-
 
1534
	 * @return bool True if the $user has access to the given $module, false otherwise.
-
 
1535
	 */
-
 
1536
	function CheckModuleACL($module, $module_type, $user = null)
-
 
1537
	{
-
 
1538
		$acl = $this->GetModuleACL($module, $module_type);
-
 
1539
		if ($acl === null) return true; // undefined ACL means everybody has access
-
 
1540
		return $this->CheckACL($acl, $user);
652
 
1541
	}
653
 
1542
 
654
 
1543
 
655
	// MAINTENANCE
1544
	// MAINTENANCE
656
	function Maintenance() {
1545
	function Maintenance() {
657
		// purge referrers
1546
		// purge referrers
658
		$this->PurgeReferrers();
1547
		$this->PurgeReferrers();
659
		// purge old page revisions
1548
		// purge old page revisions
660
		$this->PurgePages();
1549
		$this->PurgePages();
661
	}
1550
	}
662
 
1551
 
663
 
1552
 
664
 
1553
 
665
	// THE BIG EVIL NASTY ONE!
1554
	// THE BIG EVIL NASTY ONE!
666
	function Run($tag, $method = "") {
1555
	function Run($tag, $method = "") {
667
		if(!($this->GetMicroTime()%3)) $this->Maintenance(); 
1556
		if(!($this->GetMicroTime()%9)) $this->Maintenance(); 
668
 
1557
 
669
		$this->ReadInterWikiConfig();
1558
		$this->ReadInterWikiConfig();
670
 
1559
 
671
		// do our stuff!
1560
		// do our stuff!
672
		if (!$this->method = trim($method)) $this->method = "show";
1561
		if (!$this->method = trim($method)) $this->method = "show";
673
		if (!$this->tag = trim($tag)) $this->Redirect($this->href("", $this->config["root_page"]));
1562
		if (!$this->tag = trim($tag)) $this->Redirect($this->href("", $this->config["root_page"]));
674
		if ((!$this->GetUser() && isset($_COOKIE["name"])) && ($user = $this->LoadUser($_COOKIE["name"], $_COOKIE["password"]))) $this->SetUser($user, $_COOKIE["remember"]);
1563
		if ((!$this->GetUser() && isset($_COOKIE["name"])) && ($user = $this->LoadUser($_COOKIE["name"], $_COOKIE["password"]))) $this->SetUser($user, $_COOKIE["remember"]);
675
		$this->SetPage($this->LoadPage($tag, (isset($_REQUEST["time"]) ? $_REQUEST["time"] :'')));
1564
		$this->SetPage($this->LoadPage($tag, (isset($_REQUEST["time"]) ? $_REQUEST["time"] :'')));
676
		$this->LogReferrer();
1565
		$this->LogReferrer();
677
 
1566
 
678
      //correction pour un support plus facile de nouveaux handlers
1567
		//correction pour un support plus facile de nouveaux handlers
-
 
1568
		if ($this->CheckModuleACL($this->method, 'handler'))
-
 
1569
		{
679
      print($this->Method($this->method));
1570
			echo $this->Method($this->method);
-
 
1571
		}
-
 
1572
		else
-
 
1573
		{
-
 
1574
			echo 'Vous ne pouvez pas acc&eacute;der &agrave; cette page par le handler sp&eacute;cifi&eacute;.';
-
 
1575
		}
-
 
1576
 
-
 
1577
		// action redirect: aucune redirection n'a eu lieu, effacer la liste des redirections pr?c?dentes
-
 
1578
		if(!empty($_SESSION['redirects'])) session_unregister('redirects');
680
	}
1579
	}
681
}
1580
}
682
 
1581
 
683
 
1582
 
684
 
1583
 
685
// stupid version check
1584
// stupid version check
686
if (!isset($_REQUEST)) die('$_REQUEST[] not found. Wakka requires PHP 4.1.0 or higher!');
1585
if (!isset($_REQUEST)) die('$_REQUEST[] not found. Wakka requires PHP 4.1.0 or higher!');
687
 
1586
 
688
// workaround for the amazingly annoying magic quotes.
1587
// workaround for the amazingly annoying magic quotes.
689
function magicQuotesSuck(&$a)
1588
function magicQuotesSuck(&$a)
690
{
1589
{
691
	if (is_array($a))
1590
	if (is_array($a))
692
	{
1591
	{
693
		foreach ($a as $k => $v)
1592
		foreach ($a as $k => $v)
694
		{
1593
		{
695
			if (is_array($v))
1594
			if (is_array($v))
696
				magicQuotesSuck($a[$k]);
1595
				magicQuotesSuck($a[$k]);
697
			else
1596
			else
698
				$a[$k] = stripslashes($v);
1597
				$a[$k] = stripslashes($v);
699
		}
1598
		}
700
	}
1599
	}
701
}
1600
}
-
 
1601
 
702
set_magic_quotes_runtime(0);
1602
if (get_magic_quotes_runtime())
-
 
1603
{
-
 
1604
    // Deactivate
-
 
1605
    set_magic_quotes_runtime(false);
-
 
1606
}
-
 
1607
 
703
if (get_magic_quotes_gpc())
1608
if (get_magic_quotes_gpc())
704
{
1609
{
705
	magicQuotesSuck($_POST);
1610
	magicQuotesSuck($_POST);
706
	magicQuotesSuck($_GET);
1611
	magicQuotesSuck($_GET);
707
	magicQuotesSuck($_COOKIE);
1612
	magicQuotesSuck($_COOKIE);
708
}
1613
}
709
 
1614
 
710
 
1615
 
711
// default configuration values
1616
// default configuration values
712
$wakkaConfig= array();
1617
$wakkaConfig= array();
-
 
1618
$_rewrite_mode = detectRewriteMode();
713
$wakkaDefaultConfig = array(
1619
$wakkaDefaultConfig = array(
714
	'wakka_version'		=> '',
1620
	'wakka_version'		=> '',
715
	'wikini_version'	=> '',
1621
	'wikini_version'	=> '',
716
	'debug'			=> 'no',
1622
	'debug'				=> 'no',
717
	"mysql_host"		=> "localhost",
1623
	"mysql_host"		=> "localhost",
718
	"mysql_database"		=> "wikini",
1624
	"mysql_database"	=> "wikini",
719
	"mysql_user"		=> "wikini",
1625
	"mysql_user"		=> "wikini",
720
	"mysql_password"		=> '',
1626
	"mysql_password"	=> '',
721
	"table_prefix"		=> "wikini_",
1627
	"table_prefix"		=> "wikini_",
722
	"root_page"			=> "PagePrincipale",
1628
	"root_page"			=> "PagePrincipale",
723
	"wakka_name"		=> "MonSiteWikiNi",
1629
	"wakka_name"		=> "MonSiteWikiNi",
724
	"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=" : ""),
1630
	"base_url"			=> computeBaseURL($_rewrite_mode),
725
	"rewrite_mode"		=> (preg_match("/".preg_quote("wakka.php")."$/", $_SERVER["REQUEST_URI"]) ? "0" : "1"),
1631
	"rewrite_mode"		=> $_rewrite_mode,
726
	'meta_keywords'		=> '',
1632
	'meta_keywords'		=> '',
727
	'meta_description'	=> '',
1633
	'meta_description'	=> '',
728
	"action_path"		=> "actions",
1634
	"action_path"		=> "actions",
729
	"handler_path"		=> "handlers",
1635
	"handler_path"		=> "handlers",
730
	"header_action"		=> "header",
1636
	"header_action"		=> "header",
731
	"footer_action"		=> "footer",
1637
	"footer_action"		=> "footer",
732
	"navigation_links"		=> "DerniersChangements :: DerniersCommentaires :: ParametresUtilisateur",
1638
	"navigation_links"		=> "DerniersChangements :: DerniersCommentaires :: ParametresUtilisateur",
733
	"referrers_purge_time"	=> 24,
1639
	"referrers_purge_time"	=> 24,
734
	"pages_purge_time"	=> 90,
1640
	"pages_purge_time"	=> 90,
735
	"default_write_acl"	=> "*",
1641
	"default_write_acl"	=> "*",
736
	"default_read_acl"	=> "*",
1642
	"default_read_acl"	=> "*",
737
	"default_comment_acl"	=> "*",
1643
	"default_comment_acl"	=> "*",
738
	"menu_page"	 	=> "PageMenu",
1644
	"preview_before_save"	=> 0,
739
	"preview_before_save"	=> "0");
1645
	'allow_raw_html'	=> false);
-
 
1646
unset($_rewrite_mode);
740
 
1647
 
741
// load config
1648
// load config
742
if (!$configfile = GetEnv("WAKKA_CONFIG")) $configfile = "wakka.config.php";
1649
if (!$configfile = GetEnv("WAKKA_CONFIG")) $configfile = "wakka.config.php";
743
if (file_exists($configfile)) include($configfile);
1650
if (file_exists($configfile)) include($configfile);
744
$wakkaConfigLocation = $configfile;
1651
$wakkaConfigLocation = $configfile;
745
$wakkaConfig = array_merge($wakkaDefaultConfig, $wakkaConfig);
1652
$wakkaConfig = array_merge($wakkaDefaultConfig, $wakkaConfig);
746
 
1653
 
747
// check for locking
1654
// check for locking
748
if (file_exists("locked")) {
1655
if (file_exists("locked")) {
749
	// read password from lockfile
1656
	// read password from lockfile
750
	$lines = file("locked");
1657
	$lines = file("locked");
751
	$lockpw = trim($lines[0]);
1658
	$lockpw = trim($lines[0]);
752
	
1659
 
753
	// is authentification given?
1660
	// is authentification given?
754
	if (isset($_SERVER["PHP_AUTH_USER"])) {
1661
	if (isset($_SERVER["PHP_AUTH_USER"])) {
755
		if (!(($_SERVER["PHP_AUTH_USER"] == "admin") && ($_SERVER["PHP_AUTH_PW"] == $lockpw))) {
1662
		if (!(($_SERVER["PHP_AUTH_USER"] == "admin") && ($_SERVER["PHP_AUTH_PW"] == $lockpw))) {
756
			$ask = 1;
1663
			$ask = 1;
757
		}
1664
		}
758
	} else {
1665
	} else {
759
		$ask = 1;
1666
		$ask = 1;
760
	}
1667
	}
761
	
1668
 
762
	if ($ask) {
1669
	if ($ask) {
763
		header("WWW-Authenticate: Basic realm=\"".$wakkaConfig["wakka_name"]." Install/Upgrade Interface\"");
1670
		header("WWW-Authenticate: Basic realm=\"".$wakkaConfig["wakka_name"]." Install/Upgrade Interface\"");
764
		header("HTTP/1.0 401 Unauthorized");
1671
		header("HTTP/1.0 401 Unauthorized");
765
		echo "Ce site est en cours de mise &agrave; jour. Veuillez essayer plus tard." ;
1672
		echo "Ce site est en cours de mise &agrave; jour. Veuillez essayer plus tard." ;
766
		exit;
1673
		exit;
767
	}
1674
	}
768
}
1675
}
769
 
1676
 
770
 
1677
 
771
// compare versions, start installer if necessary
1678
// compare versions, start installer if necessary
772
if ($wakkaConfig["wakka_version"] && (!$wakkaConfig["wikini_version"])) { $wakkaConfig["wikini_version"]=$wakkaConfig["wakka_version"]; }
1679
if ($wakkaConfig["wakka_version"] && (!$wakkaConfig["wikini_version"])) { $wakkaConfig["wikini_version"]=$wakkaConfig["wakka_version"]; }
773
if (($wakkaConfig["wakka_version"] != WAKKA_VERSION) || ($wakkaConfig["wikini_version"] != WIKINI_VERSION)) {
1680
if (($wakkaConfig["wakka_version"] != WAKKA_VERSION) || ($wakkaConfig["wikini_version"] != WIKINI_VERSION)) {
774
	// start installer
1681
	// start installer
775
	if (!isset($_REQUEST["installAction"]) OR !$installAction = trim($_REQUEST["installAction"])) $installAction = "default";
1682
	if (!isset($_REQUEST["installAction"]) OR !$installAction = trim($_REQUEST["installAction"])) $installAction = "default";
776
	include("setup/header.php");
1683
	include("setup/header.php");
777
	if (file_exists("setup/".$installAction.".php")) include("setup/".$installAction.".php"); else echo "<i>Invalid action</i>" ;
1684
	if (file_exists("setup/".$installAction.".php")) include("setup/".$installAction.".php"); else echo "<i>Invalid action</i>" ;
778
	include("setup/footer.php");
1685
	include("setup/footer.php");
779
	exit;
1686
	exit;
780
}
1687
}
-
 
1688
 
-
 
1689
// Check if the server is configured to automatically compress the output
-
 
1690
if (!ini_get('zlib.output_compression') && !ini_get('zlib.output_handler'))
-
 
1691
{ 
-
 
1692
	// Check if we can use ob_gzhandler (requires the zlib extension)
-
 
1693
	if (function_exists('ob_gzhandler'))
-
 
1694
	{
-
 
1695
		// let ob_gzhandler do the dirty job
-
 
1696
		// NB.: this must be done BEFORE session_start() when session.use_trans_sid is on
-
 
1697
		ob_start('ob_gzhandler');
-
 
1698
	}
-
 
1699
	// else lets do the dirty job by ourselves...
-
 
1700
	elseif (!empty($_SERVER['HTTP_ACCEPT_ENCODING']) && strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') && function_exists('gzencode'))
-
 
1701
	{
-
 
1702
		ob_start ('gzencode');
-
 
1703
		// Tell the browser the content is compressed with gzip 
-
 
1704
		header ("Content-Encoding: gzip"); 
-
 
1705
	}
781
 
1706
}
782
 
1707
 
783
// configuration du cookie de session
1708
// configuration du cookie de session
784
//determine le chemin pour le cookie
1709
// determine le chemin pour les cookies
-
 
1710
$a = parse_url($wakkaConfig['base_url']);
-
 
1711
$CookiePath = dirname($a['path']);
-
 
1712
// Fixe la gestion des cookie sous les OS utilisant le \ comme s?parteur de chemin
785
$a = parse_url($wakkaConfig['base_url']);
1713
$CookiePath = str_replace("\\","/",$CookiePath);
786
$CookiePath = dirname($a['path']);
1714
// ajoute un '/' terminal sauf si on est ? la racine web
787
if ($CookiePath != '/') $CookiePath .= '/';
1715
if ($CookiePath != '/') $CookiePath .= '/';
788
$a = session_get_cookie_params();
1716
$a = session_get_cookie_params();
789
session_set_cookie_params($a['lifetime'],$CookiePath);
1717
session_set_cookie_params($a['lifetime'],$CookiePath);
790
unset($a);
1718
unset($a);
791
unset($CookiePath);
1719
unset($CookiePath);
792
 
1720
 
793
// start session
1721
// start session
794
session_start();
1722
session_start();
795
 
1723
 
796
// fetch wakka location
1724
// fetch wakka location
797
if (!isset($_REQUEST["wiki"])) $_REQUEST["wiki"] = '';
1725
if (empty($_REQUEST['wiki']))
798
 
1726
{
-
 
1727
	// redirect to the root page
-
 
1728
	header('Location: ' . $wakkaConfig['base_url'] . $wakkaConfig['root_page']);
-
 
1729
	exit;
-
 
1730
}
799
$wiki = $_REQUEST["wiki"];
1731
$wiki = $_REQUEST['wiki'];
800
 
1732
 
801
// remove leading slash
1733
// remove leading slash
802
$wiki = preg_replace("/^\//", "", $wiki);
1734
$wiki = preg_replace("/^\//", "", $wiki);
803
 
1735
 
804
// split into page/method
1736
// split into page/method, checking wiki name & method name (XSS proof)
-
 
1737
if (preg_match('`^' . WN_TAG_HANDLER_CAPTURE . '$`', $wiki, $matches))
-
 
1738
{
-
 
1739
	list(, $page, $method) = $matches;
805
if (preg_match("#^(.+?)/([A-Za-z0-9_]*)$#", $wiki, $matches)) list(, $page, $method) = $matches;
1740
}
-
 
1741
elseif (preg_match('`^' . WN_PAGE_TAG . '$`', $wiki))
-
 
1742
{
-
 
1743
	$page = $wiki;
-
 
1744
}
-
 
1745
else
-
 
1746
{
-
 
1747
	echo "<p>Le nom de la page est incorrect.</p>";
-
 
1748
	exit;
806
else if (preg_match("#^(.*)$#", $wiki, $matches)) list(, $page) = $matches;
1749
}
807
 
1750
 
808
// create wiki object
1751
// create wiki object
809
$wiki = new Wiki($wakkaConfig);
1752
$wiki = new Wiki($wakkaConfig);
810
// check for database access
1753
// check for database access
811
if (!$wiki->dblink)
1754
if (!$wiki->dblink)
812
{
1755
{
813
	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>";
1756
	echo	"<p>Pour des raisons ind&eacute;pendantes de notre volont&eacute;, ".
-
 
1757
		"le contenu de ce Wiki est temporairement inaccessible. Veuillez ".
-
 
1758
		"r&eacute;essayer ult&eacute;rieurement, merci de votre ".
-
 
1759
		"compr&eacute;hension.</p>";
-
 
1760
	// Log error (useful to find the buggy server in a load balancing platform)
-
 
1761
	trigger_error("WikiNi : DB connection failed");
814
	exit;
1762
	exit;
815
}
1763
}
816
 
-
 
817
function compress_output($output) 
-
 
818
{ 
-
 
819
	return gzencode($output); 
-
 
820
} 
-
 
821
 
-
 
822
// Check if the browser supports gzip encoding, HTTP_ACCEPT_ENCODING 
-
 
823
if (strstr ($HTTP_SERVER_VARS['HTTP_ACCEPT_ENCODING'], 'gzip') && function_exists('gzencode') )
-
 
824
{ 
-
 
825
	// Start output buffering, and register compress_output() (see 
-
 
826
	// below) 
-
 
827
//	ob_start ("compress_output"); 
-
 
828
 
-
 
829
	// Tell the browser the content is compressed with gzip 
-
 
830
//	header ("Content-Encoding: gzip"); 
-
 
831
} 
-
 
832
 
1764
 
833
 
1765
 
834
// go!
1766
// go!
835
if (!isset($method)) $method='';
1767
if (!isset($method)) $method='';
-
 
1768
 
836
 
1769
 
837
// Security (quick hack)  : Check method syntax
1770
// Security (quick hack)  : Check method syntax
838
if (!(preg_match('#^[A-Za-z0-9_]*$#',$method))) {
1771
if (!(preg_match('#^[A-Za-z0-9_]*$#',$method))) {
839
	$method='';
1772
	$method='';
840
}
1773
}
841
 
-
 
842
include('tools/prepend.php');//$wiki->Run($page, $method);
1774
include('tools/prepend.php');//$wiki->Run($page, $method);
843
?>
1775
?>