Skip to content

Commit

Permalink
Add support for unmapped filter fields
Browse files Browse the repository at this point in the history
  • Loading branch information
yceruto committed Jun 25, 2019
1 parent 0212add commit d9d82d6
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 17 deletions.
20 changes: 20 additions & 0 deletions doc/book/list-search-show-configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,26 @@ new filter to the field which will use it:
# optionally you can pass options to the filter class
# type_options: {}
.. tip::

When configuring filters to entities, all filters are validated. Any filter
properties that do not exist on the entity class will cause an exception to be
thrown.

In cases where you need extra filters in the form that will not be mapped to
the underlying entity class, you need to set the ``mapped`` option to ``false``::

# config/packages/easy_admin.yaml
easy_admin:
entities:
Users:
class: App\Entity\User
list:
filters:
- property: 'unmapped'
type: 'App\Form\Filter\CustomFilterType'
mapped: false

If the options passed to the filter are dynamic, you can't define them in the
YAML config file. Instead, :ref:`create a custom controller <overriding-the-entity-controller>`
for your entity and override the ``createFiltersForm()`` method::
Expand Down
32 changes: 16 additions & 16 deletions src/Configuration/PropertyConfigPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -242,26 +242,26 @@ private function processFilterConfig(array $backendConfig): array
foreach ($entityConfig['list']['filters'] ?? [] as $propertyName => $filterConfig) {
$originalFilterConfig = $filterConfig;

if (!\array_key_exists($propertyName, $entityConfig['properties'])) {
throw new \InvalidArgumentException(\sprintf('The "%s" filter configured in the "list" view of the "%s" entity refers to a property called "%s" which is not defined in that entity.', $propertyName, $entityName, $propertyName));
}

// if the original filter didn't define the 'type' option, it will now
// be defined thanks to the 'type' value added by Doctrine's metadata
$filterConfig += $entityConfig['properties'][$propertyName];

if (!isset($originalFilterConfig['type'])) {
$guessedType = $this->filterRegistry->getTypeGuesser()
->guessType($entityConfig['class'], $propertyName);

if (null !== $guessedType) {
$filterConfig['type'] = $guessedType->getType();
$filterConfig['type_options'] = \array_replace_recursive($guessedType->getOptions(), $filterConfig['type_options']);
if (\array_key_exists($propertyName, $entityConfig['properties'])) {
// if the original filter didn't define the 'type' option, it will now
// be defined thanks to the 'type' value added by Doctrine's metadata
$filterConfig += $entityConfig['properties'][$propertyName];

if (!isset($originalFilterConfig['type'])) {
$guessedType = $this->filterRegistry->getTypeGuesser()
->guessType($entityConfig['class'], $propertyName);

if (null !== $guessedType) {
$filterConfig['type'] = $guessedType->getType();
$filterConfig['type_options'] = \array_replace_recursive($guessedType->getOptions(), $filterConfig['type_options']);
}
}
} elseif ($filterConfig['mapped'] ?? true) {
throw new \InvalidArgumentException(\sprintf('The "%s" filter configured in the "list" view of the "%s" entity refers to a property called "%s" which is not defined in that entity. Set the "mapped" option to false if it is not intended to be a mapped property.', $propertyName, $entityName, $propertyName));
}

if (!isset($filterConfig['type'])) {
throw new \InvalidArgumentException(\sprintf('The "%s" filter defined in the "list" view of the "%s" entity must define its own "type" explicitly because EasyAdmin cannot autoconfigure it using the "%s" data type of the associated property.', $propertyName, $entityName, $filterConfig['type']));
throw new \InvalidArgumentException(\sprintf('The "%s" filter defined in the "list" view of the "%s" entity must define its own "type" explicitly because EasyAdmin cannot autoconfigure it.', $propertyName, $entityName));
}

$backendConfig['entities'][$entityName]['list']['filters'][$propertyName] = $filterConfig;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# EXCEPTION
expected_exception:
class: \InvalidArgumentException
message_string: 'The "this-property-does-not-exist" filter configured in the "list" view of the "Category" entity refers to a property called "this-property-does-not-exist" which is not defined in that entity.'
message_string: 'The "this-property-does-not-exist" filter configured in the "list" view of the "Category" entity refers to a property called "this-property-does-not-exist" which is not defined in that entity. Set the "mapped" option to false if it is not intended to be a mapped property.'

# CONFIGURATION
easy_admin:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# TEST
# items in the 'filters' option must define the 'type' option when they are unmapped

# EXCEPTION
expected_exception:
class: \InvalidArgumentException
message_string: 'The "foo" filter defined in the "list" view of the "Category" entity must define its own "type" explicitly because EasyAdmin cannot autoconfigure it.'

# CONFIGURATION
easy_admin:
entities:
Category:
class: AppTestBundle\Entity\UnitTests\Category
list:
filters: [{ property: 'foo', mapped: false }]

0 comments on commit d9d82d6

Please sign in to comment.