Problem/Motivation

InOperator introduces the getValueOptions() method. It returns the value options. Not all children of the class return the options. They should.

Proposed resolution

Return the values the method already sets up.

Remaining tasks

Review. Commit.

User interface changes

NONE

API changes

NONE. Children do the same return behavior as InOperation already does.

Data model changes

NONE

Comments

EclipseGc created an issue. See original summary.

eclipsegc’s picture

Issue summary: View changes
Status: Active » Needs review
StatusFileSize
new662 bytes

CODE!

Status: Needs review » Needs work

The last submitted patch, 2: 2605214-1.patch, failed testing.

eclipsegc’s picture

Status: Needs work » Needs review

This appears to be passing tests as expected.

Eclipse

eclipsegc’s picture

Issue tags: +rc target triage

Tagging for rc triage.

Eclipse

alexpott’s picture

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

Looks like a testable bug to me...

dawehner’s picture

Historically this function was not meant to return something, but yeah I always hated that design.

These are the examples we should change in order to be consistent.

  • \Drupal\views\Plugin\views\filter\LanguageFilter::getValueOptions
    
  • \Drupal\user\Plugin\views\filter\Roles::getValueOptions
  • \Drupal\user\Plugin\views\filter\Permissions::getValueOptions
  • \Drupal\user\Plugin\views\filter\Name::getValueOptions
  • \Drupal\taxonomy\Plugin\views\filter\TaxonomyIndexTid::getValueOptions
  • \Drupal\file\Plugin\views\filter\Status::getValueOptions
  • \Drupal\comment\Plugin\views\filter\NodeComment::getValueOptions
eclipsegc’s picture

Over in #2607594: Customize views block settings on each block instance I'm using this method to determine user input on exposed filters that are being used as block configuration. For every single one of the filter plugins dawhener just mentioned, I'd have to guess at the submitted value during block submit in order to determine if the form element had been interacted with at all. With return values (which at least some other filters actually do) I can determine if the exposed filter's "submitted value" should be saved as configuration or if I can throw it away.

Eclipse

chuchunaku’s picture

StatusFileSize
new2.85 KB

Making sure that the other plugins all have proper return values.

