If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.
Guess what! Server-side validation is really, really fun. Google for Symfony validation, and find the book chapter.
There is one weird thing about validation... which I love. Here it is: you don't
apply validation to your form. Nope, there will be no validation code inside of
GenusFormType
. Instead, you add validation to the class that is bound to your
form. When the form is submitted, it automatically reads those validation rules
and uses them.
Validation is added with annotations. So copy the use
statement from the code block,
find Genus
and paste it on top:
... lines 1 - 6 | |
use Symfony\Component\Validator\Constraints as Assert; | |
... lines 8 - 141 |
Good start! Next, we'll add validation rules - called constraints - above each property. On the left side bar, find the "Constraints" link.
Check out this menu of validation rules: NotBlank
, NotNull
, Email
, Length
,
Regex
... so many things! Pretty much anything you can dream up is inside of this
list.
Let's start with an easy one: above the name
property, add @Assert\NotBlank
:
... lines 1 - 12 | |
class Genus | |
{ | |
... lines 15 - 21 | |
/** | |
* @Assert\NotBlank() | |
... line 24 | |
*/ | |
private $name; | |
... lines 27 - 139 | |
} |
Without doing anything else, refresh. Boom! Validation error. And, it looks nice.
Let's add some more. For subFamily
- that should be required, so add @NotBlank
:
... lines 1 - 12 | |
class Genus | |
{ | |
... lines 15 - 27 | |
/** | |
* @Assert\NotBlank() | |
... lines 30 - 31 | |
*/ | |
private $subFamily; | |
... lines 34 - 143 | |
} |
For speciesCount
, add @NotBlank
again:
... lines 1 - 12 | |
class Genus | |
{ | |
... lines 15 - 34 | |
/** | |
* @Assert\NotBlank() | |
... lines 37 - 38 | |
*/ | |
private $speciesCount; | |
... lines 41 - 143 | |
} |
But in addition to that, we want speciesCount
to be a positive number: we don't want
some funny biologist entering negative 10.
On the constraints list, there's one called Range
. Check that out.
Ok cool: just like the form field types, you can pass options to the constraints.
The Range
constraint has several: min
, max
, minMessage
and maxMessage
.
Add @Assert\Range
with min=0
and minMessage="Negative species! Come on..."
:
... lines 1 - 12 | |
class Genus | |
{ | |
... lines 15 - 34 | |
/** | |
* @Assert\NotBlank() | |
* @Assert\Range(min=0, minMessage="Negative species! Come on...") | |
... line 38 | |
*/ | |
private $speciesCount; | |
... lines 41 - 143 | |
} |
Ok, let's finish up. It's ok if funFact
is empty - so don't add anything there.
The same is true for isPublished
: we could add a constraint to make sure this
is a boolean, but the sanity validation on the form already takes care of that.
Finally, let's make sure firstDiscoveredAt
is also NotBlank
:
... lines 1 - 12 | |
class Genus | |
{ | |
... lines 15 - 51 | |
/** | |
* @Assert\NotBlank() | |
... line 54 | |
*/ | |
private $firstDiscoveredAt; | |
... lines 57 - 143 | |
} |
Ok, refresh! Leave everything blank and put -10 for the number of species. I love it!
// composer.json
{
"require": {
"php": ">=5.5.9",
"symfony/symfony": "3.1.*", // v3.1.4
"doctrine/orm": "^2.5", // v2.7.2
"doctrine/doctrine-bundle": "^1.6", // 1.6.4
"doctrine/doctrine-cache-bundle": "^1.2", // 1.3.0
"symfony/swiftmailer-bundle": "^2.3", // v2.3.11
"symfony/monolog-bundle": "^2.8", // 2.11.1
"symfony/polyfill-apcu": "^1.0", // v1.2.0
"sensio/distribution-bundle": "^5.0", // v5.0.22
"sensio/framework-extra-bundle": "^3.0.2", // v3.0.16
"incenteev/composer-parameter-handler": "^2.0", // v2.1.2
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"knplabs/knp-markdown-bundle": "^1.4", // 1.4.2
"doctrine/doctrine-migrations-bundle": "^1.1" // 1.1.1
},
"require-dev": {
"sensio/generator-bundle": "^3.0", // v3.0.7
"symfony/phpunit-bridge": "^3.0", // v3.1.3
"nelmio/alice": "^2.1", // 2.1.4
"doctrine/doctrine-fixtures-bundle": "^2.3" // 2.3.0
}
}