Passed
Push — 1.10.x ( 918f1f...c8b126 )
by Yannick
419:13 queued 372:02
created
main/inc/lib/kses-0.2.2/oop/test.oop.kses.php 1 patch
Indentation   +503 added lines, -503 removed lines patch added patch discarded remove patch
@@ -1,507 +1,507 @@
 block discarded – undo
1 1
 <?php
2 2
 
3
-	//	This is a q&d program that shows some of the results of
4
-	//	running KSES.  If you have further questions, check the
5
-	//	current valid email address at http://chaos.org/contact/
6
-
7
-	//	Make sure we're in a usable PHP environment
8
-	if(substr(phpversion(), 0, 1) < 4)
9
-	{
10
-		define('KSESTEST_VER', 0);
11
-	}
12
-	elseif(substr(phpversion(), 0, 1) >= 5)
13
-	{
14
-		define('KSESTEST_VER', 5);
15
-	}
16
-	else
17
-	{
18
-		define('KSESTEST_VER', 4);
19
-	}
20
-
21
-	//	See if we're in command line or web
22
-	if($_SERVER["DOCUMENT_ROOT"] == "")
23
-	{
24
-		define('KSESTEST_ENV', 'CLI');
25
-	}
26
-	else
27
-	{
28
-		define('KSESTEST_ENV', 'WEB');
29
-	}
30
-
31
-	if(KSESTEST_VER == 0)
32
-	{
33
-		$message = array(
34
-			"Error: Not using a current version of PHP!",
35
-			"You are using PHP version " . phpversion() . ".",
36
-			"KSES Class version requires PHP4 or better.",
37
-			"KSES test program ending."
38
-			);
39
-
40
-		displayPage(
41
-			array("title" => "Error running KSES test", "message" => $message)
42
-		);
43
-
44
-		exit();
45
-	}
46
-
47
-	$include_file = "php" . KSESTEST_VER . ".class.kses.php";
48
-	if(file_exists($include_file) && is_readable($include_file))
49
-	{
50
-		include_once($include_file);
51
-	}
52
-	else
53
-	{
54
-		$message = array(
55
-			"Error:  Unable to find '" . $include_file . "'.",
56
-			"Please check your include path and make sure the file is available.",
57
-			"Path: " . ini_get('include_path')
58
-		);
59
-
60
-		displayPage(
61
-			array('title' => 'Unable to include ' . $include_file, 'message' => $message)
62
-		);
63
-
64
-		exit();
65
-	}
66
-
67
-	$kses_type = "kses" . KSESTEST_VER;
68
-	$myKses = new $kses_type;
69
-
70
-	$test_text = array();
71
-	$test_text = test1_protocols($myKses);
72
-	$test_text = array_merge($test_text, test1_html($myKses));
73
-	$test_text = array_merge($test_text, test1_kses($myKses));
74
-
75
-	displayPage(
76
-		array('title' => 'New Test', 'message' => $test_text)
77
-	);
78
-
79
-	function test1_kses(&$myKses)
80
-	{
81
-		$out = array(output_hr(), "Testing current configuration");
82
-
83
-		$test_tags = array(
84
-			'<a href="http://www.chaos.org/">www.chaos.org</a>',
85
-			'<a name="X">Short \'a name\' tag</a>',
86
-			'<td colspan="3" rowspan="5">Foo</td>',
87
-			'<td rowspan="2" class="mugwump" style="background-color: rgb(255, 204 204);">Bar</td>',
88
-			'<td nowrap>Very Long String running to 1000 characters...</td>',
89
-			'<td bgcolor="#00ff00" nowrap>Very Long String with a blue background</td>',
90
-			'<a href="proto1://www.foo.com">New protocol test</a>',
91
-			'<img src="proto2://www.foo.com" />',
92
-			'<a href="javascript:javascript:javascript:javascript:javascript:alert(\'Boo!\');">bleep</a>',
93
-			'<a href="proto4://abc.xyz.foo.com">Another new protocol</a>',
94
-			'<a href="proto9://foo.foo.foo.foo.foo.org/">Test of "proto9"</a>',
95
-			'<td width="75">Bar!</td>',
96
-			'<td width="200">Long Cell</td>'
97
-		);
98
-
99
-		$out_li = array();
100
-		// Keep only allowed HTML from the presumed 'form'.
101
-		foreach($test_tags as $tag)
102
-		{
103
-			$temp  = $myKses->Parse($tag);
104
-			$check = ($temp == $tag) ? true : false;
105
-			$text  = ($temp == $tag) ? 'pass' : 'fail';
106
-
107
-			$li_text  = output_testresult($check, $text) . output_newline();
108
-			$li_text .= "Input: &nbsp;" . output_translate($tag) . output_newline();
109
-			$li_text .= "Output: " . output_translate($temp);
110
-			if(KSESTEST_ENV == 'CLI')
111
-			{
112
-				$li_text .= output_newline();
113
-			}
114
-
115
-			array_push($out_li, output_code_wrap($li_text));
116
-		}
117
-
118
-		$out = array_merge($out, array(output_ul($out_li)));
119
-		array_push($out, output_hr());
120
-		array_push($out, "Testing is now finished.");
121
-		return $out;
122
-	}
123
-
124
-	function output_code_wrap($text)
125
-	{
126
-		if(KSESTEST_ENV == 'CLI')
127
-		{
128
-			return $text;
129
-		}
130
-		else
131
-		{
132
-			return "<code>\n$text<code>\n";
133
-		}
134
-	}
135
-
136
-	function output_translate($text)
137
-	{
138
-		if(KSESTEST_ENV == 'CLI')
139
-		{
140
-			return $text;
141
-		}
142
-		else
143
-		{
144
-			return htmlentities($text);
145
-		}
146
-	}
147
-
148
-	function output_testresult($pass = false, $text = "")
149
-	{
150
-		if(KSESTEST_ENV == 'CLI')
151
-		{
152
-			return '[' . $text . ']';
153
-		}
154
-		else
155
-		{
156
-			if($pass == true)
157
-			{
158
-				return '<span style="color: green;">[' . $text . ']</span>';
159
-			}
160
-			else
161
-			{
162
-				return '<span style="color: red;">[' . $text . ']</span>';
163
-			}
164
-		}
165
-	}
166
-
167
-	function output_spaces()
168
-	{
169
-		if(KSESTEST_ENV == 'WEB')
170
-		{
171
-			$out = "&nbsp;&nbsp;&nbsp;";
172
-		}
173
-		else
174
-		{
175
-			$out = "   ";
176
-		}
177
-
178
-		return $out;
179
-	}
180
-
181
-	function output_newline()
182
-	{
183
-		if(KSESTEST_ENV == 'WEB')
184
-		{
185
-			$out = "<br />\n";
186
-		}
187
-		else
188
-		{
189
-			$out = "\n";
190
-		}
191
-
192
-		return $out;
193
-	}
194
-
195
-	function displayPage($data = array())
196
-	{
197
-		$title   = ($data['title'] == '') ? 'No title' : $data['title'];
198
-		$message = ($data['message'] == '') ? array('No message') : $data['message'];
199
-
200
-		$out = "";
201
-
202
-		foreach($message as $text)
203
-		{
204
-			if(KSESTEST_ENV == 'WEB')
205
-			{
206
-				$header = "\t\t<h1>$title</h1>\n\t\t<hr />\n";
207
-				$out .= "\t\t<p>\n";
208
-				$out .= "\t\t\t$text\n";
209
-				$out .= "\t\t</p>\n";
210
-			}
211
-			else
212
-			{
213
-				$header = "$title\n" . str_repeat('-', 60) . "\n\n";
214
-				$out .= "\t$text\n\n";
215
-			}
216
-		}
217
-
218
-		if(KSESTEST_ENV == 'WEB')
219
-		{
220
-			echo "<html>\n";
221
-			echo "\t<head>\n";
222
-			echo "\t\t<title>$title</title>\n";
223
-			echo "\t</head>\n";
224
-			echo "\t<body>\n";
225
-			echo $header;
226
-			echo $out;
227
-			echo "\t</body>\n";
228
-			echo "</html>\n";
229
-		}
230
-		else
231
-		{
232
-			echo $header;
233
-			echo $out;
234
-		}
235
-	}
236
-
237
-	function output_hr()
238
-	{
239
-		if(KSESTEST_ENV == 'WEB')
240
-		{
241
-			return "\t\t\t<hr />\n";
242
-		}
243
-		else
244
-		{
245
-			return str_repeat(60, '-') . "\n";
246
-		}
247
-	}
248
-
249
-	function output_ul($data = array(), $padding = "")
250
-	{
251
-		if(!is_array($data) || count($data) < 1)
252
-		{
253
-			return "";
254
-		}
255
-
256
-		$text = "";
257
-		if(KSESTEST_ENV == 'WEB')
258
-		{
259
-			$text = "\t\t\t<ul>\n";
260
-			foreach($data as $li)
261
-			{
262
-				$text .= "\t\t\t\t<li>$li</li>\n";
263
-			}
264
-			$text .= "\t\t\t</ul>\n";
265
-		}
266
-		else
267
-		{
268
-			foreach($data as $li)
269
-			{
270
-				$text .= $padding . "   * $li\n";
271
-			}
272
-		}
273
-
274
-		return $text;
275
-	}
276
-
277
-	function test1_protocols(&$myKses)
278
-	{
279
-		$default_prots = $myKses->dumpProtocols();
280
-		$out_text = array();
281
-		if(count($default_prots) > 0)
282
-		{
283
-			array_push($out_text, "Initial protocols from KSES" . KSESTEST_VER . ":");
284
-			array_push($out_text, output_ul($default_prots));
285
-			array_push($out_text, output_hr());
286
-		}
287
-
288
-		$myKses->AddProtocols(array("proto1", "proto2:", "proto3"));   // Add a list of protocols
289
-		$myKses->AddProtocols("proto4:");  // Add a single protocol (Note ':' is optional at end)
290
-		$myKses->AddProtocol("proto9", "mystery:", "anarchy");
291
-		$myKses->AddProtocol("alpha", "beta", "gamma:");
292
-
293
-		$add_protocol  = "\t\t\t<ol>\n";
294
-		$add_protocol .= "\t\t\t\t" . '<li>$myKses->AddProtocols(array("proto1", "proto2:", "proto3"));</li>' . "\n";
295
-		$add_protocol .= "\t\t\t\t" . '<li>$myKses->AddProtocols("proto4:");</li>' . "\n";
296
-		$add_protocol .= "\t\t\t\t" . '<li>$myKses->AddProtocols("proto4:");</li>' . "\n";
297
-		$add_protocol .= "\t\t\t\t" . '<li>$myKses->AddProtocol("proto9", "mystery:", "anarchy");</li>' . "\n";
298
-		$add_protocol .= "\t\t\t\t" . '<li>$myKses->AddProtocol("alpha", "beta", "gamma:");</li>' . "\n";
299
-		$add_protocol .= "\t\t\t</ol>\n";
300
-
301
-		array_push($out_text, $add_protocol);
302
-
303
-		$new_prots = $myKses->dumpProtocols();
304
-		if(count($new_prots) > 0)
305
-		{
306
-			array_push($out_text, "New protocols from KSES" . KSESTEST_VER . " after using AddProtocol(s):");
307
-			array_push($out_text, output_ul($new_prots));
308
-			array_push($out_text, output_hr());
309
-		}
310
-
311
-		$myKses->RemoveProtocols(array("mystery", "anarchy:"));
312
-		$myKses->RemoveProtocols("alpha:");
313
-		$myKses->RemoveProtocol("beta:");
314
-		$myKses->RemoveProtocol("gamma");
315
-
316
-		$remove_protocol  = "\t\t\t<ol>\n";
317
-		$remove_protocol .= "\t\t\t\t" . '<li>$myKses->RemoveProtocols(array("mystery", "anarchy:"));</li>' . "\n";
318
-		$remove_protocol .= "\t\t\t\t" . '<li>$myKses->RemoveProtocols("alpha:");</li>' . "\n";
319
-		$remove_protocol .= "\t\t\t\t" . '<li>$myKses->RemoveProtocol("beta:");</li>' . "\n";
320
-		$remove_protocol .= "\t\t\t\t" . '<li>$myKses->RemoveProtocol("gamma");</li>' . "\n";
321
-		$remove_protocol .= "\t\t\t</ol>\n";
322
-		array_push($out_text, $remove_protocol);
323
-
324
-		$new_prots = $myKses->dumpProtocols();
325
-		if(count($new_prots) > 0)
326
-		{
327
-			array_push($out_text, "Resulting protocols from KSES" . KSESTEST_VER . " after using RemoveProtocol(s):");
328
-			array_push($out_text, output_ul($new_prots));
329
-			array_push($out_text, output_hr());
330
-		}
331
-
332
-		$myKses->SetProtocols(array("https", "gopher", "news"));
333
-		$set_protocol  = "\t\t\t<ol>\n";
334
-		$set_protocol .= "\t\t\t\t" . '<li>$myKses->SetProtocols(array("https", "gopher", "news"));</li>' . "\n";
335
-		$set_protocol .= "\t\t\t</ol>\n";
336
-		array_push($out_text, $set_protocol);
337
-
338
-		$new_prots = $myKses->dumpProtocols();
339
-		if(count($new_prots) > 0)
340
-		{
341
-			array_push($out_text, "Resulting protocols from KSES" . KSESTEST_VER . " after using SetProtocols:");
342
-			array_push($out_text, output_ul($new_prots));
343
-			array_push($out_text, output_hr());
344
-		}
345
-
346
-		//	Invisible reset
347
-		$myKses->SetProtocols(array("http", "proto1", "proto2", "proto9"));
348
-
349
-		return $out_text;
350
-	}
351
-
352
-	function test1_html(&$myKses)
353
-	{
354
-		$out = array();
355
-
356
-		//	Allows <p>|</p> tag
357
-		$myKses->AddHTML("p");
358
-
359
-		//	Allows 'a' tag with href|name attributes,
360
-		//	href has minlen of 10 chars, and maxlen of 25 chars
361
-		//	name has minlen of  2 chars
362
-		$myKses->AddHTML(
363
-			"a",
364
-			array(
365
-				"href" => array('maxlen' => 25, 'minlen' => 10),
366
-				"name" => array('minlen' => 2)
367
-			)
368
-		);
369
-
370
-		//	Allows 'td' tag with colspan|rowspan|class|style|width|nowrap attributes,
371
-		//		colspan has minval of   2       and maxval of 5
372
-		//		rowspan has minval of   3       and maxval of 6
373
-		//		class   has minlen of   1 char  and maxlen of   10 chars
374
-		//		style   has minlen of  10 chars and maxlen of 100 chars
375
-		//		width   has maxval of 100
376
-		//		nowrap  is valueless
377
-		$myKses->AddHTML(
378
-			"td",
379
-			array(
380
-				"colspan" => array('minval' =>   2, 'maxval' =>   5),
381
-				"rowspan" => array('minval' =>   3, 'maxval' =>   6),
382
-				"class"   => array("minlen" =>   1, 'maxlen' =>  10),
383
-				"width"   => array("maxval" => 100),
384
-				"style"   => array('minlen' =>  10, 'maxlen' => 100),
385
-				"nowrap"  => array('valueless' => 'y')
386
-			)
387
-		);
388
-
389
-		array_push($out, "Modifying HTML Tests:");
390
-		$code_text  = "<pre>\n";
391
-		$code_text .= "      //   Allows &lt;p&gt;|&lt;/p&gt; tag\n";
392
-		$code_text .= "      \$myKses-&gt;AddHTML(\"p\");\n";
393
-		$code_text .= "\n";
394
-		$code_text .= "      //   Allows 'a' tag with href|name attributes,\n";
395
-		$code_text .= "      //   href has minlen of 10 chars, and maxlen of 25 chars\n";
396
-		$code_text .= "      //   name has minlen of  2 chars\n";
397
-		$code_text .= "      \$myKses-&gt;AddHTML(\n";
398
-		$code_text .= "         \"a\",\n";
399
-		$code_text .= "         array(\n";
400
-		$code_text .= "            \"href\" =&gt; array('maxlen' =&gt; 25, 'minlen' =&gt; 10),\n";
401
-		$code_text .= "            \"name\" =&gt; array('minlen' =&gt; 2)\n";
402
-		$code_text .= "         )\n";
403
-		$code_text .= "      );\n";
404
-		$code_text .= "\n";
405
-		$code_text .= "      //   Allows 'td' tag with colspan|rowspan|class|style|width|nowrap attributes,\n";
406
-		$code_text .= "      //      colspan has minval of   2       and maxval of 5\n";
407
-		$code_text .= "      //      rowspan has minval of   3       and maxval of 6\n";
408
-		$code_text .= "      //      class   has minlen of   1 char  and maxlen of   10 chars\n";
409
-		$code_text .= "      //      style   has minlen of  10 chars and maxlen of 100 chars\n";
410
-		$code_text .= "      //      width   has maxval of 100\n";
411
-		$code_text .= "      //      nowrap  is valueless\n";
412
-		$code_text .= "      \$myKses-&gt;AddHTML(\n";
413
-		$code_text .= "         \"td\",\n";
414
-		$code_text .= "         array(\n";
415
-		$code_text .= "            \"colspan\" =&gt; array('minval' =&gt;   2, 'maxval' =&gt;   5),\n";
416
-		$code_text .= "            \"rowspan\" =&gt; array('minval' =&gt;   3, 'maxval' =&gt;   6),\n";
417
-		$code_text .= "            \"class\"   =&gt; array(\"minlen\" =&gt;   1, 'maxlen' =&gt;  10),\n";
418
-		$code_text .= "            \"width\"   =&gt; array(\"maxval\" =&gt; 100),\n";
419
-		$code_text .= "            \"style\"   =&gt; array('minlen' =&gt;  10, 'maxlen' =&gt; 100),\n";
420
-		$code_text .= "            \"nowrap\"  =&gt; array('valueless' =&gt; 'y')\n";
421
-		$code_text .= "         )\n";
422
-		$code_text .= "      );\n";
423
-		$code_text .= "</pre>\n";
424
-
425
-		array_push($out, $code_text);
426
-		array_push($out, output_hr());
427
-		array_push($out, "Net results:");
428
-
429
-		$out_elems = $myKses->DumpElements();
430
-		if(count($out_elems) > 0)
431
-		{
432
-			//array_push($out, "\t\t\t<ul>\n");
433
-			foreach($out_elems as $tag => $attr_data)
434
-			{
435
-				$out_li_elems = array();
436
-				$elem_text = "(X)HTML element $tag";
437
-				$allow = "";
438
-				if(isset($attr_data) && is_array($attr_data) && count($attr_data) > 0)
439
-				{
440
-					$allow = " allows attribute";
441
-					if(count($attr_data) > 1)
442
-					{
443
-						$allow .= "s";
444
-					}
445
-					$allow .= ":\n";
446
-				}
447
-
448
-				array_push($out_li_elems, "$elem_text$allow");
449
-
450
-				$attr_test_li = array();
451
-				if(isset($attr_data) && is_array($attr_data) && count($attr_data) > 0)
452
-				{
453
-					foreach($attr_data as $attr_name => $attr_tests)
454
-					{
455
-						$li_text = $attr_name;
456
-						if(isset($attr_tests) && count($attr_tests) > 0)
457
-						{
458
-							foreach($attr_tests as $test_name => $test_val)
459
-							{
460
-								switch($test_name)
461
-								{
462
-									case "maxlen":
463
-										$li_text .= " - maximum length of '" . $test_val . "' characters";
464
-										break;
465
-									case "minlen":
466
-										$li_text .= " - minimum length of '" . $test_val . "' characters";
467
-										break;
468
-									case "minval":
469
-										$li_text .= " - minimum value of '" . $test_val . "'";
470
-										break;
471
-									case "maxval":
472
-										$li_text .= " - maximum value of '" . $test_val . "'";
473
-										break;
474
-									case "valueless":
475
-										switch(strtolower($test_val))
476
-										{
477
-											case 'n':
478
-												$li_text .= " - must not be valueless";
479
-												break;
480
-											case 'y':
481
-												$li_text .= " - must be valueless";
482
-												break;
483
-											default:
484
-												break;
485
-										}
486
-										break;
487
-									default:
488
-										break;
489
-								}
490
-							}
491
-						}
492
-						array_push($attr_test_li, $li_text);
493
-					}
494
-					if(count($attr_test_li) > 0)
495
-					{
496
-						$attr_test_li = output_ul($attr_test_li, "   ");
497
-						$out_li_elems = array("$elem_text$allow$attr_test_li");
498
-					}
499
-				}
500
-				$out = array_merge($out, $out_li_elems);
501
-			}
502
-		}
503
-
504
-		return $out;
505
-	}
3
+    //	This is a q&d program that shows some of the results of
4
+    //	running KSES.  If you have further questions, check the
5
+    //	current valid email address at http://chaos.org/contact/
6
+
7
+    //	Make sure we're in a usable PHP environment
8
+    if(substr(phpversion(), 0, 1) < 4)
9
+    {
10
+        define('KSESTEST_VER', 0);
11
+    }
12
+    elseif(substr(phpversion(), 0, 1) >= 5)
13
+    {
14
+        define('KSESTEST_VER', 5);
15
+    }
16
+    else
17
+    {
18
+        define('KSESTEST_VER', 4);
19
+    }
20
+
21
+    //	See if we're in command line or web
22
+    if($_SERVER["DOCUMENT_ROOT"] == "")
23
+    {
24
+        define('KSESTEST_ENV', 'CLI');
25
+    }
26
+    else
27
+    {
28
+        define('KSESTEST_ENV', 'WEB');
29
+    }
30
+
31
+    if(KSESTEST_VER == 0)
32
+    {
33
+        $message = array(
34
+            "Error: Not using a current version of PHP!",
35
+            "You are using PHP version " . phpversion() . ".",
36
+            "KSES Class version requires PHP4 or better.",
37
+            "KSES test program ending."
38
+            );
39
+
40
+        displayPage(
41
+            array("title" => "Error running KSES test", "message" => $message)
42
+        );
43
+
44
+        exit();
45
+    }
46
+
47
+    $include_file = "php" . KSESTEST_VER . ".class.kses.php";
48
+    if(file_exists($include_file) && is_readable($include_file))
49
+    {
50
+        include_once($include_file);
51
+    }
52
+    else
53
+    {
54
+        $message = array(
55
+            "Error:  Unable to find '" . $include_file . "'.",
56
+            "Please check your include path and make sure the file is available.",
57
+            "Path: " . ini_get('include_path')
58
+        );
59
+
60
+        displayPage(
61
+            array('title' => 'Unable to include ' . $include_file, 'message' => $message)
62
+        );
63
+
64
+        exit();
65
+    }
66
+
67
+    $kses_type = "kses" . KSESTEST_VER;
68
+    $myKses = new $kses_type;
69
+
70
+    $test_text = array();
71
+    $test_text = test1_protocols($myKses);
72
+    $test_text = array_merge($test_text, test1_html($myKses));
73
+    $test_text = array_merge($test_text, test1_kses($myKses));
74
+
75
+    displayPage(
76
+        array('title' => 'New Test', 'message' => $test_text)
77
+    );
78
+
79
+    function test1_kses(&$myKses)
80
+    {
81
+        $out = array(output_hr(), "Testing current configuration");
82
+
83
+        $test_tags = array(
84
+            '<a href="http://www.chaos.org/">www.chaos.org</a>',
85
+            '<a name="X">Short \'a name\' tag</a>',
86
+            '<td colspan="3" rowspan="5">Foo</td>',
87
+            '<td rowspan="2" class="mugwump" style="background-color: rgb(255, 204 204);">Bar</td>',
88
+            '<td nowrap>Very Long String running to 1000 characters...</td>',
89
+            '<td bgcolor="#00ff00" nowrap>Very Long String with a blue background</td>',
90
+            '<a href="proto1://www.foo.com">New protocol test</a>',
91
+            '<img src="proto2://www.foo.com" />',
92
+            '<a href="javascript:javascript:javascript:javascript:javascript:alert(\'Boo!\');">bleep</a>',
93
+            '<a href="proto4://abc.xyz.foo.com">Another new protocol</a>',
94
+            '<a href="proto9://foo.foo.foo.foo.foo.org/">Test of "proto9"</a>',
95
+            '<td width="75">Bar!</td>',
96
+            '<td width="200">Long Cell</td>'
97
+        );
98
+
99
+        $out_li = array();
100
+        // Keep only allowed HTML from the presumed 'form'.
101
+        foreach($test_tags as $tag)
102
+        {
103
+            $temp  = $myKses->Parse($tag);
104
+            $check = ($temp == $tag) ? true : false;
105
+            $text  = ($temp == $tag) ? 'pass' : 'fail';
106
+
107
+            $li_text  = output_testresult($check, $text) . output_newline();
108
+            $li_text .= "Input: &nbsp;" . output_translate($tag) . output_newline();
109
+            $li_text .= "Output: " . output_translate($temp);
110
+            if(KSESTEST_ENV == 'CLI')
111
+            {
112
+                $li_text .= output_newline();
113
+            }
114
+
115
+            array_push($out_li, output_code_wrap($li_text));
116
+        }
117
+
118
+        $out = array_merge($out, array(output_ul($out_li)));
119
+        array_push($out, output_hr());
120
+        array_push($out, "Testing is now finished.");
121
+        return $out;
122
+    }
123
+
124
+    function output_code_wrap($text)
125
+    {
126
+        if(KSESTEST_ENV == 'CLI')
127
+        {
128
+            return $text;
129
+        }
130
+        else
131
+        {
132
+            return "<code>\n$text<code>\n";
133
+        }
134
+    }
135
+
136
+    function output_translate($text)
137
+    {
138
+        if(KSESTEST_ENV == 'CLI')
139
+        {
140
+            return $text;
141
+        }
142
+        else
143
+        {
144
+            return htmlentities($text);
145
+        }
146
+    }
147
+
148
+    function output_testresult($pass = false, $text = "")
149
+    {
150
+        if(KSESTEST_ENV == 'CLI')
151
+        {
152
+            return '[' . $text . ']';
153
+        }
154
+        else
155
+        {
156
+            if($pass == true)
157
+            {
158
+                return '<span style="color: green;">[' . $text . ']</span>';
159
+            }
160
+            else
161
+            {
162
+                return '<span style="color: red;">[' . $text . ']</span>';
163
+            }
164
+        }
165
+    }
166
+
167
+    function output_spaces()
168
+    {
169
+        if(KSESTEST_ENV == 'WEB')
170
+        {
171
+            $out = "&nbsp;&nbsp;&nbsp;";
172
+        }
173
+        else
174
+        {
175
+            $out = "   ";
176
+        }
177
+
178
+        return $out;
179
+    }
180
+
181
+    function output_newline()
182
+    {
183
+        if(KSESTEST_ENV == 'WEB')
184
+        {
185
+            $out = "<br />\n";
186
+        }
187
+        else
188
+        {
189
+            $out = "\n";
190
+        }
191
+
192
+        return $out;
193
+    }
194
+
195
+    function displayPage($data = array())
196
+    {
197
+        $title   = ($data['title'] == '') ? 'No title' : $data['title'];
198
+        $message = ($data['message'] == '') ? array('No message') : $data['message'];
199
+
200
+        $out = "";
201
+
202
+        foreach($message as $text)
203
+        {
204
+            if(KSESTEST_ENV == 'WEB')
205
+            {
206
+                $header = "\t\t<h1>$title</h1>\n\t\t<hr />\n";
207
+                $out .= "\t\t<p>\n";
208
+                $out .= "\t\t\t$text\n";
209
+                $out .= "\t\t</p>\n";
210
+            }
211
+            else
212
+            {
213
+                $header = "$title\n" . str_repeat('-', 60) . "\n\n";
214
+                $out .= "\t$text\n\n";
215
+            }
216
+        }
217
+
218
+        if(KSESTEST_ENV == 'WEB')
219
+        {
220
+            echo "<html>\n";
221
+            echo "\t<head>\n";
222
+            echo "\t\t<title>$title</title>\n";
223
+            echo "\t</head>\n";
224
+            echo "\t<body>\n";
225
+            echo $header;
226
+            echo $out;
227
+            echo "\t</body>\n";
228
+            echo "</html>\n";
229
+        }
230
+        else
231
+        {
232
+            echo $header;
233
+            echo $out;
234
+        }
235
+    }
236
+
237
+    function output_hr()
238
+    {
239
+        if(KSESTEST_ENV == 'WEB')
240
+        {
241
+            return "\t\t\t<hr />\n";
242
+        }
243
+        else
244
+        {
245
+            return str_repeat(60, '-') . "\n";
246
+        }
247
+    }
248
+
249
+    function output_ul($data = array(), $padding = "")
250
+    {
251
+        if(!is_array($data) || count($data) < 1)
252
+        {
253
+            return "";
254
+        }
255
+
256
+        $text = "";
257
+        if(KSESTEST_ENV == 'WEB')
258
+        {
259
+            $text = "\t\t\t<ul>\n";
260
+            foreach($data as $li)
261
+            {
262
+                $text .= "\t\t\t\t<li>$li</li>\n";
263
+            }
264
+            $text .= "\t\t\t</ul>\n";
265
+        }
266
+        else
267
+        {
268
+            foreach($data as $li)
269
+            {
270
+                $text .= $padding . "   * $li\n";
271
+            }
272
+        }
273
+
274
+        return $text;
275
+    }
276
+
277
+    function test1_protocols(&$myKses)
278
+    {
279
+        $default_prots = $myKses->dumpProtocols();
280
+        $out_text = array();
281
+        if(count($default_prots) > 0)
282
+        {
283
+            array_push($out_text, "Initial protocols from KSES" . KSESTEST_VER . ":");
284
+            array_push($out_text, output_ul($default_prots));
285
+            array_push($out_text, output_hr());
286
+        }
287
+
288
+        $myKses->AddProtocols(array("proto1", "proto2:", "proto3"));   // Add a list of protocols
289
+        $myKses->AddProtocols("proto4:");  // Add a single protocol (Note ':' is optional at end)
290
+        $myKses->AddProtocol("proto9", "mystery:", "anarchy");
291
+        $myKses->AddProtocol("alpha", "beta", "gamma:");
292
+
293
+        $add_protocol  = "\t\t\t<ol>\n";
294
+        $add_protocol .= "\t\t\t\t" . '<li>$myKses->AddProtocols(array("proto1", "proto2:", "proto3"));</li>' . "\n";
295
+        $add_protocol .= "\t\t\t\t" . '<li>$myKses->AddProtocols("proto4:");</li>' . "\n";
296
+        $add_protocol .= "\t\t\t\t" . '<li>$myKses->AddProtocols("proto4:");</li>' . "\n";
297
+        $add_protocol .= "\t\t\t\t" . '<li>$myKses->AddProtocol("proto9", "mystery:", "anarchy");</li>' . "\n";
298
+        $add_protocol .= "\t\t\t\t" . '<li>$myKses->AddProtocol("alpha", "beta", "gamma:");</li>' . "\n";
299
+        $add_protocol .= "\t\t\t</ol>\n";
300
+
301
+        array_push($out_text, $add_protocol);
302
+
303
+        $new_prots = $myKses->dumpProtocols();
304
+        if(count($new_prots) > 0)
305
+        {
306
+            array_push($out_text, "New protocols from KSES" . KSESTEST_VER . " after using AddProtocol(s):");
307
+            array_push($out_text, output_ul($new_prots));
308
+            array_push($out_text, output_hr());
309
+        }
310
+
311
+        $myKses->RemoveProtocols(array("mystery", "anarchy:"));
312
+        $myKses->RemoveProtocols("alpha:");
313
+        $myKses->RemoveProtocol("beta:");
314
+        $myKses->RemoveProtocol("gamma");
315
+
316
+        $remove_protocol  = "\t\t\t<ol>\n";
317
+        $remove_protocol .= "\t\t\t\t" . '<li>$myKses->RemoveProtocols(array("mystery", "anarchy:"));</li>' . "\n";
318
+        $remove_protocol .= "\t\t\t\t" . '<li>$myKses->RemoveProtocols("alpha:");</li>' . "\n";
319
+        $remove_protocol .= "\t\t\t\t" . '<li>$myKses->RemoveProtocol("beta:");</li>' . "\n";
320
+        $remove_protocol .= "\t\t\t\t" . '<li>$myKses->RemoveProtocol("gamma");</li>' . "\n";
321
+        $remove_protocol .= "\t\t\t</ol>\n";
322
+        array_push($out_text, $remove_protocol);
323
+
324
+        $new_prots = $myKses->dumpProtocols();
325
+        if(count($new_prots) > 0)
326
+        {
327
+            array_push($out_text, "Resulting protocols from KSES" . KSESTEST_VER . " after using RemoveProtocol(s):");
328
+            array_push($out_text, output_ul($new_prots));
329
+            array_push($out_text, output_hr());
330
+        }
331
+
332
+        $myKses->SetProtocols(array("https", "gopher", "news"));
333
+        $set_protocol  = "\t\t\t<ol>\n";
334
+        $set_protocol .= "\t\t\t\t" . '<li>$myKses->SetProtocols(array("https", "gopher", "news"));</li>' . "\n";
335
+        $set_protocol .= "\t\t\t</ol>\n";
336
+        array_push($out_text, $set_protocol);
337
+
338
+        $new_prots = $myKses->dumpProtocols();
339
+        if(count($new_prots) > 0)
340
+        {
341
+            array_push($out_text, "Resulting protocols from KSES" . KSESTEST_VER . " after using SetProtocols:");
342
+            array_push($out_text, output_ul($new_prots));
343
+            array_push($out_text, output_hr());
344
+        }
345
+
346
+        //	Invisible reset
347
+        $myKses->SetProtocols(array("http", "proto1", "proto2", "proto9"));
348
+
349
+        return $out_text;
350
+    }
351
+
352
+    function test1_html(&$myKses)
353
+    {
354
+        $out = array();
355
+
356
+        //	Allows <p>|</p> tag
357
+        $myKses->AddHTML("p");
358
+
359
+        //	Allows 'a' tag with href|name attributes,
360
+        //	href has minlen of 10 chars, and maxlen of 25 chars
361
+        //	name has minlen of  2 chars
362
+        $myKses->AddHTML(
363
+            "a",
364
+            array(
365
+                "href" => array('maxlen' => 25, 'minlen' => 10),
366
+                "name" => array('minlen' => 2)
367
+            )
368
+        );
369
+
370
+        //	Allows 'td' tag with colspan|rowspan|class|style|width|nowrap attributes,
371
+        //		colspan has minval of   2       and maxval of 5
372
+        //		rowspan has minval of   3       and maxval of 6
373
+        //		class   has minlen of   1 char  and maxlen of   10 chars
374
+        //		style   has minlen of  10 chars and maxlen of 100 chars
375
+        //		width   has maxval of 100
376
+        //		nowrap  is valueless
377
+        $myKses->AddHTML(
378
+            "td",
379
+            array(
380
+                "colspan" => array('minval' =>   2, 'maxval' =>   5),
381
+                "rowspan" => array('minval' =>   3, 'maxval' =>   6),
382
+                "class"   => array("minlen" =>   1, 'maxlen' =>  10),
383
+                "width"   => array("maxval" => 100),
384
+                "style"   => array('minlen' =>  10, 'maxlen' => 100),
385
+                "nowrap"  => array('valueless' => 'y')
386
+            )
387
+        );
388
+
389
+        array_push($out, "Modifying HTML Tests:");
390
+        $code_text  = "<pre>\n";
391
+        $code_text .= "      //   Allows &lt;p&gt;|&lt;/p&gt; tag\n";
392
+        $code_text .= "      \$myKses-&gt;AddHTML(\"p\");\n";
393
+        $code_text .= "\n";
394
+        $code_text .= "      //   Allows 'a' tag with href|name attributes,\n";
395
+        $code_text .= "      //   href has minlen of 10 chars, and maxlen of 25 chars\n";
396
+        $code_text .= "      //   name has minlen of  2 chars\n";
397
+        $code_text .= "      \$myKses-&gt;AddHTML(\n";
398
+        $code_text .= "         \"a\",\n";
399
+        $code_text .= "         array(\n";
400
+        $code_text .= "            \"href\" =&gt; array('maxlen' =&gt; 25, 'minlen' =&gt; 10),\n";
401
+        $code_text .= "            \"name\" =&gt; array('minlen' =&gt; 2)\n";
402
+        $code_text .= "         )\n";
403
+        $code_text .= "      );\n";
404
+        $code_text .= "\n";
405
+        $code_text .= "      //   Allows 'td' tag with colspan|rowspan|class|style|width|nowrap attributes,\n";
406
+        $code_text .= "      //      colspan has minval of   2       and maxval of 5\n";
407
+        $code_text .= "      //      rowspan has minval of   3       and maxval of 6\n";
408
+        $code_text .= "      //      class   has minlen of   1 char  and maxlen of   10 chars\n";
409
+        $code_text .= "      //      style   has minlen of  10 chars and maxlen of 100 chars\n";
410
+        $code_text .= "      //      width   has maxval of 100\n";
411
+        $code_text .= "      //      nowrap  is valueless\n";
412
+        $code_text .= "      \$myKses-&gt;AddHTML(\n";
413
+        $code_text .= "         \"td\",\n";
414
+        $code_text .= "         array(\n";
415
+        $code_text .= "            \"colspan\" =&gt; array('minval' =&gt;   2, 'maxval' =&gt;   5),\n";
416
+        $code_text .= "            \"rowspan\" =&gt; array('minval' =&gt;   3, 'maxval' =&gt;   6),\n";
417
+        $code_text .= "            \"class\"   =&gt; array(\"minlen\" =&gt;   1, 'maxlen' =&gt;  10),\n";
418
+        $code_text .= "            \"width\"   =&gt; array(\"maxval\" =&gt; 100),\n";
419
+        $code_text .= "            \"style\"   =&gt; array('minlen' =&gt;  10, 'maxlen' =&gt; 100),\n";
420
+        $code_text .= "            \"nowrap\"  =&gt; array('valueless' =&gt; 'y')\n";
421
+        $code_text .= "         )\n";
422
+        $code_text .= "      );\n";
423
+        $code_text .= "</pre>\n";
424
+
425
+        array_push($out, $code_text);
426
+        array_push($out, output_hr());
427
+        array_push($out, "Net results:");
428
+
429
+        $out_elems = $myKses->DumpElements();
430
+        if(count($out_elems) > 0)
431
+        {
432
+            //array_push($out, "\t\t\t<ul>\n");
433
+            foreach($out_elems as $tag => $attr_data)
434
+            {
435
+                $out_li_elems = array();
436
+                $elem_text = "(X)HTML element $tag";
437
+                $allow = "";
438
+                if(isset($attr_data) && is_array($attr_data) && count($attr_data) > 0)
439
+                {
440
+                    $allow = " allows attribute";
441
+                    if(count($attr_data) > 1)
442
+                    {
443
+                        $allow .= "s";
444
+                    }
445
+                    $allow .= ":\n";
446
+                }
447
+
448
+                array_push($out_li_elems, "$elem_text$allow");
449
+
450
+                $attr_test_li = array();
451
+                if(isset($attr_data) && is_array($attr_data) && count($attr_data) > 0)
452
+                {
453
+                    foreach($attr_data as $attr_name => $attr_tests)
454
+                    {
455
+                        $li_text = $attr_name;
456
+                        if(isset($attr_tests) && count($attr_tests) > 0)
457
+                        {
458
+                            foreach($attr_tests as $test_name => $test_val)
459
+                            {
460
+                                switch($test_name)
461
+                                {
462
+                                    case "maxlen":
463
+                                        $li_text .= " - maximum length of '" . $test_val . "' characters";
464
+                                        break;
465
+                                    case "minlen":
466
+                                        $li_text .= " - minimum length of '" . $test_val . "' characters";
467
+                                        break;
468
+                                    case "minval":
469
+                                        $li_text .= " - minimum value of '" . $test_val . "'";
470
+                                        break;
471
+                                    case "maxval":
472
+                                        $li_text .= " - maximum value of '" . $test_val . "'";
473
+                                        break;
474
+                                    case "valueless":
475
+                                        switch(strtolower($test_val))
476
+                                        {
477
+                                            case 'n':
478
+                                                $li_text .= " - must not be valueless";
479
+                                                break;
480
+                                            case 'y':
481
+                                                $li_text .= " - must be valueless";
482
+                                                break;
483
+                                            default:
484
+                                                break;
485
+                                        }
486
+                                        break;
487
+                                    default:
488
+                                        break;
489
+                                }
490
+                            }
491
+                        }
492
+                        array_push($attr_test_li, $li_text);
493
+                    }
494
+                    if(count($attr_test_li) > 0)
495
+                    {
496
+                        $attr_test_li = output_ul($attr_test_li, "   ");
497
+                        $out_li_elems = array("$elem_text$allow$attr_test_li");
498
+                    }
499
+                }
500
+                $out = array_merge($out, $out_li_elems);
501
+            }
502
+        }
503
+
504
+        return $out;
505
+    }
506 506
 
