3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
10 namespace Zend\Soap\Server
;
13 use Zend\Soap\Exception
;
16 * Wraps WSDL Document/Literal Style service objects to hide SOAP request
17 * message abstraction from the actual service object.
19 * When using the document/literal SOAP message pattern you end up with one
20 * object passed to your service methods that contains all the parameters of
21 * the method. This obviously leads to a problem since Zend\Soap\Wsdl tightly
22 * couples method parameters to request message parameters.
26 * class MyCalculatorService
33 * public function add($x, $y) {}
36 * The document/literal wrapper pattern would lead php ext/soap to generate a
37 * single "request" object that contains $x and $y properties. To solve this a
38 * wrapper service is needed that extracts the properties and delegates a
39 * proper call to the underlying service.
41 * The input variable from a document/literal SOAP-call to the client
42 * MyCalculatorServiceClient#add(10, 20) would lead PHP ext/soap to create
43 * the following request object:
45 * $addRequest = new \stdClass;
46 * $addRequest->x = 10;
47 * $addRequest->y = 20;
49 * This object does not match the signature of the server-side
50 * MyCalculatorService and lead to failure.
52 * Also the response object in this case is supposed to be an array
53 * or object with a property "addResult":
55 * $addResponse = new \stdClass;
56 * $addResponse->addResult = 30;
58 * To keep your service object code free from this implementation detail
59 * of SOAP this wrapper service handles the parsing between the formats.
63 * $service = new MyCalculatorService();
64 * $soap = new \Zend\Soap\Server($wsdlFile);
65 * $soap->setObject(new \Zend\Soap\Server\DocumentLiteralWrapper($service));
69 class DocumentLiteralWrapper
77 * @var ReflectionObject
79 protected $reflection;
82 * Pass Service object to the constructor
84 * @param object $object
86 public function __construct($object)
88 $this->object = $object;
89 $this->reflection
= new ReflectionObject($this->object);
93 * Proxy method that does the heavy document/literal decomposing.
95 * @param string $method
99 public function __call($method, $args)
101 $this->_assertOnlyOneArgument($args);
102 $this->_assertServiceDelegateHasMethod($method);
104 $delegateArgs = $this->_parseArguments($method, $args[0]);
105 $ret = call_user_func_array(array($this->object, $method), $delegateArgs);
106 return $this->_getResultMessage($method, $ret);
110 * Parse the document/literal wrapper into arguments to call the real
113 * @param string $method
114 * @param object $document
116 * @throws Exception\UnexpectedValueException
118 protected function _parseArguments($method, $document)
120 $reflMethod = $this->reflection
->getMethod($method);
122 foreach ($reflMethod->getParameters() as $param) {
123 $params[$param->getName()] = $param;
126 $delegateArgs = array();
127 foreach (get_object_vars($document) as $argName => $argValue) {
128 if (!isset($params[$argName])) {
129 throw new Exception\
UnexpectedValueException(sprintf(
130 "Received unknown argument %s which is not an argument to %s::%s",
132 get_class($this->object),
136 $delegateArgs[$params[$argName]->getPosition()] = $argValue;
139 return $delegateArgs;
143 * Returns result message content
145 * @param string $method
149 protected function _getResultMessage($method, $ret)
151 return array($method . 'Result' => $ret);
155 * @param string $method
156 * @throws Exception\BadMethodCallException
158 protected function _assertServiceDelegateHasMethod($method)
160 if (!$this->reflection
->hasMethod($method)) {
161 throw new Exception\
BadMethodCallException(sprintf(
162 "Method %s does not exist on delegate object %s",
164 get_class($this->object)
171 * @throws Exception\UnexpectedValueException
173 protected function _assertOnlyOneArgument(array $args)
175 if (count($args) != 1) {
176 throw new Exception\
UnexpectedValueException(sprintf(
177 "Expecting exactly one argument that is the document/literal wrapper, got %d",