includes: - utils/phpstan-extensions/config/phpstan-extensions.neon - vendor/phpstan/phpstan/conf/bleedingEdge.neon - vendor/symplify/phpstan-extensions/config/config.neon - vendor/thecodingmachine/phpstan-strict-rules/phpstan-strict-rules.neon # see https://github.com/symplify/coding-standard - vendor/symplify/coding-standard/config/symplify-rules.neon services: # require constant in argument position - class: Symplify\CodingStandard\Rules\RequireMethodCallArgumentConstantRule tags: [phpstan.rules.rule] arguments: constantArgByMethodByType: Symfony\Component\Console\Command\Command: addArgument: [0] addOption: [0] Symfony\Component\Console\Input\InputInterface: getOption: [0] getArgument: [0] PhpParser\Node: getAttribute: [0] setAttribute: [0] - class: Symplify\CodingStandard\Rules\SeeAnnotationToTestRule tags: [phpstan.rules.rule] arguments: requiredSeeTypes: - PHPStan\Rules\Rule - Rector\Core\Rector\AbstractRector - Rector\FileSystemRector\Rector\AbstractFileSystemRector - class: Symplify\CodingStandard\Rules\NoStaticCallRule tags: [phpstan.rules.rule] arguments: allowedStaticCallClasses: - PHPStan\Type\VerbosityLevel - Rector\NodeTypeResolver\ClassExistenceStaticHelper # this rule prevents bug in phar like these: https://github.com/rectorphp/rector/pull/3692/files - class: Symplify\CodingStandard\Rules\RequireStringArgumentInMethodCallRule tags: [phpstan.rules.rule] arguments: stringArgByMethodByType: Rector\Core\Rector\AbstractRector: isObjectType: [1] - class: Symplify\CodingStandard\Rules\ClassNameRespectsParentSuffixRule tags: [phpstan.rules.rule] arguments: parentClasses: - Rector - class: Symplify\CodingStandard\Rules\PreferredClassRule tags: [phpstan.rules.rule] arguments: oldToPrefferedClasses: # prevent PHPStorm autocomplete mess 'Symfony\Component\DependencyInjection\Variable': 'PhpParser\Node\Expr\Variable' 'phpDocumentor\Reflection\Types\Expression': 'PhpParser\Node\Stmt\Expression' 'phpDocumentor\Reflection\DocBlock\Tags\Param': 'PhpParser\Node\Param' 'phpDocumentor\Reflection\DocBlock\Tags\Return_': 'PhpParser\Node\Stmt\Return_' 'Closure': 'PhpParser\Node\Expr\Closure' 'PHPUnit\TextUI\Configuration\Variable': 'PhpParser\Node\Expr\Variable' 'PhpCsFixer\FixerDefinition\CodeSample': 'Rector\Core\RectorDefinition\CodeSample' 'SebastianBergmann\Type\MixedType': 'PHPStan\Type\MixedType' 'Hoa\Protocol\Node\Node': 'PhpParser\Node' 'Nette\Utils\FileSystem': 'Symplify\SmartFileSystem\SmartFileSystem' 'Symfony\Component\Filesystem\Filesystem': 'Symplify\SmartFileSystem\SmartFileSystem' parameters: level: max # see https://github.com/symplify/coding-standard symplify: max_method_cognitive_complexity: 9 # default: 8 max_class_cognitive_complexity: 50 # to allow installing with various phsptan versions without reporting old errors here reportUnmatchedIgnoredErrors: false checkGenericClassInNonGenericObjectType: false scanDirectories: - stubs bootstrapFiles: - vendor/symfony/dependency-injection/Loader/Configurator/ContainerConfigurator.php paths: - bin - src - rules - packages - tests - compiler/src - utils # this cannot be put it, because it wipes PHPStan cache on each run :( - must run in separate #- config excludes_analyse: # iterable types - '#with no value type specified in iterable type array#' - '#type specified in iterable type (array|iterable)#' # phsptan bug - utils/phpstan-extensions/src/Rule/PreventParentMethodVisibilityOverrideRule.php - utils/phpstan-extensions/src/Rule/KeepRectorNamespaceForRectorRule.php - packages/rector-generator/templates/* # generated files - 'packages/doctrine-annotation-generated/src/ConstantPreservingDocParser.php' - 'packages/doctrine-annotation-generated/src/ConstantPreservingAnnotationReader.php' - "*/Expected/*" # complex printer - '*tests/Rector/MethodCall/RenameMethodRector/**/SomeClass.php' # tests files - '*tests/*/Fixture/*' - '*tests/*/Source/*' - '*tests/Source/*' # part of composer - '*/tests/Rector/Psr4/MultipleClassFileToPsr4ClassesRector/Expected/Just*ExceptionWithoutNamespace.php' # tests - tests/DependencyInjection/config ignoreErrors: # @todo remove # iterable types - '#with no value type specified in iterable type array#' - '#type specified in iterable type (array|iterable)#' # false positive - '#PHPDoc tag \@param for parameter \$node with type float is incompatible with native type PhpParser\\Node#' # misuse of interface and class - '#Parameter \#1 (.*?) expects Symfony\\Component\\DependencyInjection\\ContainerBuilder, Symfony\\Component\\DependencyInjection\\ContainerInterface given#' - '#Strict comparison using === between string and null will always evaluate to false#' # false positive - type is set by annotation above - '#Array \(array\) does not accept PhpParser\\Node#' # irrelevant - '#Call to function in_array\(\) with arguments string, (.*?) and true will always evaluate to false#' # known values - '#Access to an undefined property PhpParser\\Node\\Expr::\$right#' - '#Access to an undefined property PhpParser\\Node\\Expr\\MethodCall\|PhpParser\\Node\\Stmt\\ClassMethod::\$params#' - '#Cannot call method getName\(\) on PHPStan\\Reflection\\ClassReflection\|null#' # false positive, has annotation type above - '#Method Rector\\CodeQuality\\Rector\\Foreach_\\SimplifyForeachToCoalescingRector\:\:matchReturnOrAssignNode\(\) should return PhpParser\\Node\\Expr\\Assign\|PhpParser\\Node\\Stmt\\Return_\|null but returns PhpParser\\Node\|null#' - '#Access to an undefined property PhpParser\\Node::\$(\w+)#' # intentionally incorrect - part of the test - '#Parameter \#2 \$codeSamples of class Rector\\Core\\RectorDefinition\\RectorDefinition constructor expects array, array given#' # known values - '#Cannot access property \$value on PhpParser\\Node\\Expr\\ArrayItem\|null#' # known values - '#Strict comparison using === between PhpParser\\Node\\Expr and null will always evaluate to false#' - '#Access to an undefined property PhpParser\\Node\\Stmt\:\:\$expr#' - '#Cannot access property \$stmts on PhpParser\\Node\\Stmt\\Else_\|null#' # node finder - '#Method Rector\\(.*?) should return array but returns array#' # part of test - '#(.*?)(AttributeAwareNodeInterface|AttributeAware(.*?)TagValueNode)(.*?)#' - '#Parameter \#1 \$children of class PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocNode constructor expects array, array given#' - '#Method Rector\\PHPUnit\\Rector\\MethodCall\\ReplaceAssertArraySubsetRector\:\:matchArray\(\) should return PhpParser\\Node\\Expr\\Array_\|null but returns PhpParser\\Node\\Expr#' - '#(.*?)PhpParser\\Node\\Expr\\Error\|PhpParser\\Node\\Expr\\Variable given#' # false positive 0.11.5 - '#Unreachable statement \- code above always terminates#' - '#Negated boolean expression is always true#' - '#Strict comparison using \=\=\= between PhpParser\\Node and null will always evaluate to false#' # known types - '#Access to an undefined property PhpParser\\Node\\Expr\\Error\|PhpParser\\Node\\Expr\\Variable\:\:\$name#' - '#Strict comparison using \=\=\= between PhpParser\\Node\\Expr\\ArrayItem and null will always evaluate to false#' - '#Parameter \#2 \.\.\.\$args of function array_merge expects array, array\|false given#' - '#Access to an undefined property PhpParser\\Node\\Expr\:\:\$args#' - '#Parameter \#2 \$name of method Rector\\Core\\Rector\\AbstractRector\:\:isName\(\) expects string, string\|null given#' # cascade irrelevant - '#Parameter (.*?) expects array, array given#' # known value - '#Cannot cast array\|bool\|string\|null to string#' # array is callable - '#If condition is always true#' - '#Ternary operator condition is always true#' - '#Access to an undefined property PhpParser\\Node\\FunctionLike\|PhpParser\\Node\\Stmt\\ClassLike\:\:\$stmts#' - '#Property Rector\\TypeDeclaration\\TypeInferer\\(.*?)\:\:\$(.*?)TypeInferers \(array\) does not accept array#' # sense-less errors # 3rd party - message: '#Use default null value and nullable compare instead of isset on object#' path: 'rules/symfony/src/ServiceMapProvider.php' # PHP 7.4 1_000 support - '#Property PhpParser\\Node\\Scalar\\DNumber\:\:\$value \(float\) does not accept string#' - '#Call to function is_string\(\) with float will always evaluate to false#' - '#Method Rector\\NodeTypeResolver\\PHPStan\\Type\\TypeFactory\:\:createUnionOrSingleType\(\) should return PHPStan\\Type\\MixedType\|PHPStan\\Type\\UnionType but returns PHPStan\\Type\\Type#' # test - '#Class Rector\\DynamicTypeAnalysis\\Tests\\Rector\\ClassMethod\\AddArgumentTypeWithProbeDataRector\\Fixture\\SomeClass not found#' - message: '#Class Rector\\Generic\\Tests\\Rector\\StaticCall\\SwapClassMethodArgumentsRector\\Fixture\\SomeClass not found#' path: rules/generic/tests/Rector/StaticCall/SwapClassMethodArgumentsRector/SwapClassMethodArgumentsRectorTest.php # internal rule - '#Class "Rector\\Utils\\(.*?)" is missing @see annotation with test case class reference#' # mixed - '#Offset int\|string\|null does not exist on array\|null#' - '#class-string\|T of object#' # known values - '#Offset 0 does not exist on array\|null#' - '#Parameter \#1 \$left of class PhpParser\\Node\\Expr\\BinaryOp\\Spaceship constructor expects PhpParser\\Node\\Expr, PhpParser\\Node\\Expr\|null given#' - '#Parameter \#2 \$right of class PhpParser\\Node\\Expr\\BinaryOp\\Spaceship constructor expects PhpParser\\Node\\Expr, PhpParser\\Node\\Expr\|null given#' # false positive - '#Comparison operation "<" between 0 and 2 is always true#' - '#Method Rector\\Symfony\\Rector\\MethodCall\\AbstractToConstructorInjectionRector\:\:getServiceTypeFromMethodCallArgument\(\) should return PHPStan\\Type\\Type but returns PHPStan\\Type\\Type\|null#' - '#Parameter \#1 \$expected of method PHPUnit\\Framework\\Assert\:\:assertInstanceOf\(\) expects class\-string, string given#' - '#Unable to resolve the template type ExpectedType in call to method PHPUnit\\Framework\\Assert\:\:assertInstanceOf\(\)#' # fix Symplify 7.2 later - '#Method (.*?) returns bool type, so the name should start with is/has/was#' - '#In method "Rector\\BetterPhpDocParser\\AnnotationReader\\NodeAnnotationReader\:\:createPropertyReflectionFromPropertyNode", caught "Throwable" must be rethrown\. Either catch a more specific exception or add a "throw" clause in the "catch" block to propagate the exception\. More info\: http\://bit\.ly/failloud#' # doc is not enough - '#Result of \|\| is always true#' # known value - '#Parameter \#2 \$name of class PhpParser\\Node\\Expr\\MethodCall constructor expects PhpParser\\Node\\Expr\|PhpParser\\Node\\Identifier\|string, string\|null given#' - '#Parameter \#1 \$eventListenerTag of method Rector\\SymfonyCodeQuality\\Rector\\Class_\\EventListenerToEventSubscriberRector\:\:createEventItem\(\) expects Rector\\Symfony\\ValueObject\\Tag\\EventListenerTag, Rector\\Symfony\\Contract\\Tag\\TagInterface given#' - '#Method Rector\\BetterPhpDocParser\\PhpDocInfo\\PhpDocInfoFactory\:\:parseTokensToPhpDocNode\(\) should return Rector\\AttributeAwarePhpDoc\\Ast\\PhpDoc\\AttributeAwarePhpDocNode but returns PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocNode#' - '#Property PhpParser\\Node\\Stmt\\Expression\:\:\$expr \(PhpParser\\Node\\Expr\) does not accept PhpParser\\Node\\Expr\|null#' - '#Call to an undefined method PHPStan\\Type\\Type\:\:getClassName\(\)#' - '#Parameter \#1 \$typeNode of method Rector\\StaticTypeMapper\\StaticTypeMapper\:\:mapPHPStanPhpDocTypeNodeToPHPStanType\(\) expects PHPStan\\PhpDocParser\\Ast\\Type\\TypeNode, PHPStan\\PhpDocParser\\Ast\\Node given#' - '#Parameter \#1 \$sprintfFuncCall of method Rector\\Core\\PhpParser\\NodeTransformer\:\:transformSprintfToArray\(\) expects PhpParser\\Node\\Expr\\FuncCall, PhpParser\\Node given#' - '#Parameter \#1 \$nodes of method Rector\\Core\\PhpParser\\Node\\BetterNodeFinder\:\:find\(\) expects array\|PhpParser\\Node, array\|null given#' - '#Method Rector\\SOLID\\Reflection\\ParentConstantReflectionResolver\:\:(.*?)\(\) should return ReflectionClassConstant\|null but returns ReflectionClassConstant\|false#' - '#Parameter \#1 \$firstStmt of method Rector\\Generic\\Rector\\ClassMethod\\NormalToFluentRector\:\:isBothMethodCallMatch\(\) expects PhpParser\\Node\\Stmt\\Expression, PhpParser\\Node\\Stmt given#' - '#Method Rector\\Core\\Rector\\AbstractRector\:\:wrapToArg\(\) should return array but returns array#' - '#Method Rector\\FileSystemRector\\Rector\\AbstractFileSystemRector\:\:wrapToArg\(\) should return array but returns array#' - '#Cannot call method (.*?)\(\) on Rector\\BetterPhpDocParser\\PhpDocInfo\\PhpDocInfo\|null#' - '#Parameter \#(.*?) (.*?) of class PhpParser\\Node\\Expr\\BinaryOp\\(.*?) constructor expects PhpParser\\Node\\Expr, PhpParser\\Node given#' - '#Access to an undefined property PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagValueNode\:\:\$description#' - '#Method Rector\\Php80\\Rector\\NotIdentical\\StrContainsRector\:\:matchNotIdenticalToFalse\(\) should return PhpParser\\Node\\Expr\\FuncCall\|null but returns PhpParser\\Node\\Expr#' - '#Parameter \#2 \$name of method Rector\\Core\\Rector\\AbstractRector\:\:isVariableName\(\) expects string, string\|null given#' # broken - '#Cannot call method getParentNode\(\) on Rector\\DeadCode\\ValueObject\\VariableNodeUse\|null#' - '#Parameter \#2 \$name of method Rector\\NodeNameResolver\\NodeNameResolver\:\:isName\(\) expects string, string\|null given#' - '#Parameter \#1 \$keyName of method Rector\\AttributeAwarePhpDoc\\Ast\\Type\\AttributeAwareArrayShapeItemNode\:\:createKeyWithSpacePattern\(\) expects PHPStan\\PhpDocParser\\Ast\\ConstExpr\\ConstExprIntegerNode\|PHPStan\\PhpDocParser\\Ast\\Type\\IdentifierTypeNode\|null, PHPStan\\PhpDocParser\\Ast\\ConstExpr\\ConstExprIntegerNode\|PHPStan\\PhpDocParser\\Ast\\ConstExpr\\ConstExprStringNode\|PHPStan\\PhpDocParser\\Ast\\Type\\IdentifierTypeNode\|null given#' - '#Method Rector\\Caching\\Detector\\ChangedFilesDetector\:\:hashFile\(\) should return string but returns string\|false#' - '#If condition is always false#' - '#Parameter \#1 \$funcCall of method Rector\\Php80\\MatchAndRefactor\\StrStartsWithMatchAndRefactor\\AbstractMatchAndRefactor\:\:createStrStartsWithValueObjectFromFuncCall\(\) expects PhpParser\\Node\\Expr\\FuncCall, PhpParser\\Node\\Expr given#' # mostly strings in tests - '#Class (.*?) should be written with \:\:class notation, string found#' - '#Method Rector\\Naming\\Naming\\PropertyNaming\:\:resolveShortClassName\(\) should return string but returns string\|null#' - message: "#in iterable type Iterator#" paths: - *Test.php - *TestCase.php - message: "#^Cognitive complexity for \"Rector\\\\BetterPhpDocParser\\\\Printer\\\\WhitespaceDetector\\:\\:detectOldWhitespaces\\(\\)\" is 18, keep it under 9$#" count: 1 path: packages/better-php-doc-parser/src/Printer/WhitespaceDetector.php - message: "#^Parameter \\#1 \\$input of function array_splice expects array, array\\\\|null given\\.$#" count: 1 path: rules/coding-style/src/Rector/ClassMethod/NewlineBeforeNewAssignSetRector.php - message: "#^Cognitive complexity for \"Rector\\\\PhpSpecToPHPUnit\\\\Rector\\\\MethodCall\\\\PhpSpecPromisesToPHPUnitAssertRector\\:\\:refactor\\(\\)\" is 13, keep it under 9$#" count: 1 path: rules/php-spec-to-phpunit/src/Rector/MethodCall/PhpSpecPromisesToPHPUnitAssertRector.php - message: "#Use explicit property fetch names over dynamic#" path: packages/doctrine-annotation-generated/src/PhpDocNode/ConstantReferenceIdentifierRestorer.php - "#^Cognitive complexity for \"Rector\\\\Php70\\\\EregToPcreTransformer\\:\\:(.*?)\" is (.*?), keep it under 9$#" - '#In method "Rector\\Utils\\ProjectValidator\\Process\\ParallelTaskRunner\:\:(.*?)", caught "Throwable" must be rethrown\. Either catch a more specific exception or add a "throw" clause in the "catch" block to propagate the exception#' # weird - '#Method (.*?) specified in iterable type Symfony\\Component\\Process\\Process#' - '#Cannot cast PhpParser\\Node\\Expr\\Error\|PhpParser\\Node\\Identifier to string#' - '#Parameter \#1 \$node of method Rector\\PostRector\\Collector\\NodesToAddCollector\:\:wrapToExpression\(\) expects PhpParser\\Node\\Expr\|PhpParser\\Node\\Stmt, PhpParser\\Node given#' - '#Access to an undefined property PhpParser\\Node\\Expr\:\:\$class#' - '#Method Rector\\BetterPhpDocParser\\Tests\\PhpDocParser\\AbstractPhpDocInfoTest\:\:parseFileAndGetFirstNodeOfType\(\) should return PhpParser\\Node but returns PhpParser\\Node\|null#' - '#Property PhpParser\\Node\\Stmt\\Namespace_\:\:\$stmts \(array\) does not accept array#' - '#Cognitive complexity for "Rector\\TypeDeclaration\\PHPStan\\Type\\ObjectTypeSpecifier\:\:matchShortenedObjectType\(\)" is 10, keep it under 9#' - '#Parameter \#1 \$type of method PhpParser\\Builder\\FunctionLike\:\:setReturnType\(\) expects PhpParser\\Node\\Name\|PhpParser\\Node\\NullableType\|string, PhpParser\\Node\\Identifier\|PhpParser\\Node\\Name\|PhpParser\\Node\\NullableType\|PhpParser\\Node\\UnionType given#' - '#Cognitive complexity for "Rector\\Core\\PhpParser\\Node\\Value\\ValueResolver\:\:getValue\(\)" is \d+, keep it under 9#' - '#Cognitive complexity for "Rector\\NetteKdyby\\ContributeEventClassResolver\:\:resolveGetterMethodByEventClassAndParam\(\)" is \d+, keep it under 9#' - '#Parameter \#1 \$type of class PhpParser\\Node\\NullableType constructor expects PhpParser\\Node\\Identifier\|PhpParser\\Node\\Name\|string, PhpParser\\Node\\Identifier\|PhpParser\\Node\\Name\|PhpParser\\Node\\NullableType\|PhpParser\\Node\\UnionType given#' - '#Parameter \#1 \$object of function get_class expects object, PhpParser\\Node\|null given#' - '#Class "Rector\\FileSystemRector\\Rector\\Removing\\RemoveProjectFileRector" is missing @see annotation with test case class reference#' - '#Parameter \#1 \$type of method PhpParser\\Builder\\Param\:\:setType\(\) expects PhpParser\\Node\\Name\|PhpParser\\Node\\NullableType\|PhpParser\\Node\\UnionType\|string, PhpParser\\Node\\Identifier\|PhpParser\\Node\\Name\|PhpParser\\Node\\NullableType\|PhpParser\\Node\\UnionType given#' - '#Parameter \#1 \$node of method Rector\\Core\\PhpParser\\Node\\BetterNodeFinder\:\:findFirstAncestorInstanceOf\(\) expects PhpParser\\Node, PhpParser\\Node\\Expr\\Variable\|null given#' - '#Parameter \#1 \$objectType of method Rector\\Naming\\Naming\\PropertyNaming\:\:fqnToVariableName\(\) expects PHPStan\\Type\\ObjectType\|string, PHPStan\\Type\\Type given#' # known value - '#Property PhpParser\\Node\\Stmt\\Foreach_\:\:\$valueVar \(PhpParser\\Node\\Expr\) does not accept PhpParser\\Node\\Expr\|null#' - '#Access to an undefined property PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagValueNode\:\:\$type#' # local type - message: '#Method call "isObjectType\(\)" argument on position 1 cannot use "\:\:class" reference#' path: 'packages/dynamic-type-analysis/src/Rector/StaticCall/RemoveArgumentTypeProbeRector.php' # only local use - message: '#Class "Rector\\RectorGenerator\\Rector\\Closure\\AddNewServiceToSymfonyPhpConfigRector" is missing @see annotation with test case class reference#' path: 'packages/rector-generator/src/Rector/Closure/AddNewServiceToSymfonyPhpConfigRector.php' - '#Class Rector\\Renaming\\Tests\\Rector\\MethodCall\\RenameMethodRector\\Fixture\\SkipSelfMethodRename not found#' # fixed in symplfiy dev - message: '#Separate function "Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ref\(\)" in method call to standalone row to improve readability#' path: 'packages/rector-generator/config/config.php' - '#Parameter \#1 \$shortControlString of method Rector\\NetteCodeQuality\\Rector\\Assign\\MakeGetComponentAssignAnnotatedRector\:\:resolveTypeFromShortControlNameAndVariable\(\) expects PhpParser\\Node\\Scalar\\String_, PhpParser\\Node\\Expr\|null given#' - '#Parameter \#1 \$variable of class Rector\\Php70\\ValueObject\\VariableAssignPair constructor expects PhpParser\\Node\\Expr\\ArrayDimFetch\|PhpParser\\Node\\Expr\\PropertyFetch\|PhpParser\\Node\\Expr\\StaticPropertyFetch\|PhpParser\\Node\\Expr\\Variable, PhpParser\\Node\\Expr given#' # is nested expr - '#Access to an undefined property PhpParser\\Node\\Expr\:\:\$expr#' - '#Cognitive complexity for "Rector\\DeadCode\\NodeManipulator\\LivingCodeManipulator\:\:keepLivingCodeFromExpr\(\)" is \d+, keep it under 9#' - '#Parameter \#1 \$files of method Symplify\\SmartFileSystem\\Finder\\FinderSanitizer\:\:sanitize\(\) expects \(iterable&Nette\\Utils\\Finder\)\|Symfony\\Component\\Finder\\Finder, array given#' - '#Static property Rector\\Core\\Testing\\PHPUnit\\AbstractGenericRectorTestCase\:\:\$allRectorContainer \(Rector\\Naming\\Tests\\Rector\\Class_\\RenamePropertyToMatchTypeRector\\Source\\ContainerInterface\|Symfony\\Component\\DependencyInjection\\Container\|null\) does not accept Psr\\Container\\ContainerInterface#' # stubs - '#Static property Symplify\\PackageBuilder\\Tests\\AbstractKernelTestCase\:\:\$container \(Psr\\Container\\ContainerInterface\) does not accept Rector\\Naming\\Tests\\Rector\\Class_\\RenamePropertyToMatchTypeRector\\Source\\ContainerInterface\|Symfony\\Component\\DependencyInjection\\Container#' # wtf - message: '#Else branch is unreachable because ternary operator condition is always true#' path: 'rules/psr4/src/Composer/PSR4NamespaceMatcher.php' # false positive - '#Parameter \#1 \$arrayItem of method Rector\\NetteKdyby\\NodeResolver\\ListeningMethodsCollector\:\:resolveCustomClassMethodAndEventClass\(\) expects PhpParser\\Node\\Expr\\ArrayItem, PhpParser\\Node given#' - '#Class with base "(.*?)" name is already used in "_HumbugBox(.*?)"#' - message: '#Class "Rector\\RectorGenerator\\ValueObject\\RectorRecipe" has invalid namespace category "ValueObject"\. Pick one of\: ""#' path: packages/rector-generator/src/ValueObject/RectorRecipe.php - '#Parameter \#2 \$currentNode of method Rector\\CodingStyle\\Rector\\Assign\\ManualJsonStringToJsonEncodeArrayRector\:\:matchNextExprAssignConcatToSameVariable\(\) expects PhpParser\\Node\\Expr\\Assign\|PhpParser\\Node\\Expr\\AssignOp\\Concat, PhpParser\\Node given#' - message: '#Array (with keys|destruct) is not allowed\. Use value object to pass data instead#' paths: # working with cvs file # 3rd party package - rules/php70/src/EregToPcreTransformer.php # output format - packages/changes-reporting/src/Output/JsonOutputFormatter.php # template variables - packages/rector-generator/src/TemplateVariablesFactory.php # output format to json - rules/doctrine/src/Collector/UuidMigrationDataCollector.php # should be replaced by symplify/composer-json-manipulator in the future - compiler/src/Composer/ComposerJsonManipulator.php # not sure how to improve - rules/symfony/src/ValueObject/Tag/EventListenerTag.php - message: '#Use explicit return value over magic &reference#' paths: # 3rd party code - rules/php70/src/EregToPcreTransformer.php - '#Cannot access property \$key on PhpParser\\Node\\Expr\\ArrayItem\|null#' - '#Class Nette\\DI\\CompilerExtension not found#' - '#Class Latte\\Macros\\MacroSet not found#' # symfony/console - message: '#Cannot cast array\|string\|true to string#' path: 'src/Configuration/Configuration.php' - message: '#Use explicit return value over magic &reference#' path: 'rules/dead-code/src/Rector/BinaryOp/RemoveDuplicatedInstanceOfRector.php' - message: '#Class with base "NodeNameResolver" name is already used in "Symplify\\CodingStandard\\PhpParser\\NodeNameResolver", "Rector\\NodeNameResolver\\NodeNameResolver"\. Use unique name to make classes easy to recognize#' path: 'packages/node-name-resolver/src/NodeNameResolver.php' - message: '#Use value object over return of values#' path: 'rules/phpunit/src/Composer/ComposerAutoloadedDirectoryProvider.php' - message: '#Use value object over return of values#' path: 'rules/php70/src/EregToPcreTransformer.php' # new symplify rules - '#Do not use static calls#' - '#Too many public elements on class \- \d+\. Try narrow it down under 10#' - '#Class has too many properties \d+\. Try narrowing it down under 10#' - '#Variable "\$attributeAwareFullyQualifiedIdentifierTypeNode" is too long with 46 chars\. Narrow it under 40 chars#' # 3rd party - '#Class cognitive complexity for "(NodeTypeResolver|EregToPcreTransformer|DumpNodesCommand)" is \d+, keep it under 50#' - message: '#Method "__construct\(\)" is using too many parameters \- \d+\. Make it under 10#' paths: - packages/node-type-resolver/src/NodeScopeAndMetadataDecorator.php # the smallest descriptive method - '#Variable "\$inverseJoinColumnsOpeningAndClosingSpace" is too long with \d+ chars\. Narrow it under 40 chars#' # complex - single repository for all nodes - '#Class cognitive complexity for "NodeRepository" is \d+, keep it under 50#' - '#Method "autowireAbstractRectorDependencies\(\)" is using too many parameters \- 11\. Make it under 10#' # symplify rules fix later - '#Use another value object over string with value object arrays#' - '#Use decouled factory service to create "(.*?)" object#' - '#Add regex101\.org link to that shows the regex in practise, so it will be easier to maintain in case of bug/extension in the future#' # hotskips, fix sooner - '#Post operation are forbidden, as they make 2 values at the same line\. Use pre instead#' - '#Use value object over multi array assign#' - message: '#Do not use static property#' paths: # cannot be handled any other way - packages/doctrine-annotation-generated/src/DataCollector/ResolvedConstantStaticCollector.php # 12 - packages/dynamic-type-analysis/src/Probe/TypeStaticProbe.php # 19 - packages/dynamic-type-analysis/src/Probe/TypeStaticProbe.php # 24 - packages/dynamic-type-analysis/tests/ProbeStorage/StaticInMemoryProbeStorage.php # 14 - src/Testing/PHPUnit/AbstractGenericRectorTestCase.php # 68 - '#(.*?) expects class\-string, string given#' # Temprory ignored - '#Do not use scalar or array as constructor parameter\. Use ParameterProvider service instead#' - message: '#Use local named constant instead of inline string for regex to explain meaning by constant name#' paths: - packages/better-php-doc-parser/src/PartPhpDocTagPrinter/Behavior/ArrayPartPhpDocTagPrinterTrait.php # 27 - '#Do not use trait#' - '#Method "(.*?)" is using too many parameters \- \d+\. Make it under 8#' - message: '#Use local named constant instead of inline string for regex to explain meaning by constant name#' paths: # trait cannot extract constant, decouple this - packages/better-php-doc-parser/src/PhpDocNode/PrintTagValueNodeTrait.php # 52 - message: '#Instead of "Symfony\\Component\\Finder\\SplFileInfo" class/interface use "Symplify\\SmartFileSystem\\SmartFileInfo"#' paths: - src/FileSystem/FilesFinder.php # @todo fix in symplify #- # message: '#Method call argument on position 0 must use constant over value#' # path: 'src/Rector/AbstractRector.php' - '#Method Rector\\DocumentationGenerator\\Tests\\Printer\\RectorsDocumentationPrinter\\RectorsDocumentationPrinterTest\:\:createRectorsFromRectorClasses\(\) should return array but returns array#' - '#Parameter \#1 \$rectors of method Rector\\DocumentationGenerator\\Printer\\RectorsDocumentationPrinter\:\:print\(\) expects array, array given#' - message: '#Use "Nette\\Utils\\Strings\:\:contains\(\)" static call over "strstr\(\)" func call#' paths: - utils/phpstan-extensions/src/Rule/CheckNotTestsNamespaceOutsideTestsDirectoryRule.php # 76 - utils/phpstan-extensions/src/Rule/CheckNotTestsNamespaceOutsideTestsDirectoryRule.php # 81 - message: '#Do not call parent method if no override process#' paths: - rules/symfony/tests/Rector/MethodCall/StringFormTypeToClassRector/WithContainerTest.php # 30 - src/PhpParser/Builder/UseBuilder.php # 19 - message: '#Use "Nette\\Utils\\Strings\:\:contains\(\)" static call over "strstr\(\)" func call#' paths: - utils/phpstan-extensions/src/Rule/CheckNotTestsNamespaceOutsideTestsDirectoryRule.php # 76 - utils/phpstan-extensions/src/Rule/CheckNotTestsNamespaceOutsideTestsDirectoryRule.php # 81 - message: '#Do not call parent method if parent method is empty#' paths: - rules/type-declaration/src/Exception/ConflictingPriorityException.php # 26 - src/Exception/Application/FileProcessingException.php # 22 - src/Exception/Rector/RectorNotFoundOrNotValidRectorClassException.php # 15 - src/Exception/ShouldNotHappenException.php # 18 - src/Testing/PHPUnit/AbstractGenericRectorTestCase.php # 77 - message: '#Do not use factory in constructor#' paths: - compiler/src/Console/Command/CompileCommand.php # 70 - packages/node-type-resolver/src/DependencyInjection/PHPStanServicesFactory.php # 38 - packages/node-type-resolver/src/PHPStan/Scope/NodeVisitor/RemoveDeepChainMethodCallNodeVisitor.php # 37 - packages/phpstan-static-type-mapper/src/PHPStanStaticTypeMapper.php # 37 - packages/post-rector/src/Rector/NameImportingPostRector.php # 39 - rules/nette-code-quality/src/NodeResolver/MethodNamesByInputNamesResolver.php # 21 - rules/nette-to-symfony/src/Rector/ClassMethod/RenameEventNamesInEventSubscriberRector.php # 37 - rules/type-declaration/src/Exception/ConflictingPriorityException.php # 12 - src/Application/ActiveRectorsProvider.php # 27 - src/Autoloading/AdditionalAutoloader.php # 39 - src/Configuration/Configuration.php # 104 - src/Console/Application.php # 39 - src/Console/Output/OutputFormatterCollector.php # 20 - src/Exception/Application/FileProcessingException.php # 13 - src/FileSystem/FilesFinder.php # 56 - src/Php/TypeAnalyzer.php # 47 - src/PhpParser/NodeTraverser/RectorNodeTraverser.php # 30 - src/Skip/Skipper.php # 30 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/PhpDoc/AttributeAwareMethodTagValueNodeFactory.php # 53 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/PhpDoc/AttributeAwareMethodTagValueParameterNodeFactory.php # 50 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/PhpDoc/AttributeAwareParamTagValueNodeFactory.php # 48 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/PhpDoc/AttributeAwarePhpDocNodeFactory.php # 61 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/PhpDoc/AttributeAwarePropertyTagValueNodeFactory.php # 42 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/PhpDoc/AttributeAwareReturnTagValueNodeFactory.php # 42 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/PhpDoc/AttributeAwareThrowsTagValueNodeFactory.php # 42 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/PhpDoc/AttributeAwareVarTagValueNodeFactory.php # 42 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/Type/AttributeAwareArrayShapeItemNodeFactory.php # 41 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/Type/AttributeAwareArrayShapeNodeFactory.php # 45 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/Type/AttributeAwareArrayTypeNodeFactory.php # 42 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/Type/AttributeAwareCallableTypeNodeFactory.php # 48 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/Type/AttributeAwareGenericTypeNodeFactory.php # 47 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/Type/AttributeAwareIntersectionTypeNodeFactory.php # 44 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/Type/AttributeAwareNullableTypeNodeFactory.php # 42 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/Type/AttributeAwareUnionTypeNodeFactory.php # 44 - packages/better-php-doc-parser/src/PhpDocNodeFactory/PHPUnitDataProviderDocNodeFactory.php # 52 - packages/better-php-doc-parser/src/PhpDocNodeFactory/ParamPhpDocNodeFactory.php # 81 - packages/dynamic-type-analysis/src/Probe/TypeStaticProbe.php # 82 - packages/node-type-resolver/src/FileSystem/CurrentFileInfoProvider.php # 22 - packages/node-type-resolver/src/FileSystem/CurrentFileInfoProvider.php # 35 - packages/phpstan-static-type-mapper/src/TypeMapper/ObjectTypeMapper.php # 123 - packages/phpstan-static-type-mapper/src/TypeMapper/ObjectWithoutClassTypeMapper.php # 72 - packages/rector-generator/src/Rector/Closure/AddNewServiceToSymfonyPhpConfigRector.php # 39 - rules/nette-code-quality/src/FormControlTypeResolver/AssignedVariablesMethodCallsFormTypeResolver.php # 50 - rules/nette-code-quality/src/FormControlTypeResolver/ClassMethodFormTypeResolver.php # 67 - rules/nette-code-quality/src/FormControlTypeResolver/ConstructorFormControlTypeResolver.php # 62 - rules/nette-code-quality/src/FormControlTypeResolver/GetComponentMethodCallFormControlTypeResolver.php # 110 - rules/nette-code-quality/src/FormControlTypeResolver/MagicNetteFactoryInterfaceFormControlTypeResolver.php # 95 - rules/nette-code-quality/src/FormControlTypeResolver/MethodCallFormControlTypeResolver.php # 59 - rules/nette-code-quality/src/FormControlTypeResolver/NewFormControlTypeResolver.php # 61 - rules/nette-code-quality/src/FormControlTypeResolver/ReturnFormControlTypeResolver.php # 54 - rules/nette-code-quality/src/FormControlTypeResolver/ThisVariableInAnotherMethodFormControlTypeResolver.php # 52 - rules/nette-code-quality/src/FormControlTypeResolver/VariableConstructorFormControlTypeResolver.php # 84 - src/Configuration/ChangeConfiguration.php # 17 - src/Configuration/Configuration.php # 149 - src/Configuration/Configuration.php # 172 - src/Configuration/Configuration.php # 204 - src/Configuration/Configuration.php # 227 - src/Configuration/CurrentNodeProvider.php # 16 - src/HttpKernel/RectorKernel.php # 70 - src/Rector/AbstractRector/CallableNodeTraverserTrait.php # 24 - src/Rector/AbstractRector/CallableNodeTraverserTrait.php # 24 - src/Rector/AbstractRector/ConstFetchAnalyzerTrait.php # 24 - src/Rector/AbstractRector/ConstFetchAnalyzerTrait.php # 24 - src/Testing/NodeVisitor/AttributeCollectingNodeVisitor.php # 24 - message: '#Do not use factory in constructor#' paths: - src/Testing/PHPUnit/Runnable/ClassLikeNamesSuffixer.php # 27 - src/Testing/PHPUnit/Runnable/RunnableClassFinder.php # 29 - utils/node-documentation-generator/src/ValueObject/NodeInfo.php # 29 - message: '#Method with @required need to be named autowire\+class name#' paths: - packages/node-collector/src/NodeCollector/NodeRepository.php # 126 - packages/node-collector/src/NodeCollector/ParsedClassConstFetchNodeCollector.php # 44 - packages/node-collector/src/NodeCollector/ParsedPropertyFetchNodeCollector.php # 46 - packages/node-name-resolver/src/NodeNameResolver/ClassConstFetchNameResolver.php # 22 - packages/node-name-resolver/src/NodeNameResolver/ClassConstNameResolver.php # 22 - packages/node-name-resolver/src/NodeNameResolver/ParamNameResolver.php # 22 - packages/node-name-resolver/src/NodeNameResolver/PropertyNameResolver.php # 22 - packages/node-name-resolver/src/NodeNameResolver/UseNameResolver.php # 22 - packages/node-type-resolver/src/NodeTypeResolver/ArrayDimFetchTypeResolver.php # 24 - packages/node-type-resolver/src/NodeTypeResolver/CastTypeResolver.php # 23 - packages/node-type-resolver/src/NodeTypeResolver/ClassConstFetchTypeResolver.php # 23 - packages/node-type-resolver/src/NodeTypeResolver/ClassMethodOrClassConstTypeResolver.php # 27 - packages/node-type-resolver/src/NodeTypeResolver/ParamTypeResolver.php # 58 - packages/node-type-resolver/src/NodeTypeResolver/PropertyFetchTypeResolver.php # 79 - packages/node-type-resolver/src/NodeTypeResolver/StaticCallTypeResolver.php # 37 - packages/node-type-resolver/src/NodeTypeResolver/VariableTypeResolver.php # 92 - packages/phpstan-static-type-mapper/src/TypeMapper/CallableTypeMapper.php # 28 - packages/static-type-mapper/src/PhpDocParser/ArrayTypeMapper.php # 35 - packages/static-type-mapper/src/PhpDocParser/NullableTypeMapper.php # 32 - rules/naming/src/Guard/PropertyConflictingNameGuard/MatchPropertyTypeConflictingNameGuard.php # 14 - rules/naming/src/Guard/PropertyConflictingNameGuard/UnderscoreCamelCaseConflictingNameGuard.php # 14 - rules/symfony/src/Rector/MethodCall/AbstractToConstructorInjectionRector.php # 37 - rules/type-declaration/src/TypeInferer/ParamTypeInferer/PHPUnitDataProviderParamTypeInferer.php # 51 - src/Console/Command/AbstractCommand.php # 26 - src/Rector/AbstractRector.php # 125 - src/Rector/AbstractRector/BetterStandardPrinterTrait.php # 37 - src/Rector/AbstractRector/BetterStandardPrinterTrait.php # 37 - src/Rector/AbstractRector/CallableNodeTraverserTrait.php # 24 - src/Rector/AbstractRector/CallableNodeTraverserTrait.php # 24 - src/Rector/AbstractRector/ComplexRemovalTrait.php # 59 - src/Rector/AbstractRector/ComplexRemovalTrait.php # 59 - src/Rector/AbstractRector/ConstFetchAnalyzerTrait.php # 24 - src/Rector/AbstractRector/ConstFetchAnalyzerTrait.php # 24 - src/Rector/AbstractRector/NodeTypeResolverTrait.php # 59 - src/Rector/AbstractRector/NodeTypeResolverTrait.php # 59 - src/Rector/AbstractRector/VisibilityTrait.php # 29 - src/Rector/AbstractRector/VisibilityTrait.php # 29 - message: '#Do not use setter on a service#' paths: - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/PhpDoc/AttributeAwareExtendsTagValueNodeFactory.php # 42 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/PhpDoc/AttributeAwareImplementsTagValueNodeFactory.php # 42 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/PhpDoc/AttributeAwareMethodTagValueNodeFactory.php # 53 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/PhpDoc/AttributeAwareMethodTagValueParameterNodeFactory.php # 50 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/PhpDoc/AttributeAwareParamTagValueNodeFactory.php # 48 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/PhpDoc/AttributeAwarePhpDocNodeFactory.php # 61 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/PhpDoc/AttributeAwarePropertyTagValueNodeFactory.php # 42 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/PhpDoc/AttributeAwareReturnTagValueNodeFactory.php # 42 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/PhpDoc/AttributeAwareThrowsTagValueNodeFactory.php # 42 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/PhpDoc/AttributeAwareVarTagValueNodeFactory.php # 42 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/Type/AttributeAwareArrayShapeItemNodeFactory.php # 41 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/Type/AttributeAwareArrayShapeNodeFactory.php # 45 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/Type/AttributeAwareArrayTypeNodeFactory.php # 42 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/Type/AttributeAwareCallableTypeNodeFactory.php # 48 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/Type/AttributeAwareGenericTypeNodeFactory.php # 47 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/Type/AttributeAwareIntersectionTypeNodeFactory.php # 44 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/Type/AttributeAwareNullableTypeNodeFactory.php # 42 - packages/attribute-aware-php-doc/src/AttributeAwareNodeFactory/Type/AttributeAwareUnionTypeNodeFactory.php # 44 - packages/better-php-doc-parser/src/PhpDocNodeFactory/PHPUnitDataProviderDocNodeFactory.php # 52 - packages/better-php-doc-parser/src/PhpDocNodeFactory/ParamPhpDocNodeFactory.php # 81 - packages/dynamic-type-analysis/src/Probe/TypeStaticProbe.php # 82 - packages/node-type-resolver/src/FileSystem/CurrentFileInfoProvider.php # 22 - packages/node-type-resolver/src/FileSystem/CurrentFileInfoProvider.php # 35 - packages/phpstan-static-type-mapper/src/TypeMapper/ObjectTypeMapper.php # 123 - packages/phpstan-static-type-mapper/src/TypeMapper/ObjectWithoutClassTypeMapper.php # 72 - packages/rector-generator/src/Rector/Closure/AddNewServiceToSymfonyPhpConfigRector.php # 39 - rules/nette-code-quality/src/FormControlTypeResolver/AssignedVariablesMethodCallsFormTypeResolver.php # 50 - rules/nette-code-quality/src/FormControlTypeResolver/ClassMethodFormTypeResolver.php # 67 - rules/nette-code-quality/src/FormControlTypeResolver/ConstructorFormControlTypeResolver.php # 62 - rules/nette-code-quality/src/FormControlTypeResolver/GetComponentMethodCallFormControlTypeResolver.php # 110 - rules/nette-code-quality/src/FormControlTypeResolver/MagicNetteFactoryInterfaceFormControlTypeResolver.php # 95 - rules/nette-code-quality/src/FormControlTypeResolver/MethodCallFormControlTypeResolver.php # 59 - rules/nette-code-quality/src/FormControlTypeResolver/NewFormControlTypeResolver.php # 61 - rules/nette-code-quality/src/FormControlTypeResolver/ReturnFormControlTypeResolver.php # 54 - rules/nette-code-quality/src/FormControlTypeResolver/ThisVariableInAnotherMethodFormControlTypeResolver.php # 52 - rules/nette-code-quality/src/FormControlTypeResolver/VariableConstructorFormControlTypeResolver.php # 84 - src/Configuration/ChangeConfiguration.php # 17 - src/Configuration/Configuration.php # 149 - src/Configuration/Configuration.php # 172 - src/Configuration/Configuration.php # 204 - src/Configuration/Configuration.php # 227 - src/Configuration/CurrentNodeProvider.php # 16 - src/Rector/AbstractRector/CallableNodeTraverserTrait.php # 24 - src/Rector/AbstractRector/CallableNodeTraverserTrait.php # 24 - src/Rector/AbstractRector/ConstFetchAnalyzerTrait.php # 24 - src/Rector/AbstractRector/ConstFetchAnalyzerTrait.php # 24 - src/Testing/NodeVisitor/AttributeCollectingNodeVisitor.php # 24 - src/Testing/NodeVisitor/AttributeCollectingNodeVisitor.php # 24 - '#Use "Symplify\\SmartFileSystem\\SmartFileSystem\:\:dumpFile\(\)" static call over "file_put_contents\(\)" func call#' - '#Class name start with Abstract must have abstract keyword#' - '#Parameter \#1 \$name of method Rector\\Restoration\\Rector\\Use_\\RestoreFullyQualifiedNameRector\:\:resolveFullyQualifiedName\(\) expects PhpParser\\Node\\Name, PhpParser\\Node\\Identifier\|PhpParser\\Node\\Name given#' - '#Class with base "CheckNotTestsNamespaceOutsideTestsDirectoryRule" name is already used in "Rector\\PHPStanExtensions\\Rule\\CheckNotTestsNamespaceOutsideTestsDirectoryRule", "Symplify\\CodingStandard\\Rules\\CheckNotTestsNamespaceOutsideTestsDirectoryRule"\. Use unique name to make classes easy to recognize#' - message: '#Do not use setter on a service#' paths: - src/HttpKernel/RectorKernel.php # buggy, is fixed on symplify dev-master - message: '#Method call argument on position 0 must use constant over value#' paths: - src/Rector/AbstractRector.php # 419 - src/Rector/AbstractRector.php # 419