507 507
 ?>
508 508
\ No newline at end of file
Please login to merge, or discard this patch.
main/inc/lib/kses-0.2.2/oop/php4.class.kses.php 1 patch
Indentation   +1137 added lines, -1137 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php
2
-	/*
2
+    /*
3 3
 	 * ==========================================================================================
4 4
 	 *
5 5
 	 * This program is free software and open source software; you can redistribute
@@ -20,1143 +20,1143 @@  discard block
 block discarded – undo
20 20
 	 * ==========================================================================================
21 21
 	 */
22 22
 
23
-	/**
24
-	*	Class file for PHP4 OOP version of kses
25
-	*
26
-	*	This is an updated version of kses to work with PHP4 that works under E_STRICT.
27
-	*
28
-	*	This upgrade provides the following:
29
-	*	+ Version number synced to procedural version number
30
-	*	+ PHPdoc style documentation has been added to the class.  See http://www.phpdoc.org/ for more info.
31
-	*	+ Some methods are now deprecated due to nomenclature style change.  See method documentation for specifics.
32
-	*	+ Kses4 now works in E_STRICT
33
-	*	+ Addition of methods AddProtocols(), filterKsestextHook(), RemoveProtocol() and RemoveProtocols()
34
-	*	+ Deprecated _hook(), Protocols()
35
-	*	+ Integrated code from kses 0.2.2 into class.
36
-	*	+ Added methods DumpProtocols(), DumpMethods()
37
-	*
38
-	*	@package    kses
39
-	*	@subpackage kses4
40
-	*/
41
-
42
-	if(substr(phpversion(), 0, 1) < 4)
43
-	{
44
-		die("Class kses requires PHP 4 or higher.");
45
-	}
46
-
47
-	/**
48
-	*	Only install KSES4 once
49
-	*/
50
-	if(!defined('KSES_CLASS_PHP4'))
51
-	{
52
-		define('KSES_CLASS_PHP4', true);
53
-
54
-	/**
55
-	*	Kses strips evil scripts!
56
-	*
57
-	*	This class provides the capability for removing unwanted HTML/XHTML, attributes from
58
-	*	tags, and protocols contained in links.  The net result is a much more powerful tool
59
-	*	than the PHP internal strip_tags()
60
-	*
61
-	*	This is a fork of a slick piece of procedural code called 'kses' written by Ulf Harnhammar
62
-	*	The entire set of functions was wrapped in a PHP object with some internal modifications
63
-	*	by Richard Vasquez (http://www.chaos.org/) 7/25/2003
64
-	*
65
-	*	This upgrade provides the following:
66
-	*	+ Version number synced to procedural version number
67
-	*	+ PHPdoc style documentation has been added to the class.  See http://www.phpdoc.org/ for more info.
68
-	*	+ Some methods are now deprecated due to nomenclature style change.  See method documentation for specifics.
69
-	*	+ Kses4 now works in E_STRICT
70
-	*	+ Addition of methods AddProtocols(), filterKsestextHook(), RemoveProtocol(), RemoveProtocols() and SetProtocols()
71
-	*	+ Deprecated _hook(), Protocols()
72
-	*	+ Integrated code from kses 0.2.2 into class.
73
-	*
74
-	*	@author     Richard R. V�squez, Jr. (Original procedural code by Ulf H�rnhammar)
75
-	*	@link       http://sourceforge.net/projects/kses/ Home Page for Kses
76
-	*	@link       http://chaos.org/contact/ Contact page with current email address for Richard Vasquez
77
-	*	@copyright  Richard R. V�squez, Jr. 2003-2005
78
-	*	@version    PHP4 OOP 0.2.2
79
-	*	@license    http://www.gnu.org/licenses/gpl.html GNU Public License
80
-	*	@package    kses
81
-	*/
82
-		class kses4
83
-		{
84
-			/**#@+
23
+    /**
24
+     *	Class file for PHP4 OOP version of kses
25
+     *
26
+     *	This is an updated version of kses to work with PHP4 that works under E_STRICT.
27
+     *
28
+     *	This upgrade provides the following:
29
+     *	+ Version number synced to procedural version number
30
+     *	+ PHPdoc style documentation has been added to the class.  See http://www.phpdoc.org/ for more info.
31
+     *	+ Some methods are now deprecated due to nomenclature style change.  See method documentation for specifics.
32
+     *	+ Kses4 now works in E_STRICT
33
+     *	+ Addition of methods AddProtocols(), filterKsestextHook(), RemoveProtocol() and RemoveProtocols()
34
+     *	+ Deprecated _hook(), Protocols()
35
+     *	+ Integrated code from kses 0.2.2 into class.
36
+     *	+ Added methods DumpProtocols(), DumpMethods()
37
+     *
38
+     *	@package    kses
39
+     *	@subpackage kses4
40
+     */
41
+
42
+    if(substr(phpversion(), 0, 1) < 4)
43
+    {
44
+        die("Class kses requires PHP 4 or higher.");
45
+    }
46
+
47
+    /**
48
+     *	Only install KSES4 once
49
+     */
50
+    if(!defined('KSES_CLASS_PHP4'))
51
+    {
52
+        define('KSES_CLASS_PHP4', true);
53
+
54
+    /**
55
+     *	Kses strips evil scripts!
56
+     *
57
+     *	This class provides the capability for removing unwanted HTML/XHTML, attributes from
58
+     *	tags, and protocols contained in links.  The net result is a much more powerful tool
59
+     *	than the PHP internal strip_tags()
60
+     *
61
+     *	This is a fork of a slick piece of procedural code called 'kses' written by Ulf Harnhammar
62
+     *	The entire set of functions was wrapped in a PHP object with some internal modifications
63
+     *	by Richard Vasquez (http://www.chaos.org/) 7/25/2003
64
+     *
65
+     *	This upgrade provides the following:
66
+     *	+ Version number synced to procedural version number
67
+     *	+ PHPdoc style documentation has been added to the class.  See http://www.phpdoc.org/ for more info.
68
+     *	+ Some methods are now deprecated due to nomenclature style change.  See method documentation for specifics.
69
+     *	+ Kses4 now works in E_STRICT
70
+     *	+ Addition of methods AddProtocols(), filterKsestextHook(), RemoveProtocol(), RemoveProtocols() and SetProtocols()
71
+     *	+ Deprecated _hook(), Protocols()
72
+     *	+ Integrated code from kses 0.2.2 into class.
73
+     *
74
+     *	@author     Richard R. V�squez, Jr. (Original procedural code by Ulf H�rnhammar)
75
+     *	@link       http://sourceforge.net/projects/kses/ Home Page for Kses
76
+     *	@link       http://chaos.org/contact/ Contact page with current email address for Richard Vasquez
77
+     *	@copyright  Richard R. V�squez, Jr. 2003-2005
78
+     *	@version    PHP4 OOP 0.2.2
79
+     *	@license    http://www.gnu.org/licenses/gpl.html GNU Public License
80
+     *	@package    kses
81
+     */
82
+        class kses4
83
+        {
84
+            /**#@+
85 85
 			 *	@access private
86 86
 			 *	@var array
87 87
 			 */
88
-			var $allowed_protocols = array();
89
-			var $allowed_html      = array();
90
-			/**#@-*/
91
-
92
-			/**
93
-			 *	Constructor for kses.
94
-			 *
95
-			 *	This sets a default collection of protocols allowed in links, and creates an
96
-			 *	empty set of allowed HTML tags.
97
-			 *	@since PHP4 OOP 0.0.1
98
-			 */
99
-			function kses4()
100
-			{
101
-				/**
102
-				 *	You could add protocols such as ftp, new, gopher, mailto, irc, etc.
103
-				 *
104
-				 *	The base values the original kses provided were:
105
-				 *		'http', 'https', 'ftp', 'news', 'nntp', 'telnet', 'gopher', 'mailto'
106
-				 */
107
-				$this->allowed_protocols = array('http', 'ftp', 'mailto');
108
-				$this->allowed_html      = array();
109
-			}
110
-
111
-			/**
112
-			 *	Basic task of kses - parses $string and strips it as required.
113
-			 *
114
-			 *	This method strips all the disallowed (X)HTML tags, attributes
115
-			 *	and protocols from the input $string.
116
-			 *
117
-			 *	@access public
118
-			 *	@param string $string String to be stripped of 'evil scripts'
119
-			 *	@return string The stripped string
120
-			 *	@since PHP4 OOP 0.2.1
121
-			 */
122
-			function Parse($string = "")
123
-			{
124
-				if (get_magic_quotes_gpc())
125
-				{
126
-					$string = stripslashes($string);
127
-				}
128
-				$string = $this->_no_null($string);
129
-				$string = $this->_js_entities($string);
130
-				$string = $this->_normalize_entities($string);
131
-				$string = $this->filterKsesTextHook($string);
132
-				return    $this->_split($string);
133
-			}
134
-
135
-			/**
136
-			 *	Allows for single/batch addition of protocols
137
-			 *
138
-			 *	This method accepts one argument that can be either a string
139
-			 *	or an array of strings.  Invalid data will be ignored.
140
-			 *
141
-			 *	The argument will be processed, and each string will be added
142
-			 *	via AddProtocol().
143
-			 *
144
-			 *	@access public
145
-			 *	@param mixed , A string or array of protocols that will be added to the internal list of allowed protocols.
146
-			 *	@return bool Status of adding valid protocols.
147
-			 *	@see AddProtocol()
148
-			 *	@since PHP4 OOP 0.2.1
149
-			 */
150
-			function AddProtocols()
151
-			{
152
-				$c_args = func_num_args();
153
-				if($c_args != 1)
154
-				{
155
-					trigger_error("kses4::AddProtocols() did not receive an argument.", E_USER_WARNING);
156
-					return false;
157
-				}
158
-
159
-				$protocol_data = func_get_arg(0);
160
-
161
-				if(is_array($protocol_data) && count($protocol_data) > 0)
162
-				{
163
-					foreach($protocol_data as $protocol)
164
-					{
165
-						$this->AddProtocol($protocol);
166
-					}
167
-					return true;
168
-				}
169
-				elseif(is_string($protocol_data))
170
-				{
171
-					$this->AddProtocol($protocol_data);
172
-					return true;
173
-				}
174
-				else
175
-				{
176
-					trigger_error("kses4::AddProtocols() did not receive a string or an array.", E_USER_WARNING);
177
-					return false;
178
-				}
179
-			}
180
-
181
-			/**
182
-			 *	Allows for single/batch addition of protocols
183
-			 *
184
-			 *	@deprecated Use AddProtocols()
185
-			 *	@see AddProtocols()
186
-			 *	@return bool
187
-			 *	@since PHP4 OOP 0.0.1
188
-			 */
189
-			function Protocols()
190
-			{
191
-				$c_args = func_num_args();
192
-				if($c_args != 1)
193
-				{
194
-					trigger_error("kses4::Protocols() did not receive an argument.", E_USER_WARNING);
195
-					return false;
196
-				}
197
-
198
-				return $this->AddProtocols(func_get_arg(0));
199
-			}
200
-
201
-			/**
202
-			 *	Adds a single protocol to $this->allowed_protocols.
203
-			 *
204
-			 *	This method accepts a string argument and adds it to
205
-			 *	the list of allowed protocols to keep when performing
206
-			 *	Parse().
207
-			 *
208
-			 *	@access public
209
-			 *	@param string $protocol The name of the protocol to be added.
210
-			 *	@return bool Status of adding valid protocol.
211
-			 *	@since PHP4 OOP 0.0.1
212
-			 */
213
-			function AddProtocol($protocol = "")
214
-			{
215
-				if(!is_string($protocol))
216
-				{
217
-					trigger_error("kses4::AddProtocol() requires a string.", E_USER_WARNING);
218
-					return false;
219
-				}
220
-
221
-				$protocol = strtolower(trim($protocol));
222
-				if($protocol == "")
223
-				{
224
-					trigger_error("kses4::AddProtocol() tried to add an empty/NULL protocol.", E_USER_WARNING);
225
-					return false;
226
-				}
227
-
228
-				// Remove any inadvertent ':' at the end of the protocol.
229
-				if(substr($protocol, strlen($protocol) - 1, 1) == ":")
230
-				{
231
-					$protocol = substr($protocol, 0, strlen($protocol) - 1);
232
-				}
233
-
234
-				if(!in_array($protocol, $this->allowed_protocols))
235
-				{
236
-					array_push($this->allowed_protocols, $protocol);
237
-					sort($this->allowed_protocols);
238
-				}
239
-				return true;
240
-			}
241
-
242
-			/**
243
-			 *	Allows for single/batch replacement of protocols
244
-			 *
245
-			 *	This method accepts one argument that can be either a string
246
-			 *	or an array of strings.  Invalid data will be ignored.
247
-			 *
248
-			 *	Existing protocols will be removed, then the argument will be
249
-			 *	processed, and each string will be added via AddProtocol().
250
-			 *
251
-			 *	@access public
252
-			 *	@param mixed , A string or array of protocols that will be the new internal list of allowed protocols.
253
-			 *	@return bool Status of replacing valid protocols.
254
-			 *	@since PHP4 OOP 0.2.2
255
-			 *	@see AddProtocol()
256
-			 */
257
-			function SetProtocols()
258
-			{
259
-				$c_args = func_num_args();
260
-				if($c_args != 1)
261
-				{
262
-					trigger_error("kses4::SetProtocols() did not receive an argument.", E_USER_WARNING);
263
-					return false;
264
-				}
265
-
266
-				$protocol_data = func_get_arg(0);
267
-
268
-				if(is_array($protocol_data) && count($protocol_data) > 0)
269
-				{
270
-					$this->allowed_protocols = array();
271
-					foreach($protocol_data as $protocol)
272
-					{
273
-						$this->AddProtocol($protocol);
274
-					}
275
-					return true;
276
-				}
277
-				elseif(is_string($protocol_data))
278
-				{
279
-					$this->allowed_protocols = array();
280
-					$this->AddProtocol($protocol_data);
281
-					return true;
282
-				}
283
-				else
284
-				{
285
-					trigger_error("kses4::SetProtocols() did not receive a string or an array.", E_USER_WARNING);
286
-					return false;
287
-				}
288
-			}
289
-
290
-			/**
291
-			 *	Raw dump of allowed protocols
292
-			 *
293
-			 *	This returns an indexed array of allowed protocols for a particular KSES
294
-			 *	instantiation.
295
-			 *
296
-			 *	@access public
297
-			 *	@return array The list of allowed protocols.
298
-			 *	@since PHP4 OOP 0.2.2
299
-			 */
300
-			function DumpProtocols()
301
-			{
302
-				return $this->allowed_protocols;
303
-			}
304
-
305
-			/**
306
-			 *	Raw dump of allowed (X)HTML elements
307
-			 *
308
-			 *	This returns an indexed array of allowed (X)HTML elements and attributes
309
-			 *	for a particular KSES instantiation.
310
-			 *
311
-			 *	@access public
312
-			 *	@return array The list of allowed elements.
313
-			 *	@since PHP4 OOP 0.2.2
314
-			 */
315
-			function DumpElements()
316
-			{
317
-				return $this->allowed_html;
318
-			}
319
-
320
-			/**
321
-			 *	Adds valid (X)HTML with corresponding attributes that will be kept when stripping 'evil scripts'.
322
-			 *
323
-			 *	This method accepts one argument that can be either a string
324
-			 *	or an array of strings.  Invalid data will be ignored.
325
-			 *
326
-			 *	@access public
327
-			 *	@param string $tag (X)HTML tag that will be allowed after stripping text.
328
-			 *	@param array $attribs Associative array of allowed attributes - key => attribute name - value => attribute parameter
329
-			 *	@return bool Status of Adding (X)HTML and attributes.
330
-			 *	@since PHP4 OOP 0.0.1
331
-			 */
332
-			function AddHTML($tag = "", $attribs = array())
333
-			{
334
-				if(!is_string($tag))
335
-				{
336
-					trigger_error("kses4::AddHTML() requires the tag to be a string", E_USER_WARNING);
337
-					return false;
338
-				}
339
-
340
-				$tag = strtolower(trim($tag));
341
-				if($tag == "")
342
-				{
343
-					trigger_error("kses4::AddHTML() tried to add an empty/NULL tag", E_USER_WARNING);
344
-					return false;
345
-				}
346
-
347
-				if(!is_array($attribs))
348
-				{
349
-					trigger_error("kses4::AddHTML() requires an array (even an empty one) of attributes for '$tag'", E_USER_WARNING);
350
-					return false;
351
-				}
352
-
353
-				$new_attribs = array();
354
-				if(is_array($attribs) && count($attribs) > 0)
355
-				{
356
-					foreach($attribs as $idx1 => $val1)
357
-					{
358
-						$new_idx1 = strtolower($idx1);
359
-						$new_val1 = $attribs[$idx1];
360
-
361
-						if(is_array($new_val1) && count($new_val1) > 0)
362
-						{
363
-							$tmp_val = array();
364
-							foreach($new_val1 as $idx2 => $val2)
365
-							{
366
-								$new_idx2 = strtolower($idx2);
367
-								$tmp_val[$new_idx2] = $val2;
368
-							}
369
-							$new_val1 = $tmp_val;
370
-						}
371
-
372
-						$new_attribs[$new_idx1] = $new_val1;
373
-					}
374
-				}
375
-
376
-				$this->allowed_html[$tag] = $new_attribs;
377
-				return true;
378
-			}
379
-
380
-			/**
381
-			 *	Removes a single protocol from $this->allowed_protocols.
382
-			 *
383
-			 *	This method accepts a string argument and removes it from
384
-			 *	the list of allowed protocols to keep when performing
385
-			 *	Parse().
386
-			 *
387
-			 *	@access public
388
-			 *	@param string $protocol The name of the protocol to be removed.
389
-			 *	@return bool Status of removing valid protocol.
390
-			 *	@since PHP4 OOP 0.2.1
391
-			 */
392
-			function RemoveProtocol($protocol = "")
393
-			{
394
-				if(!is_string($protocol))
395
-				{
396
-					trigger_error("kses4::RemoveProtocol() requires a string.", E_USER_WARNING);
397
-					return false;
398
-				}
399
-
400
-				// Remove any inadvertent ':' at the end of the protocol.
401
-				if(substr($protocol, strlen($protocol) - 1, 1) == ":")
402
-				{
403
-					$protocol = substr($protocol, 0, strlen($protocol) - 1);
404
-				}
405
-
406
-				$protocol = strtolower(trim($protocol));
407
-				if($protocol == "")
408
-				{
409
-					trigger_error("kses4::RemoveProtocol() tried to remove an empty/NULL protocol.", E_USER_WARNING);
410
-					return false;
411
-				}
412
-
413
-				//	Ensures that the protocol exists before removing it.
414
-				if(in_array($protocol, $this->allowed_protocols))
415
-				{
416
-					$this->allowed_protocols = array_diff($this->allowed_protocols, array($protocol));
417
-					sort($this->allowed_protocols);
418
-				}
419
-
420
-				return true;
421
-			}
422
-
423
-			/**
424
-			 *	Allows for single/batch removal of protocols
425
-			 *
426
-			 *	This method accepts one argument that can be either a string
427
-			 *	or an array of strings.  Invalid data will be ignored.
428
-			 *
429
-			 *	The argument will be processed, and each string will be removed
430
-			 *	via RemoveProtocol().
431
-			 *
432
-			 *	@access public
433
-			 *	@param mixed , A string or array of protocols that will be removed from the internal list of allowed protocols.
434
-			 *	@return bool Status of removing valid protocols.
435
-			 *	@see RemoveProtocol()
436
-			 *	@since PHP5 OOP 0.2.1
437
-			 */
438
-			function RemoveProtocols()
439
-			{
440
-				$c_args = func_num_args();
441
-				if($c_args != 1)
442
-				{
443
-					return false;
444
-				}
445
-
446
-				$protocol_data = func_get_arg(0);
447
-
448
-				if(is_array($protocol_data) && count($protocol_data) > 0)
449
-				{
450
-					foreach($protocol_data as $protocol)
451
-					{
452
-						$this->RemoveProtocol($protocol);
453
-					}
454
-				}
455
-				elseif(is_string($protocol_data))
456
-				{
457
-					$this->RemoveProtocol($protocol_data);
458
-					return true;
459
-				}
460
-				else
461
-				{
462
-					trigger_error("kses4::RemoveProtocols() did not receive a string or an array.", E_USER_WARNING);
463
-					return false;
464
-				}
465
-			}
466
-
467
-			/**
468
-			 *	This method removes any NULL or characters in $string.
469
-			 *
470
-			 *	@access private
471
-			 *	@param string $string
472
-			 *	@return string String without any NULL/chr(173)
473
-			 *	@since PHP4 OOP 0.0.1
474
-			 */
475
-			function _no_null($string)
476
-			{
477
-				$string = preg_replace('/\0+/', '', $string);
478
-				$string = preg_replace('/(\\\\0)+/', '', $string);
479
-				return $string;
480
-			}
481
-
482
-			/**
483
-			 *	This function removes the HTML JavaScript entities found in early versions of
484
-			 *	Netscape 4.
485
-			 *
486
-			 *	@access private
487
-			 *	@param string $string
488
-			 *	@return string String without any NULL/chr(173)
489
-			 *	@since PHP4 OOP 0.0.1
490
-			 */
491
-			function _js_entities($string)
492
-			{
493
-			  return preg_replace('%&\s*\{[^}]*(\}\s*;?|$)%', '', $string);
494
-			}
495
-
496
-			/**
497
-			 *	Normalizes HTML entities
498
-			 *
499
-			 *	This function normalizes HTML entities. It will convert "AT&T" to the correct
500
-			 *	"AT&amp;T", "&#00058;" to "&#58;", "&#XYZZY;" to "&amp;#XYZZY;" and so on.
501
-			 *
502
-			 *	@access private
503
-			 *	@param string $string
504
-			 *	@return string String with normalized entities
505
-			 *	@since PHP4 OOP 0.0.1
506
-			 */
507
-			function _normalize_entities($string)
508
-			{
509
-				# Disarm all entities by converting & to &amp;
510
-			  $string = str_replace('&', '&amp;', $string);
511
-
512
-				# Change back the allowed entities in our entity white list
513
-
514
-			  $string = preg_replace('/&amp;([A-Za-z][A-Za-z0-9]{0,19});/', '&\\1;', $string);
515
-			  $string = preg_replace('/&amp;#0*([0-9]{1,5});/e', '\$this->_normalize_entities2("\\1")', $string);
516
-			  $string = preg_replace('/&amp;#([Xx])0*(([0-9A-Fa-f]{2}){1,2});/', '&#\\1\\2;', $string);
517
-
518
-			  return $string;
519
-			}
520
-
521
-			/**
522
-			 *	Helper method used by normalizeEntites()
523
-			 *
524
-			 *	This method helps normalizeEntities() to only accept 16 bit values
525
-			 *	and nothing more for &#number; entities.
526
-			 *
527
-			 *	This method helps normalize_entities() during a preg_replace()
528
-			 *	where a &#(0)*XXXXX; occurs.  The '(0)*XXXXXX' value is converted to
529
-			 *	a number and the result is returned as a numeric entity if the number
530
-			 *	is less than 65536.  Otherwise, the value is returned 'as is'.
531
-			 *
532
-			 *	@access private
533
-			 *	@param string $i
534
-			 *	@return string Normalized numeric entity
535
-			 *	@see _normalize_entities()
536
-			 *	@since PHP4 OOP 0.0.1
537
-			 */
538
-			function _normalize_entities2($i)
539
-			{
540
-			  return (($i > 65535) ? "&amp;#$i;" : "&#$i;");
541
-			}
542
-
543
-			/**
544
-			 *	Allows for additional user defined modifications to text.
545
-			 *
546
-			 *	@deprecated use filterKsesTextHook()
547
-			 *	@param string $string
548
-			 *	@see filterKsesTextHook()
549
-			 *	@return string
550
-			 *	@since PHP4 OOP 0.0.1
551
-			 */
552
-			function _hook($string)
553
-			{
554
-			  return $this->filterKsesTextHook($string);
555
-			}
556
-
557
-			/**
558
-			 *	Allows for additional user defined modifications to text.
559
-			 *
560
-			 *	This method allows for additional modifications to be performed on
561
-			 *	a string that's being run through Parse().  Currently, it returns the
562
-			 *	input string 'as is'.
563
-			 *
564
-			 *	This method is provided for users to extend the kses class for their own
565
-			 *	requirements.
566
-			 *
567
-			 *	@access public
568
-			 *	@param string $string String to perfrom additional modifications on.
569
-			 *	@return string User modified string.
570
-			 *	@see Parse()
571
-			 *	@since PHP5 OOP 1.0.0
572
-			 */
573
-			function filterKsesTextHook($string)
574
-			{
575
-			  return $string;
576
-			}
577
-
578
-			/**
579
-			 *	This method goes through an array, and changes the keys to all lower case.
580
-			 *
581
-			 *	@access private
582
-			 *	@param array $in_array Associative array
583
-			 *	@return array Modified array
584
-			 *	@since PHP4 OOP 0.0.1
585
-			 */
586
-			function _array_lc($inarray)
587
-			{
588
-			  $outarray = array();
589
-
590
-				if(is_array($inarray) && count($inarray) > 0)
591
-				{
592
-					foreach ($inarray as $inkey => $inval)
593
-					{
594
-						$outkey = strtolower($inkey);
595
-						$outarray[$outkey] = array();
596
-
597
-						if(is_array($inval) && count($inval) > 0)
598
-						{
599
-							foreach ($inval as $inkey2 => $inval2)
600
-							{
601
-								$outkey2 = strtolower($inkey2);
602
-								$outarray[$outkey][$outkey2] = $inval2;
603
-							}
604
-						}
605
-					}
606
-				}
607
-
608
-			  return $outarray;
609
-			}
610
-
611
-			/**
612
-			 *	This method searched for HTML tags, no matter how malformed.  It also
613
-			 *	matches stray ">" characters.
614
-			 *
615
-			 *	@access private
616
-			 *	@param string $string
617
-			 *	@return string HTML tags
618
-			 *	@since PHP4 OOP 0.0.1
619
-			 */
620
-			function _split($string)
621
-			{
622
-				return preg_replace(
623
-					'%(<'.   # EITHER: <
624
-					'[^>]*'. # things that aren't >
625
-					'(>|$)'. # > or end of string
626
-					'|>)%e', # OR: just a >
627
-					"\$this->_split2('\\1')",
628
-					$string);
629
-			}
630
-
631
-			/**
632
-			 *	This method strips out disallowed and/or mangled (X)HTML tags along with assigned attributes.
633
-			 *
634
-			 *	This method does a lot of work. It rejects some very malformed things
635
-			 *	like <:::>. It returns an empty string if the element isn't allowed (look
636
-			 *	ma, no strip_tags()!). Otherwise it splits the tag into an element and an
637
-			 *	allowed attribute list.
638
-			 *
639
-			 *	@access private
640
-			 *	@param string $string
641
-			 *	@return string Modified string minus disallowed/mangled (X)HTML and attributes
642
-			 *	@since PHP4 OOP 0.0.1
643
-			 */
644
-			function _split2($string)
645
-			{
646
-				$string = $this->_stripslashes($string);
647
-
648
-				if (substr($string, 0, 1) != '<')
649
-				{
650
-					# It matched a ">" character
651
-					return '&gt;';
652
-				}
653
-
654
-				if (!preg_match('%^<\s*(/\s*)?([a-zA-Z0-9]+)([^>]*)>?$%', $string, $matches))
655
-				{
656
-					# It's seriously malformed
657
-					return '';
658
-				}
659
-
660
-				$slash    = trim($matches[1]);
661
-				$elem     = $matches[2];
662
-				$attrlist = $matches[3];
663
-
664
-				if (
665
-					!isset($this->allowed_html[strtolower($elem)]) ||
666
-					!is_array($this->allowed_html[strtolower($elem)])
667
-				)
668
-				{
669
-					# They are using a not allowed HTML element
670
-					return '';
671
-				}
672
-
673
-				if ($slash != '')
674
-				{
675
-					return "<$slash$elem>";
676
-				}
677
-				# No attributes are allowed for closing elements
678
-
679
-				return $this->_attr("$slash$elem", $attrlist);
680
-			}
681
-
682
-			/**
683
-			 *	This method strips out disallowed attributes for (X)HTML tags.
684
-			 *
685
-			 *	This method removes all attributes if none are allowed for this element.
686
-			 *	If some are allowed it calls $this->_hair() to split them further, and then it
687
-			 *	builds up new HTML code from the data that $this->_hair() returns. It also
688
-			 *	removes "<" and ">" characters, if there are any left. One more thing it
689
-			 *	does is to check if the tag has a closing XHTML slash, and if it does,
690
-			 *	it puts one in the returned code as well.
691
-			 *
692
-			 *	@access private
693
-			 *	@param string $element (X)HTML tag to check
694
-			 *	@param string $attr Text containing attributes to check for validity.
695
-			 *	@return string Resulting valid (X)HTML or ''
696
-			 *	@see _hair()
697
-			 *	@since PHP4 OOP 0.0.1
698
-			 */
699
-			function _attr($element, $attr)
700
-			{
701
-				# Is there a closing XHTML slash at the end of the attributes?
702
-				$xhtml_slash = '';
703
-				if (preg_match('%\s/\s*$%', $attr))
704
-				{
705
-					$xhtml_slash = ' /';
706
-				}
707
-
708
-				# Are any attributes allowed at all for this element?
709
-				if (
710
-					!isset($this->allowed_html[strtolower($element)]) ||
711
-					count($this->allowed_html[strtolower($element)]) == 0
712
-				)
713
-				{
714
-					return "<$element$xhtml_slash>";
715
-				}
716
-
717
-				# Split it
718
-				$attrarr = $this->_hair($attr);
719
-
720
-				# Go through $attrarr, and save the allowed attributes for this element
721
-				# in $attr2
722
-				$attr2 = '';
723
-				if(is_array($attrarr) && count($attrarr) > 0)
724
-				{
725
-					foreach ($attrarr as $arreach)
726
-					{
727
-						if(!isset($this->allowed_html[strtolower($element)][strtolower($arreach['name'])]))
728
-						{
729
-							continue;
730
-						}
731
-
732
-						$current = $this->allowed_html[strtolower($element)][strtolower($arreach['name'])];
733
-						if ($current == '')
734
-						{
735
-							# the attribute is not allowed
736
-							continue;
737
-						}
738
-
739
-						if (!is_array($current))
740
-						{
741
-							# there are no checks
742
-							$attr2 .= ' '.$arreach['whole'];
743
-						}
744
-						else
745
-						{
746
-							# there are some checks
747
-							$ok = true;
748
-							if(is_array($current) && count($current) > 0)
749
-							{
750
-								foreach ($current as $currkey => $currval)
751
-								{
752
-									if (!$this->_check_attr_val($arreach['value'], $arreach['vless'], $currkey, $currval))
753
-									{
754
-										$ok = false;
755
-										break;
756
-									}
757
-								}
758
-
759
-								if ($ok)
760
-								{
761
-									# it passed them
762
-									$attr2 .= ' '.$arreach['whole'];
763
-								}
764
-							}
765
-						}
766
-					}
767
-				}
768
-
769
-				# Remove any "<" or ">" characters
770
-				$attr2 = preg_replace('/[<>]/', '', $attr2);
771
-				return "<$element$attr2$xhtml_slash>";
772
-			}
773
-
774
-			/**
775
-			 *	This method combs through an attribute list string and returns an associative array of attributes and values.
776
-			 *
777
-			 *	This method does a lot of work. It parses an attribute list into an array
778
-			 *	with attribute data, and tries to do the right thing even if it gets weird
779
-			 *	input. It will add quotes around attribute values that don't have any quotes
780
-			 *	or apostrophes around them, to make it easier to produce HTML code that will
781
-			 *	conform to W3C's HTML specification. It will also remove bad URL protocols
782
-			 *	from attribute values.
783
-			 *
784
-			 *	@access private
785
-			 *	@param string $attr Text containing tag attributes for parsing
786
-			 *	@return array Associative array containing data on attribute and value
787
-			 *	@since PHP4 OOP 0.0.1
788
-			 */
789
-			function _hair($attr)
790
-			{
791
-				$attrarr  = array();
792
-				$mode     = 0;
793
-				$attrname = '';
794
-
795
-				# Loop through the whole attribute list
796
-
797
-				while (strlen($attr) != 0)
798
-				{
799
-					# Was the last operation successful?
800
-					$working = 0;
801
-
802
-					switch ($mode)
803
-					{
804
-						case 0:	# attribute name, href for instance
805
-							if (preg_match('/^([-a-zA-Z]+)/', $attr, $match))
806
-							{
807
-								$attrname = $match[1];
808
-								$working = $mode = 1;
809
-								$attr = preg_replace('/^[-a-zA-Z]+/', '', $attr);
810
-							}
811
-							break;
812
-						case 1:	# equals sign or valueless ("selected")
813
-							if (preg_match('/^\s*=\s*/', $attr)) # equals sign
814
-							{
815
-								$working = 1;
816
-								$mode    = 2;
817
-								$attr    = preg_replace('/^\s*=\s*/', '', $attr);
818
-								break;
819
-							}
820
-							if (preg_match('/^\s+/', $attr)) # valueless
821
-							{
822
-								$working   = 1;
823
-								$mode      = 0;
824
-								$attrarr[] = array(
825
-									'name'  => $attrname,
826
-									'value' => '',
827
-									'whole' => $attrname,
828
-									'vless' => 'y'
829
-								);
830
-								$attr      = preg_replace('/^\s+/', '', $attr);
831
-							}
832
-							break;
833
-						case 2: # attribute value, a URL after href= for instance
834
-							if (preg_match('/^"([^"]*)"(\s+|$)/', $attr, $match)) # "value"
835
-							{
836
-								$thisval   = $this->_bad_protocol($match[1]);
837
-								$attrarr[] = array(
838
-									'name'  => $attrname,
839
-									'value' => $thisval,
840
-									'whole' => "$attrname=\"$thisval\"",
841
-									'vless' => 'n'
842
-								);
843
-								$working   = 1;
844
-								$mode      = 0;
845
-								$attr      = preg_replace('/^"[^"]*"(\s+|$)/', '', $attr);
846
-								break;
847
-							}
848
-							if (preg_match("/^'([^']*)'(\s+|$)/", $attr, $match)) # 'value'
849
-							{
850
-								$thisval   = $this->_bad_protocol($match[1]);
851
-								$attrarr[] = array(
852
-									'name'  => $attrname,
853
-									'value' => $thisval,
854
-									'whole' => "$attrname='$thisval'",
855
-									'vless' => 'n'
856
-								);
857
-								$working   = 1;
858
-								$mode      = 0;
859
-								$attr      = preg_replace("/^'[^']*'(\s+|$)/", '', $attr);
860
-								break;
861
-							}
862
-							if (preg_match("%^([^\s\"']+)(\s+|$)%", $attr, $match)) # value
863
-							{
864
-								$thisval   = $this->_bad_protocol($match[1]);
865
-								$attrarr[] = array(
866
-									'name'  => $attrname,
867
-									'value' => $thisval,
868
-									'whole' => "$attrname=\"$thisval\"",
869
-									'vless' => 'n'
870
-								);
871
-								# We add quotes to conform to W3C's HTML spec.
872
-								$working   = 1;
873
-								$mode      = 0;
874
-								$attr      = preg_replace("%^[^\s\"']+(\s+|$)%", '', $attr);
875
-							}
876
-							break;
877
-					}
878
-
879
-					if ($working == 0) # not well formed, remove and try again
880
-					{
881
-						$attr = $this->_html_error($attr);
882
-						$mode = 0;
883
-					}
884
-				}
885
-
886
-				# special case, for when the attribute list ends with a valueless
887
-				# attribute like "selected"
888
-				if ($mode == 1)
889
-				{
890
-					$attrarr[] = array(
891
-						'name'  => $attrname,
892
-						'value' => '',
893
-						'whole' => $attrname,
894
-						'vless' => 'y'
895
-					);
896
-				}
897
-
898
-				return $attrarr;
899
-			}
900
-
901
-			/**
902
-			 *	This method removes disallowed protocols.
903
-			 *
904
-			 *	This method removes all non-allowed protocols from the beginning of
905
-			 *	$string. It ignores whitespace and the case of the letters, and it does
906
-			 *	understand HTML entities. It does its work in a while loop, so it won't be
907
-			 *	fooled by a string like "javascript:javascript:alert(57)".
908
-			 *
909
-			 *	@access private
910
-			 *	@param string $string String to check for protocols
911
-			 *	@return string String with removed protocols
912
-			 *	@since PHP4 OOP 0.0.1
913
-			 */
914
-			function _bad_protocol($string)
915
-			{
916
-				$string  = $this->_no_null($string);
917
-				$string = preg_replace('/\xad+/', '', $string); # deals with Opera "feature"
918
-				$string2 = $string.'a';
919
-
920
-				while ($string != $string2)
921
-				{
922
-					$string2 = $string;
923
-					$string  = $this->_bad_protocol_once($string);
924
-				} # while
925
-
926
-				return $string;
927
-			}
928
-
929
-			/**
930
-			 *	Helper method used by _bad_protocol()
931
-			 *
932
-			 *	This function searches for URL protocols at the beginning of $string, while
933
-			 *	handling whitespace and HTML entities.
934
-			 *  Function updated to fix security vulnerability (see http://projects.dokeos.com/index.php?do=details&task_id=2312)
935
-			 *
936
-			 *	@access private
937
-			 *	@param string $string String to check for protocols
938
-			 *	@return string String with removed protocols
939
-			 *	@see _bad_protocol()
940
-			 *	@since PHP4 OOP 0.0.1
941
-			 */
942
-			function _bad_protocol_once($string)
943
-			{
944
-				$string2 = preg_split('/:|&#58;|&#x3a;/i', $string, 2);
945
-				if(isset($string2[1]) && !preg_match('%/\?%',$string2[0]))
946
-				{
947
-					$string = $this->_bad_protocol_once2($string2[0]).trim($string2[1]);
948
-				}
949
-				return $string;
950
-			}
951
-			/**
952
-			 *	Helper method used by _bad_protocol_once() regex
953
-			 *
954
-			 *	This function processes URL protocols, checks to see if they're in the white-
955
-			 *	list or not, and returns different data depending on the answer.
956
-			 *
957
-			 *	@access private
958
-			 *	@param string $string String to check for protocols
959
-			 *	@return string String with removed protocols
960
-			 *	@see _bad_protocol()
961
-			 *	@see _bad_protocol_once()
962
-			 *	@since PHP4 OOP 0.0.1
963
-			 */
964
-			function _bad_protocol_once2($string)
965
-			{
966
-				$string = $this->_decode_entities($string);
967
-				$string = preg_replace('/\s/', '', $string);
968
-				$string = $this->_no_null($string);
969
-				$string = preg_replace('/\xad+/', '', $string); # deals with Opera "feature"
970
-				$string = strtolower($string);
971
-
972
-				$allowed = false;
973
-				if(is_array($this->allowed_protocols) && count($this->allowed_protocols) > 0)
974
-				{
975
-					foreach ($this->allowed_protocols as $one_protocol)
976
-					{
977
-						if (strtolower($one_protocol) == $string)
978
-						{
979
-							$allowed = true;
980
-							break;
981
-						}
982
-					}
983
-				}
984
-
985
-				if ($allowed)
986
-				{
987
-					return "$string:";
988
-				}
989
-				else
990
-				{
991
-					return '';
992
-				}
993
-			}
994
-
995
-			/**
996
-			 *	This function performs different checks for attribute values.
997
-			 *
998
-			 *	The currently implemented checks are "maxlen", "minlen", "maxval",
999
-			 *	"minval" and "valueless" with even more checks to come soon.
1000
-			 *
1001
-			 *	@access private
1002
-			 *	@param string $value The value of the attribute to be checked.
1003
-			 *	@param string $vless Indicates whether the the value is supposed to be valueless
1004
-			 *	@param string $checkname The check to be performed
1005
-			 *	@param string $checkvalue The value that is to be checked against
1006
-			 *	@return bool Indicates whether the check passed or not
1007
-			 *	@since PHP4 OOP 0.0.1
1008
-			 */
1009
-			function _check_attr_val($value, $vless, $checkname, $checkvalue)
1010
-			{
1011
-				$ok = true;
1012
-
1013
-				switch (strtolower($checkname))
1014
-				{
1015
-					/**
1016
-					*	The maxlen check makes sure that the attribute value has a length not
1017
-					*	greater than the given value. This can be used to avoid Buffer Overflows
1018
-					*	in WWW clients and various Internet servers.
1019
-					*/
1020
-					case 'maxlen':
1021
-						if (strlen($value) > $checkvalue)
1022
-						{
1023
-							$ok = false;
1024
-						}
1025
-						break;
1026
-
1027
-					/**
1028
-					*	The minlen check makes sure that the attribute value has a length not
1029
-					*	smaller than the given value.
1030
-					*/
1031
-					case 'minlen':
1032
-						if (strlen($value) < $checkvalue)
1033
-						{
1034
-							$ok = false;
1035
-						}
1036
-						break;
1037
-
1038
-					/**
1039
-					*	The maxval check does two things: it checks that the attribute value is
1040
-					*	an integer from 0 and up, without an excessive amount of zeroes or
1041
-					*	whitespace (to avoid Buffer Overflows). It also checks that the attribute
1042
-					*	value is not greater than the given value.
1043
-					*	This check can be used to avoid Denial of Service attacks.
1044
-					*/
1045
-					case 'maxval':
1046
-						if (!preg_match('/^\s{0,6}[0-9]{1,6}\s{0,6}$/', $value))
1047
-						{
1048
-							$ok = false;
1049
-						}
1050
-						if ($value > $checkvalue)
1051
-						{
1052
-							$ok = false;
1053
-						}
1054
-						break;
1055
-
1056
-					/**
1057
-					*	The minval check checks that the attribute value is a positive integer,
1058
-					*	and that it is not smaller than the given value.
1059
-					*/
1060
-					case 'minval':
1061
-						if (!preg_match('/^\s{0,6}[0-9]{1,6}\s{0,6}$/', $value))
1062
-						{
1063
-							$ok = false;
1064
-						}
1065
-						if ($value < $checkvalue)
1066
-						{
1067
-							$ok = false;
1068
-						}
1069
-						break;
1070
-
1071
-					/**
1072
-					*	The valueless check checks if the attribute has a value
1073
-					*	(like <a href="blah">) or not (<option selected>). If the given value
1074
-					*	is a "y" or a "Y", the attribute must not have a value.
1075
-					*	If the given value is an "n" or an "N", the attribute must have one.
1076
-					*/
1077
-					case 'valueless':
1078
-					if (strtolower($checkvalue) != $vless)
1079
-					{
1080
-						$ok = false;
1081
-					}
1082
-					break;
1083
-
1084
-				}
1085
-
1086
-				return $ok;
1087
-			}
1088
-
1089
-			/**
1090
-			 *	Changes \" to "
1091
-			 *
1092
-			 *	This function changes the character sequence  \"  to just  "
1093
-			 *	It leaves all other slashes alone. It's really weird, but the quoting from
1094
-			 *	preg_replace(//e) seems to require this.
1095
-			 *
1096
-			 *	@access private
1097
-			 *	@param string $string The string to be stripped.
1098
-			 *	@return string string stripped of \"
1099
-			 *	@since PHP4 OOP 0.0.1
1100
-			 */
1101
-			function _stripslashes($string)
1102
-			{
1103
-				return preg_replace('%\\\\"%', '"', $string);
1104
-			}
1105
-
1106
-			/**
1107
-			 *	helper method for _hair()
1108
-			 *
1109
-			 *	This function deals with parsing errors in _hair(). The general plan is
1110
-			 *	to remove everything to and including some whitespace, but it deals with
1111
-			 *	quotes and apostrophes as well.
1112
-			 *
1113
-			 *	@access private
1114
-			 *	@param string $string The string to be stripped.
1115
-			 *	@return string string stripped of whitespace
1116
-			 *	@see _hair()
1117
-			 *	@since PHP4 OOP 0.0.1
1118
-			 */
1119
-			function _html_error($string)
1120
-			{
1121
-				return preg_replace('/^("[^"]*("|$)|\'[^\']*(\'|$)|\S)*\s*/', '', $string);
1122
-			}
1123
-
1124
-			/**
1125
-			 *	Decodes numeric HTML entities
1126
-			 *
1127
-			 *	This method decodes numeric HTML entities (&#65; and &#x41;). It doesn't
1128
-			 *	do anything with other entities like &auml;, but we don't need them in the
1129
-			 *	URL protocol white listing system anyway.
1130
-			 *
1131
-			 *	@access private
1132
-			 *	@param string $value The entitiy to be decoded.
1133
-			 *	@return string Decoded entity
1134
-			 *	@since PHP4 OOP 0.0.1
1135
-			 */
1136
-			function _decode_entities($string)
1137
-			{
1138
-				$string = preg_replace('/&#([0-9]+);/e', 'chr("\\1")', $string);
1139
-				$string = preg_replace('/&#[Xx]([0-9A-Fa-f]+);/e', 'chr(hexdec("\\1"))', $string);
1140
-				return $string;
1141
-			}
1142
-
1143
-			/**
1144
-			 *	Returns PHP4 OOP version # of kses.
1145
-			 *
1146
-			 *	Since this class has been refactored and documented and proven to work,
1147
-			 *	I'm syncing the version number to procedural kses.
1148
-			 *
1149
-			 *	@access public
1150
-			 *	@return string Version number
1151
-			 *	@since PHP4 OOP 0.0.1
1152
-			 */
1153
-			function _version()
1154
-			{
1155
-				return 'PHP4 0.2.2 (OOP fork of procedural kses 0.2.2)';
1156
-			}
1157
-		}
1158
-
1159
-
1160
-
1161
-	}
88
+            var $allowed_protocols = array();
89
+            var $allowed_html      = array();
90
+            /**#@-*/
91
+
92
+            /**
93
+             *	Constructor for kses.
94
+             *
95
+             *	This sets a default collection of protocols allowed in links, and creates an
96
+             *	empty set of allowed HTML tags.
97
+             *	@since PHP4 OOP 0.0.1
98
+             */
99
+            function kses4()
100
+            {
101
+                /**
102
+                 *	You could add protocols such as ftp, new, gopher, mailto, irc, etc.
103
+                 *
104
+                 *	The base values the original kses provided were:
105
+                 *		'http', 'https', 'ftp', 'news', 'nntp', 'telnet', 'gopher', 'mailto'
106
+                 */
107
+                $this->allowed_protocols = array('http', 'ftp', 'mailto');
108
+                $this->allowed_html      = array();
109
+            }
110
+
111
+            /**
112
+             *	Basic task of kses - parses $string and strips it as required.
113
+             *
114
+             *	This method strips all the disallowed (X)HTML tags, attributes
115
+             *	and protocols from the input $string.
116
+             *
117
+             *	@access public
118
+             *	@param string $string String to be stripped of 'evil scripts'
119
+             *	@return string The stripped string
120
+             *	@since PHP4 OOP 0.2.1
121
+             */
122
+            function Parse($string = "")
123
+            {
124
+                if (get_magic_quotes_gpc())
125
+                {
126
+                    $string = stripslashes($string);
127
+                }
128
+                $string = $this->_no_null($string);
129
+                $string = $this->_js_entities($string);
130
+                $string = $this->_normalize_entities($string);
131
+                $string = $this->filterKsesTextHook($string);
132
+                return    $this->_split($string);
133
+            }
134
+
135
+            /**
136
+             *	Allows for single/batch addition of protocols
137
+             *
138
+             *	This method accepts one argument that can be either a string
139
+             *	or an array of strings.  Invalid data will be ignored.
140
+             *
141
+             *	The argument will be processed, and each string will be added
142
+             *	via AddProtocol().
143
+             *
144
+             *	@access public
145
+             *	@param mixed , A string or array of protocols that will be added to the internal list of allowed protocols.
146
+             *	@return bool Status of adding valid protocols.
147
+             *	@see AddProtocol()
148
+             *	@since PHP4 OOP 0.2.1
149
+             */
150
+            function AddProtocols()
151
+            {
152
+                $c_args = func_num_args();
153
+                if($c_args != 1)
154
+                {
155
+                    trigger_error("kses4::AddProtocols() did not receive an argument.", E_USER_WARNING);
156
+                    return false;
157
+                }
158
+
159
+                $protocol_data = func_get_arg(0);
160
+
161
+                if(is_array($protocol_data) && count($protocol_data) > 0)
162
+                {
163
+                    foreach($protocol_data as $protocol)
164
+                    {
165
+                        $this->AddProtocol($protocol);
166
+                    }
167
+                    return true;
168
+                }
169
+                elseif(is_string($protocol_data))
170
+                {
171
+                    $this->AddProtocol($protocol_data);
172
+                    return true;
173
+                }
174
+                else
175
+                {
176
+                    trigger_error("kses4::AddProtocols() did not receive a string or an array.", E_USER_WARNING);
177
+                    return false;
178
+                }
179
+            }
180
+
181
+            /**
182
+             *	Allows for single/batch addition of protocols
183
+             *
184
+             *	@deprecated Use AddProtocols()
185
+             *	@see AddProtocols()
186
+             *	@return bool
187
+             *	@since PHP4 OOP 0.0.1
188
+             */
189
+            function Protocols()
190
+            {
191
+                $c_args = func_num_args();
192
+                if($c_args != 1)
193
+                {
194
+                    trigger_error("kses4::Protocols() did not receive an argument.", E_USER_WARNING);
195
+                    return false;
196
+                }
197
+
198
+                return $this->AddProtocols(func_get_arg(0));
199
+            }
200
+
201
+            /**
202
+             *	Adds a single protocol to $this->allowed_protocols.
203
+             *
204
+             *	This method accepts a string argument and adds it to
205
+             *	the list of allowed protocols to keep when performing
206
+             *	Parse().
207
+             *
208
+             *	@access public
209
+             *	@param string $protocol The name of the protocol to be added.
210
+             *	@return bool Status of adding valid protocol.
211
+             *	@since PHP4 OOP 0.0.1
212
+             */
213
+            function AddProtocol($protocol = "")
214
+            {
215
+                if(!is_string($protocol))
216
+                {
217
+                    trigger_error("kses4::AddProtocol() requires a string.", E_USER_WARNING);
218
+                    return false;
219
+                }
220
+
221
+                $protocol = strtolower(trim($protocol));
222
+                if($protocol == "")
223
+                {
224
+                    trigger_error("kses4::AddProtocol() tried to add an empty/NULL protocol.", E_USER_WARNING);
225
+                    return false;
226
+                }
227
+
228
+                // Remove any inadvertent ':' at the end of the protocol.
229
+                if(substr($protocol, strlen($protocol) - 1, 1) == ":")
230
+                {
231
+                    $protocol = substr($protocol, 0, strlen($protocol) - 1);
232
+                }
233
+
234
+                if(!in_array($protocol, $this->allowed_protocols))
235
+                {
236
+                    array_push($this->allowed_protocols, $protocol);
237
+                    sort($this->allowed_protocols);
238
+                }
239
+                return true;
240
+            }
241
+
242
+            /**
243
+             *	Allows for single/batch replacement of protocols
244
+             *
245
+             *	This method accepts one argument that can be either a string
246
+             *	or an array of strings.  Invalid data will be ignored.
247
+             *
248
+             *	Existing protocols will be removed, then the argument will be
249
+             *	processed, and each string will be added via AddProtocol().
250
+             *
251
+             *	@access public
252
+             *	@param mixed , A string or array of protocols that will be the new internal list of allowed protocols.
253
+             *	@return bool Status of replacing valid protocols.
254
+             *	@since PHP4 OOP 0.2.2
255
+             *	@see AddProtocol()
256
+             */
257
+            function SetProtocols()
258
+            {
259
+                $c_args = func_num_args();
260
+                if($c_args != 1)
261
+                {
262
+                    trigger_error("kses4::SetProtocols() did not receive an argument.", E_USER_WARNING);
263
+                    return false;
264
+                }
265
+
266
+                $protocol_data = func_get_arg(0);
267
+
268
+                if(is_array($protocol_data) && count($protocol_data) > 0)
269
+                {
270
+                    $this->allowed_protocols = array();
271
+                    foreach($protocol_data as $protocol)
272
+                    {
273
+                        $this->AddProtocol($protocol);
274
+                    }
275
+                    return true;
276
+                }
277
+                elseif(is_string($protocol_data))
278
+                {
279
+                    $this->allowed_protocols = array();
280
+                    $this->AddProtocol($protocol_data);
281
+                    return true;
282
+                }
283
+                else
284
+                {
285
+                    trigger_error("kses4::SetProtocols() did not receive a string or an array.", E_USER_WARNING);
286
+                    return false;
287
+                }
288
+            }
289
+
290
+            /**
291
+             *	Raw dump of allowed protocols
292
+             *
293
+             *	This returns an indexed array of allowed protocols for a particular KSES
294
+             *	instantiation.
295
+             *
296
+             *	@access public
297
+             *	@return array The list of allowed protocols.
298
+             *	@since PHP4 OOP 0.2.2
299
+             */
300
+            function DumpProtocols()
301
+            {
302
+                return $this->allowed_protocols;
303
+            }
304
+
305
+            /**
306
+             *	Raw dump of allowed (X)HTML elements
307
+             *
308
+             *	This returns an indexed array of allowed (X)HTML elements and attributes
309
+             *	for a particular KSES instantiation.
310
+             *
311
+             *	@access public
312
+             *	@return array The list of allowed elements.
313
+             *	@since PHP4 OOP 0.2.2
314
+             */
315
+            function DumpElements()
316
+            {
317
+                return $this->allowed_html;
318
+            }
319
+
320
+            /**
321
+             *	Adds valid (X)HTML with corresponding attributes that will be kept when stripping 'evil scripts'.
322
+             *
323
+             *	This method accepts one argument that can be either a string
324
+             *	or an array of strings.  Invalid data will be ignored.
325
+             *
326
+             *	@access public
327
+             *	@param string $tag (X)HTML tag that will be allowed after stripping text.
328
+             *	@param array $attribs Associative array of allowed attributes - key => attribute name - value => attribute parameter
329
+             *	@return bool Status of Adding (X)HTML and attributes.
330
+             *	@since PHP4 OOP 0.0.1
331
+             */
332
+            function AddHTML($tag = "", $attribs = array())
333
+            {
334
+                if(!is_string($tag))
335
+                {
336
+                    trigger_error("kses4::AddHTML() requires the tag to be a string", E_USER_WARNING);
337
+                    return false;
338
+                }
339
+
340
+                $tag = strtolower(trim($tag));
341
+                if($tag == "")
342
+                {
343
+                    trigger_error("kses4::AddHTML() tried to add an empty/NULL tag", E_USER_WARNING);
344
+                    return false;
345
+                }
346
+
347
+                if(!is_array($attribs))
348
+                {
349
+                    trigger_error("kses4::AddHTML() requires an array (even an empty one) of attributes for '$tag'", E_USER_WARNING);
350
+                    return false;
351
+                }
352
+
353
+                $new_attribs = array();
354
+                if(is_array($attribs) && count($attribs) > 0)
355
+                {
356
+                    foreach($attribs as $idx1 => $val1)
357
+                    {
358
+                        $new_idx1 = strtolower($idx1);
359
+                        $new_val1 = $attribs[$idx1];
360
+
361
+                        if(is_array($new_val1) && count($new_val1) > 0)
362
+                        {
363
+                            $tmp_val = array();
364
+                            foreach($new_val1 as $idx2 => $val2)
365
+                            {
366
+                                $new_idx2 = strtolower($idx2);
367
+                                $tmp_val[$new_idx2] = $val2;
368
+                            }
369
+                            $new_val1 = $tmp_val;
370
+                        }
371
+
372
+                        $new_attribs[$new_idx1] = $new_val1;
373
+                    }
374
+                }
375
+
376
+                $this->allowed_html[$tag] = $new_attribs;
377
+                return true;
378
+            }
379
+
380
+            /**
381
+             *	Removes a single protocol from $this->allowed_protocols.
382
+             *
383
+             *	This method accepts a string argument and removes it from
384
+             *	the list of allowed protocols to keep when performing
385
+             *	Parse().
386
+             *
387
+             *	@access public
388
+             *	@param string $protocol The name of the protocol to be removed.
389
+             *	@return bool Status of removing valid protocol.
390
+             *	@since PHP4 OOP 0.2.1
391
+             */
392
+            function RemoveProtocol($protocol = "")
393
+            {
394
+                if(!is_string($protocol))
395
+                {
396
+                    trigger_error("kses4::RemoveProtocol() requires a string.", E_USER_WARNING);
397
+                    return false;
398
+                }
399
+
400
+                // Remove any inadvertent ':' at the end of the protocol.
401
+                if(substr($protocol, strlen($protocol) - 1, 1) == ":")
402
+                {
403
+                    $protocol = substr($protocol, 0, strlen($protocol) - 1);
404
+                }
405
+
406
+                $protocol = strtolower(trim($protocol));
407
+                if($protocol == "")
408
+                {
409
+                    trigger_error("kses4::RemoveProtocol() tried to remove an empty/NULL protocol.", E_USER_WARNING);
410
+                    return false;
411
+                }
412
+
413
+                //	Ensures that the protocol exists before removing it.
414
+                if(in_array($protocol, $this->allowed_protocols))
415
+                {
416
+                    $this->allowed_protocols = array_diff($this->allowed_protocols, array($protocol));
417
+                    sort($this->allowed_protocols);
418
+                }
419
+
420
+                return true;
421
+            }
422
+
423
+            /**
424
+             *	Allows for single/batch removal of protocols
425
+             *
426
+             *	This method accepts one argument that can be either a string
427
+             *	or an array of strings.  Invalid data will be ignored.
428
+             *
429
+             *	The argument will be processed, and each string will be removed
430
+             *	via RemoveProtocol().
431
+             *
432
+             *	@access public
433
+             *	@param mixed , A string or array of protocols that will be removed from the internal list of allowed protocols.
434
+             *	@return bool Status of removing valid protocols.
435
+             *	@see RemoveProtocol()
436
+             *	@since PHP5 OOP 0.2.1
437
+             */
438
+            function RemoveProtocols()
439
+            {
440
+                $c_args = func_num_args();
441
+                if($c_args != 1)
442
+                {
443
+                    return false;
444
+                }
445
+
446
+                $protocol_data = func_get_arg(0);
447
+
448
+                if(is_array($protocol_data) && count($protocol_data) > 0)
449
+                {
450
+                    foreach($protocol_data as $protocol)
451
+                    {
452
+                        $this->RemoveProtocol($protocol);
453
+                    }
454
+                }
455
+                elseif(is_string($protocol_data))
456
+                {
457
+                    $this->RemoveProtocol($protocol_data);
458
+                    return true;
459
+                }
460
+                else
461
+                {
462
+                    trigger_error("kses4::RemoveProtocols() did not receive a string or an array.", E_USER_WARNING);
463
+                    return false;
464
+                }
465
+            }
466
+
467
+            /**
468
+             *	This method removes any NULL or characters in $string.
469
+             *
470
+             *	@access private
471
+             *	@param string $string
472
+             *	@return string String without any NULL/chr(173)
473
+             *	@since PHP4 OOP 0.0.1
474
+             */
475
+            function _no_null($string)
476
+            {
477
+                $string = preg_replace('/\0+/', '', $string);
478
+                $string = preg_replace('/(\\\\0)+/', '', $string);
479
+                return $string;
480
+            }
481
+
482
+            /**
483
+             *	This function removes the HTML JavaScript entities found in early versions of
484
+             *	Netscape 4.
485
+             *
486
+             *	@access private
487
+             *	@param string $string
488
+             *	@return string String without any NULL/chr(173)
489
+             *	@since PHP4 OOP 0.0.1
490
+             */
491
+            function _js_entities($string)
492
+            {
493
+                return preg_replace('%&\s*\{[^}]*(\}\s*;?|$)%', '', $string);
494
+            }
495
+
496
+            /**
497
+             *	Normalizes HTML entities
498
+             *
499
+             *	This function normalizes HTML entities. It will convert "AT&T" to the correct
500
+             *	"AT&amp;T", "&#00058;" to "&#58;", "&#XYZZY;" to "&amp;#XYZZY;" and so on.
501
+             *
502
+             *	@access private
503
+             *	@param string $string
504
+             *	@return string String with normalized entities
505
+             *	@since PHP4 OOP 0.0.1
506
+             */
507
+            function _normalize_entities($string)
508
+            {
509
+                # Disarm all entities by converting & to &amp;
510
+                $string = str_replace('&', '&amp;', $string);
511
+
512
+                # Change back the allowed entities in our entity white list
513
+
514
+                $string = preg_replace('/&amp;([A-Za-z][A-Za-z0-9]{0,19});/', '&\\1;', $string);
515
+                $string = preg_replace('/&amp;#0*([0-9]{1,5});/e', '\$this->_normalize_entities2("\\1")', $string);
516
+                $string = preg_replace('/&amp;#([Xx])0*(([0-9A-Fa-f]{2}){1,2});/', '&#\\1\\2;', $string);
517
+
518
+                return $string;
519
+            }
520
+
521
+            /**
522
+             *	Helper method used by normalizeEntites()
523
+             *
524
+             *	This method helps normalizeEntities() to only accept 16 bit values
525
+             *	and nothing more for &#number; entities.
526
+             *
527
+             *	This method helps normalize_entities() during a preg_replace()
528
+             *	where a &#(0)*XXXXX; occurs.  The '(0)*XXXXXX' value is converted to
529
+             *	a number and the result is returned as a numeric entity if the number
530
+             *	is less than 65536.  Otherwise, the value is returned 'as is'.
531
+             *
532
+             *	@access private
533
+             *	@param string $i
534
+             *	@return string Normalized numeric entity
535
+             *	@see _normalize_entities()
536
+             *	@since PHP4 OOP 0.0.1
537
+             */
538
+            function _normalize_entities2($i)
539
+            {
540
+                return (($i > 65535) ? "&amp;#$i;" : "&#$i;");
541
+            }
542
+
543
+            /**
544
+             *	Allows for additional user defined modifications to text.
545
+             *
546
+             *	@deprecated use filterKsesTextHook()
547
+             *	@param string $string
548
+             *	@see filterKsesTextHook()
549
+             *	@return string
550
+             *	@since PHP4 OOP 0.0.1
551
+             */
552
+            function _hook($string)
553
+            {
554
+                return $this->filterKsesTextHook($string);
555
+            }
556
+
557
+            /**
558
+             *	Allows for additional user defined modifications to text.
559
+             *
560
+             *	This method allows for additional modifications to be performed on
561
+             *	a string that's being run through Parse().  Currently, it returns the
562
+             *	input string 'as is'.
563
+             *
564
+             *	This method is provided for users to extend the kses class for their own
565
+             *	requirements.
566
+             *
567
+             *	@access public
568
+             *	@param string $string String to perfrom additional modifications on.
569
+             *	@return string User modified string.
570
+             *	@see Parse()
571
+             *	@since PHP5 OOP 1.0.0
572
+             */
573
+            function filterKsesTextHook($string)
574
+            {
575
+                return $string;
576
+            }
577
+
578
+            /**
579
+             *	This method goes through an array, and changes the keys to all lower case.
580
+             *
581
+             *	@access private
582
+             *	@param array $in_array Associative array
583
+             *	@return array Modified array
584
+             *	@since PHP4 OOP 0.0.1
585
+             */
586
+            function _array_lc($inarray)
587
+            {
588
+                $outarray = array();
589
+
590
+                if(is_array($inarray) && count($inarray) > 0)
591
+                {
592
+                    foreach ($inarray as $inkey => $inval)
593
+                    {
594
+                        $outkey = strtolower($inkey);
595
+                        $outarray[$outkey] = array();
596
+
597
+                        if(is_array($inval) && count($inval) > 0)
598
+                        {
599
+                            foreach ($inval as $inkey2 => $inval2)
600
+                            {
601
+                                $outkey2 = strtolower($inkey2);
602
+                                $outarray[$outkey][$outkey2] = $inval2;
603
+                            }
604
+                        }
605
+                    }
606
+                }
607
+
608
+                return $outarray;
609
+            }
610
+
611
+            /**
612
+             *	This method searched for HTML tags, no matter how malformed.  It also
613
+             *	matches stray ">" characters.
614
+             *
615
+             *	@access private
616
+             *	@param string $string
617
+             *	@return string HTML tags
618
+             *	@since PHP4 OOP 0.0.1
619
+             */
620
+            function _split($string)
621
+            {
622
+                return preg_replace(
623
+                    '%(<'.   # EITHER: <
624
+                    '[^>]*'. # things that aren't >
625
+                    '(>|$)'. # > or end of string
626
+                    '|>)%e', # OR: just a >
627
+                    "\$this->_split2('\\1')",
628
+                    $string);
629
+            }
630
+
631
+            /**
632
+             *	This method strips out disallowed and/or mangled (X)HTML tags along with assigned attributes.
633
+             *
634
+             *	This method does a lot of work. It rejects some very malformed things
635
+             *	like <:::>. It returns an empty string if the element isn't allowed (look
636
+             *	ma, no strip_tags()!). Otherwise it splits the tag into an element and an
637
+             *	allowed attribute list.
638
+             *
639
+             *	@access private
640
+             *	@param string $string
641
+             *	@return string Modified string minus disallowed/mangled (X)HTML and attributes
642
+             *	@since PHP4 OOP 0.0.1
643
+             */
644
+            function _split2($string)
645
+            {
646
+                $string = $this->_stripslashes($string);
647
+
648
+                if (substr($string, 0, 1) != '<')
649
+                {
650
+                    # It matched a ">" character
651
+                    return '&gt;';
652
+                }
653
+
654
+                if (!preg_match('%^<\s*(/\s*)?([a-zA-Z0-9]+)([^>]*)>?$%', $string, $matches))
655
+                {
656
+                    # It's seriously malformed
657
+                    return '';
658
+                }
659
+
660
+                $slash    = trim($matches[1]);
661
+                $elem     = $matches[2];
662
+                $attrlist = $matches[3];
663
+
664
+                if (
665
+                    !isset($this->allowed_html[strtolower($elem)]) ||
666
+                    !is_array($this->allowed_html[strtolower($elem)])
667
+                )
668
+                {
669
+                    # They are using a not allowed HTML element
670
+                    return '';
671
+                }
672
+
673
+                if ($slash != '')
674
+                {
675
+                    return "<$slash$elem>";
676
+                }
677
+                # No attributes are allowed for closing elements
678
+
679
+                return $this->_attr("$slash$elem", $attrlist);
680
+            }
681
+
682
+            /**
683
+             *	This method strips out disallowed attributes for (X)HTML tags.
684
+             *
685
+             *	This method removes all attributes if none are allowed for this element.
686
+             *	If some are allowed it calls $this->_hair() to split them further, and then it
687
+             *	builds up new HTML code from the data that $this->_hair() returns. It also
688
+             *	removes "<" and ">" characters, if there are any left. One more thing it
689
+             *	does is to check if the tag has a closing XHTML slash, and if it does,
690
+             *	it puts one in the returned code as well.
691
+             *
692
+             *	@access private
693
+             *	@param string $element (X)HTML tag to check
694
+             *	@param string $attr Text containing attributes to check for validity.
695
+             *	@return string Resulting valid (X)HTML or ''
696
+             *	@see _hair()
697
+             *	@since PHP4 OOP 0.0.1
698
+             */
699
+            function _attr($element, $attr)
700
+            {
701
+                # Is there a closing XHTML slash at the end of the attributes?
702
+                $xhtml_slash = '';
703
+                if (preg_match('%\s/\s*$%', $attr))
704
+                {
705
+                    $xhtml_slash = ' /';
706
+                }
707
+
708
+                # Are any attributes allowed at all for this element?
709
+                if (
710
+                    !isset($this->allowed_html[strtolower($element)]) ||
711
+                    count($this->allowed_html[strtolower($element)]) == 0
712
+                )
713
+                {
714
+                    return "<$element$xhtml_slash>";
715
+                }
716
+
717
+                # Split it
718
+                $attrarr = $this->_hair($attr);
719
+
720
+                # Go through $attrarr, and save the allowed attributes for this element
721
+                # in $attr2
722
+                $attr2 = '';
723
+                if(is_array($attrarr) && count($attrarr) > 0)
724
+                {
725
+                    foreach ($attrarr as $arreach)
726
+                    {
727
+                        if(!isset($this->allowed_html[strtolower($element)][strtolower($arreach['name'])]))
728
+                        {
729
+                            continue;
730
+                        }
731
+
732
+                        $current = $this->allowed_html[strtolower($element)][strtolower($arreach['name'])];
733
+                        if ($current == '')
734
+                        {
735
+                            # the attribute is not allowed
736
+                            continue;
737
+                        }
738
+
739
+                        if (!is_array($current))
740
+                        {
741
+                            # there are no checks
742
+                            $attr2 .= ' '.$arreach['whole'];
743
+                        }
744
+                        else
745
+                        {
746
+                            # there are some checks
747
+                            $ok = true;
748
+                            if(is_array($current) && count($current) > 0)
749
+                            {
750
+                                foreach ($current as $currkey => $currval)
751
+                                {
752
+                                    if (!$this->_check_attr_val($arreach['value'], $arreach['vless'], $currkey, $currval))
753
+                                    {
754
+                                        $ok = false;
755
+                                        break;
756
+                                    }
757
+                                }
758
+
759
+                                if ($ok)
760
+                                {
761
+                                    # it passed them
762
+                                    $attr2 .= ' '.$arreach['whole'];
763
+                                }
764
+                            }
765
+                        }
766
+                    }
767
+                }
768
+
769
+                # Remove any "<" or ">" characters
770
+                $attr2 = preg_replace('/[<>]/', '', $attr2);
771
+                return "<$element$attr2$xhtml_slash>";
772
+            }
773
+
774
+            /**
775
+             *	This method combs through an attribute list string and returns an associative array of attributes and values.
776
+             *
777
+             *	This method does a lot of work. It parses an attribute list into an array
778
+             *	with attribute data, and tries to do the right thing even if it gets weird
779
+             *	input. It will add quotes around attribute values that don't have any quotes
780
+             *	or apostrophes around them, to make it easier to produce HTML code that will
781
+             *	conform to W3C's HTML specification. It will also remove bad URL protocols
782
+             *	from attribute values.
783
+             *
784
+             *	@access private
785
+             *	@param string $attr Text containing tag attributes for parsing
786
+             *	@return array Associative array containing data on attribute and value
787
+             *	@since PHP4 OOP 0.0.1
788
+             */
789
+            function _hair($attr)
790
+            {
791
+                $attrarr  = array();
792
+                $mode     = 0;
793
+                $attrname = '';
794
+
795
+                # Loop through the whole attribute list
796
+
797
+                while (strlen($attr) != 0)
798
+                {
799
+                    # Was the last operation successful?
800
+                    $working = 0;
801
+
802
+                    switch ($mode)
803
+                    {
804
+                        case 0:	# attribute name, href for instance
805
+                            if (preg_match('/^([-a-zA-Z]+)/', $attr, $match))
806
+                            {
807
+                                $attrname = $match[1];
808
+                                $working = $mode = 1;
809
+                                $attr = preg_replace('/^[-a-zA-Z]+/', '', $attr);
810
+                            }
811
+                            break;
812
+                        case 1:	# equals sign or valueless ("selected")
813
+                            if (preg_match('/^\s*=\s*/', $attr)) # equals sign
814
+                            {
815
+                                $working = 1;
816
+                                $mode    = 2;
817
+                                $attr    = preg_replace('/^\s*=\s*/', '', $attr);
818
+                                break;
819
+                            }
820
+                            if (preg_match('/^\s+/', $attr)) # valueless
821
+                            {
822
+                                $working   = 1;
823
+                                $mode      = 0;
824
+                                $attrarr[] = array(
825
+                                    'name'  => $attrname,
826
+                                    'value' => '',
827
+                                    'whole' => $attrname,
828
+                                    'vless' => 'y'
829
+                                );
830
+                                $attr      = preg_replace('/^\s+/', '', $attr);
831
+                            }
832
+                            break;
833
+                        case 2: # attribute value, a URL after href= for instance
834
+                            if (preg_match('/^"([^"]*)"(\s+|$)/', $attr, $match)) # "value"
835
+                            {
836
+                                $thisval   = $this->_bad_protocol($match[1]);
837
+                                $attrarr[] = array(
838
+                                    'name'  => $attrname,
839
+                                    'value' => $thisval,
840
+                                    'whole' => "$attrname=\"$thisval\"",
841
+                                    'vless' => 'n'
842
+                                );
843
+                                $working   = 1;
844
+                                $mode      = 0;
845
+                                $attr      = preg_replace('/^"[^"]*"(\s+|$)/', '', $attr);
846
+                                break;
847
+                            }
848
+                            if (preg_match("/^'([^']*)'(\s+|$)/", $attr, $match)) # 'value'
849
+                            {
850
+                                $thisval   = $this->_bad_protocol($match[1]);
851
+                                $attrarr[] = array(
852
+                                    'name'  => $attrname,
853
+                                    'value' => $thisval,
854
+                                    'whole' => "$attrname='$thisval'",
855
+                                    'vless' => 'n'
856
+                                );
857
+                                $working   = 1;
858
+                                $mode      = 0;
859
+                                $attr      = preg_replace("/^'[^']*'(\s+|$)/", '', $attr);
860
+                                break;
861
+                            }
862
+                            if (preg_match("%^([^\s\"']+)(\s+|$)%", $attr, $match)) # value
863
+                            {
864
+                                $thisval   = $this->_bad_protocol($match[1]);
865
+                                $attrarr[] = array(
866
+                                    'name'  => $attrname,
867
+                                    'value' => $thisval,
868
+                                    'whole' => "$attrname=\"$thisval\"",
869
+                                    'vless' => 'n'
870
+                                );
871
+                                # We add quotes to conform to W3C's HTML spec.
872
+                                $working   = 1;
873
+                                $mode      = 0;
874
+                                $attr      = preg_replace("%^[^\s\"']+(\s+|$)%", '', $attr);
875
+                            }
876
+                            break;
877
+                    }
878
+
879
+                    if ($working == 0) # not well formed, remove and try again
880
+                    {
881
+                        $attr = $this->_html_error($attr);
882
+                        $mode = 0;
883
+                    }
884
+                }
885
+
886
+                # special case, for when the attribute list ends with a valueless
887
+                # attribute like "selected"
888
+                if ($mode == 1)
889
+                {
890
+                    $attrarr[] = array(
891
+                        'name'  => $attrname,
892
+                        'value' => '',
893
+                        'whole' => $attrname,
894
+                        'vless' => 'y'
895
+                    );
896
+                }
897
+
898
+                return $attrarr;
899
+            }
900
+
901
+            /**
902
+             *	This method removes disallowed protocols.
903
+             *
904
+             *	This method removes all non-allowed protocols from the beginning of
905
+             *	$string. It ignores whitespace and the case of the letters, and it does
906
+             *	understand HTML entities. It does its work in a while loop, so it won't be
907
+             *	fooled by a string like "javascript:javascript:alert(57)".
908
+             *
909
+             *	@access private
910
+             *	@param string $string String to check for protocols
911
+             *	@return string String with removed protocols
912
+             *	@since PHP4 OOP 0.0.1
913
+             */
914
+            function _bad_protocol($string)
915
+            {
916
+                $string  = $this->_no_null($string);
917
+                $string = preg_replace('/\xad+/', '', $string); # deals with Opera "feature"
918
+                $string2 = $string.'a';
919
+
920
+                while ($string != $string2)
921
+                {
922
+                    $string2 = $string;
923
+                    $string  = $this->_bad_protocol_once($string);
924
+                } # while
925
+
926
+                return $string;
927
+            }
928
+
929
+            /**
930
+             *	Helper method used by _bad_protocol()
931
+             *
932
+             *	This function searches for URL protocols at the beginning of $string, while
933
+             *	handling whitespace and HTML entities.
934
+             *  Function updated to fix security vulnerability (see http://projects.dokeos.com/index.php?do=details&task_id=2312)
935
+             *
936
+             *	@access private
937
+             *	@param string $string String to check for protocols
938
+             *	@return string String with removed protocols
939
+             *	@see _bad_protocol()
940
+             *	@since PHP4 OOP 0.0.1
941
+             */
942
+            function _bad_protocol_once($string)
943
+            {
944
+                $string2 = preg_split('/:|&#58;|&#x3a;/i', $string, 2);
945
+                if(isset($string2[1]) && !preg_match('%/\?%',$string2[0]))
946
+                {
947
+                    $string = $this->_bad_protocol_once2($string2[0]).trim($string2[1]);
948
+                }
949
+                return $string;
950
+            }
951
+            /**
952
+             *	Helper method used by _bad_protocol_once() regex
953
+             *
954
+             *	This function processes URL protocols, checks to see if they're in the white-
955
+             *	list or not, and returns different data depending on the answer.
956
+             *
957
+             *	@access private
958
+             *	@param string $string String to check for protocols
959
+             *	@return string String with removed protocols
960
+             *	@see _bad_protocol()
961
+             *	@see _bad_protocol_once()
962
+             *	@since PHP4 OOP 0.0.1
963
+             */
964
+            function _bad_protocol_once2($string)
965
+            {
966
+                $string = $this->_decode_entities($string);
967
+                $string = preg_replace('/\s/', '', $string);
968
+                $string = $this->_no_null($string);
969
+                $string = preg_replace('/\xad+/', '', $string); # deals with Opera "feature"
970
+                $string = strtolower($string);
971
+
972
+                $allowed = false;
973
+                if(is_array($this->allowed_protocols) && count($this->allowed_protocols) > 0)
974
+                {
975
+                    foreach ($this->allowed_protocols as $one_protocol)
976
+                    {
977
+                        if (strtolower($one_protocol) == $string)
978
+                        {
979
+                            $allowed = true;
980
+                            break;
981
+                        }
982
+                    }
983
+                }
984
+
985
+                if ($allowed)
986
+                {
987
+                    return "$string:";
988
+                }
989
+                else
990
+                {
991
+                    return '';
992
+                }
993
+            }
994
+
995
+            /**
996
+             *	This function performs different checks for attribute values.
997
+             *
998
+             *	The currently implemented checks are "maxlen", "minlen", "maxval",
999
+             *	"minval" and "valueless" with even more checks to come soon.
1000
+             *
1001
+             *	@access private
1002
+             *	@param string $value The value of the attribute to be checked.
1003
+             *	@param string $vless Indicates whether the the value is supposed to be valueless
1004
+             *	@param string $checkname The check to be performed
1005
+             *	@param string $checkvalue The value that is to be checked against
1006
+             *	@return bool Indicates whether the check passed or not
1007
+             *	@since PHP4 OOP 0.0.1
1008
+             */
1009
+            function _check_attr_val($value, $vless, $checkname, $checkvalue)
1010
+            {
1011
+                $ok = true;
1012
+
1013
+                switch (strtolower($checkname))
1014
+                {
1015
+                    /**
1016
+                     *	The maxlen check makes sure that the attribute value has a length not
1017
+                     *	greater than the given value. This can be used to avoid Buffer Overflows
1018
+                     *	in WWW clients and various Internet servers.
1019
+                     */
1020
+                    case 'maxlen':
1021
+                        if (strlen($value) > $checkvalue)
1022
+                        {
1023
+                            $ok = false;
1024
+                        }
1025
+                        break;
1026
+
1027
+                    /**
1028
+                     *	The minlen check makes sure that the attribute value has a length not
1029
+                     *	smaller than the given value.
1030
+                     */
1031
+                    case 'minlen':
1032
+                        if (strlen($value) < $checkvalue)
1033
+                        {
1034
+                            $ok = false;
1035
+                        }
1036
+                        break;
1037
+
1038
+                    /**
1039
+                     *	The maxval check does two things: it checks that the attribute value is
1040
+                     *	an integer from 0 and up, without an excessive amount of zeroes or
1041
+                     *	whitespace (to avoid Buffer Overflows). It also checks that the attribute
1042
+                     *	value is not greater than the given value.
1043
+                     *	This check can be used to avoid Denial of Service attacks.
1044
+                     */
1045
+                    case 'maxval':
1046
+                        if (!preg_match('/^\s{0,6}[0-9]{1,6}\s{0,6}$/', $value))
1047
+                        {
1048
+                            $ok = false;
1049
+                        }
1050
+                        if ($value > $checkvalue)
1051
+                        {
1052
+                            $ok = false;
1053
+                        }
1054
+                        break;
1055
+
1056
+                    /**
1057
+                     *	The minval check checks that the attribute value is a positive integer,
1058
+                     *	and that it is not smaller than the given value.
1059
+                     */
1060
+                    case 'minval':
1061
+                        if (!preg_match('/^\s{0,6}[0-9]{1,6}\s{0,6}$/', $value))
1062
+                        {
1063
+                            $ok = false;
1064
+                        }
1065
+                        if ($value < $checkvalue)
1066
+                        {
1067
+                            $ok = false;
1068
+                        }
1069
+                        break;
1070
+
1071
+                    /**
1072
+                     *	The valueless check checks if the attribute has a value
1073
+                     *	(like <a href="blah">) or not (<option selected>). If the given value
1074
+                     *	is a "y" or a "Y", the attribute must not have a value.
1075
+                     *	If the given value is an "n" or an "N", the attribute must have one.
1076
+                     */
1077
+                    case 'valueless':
1078
+                    if (strtolower($checkvalue) != $vless)
1079
+                    {
1080
+                        $ok = false;
1081
+                    }
1082
+                    break;
1083
+
1084
+                }
1085
+
1086
+                return $ok;
1087
+            }
1088
+
1089
+            /**
1090
+             *	Changes \" to "
1091
+             *
1092
+             *	This function changes the character sequence  \"  to just  "
1093
+             *	It leaves all other slashes alone. It's really weird, but the quoting from
1094
+             *	preg_replace(//e) seems to require this.
1095
+             *
1096
+             *	@access private
1097
+             *	@param string $string The string to be stripped.
1098
+             *	@return string string stripped of \"
1099
+             *	@since PHP4 OOP 0.0.1
1100
+             */
1101
+            function _stripslashes($string)
1102
+            {
1103
+                return preg_replace('%\\\\"%', '"', $string);
1104
+            }
1105
+
1106
+            /**
1107
+             *	helper method for _hair()
1108
+             *
1109
+             *	This function deals with parsing errors in _hair(). The general plan is
1110
+             *	to remove everything to and including some whitespace, but it deals with
1111
+             *	quotes and apostrophes as well.
1112
+             *
1113
+             *	@access private
1114
+             *	@param string $string The string to be stripped.
1115
+             *	@return string string stripped of whitespace
1116
+             *	@see _hair()
1117
+             *	@since PHP4 OOP 0.0.1
1118
+             */
1119
+            function _html_error($string)
1120
+            {
1121
+                return preg_replace('/^("[^"]*("|$)|\'[^\']*(\'|$)|\S)*\s*/', '', $string);
1122
+            }
1123
+
1124
+            /**
1125
+             *	Decodes numeric HTML entities
1126
+             *
1127
+             *	This method decodes numeric HTML entities (&#65; and &#x41;). It doesn't
1128
+             *	do anything with other entities like &auml;, but we don't need them in the
1129
+             *	URL protocol white listing system anyway.
1130
+             *
1131
+             *	@access private
1132
+             *	@param string $value The entitiy to be decoded.
1133
+             *	@return string Decoded entity
1134
+             *	@since PHP4 OOP 0.0.1
1135
+             */
1136
+            function _decode_entities($string)
1137
+            {
1138
+                $string = preg_replace('/&#([0-9]+);/e', 'chr("\\1")', $string);
1139
+                $string = preg_replace('/&#[Xx]([0-9A-Fa-f]+);/e', 'chr(hexdec("\\1"))', $string);
1140
+                return $string;
1141
+            }
1142
+
1143
+            /**
1144
+             *	Returns PHP4 OOP version # of kses.
1145
+             *
1146
+             *	Since this class has been refactored and documented and proven to work,
1147
+             *	I'm syncing the version number to procedural kses.
1148
+             *
1149
+             *	@access public
1150
+             *	@return string Version number
1151
+             *	@since PHP4 OOP 0.0.1
1152
+             */
1153
+            function _version()
1154
+            {
1155
+                return 'PHP4 0.2.2 (OOP fork of procedural kses 0.2.2)';
1156
+            }
1157
+        }
1158
+
1159
+
1160
+
1161
+    }
1162 1162
 ?>
