Skip to content

Updating product page output based on selected Variation

Unfortunately my mixin is not working. I guess it’s not loaded by Magento Version 2.4.6. It worked until Magento 2.3.x. Any ideas?

Vendor/Module/registration.php

<?php

MagentoFrameworkComponentComponentRegistrar::register(
    MagentoFrameworkComponentComponentRegistrar::MODULE,
    'Vendor_Module',
    __DIR__
);

Vendor/Module/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_Module" setup_version="1.0.0">
        <sequence>
            <module name="Magento_ConfigurableProduct"/>
            <module name="Magento_Swatches"/>
            <module name="Vendor_AttributesDataOutput"/>
        </sequence>
    </module>
</config>

Vendor/Module/etc/frontend/di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="MagentoConfigurableProductBlockProductViewTypeConfigurable">
        <plugin disabled="false" name="Vendor_Module_Plugin_Magento_ConfigurableProduct_Block_Product_View_Type_Configurable" sortOrder="10" type="VendorModulePluginMagentoConfigurableProductBlockProductViewTypeConfigurable"/>
    </type>
    <type name="MagentoSwatchesBlockProductRendererConfigurable">
        <plugin disabled="false" name="Vendor_Module_Plugin_Magento_Swatches_Block_Product_Renderer_Configurable" sortOrder="10" type="VendorModulePluginMagentoSwatchesBlockProductRendererConfigurable"/>
    </type>
</config>

Vendor/Module/Plugin/Magento/ConfigurableProduct/Block/Product/View/Type/Configurable.php

<?php
 
namespace VendorModulePluginMagentoConfigurableProductBlockProductViewType;

class Configurable
{

    protected $dataAttributes;
    protected $productFactory;
    protected $logger;

    public function __construct(VendorAttributesDataOutputBlockVendorDataAttributes $dataAttributes, MagentoCatalogModelProductFactory $productFactory, PsrLogLoggerInterface $logger)
    {
        $this->dataAttributes = $dataAttributes;
        $this->productFactory = $productFactory;
        $this->logger = $logger;
    }
    public function afterGetJsonConfig(MagentoConfigurableProductBlockProductViewTypeConfigurable $subject, $result) {

        $jsonResult = json_decode($result, true);

        $jsonResult['skus'] = [];
        $jsonResult['names'] = [];
        $jsonResult['countries'] = [];
        $jsonResult['dimensions'] = [];

        foreach ($subject->getAllowProducts() as $simpleProduct) {
            $reloadedSimpleProduct = $this->productFactory->create()->load($simpleProduct->getId());
            $jsonResult['skus'][$simpleProduct->getId()] = $simpleProduct->getSku();
            $jsonResult['names'][$simpleProduct->getId()] = $simpleProduct->getName();
            $jsonResult['countries'][$simpleProduct->getId()] = $this->dataAttributes->getCountryHtml($reloadedSimpleProduct->getCountryOfManufacture());
            $jsonResult['dimensions'][$simpleProduct->getId()] = $this->dataAttributes->getDimensionsHtml($reloadedSimpleProduct->getResource()->getAttribute('length')->getFrontend()->getValue($reloadedSimpleProduct), $reloadedSimpleProduct->getResource()->getAttribute('width')->getFrontend()->getValue($reloadedSimpleProduct), $reloadedSimpleProduct->getResource()->getAttribute('height')->getFrontend()->getValue($reloadedSimpleProduct));
        }

        $result = json_encode($jsonResult);

        return $result;
    }
}

Vendor/Module/Plugin/Magento/Swatches/Block/Product/Renderer/Configurable.php

<?php

namespace VendorModulePluginMagentoSwatchesBlockProductRenderer;

class Configurable
{

    protected $dataAttributes;
    protected $productFactory;
    protected $logger;

    public function __construct(VendorAttributesDataOutputBlockVendorDataAttributes $dataAttributes, MagentoCatalogModelProductFactory $productFactory, PsrLogLoggerInterface $logger)
    {
        $this->dataAttributes = $dataAttributes;
        $this->productFactory = $productFactory;
        $this->logger = $logger;
    }
    public function afterGetJsonConfig(MagentoSwatchesBlockProductRendererConfigurable $subject, $result) {

        $jsonResult = json_decode($result, true);

        $jsonResult['skus'] = [];
        $jsonResult['names'] = [];
        $jsonResult['countries'] = [];
        $jsonResult['dimensions'] = [];

        foreach ($subject->getAllowProducts() as $simpleProduct) {
            $reloadedSimpleProduct = $this->productFactory->create()->load($simpleProduct->getId());
            $jsonResult['skus'][$simpleProduct->getId()] = $simpleProduct->getSku();
            $jsonResult['names'][$simpleProduct->getId()] = $simpleProduct->getName();
            $jsonResult['countries'][$simpleProduct->getId()] = $this->dataAttributes->getCountryHtml($reloadedSimpleProduct->getCountryOfManufacture());
            $jsonResult['dimensions'][$simpleProduct->getId()] = $this->dataAttributes->getDimensionsHtml($reloadedSimpleProduct->getResource()->getAttribute('length')->getFrontend()->getValue($reloadedSimpleProduct), $reloadedSimpleProduct->getResource()->getAttribute('width')->getFrontend()->getValue($reloadedSimpleProduct), $reloadedSimpleProduct->getResource()->getAttribute('height')->getFrontend()->getValue($reloadedSimpleProduct));
        }

        $result = json_encode($jsonResult);

        return $result;
    }
}

