System for defining something similar to Java or Swift Enum types in PHP.
Define an Enum by creating a class which extends from \MadisonSolutions\Enum, and then define the possible Enum members with the definitions()
method.
You can define any other methods you like in the class - in the example below, there's an additional charge()
method for calculating shipping charges.
Note that the constructor method is private - instances of the Enum class cannot be created directly.
class ShippingMethod extends \MadisonSolutions\Enum\Enum
{
public static function definitions() : array
{
return [
'collection' => [
'label' => 'Collection',
'description' => 'Collect in person from our store.',
'fixed_charge' => 0,
'charge_per_kg' => 0,
],
'van' => [
'label' => 'Local van delivery',
'description' => 'Local delivery by our own vans.',
'fixed_charge' => 10,
'charge_per_kg' => 0,
],
'courier' => [
'label' => 'Nationwide delivery',
'description' => 'Nationwide delivery by courier service.',
'fixed_charge' => 5,
'charge_per_kg' => 3,
],
];
}
public function charge($weight) {
return $this->fixed_charge + $weight * $this->charge_per_kg;
}
}
foreach (ShippingMethods::members() as $method) {
echo $method->label . ': ' . $method->charge($weight) . "\n";
}
$freeMethods = ShippingMethods::subset(function ($method) {
return $method->fixed_charge === 0 && $method->charge_per_kg === 0;
});
You should not directly create instances of any Enum class - instead use static methods on the class.
$van = ShippingMethods::van();
// or
$van = ShippingMethod::named('van');
$method = ShippingMethod::maybeNamed($_POST['shipping-method']);
if (! $method) {
die("No such shipping method {$_POST['shipping-method']}");
}
if ($method == ShippingMethods::collection()) {
echo "You are collecting in person.";
}
// or
if ($method->name == 'collection') {
echo "You are collecting in person.";
}
// or
switch ($method) {
case ShippingMethods::collection():
echo "You are collecting in person.";
break;
}
// store
$stringValue = ShippingMethods::nameOf($method);
// save $stringValue in database
// load
$method = ShippingMethod::maybeNamed($stringValue);
Alternatively the serialize and unserialize methods can be used, however unserialize will throw an UnexpectedValueException if the serialized member no longer exists (because for example the definitions were changed between the time the data was saved, and when it was restored).
function validateShippingMethod($order, ShippingMethod $method) {
if ($method === ShippingMethods::van()) {
if (! $order->address->isLocal()) {
die("Van delivery is only available for local addresses");
}
}
}