EasyCorp / EasyAdminBundle

EasyAdmin is a fast, beautiful and modern admin generator for Symfony applications.
MIT License
4.06k stars 1.02k forks source link

Validation errors on filters #4737

Open cve opened 3 years ago

cve commented 3 years ago

Describe the bug I want to filter Offer entity by their Product entity without validation errors

To Reproduce I'm using EasyAdmin 3. I have Product, VatRate and Offer entities. Product entity has ManyToOne VatRate with NotBlank constraint and OneToMany Offer entity. When I want to display list of Offers with specific Product then in filters at Product field I see "This value should not be blank" (because VatRate is required on Product entity, but it should not be required on filters)

(OPTIONAL) Additional context I'm trying to decorate EasyCorp\Bundle\EasyAdminBundle\Factory\FormFactory to add 'validation_grops' => ['Admin'] at createFiltersForm but this not work, because FormFactory type hint does not have an interface and fails in EasyCorp\Bundle\EasyAdminBundle\Orm\EntityRepository

pkly commented 3 years ago

I'm pretty sure that if you want to modify validation groups you'll use the getCrud -> newForm/editForm options instead.

cve commented 3 years ago

Thanks @pkly, but the problem is in filters form, which is in list view.

pkly commented 3 years ago

oh, my bad why would that be even displayed if all it's supposed to be is just applying filters to the index query? this is kinda weird, can you share your configureFilters method and possibly other code you changed?

cve commented 3 years ago

I've checked that if I remove @Assert\NotBlank from my vatRate (ManyToOne VatRate) in Product then it works. I think this is because FormFactory has $form->isValid()

pkly commented 3 years ago

doesn't that just mean that your entity is invalid in the first place?

cve commented 3 years ago

I'll prepare fork from admin demo for that

cve commented 3 years ago

Ok, I have that, please clone this https://github.com/cve/easyadmin-demo/tree/filter_not_valid, run and try to use author filter on blog posts and you should see that: image

cve commented 2 years ago

@pkly Did You see that?

pkly commented 2 years ago

No, sorry, I'm currently busy with work and cannot check this. But like I said before, my guess is that the entities you're using are just invaliid, that is their validation rules are not matching up with the expected state that was persisted, and this you're getting this error since it's dubbling up from the entity. Btw you shouldn't put things like @Assert\NotBlank() on ManyToOne afaik.

https://github.com/cve/easyadmin-demo/blob/9bbeb25539d3606150776c76e27ba15d88d14eb0/src/Entity/User.php#L86

I'm guessing this error occurs since you have nothing there, or in some other field that has the @Assert\NotBlank annotation.

oleg-andreyev commented 2 years ago

Today encountered same issue. I think the biggest problem here is that "Filter Form" does not define it's own Validation Group and it's caused that "Default" group is validated.

As an example we have EntityFilter (which is used to filter "parent" in category tree), which is checking entire entity including Callback constraints.

I think solution for this is to allow to configure "validation_groups" in \EasyCorp\Bundle\EasyAdminBundle\Dto\FilterConfigDto and later re-use it when building \EasyCorp\Bundle\EasyAdminBundle\Form\Type\FiltersFormType

vlady777 commented 1 year ago

Fast solution could be the following: https://github.com/EasyCorp/EasyAdminBundle/issues/4842#issuecomment-1377644859

teklakct commented 4 weeks ago

I had the same surprise today :)

I believe that FiltersFormType should not use the Default validation group at all, but its own specified one. I cannot find an argument to check if the entity is valid when it is used as a "source of ID" to add a where statement to the query. Especially when I cannot find any validation rules for the filter form.

Eg for DateTimeFilter when ComparisonType::BETWEEN is used it's possible to enter invalid dates

filters[myDateField][comparison]: between
filters[myDateField][value]: 2024-09-01T00:00
filters[myDateField][value2]: 2023-08-30T00:00

and we end up with the query like (...) AND WHERE entity.myDateField BETWEEN 2024-09-01T00:00 and 2023-08-30T00:00 which seems to be useless.

@javiereguiluz what do you think about specifying the validation group when creating a filter form for any future constraints used in this form?


namespace EasyCorp\Bundle\EasyAdminBundle\Factory;

final class FormFactory {
 // ..

    public function createFiltersForm(FilterCollection $filters, Request $request): FormInterface
    {
        // filtering always returns to the index page of the same CRUD entity and with the same query parameters
        $urlQueryParameters = $request->query->all();
        if ($urlQueryParameters[EA::CRUD_ACTION] ?? null) {
            $urlQueryParameters[EA::CRUD_ACTION] = Action::INDEX;
        }
        $actionUrl = $this->adminUrlGenerator->setAll($urlQueryParameters)->generateUrl();

        $filtersForm = $this->symfonyFormFactory->createNamed('filters', FiltersFormType::class, null, [
            'method' => 'GET',
            'action' => $actionUrl,
            'ea_filters' => $filters,
+            'validation_groups' => ['ea_filters'],
        ]);

        return $filtersForm->handleRequest($request);
    }