Skip to content

CorrectDefaultTypesOnEntityPropertyRector type "boolean" add support for integer values #9905

Description

@raphaelincert

Bug Report

Subject Details
Rector version 2.6.7

Hi,
the rule CorrectDefaultTypesOnEntityPropertyRector currently crashes rector if a property with doctrine type "boolean" is initialized as int.

devilbox@php-8.0.27 in /shared/httpd/my-gms/htdocs $ ./vendor/bin/rector --clear-cache --debug Common/Model/InterfaceEntry.php
[file] /shared/httpd/my-gms/htdocs/Common/Model/InterfaceEntry.php


 [ERROR] Could not process "/shared/httpd/my-gms/htdocs/Common/Model/InterfaceEntry.php" file, due to:
         "System error: ""

         Stack trace:
         #0
         vendor/rector/rector/vendor/rector/rector-doctrine/rules/CodeQuality/Rector/Property/CorrectDefaultTypesOnEntit
         yPropertyRector.php(110):
         Rector\Doctrine\CodeQuality\Rector\Property\CorrectDefaultTypesOnEntityPropertyRector->refactorToBoolType(Obje
         ct(PhpParser\Node\PropertyItem), Object(PhpParser\Node\Stmt\Property))
         #1 vendor/rector/rector/src/Rector/AbstractRector.php(129):
         Rector\Doctrine\CodeQuality\Rector\Property\CorrectDefaultTypesOnEntityPropertyRector->refactor(Object(PhpPars
         er\Node\Stmt\Property))
         #2 vendor/rector/rector/src/PhpParser/NodeTraverser/RectorNodeTraverser.php(203):
         Rector\Rector\AbstractRector->enterNode(Object(PhpParser\Node\Stmt\Property))
         #3 vendor/rector/rector/src/PhpParser/NodeTraverser/RectorNodeTraverser.php(139):
         Rector\PhpParser\NodeTraverser\RectorNodeTraverser->traverseArray(Array)
         #4 vendor/rector/rector/src/PhpParser/NodeTraverser/RectorNodeTraverser.php(235):
         Rector\PhpParser\NodeTraverser\RectorNodeTraverser->traverseNode(Object(PhpParser\Node\Stmt\Class_))
         #5 vendor/rector/rector/src/PhpParser/NodeTraverser/RectorNodeTraverser.php(139):
         Rector\PhpParser\NodeTraverser\RectorNodeTraverser->traverseArray(Array)
         #6 vendor/rector/rector/src/PhpParser/NodeTraverser/RectorNodeTraverser.php(235):
         Rector\PhpParser\NodeTraverser\RectorNodeTraverser->traverseNode(Object(PhpParser\Node\Stmt\Namespace_))
         #7 vendor/rector/rector/src/PhpParser/NodeTraverser/RectorNodeTraverser.php(139):
         Rector\PhpParser\NodeTraverser\RectorNodeTraverser->traverseArray(Array)
         #8 vendor/rector/rector/src/PhpParser/NodeTraverser/RectorNodeTraverser.php(235):
         Rector\PhpParser\NodeTraverser\RectorNodeTraverser->traverseNode(Object(Rector\PhpParser\Node\FileNode))
         #9 vendor/rector/rector/src/PhpParser/NodeTraverser/RectorNodeTraverser.php(88):
         Rector\PhpParser\NodeTraverser\RectorNodeTraverser->traverseArray(Array)
         #10 vendor/rector/rector/src/Application/FileProcessor.php(104):
         Rector\PhpParser\NodeTraverser\RectorNodeTraverser->traverse(Array)
         #11 vendor/rector/rector/src/Application/ApplicationFileProcessor.php(198):
         Rector\Application\FileProcessor->processFile(Object(Rector\ValueObject\Application\File),
         Object(Rector\ValueObject\Configuration))
         #12 vendor/rector/rector/src/Application/ApplicationFileProcessor.php(166):
         Rector\Application\ApplicationFileProcessor->processFile(Object(Rector\ValueObject\Application\File),
         Object(Rector\ValueObject\Configuration))
         #13 vendor/rector/rector/src/Application/ApplicationFileProcessor.php(136):
         Rector\Application\ApplicationFileProcessor->processFiles(Array, Object(Rector\ValueObject\Configuration),
         Object(Closure), Object(Closure))
         #14 vendor/rector/rector/src/Console/Command/ProcessCommand.php(182):
         Rector\Application\ApplicationFileProcessor->run(Object(Rector\ValueObject\Configuration),
         Object(RectorPrefix202609\Symfony\Component\Console\Input\ArgvInput))
         #15 vendor/rector/rector/vendor/symfony/console/Command/Command.php(289):
         Rector\Console\Command\ProcessCommand->execute(Object(RectorPrefix202609\Symfony\Component\Console\Input\ArgvI
         nput), Object(RectorPrefix202609\Symfony\Component\Console\Output\ConsoleOutput))
         #16 vendor/rector/rector/vendor/symfony/console/Application.php(911):
         RectorPrefix202609\Symfony\Component\Console\Command\Command->run(Object(RectorPrefix202609\Symfony\Component\
         Console\Input\ArgvInput), Object(RectorPrefix202609\Symfony\Component\Console\Output\ConsoleOutput))
         #17 vendor/rector/rector/vendor/symfony/console/Application.php(279):
         RectorPrefix202609\Symfony\Component\Console\Application->doRunCommand(Object(Rector\Console\Command\ProcessCo
         mmand), Object(RectorPrefix202609\Symfony\Component\Console\Input\ArgvInput),
         Object(RectorPrefix202609\Symfony\Component\Console\Output\ConsoleOutput))
         #18 vendor/rector/rector/src/Console/ConsoleApplication.php(77):
         RectorPrefix202609\Symfony\Component\Console\Application->doRun(Object(RectorPrefix202609\Symfony\Component\Co
         nsole\Input\ArgvInput), Object(RectorPrefix202609\Symfony\Component\Console\Output\ConsoleOutput))
         #19 vendor/rector/rector/vendor/symfony/console/Application.php(162):
         Rector\Console\ConsoleApplication->doRun(Object(RectorPrefix202609\Symfony\Component\Console\Input\ArgvInput),
         Object(RectorPrefix202609\Symfony\Component\Console\Output\ConsoleOutput))
         #20 vendor/rector/rector/bin/rector.php(138): RectorPrefix202609\Symfony\Component\Console\Application->run()
         #21 vendor/rector/rector/bin/rector(5): require_once('/shared/httpd/m...')
         #22 vendor/bin/rector(120): include('/shared/httpd/m...')
         #23 {main}". On line: 133

Please have a look at the doctrine doc: https://www.doctrine-project.org/projects/doctrine-dbal/en/4.4/reference/types.html#boolean
The crucial part is:

As most of the database vendors do not have a native boolean type, this type silently falls back to the smallest possible integer or bit data type if necessary to ensure the least possible data storage requirements are met.

In my case i use mariadb and store boolean as TINYINT(1) with "1" & "0" for true and false.

The problem is that CorrectDefaultTypesOnEntityPropertyRector::refactorToBoolType() only checks for strings:

Image

In my opinion the check should be changed instanceof String_ || instanceof Int_.

Best regards

Minimal PHP Code Causing Issue

class InterfaceEntry
{
    /**
     * @var boolean
     * @Type("boolean")
     * @Column(name="is_overwrite", type="boolean", nullable=false)
     */
    private $isOverwrite = 0;
}

Expected Behaviour

property with int default should be changed to bool

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions