source: trunk/workflow/inc/report/xajax/xajax.inc.php @ 7655

Revision 7655, 36.8 KB checked in by douglasz, 11 years ago (diff)

Ticket #3236 - Melhorias de performance no codigo do Expresso.

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 */
48if (!defined ('XAJAX_DEFAULT_CHAR_ENCODING'))
49{
50        define ('XAJAX_DEFAULT_CHAR_ENCODING', 'iso-8859-1' );
51}
52
53require_once(dirname(__FILE__)."/xajaxResponse.inc.php");
54
55/**
56 * Communication Method Defines
57 */
58if (!defined ('XAJAX_GET'))
59{
60        define ('XAJAX_GET', 0);
61}
62if (!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 */
75class 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'])) {
878                        if (!empty($_SERVER['HTTP_SCHEME'])) {
879                                $aURL['scheme'] = $_SERVER['HTTP_SCHEME'];
880                        } else {
881                                $aURL['scheme'] = (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) != 'off') ? 'https' : 'http';
882                        }
883                }
884
885                if (empty($aURL['host'])) {
886                        if (!empty($_SERVER['HTTP_HOST'])) {
887                                if (strpos($_SERVER['HTTP_HOST'], ':') > 0) {
888                                        list($aURL['host'], $aURL['port']) = explode(':', $_SERVER['HTTP_HOST']);
889                                } else {
890                                        $aURL['host'] = $_SERVER['HTTP_HOST'];
891                                }
892                        } else if (!empty($_SERVER['SERVER_NAME'])) {
893                                $aURL['host'] = $_SERVER['SERVER_NAME'];
894                        } else {
895                                print "xajax Error: xajax failed to automatically identify your Request URI.";
896                                print "Please set the Request URI explicitly when you instantiate the xajax object.";
897                                exit();
898                        }
899                }
900
901                if (empty($aURL['port']) && !empty($_SERVER['SERVER_PORT'])) {
902                        $aURL['port'] = $_SERVER['SERVER_PORT'];
903                }
904
905                if (empty($aURL['path'])) {
906                        if (!empty($_SERVER['PATH_INFO'])) {
907                                $sPath = parse_url($_SERVER['PATH_INFO']);
908                        } else {
909                                $sPath = parse_url($_SERVER['PHP_SELF']);
910                        }
911                        $aURL['path'] = $sPath['path'];
912                        unset($sPath);
913                }
914
915                if (!empty($aURL['query'])) {
916                        $aURL['query'] = '?'.$aURL['query'];
917                }
918
919                // Build the URL: Start with scheme, user and pass
920                $sURL = $aURL['scheme'].'://';
921                if (!empty($aURL['user'])) {
922                        $sURL.= $aURL['user'];
923                        if (!empty($aURL['pass'])) {
924                                $sURL.= ':'.$aURL['pass'];
925                        }
926                        $sURL.= '@';
927                }
928
929                // Add the host
930                $sURL.= $aURL['host'];
931
932                // Add the port if needed
933                if (!empty($aURL['port']) && (($aURL['scheme'] == 'http' && $aURL['port'] != 80) || ($aURL['scheme'] == 'https' && $aURL['port'] != 443))) {
934                        $sURL.= ':'.$aURL['port'];
935                }
936
937                // Add the path and the query string
938                $sURL.= $aURL['path'].@$aURL['query'];
939
940                // Clean up
941                unset($aURL);
942                return $sURL;
943        }
944       
945        /**
946         * Returns true if the function name is associated with an object callback,
947         * false if not.
948         *
949         * @param string the name of the function
950         * @access private
951         * @return boolean
952         */
953        function _isObjectCallback($sFunction)
954        {
955                if (array_key_exists($sFunction, $this->aObjects)) return true;
956                return false;
957        }
958       
959        /**
960         * Returns true if the function or object callback can be called, false if
961         * not.
962         *
963         * @param string the name of the function
964         * @access private
965         * @return boolean
966         */
967        function _isFunctionCallable($sFunction)
968        {
969                if ($this->_isObjectCallback($sFunction)) {
970                        if (is_object($this->aObjects[$sFunction][0])) {
971                                return method_exists($this->aObjects[$sFunction][0], $this->aObjects[$sFunction][1]);
972                        }
973                        else {
974                                return is_callable($this->aObjects[$sFunction]);
975                        }
976                }
977                else {
978                        return function_exists($sFunction);
979                }       
980        }
981       
982        /**
983         * Calls the function, class method, or object method with the supplied
984         * arguments.
985         *
986         * @param string the name of the function
987         * @param array  arguments to pass to the function
988         * @access private
989         * @return mixed the output of the called function or method
990         */
991        function _callFunction($sFunction, $aArgs)
992        {
993                if ($this->_isObjectCallback($sFunction)) {
994                        $mReturn = call_user_func_array($this->aObjects[$sFunction], $aArgs);
995                }
996                else {
997                        $mReturn = call_user_func_array($sFunction, $aArgs);
998                }
999                return $mReturn;
1000        }
1001       
1002        /**
1003         * Generates the Javascript wrapper for the specified PHP function.
1004         *
1005         * @param string the name of the function
1006         * @param mixed  the request type
1007         * @access private
1008         * @return string
1009         */
1010        function _wrap($sFunction,$sRequestType=XAJAX_POST)
1011        {
1012                $js = "function ".$this->sWrapperPrefix."$sFunction(){return xajax.call(\"$sFunction\", arguments, ".$sRequestType.");}\n";             
1013                return $js;
1014        }
1015
1016        /**
1017         * Takes a string containing xajax xjxobj XML or xjxquery XML and builds an
1018         * array representation of it to pass as an argument to the PHP function
1019         * being called.
1020         *
1021         * @param string the root tag of the XML
1022         * @param string XML to convert
1023         * @access private
1024         * @return array
1025         */
1026        function _xmlToArray($rootTag, $sXml)
1027        {
1028                $aArray = array();
1029                $sXml = str_replace("<$rootTag>","<$rootTag>|~|",$sXml);
1030                $sXml = str_replace("</$rootTag>","</$rootTag>|~|",$sXml);
1031                $sXml = str_replace("<e>","<e>|~|",$sXml);
1032                $sXml = str_replace("</e>","</e>|~|",$sXml);
1033                $sXml = str_replace("<k>","<k>|~|",$sXml);
1034                $sXml = str_replace("</k>","|~|</k>|~|",$sXml);
1035                $sXml = str_replace("<v>","<v>|~|",$sXml);
1036                $sXml = str_replace("</v>","|~|</v>|~|",$sXml);
1037                $sXml = str_replace("<q>","<q>|~|",$sXml);
1038                $sXml = str_replace("</q>","|~|</q>|~|",$sXml);
1039               
1040                $this->aObjArray = explode("|~|",$sXml);
1041               
1042                $this->iPos = 0;
1043                $aArray = $this->_parseObjXml($rootTag);
1044       
1045                return $aArray;
1046        }
1047       
1048        /**
1049         * A recursive function that generates an array from the contents of
1050         * $this->aObjArray.
1051         *
1052         * @param string the root tag of the XML
1053         * @access private
1054         * @return array
1055         */
1056        function _parseObjXml($rootTag)
1057        {
1058                $aArray = array();
1059               
1060                if ($rootTag == "xjxobj")
1061                {
1062                        while(!stristr($this->aObjArray[$this->iPos],"</xjxobj>"))
1063                        {
1064                                $this->iPos++;
1065                                if(stristr($this->aObjArray[$this->iPos],"<e>"))
1066                                {
1067                                        $key = "";
1068                                        $value = null;
1069                                               
1070                                        $this->iPos++;
1071                                        while(!stristr($this->aObjArray[$this->iPos],"</e>"))
1072                                        {
1073                                                if(stristr($this->aObjArray[$this->iPos],"<k>"))
1074                                                {
1075                                                        $this->iPos++;
1076                                                        while(!stristr($this->aObjArray[$this->iPos],"</k>"))
1077                                                        {
1078                                                                $key .= $this->aObjArray[$this->iPos];
1079                                                                $this->iPos++;
1080                                                        }
1081                                                }
1082                                                if(stristr($this->aObjArray[$this->iPos],"<v>"))
1083                                                {
1084                                                        $this->iPos++;
1085                                                        while(!stristr($this->aObjArray[$this->iPos],"</v>"))
1086                                                        {
1087                                                                if(stristr($this->aObjArray[$this->iPos],"<xjxobj>"))
1088                                                                {
1089                                                                        $value = $this->_parseObjXml("xjxobj");
1090                                                                        $this->iPos++;
1091                                                                }
1092                                                                else
1093                                                                {
1094                                                                        $value .= $this->aObjArray[$this->iPos];
1095                                                                        if ($this->bDecodeUTF8Input)
1096                                                                        {
1097                                                                                $value = $this->_decodeUTF8Data($value);
1098                                                                        }
1099                                                                }
1100                                                                $this->iPos++;
1101                                                        }
1102                                                }
1103                                                $this->iPos++;
1104                                        }
1105                                       
1106                                        $aArray[$key]=$value;
1107                                }
1108                        }
1109                }
1110               
1111                if ($rootTag == "xjxquery")
1112                {
1113                        $sQuery = "";
1114                        $this->iPos++;
1115                        while(!stristr($this->aObjArray[$this->iPos],"</xjxquery>"))
1116                        {
1117                                if (stristr($this->aObjArray[$this->iPos],"<q>") || stristr($this->aObjArray[$this->iPos],"</q>"))
1118                                {
1119                                        $this->iPos++;
1120                                        continue;
1121                                }
1122                                $sQuery .= $this->aObjArray[$this->iPos];
1123                                $this->iPos++;
1124                        }
1125                       
1126                        parse_str($sQuery, $aArray);
1127                        if ($this->bDecodeUTF8Input)
1128                        {
1129                                foreach($aArray as $key => $value)
1130                                {
1131                                        $aArray[$key] = $this->_decodeUTF8Data($value);
1132                                }
1133                        }
1134                        // If magic quotes is on, then we need to strip the slashes from the
1135                        // array values because of the parse_str pass which adds slashes
1136                        if (get_magic_quotes_gpc() == 1) {
1137                                $newArray = array();
1138                                foreach ($aArray as $sKey => $sValue) {
1139                                        if (is_string($sValue))
1140                                                $newArray[$sKey] = stripslashes($sValue);
1141                                        else
1142                                                $newArray[$sKey] = $sValue;
1143                                }
1144                                $aArray = $newArray;
1145                        }
1146                }
1147               
1148                return $aArray;
1149        }
1150       
1151        /**
1152         * Decodes string data from UTF-8 to the current xajax encoding.
1153         *
1154         * @param string data to convert
1155         * @access private
1156         * @return string converted data
1157         */
1158        function _decodeUTF8Data($sData)
1159        {
1160                $sValue = $sData;
1161                if ($this->bDecodeUTF8Input)
1162                {
1163                        $sFuncToUse = NULL;
1164                       
1165                        if (function_exists('iconv'))
1166                        {
1167                                $sFuncToUse = "iconv";
1168                        }
1169                        else if (function_exists('mb_convert_encoding'))
1170                        {
1171                                $sFuncToUse = "mb_convert_encoding";
1172                        }
1173                        else if ($this->sEncoding == "ISO-8859-1")
1174                        {
1175                                $sFuncToUse = "utf8_decode";
1176                        }
1177                        else
1178                        {
1179                                trigger_error("The incoming xajax data could not be converted from UTF-8", E_USER_NOTICE);
1180                        }
1181                       
1182                        if ($sFuncToUse)
1183                        {
1184                                if (is_string($sValue))
1185                                {
1186                                        if ($sFuncToUse == "iconv")
1187                                        {
1188                                                $sValue = iconv("UTF-8", $this->sEncoding.'//TRANSLIT', $sValue);
1189                                        }
1190                                        else if ($sFuncToUse == "mb_convert_encoding")
1191                                        {
1192                                                $sValue = mb_convert_encoding($sValue, $this->sEncoding, "UTF-8");
1193                                        }
1194                                        else
1195                                        {
1196                                                $sValue = utf8_decode($sValue);
1197                                        }
1198                                }
1199                        }
1200                }
1201                return $sValue;
1202        }
1203               
1204}// end class xajax
1205
1206/**
1207 * This function is registered with PHP's set_error_handler() function if
1208 * the xajax error handling system is turned on.
1209 */
1210function xajaxErrorHandler($errno, $errstr, $errfile, $errline)
1211{
1212        $errorReporting = error_reporting();
1213        if (($errno & $errorReporting) == 0) return;
1214       
1215        if ($errno == E_NOTICE) {
1216                $errTypeStr = "NOTICE";
1217        }
1218        else if ($errno == E_WARNING) {
1219                $errTypeStr = "WARNING";
1220        }
1221        else if ($errno == E_USER_NOTICE) {
1222                $errTypeStr = "USER NOTICE";
1223        }
1224        else if ($errno == E_USER_WARNING) {
1225                $errTypeStr = "USER WARNING";
1226        }
1227        else if ($errno == E_USER_ERROR) {
1228                $errTypeStr = "USER FATAL ERROR";
1229        }
1230        else if ($errno == E_STRICT) {
1231                return;
1232        }
1233        else {
1234                $errTypeStr = "UNKNOWN: $errno";
1235        }
1236        $GLOBALS['xajaxErrorHandlerText'] .= "\n----\n[$errTypeStr] $errstr\nerror in line $errline of file $errfile";
1237}
1238
1239?>
Note: See TracBrowser for help on using the repository browser.