1: <?php
2:
3: namespace wei;
4:
5: use SoapClient;
6:
7: /**
8: * A Soap client that works like HTTP service
9: *
10: * @author Twin Huang <twinhuang@qq.com>
11: */
12: class Soap extends Base
13: {
14: /**
15: * The request URL
16: *
17: * @var string
18: */
19: protected $url;
20:
21: /**
22: * The name of the SOAP function to call.
23: *
24: * @var string
25: */
26: protected $method;
27:
28: /**
29: * The parameters send to the SOAP function
30: *
31: * @var array
32: */
33: protected $data = array();
34:
35: /**
36: * Whether use the global options in `$wei->http` object when create a
37: * new object
38: *
39: * @var bool
40: */
41: protected $global = false;
42:
43: /**
44: * Whether throw exception or keep silent when request error
45: *
46: * Note that the exception is thrown after triggered complete callback, rather than triggered error callback
47: *
48: * @var bool
49: */
50: protected $throwException = true;
51:
52: /**
53: * A callback triggered after prepared the data and before the `beforeSend` callback
54: *
55: * @var callable
56: */
57: protected $beforeExecute;
58:
59: /**
60: * A callback triggered after prepared the data and before the process the request
61: *
62: * @var callable
63: */
64: protected $beforeSend;
65:
66: /**
67: * A callback triggered after the request is called success
68: *
69: * @var callable
70: */
71: protected $success;
72:
73: /**
74: * A callback triggered when the request fails
75: *
76: * The `$textStatus` could be `curl`, `http`, and `parser`
77: *
78: * @var callable
79: */
80: protected $error;
81:
82: /**
83: * A callback triggered when request finishes (after `success` and `error` callbacks are executed)
84: *
85: * @var callable
86: */
87: protected $complete;
88:
89: /**
90: * The parsed response data
91: *
92: * @var mixed
93: */
94: protected $response;
95:
96: /**
97: * The instance of soap client
98: *
99: * @var SoapClient
100: */
101: protected $soapClient;
102:
103: /**
104: * The error exception object
105: *
106: * @var \ErrorException
107: */
108: protected $errorException;
109:
110: /**
111: * The default options of current object
112: *
113: * @var array
114: */
115: private $defaultOptions;
116:
117: /**
118: * Constructor
119: *
120: * @param array $options
121: */
122: public function __construct(array $options = array())
123: {
124: // Merges options from default Soap service
125: if (isset($options['global']) && true == $options['global']) {
126: $options += (array)$options['wei']->getConfig('soap');
127: }
128: parent::__construct($options);
129: $this->defaultOptions = $options;
130: }
131:
132: /**
133: * Create a new Soap service and execute
134: *
135: * @param array $options A options array if the first parameter is string
136: * @return $this A new Soap object
137: */
138: public function __invoke(array $options = array())
139: {
140: $soap = new self($options + $this->defaultOptions);
141: return $soap->execute();
142: }
143:
144: /**
145: * Execute the request, parse the response data and trigger relative callbacks
146: */
147: public function execute()
148: {
149: try {
150: // Note that when provided a non-existing WSDL, PHP will still generate an error in error_get_last()
151: // https://github.com/bcosca/fatfree/issues/404
152: // https://bugs.php.net/bug.php?id=65779
153:
154: // Prepare request
155: $soapClient = $this->soapClient = new SoapClient($this->url, array(
156: 'trace' => $this->wei->isDebug()
157: ));
158:
159: // Execute beforeExecute and beforeSend callbacks
160: $this->beforeExecute && call_user_func($this->beforeExecute, $this, $soapClient);
161: $this->beforeSend && call_user_func($this->beforeSend, $this, $soapClient);
162:
163: // Execute request
164: $this->response = $soapClient->__soapCall($this->method, array($this->data));
165: } catch (\SoapFault $e) {
166: $soapClient = null;
167: $this->errorException = $e;
168: }
169:
170: // Trigger success, error and complete callbacks
171: if (!$this->errorException) {
172: $this->success && call_user_func($this->success, $this->response, $this, $soapClient);
173: } else {
174: $this->error && call_user_func($this->error, $this, $soapClient);
175: }
176: $this->complete && call_user_func($this->complete, $this, $soapClient);
177:
178: if ($this->throwException && $this->errorException) {
179: throw $this->errorException;
180: }
181:
182: return $this;
183: }
184:
185: /**
186: * Returns the parsed response data
187: *
188: * @return mixed
189: */
190: public function getResponse()
191: {
192: return $this->response;
193: }
194:
195: /**
196: * Returns the request URL
197: *
198: * @return string
199: */
200: public function getUrl()
201: {
202: return $this->url;
203: }
204:
205: /**
206: * Returns the request method
207: *
208: * @return string
209: */
210: public function getMethod()
211: {
212: return $this->method;
213: }
214:
215: /**
216: * Returns the data to send to the server
217: *
218: * @return array|string
219: */
220: public function getData()
221: {
222: return $this->data;
223: }
224:
225: /**
226: * Returns the error exception object
227: *
228: * @return \SoapFault
229: */
230: public function getErrorException()
231: {
232: return $this->errorException;
233: }
234: }