Auto similar products by attributes in OpenCart 3
In today's short note, we will see how we can remake the related product block in opencart 3 in such a way that we would automatically display products similar in attributes.
Input data - there is a product on the site - car tires, and we need to display 4 cards with the same attributes - width, diameter and profile in the block of a similar product.
I want to note right away that the solution below is a quick option that immediately came to mind and which worked. I have no doubt that it can be improved and minimized code / load, so everything is laid out as is.
First of all, open the file catalog/model/catalog/product.php, and looking for a function around line 397
public function getProductRelated($product_id) {
and after the line
$product_data = array();
get attributes for filtering the current open product
$diameter_value = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_attribute WHERE product_id = $product_id AND attribute_id = 15"); foreach($diameter_value->rows as $diameter){ $diameter = $diameter['text']; } $profile_value = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_attribute WHERE product_id = $product_id AND attribute_id = 20"); foreach($profile_value->rows as $profile){ $profile = $profile['text']; } $width_value = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_attribute WHERE product_id = $product_id AND attribute_id = 19"); foreach($width_value->rows as $width){ $width = $width['text']; }
After commenting out the standard request for similar products of the standard method
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_related pr LEFT JOIN " . DB_PREFIX . "product p ON (pr.related_id = p.ðÊÉíU ðÊÉíU ЛÉÉíU ™ÉÉíU XÊÉíU ÊÉíU @ ÊÉíU r.product_id = '" . (int)$product_id . "' AND p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '" . (int)$this->config->get('config_store_id') . "'"); foreach ($query->rows as $result) { $product_data[$result['related_id']] = $this->getProduct($result['related_id']); }
and add a selection of product IDs that have the same three attributes as the open product, while excluding its ID, and making a limit of 4 items.
$related_product_id = $this->db->query("SELECT `product_id` FROM `oc_product_attribute` WHERE `text` IN ('$diameter', '$profile', '$width') GROUP BY `product_id` HAVING count(*) = 3 AND `product_id` != $product_id LIMIT 4"); foreach($related_product_id->rows as $result){ $product_data[$result['product_id']] = $this->getProduct($result['product_id']); }
That's actually all. Now we will display on all products 4 products similar in attributes.