/** * Add a function to the WSDL document. * * @param Zend_Server_Reflection_Function_Abstract $function function to add * @param Zend_Soap_Wsdl $wsdl WSDL document * @param object $port wsdl:portType * @param object $binding wsdl:binding * @return void */ protected function _addFunctionToWsdl($function, $wsdl, $port, $binding) { $uri = $this->getUri(); // We only support one prototype: the one with the maximum number of arguments $prototype = null; $maxNumArgumentsOfPrototype = -1; foreach ($function->getPrototypes() as $tmpPrototype) { $numParams = count($tmpPrototype->getParameters()); if ($numParams > $maxNumArgumentsOfPrototype) { $maxNumArgumentsOfPrototype = $numParams; $prototype = $tmpPrototype; } } if ($prototype === null) { require_once "Zend/Soap/AutoDiscover/Exception.php"; throw new Zend_Soap_AutoDiscover_Exception("No prototypes could be found for the '" . $function->getName() . "' function"); } // Add the input message (parameters) $args = array(); if ($this->_bindingStyle['style'] == 'document') { // Document style: wrap all parameters in a sequence element $sequence = array(); foreach ($prototype->getParameters() as $param) { $sequenceElement = array('name' => $param->getName(), 'type' => $wsdl->getType($param->getType())); if ($param->isOptional()) { $sequenceElement['nillable'] = 'true'; } $sequence[] = $sequenceElement; } $element = array('name' => $function->getName(), 'sequence' => $sequence); // Add the wrapper element part, which must be named 'parameters' $args['parameters'] = array('element' => $wsdl->addElement($element)); } else { // RPC style: add each parameter as a typed part foreach ($prototype->getParameters() as $param) { $args[$param->getName()] = array('type' => $wsdl->getType($param->getType())); } } $wsdl->addMessage($function->getName() . 'In', $args); $isOneWayMessage = false; if ($prototype->getReturnType() == "void") { $isOneWayMessage = true; } if ($isOneWayMessage == false) { // Add the output message (return value) $args = array(); if ($this->_bindingStyle['style'] == 'document') { // Document style: wrap the return value in a sequence element $sequence = array(); if ($prototype->getReturnType() != "void") { $sequence[] = array('name' => $function->getName() . 'Result', 'type' => $wsdl->getType($prototype->getReturnType())); } $element = array('name' => $function->getName() . 'Response', 'sequence' => $sequence); // Add the wrapper element part, which must be named 'parameters' $args['parameters'] = array('element' => $wsdl->addElement($element)); } else { if ($prototype->getReturnType() != "void") { // RPC style: add the return value as a typed part $args['return'] = array('type' => $wsdl->getType($prototype->getReturnType())); } } $wsdl->addMessage($function->getName() . 'Out', $args); } // Add the portType operation if ($isOneWayMessage == false) { $portOperation = $wsdl->addPortOperation($port, $function->getName(), 'tns:' . $function->getName() . 'In', 'tns:' . $function->getName() . 'Out'); } else { $portOperation = $wsdl->addPortOperation($port, $function->getName(), 'tns:' . $function->getName() . 'In', false); } $desc = $function->getDescription(); if (strlen($desc) > 0) { $wsdl->addDocumentation($portOperation, $desc); } // When using the RPC style, make sure the operation style includes a 'namespace' attribute (WS-I Basic Profile 1.1 R2717) if ($this->_bindingStyle['style'] == 'rpc' && !isset($this->_operationBodyStyle['namespace'])) { $this->_operationBodyStyle['namespace'] = '' . $uri; } // Add the binding operation if ($isOneWayMessage == false) { $operation = $wsdl->addBindingOperation($binding, $function->getName(), $this->_operationBodyStyle, $this->_operationBodyStyle); } else { $operation = $wsdl->addBindingOperation($binding, $function->getName(), $this->_operationBodyStyle); } $wsdl->addSoapOperation($operation, $uri . '#' . $function->getName()); // Add the function name to the list $this->_functions[] = $function->getName(); }
/** * Build a method signature * * @param Zend_Server_Reflection_Function_Abstract $reflection * @param null|string|object $class * @return Zend_Server_Method_Definition * @throws Zend_Server_Exception on duplicate entry */ protected function _buildSignature(Zend_Server_Reflection_Function_Abstract $reflection, $class = null) { $ns = $reflection->getNamespace(); $name = $reflection->getName(); $method = empty($ns) ? $name : $ns . '.' . $name; if (!$this->_overwriteExistingMethods && $this->_table->hasMethod($method)) { #require_once 'Zend/Server/Exception.php'; throw new Zend_Server_Exception('Duplicate method registered: ' . $method); } $definition = new Zend_Server_Method_Definition(); $definition->setName($method)->setCallback($this->_buildCallback($reflection))->setMethodHelp($reflection->getDescription())->setInvokeArguments($reflection->getInvokeArguments()); foreach ($reflection->getPrototypes() as $proto) { $prototype = new Zend_Server_Method_Prototype(); $prototype->setReturnType($this->_fixType($proto->getReturnType())); foreach ($proto->getParameters() as $parameter) { $param = new Zend_Server_Method_Parameter(array('type' => $this->_fixType($parameter->getType()), 'name' => $parameter->getName(), 'optional' => $parameter->isOptional())); if ($parameter->isDefaultValueAvailable()) { $param->setDefaultValue($parameter->getDefaultValue()); } $prototype->addParameter($param); } $definition->addPrototype($prototype); } if (is_object($class)) { $definition->setObject($class); } $this->_table->addMethod($definition); return $definition; }
/** * Dispatch method * * @param Zend_Server_Reflection_Function_Abstract $invocable * @param array $params * @return mixed */ protected function _dispatch(Zend_Server_Reflection_Function_Abstract $invocable, array $params) { if ($invocable instanceof Zend_Server_Reflection_Function) { $function = $invocable->getName(); return call_user_func_array($function, $params); } $class = $invocable->getDeclaringClass(); $object = $class->newInstance(); return $invocable->invokeArgs($object, $params); }
/** * Given some sort of Zend Reflection function/method object, return a profile array, ready to be serialized and stored * * @param Zend_Server_Reflection_Function_Abstract $function can be any subclass of this object type * * @return array */ function admin_mnet_method_profile(Zend_Server_Reflection_Function_Abstract $function) { $protos = $function->getPrototypes(); $proto = array_pop($protos); $ret = $proto->getReturnValue(); $profile = array( 'parameters' => array(), 'return' => array( 'type' => $ret->getType(), 'description' => $ret->getDescription(), ), ); foreach ($proto->getParameters() as $p) { $profile['parameters'][] = array( 'name' => $p->getName(), 'type' => $p->getType(), 'description' => $p->getDescription(), ); } return $profile; }
/** * Map PHP parameter types to XML-RPC types * * @param Zend_Server_Reflection_Function_Abstract $method * @return void */ protected function _fixTypes(Zend_Server_Reflection_Function_Abstract $method) { foreach ($method->getPrototypes() as $prototype) { foreach ($prototype->getParameters() as $param) { $pType = $param->getType(); if (isset($this->_typeMap[$pType])) { $param->setType($this->_typeMap[$pType]); } else { $param->setType('void'); } } } }