-
-
Notifications
You must be signed in to change notification settings - Fork 912
Add filter locator and deprecate filter collection #1099
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is really nice work ❤️
src/Api/FilterCollectionFactory.php
Outdated
try { | ||
$filters[$filter] = $filterLocator->get($filter); | ||
} catch (\Throwable $e) { | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we use if ($filterLocator->has($filter)) {}
instead of catching?
|
||
public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, Fil 8000 terCollection $filters) | ||
public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, $filterLocator) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no such typing as ContainerInterface | FilterCollection
in php right? Maybe we could document this new argument though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same goes in the other classes with the same change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works only for try/catch with PHP 7.1. I will add some PHPDoc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just made the change. Is it good for you like this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 I hope that phpstan is fine with it and yeah this is better for future developers IMO. Thanks!
@@ -32,7 +32,7 @@ | |||
protected function extractPath(string $path) | |||
{ | |||
try { | |||
$resourcesYaml = Yaml::parse(file_get_contents($path)); | |||
$resourcesYaml = Yaml::parse(file_get_contents($path), Yaml::PARSE_KEYS_AS_STRINGS); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm why this change? Did you hit a bug? This might need to be backported to 2.0 if it's the case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have deprecation warnings from the component without this change and tests fail...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh okay this is because symfony 3.3 then alright! Thanks for the information.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a3d11b5
to
30687bf
Compare
Tests fail because the master branch fails too. |
|
||
<service id="api_platform.filter_collection_factory" class="ApiPlatform\Core\Api\FilterCollectionFactory" public="false" /> | ||
|
||
<service id="api_platform.filters" class="ApiPlatform\Core\Api\FilterCollection" public="false"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like a good candidate for <defaults public="false" />
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, nice, I missed this feature! Thanks!
30687bf
to
ee63f10
Compare
composer.json
Outdated
@@ -23,7 +23,7 @@ | |||
"symfony/property-access": "^2.7 || ^3.0", | |||
"symfony/property-info": "^3.3@beta", | |||
"symfony/serializer": "^3.3@beta", | |||
"willdurand/negotiation": "^2.0.3" | |||
"willdurand/negotiation": "~2.2.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice one maybe we can patch this in a separated pr?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be ~2.2.3
right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about >=2.0.3 <2.3.0
? BTW it's ~2.2.1
!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^2.0.3 <2.3
Ok, I got it. The problem comes from the new release of |
Does anyone have an idea to fix/avoid that?
|
@meyerbaptiste CodeCoverage loads classes which causes the FilterCollection deprecation to be triggered. What you need is to move the deprecation to the constructor: diff --git a/src/Api/FilterCollection.php b/src/Api/FilterCollection.php
index 32b1157..76af317 100644
--- a/src/Api/FilterCollection.php
+++ b/src/Api/FilterCollection.php
@@ -15,8 +15,6 @@ namespace ApiPlatform\Core\Api;
use Psr\Container\ContainerInterface;
-@trigger_error(sprintf('The %s class is deprecated since version 2.1 and will be removed in 3.0. Implement the %s interface as service locator instead.', FilterCollection::class, ContainerInterface::class), E_USER_DEPRECATED);
-
/**
* A list of filters.
*
@@ -26,4 +24,10 @@ use Psr\Container\ContainerInterface;
*/
final class FilterCollection extends \ArrayObject
{
+ public function __construct($input = [], $flags = 0, $iterator_class = \ArrayIterator::class)
+ {
+ @trigger_error(sprintf('The %s class is deprecated since version 2.1 and will be removed in 3.0. Implement the %s interface as service locator instead.', self::class, ContainerInterface::class), E_USER_DEPRECATED);
+
+ parent::__construct($input, $flags, $iterator_class);
+ }
} Or exclude this class from code coverage, I don't use coverage at all so I can't say if it's a good idea nor help. |
Also you can mark specific tests as |
@soyuka comment made me think that maybe moving the |
b6c70ea
to
b17b8e6
Compare
444b0a6
to
fca4e6a
Compare
src/Api/IdentifiersExtractor.php
Outdated
@@ -76,6 +76,7 @@ public function getIdentifiersFromItem($item): array | |||
throw new RuntimeException(sprintf('No identifier found in "%s" through relation "%s" of "%s" used as identifier', $relatedResourceClass, $propertyName, $resourceClass)); | |||
} | |||
} | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was fixed by 7dfdcb1
features/main/crud.feature
Outdated
@@ -123,73 +123,67 @@ Feature: Create-Retrieve-Update-Delete | |||
"hydra:totalItems": 1, | |||
"hydra:search": { | |||
"@type": "hydra:IriTemplate", | |||
"hydra:template": "/dummies{?id,id[],name,alias,description,relatedDummy.name,relatedDummy.name[],relatedDummies,relatedDummies[],dummy,relatedDummies.name,order[id],order[name],order[relatedDummy.symfony],dummyDate[before],dummyDate[after],relatedDummy.dummyDate[before],relatedDummy.dummyDate[after],dummyFloat[between],dummyFloat[gt],dummyFloat[gte],dummyFloat[lt],dummyFloat[lte],dummyPrice[between],dummyPrice[gt],dummyPrice[gte],dummyPrice[lt],dummyPrice[lte],dummyBoolean,dummyFloat,dummyPrice,description[exists],relatedDummy.name[exists],dummyBoolean[exists]}", | |||
"hydra:template": "\/dummies{?dummyBoolean,dummyDate[before],dummyDate[after],relatedDummy.dummyDate[before],relatedDummy.dummyDate[after],description[exists],relatedDummy.name[exists],dummyBoolean[exists],dummyFloat,dummyPrice,order[id],order[name],order[relatedDummy.symfony],dummyFloat[between],dummyFloat[gt],dummyFloat[gte],dummyFloat[lt],dummyFloat[lte],dummyPrice[between],dummyPrice[gt],dummyPrice[gte],dummyPrice[lt],dummyPrice[lte],id,id[],name,alias,description,relatedDummy.name,relatedDummy.name[],relatedDummies,relatedDummies[],dummy,relatedDummies.name}", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what went wrong here? If this is due to random sorting maybe we should sort everything to avoid such issues in the feature?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(we discussed this IRL with @meyerbaptiste).
Before: filters were in the same order than declared in services.yml
Now: filters are in the order the configuration in the resource.
It's not a BC break (the JSON parser should not depend of the order).
I prefer to not sort the filters, it allows to detect when we change the output, it's a desirable behavior.
fca4e6a
to
2d6e3a2
Compare
src/Api/FilterCollection.php
Outdated
*/ | ||
final class FilterCollection extends \ArrayObject | ||
{ | ||
public function __construct($input = [], $flags = 0, $iterator_class = 'ArrayIterator') | ||
{ | ||
@trigger_error(sprintf('The %s class is deprecated since version 2.1 and will be removed in 3.0. Implement the %s interface as service locator instead.', self::class, ContainerInterface::class), E_USER_DEPRECATED); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would say Provide and implementation of "%s" instead
.
src/Api/FilterCollectionFactory.php
Outdated
{ | ||
private $filtersIds; | ||
|
||
public function __construct(string ...$filtersIds) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not using an array?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a hack to have a typed array...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer to use a raw array and use string[]
in the PHPDoc, PHPStan will be able to check types using the PHPDoc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bad day for variadic functions 😭
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you really want a check you could also force it after in the code:
$filterIds = (function (string ...$filterIds) { return $filterIds; })(...$filterIds);
Or use a lib like https://github.com/beberlei/assert
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't have to enforce this. The PHPDoc is the contract and it's an @internal
class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm just giving alternatives to enforce it, not saying you have to enforce it :P
34041be
to
ff3f1ba
Compare
All comments are fixed. |
e9f4c29
to
9ca1d00
Compare
9ca1d00
to
08fc0a0
Compare
Thanks @meyerbaptiste |
Unfortunately, this must be reverted because bumping the required versions in composer.json is a major BC break. It means we suddenly drop support for a lot of people... 😞 |
@teohhanhui it's not, its allowed by semver (and we do this very often in Symfony). Note that we don't force to upgrade to new major versions, just to the last minor. |
But if we're thinking in semver, 2.1 is not a major version. It's a minor version. This is yet another reason (just realized this today) why I think Symfony does not really follow semver, despite their claims... |
Semver is about code API. Not about dependencies. Every major project (including Symfony, Doctrine...) do this and this is totally acceptable. It's also the only way to no being stuck with very old and versions. |
I don't know if we'll ever reach agreement about the technicality of whether bumping dependencies is a BC break, but in the spirit of semver, it'd be best if we can tag a major release when we drop support for an older minor version of Symfony. In any case, stability flags only work at the project root level. So when we use |
You're right about stability flags, but it's just a temporary solution. We'll not release 2.1 before the release of Symfony 3.3. |
Looks like you're right about semver: http://semver.org/#what-should-i-do-if-i-update-my-own-dependencies-without-changing-the-public-api 😄 |
…cator Add filter locator and deprecate filter collection
First step before #1082 and #1083, we have to refactor the
FilterCollection
to avoid circular references with new filters.Our solution is to use the PSR11 and a service locator. Thanks to http://symfony.com/blog/new-in-symfony-3-3-service-locators.