Problem/Motivation
There are a number of instances where we are passing a callable that doesn't return bool to functions that expect callables that return bool. These were detected by enabling the checkFunctionArgumentTypes phpstan parameter.
Parameter #2 $callback of function array_filter expects (callable(string): bool)|null, 'strlen' given.
- modules/field/src/Plugin/migrate/process/d6/FieldInstanceOptionTranslation.php
- modules/field/src/Plugin/migrate/process/d6/FieldOptionTranslation.php
- modules/field/src/Plugin/migrate/process/d6/FieldSettings.php
- modules/user/src/Plugin/migrate/process/d6/ProfileFieldOptionTranslation.php
- modules/views/src/Plugin/views/HandlerBase.php
Parameter #2 $callback of function array_filter expects (callable(mixed): bool)|null, 'strlen' given.
- core/lib/Drupal/Core/Datetime/Element/Datelist.php
- core/modules/sqlite/src/Driver/Database/sqlite/Connection.php
Parameter #2 $callback of function array_filter expects (callable(string): bool)|null, 'mb_strlen' given.
- core/lib/Drupal/Core/TypedData/Plugin/DataType/ItemList.php
- core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php
Parameter #1 $callback of function set_error_handler expects (callable(int, string, string, int): bool)|null, 'var_dump' given.
- core/lib/Drupal/Core/Utility/Error.php
Steps to reproduce
Add to phpstan.neon.dist:
parameters:
checkFunctionArgumentTypes: true
Run phpstan
Grep output for something like this:
grep -e "callable\(.*\): bool.*,.*' given\." output.txt
Proposed resolution
We can fix the array_filter calls inline:
- Replace
'strlen'withfn (string $value): bool => strlen($value) > 0 - Replace
'mb_strlen'withfn (string $value): bool => mb_strlen($value) > 0
Or create a helper function isEmptyString(string $string): bool somewhere, e.g. in Drupal\Component\Utility\Unicode and use it as the callback.
Remaining tasks
For set_error_handler we probably need a wrapping function around var_dump that returns FALSE. I suggest we do a follow up issue for that since it's quite different to the rest of this issue.
User interface changes
Introduced terminology
API changes
Data model changes
Release notes snippet
Issue fork drupal-3471932
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
- 3471932-callables
changes, plain diff MR !9404
Comments
Comment #3
mstrelan commentedI went with the helper function in Unicode, then realised we need the reverse of that so I implemented that too. Since we're only checking if the string is empty it doesn't matter if we were using
strlenormb_strlenbefore, they would either return 0 or something other than 0 and that's all that matters.Comment #4
bbralaHmm, one could choose to use the helper function. Unicode is a weird place though. And a String class cant be called String i think.
But personally since the logic in the 2 methods is so simple, why not use
Comment #5
mstrelan commentedThanks for looking at this @bbrala. I initially went down the simple arrow function route:
fn ($value) => strlen($value) > 0But
strlenis coercing values to a string. If we later adddeclare(strict_types=1)then we get aTypeError. So we'd need to cast to match the current logic:fn ($value) => strlen((string) $value) > 0But later we might decide arrow functions should be typed:
fn (mixed $value): bool => strlen((string) $value) > 0We might also later decide to enable SlevomatCodingStandard.Functions.StaticClosure:
static fn (mixed $value): bool => strlen((string) $value) > 0It's starting to get rather convoluted, and we need to reuse this in a number of different places. This is why I went with the helper function.
I guess we do need to allow
mixedand do the casting, and find a better spot for it. Perhaps the helper function could do thearray_filterpart as well.Comment #6
bbralaHmmz yeah that will get out of hand. The better question might be then if we should just do your current setup and technically be more strict (and correct) on the output.
We do need a new place for that though. Unicode feels wrong.
I did check, didn't find a better place. So guessing an ArrayFilter helper makes sense.
Comment #7
mstrelan commentedNice timing, I was just finishing up the tests. What do you think of these changes?
Comment #8
smustgrave commentedRe-ran unit tests twice but they fail each time so seems like could be related.
Comment #9
mstrelan commentedThe array to string conversion is bogus, it doesn't work with the
strlenwe had before so it doesn't need to work now.Comment #10
bbralaFeedback and conceirns addressed. All good.
Comment #11
quietone commentedI read the IS, comments and the MR. thanks for the easy to understand issue summary. All questions answered. Just needs another committer to look at this.
Leaving at RTBC
Comment #15
catchCommitted/pushed to 11.x and cherry-picked to 10.4.x, thanks!