I recently made a modification to catalog-category-view.xml
and overrode category.products.list
.
It seemed to work at the time, I had badges displaying on a rendered page.
Now the template file errors because $pos
(line 42 in src file) returns null.
I have not changed anything about the template file except for the injection of a small php if statement and an additional docblock. Here is the error:
2021/01/08 17:15:14 [error] 1415#1415: *1053 FastCGI sent in stderr: "PHP message: PHP Fatal error: Uncaught TypeError: strpos() expects parameter 1 to be string, null given in /var/www/html/magento-new/app/code/Vendor/Module/view/frontend/templates/product/list.phtml:97
Stack trace:
#0 /var/www/html/magento-new/app/code/Vendor/Module/view/frontend/templates/product/list.phtml(97): strpos(NULL, 'grid-actions')
#1 /var/www/html/magento-new/vendor/magento/framework/View/TemplateEngine/Php.php(59): include('/var/www/html/m...')
#2 /var/www/html/magento-new/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Framework\View\TemplateEngine\Php->render(Object(Magento\Catalog\Block\Product\ListProduct\Interceptor), '/var/www/html/m...', Array)
#3 /var/www/html/magento-new/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Framework\View\TemplateEngine\Php\Interceptor->___callParent('render', Array)
#4 /var/www/html/magento-new/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Framework\View\TemplateEngine\Php\" while reading response header from upstream, client: 127.0.0.1, server: dev.magento.com, request: "GET /gear/fitness-equipment.html HTTP/1.1", upstream: "fastcgi://unix:/var/run/php/php7.3-fpm.sock:", host: "dev.magento.com", referrer: "http://dev.magento.com/gear.html"
app/code/Vendor/Module/view/frontend/layout/catalog_category_view.xml
:
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left"
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<head>
<css src="Vendor_Module/assets/css/styles.css"/>
</head>
<body>
<referenceBlock name="category.products.list" template="Vendor_Module::product/list.phtml">
<arguments>
<argument name="view_model" xsi:type="object">Vendor\Module\ViewModel\ProductList</argument>
</arguments>
</referenceBlock>
</body>
</page>
Relevant snippet from app/code/Vendor/Module/view/frontend/templates/product/list.phtml
:
<?php foreach ($_productCollection as $_product) :?>
<li class="item product product-item">
<div class="product-item-info" data-container="product-<?= /* @noEscape */ $viewMode ?>">
<?php
$productImage = $block->getImage($_product, $imageDisplayArea);
if ($pos != null) {
$position = ' style="left:' . $productImage->getWidth() . 'px;'
. 'top:' . $productImage->getHeight() . 'px;"';
}
$productBadgeId = $_product->getData('product_badge');
?>
<?php if($productBadgeId): ?>
<img
src=<?= $block->getViewModel()->getBadgeImage($productBadgeId) ?>
class="product-item-badge"
alt=<?= $block->getViewModel()->getBadgeImageAlt($productBadgeId)?>
/>
<?php endif; ?>
<?php // Product Image ?>
My only additions: $productBadgeId
and the <?php if($productBadgeId)?>
if statement
app/code/Vendor/Module/ViewModel/ProductList.php
:
<?php
/**
* @package Vendor_Module
* @author Scott Anderson <scott.anderson@Vendor.com>
* @copyright Copyright (c) 2020 Vendor, Inc (http://Vendor.com)
* @license http://opensource.org/licenses/OSL-3.0 The Open Software License 3.0 (OSL-3.0)
*/
declare(strict_types=1);
namespace Vendor\Module\ViewModel;
use Exception;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\View\Element\Block\ArgumentInterface;
use Vendor\Module\Model\BadgeRepository;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Framework\UrlInterface;
use Vendor\Module\Model\ResourceModel\Badge;
/**
* Class ProductList
* @package Vendor\Module\ViewModel
*/
class ProductList implements ArgumentInterface
{
/**
* @var BadgeRepository
*/
protected $badgeRepository;
/**
* @var StoreManagerInterface
*/
protected $_storeManager;
/**
* @param BadgeRepository $badgeRepository
* @param StoreManagerInterface $storeManager
*/
public function __construct(
BadgeRepository $badgeRepository,
StoreManagerInterface $storeManager
)
{
$this->badgeRepository = $badgeRepository;
$this->_storeManager = $storeManager;
}
/**
* @param int|null $badgeId
*
* @return Badge|string|null
* @throws NoSuchEntityException
*/
public function getBadgeImage(int $badgeId = null)
{
if ($badgeId) {
$badge = $this->badgeRepository->get($badgeId);
if ($badge) {
$mediaUrl = $this->_storeManager->getStore()->getBaseUrl(UrlInterface::URL_TYPE_MEDIA);
return $mediaUrl . $badge->getImage();
}
}
return $badgeId;
}
/**
* @param int $badgeId
*
* @return mixed
* @throws Exception
*/
public function getBadgeImageAlt(int $badgeId)
{
$badge = $this->badgeRepository->get($badgeId);
return $badge->getName();
}
}
If anyone wants other files such as di.xml
please let me know - I am not sure what else could be relevant.
I was also making a cron job in a different module which may have caused inconsistencies in the db, but I don't really know how to check this. I wonder if my viewModel needs to extend something, but I can't see anything in module-catalog
app/code/Vendor/Module/view/frontend/templates/product/list.phtml
? Full code? – Amit Bera♦ Jan 11 at 11:44declare(strict_types=1);
at the top and apparently for template files this is a bad idea, and resulted in the errors shown. Anyways the full code of this file is otherwise copy-paste from module-catalog – Scott Anderson Jan 11 at 11:49