Skip to content
Snippets Groups Projects
Commit 8d2f88bf authored by catch's avatar catch
Browse files

Issue #2183565 by plopesc, alexpott, jcnventura, DuaelFr, melvinlouwerse,...

Issue #2183565 by plopesc, alexpott, jcnventura, DuaelFr, melvinlouwerse, grndlvl, cesarmiquel, Sweetchuck, yogeshmpawar, BetoAveiga, Sivaji_Ganesh_Jojodae, drugan, marvil07, smustgrave, poker10, catch, bbrala: Avoid loading all terms on the taxonomy overview form

(cherry picked from commit 7c1e3a1b)
parent c164e76f
Branches
Tags
16 merge requests!8376Drupal views: adding more granularity to the ‘use ajax’ functionality,!8300Issue #3443586 View area displays even when parent view has no results.,!7567Issue #3153723 by quietone, Hardik_Patel_12: Change the scaffolding...,!7565Issue #3153723 by quietone, Hardik_Patel_12: Change the scaffolding...,!7509Change label "Block description" to "Block type",!7344Issue #3292350 by O'Briat, KlemenDEV, hswong3i, smustgrave, quietone: Update...,!6922Issue #3412959 by quietone, smustgrave, longwave: Fix 12 'un' words,!6848Issue #3417553 by longwave: Remove withConsecutive() in CacheCollectorTest,!6720Revert "Issue #3358581 by pfrenssen, _tarik_, a.dmitriiev, smustgrave:...,!6560Update ClaroPreRender.php, confirming classes provided are in array format,!6528Issue #3414261 by catch: Add authenticated user umami performance tests,!6501Issue #3263668 by omkar-pd, Wim Leers, hooroomoo: Re-enable inline form errors...,!6354Draft: Issue #3380392 by phma: Updating language weight from the overview reverts label if translated,!6324Issue #3416723 by Ludo.R: Provide a "node type" views default argument,!6119Issue #3405704 by Spokje, longwave: symfony/psr-http-message-bridge major version bump,!5950Issue #3403653 by alexpott, longwave: Incorporate improvements to how contrib runs PHPStan to core
Pipeline #66567 passed
Pipeline: drupal

