Skip to content
Snippets Groups Projects
Verified Commit 46564ee7 authored by Alex Pott's avatar Alex Pott
Browse files

Issue #2765297 by mohit_aghera, joseph.olstad, sylus, alexpott, ducktape,...

Issue #2765297 by mohit_aghera, joseph.olstad, sylus, alexpott, ducktape, anmolgoyal74, heikki, kishor_kolekar, kriboogh, googletorp, dnotes, mpp, catch, Lendude, Berdir, borisson_, xjm: Return translated term name on views "Content: Has taxonomy term ID (with depth)"

(cherry picked from commit 1bcc7f34)
parent 8ac67595
Branches
Tags
28 merge requests!11958Issue #3490507 by alexpott, smustgrave: Fix bogus mocking in...,!11769Issue #3517987: Add option to contextual filters to encode slashes in query parameter.,!11185Issue #3477324 by andypost, alexpott: Fix usage of str_getcsv() and fgetcsv() for PHP 8.4,!10602Issue #3438769 by vinmayiswamy, antonnavi, michelle, amateescu: Sub workspace does not clear,!10301Issue #3469309 by mstrelan, smustgrave, moshe weitzman: Use one-time login...,!10187Issue #3487488 by dakwamine: ExtensionMimeTypeGuesser::guessMimeType must support file names with "0" (zero) like foo.0.zip,!9944Issue #3483353: Consider making the createCopy config action optionally fail...,!9929Issue #3445469 by pooja_sharma, smustgrave: Add additional test coverage for...,!9787Resolve issue 3479427 - bootstrap barrio issue under Windows,!9742Issue #3463908 by catch, quietone: Split OptionsFieldUiTest into two,!9526Issue #3458177 by mondrake, catch, quietone, godotislate, longwave, larowlan,...,!8738Issue #3424162 by camilledavis, dineshkumarbollu, smustgrave: Claro...,!8704Make greek characters available in ckeditor5,!8597Draft: Issue #3442259 by catch, quietone, dww: Reduce time of Migrate Upgrade tests...,!8533Issue #3446962 by kim.pepper: Remove incorrectly added...,!8517Issue #3443748 by NexusNovaz, smustgrave: Testcase creates false positive,!8325Update file Sort.php,!8095Expose document root on install,!7930Resolve #3427374 "Taxonomytid viewsargumentdefault plugin",!7627Issue #3439440 by nicxvan, Binoli Lalani, longwave: Remove country support from DateFormatter,!7445Issue #3440169: When using drupalGet(), provide an associative array for $headers,!7401#3271894 Fix documented StreamWrapperInterface return types for realpath() and dirname(),!7384Add constraints to system.advisories,!7078Issue #3320569 by Spokje, mondrake, smustgrave, longwave, quietone, Lendude,...,!6622Issue #2559833 by piggito, mohit_aghera, larowlan, guptahemant, vakulrai,...,!6502Draft: Resolve #2938524 "Plach testing issue",!38582585169-10.1.x,!3226Issue #2987537: Custom menu link entity type should not declare "bundle" entity key
Pipeline #122420 passed with warnings
Pipeline: drupal

#122441

    Pipeline: drupal

    #122437

      Pipeline: drupal

      #122435

        +1
        ...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
        namespace Drupal\taxonomy\Plugin\views\argument; namespace Drupal\taxonomy\Plugin\views\argument;
        use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityStorageInterface;
        use Drupal\Core\Entity\EntityRepositoryInterface;
        use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\FormStateInterface;
        use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
        use Drupal\taxonomy\TaxonomyIndexDepthQueryTrait; use Drupal\taxonomy\TaxonomyIndexDepthQueryTrait;
        ...@@ -26,16 +27,26 @@ class IndexTidDepth extends ArgumentPluginBase implements ContainerFactoryPlugin ...@@ -26,16 +27,26 @@ class IndexTidDepth extends ArgumentPluginBase implements ContainerFactoryPlugin
        /** /**
        * @var \Drupal\Core\Entity\EntityStorageInterface * @var \Drupal\Core\Entity\EntityStorageInterface
        *
        * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. There is no
        * replacement.
        *
        * @see https://www.drupal.org/node/3427843
        */ */
        protected $termStorage; protected $termStorage;
        /** /**
        * {@inheritdoc} * {@inheritdoc}
        */ */
        public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityStorageInterface $termStorage) { public function __construct(array $configuration, $plugin_id, $plugin_definition, protected EntityStorageInterface|EntityRepositoryInterface $entityRepository) {
        parent::__construct($configuration, $plugin_id, $plugin_definition); parent::__construct($configuration, $plugin_id, $plugin_definition);
        $this->termStorage = $termStorage; if ($entityRepository instanceof EntityStorageInterface) {
        // @phpstan-ignore-next-line
        $this->termStorage = $entityRepository;
        @trigger_error('Calling ' . __CLASS__ . '::__construct() with the $termStorage argument as \Drupal\Core\Entity\EntityStorageInterface is deprecated in drupal:10.3.0 and it will require Drupal\Core\Entity\EntityRepositoryInterface in drupal:11.0.0. See https://www.drupal.org/node/3427843', E_USER_DEPRECATED);
        $this->entityRepository = \Drupal::service('entity.repository');
        }
        } }
        /** /**
        ...@@ -46,7 +57,7 @@ public static function create(ContainerInterface $container, array $configuratio ...@@ -46,7 +57,7 @@ public static function create(ContainerInterface $container, array $configuratio
        $configuration, $configuration,
        $plugin_id, $plugin_id,
        $plugin_definition, $plugin_definition,
        $container->get('entity_type.manager')->getStorage('taxonomy_term') $container->get('entity.repository')
        ); );
        } }
        ...@@ -114,9 +125,9 @@ public function query($group_by = FALSE) { ...@@ -114,9 +125,9 @@ public function query($group_by = FALSE) {
        } }
        public function title() { public function title() {
        $term = $this->termStorage->load($this->argument); $term = $this->entityRepository->getCanonical('taxonomy_term', $this->argument);
        if (!empty($term)) { if (!empty($term)) {
        return $term->getName(); return $term->label();
        } }
        // TODO review text // TODO review text
        return $this->t('No name'); return $this->t('No name');
        ......
        ...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
        namespace Drupal\taxonomy\Plugin\views\argument; namespace Drupal\taxonomy\Plugin\views\argument;
        use Drupal\Core\Entity\EntityRepositoryInterface;
        use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityStorageInterface;
        use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
        use Drupal\views\Attribute\ViewsArgument; use Drupal\views\Attribute\ViewsArgument;
        ...@@ -20,16 +21,25 @@ class Taxonomy extends NumericArgument implements ContainerFactoryPluginInterfac ...@@ -20,16 +21,25 @@ class Taxonomy extends NumericArgument implements ContainerFactoryPluginInterfac
        /** /**
        * @var \Drupal\Core\Entity\EntityStorageInterface * @var \Drupal\Core\Entity\EntityStorageInterface
        *
        * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. There is no
        * replacement.
        *
        * @see https://www.drupal.org/node/3427843
        */ */
        protected $termStorage; protected $termStorage;
        /** /**
        * {@inheritdoc} * {@inheritdoc}
        */ */
        public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityStorageInterface $term_storage) { public function __construct(array $configuration, $plugin_id, $plugin_definition, protected EntityStorageInterface|EntityRepositoryInterface $entityRepository) {
        parent::__construct($configuration, $plugin_id, $plugin_definition); parent::__construct($configuration, $plugin_id, $plugin_definition);
        if ($entityRepository instanceof EntityStorageInterface) {
        $this->termStorage = $term_storage; // @phpstan-ignore-next-line
        $this->termStorage = $this->entityRepository;
        @trigger_error('Calling ' . __CLASS__ . '::__construct() with the $termStorage argument as \Drupal\Core\Entity\EntityStorageInterface is deprecated in drupal:10.3.0 and it will require Drupal\Core\Entity\EntityRepositoryInterface in drupal:11.0.0. See https://www.drupal.org/node/3427843', E_USER_DEPRECATED);
        $this->entityRepository = \Drupal::service('entity.repository');
        }
        } }
        /** /**
        ...@@ -40,7 +50,7 @@ public static function create(ContainerInterface $container, array $configuratio ...@@ -40,7 +50,7 @@ public static function create(ContainerInterface $container, array $configuratio
        $configuration, $configuration,
        $plugin_id, $plugin_id,
        $plugin_definition, $plugin_definition,
        $container->get('entity_type.manager')->getStorage('taxonomy_term') $container->get('entity.repository')
        ); );
        } }
        ...@@ -50,9 +60,9 @@ public static function create(ContainerInterface $container, array $configuratio ...@@ -50,9 +60,9 @@ public static function create(ContainerInterface $container, array $configuratio
        public function title() { public function title() {
        // There might be no valid argument. // There might be no valid argument.
        if ($this->argument) { if ($this->argument) {
        $term = $this->termStorage->load($this->argument); $term = $this->entityRepository->getCanonical('taxonomy_term', $this->argument);
        if (!empty($term)) { if (!empty($term)) {
        return $term->getName(); return $term->label();
        } }
        } }
        // TODO review text // TODO review text
        ......
        ...@@ -112,6 +112,7 @@ function taxonomy_tokens($type, $tokens, array $data, array $options, Bubbleable ...@@ -112,6 +112,7 @@ function taxonomy_tokens($type, $tokens, array $data, array $options, Bubbleable
        $replacements = []; $replacements = [];
        if ($type == 'term' && !empty($data['term'])) { if ($type == 'term' && !empty($data['term'])) {
        $term = $data['term']; $term = $data['term'];
        $term = \Drupal::service('entity.repository')->getTranslationFromContext($term, isset($options['langcode']) ? $options['langcode'] : NULL);
        foreach ($tokens as $name => $original) { foreach ($tokens as $name => $original) {
        switch ($name) { switch ($name) {
        ...@@ -120,7 +121,7 @@ function taxonomy_tokens($type, $tokens, array $data, array $options, Bubbleable ...@@ -120,7 +121,7 @@ function taxonomy_tokens($type, $tokens, array $data, array $options, Bubbleable
        break; break;
        case 'name': case 'name':
        $replacements[$original] = $term->getName(); $replacements[$original] = $term->label();
        break; break;
        case 'description': case 'description':
        ......
        <?php
        declare(strict_types=1);
        namespace Drupal\taxonomy_test\Plugin\views\argument;
        use Drupal\Core\Entity\EntityStorageInterface;
        use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
        use Drupal\taxonomy\Plugin\views\argument\Taxonomy;
        use Symfony\Component\DependencyInjection\ContainerInterface;
        /**
        * Test argument handler for testing deprecation in IndexTidDepth plugin.
        *
        * @ingroup views_argument_handlers
        *
        * @ViewsArgument("taxonomy_views_argument_test")
        */
        class TaxonomyViewsArgumentTest extends Taxonomy {
        /**
        * Constructs new IndexTidDepthTestPlugin object.
        */
        public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityStorageInterface $term_storage, protected EntityTypeBundleInfoInterface $entityTypeBundleInfo) {
        parent::__construct($configuration, $plugin_id, $plugin_definition, $term_storage);
        }
        /**
        * {@inheritdoc}
        */
        public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static {
        return new static(
        $configuration,
        $plugin_id,
        $plugin_definition,
        $container->get('entity_type.manager')->getStorage('taxonomy_term'),
        $container->get('entity_type.bundle.info'),
        );
        }
        }
        langcode: en
        status: true
        dependencies:
        config:
        - core.entity_view_mode.node.teaser
        module:
        - node
        - taxonomy
        - user
        id: taxonomy_translated_term_name_test
        label: 'Taxonomy Translated Term Name Test'
        module: taxonomy
        description: 'Content belonging to a certain taxonomy term.'
        tag: default
        base_table: node_field_data
        base_field: nid
        display:
        default:
        id: default
        display_title: Default
        display_plugin: default
        position: 0
        display_options:
        query:
        type: views_query
        options:
        query_comment: ''
        disable_sql_rewrite: false
        distinct: false
        replica: false
        query_tags: { }
        access:
        type: perm
        options:
        perm: 'access content'
        cache:
        type: tag
        options: { }
        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: 0
        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: ››
        sorts:
        sticky:
        id: sticky
        table: taxonomy_index
        field: sticky
        order: DESC
        plugin_id: standard
        relationship: none
        group_type: group
        admin_label: ''
        exposed: false
        expose:
        label: ''
        created:
        id: created
        table: taxonomy_index
        field: created
        order: DESC
        plugin_id: date
        relationship: none
        group_type: group
        admin_label: ''
        exposed: false
        expose:
        label: ''
        granularity: second
        arguments:
        term_node_tid_depth:
        id: term_node_tid_depth
        table: node_field_data
        field: term_node_tid_depth
        relationship: none
        group_type: group
        admin_label: ''
        default_action: ignore
        exception:
        value: all
        title_enable: false
        title: All
        title_enable: true
        title: '{{ arguments.term_node_tid_depth }}'
        default_argument_type: fixed
        default_argument_options:
        argument: ''
        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: 'entity:taxonomy_term'
        fail: 'not found'
        validate_options:
        access: true
        operation: view
        multiple: 0
        bundles: { }
        depth: 2
        break_phrase: false
        use_taxonomy_term_path: false
        entity_type: node
        plugin_id: taxonomy_index_tid_depth
        filters:
        langcode:
        id: langcode
        table: node_field_data
        field: langcode
        relationship: none
        group_type: group
        admin_label: ''
        operator: in
        value:
        '***LANGUAGE_language_content***': '***LANGUAGE_language_content***'
        group: 1
        exposed: false
        expose:
        operator_id: ''
        label: ''
        description: ''
        use_operator: false
        operator: ''
        identifier: ''
        required: false
        remember: false
        multiple: false
        remember_roles:
        authenticated: authenticated
        reduce: false
        operator_limit_selection: false
        operator_list: { }
        is_grouped: false
        group_info:
        label: ''
        description: ''
        identifier: ''
        optional: true
        widget: select
        multiple: false
        remember: false
        default_group: All
        default_group_multiple: { }
        group_items: { }
        plugin_id: language
        entity_type: node
        entity_field: langcode
        status:
        id: status
        table: taxonomy_index
        field: status
        relationship: none
        group_type: group
        admin_label: ''
        operator: '='
        value: '1'
        group: 1
        exposed: false
        expose:
        operator_id: ''
        label: ''
        description: ''
        use_operator: false
        operator: ''
        identifier: ''
        required: false
        remember: false
        multiple: false
        remember_roles:
        authenticated: authenticated
        operator_limit_selection: false
        operator_list: { }
        is_grouped: false
        group_info:
        label: ''
        description: ''
        identifier: ''
        optional: true
        widget: select
        multiple: false
        remember: false
        default_group: All
        default_group_multiple: { }
        group_items: { }
        plugin_id: boolean
        style:
        type: default
        options:
        grouping: { }
        row_class: ''
        default_row_class: true
        uses_fields: false
        row:
        type: 'entity:node'
        options:
        view_mode: teaser
        header:
        entity_taxonomy_term:
        id: entity_taxonomy_term
        table: views
        field: entity_taxonomy_term
        relationship: none
        group_type: group
        admin_label: ''
        empty: true
        tokenize: true
        target: '{{ raw_arguments.tid }}'
        view_mode: full
        bypass_access: false
        plugin_id: entity
        footer: { }
        empty: { }
        relationships: { }
        fields: { }
        display_extenders: { }
        link_url: ''
        link_display: page_1
        cache_metadata:
        contexts:
        - 'languages:language_interface'
        - url
        - url.query_args
        - 'user.node_grants:view'
        - user.permissions
        max-age: -1
        tags: { }
        page_1:
        id: page_1
        display_title: Page
        display_plugin: page
        position: 1
        display_options:
        query:
        type: views_query
        options: { }
        display_extenders: { }
        path: taxonomy/test/%
        cache_metadata:
        max-age: -1
        contexts: { }
        tags: { }
        page_2:
        id: page_2
        display_title: Page
        display_plugin: page
        position: 1
        display_options:
        arguments:
        tid:
        id: tid
        table: taxonomy_term_field_data
        field: tid
        relationship: term_node_tid
        group_type: group
        admin_label: ''
        entity_type: taxonomy_term
        entity_field: tid
        plugin_id: taxonomy
        default_action: ignore
        exception:
        value: all
        title_enable: false
        title: All
        title_enable: false
        title: ''
        default_argument_type: fixed
        default_argument_options:
        argument: ''
        summary_options:
        base_path: ''
        count: true
        override: false
        items_per_page: 25
        summary:
        sort_order: asc
        number_of_records: 0
        format: default_summary
        specify_validation: false
        validate:
        type: none
        fail: 'not found'
        validate_options: { }
        break_phrase: false
        not: false
        query:
        type: views_query
        options: { }
        defaults:
        relationships: false
        arguments: false
        relationships:
        term_node_tid:
        id: term_node_tid
        table: node_field_data
        field: term_node_tid
        relationship: none
        group_type: group
        admin_label: term
        entity_type: node
        plugin_id: node_term_data
        required: false
        vids: { }
        display_extenders: { }
        path: taxonomy/test2/%
        cache_metadata:
        max-age: -1
        contexts: { }
        tags: { }
        <?php
        declare(strict_types=1);
        namespace Drupal\Tests\taxonomy\Functional\Views;
        use Drupal\Core\Url;
        use Drupal\Tests\taxonomy\Functional\TaxonomyTranslationTestTrait;
        /**
        * Tests for views translation.
        *
        * @group taxonomy
        */
        class TermTranslationViewsTest extends TaxonomyTestBase {
        use TaxonomyTranslationTestTrait;
        /**
        * Term to translated term mapping.
        *
        * @var array
        */
        protected $termTranslationMap = [
        'one' => 'translatedOne',
        'two' => 'translatedTwo',
        'three' => 'translatedThree',
        ];
        /**
        * Created terms.
        *
        * @var \Drupal\taxonomy\Entity\Term[]
        */
        protected $terms = [];
        /**
        * {@inheritdoc}
        */
        protected static $modules = ['taxonomy', 'language', 'content_translation', 'views'];
        /**
        * Views used by this test.
        *
        * @var array
        */
        public static $testViews = ['taxonomy_translated_term_name_test'];
        /**
        * {@inheritdoc}
        */
        protected $defaultTheme = 'stark';
        /**
        * Language object.
        *
        * @var \Drupal\Core\Language\LanguageInterface|null
        */
        protected $translationLanguage;
        /**
        * {@inheritdoc}
        */
        protected function setUp($import_test_views = TRUE, $modules = []): void {
        parent::setUp($import_test_views, $modules);
        $this->setupLanguages();
        $this->enableTranslation();
        $this->setUpTerms();
        $this->translationLanguage = \Drupal::languageManager()->getLanguage($this->translateToLangcode);
        }
        /**
        * Ensure that proper translation is returned when contextual filter.
        *
        * Taxonomy term: Term ID & Content: Has taxonomy term ID (with depth)
        * contextual filters are enabled for two separate view modes.
        */
        public function testTermsTranslationWithContextualFilter() {
        $this->drupalLogin($this->rootUser);
        foreach ($this->terms as $term) {
        // Test with "Content: Has taxonomy term ID (with depth)" contextual filter.
        // Generate base language url and send request.
        $url = Url::fromRoute('view.taxonomy_translated_term_name_test.page_1', ['arg_0' => $term->id()])->toString();
        $this->drupalGet($url);
        $this->assertSession()->pageTextContains($term->label());
        // Generate translation URL and send request.
        $url = Url::fromRoute('view.taxonomy_translated_term_name_test.page_1', ['arg_0' => $term->id()], ['language' => $this->translationLanguage])->toString();
        $this->drupalGet($url);
        $this->assertSession()->pageTextContains($this->termTranslationMap[$term->label()]);
        // Test with "Taxonomy term: Term ID" contextual filter.
        // Generate base language url and send request.
        $url = Url::fromRoute('view.taxonomy_translated_term_name_test.page_2', ['arg_0' => $term->id()])->toString();
        $this->drupalGet($url);
        $this->assertSession()->pageTextContains($term->label());
        // Generate translation URL and send request.
        $url = Url::fromRoute('view.taxonomy_translated_term_name_test.page_2', ['arg_0' => $term->id()], ['language' => $this->translationLanguage])->toString();
        $this->drupalGet($url);
        $this->assertSession()->pageTextContains($this->termTranslationMap[$term->label()]);
        }
        }
        /**
        * Setup translated terms in a hierarchy.
        */
        protected function setUpTerms() {
        $parent_vid = 0;
        foreach ($this->termTranslationMap as $name => $translation) {
        $term = $this->createTerm([
        'name' => $name,
        'langcode' => $this->baseLangcode,
        'parent' => $parent_vid,
        'vid' => $this->vocabulary->id(),
        ]);
        $term->addTranslation($this->translateToLangcode, [
        'name' => $translation,
        ]);
        $term->save();
        // Each term is nested under the last.
        $parent_vid = $term->id();
        $this->terms[] = $term;
        }
        }
        }
        <?php
        declare(strict_types=1);
        namespace Drupal\Tests\taxonomy\Kernel\Views;
        use Drupal\KernelTests\KernelTestBase;
        use Drupal\taxonomy_test\Plugin\views\argument\TaxonomyViewsArgumentTest;
        /**
        * Tests deprecation messages in views argument plugins.
        *
        * @group taxonomy
        */
        class ViewsArgumentDeprecationTest extends KernelTestBase {
        /**
        * {@inheritdoc}
        */
        protected static $modules = [
        'system',
        'taxonomy',
        'taxonomy_test',
        'views',
        ];
        /**
        * Test the deprecation message in ViewsArgument plugin.
        *
        * @group legacy
        */
        public function testDeprecation(): void {
        $this->expectDeprecation('Calling Drupal\taxonomy\Plugin\views\argument\Taxonomy::__construct() with the $termStorage argument as \Drupal\Core\Entity\EntityStorageInterface is deprecated in drupal:10.3.0 and it will require Drupal\Core\Entity\EntityRepositoryInterface in drupal:11.0.0. See https://www.drupal.org/node/3427843');
        $plugin = \Drupal::service('plugin.manager.views.argument')->createInstance('taxonomy_views_argument_test', []);
        $this->assertInstanceOf(TaxonomyViewsArgumentTest::class, $plugin);
        }
        }
        0% Loading or .
        You are about to add 0 people to the discussion. Proceed with caution.
        Please register or to comment