Skip to main content
edited body
Source Link
D.D.
  • 15
  • 5
Error: Call to a member function getAlternativeImages() on null in /var/www/html/app/design/frontend/MagenioVendor/aldotheme/Magento_Catalog/templates/product/list/item.phtml:58
Error: Call to a member function getAlternativeImages() on null in /var/www/html/app/design/frontend/Magenio/aldo/Magento_Catalog/templates/product/list/item.phtml:58
Error: Call to a member function getAlternativeImages() on null in /var/www/html/app/design/frontend/Vendor/theme/Magento_Catalog/templates/product/list/item.phtml:58
added 2 characters in body
Source Link
D.D.
  • 15
  • 5

So I'm trying to add some related products and up-sell products from admin, but as soon as I add one the page isgets broken.

So I'm trying to add some related products and up-sell products from admin, but as soon as I add one the page is broken.

So I'm trying to add some related products and up-sell products from admin, but as soon as I add one the page gets broken.

Source Link
D.D.
  • 15
  • 5

Magento2, why adding Related Products or Up-sell products breaks the page?

So I'm trying to add some related products and up-sell products from admin, but as soon as I add one the page is broken.

In the page I see a full html template with some scripts and this error in the end:

Error: Call to a member function getAlternativeImages() on null in /var/www/html/app/design/frontend/Magenio/aldo/Magento_Catalog/templates/product/list/item.phtml:58

So my item.phtml is this:

<?php
/**
 * Hyvä Themes - https://hyva.io
 * Copyright © Hyvä Themes 2020-present. All rights reserved.
 * This product is licensed per Magento install
 * See https://hyva.io/license
 */

declare(strict_types=1);

use Hyva\Theme\Model\ViewModelRegistry;
use Hyva\Theme\ViewModel\HeroiconsOutline;
use Hyva\Theme\ViewModel\HeroiconsSolid;
use Hyva\Theme\ViewModel\ProductCompare;
use Hyva\Theme\ViewModel\ProductListItem;
use Hyva\Theme\ViewModel\ProductPage;
use Hyva\Theme\ViewModel\Wishlist;
use Magento\Catalog\Block\Product\AbstractProduct;
use Magento\Catalog\Helper\Output as CatalogOutputHelper;
use Magento\Framework\Escaper;

// phpcs:disable Magento2.Templates.ThisInTemplate
// phpcs:disable Generic.Files.LineLength.TooLong

/** @var AbstractProduct $block */
/** @var Escaper $escaper */
/** @var ViewModelRegistry $viewModels */

/** @var ProductPage $productViewModel */
$productViewModel = $viewModels->require(ProductPage::class);

/** @var ProductListItem $productListItemViewModel */
$productListItemViewModel = $viewModels->require(ProductListItem::class);

/** @var CatalogOutputHelper $catalogOutputHelper */
$catalogOutputHelper = $this->helper(CatalogOutputHelper::class);

/** @var ProductCompare $compareViewModel */
$compareViewModel = $viewModels->require(ProductCompare::class);
/** @var Wishlist $wishlistViewModel */
$wishlistViewModel = $viewModels->require(Wishlist::class);

/** @var HeroiconsOutline $heroiconsOutline */
$heroiconsOutline = $viewModels->require(HeroiconsOutline::class);
/** @var HeroiconsSolid $heroiconsSolid */
$heroiconsSolid = $viewModels->require(HeroiconsSolid::class);

/** @var Magento\Catalog\Model\Product $product */
$product = $block->getData('product');
$imageDisplayArea = $block->getData('image_display_area');
$templateType = $block->getData('template_type');
$viewMode = $block->getData('view_mode');
$showDescription = $block->getData('show_description');
$showAddToWishlist = $wishlistViewModel->isEnabled();
$showAddToCompare = $compareViewModel->showInProductList();
$viewIsGrid = $viewMode === 'grid';
$_backImageHelper = $block->getData('image_alternative_product_list');
if($_backImageHelper->getAlternativeImages($product)) {
    $productAlternativeImages = $_backImageHelper->getAlternativeImages($product);
} else {
    $productAlternativeImages = [];
}

if (!$product) {
    return '';
}
$productId = $product->getId();
$uniqueId = '_' . uniqid();

?>

<?php if ($product->isSaleable()): ?>
<form method="post"
    action="<?= $escaper->escapeUrl($productViewModel->getAddToCartUrl($product)) ?>"
    class="item product product-item product_addtocart_form flex  flex-col mb-10 lg:mb-24 relative <?= $viewIsGrid ? '' : '' ?>"
      x-data="{ active: 0 }"
    <?php if ($product->getOptions()): ?>
    enctype="multipart/form-data"
    <?php endif; ?>
>
    <?= /** @noEscape */ $block->getBlockHtml('formkey') ?>
    <input type="hidden" name="product" value="<?= (int)$productId ?>"/>
