All Projects → acelaya → Doctrine Enum Type

acelaya / Doctrine Enum Type

Licence: mit
A custom Doctrine type that maps column values to enum objects using myclabs/php-enum

Labels

Projects that are alternatives of or similar to Doctrine Enum Type

Idea Php Symfony2 Plugin
IntelliJ IDEA / PhpStorm Symfony Plugin
Stars: ✭ 797 (+558.68%)
Mutual labels:  doctrine
Factory Bot
🤖 Provides a fixture factory for doctrine/orm entities.
Stars: ✭ 57 (-52.89%)
Mutual labels:  doctrine
Search
PHP search-systems made possible
Stars: ✭ 101 (-16.53%)
Mutual labels:  doctrine
Doctrinemigrations
[DEPRECATED] Use Phinx instead
Stars: ✭ 24 (-80.17%)
Mutual labels:  doctrine
Oneupaclbundle
The missing link between Symfonys Acl implementation and your application.
Stars: ✭ 48 (-60.33%)
Mutual labels:  doctrine
Doctrine Stats
Get Doctrine stats : managed entities, lazy loaded entities, hydration time etc.
Stars: ✭ 65 (-46.28%)
Mutual labels:  doctrine
Uuid Doctrine
Allow the use of a ramsey/uuid UUID as Doctrine field type.
Stars: ✭ 751 (+520.66%)
Mutual labels:  doctrine
User Bundle
A new Symfony user bundle
Stars: ✭ 116 (-4.13%)
Mutual labels:  doctrine
Parse Comments
Parse JavaScript code comments. Works with block and line comments, and should work with CSS, LESS, SASS, or any language with the same comment formats.
Stars: ✭ 53 (-56.2%)
Mutual labels:  doctrine
Dbal Schema
DB schema manager for Doctrine DBAL
Stars: ✭ 82 (-32.23%)
Mutual labels:  doctrine
Zf Doctrine Hydrator
A collection of common hydrators for phpro/zf-doctrine-hydration-module
Stars: ✭ 9 (-92.56%)
Mutual labels:  doctrine
Lumen Doctrine
Doctrine module for the Lumen PHP framework.
Stars: ✭ 41 (-66.12%)
Mutual labels:  doctrine
Kimai2
Kimai v2 is a web-based multiuser time-tracking application. Free for everyone: freelancers, agencies, companies, organizations - all can track their times, generate invoices and more. SaaS version available at https://www.kimai.cloud
Stars: ✭ 1,216 (+904.96%)
Mutual labels:  doctrine
Doctrinetraitbundle
Generate the entities stub methods in a trait
Stars: ✭ 6 (-95.04%)
Mutual labels:  doctrine
Doctrine Dbal Postgresql
Add JSON query support to Doctrine DBAL and DQL
Stars: ✭ 114 (-5.79%)
Mutual labels:  doctrine
Doctrinebehaviors
Doctrine2 behavior traits
Stars: ✭ 782 (+546.28%)
Mutual labels:  doctrine
Forkcms
Fork is an easy to use open source CMS using Symfony Components.
Stars: ✭ 1,112 (+819.01%)
Mutual labels:  doctrine
Php Sf Flex Webpack Encore Vuejs
A simple app skeleton to try to make every components work together : symfony 4 (latest stable at the date, but work with sf 3.3+ if you just change the versions in composer.json), symfony/flex, webpack-encore, vuejs 2.5.x, boostrap 4 sass
Stars: ✭ 118 (-2.48%)
Mutual labels:  doctrine
Dtcqueuebundle
Symfony2/3/4/5 Queue Bundle (for background jobs) supporting Mongo (Doctrine ODM), Mysql (and any Doctrine ORM), RabbitMQ, Beanstalkd, Redis, and ... {write your own}
Stars: ✭ 115 (-4.96%)
Mutual labels:  doctrine
Graphql Doctrine
Automatic GraphQL types from Doctrine entities
Stars: ✭ 81 (-33.06%)
Mutual labels:  doctrine

Doctrine Enum Type

Build Status Code Coverage Latest Stable Version Total Downloads License Paypal Donate

This package provides a base implementation to define doctrine entity column types that are mapped to MyCLabs\Enum\Enum objects. That class is defined in the fantastic myclabs/php-enum package.

Installation

The recommended installation method is by using composer

composer require acelaya/doctrine-enum-type

Usage

This package provides a Acelaya\Doctrine\Type\PhpEnumType class that extends Doctrine\DBAL\Types\Type. You can use it to easily map type names to concrete Enums.

The PhpEnumType class will be used as the doctrine type for every property that is an enumeration.

Let's imagine we have this two enums.

<?php

declare(strict_types=1);

namespace Acelaya\Enum;

use MyCLabs\Enum\Enum;

class Action extends Enum
{
    public const CREATE = 'create';
    public const READ = 'read';
    public const UPDATE = 'update';
    public const DELETE = 'delete';
}
<?php

declare(strict_types=1);

namespace Acelaya\Enum;

use MyCLabs\Enum\Enum;

class Gender extends Enum
{
    public const MALE = 'male';
    public const FEMALE = 'female';
}

And this entity, with a column of each entity type.

<?php

declare(strict_types=1);

namespace Acelaya\Entity;

