<?php
class pAjaxParser {
function obj2array($obj) {
$childs = $obj->childNodes;
$arr = array();
foreach ($childs as $child) {
if ($child->nodeType == DOMIT_ELEMENT_NODE) {
$key = (eregi("pAjaxItem-([0-9]*)", $child->nodeName, $newKey)) ? $newKey[1] : $child->nodeName;
$arr[$key] = pAjaxParser::obj2array($child);
} elseif ($child->nodeType == DOMIT_TEXT_NODE || $child->nodeType == DOMIT_CDATA_SECTION_NODE)
return $child->nodeValue;
}
return $arr;
}
function getCallerArguments($charset = "UTF-8") {
$REQUEST_METHOD = strtoupper($_SERVER['REQUEST_METHOD']);
$function = "";
$arguments = array();
if ($REQUEST_METHOD == "GET") {
$function = $_GET['function'];
$arguments = pAjaxParser::decodeGetData($_GET);
unset($arguments['function']);
unset($arguments['rnd']);
} elseif ($REQUEST_METHOD == "POST") {
$DOMIT = new DOMIT_Document();
$DOMITProcInstruction = $DOMIT->createProcessingInstruction('xml', 'version="1.0" encoding="'.$charset.'"');
$DOMIT->parseXML(stripslashes(pAjaxParser::getPostData()));
$function = $DOMIT->documentElement->firstChild->firstChild->nodeValue;
$arguments = pAjaxParser::obj2array($DOMIT->documentElement->lastChild);
}
return array("function" => $function, "arguments" => $arguments);
}
function decodeGetData($data) {
foreach ($data as $k => $v)
$data[$k] = ((is_array($v)) ? pAjaxParser::decodeGetData($v) : urldecode($v));
return $data;
}
function getPostData() {
$data = "";
if (isset($_SERVER['HTTP_RAW_POST_DATA']))
$data = $_SERVER['HTTP_RAW_POST_DATA'];
elseif (isset($_SERVER['HTTP_POST_DATA']))
$data = urldecode($_SERVER['HTTP_POST_DATA']);
else {
$headers = getallheaders();
$data = urldecode($headers['Post-Data']);
}
return $data;
}
function generateXmlResponse($result, $charset = "UTF-8") {
$DOMIT = new DOMIT_Document();
$DOMITProcInstruction = & $DOMIT->createProcessingInstruction('xml', 'version="1.0" encoding="'.$charset.'"');
$DOMITResult = $DOMIT->createElement("pAjaxResponse");
$DOMITNode = pAjaxParser::phpToXmlValueNode("result", $result, $DOMIT, $charset);
if (!is_a($DOMITNode, "DOMIT_Node")) {
$DOMITError = $DOMIT->createElement("pAjaxError");
$message = (is_a($DOMITNode, "Exception")) ? $DOMITNode->getMessage() : "Invalid pAjax Document returned";
$DOMITErrorMessage = $DOMIT->createElement("pAjaxErrorMessage");
$DOMITErrorMessage->appendChild($DOMIT->createTextNode($message));
$DOMITError->appendChild($DOMITErrorMessage);
$code = (is_a($DOMITNode, "Exception")) ? $DOMITNode->getCode() : 9901;
$DOMITErrorCode = $DOMIT->createElement("pAjaxErrorCode");
$DOMITErrorCode->appendChild($DOMIT->createTextNode($code));
$DOMITError->appendChild($DOMITErrorCode);
$DOMIT->appendChild($DOMITError);
} else {
$DOMITResult->appendChild($DOMITNode);
$DOMIT->appendChild($DOMITResult);
}
return $DOMIT->toNormalizedString();
}
function & phpToXmlValueNode($n, $v, $DOMIT, $charset = "UTF-8") {
if (is_numeric($n))
$n = "pAjaxItem-" . $n;
$DOMITEl = $DOMIT->createElement($n);
$DOMITNode = pAjaxParser::phpToXmlNode($v, $DOMIT, $charset = "UTF-8");
if (is_a($DOMITNode, "DOMIT_Node")) {
$DOMITEl->setAttribute("type", pAjaxParser::getPhpType($v));
if ($DOMITNode->nodeName == "data" && $DOMITNode->getAttribute("type") == "") {
$numChilds = count($DOMITNode->childNodes);
for ($i = 0; $i < $numChilds; $i++)
$DOMITEl->appendChild($DOMITNode->childNodes[$i]);
} else
$DOMITEl->appendChild($DOMITNode);
return $DOMITEl;
}
return $DOMITNode;
}
function phpToXmlNode($v, $DOMIT, $charset = "UTF-8") {
switch ($type = pAjaxParser::getPhpType($v)) {
case "string":
case "text":
// Since DOMIT doesn't support character encoding, I'll have to support
// it my own. Please note that only string values should be encoded.
if (function_exists("mb_convert_encoding"))
// MULTIBYTE is a PECL library
$v = mb_convert_encoding($v, $charset);
elseif (function_exists("iconv") && ini_get("default_charset") != "")
// ICONV is a library in PHP4.X and bundled in PHP5.X
$v = iconv(ini_get("default_charset"), $charset, $v);
else // Can't resolve a library, use UTF-8 to resolve encoding
$v = utf8_encode($v);
return ($type == "text") ? $DOMIT->createCDATASection($v) : $DOMIT->createTextNode($v);
case "number":
// JavaScript only handles "." (dot) floating point
return $DOMIT->createTextNode(str_replace(",", ".", $v));
case "dateTime":
return $DOMIT->createTextNode(pAjaxParser::phpDateToIso8601($v));
case "boolean":
return $DOMIT->createTextNode($v ? "true" : "false");
case "array":
$DOMITEl = $DOMIT->createElement("data");
for ($i = 0; $i < count($v); $i++)
$DOMITEl->appendChild(pAjaxParser::phpToXmlValueNode("pAjaxItem-" . $i, $v[$i], $DOMIT));
return $DOMITEl;
case "struct":
$DOMITEl = $DOMIT->createElement("data");
foreach ($v as $key => $val)
$DOMITEl->appendChild(pAjaxParser::phpToXmlValueNode($key, $val, $DOMIT));
return $DOMITEl;
}
ob_start();
trigger_error("Unknown PHP Type while parsing [{$v}], type " . pAjaxParser::getPhpType($v), E_USER_ERROR);
return ob_get_clean();
}
function getPhpType($v) {
switch ($type = gettype($v)) {
case "string":
case "integer":
case "double":
case "boolean":
if (pAjaxParser::iso8601ToPhp($v) > 0)
return "dateTime";
elseif (is_bool($v) || $v == "true" || $v == "false") {
return "boolean";
} elseif (strspn($v, "0123456789-+,.") == strlen($v) && substr_count($v, ".") < 2 && substr_count($v, ",") < 2) {
preg_match_all('/[1-9.,\-+][0-9,.]*/', $v, $matches, PREG_SET_ORDER);
if (strlen($matches[0][0]) == strlen($v))
return "number";
}
if (strlen($v) > 100 || (strstr($v, "<") || strstr($v, ">")))
return "text";
return "string";
case "object":
return "struct";
case "array":
$keys = array_keys($v);
for ($i = 0; $i < count($keys); $i++) {
if (!is_numeric($keys[$i]))
return "struct";
}
return "array";
default:
return $type;
}
}
function phpDateToIso8601($v) {
$timestamp = strtotime($v);
return strftime("%Y%m%dT%H:%M:%S", $timestamp);
}
function iso8601ToPhp($v) {
if (eregi("([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})", urldecode($v), $matches))
return mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
return -1;
}
}
?>