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]; | ||
|  |     } | ||
|  | } |