0

I am trying to preselect the shipping country based on the user's country code.

I have the code already needed to get the country code which is in my model.

I have tried using the code in accepted answer to this question. It uses an after plugin but I can't get it to work. It still defaults to United States even though I 'm telling it to use use GB.

I have tried logging out in the plugin but get nothing in the logs so I don't think the plugin is getting called.

Here is the code:

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\Cart\LayoutProcessor">
        <plugin name="asg_country_list"
                type="Asg\GeoIp\Plugin\Checkout\Block\Cart\LayoutProcessor" sortOrder="1"/>
    </type>
</config>

LayoutProcessor.php

<?php

namespace Asg\GeoIp\Plugin\Checkout\Block\Cart;

class LayoutProcessor
{
    public function beforeProcess(
        \Magento\Checkout\Block\Cart\LayoutProcessor $subject,
        $jsLayout
    ) {
        $path = '/var/www/magento.local/var/log/test.log';

        file_put_contents($path, 'this is a test');
    }

    public function afterProcess(
        \Magento\Checkout\Block\Cart\LayoutProcessor $subject,
        $jsLayout
    ) {
        $selectedCountry = 'GB';

        $this->_logger->info($selectedCountry);

        if (isset($jsLayout['components']['checkoutProvider']['dictionaries'])) {

            foreach ($jsLayout['components']['checkoutProvider']['dictionaries']['country_id'] as &$country) {
                if ($country['value'] == $selectedCountry) {
                    $country['is_default'] = 1;
                } else {
                    if (isset($country['is_default'])) {
                        unset($country['is_default']);
                    }
                }
            }
        }
        if (isset($jsLayout['components']['block-summary']['children']['block-shipping']['children']['address-fieldsets'])) {
            $jsLayout['components']['block-summary']['children']['block-shipping']['children']['address-fieldsets']['children']['country_id']['value'] = $selectedCountry;
        }

        return $jsLayout;
    }
}

I'm using Magento 2.3.4. Could the plugin be calling the wrong module since the original question was Magento 2.2?

1 Answer 1

0

tried the plugin code that you have and confirmed that it works with 2.3.x. Both beforeProcess and afterProcess methods have been called.

check your logs (debug.log, exception.log and system.log)...if its a development environment, then enable the developer mode, which explicitly displays an error , if an error has been thrown.

In your Plugin Class Asg\GeoIp\Plugin\Checkout\Block\Cart\LayoutProcessor i can see inside the afterProcess method you have used _logger variable which calls the logging method info, whereas i dont see a constructor where the \Psr\Log\LoggerInterface is injected and initialized.

$this->_logger->info($selectedCountry);

try this plugin class

<?php

namespace Asg\GeoIp\Plugin\Checkout\Block\Cart;

class LayoutProcessor
{
    /**
     * @var \Psr\Log\LoggerInterface
     */
    protected $logger;

    /**
     *
     */
    public function __construct(
        \Psr\Log\LoggerInterface $logger
    ) {
        $this->logger = $logger ?:
            \Magento\Framework\App\ObjectManager::getInstance()
                ->get('\Psr\Log\LoggerInterface');
    }

    /**
     * Process js Layout of block
     *
     * @param \Magento\Checkout\Block\Cart\LayoutProcessor $layoutProcessor
     * @param array $jsLayout
     * @return void | null
     *
     */
    public function beforeProcess(\Magento\Checkout\Block\Cart\LayoutProcessor $layoutProcessor, $jsLayout)
    {
        
        $path = '/var/www/magento.local/var/log/test.log';
        file_put_contents($path,'this is a test');
//        return null;
    }
    
    public function afterProcess(
        \Magento\Checkout\Block\Cart\LayoutProcessor $subject,
        $jsLayout
    ) {
        $selectedCountry = 'GB';

        $this->logger->info('$selectedCountry : '.$selectedCountry);

        if (isset($jsLayout['components']['checkoutProvider']['dictionaries'])) {

            foreach ($jsLayout['components']['checkoutProvider']['dictionaries']['country_id'] as &$country) {
                if ($country['value'] == $selectedCountry) {
                    $country['is_default'] = 1;
                } else {
                    if (isset($country['is_default'])) {
                        unset($country['is_default']);
                    }
                }
            }
        }
        if (isset($jsLayout['components']['block-summary']['children']['block-shipping']['children']['address-fieldsets'])) {
            $jsLayout['components']['block-summary']['children']['block-shipping']['children']['address-fieldsets']['children']['country_id']['value'] = $selectedCountry;
        }

        return $jsLayout;
    }
    
}
1
  • Thanks @Haijerome. I could see the log file being written to on a live dev server but that server it really slow and I can't view the checkout page properly (nothing to do with code, just rendering too slow). I also tried it on a local server (vagrant) but the log is not written to. I know that the plugin is now getting called but can you confirm that the shipping option is getting set? I still can't get that to default to the option set in the plugin
    – AdRock
    Commented Feb 24, 2021 at 14:28

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.