En la primera parte vimos una introducción a los enumeradores y su uso más básico. En esta segunda parte, veremos aspectos algo más avanzados.
Por ejemplo, supongamos que tenemos que realizar una llamada a una API REST externa para mandar un objeto JSON que actualice el estado de la suscripción de cierto cliente respecto cierto servicio.
Viendo el esquema de la petición a efectuar, especificado en la documentación de dicha API, vemos que tenemos que mandar un campo llamado status_id
. También aparece una correspondencia entre los posibles nombres de los estados que puede tener una suscripción (lo que ve el usuario final) y sus valores (uuid):
| Status Name | Status Value |
| -----------------|--------------------------------------|
| Active | 1fab144c-594d-4d08-ace4-b6428ec0b900 |
| Canceled | ec9a0697-b1f9-4b51-832f-2d32b7727e37 |
| Expired | 239add72-e737-43eb-8160-2c328bace8ba |
| Pending | 9b858308-fa43-4d9f-ae1d-84efb505a0e6 |
| Awaiting renewal | de0217a3-1c82-4a11-972a-21b647313175 |
Entonces... ¿Cómo podemos trasladar el contenido de dicha tabla a un enum
de PHP para poder interactuar fácilmente con esa información? Pues de la siguiente manera:
enum SubscriptionStatus : string
{
case Active = '1fab144c-594d-4d08-ace4-b6428ec0b900';
case Canceled = 'ec9a0697-b1f9-4b51-832f-2d32b7727e37';
case Pending = '239add72-e737-43eb-8160-2c328bace8ba';
case Expired = '9b858308-fa43-4d9f-ae1d-84efb505a0e6';
case AwaitingRenewal = 'de0217a3-1c82-4a11-972a-21b647313175';
}
Nota: Como podemos observar en la primera línea del enum, en el caso de contener valores, podemos especificar de que tipo de datos van a ser. Se puede elegir entre int
o string
, pero no utilizar una unión de ambos (int|string
).
Nota 2: Este tipo de enums implementan la interfaz interna BackedEnum
de manera implícita, lo cual agrega dos métodos adicionales from
y tryFrom
. Se puede leer más detalles aquí.
Si realizamos un dump sobre el método cases()
del enum
, que ya vimos en la parte anterior, vemos que nos devuelve el siguiente resultado:
>>> SubscriptionStatus::cases();
[
{
+name: "Active",
+value: "1fab144c-594d-4d08-ace4-b6428ec0b900",
},
{
+name: "Canceled",
+value: "ec9a0697-b1f9-4b51-832f-2d32b7727e37",
},
{
+name: "Pending",
+value: "239add72-e737-43eb-8160-2c328bace8ba",
},
{
+name: "Expired",
+value: "9b858308-fa43-4d9f-ae1d-84efb505a0e6",
},
{
+name: "AwaitingRenewal",
+value: "de0217a3-1c82-4a11-972a-21b647313175",
},
]
Así pues, una vez unidas todas las piezas del puzle, podemos proceder a finalizar el desarrollo. En el formulario del front-end a través del cual el usuario final podrá cambiar el estatus, se podría representar así (ejemplo de implementación a través de Blade):
<select name="status_id">
@foreach(SubscriptionStatus::cases() as $status)
<option value="{{ $status->value }}"
{{ $subscription->status === $status->value ? 'selected' : null }}>
{{ $status->name }}
</option>
@endforeach
</select>
En cuanto al método encargado de procesar dicho formulario, quedaría de la siguiente forma (en Laravel):
public function updateStatus(UpdateSubscriptionRequest $request, string $id) : RedirectResponse
{
try {
$this->makeRequest(
endpoint: "subscription/{$id}/update-status",
method: HttpMethod::Patch->name,
body: json_encode(
[
'subscription_id' => $request->subscription_id
]
);
);
toast()->success(Lang::get('subscriptions::cruds.update-status.messages.success'));
} catch (Throwable $e) {
Log::error($e->getMessage);
toast()->error(Lang::get('subscriptions::cruds.update-status.messages.error'));
} finally {
return redirect()->back();
}
}
Lo que, por ejemplo, en caso de cancelar la suscripción, enviaría el siguiente objeto JSON:
{
"status_id": "ec9a0697-b1f9-4b51-832f-2d32b7727e37"
}
Y eso es todo por hoy. ¡Hasta la próxima!