tim.plunkett’s picture

  1. +++ b/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php
    @@ -89,7 +89,9 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o
    +  public function getValueOptions() { /* don't overwrite the value options */
    +    return $this->valueOptions;
    

    This should be converted to a // comment on it's own line in between. Also capitalize the D and put a . at the end

  2. +++ b/core/modules/user/src/Plugin/views/filter/Name.php
    @@ -102,7 +102,9 @@ protected function valueSubmit($form, FormStateInterface $form_state) {
       // Override to do nothing.
    

    Hmm. This and the other one should probably be the same comment. Maybe it needs rewriting in general. Also they could use {@inheritdoc} docblocks.

chuchunaku’s picture

StatusFileSize
new3.02 KB

Thanks @tim.plunkett . I made the above changes and attached a new patch.

jacobak’s picture

Status: Needs work » Needs review
jacobak’s picture

@ChuChuNaKu,
Your changes look good, but based on the files suggested for change by @dawehner, you missed making changes to:
\Drupal\user\Plugin\views\filter\Permissions::getValueOptions
\Drupal\views\Plugin\views\filter\LanguageFilter::getValueOptions

Should these also be changed?

Also in some of the cases there are comments that note: // Don't overwrite the value options.
Should there be a comment such as //Overwrite the value options.
or something similar in functions that do change them?

dawehner’s picture

Status: Needs review » Needs work

YEAH IMHO we should change all of them.

chuchunaku’s picture

StatusFileSize
new4.26 KB

Sorry about that! I included the two missing changes.

andypost’s picture

Status: Needs work » Needs review
dawehner’s picture

+++ b/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php
@@ -89,7 +89,13 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o
+    // Don't overwrite the value options.

+++ b/core/modules/user/src/Plugin/views/filter/Name.php
@@ -101,8 +101,13 @@ protected function valueSubmit($form, FormStateInterface $form_state) {
+    // Don't overwrite the value options.

This is a super weird comment now. Can we maybe come up with something better?

chuchunaku’s picture

I just used the comment that was already there but I'm open for suggestions. How about $this->valueOptions should not be overwritten ?

gábor hojtsy’s picture

StatusFileSize
new4.18 KB
new1.02 KB

So the two methods where the comment is debated the methods override the base implementation in InOperator. That has:

  public function getValueOptions() {
    if (isset($this->valueOptions)) {
      return $this->valueOptions;
    }

    if (isset($this->definition['options callback']) && is_callable($this->definition['options callback'])) {
      if (isset($this->definition['options arguments']) && is_array($this->definition['options arguments'])) {
        $this->valueOptions = call_user_func_array($this->definition['options callback'], $this->definition['options arguments']);
      }
      else {
        $this->valueOptions = call_user_func($this->definition['options callback']);
      }
    }
    else {
      $this->valueOptions = array(t('Yes'), $this->t('No'));
    }

    return $this->valueOptions;
  }

(Note the InOperator already returns the options :P) So in effect, what we are doing in this patch is we return the value even if not set. (With or without this patch, options callback is not supported). Not sure this can be succinctly explained in a short comment. I guess Yes/No are not good defaults for a taxonomy term or username :) We could say "return the value options as-is" but that is what the code does, so not a very valuable comment. I would just do away with the comment.

gábor hojtsy’s picture

As for what tests are there for getValueOptions():

core/modules/user/src/Tests/Views/HandlerFilterPermissionTest.php:    $view->filter['permission']->getValueOptions();
core/modules/user/src/Tests/Views/HandlerFilterPermissionTest.php:    $value_options = $view->filter['permission']->getValueOptions();
core/modules/views/src/Tests/Entity/FilterEntityBundleTest.php:    $this->assertIdentical($view->filter['type']->getValueOptions(), $expected);

Are all the test mentions.

gábor hojtsy’s picture

Also as to whether this is an API change InOperator::getValueOptions() is not defined on an interface. Parents do not implement it. The first definition is on InOperator. That returns the value options. So the children do it wrong to not return it. Not sure if adding an interface would constitute an API change in a funny turn of events given a new requirement :D So for a point release fix, I don't think we should make an interface.

gábor hojtsy’s picture

Title: Views LanguageFilter::getValueOptions does not return values and should. » Views InOperator::getValueOptions() children do not return values like InOperator::getValueOptions()
Issue tags: -Quick fix, -rc target triage
gábor hojtsy’s picture

Issue summary: View changes
Issue tags: -Needs tests
StatusFileSize
new2.98 KB
new7.15 KB

Test coverage. In detail:

- language filter tested with all options
- permissions filter test updated to not call the get method twice, so expecting it to return the right value right away
- roles test updated to assert for roles options
- user name filter test updated to assert NULL (there is nothing that sets the value options, so that will be NULL)

Reviews welcome :)

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

Great cleanup!
For those methods it is perfect to return effectively NULL, as they don't provide all possible value options. Examples like the taxonomy one would cause too many items at once,
so we rather rely on an autocomplete widget.

+++ b/core/modules/user/src/Tests/Views/HandlerFilterPermissionTest.php
@@ -74,7 +74,6 @@ public function testFilterPermission() {
-    $view->filter['permission']->getValueOptions();
 
     // Test the value options.
     $value_options = $view->filter['permission']->getValueOptions();

Nice small cleanup!

gábor hojtsy’s picture

@dawehner: yeah, re the one line removed, now that the permissions are returned in all cases immediately, we can/should get rid of calling it twice :)

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
  /**
   * Child classes should be used to override this function and set the
   * 'value options', unless 'options callback' is defined as a valid function
   * or static public method to generate these values.
   *
   * This can use a guard to be used to reduce database hits as much as
   * possible.
   *
   * @return
   *   Return the stored values in $this->valueOptions if someone expects it.
   */
  public function getValueOptions() {

Let's fix up the @return documentation as we're now saying that it should always return $this->valueOptions so the "if someone expects it." seems a bit weird.

I'm not sure but maybe also it might be worth a CR for existing contrib views plugins to find out about this fix as they might have copied the incorrect behaviour - from one of the child classes.

gábor hojtsy’s picture

Status: Needs work » Needs review
StatusFileSize
new7.88 KB
new738 bytes

Updated with that suggestion.

gábor hojtsy’s picture

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

Thank you

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed 66ae877 and pushed to 8.0.x and 8.1.x. Thanks!

  • alexpott committed 1546d71 on 8.1.x
    Issue #2605214 by Gábor Hojtsy, ChuChuNaKu, EclipseGc, dawehner: Views...
alexpott’s picture

+++ b/core/modules/views/src/Plugin/views/filter/InOperator.php
@@ -59,8 +59,8 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o
-   * @return
-   *   Return the stored values in $this->valueOptions if someone expects it.
+   * @return array|NULL
+   *   The stored values from $this->valueOptions.

I've committed this to 8.0.x because even though it is an API change now everything conforms to the documentation.

Status: Fixed » Closed (fixed)

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

quietone’s picture

published the cr