<?php
/**
* pAJAX - AJAX Requests Implementation
*
* This class provides an implementation to AJAX Requests, using JavaScript <-> PHP languages
*
* @package pAJAX
*
* @author Guilherme Blanco <hide@address.com>
* @copyright Copyright® 2005, PontUKom Corp
*
* @access public
*/
/**
* @global boolean AJAX Module Loaded
*/
if (!defined("CLASS_PAJAX"))
define("CLASS_PAJAX", 1);
// Commom support between PHP versions
$XMLSupport = dirname(__FILE__)."/XMLSupport/xml_domit_include.php";
if (file_exists($XMLSupport)) require_once $XMLSupport;
// Load auxiliar class source
$pAjaxParser = dirname(__FILE__)."/class.pAjaxParser.php";
if (file_exists($pAjaxParser)) require_once $pAjaxParser;
// Removing used variables
unset($XMLSupport, $pAjaxParser);
class pAjax {
/**
* @var array $exportList List of functions/methods that can be accessed
* @access private
*/
var $exportList = array();
/**
* @var boolean $domainProtection Domain Protection Enabled/Disabled
* @access private
*/
var $domainProtection;
/**
* @var boolean $exportProtection Export Protection Enabled/Disabled
* @access private
*/
var $exportProtection;
/**
* Constructor - Generates an pAjax Object
*
* @access public
* @return object $this pAjax
*/
function __construct() {
$this->enableDomainProtection();
$this->disableExportProtection();
} // End of Method pAJAX
/**
* HandleRequest - Parses requests and redirect to correct calls
*
* @access public
* @param string $charset XML Document charset (Default: UTF-8)
* @return void
*/
function handleRequest($charset = "UTF-8") {
// Retrieving the request method
$REQUEST_METHOD = strtoupper($_SERVER['REQUEST_METHOD']);
// Checking if the request is valid
if (!($REQUEST_METHOD == "POST" || ($REQUEST_METHOD == "GET" && isset($_GET['function']))))
return;
// If domain protection is enabled, validate it
if ($this->domainProtection && !$this->isValidDomain()) {
trigger_error("Domain is not valid to execute this script", E_USER_ERROR);
return;
}
$data = pAjaxParser::getCallerArguments($charset);
$func = $data['function'];
$args = $data['arguments'];
// If function export list is enabled, validate it
if ($this->exportProtection && !$this->isValidFunction($func)) {
trigger_error("Function does not exist in export list", E_USER_ERROR);
return;
}
// Set the custom headers for response
header("Content-type: text/xml; charset=".$charset);
if ($REQUEST_METHOD == "GET") {
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
}
// Effectively execute the function/method call
ob_start();
echo pAjaxParser::generateXmlResponse($this->execCall($func, $args), $charset);
ob_end_flush();
// Terminate the script
exit;
// Should never be excuted, but if, throw an error
trigger_error("Unexpected behavior executing RPC call", E_USER_ERROR);
}
/**
* ShowJavaScript - Get the Ajax JavaScript Code Part
*
* @access public
* @param $baseDir Path of JavaScript files (Default: "." - same directory)
* @return void
*/
function showJavaScript($baseDir = ".") {
ob_start();
echo "<script type=\"text/javascript\" src=\"{$baseDir}/pajax-commom.js\"></script>\n";
echo "<script type=\"text/javascript\" src=\"{$baseDir}/pajax-parser.js\"></script>\n";
echo "<script type=\"text/javascript\" src=\"{$baseDir}/pajax-core.js\"></script>\n";
ob_end_flush();
}
/**
* ExecCall - Effectively execute the call and get its return
*
* @access private
* @param string $function Function/Method do be called
* @param array $arguments Arguments to be passed to the function/method call
* @return array $data Array containing the function to be called and the arguments
*/
function execCall($function, $arguments) {
if (is_array($arguments) && count($arguments) == 1) {
$keys = array_keys($arguments);
$arguments = $arguments[$keys[0]];
}
if ($function == "") {
// [TODO]
} elseif (strpos($function, ".") === false) {
// Calling a procedure/function
$result = call_user_func_array($function, $arguments);
} else {
// Calling a method inside an object
$arrObjects = explode(".", $function);
$numObjects = count($arrObjects) - 1;
$object = null;
// Find the object (or sub-object)
for ($i = 0; $i < $numObjects; $i++) {
$object = (is_object($object)) ? $object->$arrObjects[$i] : $GLOBALS[$arrObjects[$i]];
}
$method = $arrObjects[$numObjects];
$result = call_user_func_array(array(&$object, $method), $arguments);
}
return $result;
}
/**
* IsValidDomain - Checks is the request domain is the same than the server
*
* @access private
* @return boolean Domain valid/not valid
*/
function isValidDomain() {
if (isset($_SERVER['HTTP_REFERER'])) {
if (eregi("(http:\/\/)?([^\/]*)\/(.*)", $_SERVER['HTTP_REFERER'], $matches)) {
if ($matches[2] == $_SERVER['SERVER_NAME']) return true;
}
} elseif (!isset($_SERVER['HTTP_REFERER']) && !$this->exportProtection)
trigger_error("Invalid Referer. Export protection is disabled, could not continue executing", E_USER_ERROR);
return false;
}
/**
* IsValidFunction - Checks is the function is mapped in export list
*
* @access private
* @param string $function Function/Method to be checked
* @return boolean Function is valid/not valid
*/
function isValidFunction($function) {
// If exist any exportList function, try to find the selected one
if (count($this->exportList) > 0) {
foreach ($this->exportList as $k => $v) {
if ($function == $v) return true;
}
}
return false;
}
/**
* Export - Map functions/methods that can be accessed
*
* @access public
* @param array|string $function Function/Method that can be called from requests
* @return void
*/
function export() {
// Support: export(string|array [, ...])
$numArgs = func_num_args();
for ($i = 0; $i < $numArgs; $i++) {
$arg = func_get_arg($i);
// Argument is an array, merge with existent list
if (is_array($arg))
$this->exportList = array_merge($this->exportList, $arg);
//Argument is a string, add it
else
$this->exportList[] = $arg;
}
}
/**
* EnableDomainProtection - Activate Domain Protection
*
* @access public
* @return void
*/
function enableDomainProtection() { $this->domainProtection = true; }
/**
* EnableExportProtection - Activate Export Protection
*
* @access public
* @return void
*/
function enableExportProtection() { $this->exportProtection = true; }
/**
* DisableDomainProtection - Deactivate Domain Protection
*
* @access public
* @return void
*/
function disableDomainProtection() { $this->domainProtection = false; }
/**
* DisableExportProtection - Deactivate Export Protection
*
* @access public
* @return void
*/
function disableExportProtection() { $this->exportProtection = false; }
}
?>