1163 1163
\ No newline at end of file
Please login to merge, or discard this patch.
main/inc/lib/xajax/xajax.inc.php 1 patch
Indentation   +1165 added lines, -1165 removed lines patch added patch discarded remove patch
@@ -47,7 +47,7 @@  discard block
 block discarded – undo
47 47
  */
48 48
 if (!defined ('XAJAX_DEFAULT_CHAR_ENCODING'))
49 49
 {
50
-	define ('XAJAX_DEFAULT_CHAR_ENCODING', 'utf-8' );
50
+    define ('XAJAX_DEFAULT_CHAR_ENCODING', 'utf-8' );
51 51
 }
52 52
 
53 53
 /**
@@ -55,11 +55,11 @@  discard block
 block discarded – undo
55 55
  */
56 56
 if (!defined ('XAJAX_GET'))
57 57
 {
58
-	define ('XAJAX_GET', 0);
58
+    define ('XAJAX_GET', 0);
59 59
 }
60 60
 if (!defined ('XAJAX_POST'))
61 61
 {
62
-	define ('XAJAX_POST', 1);
62
+    define ('XAJAX_POST', 1);
63 63
 }
64 64
 
65 65
 /**
@@ -72,1145 +72,1145 @@  discard block
 block discarded – undo
72 72
  */
