Maria Gonzalez Posted May 8 Share Posted May 8 (edited) Hi, I'm developping a module to display a tag on a product but only if the product has the "HOT" feature equals 1. Here's my code: public function hookDisplayProductPriceBlock($params) { $product = $params['product']; if ($product->HOT == 1) { return $this->display(__FILE__, 'views/templates/hook/hotproduct.tpl'); } } It doesn't show anything on a product with the HOT attribute at 1. If I remove the condition, it does show! I also tried that: public function hookDisplayProductPriceBlock($params) { $product = $params['product']; // Obtener las características del producto $features = $product->getFrontFeatures($this->context->language->id); // Buscar la característica "HOT" entre las características del producto $hotValue = null; foreach ($features as $feature) { if ($feature['name'] === 'HOT') { return $this->display(__FILE__, 'views/templates/hook/hotproduct.tpl'); break; } } //if ($product->HOT == 1) { // return $this->display(__FILE__, 'views/templates/hook/hotproduct.tpl'); // } } but give me this error: PHP Fatal error: Uncaught Error: Call to undefined method PrestaShop\PrestaShop\Adapter\Presenter\Product\ProductLazyArray::getFrontFeatures() Any idea? Edited May 8 by Maria Gonzalez (see edit history) Link to comment Share on other sites More sharing options...
Maria Gonzalez Posted May 10 Author Share Posted May 10 1 hour ago, ZHSoft said: It seems like you're encountering a couple of issues here. Let's address them: 1. **Accessing Product Features**: The method `getFrontFeatures()` is not available in the `ProductLazyArray` class, which is what `$product` is in your context. Instead, you should fetch product features using the `Feature` class. 2. **Checking for the "HOT" Feature**: Once you've fetched the product features, you need to check if the "HOT" feature is enabled for the product. This typically involves finding the feature ID for "HOT" and then checking if it's enabled for the product. Here's how you can adjust your code to address these issues: public function hookDisplayProductPriceBlock($params) { $product = $params['product']; // Get the features for the product $features = Feature::getFeatures($this->context->language->id, $product->id); // Iterate through features to find "HOT" feature foreach ($features as $feature) { if ($feature['name'] === 'HOT') { // Check if the feature is enabled for the product $productHasHotFeature = FeatureProduct::isFeatureProductActive($product->id, $feature['id_feature']); if ($productHasHotFeature) { return $this->display(__FILE__, 'views/templates/hook/hotproduct.tpl'); } } } // If "HOT" feature not found or not enabled, return null return null; } This code fetches the features for the product, iterates through them to find the "HOT" feature, and then checks if it's enabled for the product. If it is, it displays the `hotproduct.tpl` template. If not, it returns null, indicating that nothing should be displayed. Make sure to replace `'HOT'` with the actual name of your feature if it's different, and adjust the logic accordingly if necessary. Hi, thanks for your suggestion. With your code I get the following error: PHP message: PHP Fatal error: Uncaught Error: Class "FeatureProduct" not found in /var/www/html/xxxx.fr/modules/hotproduct/hotproduct.php:44 Stack trace: #0 /var/www/html/xxxx.fr/classes/Hook.php(1043): HotProduct->hookDisplayProductPriceBlock() #1 /var/www/html/xxxx.fr/classes/Hook.php(418): HookCore::coreCallHook() #2 /var/www/html/xxxx.fr/classes/Hook.php(981): HookCore::callHookOn() #3 /var/www/html/xxxx.fr/config/smarty.config.inc.php(198): HookCore::exec() #4 /var/www/html/xxxx.fr/classes/Smarty/SmartyLazyRegister.php(81): smartyHook() #5 /var/www/html/xxxx.fr/var/cache/prod/smarty/compile/classiclayouts_layout_full_width_tpl/f6/92/45/f69245805fd171a2ee2e24dea3052363e7eda826_2.file.product-prices.tpl.php(102): SmartyLazyRegister->__call() #6 /var/www/html/xxxx.fr/vendor/smarty/smarty/libs/sysplugins/smarty_internal_runtime_inheritance.php(248): Block_156355770663dd0e09f6ce4_83936101->callBlock() #7 /var/www/html/xxxx.fr/vendor/smarty/smarty/libs/" while reading response header from upstream, client: 192.168.0.25, server: www.xxxx.fr, request: "GET /xlus.html HTTP/1.1", upstream: "fastcgi://unix:/run/php/php8.2-fpm.sock:", host: "xxxx.fr", referrer: "https://xxxx.fr/1xxe" Link to comment Share on other sites More sharing options...
Andrei H Posted May 11 Share Posted May 11 Hello, If you try and print out the $params['product'] array, you will see that it has a 'features' key, which contains all the features. public function hookDisplayProductPriceBlock($params) { if ($this->isDisplayed) { return; } foreach ($params['product']['features'] as $feature) { if ($feature['name'] === 'HOT') { echo '<p>This is a hot feature</p>'; $this->isDisplayed = true; } } } You will also need to add a property in the class called $isDisplayed and initially set it to false. This is because this hook is called multiple times, thus printing that line in each call. This will prevent it displaying the content more than once. Link to comment Share on other sites More sharing options...
Maria Gonzalez Posted May 11 Author Share Posted May 11 40 minutes ago, Andrei H said: Hello, If you try and print out the $params['product'] array, you will see that it has a 'features' key, which contains all the features. public function hookDisplayProductPriceBlock($params) { if ($this->isDisplayed) { return; } foreach ($params['product']['features'] as $feature) { if ($feature['name'] === 'HOT') { echo '<p>This is a hot feature</p>'; $this->isDisplayed = true; } } } You will also need to add a property in the class called $isDisplayed and initially set it to false. This is because this hook is called multiple times, thus printing that line in each call. This will prevent it displaying the content more than once. Thanks Andrei! It works!! However a scrange issue is happening with that code. It gives me error 502 : Bad Gateway on the category page.... Link to comment Share on other sites More sharing options...
ventura Posted May 11 Share Posted May 11 use echo '<p>This is a hot feature</p>'; this is not a recommended practice depending on the context in which it is applied and may generate errors when rendering content. 1 Link to comment Share on other sites More sharing options...
Andrei H Posted May 11 Share Posted May 11 6 minutes ago, ventura said: use echo '<p>This is a hot feature</p>'; this is not a recommended practice depending on the context in which it is applied and may generate errors when rendering content. Hello, Yes, that's true. I was just trying to highlight how this can be achieved. That line should be replaced with return $this->display(__FILE__, 'views/templates/hook/hotproduct.tpl'); and the $this->isDisplayed = true; added above it. However, I am not sure if that is causing the 502. If you remove the code, does it clear the 502? Link to comment Share on other sites More sharing options...
Maria Gonzalez Posted May 11 Author Share Posted May 11 (edited) 1 hour ago, Andrei H said: Hello, Yes, that's true. I was just trying to highlight how this can be achieved. That line should be replaced with return $this->display(__FILE__, 'views/templates/hook/hotproduct.tpl'); and the $this->isDisplayed = true; added above it. However, I am not sure if that is causing the 502. If you remove the code, does it clear the 502? Yes, I have done those changes and the 502 on category page still happens! If I remove the code, the error clears The nginx error I'm having is: PHP message: PHP Warning: Undefined property: HotProduct::$isDisplayed (on the if) Edited May 11 by Maria Gonzalez (see edit history) Link to comment Share on other sites More sharing options...
Maria Gonzalez Posted May 11 Author Share Posted May 11 1 hour ago, Maria Gonzalez said: Yes, I have done those changes and the 502 on category page still happens! If I remove the code, the error clears The nginx error I'm having is: PHP message: PHP Warning: Undefined property: HotProduct::$isDisplayed (on the if) SOLVED, forget to initialize at the class construct! 1 Link to comment Share on other sites More sharing options...
Maria Gonzalez Posted May 11 Author Share Posted May 11 1 hour ago, Maria Gonzalez said: SOLVED, forget to initialize at the class construct! I had notice that in the category view, if 2 products has the feature HOT, only is displayed on the first one ... Link to comment Share on other sites More sharing options...
Andrei H Posted May 11 Share Posted May 11 Hello, Yes, I just noticed that as well. It looks like the if is stopping the display.You can rewrite the hook as follows: public function hookDisplayProductPriceBlock($params) { $productId = $params['product']['id_product']; if (!empty($this->isDisplayed[$productId])) { return; } foreach ($params['product']['features'] as $feature) { if ($feature['name'] === 'HOT') { $this->isDisplayed[$productId] = true; return $this->display(__FILE__, 'views/templates/hook/hotproduct.tpl'); } } } You will also need to change the isDisplayed property in your constructor. It should be an empty array now. This way, it should be displayed for all the products. The only downside is that if the same product is displayed multiple times in a page, only the first one will have the text. Link to comment Share on other sites More sharing options...
Maria Gonzalez Posted May 11 Author Share Posted May 11 2 hours ago, Andrei H said: Hello, Yes, I just noticed that as well. It looks like the if is stopping the display.You can rewrite the hook as follows: public function hookDisplayProductPriceBlock($params) { $productId = $params['product']['id_product']; if (!empty($this->isDisplayed[$productId])) { return; } foreach ($params['product']['features'] as $feature) { if ($feature['name'] === 'HOT') { $this->isDisplayed[$productId] = true; return $this->display(__FILE__, 'views/templates/hook/hotproduct.tpl'); } } } You will also need to change the isDisplayed property in your constructor. It should be an empty array now. This way, it should be displayed for all the products. The only downside is that if the same product is displayed multiple times in a page, only the first one will have the text. I see that it should work now! but it's not, still only shown on the first product!! Link to comment Share on other sites More sharing options...
Andrei H Posted May 13 Share Posted May 13 Hello, Have you also tried to clear the cache from Admin -> Advanced Parameters -> Performance? It looks like the product data is cached for some pages. If this still not works, you will need to do some local debugging. For me, it is working as expected. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now