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