From 28721d5e3128d712109e93ec8f007e4c7c2988e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 11 Mar 2019 12:57:26 +0100 Subject: [PATCH 1/5] [Validator][Doctrine] Add docs for automatic validation --- doctrine.rst | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/doctrine.rst b/doctrine.rst index 806a6a33209..cc6dba3d4eb 100644 --- a/doctrine.rst +++ b/doctrine.rst @@ -412,6 +412,72 @@ Take a look at the previous example in more detail: Whether you're creating or updating objects, the workflow is always the same: Doctrine is smart enough to know if it should INSERT or UPDATE your entity. +Validating Objects +------------------ + +:doc:`The Symfony validator ` reuse Doctrine metadata +to perform some basic validation tasks:: + + // src/Controller/ProductController.php + namespace App\Controller; + + // ... + use Symfony\Component\HttpFoundation\Response; + use Symfony\Component\Validator\Validator\ValidatorInterface; + + use App\Entity\Product; + + class ProductController extends AbstractController + { + /** + * @Route("/product", name="product") + */ + public function index(ValidatorInterface $validator) + { + $product = new Product(); + $product->setName(null); // The column in database isn't nullable + $product->setPrice('1999'); // Type mismatch, an integer is expected + + // ... + + $errors = $validator->validate($product); + if (count($errors) > 0) { + return new Response((string) $errors, 400); + } + + // Will not be reached in this example + $entityManager = $this->getDoctrine()->getManager(); + $entityManager->persist($product); + $entityManager->flush(); + + return new Response('Saved new product with id '.$product->getId()); + } + } + +The following table summaries the mapping between Doctrine metadata and +the corresponding validation constraints: + ++--------------------+-----------------------------------------------------------+-------------------------------------------------------------------------+ +| Doctrine attribute | Validation constraint | Notes | ++====================+===========================================================+=========================================================================+ +| ``nullable=true`` | :doc:`NotNull ` | Relies on :doc:`the PropertyInfo component ` | ++--------------------+-----------------------------------------------------------+-------------------------------------------------------------------------+ +| ``type`` | :doc:`Type ` | Relies on :doc:`the PropertyInfo component ` | ++--------------------+-----------------------------------------------------------+-------------------------------------------------------------------------+ +| ``unique=true`` | :doc:`UniqueEntity ` | | ++--------------------+-----------------------------------------------------------+-------------------------------------------------------------------------+ +| ``length`` | :doc:`Length ` | | ++--------------------+-----------------------------------------------------------+-------------------------------------------------------------------------+ + +Because :doc:`the Form component ` as well as `API Platform`_ +internally use the Validator Component, all your forms +and web APIs will also automatically benefit from these default constraints. + +.. tip:: + + Don't forget to add :doc:`more precise validation constraints ` + to ensure that data provided by the user is correct. + Fetching Objects from the Database ---------------------------------- @@ -812,3 +878,4 @@ Learn more .. _`ParamConverter`: http://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/converters.html .. _`limit of 767 bytes for the index key prefix`: https://dev.mysql.com/doc/refman/5.6/en/innodb-restrictions.html .. _`Doctrine screencast series`: https://symfonycasts.com/screencast/symfony-doctrine +.. _`API Platform`: https://api-platform.com/docs/core/validation/ From f7b26a0d06aa6edb1aae777d74374042ef200216 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 11 Mar 2019 14:03:47 +0100 Subject: [PATCH 2/5] Review --- doctrine.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doctrine.rst b/doctrine.rst index cc6dba3d4eb..bef0f149c33 100644 --- a/doctrine.rst +++ b/doctrine.rst @@ -415,7 +415,7 @@ is smart enough to know if it should INSERT or UPDATE your entity. Validating Objects ------------------ -:doc:`The Symfony validator ` reuse Doctrine metadata +:doc:`The Symfony validator ` reuses Doctrine metadata to perform some basic validation tasks:: // src/Controller/ProductController.php @@ -454,7 +454,7 @@ to perform some basic validation tasks:: } } -The following table summaries the mapping between Doctrine metadata and +The following table summarizes the mapping between Doctrine metadata and the corresponding validation constraints: +--------------------+-----------------------------------------------------------+-------------------------------------------------------------------------+ From 0d68e500ff300026a3de414b2c4fec0bc10ce9e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 11 Mar 2019 15:17:44 +0100 Subject: [PATCH 3/5] versionadded --- doctrine.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doctrine.rst b/doctrine.rst index bef0f149c33..743ffdcf806 100644 --- a/doctrine.rst +++ b/doctrine.rst @@ -473,6 +473,10 @@ Because :doc:`the Form component ` as well as `API Platform`_ internally use the Validator Component, all your forms and web APIs will also automatically benefit from these default constraints. +.. versionadded:: 4.3 + + The automatic validation has been added in Symfony 4.3. + .. tip:: Don't forget to add :doc:`more precise validation constraints ` From 6a66092e8475d5989cde6fd368c22493113ad00c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 31 Mar 2019 14:47:21 +0200 Subject: [PATCH 4/5] Review comments --- doctrine.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doctrine.rst b/doctrine.rst index 743ffdcf806..577569d34b7 100644 --- a/doctrine.rst +++ b/doctrine.rst @@ -347,9 +347,9 @@ and save it! class ProductController extends AbstractController { /** - * @Route("/product", name="product") + * @Route("/product", name="create_product"): Response */ - public function index() + public function createProduct() { // you can fetch the EntityManager via $this->getDoctrine() // or you can add an argument to your action: index(EntityManagerInterface $entityManager) @@ -430,9 +430,9 @@ to perform some basic validation tasks:: class ProductController extends AbstractController { /** - * @Route("/product", name="product") + * @Route("/product", name="create_product") */ - public function index(ValidatorInterface $validator) + public function createProduct(ValidatorInterface $validator): Response { $product = new Product(); $product->setName(null); // The column in database isn't nullable From fbe3e8b81fb80844ffb431123f63a7bb28f0cd14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 31 Mar 2019 16:54:17 +0200 Subject: [PATCH 5/5] Fix return type mistake --- doctrine.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doctrine.rst b/doctrine.rst index 577569d34b7..ec6447811e4 100644 --- a/doctrine.rst +++ b/doctrine.rst @@ -347,9 +347,9 @@ and save it! class ProductController extends AbstractController { /** - * @Route("/product", name="create_product"): Response + * @Route("/product", name="create_product") */ - public function createProduct() + public function createProduct(): Response { // you can fetch the EntityManager via $this->getDoctrine() // or you can add an argument to your action: index(EntityManagerInterface $entityManager)