73 73
 class xajax
74 74
 {
75
-	/**#@+
75
+    /**#@+
76 76
 	 * @access protected
77 77
 	 */
78
-	/**
79
-	 * @var array Array of PHP functions that will be callable through javascript wrappers
80
-	 */
81
-	var $aFunctions;
82
-	/**
83
-	 * @var array Array of object callbacks that will allow Javascript to call PHP methods (key=function name)
84
-	 */
85
-	var $aObjects;
86
-	/**
87
-	 * @var array Array of RequestTypes to be used with each function (key=function name)
88
-	 */
89
-	var $aFunctionRequestTypes;
90
-	/**
91
-	 * @var array Array of Include Files for any external functions (key=function name)
92
-	 */
93
-	var $aFunctionIncludeFiles;
94
-	/**
95
-	 * @var string Name of the PHP function to call if no callable function was found
96
-	 */
97
-	var $sCatchAllFunction;
98
-	/**
99
-	 * @var string Name of the PHP function to call before any other function
100
-	 */
101
-	var $sPreFunction;
102
-	/**
103
-	 * @var string The URI for making requests to the xajax object
104
-	 */
105
-	var $sRequestURI;
106
-	/**
107
-	 * @var string The prefix to prepend to the javascript wraper function name
108
-	 */
109
-	var $sWrapperPrefix;
110
-	/**
111
-	 * @var boolean Show debug messages (default false)
112
-	 */
113
-	var $bDebug;
114
-	/**
115
-	 * @var boolean Show messages in the client browser's status bar (default false)
116
-	 */
117
-	var $bStatusMessages;
118
-	/**
119
-	 * @var boolean Allow xajax to exit after processing a request (default true)
120
-	 */
121
-	var $bExitAllowed;
122
-	/**
123
-	 * @var boolean Use wait cursor in browser (default true)
124
-	 */
125
-	var $bWaitCursor;
126
-	/**
127
-	 * @var boolean Use an special xajax error handler so the errors are sent to the browser properly (default false)
128
-	 */
129
-	var $bErrorHandler;
130
-	/**
131
-	 * @var string Specify what, if any, file xajax should log errors to (and more information in a future release)
132
-	 */
133
-	var $sLogFile;
134
-	/**
135
-	 * @var boolean Clean all output buffers before outputting response (default false)
136
-	 */
137
-	var $bCleanBuffer;
138
-	/**
139
-	 * @var string String containing the character encoding used
140
-	 */
141
-	var $sEncoding;
142
-	/**
143
-	 * @var boolean Decode input request args from UTF-8 (default false)
144
-	 */
145
-	var $bDecodeUTF8Input;
146
-	/**
147
-	 * @var boolean Convert special characters to HTML entities (default false)
148
-	 */
149
-	var $bOutputEntities;
150
-	/**
151
-	 * @var array Array for parsing complex objects
152
-	 */
153
-	var $aObjArray;
154
-	/**
155
-	 * @var integer Position in $aObjArray
156
-	 */
157
-	var $iPos;
158
-
159
-	/**#@-*/
160
-
161
-	/**
162
-	 * Constructor. You can set some extra xajax options right away or use
163
-	 * individual methods later to set options.
164
-	 *
165
-	 * @param string  defaults to the current browser URI
166
-	 * @param string  defaults to "xajax_";
167
-	 * @param string  defaults to XAJAX_DEFAULT_CHAR_ENCODING defined above
168
-	 * @param boolean defaults to false
169
-	 */
170
-	function xajax($sRequestURI="",$sWrapperPrefix="xajax_",$sEncoding=XAJAX_DEFAULT_CHAR_ENCODING,$bDebug=false)
171
-	{
172
-		$this->aFunctions = array();
173
-		$this->aObjects = array();
174
-		$this->aFunctionIncludeFiles = array();
175
-		$this->sRequestURI = $sRequestURI;
176
-		if ($this->sRequestURI == "")
177
-			$this->sRequestURI = $this->_detectURI();
178
-		$this->sWrapperPrefix = $sWrapperPrefix;
179
-		$this->bDebug = $bDebug;
180
-		$this->bStatusMessages = false;
181
-		$this->bWaitCursor = true;
182
-		$this->bExitAllowed = true;
183
-		$this->bErrorHandler = false;
184
-		$this->sLogFile = "";
185
-		$this->bCleanBuffer = false;
186
-		$this->setCharEncoding($sEncoding);
187
-		$this->bDecodeUTF8Input = false;
188
-		$this->bOutputEntities = false;
189
-	}
190
-
191
-	/**
192
-	 * Sets the URI to which requests will be made.
193
-	 * <i>Usage:</i> <kbd>$xajax->setRequestURI("http://www.xajaxproject.org");</kbd>
194
-	 *
195
-	 * @param string the URI (can be absolute or relative) of the PHP script
196
-	 *               that will be accessed when an xajax request occurs
197
-	 */
198
-	function setRequestURI($sRequestURI)
199
-	{
200
-		$this->sRequestURI = $sRequestURI;
201
-	}
202
-
203
-	/**
204
-	 * Sets the prefix that will be appended to the Javascript wrapper
205
-	 * functions (default is "xajax_").
206
-	 *
207
-	 * @param string
208
-	 */
209
-	//
210
-	function setWrapperPrefix($sPrefix)
211
-	{
212
-		$this->sWrapperPrefix = $sPrefix;
213
-	}
214
-
215
-	/**
216
-	 * Enables debug messages for xajax.
217
-	 * */
218
-	function debugOn()
219
-	{
220
-		$this->bDebug = true;
221
-	}
222
-
223
-	/**
224
-	 * Disables debug messages for xajax (default behavior).
225
-	 */
226
-	function debugOff()
227
-	{
228
-		$this->bDebug = false;
229
-	}
230
-
231
-	/**
232
-	 * Enables messages in the browser's status bar for xajax.
233
-	 */
234
-	function statusMessagesOn()
235
-	{
236
-		$this->bStatusMessages = true;
237
-	}
238
-
239
-	/**
240
-	 * Disables messages in the browser's status bar for xajax (default behavior).
241
-	 */
242
-	function statusMessagesOff()
243
-	{
244
-		$this->bStatusMessages = false;
245
-	}
246
-
247
-	/**
248
-	 * Enables the wait cursor to be displayed in the browser (default behavior).
249
-	 */
250
-	function waitCursorOn()
251
-	{
252
-		$this->bWaitCursor = true;
253
-	}
254
-
255
-	/**
256
-	 * Disables the wait cursor to be displayed in the browser.
257
-	 */
258
-	function waitCursorOff()
259
-	{
260
-		$this->bWaitCursor = false;
261
-	}
262
-
263
-	/**
264
-	 * Enables xajax to exit immediately after processing a request and
265
-	 * sending the response back to the browser (default behavior).
266
-	 */
267
-	function exitAllowedOn()
268
-	{
269
-		$this->bExitAllowed = true;
270
-	}
271
-
272
-	/**
273
-	 * Disables xajax's default behavior of exiting immediately after
274
-	 * processing a request and sending the response back to the browser.
275
-	 */
276
-	function exitAllowedOff()
277
-	{
278
-		$this->bExitAllowed = false;
279
-	}
280
-
281
-	/**
282
-	 * Turns on xajax's error handling system so that PHP errors that occur
283
-	 * during a request are trapped and pushed to the browser in the form of
284
-	 * a Javascript alert.
285
-	 */
286
-	function errorHandlerOn()
287
-	{
288
-		$this->bErrorHandler = true;
289
-	}
290
-
291
-	/**
292
-	 * Turns off xajax's error handling system (default behavior).
293
-	 */
294
-	function errorHandlerOff()
295
-	{
296
-		$this->bErrorHandler = false;
297
-	}
298
-
299
-	/**
300
-	 * Specifies a log file that will be written to by xajax during a request
301
-	 * (used only by the error handling system at present). If you don't invoke
302
-	 * this method, or you pass in "", then no log file will be written to.
303
-	 * <i>Usage:</i> <kbd>$xajax->setLogFile("/xajax_logs/errors.log");</kbd>
304
-	 */
305
-	function setLogFile($sFilename)
306
-	{
307
-		$this->sLogFile = $sFilename;
308
-	}
309
-
310
-	/**
311
-	 * Causes xajax to clean out all output buffers before outputting a
312
-	 * response (default behavior).
313
-	 */
314
-	function cleanBufferOn()
315
-	{
316
-		$this->bCleanBuffer = true;
317
-	}
318
-	/**
319
-	 * Turns off xajax's output buffer cleaning.
320
-	 */
321
-	function cleanBufferOff()
322
-	{
323
-		$this->bCleanBuffer = false;
324
-	}
325
-
326
-	/**
327
-	 * Sets the character encoding for the HTTP output based on
328
-	 * <kbd>$sEncoding</kbd>, which is a string containing the character
329
-	 * encoding to use. You don't need to use this method normally, since the
330
-	 * character encoding for the response gets set automatically based on the
331
-	 * <kbd>XAJAX_DEFAULT_CHAR_ENCODING</kbd> constant.
332
-	 * <i>Usage:</i> <kbd>$xajax->setCharEncoding("utf-8");</kbd>
333
-	 *
334
-	 * @param string the encoding type to use (utf-8, iso-8859-1, etc.)
335
-	 */
336
-	function setCharEncoding($sEncoding)
337
-	{
338
-		$this->sEncoding = $sEncoding;
339
-	}
340
-
341
-	/**
342
-	 * Causes xajax to decode the input request args from UTF-8 to the current
343
-	 * encoding if possible. Either the iconv or mb_string extension must be
344
-	 * present for optimal functionality.
345
-	 */
346
-	function decodeUTF8InputOn()
347
-	{
348
-		$this->bDecodeUTF8Input = true;
349
-	}
350
-
351
-	/**
352
-	 * Turns off decoding the input request args from UTF-8 (default behavior).
353
-	 */
354
-	function decodeUTF8InputOff()
355
-	{
356
-		$this->bDecodeUTF8Input = false;
357
-	}
358
-
359
-	/**
360
-	 * Tells the response object to convert special characters to HTML entities
361
-	 * automatically (only works if the mb_string extension is available).
362
-	 */
363
-	function outputEntitiesOn()
364
-	{
365
-		$this->bOutputEntities = true;
366
-	}
367
-
368
-	/**
369
-	 * Tells the response object to output special characters intact. (default
370
-	 * behavior).
371
-	 */
372
-	function outputEntitiesOff()
373
-	{
374
-		$this->bOutputEntities = false;
375
-	}
376
-
377
-	/**
378
-	 * Registers a PHP function or method to be callable through xajax in your
379
-	 * Javascript. If you want to register a function, pass in the name of that
380
-	 * function. If you want to register a static class method, pass in an
381
-	 * array like so:
382
-	 * <kbd>array("myFunctionName", "myClass", "myMethod")</kbd>
383
-	 * For an object instance method, use an object variable for the second
384
-	 * array element (and in PHP 4 make sure you put an & before the variable
385
-	 * to pass the object by reference). Note: the function name is what you
386
-	 * call via Javascript, so it can be anything as long as it doesn't
387
-	 * conflict with any other registered function name.
388
-	 *
389
-	 * <i>Usage:</i> <kbd>$xajax->registerFunction("myFunction");</kbd>
390
-	 * or: <kbd>$xajax->registerFunction(array("myFunctionName", &$myObject, "myMethod"));</kbd>
391
-	 *
392
-	 * @param mixed  contains the function name or an object callback array
393
-	 * @param mixed  request type (XAJAX_GET/XAJAX_POST) that should be used
394
-	 *               for this function.  Defaults to XAJAX_POST.
395
-	 */
396
-	function registerFunction($mFunction,$sRequestType=XAJAX_POST)
397
-	{
398
-		if (is_array($mFunction)) {
399
-			$this->aFunctions[$mFunction[0]] = 1;
400
-			$this->aFunctionRequestTypes[$mFunction[0]] = $sRequestType;
401
-			$this->aObjects[$mFunction[0]] = array_slice($mFunction, 1);
402
-		}
403
-		else {
404
-			$this->aFunctions[$mFunction] = 1;
405
-			$this->aFunctionRequestTypes[$mFunction] = $sRequestType;
406
-		}
407
-	}
408
-
409
-	/**
410
-	 * Registers a PHP function to be callable through xajax which is located
411
-	 * in some other file.  If the function is requested the external file will
412
-	 * be included to define the function before the function is called.
413
-	 *
414
-	 * <i>Usage:</i> <kbd>$xajax->registerExternalFunction("myFunction","myFunction.inc.php",XAJAX_POST);</kbd>
415
-	 *
416
-	 * @param string contains the function name or an object callback array
417
-	 *               ({@link xajax::registerFunction() see registerFunction} for
418
-	 *               more info on object callback arrays)
419
-	 * @param string contains the path and filename of the include file
420
-	 * @param mixed  the RequestType (XAJAX_GET/XAJAX_POST) that should be used
421
-	 *		          for this function. Defaults to XAJAX_POST.
422
-	 */
423
-	function registerExternalFunction($mFunction,$sIncludeFile,$sRequestType=XAJAX_POST)
424
-	{
425
-		$this->registerFunction($mFunction, $sRequestType);
426
-
427
-		if (is_array($mFunction)) {
428
-			$this->aFunctionIncludeFiles[$mFunction[0]] = $sIncludeFile;
429
-		}
430
-		else {
431
-			$this->aFunctionIncludeFiles[$mFunction] = $sIncludeFile;
432
-		}
433
-	}
434
-
435
-	/**
436
-	 * Registers a PHP function to be called when xajax cannot find the
437
-	 * function being called via Javascript. Because this is technically
438
-	 * impossible when using "wrapped" functions, the catch-all feature is
439
-	 * only useful when you're directly using the xajax.call() Javascript
440
-	 * method. Use the catch-all feature when you want more dynamic ability to
441
-	 * intercept unknown calls and handle them in a custom way.
442
-	 *
443
-	 * <i>Usage:</i> <kbd>$xajax->registerCatchAllFunction("myCatchAllFunction");</kbd>
444
-	 *
445
-	 * @param string contains the function name or an object callback array
446
-	 *               ({@link xajax::registerFunction() see registerFunction} for
447
-	 *               more info on object callback arrays)
448
-	 */
449
-	function registerCatchAllFunction($mFunction)
450
-	{
451
-		if (is_array($mFunction)) {
452
-			$this->sCatchAllFunction = $mFunction[0];
453
-			$this->aObjects[$mFunction[0]] = array_slice($mFunction, 1);
454
-		}
455
-		else {
456
-			$this->sCatchAllFunction = $mFunction;
457
-		}
458
-	}
459
-
460
-	/**
461
-	 * Registers a PHP function to be called before xajax calls the requested
462
-	 * function. xajax will automatically add the request function's response
463
-	 * to the pre-function's response to create a single response. Another
464
-	 * feature is the ability to return not just a response, but an array with
465
-	 * the first element being false (a boolean) and the second being the
466
-	 * response. In this case, the pre-function's response will be returned to
467
-	 * the browser without xajax calling the requested function.
468
-	 *
469
-	 * <i>Usage:</i> <kbd>$xajax->registerPreFunction("myPreFunction");</kbd>
470
-	 *
471
-	 * @param string contains the function name or an object callback array
472
-	 *               ({@link xajax::registerFunction() see registerFunction} for
473
-	 *               more info on object callback arrays)
474
-	 */
475
-	function registerPreFunction($mFunction)
476
-	{
477
-		if (is_array($mFunction)) {
478
-			$this->sPreFunction = $mFunction[0];
479
-			$this->aObjects[$mFunction[0]] = array_slice($mFunction, 1);
480
-		}
481
-		else {
482
-			$this->sPreFunction = $mFunction;
483
-		}
484
-	}
485
-
486
-	/**
487
-	 * Returns true if xajax can process the request, false if otherwise.
488
-	 * You can use this to determine if xajax needs to process the request or
489
-	 * not.
490
-	 *
491
-	 * @return boolean
492
-	 */
493
-	function canProcessRequests()
494
-	{
495
-		if ($this->getRequestMode() != -1) return true;
496
-		return false;
497
-	}
498
-
499
-	/**
500
-	 * Returns the current request mode (XAJAX_GET or XAJAX_POST), or -1 if
501
-	 * there is none.
502
-	 *
503
-	 * @return mixed
504
-	 */
505
-	function getRequestMode()
506
-	{
507
-		if (!empty($_GET["xajax"]))
508
-			return XAJAX_GET;
509
-
510
-		if (!empty($_POST["xajax"]))
511
-			return XAJAX_POST;
512
-
513
-		return -1;
514
-	}
515
-
516
-	/**
517
-	 * This is the main communications engine of xajax. The engine handles all
518
-	 * incoming xajax requests, calls the apporiate PHP functions (or
519
-	 * class/object methods) and passes the XML responses back to the
520
-	 * Javascript response handler. If your RequestURI is the same as your Web
521
-	 * page then this function should be called before any headers or HTML has
522
-	 * been sent.
523
-	 */
524
-	function processRequests()
525
-	{
526
-
527
-		$requestMode = -1;
528
-		$sFunctionName = "";
529
-		$bFoundFunction = true;
530
-		$bFunctionIsCatchAll = false;
531
-		$sFunctionNameForSpecial = "";
532
-		$aArgs = array();
533
-		$sPreResponse = "";
534
-		$bEndRequest = false;
535
-		$sResponse = "";
536
-
537
-		$requestMode = $this->getRequestMode();
538
-		if ($requestMode == -1) return;
539
-
540
-		if ($requestMode == XAJAX_POST)
541
-		{
542
-			$sFunctionName = $_POST["xajax"];
543
-
544
-			if (!empty($_POST["xajaxargs"]))
545
-				$aArgs = $_POST["xajaxargs"];
546
-		}
547
-		else
548
-		{
549
-			header ("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
550
-			header ("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
551
-			header ("Cache-Control: no-cache, must-revalidate");
552
-			header ("Pragma: no-cache");
553
-
554
-			$sFunctionName = $_GET["xajax"];
555
-
556
-			if (!empty($_GET["xajaxargs"]))
557
-				$aArgs = $_GET["xajaxargs"];
558
-		}
559
-
560
-		// Use xajax error handler if necessary
561
-		if ($this->bErrorHandler) {
562
-			$GLOBALS['xajaxErrorHandlerText'] = "";
563
-			set_error_handler("xajaxErrorHandler");
564
-		}
565
-
566
-		if ($this->sPreFunction) {
567
-			if (!$this->_isFunctionCallable($this->sPreFunction)) {
568
-				$bFoundFunction = false;
569
-				$objResponse = new xajaxResponse();
570
-				$objResponse->addAlert("Unknown Pre-Function ". $this->sPreFunction);
571
-				$sResponse = $objResponse->getXML();
572
-			}
573
-		}
574
-		//include any external dependencies associated with this function name
575
-		if (array_key_exists($sFunctionName,$this->aFunctionIncludeFiles))
576
-		{
577
-			ob_start();
578
-			include_once($this->aFunctionIncludeFiles[$sFunctionName]);
579
-			ob_end_clean();
580
-		}
581
-
582
-		if ($bFoundFunction) {
583
-			$sFunctionNameForSpecial = $sFunctionName;
584
-			if (!array_key_exists($sFunctionName, $this->aFunctions))
585
-			{
586
-				if ($this->sCatchAllFunction) {
587
-					$sFunctionName = $this->sCatchAllFunction;
588
-					$bFunctionIsCatchAll = true;
589
-				}
590
-				else {
591
-					$bFoundFunction = false;
592
-					$objResponse = new xajaxResponse();
593
-					$objResponse->addAlert("Unknown Function $sFunctionName.");
594
-					$sResponse = $objResponse->getXML();
595
-				}
596
-			}
597
-			else if ($this->aFunctionRequestTypes[$sFunctionName] != $requestMode)
598
-			{
599
-				$bFoundFunction = false;
600
-				$objResponse = new xajaxResponse();
601
-				$objResponse->addAlert("Incorrect Request Type.");
602
-				$sResponse = $objResponse->getXML();
603
-			}
604
-		}
605
-
606
-		if ($bFoundFunction)
607
-		{
608
-			for ($i = 0; $i < sizeof($aArgs); $i++)
609
-			{
610
-				// If magic quotes is on, then we need to strip the slashes from the args
611
-				if (get_magic_quotes_gpc() == 1 && is_string($aArgs[$i])) {
612
-
613
-					$aArgs[$i] = stripslashes($aArgs[$i]);
614
-				}
615
-				if (stristr($aArgs[$i],"<xjxobj>") != false)
616
-				{
617
-					$aArgs[$i] = $this->_xmlToArray("xjxobj",$aArgs[$i]);
618
-				}
619
-				else if (stristr($aArgs[$i],"<xjxquery>") != false)
620
-				{
621
-					$aArgs[$i] = $this->_xmlToArray("xjxquery",$aArgs[$i]);
622
-				}
623
-				else if ($this->bDecodeUTF8Input)
624
-				{
625
-					$aArgs[$i] = $this->_decodeUTF8Data($aArgs[$i]);
626
-				}
627
-			}
628
-
629
-			if ($this->sPreFunction) {
630
-				$mPreResponse = $this->_callFunction($this->sPreFunction, array($sFunctionNameForSpecial, $aArgs));
631
-				if (is_array($mPreResponse) && $mPreResponse[0] === false) {
632
-					$bEndRequest = true;
633
-					$sPreResponse = $mPreResponse[1];
634
-				}
635
-				else {
636
-					$sPreResponse = $mPreResponse;
637
-				}
638
-				if (is_a($sPreResponse, "xajaxResponse")) {
639
-					$sPreResponse = $sPreResponse->getXML();
640
-				}
641
-				if ($bEndRequest) $sResponse = $sPreResponse;
642
-			}
643
-
644
-			if (!$bEndRequest) {
645
-				if (!$this->_isFunctionCallable($sFunctionName)) {
646
-					$objResponse = new xajaxResponse();
647
-					$objResponse->addAlert("The Registered Function $sFunctionName Could Not Be Found.");
648
-					$sResponse = $objResponse->getXML();
649
-				}
650
-				else {
651
-					if ($bFunctionIsCatchAll) {
652
-						$aArgs = array($sFunctionNameForSpecial, $aArgs);
653
-					}
654
-					$sResponse = $this->_callFunction($sFunctionName, $aArgs);
655
-				}
656
-				if (is_a($sResponse, "xajaxResponse")) {
657
-					$sResponse = $sResponse->getXML();
658
-				}
659
-				if (!is_string($sResponse) || strpos($sResponse, "<xjx>") === FALSE) {
660
-					$objResponse = new xajaxResponse();
661
-					$objResponse->addAlert("No XML Response Was Returned By Function $sFunctionName.");
662
-					$sResponse = $objResponse->getXML();
663
-				}
664
-				else if ($sPreResponse != "") {
665
-					$sNewResponse = new xajaxResponse($this->sEncoding, $this->bOutputEntities);
666
-					$sNewResponse->loadXML($sPreResponse);
667
-					$sNewResponse->loadXML($sResponse);
668
-					$sResponse = $sNewResponse->getXML();
669
-				}
670
-			}
671
-		}
672
-
673
-		$sContentHeader = "Content-type: text/xml;";
674
-		if ($this->sEncoding && strlen(trim($this->sEncoding)) > 0)
675
-			$sContentHeader .= " charset=".$this->sEncoding;
676
-		header($sContentHeader);
677
-		if ($this->bErrorHandler && !empty( $GLOBALS['xajaxErrorHandlerText'] )) {
678
-			$sErrorResponse = new xajaxResponse();
679
-			$sErrorResponse->addAlert("** PHP Error Messages: **" . $GLOBALS['xajaxErrorHandlerText']);
680
-			if ($this->sLogFile) {
681
-				$fH = @fopen($this->sLogFile, "a");
682
-				if (!$fH) {
683
-					$sErrorResponse->addAlert("** Logging Error **\n\nxajax was unable to write to the error log file:\n" . $this->sLogFile);
684
-				}
685
-				else {
686
-					fwrite($fH, "** xajax Error Log - " . strftime("%b %e %Y %I:%M:%S %p") . " **" . $GLOBALS['xajaxErrorHandlerText'] . "\n\n\n");
687
-					fclose($fH);
688
-				}
689
-			}
690
-
691
-			$sErrorResponse->loadXML($sResponse);
692
-			$sResponse = $sErrorResponse->getXML();
693
-
694
-		}
695
-		if ($this->bCleanBuffer) while (@ob_end_clean());
696
-		print $sResponse;
697
-		if ($this->bErrorHandler) restore_error_handler();
698
-
699
-		if ($this->bExitAllowed)
700
-			exit();
701
-	}
702
-
703
-	/**
704
-	 * Prints the xajax Javascript header and wrapper code into your page by
705
-	 * printing the output of the getJavascript() method. It should only be
706
-	 * called between the <pre><head> </head></pre> tags in your HTML page.
707
-	 * Remember, if you only want to obtain the result of this function, use
708
-	 * {@link xajax::getJavascript()} instead.
709
-	 *
710
-	 * <i>Usage:</i>
711
-	 * <code>
712
-	 *  <head>
713
-	 *		...
714
-	 *		< ?php $xajax->printJavascript(); ? >
715
-	 * </code>
716
-	 *
717
-	 * @param string the relative address of the folder where xajax has been
718
-	 *               installed. For instance, if your PHP file is
719
-	 *               "http://www.myserver.com/myfolder/mypage.php"
720
-	 *               and xajax was installed in
721
-	 *               "http://www.myserver.com/anotherfolder", then $sJsURI
722
-	 *               should be set to "../anotherfolder". Defaults to assuming
723
-	 *               xajax is in the same folder as your PHP file.
724
-	 * @param string the relative folder/file pair of the xajax Javascript
725
-	 *               engine located within the xajax installation folder.
726
-	 *               Defaults to xajax_js/xajax.js.
727
-	 */
728
-	function printJavascript($sJsURI="", $sJsFile=NULL)
729
-	{
730
-		print $this->getJavascript($sJsURI, $sJsFile);
731
-	}
732
-
733
-	/**
734
-	 * Returns the xajax Javascript code that should be added to your HTML page
735
-	 * between the <kbd><head> </head></kbd> tags.
736
-	 *
737
-	 * <i>Usage:</i>
738
-	 * <code>
739
-	 *  < ?php $xajaxJSHead = $xajax->getJavascript(); ? >
740
-	 *	<head>
741
-	 *		...
742
-	 *		< ?php echo $xajaxJSHead; ? >
743
-	 * </code>
744
-	 *
745
-	 * @param string the relative address of the folder where xajax has been
746
-	 *               installed. For instance, if your PHP file is
747
-	 *               "http://www.myserver.com/myfolder/mypage.php"
748
-	 *               and xajax was installed in
749
-	 *               "http://www.myserver.com/anotherfolder", then $sJsURI
750
-	 *               should be set to "../anotherfolder". Defaults to assuming
751
-	 *               xajax is in the same folder as your PHP file.
752
-	 * @param string the relative folder/file pair of the xajax Javascript
753
-	 *               engine located within the xajax installation folder.
754
-	 *               Defaults to xajax_js/xajax.js.
755
-	 * @return string
756
-	 */
757
-	function getJavascript($sJsURI="", $sJsFile=NULL)
758
-	{
759
-		$html = $this->getJavascriptConfig();
760
-		$html .= $this->getJavascriptInclude($sJsURI, $sJsFile);
761
-
762
-		return $html;
763
-	}
764
-
765
-	/**
766
-	 * Returns a string containing inline Javascript that sets up the xajax
767
-	 * runtime (typically called internally by xajax from get/printJavascript).
768
-	 *
769
-	 * @return string
770
-	 */
771
-	function getJavascriptConfig()
772
-	{
773
-		$html  = "\t<script type=\"text/javascript\">\n";
774
-		$html .= "var xajaxRequestUri=\"".$this->sRequestURI."\";\n";
775
-		$html .= "var xajaxDebug=".($this->bDebug?"true":"false").";\n";
776
-		$html .= "var xajaxStatusMessages=".($this->bStatusMessages?"true":"false").";\n";
777
-		$html .= "var xajaxWaitCursor=".($this->bWaitCursor?"true":"false").";\n";
778
-		$html .= "var xajaxDefinedGet=".XAJAX_GET.";\n";
779
-		$html .= "var xajaxDefinedPost=".XAJAX_POST.";\n";
780
-		$html .= "var xajaxLoaded=false;\n";
781
-
782
-		foreach($this->aFunctions as $sFunction => $bExists) {
783
-			$html .= $this->_wrap($sFunction,$this->aFunctionRequestTypes[$sFunction]);
784
-		}
785
-
786
-		$html .= "\t</script>\n";
787
-		return $html;
788
-	}
789
-
790
-	/**
791
-	 * Returns a string containing a Javascript include of the xajax.js file
792
-	 * along with a check to see if the file loaded after six seconds
793
-	 * (typically called internally by xajax from get/printJavascript).
794
-	 *
795
-	 * @param string the relative address of the folder where xajax has been
796
-	 *               installed. For instance, if your PHP file is
797
-	 *               "http://www.myserver.com/myfolder/mypage.php"
798
-	 *               and xajax was installed in
799
-	 *               "http://www.myserver.com/anotherfolder", then $sJsURI
800
-	 *               should be set to "../anotherfolder". Defaults to assuming
801
-	 *               xajax is in the same folder as your PHP file.
802
-	 * @param string the relative folder/file pair of the xajax Javascript
803
-	 *               engine located within the xajax installation folder.
804
-	 *               Defaults to xajax_js/xajax.js.
805
-	 * @return string
806
-	 */
807
-	function getJavascriptInclude($sJsURI="", $sJsFile=NULL)
808
-	{
809
-		if ($sJsFile == NULL) $sJsFile = "xajax_js/xajax.js";
810
-
811
-		if ($sJsURI != "" && substr($sJsURI, -1) != "/") $sJsURI .= "/";
812
-
813
-		$html = "\t<script type=\"text/javascript\" src=\"" . $sJsURI . $sJsFile . "\"></script>\n";
814
-		$html .= "\t<script type=\"text/javascript\">\n";
815
-		$html .= "window.setTimeout(function () { if (!xajaxLoaded) { alert('Error: the xajax Javascript file could not be included. Perhaps the URL is incorrect?\\nURL: {$sJsURI}{$sJsFile}'); } }, 6000);\n";
816
-		$html .= "\t</script>\n";
817
-		return $html;
818
-	}
819
-
820
-	/**
821
-	 * This method can be used to create a new xajax.js file out of the
822
-	 * xajax_uncompressed.js file (which will only happen if xajax.js doesn't
823
-	 * already exist on the filesystem).
824
-	 *
825
-	 * @param string an optional argument containing the full server file path
826
-	 *               of xajax.js.
827
-	 */
828
-	function autoCompressJavascript($sJsFullFilename=NULL)
829
-	{
830
-		$sJsFile = "xajax_js/xajax.js";
831
-
832
-		if ($sJsFullFilename) {
833
-			$realJsFile = $sJsFullFilename;
834
-		}
835
-		else {
836
-			$realPath = realpath(dirname(__FILE__));
837
-			$realJsFile = $realPath . "/". $sJsFile;
838
-		}
839
-
840
-		// Create a compressed file if necessary
841
-		if (!file_exists($realJsFile)) {
842
-			$srcFile = str_replace(".js", "_uncompressed.js", $realJsFile);
843
-			if (!file_exists($srcFile)) {
844
-				trigger_error("The xajax uncompressed Javascript file could not be found in the <b>" . dirname($realJsFile) . "</b> folder. Error ", E_USER_ERROR);
845
-			}
846
-			require(dirname(__FILE__)."/xajaxCompress.php");
847
-			$javaScript = implode('', file($srcFile));
848
-			$compressedScript = xajaxCompressJavascript($javaScript);
849
-			$fH = @fopen($realJsFile, "w");
850
-			if (!$fH) {
851
-				trigger_error("The xajax compressed javascript file could not be written in the <b>" . dirname($realJsFile) . "</b> folder. Error ", E_USER_ERROR);
852
-			}
853
-			else {
854
-				fwrite($fH, $compressedScript);
855
-				fclose($fH);
856
-			}
857
-		}
858
-	}
859
-
860
-	/**
861
-	 * Returns the current URL based upon the SERVER vars.
862
-	 *
863
-	 * @access private
864
-	 * @return string
865
-	 */
866
-	function _detectURI() {
867
-		$aURL = array();
868
-
869
-		// Try to get the request URL
870
-		if (!empty($_SERVER['REQUEST_URI'])) {
871
-			$aURL = parse_url($_SERVER['REQUEST_URI']);
872
-		}
873
-
874
-		// Fill in the empty values
875
-		if (empty($aURL['scheme'])) {
876
-			if (!empty($_SERVER['HTTP_SCHEME'])) {
877
-				$aURL['scheme'] = $_SERVER['HTTP_SCHEME'];
878
-			} else {
879
-				$aURL['scheme'] = (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) != 'off') ? 'https' : 'http';
880
-			}
881
-		}
882
-
883
-		if (empty($aURL['host'])) {
884
-			if (!empty($_SERVER['HTTP_HOST'])) {
885
-				if (strpos($_SERVER['HTTP_HOST'], ':') > 0) {
886
-					list($aURL['host'], $aURL['port']) = explode(':', $_SERVER['HTTP_HOST']);
887
-				} else {
888
-					$aURL['host'] = $_SERVER['HTTP_HOST'];
889
-				}
890
-			} else if (!empty($_SERVER['SERVER_NAME'])) {
891
-				$aURL['host'] = $_SERVER['SERVER_NAME'];
892
-			} else {
893
-				print "xajax Error: xajax failed to automatically identify your Request URI.";
894
-				print "Please set the Request URI explicitly when you instantiate the xajax object.";
895
-				exit();
896
-			}
897
-		}
898
-
899
-		if (empty($aURL['port']) && !empty($_SERVER['SERVER_PORT'])) {
900
-			$aURL['port'] = $_SERVER['SERVER_PORT'];
901
-		}
902
-
903
-		if (empty($aURL['path'])) {
904
-			if (!empty($_SERVER['PATH_INFO'])) {
905
-				$sPath = parse_url($_SERVER['PATH_INFO']);
906
-			} else {
907
-				$sPath = parse_url(api_get_self());
908
-			}
909
-			$aURL['path'] = $sPath['path'];
910
-			unset($sPath);
911
-		}
912
-
913
-		if (!empty($aURL['query'])) {
914
-			$aURL['query'] = '?'.$aURL['query'];
915
-		}
916
-
917
-		// Build the URL: Start with scheme, user and pass
918
-		$sURL = $aURL['scheme'].'://';
919
-		if (!empty($aURL['user'])) {
920
-			$sURL.= $aURL['user'];
921
-			if (!empty($aURL['pass'])) {
922
-				$sURL.= ':'.$aURL['pass'];
923
-			}
924
-			$sURL.= '@';
925
-		}
926
-
927
-		// Add the host
928
-		$sURL.= $aURL['host'];
929
-
930
-		// Add the port if needed
931
-		if (!empty($aURL['port']) && (($aURL['scheme'] == 'http' && $aURL['port'] != 80) || ($aURL['scheme'] == 'https' && $aURL['port'] != 443))) {
932
-			$sURL.= ':'.$aURL['port'];
933
-		}
934
-
935
-		// Add the path and the query string
936
-		$sURL.= $aURL['path'].@$aURL['query'];
937
-
938
-		// Clean up
939
-		unset($aURL);
940
-		return $sURL;
941
-	}
942
-
943
-	/**
944
-	 * Returns true if the function name is associated with an object callback,
945
-	 * false if not.
946
-	 *
947
-	 * @param string the name of the function
948
-	 * @access private
949
-	 * @return boolean
950
-	 */
951
-	function _isObjectCallback($sFunction)
952
-	{
953
-		if (array_key_exists($sFunction, $this->aObjects)) return true;
954
-		return false;
955
-	}
956
-
957
-	/**
958
-	 * Returns true if the function or object callback can be called, false if
959
-	 * not.
960
-	 *
961
-	 * @param string the name of the function
962
-	 * @access private
963
-	 * @return boolean
964
-	 */
965
-	function _isFunctionCallable($sFunction)
966
-	{
967
-		if ($this->_isObjectCallback($sFunction)) {
968
-			if (is_object($this->aObjects[$sFunction][0])) {
969
-				return method_exists($this->aObjects[$sFunction][0], $this->aObjects[$sFunction][1]);
970
-			}
971
-			else {
972
-				return is_callable($this->aObjects[$sFunction]);
973
-			}
974
-		}
975
-		else {
976
-			return function_exists($sFunction);
977
-		}
978
-	}
979
-
980
-	/**
981
-	 * Calls the function, class method, or object method with the supplied
982
-	 * arguments.
983
-	 *
984
-	 * @param string the name of the function
985
-	 * @param array  arguments to pass to the function
986
-	 * @access private
987
-	 * @return mixed the output of the called function or method
988
-	 */
989
-	function _callFunction($sFunction, $aArgs)
990
-	{
991
-		if ($this->_isObjectCallback($sFunction)) {
992
-			$mReturn = call_user_func_array($this->aObjects[$sFunction], $aArgs);
993
-		}
994
-		else {
995
-			$mReturn = call_user_func_array($sFunction, $aArgs);
996
-		}
997
-		return $mReturn;
998
-	}
999
-
1000
-	/**
1001
-	 * Generates the Javascript wrapper for the specified PHP function.
1002
-	 *
1003
-	 * @param string the name of the function
1004
-	 * @param mixed  the request type
1005
-	 * @access private
1006
-	 * @return string
1007
-	 */
1008
-	function _wrap($sFunction,$sRequestType=XAJAX_POST)
1009
-	{
1010
-		$js = "function ".$this->sWrapperPrefix."$sFunction(){return xajax.call(\"$sFunction\", arguments, ".$sRequestType.");}\n";
1011
-		return $js;
1012
-	}
1013
-
1014
-	/**
1015
-	 * Takes a string containing xajax xjxobj XML or xjxquery XML and builds an
1016
-	 * array representation of it to pass as an argument to the PHP function
1017
-	 * being called.
1018
-	 *
1019
-	 * @param string the root tag of the XML
1020
-	 * @param string XML to convert
1021
-	 * @access private
1022
-	 * @return array
1023
-	 */
1024
-	function _xmlToArray($rootTag, $sXml)
1025
-	{
1026
-		$aArray = array();
1027
-		$sXml = str_replace("<$rootTag>","<$rootTag>|~|",$sXml);
1028
-		$sXml = str_replace("</$rootTag>","</$rootTag>|~|",$sXml);
1029
-		$sXml = str_replace("<e>","<e>|~|",$sXml);
1030
-		$sXml = str_replace("</e>","</e>|~|",$sXml);
1031
-		$sXml = str_replace("<k>","<k>|~|",$sXml);
1032
-		$sXml = str_replace("</k>","|~|</k>|~|",$sXml);
1033
-		$sXml = str_replace("<v>","<v>|~|",$sXml);
1034
-		$sXml = str_replace("</v>","|~|</v>|~|",$sXml);
1035
-		$sXml = str_replace("<q>","<q>|~|",$sXml);
1036
-		$sXml = str_replace("</q>","|~|</q>|~|",$sXml);
1037
-
1038
-		$this->aObjArray = explode("|~|",$sXml);
1039
-
1040
-		$this->iPos = 0;
1041
-		$aArray = $this->_parseObjXml($rootTag);
1042
-
1043
-		return $aArray;
1044
-	}
1045
-
1046
-	/**
1047
-	 * A recursive function that generates an array from the contents of
1048
-	 * $this->aObjArray.
1049
-	 *
1050
-	 * @param string the root tag of the XML
1051
-	 * @access private
1052
-	 * @return array
1053
-	 */
1054
-	function _parseObjXml($rootTag)
1055
-	{
1056
-		$aArray = array();
1057
-
1058
-		if ($rootTag == "xjxobj")
1059
-		{
1060
-			while(!stristr($this->aObjArray[$this->iPos],"</xjxobj>"))
1061
-			{
1062
-				$this->iPos++;
1063
-				if(stristr($this->aObjArray[$this->iPos],"<e>"))
1064
-				{
1065
-					$key = "";
1066
-					$value = null;
1067
-
1068
-					$this->iPos++;
1069
-					while(!stristr($this->aObjArray[$this->iPos],"</e>"))
1070
-					{
1071
-						if(stristr($this->aObjArray[$this->iPos],"<k>"))
1072
-						{
1073
-							$this->iPos++;
1074
-							while(!stristr($this->aObjArray[$this->iPos],"</k>"))
1075
-							{
1076
-								$key .= $this->aObjArray[$this->iPos];
1077
-								$this->iPos++;
1078
-							}
1079
-						}
1080
-						if(stristr($this->aObjArray[$this->iPos],"<v>"))
1081
-						{
1082
-							$this->iPos++;
1083
-							while(!stristr($this->aObjArray[$this->iPos],"</v>"))
1084
-							{
1085
-								if(stristr($this->aObjArray[$this->iPos],"<xjxobj>"))
1086
-								{
1087
-									$value = $this->_parseObjXml("xjxobj");
1088
-									$this->iPos++;
1089
-								}
1090
-								else
1091
-								{
1092
-									$value .= $this->aObjArray[$this->iPos];
1093
-									if ($this->bDecodeUTF8Input)
1094
-									{
1095
-										$value = $this->_decodeUTF8Data($value);
1096
-									}
1097
-								}
1098
-								$this->iPos++;
1099
-							}
1100
-						}
1101
-						$this->iPos++;
1102
-					}
1103
-
1104
-					$aArray[$key]=$value;
1105
-				}
1106
-			}
1107
-		}
1108
-
1109
-		if ($rootTag == "xjxquery")
1110
-		{
1111
-			$sQuery = "";
1112
-			$this->iPos++;
1113
-			while(!stristr($this->aObjArray[$this->iPos],"</xjxquery>"))
1114
-			{
1115
-				if (stristr($this->aObjArray[$this->iPos],"<q>") || stristr($this->aObjArray[$this->iPos],"</q>"))
1116
-				{
1117
-					$this->iPos++;
1118
-					continue;
1119
-				}
1120
-				$sQuery	.= $this->aObjArray[$this->iPos];
1121
-				$this->iPos++;
1122
-			}
1123
-
1124
-			parse_str($sQuery, $aArray);
1125
-			if ($this->bDecodeUTF8Input)
1126
-			{
1127
-				foreach($aArray as $key => $value)
1128
-				{
1129
-					$aArray[$key] = $this->_decodeUTF8Data($value);
1130
-				}
1131
-			}
1132
-			// If magic quotes is on, then we need to strip the slashes from the
1133
-			// array values because of the parse_str pass which adds slashes
1134
-			if (get_magic_quotes_gpc() == 1) {
1135
-				$newArray = array();
1136
-				foreach ($aArray as $sKey => $sValue) {
1137
-					if (is_string($sValue))
1138
-						$newArray[$sKey] = stripslashes($sValue);
1139
-					else
1140
-						$newArray[$sKey] = $sValue;
1141
-				}
1142
-				$aArray = $newArray;
1143
-			}
1144
-		}
1145
-
1146
-		return $aArray;
1147
-	}
1148
-
1149
-	/**
1150
-	 * Decodes string data from UTF-8 to the current xajax encoding.
1151
-	 *
1152
-	 * @param string data to convert
1153
-	 * @access private
1154
-	 * @return string converted data
1155
-	 */
1156
-	function _decodeUTF8Data($sData)
1157
-	{
1158
-		$sValue = $sData;
1159
-		if ($this->bDecodeUTF8Input)
1160
-		{
1161
-			$sFuncToUse = NULL;
1162
-
1163
-			// An adaptation for the Dokeos LMS, 22-AUG-2009.
1164
-			if (function_exists('api_convert_encoding'))
1165
-			{
1166
-				$sFuncToUse = "api_convert_encoding";
1167
-			}
1168
-			//if (function_exists('iconv'))
1169
-			elseif (function_exists('iconv'))
1170
-			//
1171
-			{
1172
-				$sFuncToUse = "iconv";
1173
-			}
1174
-			else if (function_exists('mb_convert_encoding'))
1175
-			{
1176
-				$sFuncToUse = "mb_convert_encoding";
1177
-			}
1178
-			else if ($this->sEncoding == "ISO-8859-1")
1179
-			{
1180
-				$sFuncToUse = "utf8_decode";
1181
-			}
1182
-			else
1183
-			{
1184
-				trigger_error("The incoming xajax data could not be converted from UTF-8", E_USER_NOTICE);
1185
-			}
1186
-
1187
-			if ($sFuncToUse)
1188
-			{
1189
-				if (is_string($sValue))
1190
-				{
1191
-					if ($sFuncToUse == "iconv")
1192
-					{
1193
-						$sValue = iconv("UTF-8", $this->sEncoding.'//TRANSLIT', $sValue);
1194
-					}
1195
-					else if ($sFuncToUse == "mb_convert_encoding")
1196
-					{
1197
-						$sValue = mb_convert_encoding($sValue, $this->sEncoding, "UTF-8");
1198
-					}
1199
-					// Added code, an adaptation for the Dokeos LMS, 22-AUG-2009.
1200
-					else if ($sFuncToUse == "api_convert_encoding")
1201
-					{
1202
-						$sValue = api_convert_encoding($sValue, $this->sEncoding, "UTF-8");
1203
-					}
1204
-					//
1205
-					else
1206
-					{
1207
-						$sValue = utf8_decode($sValue);
1208
-					}
1209
-				}
1210
-			}
1211
-		}
1212
-		return $sValue;
1213
-	}
78
+    /**
79
+     * @var array Array of PHP functions that will be callable through javascript wrappers
80
+     */
81
+    var $aFunctions;
82
+    /**
83
+     * @var array Array of object callbacks that will allow Javascript to call PHP methods (key=function name)
84
+     */
85
+    var $aObjects;
86
+    /**
87
+     * @var array Array of RequestTypes to be used with each function (key=function name)
88
+     */
89
+    var $aFunctionRequestTypes;
90
+    /**
91
+     * @var array Array of Include Files for any external functions (key=function name)
92
+     */
93
+    var $aFunctionIncludeFiles;
94
+    /**
95
+     * @var string Name of the PHP function to call if no callable function was found
96
+     */
97
+    var $sCatchAllFunction;
98
+    /**
99
+     * @var string Name of the PHP function to call before any other function
100
+     */
101
+    var $sPreFunction;
102
+    /**
103
+     * @var string The URI for making requests to the xajax object
104
+     */
105
+    var $sRequestURI;
106
+    /**
107
+     * @var string The prefix to prepend to the javascript wraper function name
108
+     */
109
+    var $sWrapperPrefix;
110
+    /**
111
+     * @var boolean Show debug messages (default false)
112
+     */
113
+    var $bDebug;
114
+    /**
115
+     * @var boolean Show messages in the client browser's status bar (default false)
116
+     */
117
+    var $bStatusMessages;
118
+    /**
119
+     * @var boolean Allow xajax to exit after processing a request (default true)
120
+     */
121
+    var $bExitAllowed;
122
+    /**
123
+     * @var boolean Use wait cursor in browser (default true)
124
+     */
125
+    var $bWaitCursor;
126
+    /**
127
+     * @var boolean Use an special xajax error handler so the errors are sent to the browser properly (default false)
128
+     */
129
+    var $bErrorHandler;
130
+    /**
131
+     * @var string Specify what, if any, file xajax should log errors to (and more information in a future release)
132
+     */
133
+    var $sLogFile;
134
+    /**
135
+     * @var boolean Clean all output buffers before outputting response (default false)
136
+     */
137
+    var $bCleanBuffer;
138
+    /**
139
+     * @var string String containing the character encoding used
140
+     */
141
+    var $sEncoding;
142
+    /**
143
+     * @var boolean Decode input request args from UTF-8 (default false)
144
+     */
145
+    var $bDecodeUTF8Input;
146
+    /**
147
+     * @var boolean Convert special characters to HTML entities (default false)
148
+     */
149
+    var $bOutputEntities;
150
+    /**
151
+     * @var array Array for parsing complex objects
152
+     */
153
+    var $aObjArray;
154
+    /**
155
+     * @var integer Position in $aObjArray
156
+     */
157
+    var $iPos;
158
+
159
+    /**#@-*/
160
+
161
+    /**
162
+     * Constructor. You can set some extra xajax options right away or use
163
+     * individual methods later to set options.
164
+     *
165
+     * @param string  defaults to the current browser URI
166
+     * @param string  defaults to "xajax_";
167
+     * @param string  defaults to XAJAX_DEFAULT_CHAR_ENCODING defined above
168
+     * @param boolean defaults to false
169
+     */
170
+    function xajax($sRequestURI="",$sWrapperPrefix="xajax_",$sEncoding=XAJAX_DEFAULT_CHAR_ENCODING,$bDebug=false)
171
+    {
172
+        $this->aFunctions = array();
173
+        $this->aObjects = array();
174
+        $this->aFunctionIncludeFiles = array();
175
+        $this->sRequestURI = $sRequestURI;
176
+        if ($this->sRequestURI == "")
177
+            $this->sRequestURI = $this->_detectURI();
178
+        $this->sWrapperPrefix = $sWrapperPrefix;
179
+        $this->bDebug = $bDebug;
180
+        $this->bStatusMessages = false;
181
+        $this->bWaitCursor = true;
182
+        $this->bExitAllowed = true;
183
+        $this->bErrorHandler = false;
184
+        $this->sLogFile = "";
185
+        $this->bCleanBuffer = false;
186
+        $this->setCharEncoding($sEncoding);
187
+        $this->bDecodeUTF8Input = false;
188
+        $this->bOutputEntities = false;
189
+    }
190
+
191
+    /**
192
+     * Sets the URI to which requests will be made.
193
+     * <i>Usage:</i> <kbd>$xajax->setRequestURI("http://www.xajaxproject.org");</kbd>
194
+     *
195
+     * @param string the URI (can be absolute or relative) of the PHP script
196
+     *               that will be accessed when an xajax request occurs
197
+     */
198
+    function setRequestURI($sRequestURI)
199
+    {
200
+        $this->sRequestURI = $sRequestURI;
201
+    }
202
+
203
+    /**
204
+     * Sets the prefix that will be appended to the Javascript wrapper
205
+     * functions (default is "xajax_").
206
+     *
207
+     * @param string
208
+     */
209
+    //
210
+    function setWrapperPrefix($sPrefix)
211
+    {
212
+        $this->sWrapperPrefix = $sPrefix;
213
+    }
214
+
215
+    /**
216
+     * Enables debug messages for xajax.
217
+     * */
218
+    function debugOn()
219
+    {
220
+        $this->bDebug = true;
221
+    }
222
+
223
+    /**
224
+     * Disables debug messages for xajax (default behavior).
225
+     */
226
+    function debugOff()
227
+    {
228
+        $this->bDebug = false;
229
+    }
230
+
231
+    /**
232
+     * Enables messages in the browser's status bar for xajax.
233
+     */
234
+    function statusMessagesOn()
235
+    {
236
+        $this->bStatusMessages = true;
237
+    }
238
+
239
+    /**
240
+     * Disables messages in the browser's status bar for xajax (default behavior).
241
+     */
242
+    function statusMessagesOff()
243
+    {
244
+        $this->bStatusMessages = false;
245
+    }
246
+
247
+    /**
248
+     * Enables the wait cursor to be displayed in the browser (default behavior).
249
+     */
250
+    function waitCursorOn()
251
+    {
252
+        $this->bWaitCursor = true;
253
+    }
254
+
255
+    /**
256
+     * Disables the wait cursor to be displayed in the browser.
257
+     */
258
+    function waitCursorOff()
259
+    {
260
+        $this->bWaitCursor = false;
261
+    }
262
+
263
+    /**
264
+     * Enables xajax to exit immediately after processing a request and
265
+     * sending the response back to the browser (default behavior).
266
+     */
267
+    function exitAllowedOn()
268
+    {
269
+        $this->bExitAllowed = true;
270
+    }
271
+
272
+    /**
273
+     * Disables xajax's default behavior of exiting immediately after
274
+     * processing a request and sending the response back to the browser.
275
+     */
276
+    function exitAllowedOff()
277
+    {
278
+        $this->bExitAllowed = false;
279
+    }
280
+
281
+    /**
282
+     * Turns on xajax's error handling system so that PHP errors that occur
283
+     * during a request are trapped and pushed to the browser in the form of
284
+     * a Javascript alert.
285
+     */
286
+    function errorHandlerOn()
287
+    {
288
+        $this->bErrorHandler = true;
289
+    }
290
+
291
+    /**
292
+     * Turns off xajax's error handling system (default behavior).
293
+     */
294
+    function errorHandlerOff()
295
+    {
296
+        $this->bErrorHandler = false;
297
+    }
298
+
299
+    /**
300
+     * Specifies a log file that will be written to by xajax during a request
301
+     * (used only by the error handling system at present). If you don't invoke
302
+     * this method, or you pass in "", then no log file will be written to.
303
+     * <i>Usage:</i> <kbd>$xajax->setLogFile("/xajax_logs/errors.log");</kbd>
304
+     */
305
+    function setLogFile($sFilename)
306
+    {
307
+        $this->sLogFile = $sFilename;
308
+    }
309
+
310
+    /**
311
+     * Causes xajax to clean out all output buffers before outputting a
312
+     * response (default behavior).
313
+     */
314
+    function cleanBufferOn()
315
+    {
316
+        $this->bCleanBuffer = true;
317
+    }
318
+    /**
319
+     * Turns off xajax's output buffer cleaning.
320
+     */
321
+    function cleanBufferOff()
322
+    {
323
+        $this->bCleanBuffer = false;
324
+    }
325
+
326
+    /**
327
+     * Sets the character encoding for the HTTP output based on
328
+     * <kbd>$sEncoding</kbd>, which is a string containing the character
329
+     * encoding to use. You don't need to use this method normally, since the
330
+     * character encoding for the response gets set automatically based on the
331
+     * <kbd>XAJAX_DEFAULT_CHAR_ENCODING</kbd> constant.
332
+     * <i>Usage:</i> <kbd>$xajax->setCharEncoding("utf-8");</kbd>
333
+     *
334
+     * @param string the encoding type to use (utf-8, iso-8859-1, etc.)
335
+     */
336
+    function setCharEncoding($sEncoding)
337
+    {
338
+        $this->sEncoding = $sEncoding;
339
+    }
340
+
341
+    /**
342
+     * Causes xajax to decode the input request args from UTF-8 to the current
343
+     * encoding if possible. Either the iconv or mb_string extension must be
344
+     * present for optimal functionality.
345
+     */
346
+    function decodeUTF8InputOn()
347
+    {
348
+        $this->bDecodeUTF8Input = true;
349
+    }
350
+
351
+    /**
352
+     * Turns off decoding the input request args from UTF-8 (default behavior).
353
+     */
354
+    function decodeUTF8InputOff()
355
+    {
356
+        $this->bDecodeUTF8Input = false;
357
+    }
358
+
359
+    /**
360
+     * Tells the response object to convert special characters to HTML entities
361
+     * automatically (only works if the mb_string extension is available).
362
+     */
363
+    function outputEntitiesOn()
364
+    {
365
+        $this->bOutputEntities = true;
366
+    }
367
+
368
+    /**
369
+     * Tells the response object to output special characters intact. (default
370
+     * behavior).
371
+     */
372
+    function outputEntitiesOff()
373
+    {
374
+        $this->bOutputEntities = false;
375
+    }
376
+
377
+    /**
378
+     * Registers a PHP function or method to be callable through xajax in your
379
+     * Javascript. If you want to register a function, pass in the name of that
380
+     * function. If you want to register a static class method, pass in an
381
+     * array like so:
382
+     * <kbd>array("myFunctionName", "myClass", "myMethod")</kbd>
383
+     * For an object instance method, use an object variable for the second
384
+     * array element (and in PHP 4 make sure you put an & before the variable
385
+     * to pass the object by reference). Note: the function name is what you
386
+     * call via Javascript, so it can be anything as long as it doesn't
387
+     * conflict with any other registered function name.
388
+     *
389
+     * <i>Usage:</i> <kbd>$xajax->registerFunction("myFunction");</kbd>
390
+     * or: <kbd>$xajax->registerFunction(array("myFunctionName", &$myObject, "myMethod"));</kbd>
391
+     *
392
+     * @param mixed  contains the function name or an object callback array
393
+     * @param mixed  request type (XAJAX_GET/XAJAX_POST) that should be used
394
+     *               for this function.  Defaults to XAJAX_POST.
395
+     */
396
+    function registerFunction($mFunction,$sRequestType=XAJAX_POST)
397
+    {
398
+        if (is_array($mFunction)) {
399
+            $this->aFunctions[$mFunction[0]] = 1;
400
+            $this->aFunctionRequestTypes[$mFunction[0]] = $sRequestType;
401
+            $this->aObjects[$mFunction[0]] = array_slice($mFunction, 1);
402
+        }
403
+        else {
404
+            $this->aFunctions[$mFunction] = 1;
405
+            $this->aFunctionRequestTypes[$mFunction] = $sRequestType;
406
+        }
407
+    }
408
+
409
+    /**
410
+     * Registers a PHP function to be callable through xajax which is located
411
+     * in some other file.  If the function is requested the external file will
412
+     * be included to define the function before the function is called.
413
+     *
414
+     * <i>Usage:</i> <kbd>$xajax->registerExternalFunction("myFunction","myFunction.inc.php",XAJAX_POST);</kbd>
415
+     *
416
+     * @param string contains the function name or an object callback array
417
+     *               ({@link xajax::registerFunction() see registerFunction} for
418
+     *               more info on object callback arrays)
419
+     * @param string contains the path and filename of the include file
420
+     * @param mixed  the RequestType (XAJAX_GET/XAJAX_POST) that should be used
421
+     *		          for this function. Defaults to XAJAX_POST.
422
+     */
423
+    function registerExternalFunction($mFunction,$sIncludeFile,$sRequestType=XAJAX_POST)
424
+    {
425
+        $this->registerFunction($mFunction, $sRequestType);
426
+
427
+        if (is_array($mFunction)) {
428
+            $this->aFunctionIncludeFiles[$mFunction[0]] = $sIncludeFile;
429
+        }
430
+        else {
431
+            $this->aFunctionIncludeFiles[$mFunction] = $sIncludeFile;
432
+        }
433
+    }
434
+
435
+    /**
436
+     * Registers a PHP function to be called when xajax cannot find the
437
+     * function being called via Javascript. Because this is technically
438
+     * impossible when using "wrapped" functions, the catch-all feature is
439
+     * only useful when you're directly using the xajax.call() Javascript
440
+     * method. Use the catch-all feature when you want more dynamic ability to
441
+     * intercept unknown calls and handle them in a custom way.
442
+     *
443
+     * <i>Usage:</i> <kbd>$xajax->registerCatchAllFunction("myCatchAllFunction");</kbd>
444
+     *
445
+     * @param string contains the function name or an object callback array
446
+     *               ({@link xajax::registerFunction() see registerFunction} for
447
+     *               more info on object callback arrays)
448
+     */
449
+    function registerCatchAllFunction($mFunction)
450
+    {
451
+        if (is_array($mFunction)) {
452
+            $this->sCatchAllFunction = $mFunction[0];
453
+            $this->aObjects[$mFunction[0]] = array_slice($mFunction, 1);
454
+        }
455
+        else {
456
+            $this->sCatchAllFunction = $mFunction;
457
+        }
458
+    }
459
+
460
+    /**
461
+     * Registers a PHP function to be called before xajax calls the requested
462
+     * function. xajax will automatically add the request function's response
463
+     * to the pre-function's response to create a single response. Another
464
+     * feature is the ability to return not just a response, but an array with
465
+     * the first element being false (a boolean) and the second being the
466
+     * response. In this case, the pre-function's response will be returned to
467
+     * the browser without xajax calling the requested function.
468
+     *
469
+     * <i>Usage:</i> <kbd>$xajax->registerPreFunction("myPreFunction");</kbd>
470
+     *
471
+     * @param string contains the function name or an object callback array
472
+     *               ({@link xajax::registerFunction() see registerFunction} for
473
+     *               more info on object callback arrays)
474
+     */
475
+    function registerPreFunction($mFunction)
476
+    {
477
+        if (is_array($mFunction)) {
478
+            $this->sPreFunction = $mFunction[0];
479
+            $this->aObjects[$mFunction[0]] = array_slice($mFunction, 1);
480
+        }
481
+        else {
482
+            $this->sPreFunction = $mFunction;
483
+        }
484
+    }
485
+
486
+    /**
487
+     * Returns true if xajax can process the request, false if otherwise.
488
+     * You can use this to determine if xajax needs to process the request or
489
+     * not.
490
+     *
491
+     * @return boolean
492
+     */
493
+    function canProcessRequests()
494
+    {
495
+        if ($this->getRequestMode() != -1) return true;
496
+        return false;
497
+    }
498
+
499
+    /**
500
+     * Returns the current request mode (XAJAX_GET or XAJAX_POST), or -1 if
501
+     * there is none.
502
+     *
503
+     * @return mixed
504
+     */
505
+    function getRequestMode()
506
+    {
507
+        if (!empty($_GET["xajax"]))
508
+            return XAJAX_GET;
509
+
510
+        if (!empty($_POST["xajax"]))
511
+            return XAJAX_POST;
512
+
513
+        return -1;
514
+    }
515
+
516
+    /**
517
+     * This is the main communications engine of xajax. The engine handles all
518
+     * incoming xajax requests, calls the apporiate PHP functions (or
519
+     * class/object methods) and passes the XML responses back to the
520
+     * Javascript response handler. If your RequestURI is the same as your Web
521
+     * page then this function should be called before any headers or HTML has
522
+     * been sent.
523
+     */
524
+    function processRequests()
525
+    {
526
+
527
+        $requestMode = -1;
528
+        $sFunctionName = "";
529
+        $bFoundFunction = true;
530
+        $bFunctionIsCatchAll = false;
531
+        $sFunctionNameForSpecial = "";
532
+        $aArgs = array();
533
+        $sPreResponse = "";
534
+        $bEndRequest = false;
535
+        $sResponse = "";
536
+
537
+        $requestMode = $this->getRequestMode();
538
+        if ($requestMode == -1) return;
539
+
540
+        if ($requestMode == XAJAX_POST)
541
+        {
542
+            $sFunctionName = $_POST["xajax"];
543
+
544
+            if (!empty($_POST["xajaxargs"]))
545
+                $aArgs = $_POST["xajaxargs"];
546
+        }
547
+        else
548
+        {
549
+            header ("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
550
+            header ("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
551
+            header ("Cache-Control: no-cache, must-revalidate");
552
+            header ("Pragma: no-cache");
553
+
554
+            $sFunctionName = $_GET["xajax"];
555
+
556
+            if (!empty($_GET["xajaxargs"]))
557
+                $aArgs = $_GET["xajaxargs"];
558
+        }
559
+
560
+        // Use xajax error handler if necessary
561
+        if ($this->bErrorHandler) {
562
+            $GLOBALS['xajaxErrorHandlerText'] = "";
563
+            set_error_handler("xajaxErrorHandler");
564
+        }
565
+
566
+        if ($this->sPreFunction) {
567
+            if (!$this->_isFunctionCallable($this->sPreFunction)) {
568
+                $bFoundFunction = false;
569
+                $objResponse = new xajaxResponse();
570
+                $objResponse->addAlert("Unknown Pre-Function ". $this->sPreFunction);
571
+                $sResponse = $objResponse->getXML();
572
+            }
573
+        }
574
+        //include any external dependencies associated with this function name
575
+        if (array_key_exists($sFunctionName,$this->aFunctionIncludeFiles))
576
+        {
577
+            ob_start();
578
+            include_once($this->aFunctionIncludeFiles[$sFunctionName]);
579
+            ob_end_clean();
580
+        }
581
+
582
+        if ($bFoundFunction) {
583
+            $sFunctionNameForSpecial = $sFunctionName;
584
+            if (!array_key_exists($sFunctionName, $this->aFunctions))
585
+            {
586
+                if ($this->sCatchAllFunction) {
587
+                    $sFunctionName = $this->sCatchAllFunction;
588
+                    $bFunctionIsCatchAll = true;
589
+                }
590
+                else {
591
+                    $bFoundFunction = false;
592
+                    $objResponse = new xajaxResponse();
593
+                    $objResponse->addAlert("Unknown Function $sFunctionName.");
594
+                    $sResponse = $objResponse->getXML();
595
+                }
596
+            }
597
+            else if ($this->aFunctionRequestTypes[$sFunctionName] != $requestMode)
598
+            {
599
+                $bFoundFunction = false;
600
+                $objResponse = new xajaxResponse();
601
+                $objResponse->addAlert("Incorrect Request Type.");
602
+                $sResponse = $objResponse->getXML();
603
+            }
604
+        }
605
+
606
+        if ($bFoundFunction)
607
+        {
608
+            for ($i = 0; $i < sizeof($aArgs); $i++)
609
+            {
610
+                // If magic quotes is on, then we need to strip the slashes from the args
611
+                if (get_magic_quotes_gpc() == 1 && is_string($aArgs[$i])) {
612
+
613
+                    $aArgs[$i] = stripslashes($aArgs[$i]);
614
+                }
615
+                if (stristr($aArgs[$i],"<xjxobj>") != false)
616
+                {
617
+                    $aArgs[$i] = $this->_xmlToArray("xjxobj",$aArgs[$i]);
618
+                }
619
+                else if (stristr($aArgs[$i],"<xjxquery>") != false)
620
+                {
621
+                    $aArgs[$i] = $this->_xmlToArray("xjxquery",$aArgs[$i]);
622
+                }
623
+                else if ($this->bDecodeUTF8Input)
624
+                {
625
+                    $aArgs[$i] = $this->_decodeUTF8Data($aArgs[$i]);
626
+                }
627
+            }
628
+
629
+            if ($this->sPreFunction) {
630
+                $mPreResponse = $this->_callFunction($this->sPreFunction, array($sFunctionNameForSpecial, $aArgs));
631
+                if (is_array($mPreResponse) && $mPreResponse[0] === false) {
632
+                    $bEndRequest = true;
633
+                    $sPreResponse = $mPreResponse[1];
634
+                }
635
+                else {
636
+                    $sPreResponse = $mPreResponse;
637
+                }
638
+                if (is_a($sPreResponse, "xajaxResponse")) {
639
+                    $sPreResponse = $sPreResponse->getXML();
640
+                }
641
+                if ($bEndRequest) $sResponse = $sPreResponse;
642
+            }
643
+
644
+            if (!$bEndRequest) {
645
+                if (!$this->_isFunctionCallable($sFunctionName)) {
646
+                    $objResponse = new xajaxResponse();
647
+                    $objResponse->addAlert("The Registered Function $sFunctionName Could Not Be Found.");
648
+                    $sResponse = $objResponse->getXML();
649
+                }
650
+                else {
651
+                    if ($bFunctionIsCatchAll) {
652
+                        $aArgs = array($sFunctionNameForSpecial, $aArgs);
653
+                    }
654
+                    $sResponse = $this->_callFunction($sFunctionName, $aArgs);
655
+                }
656
+                if (is_a($sResponse, "xajaxResponse")) {
657
+                    $sResponse = $sResponse->getXML();
658
+                }
659
+                if (!is_string($sResponse) || strpos($sResponse, "<xjx>") === FALSE) {
660
+                    $objResponse = new xajaxResponse();
661
+                    $objResponse->addAlert("No XML Response Was Returned By Function $sFunctionName.");
662
+                    $sResponse = $objResponse->getXML();
663
+                }
664
+                else if ($sPreResponse != "") {
665
+                    $sNewResponse = new xajaxResponse($this->sEncoding, $this->bOutputEntities);
666
+                    $sNewResponse->loadXML($sPreResponse);
667
+                    $sNewResponse->loadXML($sResponse);
668
+                    $sResponse = $sNewResponse->getXML();
669
+                }
670
+            }
671
+        }
672
+
673
+        $sContentHeader = "Content-type: text/xml;";
674
+        if ($this->sEncoding && strlen(trim($this->sEncoding)) > 0)
675
+            $sContentHeader .= " charset=".$this->sEncoding;
676
+        header($sContentHeader);
677
+        if ($this->bErrorHandler && !empty( $GLOBALS['xajaxErrorHandlerText'] )) {
678
+            $sErrorResponse = new xajaxResponse();
679
+            $sErrorResponse->addAlert("** PHP Error Messages: **" . $GLOBALS['xajaxErrorHandlerText']);
680
+            if ($this->sLogFile) {
681
+                $fH = @fopen($this->sLogFile, "a");
682
+                if (!$fH) {
683
+                    $sErrorResponse->addAlert("** Logging Error **\n\nxajax was unable to write to the error log file:\n" . $this->sLogFile);
684
+                }
685
+                else {
686
+                    fwrite($fH, "** xajax Error Log - " . strftime("%b %e %Y %I:%M:%S %p") . " **" . $GLOBALS['xajaxErrorHandlerText'] . "\n\n\n");
687
+                    fclose($fH);
688
+                }
689
+            }
690
+
691
+            $sErrorResponse->loadXML($sResponse);
692
+            $sResponse = $sErrorResponse->getXML();
693
+
694
+        }
695
+        if ($this->bCleanBuffer) while (@ob_end_clean());
696
+        print $sResponse;
697
+        if ($this->bErrorHandler) restore_error_handler();
698
+
699
+        if ($this->bExitAllowed)
700
+            exit();
701
+    }
702
+
703
+    /**
704
+     * Prints the xajax Javascript header and wrapper code into your page by
705
+     * printing the output of the getJavascript() method. It should only be
706
+     * called between the <pre><head> </head></pre> tags in your HTML page.
707
+     * Remember, if you only want to obtain the result of this function, use
708
+     * {@link xajax::getJavascript()} instead.
709
+     *
710
+     * <i>Usage:</i>
711
+     * <code>
712
+     *  <head>
713
+     *		...
714
+     *		< ?php $xajax->printJavascript(); ? >
715
+     * </code>
716
+     *
717
+     * @param string the relative address of the folder where xajax has been
718
+     *               installed. For instance, if your PHP file is
719
+     *               "http://www.myserver.com/myfolder/mypage.php"
720
+     *               and xajax was installed in
721
+     *               "http://www.myserver.com/anotherfolder", then $sJsURI
722
+     *               should be set to "../anotherfolder". Defaults to assuming
723
+     *               xajax is in the same folder as your PHP file.
724
+     * @param string the relative folder/file pair of the xajax Javascript
725
+     *               engine located within the xajax installation folder.
726
+     *               Defaults to xajax_js/xajax.js.
727
+     */
728
+    function printJavascript($sJsURI="", $sJsFile=NULL)
729
+    {
730
+        print $this->getJavascript($sJsURI, $sJsFile);
731
+    }
732
+
733
+    /**
734
+     * Returns the xajax Javascript code that should be added to your HTML page
735
+     * between the <kbd><head> </head></kbd> tags.
736
+     *
737
+     * <i>Usage:</i>
738
+     * <code>
739
+     *  < ?php $xajaxJSHead = $xajax->getJavascript(); ? >
740
+     *	<head>
741
+     *		...
742
+     *		< ?php echo $xajaxJSHead; ? >
743
+     * </code>
744
+     *
745
+     * @param string the relative address of the folder where xajax has been
746
+     *               installed. For instance, if your PHP file is
747
+     *               "http://www.myserver.com/myfolder/mypage.php"
748
+     *               and xajax was installed in
749
+     *               "http://www.myserver.com/anotherfolder", then $sJsURI
750
+     *               should be set to "../anotherfolder". Defaults to assuming
751
+     *               xajax is in the same folder as your PHP file.
752
+     * @param string the relative folder/file pair of the xajax Javascript
753
+     *               engine located within the xajax installation folder.
754
+     *               Defaults to xajax_js/xajax.js.
755
+     * @return string
756
+     */
757
+    function getJavascript($sJsURI="", $sJsFile=NULL)
758
+    {
759
+        $html = $this->getJavascriptConfig();
760
+        $html .= $this->getJavascriptInclude($sJsURI, $sJsFile);
761
+
762
+        return $html;
763
+    }
764
+
765
+    /**
766
+     * Returns a string containing inline Javascript that sets up the xajax
767
+     * runtime (typically called internally by xajax from get/printJavascript).
768
+     *
769
+     * @return string
770
+     */
771
+    function getJavascriptConfig()
772
+    {
773
+        $html  = "\t<script type=\"text/javascript\">\n";
774
+        $html .= "var xajaxRequestUri=\"".$this->sRequestURI."\";\n";
775
+        $html .= "var xajaxDebug=".($this->bDebug?"true":"false").";\n";
776
+        $html .= "var xajaxStatusMessages=".($this->bStatusMessages?"true":"false").";\n";
777
+        $html .= "var xajaxWaitCursor=".($this->bWaitCursor?"true":"false").";\n";
778
+        $html .= "var xajaxDefinedGet=".XAJAX_GET.";\n";
779
+        $html .= "var xajaxDefinedPost=".XAJAX_POST.";\n";
780
+        $html .= "var xajaxLoaded=false;\n";
781
+
782
+        foreach($this->aFunctions as $sFunction => $bExists) {
783
+            $html .= $this->_wrap($sFunction,$this->aFunctionRequestTypes[$sFunction]);
784
+        }
785
+
786
+        $html .= "\t</script>\n";
787
+        return $html;
788
+    }
789
+
790
+    /**
791
+     * Returns a string containing a Javascript include of the xajax.js file
792
+     * along with a check to see if the file loaded after six seconds
793
+     * (typically called internally by xajax from get/printJavascript).
794
+     *
795
+     * @param string the relative address of the folder where xajax has been
796
+     *               installed. For instance, if your PHP file is
797
+     *               "http://www.myserver.com/myfolder/mypage.php"
798
+     *               and xajax was installed in
799
+     *               "http://www.myserver.com/anotherfolder", then $sJsURI
800
+     *               should be set to "../anotherfolder". Defaults to assuming
801
+     *               xajax is in the same folder as your PHP file.
802
+     * @param string the relative folder/file pair of the xajax Javascript
803
+     *               engine located within the xajax installation folder.
804
+     *               Defaults to xajax_js/xajax.js.
805
+     * @return string
806
+     */
807
+    function getJavascriptInclude($sJsURI="", $sJsFile=NULL)
808
+    {
809
+        if ($sJsFile == NULL) $sJsFile = "xajax_js/xajax.js";
810
+
811
+        if ($sJsURI != "" && substr($sJsURI, -1) != "/") $sJsURI .= "/";
812
+
813
+        $html = "\t<script type=\"text/javascript\" src=\"" . $sJsURI . $sJsFile . "\"></script>\n";
814
+        $html .= "\t<script type=\"text/javascript\">\n";
815
+        $html .= "window.setTimeout(function () { if (!xajaxLoaded) { alert('Error: the xajax Javascript file could not be included. Perhaps the URL is incorrect?\\nURL: {$sJsURI}{$sJsFile}'); } }, 6000);\n";
816
+        $html .= "\t</script>\n";
817
+        return $html;
818
+    }
819
+
820
+    /**
821
+     * This method can be used to create a new xajax.js file out of the
822
+     * xajax_uncompressed.js file (which will only happen if xajax.js doesn't
823
+     * already exist on the filesystem).
824
+     *
825
+     * @param string an optional argument containing the full server file path
826
+     *               of xajax.js.
827
+     */
828
+    function autoCompressJavascript($sJsFullFilename=NULL)
829
+    {
830
+        $sJsFile = "xajax_js/xajax.js";
831
+
832
+        if ($sJsFullFilename) {
833
+            $realJsFile = $sJsFullFilename;
834
+        }
835
+        else {
836
+            $realPath = realpath(dirname(__FILE__));
837
+            $realJsFile = $realPath . "/". $sJsFile;
838
+        }
839
+
840
+        // Create a compressed file if necessary
841
+        if (!file_exists($realJsFile)) {
842
+            $srcFile = str_replace(".js", "_uncompressed.js", $realJsFile);
843
+            if (!file_exists($srcFile)) {
844
+                trigger_error("The xajax uncompressed Javascript file could not be found in the <b>" . dirname($realJsFile) . "</b> folder. Error ", E_USER_ERROR);
845
+            }
846
+            require(dirname(__FILE__)."/xajaxCompress.php");
847
+            $javaScript = implode('', file($srcFile));
848
+            $compressedScript = xajaxCompressJavascript($javaScript);
849
+            $fH = @fopen($realJsFile, "w");
850
+            if (!$fH) {
851
+                trigger_error("The xajax compressed javascript file could not be written in the <b>" . dirname($realJsFile) . "</b> folder. Error ", E_USER_ERROR);
852
+            }
853
+            else {
854
+                fwrite($fH, $compressedScript);
855
+                fclose($fH);
856
+            }
857
+        }
858
+    }
859
+
860
+    /**
861
+     * Returns the current URL based upon the SERVER vars.
862
+     *
863
+     * @access private
864
+     * @return string
865
+     */
866
+    function _detectURI() {
867
+        $aURL = array();
868
+
869
+        // Try to get the request URL
870
+        if (!empty($_SERVER['REQUEST_URI'])) {
871
+            $aURL = parse_url($_SERVER['REQUEST_URI']);
872
+        }
873
+
874
+        // Fill in the empty values
875
+        if (empty($aURL['scheme'])) {
876
+            if (!empty($_SERVER['HTTP_SCHEME'])) {
877
+                $aURL['scheme'] = $_SERVER['HTTP_SCHEME'];
878
+            } else {
879
+                $aURL['scheme'] = (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) != 'off') ? 'https' : 'http';
880
+            }
881
+        }
882
+
883
+        if (empty($aURL['host'])) {
884
+            if (!empty($_SERVER['HTTP_HOST'])) {
885
+                if (strpos($_SERVER['HTTP_HOST'], ':') > 0) {
886
+                    list($aURL['host'], $aURL['port']) = explode(':', $_SERVER['HTTP_HOST']);
887
+                } else {
888
+                    $aURL['host'] = $_SERVER['HTTP_HOST'];
889
+                }
890
+            } else if (!empty($_SERVER['SERVER_NAME'])) {
891
+                $aURL['host'] = $_SERVER['SERVER_NAME'];
892
+            } else {
893
+                print "xajax Error: xajax failed to automatically identify your Request URI.";
894
+                print "Please set the Request URI explicitly when you instantiate the xajax object.";
895
+                exit();
896
+            }
897
+        }
898
+
899
+        if (empty($aURL['port']) && !empty($_SERVER['SERVER_PORT'])) {
900
+            $aURL['port'] = $_SERVER['SERVER_PORT'];
901
+        }
902
+
903
+        if (empty($aURL['path'])) {
904
+            if (!empty($_SERVER['PATH_INFO'])) {
905
+                $sPath = parse_url($_SERVER['PATH_INFO']);
906
+            } else {
907
+                $sPath = parse_url(api_get_self());
908
+            }
909
+            $aURL['path'] = $sPath['path'];
910
+            unset($sPath);
911
+        }
912
+
913
+        if (!empty($aURL['query'])) {
914
+            $aURL['query'] = '?'.$aURL['query'];
915
+        }
916
+
917
+        // Build the URL: Start with scheme, user and pass
918
+        $sURL = $aURL['scheme'].'://';
919
+        if (!empty($aURL['user'])) {
920
+            $sURL.= $aURL['user'];
921
+            if (!empty($aURL['pass'])) {
922
+                $sURL.= ':'.$aURL['pass'];
923
+            }
924
+            $sURL.= '@';
925
+        }
926
+
927
+        // Add the host
928
+        $sURL.= $aURL['host'];
929
+
930
+        // Add the port if needed
931
+        if (!empty($aURL['port']) && (($aURL['scheme'] == 'http' && $aURL['port'] != 80) || ($aURL['scheme'] == 'https' && $aURL['port'] != 443))) {
932
+            $sURL.= ':'.$aURL['port'];
933
+        }
934
+
935
+        // Add the path and the query string
936
+        $sURL.= $aURL['path'].@$aURL['query'];
937
+
938
+        // Clean up
939
+        unset($aURL);
940
+        return $sURL;
941
+    }
942
+
943
+    /**
944
+     * Returns true if the function name is associated with an object callback,
945
+     * false if not.
946
+     *
947
+     * @param string the name of the function
948
+     * @access private
949
+     * @return boolean
950
+     */
951
+    function _isObjectCallback($sFunction)
952
+    {
953
+        if (array_key_exists($sFunction, $this->aObjects)) return true;
954
+        return false;
955
+    }
956
+
957
+    /**
958
+     * Returns true if the function or object callback can be called, false if
959
+     * not.
960
+     *
961
+     * @param string the name of the function
962
+     * @access private
963
+     * @return boolean
964
+     */
965
+    function _isFunctionCallable($sFunction)
966
+    {
967
+        if ($this->_isObjectCallback($sFunction)) {
968
+            if (is_object($this->aObjects[$sFunction][0])) {
969
+                return method_exists($this->aObjects[$sFunction][0], $this->aObjects[$sFunction][1]);
970
+            }
971
+            else {
972
+                return is_callable($this->aObjects[$sFunction]);
973
+            }
974
+        }
975
+        else {
976
+            return function_exists($sFunction);
977
+        }
978
+    }
979
+
980
+    /**
981
+     * Calls the function, class method, or object method with the supplied
982
+     * arguments.
983
+     *
984
+     * @param string the name of the function
985
+     * @param array  arguments to pass to the function
986
+     * @access private
987
+     * @return mixed the output of the called function or method
988
+     */
989
+    function _callFunction($sFunction, $aArgs)
990
+    {
991
+        if ($this->_isObjectCallback($sFunction)) {
992
+            $mReturn = call_user_func_array($this->aObjects[$sFunction], $aArgs);
993
+        }
994
+        else {
995
+            $mReturn = call_user_func_array($sFunction, $aArgs);
996
+        }
997
+        return $mReturn;
998
+    }
999
+
1000
+    /**
1001
+     * Generates the Javascript wrapper for the specified PHP function.
1002
+     *
1003
+     * @param string the name of the function
1004
+     * @param mixed  the request type
1005
+     * @access private
1006
+     * @return string
1007
+     */
1008
+    function _wrap($sFunction,$sRequestType=XAJAX_POST)
1009
+    {
1010
+        $js = "function ".$this->sWrapperPrefix."$sFunction(){return xajax.call(\"$sFunction\", arguments, ".$sRequestType.");}\n";
1011
+        return $js;
1012
+    }
1013
+
1014
+    /**
1015
+     * Takes a string containing xajax xjxobj XML or xjxquery XML and builds an
1016
+     * array representation of it to pass as an argument to the PHP function
1017
+     * being called.
1018
+     *
1019
+     * @param string the root tag of the XML
1020
+     * @param string XML to convert
1021
+     * @access private
1022
+     * @return array
1023
+     */
1024
+    function _xmlToArray($rootTag, $sXml)
1025
+    {
1026
+        $aArray = array();
1027
+        $sXml = str_replace("<$rootTag>","<$rootTag>|~|",$sXml);
1028
+        $sXml = str_replace("</$rootTag>","</$rootTag>|~|",$sXml);
1029
+        $sXml = str_replace("<e>","<e>|~|",$sXml);
1030
+        $sXml = str_replace("</e>","</e>|~|",$sXml);
1031
+        $sXml = str_replace("<k>","<k>|~|",$sXml);
1032
+        $sXml = str_replace("</k>","|~|</k>|~|",$sXml);
1033
+        $sXml = str_replace("<v>","<v>|~|",$sXml);
1034
+        $sXml = str_replace("</v>","|~|</v>|~|",$sXml);
1035
+        $sXml = str_replace("<q>","<q>|~|",$sXml);
1036
+        $sXml = str_replace("</q>","|~|</q>|~|",$sXml);
1037
+
1038
+        $this->aObjArray = explode("|~|",$sXml);
1039
+
1040
+        $this->iPos = 0;
1041
+        $aArray = $this->_parseObjXml($rootTag);
1042
+
1043
+        return $aArray;
1044
+    }
1045
+
1046
+    /**
1047
+     * A recursive function that generates an array from the contents of
1048
+     * $this->aObjArray.
1049
+     *
1050
+     * @param string the root tag of the XML
1051
+     * @access private
1052
+     * @return array
1053
+     */
1054
+    function _parseObjXml($rootTag)
1055
+    {
1056
+        $aArray = array();
1057
+
1058
+        if ($rootTag == "xjxobj")
1059
+        {
1060
+            while(!stristr($this->aObjArray[$this->iPos],"</xjxobj>"))
1061
+            {
1062
+                $this->iPos++;
1063
+                if(stristr($this->aObjArray[$this->iPos],"<e>"))
1064
+                {
1065
+                    $key = "";
1066
+                    $value = null;
1067
+
1068
+                    $this->iPos++;
1069
+                    while(!stristr($this->aObjArray[$this->iPos],"</e>"))
1070
+                    {
1071
+                        if(stristr($this->aObjArray[$this->iPos],"<k>"))
1072
+                        {
1073
+                            $this->iPos++;
1074
+                            while(!stristr($this->aObjArray[$this->iPos],"</k>"))
1075
+                            {
1076
+                                $key .= $this->aObjArray[$this->iPos];
1077
+                                $this->iPos++;
1078
+                            }
1079
+                        }
1080
+                        if(stristr($this->aObjArray[$this->iPos],"<v>"))
1081
+                        {
1082
+                            $this->iPos++;
1083
+                            while(!stristr($this->aObjArray[$this->iPos],"</v>"))
1084
+                            {
1085
+                                if(stristr($this->aObjArray[$this->iPos],"<xjxobj>"))
1086
+                                {
1087
+                                    $value = $this->_parseObjXml("xjxobj");
1088
+                                    $this->iPos++;
1089
+                                }
1090
+                                else
1091
+                                {
1092
+                                    $value .= $this->aObjArray[$this->iPos];
1093
+                                    if ($this->bDecodeUTF8Input)
1094
+                                    {
1095
+                                        $value = $this->_decodeUTF8Data($value);
1096
+                                    }
1097
+                                }
1098
+                                $this->iPos++;
1099
+                            }
1100
+                        }
1101
+                        $this->iPos++;
1102
+                    }
1103
+
1104
+                    $aArray[$key]=$value;
1105
+                }
1106
+            }
1107
+        }
1108
+
1109
+        if ($rootTag == "xjxquery")
1110
+        {
1111
+            $sQuery = "";
1112
+            $this->iPos++;
1113
+            while(!stristr($this->aObjArray[$this->iPos],"</xjxquery>"))
1114
+            {
1115
+                if (stristr($this->aObjArray[$this->iPos],"<q>") || stristr($this->aObjArray[$this->iPos],"</q>"))
1116
+                {
1117
+                    $this->iPos++;
1118
+                    continue;
1119
+                }
1120
+                $sQuery	.= $this->aObjArray[$this->iPos];
1121
+                $this->iPos++;
1122
+            }
1123
+
1124
+            parse_str($sQuery, $aArray);
1125
+            if ($this->bDecodeUTF8Input)
1126
+            {
1127
+                foreach($aArray as $key => $value)
1128
+                {
1129
+                    $aArray[$key] = $this->_decodeUTF8Data($value);
1130
+                }
1131
+            }
1132
+            // If magic quotes is on, then we need to strip the slashes from the
1133
+            // array values because of the parse_str pass which adds slashes
1134
+            if (get_magic_quotes_gpc() == 1) {
1135
+                $newArray = array();
1136
+                foreach ($aArray as $sKey => $sValue) {
1137
+                    if (is_string($sValue))
1138
+                        $newArray[$sKey] = stripslashes($sValue);
1139
+                    else
1140
+                        $newArray[$sKey] = $sValue;
1141
+                }
1142
+                $aArray = $newArray;
1143
+            }
1144
+        }
1145
+
1146
+        return $aArray;
1147
+    }
1148
+
1149
+    /**
1150
+     * Decodes string data from UTF-8 to the current xajax encoding.
1151
+     *
1152
+     * @param string data to convert
1153
+     * @access private
1154
+     * @return string converted data
1155
+     */
1156
+    function _decodeUTF8Data($sData)
1157
+    {
1158
+        $sValue = $sData;
1159
+        if ($this->bDecodeUTF8Input)
1160
+        {
1161
+            $sFuncToUse = NULL;
1162
+
1163
+            // An adaptation for the Dokeos LMS, 22-AUG-2009.
1164
+            if (function_exists('api_convert_encoding'))
1165
+            {
1166
+                $sFuncToUse = "api_convert_encoding";
1167
+            }
1168
+            //if (function_exists('iconv'))
1169
+            elseif (function_exists('iconv'))
1170
+            //
1171
+            {
1172
+                $sFuncToUse = "iconv";
1173
+            }
1174
+            else if (function_exists('mb_convert_encoding'))
1175
+            {
1176
+                $sFuncToUse = "mb_convert_encoding";
1177
+            }
1178
+            else if ($this->sEncoding == "ISO-8859-1")
1179
+            {
1180
+                $sFuncToUse = "utf8_decode";
1181
+            }
1182
+            else
1183
+            {
1184
+                trigger_error("The incoming xajax data could not be converted from UTF-8", E_USER_NOTICE);
1185
+            }
1186
+
1187
+            if ($sFuncToUse)
1188
+            {
1189
+                if (is_string($sValue))
1190
+                {
1191
+                    if ($sFuncToUse == "iconv")
1192
+                    {
1193
+                        $sValue = iconv("UTF-8", $this->sEncoding.'//TRANSLIT', $sValue);
1194
+                    }
1195
+                    else if ($sFuncToUse == "mb_convert_encoding")
1196
+                    {
1197
+                        $sValue = mb_convert_encoding($sValue, $this->sEncoding, "UTF-8");
1198
+                    }
1199
+                    // Added code, an adaptation for the Dokeos LMS, 22-AUG-2009.
1200
+                    else if ($sFuncToUse == "api_convert_encoding")
1201
+                    {
1202
+                        $sValue = api_convert_encoding($sValue, $this->sEncoding, "UTF-8");
1203
+                    }
1204
+                    //
1205
+                    else
1206
+                    {
1207
+                        $sValue = utf8_decode($sValue);
1208
+                    }
1209
+                }
1210
+            }
1211
+        }
1212
+        return $sValue;
1213
+    }
1214 1214
 
1215 1215
 }// end class xajax
1216 1216
 
@@ -1220,31 +1220,31 @@  discard block
 block discarded – undo
1220 1220
  */
1221 1221
 function xajaxErrorHandler($errno, $errstr, $errfile, $errline)
1222 1222
 {
1223
-	$errorReporting = error_reporting();
1224
-	if (($errno & $errorReporting) == 0) return;
1225
-
1226
-	if ($errno == E_NOTICE) {
1227
-		$errTypeStr = "NOTICE";
1228
-	}
1229
-	else if ($errno == E_WARNING) {
1230
-		$errTypeStr = "WARNING";
1231
-	}
1232
-	else if ($errno == E_USER_NOTICE) {
1233
-		$errTypeStr = "USER NOTICE";
1234
-	}
1235
-	else if ($errno == E_USER_WARNING) {
1236
-		$errTypeStr = "USER WARNING";
1237
-	}
1238
-	else if ($errno == E_USER_ERROR) {
1239
-		$errTypeStr = "USER FATAL ERROR";
1240
-	}
1241
-	else if ($errno == E_STRICT) {
1242
-		return;
1243
-	}
1244
-	else {
1245
-		$errTypeStr = "UNKNOWN: $errno";
1246
-	}
1247
-	$GLOBALS['xajaxErrorHandlerText'] .= "\n----\n[$errTypeStr] $errstr\nerror in line $errline of file $errfile";
1223
+    $errorReporting = error_reporting();
1224
+    if (($errno & $errorReporting) == 0) return;
1225
+
1226
+    if ($errno == E_NOTICE) {
1227
+        $errTypeStr = "NOTICE";
1228
+    }
1229
+    else if ($errno == E_WARNING) {
1230
+        $errTypeStr = "WARNING";
1231
+    }
1232
+    else if ($errno == E_USER_NOTICE) {
1233
+        $errTypeStr = "USER NOTICE";
1234
+    }
1235
+    else if ($errno == E_USER_WARNING) {
1236
+        $errTypeStr = "USER WARNING";
1237
+    }
1238
+    else if ($errno == E_USER_ERROR) {
1239
+        $errTypeStr = "USER FATAL ERROR";
1240
+    }
1241
+    else if ($errno == E_STRICT) {
1242
+        return;
1243
+    }
1244
+    else {
1245
+        $errTypeStr = "UNKNOWN: $errno";
1246
+    }
1247
+    $GLOBALS['xajaxErrorHandlerText'] .= "\n----\n[$errTypeStr] $errstr\nerror in line $errline of file $errfile";
1248 1248
 }
1249 1249
 
1250 1250
 ?>
Please login to merge, or discard this patch.
main/inc/lib/userportal.lib.php 1 patch
Indentation   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -248,17 +248,17 @@  discard block
 block discarded – undo
248 248
                 }
249 249
             }
