175 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			175 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| /**
 | |
|  * IXR_IntrospectionServer
 | |
|  *
 | |
|  * @package IXR
 | |
|  * @since 1.5.0
 | |
|  */
 | |
| class IXR_IntrospectionServer extends IXR_Server
 | |
| {
 | |
|     var $signatures;
 | |
|     var $help;
 | |
| 
 | |
| 	/**
 | |
| 	 * PHP5 constructor.
 | |
| 	 */
 | |
|     function __construct()
 | |
|     {
 | |
|         $this->setCallbacks();
 | |
|         $this->setCapabilities();
 | |
|         $this->capabilities['introspection'] = array(
 | |
|             'specUrl' => 'http://xmlrpc.usefulinc.com/doc/reserved.html',
 | |
|             'specVersion' => 1
 | |
|         );
 | |
|         $this->addCallback(
 | |
|             'system.methodSignature',
 | |
|             'this:methodSignature',
 | |
|             array('array', 'string'),
 | |
|             'Returns an array describing the return type and required parameters of a method'
 | |
|         );
 | |
|         $this->addCallback(
 | |
|             'system.getCapabilities',
 | |
|             'this:getCapabilities',
 | |
|             array('struct'),
 | |
|             'Returns a struct describing the XML-RPC specifications supported by this server'
 | |
|         );
 | |
|         $this->addCallback(
 | |
|             'system.listMethods',
 | |
|             'this:listMethods',
 | |
|             array('array'),
 | |
|             'Returns an array of available methods on this server'
 | |
|         );
 | |
|         $this->addCallback(
 | |
|             'system.methodHelp',
 | |
|             'this:methodHelp',
 | |
|             array('string', 'string'),
 | |
|             'Returns a documentation string for the specified method'
 | |
|         );
 | |
|     }
 | |
| 
 | |
| 	/**
 | |
| 	 * PHP4 constructor.
 | |
| 	 */
 | |
| 	public function IXR_IntrospectionServer() {
 | |
| 		self::__construct();
 | |
| 	}
 | |
| 
 | |
|     function addCallback($method, $callback, $args, $help)
 | |
|     {
 | |
|         $this->callbacks[$method] = $callback;
 | |
|         $this->signatures[$method] = $args;
 | |
|         $this->help[$method] = $help;
 | |
|     }
 | |
| 
 | |
|     function call($methodname, $args)
 | |
|     {
 | |
|         // Make sure it's in an array
 | |
|         if ($args && !is_array($args)) {
 | |
|             $args = array($args);
 | |
|         }
 | |
| 
 | |
|         // Over-rides default call method, adds signature check
 | |
|         if (!$this->hasMethod($methodname)) {
 | |
|             return new IXR_Error(-32601, 'server error. requested method "'.$this->message->methodName.'" not specified.');
 | |
|         }
 | |
|         $method = $this->callbacks[$methodname];
 | |
|         $signature = $this->signatures[$methodname];
 | |
|         $returnType = array_shift($signature);
 | |
| 
 | |
|         // Check the number of arguments
 | |
|         if (count($args) != count($signature)) {
 | |
|             return new IXR_Error(-32602, 'server error. wrong number of method parameters');
 | |
|         }
 | |
| 
 | |
|         // Check the argument types
 | |
|         $ok = true;
 | |
|         $argsbackup = $args;
 | |
|         for ($i = 0, $j = count($args); $i < $j; $i++) {
 | |
|             $arg = array_shift($args);
 | |
|             $type = array_shift($signature);
 | |
|             switch ($type) {
 | |
|                 case 'int':
 | |
|                 case 'i4':
 | |
|                     if (is_array($arg) || !is_int($arg)) {
 | |
|                         $ok = false;
 | |
|                     }
 | |
|                     break;
 | |
|                 case 'base64':
 | |
|                 case 'string':
 | |
|                     if (!is_string($arg)) {
 | |
|                         $ok = false;
 | |
|                     }
 | |
|                     break;
 | |
|                 case 'boolean':
 | |
|                     if ($arg !== false && $arg !== true) {
 | |
|                         $ok = false;
 | |
|                     }
 | |
|                     break;
 | |
|                 case 'float':
 | |
|                 case 'double':
 | |
|                     if (!is_float($arg)) {
 | |
|                         $ok = false;
 | |
|                     }
 | |
|                     break;
 | |
|                 case 'date':
 | |
|                 case 'dateTime.iso8601':
 | |
|                     if (!is_a($arg, 'IXR_Date')) {
 | |
|                         $ok = false;
 | |
|                     }
 | |
|                     break;
 | |
|             }
 | |
|             if (!$ok) {
 | |
|                 return new IXR_Error(-32602, 'server error. invalid method parameters');
 | |
|             }
 | |
|         }
 | |
|         // It passed the test - run the "real" method call
 | |
|         return parent::call($methodname, $argsbackup);
 | |
|     }
 | |
| 
 | |
|     function methodSignature($method)
 | |
|     {
 | |
|         if (!$this->hasMethod($method)) {
 | |
|             return new IXR_Error(-32601, 'server error. requested method "'.$method.'" not specified.');
 | |
|         }
 | |
|         // We should be returning an array of types
 | |
|         $types = $this->signatures[$method];
 | |
|         $return = array();
 | |
|         foreach ($types as $type) {
 | |
|             switch ($type) {
 | |
|                 case 'string':
 | |
|                     $return[] = 'string';
 | |
|                     break;
 | |
|                 case 'int':
 | |
|                 case 'i4':
 | |
|                     $return[] = 42;
 | |
|                     break;
 | |
|                 case 'double':
 | |
|                     $return[] = 3.1415;
 | |
|                     break;
 | |
|                 case 'dateTime.iso8601':
 | |
|                     $return[] = new IXR_Date(time());
 | |
|                     break;
 | |
|                 case 'boolean':
 | |
|                     $return[] = true;
 | |
|                     break;
 | |
|                 case 'base64':
 | |
|                     $return[] = new IXR_Base64('base64');
 | |
|                     break;
 | |
|                 case 'array':
 | |
|                     $return[] = array('array');
 | |
|                     break;
 | |
|                 case 'struct':
 | |
|                     $return[] = array('struct' => 'struct');
 | |
|                     break;
 | |
|             }
 | |
|         }
 | |
|         return $return;
 | |
|     }
 | |
| 
 | |
|     function methodHelp($method)
 | |
|     {
 | |
|         return $this->help[$method];
 | |
|     }
 | |
| }
 |