Related product in Drupal 9 Commerce 2

If you ever want to make a views block with recommended products on the product page that have the same taxonomy term, using a taxonomy filter from URL, then you may not work. 

The solution in the form of such a patch was found in drupal.org:

From 0f3498415254f0351ed35d907287a2a193688dd4 Mon Sep 17 00:00:00 2001
From: Anas Mawlawi <[email protected]>
Date: Tue, 15 Oct 2019 11:03:05 +0300
Subject: [PATCH 1/1] Override core default taxonomy term id views argument
 default

---
 modules/product/commerce_product.module       | 10 +++
 .../views/argument_default/ProductTid.php     | 81 +++++++++++++++++++
 2 files changed, 91 insertions(+)
 create mode 100644 modules/product/src/Plugin/views/argument_default/ProductTid.php

diff --git a/modules/product/commerce_product.module b/modules/product/commerce_product.module
index 57945667..5dceec1a 100644
--- a/modules/product/commerce_product.module
+++ b/modules/product/commerce_product.module
@@ -351,3 +351,13 @@ function commerce_product_type_labels() {
 
   return EntityHelper::extractLabels($product_types);
 }
+
+/**
+ * Implements hook_views_plugins_argument_default_alter().
+ *
+ * Override the core default taxonomy term id views argument default
+ * to provide commerce product entity integration.
+ */
+function commerce_product_views_plugins_argument_default_alter(array &$plugins) {
+  $plugins['taxonomy_tid']['class'] = 'Drupal\commerce_product\Plugin\views\argument_default\ProductTid';
+}
diff --git a/modules/product/src/Plugin/views/argument_default/ProductTid.php b/modules/product/src/Plugin/views/argument_default/ProductTid.php
new file mode 100644
index 00000000..3b67cbe3
--- /dev/null
+++ b/modules/product/src/Plugin/views/argument_default/ProductTid.php
@@ -0,0 +1,81 @@
+<?php
+
+namespace Drupal\commerce_product\Plugin\views\argument_default;
+
+use Drupal\taxonomy\TermInterface;
+use Drupal\node\NodeInterface;
+use Drupal\commerce_product\Entity\ProductInterface;
+use Drupal\taxonomy\Plugin\views\argument_default\Tid;
+
+class ProductTid extends Tid {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getArgument() {
+    // Load default argument from taxonomy page.
+    if (!empty($this->options['term_page'])) {
+      if (($taxonomy_term = $this->routeMatch->getParameter('taxonomy_term')) && $taxonomy_term instanceof TermInterface) {
+        return $taxonomy_term->id();
+      }
+    }
+    // Load default argument from node.
+    if (!empty($this->options['node'])) {
+      // Just check, if a node could be detected.
+      if (($node = $this->routeMatch->getParameter('node')) && $node instanceof NodeInterface) {
+        $taxonomy = [];
+        foreach ($node->getFieldDefinitions() as $field) {
+          if ($field->getType() == 'entity_reference' && $field->getSetting('target_type') == 'taxonomy_term') {
+            $taxonomy_terms = $node->{$field->getName()}->referencedEntities();
+            /** @var \Drupal\taxonomy\TermInterface $taxonomy_term */
+            foreach ($taxonomy_terms as $taxonomy_term) {
+              $taxonomy[$taxonomy_term->id()] = $taxonomy_term->bundle();
+            }
+          }
+        }
+        if (!empty($this->options['limit'])) {
+          $tids = [];
+          // filter by vocabulary
+          foreach ($taxonomy as $tid => $vocab) {
+            if (!empty($this->options['vids'][$vocab])) {
+              $tids[] = $tid;
+            }
+          }
+          return implode($this->options['anyall'], $tids);
+        }
+        // Return all tids.
+        else {
+          return implode($this->options['anyall'], array_keys($taxonomy));
+        }
+      }
+      // Just check, if a product could be detected.
+      elseif (($product = $this->routeMatch->getParameter('commerce_product')) && $product instanceof ProductInterface) {
+        $taxonomy = [];
+        foreach ($product->getFieldDefinitions() as $field) {
+          if ($field->getType() == 'entity_reference' && $field->getSetting('target_type') == 'taxonomy_term') {
+            $taxonomy_terms = $product->{$field->getName()}->referencedEntities();
+            /** @var \Drupal\taxonomy\TermInterface $taxonomy_term */
+            foreach ($taxonomy_terms as $taxonomy_term) {
+              $taxonomy[$taxonomy_term->id()] = $taxonomy_term->bundle();
+            }
+          }
+        }
+        if (!empty($this->options['limit'])) {
+          $tids = [];
+          // filter by vocabulary
+          foreach ($taxonomy as $tid => $vocab) {
+            if (!empty($this->options['vids'][$vocab])) {
+              $tids[] = $tid;
+            }
+          }
+          return implode($this->options['anyall'], $tids);
+        }
+        // Return all tids.
+        else {
+          return implode($this->options['anyall'], array_keys($taxonomy));
+        }
+      }
+    }
+  }
+
+}
-- 
2.23.0

After accepting this patch in the block will begin to display goods which have the same taxonomy term as open.

Простий текст

  • Не дозволено жодних HTML теґів.
  • Рядки й абзаци переносяться автоматично.
  • Адреси вебсторінок та адреси електронної пошти автоматично перетворюються у посилання.
Код мови коментаря.