1

I am trying to add custom-linked products such as cross-sell products in a programmatically way but my linked product not showing on the cart page any ideas? here is my code

app\code\Vendor\Module\Block\Cart

   <?php
    
    namespace Vendor\Module\Block\Cart;
    
    use Magento\CatalogInventory\Helper\Stock as StockHelper;
    
    class Crosssell extends \Magento\Checkout\Block\Cart\Crosssell
    {
        public function __construct(
            \Magento\Catalog\Block\Product\Context $context,
            \Magento\Checkout\Model\Session $checkoutSession,
            \Magento\Catalog\Model\Product\Visibility $productVisibility,
            \Magento\Catalog\Model\Product\LinkFactory $productLinkFactory,
            \Magento\Quote\Model\Quote\Item\RelatedProducts $itemRelationsList,
            \Magento\CatalogInventory\Helper\Stock $stockHelper,
            array $data = []
        ) {
            parent::__construct(
                $context,
                $checkoutSession,
                $productVisibility,
                $productLinkFactory,
                $itemRelationsList,
                $stockHelper,
                $data
            );
    
            $this->_maxItemCount = 2; // here you can set product display limit
        }
    }

app/code/Vendor/Module/view/frontend/layout/checkout_cart_index.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
    <referenceContainer name="content">
        <block class="Vendor\Module\Block\Cart\Crosssell" name="cross.custom.linked" after="-" template="Vendor_Module::product/list/items.phtml"/>
    </referenceContainer>
</body>
</page>

app/code/Vendor/Module/view/frontend/templates/product/list/items.phtml

<?php
$myBlock = \Magento\Framework\App\ObjectManager::getInstance()->get('Vendor\Module\Block\Cart\Crosssell');
$currentProduct = $myBlock->getCurrentProduct();

if ($currentProduct = $myBlock->getCurrentProduct()) {
    $crossSellProducts = $currentProduct->getCrossSellProducts();

    if (!empty($crossSellProduct)) {
        echo 'CrossSell Products <br />';
        foreach ($crossSellProducts as $crossSellProduct) {
            echo $crossSellProduct->getSku() . '<br />';
        }
    }

}

My Model Files are:

app/code/Vendor/Module/Model/Product/Link.php

<?php

namespace Vendor\Module\Model\Product;

class Link extends \Magento\Catalog\Model\Product\Link
{
    const LINK_TYPE_CUSTOMLINK = 7;
}

app/code/Vendor/Module/Model/ProductLink/CollectionProvider/CustomLinkProducts.php

<?php
namespace Vendor\Module\Model\ProductLink\CollectionProvider;

class CustomLinkProducts
{
    public function getLinkedProducts($product)
    {
        return $product->getCustomLinkProducts();
    }
}

app/code/Vendor/Module/Model/Product.php

<?php
namespace Vendor\Module\Model;

class Product extends \Magento\Catalog\Model\Product
{
    const LINK_TYPE = 'customlink';
    const LINK_TYPE_CUSTOMLINK = 7;

    /**
     * Retrieve array of customlink products
     *
     * @return array
     */
    public function getCustomLinkProducts()
    {
        if (!$this->hasCustomLinkProducts()) {
            $products = [];
            $collection = $this->getCustomLinkProductCollection();
            foreach ($collection as $product) {
                $products[] = $product;
            }
            $this->setCustomLinkProducts($products);
        }
        return $this->getData('custom_link_products');
    }

    /**
     * Retrieve customlink products identifiers
     *
     * @return array
     */
    public function getCustomLinkProductIds()
    {
        if (!$this->hasCustomLinkProductIds()) {
            $ids = [];
            foreach ($this->getCustomLinkProducts() as $product) {
                $ids[] = $product->getId();
            }
            $this->setCustomLinkProductIds($ids);
        }
        return [$this->getData('custom_link_product_ids')];
    }

    /**
     * Retrieve collection customlink product
     *
     * @return \Magento\Catalog\Model\ResourceModel\Product\Link\Product\Collection
     */
    public function getCustomLinkProductCollection()
    {
        $collection = $this->getLinkInstance()->setLinkTypeId(
            static::LINK_TYPE_CUSTOMLINK
        )->getProductCollection()->setIsStrongMode();
        $collection->setProduct($this);

        return $collection;
    }
}

