Question

I created a boolean option (Yes / No) in Store -> Configuration, with which I can display or not the checkout sidebar.

The configuration path is: vendorname_sidebar/display/enabled.

Below is a part about sidebar from the layout XML from checkout_index_index.xml of the Checkout module.

How do I show or not show the sidebar in checkout depending on this setting in Store -> Configuration?

<item name="sidebar" xsi:type="array">
    <item name="sortOrder" xsi:type="string">50</item>
    <item name="component" xsi:type="string">Magento_Checkout/js/view/sidebar</item>
    <item name="displayArea" xsi:type="string">sidebar</item>
    ...
</item>
Était-ce utile?

La solution

In the answers to this question "Remove a UI component child via Layout XML" you can see how you can disable the sidebar UI component by XML. Now you do not want to do this this way, because then it would always be removed/disabled.

If you look at the complete layout XML in checkout_index_index.xml, it looks something like this:

<page ........>
  <body>
    <referenceContainer name="content">
      <block class="Magento\Checkout\Block\Onepage" name="checkout.root" template="onepage.phtml" cacheable="false">
        <arguments>
          <argument name="jsLayout" xsi:type="array">
            <item name="types" xsi:type="array">........</item>
            <item name="components" xsi:type="array">
              <item name="checkout" xsi:type="array">
                <item name="component" xsi:type="string">uiComponent</item>
                ........
                <item name="children" xsi:type="array">
                  ........
                  <item name="sidebar" xsi:type="array">
                    <item name="sortOrder" xsi:type="string">50</item>
                    <item name="component" xsi:type="string">Magento_Checkout/js/view/sidebar</item>
                    <item name="displayArea" xsi:type="string">sidebar</item>
                    <item name="config" xsi:type="array">
                      ........
                    </item>
                    ........

You see that the whole <item ...> XML is part of a bigger <arguments> structure that is a child of the <block class="Magento\Checkout\Block\Onepage" ...> definition. This whole structure is converted to a PHP associative array and passed into the $data argument of the constructor when creating this block class.

The jsLayout is a UI Components definition and you could disable the sidebar component by setting componentDisabled to true in the config.

If we look at the Magento\Checkout\Block\Onepage constructor, we can see what happens to all this data. Also we see that there is an array argument layoutProcessors.

public function __construct(
    ........
    array $layoutProcessors = [],
    array $data = []
) {
    ........
    $this->jsLayout = isset($data['jsLayout']) && is_array($data['jsLayout']) ? $data['jsLayout'] : [];
    $this->layoutProcessors = $layoutProcessors;
}

Now the jsLayout is retreived from the Block by calling its getJsLayout() method which runs the layout processors first before returning the data as JSON:

public function getJsLayout()
{
    foreach ($this->layoutProcessors as $processor) {
        $this->jsLayout = $processor->process($this->jsLayout);
    }
    return \Zend_Json::encode($this->jsLayout);
}

So, you should also add a layout processor via Dependency Injection (DI) in your module's etc/frontend/di.xml:

<config ........>
    <type name="Magento\Checkout\Block\Onepage">
        <arguments>
            <argument name="layoutProcessors" xsi:type="array">
                <item name="sidebarSwitcher" xsi:type="object">Vendorname\Sidebar\Block\CheckoutOnepage\SidebarSwitcherProcessor</item>
            </argument>
        </arguments>
    </type>
</config>

This \Vendorname\Sidebar\Block\CheckoutOnepage\SidebarSwitcherProcessor class should implement \Magento\Checkout\Block\Checkout\LayoutProcessorInterface and (therefor) you should have a public method called process() where you can disable the sidebar based on the config you mention:

namespace Vendorname\Sidebar\Block\CheckoutOnepage;

use Magento\Checkout\Block\Checkout\LayoutProcessorInterface;

class SidebarSwitcherProcessor implements LayoutProcessorInterface
{
    public function process($jsLayout) {
        if (..... check config value .....) {
            $jsLayout['components']['checkout']['children']['sidebar']['config']['componentDisabled'] = true;
        }
        return $jsLayout;
    }
}

Autres conseils

For use Scope Config Interface on the component from checkout page, you must create a Plugin see below:

Below code is must in Vendorname/SidebarActivation/etc/frontend/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Checkout\Block\Checkout\LayoutProcessor">
        <plugin name="SidebarDisable" type="Vendorname\SidebarActivation\Plugin\SidebarDisable"/>
    </type>
</config>

Below code is in Vendorname/SidebarActivation/Plugin/SidebarDisable.php

<?php

namespace Vendorname\SidebarActivation\Plugin;

use Magento\Checkout\Block\Checkout\LayoutProcessor;

/**
 * Class SidebarDisable
 *
 * @package Vendorname\SidebarActivation\Plugin
 */
class SidebarDisable {

    /**
     * @param \Magento\Checkout\Block\Checkout\LayoutProcessor $processor
     * @param array $jsLayout
     *
     * @return array
     */
    public function afterProcess(
        LayoutProcessor $processor,
        array $jsLayout
    ){
        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $enable = $objectManager->get('Magento\Framework\App\Config\ScopeConfigInterface')->getValue('sectionid/groupid/fieldid');

        if($enable){
            $jsLayout['components']['checkout']['children']['sidebar']['config']['componentDisabled'] = true;
        }

        return $jsLayout;
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à magento.stackexchange
scroll top