Vendor/Module/view/frontend/requirejs-config.js

var config = {
    config: {
        mixins: {
            'Magento_ConfigurableProduct/js/configurable': {
                'Vendor_Module/js/model/skuswitch': true
            },
            'Magento_Swatches/js/swatch-renderer': {
                'Vendor_Module/js/model/swatch-skuswitch': true
            }
        }
    }
};

Vendor/Module/view/frontend/web/js/model/skuswitch.js

define([
    'jquery',
    'mage/utils/wrapper'
], function ($, wrapper) {
    'use strict';
    return function(targetModule){

        var reloadPrice = targetModule.prototype._reloadPrice;
        targetModule.prototype.configurableSku = $('div.product-info-main .sku .value').html();
        targetModule.prototype.configurableName = $('h1.page-title .base').html();
        targetModule.prototype.configurableCountry = $('.data-country').html();
        targetModule.prototype.configurableDimensions = $('.data-dimensions').html();

        var reloadPriceWrapper = wrapper.wrap(reloadPrice, function(original){
            //do extra stuff
            var simpleSku = this.configurableSku;
            var simpleName = this.configurableName;
            var simpleCountry = this.configurableCountry;
            var simpleDimensions = this.configurableDimensions;

            if(this.simpleProduct){
                simpleSku = this.options.spConfig.skus[this.simpleProduct];
                simpleName = this.options.spConfig.names[this.simpleProduct];
                simpleCountry = this.options.spConfig.countries[this.simpleProduct];
                simpleDimensions = this.options.spConfig.dimensions[this.simpleProduct];
            }

            $('div.product-info-main .sku .value').html(simpleSku);
            $('h1.page-title .base').html(simpleName);
            $('.data-country').html(simpleCountry);
            $('.data-dimensions').html(simpleDimensions);
            
            //return original value
            return original();
        });

        targetModule.prototype._reloadPrice = reloadPriceWrapper;
        return targetModule;
    };
});

Vendor/Module/view/frontend/web/js/model/swatch-skuswitch.js

define([
    'jquery',
    'mage/utils/wrapper'
], function ($, wrapper) {
    'use strict';

    return function(targetModule){

        var updatePrice = targetModule.prototype._UpdatePrice;
        targetModule.prototype.configurableSku = $('div.product-info-main .sku .value').html();
        targetModule.prototype.configurableName = $('h1.page-title .base').html();
        targetModule.prototype.configurableCountry = $('.budoland-data-country').html();
        targetModule.prototype.configurableDimensions = $('.budoland-data-dimensions').html();

        var updatePriceWrapper = wrapper.wrap(updatePrice, function(original){
            //do extra stuff
            var allSelected = true;
            for(var i = 0; i<this.options.jsonConfig.attributes.length;i++){
                if (!$('div.product-info-main .product-options-wrapper .swatch-attribute.' + this.options.jsonConfig.attributes[i].code).attr('option-selected')){
                    allSelected = false;
                }
            }
            var simpleSku  = this.configurableSku;
            var simpleName = this.configurableName;
            var simpleCountry = this.configurableCountry;
            var simpleDimensions = this.configurableDimensions;

            if (allSelected){
                var products = this._CalcProducts();
                simpleSku = this.options.jsonConfig.skus[products.slice().shift()];
                simpleName = this.options.jsonConfig.names[products.slice().shift()];
                simpleCountry = this.options.jsonConfig.countries[products.slice().shift()];
                simpleDimensions = this.options.jsonConfig.dimensions[products.slice().shift()];
            }
            $('div.product-info-main .sku .value').html(simpleSku);
            $('h1.page-title .base').html(simpleName);
            $('.budoland-data-country').html(simpleCountry);
            $('.budoland-data-dimensions').html(simpleDimensions);

            //return original value
            return original();
        });

        targetModule.prototype._UpdatePrice = updatePriceWrapper;
        return targetModule;
    };
});