somnambulist / doctrine-enum-bridge
Allows any enumeration library to be used with Doctrine type system.
Installs: 15 652
Dependents: 1
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 0
Requires
- php: >=7
- doctrine/dbal: ~2.5
Requires (Dev)
- eloquent/enumeration: 5.1.*
- myclabs/php-enum: ^1.4
- phpunit/phpunit: ~6.2
This package is auto-updated.
Last update: 2020-02-03 17:24:20 UTC
README
This repository has been archived. Please update to the combined package.s
Doctrine Enum Bridge
Provides a bridge between different enumeration implementations and Doctrine. Any type of PHP enumerable (e.g. Eloquent\Enumeration or myclabs/php-enum can be used with this adaptor.
A default, string casting, serializer is used if no serializer is provided.
All enumerations are stored using the DBs native varchar format. If you wish to use a custom
DB type, extend and re-implement the getSQLDeclaration()
method.
Requirements
- PHP 7+
- Doctrine 2.5+
Installation
Install using composer, or checkout / pull the files from github.com.
- composer require somnambulist/doctrine-enum-bridge
Usage
In your frameworks application service provider / bundle boot method, register your enums and the appropriate callables to create / serialize as needed. A default serializer that casts the enumerable to a string will be used if none is provided.
The callbacks will receive:
- value - the current value either a PHP type, or the database type (for constructor)
- name - the bound name given to the enumeration this could be the FQCN
- platform - the Doctrine AbstractPlatform instance
For example, in a Symfony project, in your AppBundle class:
class AppBundle extends Bundle { public function boot() { EnumerationBridge::registerEnumType(Action::class, function ($value) { if (Action::isValid($value)) { return new Action($value); } throw new InvalidArgumentException(sprintf( 'The value "%s" is not valid for the enum "%s". Expected one of ["%s"]', $value, Action::class, implode('", "', Action::toArray()) )); }); } }
In Laravel, add to your AppServiceProvider (register
and boot
should both work):
class AppServiceProvider extends ServiceProvider { public function boot() { EnumerationBridge::registerEnumType(Action::class, function ($value) { if (Action::isValid($value)) { return new Action($value); } throw new InvalidArgumentException(sprintf( 'The value "%s" is not valid for the enum "%s". Expected one of ["%s"]', $value, Action::class, implode('", "', Action::toArray()) )); }); } }
Note: the bridge will check if the type has already been registered and skip it if that is
the case. If you wish to replace an existing type then you should use Type::overrideType()
,
however that will only work if the type has already been registered.
Register Multiple Types
Multiple enumerations can be registered at once by calling registerEnumTypes()
and passing an
array of enum name and either an array of callables (constructor, serializer) or just the
constructor:
class AppBundle extends Bundle { public function boot() { EnumerationBridge::registerEnumTypes( [ 'gender' => [ function ($value) { if (Gender::isValidValue($value)) { return Gender::memberByValue($value); } throw new InvalidArgumentException(sprintf( 'The value "%s" is not valid for the enum "%s"', $value, Gender::class )); }, function ($value, $platform) { return is_null($value) ? 'default' : $value->value(); } ] ] ); } }
Usage in Doctrine Mapping Files
In your Doctrine mapping files simply set the type on the field:
fields: name: type: string length: 255 gender: type: gender action: type: AppBundle\Enumerable\Action
Share a Constructor
For enumerables that have the same signature / method names, a constructor callable can be shared.
To share a constructor callable, use the FQCN as the name of the enumerable or you could use a hash map of aliases to Enumerables:
class AppBundle extends Bundle { public function boot() { $constructor = function ($value, $class) { // constructor method should handle nulls if (is_null($value)) { return null; } if ($class::isValid($value)) { return new $class($value); } throw new InvalidArgumentException(sprintf( 'The value "%s" is not valid for the enum "%s". Expected one of ["%s"]', $value, $class, implode('", "', $class::toArray()) )); } EnumerationBridge::registerEnumType(Action::class, $constructor); EnumerationBridge::registerEnumType(Country::class, $constructor); EnumerationBridge::registerEnumType(Currency::class, $constructor); } }
Because each enumerable can be mapped to its own construct / serializer handlers, complex multitions from the Eloquent\Enumerable library can be handled by this bridge.