Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
MethodsMap.php
Go to the documentation of this file.
1 <?php
8 
10 use Zend\Code\Reflection\ClassReflection;
11 use Zend\Code\Reflection\MethodReflection;
12 use Zend\Code\Reflection\ParameterReflection;
13 use Magento\Framework\App\Cache\Type\Reflection as ReflectionCache;
14 
19 {
20  const SERVICE_METHOD_PARAMS_CACHE_PREFIX = 'service_method_params_';
21  const SERVICE_INTERFACE_METHODS_CACHE_PREFIX = 'serviceInterfaceMethodsMap';
22  const BASE_MODEL_CLASS = \Magento\Framework\Model\AbstractExtensibleModel::class;
23 
24  const METHOD_META_NAME = 'name';
25  const METHOD_META_TYPE = 'type';
26  const METHOD_META_HAS_DEFAULT_VALUE = 'isDefaultValueAvailable';
27  const METHOD_META_DEFAULT_VALUE = 'defaultValue';
28 
32  private $cache;
33 
37  private $typeProcessor;
38 
42  private $serviceInterfaceMethodsMap = [];
43 
47  private $fieldNamer;
48 
52  private $serializer;
53 
60  public function __construct(
61  \Magento\Framework\Cache\FrontendInterface $cache,
62  TypeProcessor $typeProcessor,
63  \Magento\Framework\Api\AttributeTypeResolverInterface $typeResolver,
64  FieldNamer $fieldNamer
65  ) {
66  $this->cache = $cache;
67  $this->typeProcessor = $typeProcessor;
68  $this->attributeTypeResolver = $typeResolver;
69  $this->fieldNamer = $fieldNamer;
70  }
71 
79  public function getMethodReturnType($typeName, $methodName)
80  {
81  return $this->getMethodsMap($typeName)[$methodName]['type'];
82  }
83 
98  public function getMethodsMap($interfaceName)
99  {
100  $key = self::SERVICE_INTERFACE_METHODS_CACHE_PREFIX . "-" . md5($interfaceName);
101  if (!isset($this->serviceInterfaceMethodsMap[$key])) {
102  $methodMap = $this->cache->load($key);
103  if ($methodMap) {
104  $this->serviceInterfaceMethodsMap[$key] = $this->getSerializer()->unserialize($methodMap);
105  } else {
106  $methodMap = $this->getMethodMapViaReflection($interfaceName);
107  $this->serviceInterfaceMethodsMap[$key] = $methodMap;
108  $this->cache->save($this->getSerializer()->serialize($this->serviceInterfaceMethodsMap[$key]), $key);
109  }
110  }
111  return $this->serviceInterfaceMethodsMap[$key];
112  }
113 
121  public function getMethodParams($serviceClassName, $serviceMethodName)
122  {
123  $cacheId = self::SERVICE_METHOD_PARAMS_CACHE_PREFIX . hash('md5', $serviceClassName . $serviceMethodName);
124  $params = $this->cache->load($cacheId);
125  if ($params !== false) {
126  return $this->getSerializer()->unserialize($params);
127  }
128  $serviceClass = new ClassReflection($serviceClassName);
130  $serviceMethod = $serviceClass->getMethod($serviceMethodName);
131  $params = [];
133  foreach ($serviceMethod->getParameters() as $paramReflection) {
134  $isDefaultValueAvailable = $paramReflection->isDefaultValueAvailable();
135  $params[] = [
136  self::METHOD_META_NAME => $paramReflection->getName(),
137  self::METHOD_META_TYPE => $this->typeProcessor->getParamType($paramReflection),
138  self::METHOD_META_HAS_DEFAULT_VALUE => $isDefaultValueAvailable,
139  self::METHOD_META_DEFAULT_VALUE => $isDefaultValueAvailable ? $paramReflection->getDefaultValue() : null
140  ];
141  }
142  $this->cache->save($this->getSerializer()->serialize($params), $cacheId, [ReflectionCache::CACHE_TAG]);
143  return $params;
144  }
145 
152  private function getMethodMapViaReflection($interfaceName)
153  {
154  $methodMap = [];
155  $class = new ClassReflection($interfaceName);
156  $baseClassMethods = false;
157  foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
158  // Include all the methods of classes inheriting from AbstractExtensibleObject.
159  // Ignore all the methods of AbstractExtensibleModel's parent classes
160  if ($method->class === self::BASE_MODEL_CLASS) {
161  $baseClassMethods = true;
162  } elseif ($baseClassMethods) {
163  // ReflectionClass::getMethods() sorts the methods by class (lowest in inheritance tree first)
164  // then by the order they are defined in the class definition
165  break;
166  }
167 
168  if ($this->isSuitableMethod($method)) {
169  $methodMap[$method->getName()] = $this->typeProcessor->getGetterReturnType($method);
170  }
171  }
172  return $methodMap;
173  }
174 
181  private function isSuitableMethod($method)
182  {
183  $isSuitableMethodType = !($method->isConstructor() || $method->isFinal()
184  || $method->isStatic() || $method->isDestructor());
185 
186  $isExcludedMagicMethod = strpos($method->getName(), '__') === 0;
187  return $isSuitableMethodType && !$isExcludedMagicMethod;
188  }
189 
197  public function isMethodValidForDataField($type, $methodName)
198  {
199  $methods = $this->getMethodsMap($type);
200  if (isset($methods[$methodName])) {
201  $methodMetadata = $methods[$methodName];
202  // any method with parameter(s) gets ignored because we do not know the type and value of
203  // the parameter(s), so we are not able to process
204  if ($methodMetadata['parameterCount'] > 0) {
205  return false;
206  }
207 
208  return $this->fieldNamer->getFieldNameForMethodName($methodName) !== null;
209  }
210 
211  return false;
212  }
213 
221  public function isMethodReturnValueRequired($type, $methodName)
222  {
223  $methods = $this->getMethodsMap($type);
224  return $methods[$methodName]['isRequired'];
225  }
226 
233  private function getSerializer()
234  {
235  if ($this->serializer === null) {
237  ->get(SerializerInterface::class);
238  }
239  return $this->serializer;
240  }
241 }
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
$type
Definition: item.phtml:13
__construct(\Magento\Framework\Cache\FrontendInterface $cache, TypeProcessor $typeProcessor, \Magento\Framework\Api\AttributeTypeResolverInterface $typeResolver, FieldNamer $fieldNamer)
Definition: MethodsMap.php:60
$methods
Definition: billing.phtml:71
$_option $_optionId $class
Definition: date.phtml:13
$method
Definition: info.phtml:13
getMethodReturnType($typeName, $methodName)
Definition: MethodsMap.php:79
isMethodValidForDataField($type, $methodName)
Definition: MethodsMap.php:197
isMethodReturnValueRequired($type, $methodName)
Definition: MethodsMap.php:221
$params[\Magento\Store\Model\StoreManager::PARAM_RUN_CODE]
Definition: website.php:18