0

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

3
  • Please provide the code of app/code/Vendor/Module/view/frontend/templates/product/list.phtml ? Full code? – Amit Bera Jan 11 at 11:44
  • @AmitBera I solved this, so not necessary - I added declare(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
  • 1
    Please post the answer at here. It will help pther people – Amit Bera Jan 11 at 11:50
0

This string of errors were caused by a simple mistake, when pushing to code review I added declare(strict_types=1) at the top of my app/code/Vendor/Module/view/frontend/templates/product/list.phtml file.

This is not necessary in M2 template files as far as I am aware (although for PSR compliance it is advised to use it at the top of your PHP class files [below the docblock]). A summary of the amendment:

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
/**
 * @package      Vendor_Module
 * @author       Some Guy <some.guy@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); \\ remove this!

use Magento\Framework\App\Action\Action;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.