<?php
/**
* PHP Olait Wrapper.
* v .01.01 design to produce a cleaner code. so the produced javascript function can be included in a source of script.
* v .01.02 add dojo smd wrapper
* @author Henry Eko H, hide@address.com
* @copyright Oktober 2006
*
* //DEVNOTE: dojo's SMD requires the method mapping descripe method's arguments.
* this can only be done with PHP Reflection class; which limit this code to PHP5 only.
* TODO : add dojo's SMD smarty cacher
* FIXME : jsolait/lib/urllib.js do not support async callback on opera
*/
require_once("phpolait.php");
/**
* JSONRPCServer Wrapper
*
* provide functionality so the produced script can be included via javascript source
*
*/
class JSONRpcServerEx extends JSONRpcServer {
/**
* function to write javascript as pure code.
* all necessary libraries must be included manually in the calling page
*
* Prepares the javascript wrappers that will be presented on the client side.
* @param string $proxyvar The name of the proxy variable for accessing the JSON-RPC methods.
*
*/
function srcJavaScript($proxyvar, $proxyClassName = "PHPOlait"){
if ($this->methodMap==null) { // This is the easy case
$methods = get_class_methods( $this->object );
} else {
$methods = array_keys( $this->methodMap );
}
$this->jsWrapperHeaderEx( $_SERVER["PHP_SELF"], $methods, $this->jsolaitlib , $proxyClassName );
foreach ($methods as $name) {
$this->jsWrapperMethod($name);
}
$this->jsWrapperFooterEx($proxyvar , $proxyClassName);
}
/**
* function to write pure javascript code
*
* @param string $pageUrl URL of this page.
* @param array $methodArray List of methods to be called on the server.
* @param string $jsolaitPath
* @param string proxyClassName Name of proxy phpolait class
* */
private function jsWrapperHeaderEx($pageUrl, $methodArray, $jsolaitPath, $proxyClassName) {
$header = <<<EOJS
function $proxyClassName() {
var serviceURL = "$pageUrl";
var methods = [%METHODLIST%];
var jsonrpc = null;
var server = null;
try{
jsolait.baseURL = '$jsolaitPath';
jsolait.libURL = '$jsolaitPath/jsolait';
jsonrpc = importModule("jsonrpc");
server = new jsonrpc.ServiceProxy(serviceURL, methods);
}catch(e){
reportException(e);
throw "importing of jsonrpc module failed.";
}
this._doJSON = function(method, args) {
try {
var resultString;
var result;
resultString = server[method].apply(server,args);
return resultString;
} catch (e) {
alert(e);
}
}
EOJS;
$header = str_replace("%PAGE_NAME%", $pageUrl, $header);
$methodList = "'" . implode($methodArray, "','") . "'";
$header = str_replace("%METHODLIST%", $methodList, $header);
print $header;
}
/**
* Closes the class definition and sets the global variable for accessing the methods.
* Pure javascript code only
* @param string varName Name of the global variable by which to access the JSON methods.
* @param string proxyClassName Name of proxy phpolait class
*/
private function jsWrapperFooterEx($varName, $proxyClassName ) {
print <<<EOJS
}
var $varName = new $proxyClassName();
EOJS;
}
//the methods below add ability to write dojo's smd
/**
* write DOJO's SMD generator
* @param string $proxyvar The name of the proxy variable for accessing the JSON-RPC methods.
*/
function srcSMD(){
$strObjName = get_class($this->object);
$reflectObj;
$aMethod;
if ($strObjName == ""){
//this is error. throw proper smd error
}else{
$reflectObj = new ReflectionClass($strObjName);
$this->djSMDWrapperHeader($_SERVER["PHP_SELF"],$strObjName);
//$aMethod = new ReflectionMethod();
$blnFirstRun = true;
//walk trough methods and its parameters
foreach ($reflectObj->getMethods() as $aMethod) {
if (!$aMethod->isConstructor() && !$aMethod->isDestructor()){
$strMethodCode = $this->djSMDWrapperMethod($aMethod);
if ($blnFirstRun){
$blnFirstRun = false;
}else{
$strMethodCode = "," . $strMethodCode;
}
print($strMethodCode);
}
}
$this->djSMDWrapperFooter();
}
}
/**
* function to write pure SMD Header code
*
* @param string $pageUrl URL of this page.
* @param array $methodArray List of methods to be called on the server.
* @param string proxyClassName Name of proxy phpolait class
* */
private function djSMDWrapperHeader($pageUrl, $objectName){
$header = <<<SMD_HDR
{
"SMDVersion":".1",
"objectName":"$objectName",
"serviceType":"JSON-RPC",
"serviceURL":"$pageUrl",
"generator":"PHPOlait",
"methods":[
SMD_HDR;
print(header("Content-Type:text/json-comment-filtered"));
print($header);
}
/**
* function to write SMD method mapping
* @param ReflectionMethod $method method name
* @return string
*/
private function djSMDWrapperMethod($method){
$strMethodName=$method->getName();
$strParamsList="";
$strMethodCode="";
$params = $method->getParameters();
$aParams = new ReflectionParameter();
foreach ($params as $aParams) {
$strParamName = $aParams->getName();
$strParamsList .= $strParamsList==""?"":"," ;
$strParamsList .= <<<SMD_METHOD
{
"name":"$strParamName",
"type":"STRING"
}
SMD_METHOD;
}
if ($strParamsList!=""){
$strParamsList = "," . <<<SMD_METHOD
"parameters":[$strParamsList]
SMD_METHOD;
}
$strMethodCode = <<<SMD_METHOD
{
"name":"$strMethodName"$strParamsList
}
SMD_METHOD;
//print($strMethodCode);
return $strMethodCode;
}
/**
* Closes the class definition and sets the global variable for accessing the methods.
* SMD code only
* SMD is only a method mapping. do not need js var Name and proxy Class Name
* var name and proxy class name must be explicitly describe in js code
*/
private function djSMDWrapperFooter(){
$footer = <<<SMD_FTR
]
}
SMD_FTR;
print($footer);
}
}
?>