From cc7fb382d74b1a768e0aedd5ed92c951b91019fb Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Wed, 6 Jul 2011 18:48:08 +0100 Subject: [PATCH] MDL-20804 Improve the automatically generated WSDL. Note that this is currently very much a proof-of-concept implementation. It should receive a lot of careful testing and review before we think about integrating it. --- webservice/lib.php | 61 +++++++++++++++++------------------- webservice/soap/locallib.php | 26 +++++++++++++++ 2 files changed, 55 insertions(+), 32 deletions(-) diff --git a/webservice/lib.php b/webservice/lib.php index 72ebffbd9a9..684a541d94b 100644 --- a/webservice/lib.php +++ b/webservice/lib.php @@ -924,22 +924,7 @@ class '.$classname.' { } $params[] = $param; $paramanddefaults[] = $paramanddefault; - $type = 'string'; - if ($keydesc instanceof external_value) { - switch($keydesc->type) { - case PARAM_BOOL: // 0 or 1 only for now - case PARAM_INT: - $type = 'int'; break; - case PARAM_FLOAT; - $type = 'double'; break; - default: - $type = 'string'; - } - } else if ($keydesc instanceof external_single_structure) { - $type = 'object|struct'; - } else if ($keydesc instanceof external_multiple_structure) { - $type = 'array'; - } + $type = $this->get_phpdoc_type($keydesc); $params_desc[] = ' * @param '.$type.' $'.$name.' '.$keydesc->desc; } $params = implode(', ', $params); @@ -951,22 +936,7 @@ class '.$classname.' { if (is_null($function->returns_desc)) { $return = ' * @return void'; } else { - $type = 'string'; - if ($function->returns_desc instanceof external_value) { - switch($function->returns_desc->type) { - case PARAM_BOOL: // 0 or 1 only for now - case PARAM_INT: - $type = 'int'; break; - case PARAM_FLOAT; - $type = 'double'; break; - default: - $type = 'string'; - } - } else if ($function->returns_desc instanceof external_single_structure) { - $type = 'object|struct'; //only 'object' is supported by SOAP, 'struct' by XML-RPC MDL-23083 - } else if ($function->returns_desc instanceof external_multiple_structure) { - $type = 'array'; - } + $type = $this->get_phpdoc_type($function->returns_desc); $return = ' * @return '.$type.' '.$function->returns_desc->desc; } @@ -986,6 +956,33 @@ class '.$classname.' { return $code; } + protected function get_phpdoc_type($keydesc) { + if ($keydesc instanceof external_value) { + switch($keydesc->type) { + case PARAM_BOOL: // 0 or 1 only for now + case PARAM_INT: + $type = 'int'; break; + case PARAM_FLOAT; + $type = 'double'; break; + default: + $type = 'string'; + } + + } else if ($keydesc instanceof external_single_structure) { + $classname = $this->generate_simple_struct_class($keydesc); + $type = $classname; + + } else if ($keydesc instanceof external_multiple_structure) { + $type = 'array'; + } + + return $type; + } + + protected function generate_simple_struct_class(external_single_structure $structdesc) { + return 'object|struct'; //only 'object' is supported by SOAP, 'struct' by XML-RPC MDL-23083 + } + /** * You can override this function in your child class to add extra code into the dynamically * created service class. For example it is used in the amf server to cast types of parameters and to diff --git a/webservice/soap/locallib.php b/webservice/soap/locallib.php index 02e262b19ad..e4d8b8c536f 100644 --- a/webservice/soap/locallib.php +++ b/webservice/soap/locallib.php @@ -134,6 +134,32 @@ class webservice_soap_server extends webservice_zend_server { echo $xml; } + + protected function generate_simple_struct_class(external_single_structure $structdesc) { + // let's use unique class name, there might be problem in unit tests + $classname = 'webservices_struct_class_000000'; + while(class_exists($classname)) { + $classname++; + } + + $fields = array(); + foreach ($structdesc->keys as $name => $fieldsdesc) { + $type = $this->get_phpdoc_type($fieldsdesc); + $fields[] = ' /** @var '.$type." */\n" . + ' public $'.$name.';'; + } + + $code = ' +/** + * Virtual struct class for web services for user id '.$USER->id.' in context '.$this->restricted_context->id.'. + */ +class '.$classname.' { +'.implode("\n", $fields).' +} +'; + eval($code); + return $classname; + } } /**