watchdog error:
TypeError: round(): Argument #1 ($num) must be of type int|float, string given in round() (line 173 of /xxx_proj_folder/docroot/core/modules/views/src/Plugin/views/field/NumericField.php)
#0 /xxx_proj_folder/docroot/core/modules/views/src/Plugin/views/field/NumericField.php(173): round('2021-06-29', 0)
code:
$value = round($value, $precision);
value is string '2021-06-29' (just example)
if php version is 7, it will return '2021' and no error,
php 8 will throw this error.
related issue:
https://www.drupal.org/project/drupal/issues/3151654
Repro steps
Show the most recent log item that references each event.
1. Create content types for Event and Log.
2. Add a reference field to Log that references Event.
3. Add a date field to the Log.
4. Create a view that lists Logs.
5. Add the Event reference field, formatted as a linked label.
6. Add the Log date field.
7. Enable aggregation.
8. Set Max on the date field.
Here is where views throws the error in the browser console and things start breaking.
Issue fork drupal-3302573
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:
Comments
Comment #2
caohan@ciandt.com commentedAdd patch for temporary solution.
Comment #3
vlad.dancerComment #4
vlad.dancerI think you need to cast date result into int:
$value = (int) date("Y",strtotime($value));But that might work only for you because others could have a different date format and separator like "/".
I would say that it is safe to do casting here instead of creating a new condition because it is exactly what PHP 7 did before and let's follow old code behaviour here.
$value = round((int) $value, $precision);Comment #5
vlad.dancerTests failed due to code quality checks failed.
Comment #6
anchal_gupta commentedfix cs error #2. Please review it
Comment #7
anchal_gupta commentedComment #8
vlad.dancerLet's trigger tests
Comment #10
nanobyt3 commented#7 seems to work for me, at least where 'year' is being used.
PHP 8 & MySQL 5.7
Comment #11
nanobyt3 commentedJust a minor change to date-string check condition, for better coverage.
Comment #12
smustgrave commentedMoving back to NW for a test.
Comment #13
vlad.dancerI would leave here an alternative fix for date cases like "2021/2022"
Comment #14
nanobyt3 commentedThis would work too.
I would suggest something like:
else we are ignoring $precision completely.
Comment #15
vlad.dancerThen it might looks like
Comment #16
nanobyt3 commentedActually, it would be easier to mimic how PHP v7.x handled it.
After doing some tests, it seems a simple type cast should be sufficient.
So as not to handle the string with any assumptions and in a more generalized way.
Attaching the effective patch.
Just some thoughts: Since this is a render/display utility function, there could be a more agreed-upon way to display a string, passed through an aggregating function.
Comment #17
nanobyt3 commentedComment #18
narendra.rajwar27Re-rolled patch for Drupal 9.5.x
Comment #19
hipp2bsquare commentedI tested patch #18 on Drupal 9.4.6 and php 8.1 and it worked for me -- though my issue was related to a text field rather than date field. Same error message, though.
Comment #21
smustgrave commentedThis still needs a test case
Also would be helpful to have steps to reproduce this issue.
Comment #23
mortona2k commentedI added steps to create a view that triggers the error and is fixed with this patch.
Comment #24
mortona2k commentedThere are two very different approaches in the patches here.
#11 has:
This will convert date strings to year.
#18 has:
This will convert a date string to to a number like 2025.0.
A patch in #3338895 has:
Basically the same as #18, without the check for a string.
I bundled them all together and came up with this:
Now a date string is converted to a timestamp. However, I'm not sure if this does anything for the max comparison, or if this just rendering the value afterwards.