This course is still being released! Check back later for more chapters.
Validación de la configuración del bundle
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
With a Subscription, click any sentence in the script to jump to that part of the video!
Login SubscribeYa tenemos esta opción de configuración translation_class
en nuestro bundle. Necesita cierta validación: primero, debe ser obligatoria; segundo, debe ser una cadena no vacía; y tercero, debe ser una clase válida que extienda la clase Translation
de nuestro bundle.
Como hemos utilizado stringNode()
, ya tenemos una validación básica: debe ser una cadena. Añadamos el resto.
Obligatorio y no vacío
Debajo de nuestra llamada a ->example()
, añade una nueva línea y una sangría. Añade ->isRequired()
. Esto asegura que el usuario lo establece, pero queremos evitar que lo establezca como nulo o como una cadena vacía. Así que añade también ->cannotBeEmpty()
:
// ... lines 1 - 10 | |
final class ObjectTranslationBundle extends AbstractBundle | |
{ | |
// ... lines 13 - 14 | |
public function configure(DefinitionConfigurator $definition): void | |
{ | |
$definition->rootNode() | |
->children() | |
->stringNode('translation_class') | |
// ... lines 20 - 21 | |
->isRequired() | |
->cannotBeEmpty() | |
->end() | |
->end() | |
; | |
} | |
// ... lines 28 - 39 | |
} |
En tu terminal, vuelca la configuración del bundle:
symfony console config:dump-reference symfonycasts_object_translation
Ooo, ¡un error! "translation_class"... debe estar configurada. Incluso muestra la descripción de nuestro nodo para ayudarnos. ¡Perfecto!
Esto nos obliga ahora a crear esta configuración. En el directorio config/packages
de tu aplicación, crea un nuevo archivo llamado symfonycasts_object_translation.yaml
.
Dentro, añade el nombre del nodo de nivel superior, el alias de extensión de nuestro bundle:symfonycasts_object_translation:
. A continuación, debajo, indenta y añade nuestro nodo: translation_class
. Establécelo como una cadena vacía por ahora:
symfonycasts_object_translation: | |
translation_class: '' |
Ejecuta de nuevo el comando en tu terminal:
symfony console config:dump-reference symfonycasts_object_translation
Un error diferente: "translation_class" no puede contener un valor vacío. Esto se debe a la opción cannotBeEmpty()
.
Así que, volviendo a nuestra configuración, establece translation_class
en sólo Translation
:
symfonycasts_object_translation: | |
translation_class: 'Translation' |
Vuelve a ejecutar el comando:
symfony console config:dump-reference symfonycasts_object_translation
¡Woo! Todo correcto. Incluso ha añadido "Obligatorio" antes del comentario de ejemplo.
Validación personalizada
Para nuestro tercer requisito: "un nombre de clase válido que extienda la clase Translation
de nuestro bundle", necesitaremos una validación personalizada.
En la definición translation_class
de nuestro bundle, después de cannotBeEmpty()
, añade una nueva línea, haz sangría y añade ->validate()
. Esto inicia una cadena de validación personalizada que también debe cerrarse con ->end()
. Dentro, añade ->ifTrue()
con una función: fn($v) =>
!class_exists($v). Esta función se ejecuta con el valor proporcionado por el usuario, $v
. Si la función devuelve true
, la validación falla. En nuestro caso, si la clase no existe. Ahora, necesitamos lanzar un mensaje de error. Añade->thenInvalid('The translation class %s does not
exist.'). El %s
será el valor proporcionado por el usuario.
// ... lines 1 - 10 | |
final class ObjectTranslationBundle extends AbstractBundle | |
{ | |
// ... lines 13 - 14 | |
public function configure(DefinitionConfigurator $definition): void | |
{ | |
$definition->rootNode() | |
->children() | |
->stringNode('translation_class') | |
// ... lines 20 - 23 | |
->validate() | |
->ifTrue(fn ($v) => !class_exists($v)) | |
->thenInvalid('The translation_class %s does not exist.') | |
->end() | |
->end() | |
->end() | |
; | |
} | |
// ... lines 32 - 43 | |
} |
¡Vamos a probarlo! De nuevo en tu terminal, ejecuta de nuevo el comando:
symfony console config:dump-reference symfonycasts_object_translation
¡Genial! Nuestro error personalizado: "La clase de traducción Traducción no existe"
En nuestra configuración, seamos descarados y fijémosla en una clase real, pero no en una clase de traducción válida: App\Entity\Article
:
symfonycasts_object_translation: | |
translation_class: 'App\Entity\Article' |
Ejecuta de nuevo el comando...
symfony console config:dump-reference symfonycasts_object_translation
Mejorar la validación personalizada
Esto pasa nuestra validación, pero sigue sin ser lo que queremos: Article
no extiende la clase Translation
de nuestro bundle.
De vuelta a nuestra configuración, podríamos encadenar otra validación después de la primera, pero vamos a simplificarlo. Cambia class_exists
por is_a
. Para el segundo argumento, añade Translation::class
-asegúrate de importar el de nuestro bundle.is_a
comprueba si un objeto es una instancia de una clase string. Por defecto, $v
debe ser un objeto real, así que pasa true
como tercer argumento para permitir que$v
sea una cadena de clase:
// ... lines 1 - 11 | |
final class ObjectTranslationBundle extends AbstractBundle | |
{ | |
// ... lines 14 - 15 | |
public function configure(DefinitionConfigurator $definition): void | |
{ | |
$definition->rootNode() | |
->children() | |
->stringNode('translation_class') | |
// ... lines 21 - 24 | |
->validate() | |
->ifTrue(fn ($v) => !is_a($v, Translation::class, true)) | |
// ... line 27 | |
->end() | |
->end() | |
->end() | |
; | |
} | |
// ... lines 33 - 44 | |
} |
Ejecuta de nuevo el comando:
symfony console config:dump-reference symfonycasts_object_translation
¡Error! "La clase de traducción App\Entity\Article no existe". Hmm, tenemos que actualizar el mensaje de error. De vuelta a nuestra configuración, ajusta el mensajethenInvalid()
para que diga "...debe extender SymfonyCasts\ObjectTranslationBundle\Model\Translation"
// ... lines 1 - 11 | |
final class ObjectTranslationBundle extends AbstractBundle | |
{ | |
// ... lines 14 - 15 | |
public function configure(DefinitionConfigurator $definition): void | |
{ | |
$definition->rootNode() | |
->children() | |
->stringNode('translation_class') | |
// ... lines 21 - 24 | |
->validate() | |
// ... line 26 | |
->thenInvalid('The translation_class %s must extend SymfonyCasts\ObjectTranslationBundle\Model\Translation.') | |
->end() | |
->end() | |
->end() | |
; | |
} | |
// ... lines 33 - 44 | |
} |
Ejecuta de nuevo... "La clase de traducción App\Entity\Article sí debe extender". ¡Qué mala gramática! Elimina el "debe" e inténtalo de nuevo. Perfecto "La clase de traducción App\Entidad\Artículo debe extender..." ¡Mucho mejor!
Arréglalo en nuestra configuración cambiando Article
por Translation
:
symfonycasts_object_translation: | |
translation_class: 'App\Entity\Translation' |
Ejecuta de nuevo el comando... ¡todo bien!
A continuación, utilizaremos este valor de configuración en el servicio de nuestro bundle