Login to bookmark this video
Buy Access to Course
10.

Bundle Configuration Validation

|

Share this awesome video!

|

Lucky you! You found an early release chapter - it will be fully polished and published shortly!

This Chapter isn't quite ready...

Get Notified About this Course!

We will send you messages regarding this course only
and nothing else, we promise.
You can unsubscribe anytime by emailing us at:
privacy@symfonycasts.com

Alight, we have this translation_class configuration option in our bundle. It needs some validation: first, it should be required, second, it should be a non-empty string, and third, it should be a valid class that extends our bundle's Translation class.

Since we used stringNode(), we already have some basic validation, it must be a string. Let's add the rest.

Required and Non-Empty

Below our ->example() call, add a new line and indent. Add ->isRequired(). This makes sure the user sets it, but we want to prevent them from setting it as null or an empty string. So, also add ->cannotBeEmpty().

At your terminal, dump the bundle configuration:

symfony console config:dump-reference symfonycasts_object_translation

Ooo, an error! "translation_class"... must be configured. It even shows our node's description to help us. Perfect!

This is now forcing us to create this configuration. In your app's config/packages directory, create a new file named symfonycasts_object_translation.yaml.

Inside, add the top level node name, our bundle's extension alias: symfonycasts_object_translation:. Then, underneath, indent and add our node: translation_class. Set it as an empty string for now.

Re-run the command again in your terminal:

symfony console config:dump-reference symfonycasts_object_translation

A different error: "translation_class" cannot contain an empty value. This is because of that cannotBeEmpty() option.

So, back in our configuration, set translation_class to just Translation.

Re-run the command:

symfony console config:dump-reference symfonycasts_object_translation

Woo! All good. It even added "Required" before the example comment.

Custom Validation

For our third requirement: "a valid class name that extends our bundle's Translation class", we'll need some custom validation.

In our bundle's translation_class definition, after cannotBeEmpty(), add a new line, indent, and add ->validate(). This starts a custom validation chain which also needs to closed with ->end(). Inside, add ->ifTrue() with a function: fn($v) => !class_exists($v). This function runs with the user-supplied value, $v. If the function returns true, the validation fails. In our case, if the class does not exist. Now, we need to throw an error message. Add ->thenInvalid('The translation class %s does not exist.'). The %s will be the user-supplied value.

Let's test this out! Back in your terminal, run the command again:

symfony console config:dump-reference symfonycasts_object_translation

Sweet! Our custom error: "The translation class Translation does not exist."

In our configuration, let's be cheeky and set it to a real class, but not a valid translation class: App\Entity\Article.

Run the command again...

symfony console config:dump-reference symfonycasts_object_translation

Improving Custom Validation

This passes our validation but is still not what we want - Article doesn't extend our bundle's Translation class.

Back in our configuration, we could chain another validation after the first one but let's keep it simple. Change the class_exists to is_a. For the second argument, add Translation::class - make sure to import the one from our bundle. is_a checks if an object is an instance of a class string. By default, $v should be an actual object, so pass true as the third argument to allow $v to be a class string.

Run the command again:

symfony console config:dump-reference symfonycasts_object_translation

Error! "The translation class App\Entity\Article does not exist". Hmm, we need to update the error message. Back in our configuration, adjust the thenInvalid() message to read "...must extend SymfonyCasts\ObjectTranslationBundle\Model\Translation."

Run again... "The translation class App\Entity\Article does must extend". Ew, that's some bad grammar! Remove the "does" and try again. Perfect! "The translation class App\Entity\Article must extend..." Much better!

Fix this in our config by swapping Article for Translation.

Run the command again... all good!

Next, we'll actually use this configuration value in our bundle's service!