Add filter locator and deprecate filter collection#1099
Add filter locator and deprecate filter collection#1099dunglas merged 1 commit intoapi-platform:masterfrom
Conversation
| try { | ||
| $filters[$filter] = $filterLocator->get($filter); | ||
| } catch (\Throwable $e) { | ||
| } |
There was a problem hiding this comment.
Shouldn't we use if ($filterLocator->has($filter)) {} instead of catching?
| private $filters; | ||
|
|
||
| public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, FilterCollection $filters) | ||
| public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, $filterLocator) |
There was a problem hiding this comment.
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.
same goes in the other classes with the same change
There was a problem hiding this comment.
This works only for try/catch with PHP 7.1. I will add some PHPDoc.
There was a problem hiding this comment.
I just made the change. Is it good for you like this?
There was a problem hiding this comment.
👍 I hope that phpstan is fine with it and yeah this is better for future developers IMO. Thanks!
| { | ||
| 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.
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.
I have deprecation warnings from the component without this change and tests fail...
There was a problem hiding this comment.
oh okay this is because symfony 3.3 then alright! Thanks for the information.
There was a problem hiding this comment.
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.
Looks like a good candidate for <defaults public="false" />
There was a problem hiding this comment.
Oh, nice, I missed this feature! Thanks!
30687bf to
ee63f10
Compare
composer.json
Outdated
| "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.
nice one maybe we can patch this in a separated pr?
There was a problem hiding this comment.
What about >=2.0.3 <2.3.0? BTW it's ~2.2.1!
|
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
| throw new RuntimeException(sprintf('No identifier found in "%s" through relation "%s" of "%s" used as identifier', $relatedResourceClass, $propertyName, $resourceClass)); | ||
| } | ||
| } | ||
|
|
features/main/crud.feature
Outdated
| "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.
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.
(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
| { | ||
| 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.
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.
Just a hack to have a typed array...
There was a problem hiding this comment.
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.
Bad day for variadic functions 😭
There was a problem hiding this comment.
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.
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.
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
FilterCollectionto 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.