If you are having trouble with dot notation in EasyAdmin filters and cannot wait for Use filters on nested properties #4882, you can use this workaround.
Of course, this code is not optimal and probably does not support all comparison cases, but it can still work as a foundation for your temporary solution.
Tested on EasyAdmin v4.9.4
Entities
For the sake of clarity in the example, all mapping and other methods are omitted.
class Location
{
public string $id;
public string $name;
public function getNiceName(): string
{
return \sprint('#%d - %s', $this->id, $this->name);
}
}
class Offer
{
public string $id;
#[ORM\ManyToOne(targetEntity: Location::class))]
private Location $location
}
class Contract
{
public string $id;
#[ORM\ManyToOne(targetEntity: Offer::class))]
private Location $offer
}
class Invoice
{
public string $id;
#[ORM\ManyToOne(targetEntity: Contract::class))]
private Location $contract
}
Filters
Filter by location, where Location::class
is assosiated with Offer::class
(offer.location)
, and to get Offer::class
we need to have Contract::class
(contract.offer.location)
.
class InvoiceCrudController extends AbstractCrudController
{
public static function getEntityFqcn(): string
{
return Invoice::class;
}
public function configureFilters(Filters $filters): Filters
{
return $filters
->add(AssociatedEntityFilter::new('contract.offer.location', 'Location')
->setFormTypeOptions([
'value_type_options.class' => Location::class,
'value_type_options.choice_label' => 'getNiceName',
])
);
}
}
Or filter in Contract::class
crud
class ContractCrudController extends AbstractCrudController
{
public static function getEntityFqcn(): string
{
return Contract::class;
}
public function configureFilters(Filters $filters): Filters
{
return $filters
->add(AssociatedEntityFilter::new('offer.location', 'Location')
->setFormTypeOptions([
'value_type_options.class' => Location::class,
'value_type_options.choice_label' => 'getNiceName',
])
);
}
}
Also works as EntityFilter
class OfferCrudController extends AbstractCrudController
{
public static function getEntityFqcn(): string
{
return Offer::class;
}
public function configureFilters(Filters $filters): Filters
{
return $filters
->add(AssociatedEntityFilter::new('location', 'Location')
->setFormTypeOptions([
'value_type_options.class' => Location::class,
'value_type_options.choice_label' => 'getNiceName',
])
);
}
}
Suggestion : not sure about the trait, as it's used only one time. I replaced it with a private method to reduce complexity.
Error on my case : I added 2 filters :
As you are removing the "bar." of the property name on the "new" method (line 22), the property name is also "foo" instead of "bar.foo", and there is an EasyAdmin Exception triggered because you can't define multiple filters for one property".
Suggestion : Keep the "pathToProperty" as propery name for the DTO, and retrive the real one on the apply method.
I did that here, it's working. Actually you have to replace the dots with a specific placeholder, otherwise there is another error related to an array..
ex :
and in the apply method :
Anyway, very usefull, thanks.