0

I created a new shippping method, I need to generate data and pass it to the window.checkoutConfig javascript object.

Normally you do this by implementing the ConfigProviderInterface from vendor/magento/module-checkout/Model/ConfigProviderInterface.php, but this only works if the data already exist and you just have to write it into the $config.

I need to generate the data during runtime while I am generating the shipping method. The data is simply a HTML code.

How can I write the data into the config, so that it is available under window.checkoutConfig.express_note?

Shipping Method:

MODULE/Model/Carrier/Express.php

<?php
/**
 * Copyright ©  All rights reserved.
 * See COPYING.txt for license details.
 */
declare(strict_types=1);

namespace Company\Shipping\Model\Carrier;

use Magento\Quote\Model\Quote\Address\RateRequest;
use Magento\Shipping\Model\Rate\Result;

class Express extends \Magento\Shipping\Model\Carrier\AbstractCarrier implements
    \Magento\Shipping\Model\Carrier\CarrierInterface
{

    protected $_code = 'express';

    protected $_isFixed = true;

    protected $_rateResultFactory;

    protected $_rateMethodFactory;

    /**
     * Constructor
     *
     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
     * @param \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
     * @param \Psr\Log\LoggerInterface $logger
     * @param \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory
     * @param \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
     * @param array $data
     */
    public function __construct(
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
        \Psr\Log\LoggerInterface $logger,
        \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory,
        \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
        array $data = []
    ) {
        $this->_rateResultFactory = $rateResultFactory;
        $this->_rateMethodFactory = $rateMethodFactory;
        parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
    }

    /**
     * {@inheritdoc}
     */
    public function collectRates(RateRequest $request)
    {
        if (!$this->getConfigFlag('active')) {
            return false;
        }

        $note = "<div>dynamically generated html code</div>";    // How to make this data available under window.checkoutConfig.express_note ?

        $shippingPrice = $this->getConfigData('price');

        $result = $this->_rateResultFactory->create();

        if ($shippingPrice !== false) {
            $method = $this->_rateMethodFactory->create();

            $method->setCarrier($this->_code);
            $method->setCarrierTitle($this->getConfigData('title'));

            $method->setMethod($this->_code);
            $method->setMethodTitle($this->getConfigData('name'));

            if ($request->getFreeShipping() === true || $request->getPackageQty() == $this->getFreeBoxes()) {
                $shippingPrice = '0.00';
            }

            $method->setPrice($shippingPrice);
            $method->setCost($shippingPrice);

            $result->append($method);
        }

        return $result;
    }

    /**
     * getAllowedMethods
     *
     * @return array
     */
    public function getAllowedMethods()
    {
        return [$this->_code => $this->getConfigData('name')];
    }
}
0

Simply add it in script ?

$note = "<div>dynamically generated html code</div>"
$note.="<script>window.checkoutConfig.express_note = <?php YOUR_CONTENT_VALUE ?></script>";

So as when your note will be append to the html, the script will be sent too and the variable will be set.

4
  • But the method collectRates does not return $html so how should this work? – Black Oct 21 '20 at 14:59
  • 1
    Yeah you right. I guess this is for this kind of situation we need knockoutjs, but this is out of my skills sorry. A bad way of doing things would be to setup something like a cookie in your php method and then try to assign the checkoutConfig by reading these cookie. – Claims Oct 21 '20 at 15:18
  • No knockoutjs is just a template engine, it does not help me to add data from PHP to the window object. Using cookies would be a good workaround. Thanks for the idea :) – Black Oct 21 '20 at 15:20
  • 1
    When you are bad at the game you start searching for cheatcode :D Hope it will help. – Claims Oct 21 '20 at 15:31
0

I solved it by implementing the ConfigProviderInterface from vendor/magento/module-checkout/Model/ConfigProviderInterface.php and moving the generation code to my plugin.

Company/Shipping/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\Model\CompositeConfigProvider">
        <arguments>
            <argument name="configProviders" xsi:type="array">
                <item name="company_shipping_configprovider" xsi:type="object">Company\Shipping\Model\Config\Express</item>
            </argument>
        </arguments>
    </type>
</config>

Company/Shipping/Model/Config/Express.php

<?php

namespace Company\Shipping\Model\Config;

class Express implements \Magento\Checkout\Model\ConfigProviderInterface
{
    ...

    /**
     * @var array
     */
    protected $dynamicHtml;

    public function __construct(
        ...
    ) {
        ...
        $this->rule = $this->createDynamicHtml();
    }

    public function getConfig()
    {
        $config = [];
        $config['dynamicHtml'] = $this->dynamicHtml;
        return $config;
    }

    public function getDynamicHtml()
    {
        return $this->dynamicHtml;
    }

    public function createDynamicHtml()
    {
        ...
    }
    ...

Then in the carrier collectRates method I am fetching the value from the dynamic generated html.

Company/Shipping/Model/Carrier/Express.php

<?php
/**
 * Copyright ©  All rights reserved.
 * See COPYING.txt for license details.
 */
declare(strict_types=1);

namespace Company\Shipping\Model\Carrier;

use Magento\Quote\Model\Quote\Address\RateRequest;
use Magento\Shipping\Model\Rate\Result;

class Express extends \Magento\Shipping\Model\Carrier\AbstractCarrier implements
    \Magento\Shipping\Model\Carrier\CarrierInterface
{

    ...

    protected $_expressSettingsFactory;

    /**
     * Constructor
     *
     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
     * @param \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
     * @param \Psr\Log\LoggerInterface $logger
     * @param \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory
     * @param \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
     * @param array $data
     * @param \Company\Shipping\Model\Config\ExpressFactory $expressSettingsFactory
     */
    public function __construct(
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
        \Psr\Log\LoggerInterface $logger,
        \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory,
        \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
        array $data = [],
        \Company\Shipping\Model\Config\ExpressFactory $expressSettingsFactory
    ) {
        $this->_rateResultFactory = $rateResultFactory;
        $this->_rateMethodFactory = $rateMethodFactory;
        $this->_expressSettingsFactory = $expressSettingsFactory;
        parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
    }

    /**
     * {@inheritdoc}
     */
    public function collectRates(RateRequest $request)
    {
        if (!$this->getConfigFlag('active')) {
            return false;
        }

        /** @var \Company\Shipping\Model\Config\Express $expressSettings */
        $expressSettings = $this->_expressSettingsFactory->create();

        $note = $expressSettings->getDynamicHtml();

        ...

    }

    ...
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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