Last active
August 29, 2020 23:23
-
-
Save themsaid/593a1972adbe35150e730c0ad3632cad to your computer and use it in GitHub Desktop.
PHP Enumerated Type
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trait HasEnums | |
{ | |
/** | |
* The array of enumerators of a given group. | |
* | |
* @param null|string $group | |
* @return array | |
*/ | |
static function enums($group = null) | |
{ | |
$constants = (new ReflectionClass(get_called_class()))->getConstants(); | |
if ($group) { | |
return array_filter($constants, function ($key) use ($group) { | |
return strpos($key, $group.'_') === 0; | |
}, ARRAY_FILTER_USE_KEY); | |
} | |
return $constants; | |
} | |
/** | |
* Check if the given value is valid within the given group. | |
* | |
* @param mixed $value | |
* @param null|string $group | |
* @return bool | |
*/ | |
static function isValidEnumValue($value, $group = null) | |
{ | |
$constants = static::enums($group); | |
return in_array($value, $constants); | |
} | |
/** | |
* Check if the given key exists. | |
* | |
* @param mixed $key | |
* @return bool | |
*/ | |
static function isValidEnumKey($key) | |
{ | |
return array_key_exists($key, static::enums()); | |
} | |
} |
Its really great! 👍
I came up with something almost identical a time ago!
I also use a method called const (never thought of a better name) in the trait that checks if an object's auto-detected attribute is equal to a constant in the model.
public function const($constant)
{
$constants = (new ReflectionClass(get_called_class()))->getConstants();
if (isset($constants[$constant])) {
$attr = strtolower(explode('_', $constant)[0]);
return $this->$attr == $constants[$constant];
}
return false;
}
So I can do something like:
$order->const('TYPE_DINE_IN');
Which is equivalent to:
$order->type == App\Models\Order::TYPE_DINE_IN;
Yes, I like to put all my models in its own namespace, and with this, I can avoid namespacing the constants in, for example, Blade views:
// normally
@if ($order->type == App\Models\Order::TYPE_TAKEAWAY)
// some code
@endif
// with trait
@if ($order->const('TYPE_TAKEAWAY'))
// some code
@endif
Of course, this method has some shortcomings —like if your attribute has a composite name like $order->delivery_status
and your constants are in the form of DELIVERY_STATUS_SENT
— because the method expects a single word in the attribute name, but it works for me the 99% of the time.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice! Thanks for sharing.