use Acelaya\Enum\Action;
use Acelaya\Enum\Gender;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity()
 * @ORM\Table(name="users")
 */
class User
{
    /**
     * @var int
     *
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
    /**
     * @var string
     *
     * @ORM\Column()
     */
    protected $name;
    /**
     * @var Action
     *
     * @ORM\Column(type=Action::class, length=10)
     */
    protected $action;
    /**
     * @var Gender
     *
     * @ORM\Column(type="php_enum_gender")
     */
    protected $gender;

    // Getters and setters...
}

The column type of the action property is the FQCN of the Action enum, and the gender column type is php_enum_gender. To get this working, you have to register the concrete column types, using the Acelaya\Doctrine\Type\PhpEnumType::registerEnumType static method.

<?php

declare(strict_types=1);

// in bootstrapping code

// ...

use Acelaya\Doctrine\Type\PhpEnumType;
use Acelaya\Enum\Action;
use Acelaya\Enum\Gender;

// ...

// Register my types
PhpEnumType::registerEnumType(Action::class);
PhpEnumType::registerEnumType('php_enum_gender', Gender::class);

// Don't forget to register the enums for schema operations
$platform = $em->getConnection()->getDatabasePlatform();
$platform->registerDoctrineTypeMapping('VARCHAR', Action::class);
$platform->registerDoctrineTypeMapping('VARCHAR', 'php_enum_gender');

That will internally register a customized doctrine type. As you can see, it its possible to just pass the FQCN of the enum, making the type use it as the name, but you can also provide a different name.

Alternatively you can use the Acelaya\Doctrine\Type\PhpEnumType::registerEnumTypes, which expects an array of enums to register.

<?php

declare(strict_types=1);

// ...

use Acelaya\Doctrine\Type\PhpEnumType;
use Acelaya\Enum\Action;
use Acelaya\Enum\Gender;

PhpEnumType::registerEnumTypes([
    Action::class,
    'php_enum_gender' => Gender::class,
]);

With this method, elements with a string key will be registered with that name, and elements with integer key will use the value as the type name.

Do the same for each concrete enum you want to register.

If you need more information on custom doctrine column types, read this http://doctrine-orm.readthedocs.io/en/latest/cookbook/custom-mapping-types.html

Customize SQL declaration

By default, the Acelaya\Doctrine\Type\PhpEnumType class defines all enums as a VARCHAR like this:

public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
{
    return $platform->getVarcharTypeDeclarationSQL($fieldDeclaration);
}

This means that you can customize the length (which defaults to 255), but not the column type.

If you want something more specific, like a MySQL enum, just extend PhpEnumType and overwrite the getSQLDeclaration() method with something like this.

<?php

declare(strict_types=1);

namespace App\Type;

use Acelaya\Doctrine\Type\PhpEnumType;
use Doctrine\DBAL\Platforms\AbstractPlatform;

use function call_user_func;
use function implode;
use function sprintf;

class MyPhpEnumType extends PhpEnumType
{
    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform): string
    {
        $values = call_user_func([$this->enumClass, 'toArray']);
        return sprintf(
            'ENUM("%s") COMMENT "%s"',
            implode('", "', $values),
            $this->getName()
        );
    }
}

Then remember to register the enums with your own class.

<?php

declare(strict_types=1);

// ...

use Acelaya\Enum\Action;
use Acelaya\Enum\Gender;
use App\Type\MyPhpEnumType;

MyPhpEnumType::registerEnumTypes([
    Action::class,
    'php_enum_gender' => Gender::class,
]);

Customize value casting

The library assumes all the values of the enumeration are strings, but that might not always be the case.

Since v2.2.0, the library provides a way to define hooks which customize how values are cast from the database and to the database, by using the castValueIn and castValueOut static methods in the enumeration.

For example, let's imagine we have this enum:

<?php

declare(strict_types=1);

namespace Acelaya\Enum;

use MyCLabs\Enum\Enum;

class Status extends Enum
{
    public const SUCCESS = 1;
    public const ERROR = 2;
}

Using the generic PhpEnumType would cause an error when casting the value from the database, since it will be deserialized as a string.

In order to get it working, you have to add the castValueIn static method in the enum:

<?php

declare(strict_types=1);

namespace Acelaya\Enum;

use MyCLabs\Enum\Enum;

class Status extends Enum
{
    public const SUCCESS = 1;
    public const ERROR = 2;

    public static function castValueIn($value): int
    {
        return (int) $value;
    }
}

This method is automatically invoked before checking if the value is valid, and creating the enum instance.

The same way, a castValueOut method can be defined in order to modify the value before getting it persisted into the database.

<?php

declare(strict_types=1);

namespace Acelaya\Enum;

use MyCLabs\Enum\Enum;

use function strtolower;

class Gender extends Enum
{
    public const MALE = 'male';
    public const FEMALE = 'female';

    public static function castValueOut(self $value): string
    {
        return strtolower((string) $value);
    }
}

These methods can also be used to customize the values. For example, if you used to have values with underscores and want to replace them by dashes, you could define these methods in your enum, in order to keep backward compatibility.

<?php

// ...
public static function castValueIn($value): string
{
    return \str_replace('_', '-', $value);
}

public static function castValueOut(self $value): string
{
    return \str_replace('-', '_', (string) $value);
}
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].