diff --git a/app/code/Magento/Catalog/Api/ProductRepositoryInterface.php b/app/code/Magento/Catalog/Api/ProductRepositoryInterface.php index 231145a71c5ed..18cf0bdec693c 100644 --- a/app/code/Magento/Catalog/Api/ProductRepositoryInterface.php +++ b/app/code/Magento/Catalog/Api/ProductRepositoryInterface.php @@ -29,7 +29,7 @@ public function save(\Magento\Catalog\Api\Data\ProductInterface $product, $saveO * * @param string $sku * @param bool $editMode - * @param null|int $storeId + * @param int|null $storeId * @param bool $forceReload * @return \Magento\Catalog\Api\Data\ProductInterface * @throws \Magento\Framework\Exception\NoSuchEntityException diff --git a/app/code/Magento/Quote/Api/GuestCartTotalManagementInterface.php b/app/code/Magento/Quote/Api/GuestCartTotalManagementInterface.php index ea6e2a873090a..80514761a7ba6 100644 --- a/app/code/Magento/Quote/Api/GuestCartTotalManagementInterface.php +++ b/app/code/Magento/Quote/Api/GuestCartTotalManagementInterface.php @@ -14,7 +14,7 @@ interface GuestCartTotalManagementInterface * Set shipping/billing methods and additional data for cart and collect totals for guest. * * @param string $cartId The cart ID. - * @param \Magento\Quote\Api\Data\PaymentInterface Payment method data. + * @param \Magento\Quote\Api\Data\PaymentInterface $paymentMethod Payment method data. * @param string $shippingCarrierCode The carrier code. * @param string $shippingMethodCode The shipping method code. * @param \Magento\Quote\Api\Data\TotalsAdditionalDataInterface $additionalData Additional data to collect totals. diff --git a/app/code/Magento/Webapi/Controller/Soap.php b/app/code/Magento/Webapi/Controller/Soap.php index 63d9968b49500..cc040657fd435 100644 --- a/app/code/Magento/Webapi/Controller/Soap.php +++ b/app/code/Magento/Webapi/Controller/Soap.php @@ -69,8 +69,11 @@ class Soap implements \Magento\Framework\App\FrontControllerInterface protected $areaList; /** - * Initialize dependencies. - * + * @var \Magento\Framework\Webapi\Rest\Response\RendererFactory + */ + protected $rendererFactory; + + /** * @param Soap\Request $request * @param Response $response * @param \Magento\Webapi\Model\Soap\Wsdl\Generator $wsdlGenerator @@ -79,7 +82,9 @@ class Soap implements \Magento\Framework\App\FrontControllerInterface * @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( \Magento\Webapi\Controller\Soap\Request $request, @@ -90,6 +95,7 @@ public function __construct( \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; @@ -101,6 +107,7 @@ public function __construct( $this->_localeResolver = $localeResolver; $this->_pathProcessor = $pathProcessor; $this->areaList = $areaList; + $this->rendererFactory = $rendererFactory; } /** @@ -122,6 +129,15 @@ public function dispatch(\Magento\Framework\App\RequestInterface $request) ); $this->_setResponseContentType(self::CONTENT_TYPE_WSDL_REQUEST); $this->_setResponseBody($responseBody); + } else if ($this->_isWsdlListRequest()) { + $servicesList = []; + foreach (array_keys($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(); } @@ -141,6 +157,16 @@ 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; + } + /** * Parse the Authorization header and return the access token e.g. Authorization: Bearer * diff --git a/app/code/Magento/Webapi/Model/Soap/Config.php b/app/code/Magento/Webapi/Model/Soap/Config.php index 70c89d3c12efd..98e38cd8424ab 100644 --- a/app/code/Magento/Webapi/Model/Soap/Config.php +++ b/app/code/Magento/Webapi/Model/Soap/Config.php @@ -141,7 +141,7 @@ protected function getSoapOperations($requestedServices) * * @return array */ - protected function getSoapServicesConfig() + public function getSoapServicesConfig() { if (null === $this->soapServices) { $soapServicesConfig = $this->cache->load(self::CACHE_ID); diff --git a/app/code/Magento/Webapi/Model/Soap/Config/ClassReflector.php b/app/code/Magento/Webapi/Model/Soap/Config/ClassReflector.php index 697b02cd9defa..1936cb89cae90 100644 --- a/app/code/Magento/Webapi/Model/Soap/Config/ClassReflector.php +++ b/app/code/Magento/Webapi/Model/Soap/Config/ClassReflector.php @@ -5,8 +5,6 @@ */ namespace Magento\Webapi\Model\Soap\Config; -use Zend\Server\Reflection; -use Zend\Server\Reflection\ReflectionMethod; use Zend\Code\Reflection\MethodReflection; /** @@ -66,8 +64,8 @@ public function __construct(\Magento\Framework\Reflection\TypeProcessor $typePro public function reflectClassMethods($className, $methods) { $data = []; - $classReflection = new \Zend\Server\Reflection\ReflectionClass(new \ReflectionClass($className)); - /** @var $methodReflection ReflectionMethod */ + $classReflection = new \Zend\Code\Reflection\ClassReflection($className); + /** @var \Zend\Code\Reflection\MethodReflection $methodReflection */ foreach ($classReflection->getMethods() as $methodReflection) { $methodName = $methodReflection->getName(); if (array_key_exists($methodName, $methods)) { @@ -80,33 +78,30 @@ public function reflectClassMethods($className, $methods) /** * Retrieve method interface and documentation description. * - * @param ReflectionMethod $method + * @param \Zend\Code\Reflection\MethodReflection $method * @return array * @throws \InvalidArgumentException */ - public function extractMethodData(ReflectionMethod $method) + public function extractMethodData(\Zend\Code\Reflection\MethodReflection $method) { $methodData = ['documentation' => $this->extractMethodDescription($method), 'interface' => []]; - $prototypes = $method->getPrototypes(); - /** Take the fullest interface that also includes optional parameters. */ - /** @var \Zend\Server\Reflection\Prototype $prototype */ - $prototype = end($prototypes); - /** @var \Zend\Server\Reflection\ReflectionParameter $parameter */ - foreach ($prototype->getParameters() as $parameter) { + /** @var \Zend\Code\Reflection\ParameterReflection $parameter */ + foreach ($method->getParameters() as $parameter) { $parameterData = [ - 'type' => $this->_typeProcessor->register($parameter->getType()), + 'type' => $this->_typeProcessor->register($this->_typeProcessor->getParamType($parameter)), 'required' => !$parameter->isOptional(), - 'documentation' => $parameter->getDescription(), + 'documentation' => $this->_typeProcessor->getParamDescription($parameter), ]; if ($parameter->isOptional()) { $parameterData['default'] = $parameter->getDefaultValue(); } $methodData['interface']['in']['parameters'][$parameter->getName()] = $parameterData; } - if ($prototype->getReturnType() != 'void' && $prototype->getReturnType() != 'null') { + $returnType = $this->_typeProcessor->getGetterReturnType($method); + if ($returnType != 'void' && $returnType != 'null') { $methodData['interface']['out']['parameters']['result'] = [ - 'type' => $this->_typeProcessor->register($prototype->getReturnType()), - 'documentation' => $prototype->getReturnValue()->getDescription(), + 'type' => $this->_typeProcessor->register($returnType['type']), + 'documentation' => $returnType['description'], 'required' => true, ]; } @@ -117,10 +112,10 @@ public function extractMethodData(ReflectionMethod $method) /** * Retrieve method full documentation description. * - * @param ReflectionMethod $method + * @param \Zend\Code\Reflection\MethodReflection $method * @return string */ - protected function extractMethodDescription(ReflectionMethod $method) + protected function extractMethodDescription(\Zend\Code\Reflection\MethodReflection $method) { $methodReflection = new MethodReflection( $method->getDeclaringClass()->getName(), diff --git a/app/code/Magento/Webapi/Model/Soap/Server.php b/app/code/Magento/Webapi/Model/Soap/Server.php index 75460fcf1dd46..356afdbad8778 100644 --- a/app/code/Magento/Webapi/Model/Soap/Server.php +++ b/app/code/Magento/Webapi/Model/Soap/Server.php @@ -21,6 +21,8 @@ class Server const REQUEST_PARAM_WSDL = 'wsdl'; + const REQUEST_PARAM_LIST_WSDL = 'wsdl_list'; + /** * @var \Magento\Framework\App\AreaLIst */ diff --git a/app/code/Magento/Webapi/Model/Soap/Wsdl/Generator.php b/app/code/Magento/Webapi/Model/Soap/Wsdl/Generator.php index c0788c9376106..e412de30599a1 100644 --- a/app/code/Magento/Webapi/Model/Soap/Wsdl/Generator.php +++ b/app/code/Magento/Webapi/Model/Soap/Wsdl/Generator.php @@ -80,6 +80,16 @@ public function __construct( $this->customAttributeTypeLocator = $customAttributeTypeLocator; } + /** + * Retrieve an array of services + * + * @return array + */ + public function getListOfServices() + { + return $this->_apiConfig->getSoapServicesConfig(); + } + /** * Generate WSDL file based on requested services (uses cache) * diff --git a/app/code/Magento/Webapi/Test/Unit/Controller/SoapTest.php b/app/code/Magento/Webapi/Test/Unit/Controller/SoapTest.php index b1feef3a52821..b65d6f2929477 100644 --- a/app/code/Magento/Webapi/Test/Unit/Controller/SoapTest.php +++ b/app/code/Magento/Webapi/Test/Unit/Controller/SoapTest.php @@ -44,6 +44,11 @@ class SoapTest extends \PHPUnit_Framework_TestCase */ protected $_localeMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\State + */ + protected $_appStateMock; + /** * Set up Controller object. */ @@ -71,7 +76,8 @@ protected function setUp() ->disableOriginalConstructor() ->setMethods(['maskException']) ->getMock(); - $this->_appStateMock = $this->getMock('\Magento\Framework\App\State', [], [], '', false); + + $this->_appStateMock = $this->getMock('Magento\Framework\App\State', [], [], '', false); $localeResolverMock = $this->getMockBuilder( 'Magento\Framework\Locale\Resolver' @@ -93,6 +99,10 @@ protected function setUp() $areaListMock = $this->getMock('Magento\Framework\App\AreaList', [], [], '', false); $areaMock = $this->getMock('Magento\Framework\App\AreaInterface'); $areaListMock->expects($this->any())->method('getArea')->will($this->returnValue($areaMock)); + + $rendererMock = $this->getMockBuilder('Magento\Framework\Webapi\Rest\Response\RendererFactory') + ->disableOriginalConstructor() + ->getMock(); $this->_soapController = new \Magento\Webapi\Controller\Soap( $this->_requestMock, $this->_responseMock, @@ -102,6 +112,7 @@ protected function setUp() $this->_appStateMock, $localeResolverMock, $pathProcessorMock, + $rendererMock, $areaListMock ); } diff --git a/app/code/Magento/Webapi/Test/Unit/Model/Soap/Config/ClassReflectorTest.php b/app/code/Magento/Webapi/Test/Unit/Model/Soap/Config/ClassReflectorTest.php index 376a683d98f68..cf94b5264c2b6 100644 --- a/app/code/Magento/Webapi/Test/Unit/Model/Soap/Config/ClassReflectorTest.php +++ b/app/code/Magento/Webapi/Test/Unit/Model/Soap/Config/ClassReflectorTest.php @@ -49,10 +49,10 @@ public function testReflectClassMethods() public function testExtractMethodData() { - $classReflection = new \Zend\Server\Reflection\ReflectionClass( - new \ReflectionClass('\\Magento\\Webapi\\Test\\Unit\\Model\\Config\\TestServiceForClassReflector') + $classReflection = new \Zend\Code\Reflection\ClassReflection( + '\\Magento\\Webapi\\Test\\Unit\\Model\\Config\\TestServiceForClassReflector' ); - /** @var $methodReflection ReflectionMethod */ + /** @var $methodReflection \Zend\Code\Reflection\MethodReflection */ $methodReflection = $classReflection->getMethods()[0]; $methodData = $this->_classReflector->extractMethodData($methodReflection); $expectedResponse = $this->_getSampleReflectionData(); diff --git a/app/code/Magento/Webapi/etc/di.xml b/app/code/Magento/Webapi/etc/di.xml index c58acdbf51c4b..28d00c467ea83 100644 --- a/app/code/Magento/Webapi/etc/di.xml +++ b/app/code/Magento/Webapi/etc/di.xml @@ -43,4 +43,30 @@ + + + + + */* + Magento\Framework\Webapi\Rest\Response\Renderer\Json + + + application/json + Magento\Framework\Webapi\Rest\Response\Renderer\Json + + + text/xml + Magento\Framework\Webapi\Rest\Response\Renderer\Xml + + + application/xml + Magento\Framework\Webapi\Rest\Response\Renderer\Xml + + + application/xhtml+xml + Magento\Framework\Webapi\Rest\Response\Renderer\Xml + + + + diff --git a/app/code/Magento/Webapi/etc/webapi_rest/di.xml b/app/code/Magento/Webapi/etc/webapi_rest/di.xml index 7941e76f564b0..5e409281a9c66 100644 --- a/app/code/Magento/Webapi/etc/webapi_rest/di.xml +++ b/app/code/Magento/Webapi/etc/webapi_rest/di.xml @@ -33,32 +33,6 @@ - - - - - */* - Magento\Framework\Webapi\Rest\Response\Renderer\Json - - - application/json - Magento\Framework\Webapi\Rest\Response\Renderer\Json - - - text/xml - Magento\Framework\Webapi\Rest\Response\Renderer\Xml - - - application/xml - Magento\Framework\Webapi\Rest\Response\Renderer\Xml - - - application/xhtml+xml - Magento\Framework\Webapi\Rest\Response\Renderer\Xml - - - - Magento\Framework\Webapi\Rest\Request\Proxy diff --git a/dev/tests/api-functional/_files/Magento/TestJoinDirectives/Api/TestRepositoryInterface.php b/dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/Api/TestRepositoryInterface.php similarity index 90% rename from dev/tests/api-functional/_files/Magento/TestJoinDirectives/Api/TestRepositoryInterface.php rename to dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/Api/TestRepositoryInterface.php index fd70ae4b5fb01..8bac81a5b48fe 100644 --- a/dev/tests/api-functional/_files/Magento/TestJoinDirectives/Api/TestRepositoryInterface.php +++ b/dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/Api/TestRepositoryInterface.php @@ -3,7 +3,7 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\TestJoinDirectives\Api; +namespace Magento\TestModuleJoinDirectives\Api; /** * Interface TestRepositoryInterface diff --git a/dev/tests/api-functional/_files/Magento/TestJoinDirectives/Model/TestRepository.php b/dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/Model/TestRepository.php similarity index 94% rename from dev/tests/api-functional/_files/Magento/TestJoinDirectives/Model/TestRepository.php rename to dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/Model/TestRepository.php index 42cedf2108dfa..fb7c032690906 100644 --- a/dev/tests/api-functional/_files/Magento/TestJoinDirectives/Model/TestRepository.php +++ b/dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/Model/TestRepository.php @@ -3,9 +3,9 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\TestJoinDirectives\Model; +namespace Magento\TestModuleJoinDirectives\Model; -use Magento\TestJoinDirectives\Api\TestRepositoryInterface; +use Magento\TestModuleJoinDirectives\Api\TestRepositoryInterface; use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface; /** diff --git a/dev/tests/api-functional/_files/Magento/TestJoinDirectives/composer.json b/dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/composer.json similarity index 100% rename from dev/tests/api-functional/_files/Magento/TestJoinDirectives/composer.json rename to dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/composer.json diff --git a/dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/acl.xml b/dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/etc/acl.xml similarity index 67% rename from dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/acl.xml rename to dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/etc/acl.xml index ad548566ba7d1..6f0216da051a4 100644 --- a/dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/acl.xml +++ b/dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/etc/acl.xml @@ -9,8 +9,8 @@ - - + + diff --git a/dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/di.xml b/dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/etc/di.xml similarity index 68% rename from dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/di.xml rename to dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/etc/di.xml index a3633a8adf41f..8dfb257cc66be 100644 --- a/dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/di.xml +++ b/dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/etc/di.xml @@ -6,5 +6,5 @@ */ --> - + diff --git a/dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/extension_attributes.xml b/dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/etc/extension_attributes.xml similarity index 100% rename from dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/extension_attributes.xml rename to dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/etc/extension_attributes.xml diff --git a/dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/module.xml b/dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/etc/module.xml similarity index 80% rename from dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/module.xml rename to dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/etc/module.xml index 7f91223ddc7d2..b17690769cddc 100644 --- a/dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/module.xml +++ b/dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/etc/module.xml @@ -6,5 +6,5 @@ */ --> - + diff --git a/dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/webapi.xml b/dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/etc/webapi.xml similarity index 59% rename from dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/webapi.xml rename to dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/etc/webapi.xml index 741e134c76d7e..8e47fcbe525b2 100644 --- a/dev/tests/api-functional/_files/Magento/TestJoinDirectives/etc/webapi.xml +++ b/dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/etc/webapi.xml @@ -8,10 +8,10 @@ - - + + - + diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/JoinDirectivesTest.php b/dev/tests/api-functional/testsuite/Magento/Webapi/JoinDirectivesTest.php index 0130fac8f341f..264dad8ab6b66 100644 --- a/dev/tests/api-functional/testsuite/Magento/Webapi/JoinDirectivesTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Webapi/JoinDirectivesTest.php @@ -54,8 +54,8 @@ public function testGetList() $searchCriteria = $this->searchBuilder->create()->__toArray(); $requestData = ['searchCriteria' => $searchCriteria]; - $restResourcePath = '/V1/TestJoinDirectives/'; - $soapService = 'testJoinDirectivesTestRepositoryV1'; + $restResourcePath = '/V1/TestModuleJoinDirectives/'; + $soapService = 'testModuleJoinDirectivesTestRepositoryV1'; $expectedExtensionAttributes = $this->getExpectedExtensionAttributes(); $serviceInfo = [ diff --git a/lib/internal/Magento/Framework/Reflection/Test/Unit/DataObject.php b/lib/internal/Magento/Framework/Reflection/Test/Unit/DataObject.php index 501ac376fe70d..6702c3e57300c 100644 --- a/lib/internal/Magento/Framework/Reflection/Test/Unit/DataObject.php +++ b/lib/internal/Magento/Framework/Reflection/Test/Unit/DataObject.php @@ -20,6 +20,11 @@ class DataObject */ protected $isActive; + /** + * @var string + */ + private $name; + /** * @return string */ @@ -55,4 +60,14 @@ public function setIsActive($isActive) $this->isActive = $isActive; return $this; } + + /** + * @param null|string $name Name of the attribute + * @return $this + */ + public function setName($name = null) + { + $this->name = $name; + return $this; + } } diff --git a/lib/internal/Magento/Framework/Reflection/Test/Unit/TypeProcessorTest.php b/lib/internal/Magento/Framework/Reflection/Test/Unit/TypeProcessorTest.php index 4f6b76f302e93..d02de6584d9eb 100644 --- a/lib/internal/Magento/Framework/Reflection/Test/Unit/TypeProcessorTest.php +++ b/lib/internal/Magento/Framework/Reflection/Test/Unit/TypeProcessorTest.php @@ -213,4 +213,24 @@ public function testFindSetterMethodNameWrongCamelCasedAttribute() $class = new ClassReflection("\\Magento\\Framework\\Reflection\\Test\\Unit\\DataObject"); $this->_typeProcessor->findSetterMethodName($class, 'ActivE'); } + + /** + * @expectedException \LogicException + * @expectedExceptionMessageRegExp /@param annotation is incorrect for the parameter "name" \w+/ + */ + public function testGetParamType() + { + $class = new ClassReflection("\\Magento\\Framework\\Reflection\\Test\\Unit\\DataObject"); + $methodReflection = $class->getMethod('setName'); + $paramsReflection = $methodReflection->getParameters(); + $this->_typeProcessor->getParamType($paramsReflection[0]); + } + + public function testGetParameterDescription() + { + $class = new ClassReflection("\\Magento\\Framework\\Reflection\\Test\\Unit\\DataObject"); + $methodReflection = $class->getMethod('setName'); + $paramsReflection = $methodReflection->getParameters(); + $this->assertEquals('Name of the attribute', $this->_typeProcessor->getParamDescription($paramsReflection[0])); + } } diff --git a/lib/internal/Magento/Framework/Reflection/TypeProcessor.php b/lib/internal/Magento/Framework/Reflection/TypeProcessor.php index 2653248cec8dd..c4d0bc217eb6e 100644 --- a/lib/internal/Magento/Framework/Reflection/TypeProcessor.php +++ b/lib/internal/Magento/Framework/Reflection/TypeProcessor.php @@ -473,14 +473,25 @@ public function processSimpleAndAnyType($value, $type) * * @param ParameterReflection $param * @return string + * @throws \LogicException */ public function getParamType(ParameterReflection $param) { $type = $param->getType(); + if ($param->getType() == 'null') { + throw new \LogicException(sprintf( + '@param annotation is incorrect for the parameter "%s" in the method "%s:%s".' + . ' First declared type should not be null. E.g. string|null', + $param->getName(), + $param->getDeclaringClass()->getName(), + $param->getDeclaringFunction()->name + )); + } if ($type == 'array') { // try to determine class, if it's array of objects $docBlock = $param->getDeclaringFunction()->getDocBlock(); $pattern = "/\@param\s+([\w\\\_]+\[\])\s+\\\${$param->getName()}\n/"; + $matches = []; if (preg_match($pattern, $docBlock->getContents(), $matches)) { return $matches[1]; } @@ -489,6 +500,26 @@ public function getParamType(ParameterReflection $param) return $type; } + /** + * Get parameter description + * + * @param ParameterReflection $param + * @return string|null + */ + public function getParamDescription(ParameterReflection $param) + { + $docBlock = $param->getDeclaringFunction()->getDocBlock(); + $docBlockLines = explode("\n", $docBlock->getContents()); + $pattern = "/\@param\s+([\w\\\_\[\]\|]+)\s+(\\\${$param->getName()})\s(.*)/"; + $matches = []; + + foreach ($docBlockLines as $line) { + if (preg_match($pattern, $line, $matches)) { + return $matches[3]; + } + } + } + /** * Find the getter method name for a property from the given class *