1<?php 2/** 3 * Description of IJR_InspectionServer 4 * 5 * @author Andreas Gohr <andi@splitbrain.org> 6 * @author Magnus Wolf <mwolf2706@googlemail.com> 7 */ 8require_once('./IJR_Server.php'); 9require_once('./IJR_CallbackDefines.php'); 10 11class IJR_IntrospectionServer extends IJR_Server { 12 private $signatures; 13 private $help; 14 private $callbackMethods; 15 16 protected function IJR_IntrospectionServer() { 17 $this->setCallbacks(); 18 $this->setCapabilities(); 19 $this->capabilities['introspection'] = array( 20 'specUrl' => 'http://xmlrpc.usefulinc.com/doc/reserved.html', 21 'specVersion' => 1 22 ); 23 $callbackDef = new IJR_CallbackDefines(); 24 $this->callbackMethods = $callbackDef->getSystemMethods(); 25 26 foreach($this->callbackMethods as $key) 27 { 28 $this->addCallback($key['method'], $key['callback'], $key['args'], $key['help']); 29 } 30 } 31 32 protected function addCallback($method, $callback, $args, $help) { 33 $this->callbacks[$method] = $callback; 34 $this->signatures[$method] = $args; 35 $this->help[$method] = $help; 36 } 37 38 protected function call($methodname, $args) { 39 if ($args && !is_array($args)) 40 { 41 $args = array($args); 42 } 43 if (!$this->hasMethod($methodname)) 44 { 45 return new IJR_Error(-32601, 'server error. requested method "'.$methodname.'" not specified.'); 46 } 47 48 $method = $this->callbacks[$methodname]; 49 $signature = $this->signatures[$methodname]; 50 $returnType = array_shift($signature); 51 52 if (count($args) < count($signature)) 53 { 54 return new IJR_Error(-32602, 'server error. missing method parameters'); 55 } 56 // Check the argument types 57 $ok = true; 58 $argsbackup = $args; 59 60 for ($i = 0, $j = count($args); $i < $j; $i++) { 61 62 $arg = array_shift($args); 63 $type = array_shift($signature); 64 65 switch ($type) { 66 case 'int': 67 case 'i4': 68 if (is_array($arg) || !is_int($arg)) { 69 $ok = false; 70 } 71 break; 72 case 'base64': 73 case 'string': 74 if (!is_string($arg)) { 75 $ok = false; 76 } 77 break; 78 case 'boolean': 79 if ($arg !== false && $arg !== true) { 80 $ok = false; 81 } 82 break; 83 case 'float': 84 case 'double': 85 if (!is_float($arg)) { 86 $ok = false; 87 } 88 break; 89 case 'date': 90 case 'dateTime.iso8601': 91 if (!is_a($arg, 'IJR_Date')) { 92 $ok = false; 93 } 94 break; 95 } 96 if (!$ok) { 97 return new IJR_Error(-32602, 'server error. invalid method parameters'); 98 } 99 } 100 return parent::call($methodname, $argsbackup); 101 } 102 103 private function methodSignature($method) { 104 if (!$this->hasMethod($method)) { 105 return new IJR_Error(-32601, 'server error. requested method "'.$method.'" not specified.'); 106 } 107 // We should be returning an array of types 108 $types = $this->signatures[$method]; 109 $return = array(); 110 foreach ($types as $type) { 111 switch ($type) { 112 case 'string': 113 $return[] = 'string'; 114 break; 115 case 'int': 116 case 'i4': 117 $return[] = 42; 118 break; 119 case 'double': 120 $return[] = 3.1415; 121 break; 122 case 'dateTime.iso8601': 123 $return[] = new IJR_Date(time()); 124 break; 125 case 'boolean': 126 $return[] = true; 127 break; 128 case 'base64': 129 $return[] = new IJR_Base64('base64'); 130 break; 131 case 'array': 132 $return[] = array('array'); 133 break; 134 case 'struct': 135 $return[] = array('struct' => 'struct'); 136 break; 137 } 138 } 139 return $return; 140 } 141 142 function methodHelp($method) { 143 return $this->help[$method]; 144 } 145} 146?> 147