Skip to content

Commit c337b97

Browse files
committed
Make categories faster, remove home category
1 parent 48702f5 commit c337b97

2 files changed

Lines changed: 71 additions & 14 deletions

File tree

classes/Hook/HookActionObjectProductInCartDeleteBefore.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public function run()
5454
if (!Validate::isLoadedObject($product)) {
5555
return;
5656
}
57-
$product = (array) $product;
57+
$product = (array) $product;
5858
$product['id_product'] = $product['id'];
5959

6060
// Get some basic information

classes/Wrapper/ProductWrapper.php

Lines changed: 70 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,13 @@
2626
use Manufacturer;
2727
use PrestaShop\PrestaShop\Adapter\Presenter\Product\ProductLazyArray;
2828
use PrestaShop\PrestaShop\Adapter\Presenter\Product\ProductListingLazyArray;
29-
use Product;
3029
use Shop;
3130

3231
class ProductWrapper
3332
{
3433
private $context;
34+
private $categories = [];
35+
private $homeCategory = 0;
3536

3637
public function __construct(Context $context)
3738
{
@@ -55,6 +56,17 @@ public function prepareItemListFromProductList($productList, $useProvidedQuantit
5556
return [];
5657
}
5758

59+
// Preload categories for the whole list
60+
$productIds = [];
61+
foreach ($productList as $product) {
62+
if (!empty($product['id_product'])) {
63+
$productIds[] = $product['id_product'];
64+
} elseif (!empty($product['id'])) {
65+
$productIds[] = $product['id'];
66+
}
67+
}
68+
$this->loadCategories($productIds);
69+
5870
// Prepare each item and override the counter
5971
$counter = 0;
6072
foreach ($productList as $product) {
@@ -67,6 +79,42 @@ public function prepareItemListFromProductList($productList, $useProvidedQuantit
6779
return $items;
6880
}
6981

82+
/**
83+
* Loads all product categories for provided product IDs
84+
*
85+
* @param array $productIds
86+
*/
87+
private function loadCategories($productIds) {
88+
if (empty($productIds)) {
89+
return;
90+
}
91+
92+
// Initialize home category
93+
$this->homeCategory = (int) Configuration::get('PS_HOME_CATEGORY');
94+
95+
// Initialize our cache
96+
$this->categories = [];
97+
foreach($productIds as $id) {
98+
$this->categories[(int) $id] = [];
99+
}
100+
101+
// Load categories for all products
102+
$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(
103+
'
104+
SELECT cp.`id_category`, cp.`id_product`, cl.`name` FROM `' . _DB_PREFIX_ . 'category_product` cp
105+
LEFT JOIN `' . _DB_PREFIX_ . 'category` c ON (c.id_category = cp.id_category)
106+
LEFT JOIN `' . _DB_PREFIX_ . 'category_lang` cl ON (cp.`id_category` = cl.`id_category`' . Shop::addSqlRestrictionOnLang('cl') . ')
107+
' . Shop::addSqlAssociation('category', 'c') . '
108+
WHERE cp.`id_product` IN (' . implode(',', $productIds) . ') AND cl.`id_lang` = ' . (int) $this->context->language->id . '
109+
ORDER BY c.`level_depth` DESC'
110+
);
111+
112+
// Store it by product ID
113+
foreach ($result as $row) {
114+
$this->categories[(int) $row['id_product']][] = $row;
115+
}
116+
}
117+
70118
/**
71119
* Takes provided (lazy) array and converts it to a format that GA4 requires. It can handle:
72120
* - ProductLazyArray from product page
@@ -137,25 +185,34 @@ public function prepareItemFromProduct($product, $useProvidedQuantity = false)
137185
$item['quantity'] = $product['quantity'];
138186
}
139187

140-
// Prepare category information, put default category as the main one
141-
$productCategories1 = [];
142-
$productCategories2 = [];
143-
foreach (Product::getProductCategoriesFull((int) $product['id']) as $productCategory) {
144-
if ($productCategory['id_category'] == $product['id_category_default']) {
145-
$productCategories1[] = $productCategory;
146-
} else {
147-
$productCategories2[] = $productCategory;
148-
}
188+
// Prepare category information, if not loaded before, we will fetch it
189+
if (!isset($this->categories[(int) $product_id])) {
190+
$this->loadCategories([(int) $product_id]);
149191
}
150-
$productCategories = array_merge($productCategories1, $productCategories2);
151192

152-
// Limit categories to 5
153-
$productCategories = array_slice($productCategories, 0, 5, true);
193+
$productCategories = $this->categories[(int) $product_id];
194+
195+
// If the category is our default one, we will move it to the beginning of that list
196+
foreach ($productCategories as $key => $category) {
197+
if ($category['id_category'] == $product['id_category_default']) {
198+
$productCategories = [$key => $category] + $productCategories;
199+
break;
200+
}
201+
}
154202

155203
// Add it to our item
156204
$counter = 1;
157205
foreach ($productCategories as $productCategory) {
206+
// Skip home category if we have more than 1 category
207+
if (count($productCategories) > 1 && $productCategory['id_category'] == $this->homeCategory) {
208+
continue;
209+
}
210+
211+
// Add it with proper key
158212
$item[$counter == 1 ? 'item_category' : 'item_category' . $counter] = $productCategory['name'];
213+
if ($counter == 5) {
214+
break;
215+
}
159216
++$counter;
160217
}
161218

0 commit comments

Comments
 (0)