<?php else: ?>
<div class="item product product-item flex flex-col  relative <?= $viewIsGrid ? '' : '' ?>">
<?php endif; ?>
    <?php
    $productImage = $block->getImage($product, $imageDisplayArea);
    ?>
    <?php // Product Image ?>
    <div class="flex items-center gap-1 z-40">
        <span class="cursor-pointer h-1.5 w-1/3"
              @click.prevent="active = 0"
              :class="{'bg-secondary' : active === 0, 'bg-container-darker' : active !== 0}">
        </span>
        <?php foreach($productAlternativeImages as $key => $alternativeImg): ?>
            <span :class="{'bg-secondary' : active === <?= $key+1 ?>, 'bg-container-darker' : active !== <?= $key+1 ?>}"
                  class="cursor-pointer bg-primary h-1.5 w-1/3"
                  @click.prevent="active = <?= $key+1 ?>"></span>
        <?php endforeach; ?>
    </div>

    <button class="transform rotate-180 w-10 h-10 absolute right-3 top-3 z-40"
            @click.prevent="active >= 0 && active < <?= count($productAlternativeImages) ?> ? active = active+1 : active = 0" >
        <svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
            <path d="M16 8.94434L2 8.94433" stroke="black" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
            <path d="M9 15.8887L2 8.94433L9 2" stroke="black" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
        </svg>
    </button>


    <a href="<?= $escaper->escapeUrl($product->getProductUrl()) ?>"

        class="product pt-full relative photo product-item-photo block mb-3 <?= $viewIsGrid ? '' : 'md:mb-0' ?>"
        tabindex="-1">

        <img class="hover:shadow-sm object-contain"
             x-show="active === 0"
             loading="lazy"
             @update-gallery-<?= (int)$productId ?>.window="$el.src = event.detail"
             alt="<?= $escaper->escapeHtmlAttr($productImage->getLabel()) ?>"
             title="<?= $escaper->escapeHtmlAttr($productImage->getLabel()) ?>"
             src="<?= $escaper->escapeUrl($productImage->getImageUrl()) ?>"
             width="100%"
             height="<?= $escaper->escapeHtmlAttr($productImage->getHeight()) ?>"
        />

        <?php foreach($productAlternativeImages as $key => $alternativeImg): ?>
            <img class="hover:shadow-sm object-contain aspect-square"
                 x-show = "active === <?= $key+1 ?> "
                 src="<?= $alternativeImg->getData('image_url') ?>"
                 width="<?= $escaper->escapeHtmlAttr($productImage->getWidth()) ?>"
                 height="<?= $escaper->escapeHtmlAttr($productImage->getHeight()) ?>"
                 alt="<?= $escaper->escapeHtmlAttr($productImage->getLabel()) ?>"
            />
        <?php endforeach; ?>
    </a>
    <div class="product-info flex flex-col flex-grow">
        <?php $productNameStripped = $block->stripTags($product->getName(), null, true); ?>
        <div class="mt-2 items-center justify-center text-primary text-lg lg:text-3xl  <?= $viewIsGrid ? '' : 'md:text-left' ?>">
            <a class="product-item-link"
               href="<?= $escaper->escapeUrl($product->getProductUrl()) ?>">
                <?= /* @noEscape */
                $catalogOutputHelper->productAttribute($product, $product->getName(), 'name') ?>
            </a>
        </div>

        <div class="py-1 mx-auto hidden w-6/12 <?= $viewIsGrid ? '' : 'md:mx-0 md:w-auto' ?>">
            <?= $block->getReviewsSummaryHtml($product, 'short') ?>
        </div>

        <?php if ($product->isAvailable()):?>
            <?= $block->getProductDetailsHtml($product) ?>
        <?php endif; ?>

        <script>
            function initPriceBox_<?= /** @noEscape */ $uniqueId ?>()
            {
                return {
                    updatePrice(priceData) {
                        const regularPriceLabel = this.$el.querySelector('.normal-price .price-label');
                        const regularPriceElement = this.$el.querySelector('.normal-price .price-wrapper .price');
                        if (priceData.finalPrice.amount < priceData.oldPrice.amount) {
                            regularPriceLabel.classList.add('hidden');
                        } else {
                            regularPriceLabel.classList.remove('hidden');
                        }
                        regularPriceElement.innerText = hyva.formatPrice(priceData.finalPrice.amount);
                    }
                }
            }
        </script>
        <div class="lg:pt-1 text-xs lg:text-2xl"
             x-data="initPriceBox_<?= /** @noEscape */ $uniqueId ?>()"
             @update-prices-<?= (int)$productId ?>.window="updatePrice(event.detail);"
        >
            <?= /* @noEscape */ $productListItemViewModel->getProductPriceHtml($product) ?>
        </div>

        <div class=" mt-auto pt-3 flex flex-wrap justify-center items-center">
            <?php if ($product->isSaleable()): ?>
            <button class="hidden w-auto btn btn-primary justify-center text-sm mr-auto
                        <?= $viewIsGrid ? 'mr-auto' : 'mr-auto md:mr-0' ?>"
                    aria-label="<?= $escaper->escapeHtmlAttr(__('Add to Cart')) ?>"
            >
                <?= $heroiconsOutline->shoppingCartHtml("h-6 w-6 border-current inline", 25, 25) ?>
                <span class="ml-2 inline <?= $viewIsGrid ? 'md:ml-0 md:hidden lg:ml-2 lg:inline' : '' ?>">
                    <?= $escaper->escapeHtml(__('Add to Cart')) ?>
                </span>
            </button>
            <?php endif; ?>
            <?php if ($showAddToWishlist): ?>
            <script>
                function initWishlist() {
                    return {
                        addToWishlist(productId) {
                            var formKey = document.querySelector('input[name=form_key]').value;
                            var postUrl = BASE_URL+"wishlist/index/add/";
                            fetch(postUrl, {
                                "headers": {
                                    "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
                                },
                                "body": "form_key="+ formKey + "&product="+productId+"&uenc="+btoa(window.location.href),
                                "method": "POST",
                                "mode": "cors",
                                "credentials": "include"
                            }).then(function (response) {
                                if (response.redirected) {
                                    window.location.href = response.url;
                                } else if (response.ok) {
                                    return response.json();
                                } else {
                                    typeof window.dispatchMessages !== "undefined" && window.dispatchMessages(
                                        [{
                                            type: "warning",
                                            text: "<?= $escaper->escapeHtml(__('Could not add item to wishlist.')) ?>"
                                        }], 5000
                                    );
                                }
                            }).then(function (response) {
                                if(!response) { return }
                                typeof window.dispatchMessages !== "undefined" && window.dispatchMessages(
                                    [{
                                        type: (response.success) ? "success" : "error",
                                        text: (response.success)
                                            ? "<?= $escaper->escapeHtml(__("%1 has been added to your Wish List.", __("Product"))) ?>"
                                            : response.error_message
                                    }], 5000
                                );
                                var reloadCustomerDataEvent = new CustomEvent("reload-customer-section-data");
                                window.dispatchEvent(reloadCustomerDataEvent);
                            }).catch(function (error) {
                                typeof window.dispatchMessages !== "undefined" && window.dispatchMessages(
                                    [{
                                        type: "error",
                                        text: error
                                    }], 5000
                                );
                            });
                        }
                    }
                }
            </script>
            <button x-data="initWishlist()"
                    @click.prevent="addToWishlist(<?= (int)$productId ?>)"
                    aria-label="<?= $escaper->escapeHtmlAttr(__('Add to Wish List')) ?>"
                    type="button"
                    class="absolute left-3 top-3 z-20 w-9 h-9 p-0 border-0 inline-flex flex-shrink-0 items-center justify-center text-grayLight hover:text-red-600">
                <svg class="w-5 h-5 lg:w-7 lg:h-7" width="29" height="26" viewBox="0 0 29 26" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
                    <path d="M21.4955 0C15.8084 0 14.4976 5.56033 14.4976 5.56033C14.4976 5.56033 13.185 0 7.49795 0C1.81086 0 -1.34769 6.06631 0.554216 10.7863C2.45612 15.5064 6.59019 23.0075 14.501 26C22.4117 23.0075 26.5543 15.5046 28.4494 10.7863C30.3445 6.06811 27.1826 0 21.4955 0Z"
                          fill=""/>
                </svg>

            </button>
            <?php endif; ?>
            <?php if ($showAddToCompare): ?>
            <script>
            function initCompare() {
                return {
                    addToCompare(productId) {
                        const formKey = document.querySelector('input[name=form_key]').value;
                        const postUrl = BASE_URL + 'catalog/product_compare/add/';

                        fetch(postUrl, {
                            "headers": {
                                "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
                            },
                            "body": "form_key="+ formKey + "&product="+productId+"&uenc="+btoa(window.location.href),
                            "method": "POST",
                            "mode": "cors",
                            "credentials": "include"
                        }).then(function (response) {
                            if (response.redirected) {
                                window.location.href = response.url;
                            }
                        }).catch(function (error) {
                            typeof window.dispatchMessages !== "undefined" && window.dispatchMessages(
                                [{
                                    type: "error",
                                    text: error
                                }], 5000
                            );
                        });
                    }
                };
            }
            </script>
            <button x-data="initCompare()"
                    @click.prevent="addToCompare(<?= (int)$productId ?>)"
                    aria-label="<?= $escaper->escapeHtmlAttr(__('Add to Compare')) ?>"
                    type="button"
                    class="rounded-full w-9 h-9 bg-gray-200 p-0 border-0 inline-flex flex-shrink-0 items-center justify-center text-gray-500 hover:text-yellow-500 ml-2">
                <?= $heroiconsOutline->scaleHtml("w-5 h-5", 25, 25) ?>
            </button>
            <?php endif; ?>
        </div>
    </div>
<?php if ($product->isSaleable()): ?>
</form>
<?php else: ?>
</div>
<?php endif; ?>

and that function getAlternativeImages(), in item.phtml is used here:

if($_backImageHelper->getAlternativeImages($product)) {
    $productAlternativeImages = $_backImageHelper->getAlternativeImages($product);
} else {
    $productAlternativeImages = [];
}

I'm not understanding why this is happening, it seems that $product is null, but still I can see the product page correctly except for when adding related products or up-sell ones.

If you guys could help it would be awesome, save my day for sure.