Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for nullable enums #19

Closed
Wirone opened this issue Sep 30, 2020 · 4 comments · Fixed by #20
Closed

Support for nullable enums #19

Wirone opened this issue Sep 30, 2020 · 4 comments · Fixed by #20
Labels
feature New feature or request

Comments

@Wirone
Copy link
Contributor

Wirone commented Sep 30, 2020

PlatenumDoctrineType does not support nullable fields. When entity which uses enums on nullable fields is persisted, there is Call to a member function getValue() on null error. Unfortunately since class is final it's impossible to override convertToDatabaseValue() and convertToPHPValue() methods.

@Wirone Wirone mentioned this issue Sep 30, 2020
@thunderer
Copy link
Owner

You can register Platenum embeddables manually, PlatenumDoctrineType is just a default solution provided with the library. In one of my current projects we do that through an equivalent XML:

    <embeddable name="FQCN">
        <field name="value" type="smallint" column="value" nullable="false" />
    </embeddable>

I see your point though, so let's move the discussion to #20.

@thunderer
Copy link
Owner

Leaving these notes for future readers:

@thunderer thunderer added the feature New feature or request label Oct 1, 2020
@Wirone
Copy link
Contributor Author

Wirone commented Oct 1, 2020

Thanks for related issues. "Problem" with embeddables is that they use prefixes (class-field) and requires more configuration than simple field with custom type, so I wanted to use custom types.

On the side note - I found it hard yesterday to find correct place in Symfony app to call PlatenumDoctrineType::registerString() so types would be registered system-wide. I ended up with:

<?php

declare(strict_types=1);

namespace App\Infrastructure\Persistence\Doctrine;

use App\Foo;
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Thunder\Platenum\Doctrine\PlatenumDoctrineType;

class PlatenumTypeInitializer implements EventSubscriberInterface
{
    private bool $initialized = false;

    public function registerTypes(): void
    {
        if (true === $this->initialized) {
            return;
        }

        PlatenumDoctrineType::registerString('foo', Foo::class);

        $this->initialized = true;
    }

    public static function getSubscribedEvents(): array
    {
        return [
            KernelEvents::REQUEST => ['registerTypes', 10000000],
            ConsoleEvents::COMMAND => ['registerTypes', 10000000],
        ];
    }
}

@thunderer
Copy link
Owner

@Wirone I used them both ways (embeddable and custom type) in different projects, I guess it's a matter of personal taste and team approach. Custom types definitely feel cleaner and "better isolated" especially when you apply Hexagonal architecture as I see from your code example. :) As for the place for their registration, though, it depends on your overall approach:

  • my private projects are based on manually wired components rather than stock frameworks and I rely on container to provide all dependencies, including the kernel. Registration logic is written there in the container factory to ensure it's the only place you can get the container from and it should be called only once during the lifetime of the application,
  • in regular Symfony applications I put that logic behind proper guard if(false === Type::hasType('uuid')) in the application kernel's constructor. Since that's a global state initialization I think it wouldn't be a bad thing to call that code even in index.php, but then the other environments wouldn't have them, so kernel is the outermost generic place to do that. I wouldn't personally move it to framework events as the whole application should not know about this being a problem at all.

Side note: In Doctrine 3.0 the global Type container will be replaced with proper TypeRegistry, so our problem will go away.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants