Completed
Push — master ( dca322...47e653 )
by Julito
08:54
created

xajax::processRequests()   F

Complexity

Conditions 42
Paths > 20000

Size

Total Lines 176
Code Lines 113

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 42
eloc 113
nc 2641921
nop 0
dl 0
loc 176
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * xajax.inc.php :: Main xajax class and setup file
4
 *
5
 * xajax version 0.2.4
6
 * copyright (c) 2005 by Jared White & J. Max Wilson
7
 * http://www.xajaxproject.org
8
 *
9
 * xajax is an open source PHP class library for easily creating powerful
10
 * PHP-driven, web-based Ajax Applications. Using xajax, you can asynchronously
11
 * call PHP functions and update the content of your your webpage without
12
 * reloading the page.
13
 *
14
 * xajax is released under the terms of the LGPL license
15
 * http://www.gnu.org/copyleft/lesser.html#SEC3
16
 *
17
 * This library is free software; you can redistribute it and/or
18
 * modify it under the terms of the GNU Lesser General Public
19
 * License as published by the Free Software Foundation; either
20
 * version 2.1 of the License, or (at your option) any later version.
21
 *
22
 * This library is distributed in the hope that it will be useful,
23
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25
 * Lesser General Public License for more details.
26
 *
27
 * You should have received a copy of the GNU Lesser General Public
28
 * License along with this library; if not, write to the Free Software
29
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
30
 *
31
 * @package chamilo.include.xajax
32
 * @version $Id: xajax.inc.php,v 1.1 2006/07/21 15:29:46 elixir_inter Exp $
33
 * @copyright Copyright (c) 2005-2006  by Jared White & J. Max Wilson
34
 * @license http://www.gnu.org/copyleft/lesser.html#SEC3 LGPL License
35
 */
36
37
/*
38
   ----------------------------------------------------------------------------
39
   | Online documentation for this class is available on the xajax wiki at:   |
40
   | http://wiki.xajaxproject.org/Documentation:xajax.inc.php                 |
41
   ----------------------------------------------------------------------------
42
*/
43
44
/**
45
 * Define XAJAX_DEFAULT_CHAR_ENCODING that is used by both
46
 * the xajax and xajaxResponse classes
47
 */
48
if (!defined ('XAJAX_DEFAULT_CHAR_ENCODING'))
49
{
50
	define ('XAJAX_DEFAULT_CHAR_ENCODING', 'utf-8' );
51
}
52
53
/**
54
 * Communication Method Defines
55
 */
56
if (!defined ('XAJAX_GET'))
57
{
58
	define ('XAJAX_GET', 0);
59
}
60
if (!defined ('XAJAX_POST'))
61
{
62
	define ('XAJAX_POST', 1);
63
}
64
65
/**
66
 * The xajax class generates the xajax javascript for your page including the
67
 * Javascript wrappers for the PHP functions that you want to call from your page.
68
 * It also handles processing and executing the command messages in the XML responses
69
 * sent back to your page from your PHP functions.
70
 *
71
 * @package chamilo.include.xajax
72
 */
