/** * Constructor * * @param string $name The name * @param array $settings Settings array (default: NULL) */ public function PhpWsdlObject($name, $settings = null) { $this->GUID = uniqid(); PhpWsdl::Debug('New PhpWsdlObject "' . $name . '" with GUID "' . $this->GUID . '"'); $this->Name = $name; if (!is_null($settings)) { if (isset($settings['docs'])) { $this->Docs = $settings['docs']; } if (isset($settings['settings'])) { $this->Settings = $settings['settings']; } } }
public function __call($method, $param) { if (PhpWsdl::$Debugging) { PhpWsdl::Debug('Proxy call method ' . $method . ': ' . print_r($param, true)); } PhpWsdl::$ProxyServer->CreateWsdl(); $m = PhpWsdl::$ProxyServer->GetMethod($method); if (is_null($m)) { throw new SoapFault('MissingMethod', 'Method "' . $method . '" not found'); } // Try to fix the missing parameters issue if the SoapServer is not running in WSDL mode if (!PhpWsdl::$UseProxyWsdl) { $pLen = sizeof($m->Param); $temp = sizeof($param); if ($pLen != $temp) { PhpWsdl::Debug('Wrong parameter count (' . $temp . '/' . $pLen . ')'); $req = new DOMDocument(); if ($req->loadXml(file_get_contents('php://input'))) { $x = new DOMXPath($req); $temp = $param; $param = array(); $pos = 0; // Current index in the received parameter array $i = -1; while (++$i < $pLen) { $p = $m->Param[$i]; if ($x->query("/*[local-name()='Envelope']/*[local-name()='Body']/*[local-name()='" . $m->Name . "']/*[local-name()='" . $p->Name . "']")->length > 0) { PhpWsdl::Debug('Parameter "' . $p->Name . '" was received'); $param[] = $temp[$pos]; $pos++; } else { PhpWsdl::Debug('Parameter "' . $p->Name . '" was missing'); $param[] = null; } } } else { PhpWsdl::Debug('Could not parse SOAP request XML'); } } } // Prepare the method call $call = $m->IsGlobal ? $method : array(is_null($m->Class) ? PhpWsdl::$ProxyObject : $m->Class, $method); // Call the target method PhpWsdl::Debug('Call the target method'); $res = sizeof($param) < 1 ? call_user_func($call) : call_user_func_array($call, $param); // Return the encoded response $type = is_null($m->Return) ? null : $m->Return->Name; return PhpWsdl::$EncodeProxyReturn && !is_null($type) ? PhpWsdl::DoEncoding($type, $res, false, PhpWsdl::$ProxyServer) : $res; }
/** * This will forward a request to another URI, output the response and exit * * @param string $targetUri The target URI */ public static function RunForwarder($targetUri) { require_once dirname(__FILE__) . '/class.phpwsdl.php'; PhpWsdl::Debug('Run PhpWsdlAjax forwarder at ' . $targetUri); if ($_SERVER['REQUEST_METHOD'] == 'GET') { PhpWsdl::Debug('Forward GET request'); ob_start('ob_gzhandler'); echo self::HttpRequest(isset($_SERVER['QUERY_STRING']) ? '?' . $_SERVER['QUERY_STRING'] : '', null, $targetUri); } else { PhpWsdl::Debug('Forward POST request'); ob_start('ob_gzhandler'); echo self::HttpRequest(null, file_get_contents('php://input'), $targetUri); } exit; }
/** * Interpret a WSDL definition * * @param string $def WSDL definition * @param string $method Method name */ public function InterpretDefinition($def, $method, $keywords, $docs) { PhpWsdl::Debug('Interpret definition'); if (!PhpWsdl::CallHook('BeforeInterpretDefinitionHook', array('sender' => $this, 'server' => $this->Server, 'def' => &$def, 'method' => &$method, 'keywords' => &$keywords, 'docs' => &$docs))) { return null; } // Initialize some variables $param = array(); // List ob parameter objects $return = null; // The return value object $elements = array(); // List of element objects $settings = array(); // Settings hash $omit = false; // Omit the object $type = null; // Type identifier $buffer = array(); // Other data // Interpret keywords $i = -1; $len = sizeof($keywords); while (++$i < $len) { $keyword = $keywords[$i]; if (PhpWsdl::$Debugging) { PhpWsdl::Debug('Interpret keyword ' . print_r($keyword, true)); } // Call the global keyword handler if (!PhpWsdl::CallHook('InterpretKeywordHook', array('sender' => $this, 'server' => $this->Server, 'def' => &$def, 'method' => &$method, 'keywords' => &$keywords, 'docs' => &$docs, 'param' => &$param, 'elements' => &$elements, 'return' => &$return, 'settings' => &$settings, 'omit' => &$omit, 'keyword' => &$keyword, 'type' => &$type, 'buffer' => &$buffer, 'newkeyword' => &$newkeyword))) { continue; } if ($omit) { return null; } // Call the keyword handler if (!PhpWsdl::CallHook('InterpretKeyword' . $keyword[0] . 'Hook', array('sender' => $this, 'server' => $this->Server, 'def' => &$def, 'method' => &$method, 'keywords' => &$keywords, 'docs' => &$docs, 'param' => &$param, 'elements' => &$elements, 'return' => &$return, 'settings' => &$settings, 'omit' => &$omit, 'keyword' => &$keyword, 'type' => &$type, 'buffer' => &$buffer, 'newkeyword' => &$newkeyword))) { continue; } if ($omit) { return null; } PhpWsdl::Debug('Keyword not handled'); } // Create object $obj = null; if (!PhpWsdl::CallHook('CreateObjectHook', array('sender' => $this, 'server' => $this->Server, 'def' => &$def, 'method' => &$method, 'keywords' => &$keywords, 'docs' => &$docs, 'param' => &$param, 'elements' => &$elements, 'return' => &$return, 'settings' => &$settings, 'omit' => &$omit, 'type' => &$type, 'buffer' => &$buffer, 'obj' => &$obj))) { return null; } if (!PhpWsdl::CallHook('AfterInterpretDefinitionHook', array('sender' => $this, 'server' => $this->Server, 'def' => &$def, 'method' => &$method, 'keywords' => &$keywords, 'docs' => &$docs, 'param' => &$param, 'elements' => &$elements, 'return' => &$return, 'settings' => &$settings, 'omit' => &$omit, 'type' => &$type, 'buffer' => &$buffer, 'obj' => &$obj))) { return null; } PhpWsdl::Debug('Object ' . (is_null($obj) ? 'not created' : 'created')); return $obj; }
/** * Create complex type object * * @param array $data The parser data * @return boolean Response */ public static function CreateComplexTypeObject($data) { if ($data['method'] != '') { return true; } if (!is_null($data['obj'])) { return true; } if (!is_array($data['type'])) { return true; } if (!isset($data['type']['id'])) { return true; } if ($data['type']['id'] != 'complex') { return true; } if (!is_null($data['docs'])) { $data['settings']['docs'] = $data['docs']; } else { $data['settings']['docs'] = $data['type']['docs']; } PhpWsdl::Debug('Add complex type ' . $data['type']['name']); $data['settings']['isarray'] = !is_null($data['type']['type']); $data['obj'] = new PhpWsdlComplex($data['type']['name'], $data['elements'], $data['settings']); $data['obj']->Type = $data['type']['type']; $data['settings'] = array(); $data['server']->Types[] = $data['obj']; return true; }
/** * Interpret a element keyword * * @param array $data The parser data * @return boolean Response */ public static function InterpretElement($data) { $info = explode(' ', $data['keyword'][1], 3); if (sizeof($info) < 2) { return true; } $name = substr($info[1], 1); if (substr($name, strlen($name) - 1, 1) == ';') { $name = substr($name, 0, strlen($name) - 1); } PhpWsdl::Debug('Interpret element ' . $name); if ($data['server']->ParseDocs) { if (sizeof($info) > 2) { $data['settings']['docs'] = trim($info[2]); } } $data['elements'][] = new PhpWsdlElement($name, $info[0], $data['settings']); $data['settings'] = array(); return false; }
/** * Write WSDL to cache * * @param string $wsdl The UTF-8 encoded WSDL string (default: NULL) * @param string $wsdluri The SOAP WSDL URI or NULL to use the default (default: NULL) * @param string $file The target filename or NULL to use the default (default: NULL) * @param boolean $force Force refresh (default: FALSE) * @return boolean Succeed? */ public function WriteWsdlToCache($wsdl = null, $wsdluri = null, $file = null, $force = false) { PhpWsdl::Debug('Write WSDL to the cache'); if (is_null($wsdluri)) { $wsdluri = $this->WsdlUri; } if ($wsdluri == $this->WsdlUri && !is_null($wsdl)) { $this->WSDL = $wsdl; } if (is_null($wsdl)) { if (is_null($this->WSDL)) { PhpWsdl::Debug('No WSDL'); return false; // WSDL not defined } $wsdl = $this->WSDL; } if (is_null($file)) { $file = $this->GetCacheFileName($wsdluri); if (is_null($file)) { PhpWsdl::Debug('No cache file'); return false; // No cache file } } $temp = substr($file, 0, 1); if ($temp != '/' && $temp != '.') { if (is_null(PhpWsdl::$CacheFolder)) { PhpWsdl::Debug('No cache folder'); return false; // No cache folder } $file = PhpWsdl::$CacheFolder . '/' . $file; } if (!$force) { if ($this->IsCacheValid($file)) { PhpWsdl::Debug('Cache is still valid'); return true; // Existing cache is still valid } } PhpWsdl::Debug('Write to ' . $file); if (file_put_contents($file, $wsdl) === false) { PhpWsdl::Debug('Could not write to cache'); return false; // Error writing to cache } if (file_put_contents($file . '.cache', time()) === false) { PhpWsdl::Debug('Could not write cache time file'); return false; // Error writing to cache } $data = array('version' => self::$VERSION, 'servicename' => $this->ServiceName, 'endpoint' => $this->EndPoint, 'namespace' => $this->NameSpace); PhpWsdl::CallHook('ClientWriteCacheHook', array('client' => $this, 'data' => &$data)); if (file_put_contents($file . '.obj', serialize($data)) === false) { PhpWsdl::Debug('Could not write serialized cache'); return false; } return true; }
/** * Fill an PhpWsdl object with data from an NuSOAP object * Development status: Beta * * @param nusoap_server $nusoap NuSOAP server object * @param PhpWsdl $phpwsdl PhpWsdl object or NULL to create a new one (default: NULL) * @return PhpWsdl PhpWsdl object */ public static function CreatePhpWsdl($nusoap, $phpwsdl = null) { //TODO This has still to be tested with some real NuSOAP webservice objects! PhpWsdl::Debug('Create PhpWsdl from NuSOAP'); if (is_null($phpwsdl)) { $phpwsdl = PhpWsdl::CreateInstance(); } // Basic configuration $phpwsdl->Name = $nusoap->wsdl->serviceName; $phpwsdl->EndPoint = $nusoap->wsdl->endpoint; $phpwsdl->NameSpace = $nusoap->wsdl->namespaces['tns']; // Types PhpWsdl::Debug('Add types'); $ntl = $nusoap->wsdl->schemas[$phpwsdl->NameSpace][0]->complexTypes; $keys = array_keys($ntl); $i = -1; $len = sizeof($keys); while (++$i < $len) { $nt = $ntl[$keys[$i]]; $name = $nt['name']; PhpWsdl::Debug('Add type ' . $name); if (!is_null($phpwsdl->GetType($name))) { PhpWsdl::Debug('WARNING: Double type detected!'); continue; } if ($nt['typeClass'] == 'complexType' && $nt['phpType'] == 'array') { // Array PhpWsdl::Debug('Array type'); list($temp, $type) = explode(':', $nt['arrayType'], 2); $t = new PhpWsdlComplex($name); $t->Type = $type; $t->IsArray = true; $phpwsdl->Types[] = $t; } else { if ($nt['typeClass'] == 'complexType') { // Complex type PhpWsdl::Debug('Complex type'); if ($nt['phpType'] != 'struct') { PhpWsdl::Debug('WARNING: Not a PHP struct'); } if ($nt['compositor'] != 'sequence') { PhpWsdl::Debug('WARNING: Not sequenced elements'); } $el = array(); $ek = array_keys($nt['elements']); $j = -1; $eLen = sizeof($ek); while (++$j < $eLen) { $n = $nt['elements'][$ek[$j]]['name']; list($temp, $type) = explode(':', $nt['elements'][$ek[$j]]['type']); PhpWsdl::Debug('Found element ' . $n . ' type of ' . $type); $el[] = new PhpWsdlElement($n, $type); } $phpwsdl->Types[] = new PhpWsdlComplex($name, $el); } else { if ($nt['typeClass'] == 'simpleType') { // Enumeration PhpWsdl::Debug('Enumeration'); list($temp, $type) = explode(':', $nt['type']); $phpwsdl->Types[] = new PhpWsdlEnum($name, $type, $nt['enumeration']); } else { PhpWsdl::Debug('WARNING: PHP type "' . $nt['phpType'] . '" is not supported!'); } } } } // Methods PhpWsdl::Debug('Add methods'); $nml = $nusoap->operations; $keys = array_keys($nml); $i = -1; $len = sizeof($keys); while (++$i < $len) { $nm = $nml[$keys[$i]]; // Get the method name $name = $nml['name']; PhpWsdl::Debug('Add method ' . $name); $glob = strpos($name, '.') < 0; if (!$glob) { list($temp, $name) = explode('.', $name, 2); PhpWsdl::Debug('Class method ' . $name); } else { PhpWsdl::Debug('Global method'); } if (!is_null($phpwsdl->GetMethod($name))) { PhpWsdl::Debug('WARNING: Double method detected!'); continue; } // Get parameters $param = array(); $pk = array_keys($nm['in']); $j = -1; $pLen = sizeof($pk); while (++$j < $pLen) { list($temp, $type) = explode(':', $nm['in'][$pk[$j]], 2); PhpWsdl::Debug('Parameter ' . $ok[$j] . ' type of ' . $type); $param[] = new PhpWsdlParam($pk[$j], $type); } // Get return type $r = null; if (sizeof($nm['out']) > 0) { $pk = array_keys($nm['in']); list($temp, $type) = explode(':', $nm['out'][$pk[0]], 2); PhpWsdl::Debug('Return ' . $pk[0] . ' type of ' . $type); $r = new PhpWsdlParam($pk[0], $type); } // Create method $m = new PhpWsdlMethod($name, $param, $r); $m->IsGlobal = $glob; $phpwsdl->Methods[] = $m; } return $phpwsdl; }
/** * Run the Zend server * * @param array $data The server data * @return boolean Response */ public static function RunServer($data) { $server = $data['soapserver']; if ($server !== self::$Server || !class_exists('Zend_Soap_Server')) { PhpWsdl::Debug('Zend not found or server object changed'); return true; // We can't handle this server run! } if (!PhpWsdl::CallHook('ZendRunHook', $data)) { return false; } self::$Server->handle(); return false; }
/** * Interpret a return value * * @param array $data The parser data * @return boolean Response */ public static function InterpretReturn($data) { if ($data['method'] == '') { return true; } $info = explode(' ', $data['keyword'][1], 2); if (sizeof($info) < 1) { return true; } PhpWsdl::Debug('Interpret return'); if ($data['server']->ParseDocs) { if (sizeof($info) > 1) { $data['settings']['docs'] = trim($info[1]); } } $data['return'] = new PhpWsdlParam(str_replace('%method%', $data['method'], self::$DefaultReturnName), $info[0], $data['settings']); $data['settings'] = array(); return false; }
/** * Compress a JavaScript * * @param string $js The uncompressed JavaScript * @return string The compressed JavaScript */ private function PackJavaScript($js) { if (!self::IsJsPackerAvailable()) { return $js; } PhpWsdl::Debug('Compress a JavaScript'); if (PhpWsdl::HasHookHandler('ServersPackJsHook')) { return PhpWsdl::CallHook('ServersPackJsHook', array('server' => $this, 'js' => &$js)); } $packer = new PhpWsdlJavaScriptPacker(utf8_decode($js), 62, true, true); return utf8_encode($packer->pack()); }
/** * Create method object * * @param array $data The parser data * @return boolean Response */ public static function CreateMethodObject($data) { if (!is_null($data['obj'])) { return true; } if ($data['method'] == '') { return true; } if (!is_null($data['type'])) { return true; } PhpWsdl::Debug('Add method ' . $data['method']); $server = $data['server']; if (!is_null($server->GetMethod($data['method']))) { PhpWsdl::Debug('WARNING: Double method detected!'); return true; } if ($server->ParseDocs) { if (!is_null($data['docs'])) { $data['settings']['docs'] = $data['docs']; } } $data['obj'] = new PhpWsdlMethod($data['method'], $data['param'], $data['return'], $data['settings']); $data['settings'] = array(); $server->Methods[] = $data['obj']; return true; }
/** * Create enumeration object * * @param array $data The parser data * @return boolean Response */ public static function CreateEnumTypeObject($data) { if ($data['method'] != '') { return true; } if (!is_null($data['obj'])) { return true; } if (!is_array($data['type'])) { return true; } if (!isset($data['type']['id'])) { return true; } if ($data['type']['id'] != 'enum') { return true; } if (!isset($data['type']['elements'])) { return true; } if (!is_array($data['type']['elements'])) { return true; } if (!is_null($data['docs'])) { $data['settings']['docs'] = $data['docs']; } else { $data['settings']['docs'] = $data['type']['docs']; } PhpWsdl::Debug('Add enumeration ' . $data['type']['name']); $data['obj'] = new PhpWsdlEnum($data['type']['name'], $data['type']['type'], $data['type']['elements'], $data['settings']); $data['settings'] = array(); $data['server']->Types[] = $data['obj']; return true; }