Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
InterfaceValidator.php
Go to the documentation of this file.
1 <?php
7 
10 
12 {
13  const METHOD_BEFORE = 'before';
14 
15  const METHOD_AROUND = 'around';
16 
17  const METHOD_AFTER = 'after';
18 
24  protected $_argumentsReader;
25 
29  public function __construct(\Magento\Framework\Code\Reader\ArgumentsReader $argumentsReader = null)
30  {
31  $this->_argumentsReader = $argumentsReader ?: new \Magento\Framework\Code\Reader\ArgumentsReader();
32  }
33 
45  public function validate($pluginClass, $interceptedType)
46  {
47  $interceptedType = '\\' . trim($interceptedType, '\\');
48  $pluginClass = '\\' . trim($pluginClass, '\\');
49  $plugin = new \ReflectionClass($pluginClass);
50  $type = new \ReflectionClass($interceptedType);
51 
52  foreach ($plugin->getMethods(\ReflectionMethod::IS_PUBLIC) as $pluginMethod) {
54  $originMethodName = $this->getOriginMethodName($pluginMethod->getName());
55  if ($originMethodName === null) {
56  continue;
57  }
58  if (!$type->hasMethod($originMethodName)) {
59  throw new ValidatorException(
60  new Phrase(
61  'Incorrect interface in %1. There is no method [ %2 ] in %3 interface',
62  [$pluginClass, $originMethodName, $interceptedType]
63  )
64  );
65  }
66  $originMethod = $type->getMethod($originMethodName);
67 
68  $pluginMethodParameters = $this->getMethodParameters($pluginMethod);
69  $originMethodParameters = $this->getMethodParameters($originMethod);
70 
71  $methodType = $this->getMethodType($pluginMethod->getName());
72 
73  $subject = array_shift($pluginMethodParameters);
74  if (!$this->_argumentsReader->isCompatibleType(
75  $subject['type'],
76  $interceptedType
77  ) || $subject['type'] === null
78  ) {
79  throw new ValidatorException(
80  new Phrase(
81  'Invalid [%1] $%2 type in %3::%4. It must be compatible with %5',
82  [$subject['type'], $subject['name'], $pluginClass, $pluginMethod->getName(), $interceptedType]
83  )
84  );
85  }
86 
87  switch ($methodType) {
90  $pluginMethodParameters,
91  $originMethodParameters,
92  $pluginClass,
93  $pluginMethod->getName()
94  );
95  break;
97  $proceed = array_shift($pluginMethodParameters);
98  if (!$this->_argumentsReader->isCompatibleType($proceed['type'], '\\Closure')) {
99  throw new ValidatorException(
100  new Phrase(
101  'Invalid [%1] $%2 type in %3::%4. It must be compatible with \\Closure',
102  [$proceed['type'], $proceed['name'], $pluginClass, $pluginMethod->getName()]
103  )
104  );
105  }
107  $pluginMethodParameters,
108  $originMethodParameters,
109  $pluginClass,
110  $pluginMethod->getName()
111  );
112  break;
113  case self::METHOD_AFTER:
114  if (count($pluginMethodParameters) > 1) {
115  // remove result
116  array_shift($pluginMethodParameters);
117  $matchedParameters = array_intersect_key($originMethodParameters, $pluginMethodParameters);
119  $pluginMethodParameters,
120  $matchedParameters,
121  $pluginClass,
122  $pluginMethod->getName()
123  );
124  }
125  break;
126  }
127  }
128  }
129 
141  protected function validateMethodsParameters(array $pluginParameters, array $originParameters, $class, $method)
142  {
143  if (count($pluginParameters) != count($originParameters)) {
144  throw new ValidatorException(
145  new Phrase(
146  'Invalid method signature. Invalid method parameters count in %1::%2',
147  [$class, $method]
148  )
149  );
150  }
151  foreach ($pluginParameters as $position => $data) {
152  if (!$this->_argumentsReader->isCompatibleType($data['type'], $originParameters[$position]['type'])) {
153  throw new ValidatorException(
154  new Phrase(
155  'Incompatible parameter type [%1 $%2] in %3::%4. It must be compatible with %5',
156  [$data['type'], $data['name'], $class, $method, $originParameters[$position]['type']]
157  )
158  );
159  }
160  }
161  }
162 
170  protected function getParametersType(\ReflectionParameter $parameter)
171  {
172  $parameterClass = $parameter->getClass();
173  $type = $parameterClass ? '\\' . $parameterClass->getName() : ($parameter->isArray() ? 'array' : null);
174  return $type;
175  }
176 
184  protected function getOriginMethodName($pluginMethodName)
185  {
186  switch ($this->getMethodType($pluginMethodName)) {
187  case self::METHOD_BEFORE:
188  case self::METHOD_AROUND:
189  return lcfirst(substr($pluginMethodName, 6));
190 
191  case self::METHOD_AFTER:
192  return lcfirst(substr($pluginMethodName, 5));
193 
194  default:
195  return null;
196  }
197  }
198 
206  protected function getMethodType($pluginMethodName)
207  {
208  if (substr($pluginMethodName, 0, 6) == self::METHOD_BEFORE) {
209  return self::METHOD_BEFORE;
210  } elseif (substr($pluginMethodName, 0, 6) == self::METHOD_AROUND) {
211  return self::METHOD_AROUND;
212  } elseif (substr($pluginMethodName, 0, 5) == self::METHOD_AFTER) {
213  return self::METHOD_AFTER;
214  }
215 
216  return null;
217  }
218 
226  protected function getMethodParameters(\ReflectionMethod $method)
227  {
228  $output = [];
229  foreach ($method->getParameters() as $parameter) {
230  $output[$parameter->getPosition()] = [
231  'name' => $parameter->getName(),
232  'type' => $this->getParametersType($parameter),
233  ];
234  }
235  return $output;
236  }
237 }
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
$type
Definition: item.phtml:13
$_option $_optionId $class
Definition: date.phtml:13
validateMethodsParameters(array $pluginParameters, array $originParameters, $class, $method)
$method
Definition: info.phtml:13
__construct(\Magento\Framework\Code\Reader\ArgumentsReader $argumentsReader=null)