FacetsHierarchy Taxonomy uses taxonomy_term_hierachy which is dropped in drupal 8.3.
Patch uses table taxonomy_term__parent instead.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Christian.wiedemann created an issue. See original summary.

borisson_’s picture

Status: Active » Needs review

Setting to needs review for testbot.

Status: Needs review » Needs work

The last submitted patch, facets-hierarchy-with-parent-table.patch, failed testing. View results

borisson_’s picture

Status: Needs work » Postponed

Is this already committed? I think that's part of #2543726: Make $term->parent behave like any other entity reference field, to fix REST and Migrate support and de-customize its Views integration? As you can see this completely fails on the Integration tests.

Berdir’s picture

Also, with it now being a proper field, maybe those queries could be converted to entity queries instead so we don't have to rely on the internal DB structure anymore?

Wim Leers’s picture

Also, with it now being a proper field, maybe those queries could be converted to entity queries instead so we don't have to rely on the internal DB structure anymore?

🎉

larowlan’s picture

+++ b/src/Plugin/facets/hierarchy/Taxonomy.php
@@ -72,9 +72,9 @@ class Taxonomy extends HierarchyPluginBase {
-      $query = $this->database->select('taxonomy_term_hierarchy', 'h');
-      $query->addField('h', 'tid');
-      $query->condition('h.parent', $id);
+      $query = $this->database->select('taxonomy_term__parent', 'h');
+      $query->addField('h', 'entity_id');
+      $query->condition('h.parent_target_id', $id);

@@ -89,18 +89,18 @@ class Taxonomy extends HierarchyPluginBase {
-    $result = $this->database->select('taxonomy_term_hierarchy', 'th')
-      ->fields('th', ['tid', 'parent'])
-      ->condition('th.parent', '0', '>')
+    $result = $this->database->select('taxonomy_term__parent', 'th')
+      ->fields('th', ['entity_id', 'parent_target_id'])
+      ->condition('th.parent_target_id', '0', '>')
       ->condition((new Condition('OR'))
-        ->condition('th.tid', $ids, 'IN')
-        ->condition('th.parent', $ids, 'IN')
+        ->condition('th.entity_id', $ids, 'IN')

@@ -118,9 +118,10 @@ class Taxonomy extends HierarchyPluginBase {
-      $query = $this->database->select('taxonomy_term_hierarchy', 'h');
-      $query->addField('h', 'parent');
-      $query->condition('h.tid', $tid);
+      $query = $this->database->select('taxonomy_term__
+      parent', 'h');
+      $query->addField('h', 'parent_target_id');
+      $query->condition('h.entity_id', $tid);
       $parent[$tid] = $query->execute()->fetchField();

This is the wrong fix in my opinion.

It should be using the term storage handler, which has methods to fetch the hierarchy for you - and therefore will work with non sql entity storage.

The original code shouldn't interact with the tables direct.

IF we switched this to use the term storage handler, the code would work both now *and* after the core issue goes in

Berdir’s picture

Priority: Normal » Major
Status: Postponed » Needs work

If we can indeed replace that code with methods from \Drupal\taxonomy\TermStorageInterface then that is definitely the best solution.

Also means that is not postponed but needs work and is major if not critical, as Drupal core will eventually break this. Maybe/hopefully in 8.5, if not then in 8.6.

borisson_’s picture

It should be using the term storage handler, which has methods to fetch the hierarchy for you - and therefore will work with non sql entity storage.

The original code shouldn't interact with the tables direct.

IF we switched this to use the term storage handler, the code would work both now *and* after the core issue goes in

If I understand this correctly, we should be using \Drupal\taxonomy\TermStorageInterface::loadParents to replace this? Sounds like a good solution. I didn't know about those methods, that really helps, thanks!

larowlan’s picture

Yep those methods are part of the API and will stay, the implementation underneath is up to core to keep consistent

Wim Leers’s picture

@borisson_ Let me know what I can do to help here. This is soft-blocking #2543726: Make $term->parent behave like any other entity reference field, to fix REST and Migrate support and de-customize its Views integration from landing in Drupal core 8.5, which in turn is blocking A) REST support for Term entities' parents, B) Migrate support for Term entities, C) more reliable Views integration for Term entities.

Wim Leers’s picture

borisson_’s picture

I'm going to try to implement the suggestion made in #7 tonight, my personal laptop is broken so I'll probably have some fun first with setting up a dev env on my windows machine first.

So if I can get all of that to work it shouldn't be too hard to actually implement #7. I'd love to see a review when I get the patch up. I'll tag a new release to help with upgrades after we get this in.

Wim Leers’s picture

Wim Leers’s picture

Title: FacetsHierarchy Taxonomy uses old (taxonmy_term_hierachy) table. » FacetsHierarchy Taxonomy uses old (taxonomy_term_hierachy) table.
borisson_’s picture

Status: Needs work » Needs review
FileSize
4.6 KB

I tested unit and kernel tests locally and they are still green. Hopefully the integration tests still pass as well. No interdiff, because it's a new approach.

Status: Needs review » Needs work

The last submitted patch, 16: 2919034-15.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Berdir’s picture

+++ b/src/Plugin/facets/hierarchy/Taxonomy.php
@@ -72,15 +74,8 @@ class Taxonomy extends HierarchyPluginBase {
   public function getNestedChildIds($id) {
     $children = &drupal_static(__FUNCTION__, []);
     if (!isset($children[$id])) {
-      $query = $this->database->select('taxonomy_term_hierarchy', 'h');
-      $query->addField('h', 'tid');
-      $query->condition('h.parent', $id);

those methods AFAIK all have their own static cache, so you can probably remove that?

I don't think loadTree has the same structure through, that returns some weird object-not-really-entities thing by default. You probably want to get the ID's of those. Maybe you need to recursively call loadChildren() instead?

borisson_’s picture

Status: Needs work » Needs review
FileSize
1.9 KB
4.93 KB

The tests that failed are now green locally, I also removed static cache, thanks @Berdir!

Berdir’s picture

  1. +++ b/src/Plugin/facets/hierarchy/Taxonomy.php
    @@ -72,11 +70,15 @@ class Taxonomy extends HierarchyPluginBase {
    -      $term = Term::load($id)->getVocabularyId();
    -      $children = $this->termStorage->loadTree($term, $id);
    +    $children = $this->termStorage->loadChildren($id);
    +    $subchilds = [];
    +    $children = array_filter(array_values(array_map(function ($it) {
    +      return $it->id();
    +    }, $children)));
    +    foreach ($children as $child) {
    +      $subchilds = array_merge($subchilds, $this->getNestedChildIds($child));
         }
    +    $children[$id] = array_merge($children, $subchilds);
         return isset($children[$id]) ? $children[$id] : [];
    

    You seem to be using the $children variable twice now, once to load the children terms and once as a left-over of the static cache. I think you can just do return array_merge(); on the second-last line.

  2. +++ b/src/Plugin/facets/hierarchy/Taxonomy.php
    @@ -105,16 +107,13 @@ class Taxonomy extends HierarchyPluginBase {
         }
    +    $parent[$tid] = reset($parents)->id();
         return isset($parent[$tid]) ? $parent[$tid] : FALSE;
    

    same here, you don't need $parent anymore.

borisson_’s picture

FileSize
1.29 KB
4.84 KB
borisson_’s picture

FileSize
481 bytes
4.81 KB

Fixed a coding standards issue. Should now be ready.

Berdir’s picture

Looks pretty good to me visually.

One thing to point out is that those methods are not new in 8.x, they're basically a 1:1 port of helper functions in 7.x and earlier. So it is likely that they weren't used on purpose so far as this now loads the entities when we only need the ids. An entity query might be faster but that will only start to work with the core issue.

borisson_’s picture

I tested this with ab, to make sure that @Berdir's worry wasn't too much. This was with all cache modules disabled. This is with 4 facets, 3 enabled and 1 with a taxonomy tree (with 12 items in it).

Without patch:

Requests per second:    1.05 [#/sec] (mean)
Time per request:       950.749 [ms] (mean)

With patch:

Requests per second:    1.04 [#/sec] (mean)
Time per request:       965.000 [ms] (mean)

So there is a difference but it is small. I think that with a bigger vocabulary there might be a bigger problem, so we should probably test that as well.

However, the increased readability and less complexity in the actual code is worth taking a small performance hit I think.

I'll try to test this again with a bigger vocabulary in the coming days.

Wim Leers’s picture

Status: Needs review » Reviewed & tested by the community

However, the increased readability and less complexity in the actual code is worth taking a small performance hit I think.

… and the performance hit should disappear when updating to 8.6 (and hopefully #2543726: Make $term->parent behave like any other entity reference field, to fix REST and Migrate support and de-customize its Views integration will also still land in 8.5).

  • borisson_ committed 5ad1df5 on 8.x-1.x
    Issue #2919034 by borisson_, Christian.wiedemann, Berdir, larowlan:...
borisson_’s picture

Status: Reviewed & tested by the community » Fixed

Committed and pushed, thanks so much for helping out and for all this information.

Wim Leers’s picture

🎉

Status: Fixed » Closed (fixed)

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