-
-
Notifications
You must be signed in to change notification settings - Fork 38
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
Refactor AllowList
Filter, Add generic template to FilterInterface
#118
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.
Overall, having final around works for me pretty well.
I'd remove setOptions
and/or all the setter methods at all.
All these mutable classes are painful and when I have a look into our project, no1 ever used those setters.
Having immutable filters makes absolutely sense to me and thus I'd be fine with changing that. But if we want to keep setter methods, lets at least remove setOptions
, no?
* } | ||
* @extends AbstractFilter<Options> | ||
* @implements FilterInterface<null> |
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 am not sure why there is null
but yet do not really have the mood to give this a more closer look.
I guess you know why and thus I trust this.
/** @psalm-suppress UnusedClass */ | ||
final class AllowListChecks | ||
{ | ||
public function filterReturnTypeIsUnionOfInputAndNull(int $value): int|null |
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.
since there is null
allowed here, I guess null
works in the template?
so even if you remove int
from return value here, that static analysis will still pass, right?
Not sure if that is how it supposed to be?
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 test verifies that when input type is known, it will be present in the returned union. Without the int
here, the union would be mixed|null
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 am not 100% sure if the templating stuff is correct here?
But I havent yet fully understood what the template type is supposed to tell us and thus, I guess thats fine? 🤷🏼♂️
Thanks for the review @boesing Generally speaking the template on Most filters (But not AllowList), return either filtered value (T) or the input (mixed), so It's only possible to narrow the return type further on Because filters are not frequently used standalone, the benefit of the template isn't huge, but it does allow implementations to be precise about the return type 🤷♂️ I probably shouldn't have started with |
but for the allowlist there is null defined while it is actually the value which is returned when the filtering was not successful? even tho, the return type should be a templated type from constructor, but I guess that is not possible to declare 🤔 since return type would be value-of list option. imho, this Filter should not exist as it combines validation with filtering to a different value. the value is converted to sth invalid when stuff is not as it should be. I would expect s1 from combining validator rather than depending on filtering. but might be a personal thing. imho allowlist is not a good example to discuss the generics stuff as that Filter is obv special and imho should not even exist |
I completely agree with everything you say about
I really wish I'd started with a different filter! But 'A' came first… |
Works for me. I guess the outcome will provide some benefit, even tho the idea of generics is for type "safety" but for filtering and how the filters work, it will be always "mixed" as there is absolutely no way to tell if a filter was applied or not (unless explicit So from me, feel free to continue the work. But keep in mind that it still has to work with laminas-form 👍🏻 |
- Removes inheritance - Private properties instead of protected - Native return types - Native parameter types - Options can no longer be Traversable Signed-off-by: George Steel <[email protected]>
Signed-off-by: George Steel <[email protected]>
Signed-off-by: George Steel <[email protected]>
Signed-off-by: George Steel <[email protected]>
Signed-off-by: George Steel <[email protected]>
Signed-off-by: George Steel <[email protected]>
Signed-off-by: George Steel <[email protected]>
AllowList
Filter as an example of general modernisation of all filtersAllowList
Filter, Add generic template to FilterInterface
This patch is indicative of the plans for all the shipped filters where feasible:
The reason options can no longer be Traversable is because we can rely on static analysis by using the documented array shape. Allowing Traversable will require a lot of type juggling and coercion, and it becomes difficult to know where to stop, for example, given the
strict
option here, previously, at leastbool|int<0,1>|'0'|'1'
were acceptable, so why not also'y'|'n'|'yes'|'no'|'true'|'false'
too? We can all agree that native types are an improvement, so we might as well get rid of the idea that Options arrays|Traversables can have mixed values too.Questions…
Option value setters and getters. Can we get rid of them?
It's unlikely that filters are mutated at runtime. Most consumers will be using them via an InputFilter as part of an array spec such as:
Handling the option values in
__construct
andsetOptions
seems sufficient, and the getters just feel like a testing convenience.We'll also still have runtime type safety via native property types.
Inheritance Removal…
… might be invalid in this case. I can think of 2 reasons why a parent abstract might be useful:
__invoke(mixed):mixed
(without useful type inference) that just proxies tofilter()
setOptions
during__construct
.Therefore, might it be better to strip everything else out of the
AbstractFilter
bar these 2 functions?Introduce an
AcceptsOptionsInterface
something along the lines of
This patch is cut from #117 so it'll be easier to review just fab100b in isolation.