250 250
 
251
-			if (trim($home_top_temp) == '' && api_is_platform_admin()) {
252
-				$home_top_temp = '<div class="welcome-mascot">' . get_lang('PortalHomepageDefaultIntroduction') . '</div>';
253
-			} else {
254
-				$home_top_temp = '<div class="welcome-home-top-temp">' . $home_top_temp . '</div>';
255
-			}
256
-			$open = str_replace('{rel_path}', api_get_path(REL_PATH), $home_top_temp);
257
-			$html = api_to_system_encoding($open, api_detect_encoding(strip_tags($open)));
258
-		}
259
-
260
-		return $html;
261
-	}
251
+            if (trim($home_top_temp) == '' && api_is_platform_admin()) {
252
+                $home_top_temp = '<div class="welcome-mascot">' . get_lang('PortalHomepageDefaultIntroduction') . '</div>';
253
+            } else {
254
+                $home_top_temp = '<div class="welcome-home-top-temp">' . $home_top_temp . '</div>';
255
+            }
256
+            $open = str_replace('{rel_path}', api_get_path(REL_PATH), $home_top_temp);
257
+            $html = api_to_system_encoding($open, api_detect_encoding(strip_tags($open)));
258
+        }
259
+
260
+        return $html;
261
+    }
262 262
 
