Soap.php 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. <?php
  2. /**
  3. * Front controller for WebAPI SOAP area.
  4. *
  5. * Copyright © Magento, Inc. All rights reserved.
  6. * See COPYING.txt for license details.
  7. */
  8. namespace Magento\Webapi\Controller;
  9. use Magento\Framework\Webapi\ErrorProcessor;
  10. use Magento\Framework\Webapi\Request;
  11. use Magento\Framework\Webapi\Response;
  12. /**
  13. *
  14. * SOAP Web API entry point.
  15. *
  16. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  17. */
  18. class Soap implements \Magento\Framework\App\FrontControllerInterface
  19. {
  20. /**#@+
  21. * Content types used for responses processed by SOAP web API.
  22. */
  23. const CONTENT_TYPE_SOAP_CALL = 'application/soap+xml';
  24. const CONTENT_TYPE_WSDL_REQUEST = 'text/xml';
  25. /**#@-*/
  26. /**#@-*/
  27. protected $_soapServer;
  28. /**
  29. * @var \Magento\Webapi\Model\Soap\Wsdl\Generator
  30. */
  31. protected $_wsdlGenerator;
  32. /**
  33. * @var Request
  34. */
  35. protected $_request;
  36. /**
  37. * @var Response
  38. */
  39. protected $_response;
  40. /**
  41. * @var ErrorProcessor
  42. */
  43. protected $_errorProcessor;
  44. /**
  45. * @var \Magento\Framework\App\State
  46. */
  47. protected $_appState;
  48. /**
  49. * @var \Magento\Framework\Locale\ResolverInterface
  50. */
  51. protected $_localeResolver;
  52. /**
  53. * @var PathProcessor
  54. */
  55. protected $_pathProcessor;
  56. /**
  57. * @var \Magento\Framework\App\AreaList
  58. */
  59. protected $areaList;
  60. /**
  61. * @var \Magento\Framework\Webapi\Rest\Response\RendererFactory
  62. */
  63. protected $rendererFactory;
  64. /**
  65. * @param Request $request
  66. * @param Response $response
  67. * @param \Magento\Webapi\Model\Soap\Wsdl\Generator $wsdlGenerator
  68. * @param \Magento\Webapi\Model\Soap\Server $soapServer
  69. * @param ErrorProcessor $errorProcessor
  70. * @param \Magento\Framework\App\State $appState
  71. * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
  72. * @param PathProcessor $pathProcessor
  73. * @param \Magento\Framework\Webapi\Rest\Response\RendererFactory $rendererFactory
  74. * @param \Magento\Framework\App\AreaList $areaList
  75. * @SuppressWarnings(PHPMD.ExcessiveParameterList)
  76. */
  77. public function __construct(
  78. Request $request,
  79. \Magento\Framework\Webapi\Response $response,
  80. \Magento\Webapi\Model\Soap\Wsdl\Generator $wsdlGenerator,
  81. \Magento\Webapi\Model\Soap\Server $soapServer,
  82. ErrorProcessor $errorProcessor,
  83. \Magento\Framework\App\State $appState,
  84. \Magento\Framework\Locale\ResolverInterface $localeResolver,
  85. PathProcessor $pathProcessor,
  86. \Magento\Framework\Webapi\Rest\Response\RendererFactory $rendererFactory,
  87. \Magento\Framework\App\AreaList $areaList
  88. ) {
  89. $this->_request = $request;
  90. $this->_response = $response;
  91. $this->_wsdlGenerator = $wsdlGenerator;
  92. $this->_soapServer = $soapServer;
  93. $this->_errorProcessor = $errorProcessor;
  94. $this->_appState = $appState;
  95. $this->_localeResolver = $localeResolver;
  96. $this->_pathProcessor = $pathProcessor;
  97. $this->areaList = $areaList;
  98. $this->rendererFactory = $rendererFactory;
  99. }
  100. /**
  101. * Dispatch SOAP request.
  102. *
  103. * @param \Magento\Framework\App\RequestInterface $request
  104. * @return \Magento\Framework\App\ResponseInterface
  105. */
  106. public function dispatch(\Magento\Framework\App\RequestInterface $request)
  107. {
  108. $path = $this->_pathProcessor->process($request->getPathInfo());
  109. $this->_request->setPathInfo($path);
  110. $this->areaList->getArea($this->_appState->getAreaCode())->load(\Magento\Framework\App\Area::PART_TRANSLATE);
  111. try {
  112. if ($this->_isWsdlRequest()) {
  113. $this->validateWsdlRequest();
  114. $responseBody = $this->_wsdlGenerator->generate(
  115. $this->_request->getRequestedServices(),
  116. $this->_request->getScheme(),
  117. $this->_request->getHttpHost(),
  118. $this->_soapServer->generateUri()
  119. );
  120. $this->_setResponseContentType(self::CONTENT_TYPE_WSDL_REQUEST);
  121. $this->_setResponseBody($responseBody);
  122. } elseif ($this->_isWsdlListRequest()) {
  123. $servicesList = [];
  124. foreach ($this->_wsdlGenerator->getListOfServices() as $serviceName) {
  125. $servicesList[$serviceName]['wsdl_endpoint'] = $this->_soapServer->getEndpointUri()
  126. . '?' . \Magento\Webapi\Model\Soap\Server::REQUEST_PARAM_WSDL . '&services=' . $serviceName;
  127. }
  128. $renderer = $this->rendererFactory->get();
  129. $this->_setResponseContentType($renderer->getMimeType());
  130. $this->_setResponseBody($renderer->render($servicesList));
  131. } else {
  132. $this->_soapServer->handle();
  133. }
  134. } catch (\Exception $e) {
  135. $this->_prepareErrorResponse($e);
  136. }
  137. return $this->_response;
  138. }
  139. /**
  140. * Check if current request is WSDL request. SOAP operation execution request is another type of requests.
  141. *
  142. * @return bool
  143. */
  144. protected function _isWsdlRequest()
  145. {
  146. return $this->_request->getParam(\Magento\Webapi\Model\Soap\Server::REQUEST_PARAM_WSDL) !== null;
  147. }
  148. /**
  149. * Check if current request is WSDL request. SOAP operation execution request is another type of requests.
  150. *
  151. * @return bool
  152. */
  153. protected function _isWsdlListRequest()
  154. {
  155. return $this->_request->getParam(\Magento\Webapi\Model\Soap\Server::REQUEST_PARAM_LIST_WSDL) !== null;
  156. }
  157. /**
  158. * Set body and status code to response using information extracted from provided exception.
  159. *
  160. * @param \Exception $exception
  161. * @return void
  162. */
  163. protected function _prepareErrorResponse($exception)
  164. {
  165. $maskedException = $this->_errorProcessor->maskException($exception);
  166. if ($this->_isWsdlRequest()) {
  167. $httpCode = $maskedException->getHttpCode();
  168. $contentType = self::CONTENT_TYPE_WSDL_REQUEST;
  169. } else {
  170. $httpCode = Response::HTTP_OK;
  171. $contentType = self::CONTENT_TYPE_SOAP_CALL;
  172. }
  173. $this->_setResponseContentType($contentType);
  174. $this->_response->setHttpResponseCode($httpCode);
  175. $soapFault = new \Magento\Webapi\Model\Soap\Fault(
  176. $this->_request,
  177. $this->_soapServer,
  178. $maskedException,
  179. $this->_localeResolver,
  180. $this->_appState
  181. );
  182. $this->_setResponseBody($soapFault->toXml());
  183. }
  184. /**
  185. * Set content type to response object.
  186. *
  187. * @param string $contentType
  188. * @return $this
  189. */
  190. protected function _setResponseContentType($contentType = 'text/xml')
  191. {
  192. $this->_response->clearHeaders()->setHeader(
  193. 'Content-Type',
  194. "{$contentType}; charset={$this->_soapServer->getApiCharset()}"
  195. );
  196. return $this;
  197. }
  198. /**
  199. * Replace WSDL xml encoding from config, if present, else default to UTF-8 and set it to the response object.
  200. *
  201. * @param string $responseBody
  202. * @return $this
  203. */
  204. protected function _setResponseBody($responseBody)
  205. {
  206. $this->_response->setBody(
  207. preg_replace(
  208. '/<\?xml version="([^\"]+)"([^\>]+)>/i',
  209. '<?xml version="$1" encoding="' . $this->_soapServer->getApiCharset() . '"?>',
  210. $responseBody
  211. )
  212. );
  213. return $this;
  214. }
  215. /**
  216. * Validate wsdl request
  217. *
  218. * @return void
  219. * @throws \Magento\Framework\Webapi\Exception
  220. */
  221. protected function validateWsdlRequest()
  222. {
  223. $wsdlParam = \Magento\Webapi\Model\Soap\Server::REQUEST_PARAM_WSDL;
  224. $servicesParam = Request::REQUEST_PARAM_SERVICES;
  225. $requestParams = array_keys($this->_request->getParams());
  226. $allowedParams = [$wsdlParam, $servicesParam];
  227. $notAllowedParameters = array_diff($requestParams, $allowedParams);
  228. if (count($notAllowedParameters)) {
  229. $notAllowed = implode(', ', $notAllowedParameters);
  230. $message = __(
  231. 'Not allowed parameters: %1. Please use only %2 and %3.',
  232. $notAllowed,
  233. $wsdlParam,
  234. $servicesParam
  235. );
  236. throw new \Magento\Framework\Webapi\Exception($message);
  237. }
  238. }
  239. }