phpstan-doctrine icon indicating copy to clipboard operation
phpstan-doctrine copied to clipboard

EntityRelationRule failing for every custom type even when type descriptors are registered

Open janedbal opened this issue 2 years ago • 1 comments

Having following entity with custom type and descriptor:

enum FeeCategory: string {}

#[Entity]
class Fee
{

    #[Column(type: FeeCategoryType::NAME]
    private FeeCategory $feeCategory;

}

class FeeCategoryType extends StringType
{

    final public const NAME = 'fee_category';

    /**
     * @return class-string<BackedEnum<string>>
     */
    public function getEnumClass(): string
    {
        return FeeCategory::class;
    }

    public function getName(): string
    {
        return self::NAME;
    }

    /**
     * @param BackedEnum<string>|string|null $value
     * @return BackedEnum<string>|null
     */
    public function convertToPHPValue($value, AbstractPlatform $platform): ?BackedEnum
    {
        if ($value instanceof BackedEnum) {
            return $value;
        }

        $value = parent::convertToPHPValue($value, $platform);

        if ($value === null) {
            return null;
        }

        return static::getEnumClass()::from($value);
    }

    /**
     * @param BackedEnum<string>|string|null $value
     */
    public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string
    {
        if (!$value instanceof BackedEnum) {
            return $value;
        }

        return $value->value;
    }

    public function requiresSQLCommentHint(AbstractPlatform $platform): bool
    {
        return true;
    }

}

class FeeCategoryTypeDescriptor implements DoctrineTypeDescriptor
{

    public function getType(): string
    {
        return FeeCategoryType::class;
    }

    public function getWritableToPropertyType(): Type
    {
        return new ObjectType(FeeCategory::class);
    }

    public function getWritableToDatabaseType(): Type
    {
        return new StringType();
    }

    public function getDatabaseInternalType(): Type
    {
        return new StringType();
    }

}

Still produces error

Property Fee::$feeCategory type mapping mismatch: property can contain FeeCategory but database expects string.

I think this rule should utilize the knowledge from the descriptor.


Used version: 1.3.29, bleedingEdge enabled.

janedbal avatar Jan 18 '23 10:01 janedbal

Not sure if you are aware, if so, please ignore: Doctrine now supports enumType so that you can write it like this:

enum FeeCategory: string {}

#[Entity]
class Fee
{

    #[Column(type: 'string', enumType: FeeCategory::class]
    private FeeCategory $feeCategory;

}

This way, you don't have to use a custom type and it works.

ruudk avatar Jul 04 '24 18:07 ruudk