263 263
     function return_notice()
264 264
     {
@@ -509,7 +509,7 @@  discard block
 block discarded – undo
509 509
                     $thereIsSubCat = true;
510 510
                 } elseif (api_get_setting('show_empty_course_categories') == 'true') {
511 511
                     /* End changed code to eliminate the (0 courses) after empty categories. */
512
-                      $htmlListCat .= '<li>';
512
+                        $htmlListCat .= '<li>';
513 513
                     $htmlListCat .= $catLine['name'];
514 514
                     $htmlListCat .= "</li>";
515 515
                     $thereIsSubCat = true;
@@ -639,11 +639,11 @@  discard block
 block discarded – undo
639 639
     }
640 640
 
641 641
     /**
642
-    * retrieves all the courses that the user has already subscribed to
643
-    * @author Patrick Cool <[email protected]>, Ghent University, Belgium
644
-    * @param int $user_id: the id of the user
645
-    * @return array an array containing all the information of the courses of the given user
646
-    */
642
+     * retrieves all the courses that the user has already subscribed to
643
+     * @author Patrick Cool <[email protected]>, Ghent University, Belgium
644
+     * @param int $user_id: the id of the user
645
+     * @return array an array containing all the information of the courses of the given user
646
+     */
647 647
     public function get_courses_of_user($user_id)
