Show random/default cross-sell items in onepage checkout

All we need is an easy explanation of the problem, so here it is.

In Onepage Checkout screen, I want to show default/random cross-sell items if none of the cart items have defined cross-sell items. I mean Onepage checkout screen will always show cross-sell products. Is there any settings for that in Magento 2 or I need to implement it? Thanks in advance.

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

I found a solution. I’ve created one module and plugin.

I added a page in admin panel for setting default cross sell items. Then I wrote beforeLoad plugin for Magento\Catalog\Model\ResourceModel\Product\Collection class and appended the ids I’ve set to the cross sell items.

├── Helper
│   └── Data.php
├── Plugin
│   └── CollectionPlugin.php
├── etc
│   ├── adminhtml
│   │   └── system.xml
│   ├── config.xml
│   ├── di.xml
│   └── module.xml
└── registration.php

Helper/Data.php

<?php

namespace Vendor\UniversalCrossSell\Helper;

use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Store\Model\ScopeInterface;

class Data extends AbstractHelper
{

    const XML_PATH_CROSSSELL = 'universal_cross_sell/';

    public function getConfigValue($field, $storeId = null)
    {
        return $this->scopeConfig->getValue(
            $field, ScopeInterface::SCOPE_STORE, $storeId
        );
    }

    public function getGeneralConfig($code, $storeId = null)
    {

        return $this->getConfigValue(self::XML_PATH_CROSSSELL .'general/'. $code, $storeId);
    }

}

Plugin/CollectionPlugin.php

<?php
namespace Vendor\UniversalCrossSell\Plugin;

class CollectionPlugin
{
    protected $helperData;

    public function __construct(\Vendor\UniversalCrossSell\Helper\Data $helperData)
    {
        $this->helperData = $helperData;
    }


    /**
     * @param Collection $subject
     * @param bool $printQuery
     * @param bool $logQuery
     */
    public function beforeLoad(\Magento\Catalog\Model\ResourceModel\Product\Collection $productCollection, $printQuery = false, $logQuery = false)
    {
        if (!$productCollection->isLoaded()) {

            if (!$productCollection instanceof \Magento\Catalog\Model\ResourceModel\Product\Link\Product\Collection) {
                return;
            }

            if($productCollection->getLinkModel()->getLinkTypeId() != \Magento\Catalog\Model\Product\Link::LINK_TYPE_CROSSSELL) {
                return;
            }

            if(!$this->helperData->getGeneralConfig('enable')) {
                return;
            }

            $universal_cross_sell_ids = $this->helperData->getGeneralConfig('product_ids');
            if(!$universal_cross_sell_ids) {
                return;
            }

            $universal_cross_sell_ids = @array_filter(explode(',', str_replace(' ', '', $universal_cross_sell_ids)), 'is_numeric');
            if(!$universal_cross_sell_ids) {
                return;
            }

            $productCollection->getSelect()->orWhere('e.entity_id IN (?)', $universal_cross_sell_ids);   //$universal_cross_sell_ids
        }

        return [$printQuery, $logQuery];
    }
}

etc/adminhtml/system.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
    <system>
        <tab id="cross_sell_conf" translate="label" sortOrder="10">
            <label>Cross Sell Configuration</label>
        </tab>
        <section id="universal_cross_sell" translate="label" sortOrder="130" showInDefault="1" showInWebsite="1" showInStore="1">
            <class>separator-top</class>
            <label>Universal Cross Sell</label>
            <tab>cross_sell_conf</tab>
            <resource>Vendor_UniversalCrossSell::universal_cross_sell_config</resource>
            <group id="general" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="0" showInStore="0">
                <label>General Configuration</label>
                <field id="enable" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0">
                    <label>Module Enable</label>
                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
                </field>
                <field id="product_ids" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0">
                    <label>Product IDS</label>
                    <comment>These products will display in cross sell. for example: 12345, 6789</comment>
                </field>
            </group>
        </section>
    </system>
</config>

etc/config.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
    <default>
        <universal_cross_sell>
            <general>
                <enable>1</enable>
                <product_ids>25723, 25909, 23976, 25908, 24629, 25616</product_ids>
            </general>
        </universal_cross_sell>
    </default>
</config>

etc/config.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\TargetRule\Block\Checkout\Cart\Crosssell" type="Vendor\UniversalCrossSell\Block\Checkout\Cart\Crosssell" />

    <type name="Magento\Catalog\Model\ResourceModel\Product\Collection">
        <plugin name="beforeproductCollectionPlugin" type="Vendor\UniversalCrossSell\Plugin\CollectionPlugin" />
    </type>
</config>

etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_UniversalCrossSell" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Catalog" />
        </sequence>
    </module>
</config>

registration.php

<?php

use \Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(
    ComponentRegistrar::MODULE,
    'Vendor_UniversalCrossSell',
    __DIR__
);

After doing them, I have set default items to the admin panel.

Store->Configuration->Cross Sell Configuration->Universal Cross Sell

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply