root/freepbx/branches/experimental/amp_conf/htdocs/panel/xajax.inc.php

Revision 2140, 35.6 kB (checked in by gregmac, 2 years ago)

Initial work on DhtmlOperatorPanel

  • Property svn:mime-type set to text/plain
  • Property svn:eol-style set to native
Line 
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 xajax
32  * @version $Id$
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 require_once(dirname(__FILE__)."/xajaxResponse.inc.php");
54
55 /**
56  * Communication Method Defines
57  */
58 if (!defined ('XAJAX_GET'))
59 {
60         define ('XAJAX_GET', 0);
61 }
62 if (!defined ('XAJAX_POST'))
63 {
64         define ('XAJAX_POST', 1);
65 }
66
67 /**
68  * The xajax class generates the xajax javascript for your page including the
69  * Javascript wrappers for the PHP functions that you want to call from your page.
70  * It also handles processing and executing the command messages in the XML responses
71  * sent back to your page from your PHP functions.
72  *
73  * @package xajax
74  */
75 class xajax
76 {
77         /**#@+
78          * @access protected
79          */
80         /**
81          * @var array Array of PHP functions that will be callable through javascript wrappers
82          */
83         var $aFunctions;
84         /**
85          * @var array Array of object callbacks that will allow Javascript to call PHP methods (key=function name)
86          */
87         var $aObjects;
88         /**
89          * @var array Array of RequestTypes to be used with each function (key=function name)
90          */
91         var $aFunctionRequestTypes;
92         /**
93          * @var array Array of Include Files for any external functions (key=function name)
94          */
95         var $aFunctionIncludeFiles;
96         /**
97          * @var string Name of the PHP function to call if no callable function was found
98          */
99         var $sCatchAllFunction;
100         /**
101          * @var string Name of the PHP function to call before any other function
102          */
103         var $sPreFunction;
104         /**
105          * @var string The URI for making requests to the xajax object
106          */
107         var $sRequestURI;
108         /**
109          * @var string The prefix to prepend to the javascript wraper function name
110          */
111         var $sWrapperPrefix;
112         /**
113          * @var boolean Show debug messages (default false)
114          */
115         var $bDebug;
116         /**
117          * @var boolean Show messages in the client browser's status bar (default false)
118          */
119         var $bStatusMessages;   
120         /**
121          * @var boolean Allow xajax to exit after processing a request (default true)
122          */
123         var $bExitAllowed;
124         /**
125          * @var boolean Use wait cursor in browser (default true)
126          */
127         var $bWaitCursor;
128         /**
129          * @var boolean Use an special xajax error handler so the errors are sent to the browser properly (default false)
130          */
131         var $bErrorHandler;
132         /**
133          * @var string Specify what, if any, file xajax should log errors to (and more information in a future release)
134          */
135         var $sLogFile;
136         /**
137          * @var boolean Clean all output buffers before outputting response (default false)
138          */
139         var $bCleanBuffer;
140         /**
141          * @var string String containing the character encoding used
142          */
143         var $sEncoding;
144         /**
145          * @var boolean Decode input request args from UTF-8 (default false)
146          */
147         var $bDecodeUTF8Input;
148         /**
149          * @var boolean Convert special characters to HTML entities (default false)
150          */
151         var $bOutputEntities;
152         /**
153          * @var array Array for parsing complex objects
154          */
155         var $aObjArray;
156         /**
157          * @var integer Position in $aObjArray
158          */
159         var $iPos;
160        
161         /**#@-*/
162        
163         /**
164          * Constructor. You can set some extra xajax options right away or use
165          * individual methods later to set options.
166          *
167          * @param string  defaults to the current browser URI
168          * @param string  defaults to "xajax_";
169          * @param string  defaults to XAJAX_DEFAULT_CHAR_ENCODING defined above
170          * @param boolean defaults to false
171          */
172         function xajax($sRequestURI="",$sWrapperPrefix="xajax_",$sEncoding=XAJAX_DEFAULT_CHAR_ENCODING,$bDebug=false)
173         {
174                 $this->aFunctions = array();
175                 $this->aObjects = array();
176                 $this->aFunctionIncludeFiles = array();
177                 $this->sRequestURI = $sRequestURI;
178                 if ($this->sRequestURI == "")
179                         $this->sRequestURI = $this->_detectURI();
180                 $this->sWrapperPrefix = $sWrapperPrefix;
181                 $this->bDebug = $bDebug;
182                 $this->bStatusMessages = false;
183                 $this->bWaitCursor = true;
184                 $this->bExitAllowed = true;
185                 $this->bErrorHandler = false;
186                 $this->sLogFile = "";
187                 $this->bCleanBuffer = false;
188                 $this->setCharEncoding($sEncoding);
189                 $this->bDecodeUTF8Input = false;
190                 $this->bOutputEntities = false;
191         }
192                
193         /**
194          * Sets the URI to which requests will be made.
195          * <i>Usage:</i> <kbd>$xajax->setRequestURI("http://www.xajaxproject.org");</kbd>
196          *
197          * @param string the URI (can be absolute or relative) of the PHP script
198          *               that will be accessed when an xajax request occurs
199          */
200         function setRequestURI($sRequestURI)
201         {
202                 $this->sRequestURI = $sRequestURI;
203         }
204
205         /**
206          * Sets the prefix that will be appended to the Javascript wrapper
207          * functions (default is "xajax_").
208          *
209          * @param string
210          */
211         //
212         function setWrapperPrefix($sPrefix)
213         {
214                 $this->sWrapperPrefix = $sPrefix;
215         }
216        
217         /**
218          * Enables debug messages for xajax.
219          * */
220         function debugOn()
221         {
222                 $this->bDebug = true;
223         }
224        
225         /**
226          * Disables debug messages for xajax (default behavior).
227          */
228         function debugOff()
229         {
230                 $this->bDebug = false;
231         }
232                
233         /**
234          * Enables messages in the browser's status bar for xajax.
235          */
236         function statusMessagesOn()
237         {
238                 $this->bStatusMessages = true;
239         }
240        
241         /**
242          * Disables messages in the browser's status bar for xajax (default behavior).
243          */
244         function statusMessagesOff()
245         {
246                 $this->bStatusMessages = false;
247         }
248        
249         /**
250          * Enables the wait cursor to be displayed in the browser (default behavior).
251          */
252         function waitCursorOn()
253         {
254                 $this->bWaitCursor = true;
255         }
256        
257         /**
258          * Disables the wait cursor to be displayed in the browser.
259          */
260         function waitCursorOff()
261         {
262                 $this->bWaitCursor = false;
263         }       
264        
265         /**
266          * Enables xajax to exit immediately after processing a request and
267          * sending the response back to the browser (default behavior).
268          */
269         function exitAllowedOn()
270         {
271                 $this->bExitAllowed = true;
272         }
273        
274         /**
275          * Disables xajax's default behavior of exiting immediately after
276          * processing a request and sending the response back to the browser.
277          */
278         function exitAllowedOff()
279         {
280                 $this->bExitAllowed = false;
281         }
282        
283         /**
284          * Turns on xajax's error handling system so that PHP errors that occur
285          * during a request are trapped and pushed to the browser in the form of
286          * a Javascript alert.
287          */
288         function errorHandlerOn()
289         {
290                 $this->bErrorHandler = true;
291         }
292
293         /**
294          * Turns off xajax's error handling system (default behavior).
295          */
296         function errorHandlerOff()
297         {
298                 $this->bErrorHandler = false;
299         }
300        
301         /**
302          * Specifies a log file that will be written to by xajax during a request
303          * (used only by the error handling system at present). If you don't invoke
304          * this method, or you pass in "", then no log file will be written to.
305          * <i>Usage:</i> <kbd>$xajax->setLogFile("/xajax_logs/errors.log");</kbd>
306          */
307         function setLogFile($sFilename)
308         {
309                 $this->sLogFile = $sFilename;
310         }
311
312         /**
313          * Causes xajax to clean out all output buffers before outputting a
314          * response (default behavior).
315          */
316         function cleanBufferOn()
317         {
318                 $this->bCleanBuffer = true;
319         }
320         /**
321          * Turns off xajax's output buffer cleaning.
322          */
323         function cleanBufferOff()
324         {
325                 $this->bCleanBuffer = false;
326         }
327        
328         /**
329          * Sets the character encoding for the HTTP output based on
330          * <kbd>$sEncoding</kbd>, which is a string containing the character
331          * encoding to use. You don't need to use this method normally, since the
332          * character encoding for the response gets set automatically based on the
333          * <kbd>XAJAX_DEFAULT_CHAR_ENCODING</kbd> constant.
334          * <i>Usage:</i> <kbd>$xajax->setCharEncoding("utf-8");</kbd>
335          *
336          * @param string the encoding type to use (utf-8, iso-8859-1, etc.)
337          */
338         function setCharEncoding($sEncoding)
339         {
340                 $this->sEncoding = $sEncoding;
341         }
342
343         /**
344          * Causes xajax to decode the input request args from UTF-8 to the current
345          * encoding if possible. Either the iconv or mb_string extension must be
346          * present for optimal functionality.
347          */
348         function decodeUTF8InputOn()
349         {
350                 $this->bDecodeUTF8Input = true;
351         }
352
353         /**
354          * Turns off decoding the input request args from UTF-8 (default behavior).
355          */
356         function decodeUTF8InputOff()
357         {
358                 $this->bDecodeUTF8Input = false;
359         }
360        
361         /**
362          * Tells the response object to convert special characters to HTML entities
363          * automatically (only works if the mb_string extension is available).
364          */
365         function outputEntitiesOn()
366         {
367                 $this->bOutputEntities = true;
368         }
369        
370         /**
371          * Tells the response object to output special characters intact. (default
372          * behavior).
373          */
374         function outputEntitiesOff()
375         {
376                 $this->bOutputEntities = false;
377         }
378                                
379         /**
380          * Registers a PHP function or method to be callable through xajax in your
381          * Javascript. If you want to register a function, pass in the name of that
382          * function. If you want to register a static class method, pass in an
383          * array like so:
384          * <kbd>array("myFunctionName", "myClass", "myMethod")</kbd>
385          * For an object instance method, use an object variable for the second
386          * array element (and in PHP 4 make sure you put an & before the variable
387          * to pass the object by reference). Note: the function name is what you
388          * call via Javascript, so it can be anything as long as it doesn't
389          * conflict with any other registered function name.
390          *
391          * <i>Usage:</i> <kbd>$xajax->registerFunction("myFunction");</kbd>
392          * or: <kbd>$xajax->registerFunction(array("myFunctionName", &$myObject, "myMethod"));</kbd>
393          *
394          * @param mixed  contains the function name or an object callback array
395          * @param mixed  request type (XAJAX_GET/XAJAX_POST) that should be used
396          *               for this function.  Defaults to XAJAX_POST.
397          */
398         function registerFunction($mFunction,$sRequestType=XAJAX_POST)
399         {
400                 if (is_array($mFunction)) {
401                         $this->aFunctions[$mFunction[0]] = 1;
402                         $this->aFunctionRequestTypes[$mFunction[0]] = $sRequestType;
403                         $this->aObjects[$mFunction[0]] = array_slice($mFunction, 1);
404                 }       
405                 else {
406                         $this->aFunctions[$mFunction] = 1;
407                         $this->aFunctionRequestTypes[$mFunction] = $sRequestType;
408                 }
409         }
410        
411         /**
412          * Registers a PHP function to be callable through xajax which is located
413          * in some other file.  If the function is requested the external file will
414          * be included to define the function before the function is called.
415          *
416          * <i>Usage:</i> <kbd>$xajax->registerExternalFunction("myFunction","myFunction.inc.php",XAJAX_POST);</kbd>
417          *
418          * @param string contains the function name or an object callback array
419          *               ({@link xajax::registerFunction() see registerFunction} for
420          *               more info on object callback arrays)
421          * @param string contains the path and filename of the include file
422          * @param mixed  the RequestType (XAJAX_GET/XAJAX_POST) that should be used
423          *                        for this function. Defaults to XAJAX_POST.
424          */
425         function registerExternalFunction($mFunction,$sIncludeFile,$sRequestType=XAJAX_POST)
426         {
427                 $this->registerFunction($mFunction, $sRequestType);
428                
429                 if (is_array($mFunction)) {
430                         $this->aFunctionIncludeFiles[$mFunction[0]] = $sIncludeFile;
431                 }
432                 else {
433                         $this->aFunctionIncludeFiles[$mFunction] = $sIncludeFile;
434                 }
435         }
436        
437         /**
438          * Registers a PHP function to be called when xajax cannot find the
439          * function being called via Javascript. Because this is technically
440          * impossible when using "wrapped" functions, the catch-all feature is
441          * only useful when you're directly using the xajax.call() Javascript
442          * method. Use the catch-all feature when you want more dynamic ability to
443          * intercept unknown calls and handle them in a custom way.
444          *
445          * <i>Usage:</i> <kbd>$xajax->registerCatchAllFunction("myCatchAllFunction");</kbd>
446          *
447          * @param string contains the function name or an object callback array
448          *               ({@link xajax::registerFunction() see registerFunction} for
449          *               more info on object callback arrays)
450          */
451         function registerCatchAllFunction($mFunction)
452         {
453                 if (is_array($mFunction)) {
454                         $this->sCatchAllFunction = $mFunction[0];
455                         $this->aObjects[$mFunction[0]] = array_slice($mFunction, 1);
456                 }
457                 else {
458                         $this->sCatchAllFunction = $mFunction;
459                 }
460         }
461        
462         /**
463          * Registers a PHP function to be called before xajax calls the requested
464          * function. xajax will automatically add the request function's response
465          * to the pre-function's response to create a single response. Another
466          * feature is the ability to return not just a response, but an array with
467          * the first element being false (a boolean) and the second being the
468          * response. In this case, the pre-function's response will be returned to
469          * the browser without xajax calling the requested function.
470          *
471          * <i>Usage:</i> <kbd>$xajax->registerPreFunction("myPreFunction");</kbd>
472          *
473          * @param string contains the function name or an object callback array
474          *               ({@link xajax::registerFunction() see registerFunction} for
475          *               more info on object callback arrays)
476          */
477         function registerPreFunction($mFunction)
478         {
479                 if (is_array($mFunction)) {
480                         $this->sPreFunction = $mFunction[0];
481                         $this->aObjects[$mFunction[0]] = array_slice($mFunction, 1);
482                 }
483                 else {
484                         $this->sPreFunction = $mFunction;
485                 }
486         }
487        
488         /**
489          * Returns true if xajax can process the request, false if otherwise.
490          * You can use this to determine if xajax needs to process the request or
491          * not.
492          *
493          * @return boolean
494          */
495         function canProcessRequests()
496         {
497                 if ($this->getRequestMode() != -1) return true;
498                 return false;
499         }
500        
501         /**
502          * Returns the current request mode (XAJAX_GET or XAJAX_POST), or -1 if
503          * there is none.
504          *
505          * @return mixed
506          */
507         function getRequestMode()
508         {
509                 if (!empty($_GET["xajax"]))
510                         return XAJAX_GET;
511                
512                 if (!empty($_POST["xajax"]))
513                         return XAJAX_POST;
514                        
515                 return -1;
516         }
517        
518         /**
519          * This is the main communications engine of xajax. The engine handles all
520          * incoming xajax requests, calls the apporiate PHP functions (or
521          * class/object methods) and passes the XML responses back to the
522          * Javascript response handler. If your RequestURI is the same as your Web
523          * page then this function should be called before any headers or HTML has
524          * been sent.
525          */
526         function processRequests()
527         {       
528                
529                 $requestMode = -1;
530                 $sFunctionName = "";
531                 $bFoundFunction = true;
532                 $bFunctionIsCatchAll = false;
533                 $sFunctionNameForSpecial = "";
534                 $aArgs = array();
535                 $sPreResponse = "";
536                 $bEndRequest = false;
537                 $sResponse = "";
538                
539                 $requestMode = $this->getRequestMode();
540                 if ($requestMode == -1) return;
541        
542                 if ($requestMode == XAJAX_POST)
543                 {
544                         $sFunctionName = $_POST["xajax"];
545                        
546                         if (!empty($_POST["xajaxargs"]))
547                                 $aArgs = $_POST["xajaxargs"];
548                 }
549                 else
550                 {       
551                         header ("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
552                         header ("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
553                         header ("Cache-Control: no-cache, must-revalidate");
554                         header ("Pragma: no-cache");
555                        
556                         $sFunctionName = $_GET["xajax"];
557                        
558                         if (!empty($_GET["xajaxargs"]))
559                                 $aArgs = $_GET["xajaxargs"];
560                 }
561                
562                 // Use xajax error handler if necessary
563                 if ($this->bErrorHandler) {
564                         $GLOBALS['xajaxErrorHandlerText'] = "";
565                         set_error_handler("xajaxErrorHandler");
566                 }
567                
568                 if ($this->sPreFunction) {
569                         if (!$this->_isFunctionCallable($this->sPreFunction)) {
570                                 $bFoundFunction = false;
571                                 $objResponse = new xajaxResponse();
572                                 $objResponse->addAlert("Unknown Pre-Function ". $this->sPreFunction);
573                                 $sResponse = $objResponse->getXML();
574                         }
575                 }
576                 //include any external dependencies associated with this function name
577                 if (array_key_exists($sFunctionName,$this->aFunctionIncludeFiles))
578                 {
579                         ob_start();
580                         include_once($this->aFunctionIncludeFiles[$sFunctionName]);
581                         ob_end_clean();
582                 }
583                
584                 if ($bFoundFunction) {
585                         $sFunctionNameForSpecial = $sFunctionName;
586                         if (!array_key_exists($sFunctionName, $this->aFunctions))
587                         {
588                                 if ($this->sCatchAllFunction) {
589                                         $sFunctionName = $this->sCatchAllFunction;
590                                         $bFunctionIsCatchAll = true;
591                                 }
592                                 else {
593                                         $bFoundFunction = false;
594                                         $objResponse = new xajaxResponse();
595                                         $objResponse->addAlert("Unknown Function $sFunctionName.");
596                                         $sResponse = $objResponse->getXML();
597                                 }
598                         }
599                         else if ($this->aFunctionRequestTypes[$sFunctionName] != $requestMode)
600                         {
601                                 $bFoundFunction = false;
602                                 $objResponse = new xajaxResponse();
603                                 $objResponse->addAlert("Incorrect Request Type.");
604                                 $sResponse = $objResponse->getXML();
605                         }
606                 }
607                
608                 if ($bFoundFunction)
609                 {
610                         for ($i = 0; $i < sizeof($aArgs); $i++)
611                         {
612                                 // If magic quotes is on, then we need to strip the slashes from the args
613                                 if (get_magic_quotes_gpc() == 1 && is_string($aArgs[$i])) {
614                                
615                                         $aArgs[$i] = stripslashes($aArgs[$i]);
616                                 }
617                                 if (stristr($aArgs[$i],"<xjxobj>") != false)
618                                 {
619                                         $aArgs[$i] = $this->_xmlToArray("xjxobj",$aArgs[$i]);   
620                                 }
621                                 else if (stristr($aArgs[$i],"<xjxquery>") != false)
622                                 {
623                                         $aArgs[$i] = $this->_xmlToArray("xjxquery",$aArgs[$i]);
624                                 }
625                                 else if ($this->bDecodeUTF8Input)
626                                 {
627                                         $aArgs[$i] = $this->_decodeUTF8Data($aArgs[$i]);       
628                                 }
629                         }
630
631                         if ($this->sPreFunction) {
632                                 $mPreResponse = $this->_callFunction($this->sPreFunction, array($sFunctionNameForSpecial, $aArgs));
633                                 if (is_array($mPreResponse) && $mPreResponse[0] === false) {
634                                         $bEndRequest = true;
635                                         $sPreResponse = $mPreResponse[1];
636                                 }
637                                 else {
638                                         $sPreResponse = $mPreResponse;
639                                 }
640                                 if (is_a($sPreResponse, "xajaxResponse")) {
641                                         $sPreResponse = $sPreResponse->getXML();
642                                 }
643                                 if ($bEndRequest) $sResponse = $sPreResponse;
644                         }
645                        
646                         if (!$bEndRequest) {
647                                 if (!$this->_isFunctionCallable($sFunctionName)) {
648                                         $objResponse = new xajaxResponse();
649                                         $objResponse->addAlert("The Registered Function $sFunctionName Could Not Be Found.");
650                                         $sResponse = $objResponse->getXML();
651                                 }
652                                 else {
653                                         if ($bFunctionIsCatchAll) {
654                                                 $aArgs = array($sFunctionNameForSpecial, $aArgs);
655                                         }
656                                         $sResponse = $this->_callFunction($sFunctionName, $aArgs);
657                                 }
658                                 if (is_a($sResponse, "xajaxResponse")) {
659                                         $sResponse = $sResponse->getXML();
660                                 }
661                                 if (!is_string($sResponse) || strpos($sResponse, "<xjx>") === FALSE) {
662                                         $objResponse = new xajaxResponse();
663                                         $objResponse->addAlert("No XML Response Was Returned By Function $sFunctionName.");
664                                         $sResponse = $objResponse->getXML();
665                                 }
666                                 else if ($sPreResponse != "") {
667                                         $sNewResponse = new xajaxResponse($this->sEncoding, $this->bOutputEntities);
668                                         $sNewResponse->loadXML($sPreResponse);
669                                         $sNewResponse->loadXML($sResponse);
670                                         $sResponse = $sNewResponse->getXML();
671                                 }
672                         }
673                 }
674                
675                 $sContentHeader = "Content-type: text/xml;";
676                 if ($this->sEncoding && strlen(trim($this->sEncoding)) > 0)
677                         $sContentHeader .= " charset=".$this->sEncoding;
678                 header($sContentHeader);
679                 if ($this->bErrorHandler && !empty( $GLOBALS['xajaxErrorHandlerText'] )) {
680                         $sErrorResponse = new xajaxResponse();
681                         $sErrorResponse->addAlert("** PHP Error Messages: **" . $GLOBALS['xajaxErrorHandlerText']);
682                         if ($this->sLogFile) {
683                                 $fH = @fopen($this->sLogFile, "a");
684                                 if (!$fH) {
685                                         $sErrorResponse->addAlert("** Logging Error **\n\nxajax was unable to write to the error log file:\n" . $this->sLogFile);
686                                 }
687                                 else {
688                                         fwrite($fH, "** xajax Error Log - " . strftime("%b %e %Y %I:%M:%S %p") . " **" . $GLOBALS['xajaxErrorHandlerText'] . "\n\n\n");
689                                         fclose($fH);
690                                 }
691                         }
692
693                         $sErrorResponse->loadXML($sResponse);
694                         $sResponse = $sErrorResponse->getXML();
695                        
696                 }
697                 if ($this->bCleanBuffer) while (@ob_end_clean());
698                 print $sResponse;
699                 if ($this->bErrorHandler) restore_error_handler();
700                
701                 if ($this->bExitAllowed)
702                         exit();
703         }
704
705         /**                     
706          * Prints the xajax Javascript header and wrapper code into your page by
707          * printing the output of the getJavascript() method. It should only be
708          * called between the <pre><head> </head></pre> tags in your HTML page.
709          * Remember, if you only want to obtain the result of this function, use
710          * {@link xajax::getJavascript()} instead.
711          *
712          * <i>Usage:</i>
713          * <code>
714          *  <head>
715          *              ...
716          *              < ?php $xajax->printJavascript(); ? >
717          * </code>
718          *
719          * @param string the relative address of the folder where xajax has been
720          *               installed. For instance, if your PHP file is
721          *               "http://www.myserver.com/myfolder/mypage.php"
722          *               and xajax was installed in
723          *               "http://www.myserver.com/anotherfolder", then $sJsURI
724          *               should be set to "../anotherfolder". Defaults to assuming
725          *               xajax is in the same folder as your PHP file.
726          * @param string the relative folder/file pair of the xajax Javascript
727          *               engine located within the xajax installation folder.
728          *               Defaults to xajax_js/xajax.js.
729          */
730         function printJavascript($sJsURI="", $sJsFile=NULL)
731         {
732                 print $this->getJavascript($sJsURI, $sJsFile);
733         }
734        
735         /**
736          * Returns the xajax Javascript code that should be added to your HTML page
737          * between the <kbd><head> </head></kbd> tags.
738          *
739          * <i>Usage:</i>
740          * <code>
741          *  < ?php $xajaxJSHead = $xajax->getJavascript(); ? >
742          *      <head>
743          *              ...
744          *              < ?php echo $xajaxJSHead; ? >
745          * </code>
746          *
747          * @param string the relative address of the folder where xajax has been
748          *               installed. For instance, if your PHP file is
749          *               "http://www.myserver.com/myfolder/mypage.php"
750          *               and xajax was installed in
751          *               "http://www.myserver.com/anotherfolder", then $sJsURI
752          *               should be set to "../anotherfolder". Defaults to assuming
753          *               xajax is in the same folder as your PHP file.
754          * @param string the relative folder/file pair of the xajax Javascript
755          *               engine located within the xajax installation folder.
756          *               Defaults to xajax_js/xajax.js.
757          * @return string
758          */
759         function getJavascript($sJsURI="", $sJsFile=NULL)
760         {       
761                 $html = $this->getJavascriptConfig();
762                 $html .= $this->getJavascriptInclude($sJsURI, $sJsFile);
763                
764                 return $html;
765         }
766        
767         /**
768          * Returns a string containing inline Javascript that sets up the xajax
769          * runtime (typically called internally by xajax from get/printJavascript).
770          *
771          * @return string
772          */
773         function getJavascriptConfig()
774         {
775                 $html  = "\t<script type=\"text/javascript\">\n";
776                 $html .= "var xajaxRequestUri=\"".$this->sRequestURI."\";\n";
777                 $html .= "var xajaxDebug=".($this->bDebug?"true":"false").";\n";
778                 $html .= "var xajaxStatusMessages=".($this->bStatusMessages?"true":"false").";\n";
779                 $html .= "var xajaxWaitCursor=".($this->bWaitCursor?"true":"false").";\n";
780                 $html .= "var xajaxDefinedGet=".XAJAX_GET.";\n";
781                 $html .= "var xajaxDefinedPost=".XAJAX_POST.";\n";
782                 $html .= "var xajaxLoaded=false;\n";
783
784                 foreach($this->aFunctions as $sFunction => $bExists) {
785                         $html .= $this->_wrap($sFunction,$this->aFunctionRequestTypes[$sFunction]);
786                 }
787
788                 $html .= "\t</script>\n";
789                 return $html;           
790         }
791        
792         /**
793          * Returns a string containing a Javascript include of the xajax.js file
794          * along with a check to see if the file loaded after six seconds
795          * (typically called internally by xajax from get/printJavascript).
796          *
797          * @param string the relative address of the folder where xajax has been
798          *               installed. For instance, if your PHP file is
799          *               "http://www.myserver.com/myfolder/mypage.php"
800          *               and xajax was installed in
801          *               "http://www.myserver.com/anotherfolder", then $sJsURI
802          *               should be set to "../anotherfolder". Defaults to assuming
803          *               xajax is in the same folder as your PHP file.
804          * @param string the relative folder/file pair of the xajax Javascript
805          *               engine located within the xajax installation folder.
806          *               Defaults to xajax_js/xajax.js.
807          * @return string
808          */
809         function getJavascriptInclude($sJsURI="", $sJsFile=NULL)
810         {
811                 if ($sJsFile == NULL) $sJsFile = "xajax_js/xajax.js";
812                        
813                 if ($sJsURI != "" && substr($sJsURI, -1) != "/") $sJsURI .= "/";
814                
815                 $html = "\t<script type=\"text/javascript\" src=\"" . $sJsURI . $sJsFile . "\"></script>\n";   
816                 $html .= "\t<script type=\"text/javascript\">\n";
817                 $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";
818                 $html .= "\t</script>\n";
819                 return $html;
820         }
821
822         /**
823          * This method can be used to create a new xajax.js file out of the
824          * xajax_uncompressed.js file (which will only happen if xajax.js doesn't
825          * already exist on the filesystem).
826          *
827          * @param string an optional argument containing the full server file path
828          *               of xajax.js.
829          */
830         function autoCompressJavascript($sJsFullFilename=NULL)
831         {       
832                 $sJsFile = "xajax_js/xajax.js";
833                
834                 if ($sJsFullFilename) {
835                         $realJsFile = $sJsFullFilename;
836                 }
837                 else {
838                         $realPath = realpath(dirname(__FILE__));
839                         $realJsFile = $realPath . "/". $sJsFile;
840                 }
841
842                 // Create a compressed file if necessary
843                 if (!file_exists($realJsFile)) {
844                         $srcFile = str_replace(".js", "_uncompressed.js", $realJsFile);
845                         if (!file_exists($srcFile)) {
846                                 trigger_error("The xajax uncompressed Javascript file could not be found in the <b>" . dirname($realJsFile) . "</b> folder. Error ", E_USER_ERROR);     
847                         }
848                         require(dirname(__FILE__)."/xajaxCompress.php");
849                         $javaScript = implode('', file($srcFile));
850                         $compressedScript = xajaxCompressJavascript($javaScript);
851                         $fH = @fopen($realJsFile, "w");
852                         if (!$fH) {
853                                 trigger_error("The xajax compressed javascript file could not be written in the <b>" . dirname($realJsFile) . "</b> folder. Error ", E_USER_ERROR);
854                         }
855                         else {
856                                 fwrite($fH, $compressedScript);
857                                 fclose($fH);
858                         }
859                 }
860         }
861        
862         /**
863          * Returns the current URL based upon the SERVER vars.
864          *
865          * @access private
866          * @return string
867          */
868         function _detectURI() {
869                 $aURL = array();
870
871                 // Try to get the request URL
872                 if (!empty($_SERVER['REQUEST_URI'])) {
873                         $aURL = parse_url($_SERVER['REQUEST_URI']);
874                 }
875
876                 // Fill in the empty values
877                 if (empty($aURL['scheme'])) {