123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386 |
- <?php
- /**
- *
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\Webapi\Model\Soap\Wsdl;
- use Magento\Webapi\Model\AbstractSchemaGenerator;
- use Magento\Webapi\Model\Soap\Fault;
- use Magento\Webapi\Model\Soap\Wsdl;
- use Magento\Webapi\Model\Soap\WsdlFactory;
- use Magento\Framework\Webapi\Authorization;
- use Magento\Webapi\Model\ServiceMetadata;
- use Magento\Framework\Exception\AuthorizationException;
- /**
- * WSDL generator.
- */
- class Generator extends AbstractSchemaGenerator
- {
- /** WSDL name */
- const WSDL_NAME = 'MagentoWSDL';
- /**
- * WSDL factory instance.
- *
- * @var WsdlFactory
- */
- protected $_wsdlFactory;
- /**
- * Initialize dependencies.
- *
- * @param \Magento\Webapi\Model\Cache\Type\Webapi $cache
- * @param \Magento\Framework\Reflection\TypeProcessor $typeProcessor
- * @param \Magento\Framework\Webapi\CustomAttribute\ServiceTypeListInterface $serviceTypeList
- * @param \Magento\Webapi\Model\ServiceMetadata $serviceMetadata
- * @param Authorization $authorization
- * @param WsdlFactory $wsdlFactory
- */
- public function __construct(
- \Magento\Webapi\Model\Cache\Type\Webapi $cache,
- \Magento\Framework\Reflection\TypeProcessor $typeProcessor,
- \Magento\Framework\Webapi\CustomAttribute\ServiceTypeListInterface $serviceTypeList,
- \Magento\Webapi\Model\ServiceMetadata $serviceMetadata,
- Authorization $authorization,
- WsdlFactory $wsdlFactory
- ) {
- $this->_wsdlFactory = $wsdlFactory;
- parent::__construct(
- $cache,
- $typeProcessor,
- $serviceTypeList,
- $serviceMetadata,
- $authorization
- );
- }
- /**
- * {@inheritdoc}
- */
- protected function generateSchema($requestedServiceMetadata, $requestScheme, $requestHost, $endPointUrl)
- {
- $wsdl = $this->_wsdlFactory->create(self::WSDL_NAME, $endPointUrl);
- $wsdl->addSchemaTypeSection();
- $faultMessageName = $this->_addGenericFaultComplexTypeNodes($wsdl);
- $wsdl = $this->addCustomAttributeTypes($wsdl);
- foreach ($requestedServiceMetadata as $serviceClass => &$serviceData) {
- $portTypeName = $this->getPortTypeName($serviceClass);
- $bindingName = $this->getBindingName($serviceClass);
- $portType = $wsdl->addPortType($portTypeName);
- $binding = $wsdl->addBinding($bindingName, Wsdl::TYPES_NS . ':' . $portTypeName);
- $wsdl->addSoapBinding($binding, 'document', 'http://schemas.xmlsoap.org/soap/http', SOAP_1_2);
- $portName = $this->getPortName($serviceClass);
- $serviceName = $this->getServiceName($serviceClass);
- $wsdl->addService($serviceName, $portName, Wsdl::TYPES_NS . ':' . $bindingName, $endPointUrl, SOAP_1_2);
- foreach ($serviceData[ServiceMetadata::KEY_SERVICE_METHODS] as $methodName => $methodData) {
- $operationName = $this->typeProcessor->getOperationName($serviceClass, $methodName);
- $bindingDataPrototype = ['use' => 'literal'];
- $inputBinding = $bindingDataPrototype;
- $inputMessageName = $this->_createOperationInput($wsdl, $operationName, $methodData);
- $outputMessageName = false;
- $outputBinding = false;
- if (isset($methodData['interface']['out']['parameters'])) {
- $outputBinding = $bindingDataPrototype;
- $outputMessageName = $this->_createOperationOutput($wsdl, $operationName, $methodData);
- }
- $faultBinding = ['name' => Fault::NODE_DETAIL_WRAPPER];
- $wsdl->addPortOperation(
- $portType,
- $operationName,
- $inputMessageName,
- $outputMessageName,
- ['message' => $faultMessageName, 'name' => Fault::NODE_DETAIL_WRAPPER]
- );
- $bindingOperation = $wsdl->addBindingOperation(
- $binding,
- $operationName,
- $inputBinding,
- $outputBinding,
- $faultBinding,
- SOAP_1_2
- );
- $wsdl->addSoapOperation($bindingOperation, $operationName, SOAP_1_2);
- }
- }
- return $wsdl->toXML();
- }
- /**
- * Create and add WSDL Types for complex custom attribute classes
- *
- * @param \Magento\Webapi\Model\Soap\Wsdl $wsdl
- * @return \Magento\Webapi\Model\Soap\Wsdl
- */
- protected function addCustomAttributeTypes($wsdl)
- {
- foreach ($this->serviceTypeList->getDataTypes() as $customAttributeClass) {
- $typeName = $this->typeProcessor->register($customAttributeClass);
- $wsdl->addComplexType($this->typeProcessor->getArrayItemType($typeName));
- }
- return $wsdl;
- }
- /**
- * Create input message and corresponding element and complex types in WSDL.
- *
- * @param Wsdl $wsdl
- * @param string $operationName
- * @param array $methodData
- * @return string input message name
- */
- protected function _createOperationInput(Wsdl $wsdl, $operationName, $methodData)
- {
- $inputMessageName = $this->getInputMessageName($operationName);
- $complexTypeName = $this->getElementComplexTypeName($inputMessageName);
- $inputParameters = [];
- $elementData = [
- 'name' => $inputMessageName,
- 'type' => Wsdl::TYPES_NS . ':' . $complexTypeName,
- ];
- if (isset($methodData['interface']['in']['parameters'])) {
- $inputParameters = $methodData['interface']['in']['parameters'];
- } else {
- $elementData['nillable'] = 'true';
- }
- $wsdl->addElement($elementData);
- $callInfo = [];
- $callInfo['requiredInput']['yes']['calls'] = [$operationName];
- $typeData = [
- 'documentation' => $methodData['documentation'],
- 'parameters' => $inputParameters,
- 'callInfo' => $callInfo,
- ];
- $this->typeProcessor->setTypeData($complexTypeName, $typeData);
- $wsdl->addComplexType($complexTypeName);
- $wsdl->addMessage(
- $inputMessageName,
- [
- 'messageParameters' => [
- 'element' => Wsdl::TYPES_NS . ':' . $inputMessageName,
- ]
- ]
- );
- return Wsdl::TYPES_NS . ':' . $inputMessageName;
- }
- /**
- * Create output message and corresponding element and complex types in WSDL.
- *
- * @param Wsdl $wsdl
- * @param string $operationName
- * @param array $methodData
- * @return string output message name
- */
- protected function _createOperationOutput(Wsdl $wsdl, $operationName, $methodData)
- {
- $outputMessageName = $this->getOutputMessageName($operationName);
- $complexTypeName = $this->getElementComplexTypeName($outputMessageName);
- $wsdl->addElement(
- [
- 'name' => $outputMessageName,
- 'type' => Wsdl::TYPES_NS . ':' . $complexTypeName,
- ]
- );
- $callInfo = [];
- $callInfo['returned']['always']['calls'] = [$operationName];
- $typeData = [
- 'documentation' => sprintf('Response container for the %s call.', $operationName),
- 'parameters' => $methodData['interface']['out']['parameters'],
- 'callInfo' => $callInfo,
- ];
- $this->typeProcessor->setTypeData($complexTypeName, $typeData);
- $wsdl->addComplexType($complexTypeName);
- $wsdl->addMessage(
- $outputMessageName,
- [
- 'messageParameters' => [
- 'element' => Wsdl::TYPES_NS . ':' . $outputMessageName,
- ]
- ]
- );
- return Wsdl::TYPES_NS . ':' . $outputMessageName;
- }
- /**
- * Get name for service portType node.
- *
- * @param string $serviceName
- * @return string
- */
- public function getPortTypeName($serviceName)
- {
- return $serviceName . 'PortType';
- }
- /**
- * Get name for service binding node.
- *
- * @param string $serviceName
- * @return string
- */
- public function getBindingName($serviceName)
- {
- return $serviceName . 'Binding';
- }
- /**
- * Get name for service port node.
- *
- * @param string $serviceName
- * @return string
- */
- public function getPortName($serviceName)
- {
- return $serviceName . 'Port';
- }
- /**
- * Get name for service service.
- *
- * @param string $serviceName
- * @return string
- */
- public function getServiceName($serviceName)
- {
- return $serviceName . 'Service';
- }
- /**
- * Get input message node name for operation.
- *
- * @param string $operationName
- * @return string
- */
- public function getInputMessageName($operationName)
- {
- return $operationName . 'Request';
- }
- /**
- * Get output message node name for operation.
- *
- * @param string $operationName
- * @return string
- */
- public function getOutputMessageName($operationName)
- {
- return $operationName . 'Response';
- }
- /**
- * Add WSDL elements related to generic SOAP fault, which are common for all operations: element, type and message.
- *
- * @param Wsdl $wsdl
- * @return string Default fault message name
- */
- protected function _addGenericFaultComplexTypeNodes($wsdl)
- {
- $faultMessageName = Fault::NODE_DETAIL_WRAPPER;
- $complexTypeName = $this->getElementComplexTypeName($faultMessageName);
- $wsdl->addElement(
- [
- 'name' => $faultMessageName,
- 'type' => Wsdl::TYPES_NS . ':' . $complexTypeName,
- ]
- );
- $faultParamsComplexType = Fault::NODE_DETAIL_PARAMETER;
- $faultParamsData = [
- 'parameters' => [
- Fault::NODE_DETAIL_PARAMETER_KEY => [
- 'type' => 'string',
- 'required' => true,
- 'documentation' => '',
- ],
- Fault::NODE_DETAIL_PARAMETER_VALUE => [
- 'type' => 'string',
- 'required' => true,
- 'documentation' => '',
- ],
- ],
- ];
- $wrappedErrorComplexType = Fault::NODE_DETAIL_WRAPPED_ERROR;
- $wrappedErrorData = [
- 'parameters' => [
- Fault::NODE_DETAIL_WRAPPED_ERROR_MESSAGE => [
- 'type' => 'string',
- 'required' => true,
- 'documentation' => '',
- ],
- Fault::NODE_DETAIL_WRAPPED_ERROR_PARAMETERS => [
- 'type' => "{$faultParamsComplexType}[]",
- 'required' => false,
- 'documentation' => 'Message parameters.',
- ],
- ],
- ];
- $genericFaultTypeData = [
- 'parameters' => [
- Fault::NODE_DETAIL_TRACE => [
- 'type' => 'string',
- 'required' => false,
- 'documentation' => 'Exception calls stack trace.',
- ],
- Fault::NODE_DETAIL_PARAMETERS => [
- 'type' => "{$faultParamsComplexType}[]",
- 'required' => false,
- 'documentation' => 'Additional exception parameters.',
- ],
- Fault::NODE_DETAIL_WRAPPED_ERRORS => [
- 'type' => "{$wrappedErrorComplexType}[]",
- 'required' => false,
- 'documentation' => 'Additional wrapped errors.',
- ],
- ],
- ];
- $this->typeProcessor->setTypeData($faultParamsComplexType, $faultParamsData);
- $this->typeProcessor->setTypeData($wrappedErrorComplexType, $wrappedErrorData);
- $this->typeProcessor->setTypeData($complexTypeName, $genericFaultTypeData);
- $wsdl->addComplexType($complexTypeName);
- $wsdl->addMessage(
- $faultMessageName,
- [
- 'messageParameters' => [
- 'element' => Wsdl::TYPES_NS . ':' . $faultMessageName,
- ]
- ]
- );
- return Wsdl::TYPES_NS . ':' . $faultMessageName;
- }
- /**
- * Get service metadata
- *
- * @param string $serviceName
- * @return array
- */
- protected function getServiceMetadata($serviceName)
- {
- return $this->serviceMetadata->getServiceMetadata($serviceName);
- }
- /**
- * {@inheritdoc}
- */
- protected function getAllowedServicesMetadata($requestedServices)
- {
- $allowedServicesMetadata = parent::getAllowedServicesMetadata($requestedServices);
- if (!$allowedServicesMetadata) {
- throw new AuthorizationException(
- __(
- "The consumer isn't authorized to access %resources.",
- ['resources' => implode(', ', $requestedServices)]
- )
- );
- }
- return $allowedServicesMetadata;
- }
- }
|