public function testGetConstructorArgumentsClassExtendsDefaultPhpTypeInheridetTrue() { $expectedResult = ['message' => ['name' => 'message', 'position' => 0, 'type' => null, 'isOptional' => true, 'default' => ''], 'code' => ['name' => 'code', 'position' => 1, 'type' => null, 'isOptional' => true, 'default' => 0], 'previous' => ['name' => 'previous', 'position' => 2, 'type' => '\\Exception', 'isOptional' => true, 'default' => null]]; $class = new \ReflectionClass('ClassExtendsDefaultPhpTypeWithIOverrideConstructor'); $actualResult = $this->_model->getConstructorArguments($class, false, true); $this->assertEquals($expectedResult, $actualResult); }
/** * 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; }
/** * 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 * * @param string $className * @return bool * @throws ValidationException */ public function validate($className) { $class = new \ReflectionClass($className); $classArguments = $this->_argumentsReader->getConstructorArguments($class, true); $arguments = $this->_getObjectArguments($classArguments); $typeList = array(); $errors = array(); foreach ($arguments as $argument) { $name = $argument['name']; $type = $argument['type']; if (in_array($type, $typeList)) { $errors[] = 'Multiple type injection [' . $type . ']'; } elseif (isset($typeList[$name])) { $errors[] = 'Variable name duplication. [$' . $name . ']'; } $typeList[$name] = $type; } if (!empty($errors)) { if (false == $this->_ignoreWarning($class)) { $classPath = str_replace('\\', '/', $class->getFileName()); throw new ValidationException('Argument type duplication in class ' . $class->getName() . ' in ' . $classPath . PHP_EOL . implode(PHP_EOL, $errors)); } } return true; }
/** * 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; }
/** * 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 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; }