Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
ServiceMetadata.php
Go to the documentation of this file.
1 <?php
6 namespace Magento\Webapi\Model;
7 
12 
17 {
21  const KEY_CLASS = 'class';
22 
23  const KEY_IS_SECURE = 'isSecure';
24 
25  const KEY_SERVICE_METHODS = 'methods';
26 
27  const KEY_METHOD = 'method';
28 
29  const KEY_IS_REQUIRED = 'inputRequired';
30 
31  const KEY_ACL_RESOURCES = 'resources';
32 
33  const KEY_ROUTES = 'routes';
34 
35  const KEY_ROUTE_METHOD = 'method';
36 
37  const KEY_ROUTE_PARAMS = 'parameters';
38 
39  const SERVICES_CONFIG_CACHE_ID = 'services-services-config';
40 
41  const ROUTES_CONFIG_CACHE_ID = 'routes-services-config';
42 
43  const REFLECTED_TYPES_CACHE_ID = 'soap-reflected-types';
44 
48  protected $services;
49 
55  protected $routes;
56 
60  protected $cache;
61 
65  protected $config;
66 
70  protected $classReflector;
71 
75  protected $typeProcessor;
76 
80  private $serializer;
81 
91  public function __construct(
93  WebApiCache $cache,
94  \Magento\Webapi\Model\Config\ClassReflector $classReflector,
95  \Magento\Framework\Reflection\TypeProcessor $typeProcessor,
96  SerializerInterface $serializer = null
97  ) {
98  $this->config = $config;
99  $this->cache = $cache;
100  $this->classReflector = $classReflector;
101  $this->typeProcessor = $typeProcessor;
102  $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
103  }
104 
110  protected function initServicesMetadata()
111  {
112  $services = [];
113  foreach ($this->config->getServices()[Converter::KEY_SERVICES] as $serviceClass => $serviceVersionData) {
114  foreach ($serviceVersionData as $version => $serviceData) {
115  $serviceName = $this->getServiceName($serviceClass, $version);
116  foreach ($serviceData[Converter::KEY_METHODS] as $methodName => $methodMetadata) {
117  $services[$serviceName][self::KEY_SERVICE_METHODS][$methodName] = [
118  self::KEY_METHOD => $methodName,
119  self::KEY_IS_REQUIRED => (bool)$methodMetadata[Converter::KEY_SECURE],
120  self::KEY_IS_SECURE => $methodMetadata[Converter::KEY_SECURE],
121  self::KEY_ACL_RESOURCES => $methodMetadata[Converter::KEY_ACL_RESOURCES],
122  ];
123  $services[$serviceName][self::KEY_CLASS] = $serviceClass;
124  }
125  $reflectedMethodsMetadata = $this->classReflector->reflectClassMethods(
126  $serviceClass,
127  $services[$serviceName][self::KEY_SERVICE_METHODS]
128  );
129  $services[$serviceName][self::KEY_SERVICE_METHODS] = array_merge_recursive(
130  $services[$serviceName][self::KEY_SERVICE_METHODS],
131  $reflectedMethodsMetadata
132  );
133  $services[$serviceName][Converter::KEY_DESCRIPTION] = $this->classReflector->extractClassDescription(
134  $serviceClass
135  );
136  }
137  }
138 
139  return $services;
140  }
141 
147  public function getServicesConfig()
148  {
149  if (null === $this->services) {
150  $servicesConfig = $this->cache->load(self::SERVICES_CONFIG_CACHE_ID);
151  $typesData = $this->cache->load(self::REFLECTED_TYPES_CACHE_ID);
152  if ($servicesConfig && is_string($servicesConfig) && $typesData && is_string($typesData)) {
153  $this->services = $this->serializer->unserialize($servicesConfig);
154  $this->typeProcessor->setTypesData($this->serializer->unserialize($typesData));
155  } else {
156  $this->services = $this->initServicesMetadata();
157  $this->cache->save(
158  $this->serializer->serialize($this->services),
160  );
161  $this->cache->save(
162  $this->serializer->serialize($this->typeProcessor->getTypesData()),
163  self::REFLECTED_TYPES_CACHE_ID
164  );
165  }
166  }
167  return $this->services;
168  }
169 
177  public function getServiceMetadata($serviceName)
178  {
179  $servicesConfig = $this->getServicesConfig();
180  if (!isset($servicesConfig[$serviceName]) || !is_array($servicesConfig[$serviceName])) {
181  throw new \RuntimeException(__('Requested service is not available: "%1"', $serviceName));
182  }
183  return $servicesConfig[$serviceName];
184  }
185 
202  public function getServiceName($interfaceName, $version, $preserveVersion = true)
203  {
204  if (!preg_match(\Magento\Webapi\Model\Config::SERVICE_CLASS_PATTERN, $interfaceName, $matches)) {
205  $apiClassPattern = "#^(.+?)\\\\(.+?)\\\\Api\\\\(.+?)(Interface)?$#";
206  preg_match($apiClassPattern, $interfaceName, $matches);
207  }
208 
209  if (!empty($matches)) {
210  $moduleNamespace = $matches[1];
211  $moduleName = $matches[2];
212  $moduleNamespace = ($moduleNamespace == 'Magento') ? '' : $moduleNamespace;
213  if ($matches[4] === 'Interface') {
214  $matches[4] = $matches[3];
215  }
216  $serviceNameParts = explode('\\', trim($matches[4], '\\'));
217  if ($moduleName == $serviceNameParts[0]) {
219  $moduleName = '';
220  }
221  $parentServiceName = $moduleNamespace . $moduleName . array_shift($serviceNameParts);
222  array_unshift($serviceNameParts, $parentServiceName);
223  if ($preserveVersion) {
224  $serviceNameParts[] = $version;
225  }
226  } elseif (preg_match(\Magento\Webapi\Model\Config::API_PATTERN, $interfaceName, $matches)) {
227  $moduleNamespace = $matches[1];
228  $moduleName = $matches[2];
229  $moduleNamespace = ($moduleNamespace == 'Magento') ? '' : $moduleNamespace;
230  $serviceNameParts = explode('\\', trim($matches[3], '\\'));
231  if ($moduleName == $serviceNameParts[0]) {
233  $moduleName = '';
234  }
235  $parentServiceName = $moduleNamespace . $moduleName . array_shift($serviceNameParts);
236  array_unshift($serviceNameParts, $parentServiceName);
237  if ($preserveVersion) {
238  $serviceNameParts[] = $version;
239  }
240  } else {
241  throw new \InvalidArgumentException(sprintf('The service interface name "%s" is invalid.', $interfaceName));
242  }
243  return lcfirst(implode('', $serviceNameParts));
244  }
245 
253  public function getRouteMetadata($serviceName)
254  {
255  $routesConfig = $this->getRoutesConfig();
256  if (!isset($routesConfig[$serviceName]) || !is_array($routesConfig[$serviceName])) {
257  throw new \RuntimeException(__('Requested service is not available: "%1"', $serviceName));
258  }
259  return $routesConfig[$serviceName];
260  }
261 
267  public function getRoutesConfig()
268  {
269  if (null === $this->routes) {
270  $routesConfig = $this->cache->load(self::ROUTES_CONFIG_CACHE_ID);
271  $typesData = $this->cache->load(self::REFLECTED_TYPES_CACHE_ID);
272  if ($routesConfig && is_string($routesConfig) && $typesData && is_string($typesData)) {
273  $this->routes = $this->serializer->unserialize($routesConfig);
274  $this->typeProcessor->setTypesData($this->serializer->unserialize($typesData));
275  } else {
276  $this->routes = $this->initRoutesMetadata();
277  $this->cache->save(
278  $this->serializer->serialize($this->routes),
280  );
281  $this->cache->save(
282  $this->serializer->serialize($this->typeProcessor->getTypesData()),
283  self::REFLECTED_TYPES_CACHE_ID
284  );
285  }
286  }
287  return $this->routes;
288  }
289 
295  protected function initRoutesMetadata()
296  {
297  $routes = $this->getServicesConfig();
298  foreach ($this->config->getServices()[Converter::KEY_ROUTES] as $url => $routeData) {
299  foreach ($routeData as $method => $data) {
301  $version = explode('/', ltrim($url, '/'))[0];
302  $serviceName = $this->getServiceName($serviceClass, $version);
304  $routes[$serviceName][self::KEY_ROUTES][$url][$method][self::KEY_ROUTE_METHOD] = $methodName;
307  }
308  }
309  return $routes;
310  }
311 }
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
__()
Definition: __.php:13
getServiceName($interfaceName, $version, $preserveVersion=true)
$method
Definition: info.phtml:13
__construct(\Magento\Webapi\Model\Config $config, WebApiCache $cache, \Magento\Webapi\Model\Config\ClassReflector $classReflector, \Magento\Framework\Reflection\TypeProcessor $typeProcessor, SerializerInterface $serializer=null)