dbalabka / php-enumeration

Implementation of enumeration classes in PHP. The better alternative for enums
MIT License
53 stars 4 forks source link

Doctrine support #17

Open dbalabka opened 4 years ago

dbalabka commented 4 years ago

This library currently does not have Doctrine integration. Doctrine type implementation can be inspired by https://github.com/acelaya/doctrine-enum-type

Warxcell commented 3 years ago

This is what I use:

<?php

declare(strict_types=1);

namespace App\Doctrine;

use Dbalabka\Enumeration\Enumeration;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\StringType;

abstract class EnumType extends StringType
{
    abstract protected function getClass(): string;

    public function convertToDatabaseValue($value, AbstractPlatform $platform)
    {
        if ($value === null) {
            return null;
        }
        assert($value instanceof Enumeration);

        return $value->name();
    }

    public function convertToPHPValue($value, AbstractPlatform $platform)
    {
        if ($value === null) {
            return null;
        }
        $class = $this->getClass();

        return $class::valueOf($value);
    }

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

declare(strict_types=1);

namespace App\Doctrine;

use App\Entity\Questionnaire\Question\ChoiceTemplate;

class ChoiceTemplateType extends EnumType
{
    public function getName()
    {
        return 'choice_template';
    }

    protected function getClass(): string
    {
        return ChoiceTemplate::class;
    }
}
dbalabka commented 3 years ago

@Warxcell thanks for your contribution! PHP 8.1 will support Enums out of the box: https://php.watch/versions/8.1/enums Probably, the only feature that isn't supported, yet, is Maybe monad that will be implemented in future scope: https://wiki.php.net/rfc/adts

PHP 8.1 will be released around November 2021. So I'm going to archive this repository somewhere after 8.1 release.

If you are already using this library let me known then I can think about what I can do for you.

Warxcell commented 3 years ago

lol... I don't see any benefits from 8.1 enums.... They behave almost like constants. The most important to me using enums is the ability to assign numberable properties to them. :(

enum HTTPStatus: int {
    case OK = 200;
    case ACCESS_DENIED = 403;
    case NOT_FOUND = 404;

    public function label(): string {
        return static::getLabel($this);
    }

    public static function getLabel(self $value): string {
        return match ($value) {
            HTTPStatus::OK => 'OK',
            HTTPStatus::ACCESS_DENIED => 'Access Denied',
            HTTPStatus::NOT_FOUND => 'Page Not Found',
        };
    }
}

this is like work-around to me... With the way they are impelemented we will end-up with too much boilerplate code and possibility to forget to add values for every single method when adding new Enum. What will happen if I add case FORBIDDEN = 403 but forgot to add it's label in static method getLabel. And this become too much hassle when have 2-3 methods more to forget about.

They should be implemented like Java Enums. They are awesome.

public enum Element {
    H("Hydrogen"),
    HE("Helium"),
    NE("Neon");

    public final String label;

    private Element(String label) {
        this.label = label;
    }
}

and then you just use label. So much shorter and simpler.

Element.H.label
dbalabka commented 3 years ago

@Warxcell technically Java, PHP 8.1 and this library's enums are the same thing. They can not be compared with constants enums because all these implementations uses singleton objects to represent enum's values

I see your point about boilerplate code. It is something that can be improved in future versions of PHP. Still, you won't be able to miss to put the label into getLabel() method because match expression would not give you to make a mistake. You will get an error in runtime. Furthermore, such static analysis tools like Psalm can help you catch an error earlier.

To motivate you to use PHP 8.1 enums please review a problem with static method calls that I've described in README. IMO the benefit of using more convenient PHP 8.1 enums syntax compensate missing features.

Also, you will benefit from the fact that most of the libraries will support new enums out of the box.