648 648
     {
649 649
         $table_course = Database::get_main_table(TABLE_MAIN_COURSE);
Please login to merge, or discard this patch.
main/inc/lib/text.lib.php 1 patch
Indentation   +33 added lines, -33 removed lines patch added patch discarded remove patch
@@ -1,12 +1,12 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 /* For licensing terms, see /license.txt */
3 3
 /**
4
- * This is the text library for Chamilo.
5
- * It is loaded during the global initialization,
6
- * so the functions below are available everywhere.
7
- *
8
- * @package chamilo.library
9
- */
4
+     * This is the text library for Chamilo.
5
+     * It is loaded during the global initialization,
6
+     * so the functions below are available everywhere.
7
+     *
8
+     * @package chamilo.library
9
+     */
10 10
 
11 11
 define('EXERCISE_NUMBER_OF_DECIMALS', 2);
12 12
 
@@ -693,8 +693,8 @@  discard block
 block discarded – undo
693 693
  */
694 694
 function get_week_from_day($date) {
695 695
     if (!empty($date)) {
696
-       $time = api_strtotime($date,'UTC');
697
-       return date('W', $time);
696
+        $time = api_strtotime($date,'UTC');
697
+        return date('W', $time);
698 698
     } else {
699 699
         return date('W');
700 700
     }
@@ -712,31 +712,31 @@  discard block
 block discarded – undo
712 712
 
713 713
 function substrwords($text,$maxchar,$end='...')
714 714
 {
715
-	if(strlen($text)>$maxchar)
716
-	{
717
-		$words=explode(" ",$text);
718
-		$output = '';
719
-		$i=0;
720
-		while(1)
721
-		{
722
-			$length = (strlen($output)+strlen($words[$i]));
723
-			if($length>$maxchar)
724
-			{
725
-				break;
726
-			}
727
-			else
728
-			{
729
-				$output = $output." ".$words[$i];
730
-				$i++;
731
-			};
732
-		};
733
-	}
734
-	else
735
-	{
736
-		$output = $text;
737
-		return $output;
738
-	}
739
-	return $output.$end;
715
+    if(strlen($text)>$maxchar)
716
+    {
717
+        $words=explode(" ",$text);
718
+        $output = '';
719
+        $i=0;
720
+        while(1)
721
+        {
722
+            $length = (strlen($output)+strlen($words[$i]));
723
+            if($length>$maxchar)
724
+            {
725
+                break;
726
+            }
727
+            else
728
+            {
729
+                $output = $output." ".$words[$i];
730
+                $i++;
731
+            };
732
+        };
733
+    }
734
+    else
735
+    {
736
+        $output = $text;
737
+        return $output;
738
+    }
739
+    return $output.$end;
740 740
 }
741 741
 
742 742
 function implode_with_key($glue, $array) {
Please login to merge, or discard this patch.
main/tracking/lp_results_by_user.php 1 patch
Indentation   +102 added lines, -102 removed lines patch added patch discarded remove patch
@@ -16,34 +16,34 @@  discard block
 block discarded – undo
16 16
 $is_allowedToTrack = $is_courseAdmin || $is_platformAdmin || $is_courseCoach || $is_sessionAdmin;
17 17
 
18 18
 if (!$is_allowedToTrack) {
19
-	Display :: display_header(null);
20
-	api_not_allowed();
21
-	Display :: display_footer();
19
+    Display :: display_header(null);
20
+    api_not_allowed();
21
+    Display :: display_footer();
22 22
 }
23 23
 
24 24
 $export_to_csv = false;
25 25
 if (isset($_GET['export'])) {
26
-	$export_to_csv = true;
26
+    $export_to_csv = true;
27 27
 }
28 28
 
29 29
 if (api_is_platform_admin() ) {
30
-	$global = true;
30
+    $global = true;
31 31
 } else {
32
-	$global = false;
32
+    $global = false;
33 33
 }
34 34
 
35 35
 if ($global) {
36
-	$temp_course_list = CourseManager :: get_courses_list();
37
-	foreach($temp_course_list  as $temp_course_item) {
38
-		$course_item = CourseManager ::get_course_information($temp_course_item['code']);
36
+    $temp_course_list = CourseManager :: get_courses_list();
37
+    foreach($temp_course_list  as $temp_course_item) {
38
+        $course_item = CourseManager ::get_course_information($temp_course_item['code']);
39 39
         $course_list[] = array(
40 40
             'code' => $course_item['code'],
41 41
             'title' => $course_item['title'],
42 42
         );
43
-	}
43
+    }
44 44
 } else {
45 45
     $current_course['code'] = $_course['id'];
46
-	$course_list = array($current_course);
46
+    $course_list = array($current_course);
47 47
 }
48 48
 
49 49
 $new_course_select = array();
@@ -54,20 +54,20 @@  discard block
 block discarded – undo
54 54
 $form = new FormValidator('search_simple', 'POST', '', '', null, false);
55 55
 $form->addElement('select','course_code',get_lang('Course'), $new_course_select);
56 56
 if ($global) {
57
-	$form->addElement('hidden','view','admin');
57
+    $form->addElement('hidden','view','admin');
58 58
 } else {
59
-	//Get exam lists
59
+    //Get exam lists
60 60
     $course_id = api_get_course_int_id();
61
-	$t_quiz = Database::get_course_table(TABLE_QUIZ_TEST);
62
-	$sqlExercices = "SELECT quiz.title,id FROM ".$t_quiz." AS quiz
61
+    $t_quiz = Database::get_course_table(TABLE_QUIZ_TEST);
62
+    $sqlExercices = "SELECT quiz.title,id FROM ".$t_quiz." AS quiz
63 63
 	                 WHERE c_id = $course_id AND active='1'
64 64
 	                 ORDER BY quiz.title ASC";
65
-	$resultExercices = Database::query($sqlExercices);
66
-	$exercise_list[0] = get_lang('All');
67
-	while($a_exercices = Database::fetch_array($resultExercices)) {
68
-		$exercise_list[$a_exercices['id']] = $a_exercices['title'];
69
-	}
70
-	$form->addElement('select', 'exercise_id', get_lang('Exercise'), $exercise_list);
65
+    $resultExercices = Database::query($sqlExercices);
66
+    $exercise_list[0] = get_lang('All');
67
+    while($a_exercices = Database::fetch_array($resultExercices)) {
68
+        $exercise_list[$a_exercices['id']] = $a_exercices['title'];
69
+    }
70
+    $form->addElement('select', 'exercise_id', get_lang('Exercise'), $exercise_list);
71 71
 }
72 72
 
73 73
 //$form->addElement('submit','submit',get_lang('Filter'));
@@ -81,86 +81,86 @@  discard block
 block discarded – undo
81 81
 }
82 82
 
83 83
 if (!$export_to_csv) {
84
-	Display :: display_header(get_lang('Reporting'));
85
-	echo '<div class="actions" style ="font-size:10pt;">';
86
-	if ($global) {
84
+    Display :: display_header(get_lang('Reporting'));
85
+    echo '<div class="actions" style ="font-size:10pt;">';
86
+    if ($global) {
87 87
 
88 88
         echo '<div style="float:right"> <a href="'.api_get_self().'?export=1&score='.$filter_score.'&exercise_id='.$exercise_id.'"><img align="absbottom" src="../img/csv.gif">&nbsp;'.get_lang('ExportAsCSV').'</a>' .
89 89
                 '<a href="javascript: void(0);" onclick="javascript: window.print()"><img align="absbottom" src="../img/printmgr.gif">&nbsp;'.get_lang('Print').'</a></div>';
90 90
 
91
-		$menu_items[] = '<a href="'.api_get_path(WEB_CODE_PATH).'mySpace/?view=teacher">'.get_lang('TeacherInterface').'</a>';
91
+        $menu_items[] = '<a href="'.api_get_path(WEB_CODE_PATH).'mySpace/?view=teacher">'.get_lang('TeacherInterface').'</a>';
92 92
         if (api_is_platform_admin()) {
93
-		  $menu_items[] = '<a href="'.api_get_path(WEB_CODE_PATH).'mySpace/?view=admin">'.get_lang('AdminInterface').'</a>';
93
+            $menu_items[] = '<a href="'.api_get_path(WEB_CODE_PATH).'mySpace/?view=admin">'.get_lang('AdminInterface').'</a>';
94 94
         } else {
95 95
             $menu_items[] = '<a href="'.api_get_path(WEB_CODE_PATH).'mySpace/?view=coach">'.get_lang('AdminInterface').'</a>';
96 96
         }
97
-		$menu_items[] = get_lang('ExamTracking');
98
-		$nb_menu_items = count($menu_items);
99
-		if($nb_menu_items>1) {
100
-			foreach($menu_items as $key=> $item) {
101
-				echo $item;
102
-				if($key!=$nb_menu_items-1) {
103
-					echo ' | ';
104
-				}
105
-			}
106
-			echo '<br />';
107
-		}
108
-	} else {
109
-	    echo '<a href="courseLog.php?'.api_get_cidreq().'&studentlist=true">'.get_lang('StudentsTracking').'</a>&nbsp;|
97
+        $menu_items[] = get_lang('ExamTracking');
98
+        $nb_menu_items = count($menu_items);
99
+        if($nb_menu_items>1) {
100
+            foreach($menu_items as $key=> $item) {
101
+                echo $item;
102
+                if($key!=$nb_menu_items-1) {
103
+                    echo ' | ';
104
+                }
105
+            }
106
+            echo '<br />';
107
+        }
108
+    } else {
109
+        echo '<a href="courseLog.php?'.api_get_cidreq().'&studentlist=true">'.get_lang('StudentsTracking').'</a>&nbsp;|
110 110
 		     <a href="courseLog.php?'.api_get_cidreq().'&studentlist=false">'.get_lang('CourseTracking').'</a>&nbsp;|&nbsp';
111 111
         echo '<a href="courseLog.php?'.api_get_cidreq().'&studentlist=resources">'.get_lang('ResourcesTracking').'</a>';
112
-		echo ' | '.get_lang('ExamTracking').'';
112
+        echo ' | '.get_lang('ExamTracking').'';
113 113
         echo '<a href="'.api_get_self().'?export=1&score='.$filter_score.'&exercise_id='.$exercise_id.'"><img align="absbottom" src="../img/excel.gif">&nbsp;'.get_lang('ExportAsXLS').'</a><br /><br />';
114 114
 
115
-	}
115
+    }
116 116
     echo '</div>';
117
-	echo '<br /><br />';
118
-	$form->display();
117
+    echo '<br /><br />';
118
+    $form->display();
119 119
 }
120 120
 $main_result = array();
121 121
 $session_id = 0;
122 122
 $user_list = array();
123 123
 //Getting course list
124 124
 foreach($course_list  as $current_course ) {
125
-	$course_info = api_get_course_info($current_course['code']);
126
-	$_course = $course_info;
127
-
128
-	//Getting LP list
129
-	$list = new LearnpathList('', $current_course['code'], $session_id);
130
-	$lp_list = $list->get_flat_list();
131
-
132
-	// Looping LPs
133
-	$lps = array();
134
-	foreach ($lp_list as $lp_id =>$lp) {
135
-		$exercise_list = Event::get_all_exercises_from_lp($lp_id, $course_info['real_id']);
136
-		$attempt_result = array();
137
-		//Looping Chamilo Exercises in LP
138
-		foreach ($exercise_list as $exercise) {
139
-			$exercise_stats = Event::get_all_exercise_event_from_lp(
140
-				$exercise['path'],
141
-				$course_info['real_id'],
142
-				$session_id
143
-			);
144
-			// Looping Exercise Attempts
145
-			foreach ($exercise_stats as $stats) {
146
-				$attempt_result[$exercise['id']]['users'][$stats['exe_user_id']][$stats['exe_id']] = $stats;
147
-				$user_list[$stats['exe_user_id']] = $stats['exe_user_id'];
148
-			}
149
-			$exercise_list_name[$exercise['id']] = $exercise['title'];
150
-		}
151
-		$lps[$lp_id] = array('lp_name' =>$lp['lp_name'], 'exercises' =>$attempt_result);
152
-		$lp_list_name[$lp_id] = $lp['lp_name'];
153
-	}
154
-	$main_result[$current_course['code']] = $lps;
125
+    $course_info = api_get_course_info($current_course['code']);
126
+    $_course = $course_info;
127
+
128
+    //Getting LP list
129
+    $list = new LearnpathList('', $current_course['code'], $session_id);
130
+    $lp_list = $list->get_flat_list();
131
+
132
+    // Looping LPs
133
+    $lps = array();
134
+    foreach ($lp_list as $lp_id =>$lp) {
135
+        $exercise_list = Event::get_all_exercises_from_lp($lp_id, $course_info['real_id']);
136
+        $attempt_result = array();
137
+        //Looping Chamilo Exercises in LP
138
+        foreach ($exercise_list as $exercise) {
139
+            $exercise_stats = Event::get_all_exercise_event_from_lp(
140
+                $exercise['path'],
141
+                $course_info['real_id'],
142
+                $session_id
143
+            );
144
+            // Looping Exercise Attempts
145
+            foreach ($exercise_stats as $stats) {
146
+                $attempt_result[$exercise['id']]['users'][$stats['exe_user_id']][$stats['exe_id']] = $stats;
147
+                $user_list[$stats['exe_user_id']] = $stats['exe_user_id'];
148
+            }
149
+            $exercise_list_name[$exercise['id']] = $exercise['title'];
150
+        }
151
+        $lps[$lp_id] = array('lp_name' =>$lp['lp_name'], 'exercises' =>$attempt_result);
152
+        $lp_list_name[$lp_id] = $lp['lp_name'];
153
+    }
154
+    $main_result[$current_course['code']] = $lps;
155 155
 }
156 156
 
157 157
 if (!empty($user_list)) {
158 158
     foreach($user_list as $user_id) {
159 159
         $user_data = api_get_user_info($user_id);
160
-		$user_list_name[$user_id] = api_get_person_name(
161
-			$user_data['firstname'],
162
-			$user_data['lastname']
163
-		);
160
+        $user_list_name[$user_id] = api_get_person_name(
161
+            $user_data['firstname'],
162
+            $user_data['lastname']
163
+        );
164 164
     }
165 165
 }
166 166
 $export_array =  array();
@@ -200,15 +200,15 @@  discard block
 block discarded – undo
200 200
                         $html_result .= Display::tag('td', $result);
201 201
 
202 202
                         $html_result .= '</tr>';
203
-						$export_array[] = array(
204
-							$course_code,
205
-							$lp_list_name[$lp_id],
206
-							$exercise_list_name[$exercise_id],
207
-							$user_list_name[$user_id],
208
-							$attempt,
209
-							api_get_local_time($attempt_data['exe_date']),
210
-							$result,
211
-						);
203
+                        $export_array[] = array(
204
+                            $course_code,
205
+                            $lp_list_name[$lp_id],
206
+                            $exercise_list_name[$exercise_id],
207
+                            $user_list_name[$user_id],
208
+                            $attempt,
209
+                            api_get_local_time($attempt_data['exe_date']),
210
+                            $result,
211
+                        );
212 212
                         $attempt++;
213 213
                     }
214 214
                 }
