Skip to content

Improve the ExistsFilter behavior (to cohabit with the SearchFilter) #2243

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

epourail
Copy link
Contributor

@epourail epourail commented Oct 7, 2018

Q A
Bug fix? yes (for GraphQL)
New feature? yes
BC breaks? yes
Deprecations? yes
Tests pass? yes
Fixed tickets #2231
License MIT
Doc PR api-platform/docs#613

Improve the behavior of the ExistsFilter filter to be declared according to the following syntax:

  • on a REST collection endpoints: /dummies?exists[<property>]=true/false
  • on the GraphQL endpoint: dummies(exists: {<property>: "true/false"}) { ... }

The name of the query parameter is controlled via the bundle configuration:

api_platform:
  collection:
    exists_parameter_name: 'not_null'

It allows to use an ExistsFilter and a SearchFilter on the same property via the GraphQL endpoint.

  • Improve ExistsFilter
  • PHPUnit
  • Behat
  • Documentation

@epourail epourail changed the title Fix exists filter behavior Improve the ExistsFilter behavior (to cohabit with the SearchFilter) Oct 7, 2018
@epourail epourail changed the title Improve the ExistsFilter behavior (to cohabit with the SearchFilter) Improve the ExistsFilter behavior (to cohabit with the SearchFilter) Oct 7, 2018
@epourail epourail force-pushed the fix-exists-filter-behavior branch 7 times, most recently from acc3675 to 2c206b8 Compare October 9, 2018 16:05
epourail pushed a commit to epourail/fork-apiplatform-docs that referenced this pull request Oct 9, 2018
@alanpoulain alanpoulain self-assigned this Oct 10, 2018
@alanpoulain
Copy link
Member

Why notnull_parameter_name and not exists_parameter_name (I would call it exists_filter_parameter_name but I think you chose this to be consistent with the order filter, didn't you?).

@alanpoulain
Copy link
Member

You need to make sure the previous way of using the exists filter is still working, but deprecate it.

@@ -30,11 +34,24 @@
* Request: GET /products?brand[exists]
* Interpretation: filter products which have a brand
*
* @author Teoh Han Hui <teohhanhui@gmail.com>
* @author Julien Verger <julien.verger@gmail.com>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add you after the previous author.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

/**
* @param RequestStack|null $requestStack No prefix to prevent autowiring of this deprecated property
*/
public function __construct(ManagerRegistry $managerRegistry, $requestStack = null, string $existsParameterName = 'exists', LoggerInterface $logger = null, array $properties = null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add $existsParameterName after $logger to prevent BC.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And you can reuse the existing constant: $existsParameterName = self::QUERY_PARAMETER_KEY

*/
class ExistsFilter extends AbstractContextAwareFilter
{
const QUERY_PARAMETER_KEY = 'exists';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be kept (or it's a BC break)

/**
* @param RequestStack|null $requestStack No prefix to prevent autowiring of this deprecated property
*/
public function __construct(ManagerRegistry $managerRegistry, $requestStack = null, string $existsParameterName = 'exists', LoggerInterface $logger = null, array $properties = null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And you can reuse the existing constant: $existsParameterName = self::QUERY_PARAMETER_KEY

protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null)
public function apply(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null, array $context = [])
{
if (isset($context['filters']) && !isset($context['filters'][$this->existsParameterName])) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the first isset is useless and can be removed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the first isset is needed @dunglas if I remember correctly, that how we determine if it should be forwarded to the parent class (used before the usage of the AbstractContextAwareFilter); there is the same code in the OrderFilter (see #1866)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

got it

return;
}

if (!isset($context['filters'][$this->existsParameterName]) || !\is_array($context['filters'][$this->existsParameterName])) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the first isset can be removed (you already tested the existence of the key previously), and you can then merge both if:

if (!\is_array($context['filters'][$this->existsParameterName] ?? null)) {


$this->assertEquals([
'description[exists]' => [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to keep this test to be sure that the old behavior still work. You should use a PHPUnit's data provider to test both behaviors instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kept the test and create a new one.

@dunglas
Copy link
Member

dunglas commented Oct 12, 2018

It will be a nice improvement, thanks for working on this!

@epourail
Copy link
Contributor Author

Why notnull_parameter_name and not exists_parameter_name (I would call it exists_filter_parameter_name but I think you chose this to be consistent with the order filter, didn't you?).

@alan Yes I keep the same logic (behavior and naming) as the order filter.
I decided to name it notnull_parameter_name because, at the end, it is a IS NOTNULL/IS NULL check (and keep the default value exists to reference the previous logic)

*/
class ExistsFilter extends AbstractContextAwareFilter
final class ExistsFilter extends AbstractContextAwareFilter
Copy link
Contributor

@antograssiot antograssiot Oct 29, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can only add a @final annotation, this is a BC break even if it was forgotten in the first place, people might have extended this class
https://symfony.com/doc/current/contributing/code/bc.html#changing-classes

@epourail epourail force-pushed the fix-exists-filter-behavior branch 3 times, most recently from 5b13d41 to 09c0715 Compare November 1, 2018 12:02
epourail pushed a commit to epourail/fork-apiplatform-docs that referenced this pull request Nov 1, 2018
@epourail epourail force-pushed the fix-exists-filter-behavior branch from 190a979 to 3ee15ff Compare November 6, 2018 15:02
@epourail epourail force-pushed the fix-exists-filter-behavior branch from 3ee15ff to 671e4d6 Compare November 13, 2018 09:01
@epourail epourail force-pushed the fix-exists-filter-behavior branch from 671e4d6 to 8239fe3 Compare November 24, 2018 17:30
Copy link
Contributor Author

@epourail epourail left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alanpoulain @dunglas Concerning this PR, I set in standby the development due to lack of time and unable to fix the behat tests.
Would you take it from here (to follow and close) ?


$this->assertEquals([
'description[exists]' => [
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kept the test and create a new one.

@alanpoulain
Copy link
Member

@epourail I am planning to finish your PR. I am working on a PR and it takes a lot of time. That's why I can't right now. If anyone is willing to take it before me go ahead.

@alanpoulain alanpoulain force-pushed the fix-exists-filter-behavior branch 3 times, most recently from 092fb40 to fd548d6 Compare March 5, 2019 20:15
@alanpoulain
Copy link
Member

This PR has been rebased, tests are fixed.
I have chosen to rename the parameter exists_parameter_name to not lose our users (even if the comment of @epourail is true).

Copy link
Member

@soyuka soyuka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks really good, nice that this is still supporting the old syntax!

@alanpoulain alanpoulain force-pushed the fix-exists-filter-behavior branch from fd548d6 to 3110c9b Compare March 6, 2019 16:48
@alanpoulain alanpoulain merged commit 19c08e0 into api-platform:master Mar 6, 2019
@alanpoulain
Copy link
Member

Thank you @epourail! Nice one.

alanpoulain pushed a commit to epourail/fork-apiplatform-docs that referenced this pull request Mar 7, 2019
alanpoulain pushed a commit to api-platform/docs that referenced this pull request Mar 7, 2019
@teohhanhui
Copy link
Contributor

teohhanhui commented Mar 8, 2019

We've come full circle then! When I did the ExistsFilter, it was using this syntax at first lol...

And then this happened: #906 (comment) 🙈

meyerbaptiste added a commit to meyerbaptiste/core that referenced this pull request Mar 22, 2019
meyerbaptiste added a commit to meyerbaptiste/core that referenced this pull request Mar 25, 2019
meyerbaptiste added a commit to meyerbaptiste/core that referenced this pull request Mar 25, 2019
meyerbaptiste added a commit to meyerbaptiste/core that referenced this pull request Mar 25, 2019
soyuka added a commit that referenced this pull request Mar 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants