/** * Validate class * * @param string $className * @return bool * @throws \Magento\Framework\Code\ValidationException * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ public function validate($className) { $class = new \ReflectionClass($className); $parent = $class->getParentClass(); /** Check whether parent class exists and has __construct method */ if (!$parent) { return true; } /** Get parent class __construct arguments */ $parentArguments = $this->_argumentsReader->getConstructorArguments($parent, true, true); if (empty($parentArguments)) { return true; } /** Check whether class has __construct */ $classArguments = $this->_argumentsReader->getConstructorArguments($class); if (null === $classArguments) { return true; } /** Check whether class has parent::__construct call */ $callArguments = $this->_argumentsReader->getParentCall($class, $classArguments); if (null === $callArguments) { return true; } /** Get parent class __construct arguments */ $parentArguments = $this->_argumentsReader->getConstructorArguments($parent, true, true); foreach ($parentArguments as $index => $requiredArgument) { if (isset($callArguments[$index])) { $actualArgument = $callArguments[$index]; } else { if ($requiredArgument['isOptional']) { continue; } $classPath = str_replace('\\', '/', $class->getFileName()); throw new \Magento\Framework\Code\ValidationException('Missed required argument ' . $requiredArgument['name'] . ' in parent::__construct call. File: ' . $classPath); } $isCompatibleTypes = $this->_argumentsReader->isCompatibleType($requiredArgument['type'], $actualArgument['type']); if (false == $isCompatibleTypes) { $classPath = str_replace('\\', '/', $class->getFileName()); throw new \Magento\Framework\Code\ValidationException('Incompatible argument type: Required type: ' . $requiredArgument['type'] . '. Actual type: ' . $actualArgument['type'] . '; File: ' . PHP_EOL . $classPath . PHP_EOL); } } /** * Try to detect unused arguments * Check whether count of passed parameters less or equal that count of count parent class arguments */ if (count($callArguments) > count($parentArguments)) { $extraParameters = array_slice($callArguments, count($parentArguments)); $names = []; foreach ($extraParameters as $param) { $names[] = '$' . $param['name']; } $classPath = str_replace('\\', '/', $class->getFileName()); throw new \Magento\Framework\Code\ValidationException('Extra parameters passed to parent construct: ' . implode(', ', $names) . '. File: ' . $classPath); } return true; }
/** * Validate methods parameters compatibility * * @param array $pluginParameters * @param array $originParameters * @param string $class * @param string $method * * @return void * @throws ValidatorException */ protected function validateMethodsParameters(array $pluginParameters, array $originParameters, $class, $method) { if (count($pluginParameters) != count($originParameters)) { throw new ValidatorException(new Phrase('Invalid method signature. Invalid method parameters count in %1::%2', [$class, $method])); } foreach ($pluginParameters as $position => $data) { if (!$this->_argumentsReader->isCompatibleType($data['type'], $originParameters[$position]['type'])) { throw new ValidatorException(new Phrase('Incompatible parameter type [%1 $%2] in %3::%4. It must be compatible with %5', [$data['type'], $data['name'], $class, $method, $originParameters[$position]['type']])); } } }
/** * Validate methods parameters compatibility * * @param array $pluginParameters * @param array $originParameters * @param string $class * @param string $method * * @return void * @throws ValidatorException */ protected function validateMethodsParameters(array $pluginParameters, array $originParameters, $class, $method) { if (count($pluginParameters) != count($originParameters)) { throw new ValidatorException('Invalid method signature. Invalid method parameters count' . ' in ' . $class . '::' . $method); } foreach ($pluginParameters as $position => $data) { if (!$this->_argumentsReader->isCompatibleType($data['type'], $originParameters[$position]['type'])) { throw new ValidatorException('Incompatible parameter type [' . $data['type'] . ' $' . $data['name'] . ']' . ' in ' . $class . '::' . $method . '. It must be compatible with ' . $originParameters[$position]['type']); } } }
/** * @param string $requiredType * @param string $actualType * @param bool $expectedResult * @dataProvider testIsCompatibleTypeDataProvider */ public function testIsCompatibleType($requiredType, $actualType, $expectedResult) { $actualResult = $this->_model->isCompatibleType($requiredType, $actualType); $this->assertEquals($expectedResult, $actualResult); }