This will allow you to map strings to existing enums. This is useful when you for example are building against multiple third party API's and you need to translate the enums between one and other.
Note: Mappers
is the only one that you cannot use together with
Getters
, Extractor
and Reporters
. This is simply due to the fact that it is
implementing the methods for those by itself. Under the hood it's using their
functionality, so the methods will work just the same.
Just like with Defaults, constants can be used to map a reference to an existing enum key. When such a constant exists, Enumhancer treats it like any other case.
enum Suit
{
use Henzeb\Enumhancer\Concerns\Mappers;
case Hearts;
case Clubs;
case Spades;
case Diamonds;
const AceOfClubs = Suit::Clubs;
}
Suit::get('AceOfClubs'); //returns Suit::Clubs
Note: constants containing a reference to existing cases can also be set to private
to prevent direct reference.
You can also add a constant definition with an array inside. The name
should be starting with map
, either lower or uppercase.
enum Suit
{
use Henzeb\Enumhancer\Concerns\Mappers;
private const MAP_SUIT = [
'AceOfSpades' => Suit::Spades
];
case Hearts;
case Clubs;
case Spades;
case Diamonds;
}
Suit::get('AceOfSpades'); //returns Suit::Spades
You can also have multiple mappers
specified that way. Just add another constant.
When you plan to use a different mapper for different situations, like languages,
You can create an object that extends Henzeb\Enumhancer\Contracts\Mapper
.
class SuitMapper extends Henzeb\Enumhancer\Contracts\Mapper
{
protected function mappable(): array
{
return [
'AceOfHearts' => 'hearts',
'AceOfClubs' => 'Clubs',
'AceOfSpades' => 2,
'AceOfDiamonds' => Suit::Diamonds
];
}
}
Just like cases, keys and values don't have to be in the correct case.
Just like arrays, when a constant has a string that points to an actual
Mapper
, Enumhancer will transform it into a Mapper object and use this.
enum Suit
{
use Henzeb\Enumhancer\Concerns\Mappers;
private const MAP_SUIT = SuitMapper::class;
case Hearts;
case Clubs;
case Spades;
case Diamonds;
}
Suit::get('AceOfDiamonds'); //returns Suit::Diamonds
In some cases you might want to apply the mapper through a method.
enum Suit
{
use Henzeb\Enumhancer\Concerns\Mappers;
case Hearts;
case Clubs;
case Spades;
case Diamonds;
protected static function mapper(): Henzeb\Enumhancer\Contracts\Mapper|array|string|null
{
return SuitMapper::class;
}
}
Suit::get('AceOfHearts'); // returns Suit::Hearts
If you wish, you can add as many mappers as you like to any of the Getters methods.
Suit::get('AceOfHearts', SuitMapper::class, SuitMapperFrench::class);
Suit::get('AceOfHearts', SuitMapper::getNewInstance());
Suit::tryGet('AceOfHearts', ['AceOfClubs'=>'AceOfHearts']);
See Configure
It's possible to combine the different methods. Mapping values is done waterfall.
This means a mapper can map to a value that does not necessarily exist in the enum
object, so another mapper can map that value to the final case.
enum Suit
{
use Henzeb\Enumhancer\Concerns\Mappers;
private const MAP_SUIT = [
'AceOfHearts' => 'AceOfClubs'
];
private const MAP_FINAL = [
'AceOfClubs' => Suit::Spades
];
case Hearts;
case Clubs;
case Spades;
case Diamonds;
}
Suit::get('AceOfHearts'); //returns Suit::Spades
The order of precedence is as follows:
- Any mappers passed by argument in order of appearance
- Mapper returned by static method
- Mappers set by Configure
- Mappers (array or class name) defined in constants in order of appearance
The mapper object allows you to share one single object for multiple enums. For that to work, you have to return a multidimensional array that has a key pointing at your enum containing an array of what you want to map for this particular enum.
class SuitMapper extends Henzeb\Enumhancer\Contracts\Mapper
{
protected function mappable(): array
{
return [
Suit::class => [
'AceOfHearts' => 'hearts',
'AceOfClubs' => 1,
'AceOfSpades' => 'Spades',
],
'AceOfDiamonds' => Suit::Diamonds
];
}
}
If, for some reason, you want to know if a value is defined, you can check that with this method.
$suitMapper->defined('AceOfDiamonds'); // returns true
$suitMapper->defined('AceOfDiamonds', Suit::class); // returns true
$suitMapper->defined('AceOfHearts'); // returns false
$suitMapper->defined('AceOfHearts', Suit::class); // returns true
SuitMapper::defined('AceOfDiamonds'); // returns true
SuitMapper::defined('AceOfDiamonds', Suit::class); // returns true
SuitMapper::defined('AceOfHearts'); // returns false
SuitMapper::defined('AceOfHearts', Suit::class); // returns true
The keys
method shows you a list of defined keys.
In case of a shared mapper, without the enum class name, keys
will only return global map keys.
$suitMapper->keys();
$suitMapper->keys(Suit::class);
SuitMapper::keys();
SuitMapper::keys(Suit::class);
In some cases, you might want to flip your map. Instead of creating a second mapper, you can just call flip on your existing mapper.
In case of a shared mapper, without the enum class name, only global map keys will be flipped and used for mapping.
$suitMapper->flip();
$suitMapper->flip(Suit::class);
SuitMapper::flip();
SuitMapper::flip(Suit::class);
Just like with MAP
, you can add constants starting with
MAP_FLIP
(again, uppercased or lowercased) to point at your mapper.
enum Suit
{
use Henzeb\Enumhancer\Concerns\Mappers;
private const MAP_FLIP_SUIT = SuitMapper::class;
case Hearts;
case Clubs;
case Spades;
case Diamonds;
}