/**
  * Validate class
  *
  * @param string $className
  * @return bool
  * @throws \Magento\Framework\Exception\ValidatorException
  * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  */
 public function validate($className)
 {
     $class = new \ReflectionClass($className);
     $classArguments = $this->_argumentsReader->getConstructorArguments($class);
     if ($this->_isContextOnly($classArguments)) {
         return true;
     }
     $parent = $class->getParentClass();
     $parentArguments = [];
     if ($parent) {
         $parentClass = $parent->getName();
         if (0 !== strpos($parentClass, '\\')) {
             $parentClass = '\\' . $parentClass;
         }
         if (isset($this->_cache[$parentClass])) {
             $parentCall = $this->_argumentsReader->getParentCall($class, []);
             if (empty($classArguments) || $parentCall) {
                 $parentArguments = $this->_cache[$parentClass];
             }
         }
     }
     if (empty($classArguments)) {
         $classArguments = $parentArguments;
     }
     $requiredSequence = $this->_buildsSequence($classArguments, $parentArguments);
     if (!empty($requiredSequence)) {
         $this->_cache[$className] = $requiredSequence;
     }
     if (false == $this->_checkArgumentSequence($classArguments, $requiredSequence)) {
         $classPath = str_replace('\\', '/', $class->getFileName());
         throw new \Magento\Framework\Exception\ValidatorException(new \Magento\Framework\Phrase('Incorrect argument sequence in class %1 in %2%3Required: $%4%5Actual  : $%6%7', [$className, $classPath, PHP_EOL, implode(', $', array_keys($requiredSequence)), PHP_EOL, implode(', $', array_keys($classArguments)), PHP_EOL]));
     }
     return true;
 }
Esempio n. 2
0
 /**
  * Validate class
  *
  * @param string $className
  * @return bool
  * @throws ValidationException
  */
 public function validate($className)
 {
     $class = new \ReflectionClass($className);
     $classArguments = $this->_argumentsReader->getConstructorArguments($class);
     if ($this->_isContextOnly($classArguments)) {
         return true;
     }
     $parent = $class->getParentClass();
     $parentArguments = array();
     if ($parent) {
         $parentClass = $parent->getName();
         if (0 !== strpos($parentClass, '\\')) {
             $parentClass = '\\' . $parentClass;
         }
         if (isset($this->_cache[$parentClass])) {
             $parentCall = $this->_argumentsReader->getParentCall($class, array());
             if (empty($classArguments) || $parentCall) {
                 $parentArguments = $this->_cache[$parentClass];
             }
         }
     }
     if (empty($classArguments)) {
         $classArguments = $parentArguments;
     }
     $requiredSequence = $this->_buildsSequence($classArguments, $parentArguments);
     if (!empty($requiredSequence)) {
         $this->_cache[$className] = $requiredSequence;
     }
     if (false == $this->_checkArgumentSequence($classArguments, $requiredSequence)) {
         $classPath = str_replace('\\', '/', $class->getFileName());
         throw new ValidationException('Incorrect argument sequence in class ' . $className . ' in ' . $classPath . PHP_EOL . 'Required: $' . implode(', $', array_keys($requiredSequence)) . PHP_EOL . 'Actual  : $' . implode(', $', array_keys($classArguments)) . PHP_EOL);
     }
     return true;
 }
Esempio n. 3
0
 /**
  * Validate class. Check declaration of dependencies that already declared in context object
  *
  * @param string $className
  * @return bool
  * @throws ValidationException
  */
 public function validate($className)
 {
     $class = new \ReflectionClass($className);
     $classArguments = $this->_argumentsReader->getConstructorArguments($class);
     $errors = array();
     $contextDependencies = array();
     $actualDependencies = $this->_getObjectArguments($classArguments);
     foreach ($actualDependencies as $type) {
         /** Check if argument is context object */
         if (is_subclass_of($type, '\\Magento\\Framework\\ObjectManager\\ContextInterface')) {
             $contextDependencies = array_merge($contextDependencies, $this->_argumentsReader->getConstructorArguments(new \ReflectionClass($type), false, true));
         }
     }
     $contextDependencyTypes = $this->_getObjectArguments($contextDependencies);
     foreach ($actualDependencies as $type) {
         if (in_array($type, $contextDependencyTypes)) {
             $errors[] = $type . ' already exists in context object';
         }
     }
     if (false == empty($errors)) {
         $classPath = str_replace('\\', '/', $class->getFileName());
         throw new ValidationException('Incorrect dependency in class ' . $className . ' in ' . $classPath . PHP_EOL . implode(PHP_EOL, $errors));
     }
     return true;
 }
 /**
  * Validate class constructor arguments
  *
  * @param string $className
  * @return bool
  * @throws \Magento\Framework\Exception\ValidatorException
  */
 public function validate($className)
 {
     $class = new \ReflectionClass($className);
     $expectedArguments = $this->argumentsReader->getConstructorArguments($class);
     $actualArguments = $this->sourceArgumentsReader->getConstructorArgumentTypes($class);
     $expectedArguments = array_map(function ($element) {
         return $element['type'];
     }, $expectedArguments);
     $result = array_diff($expectedArguments, $actualArguments);
     if (!empty($result)) {
         throw new \Magento\Framework\Exception\ValidatorException(new \Magento\Framework\Phrase('Invalid constructor argument(s) in %1', [$className]));
     }
     return true;
 }
Esempio n. 5
0
 /**
  * Check whether warning must be skipped
  *
  * @param \ReflectionClass $class
  * @return bool
  */
 protected function _ignoreWarning(\ReflectionClass $class)
 {
     $annotations = $this->_argumentsReader->getAnnotations($class);
     if (isset($annotations[self::SUPPRESS_ANNOTATION])) {
         return $annotations[self::SUPPRESS_ANNOTATION] == self::TYPE_DUPLICATIONS;
     }
     return false;
 }
 /**
  * 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']);
         }
     }
 }
 /**
  * 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;
 }
 public function testGetAnnotations()
 {
     $class = new \ReflectionClass('\\ClassWithSuppressWarnings');
     $expected = ['SuppressWarnings' => 'Magento.TypeDuplication'];
     $this->assertEquals($expected, $this->_model->getAnnotations($class));
 }