73
class xajax
74
{
75
	/**#@+
76
	 * @access protected
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
	public function __construct($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
		$requestMode = -1;
527
		$sFunctionName = "";
528
		$bFoundFunction = true;
529
		$bFunctionIsCatchAll = false;
530
		$sFunctionNameForSpecial = "";
531
		$aArgs = array();
532
		$sPreResponse = "";
533
		$bEndRequest = false;
534
		$sResponse = "";
535
536
		$requestMode = $this->getRequestMode();
537
		if ($requestMode == -1) return;
538
539
		if ($requestMode == XAJAX_POST)
540
		{
541
			$sFunctionName = $_POST["xajax"];
542
543
			if (!empty($_POST["xajaxargs"]))
544
				$aArgs = $_POST["xajaxargs"];
545
		}
546
		else
547
		{
548
			header ("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
549
			header ("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
550
			header ("Cache-Control: no-cache, must-revalidate");
551
			header ("Pragma: no-cache");
552
553
			$sFunctionName = $_GET["xajax"];
554
555
			if (!empty($_GET["xajaxargs"]))
556
				$aArgs = $_GET["xajaxargs"];
557
		}
558
559
		// Use xajax error handler if necessary
560
		if ($this->bErrorHandler) {
561
			$GLOBALS['xajaxErrorHandlerText'] = "";
562
			set_error_handler("xajaxErrorHandler");
563
		}
564
565
		if ($this->sPreFunction) {
566
			if (!$this->_isFunctionCallable($this->sPreFunction)) {
567
				$bFoundFunction = false;
568
				$objResponse = new xajaxResponse();
569
				$objResponse->addAlert("Unknown Pre-Function ". $this->sPreFunction);
570
				$sResponse = $objResponse->getXML();
571
			}
572
		}
573
		//include any external dependencies associated with this function name
574
		if (array_key_exists($sFunctionName,$this->aFunctionIncludeFiles))
575
		{
576
			ob_start();
577
			include_once($this->aFunctionIncludeFiles[$sFunctionName]);
578
			ob_end_clean();
579
		}
580
581
		if ($bFoundFunction) {
582
			$sFunctionNameForSpecial = $sFunctionName;
583
			if (!array_key_exists($sFunctionName, $this->aFunctions))
584
			{
585
				if ($this->sCatchAllFunction) {
586
					$sFunctionName = $this->sCatchAllFunction;
587
					$bFunctionIsCatchAll = true;
588
				}
589
				else {
590
					$bFoundFunction = false;
591
					$objResponse = new xajaxResponse();
592
					$objResponse->addAlert("Unknown Function $sFunctionName.");
593
					$sResponse = $objResponse->getXML();
594
				}
595
			}
596
			else if ($this->aFunctionRequestTypes[$sFunctionName] != $requestMode)
597
			{
598
				$bFoundFunction = false;
599
				$objResponse = new xajaxResponse();
600
				$objResponse->addAlert("Incorrect Request Type.");
601
				$sResponse = $objResponse->getXML();
602
			}
603
		}
604
605
		if ($bFoundFunction)
606
		{
607
			for ($i = 0; $i < sizeof($aArgs); $i++)
608
			{
609
				// If magic quotes is on, then we need to strip the slashes from the args
610
				if (get_magic_quotes_gpc() == 1 && is_string($aArgs[$i])) {
611
612
					$aArgs[$i] = stripslashes($aArgs[$i]);
613
				}
614
				if (stristr($aArgs[$i],"<xjxobj>") != false)
615
				{
616
					$aArgs[$i] = $this->_xmlToArray("xjxobj",$aArgs[$i]);
617
				}
618
				else if (stristr($aArgs[$i],"<xjxquery>") != false)
619
				{
620
					$aArgs[$i] = $this->_xmlToArray("xjxquery",$aArgs[$i]);
621
				}
622
				else if ($this->bDecodeUTF8Input)
623
				{
624
					$aArgs[$i] = $this->_decodeUTF8Data($aArgs[$i]);
625
				}
626
			}
627
628
			if ($this->sPreFunction) {
629
				$mPreResponse = $this->_callFunction($this->sPreFunction, array($sFunctionNameForSpecial, $aArgs));
630
				if (is_array($mPreResponse) && $mPreResponse[0] === false) {
631
					$bEndRequest = true;
632
					$sPreResponse = $mPreResponse[1];
633
				}
634
				else {
635
					$sPreResponse = $mPreResponse;
636
				}
637
				if (is_a($sPreResponse, "xajaxResponse")) {
638
					$sPreResponse = $sPreResponse->getXML();
639
				}
640
				if ($bEndRequest) $sResponse = $sPreResponse;
641
			}
642
643
			if (!$bEndRequest) {
644
				if (!$this->_isFunctionCallable($sFunctionName)) {
645
					$objResponse = new xajaxResponse();
646
					$objResponse->addAlert("The Registered Function $sFunctionName Could Not Be Found.");
647
					$sResponse = $objResponse->getXML();
648
				}
649
				else {
650
					if ($bFunctionIsCatchAll) {
651
						$aArgs = array($sFunctionNameForSpecial, $aArgs);
652
					}
653
					$sResponse = $this->_callFunction($sFunctionName, $aArgs);
654
				}
655
				if (is_a($sResponse, "xajaxResponse")) {
656
					$sResponse = $sResponse->getXML();
657
				}
658
				if (!is_string($sResponse) || strpos($sResponse, "<xjx>") === FALSE) {
659
					$objResponse = new xajaxResponse();
660
					$objResponse->addAlert("No XML Response Was Returned By Function $sFunctionName.");
661
					$sResponse = $objResponse->getXML();
662
				}
663
				else if ($sPreResponse != "") {
664
					$sNewResponse = new xajaxResponse($this->sEncoding, $this->bOutputEntities);
665
					$sNewResponse->loadXML($sPreResponse);
666
					$sNewResponse->loadXML($sResponse);
667
					$sResponse = $sNewResponse->getXML();
668
				}
669
			}
670
		}
671
672
		$sContentHeader = "Content-type: text/xml;";
673
		if ($this->sEncoding && strlen(trim($this->sEncoding)) > 0)
674
			$sContentHeader .= " charset=".$this->sEncoding;
675
		header($sContentHeader);
676
		if ($this->bErrorHandler && !empty( $GLOBALS['xajaxErrorHandlerText'] )) {
677
			$sErrorResponse = new xajaxResponse();
678
			$sErrorResponse->addAlert("** PHP Error Messages: **" . $GLOBALS['xajaxErrorHandlerText']);
679
			if ($this->sLogFile) {
680
				$fH = @fopen($this->sLogFile, "a");
681
				if (!$fH) {
682
					$sErrorResponse->addAlert("** Logging Error **\n\nxajax was unable to write to the error log file:\n" . $this->sLogFile);
683
				}
684
				else {
685
					fwrite($fH, "** xajax Error Log - " . strftime("%b %e %Y %I:%M:%S %p") . " **" . $GLOBALS['xajaxErrorHandlerText'] . "\n\n\n");
686
					fclose($fH);
687
				}
688
			}
689
690
			$sErrorResponse->loadXML($sResponse);
691
			$sResponse = $sErrorResponse->getXML();
692
693
		}
694
		if ($this->bCleanBuffer) while (@ob_end_clean());
695
		print $sResponse;
696
		if ($this->bErrorHandler) restore_error_handler();
697
698
		if ($this->bExitAllowed)
699
			exit();
700
	}
701
702
	/**
703
	 * Prints the xajax Javascript header and wrapper code into your page by
704
	 * printing the output of the getJavascript() method. It should only be
705
	 * called between the <pre><head> </head></pre> tags in your HTML page.
706
	 * Remember, if you only want to obtain the result of this function, use
707
	 * {@link xajax::getJavascript()} instead.
708
	 *
709
	 * <i>Usage:</i>
710
	 * <code>
711
	 *  <head>
712
	 *		...
713
	 *		< ?php $xajax->printJavascript(); ? >
714
	 * </code>
715
	 *
716
	 * @param string the relative address of the folder where xajax has been
717
	 *               installed. For instance, if your PHP file is
718
	 *               "http://www.myserver.com/myfolder/mypage.php"
719
	 *               and xajax was installed in
720
	 *               "http://www.myserver.com/anotherfolder", then $sJsURI
721
	 *               should be set to "../anotherfolder". Defaults to assuming
722
	 *               xajax is in the same folder as your PHP file.
723
	 * @param string the relative folder/file pair of the xajax Javascript
724
	 *               engine located within the xajax installation folder.
725
	 *               Defaults to xajax_js/xajax.js.
726
	 */
727
	function printJavascript($sJsURI="", $sJsFile=NULL)
728
	{
729
		print $this->getJavascript($sJsURI, $sJsFile);
730
	}
731
732
	/**
733
	 * Returns the xajax Javascript code that should be added to your HTML page
734
	 * between the <kbd><head> </head></kbd> tags.
735
	 *
736
	 * <i>Usage:</i>
737
	 * <code>
738
	 *  < ?php $xajaxJSHead = $xajax->getJavascript(); ? >
739
	 *	<head>
740
	 *		...
741
	 *		< ?php echo $xajaxJSHead; ? >
742
	 * </code>
743
	 *
744
	 * @param string the relative address of the folder where xajax has been
745
	 *               installed. For instance, if your PHP file is
746
	 *               "http://www.myserver.com/myfolder/mypage.php"
747
	 *               and xajax was installed in
748
	 *               "http://www.myserver.com/anotherfolder", then $sJsURI
749
	 *               should be set to "../anotherfolder". Defaults to assuming
750
	 *               xajax is in the same folder as your PHP file.
751
	 * @param string the relative folder/file pair of the xajax Javascript
752
	 *               engine located within the xajax installation folder.
753
	 *               Defaults to xajax_js/xajax.js.
754
	 * @return string
755
	 */
756
	function getJavascript($sJsURI="", $sJsFile=NULL)
757
	{
758
		$html = $this->getJavascriptConfig();
759
		$html .= $this->getJavascriptInclude($sJsURI, $sJsFile);
760
761
		return $html;
762
	}
763
764
	/**
765
	 * Returns a string containing inline Javascript that sets up the xajax
766
	 * runtime (typically called internally by xajax from get/printJavascript).
767
	 *
768
	 * @return string
769
	 */
770
	function getJavascriptConfig()
771
	{
772
		$html  = "\t<script type=\"text/javascript\">\n";
773
		$html .= "var xajaxRequestUri=\"".$this->sRequestURI."\";\n";
774
		$html .= "var xajaxDebug=".($this->bDebug?"true":"false").";\n";
775
		$html .= "var xajaxStatusMessages=".($this->bStatusMessages?"true":"false").";\n";
776
		$html .= "var xajaxWaitCursor=".($this->bWaitCursor?"true":"false").";\n";
777
		$html .= "var xajaxDefinedGet=".XAJAX_GET.";\n";
778
		$html .= "var xajaxDefinedPost=".XAJAX_POST.";\n";
779
		$html .= "var xajaxLoaded=false;\n";
780
781
		foreach($this->aFunctions as $sFunction => $bExists) {
782
			$html .= $this->_wrap($sFunction,$this->aFunctionRequestTypes[$sFunction]);
783
		}
784
785
		$html .= "\t</script>\n";
786
		return $html;
787
	}
788
789
	/**
790
	 * Returns a string containing a Javascript include of the xajax.js file
791
	 * along with a check to see if the file loaded after six seconds
792
	 * (typically called internally by xajax from get/printJavascript).
793
	 *
794
	 * @param string the relative address of the folder where xajax has been
795
	 *               installed. For instance, if your PHP file is
796
	 *               "http://www.myserver.com/myfolder/mypage.php"
797
	 *               and xajax was installed in
798
	 *               "http://www.myserver.com/anotherfolder", then $sJsURI
799
	 *               should be set to "../anotherfolder". Defaults to assuming
800
	 *               xajax is in the same folder as your PHP file.
801
	 * @param string the relative folder/file pair of the xajax Javascript
802
	 *               engine located within the xajax installation folder.
803
	 *               Defaults to xajax_js/xajax.js.
804
	 * @return string
805
	 */
806
	function getJavascriptInclude($sJsURI="", $sJsFile=NULL)
807
	{
808
		if ($sJsFile == NULL) $sJsFile = "xajax_js/xajax.js";
809
810
		if ($sJsURI != "" && substr($sJsURI, -1) != "/") $sJsURI .= "/";
811
812
		$html = "\t<script type=\"text/javascript\" src=\"" . $sJsURI . $sJsFile . "\"></script>\n";
813
		$html .= "\t<script type=\"text/javascript\">\n";
814
		$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";
815
		$html .= "\t</script>\n";
816
		return $html;
817
	}
818
819
	/**
820
	 * Returns the current URL based upon the SERVER vars.
821
	 *
822
	 * @access private
823
	 * @return string
824
	 */
825
	function _detectURI()
826
	{
827
		$aURL = array();
828
829
		// Try to get the request URL
830
		if (!empty($_SERVER['REQUEST_URI'])) {
831
			$aURL = parse_url($_SERVER['REQUEST_URI']);
832
		}
833
834
		// Fill in the empty values
835
		if (empty($aURL['scheme'])) {
836
			if (!empty($_SERVER['HTTP_SCHEME'])) {
837
				$aURL['scheme'] = $_SERVER['HTTP_SCHEME'];
838
			} else {
839
				$aURL['scheme'] = (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) != 'off') ? 'https' : 'http';
840
			}
841
		}
842
843
		if (empty($aURL['host'])) {
844
			if (!empty($_SERVER['HTTP_HOST'])) {
845
				if (strpos($_SERVER['HTTP_HOST'], ':') > 0) {
846
					list($aURL['host'], $aURL['port']) = explode(':', $_SERVER['HTTP_HOST']);
847
				} else {
848
					$aURL['host'] = $_SERVER['HTTP_HOST'];
849
				}
850
			} else if (!empty($_SERVER['SERVER_NAME'])) {
851
				$aURL['host'] = $_SERVER['SERVER_NAME'];
852
			} else {
853
				print "xajax Error: xajax failed to automatically identify your Request URI.";
854
				print "Please set the Request URI explicitly when you instantiate the xajax object.";
855
				exit();
856
			}
857
		}
858
859
		if (empty($aURL['port']) && !empty($_SERVER['SERVER_PORT'])) {
860
			$aURL['port'] = $_SERVER['SERVER_PORT'];
861
		}
862
863
		if (empty($aURL['path'])) {
864
			if (!empty($_SERVER['PATH_INFO'])) {
865
				$sPath = parse_url($_SERVER['PATH_INFO']);
866
			} else {
867
				$sPath = parse_url(api_get_self());
868
			}
869
			$aURL['path'] = $sPath['path'];
870
			unset($sPath);
871
		}
872
873
		if (!empty($aURL['query'])) {
874
			$aURL['query'] = '?'.$aURL['query'];
875
		}
876
877
		// Build the URL: Start with scheme, user and pass
878
		$sURL  = api_get_self();
879
		// Add the path and the query string
880
		$sURL.= @$aURL['query'];
881
882
		// Clean up
883
		unset($aURL);
884
		return $sURL;
885
	}
886
887
	/**
888
	 * Returns true if the function name is associated with an object callback,
889
	 * false if not.
890
	 *
891
	 * @param string the name of the function
892
	 * @access private
893
	 * @return boolean
894
	 */
895
	function _isObjectCallback($sFunction)
896
	{
897
		if (array_key_exists($sFunction, $this->aObjects)) return true;
898
		return false;
899
	}
900
901
	/**
902
	 * Returns true if the function or object callback can be called, false if
903
	 * not.
904
	 *
905
	 * @param string the name of the function
906
	 * @access private
907
	 * @return boolean
908
	 */
909
	function _isFunctionCallable($sFunction)
910
	{
911
		if ($this->_isObjectCallback($sFunction)) {
912
			if (is_object($this->aObjects[$sFunction][0])) {
913
				return method_exists($this->aObjects[$sFunction][0], $this->aObjects[$sFunction][1]);
914
			}
915
			else {
916
				return is_callable($this->aObjects[$sFunction]);
917
			}
918
		}
919
		else {
920
			return function_exists($sFunction);
921
		}
922
	}
923
924
	/**
925
	 * Calls the function, class method, or object method with the supplied
926
	 * arguments.
927
	 *
928
	 * @param string the name of the function
929
	 * @param array  arguments to pass to the function
930
	 * @access private
931
	 * @return mixed the output of the called function or method
932
	 */
933
	function _callFunction($sFunction, $aArgs)
934
	{
935
		if ($this->_isObjectCallback($sFunction)) {
936
			$mReturn = call_user_func_array($this->aObjects[$sFunction], $aArgs);
937
		}
938
		else {
939
			$mReturn = call_user_func_array($sFunction, $aArgs);
940
		}
941
		return $mReturn;
942
	}
943
944
	/**
945
	 * Generates the Javascript wrapper for the specified PHP function.
946
	 *
947
	 * @param string the name of the function
948
	 * @param mixed  the request type
949
	 * @access private
950
	 * @return string
951
	 */
952
	function _wrap($sFunction,$sRequestType=XAJAX_POST)
953
	{
954
		$js = "function ".$this->sWrapperPrefix."$sFunction(){return xajax.call(\"$sFunction\", arguments, ".$sRequestType.");}\n";
955
		return $js;
956
	}
957
958
	/**
959
	 * Takes a string containing xajax xjxobj XML or xjxquery XML and builds an
960
	 * array representation of it to pass as an argument to the PHP function
961
	 * being called.
962
	 *
963
	 * @param string the root tag of the XML
964
	 * @param string XML to convert
965
	 * @access private
966
	 * @return array
967
	 */
968
	function _xmlToArray($rootTag, $sXml)