#66580

    Pipeline: drupal

    #66578

      Pipeline: drupal

      #66575

        +1
        ......@@ -158,7 +158,9 @@ public function buildForm(array $form, FormStateInterface $form_state, Vocabular
        $delta = 0;
        $term_deltas = [];
        $tree = $this->storageController->loadTree($taxonomy_vocabulary->id(), 0, NULL, TRUE);
        // Terms are not loaded to avoid excessive memory consumption for large
        // vocabularies. Needed terms are loaded explicitly afterward.
        $tree = $this->storageController->loadTree($taxonomy_vocabulary->id(), 0, NULL, FALSE);
        $tree_index = 0;
        $complete_tree = NULL;
        do {
        ......@@ -179,8 +181,8 @@ public function buildForm(array $form, FormStateInterface $form_state, Vocabular
        }
        // Do not let a term start the page that is not at the root.
        $term = $tree[$tree_index];
        if (isset($term->depth) && ($term->depth > 0) && !isset($back_step)) {
        $raw_term = $tree[$tree_index];
        if (isset($raw_term->depth) && ($raw_term->depth > 0) && !isset($back_step)) {
        $back_step = 0;
        while ($parent_term = $tree[--$tree_index]) {
        $before_entries--;
        ......@@ -195,7 +197,7 @@ public function buildForm(array $form, FormStateInterface $form_state, Vocabular
        $back_step = $back_step ?? 0;
        // Continue rendering the tree until we reach the a new root item.
        if ($page_entries >= $page_increment + $back_step + 1 && $term->depth == 0 && $root_entries > 1) {
        if ($page_entries >= $page_increment + $back_step + 1 && $raw_term->depth == 0 && $root_entries > 1) {
        $complete_tree = TRUE;
        // This new item at the root level is the first item on the next page.
        $after_entries++;
        ......@@ -208,20 +210,30 @@ public function buildForm(array $form, FormStateInterface $form_state, Vocabular
        // Finally, if we've gotten down this far, we're rendering a term on this
        // page.
        $page_entries++;
        $term_deltas[$term->id()] = isset($term_deltas[$term->id()]) ? $term_deltas[$term->id()] + 1 : 0;
        $key = 'tid:' . $term->id() . ':' . $term_deltas[$term->id()];
        $term_deltas[$raw_term->tid] = isset($term_deltas[$raw_term->tid]) ? $term_deltas[$raw_term->tid] + 1 : 0;
        $key = 'tid:' . $raw_term->tid . ':' . $term_deltas[$raw_term->tid];
        // Keep track of the first term displayed on this page.
        if ($page_entries == 1) {
        $form['#first_tid'] = $term->id();
        $form['#first_tid'] = $raw_term->tid;
        }
        // Keep a variable to make sure at least 2 root elements are displayed.
        if ($term->parents[0] == 0) {
        if ($raw_term->parents[0] == 0) {
        $root_entries++;
        }
        $current_page[$key] = $term;
        $current_page[$key] = $raw_term;
        } while (isset($tree[++$tree_index]));
        // Load all the terms we're going to display and set the weight and parents
        // from the tree.
        $terms = $this->storageController->loadMultiple(array_keys($term_deltas));
        $current_page = array_map(function ($raw_term) use ($terms) {
        $term = $terms[$raw_term->tid];
        $term->depth = $raw_term->depth;
        $term->parents = $raw_term->parents;
        return $term;
        }, $current_page);
        // Because we didn't use a pager query, set the necessary pager variables.
        $total_entries = $before_entries + $page_entries + $after_entries;
        $this->pagerManager->createPager($total_entries, $page_increment);
        ......@@ -518,7 +530,9 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
        $vocabulary = $form_state->get(['taxonomy', 'vocabulary']);
        $changed_terms = [];
        $tree = $this->storageController->loadTree($vocabulary->id(), 0, NULL, TRUE);
        // Terms are not loaded to avoid excessive memory consumption for large
        // vocabularies. Needed terms are loaded explicitly afterward.
        $tree = $this->storageController->loadTree($vocabulary->id(), 0, NULL, FALSE);
        if (empty($tree)) {
        return;
        ......@@ -526,14 +540,14 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
        // Build a list of all terms that need to be updated on previous pages.
        $weight = 0;
        $term = $tree[0];
        while ($term->id() != $form['#first_tid']) {
        if ($term->parents[0] == 0 && $term->getWeight() != $weight) {
        $term->setWeight($weight);
        $changed_terms[$term->id()] = $term;
        $raw_term = $tree[0];
        $term_weights = [];
        while ($raw_term->tid != $form['#first_tid']) {
        if ($raw_term->parents[0] == 0 && $raw_term->weight != $weight) {
        $term_weights[$raw_term->tid] = $weight;
        }
        $weight++;
        $term = $tree[$weight];
        $raw_term = $tree[$weight];
        }
        // Renumber the current page weights and assign any new parents.
        ......@@ -565,14 +579,19 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
        // Build a list of all terms that need to be updated on following pages.
        for ($weight; $weight < count($tree); $weight++) {
        $term = $tree[$weight];
        if ($term->parents[0] == 0 && $term->getWeight() != $weight) {
        $term->parent->target_id = $term->parents[0];
        $term->setWeight($weight);
        $changed_terms[$term->id()] = $term;
        $raw_term = $tree[$weight];
        if ($raw_term->parents[0] == 0 && $raw_term->weight != $weight) {
        $term_weights[$raw_term->tid] = $weight;
        }
        }
        // Load all the items that need to be updated at once.
        $terms = $this->storageController->loadMultiple(array_keys($term_weights));
        foreach ($terms as $term) {
        $term->setWeight($term_weights[$term->id()]);
        $changed_terms[$term->id()] = $term;
        }
        if (!empty($changed_terms)) {
        $pending_term_ids = $this->storageController->getTermIdsWithPendingRevisions();
        ......
        ......@@ -46,3 +46,15 @@ function taxonomy_test_form_taxonomy_term_form_alter(&$form, FormStateInterface
        $form['relations']['parent']['#disabled'] = TRUE;
        }
        }
        /**
        * Implements hook_ENTITY_TYPE_load() for the taxonomy term.
        */
        function taxonomy_test_taxonomy_term_load($entities) {
        $value = \Drupal::state()->get(__FUNCTION__);
        // Only record loaded terms is the test has set this to an empty array.
        if (is_array($value)) {
        $value = array_merge($value, array_keys($entities));
        \Drupal::state()->set(__FUNCTION__, array_unique($value));
        }
        }
        ......@@ -14,7 +14,7 @@ class TaxonomyTermPagerTest extends TaxonomyTestBase {
        *
        * @var array
        */
        protected static $modules = ['taxonomy'];
        protected static $modules = ['taxonomy', 'taxonomy_test'];
        /**
        * {@inheritdoc}
        ......@@ -73,4 +73,47 @@ public function testTaxonomyTermOverviewPager() {
        $this->assertSession()->responseMatches('|<nav class="pager" [^>]*>|');
        }
        /**
        * Tests that overview page only loads the necessary terms.
        */
        public function testTaxonomyTermOverviewTermLoad() {
        // Set limit to 3 terms per page.
        $this->config('taxonomy.settings')
        ->set('terms_per_page_admin', '3')
        ->save();
        $state = $this->container->get('state');
        // Create 5 terms.
        for ($x = 0; $x <= 10; $x++) {
        $this->createTerm($this->vocabulary, ['weight' => $x]);
        }
        // Check the overview page.
        $state->set('taxonomy_test_taxonomy_term_load', []);
        $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/overview');
        $loaded_terms = $state->get('taxonomy_test_taxonomy_term_load');
        $this->assertCount(4, $loaded_terms);
        // Check the overview page for submit callback.
        $state->set('taxonomy_test_taxonomy_term_load', []);
        $this->submitForm([], 'Save');
        $loaded_terms = $state->get('taxonomy_test_taxonomy_term_load');
        $this->assertCount(4, $loaded_terms);
        $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/overview', ['query' => ['page' => 2]]);
        $state->set('taxonomy_test_taxonomy_term_load', []);
        $this->submitForm([], 'Save');
        $loaded_terms = $state->get('taxonomy_test_taxonomy_term_load');
        $this->assertCount(4, $loaded_terms);
        // Adding a new term with weight < 0 implies that all root terms are updated.
        $this->createTerm($this->vocabulary, ['weight' => -1]);
        $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/overview', ['query' => ['page' => 2]]);
        $state->set('taxonomy_test_taxonomy_term_load', []);
        $this->submitForm([], 'Save');
        $loaded_terms = $state->get('taxonomy_test_taxonomy_term_load');
        $this->assertCount(12, $loaded_terms);
        }
        }
        0% Loading or .
        You are about to add 0 people to the discussion. Proceed with caution.
        Please register or to comment