Any views argument after a missing one is silently ignored (D8)

Created on 17 October 2016, about 8 years ago
Updated 24 August 2023, over 1 year ago

How to reproduce:
* Create a view with 2 arguments
* Pass arguments [NULL, foo]

Expected: Arg2 filters the view

Experienced: View is not filtered, Arg2 and following are silently ignored

Setting major as this breaks a feature with no workaround.

\Drupal\views\ViewExecutable::_buildArguments // see comments

  /**
   * Builds all the arguments.
   *
   * @return bool
   *   TRUE if the arguments were built successfully, FALSE otherwise.
   */
  protected function _buildArguments() {
    // Initially, we want to build sorts and fields. This can change, though,
    // if we get a summary view.
    if (empty($this->argument)) {
      return TRUE;
    }

    // build arguments.
    $position = -1;
    $substitutions = array();
    $status = TRUE;

    // Get the title.
    $title = $this->display_handler->getOption('title');

    // Iterate through each argument and process.
    foreach ($this->argument as $id => $arg) {
      $position++;
      $argument = $this->argument[$id];

      if ($argument->broken()) {
        continue; // =================== Good, following args not ignored
      }

      $argument->setRelationship();

      $arg = isset($this->args[$position]) ? $this->args[$position] : NULL;
      $argument->position = $position;

      if (isset($arg) || $argument->hasDefaultArgument()) {
        if (!isset($arg)) {
          $arg = $argument->getDefaultArgument();
          // make sure default args get put back.
          if (isset($arg)) {
            $this->args[$position] = $arg;
          }
          // remember that this argument was computed, not passed on the URL.
          $argument->is_default = TRUE;
        }

        // Set the argument, which will also validate that the argument can be set.
        if (!$argument->setArgument($arg)) {
          $status = $argument->validateFail($arg);
          break; // =================== Bad, following args ARE ignored
        }

        if ($argument->isException()) {
          $arg_title = $argument->exceptionTitle();
        }
        else {
          $arg_title = $argument->getTitle();
          $argument->query($this->display_handler->useGroupBy());
        }

        // Add this argument's substitution
        $substitutions["{{ arguments.$id }}"] = $arg_title;
        $substitutions["{{ raw_arguments.$id }}"] = strip_tags(Html::decodeEntities($arg));

        // Test to see if we should use this argument's title
        if (!empty($argument->options['title_enable']) && !empty($argument->options['title'])) {
          $title = $argument->options['title'];
        }
      }
      else {
        // determine default condition and handle.
        $status = $argument->defaultAction();
        break; // =================== Bad, following args ARE ignored
      }

      // Be safe with references and loops:
      unset($argument);
    }

    // set the title in the build info.
    if (!empty($title)) {
      $this->build_info['title'] = $title;
    }

    // Store the arguments for later use.
    $this->build_info['substitutions'] = $substitutions;

    return $status;
  }

🐛 Bug report
Status

Needs work

Version

9.5

Component
Views 

Last updated about 2 hours ago

Created by

🇩🇪Germany geek-merlin Freiburg, Germany

Live updates comments and jobs are added and updated live.
  • Needs tests

    The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024