969
	{
970
		$aArray = array();
971
		$sXml = str_replace("<$rootTag>","<$rootTag>|~|",$sXml);
972
		$sXml = str_replace("</$rootTag>","</$rootTag>|~|",$sXml);
973
		$sXml = str_replace("<e>","<e>|~|",$sXml);
974
		$sXml = str_replace("</e>","</e>|~|",$sXml);
975
		$sXml = str_replace("<k>","<k>|~|",$sXml);
976
		$sXml = str_replace("</k>","|~|</k>|~|",$sXml);
977
		$sXml = str_replace("<v>","<v>|~|",$sXml);
978
		$sXml = str_replace("</v>","|~|</v>|~|",$sXml);
979
		$sXml = str_replace("<q>","<q>|~|",$sXml);
980
		$sXml = str_replace("</q>","|~|</q>|~|",$sXml);
981
982
		$this->aObjArray = explode("|~|",$sXml);
983
984
		$this->iPos = 0;
985
		$aArray = $this->_parseObjXml($rootTag);
986
987
		return $aArray;
988
	}
989
990
	/**
991
	 * A recursive function that generates an array from the contents of
992
	 * $this->aObjArray.
993
	 *
994
	 * @param string the root tag of the XML
995
	 * @access private
996
	 * @return array
997
	 */
