Problem/Motivation
When creating a View with a pager, a WSOD appears if the pager setting 'items per page' is left empty.
It leave the view unusable, an a new view must be created to resolve the problem.
The following error is logged:
TypeError: Drupal\Component\Utility\Html::escape(): Argument #1 ($text) must be of type string, null given, called in ...\core\lib\Drupal\Component\Render\FormattableMarkup.php on line 238 in Drupal\Component\Utility\Html::escape() (line 431 of ...\core\lib\Drupal\Component\Utility\Html.php).
Steps to reproduce
- create/edit a view
- open the pager settings, clear the value for 'Items per page', save
- WSOD appears.
Proposed resolution
Similar to #3361177: An empty views pager offset field can cause a PHP type error to be triggered, cast $this->options['items_per_page'] to an integer
Remaining tasks
User interface changes
| Comment | File | Size | Author |
|---|
Issue fork drupal-3501659
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
kushagra.goyal commentedLooking on this issue..
Comment #3
johnvSee also the related issue.
Comment #4
quietone commentedChanges are made on on 11.x (our main development branch) first, and are then back ported as needed according to the Core change policies.
Comment #6
kushagra.goyal commentedI have raised a Merge Request (MR) to address the TypeError that occurs when in view Items per page is left empty. This issue was causing unexpected behavior, and the MR ensures proper handling of such cases to prevent errors.
Comment #7
johnvComment #8
johnvThe issue #2853054: Add validation constraints for views pager config contains a directive to use constraints, rather than if-then constructions.
if (is_null($value)) {$value = '';}can be shorter with$value ??= 0;. Setting 0 since we expect integers.Comment #11
niranjan_panem commentedI added the required attribute in pager options form in views below is the patchhttps://git.drupalcode.org/project/drupal/-/merge_requests/11050.patch
Comment #12
johnvThank you ,
whenever you create a patch/MR for an issue, you may set the issue status to 'Needs review'
it seems your MR contains too much code.
These changes in buildOptionsForm(&$form, ..) are not necessary, since $form is returned by reference.
You will not need to create/change buildOptionsForm() for the follwing, since they will inherit from SqlBase
So, you will only need to duplicate the changes from Some.php to SqlBase.php
core/modules/views/src/Plugin/views/pager/Some.phpI will now set the issue status to 'Needs work'.
Comment #13
niranjan_panem commentedComment #14
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #20
acbramley commentedComment #21
smustgrave commentedIs this not a duplicate of #3361177: An empty views pager offset field can cause a PHP type error to be triggered
Comment #22
smustgrave commentedOther one is RTBC what more would need to be done here?
Comment #23
acbramley commentedThis is for items per page, that issue is for offset (different settings)
Comment #24
smustgrave commentedfair enough.
Rebased as it was a few 100 back, but still green.
Then ran the test-only feature https://git.drupalcode.org/issue/drupal-3501659/-/jobs/7714753 and got coverage
Change seems straight forward just casting as (int), rest of the changes appear to be refinement as it was calling the same array key un-neccessarily.
LGTM
Comment #25
xjmComment #26
xjmI used the following steps to test this:
/admin/structure/views/view/comment.However, I manually tested with the diff from the MR applied and it did not appear to resolve the issue. I no longer get a console error in step 4 when I blank out the field, but I do still get a WSOD when I save the View in step 5 or try to edit it in step 6. The log message is still:
I retried a few times, including the classic
echo "hi";to make sure the code was actually applied. 😉Comment #27
smustgrave commentedThe fix from #3564838: Views: Fatal error when rendering NULL field values due to strict string typing in PHP 8.3+ appears to address that issue, should they be combined?
Comment #28
smustgrave commentedAnd I guess the test coverage needs to be a kernel or functional test to cover the WSOD?
Comment #29
xjmYeah, not sure if it should be combined or merely postponed, but we definitely need functional test coverage.
If this issue is only about the JS error, it's mis-titled, because the "WSOD" is the typecast problem and the major bug (possibly critical if it affects other elements besides this one).
Comment #30
xjmJust actually read #3564838: Views: Fatal error when rendering NULL field values due to strict string typing in PHP 8.3+ and I think that's a wontfix. Instead, I think needs to be fixed somewhere lower in the Views plugin system, but
Html::placeholderEscape()indiscriminately casting things to strings sounds kind of evil.Comment #31
smustgrave commentedFunny enough I just got hit with the bug in #3564838: Views: Fatal error when rendering NULL field values due to strict string typing in PHP 8.3+ and I'm not using views, testing something with a route for an unrelated ticket.
We can jump over to that ticket but what if we don't case a string and instead just add
($value ?? '')that fixes it tooComment #32
xjm#3564838: Views: Fatal error when rendering NULL field values due to strict string typing in PHP 8.3+ and #3361177: An empty views pager offset field can cause a PHP type error to be triggered also make me think we need this fixed at the Views plugin level in two ways:
In the short term, we can fix it for just this plugin, because this specific bug is quite bad. In general, though, we should have a followup to fix this generically at a lower level in Views.
Comment #33
xjm@smustgrave re: #31 I guess we can discuss over there and ask for FM input, but my initial reaction is extreme "yeahrghch". 😅
Comment #34
smustgrave commentedIf we fix at the plugin level though won't we have to fix ALL the pager plugins, and all the instances where it checks $options['somekey'], and if anyone is doing a custom plugin hope they update too?
Updating the plugins to not be empty but 0 makes sense but would need an upgrade hook I imagine as the bad values are already stored.
Comment #35
smustgrave commentedExample in Full.php
believe this is the code causing the WSOD because items_per_page is empty.
Comment #36
xjmWe don't need an upgrade hook necessarily; we've historically handled views data integrity issues along these lines in a gentle way where repair them on edit load or save. (Edit: That doesn't mean we shouldn't consider one; it might indeed be a good idea as we move to strict schemata.)
By the time we get to the line in #35, Views needs to have already converted the empty string to a zero. That's what we need to fix. (Versus changing
FormattableMarkupto silently accept bad input which is an even bigger and lower-level change.)Comment #37
acbramley commentedSo from what I can gather we need to:
1. Fix the WSOD for existing views as well (need to figure out why the fix wouldn't work for these)
2. Add test coverage with an existing view
Comment #38
acbramley commentedI was wrong, something has definitely changed since I wrote the fix because I can reproduce the WSOD on new views too.
It's coming from the pager plugin's
summaryTitlemethod. I agree that we should investigate if the options can be cast to integers directly.Comment #39
smustgrave commentedCould make those number fields required then can’t trigger the WSOD
Comment #40
acbramley commentedThat is definitely something we should look at doing. That would not solve existing broken views though. I've debugged through the web of code to where
$this->optionsactually comes from. It seems like it just grabs all the options directly from config and passes them down the chain.E.g
DisplayPluginCollection::initializePluginis called for the default display (and other displays). The $display array comes fromView::getDisplay(the config entity).$display['display_options']['pager']['options']are the options that eventually get passed into the pager display plugin and that has the null in there already.It looks like config validation doesn't save us here either, the views_pager data type already defines these as integers with a PositiveOrZero constraint.
Comment #41
acbramley commentedThis would at least solve the issue at a higher level:
EDIT: Scratch that, that still ends up with
Unsupported operand types: int * stringas somehow items_per_page is an empty string.Comment #42
johnvI guess it is sufficient to only fix the (saving of the) settings form. For existing views, would those views actually still have the error, or would the administrator have fixed the problem without reporting it here?
Comment #44
smustgrave commentedFYI this same error is popping up in other places. https://www.drupal.org/project/drupal/issues/3577075
Should we fix at the FormattableMarkup just stop the bleed and maybe log errors to then fix the root causes like the ones here