<?php /** * Front controller for WebAPI SOAP area. * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Webapi\Controller; use Magento\Framework\Webapi\ErrorProcessor; use Magento\Framework\Webapi\Request; use Magento\Framework\Webapi\Response; /** * * SOAP Web API entry point. * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Soap implements \Magento\Framework\App\FrontControllerInterface { /**#@+ * Content types used for responses processed by SOAP web API. */ const CONTENT_TYPE_SOAP_CALL = 'application/soap+xml'; const CONTENT_TYPE_WSDL_REQUEST = 'text/xml'; /**#@-*/ /**#@-*/ protected $_soapServer; /** * @var \Magento\Webapi\Model\Soap\Wsdl\Generator */ protected $_wsdlGenerator; /** * @var Request */ protected $_request; /** * @var Response */ protected $_response; /** * @var ErrorProcessor */ protected $_errorProcessor; /** * @var \Magento\Framework\App\State */ protected $_appState; /** * @var \Magento\Framework\Locale\ResolverInterface */ protected $_localeResolver; /** * @var PathProcessor */ protected $_pathProcessor; /** * @var \Magento\Framework\App\AreaList */ protected $areaList; /** * @var \Magento\Framework\Webapi\Rest\Response\RendererFactory */ protected $rendererFactory; /** * @param Request $request * @param Response $response * @param \Magento\Webapi\Model\Soap\Wsdl\Generator $wsdlGenerator * @param \Magento\Webapi\Model\Soap\Server $soapServer * @param ErrorProcessor $errorProcessor * @param \Magento\Framework\App\State $appState * @param \Magento\Framework\Locale\ResolverInterface $localeResolver * @param PathProcessor $pathProcessor * @param \Magento\Framework\Webapi\Rest\Response\RendererFactory $rendererFactory * @param \Magento\Framework\App\AreaList $areaList * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( Request $request, \Magento\Framework\Webapi\Response $response, \Magento\Webapi\Model\Soap\Wsdl\Generator $wsdlGenerator, \Magento\Webapi\Model\Soap\Server $soapServer, ErrorProcessor $errorProcessor, \Magento\Framework\App\State $appState, \Magento\Framework\Locale\ResolverInterface $localeResolver, PathProcessor $pathProcessor, \Magento\Framework\Webapi\Rest\Response\RendererFactory $rendererFactory, \Magento\Framework\App\AreaList $areaList ) { $this->_request = $request; $this->_response = $response; $this->_wsdlGenerator = $wsdlGenerator; $this->_soapServer = $soapServer; $this->_errorProcessor = $errorProcessor; $this->_appState = $appState; $this->_localeResolver = $localeResolver; $this->_pathProcessor = $pathProcessor; $this->areaList = $areaList; $this->rendererFactory = $rendererFactory; } /** * Dispatch SOAP request. * * @param \Magento\Framework\App\RequestInterface $request * @return \Magento\Framework\App\ResponseInterface */ public function dispatch(\Magento\Framework\App\RequestInterface $request) { $path = $this->_pathProcessor->process($request->getPathInfo()); $this->_request->setPathInfo($path); $this->areaList->getArea($this->_appState->getAreaCode())->load(\Magento\Framework\App\Area::PART_TRANSLATE); try { if ($this->_isWsdlRequest()) { $this->validateWsdlRequest(); $responseBody = $this->_wsdlGenerator->generate( $this->_request->getRequestedServices(), $this->_request->getScheme(), $this->_request->getHttpHost(), $this->_soapServer->generateUri() ); $this->_setResponseContentType(self::CONTENT_TYPE_WSDL_REQUEST); $this->_setResponseBody($responseBody); } elseif ($this->_isWsdlListRequest()) { $servicesList = []; foreach ($this->_wsdlGenerator->getListOfServices() as $serviceName) { $servicesList[$serviceName]['wsdl_endpoint'] = $this->_soapServer->getEndpointUri() . '?' . \Magento\Webapi\Model\Soap\Server::REQUEST_PARAM_WSDL . '&services=' . $serviceName; } $renderer = $this->rendererFactory->get(); $this->_setResponseContentType($renderer->getMimeType()); $this->_setResponseBody($renderer->render($servicesList)); } else { $this->_soapServer->handle(); } } catch (\Exception $e) { $this->_prepareErrorResponse($e); } return $this->_response; } /** * Check if current request is WSDL request. SOAP operation execution request is another type of requests. * * @return bool */ protected function _isWsdlRequest() { return $this->_request->getParam(\Magento\Webapi\Model\Soap\Server::REQUEST_PARAM_WSDL) !== null; } /** * Check if current request is WSDL request. SOAP operation execution request is another type of requests. * * @return bool */ protected function _isWsdlListRequest() { return $this->_request->getParam(\Magento\Webapi\Model\Soap\Server::REQUEST_PARAM_LIST_WSDL) !== null; } /** * Set body and status code to response using information extracted from provided exception. * * @param \Exception $exception * @return void */ protected function _prepareErrorResponse($exception) { $maskedException = $this->_errorProcessor->maskException($exception); if ($this->_isWsdlRequest()) { $httpCode = $maskedException->getHttpCode(); $contentType = self::CONTENT_TYPE_WSDL_REQUEST; } else { $httpCode = Response::HTTP_OK; $contentType = self::CONTENT_TYPE_SOAP_CALL; } $this->_setResponseContentType($contentType); $this->_response->setHttpResponseCode($httpCode); $soapFault = new \Magento\Webapi\Model\Soap\Fault( $this->_request, $this->_soapServer, $maskedException, $this->_localeResolver, $this->_appState ); $this->_setResponseBody($soapFault->toXml()); } /** * Set content type to response object. * * @param string $contentType * @return $this */ protected function _setResponseContentType($contentType = 'text/xml') { $this->_response->clearHeaders()->setHeader( 'Content-Type', "{$contentType}; charset={$this->_soapServer->getApiCharset()}" ); return $this; } /** * Replace WSDL xml encoding from config, if present, else default to UTF-8 and set it to the response object. * * @param string $responseBody * @return $this */ protected function _setResponseBody($responseBody) { $this->_response->setBody( preg_replace( '/<\?xml version="([^\"]+)"([^\>]+)>/i', '<?xml version="$1" encoding="' . $this->_soapServer->getApiCharset() . '"?>', $responseBody ) ); return $this; } /** * Validate wsdl request * * @return void * @throws \Magento\Framework\Webapi\Exception */ protected function validateWsdlRequest() { $wsdlParam = \Magento\Webapi\Model\Soap\Server::REQUEST_PARAM_WSDL; $servicesParam = Request::REQUEST_PARAM_SERVICES; $requestParams = array_keys($this->_request->getParams()); $allowedParams = [$wsdlParam, $servicesParam]; $notAllowedParameters = array_diff($requestParams, $allowedParams); if (count($notAllowedParameters)) { $notAllowed = implode(', ', $notAllowedParameters); $message = __( 'Not allowed parameters: %1. Please use only %2 and %3.', $notAllowed, $wsdlParam, $servicesParam ); throw new \Magento\Framework\Webapi\Exception($message); } } }