1 Answer 1

1

For displaying the custom linked product add following function in block file as well as in phtml file

app\code\Vendor\Module\Block\Cart

<?php

namespace Vendor\Module\Block\Cart;

use Magento\Catalog\Block\Product\Context;
use Magento\Catalog\Model\Product\LinkFactory;
use Magento\Catalog\Model\Product\Visibility;
use Magento\CatalogInventory\Helper\Stock as StockHelper;
use Magento\Checkout\Model\Session;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\UrlInterface;
use Magento\Quote\Model\Quote\Item\RelatedProducts;
use Magento\Framework\App\ResourceConnection;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Catalog\Model\Product;

class Crosssell extends \Magento\Checkout\Block\Cart\Crosssell
{
    /**
     * @var ResourceConnection
     */
    protected ResourceConnection  $resource;
    /**
     * @var StoreManagerInterface
     */
    protected StoreManagerInterface $storeManager;
    /**
     * @var Product
     */
    protected Product $product;

    /**
     * @param Context $context
     * @param Session $checkoutSession
     * @param Visibility $productVisibility
     * @param LinkFactory $productLinkFactory
     * @param RelatedProducts $itemRelationsList
     * @param StockHelper $stockHelper
     * @param ResourceConnection $resource
     * @param StoreManagerInterface $storeManager
     * @param Product $product
     * @param array $data
     */
    public function __construct(
        Context $context,
        Session $checkoutSession,
        Visibility $productVisibility,
        LinkFactory $productLinkFactory,
        RelatedProducts $itemRelationsList,
        StockHelper $stockHelper,
        ResourceConnection $resource,
        StoreManagerInterface $storeManager,
        Product $product,
        array $data = []
    ) {
        parent::__construct(
            $context,
            $checkoutSession,
            $productVisibility,
            $productLinkFactory,
            $itemRelationsList,
            $stockHelper,
            $data
        );
        $this->resource = $resource;
        $this->storeManager = $storeManager;
        $this->product = $product;
    }

    /**
     * @return array
     * @throws LocalizedException
     * @throws NoSuchEntityException
     */
    public function getLinkedProducts()
    {
        $productIds = [];
        $productItems = $this->_checkoutSession->getQuote()->getAllItems();
        foreach ($productItems as $item) {
            $product_id = $item->getProductId();
            $connection= $this->resource->getConnection();
            $tableName = $this->resource->getTableName('catalog_product_link'); //gives table name with prefix
            //Select Data from table
            $sql = "Select * FROM " . $tableName . " where product_id='$product_id' and link_type_id =7";
            $result = $connection->fetchAll($sql);
            foreach ($result as $id) {
                $productIds[] = $id['linked_product_id'];
            }
        }
        return $productIds;
    }

    /**
     * @return string
     * @throws NoSuchEntityException
     */
    public function getMediaUrl()
    {
        return $this->storeManager->getStore()->getBaseUrl(UrlInterface::URL_TYPE_MEDIA);
    }

    /**
     * @param $productId
     * @return Product
     */
    public function getProductCollection($productId)
    {
        return $this->product->load($productId);
    }

}

and in phtml file

app/code/Vendor/Module/view/frontend/templates/product/list/items.phtml

<?php
/* @var $block Crosssell */

use Vendor\Module\Block\Cart\Crosssell;

