Dentro del bucle, hacer que las cosas sean dinámicas no es nada nuevo... ¡lo cual es genial! Por ejemplo, {{ ship.status }}
. Cuando actualizamos, ¡se imprime! Aunque, ¡ay! Los estados se están quedando sin espacio. ¡Nuestros datos no coinciden con el diseño!
// ... lines 1 - 4 | |
{% block body %} | |
<main class="flex flex-col lg:flex-row"> | |
// ... lines 7 - 8 | |
<div class="px-12 pt-10 w-full"> | |
// ... lines 10 - 13 | |
<div class="space-y-5"> | |
{% for ship in ships %} | |
// ... lines 16 - 43 | |
{% endfor %} | |
</div> | |
// ... lines 46 - 50 | |
</div> | |
</main> | |
{% endblock %} |
¡Giro argumental! Alguien cambió los requisitos del proyecto... ¡justo en medio! ¡Eso "nunca" ocurre! El nuevo plan es éste: cada nave debe tener un estado dein progress
, waiting
, o completed
. Ensrc/Repository/StarshipRepository.php
, nuestras naves sí tienen un status
-es este argumento-, pero es una cadena que puede establecerse con cualquier valor.
Crear un Enum
Así que tenemos que hacer algunas refactorizaciones para adaptarnos al nuevo plan. Pensemos: hay exactamente tres estados válidos. Este es un caso de uso perfecto para una enum PHP.
Si no estás familiarizado con los enums, son encantadores y una forma estupenda de organizar un conjunto de estados -como publicado, no publicado y borrador- o tamaños -pequeño, mediano o grande- o cualquier cosa similar.
En el directorio Model/
-aunque esto podría vivir en cualquier sitio... estamos creando el enum para nuestra propia organización- crea una nueva clase y llámala StarshipStatusEnum
. En cuanto escribí la palabra enum, PhpStorm cambió la plantilla de class
a unaenum
. Así que no estamos creando una clase, como puedes ver, creamos una enum
// ... lines 1 - 2 | |
namespace App\Model; | |
enum StarshipStatusEnum: string | |
{ | |
// ... lines 7 - 9 | |
} |
Añade un : string
al enum para hacer lo que se llama un "enum respaldado por cadena". No profundizaremos demasiado, pero esto nos permite definir cada estado -como WAITING
y asignarlo a una cadena, lo que será útil en un minuto. Añade un estado para IN_PROGRESS
y finalmente uno para COMPLETED
.
// ... lines 1 - 2 | |
namespace App\Model; | |
enum StarshipStatusEnum: string | |
{ | |
case WAITING = 'waiting'; | |
case IN_PROGRESS = 'in progress'; | |
case COMPLETED = 'completed'; | |
} |
Y ya está Eso es todo lo que es un enum: un conjunto de "estados" que se centralizan en un solo lugar.
A continuación: abre la clase Starship
. El último argumento es actualmente un estado string
. Cámbialo para que sea un StarshipStatusEnum
. Y en la parte inferior, el método getStatus
devolverá ahora un StarshipStatusEnum
.
// ... lines 1 - 2 | |
namespace App\Model; | |
enum StarshipStatusEnum: string | |
{ | |
case WAITING = 'waiting'; | |
case IN_PROGRESS = 'in progress'; | |
case COMPLETED = 'completed'; | |
} |
Por último, en StarshipRepository
donde creamos cada Starship
, mi editor está enfadado. Dice:
¡Eh! ¡Este argumento acepta un
StarshipStatusEnum
, pero estás pasando una cadena!
Vamos a calmarlo. Cambia esto a StarshipStatusEnum::
... ¡y autocompleta las opciones! Hagamos que la primera sea IN_PROGRESS
. Y eso añadió la declaración use
para el enum
al principio de la clase. Para la siguiente, que sea COMPLETED
... y para la última, WAITING
.
// ... lines 1 - 5 | |
use App\Model\StarshipStatusEnum; | |
// ... lines 7 - 8 | |
class StarshipRepository | |
{ | |
// ... lines 11 - 14 | |
public function findAll(): array | |
{ | |
// ... lines 17 - 18 | |
return [ | |
new Starship( | |
// ... lines 21 - 24 | |
StarshipStatusEnum::IN_PROGRESS | |
), | |
new Starship( | |
// ... lines 28 - 31 | |
StarshipStatusEnum::COMPLETED | |
), | |
new Starship( | |
// ... lines 35 - 38 | |
StarshipStatusEnum::WAITING | |
), | |
]; | |
} | |
// ... lines 43 - 53 | |
} |
¡Refactorización realizada! Bueno... tal vez. Cuando actualizamos, ¡arruinado! Dice
el objeto de clase
StarshipStatusEnum
no se ha podido convertir a cadena
Y viene de la llamada a Twig de ship.status
.
Tiene sentido: ship.status
es ahora un enum... que no puede imprimirse directamente como cadena. La solución más fácil, en homepage.html.twig
, es añadir .value
.
// ... lines 1 - 4 | |
{% block body %} | |
<main class="flex flex-col lg:flex-row"> | |
// ... lines 7 - 8 | |
<div class="px-12 pt-10 w-full"> | |
// ... lines 10 - 13 | |
<div class="space-y-5"> | |
{% for ship in ships %} | |
<div class="bg-[#16202A] rounded-2xl pl-5 py-5 pr-11 flex flex-col min-[1174px]:flex-row min-[1174px]:justify-between"> | |
<div class="flex justify-center min-[1174px]:justify-start"> | |
// ... line 18 | |
<div class="ml-5"> | |
<div class="rounded-2xl py-1 px-3 flex justify-center w-32 items-center bg-amber-400/10"> | |
// ... line 21 | |
<p class="uppercase text-xs text-nowrap">{{ ship.status.value }}</p> | |
</div> | |
// ... lines 24 - 29 | |
</div> | |
</div> | |
// ... lines 32 - 42 | |
</div> | |
{% endfor %} | |
</div> | |
// ... lines 46 - 50 | |
</div> | |
</main> | |
{% endblock %} |
Como hemos hecho que nuestro enum esté respaldado por una cadena, tiene una propiedad value
, que será la cadena que asignamos al estado actual. Pruébalo ahora. ¡Tiene una pinta estupenda! En curso, completado, esperando.
A continuación: vamos a aprender cómo podemos hacer este último cambio un poco más elegante creando métodos más inteligentes en nuestra clase Starship
. Luego daremos los toques finales a nuestro diseño.