Source

trivial-remote-objects / php / RPC.php

<?php
class RPC{
  private $url;

  public static function publicMethods($obj){
    $ignored=($obj instanceof RemoteObject)?get_class_methods('RemoteObject'):array();
    return array_values(array_diff(get_class_methods($obj),$ignored,array('__construct')));
  }

  public static function rpcException($exception,$msg=null){
   return json_encode(array('errormsg'=>($msg?$msg:$exception->getMessage()),
			     'error'=>$exception,
			     'output'=>ob_get_clean()));
  }
  public static function rpcError($errno,$errstring,$errfile=NULL,$errline=NULL){
    if(error_reporting()){
      die(RPC::rpcException($errno,$errstring . " $errfile:$errline"));
    }
    return true;
  }

  public static function rpcSuccess($obj,$baseURL){
    $success=array();
    //See if this is a Remote3Object and had a useful ID
    if($obj instanceof RemoteObject && ($id = $obj->getID()) ){
      $success['methods']=$obj->getRemoteMethods();
      $success['uri']=$baseURL.'?'.
	http_build_query(array_merge($_GET,
				     array('obj_id'=>$id,
					   'obj_cls'=>get_class($obj))));
    }
    $success['success']=$obj;
    $success['output']=ob_get_clean();

    return json_encode($success);
  }
  public function toJS($obj,$j='window'){
    if(get_magic_quotes_gpc()){
      $j=stripslashes($j);
    }
    return "if(typeof($j) === 'undefined')$j=".json_encode($obj)."; RPC_init($j,".json_encode($this->url).",".json_encode($obj->getRemoteMethods()).");";
  }

  public function __construct(){
    $this->url=$_SERVER['PHP_SELF'];
  }

  public function serve($rootObj){
    ob_start();
    set_error_handler('RPC::rpcError');
    if(get_magic_quotes_gpc()){
      $_POST=array_map('stripslashes',$_POST);
    }

    $rpc=new RPC();
    $obj=$rootObj;

    $result=null;
    $rpc->url=$_SERVER['REQUEST_URI'];

    if(isset($_GET['obj_cls'])){
      $cls= $_GET['obj_cls'];
      $id = $_GET['obj_id'];
      try{
	//ensure class name is reasonable
	//and is a subclass of RemoteObject
	if(is_callable($cls,true) && 
	   is_subclass_of($cls,'RemoteObject')){
	  $obj=call_user_func(array($cls,'getObj'),$id);
	  if(! $obj instanceof RemoteObject){
	    RPC::rpcError(0,"Cannot find object");
	    return;
	  }
	}else{
	  RPC::rpcError(0,"$cls is not a remote class");
	}
      }catch(Exception $e){
	  RPC::rpcError(0,"Cannot find class $cls");
      }
    }elseif($rootObj === null){
      RPC::rpcError(0,"No class or root object specified");
    }

    //return JSON
    header("Content-Type: application/json");

    if($_SERVER['REQUEST_METHOD']==="GET"){
      if(isset($_GET['js']) && $_GET['js']){
	//returns JS
	header("Content-Type: text/javascript");
	echo $rpc->toJS($obj,$_GET['js']);
	return;
      }
      $result=$obj->getRemoteMethods();
    }else{
      $func=$_POST['f'];
      $args=json_decode($_POST['a']);
      try{
	$result=call_user_func_array(array($obj,$func),$args);
      }catch(Exception $e){
	echo RPC::rpcException($e);
	return;
      }
    }
    echo RPC::rpcSuccess($result,$rpc->url);
      
  }
}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.