public function generate($wsdl, GeneratorOptions $options = null) { try { $client = new SoapClient($wsdl); } catch (SoapFault $e) { throw new \RuntimeException('Cannot parse the WSDL file: ' . $wsdl); } $this->dom->load($wsdl); $this->wsdl = $wsdl; $this->getDocumentation(); $this->getTargetNamespace(); $this->declareService(); $this->getOperations($client); $this->getTypes($client); $this->saveCode($options->getTargetDir(), $options->getNamespace()); return; // class level docblock $code .= "/**\n"; $code .= " * " . $service['class'] . " class\n"; $code .= " * \n"; $code .= parse_doc(" * ", $service['doc']); $code .= " * \n"; $code .= " * @author {author}\n"; $code .= " * @copyright {copyright}\n"; $code .= " * @package {package}\n"; $code .= " */\n"; $code .= "class " . $service['class'] . " extends SoapClient {\n\n"; // add classmap $code .= " private static \$classmap = array(\n"; foreach ($service['types'] as $type) { $code .= " '" . $type['class'] . "' => '" . $type['class'] . "',\n"; } $code .= " );\n\n"; $code .= " public function " . $service['class'] . "(\$wsdl = \"" . $service['wsdl'] . "\", \$options = array()) {\n"; // initialize classmap (merge) $code .= " foreach(self::\$classmap as \$key => \$value) {\n"; $code .= " if(!isset(\$options['classmap'][\$key])) {\n"; $code .= " \$options['classmap'][\$key] = \$value;\n"; $code .= " }\n"; $code .= " }\n"; $code .= " parent::__construct(\$wsdl, \$options);\n"; $code .= " }\n\n"; foreach ($service['functions'] as $function) { $code .= " /**\n"; $code .= parse_doc(" * ", $function['doc']); $code .= " *\n"; $signature = array(); // used for function signature $para = array(); // just variable names if (count($function['params']) > 0) { foreach ($function['params'] as $param) { $code .= " * @param " . (isset($param[0]) ? $param[0] : '') . " " . (isset($param[1]) ? $param[1] : '') . "\n"; /*$typehint = false; foreach($service['types'] as $type) { if($type['class'] == $param[0]) { $typehint = true; } } $signature[] = ($typehint) ? implode(' ', $param) : $param[1];*/ $signature[] = (in_array($param[0], $primitive_types) or substr($param[0], 0, 7) == 'ArrayOf') ? $param[1] : implode(' ', $param); $para[] = $param[1]; } } $code .= " * @return " . $function['return'] . "\n"; $code .= " */\n"; $code .= " public function " . $function['name'] . "(" . implode(', ', $signature) . ") {\n"; // $code .= " return \$this->client->".$function['name']."(".implode(', ', $para).");\n"; $code .= " return \$this->__soapCall('" . $function['method'] . "', array("; $params = array(); if (count($signature) > 0) { // add arguments foreach ($signature as $param) { if (strpos($param, ' ')) { // slice $param = array_pop(explode(' ', $param)); } $params[] = $param; } //$code .= "\n "; $code .= implode(", ", $params); //$code .= "\n ),\n"; } $code .= "), "; //$code .= implode(', ', $signature)."),\n"; $code .= " array(\n"; $code .= " 'uri' => '" . $targetNamespace . "',\n"; $code .= " 'soapaction' => ''\n"; $code .= " )\n"; $code .= " );\n"; $code .= " }\n\n"; } $code .= "}\n\n"; print "done\n"; print "Writing " . $service['class'] . ".php..."; $fp = fopen($service['class'] . ".php", 'w'); fwrite($fp, "<?php\n" . $code . "?>\n"); fclose($fp); print "done\n"; function parse_doc($prefix, $doc) { $code = ""; $words = split(' ', $doc); $line = $prefix; foreach ($words as $word) { $line .= $word . ' '; if (strlen($line) > 90) { // new line $code .= $line . "\n"; $line = $prefix; } } $code .= $line . "\n"; return $code; } /** * Look for enumeration * * @param DOM $dom * @param string $class * @return array */ function checkForEnum(&$dom, $class) { $values = array(); $node = findType($dom, $class); if (!$node) { return $values; } $value_list = $node->getElementsByTagName('enumeration'); if ($value_list->length == 0) { return $values; } for ($i = 0; $i < $value_list->length; $i++) { $values[] = $value_list->item($i)->attributes->getNamedItem('value')->nodeValue; } return $values; } function generatePHPSymbol($s) { global $reserved_keywords; if (!preg_match('/^[A-Za-z_]/', $s)) { $s = 'value_' . $s; } if (in_array(strtolower($s), $reserved_keywords)) { $s = '_' . $s; } return preg_replace('/[-.\\s]/', '_', $s); } }
/** * Generates cachable url to method mapping * @param string $class_name * @param string $base_path */ protected function generateMap($class_name, $base_path = '') { $reflection = new ReflectionClass($class_name); $class_metadata = parse_doc($reflection->getDocComment()); $methods = $reflection->getMethods(ReflectionMethod::IS_PUBLIC + ReflectionMethod::IS_PROTECTED); foreach ($methods as $method) { $doc = $method->getDocComment(); $arguments = array(); $defaults = array(); $metadata = $class_metadata + parse_doc($doc); $params = $method->getParameters(); $position = 0; foreach ($params as $param) { $arguments[$param->getName()] = $position; $defaults[$position] = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : NULL; $position++; } $method_flag = $method->isProtected() ? isRestlerCompatibilityModeEnabled() ? 2 : 3 : (isset($metadata['protected']) ? 1 : 0); //take note of the order $call = array('class_name' => $class_name, 'method_name' => $method->getName(), 'arguments' => $arguments, 'defaults' => $defaults, 'metadata' => $metadata, 'method_flag' => $method_flag); $method_url = strtolower($method->getName()); if (preg_match_all('/@url\\s+(GET|POST|PUT|DELETE|HEAD|OPTIONS)[ \\t]*\\/?(\\S*)/s', $doc, $matches, PREG_SET_ORDER)) { foreach ($matches as $match) { $http_method = $match[1]; $url = rtrim($base_path . $match[2], '/'); $this->routes[$http_method][$url] = $call; } } else { if ($method_url[0] != '_') { //not prefixed with underscore // no configuration found so use convention if (preg_match_all('/^(GET|POST|PUT|DELETE|HEAD|OPTIONS)/i', $method_url, $matches)) { $http_method = strtoupper($matches[0][0]); $method_url = substr($method_url, strlen($http_method)); } else { $http_method = 'GET'; } $url = $base_path . ($method_url == 'index' || $method_url == 'default' ? '' : $method_url); $url = rtrim($url, '/'); $this->routes[$http_method][$url] = $call; foreach ($params as $param) { if ($param->getName() == 'request_data') { break; } $url .= $url == '' ? ':' : '/:'; $url .= $param->getName(); $this->routes[$http_method][$url] = $call; } } } } }
foreach ($service['types'] as $type) { $code .= " '" . $type['class'] . "' => '" . $type['class'] . "',\n"; } $code .= " );\n\n"; $code .= " public function " . $service['class'] . "(\$wsdl = \"" . $service['wsdl'] . "\", \$options = array()) {\n"; // initialize classmap (merge) $code .= " foreach(self::\$classmap as \$key => \$value) {\n"; $code .= " if(!isset(\$options['classmap'][\$key])) {\n"; $code .= " \$options['classmap'][\$key] = \$value;\n"; $code .= " }\n"; $code .= " }\n"; $code .= " parent::__construct(\$wsdl, \$options);\n"; $code .= " }\n\n"; foreach ($service['functions'] as $function) { $code .= " /**\n"; $code .= parse_doc(" * ", $function['doc']); $code .= " *\n"; $signature = array(); // used for function signature $para = array(); // just variable names if (count($function['params']) > 0) { foreach ($function['params'] as $param) { $code .= " * @param " . (isset($param[0]) ? $param[0] : '') . " " . (isset($param[1]) ? $param[1] : '') . "\n"; /*$typehint = false; foreach($service['types'] as $type) { if($type['class'] == $param[0]) { $typehint = true; } } $signature[] = ($typehint) ? implode(' ', $param) : $param[1];*/