Issue #2494617 by Lendude, danflanagan8, Bès, Shreya Shetty, stBorchert, Boobaa, DuaelFr, joey-santiago, drubb, nikitagupta, dawehner, alexpott: TermName views argument_validator is not working as expected
(cherry picked from commit 091a83df7b)
			
			
				merge-requests/2498/head
			
			
		
							parent
							
								
									2db9c9723b
								
							
						
					
					
						commit
						d19fa67a92
					
				| 
						 | 
				
			
			@ -66,22 +66,22 @@ class TermName extends Entity {
 | 
			
		|||
      $argument = str_replace('-', ' ', $argument);
 | 
			
		||||
      $this->argument->argument = $argument;
 | 
			
		||||
    }
 | 
			
		||||
    $terms = $this->termStorage->loadByProperties(['name' => $argument]);
 | 
			
		||||
 | 
			
		||||
    if (!$terms) {
 | 
			
		||||
      // Returned empty array no terms with the name.
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    // If bundles is set then restrict the loaded terms to the given bundles.
 | 
			
		||||
    if (!empty($this->options['bundles'])) {
 | 
			
		||||
      $terms = $this->termStorage->loadByProperties(['name' => $argument, 'vid' => $this->options['bundles']]);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      $terms = $this->termStorage->loadByProperties(['name' => $argument]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Not knowing which term will be used if more than one is returned check
 | 
			
		||||
    // each one.
 | 
			
		||||
    // $terms are already bundle tested but we need to test access control.
 | 
			
		||||
    foreach ($terms as $term) {
 | 
			
		||||
      if (!$this->validateEntity($term)) {
 | 
			
		||||
        return FALSE;
 | 
			
		||||
      if ($this->validateEntity($term)) {
 | 
			
		||||
        return TRUE;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
    return FALSE;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,235 @@
 | 
			
		|||
langcode: en
 | 
			
		||||
status: true
 | 
			
		||||
dependencies:
 | 
			
		||||
  config:
 | 
			
		||||
    - taxonomy.vocabulary.tags
 | 
			
		||||
  module:
 | 
			
		||||
    - taxonomy
 | 
			
		||||
    - user
 | 
			
		||||
id: test_taxonomy_name_argument
 | 
			
		||||
label: 'Test taxonomy term argument'
 | 
			
		||||
module: views
 | 
			
		||||
description: ''
 | 
			
		||||
tag: ''
 | 
			
		||||
base_table: taxonomy_term_field_data
 | 
			
		||||
base_field: tid
 | 
			
		||||
display:
 | 
			
		||||
  default:
 | 
			
		||||
    display_plugin: default
 | 
			
		||||
    id: default
 | 
			
		||||
    display_title: Master
 | 
			
		||||
    position: 0
 | 
			
		||||
    display_options:
 | 
			
		||||
      access:
 | 
			
		||||
        type: perm
 | 
			
		||||
        options:
 | 
			
		||||
          perm: 'access content'
 | 
			
		||||
      cache:
 | 
			
		||||
        type: tag
 | 
			
		||||
        options: {  }
 | 
			
		||||
      query:
 | 
			
		||||
        type: views_query
 | 
			
		||||
        options:
 | 
			
		||||
          disable_sql_rewrite: false
 | 
			
		||||
          distinct: false
 | 
			
		||||
          replica: false
 | 
			
		||||
          query_comment: ''
 | 
			
		||||
          query_tags: {  }
 | 
			
		||||
      exposed_form:
 | 
			
		||||
        type: basic
 | 
			
		||||
        options:
 | 
			
		||||
          submit_button: Apply
 | 
			
		||||
          reset_button: false
 | 
			
		||||
          reset_button_label: Reset
 | 
			
		||||
          exposed_sorts_label: 'Sort by'
 | 
			
		||||
          expose_sort_order: true
 | 
			
		||||
          sort_asc_label: Asc
 | 
			
		||||
          sort_desc_label: Desc
 | 
			
		||||
      pager:
 | 
			
		||||
        type: mini
 | 
			
		||||
        options:
 | 
			
		||||
          items_per_page: 10
 | 
			
		||||
          offset: 0
 | 
			
		||||
          id: 0
 | 
			
		||||
          total_pages: null
 | 
			
		||||
          expose:
 | 
			
		||||
            items_per_page: false
 | 
			
		||||
            items_per_page_label: 'Items per page'
 | 
			
		||||
            items_per_page_options: '5, 10, 25, 50'
 | 
			
		||||
            items_per_page_options_all: false
 | 
			
		||||
            items_per_page_options_all_label: '- All -'
 | 
			
		||||
            offset: false
 | 
			
		||||
            offset_label: Offset
 | 
			
		||||
          tags:
 | 
			
		||||
            previous: ‹‹
 | 
			
		||||
            next: ››
 | 
			
		||||
      style:
 | 
			
		||||
        type: default
 | 
			
		||||
        options:
 | 
			
		||||
          grouping: {  }
 | 
			
		||||
          row_class: ''
 | 
			
		||||
          default_row_class: true
 | 
			
		||||
          uses_fields: false
 | 
			
		||||
      row:
 | 
			
		||||
        type: fields
 | 
			
		||||
        options:
 | 
			
		||||
          inline: {  }
 | 
			
		||||
          separator: ''
 | 
			
		||||
          hide_empty: false
 | 
			
		||||
          default_field_elements: true
 | 
			
		||||
      fields:
 | 
			
		||||
        name:
 | 
			
		||||
          id: name
 | 
			
		||||
          table: taxonomy_term_field_data
 | 
			
		||||
          field: name
 | 
			
		||||
          entity_type: taxonomy_term
 | 
			
		||||
          entity_field: name
 | 
			
		||||
          label: ''
 | 
			
		||||
          alter:
 | 
			
		||||
            alter_text: false
 | 
			
		||||
            make_link: false
 | 
			
		||||
            absolute: false
 | 
			
		||||
            trim: false
 | 
			
		||||
            word_boundary: false
 | 
			
		||||
            ellipsis: false
 | 
			
		||||
            strip_tags: false
 | 
			
		||||
            html: false
 | 
			
		||||
          hide_empty: false
 | 
			
		||||
          empty_zero: false
 | 
			
		||||
          type: string
 | 
			
		||||
          settings:
 | 
			
		||||
            link_to_entity: true
 | 
			
		||||
          plugin_id: term_name
 | 
			
		||||
          relationship: none
 | 
			
		||||
          group_type: group
 | 
			
		||||
          admin_label: ''
 | 
			
		||||
          exclude: false
 | 
			
		||||
          element_type: ''
 | 
			
		||||
          element_class: ''
 | 
			
		||||
          element_label_type: ''
 | 
			
		||||
          element_label_class: ''
 | 
			
		||||
          element_label_colon: true
 | 
			
		||||
          element_wrapper_type: ''
 | 
			
		||||
          element_wrapper_class: ''
 | 
			
		||||
          element_default_classes: true
 | 
			
		||||
          empty: ''
 | 
			
		||||
          hide_alter_empty: true
 | 
			
		||||
          click_sort_column: value
 | 
			
		||||
          group_column: value
 | 
			
		||||
          group_columns: {  }
 | 
			
		||||
          group_rows: true
 | 
			
		||||
          delta_limit: 0
 | 
			
		||||
          delta_offset: 0
 | 
			
		||||
          delta_reversed: false
 | 
			
		||||
          delta_first_last: false
 | 
			
		||||
          multi_type: separator
 | 
			
		||||
          separator: ', '
 | 
			
		||||
          field_api_classes: false
 | 
			
		||||
          convert_spaces: false
 | 
			
		||||
      filters:
 | 
			
		||||
        vid:
 | 
			
		||||
          id: vid
 | 
			
		||||
          table: taxonomy_term_field_data
 | 
			
		||||
          field: vid
 | 
			
		||||
          relationship: none
 | 
			
		||||
          group_type: group
 | 
			
		||||
          admin_label: ''
 | 
			
		||||
          operator: in
 | 
			
		||||
          value:
 | 
			
		||||
            tags: tags
 | 
			
		||||
          group: 1
 | 
			
		||||
          exposed: false
 | 
			
		||||
          expose:
 | 
			
		||||
            operator_id: ''
 | 
			
		||||
            label: ''
 | 
			
		||||
            description: ''
 | 
			
		||||
            use_operator: false
 | 
			
		||||
            operator: ''
 | 
			
		||||
            operator_limit_selection: false
 | 
			
		||||
            operator_list: {  }
 | 
			
		||||
            identifier: ''
 | 
			
		||||
            required: false
 | 
			
		||||
            remember: false
 | 
			
		||||
            multiple: false
 | 
			
		||||
            remember_roles:
 | 
			
		||||
              authenticated: authenticated
 | 
			
		||||
            reduce: false
 | 
			
		||||
          is_grouped: false
 | 
			
		||||
          group_info:
 | 
			
		||||
            label: ''
 | 
			
		||||
            description: ''
 | 
			
		||||
            identifier: ''
 | 
			
		||||
            optional: true
 | 
			
		||||
            widget: select
 | 
			
		||||
            multiple: false
 | 
			
		||||
            remember: false
 | 
			
		||||
            default_group: All
 | 
			
		||||
            default_group_multiple: {  }
 | 
			
		||||
            group_items: {  }
 | 
			
		||||
          entity_type: taxonomy_term
 | 
			
		||||
          entity_field: vid
 | 
			
		||||
          plugin_id: bundle
 | 
			
		||||
      sorts: {  }
 | 
			
		||||
      header: {  }
 | 
			
		||||
      footer: {  }
 | 
			
		||||
      empty: {  }
 | 
			
		||||
      relationships: {  }
 | 
			
		||||
      arguments:
 | 
			
		||||
        name:
 | 
			
		||||
          id: name
 | 
			
		||||
          table: taxonomy_term_field_data
 | 
			
		||||
          field: name
 | 
			
		||||
          relationship: none
 | 
			
		||||
          group_type: group
 | 
			
		||||
          admin_label: ''
 | 
			
		||||
          default_action: ignore
 | 
			
		||||
          exception:
 | 
			
		||||
            value: all
 | 
			
		||||
            title_enable: false
 | 
			
		||||
            title: All
 | 
			
		||||
          title_enable: false
 | 
			
		||||
          title: ''
 | 
			
		||||
          default_argument_type: fixed
 | 
			
		||||
          default_argument_options:
 | 
			
		||||
            argument: ''
 | 
			
		||||
          default_argument_skip_url: false
 | 
			
		||||
          summary_options:
 | 
			
		||||
            base_path: ''
 | 
			
		||||
            count: true
 | 
			
		||||
            items_per_page: 25
 | 
			
		||||
            override: false
 | 
			
		||||
          summary:
 | 
			
		||||
            sort_order: asc
 | 
			
		||||
            number_of_records: 0
 | 
			
		||||
            format: default_summary
 | 
			
		||||
          specify_validation: true
 | 
			
		||||
          validate:
 | 
			
		||||
            type: taxonomy_term_name
 | 
			
		||||
            fail: 'not found'
 | 
			
		||||
          validate_options:
 | 
			
		||||
            bundles:
 | 
			
		||||
              views_testing_tags: views_testing_tags
 | 
			
		||||
            operation: view
 | 
			
		||||
            access: false
 | 
			
		||||
            transform: false
 | 
			
		||||
          glossary: false
 | 
			
		||||
          limit: 0
 | 
			
		||||
          case: none
 | 
			
		||||
          path_case: none
 | 
			
		||||
          transform_dash: false
 | 
			
		||||
          break_phrase: false
 | 
			
		||||
          add_table: false
 | 
			
		||||
          require_value: false
 | 
			
		||||
          entity_type: taxonomy_term
 | 
			
		||||
          entity_field: name
 | 
			
		||||
          plugin_id: string
 | 
			
		||||
      display_extenders: {  }
 | 
			
		||||
    cache_metadata:
 | 
			
		||||
      max-age: -1
 | 
			
		||||
      contexts:
 | 
			
		||||
        - 'languages:language_content'
 | 
			
		||||
        - 'languages:language_interface'
 | 
			
		||||
        - url
 | 
			
		||||
        - url.query_args
 | 
			
		||||
        - user.permissions
 | 
			
		||||
      tags: {  }
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,183 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\taxonomy\Kernel\Views;
 | 
			
		||||
 | 
			
		||||
use Drupal\taxonomy\Entity\Vocabulary;
 | 
			
		||||
use Drupal\views\Views;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests the plugin of the taxonomy: taxonomy_term_name argument validator.
 | 
			
		||||
 *
 | 
			
		||||
 * @group taxonomy
 | 
			
		||||
 */
 | 
			
		||||
class ArgumentValidatorTermNameTest extends TaxonomyTestBase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Stores the taxonomy term used by this test.
 | 
			
		||||
   *
 | 
			
		||||
   * @var array
 | 
			
		||||
   */
 | 
			
		||||
  protected $terms = [];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Stores the taxonomy names used by this test.
 | 
			
		||||
   *
 | 
			
		||||
   * @var array
 | 
			
		||||
   */
 | 
			
		||||
  protected $names = [];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Stores the taxonomy IDs used by this test.
 | 
			
		||||
   *
 | 
			
		||||
   * @var array
 | 
			
		||||
   */
 | 
			
		||||
  protected $ids = [];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public static $testViews = ['test_taxonomy_name_argument'];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected function setUp($import_test_views = TRUE): void {
 | 
			
		||||
    parent::setUp($import_test_views);
 | 
			
		||||
 | 
			
		||||
    // Add three terms to the 'tags' vocabulary.
 | 
			
		||||
    for ($i = 0; $i < 3; $i++) {
 | 
			
		||||
      $this->terms[] = $term = $this->createTerm();
 | 
			
		||||
      $this->names[] = $term->label();
 | 
			
		||||
      $this->ids[] = $term->id();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Create a second vocabulary.
 | 
			
		||||
    $vocabulary2 = Vocabulary::create([
 | 
			
		||||
      'name' => 'Views testing tags 2',
 | 
			
		||||
      'vid' => 'views_testing_tags_2',
 | 
			
		||||
    ]);
 | 
			
		||||
    $vocabulary2->save();
 | 
			
		||||
    // Add term in this vocabulary that has same name as term 3.
 | 
			
		||||
    $duplicate = $this->createTerm([
 | 
			
		||||
      'name' => $this->names[2],
 | 
			
		||||
      'vid' => 'views_testing_tags_2',
 | 
			
		||||
    ]);
 | 
			
		||||
    $this->terms[] = $duplicate;
 | 
			
		||||
    $this->names[] = $duplicate->label();
 | 
			
		||||
    $this->ids[] = $duplicate->id();
 | 
			
		||||
 | 
			
		||||
    // Add uniquely named term in second vocab as well.
 | 
			
		||||
    $unique = $this->createTerm([
 | 
			
		||||
      'vid' => 'views_testing_tags_2',
 | 
			
		||||
    ]);
 | 
			
		||||
    $this->terms[] = $unique;
 | 
			
		||||
    $this->names[] = $unique->label();
 | 
			
		||||
    $this->ids[] = $unique->id();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests the term name argument validator plugin.
 | 
			
		||||
   */
 | 
			
		||||
  public function testArgumentValidatorTermName() {
 | 
			
		||||
    $view = Views::getView('test_taxonomy_name_argument');
 | 
			
		||||
    $view->initHandlers();
 | 
			
		||||
 | 
			
		||||
    // Test with name that does not correspond to any term.
 | 
			
		||||
    $this->assertFalse($view->argument['name']->setArgument('not a term name'));
 | 
			
		||||
    $view->argument['name']->validated_title = NULL;
 | 
			
		||||
    $view->argument['name']->argument_validated = NULL;
 | 
			
		||||
 | 
			
		||||
    // Test with term in the wrong vocabulary.
 | 
			
		||||
    $this->assertFalse($view->argument['name']->setArgument($this->names[4]));
 | 
			
		||||
    $view->argument['name']->validated_title = NULL;
 | 
			
		||||
    $view->argument['name']->argument_validated = NULL;
 | 
			
		||||
 | 
			
		||||
    // Test with a couple valid names.
 | 
			
		||||
    $this->assertTrue($view->argument['name']->setArgument($this->names[0]));
 | 
			
		||||
    $this->assertEquals($this->names[0], $view->argument['name']->getTitle());
 | 
			
		||||
    $view->argument['name']->validated_title = NULL;
 | 
			
		||||
    $view->argument['name']->argument_validated = NULL;
 | 
			
		||||
 | 
			
		||||
    $this->assertTrue($view->argument['name']->setArgument($this->names[1]));
 | 
			
		||||
    $this->assertEquals($this->names[1], $view->argument['name']->getTitle());
 | 
			
		||||
    $view->argument['name']->validated_title = NULL;
 | 
			
		||||
    $view->argument['name']->argument_validated = NULL;
 | 
			
		||||
 | 
			
		||||
    // Test that multiple valid terms don't validate because multiple arguments
 | 
			
		||||
    // are currently not supported.
 | 
			
		||||
    $multiple_terms = $this->names[0] . '+' . $this->names[1];
 | 
			
		||||
    $this->assertFalse($view->argument['name']->setArgument($multiple_terms));
 | 
			
		||||
    $view->argument['name']->validated_title = NULL;
 | 
			
		||||
    $view->argument['name']->argument_validated = NULL;
 | 
			
		||||
 | 
			
		||||
    // Test term whose name is shared by term in disallowed bundle.
 | 
			
		||||
    $this->assertTrue($view->argument['name']->setArgument($this->names[2]));
 | 
			
		||||
    $this->assertEquals($this->names[2], $view->argument['name']->getTitle());
 | 
			
		||||
    $view->argument['name']->validated_title = NULL;
 | 
			
		||||
    $view->argument['name']->argument_validated = NULL;
 | 
			
		||||
 | 
			
		||||
    // Add the second vocabulary as an allowed bundle.
 | 
			
		||||
    $view->argument['name']->options['validate_options']['bundles']['views_testing_tags_2'] = 'views_testing_tags_2';
 | 
			
		||||
 | 
			
		||||
    // Test that an array of bundles is handled by passing terms with unique
 | 
			
		||||
    // names in each bundle.
 | 
			
		||||
    $this->assertTrue($view->argument['name']->setArgument($this->names[0]));
 | 
			
		||||
    $this->assertEquals($this->names[0], $view->argument['name']->getTitle());
 | 
			
		||||
    $view->argument['name']->validated_title = NULL;
 | 
			
		||||
    $view->argument['name']->argument_validated = NULL;
 | 
			
		||||
 | 
			
		||||
    $this->assertTrue($view->argument['name']->setArgument($this->names[4]));
 | 
			
		||||
    $this->assertEquals($this->names[4], $view->argument['name']->getTitle());
 | 
			
		||||
    $view->argument['name']->validated_title = NULL;
 | 
			
		||||
    $view->argument['name']->argument_validated = NULL;
 | 
			
		||||
 | 
			
		||||
    // Allow any and all bundles.
 | 
			
		||||
    $view->argument['name']->options['validate_options']['bundles'] = [];
 | 
			
		||||
 | 
			
		||||
    // Test that an empty array of bundles is handled by testing terms with
 | 
			
		||||
    // unique names in each bundle.
 | 
			
		||||
    $this->assertTrue($view->argument['name']->setArgument($this->names[0]));
 | 
			
		||||
    $this->assertEquals($this->names[0], $view->argument['name']->getTitle());
 | 
			
		||||
    $view->argument['name']->validated_title = NULL;
 | 
			
		||||
    $view->argument['name']->argument_validated = NULL;
 | 
			
		||||
 | 
			
		||||
    $this->assertTrue($view->argument['name']->setArgument($this->names[4]));
 | 
			
		||||
    $this->assertEquals($this->names[4], $view->argument['name']->getTitle());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests the access checking in term name argument validator plugin.
 | 
			
		||||
   */
 | 
			
		||||
  public function testArgumentValidatorTermNameAccess() {
 | 
			
		||||
    $this->installConfig(['user']);
 | 
			
		||||
    $this->setCurrentUser($this->createUser(['access content']));
 | 
			
		||||
    $view = Views::getView('test_taxonomy_name_argument');
 | 
			
		||||
    $view->initHandlers();
 | 
			
		||||
 | 
			
		||||
    // Enable access checking on validator.
 | 
			
		||||
    $view->argument['name']->options['validate_options']['access'] = TRUE;
 | 
			
		||||
    // Allow all bundles.
 | 
			
		||||
    $view->argument['name']->options['validate_options']['bundles'] = [];
 | 
			
		||||
 | 
			
		||||
    // A uniquely named unpublished term in an allowed bundle.
 | 
			
		||||
    $this->terms[0]->setUnpublished()->save();
 | 
			
		||||
    $this->assertFalse($view->argument['name']->setArgument($this->names[0]));
 | 
			
		||||
    $view->argument['name']->validated_title = NULL;
 | 
			
		||||
    $view->argument['name']->argument_validated = NULL;
 | 
			
		||||
 | 
			
		||||
    // A name used by two terms in a single vocabulary. One is unpublished.
 | 
			
		||||
    // We re-name the second term to match the first one.
 | 
			
		||||
    $this->terms[1]->set('name', $this->names[0])->save();
 | 
			
		||||
    $this->names[1] = $this->terms[1]->label();
 | 
			
		||||
    $this->assertTrue($view->argument['name']->setArgument($this->names[0]));
 | 
			
		||||
    $this->assertEquals($this->names[0], $view->argument['name']->getTitle());
 | 
			
		||||
    $view->argument['name']->validated_title = NULL;
 | 
			
		||||
    $view->argument['name']->argument_validated = NULL;
 | 
			
		||||
 | 
			
		||||
    // A name shared by a term in each vocabulary. One is unpublished.
 | 
			
		||||
    $this->terms[3]->setUnpublished()->save();
 | 
			
		||||
    $this->assertTrue($view->argument['name']->setArgument($this->names[3]));
 | 
			
		||||
    $this->assertEquals($this->names[3], $view->argument['name']->getTitle());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue