magento2: Fatal error on product-compare page when attributes not configured

Preconditions

  1. Magento 2.3.x

Steps to reproduce

  1. Add products to compare where at least one product has no value set for at least one of its comparable attributes (e.g. “Description” is empty).
  2. Go to the compare page (<site_root>/catalog/product_compare/index)

Expected result

  1. Compare page should load normally, where any unconfigured attributes show “N/A” or “No”.

Actual result

  1. “Fatal error: Uncaught TypeError: preg_match() expects parameter 2 to be string, object given in [site_root]/vendor/magento/module-catalog/Helper/Output.php on line 229”

The error occurs in the isDirectivesExists() method, which expects a string param. This method is called by productAttribute(), which passes $attributeHtml, which it receives as a param that is also expected to be a string. The issue is that in app/code/Magento/Catalog/view/frontend/templates/product/compare/list.phtml:119, where productAttribute() is called, the 2nd param passed is a value from \Magento\Catalog\Block\Product\Compare\ListCompare::getProductAttributeValue, which returns a \Magento\Framework\Phrase object when the value of an attribute is undefined. Therefore, an error is thrown when this object is passed through to preg_match(). The issue was triggered in commit #bdcfbc8, where a call to isDirectivesExists() is added to line 167 of app/code/Magento/Catalog/Helper/Output.php. However, this is reasonable, since a string is expected. Therefore I recommend simply modifying line 119 of list.phtml to cast the result of getProductAttributeValue() as a string, which would be appropriate, since that’s what productAttribute() is expecting.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 16 (8 by maintainers)

Commits related to this issue

Most upvoted comments

Hello, This bug is still present at version 2.3.5

If you add 1 or more products in the Compare List, and these Products have no Short Description or Description, then when you visit the Compare page you get the following Fatal Error:

Fatal error: Uncaught TypeError: preg_match() expects parameter 2 to be string, object given in /app/web/vendor/magento/module-catalog/Helper/Output.php:245 Stack trace: #0 /app/web/vendor/magento/module-catalog/Helper/Output.php(245): preg_match('/{{([a-z]{0,10}...', Object(Magento\Framework\Phrase)) #1 /app/web/vendor/magento/module-catalog/Helper/Output.php(185): Magento\Catalog\Helper\Output->isDirectivesExists(Object(Magento\Framework\Phrase)) #2 /app/web/vendor/magento/module-catalog/view/frontend/templates/product/compare/list.phtml(134): Magento\Catalog\Helper\Output->productAttribute(Object(Magento\Catalog\Model\Product\Interceptor), Object(Magento\Framework\Phrase), 'short_descripti...') #3 /app/web/vendor/magento/framework/View/TemplateEngine/Php.php(59): include('/app/web/vendor...') #4 /app/web/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Framework\View\TemplateEngine\Php->render(Object(Magento\Catalog\Block\Product\Compare\ListCompare\Interceptor), '/app/web/vendor...', Array) #5 /app/w in /app/web/vendor/magento/module-catalog/Helper/Output.php on line 245

Update: Since this BugReport is closed and nobody answered anything so far, I made a new Bug Report here: https://github.com/magento/magento2/issues/28254

Yes, I agree. I did not like the given fix either. This is why I suggested in the first place to “cast the result… as a string”. It is quite simple, and this way it is always rendered, but it will not cause any errors:

<?= /* @escapeNotVerified */ $helper->productAttribute($item, (string) $block->getProductAttributeValue($item, $attribute), $attribute->getAttributeCode()) ?>

Of course, to make the code a little cleaner, you could first set a variable:

<?php $attributeValueString = (string) $block->getProductAttributeValue($item, $attribute); ?>
<?= /* @escapeNotVerified */ $helper->productAttribute($item, $attributeValueString, $attribute->getAttributeCode()) ?>

it is mg 2.3.5 p1 but I am still facing this issue