$type = $block->getLinkedProducts();
$productItems = []; ?>
<ul class="item product product-item" style="list-style: none;">
    <?php foreach ($type as $productId) {
        $products = $block->getProductCollection($productId);
        ?>
        <li class="product-item-info ">
            <!-- cart_cross_sell_products-->
            <a href="<?= $products->getProductUrl() ?>" class="product photo product-item-photo"> <span
                    class="product-image-container product-image-container-2" style="width: 240px;">
    <span class="product-image-wrapper" style="padding-bottom: 125%;">
        <img class="product-image-photo"
             src="<?= $block->getMediaUrl() . '/catalog/product/' . ($products->getImage()) ?>" loading="lazy"
             width="240" height="300" alt="Image"></span> </span>
            </a>
            <div class="product details product-item-details">
                <strong class="product name product-item-name">
                    <a class="product-item-link" title="<?= $products->getName() ?>"
                       href="<?= $products->getProductUrl() ?>">
                        <?= $products->getName() ?></a>
                </strong>
                <div class="price-box price-final_price" data-role="priceBox" data-product-id="2"
                     data-price-box="product-id-2"> <span class="price-container price-final_price tax weee">
        <span id="product-price-2" data-price-amount="34" data-price-type="finalPrice" class="price-wrapper "><span
                class="price">$<strong><?= $products->getPrice() ?></strong></span></span>
            </span>
                </div>
                <div class="product-reviews-summary short">
                    <div class="rating-summary"><span class="label"><span>Rating:</span></span>
                        <div class="rating-result" id="rating-result_2" title="50%"><span
                                style="width: 50%;"><span>50%</span></span>
                        </div>
                        <script type="text/javascript">
                            var elemWLGBjucX = document.querySelector('#rating-result_2 span');
                            if (elemWLGBjucX) {
                                elemWLGBjucX.style.width = '50%';
                            }
                        </script>
                    </div>
                    <div class="reviews-actions">
                        <a class="action view"
                           href="<?= $products->getProductUrl() ?>#reviews">2&nbsp;<span>Reviews</span>
                        </a>
                    </div>
                </div>
                <div class="product actions product-item-actions">
                    <div class="actions-primary">
                        <?php $block2 = $this->getLayout()->createBlock('\Magento\Catalog\Block\Product\AbstractProduct'); ?>
                        <form data-role="tocart-form" data-product-sku="<?php $products->getSku() ?>"
                              action="<?= $block2->escapeUrl($block2->getAddToCartUrl($products)) ?>" method="post">
                            <input type="hidden" name="product" value="2">
                            <input type="hidden" name="uenc"
                                   value="aHR0cDovL2xvY2FsaG9zdC9tYWdlbnRvL3B1Yi9jaGVja291dC9jYXJ0Lw,,">
                            <input name="form_key" type="hidden" value="tQ0A8iUaNhW2Nhjh">
                            <button type="submit" title="Add to Cart" class="action tocart primary">
                                <span>Add to Cart</span></button>
                        </form>
                    </div>
                    <div class="secondary-addto-links actions-secondary" data-role="add-to-links">
                        <a href="#" class="action towishlist" title="Add to Wish List" aria-label="Add to Wish List"
                           data-post="{&quot;action&quot;:&quot;http:\/\/localhost\/magento\/pub\/wishlist\/index\/add\/&quot;,&quot;data&quot;:{&quot;product&quot;:2,&quot;uenc&quot;:&quot;aHR0cDovL2xvY2FsaG9zdC9tYWdlbnRvL3B1Yi9jaGVja291dC9jYXJ0Lw,,&quot;}}"
                           data-action="add-to-wishlist" role="button"> <span>Add to Wish List</span> </a>
                        <a href="#" class="action tocompare" title="Add to Compare" aria-label="Add to Compare"
                           data-post="{&quot;action&quot;:&quot;http:\/\/localhost\/magento\/pub\/catalog\/product_compare\/add\/&quot;,&quot;data&quot;:{&quot;product&quot;:&quot;2&quot;,&quot;uenc&quot;:&quot;aHR0cDovL2xvY2FsaG9zdC9tYWdlbnRvL3B1Yi9jaGVja291dC9jYXJ0Lw,,&quot;}}"
                           role="button"> <span>Add to Compare</span> </a>
                    </div>
                </div>
            </div>
        </li>

    <?php } ?>
</ul>
<style>
    li.product-item-info {
        float: left;
        margin: 20px;
        padding: 20px;
        width: 200px;
    }

    .column.main .product-item {
        display: flex;
        flex-wrap: wrap;
    }

    li.product-item-info:hover {
        background: #fff;
        box-shadow: 3px 4px 4px 0 rgb(0 0 0 / 30%);
        border: 1px solid #bbb;
    }
</style>
1
  • 1
    You should avoid plain SQL at all cost. You will be skipping validations, security features, some caching (potentially) and introduce some issues into your application... Use collections, repository classes or service contracts instead. Feb 23, 2023 at 13:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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