3
* OO AJAX Implementation for PHP
5
* SVN Rev: $Id: AJAX.php,v 1.1.2.1 2008/10/03 07:09:50 nicolasconnault Exp $
9
* @author Joshua Eichorn <josh@bluga.net>
10
* @author Arpad Ray <arpad@php.net>
11
* @author David Coallier <davidc@php.net>
12
* @author Elizabeth Smith <auroraeosrose@gmail.com>
13
* @copyright 2005-2008 Joshua Eichorn, Arpad Ray, David Coallier, Elizabeth Smith
14
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
15
* @version Release: 0.5.6
16
* @link http://pear.php.net/package/HTML_AJAX
20
* This is a quick hack, loading serializers as needed doesn't work in php5
22
require_once "HTML/AJAX/Serializer/JSON.php";
23
require_once "HTML/AJAX/Serializer/Null.php";
24
require_once "HTML/AJAX/Serializer/Error.php";
25
require_once "HTML/AJAX/Serializer/XML.php";
26
require_once "HTML/AJAX/Serializer/PHP.php";
27
require_once 'HTML/AJAX/Debug.php';
30
* OO AJAX Implementation for PHP
34
* @author Joshua Eichorn <josh@bluga.net>
35
* @author Arpad Ray <arpad@php.net>
36
* @author David Coallier <davidc@php.net>
37
* @author Elizabeth Smith <auroraeosrose@gmail.com>
38
* @copyright 2005-2008 Joshua Eichorn, Arpad Ray, David Coallier, Elizabeth Smith
39
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
40
* @version Release: 0.5.6
41
* @link http://pear.php.net/package/HTML_AJAX
46
* An array holding the instances were exporting
48
* key is the exported name
52
* array('className'=>'','exportedName'=>'','instance'=>'','exportedMethods=>'')
58
var $_exportedInstances = array();
61
* Set the server url in the generated stubs to this value
62
* If set to false, serverUrl will not be set
65
var $serverUrl = false;
68
* What encoding your going to use for serializing data
69
* from php being sent to javascript.
71
* @var string JSON|PHP|Null
73
var $serializer = 'JSON';
76
* What encoding your going to use for unserializing data sent from javascript
77
* @var string JSON|PHP|Null
79
var $unserializer = 'JSON';
82
* Option to use loose typing for JSON encoding
86
var $jsonLooseType = true;
91
* Used in to automatically choose serializers as needed
93
var $contentTypeMap = array(
94
'JSON' => 'application/json',
95
'XML' => 'application/xml',
96
'Null' => 'text/plain',
97
'Error' => 'application/error',
98
'PHP' => 'application/php-serialized',
99
'Urlencoded' => 'application/x-www-form-urlencoded'
103
* This is the debug variable that we will be passing the
104
* HTML_AJAX_Debug instance to.
106
* @param object HTML_AJAX_Debug
111
* This is to tell if debug is enabled or not. If so, then
112
* debug is called, instantiated then saves the file and such.
114
var $debugEnabled = false;
117
* This puts the error into a session variable is set to true.
118
* set to false by default.
122
var $debugSession = false;
125
* Boolean telling if the Content-Length header should be sent.
127
* If your using a gzip handler on an output buffer, or run into
128
* any compatability problems, try disabling this.
133
var $sendContentLength = true;
136
* Make Generated code compatible with php4 by lowercasing all
137
* class/method names before exporting to JavaScript.
139
* If you have code that works on php4 but not on php5 then setting
140
* this flag can fix the problem. The recommended solution is too
141
* specify the class and method names when registering the class
142
* letting you have function case in php4 as well
147
var $php4CompatCase = false;
150
* Automatically pack all generated JavaScript making it smaller
152
* If your using output compression this might not make sense
154
var $packJavaScript = false;
157
* Holds current payload info
165
* Holds iframe id IF this is an iframe xmlhttprequest
173
* Holds the list of classes permitted to be unserialized
178
var $_allowedClasses = array();
181
* Holds serializer instances
183
var $_serializers = array();
186
* PHP callbacks we're exporting
188
var $_validCallbacks = array();
191
* Interceptor instance
193
var $_interceptor = false;
196
* Set a class to handle requests
198
* @param object &$instance An instance to export
199
* @param mixed $exportedName Name used for the javascript class,
200
* if false the name of the php class is used
201
* @param mixed $exportedMethods If false all functions without a _ prefix
202
* are exported, if an array only the methods
203
* listed in the array are exported
207
function registerClass(&$instance, $exportedName = false,
208
$exportedMethods = false)
210
$className = strtolower(get_class($instance));
212
if ($exportedName === false) {
213
$exportedName = get_class($instance);
214
if ($this->php4CompatCase) {
215
$exportedName = strtolower($exportedName);
219
if ($exportedMethods === false) {
220
$exportedMethods = $this->_getMethodsToExport($className);
224
$index = strtolower($exportedName);
225
$this->_exportedInstances[$index] = array();
226
$this->_exportedInstances[$index]['className'] = $className;
227
$this->_exportedInstances[$index]['exportedName'] = $exportedName;
228
$this->_exportedInstances[$index]['instance'] =& $instance;
229
$this->_exportedInstances[$index]['exportedMethods'] = $exportedMethods;
233
* Get a list of methods in a class to export
235
* This function uses get_class_methods to get a list of callable methods,
236
* so if you're on PHP5 extending this class with a class you want to export
237
* should export its protected methods, while normally only its public methods
238
* would be exported. All methods starting with _ are removed from the export list.
239
* This covers PHP4 style private by naming as well as magic methods in either PHP4 or PHP5
241
* @param string $className Name of the class
243
* @return array all methods of the class that are public
246
function _getMethodsToExport($className)
248
$funcs = get_class_methods($className);
250
foreach ($funcs as $key => $func) {
251
if (strtolower($func) === $className || substr($func, 0, 1) === '_') {
253
} else if ($this->php4CompatCase) {
254
$funcs[$key] = strtolower($func);
261
* Generate the client Javascript code
263
* @return string generated javascript client code
265
function generateJavaScriptClient()
269
$names = array_keys($this->_exportedInstances);
270
foreach ($names as $name) {
271
$client .= $this->generateClassStub($name);
277
* Return the stub for a class
279
* @param string $name name of the class to generated the stub for,
280
* note that this is the exported name not the php class name
282
* @return string javascript proxy stub code for a single class
284
function generateClassStub($name)
286
if (!isset($this->_exportedInstances[$name])) {
290
$client = "// Client stub for the {$this->_exportedInstances[$name]['exportedName']} PHP Class\n";
291
$client .= "function {$this->_exportedInstances[$name]['exportedName']}(callback) {\n";
292
$client .= "\tmode = 'sync';\n";
293
$client .= "\tif (callback) { mode = 'async'; }\n";
294
$client .= "\tthis.className = '{$this->_exportedInstances[$name]['exportedName']}';\n";
295
if ($this->serverUrl) {
296
$client .= "\tthis.dispatcher = new HTML_AJAX_Dispatcher(this.className,mode,callback,'{$this->serverUrl}','{$this->unserializer}');\n}\n";
298
$client .= "\tthis.dispatcher = new HTML_AJAX_Dispatcher(this.className,mode,callback,false,'{$this->unserializer}');\n}\n";
300
$client .= "{$this->_exportedInstances[$name]['exportedName']}.prototype = {\n";
301
$client .= "\tSync: function() { this.dispatcher.Sync(); }, \n";
302
$client .= "\tAsync: function(callback) { this.dispatcher.Async(callback); },\n";
303
foreach ($this->_exportedInstances[$name]['exportedMethods'] as $method) {
304
$client .= $this->_generateMethodStub($method);
306
$client = substr($client, 0, (strlen($client)-2))."\n";
309
if ($this->packJavaScript) {
310
$client = $this->packJavaScript($client);
316
* Returns a methods stub
318
* @param string $method the method name
320
* @return string the js code
323
function _generateMethodStub($method)
325
$stub = "\t{$method}: function() { return ".
326
"this.dispatcher.doCall('{$method}',arguments); },\n";
331
* Populates the current payload
333
* @return string the js code
336
function populatePayload()
338
if (isset($_REQUEST['Iframe_XHR'])) {
339
$this->_iframe = $_REQUEST['Iframe_XHR_id'];
340
if (isset($_REQUEST['Iframe_XHR_headers']) &&
341
is_array($_REQUEST['Iframe_XHR_headers'])) {
342
foreach ($_REQUEST['Iframe_XHR_headers'] as $header) {
344
$array = explode(':', $header);
345
$array[0] = strip_tags(strtoupper(str_replace('-', '_', $array[0])));
346
//only content-length and content-type can go in without an
347
//http_ prefix - security
348
if (strpos($array[0], 'HTTP_') !== 0
349
&& strcmp('CONTENT_TYPE', $array[0])
350
&& strcmp('CONTENT_LENGTH', $array[0])) {
351
$array[0] = 'HTTP_' . $array[0];
353
$_SERVER[$array[0]] = strip_tags($array[1]);
356
$this->_payload = (isset($_REQUEST['Iframe_XHR_data'])
357
? $_REQUEST['Iframe_XHR_data'] : '');
359
if (isset($_REQUEST['Iframe_XHR_method'])) {
360
$_GET['m'] = $_REQUEST['Iframe_XHR_method'];
362
if (isset($_REQUEST['Iframe_XHR_class'])) {
363
$_GET['c'] = $_REQUEST['Iframe_XHR_class'];
369
* Handle a ajax request if needed
371
* The current check is if GET variables c (class) and m (method) are set,
372
* more options may be available in the future
374
* @return boolean true if an ajax call was handled, false otherwise
376
function handleRequest()
378
set_error_handler(array(&$this,'_errorHandler'));
379
if (function_exists('set_exception_handler')) {
380
set_exception_handler(array(&$this,'_exceptionHandler'));
382
if (isset($_GET['px'])) {
383
if ($this->_iframeGrabProxy()) {
384
restore_error_handler();
385
if (function_exists('restore_exception_handler')) {
386
restore_exception_handler();
392
$class = strtolower($this->_getVar('c'));
393
$method = $this->_getVar('m');
394
$phpCallback = $this->_getVar('cb');
397
if (!empty($class) && !empty($method)) {
398
if (!isset($this->_exportedInstances[$class])) {
400
trigger_error('Unknown class: '. $class);
402
if (!in_array(($this->php4CompatCase ? strtolower($method) : $method),
403
$this->_exportedInstances[$class]['exportedMethods'])) {
405
trigger_error('Unknown method: ' . $method);
407
} else if (!empty($phpCallback)) {
408
if (strpos($phpCallback, '.') !== false) {
409
$phpCallback = explode('.', $phpCallback);
411
if (!$this->_validatePhpCallback($phpCallback)) {
412
restore_error_handler();
413
if (function_exists('restore_exception_handler')) {
414
restore_exception_handler();
419
restore_error_handler();
420
if (function_exists('restore_exception_handler')) {
421
restore_exception_handler();
426
// auto-detect serializer to use from content-type
427
$type = $this->unserializer;
428
$key = array_search($this->_getClientPayloadContentType(),
429
$this->contentTypeMap);
433
$unserializer = $this->_getSerializer($type);
435
$args = $unserializer->unserialize($this->_getClientPayload(), $this->_allowedClasses);
436
if (!is_array($args)) {
437
$args = array($args);
440
if ($this->_interceptor !== false) {
441
$args = $this->_processInterceptor($class, $method, $phpCallback, $args);
444
if (empty($phpCallback)) {
445
$ret = call_user_func_array(array(&$this->_exportedInstances[$class]['instance'], $method), $args);
447
$ret = call_user_func_array($phpCallback, $args);
450
restore_error_handler();
451
$this->_sendResponse($ret);
456
* Determines the content type of the client payload
459
* a MIME content type
461
function _getClientPayloadContentType()
463
//OPERA IS STUPID FIX
464
if (isset($_SERVER['HTTP_X_CONTENT_TYPE'])) {
465
$type = $this->_getServer('HTTP_X_CONTENT_TYPE');
466
$pos = strpos($type, ';');
468
return strtolower($pos ? substr($type, 0, $pos) : $type);
469
} else if (isset($_SERVER['CONTENT_TYPE'])) {
470
$type = $this->_getServer('CONTENT_TYPE');
471
$pos = strpos($type, ';');
473
return strtolower($pos ? substr($type, 0, $pos) : $type);
479
* Send a reponse adding needed headers and serializing content
481
* Note: this method echo's output as well as setting headers to prevent caching
482
* Iframe Detection: if this has been detected as an iframe response, it has to
483
* be wrapped in different code and headers changed (quite a mess)
485
* @param mixed $response content to serialize and send
490
function _sendResponse($response)
492
if (is_object($response) && is_a($response, 'HTML_AJAX_Response')) {
493
$output = $response->getPayload();
494
$content = $response->getContentType();
496
} elseif (is_a($response, 'PEAR_Error')) {
497
$serializer = $this->_getSerializer('Error');
498
$output = $serializer->serialize(array(
499
'message' => $response->getMessage(),
500
'userinfo' => $response->getUserInfo(),
501
'code' => $response->getCode(),
502
'mode' => $response->getMode()
504
$content = $this->contentTypeMap['Error'];
507
$serializer = $this->_getSerializer($this->serializer);
508
$output = $serializer->serialize($response);
510
$serializerType = $this->serializer;
511
// let a serializer change its output type
512
if (isset($serializer->serializerNewType)) {
513
$serializerType = $serializer->serializerNewType;
516
if (isset($this->contentTypeMap[$serializerType])) {
517
$content = $this->contentTypeMap[$serializerType];
520
// headers to force things not to be cached:
522
//OPERA IS STUPID FIX
523
if (isset($_SERVER['HTTP_X_CONTENT_TYPE'])) {
524
$headers['X-Content-Type'] = $content;
525
$content = 'text/plain';
528
if ($this->_sendContentLength()) {
529
$headers['Content-Length'] = strlen($output);
532
$headers['Expires'] = 'Mon, 26 Jul 1997 05:00:00 GMT';
533
$headers['Last-Modified'] = gmdate("D, d M Y H:i:s").'GMT';
534
$headers['Cache-Control'] = 'no-cache, must-revalidate';
535
$headers['Pragma'] = 'no-cache';
536
$headers['Content-Type'] = $content.'; charset=utf-8';
538
//intercept to wrap iframe return data
539
if ($this->_iframe) {
540
$output = $this->_iframeWrapper($this->_iframe,
542
$headers['Content-Type'] = 'text/html; charset=utf-8';
545
$this->_sendHeaders($headers);
550
* Decide if we should send a Content-length header
552
* @return bool true if it's ok to send the header, false otherwise
555
function _sendContentLength()
557
if (!$this->sendContentLength) {
560
$ini_tests = array( "output_handler",
561
"zlib.output_compression",
562
"zlib.output_handler");
563
foreach ($ini_tests as $test) {
564
if (ini_get($test)) {
568
return (ob_get_level() <= 0);
572
* Actually send a list of headers
574
* @param array $array list of headers to send
579
function _sendHeaders($array)
581
foreach ($array as $header => $value) {
582
header($header . ': ' . $value);
587
* Get an instance of a serializer class
589
* @param string $type Last part of the class name
592
* @return HTML_AJAX_Serializer
594
function _getSerializer($type)
596
if (isset($this->_serializers[$type])) {
597
return $this->_serializers[$type];
600
$class = 'HTML_AJAX_Serializer_'.$type;
602
if ( (version_compare(phpversion(), 5, '>') && !class_exists($class, false))
603
|| (version_compare(phpversion(), 5, '<') && !class_exists($class)) ) {
604
// include the class only if it isn't defined
605
include_once "HTML/AJAX/Serializer/{$type}.php";
608
//handle JSON loose typing option for associative arrays
609
if ($type == 'JSON') {
610
$this->_serializers[$type] = new $class($this->jsonLooseType);
612
$this->_serializers[$type] = new $class();
614
return $this->_serializers[$type];
618
* Get payload in its submitted form, currently only supports raw post
621
* @return string raw post data
623
function _getClientPayload()
625
if (empty($this->_payload)) {
626
if (isset($GLOBALS['HTTP_RAW_POST_DATA'])) {
627
$this->_payload = $GLOBALS['HTTP_RAW_POST_DATA'];
628
} else if (function_exists('file_get_contents')) {
629
// both file_get_contents() and php://input require PHP >= 4.3.0
630
$this->_payload = file_get_contents('php://input');
632
$this->_payload = '';
635
return $this->_payload;
639
* stub for getting get vars - applies strip_tags
641
* @param string $var variable to get
644
* @return string filtered _GET value
646
function _getVar($var)
648
if (!isset($_GET[$var])) {
651
return strip_tags($_GET[$var]);
656
* stub for getting server vars - applies strip_tags
658
* @param string $var variable to get
661
* @return string filtered _GET value
663
function _getServer($var)
665
if (!isset($_SERVER[$var])) {
668
return strip_tags($_SERVER[$var]);
673
* Exception handler, passes them to _errorHandler to do the actual work
675
* @param Exception $ex Exception to be handled
680
function _exceptionHandler($ex)
682
$this->_errorHandler($ex->getCode(), $ex->getMessage(), $ex->getFile(), $ex->getLine());
687
* Error handler that sends it errors to the client side
689
* @param int $errno Error number
690
* @param string $errstr Error string
691
* @param string $errfile Error file
692
* @param string $errline Error line
697
function _errorHandler($errno, $errstr, $errfile, $errline)
699
if ($errno & error_reporting()) {
702
$e->errStr = $errstr;
703
$e->errFile = $errfile;
704
$e->errLine = $errline;
707
$this->serializer = 'Error';
708
$this->_sendResponse($e);
709
if ($this->debugEnabled) {
710
$this->debug = new HTML_AJAX_Debug($errstr, $errline, $errno, $errfile);
711
if ($this->debugSession) {
712
$this->debug->sessionError();
714
$this->debug->_saveError();
721
* Creates html to wrap serialized info for iframe xmlhttprequest fakeout
723
* @param string $id iframe instance id
724
* @param string $data data to pass
725
* @param string $headers headers to pass
728
* @return string html page with iframe passing code
730
function _iframeWrapper($id, $data, $headers = array())
732
$string = '<html><script type="text/javascript">'."\n".
733
'var Iframe_XHR_headers = new Object();';
735
foreach ($headers as $label => $value) {
736
$string .= 'Iframe_XHR_headers["'.preg_replace("/\r?\n/", "\\n",
737
addslashes($label)).'"] = "'.preg_replace("/\r?\n/", "\\n",
738
addslashes($value))."\";\n";
740
$string .= 'var Iframe_XHR_data = "' . preg_replace("/\r?\n/", "\\n",
741
addslashes($data)) . '";</script>'
742
. '<body onload="parent.HTML_AJAX_IframeXHR_instances[\''.$id.'\']'
743
. '.isLoaded(Iframe_XHR_headers, Iframe_XHR_data);"></body></html>';
748
* Handles a proxied grab request
750
* @return bool true to end the response, false to continue trying to handle it
753
function _iframeGrabProxy()
755
if (!isset($_REQUEST['Iframe_XHR_id'])) {
756
trigger_error('Invalid iframe ID');
759
$this->_iframe = $_REQUEST['Iframe_XHR_id'];
760
$this->_payload = (isset($_REQUEST['Iframe_XHR_data']) ? $_REQUEST['Iframe_XHR_data'] : '');
761
$url = urldecode($_GET['px']);
762
$url_parts = parse_url($url);
763
$urlregex = '#^https?://#i';
765
if (!preg_match($urlregex, $url) || $url_parts['host'] != $_SERVER['HTTP_HOST']) {
766
trigger_error('Invalid URL for grab proxy');
769
$method = (isset($_REQUEST['Iframe_XHR_HTTP_method'])
770
? strtoupper($_REQUEST['Iframe_XHR_HTTP_method'])
773
if ($method != 'GET' && $method != 'POST') {
774
trigger_error('Invalid grab URL');
779
if (isset($_REQUEST['Iframe_XHR_headers'])) {
780
foreach ($_REQUEST['Iframe_XHR_headers'] as $header) {
781
if (strpos($header, "\r") !== false
782
|| strpos($header, "\n") !== false) {
783
trigger_error('Invalid grab header');
786
$headers .= $header . "\r\n";
789
// tries to make request with file_get_contents()
790
if (ini_get('allow_url_fopen') && version_compare(phpversion(), '5.0.0'. '>=')) {
792
$url_parts['scheme'] => array(
794
'headers' => $headers,
795
'content' => $this->_payload
798
$ret = @file_get_contents($url, false, stream_context_create($opts));
800
$this->_sendResponse($ret);
804
// tries to make request using the curl extension
805
if (function_exists('curl_setopt')) {
807
curl_setopt($ch, CURLOPT_URL, $url);
808
curl_setopt($ch, CURLOPT_HEADER, $headers);
809
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
810
$ret = curl_exec($ch);
811
if ($ret !== false) {
813
$this->_sendResponse($ret);
817
if (isset($url_parts['port'])) {
818
$port = $url_parts['port'];
820
$port = getservbyname(strtolower($url_parts['scheme']), 'tcp');
821
if ($port === false) {
822
trigger_error('Grab proxy: Unknown port or service, defaulting to 80', E_USER_WARNING);
826
if (!isset($url_parts['path'])) {
827
$url_parts['path'] = '/';
829
if (!empty($url_parts['query'])) {
830
$url_parts['path'] .= '?' . $url_parts['query'];
832
$request = "$method {$url_parts['path']} HTTP/1.0\r\n"
833
. "Host: {$url['host']}\r\n"
834
. "Connection: close\r\n"
836
// tries to make request using the socket functions
837
$fp = fsockopen($_SERVER['HTTP_HOST'], $port, $errno, $errstr, 4);
839
fputs($fp, $request);
842
$done_headers = false;
845
$ret .= fgets($fp, 2048);
846
if ($done_headers || ($contentpos = strpos($ret, "\r\n\r\n")) === false) {
849
$done_headers = true;
850
$ret = substr($ret, $contentpos + 4);
853
$this->_sendResponse($ret);
856
// tries to make the request using the socket extension
857
$host = gethostbyname($url['host']);
858
if (($socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) < 0
859
|| ($connected = socket_connect($socket, $host, $port)) < 0
860
|| ($written = socket_write($socket, $request)) < strlen($request)) {
861
trigger_error('Grab proxy failed: ' . socket_strerror($socket));
866
$done_headers = false;
868
while ($out = socket_read($socket, 2048)) {
870
if ($done_headers || ($contentpos = strpos($ret, "\r\n\r\n")) === false) {
873
$done_headers = true;
874
$ret = substr($ret, $contentpos + 4);
876
socket_close($socket);
877
$this->_sendResponse($ret);
882
* Add a class or classes to those allowed to be unserialized
884
* @param mixed $classes the class or array of classes to add
889
function addAllowedClasses($classes)
891
if (!is_array($classes)) {
892
$this->_allowedClasses[] = $classes;
894
$this->_allowedClasses = array_merge($this->_allowedClasses, $classes);
896
$this->_allowedClasses = array_unique($this->_allowedClasses);
900
* Checks that the given callback is callable and allowed to be called
902
* @param callback $callback the callback to check
904
* @return bool true if the callback is valid, false otherwise
907
function _validatePhpCallback($callback)
909
if (!is_callable($callback)) {
912
$sig = md5(serialize($callback));
913
return isset($this->_validCallbacks[$sig]);
917
* Register a callback so it may be called from JS
919
* @param callback $callback the callback to register
924
function registerPhpCallback($callback)
926
$this->_validCallbacks[md5(serialize($callback))] = 1;
930
* Make JavaScript code smaller
932
* Currently just strips whitespace and comments, needs to remain fast
933
* Strips comments only if they are not preceeded by code
934
* Strips /*-style comments only if they span over more than one line
935
* Since strings cannot span over multiple lines, it cannot be defeated by a
936
* string containing /*
938
* @param string $input Javascript to pack
941
* @return string packed javascript
943
function packJavaScript($input)
949
$blockStart = '/^\s*\/\/\*/';
950
$blockEnd = '/\*\/\s*(.*)$/';
951
$inlineComment = '/\/\*.*\*\//';
954
$lines = explode("\n", $input);
956
foreach ($lines as $line) {
959
if (preg_match($blockEnd, $line)) {
961
$line = preg_match($blockEnd, '$1', $line);
962
$keep = strlen($line) > 0;
964
} elseif (preg_match($inlineComment, $line)) {
966
} elseif (preg_match($blockStart, $line)) {
972
foreach ($stripPregs as $preg) {
973
if (preg_match($preg, $line)) {
980
if ($keep && !$inblock) {
981
$out .= trim($line)."\n";
983
/* Enable to see what your striping out
993
* Set an interceptor class
995
* An interceptor class runs during the process of handling a request,
996
* it allows you to run security checks globally. It also allows you to
999
* You can throw errors and exceptions in your intercptor methods and
1000
* they will be passed to javascript
1002
* You can add interceptors are 3 levels
1003
* For a particular class/method, this is done by add a method to you class
1004
* named ClassName_MethodName($params)
1005
* For a particular class, method ClassName($methodName,$params)
1006
* Globally, method intercept($className,$methodName,$params)
1008
* Only one match is done, using the most specific interceptor
1010
* All methods have to return $params, if you want to empty all of the
1011
* parameters return an empty array
1013
* @param Object $instance an instance of you interceptor class
1015
* @todo handle php callbacks
1019
function setInterceptor($instance)
1021
$this->_interceptor = $instance;
1025
* Attempt to intercept a call
1027
* @param string $className Class Name
1028
* @param string $methodName Method Name
1029
* @param string $callback Not implemented
1030
* @param array $params Array of parameters to pass to the interceptor
1032
* @todo handle php callbacks
1034
* @return array Updated params
1036
function _processInterceptor($className,$methodName,$callback,$params)
1039
$m = $className.'_'.$methodName;
1040
if (method_exists($this->_interceptor, $m)) {
1041
return $this->_interceptor->$m($params);
1045
if (method_exists($this->_interceptor, $m)) {
1046
return $this->_interceptor->$m($methodName, $params);
1050
if (method_exists($this->_interceptor, $m)) {
1051
return $this->_interceptor->$m($className, $methodName, $params);
1059
* PHP 4 compat function for interface/class exists
1061
* @param string $class Class name
1062
* @param bool $autoload Should the autoloader be called
1067
function HTML_AJAX_Class_exists($class, $autoload)
1069
if (function_exists('interface_exists')) {
1070
return class_exists($class, $autoload);
1072
return class_exists($class);
1075
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */