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.
1 Answer
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