@@ -219,30 +219,30 @@  discard block
 block discarded – undo
219 219
 }
220 220
 
221 221
 if (!$export_to_csv) {
222
-	echo $html_result;
222
+    echo $html_result;
223 223
 }
224 224
 $filename = 'learning_path_results-'.date('Y-m-d-h:i:s').'.xls';
225 225
 if ($export_to_csv) {
226 226
     export_complete_report_csv($filename, $export_array);
227
-	exit;
227
+    exit;
228 228
 }
229 229
 
230 230
 function export_complete_report_csv($filename, $array)
231 231
 {
232
-	$header[] = array(
233
-		get_lang('Course'),
234
-		get_lang('LearningPath'),
235
-		get_lang('Exercise'),
236
-		get_lang('User'),
237
-		get_lang('Attempt'),
238
-		get_lang('Date'),
239
-		get_lang('Results'),
240
-	);
241
-	if (!empty($array)) {
242
-		$array = array_merge($header, $array);
243
-		Export :: arrayToCsv($array, $filename);
244
-	}
245
-	exit;
232
+    $header[] = array(
233
+        get_lang('Course'),
234
+        get_lang('LearningPath'),
235
+        get_lang('Exercise'),
236
+        get_lang('User'),
237
+        get_lang('Attempt'),
238
+        get_lang('Date'),
239
+        get_lang('Results'),
240
+    );
241
+    if (!empty($array)) {
242
+        $array = array_merge($header, $array);
243
+        Export :: arrayToCsv($array, $filename);
244
+    }
245
+    exit;
246 246
 
247 247
 }
248 248
 Display :: display_footer();
Please login to merge, or discard this patch.
main/tracking/logins_details.php 1 patch
Indentation   +9 added lines, -10 removed lines patch added patch discarded remove patch
@@ -1,17 +1,16 @@
 block discarded – undo
1 1
 <?php
2 2
 /* For licensing terms, see /license.txt */
3 3
 /**
4
- * 	@author Thomas Depraetere
5
- * 	@author Hugues Peeters
6
- * 	@author Christophe Gesche
7
- * 	@author Sebastien Piraux
8
- *
9
- * 	@package chamilo.tracking
10
-
11
- */
4
+     * 	@author Thomas Depraetere
5
+     * 	@author Hugues Peeters
6
+     * 	@author Christophe Gesche
7
+     * 	@author Sebastien Piraux
8
+     *
9
+     * 	@package chamilo.tracking
10
+     */
12 11
 /**
13
- * Code
14
- */
12
+     * Code
13
+     */
15 14
 // TODO: Is this file deprecated?
16 15
 
17 16
 /* 		INIT SECTION */
Please login to merge, or discard this patch.
main/tracking/exams.php 1 patch
Indentation   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -384,10 +384,10 @@
 block discarded – undo
384 384
     exit;
385 385
 }
386 386
 /**
387
- * @param $a
388
- * @param $b
389
- * @return int
390
- */
387
+     * @param $a
388
+     * @param $b
389
+     * @return int
390
+     */
391 391
 function sort_user($a, $b) {
392 392
     if (is_numeric($a['score']) && is_numeric($b['score'])) {
393 393
         if ($a['score'] < $b['score']) {
Please login to merge, or discard this patch.
main/tracking/course_log_tools.php 1 patch
Indentation   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -78,7 +78,7 @@  discard block
 block discarded – undo
78 78
 
79 79
 // getting all the students of the course
80 80
 if (empty($session_id)) {
81
-	// Registered students in a course outside session.
81
+    // Registered students in a course outside session.
82 82
     $a_students = CourseManager:: get_student_list_from_course_code(
83 83
         api_get_course_id(),
84 84
         false,
@@ -89,7 +89,7 @@  discard block
 block discarded – undo
89 89
         api_get_group_id()
90 90
     );
91 91
 } else {
92
-	// Registered students in session.
92
+    // Registered students in session.
93 93
     $a_students = CourseManager:: get_student_list_from_course_code(
94 94
         api_get_course_id(),
95 95
         true,
Please login to merge, or discard this patch.