0

I've made a custom Doctrine Type in symfony, that extends Doctrine\DBAL\Types\Type

I need to inject symfony's Serializer there, to decode some JSON using symfony's serializer so it can hyrdrate a specific class.

However, I can't override the constructor since it's final, and can't inject SerializerInterface

I've tried to use a setter and inject SerializerInterface, but it's not working.

class MyCustomDoctrineType extends Type
{

    private const NAME = 'my_custom_type';

    /**
     * {@inheritdoc}
     */
    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
    {
        return $platform->getJsonTypeDeclarationSQL($fieldDeclaration);
    }

    /**
     * {@inheritdoc}
     */
    public function convertToDatabaseValue($value, AbstractPlatform $platform)
    {
        if ($value === null) {
            return null;
        }

        return $value;
    }


    /**
     * {@inheritdoc}
     */
    public function convertToPHPValue($value, AbstractPlatform $platform)
    {
        if ($value === null || $value === '') {
            return null;
        }

        if (is_resource($value)) {
            $value = stream_get_contents($value);
        }

        $this->serializer->deserialize($value, MyClass::class, 'json'); // this is what I want to accomplish

        return $value;
    }

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


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

Is there any way to do dependency injection there ?

Arkounay
  • 86
  • 7
  • Thank you @emix, this helped. I added a boot() function in src/Kernel in symfony 4, and it seems to be working public function boot() { parent::boot(); \Doctrine\DBAL\Types\Type::getType(JsonRaw::NAME)->setSerializer($this->container->get('serializer')); } – Arkounay Jun 09 '20 at 13:23

1 Answers1

0

As @emix pointed, in Symfony 4 you can override the boot() function in Kernel.php and manually inject dependencies from there

public function boot()
{
    parent::boot();
    \Doctrine\DBAL\Types\Type::getType('my_type_name')->setSerializer($this->container->get('serializer'));
}
Arkounay
  • 86
  • 7
  • This worked fine for me until I updated to Symfony 6. Now it throws the following error: `The "serializer" service or alias has been removed or inlined when the container was compiled. You should either make it public, or stop using the container directly and use dependency injection instead.` – Stephan TP Mar 10 '23 at 10:31