998
	function _parseObjXml($rootTag)
999
	{
1000
		$aArray = array();
1001
1002
		if ($rootTag == "xjxobj")
1003
		{
1004
			while(!stristr($this->aObjArray[$this->iPos],"</xjxobj>"))
1005
			{
1006
				$this->iPos++;
1007
				if(stristr($this->aObjArray[$this->iPos],"<e>"))
1008
				{
1009
					$key = "";
1010
					$value = null;
1011
1012
					$this->iPos++;
1013
					while(!stristr($this->aObjArray[$this->iPos],"</e>"))
1014
					{
1015
						if(stristr($this->aObjArray[$this->iPos],"<k>"))
1016
						{
1017
							$this->iPos++;
1018
							while(!stristr($this->aObjArray[$this->iPos],"</k>"))
1019
							{
1020
								$key .= $this->aObjArray[$this->iPos];
1021
								$this->iPos++;
1022
							}
1023
						}
1024
						if(stristr($this->aObjArray[$this->iPos],"<v>"))
1025
						{
1026
							$this->iPos++;
1027
							while(!stristr($this->aObjArray[$this->iPos],"</v>"))
1028
							{
1029
								if(stristr($this->aObjArray[$this->iPos],"<xjxobj>"))
1030
								{
1031
									$value = $this->_parseObjXml("xjxobj");
1032
									$this->iPos++;
1033
								}
1034
								else
1035
								{
1036
									$value .= $this->aObjArray[$this->iPos];
1037
									if ($this->bDecodeUTF8Input)
1038
									{
1039
										$value = $this->_decodeUTF8Data($value);
1040
									}
1041
								}
1042
								$this->iPos++;
1043
							}
1044
						}
1045
						$this->iPos++;
1046
					}
1047
1048
					$aArray[$key]=$value;
1049
				}
1050
			}
1051
		}
1052
1053
		if ($rootTag == "xjxquery")
1054
		{
1055
			$sQuery = "";
1056
			$this->iPos++;
1057
			while(!stristr($this->aObjArray[$this->iPos],"</xjxquery>"))
1058
			{
1059
				if (stristr($this->aObjArray[$this->iPos],"<q>") || stristr($this->aObjArray[$this->iPos],"</q>"))
1060
				{
1061
					$this->iPos++;
1062
					continue;
1063
				}
1064
				$sQuery	.= $this->aObjArray[$this->iPos];
1065
				$this->iPos++;
1066
			}
1067
1068
			parse_str($sQuery, $aArray);
1069
			if ($this->bDecodeUTF8Input)
1070
			{
1071
				foreach($aArray as $key => $value)
1072
				{
1073
					$aArray[$key] = $this->_decodeUTF8Data($value);
1074
				}
1075
			}
1076
			// If magic quotes is on, then we need to strip the slashes from the
1077
			// array values because of the parse_str pass which adds slashes
1078
			if (get_magic_quotes_gpc() == 1) {
1079
				$newArray = array();
1080
				foreach ($aArray as $sKey => $sValue) {
1081
					if (is_string($sValue))
1082
						$newArray[$sKey] = stripslashes($sValue);
1083
					else
1084
						$newArray[$sKey] = $sValue;
1085
				}
1086
				$aArray = $newArray;
1087
			}
1088
		}
1089
1090
		return $aArray;
1091
	}
1092
1093
	/**
1094
	 * Decodes string data from UTF-8 to the current xajax encoding.
1095
	 *
1096
	 * @param string data to convert
1097
	 * @access private
1098
	 * @return string converted data
1099
	 */
1100
	function _decodeUTF8Data($sData)
1101
	{
1102
		$sValue = $sData;
1103
		if ($this->bDecodeUTF8Input)
1104
		{
1105
			$sFuncToUse = NULL;
1106
1107
			// An adaptation for the Dokeos LMS, 22-AUG-2009.
1108
			if (function_exists('api_convert_encoding'))
1109
			{
1110
				$sFuncToUse = "api_convert_encoding";
1111
			}
1112
			//if (function_exists('iconv'))
1113
			elseif (function_exists('iconv'))
1114
			//
1115
			{
1116
				$sFuncToUse = "iconv";
1117
			}
1118
			else if (function_exists('mb_convert_encoding'))
1119
			{
1120
				$sFuncToUse = "mb_convert_encoding";
1121
			}
1122
			else if ($this->sEncoding == "ISO-8859-1")
1123
			{
1124
				$sFuncToUse = "utf8_decode";
1125
			}
1126
			else
1127
			{
1128
				trigger_error("The incoming xajax data could not be converted from UTF-8", E_USER_NOTICE);
1129
			}
1130
1131
			if ($sFuncToUse)
1132
			{
1133
				if (is_string($sValue))
1134
				{
1135
					if ($sFuncToUse == "iconv")
1136
					{
1137
						$sValue = iconv("UTF-8", $this->sEncoding.'//TRANSLIT', $sValue);
1138
					}
1139
					else if ($sFuncToUse == "mb_convert_encoding")
1140
					{
1141
						$sValue = mb_convert_encoding($sValue, $this->sEncoding, "UTF-8");
1142
					}
1143
					// Added code, an adaptation for the Dokeos LMS, 22-AUG-2009.
1144
					else if ($sFuncToUse == "api_convert_encoding")
1145
					{
1146
						$sValue = api_convert_encoding($sValue, $this->sEncoding, "UTF-8");
1147
					}
1148
					//
1149
					else
1150
					{
1151
						$sValue = utf8_decode($sValue);
1152
					}
1153
				}
1154
			}
1155
		}
1156
		return $sValue;
1157
	}
1158
1159
}// end class xajax
1160
1161
/**
1162
 * This function is registered with PHP's set_error_handler() function if
1163
 * the xajax error handling system is turned on.
1164
 */
1165
function xajaxErrorHandler($errno, $errstr, $errfile, $errline)
1166
{
1167
	$errorReporting = error_reporting();
1168
	if (($errno & $errorReporting) == 0) return;
1169
1170
	if ($errno == E_NOTICE) {
1171
		$errTypeStr = "NOTICE";
1172
	}
1173
	else if ($errno == E_WARNING) {
1174
		$errTypeStr = "WARNING";
1175
	}
1176
	else if ($errno == E_USER_NOTICE) {
1177
		$errTypeStr = "USER NOTICE";
1178
	}
1179
	else if ($errno == E_USER_WARNING) {
1180
		$errTypeStr = "USER WARNING";
1181
	}
1182
	else if ($errno == E_USER_ERROR) {
1183
		$errTypeStr = "USER FATAL ERROR";
1184
	}
1185
	else if ($errno == E_STRICT) {
1186
		return;
1187
	}
1188
	else {
1189
		$errTypeStr = "UNKNOWN: $errno";
1190
	}
1191
	$GLOBALS['xajaxErrorHandlerText'] .= "\n----\n[$errTypeStr] $errstr\nerror in line $errline of file $errfile";
1192
}
1193
1194
?>
1195