Config.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Webapi\Model\Rest;
  7. use Magento\Webapi\Controller\Rest\Router\Route;
  8. use Magento\Webapi\Model\ConfigInterface as ModelConfigInterface;
  9. use Magento\Webapi\Model\Config\Converter;
  10. /**
  11. * Webapi Config Model for Rest.
  12. */
  13. class Config
  14. {
  15. /**#@+
  16. * HTTP methods supported by REST.
  17. */
  18. const HTTP_METHOD_GET = 'GET';
  19. const HTTP_METHOD_DELETE = 'DELETE';
  20. const HTTP_METHOD_PUT = 'PUT';
  21. const HTTP_METHOD_POST = 'POST';
  22. const HTTP_METHOD_PATCH = 'PATCH';
  23. /**#@-*/
  24. /**#@+
  25. * Keys that a used for config internal representation.
  26. */
  27. const KEY_IS_SECURE = 'isSecure';
  28. const KEY_CLASS = 'class';
  29. const KEY_METHOD = 'method';
  30. const KEY_ROUTE_PATH = 'routePath';
  31. const KEY_ACL_RESOURCES = 'resources';
  32. const KEY_PARAMETERS = 'parameters';
  33. /*#@-*/
  34. /*#@-*/
  35. protected $_config;
  36. /**
  37. * @var \Magento\Framework\Controller\Router\Route\Factory
  38. */
  39. protected $_routeFactory;
  40. /**
  41. * @param ModelConfigInterface $config
  42. * @param \Magento\Framework\Controller\Router\Route\Factory $routeFactory
  43. */
  44. public function __construct(
  45. ModelConfigInterface $config,
  46. \Magento\Framework\Controller\Router\Route\Factory $routeFactory
  47. ) {
  48. $this->_config = $config;
  49. $this->_routeFactory = $routeFactory;
  50. }
  51. /**
  52. * Create route object.
  53. *
  54. * @param array $routeData Expected format:
  55. * <pre>array(
  56. * 'routePath' => '/categories/:categoryId',
  57. * 'class' => \Magento\Catalog\Api\CategoryRepositoryInterface::class,
  58. * 'serviceMethod' => 'item'
  59. * 'secure' => true
  60. * );</pre>
  61. * @return \Magento\Webapi\Controller\Rest\Router\Route
  62. */
  63. protected function _createRoute($routeData)
  64. {
  65. /** @var $route \Magento\Webapi\Controller\Rest\Router\Route */
  66. $route = $this->_routeFactory->createRoute(
  67. \Magento\Webapi\Controller\Rest\Router\Route::class,
  68. $routeData[self::KEY_ROUTE_PATH]
  69. );
  70. $route->setServiceClass($routeData[self::KEY_CLASS])
  71. ->setServiceMethod($routeData[self::KEY_METHOD])
  72. ->setSecure($routeData[self::KEY_IS_SECURE])
  73. ->setAclResources($routeData[self::KEY_ACL_RESOURCES])
  74. ->setParameters($routeData[self::KEY_PARAMETERS]);
  75. return $route;
  76. }
  77. /**
  78. * Get service base URL
  79. *
  80. * @param \Magento\Framework\Webapi\Rest\Request $request
  81. * @return string|null
  82. */
  83. protected function _getServiceBaseUrl($request)
  84. {
  85. $baseUrlRegExp = '#^/?\w+/\w+#';
  86. $serviceBaseUrl = preg_match($baseUrlRegExp, $request->getPathInfo(), $matches) ? $matches[0] : null;
  87. return $serviceBaseUrl;
  88. }
  89. /**
  90. * Generate the list of available REST routes. Current HTTP method is taken into account.
  91. *
  92. * @param \Magento\Framework\Webapi\Rest\Request $request
  93. * @return Route[] matched routes
  94. * @throws \Magento\Framework\Webapi\Exception
  95. */
  96. public function getRestRoutes(\Magento\Framework\Webapi\Rest\Request $request)
  97. {
  98. $requestHttpMethod = $request->getHttpMethod();
  99. $servicesRoutes = $this->_config->getServices()[Converter::KEY_ROUTES];
  100. $routes = [];
  101. // Return the route on exact match
  102. if (isset($servicesRoutes[$request->getPathInfo()][$requestHttpMethod])) {
  103. $methodInfo = $servicesRoutes[$request->getPathInfo()][$requestHttpMethod];
  104. $routes[] = $this->_createRoute(
  105. [
  106. self::KEY_ROUTE_PATH => $request->getPathInfo(),
  107. self::KEY_CLASS => $methodInfo[Converter::KEY_SERVICE][Converter::KEY_SERVICE_CLASS],
  108. self::KEY_METHOD => $methodInfo[Converter::KEY_SERVICE][Converter::KEY_SERVICE_METHOD],
  109. self::KEY_IS_SECURE => $methodInfo[Converter::KEY_SECURE],
  110. self::KEY_ACL_RESOURCES => array_keys($methodInfo[Converter::KEY_ACL_RESOURCES]),
  111. self::KEY_PARAMETERS => $methodInfo[Converter::KEY_DATA_PARAMETERS],
  112. ]
  113. );
  114. return $routes;
  115. }
  116. $serviceBaseUrl = $this->_getServiceBaseUrl($request);
  117. ksort($servicesRoutes, SORT_STRING);
  118. foreach ($servicesRoutes as $url => $httpMethods) {
  119. // skip if baseurl is not null and does not match
  120. if (!$serviceBaseUrl || strpos(trim($url, '/'), trim($serviceBaseUrl, '/')) !== 0) {
  121. // base url does not match, just skip this service
  122. continue;
  123. }
  124. foreach ($httpMethods as $httpMethod => $methodInfo) {
  125. if (strtoupper($httpMethod) == strtoupper($requestHttpMethod)) {
  126. $aclResources = array_keys($methodInfo[Converter::KEY_ACL_RESOURCES]);
  127. $routes[] = $this->_createRoute(
  128. [
  129. self::KEY_ROUTE_PATH => $url,
  130. self::KEY_CLASS => $methodInfo[Converter::KEY_SERVICE][Converter::KEY_SERVICE_CLASS],
  131. self::KEY_METHOD => $methodInfo[Converter::KEY_SERVICE][Converter::KEY_SERVICE_METHOD],
  132. self::KEY_IS_SECURE => $methodInfo[Converter::KEY_SECURE],
  133. self::KEY_ACL_RESOURCES => $aclResources,
  134. self::KEY_PARAMETERS => $methodInfo[Converter::KEY_DATA_PARAMETERS],
  135. ]
  136. );
  137. }
  138. }
  139. }
  140. return $routes;
  141. }
  142. }