Problem/Motivation

With a View, if you limit the options of an exposed Language filter, two things happen:

  1. Several errors will be generated:
    1. Notice: Undefined property: Drupal\Core\StringTranslation\TranslatableMarkup::$option in Drupal\views\Plugin\views\filter\InOperator->reduceValueOptions() (line 277 of core/modules/views/src/Plugin/views/filter/InOperator.php)
    2. Warning: array_keys() expects parameter 1 to be array, null given in Drupal\views\Plugin\views\filter\InOperator->reduceValueOptions() (line 277 of core/modules/views/src/Plugin/views/filter/InOperator.php)
    3. Warning: array_shift() expects parameter 1 to be array, null given in Drupal\views\Plugin\views\filter\InOperator->reduceValueOptions() (line 278 of core/modules/views/src/Plugin/views/filter/InOperator.php)
  2. Special languages (site language default, site language interface, and site language content) aren't listed, even if they're selected as allowed

The cause is due to InOperator->reduceValueOptions() assuming objects it is given have an "option" property. In the case of the Language selector, some of the options arrive as TranslatableMarkup objects (site language default, site language interface, and site language content), which do not have an option property.

The comments in that method don't actually describe what kind of objects are expected to be given to that method:

    // Because options may be an array of strings, or an array of mixed arrays
    // and strings (optgroups) or an array of objects, we have to
    // step through and handle each one individually.

But since the code is verbatim from Drupal 7 Views, it doesn't have any "awareness" of the TranslatableMarkup class, which is functionally a string but of course an regular PHP object.

Proposed resolution

Over in the LanguageFilter class we can update the getValueOptions method to cast the language values to string. When they arrive to the InOperator class there won't be any TranslatableMarkup objects and the logic will work as expected.

Comments

CalebD created an issue. See original summary.

CalebD’s picture

Attached is a patch that updates LanguageFilter::getValueOptions() to cast the returned languages to string.

CalebD’s picture

Assigned: Unassigned » CalebD
Status: Active » Needs review
ragnarkurm’s picture

The patch looks good to me
and works as expected.

lendude’s picture

Version: 8.2.x-dev » 8.1.x-dev
Status: Needs review » Needs work
Issue tags: +Needs tests

Nice find!

+++ b/core/modules/views/src/Plugin/views/filter/LanguageFilter.php
@@ -67,7 +67,10 @@ public function getValueOptions() {
+      $this->valueOptions = array_map(function ($value) { return (string) $value; }, $this->listLanguages(LanguageInterface::STATE_ALL | LanguageInterface::STATE_SITE_DEFAULT | PluginBase::INCLUDE_NEGOTIATED, array_keys($this->value)));

I like what this does but this line is pretty unreadable, maybe wrap it at some point?

Also, this needs tests.

As a bug this can go against 8.1.x

MerryHamster’s picture

Worked for me

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

tsymi’s picture

Worked for me too, thanks.

d.olaresko’s picture

This patch works for 8.2.3 too.

flocondetoile’s picture

#2 fix the notices on 8.2.3

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

mkalkbrenner’s picture

Priority: Normal » Major
Issue tags: +Contributed project soft blocker

Patch #2 still applies for 8.3.x and solves the issue for Search API based views, especially Search API Solr Multilingual.
I increase the priority because this issue heavily spams the watchdog on every single search.

tstoeckler’s picture

I think the better choice would be to adapt reduceValueOptions to account for TranslatableMarkup objects.

Maybe something like changing

elseif (is_object($option)) {

to

elseif (is_object($option) && !($option instanceof MarkupInterface)) {

or something like that? That should do the trick.

dunebl’s picture

patch #2 solve the notice problem but apply with an offset on 8.4

patching file core/modules/views/src/Plugin/views/filter/LanguageFilter.php
Hunk #1 succeeded at 62 (offset -5 lines).
ajlib’s picture

Assigned: CalebD » Unassigned
Issue tags: +TCDrupal 2017

Thanks CalebD for working on this. I'm unassigning this to open it up for others to work on it.

I'm at the TCDrupal sprint and working on following the meta instructions for major issue triage (https://www.drupal.org/node/2474049).

ajlib’s picture

StatusFileSize
new34.36 KB

I was able to reproduce this on simplytest.me with 8.4.0-dev version - see attached image for errors screenshot (errors-8.4.0-dev.png). Then I applied the patch from CalebD which did not produce any errors.

The steps I used to reproduce with and without the patch:

  1. Install Drupal 8.4.0-dev with the standard profile
  2. Create a view called Test View at admin/structure/views (no other settings changed)
  3. Add 'Translation Language' under Context Filtering
  4. On the options page for 'Translation Language', check 'Expose this filter to visitors'
  5. Also check 'Limit list to selected items' and save the filter
  6. Then navigate to the Recent log messages at admin/reports/dblog to see the reported errors
ajlib’s picture

Issue tags: +D8MI, +VDC
Related issues: +#2313159: [meta] Make multilingual views work

I was searching for duplicates and found a plan around fixing multilingual views issues which this issue seems to fall under so I am linking it.

ajlib’s picture

While looking over the issue to see if the summary is up-to-date, as called for in the major issue triage documentation, I feel like it is. But, as it's likely related to a greater issue with multilingual views, which was linked in comment #17, there could be other issues and it would be good for someone else to review it.

ajlib’s picture

Issue tags: +Triaged for D8 major current state

I finished going through all the steps on the meta for major issue triage.

steveoriol’s picture

#2 fix the notices on 8.3.4

flyke’s picture

I had this error on Drupal 8.3.5:

Notice: Undefined property: Drupal\Core\StringTranslation\TranslatableMarkup::$option in Drupal\views\Plugin\views\filter\InOperator->reduceValueOptions() (line 272 of core\modules\views\src\Plugin\views\filter\InOperator.php).

I applied patch #2 (via composer) and it fixed the problem.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

sanduhrs’s picture

Status: Needs work » Needs review
StatusFileSize
new2.65 KB
new2.79 KB

Reroll against 8.5.x, applies well to 8.4.x, too.
Taking #5 and #13 into account.

marcoscano’s picture

Manually tested #23 and it works fine for removing the warning when the language is used in an exposed filter.

devad’s picture

Status: Needs review » Reviewed & tested by the community

Patch #23 works for me as well. No more log errors.

And it applies cleanly to current 8.4.x-dev and 8.5.x-dev.

marking RTBC

xjm’s picture

Status: Reviewed & tested by the community » Needs work

Thanks for working on this and for confirming that it resolves the issue.

We do still need to add an automated test that fails without the fix and passes when combined with it. Thanks!

mqanneh’s picture

Patch #23 fixed the issue for me on 8.x-4.x-dev

dunebl’s picture

small notice when applying #23

patching file core/modules/views/src/Plugin/views/filter/InOperator.php
Hunk #2 succeeded at 272 (offset 2 lines).
patching file core/modules/views/src/Plugin/views/filter/LanguageFilter.php

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

ludo.r’s picture

I applied patch #23 on Drupal 8.3.7.

Patch is applied successfully and errors disappear!

mikelutz’s picture

I don't have enough internal knowledge of views to write a full on Functional test that attempts to trigger the error naturally, however if the agreement is that LanguageFilter::getValueOptions should not return an instance of MarkupInterface as an element of its array, I'm happy to write that test.

mikelutz’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests

With a failed and passing test, I'm moving this back to needs review.

vlad.dancer’s picture

Looks good to me.
+1 RTBC

Created:
24 Mar 2016 at 18:51 EET
Updated:
20 Feb 2018 at 23:20 EET

2 years for acepting a patch for fixing a notice! ;)

andypost’s picture

Version: 8.5.x-dev » 8.6.x-dev
Status: Needs review » Reviewed & tested by the community

RTBC++ tests added #26

devad’s picture

An attempt to apply patch #31 to d8.5.0 at simplytest.me fails with http 500 error.

Do we need this patch re-roll for d8.5.0 ?

mikelutz’s picture

I don't think so. I rebased locally against a new 8.5.x pull and it applied fine, but I'll requeue the tests here and will post a new patch if they fail.

mikelutz’s picture

The tests pass against 8.5-dev and 8.6-dev. This should be fine to commit to 8.6 and cherry-pick for 8.5.1

catch’s picture

Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/modules/views/src/Plugin/views/filter/InOperator.php
    @@ -271,7 +272,7 @@ public function reduceValueOptions($input = NULL) {
    +      elseif (is_object($option) && !($option instanceof MarkupInterface)) {
    

    Is this change still necessary when it's being changed in LanguageFilter? Also it doesn't look like the test coverage handles this code.

  2. +++ b/core/modules/views/tests/src/Kernel/Handler/LanguageFilterTest.php
    @@ -0,0 +1,33 @@
    +    foreach($values as $key => $value) {
    

    Very minor - missing space after foreach().

devad’s picture

Tested patch #31 again at simplytest.me and it applies cleanly now.

It could be that simplytest.me platform had some issues these days...

mikelutz’s picture

Strictly speaking it isn't necessary to check twice. Either reduceValueOptions should gracefully handle markup, or we should require filters to return strings.

lendude’s picture

Either reduceValueOptions should gracefully handle markup, or we should require filters to return strings.

Since requiring filters to return strings would be an API change, that would be harder to do. Currently the return value is just array.

   * @return array|null
   *   The stored values from $this->valueOptions.

Also it can't require just strings, it also has support for objects, as long as they have certain properties set....

Handling this in reduceValueOptions sounds like the better route then. Probably just an
elseif ($option instanceof MarkupInterface) {$option = (string) $option; }
or something along those lines?

simgui8’s picture

#31 fixes array_shift warning when using language filter with limited options.
--Drupal 8.5.3

thanks everyone

maxplus’s picture

Thanks! #31 fixes this error for me on 8.5.4 when limiting language options:

Warning: array_shift() expects parameter 1 to be array, null given in Drupal\views\Plugin\views\filter\InOperator->reduceValueOptions()

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

handkerchief’s picture

Patch from #31 works for me too as mentioned in #42 and #43.
-- Drupal Core 8.6.x-dev

mikelutz’s picture

#41 and the reporter are correct, in_operator reduceValueOptions should handle translatable markup. The author of #31 clearly had no idea what he was doing. In fact, if you follow back through FilterPluginBase::buildExposedForm() The filter system will handle TranslatableMarkup in options just fine, all InOperator needs to do is recognize the difference between a markup object and an options object, and pass the markup through like it would a string.

Here's a new test showing that in_operator can handle translatable markup in options, and a much cleaner fix. No interdiff because it's a from scratch new approach.

Status: Needs review » Needs work

The last submitted patch, 46: 2693727-46.drupal.TESTS-ONLY.patch, failed testing. View results

mikelutz’s picture

Status: Needs work » Needs review
andypost’s picture

Status: Needs review » Reviewed & tested by the community

Would be great to get this in

ludo.r’s picture

#46 mikelutz:

The author of #31 clearly had no idea what he was doing.

#31 mikelutz

LOL :D

alexpott’s picture

Credited @Lendude, @tstoeckler, @catch for review comments

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed and pushed 0b6c398e7b to 8.7.x and 6cd36113bf to 8.6.x. Thanks!

  • alexpott committed 0b6c398 on 8.7.x
    Issue #2693727 by mikelutz, sanduhrs, CalebD, ajlib, Lendude, tstoeckler...

  • alexpott committed 6cd3611 on 8.6.x
    Issue #2693727 by mikelutz, sanduhrs, CalebD, ajlib, Lendude, tstoeckler...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.