<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Magento 2 Archives - WEB4PRO</title>
	<atom:link href="https://web4pro.net/blog-news/category/magento-2-blog/feed/" rel="self" type="application/rss+xml" />
	<link>https://web4pro.net/blog-news/category/magento-2-blog/</link>
	<description></description>
	<lastBuildDate>Thu, 11 Jan 2024 16:20:43 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://s3.eu-central-1.amazonaws.com/web4pro.net-new/wp-content/uploads/2023/04/07085114/favicon-32x32-1.png</url>
	<title>Magento 2 Archives - WEB4PRO</title>
	<link>https://web4pro.net/blog-news/category/magento-2-blog/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Magento 2.2.6 Bug When Saving Placeholder Image</title>
		<link>https://web4pro.net/blog-news/magento-2-2-6-bug-saving-placeholder-image/</link>
		
		<dc:creator><![CDATA[web4pro_su]]></dc:creator>
		<pubDate>Thu, 06 Dec 2018 11:39:10 +0000</pubDate>
				<category><![CDATA[Code for Magento]]></category>
		<category><![CDATA[Magento 2]]></category>
		<category><![CDATA[Solution]]></category>
		<category><![CDATA[web development]]></category>
		<guid isPermaLink="false">https://web4pro.net/?p=7518</guid>

					<description><![CDATA[Learn how to fix Magento 2.2.6 bug when saving Placeholders for images.]]></description>
										<content:encoded><![CDATA[
<p>If a product in Magento® 2 doesn&#8217;t have an image, a placeholder is displayed on the front end. The store administrator can set the image for the placeholder on the Product Image Placeholders page: <strong>Stores -&gt; Configuration -&gt; Catalog -&gt; Product Image Placeholders</strong> Magento. However, a bug was detected in Magento 2.2.6 that doesn&#8217;t let administrators upload their own images for placeholders. Below, we&#8217;ll examine the reason for this bug and how to fix it.</p>



<h2 class="wp-block-heading">Working with Placeholders</h2>



<p>Placeholders are configuration parameters that are set in adminhtml/system.xml in the Magento_Catalog module. Their description looks like this:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="...
&lt;group id=&quot;placeholder&quot; translate=&quot;label&quot; sortOrder=&quot;300&quot; showInDefault=&quot;1&quot; showInWebsite=&quot;1&quot; showInStore=&quot;1&quot;&gt;
    &lt;label&gt;Product Image Placeholders&lt;/label&gt;
    &lt;clone_fields&gt;1&lt;/clone_fields&gt;
    &lt;clone_model&gt;Magento\Catalog\Model\Config\CatalogClone\Media\Image&lt;/clone_model&gt;
    &lt;field id=&quot;placeholder&quot; type=&quot;image&quot; sortOrder=&quot;1&quot; showInDefault=&quot;1&quot; showInWebsite=&quot;1&quot; showInStore=&quot;1&quot;&gt;
        &lt;backend_model&gt;Magento\Config\Model\Config\Backend\Image&lt;/backend_model&gt;
        &lt;upload_dir config=&quot;system/filesystem/media&quot; scope_info=&quot;1&quot;&gt;catalog/product/placeholder&lt;/upload_dir&gt;
        &lt;base_url type=&quot;media&quot; scope_info=&quot;1&quot;&gt;catalog/product/placeholder&lt;/base_url&gt;
    &lt;/field&gt;
&lt;/group&gt;
...." style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki monokai" style="background-color: #272822" tabindex="0"><code><span class="line"><span style="color: #F8F8F2">...</span></span>
<span class="line"><span style="color: #F8F8F2">&lt;</span><span style="color: #F92672">group</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">id</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;placeholder&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">translate</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;label&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">sortOrder</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;300&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">showInDefault</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;1&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">showInWebsite</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;1&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">showInStore</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;1&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">    &lt;</span><span style="color: #F92672">label</span><span style="color: #F8F8F2">&gt;Product Image Placeholders&lt;/</span><span style="color: #F92672">label</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">    &lt;</span><span style="color: #F92672">clone_fields</span><span style="color: #F8F8F2">&gt;1&lt;/</span><span style="color: #F92672">clone_fields</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">    &lt;</span><span style="color: #F92672">clone_model</span><span style="color: #F8F8F2">&gt;Magento\Catalog\Model\Config\CatalogClone\Media\Image&lt;/</span><span style="color: #F92672">clone_model</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">    &lt;</span><span style="color: #F92672">field</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">id</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;placeholder&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">type</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;image&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">sortOrder</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;1&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">showInDefault</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;1&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">showInWebsite</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;1&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">showInStore</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;1&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">        &lt;</span><span style="color: #F92672">backend_model</span><span style="color: #F8F8F2">&gt;Magento\Config\Model\Config\Backend\Image&lt;/</span><span style="color: #F92672">backend_model</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">        &lt;</span><span style="color: #F92672">upload_dir</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">config</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;system/filesystem/media&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">scope_info</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;1&quot;</span><span style="color: #F8F8F2">&gt;catalog/product/placeholder&lt;/</span><span style="color: #F92672">upload_dir</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">        &lt;</span><span style="color: #F92672">base_url</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">type</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;media&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">scope_info</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;1&quot;</span><span style="color: #F8F8F2">&gt;catalog/product/placeholder&lt;/</span><span style="color: #F92672">base_url</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">    &lt;/</span><span style="color: #F92672">field</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">&lt;/</span><span style="color: #F92672">group</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">....</span></span></code></pre></div>



<p>This group of parameters is defined as such because a product could have any number of image attributes, including those implemented by different third-party modules.The cloning model Magento\Catalog\Model\Config\CatalogClone\Media\Image will look as follows:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="class Image extends \Magento\Framework\App\Config\Value
{
    /**
     * Eav config
     *
     * @var \Magento\Eav\Model\Config
     */
    protected $_eavConfig;
    /**
     * Attribute collection factory
     *
     * @var \Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory
     */
    protected $_attributeCollectionFactory;
    /**
     * @param \Magento\Framework\Model\Context $context
     * @param \Magento\Framework\Registry $registry
     * @param \Magento\Framework\App\Config\ScopeConfigInterface $config
     * @param \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList
     * @param \Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory $attributeCollectionFactory
     * @param \Magento\Eav\Model\Config $eavConfig
     * @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
     * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
     * @param array $data
     */
    public function __construct(
        \Magento\Framework\Model\Context $context,
        \Magento\Framework\Registry $registry,
        \Magento\Framework\App\Config\ScopeConfigInterface $config,
        \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList,
        \Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory $attributeCollectionFactory,
        \Magento\Eav\Model\Config $eavConfig,
        \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
        \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
        array $data = []
    ) {
        $this-&gt;_attributeCollectionFactory = $attributeCollectionFactory;
        $this-&gt;_eavConfig = $eavConfig;
        parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data);
    }
    /**
     * Get fields prefixes
     *
     * @return array
     */
    public function getPrefixes()
    {
        // use cached eav config
        $entityTypeId = $this-&gt;_eavConfig-&gt;getEntityType(\Magento\Catalog\Model\Product::ENTITY)-&gt;getId();
        /* @var $collection \Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection */
        $collection = $this-&gt;_attributeCollectionFactory-&gt;create();
        $collection-&gt;setEntityTypeFilter($entityTypeId);
        $collection-&gt;setFrontendInputTypeFilter('media_image');
        $prefixes = [];
        foreach ($collection as $attribute) {
            /* @var $attribute \Magento\Eav\Model\Entity\Attribute */
            $prefixes[] = [
                'field' =&gt; $attribute-&gt;getAttributeCode() . '_',
                'label' =&gt; $attribute-&gt;getFrontend()-&gt;getLabel(),
            ];
        }
        return $prefixes;
    }
}" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki monokai" style="background-color: #272822" tabindex="0"><code><span class="line"><span style="color: #66D9EF; font-style: italic">class</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E; text-decoration: underline">Image</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">extends</span><span style="color: #F8F8F2"> \Magento\Framework\App\Config\</span><span style="color: #A6E22E; font-style: italic; text-decoration: underline">Value</span></span>
<span class="line"><span style="color: #F8F8F2">{</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * Eav config</span></span>
<span class="line"><span style="color: #88846F">     *</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@var</span><span style="color: #88846F"> \Magento\Eav\Model\</span><span style="color: #66D9EF; font-style: italic">Config</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">protected</span><span style="color: #F8F8F2"> $_eavConfig;</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * Attribute collection factory</span></span>
<span class="line"><span style="color: #88846F">     *</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@var</span><span style="color: #88846F"> \Magento\Catalog\Model\ResourceModel\Product\Attribute\</span><span style="color: #66D9EF; font-style: italic">CollectionFactory</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">protected</span><span style="color: #F8F8F2"> $_attributeCollectionFactory;</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> \Magento\Framework\Model\</span><span style="color: #66D9EF; font-style: italic">Context</span><span style="color: #88846F"> $context</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> \Magento\Framework\</span><span style="color: #66D9EF; font-style: italic">Registry</span><span style="color: #88846F"> $registry</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> \Magento\Framework\App\Config\</span><span style="color: #66D9EF; font-style: italic">ScopeConfigInterface</span><span style="color: #88846F"> $config</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> \Magento\Framework\App\Cache\</span><span style="color: #66D9EF; font-style: italic">TypeListInterface</span><span style="color: #88846F"> $cacheTypeList</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> \Magento\Catalog\Model\ResourceModel\Product\Attribute\</span><span style="color: #66D9EF; font-style: italic">CollectionFactory</span><span style="color: #88846F"> $attributeCollectionFactory</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> \Magento\Eav\Model\</span><span style="color: #66D9EF; font-style: italic">Config</span><span style="color: #88846F"> $eavConfig</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> \Magento\Framework\Model\ResourceModel\</span><span style="color: #66D9EF; font-style: italic">AbstractResource</span><span style="color: #88846F"> $resource</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> \Magento\Framework\Data\Collection\</span><span style="color: #66D9EF; font-style: italic">AbstractDb</span><span style="color: #88846F"> $resourceCollection</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> </span><span style="color: #F92672">array</span><span style="color: #88846F"> $data</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">public</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF">__construct</span><span style="color: #F8F8F2">(</span></span>
<span class="line"><span style="color: #F8F8F2">        \Magento\Framework\Model\</span><span style="color: #66D9EF; font-style: italic">Context</span><span style="color: #F8F8F2"> $context,</span></span>
<span class="line"><span style="color: #F8F8F2">        \Magento\Framework\</span><span style="color: #66D9EF; font-style: italic">Registry</span><span style="color: #F8F8F2"> $registry,</span></span>
<span class="line"><span style="color: #F8F8F2">        \Magento\Framework\App\Config\</span><span style="color: #66D9EF; font-style: italic">ScopeConfigInterface</span><span style="color: #F8F8F2"> $config,</span></span>
<span class="line"><span style="color: #F8F8F2">        \Magento\Framework\App\Cache\</span><span style="color: #66D9EF; font-style: italic">TypeListInterface</span><span style="color: #F8F8F2"> $cacheTypeList,</span></span>
<span class="line"><span style="color: #F8F8F2">        \Magento\Catalog\Model\ResourceModel\Product\Attribute\</span><span style="color: #66D9EF; font-style: italic">CollectionFactory</span><span style="color: #F8F8F2"> $attributeCollectionFactory,</span></span>
<span class="line"><span style="color: #F8F8F2">        \Magento\Eav\Model\</span><span style="color: #66D9EF; font-style: italic">Config</span><span style="color: #F8F8F2"> $eavConfig,</span></span>
<span class="line"><span style="color: #F8F8F2">        \Magento\Framework\Model\ResourceModel\</span><span style="color: #66D9EF; font-style: italic">AbstractResource</span><span style="color: #F8F8F2"> $resource </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">null</span><span style="color: #F8F8F2">,</span></span>
<span class="line"><span style="color: #F8F8F2">        \Magento\Framework\Data\Collection\</span><span style="color: #66D9EF; font-style: italic">AbstractDb</span><span style="color: #F8F8F2"> $resourceCollection </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">null</span><span style="color: #F8F8F2">,</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">array</span><span style="color: #F8F8F2"> $data </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> []</span></span>
<span class="line"><span style="color: #F8F8F2">    ) {</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">_attributeCollectionFactory </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $attributeCollectionFactory;</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">_eavConfig </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $eavConfig;</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #66D9EF; font-style: italic">parent</span><span style="color: #F92672">::</span><span style="color: #A6E22E">__construct</span><span style="color: #F8F8F2">($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data);</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * Get fields prefixes</span></span>
<span class="line"><span style="color: #88846F">     *</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@return</span><span style="color: #88846F"> </span><span style="color: #F92672">array</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">public</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">getPrefixes</span><span style="color: #F8F8F2">()</span></span>
<span class="line"><span style="color: #F8F8F2">    {</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #88846F">// use cached eav config</span></span>
<span class="line"><span style="color: #F8F8F2">        $entityTypeId </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">_eavConfig</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getEntityType</span><span style="color: #F8F8F2">(\Magento\Catalog\Model\</span><span style="color: #66D9EF; font-style: italic">Product</span><span style="color: #F92672">::</span><span style="color: #AE81FF">ENTITY</span><span style="color: #F8F8F2">)</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getId</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #88846F">/* @var $collection \Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection */</span></span>
<span class="line"><span style="color: #F8F8F2">        $collection </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">_attributeCollectionFactory</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">create</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">        $collection</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">setEntityTypeFilter</span><span style="color: #F8F8F2">($entityTypeId);</span></span>
<span class="line"><span style="color: #F8F8F2">        $collection</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">setFrontendInputTypeFilter</span><span style="color: #F8F8F2">(</span><span style="color: #E6DB74">&#39;media_image&#39;</span><span style="color: #F8F8F2">);</span></span>
<span class="line"><span style="color: #F8F8F2">        $prefixes </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> [];</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">foreach</span><span style="color: #F8F8F2"> ($collection </span><span style="color: #F92672">as</span><span style="color: #F8F8F2"> $attribute) {</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #88846F">/* @var $attribute \Magento\Eav\Model\Entity\Attribute */</span></span>
<span class="line"><span style="color: #F8F8F2">            $prefixes[] </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> [</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #E6DB74">&#39;field&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> $attribute</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getAttributeCode</span><span style="color: #F8F8F2">() </span><span style="color: #F92672">.</span><span style="color: #F8F8F2"> </span><span style="color: #E6DB74">&#39;_&#39;</span><span style="color: #F8F8F2">,</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #E6DB74">&#39;label&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> $attribute</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getFrontend</span><span style="color: #F8F8F2">()</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getLabel</span><span style="color: #F8F8F2">(),</span></span>
<span class="line"><span style="color: #F8F8F2">            ];</span></span>
<span class="line"><span style="color: #F8F8F2">        }</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">return</span><span style="color: #F8F8F2"> $prefixes;</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span>
<span class="line"><span style="color: #F8F8F2">}</span></span></code></pre></div>



<p>When the administrator uploads an image in the field on the configuration page and the submit form, it will be processed on the server by the Magento\Config\Controller\Adminhtml\System\Config\Save controller and will look as follows:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="class Save extends AbstractConfig
{
    /**
     * Backend Config Model Factory
     *
     * @var \Magento\Config\Model\Config\Factory
     */
    protected $_configFactory;
    /**
     * @var \Magento\Framework\Cache\FrontendInterface
     */
    protected $_cache;
    /**
     * @var \Magento\Framework\Stdlib\StringUtils
     */
    protected $string;
    /**
     * @param \Magento\Backend\App\Action\Context $context
     * @param \Magento\Config\Model\Config\Structure $configStructure
     * @param \Magento\Config\Controller\Adminhtml\System\ConfigSectionChecker $sectionChecker
     * @param \Magento\Config\Model\Config\Factory $configFactory
     * @param \Magento\Framework\Cache\FrontendInterface $cache
     * @param \Magento\Framework\Stdlib\StringUtils $string
     */
    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \Magento\Config\Model\Config\Structure $configStructure,
        \Magento\Config\Controller\Adminhtml\System\ConfigSectionChecker $sectionChecker,
        \Magento\Config\Model\Config\Factory $configFactory,
        \Magento\Framework\Cache\FrontendInterface $cache,
        \Magento\Framework\Stdlib\StringUtils $string
    ) {
        parent::__construct($context, $configStructure, $sectionChecker);
        $this-&gt;_configFactory = $configFactory;
        $this-&gt;_cache = $cache;
        $this-&gt;string = $string;
    }
    /**
     * Get groups for save
     *
     * @return array|null
     */
    protected function _getGroupsForSave()
    {
        $groups = $this-&gt;getRequest()-&gt;getPost('groups');
        $files = $this-&gt;getRequest()-&gt;getFiles('groups');
        if ($files &amp;&amp; is_array($files)) {
            /**
             * Carefully merge $_FILES and $_POST information
             * None of ' =' or 'array_merge_recursive' can do this correct
             */
            foreach ($files as $groupName =&gt; $group) {
                $data = $this-&gt;_processNestedGroups($group);
                if (!empty($data)) {
                    if (!empty($groups[$groupName])) {
                        $groups[$groupName] = array_merge_recursive((array)$groups[$groupName], $data);
                    } else {
                        $groups[$groupName] = $data;
                    }
                }
            }
        }
        return $groups;
    }
    /**
     * Process nested groups
     *
     * @param mixed $group
     * @return array
     */
    protected function _processNestedGroups($group)
    {
        $data = [];
        if (isset($group['fields']) &amp;&amp; is_array($group['fields'])) {
            foreach ($group['fields'] as $fieldName =&gt; $field) {
                if (!empty($field['value'])) {
                    $data['fields'][$fieldName] = ['value' =&gt; $field['value']];
                }
            }
        }
        if (isset($group['groups']) &amp;&amp; is_array($group['groups'])) {
            foreach ($group['groups'] as $groupName =&gt; $groupData) {
                $nestedGroup = $this-&gt;_processNestedGroups($groupData);
                if (!empty($nestedGroup)) {
                    $data['groups'][$groupName] = $nestedGroup;
                }
            }
        }
        return $data;
    }
    /**
     * Custom save logic for section
     *
     * @return void
     */
    protected function _saveSection()
    {
        $method = '_save' . $this-&gt;string-&gt;upperCaseWords($this-&gt;getRequest()-&gt;getParam('section'), '_', '');
        if (method_exists($this, $method)) {
            $this-&gt;{$method}();
        }
    }
    /**
     * Advanced save procedure
     *
     * @return void
     */
    protected function _saveAdvanced()
    {
        $this-&gt;_cache-&gt;clean();
    }
    /**
     * Save configuration
     *
     * @return \Magento\Backend\Model\View\Result\Redirect
     */
    public function execute()
    {
        try {
            // custom save logic
            $this-&gt;_saveSection();
            $section = $this-&gt;getRequest()-&gt;getParam('section');
            $website = $this-&gt;getRequest()-&gt;getParam('website');
            $store = $this-&gt;getRequest()-&gt;getParam('store');
            $configData = [
                'section' =&gt; $section,
                'website' =&gt; $website,
                'store' =&gt; $store,
                'groups' =&gt; $this-&gt;_getGroupsForSave(),
            ];
            /** @var \Magento\Config\Model\Config $configModel  */
            $configModel = $this-&gt;_configFactory-&gt;create(['data' =&gt; $configData]);
            $configModel-&gt;save();
            $this-&gt;messageManager-&gt;addSuccess(__('You saved the configuration.'));
        } catch (\Magento\Framework\Exception\LocalizedException $e) {
            $messages = explode(&quot;\n&quot;, $e-&gt;getMessage());
            foreach ($messages as $message) {
                $this-&gt;messageManager-&gt;addError($message);
            }
        } catch (\Exception $e) {
            $this-&gt;messageManager-&gt;addException(
                $e,
                __('Something went wrong while saving this configuration:') . ' ' . $e-&gt;getMessage()
            );
        }
        $this-&gt;_saveState($this-&gt;getRequest()-&gt;getPost('config_state'));
        /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
        $resultRedirect = $this-&gt;resultRedirectFactory-&gt;create();
        return $resultRedirect-&gt;setPath(
            'adminhtml/system_config/edit',
            [
                '_current' =&gt; ['section', 'website', 'store'],
                '_nosid' =&gt; true
            ]
        );
    }
}" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki monokai" style="background-color: #272822" tabindex="0"><code><span class="line"><span style="color: #66D9EF; font-style: italic">class</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E; text-decoration: underline">Save</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">extends</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E; font-style: italic; text-decoration: underline">AbstractConfig</span></span>
<span class="line"><span style="color: #F8F8F2">{</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * Backend Config Model Factory</span></span>
<span class="line"><span style="color: #88846F">     *</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@var</span><span style="color: #88846F"> \Magento\Config\Model\Config\</span><span style="color: #66D9EF; font-style: italic">Factory</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">protected</span><span style="color: #F8F8F2"> $_configFactory;</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@var</span><span style="color: #88846F"> \Magento\Framework\Cache\</span><span style="color: #66D9EF; font-style: italic">FrontendInterface</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">protected</span><span style="color: #F8F8F2"> $_cache;</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@var</span><span style="color: #88846F"> \Magento\Framework\Stdlib\</span><span style="color: #66D9EF; font-style: italic">StringUtils</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">protected</span><span style="color: #F8F8F2"> $string;</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> \Magento\Backend\App\Action\</span><span style="color: #66D9EF; font-style: italic">Context</span><span style="color: #88846F"> $context</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> \Magento\Config\Model\Config\</span><span style="color: #66D9EF; font-style: italic">Structure</span><span style="color: #88846F"> $configStructure</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> \Magento\Config\Controller\Adminhtml\System\</span><span style="color: #66D9EF; font-style: italic">ConfigSectionChecker</span><span style="color: #88846F"> $sectionChecker</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> \Magento\Config\Model\Config\</span><span style="color: #66D9EF; font-style: italic">Factory</span><span style="color: #88846F"> $configFactory</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> \Magento\Framework\Cache\</span><span style="color: #66D9EF; font-style: italic">FrontendInterface</span><span style="color: #88846F"> $cache</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> \Magento\Framework\Stdlib\</span><span style="color: #66D9EF; font-style: italic">StringUtils</span><span style="color: #88846F"> $string</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">public</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF">__construct</span><span style="color: #F8F8F2">(</span></span>
<span class="line"><span style="color: #F8F8F2">        \Magento\Backend\App\Action\</span><span style="color: #66D9EF; font-style: italic">Context</span><span style="color: #F8F8F2"> $context,</span></span>
<span class="line"><span style="color: #F8F8F2">        \Magento\Config\Model\Config\</span><span style="color: #66D9EF; font-style: italic">Structure</span><span style="color: #F8F8F2"> $configStructure,</span></span>
<span class="line"><span style="color: #F8F8F2">        \Magento\Config\Controller\Adminhtml\System\</span><span style="color: #66D9EF; font-style: italic">ConfigSectionChecker</span><span style="color: #F8F8F2"> $sectionChecker,</span></span>
<span class="line"><span style="color: #F8F8F2">        \Magento\Config\Model\Config\</span><span style="color: #66D9EF; font-style: italic">Factory</span><span style="color: #F8F8F2"> $configFactory,</span></span>
<span class="line"><span style="color: #F8F8F2">        \Magento\Framework\Cache\</span><span style="color: #66D9EF; font-style: italic">FrontendInterface</span><span style="color: #F8F8F2"> $cache,</span></span>
<span class="line"><span style="color: #F8F8F2">        \Magento\Framework\Stdlib\</span><span style="color: #66D9EF; font-style: italic">StringUtils</span><span style="color: #F8F8F2"> $string</span></span>
<span class="line"><span style="color: #F8F8F2">    ) {</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #66D9EF; font-style: italic">parent</span><span style="color: #F92672">::</span><span style="color: #A6E22E">__construct</span><span style="color: #F8F8F2">($context, $configStructure, $sectionChecker);</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">_configFactory </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $configFactory;</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">_cache </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $cache;</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">string </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $string;</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * Get groups for save</span></span>
<span class="line"><span style="color: #88846F">     *</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@return</span><span style="color: #88846F"> </span><span style="color: #F92672">array</span><span style="color: #88846F">|</span><span style="color: #F92672">null</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">protected</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">_getGroupsForSave</span><span style="color: #F8F8F2">()</span></span>
<span class="line"><span style="color: #F8F8F2">    {</span></span>
<span class="line"><span style="color: #F8F8F2">        $groups </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getRequest</span><span style="color: #F8F8F2">()</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getPost</span><span style="color: #F8F8F2">(</span><span style="color: #E6DB74">&#39;groups&#39;</span><span style="color: #F8F8F2">);</span></span>
<span class="line"><span style="color: #F8F8F2">        $files </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getRequest</span><span style="color: #F8F8F2">()</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getFiles</span><span style="color: #F8F8F2">(</span><span style="color: #E6DB74">&#39;groups&#39;</span><span style="color: #F8F8F2">);</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> ($files </span><span style="color: #F92672">&amp;&amp;</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF">is_array</span><span style="color: #F8F8F2">($files)) {</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">             * Carefully merge $_FILES and $_POST information</span></span>
<span class="line"><span style="color: #88846F">             * None of &#39; =&#39; or &#39;array_merge_recursive&#39; can do this correct</span></span>
<span class="line"><span style="color: #88846F">             */</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #F92672">foreach</span><span style="color: #F8F8F2"> ($files </span><span style="color: #F92672">as</span><span style="color: #F8F8F2"> $groupName </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> $group) {</span></span>
<span class="line"><span style="color: #F8F8F2">                $data </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">_processNestedGroups</span><span style="color: #F8F8F2">($group);</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> (</span><span style="color: #F92672">!</span><span style="color: #66D9EF">empty</span><span style="color: #F8F8F2">($data)) {</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> (</span><span style="color: #F92672">!</span><span style="color: #66D9EF">empty</span><span style="color: #F8F8F2">($groups[$groupName])) {</span></span>
<span class="line"><span style="color: #F8F8F2">                        $groups[$groupName] </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF">array_merge_recursive</span><span style="color: #F8F8F2">((</span><span style="color: #66D9EF; font-style: italic">array</span><span style="color: #F8F8F2">)$groups[$groupName], $data);</span></span>
<span class="line"><span style="color: #F8F8F2">                    } </span><span style="color: #F92672">else</span><span style="color: #F8F8F2"> {</span></span>
<span class="line"><span style="color: #F8F8F2">                        $groups[$groupName] </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $data;</span></span>
<span class="line"><span style="color: #F8F8F2">                    }</span></span>
<span class="line"><span style="color: #F8F8F2">                }</span></span>
<span class="line"><span style="color: #F8F8F2">            }</span></span>
<span class="line"><span style="color: #F8F8F2">        }</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">return</span><span style="color: #F8F8F2"> $groups;</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * Process nested groups</span></span>
<span class="line"><span style="color: #88846F">     *</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> </span><span style="color: #F92672">mixed</span><span style="color: #88846F"> $group</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@return</span><span style="color: #88846F"> </span><span style="color: #F92672">array</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">protected</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">_processNestedGroups</span><span style="color: #F8F8F2">($group)</span></span>
<span class="line"><span style="color: #F8F8F2">    {</span></span>
<span class="line"><span style="color: #F8F8F2">        $data </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> [];</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> (</span><span style="color: #66D9EF">isset</span><span style="color: #F8F8F2">($group[</span><span style="color: #E6DB74">&#39;fields&#39;</span><span style="color: #F8F8F2">]) </span><span style="color: #F92672">&amp;&amp;</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF">is_array</span><span style="color: #F8F8F2">($group[</span><span style="color: #E6DB74">&#39;fields&#39;</span><span style="color: #F8F8F2">])) {</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #F92672">foreach</span><span style="color: #F8F8F2"> ($group[</span><span style="color: #E6DB74">&#39;fields&#39;</span><span style="color: #F8F8F2">] </span><span style="color: #F92672">as</span><span style="color: #F8F8F2"> $fieldName </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> $field) {</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> (</span><span style="color: #F92672">!</span><span style="color: #66D9EF">empty</span><span style="color: #F8F8F2">($field[</span><span style="color: #E6DB74">&#39;value&#39;</span><span style="color: #F8F8F2">])) {</span></span>
<span class="line"><span style="color: #F8F8F2">                    $data[</span><span style="color: #E6DB74">&#39;fields&#39;</span><span style="color: #F8F8F2">][$fieldName] </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> [</span><span style="color: #E6DB74">&#39;value&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> $field[</span><span style="color: #E6DB74">&#39;value&#39;</span><span style="color: #F8F8F2">]];</span></span>
<span class="line"><span style="color: #F8F8F2">                }</span></span>
<span class="line"><span style="color: #F8F8F2">            }</span></span>
<span class="line"><span style="color: #F8F8F2">        }</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> (</span><span style="color: #66D9EF">isset</span><span style="color: #F8F8F2">($group[</span><span style="color: #E6DB74">&#39;groups&#39;</span><span style="color: #F8F8F2">]) </span><span style="color: #F92672">&amp;&amp;</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF">is_array</span><span style="color: #F8F8F2">($group[</span><span style="color: #E6DB74">&#39;groups&#39;</span><span style="color: #F8F8F2">])) {</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #F92672">foreach</span><span style="color: #F8F8F2"> ($group[</span><span style="color: #E6DB74">&#39;groups&#39;</span><span style="color: #F8F8F2">] </span><span style="color: #F92672">as</span><span style="color: #F8F8F2"> $groupName </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> $groupData) {</span></span>
<span class="line"><span style="color: #F8F8F2">                $nestedGroup </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">_processNestedGroups</span><span style="color: #F8F8F2">($groupData);</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> (</span><span style="color: #F92672">!</span><span style="color: #66D9EF">empty</span><span style="color: #F8F8F2">($nestedGroup)) {</span></span>
<span class="line"><span style="color: #F8F8F2">                    $data[</span><span style="color: #E6DB74">&#39;groups&#39;</span><span style="color: #F8F8F2">][$groupName] </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $nestedGroup;</span></span>
<span class="line"><span style="color: #F8F8F2">                }</span></span>
<span class="line"><span style="color: #F8F8F2">            }</span></span>
<span class="line"><span style="color: #F8F8F2">        }</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">return</span><span style="color: #F8F8F2"> $data;</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * Custom save logic for section</span></span>
<span class="line"><span style="color: #88846F">     *</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@return</span><span style="color: #88846F"> </span><span style="color: #F92672">void</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">protected</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">_saveSection</span><span style="color: #F8F8F2">()</span></span>
<span class="line"><span style="color: #F8F8F2">    {</span></span>
<span class="line"><span style="color: #F8F8F2">        $method </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #E6DB74">&#39;_save&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">.</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">string</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">upperCaseWords</span><span style="color: #F8F8F2">(</span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getRequest</span><span style="color: #F8F8F2">()</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getParam</span><span style="color: #F8F8F2">(</span><span style="color: #E6DB74">&#39;section&#39;</span><span style="color: #F8F8F2">), </span><span style="color: #E6DB74">&#39;_&#39;</span><span style="color: #F8F8F2">, </span><span style="color: #E6DB74">&#39;&#39;</span><span style="color: #F8F8F2">);</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> (</span><span style="color: #66D9EF">method_exists</span><span style="color: #F8F8F2">(</span><span style="color: #FD971F">$this</span><span style="color: #F8F8F2">, $method)) {</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">{$method}();</span></span>
<span class="line"><span style="color: #F8F8F2">        }</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * Advanced save procedure</span></span>
<span class="line"><span style="color: #88846F">     *</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@return</span><span style="color: #88846F"> </span><span style="color: #F92672">void</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">protected</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">_saveAdvanced</span><span style="color: #F8F8F2">()</span></span>
<span class="line"><span style="color: #F8F8F2">    {</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">_cache</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">clean</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * Save configuration</span></span>
<span class="line"><span style="color: #88846F">     *</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@return</span><span style="color: #88846F"> \Magento\Backend\Model\View\Result\</span><span style="color: #66D9EF; font-style: italic">Redirect</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">public</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">execute</span><span style="color: #F8F8F2">()</span></span>
<span class="line"><span style="color: #F8F8F2">    {</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">try</span><span style="color: #F8F8F2"> {</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #88846F">// custom save logic</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">_saveSection</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">            $section </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getRequest</span><span style="color: #F8F8F2">()</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getParam</span><span style="color: #F8F8F2">(</span><span style="color: #E6DB74">&#39;section&#39;</span><span style="color: #F8F8F2">);</span></span>
<span class="line"><span style="color: #F8F8F2">            $website </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getRequest</span><span style="color: #F8F8F2">()</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getParam</span><span style="color: #F8F8F2">(</span><span style="color: #E6DB74">&#39;website&#39;</span><span style="color: #F8F8F2">);</span></span>
<span class="line"><span style="color: #F8F8F2">            $store </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getRequest</span><span style="color: #F8F8F2">()</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getParam</span><span style="color: #F8F8F2">(</span><span style="color: #E6DB74">&#39;store&#39;</span><span style="color: #F8F8F2">);</span></span>
<span class="line"><span style="color: #F8F8F2">            $configData </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> [</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #E6DB74">&#39;section&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> $section,</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #E6DB74">&#39;website&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> $website,</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #E6DB74">&#39;store&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> $store,</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #E6DB74">&#39;groups&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">_getGroupsForSave</span><span style="color: #F8F8F2">(),</span></span>
<span class="line"><span style="color: #F8F8F2">            ];</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #88846F">/** </span><span style="color: #F92672">@var</span><span style="color: #88846F"> \Magento\Config\Model\</span><span style="color: #66D9EF; font-style: italic">Config</span><span style="color: #88846F"> $configModel  */</span></span>
<span class="line"><span style="color: #F8F8F2">            $configModel </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">_configFactory</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">create</span><span style="color: #F8F8F2">([</span><span style="color: #E6DB74">&#39;data&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> $configData]);</span></span>
<span class="line"><span style="color: #F8F8F2">            $configModel</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">save</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">messageManager</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">addSuccess</span><span style="color: #F8F8F2">(</span><span style="color: #A6E22E">__</span><span style="color: #F8F8F2">(</span><span style="color: #E6DB74">&#39;You saved the configuration.&#39;</span><span style="color: #F8F8F2">));</span></span>
<span class="line"><span style="color: #F8F8F2">        } </span><span style="color: #F92672">catch</span><span style="color: #F8F8F2"> (\Magento\Framework\Exception\</span><span style="color: #66D9EF; font-style: italic">LocalizedException</span><span style="color: #F8F8F2"> $e) {</span></span>
<span class="line"><span style="color: #F8F8F2">            $messages </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF">explode</span><span style="color: #F8F8F2">(</span><span style="color: #E6DB74">&quot;</span><span style="color: #AE81FF">\n</span><span style="color: #E6DB74">&quot;</span><span style="color: #F8F8F2">, $e</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getMessage</span><span style="color: #F8F8F2">());</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #F92672">foreach</span><span style="color: #F8F8F2"> ($messages </span><span style="color: #F92672">as</span><span style="color: #F8F8F2"> $message) {</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">messageManager</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">addError</span><span style="color: #F8F8F2">($message);</span></span>
<span class="line"><span style="color: #F8F8F2">            }</span></span>
<span class="line"><span style="color: #F8F8F2">        } </span><span style="color: #F92672">catch</span><span style="color: #F8F8F2"> (\</span><span style="color: #66D9EF; font-style: italic">Exception</span><span style="color: #F8F8F2"> $e) {</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">messageManager</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">addException</span><span style="color: #F8F8F2">(</span></span>
<span class="line"><span style="color: #F8F8F2">                $e,</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #A6E22E">__</span><span style="color: #F8F8F2">(</span><span style="color: #E6DB74">&#39;Something went wrong while saving this configuration:&#39;</span><span style="color: #F8F8F2">) </span><span style="color: #F92672">.</span><span style="color: #F8F8F2"> </span><span style="color: #E6DB74">&#39; &#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">.</span><span style="color: #F8F8F2"> $e</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getMessage</span><span style="color: #F8F8F2">()</span></span>
<span class="line"><span style="color: #F8F8F2">            );</span></span>
<span class="line"><span style="color: #F8F8F2">        }</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">_saveState</span><span style="color: #F8F8F2">(</span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getRequest</span><span style="color: #F8F8F2">()</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getPost</span><span style="color: #F8F8F2">(</span><span style="color: #E6DB74">&#39;config_state&#39;</span><span style="color: #F8F8F2">));</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #88846F">/** </span><span style="color: #F92672">@var</span><span style="color: #88846F"> \Magento\Backend\Model\View\Result\</span><span style="color: #66D9EF; font-style: italic">Redirect</span><span style="color: #88846F"> $resultRedirect */</span></span>
<span class="line"><span style="color: #F8F8F2">        $resultRedirect </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">resultRedirectFactory</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">create</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">return</span><span style="color: #F8F8F2"> $resultRedirect</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">setPath</span><span style="color: #F8F8F2">(</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #E6DB74">&#39;adminhtml/system_config/edit&#39;</span><span style="color: #F8F8F2">,</span></span>
<span class="line"><span style="color: #F8F8F2">            [</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #E6DB74">&#39;_current&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> [</span><span style="color: #E6DB74">&#39;section&#39;</span><span style="color: #F8F8F2">, </span><span style="color: #E6DB74">&#39;website&#39;</span><span style="color: #F8F8F2">, </span><span style="color: #E6DB74">&#39;store&#39;</span><span style="color: #F8F8F2">],</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #E6DB74">&#39;_nosid&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">true</span></span>
<span class="line"><span style="color: #F8F8F2">            ]</span></span>
<span class="line"><span style="color: #F8F8F2">        );</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span>
<span class="line"><span style="color: #F8F8F2">}</span></span></code></pre></div>



<p>As you can see, in the execute method the save is carried out in the save() method of the Magento\Config\Model\Config class. Let&#8217;s take a look at this class.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="class Config extends \Magento\Framework\DataObject
{
    /**
     * Config data for sections
     *
     * @var array
     */
    protected $_configData;
    /**
     * Event dispatcher
     *
     * @var \Magento\Framework\Event\ManagerInterface
     */
    protected $_eventManager;
    /**
     * System configuration structure
     *
     * @var \Magento\Config\Model\Config\Structure
     */
    protected $_configStructure;
    /**
     * Application config
     *
     * @var \Magento\Framework\App\Config\ScopeConfigInterface
     */
    protected $_appConfig;
    /**
     * Global factory
     *
     * @var \Magento\Framework\App\Config\ScopeConfigInterface
     */
    protected $_objectFactory;
    /**
     * TransactionFactory
     *
     * @var \Magento\Framework\DB\TransactionFactory
     */
    protected $_transactionFactory;
    /**
     * Config data loader
     *
     * @var \Magento\Config\Model\Config\Loader
     */
    protected $_configLoader;
    /**
     * Config data factory
     *
     * @var \Magento\Framework\App\Config\ValueFactory
     */
    protected $_configValueFactory;
    /**
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    protected $_storeManager;
    /**
     * @var Config\Reader\Source\Deployed\SettingChecker
     */
    private $settingChecker;
    /**
     * @param \Magento\Framework\App\Config\ReinitableConfigInterface $config
     * @param \Magento\Framework\Event\ManagerInterface $eventManager
     * @param \Magento\Config\Model\Config\Structure $configStructure
     * @param \Magento\Framework\DB\TransactionFactory $transactionFactory
     * @param \Magento\Config\Model\Config\Loader $configLoader
     * @param \Magento\Framework\App\Config\ValueFactory $configValueFactory
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
     * @param Config\Reader\Source\Deployed\SettingChecker|null $settingChecker
     * @param array $data
     */
    public function __construct(
        \Magento\Framework\App\Config\ReinitableConfigInterface $config,
        \Magento\Framework\Event\ManagerInterface $eventManager,
        \Magento\Config\Model\Config\Structure $configStructure,
        \Magento\Framework\DB\TransactionFactory $transactionFactory,
        \Magento\Config\Model\Config\Loader $configLoader,
        \Magento\Framework\App\Config\ValueFactory $configValueFactory,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        SettingChecker $settingChecker = null,
        array $data = []
    ) {
        parent::__construct($data);
        $this-&gt;_eventManager = $eventManager;
        $this-&gt;_configStructure = $configStructure;
        $this-&gt;_transactionFactory = $transactionFactory;
        $this-&gt;_appConfig = $config;
        $this-&gt;_configLoader = $configLoader;
        $this-&gt;_configValueFactory = $configValueFactory;
        $this-&gt;_storeManager = $storeManager;
        $this-&gt;settingChecker = $settingChecker ?: ObjectManager::getInstance()-&gt;get(SettingChecker::class);
    }
    /**
     * Save config section
     * Require set: section, website, store and groups
     *
     * @throws \Exception
     * @return $this
     */
    public function save()
    {
        $this-&gt;initScope();
        $sectionId = $this-&gt;getSection();
        $groups = $this-&gt;getGroups();
        if (empty($groups)) {
            return $this;
        }
        $oldConfig = $this-&gt;_getConfig(true);
        /** @var \Magento\Framework\DB\Transaction $deleteTransaction */
        $deleteTransaction = $this-&gt;_transactionFactory-&gt;create();
        /** @var \Magento\Framework\DB\Transaction $saveTransaction */
        $saveTransaction = $this-&gt;_transactionFactory-&gt;create();
        $changedPaths = [];
        // Extends for old config data
        $extraOldGroups = [];
        foreach ($groups as $groupId =&gt; $groupData) {
            $this-&gt;_processGroup(
                $groupId,
                $groupData,
                $groups,
                $sectionId,
                $extraOldGroups,
                $oldConfig,
                $saveTransaction,
                $deleteTransaction
            );
            $groupChangedPaths = $this-&gt;getChangedPaths($sectionId, $groupId, $groupData, $oldConfig, $extraOldGroups);
            $changedPaths = \array_merge($changedPaths, $groupChangedPaths);
        }
        try {
            $deleteTransaction-&gt;delete();
            $saveTransaction-&gt;save();
            // re-init configuration
            $this-&gt;_appConfig-&gt;reinit();
            // website and store codes can be used in event implementation, so set them as well
            $this-&gt;_eventManager-&gt;dispatch(
                &quot;admin_system_config_changed_section_{$this-&gt;getSection()}&quot;,
                [
                    'website' =&gt; $this-&gt;getWebsite(),
                    'store' =&gt; $this-&gt;getStore(),
                    'changed_paths' =&gt; $changedPaths,
                ]
            );
        } catch (\Exception $e) {
            // re-init configuration
            $this-&gt;_appConfig-&gt;reinit();
            throw $e;
        }
        return $this;
    }
    /**
     * Map field name if they were cloned
     *
     * @param Group $group
     * @param string $fieldId
     * @return string
     */
    private function getOriginalFieldId(Group $group, string $fieldId): string
    {
        if ($group-&gt;shouldCloneFields()) {
            $cloneModel = $group-&gt;getCloneModel();
            /** @var \Magento\Config\Model\Config\Structure\Element\Field $field */
            foreach ($group-&gt;getChildren() as $field) {
                foreach ($cloneModel-&gt;getPrefixes() as $prefix) {
                    if ($prefix['field'] . $field-&gt;getId() === $fieldId) {
                        $fieldId = $field-&gt;getId();
                        break(2);
                    }
                }
            }
        }
        return $fieldId;
    }
    /**
     * Get field object
     *
     * @param string $sectionId
     * @param string $groupId
     * @param string $fieldId
     * @return Field
     */
    private function getField(string $sectionId, string $groupId, string $fieldId): Field
    {
        /** @var \Magento\Config\Model\Config\Structure\Element\Group $group */
        $group = $this-&gt;_configStructure-&gt;getElement($sectionId . '/' . $groupId);
        $fieldPath = $group-&gt;getPath() . '/' . $this-&gt;getOriginalFieldId($group, $fieldId);
        $field = $this-&gt;_configStructure-&gt;getElement($fieldPath);
        return $field;
    }
    /**
     * Get field path
     *
     * @param Field $field
     * @param array &amp;$oldConfig Need for compatibility with _processGroup()
     * @param array &amp;$extraOldGroups Need for compatibility with _processGroup()
     * @return string
     */
    private function getFieldPath(Field $field, array &amp;$oldConfig, array &amp;$extraOldGroups): string
    {
        $path = $field-&gt;getGroupPath() . '/' . $field-&gt;getId();
        /**
         * Look for custom defined field path
         */
        $configPath = $field-&gt;getConfigPath();
        if ($configPath &amp;&amp; strrpos($configPath, '/') &gt; 0) {
            // Extend old data with specified section group
            $configGroupPath = substr($configPath, 0, strrpos($configPath, '/'));
            if (!isset($extraOldGroups[$configGroupPath])) {
                $oldConfig = $this-&gt;extendConfig($configGroupPath, true, $oldConfig);
                $extraOldGroups[$configGroupPath] = true;
            }
            $path = $configPath;
        }
        return $path;
    }
    /**
     * Check is config value changed
     *
     * @param array $oldConfig
     * @param string $path
     * @param array $fieldData
     * @return bool
     */
    private function isValueChanged(array $oldConfig, string $path, array $fieldData): bool
    {
        if (isset($oldConfig[$path]['value'])) {
            $result = !isset($fieldData['value']) || $oldConfig[$path]['value'] !== $fieldData['value'];
        } else {
            $result = empty($fieldData['inherit']);
        }
        return $result;
    }
    /**
     * Get changed paths
     *
     * @param string $sectionId
     * @param string $groupId
     * @param array $groupData
     * @param array &amp;$oldConfig
     * @param array &amp;$extraOldGroups
     * @return array
     */
    private function getChangedPaths(
        string $sectionId,
        string $groupId,
        array $groupData,
        array &amp;$oldConfig,
        array &amp;$extraOldGroups
    ): array {
        $changedPaths = [];
        if (isset($groupData['fields'])) {
            foreach ($groupData['fields'] as $fieldId =&gt; $fieldData) {
                $field = $this-&gt;getField($sectionId, $groupId, $fieldId);
                $path = $this-&gt;getFieldPath($field, $oldConfig, $extraOldGroups);
                if ($this-&gt;isValueChanged($oldConfig, $path, $fieldData)) {
                    $changedPaths[] = $path;
                }
            }
        }
        if (isset($groupData['groups'])) {
            $subSectionId = $sectionId . '/' . $groupId;
            foreach ($groupData['groups'] as $subGroupId =&gt; $subGroupData) {
                $subGroupChangedPaths = $this-&gt;getChangedPaths(
                    $subSectionId,
                    $subGroupId,
                    $subGroupData,
                    $oldConfig,
                    $extraOldGroups
                );
                $changedPaths = \array_merge($changedPaths, $subGroupChangedPaths);
            }
        }
        return $changedPaths;
    }
    /**
     * Process group data
     *
     * @param string $groupId
     * @param array $groupData
     * @param array $groups
     * @param string $sectionPath
     * @param array &amp;$extraOldGroups
     * @param array &amp;$oldConfig
     * @param \Magento\Framework\DB\Transaction $saveTransaction
     * @param \Magento\Framework\DB\Transaction $deleteTransaction
     * @return void
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     * @SuppressWarnings(PHPMD.NPathComplexity)
     */
    protected function _processGroup(
        $groupId,
        array $groupData,
        array $groups,
        $sectionPath,
        array &amp;$extraOldGroups,
        array &amp;$oldConfig,
        \Magento\Framework\DB\Transaction $saveTransaction,
        \Magento\Framework\DB\Transaction $deleteTransaction
    ) {
        $groupPath = $sectionPath . '/' . $groupId;
        if (isset($groupData['fields'])) {
            /** @var \Magento\Config\Model\Config\Structure\Element\Group $group */
            $group = $this-&gt;_configStructure-&gt;getElement($groupPath);
            // set value for group field entry by fieldname
            // use extra memory
            $fieldsetData = [];
            foreach ($groupData['fields'] as $fieldId =&gt; $fieldData) {
                $fieldsetData[$fieldId] = $fieldData['value'] ?? null;
            }
            foreach ($groupData['fields'] as $fieldId =&gt; $fieldData) {
                $isReadOnly = $this-&gt;settingChecker-&gt;isReadOnly(
                    $groupPath . '/' . $fieldId,
                    $this-&gt;getScope(),
                    $this-&gt;getScopeCode()
                );
                if ($isReadOnly) {
                    continue;
                }
                $field = $this-&gt;getField($sectionPath, $groupId, $fieldId);
                /** @var \Magento\Framework\App\Config\ValueInterface $backendModel */
                $backendModel = $field-&gt;hasBackendModel()
                    ? $field-&gt;getBackendModel()
                    : $this-&gt;_configValueFactory-&gt;create();
                if (!isset($fieldData['value'])) {
                    $fieldData['value'] = null;
                }
                $data = [
                    'field' =&gt; $fieldId,
                    'groups' =&gt; $groups,
                    'group_id' =&gt; $group-&gt;getId(),
                    'scope' =&gt; $this-&gt;getScope(),
                    'scope_id' =&gt; $this-&gt;getScopeId(),
                    'scope_code' =&gt; $this-&gt;getScopeCode(),
                    'field_config' =&gt; $field-&gt;getData(),
                    'fieldset_data' =&gt; $fieldsetData,
                ];
                $backendModel-&gt;addData($data);
                $this-&gt;_checkSingleStoreMode($field, $backendModel);
                $path = $this-&gt;getFieldPath($field, $extraOldGroups, $oldConfig);
                $backendModel-&gt;setPath($path)-&gt;setValue($fieldData['value']);
                $inherit = !empty($fieldData['inherit']);
                if (isset($oldConfig[$path])) {
                    $backendModel-&gt;setConfigId($oldConfig[$path]['config_id']);
                    /**
                     * Delete config data if inherit
                     */
                    if (!$inherit) {
                        $saveTransaction-&gt;addObject($backendModel);
                    } else {
                        $deleteTransaction-&gt;addObject($backendModel);
                    }
                } elseif (!$inherit) {
                    $backendModel-&gt;unsConfigId();
                    $saveTransaction-&gt;addObject($backendModel);
                }
            }
        }
        if (isset($groupData['groups'])) {
            foreach ($groupData['groups'] as $subGroupId =&gt; $subGroupData) {
                $this-&gt;_processGroup(
                    $subGroupId,
                    $subGroupData,
                    $groups,
                    $groupPath,
                    $extraOldGroups,
                    $oldConfig,
                    $saveTransaction,
                    $deleteTransaction
                );
            }
        }
    }
....
}" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki monokai" style="background-color: #272822" tabindex="0"><code><span class="line"><span style="color: #66D9EF; font-style: italic">class</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E; text-decoration: underline">Config</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">extends</span><span style="color: #F8F8F2"> \Magento\Framework\</span><span style="color: #A6E22E; font-style: italic; text-decoration: underline">DataObject</span></span>
<span class="line"><span style="color: #F8F8F2">{</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * Config data for sections</span></span>
<span class="line"><span style="color: #88846F">     *</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@var</span><span style="color: #88846F"> </span><span style="color: #F92672">array</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">protected</span><span style="color: #F8F8F2"> $_configData;</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * Event dispatcher</span></span>
<span class="line"><span style="color: #88846F">     *</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@var</span><span style="color: #88846F"> \Magento\Framework\Event\</span><span style="color: #66D9EF; font-style: italic">ManagerInterface</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">protected</span><span style="color: #F8F8F2"> $_eventManager;</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * System configuration structure</span></span>
<span class="line"><span style="color: #88846F">     *</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@var</span><span style="color: #88846F"> \Magento\Config\Model\Config\</span><span style="color: #66D9EF; font-style: italic">Structure</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">protected</span><span style="color: #F8F8F2"> $_configStructure;</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * Application config</span></span>
<span class="line"><span style="color: #88846F">     *</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@var</span><span style="color: #88846F"> \Magento\Framework\App\Config\</span><span style="color: #66D9EF; font-style: italic">ScopeConfigInterface</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">protected</span><span style="color: #F8F8F2"> $_appConfig;</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * Global factory</span></span>
<span class="line"><span style="color: #88846F">     *</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@var</span><span style="color: #88846F"> \Magento\Framework\App\Config\</span><span style="color: #66D9EF; font-style: italic">ScopeConfigInterface</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">protected</span><span style="color: #F8F8F2"> $_objectFactory;</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * TransactionFactory</span></span>
<span class="line"><span style="color: #88846F">     *</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@var</span><span style="color: #88846F"> \Magento\Framework\DB\</span><span style="color: #66D9EF; font-style: italic">TransactionFactory</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">protected</span><span style="color: #F8F8F2"> $_transactionFactory;</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * Config data loader</span></span>
<span class="line"><span style="color: #88846F">     *</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@var</span><span style="color: #88846F"> \Magento\Config\Model\Config\</span><span style="color: #66D9EF; font-style: italic">Loader</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">protected</span><span style="color: #F8F8F2"> $_configLoader;</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * Config data factory</span></span>
<span class="line"><span style="color: #88846F">     *</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@var</span><span style="color: #88846F"> \Magento\Framework\App\Config\</span><span style="color: #66D9EF; font-style: italic">ValueFactory</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">protected</span><span style="color: #F8F8F2"> $_configValueFactory;</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@var</span><span style="color: #88846F"> \Magento\Store\Model\</span><span style="color: #66D9EF; font-style: italic">StoreManagerInterface</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">protected</span><span style="color: #F8F8F2"> $_storeManager;</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@var</span><span style="color: #88846F"> Config\Reader\Source\Deployed\</span><span style="color: #66D9EF; font-style: italic">SettingChecker</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">private</span><span style="color: #F8F8F2"> $settingChecker;</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> \Magento\Framework\App\Config\</span><span style="color: #66D9EF; font-style: italic">ReinitableConfigInterface</span><span style="color: #88846F"> $config</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> \Magento\Framework\Event\</span><span style="color: #66D9EF; font-style: italic">ManagerInterface</span><span style="color: #88846F"> $eventManager</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> \Magento\Config\Model\Config\</span><span style="color: #66D9EF; font-style: italic">Structure</span><span style="color: #88846F"> $configStructure</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> \Magento\Framework\DB\</span><span style="color: #66D9EF; font-style: italic">TransactionFactory</span><span style="color: #88846F"> $transactionFactory</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> \Magento\Config\Model\Config\</span><span style="color: #66D9EF; font-style: italic">Loader</span><span style="color: #88846F"> $configLoader</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> \Magento\Framework\App\Config\</span><span style="color: #66D9EF; font-style: italic">ValueFactory</span><span style="color: #88846F"> $configValueFactory</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> \Magento\Store\Model\</span><span style="color: #66D9EF; font-style: italic">StoreManagerInterface</span><span style="color: #88846F"> $storeManager</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> Config\Reader\Source\Deployed\</span><span style="color: #66D9EF; font-style: italic">SettingChecker</span><span style="color: #88846F">|</span><span style="color: #F92672">null</span><span style="color: #88846F"> $settingChecker</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> </span><span style="color: #F92672">array</span><span style="color: #88846F"> $data</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">public</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF">__construct</span><span style="color: #F8F8F2">(</span></span>
<span class="line"><span style="color: #F8F8F2">        \Magento\Framework\App\Config\</span><span style="color: #66D9EF; font-style: italic">ReinitableConfigInterface</span><span style="color: #F8F8F2"> $config,</span></span>
<span class="line"><span style="color: #F8F8F2">        \Magento\Framework\Event\</span><span style="color: #66D9EF; font-style: italic">ManagerInterface</span><span style="color: #F8F8F2"> $eventManager,</span></span>
<span class="line"><span style="color: #F8F8F2">        \Magento\Config\Model\Config\</span><span style="color: #66D9EF; font-style: italic">Structure</span><span style="color: #F8F8F2"> $configStructure,</span></span>
<span class="line"><span style="color: #F8F8F2">        \Magento\Framework\DB\</span><span style="color: #66D9EF; font-style: italic">TransactionFactory</span><span style="color: #F8F8F2"> $transactionFactory,</span></span>
<span class="line"><span style="color: #F8F8F2">        \Magento\Config\Model\Config\</span><span style="color: #66D9EF; font-style: italic">Loader</span><span style="color: #F8F8F2"> $configLoader,</span></span>
<span class="line"><span style="color: #F8F8F2">        \Magento\Framework\App\Config\</span><span style="color: #66D9EF; font-style: italic">ValueFactory</span><span style="color: #F8F8F2"> $configValueFactory,</span></span>
<span class="line"><span style="color: #F8F8F2">        \Magento\Store\Model\</span><span style="color: #66D9EF; font-style: italic">StoreManagerInterface</span><span style="color: #F8F8F2"> $storeManager,</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #66D9EF; font-style: italic">SettingChecker</span><span style="color: #F8F8F2"> $settingChecker </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">null</span><span style="color: #F8F8F2">,</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">array</span><span style="color: #F8F8F2"> $data </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> []</span></span>
<span class="line"><span style="color: #F8F8F2">    ) {</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #66D9EF; font-style: italic">parent</span><span style="color: #F92672">::</span><span style="color: #A6E22E">__construct</span><span style="color: #F8F8F2">($data);</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">_eventManager </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $eventManager;</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">_configStructure </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $configStructure;</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">_transactionFactory </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $transactionFactory;</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">_appConfig </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $config;</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">_configLoader </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $configLoader;</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">_configValueFactory </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $configValueFactory;</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">_storeManager </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $storeManager;</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">settingChecker </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $settingChecker </span><span style="color: #F92672">?:</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">ObjectManager</span><span style="color: #F92672">::</span><span style="color: #A6E22E">getInstance</span><span style="color: #F8F8F2">()</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">get</span><span style="color: #F8F8F2">(</span><span style="color: #66D9EF; font-style: italic">SettingChecker</span><span style="color: #F92672">::class</span><span style="color: #F8F8F2">);</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * Save config section</span></span>
<span class="line"><span style="color: #88846F">     * Require set: section, website, store and groups</span></span>
<span class="line"><span style="color: #88846F">     *</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@throws</span><span style="color: #88846F"> </span><span style="color: #66D9EF; font-style: italic">\Exception</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@return</span><span style="color: #88846F"> $this</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">public</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">save</span><span style="color: #F8F8F2">()</span></span>
<span class="line"><span style="color: #F8F8F2">    {</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">initScope</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">        $sectionId </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getSection</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">        $groups </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getGroups</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> (</span><span style="color: #66D9EF">empty</span><span style="color: #F8F8F2">($groups)) {</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #F92672">return</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F8F8F2">;</span></span>
<span class="line"><span style="color: #F8F8F2">        }</span></span>
<span class="line"><span style="color: #F8F8F2">        $oldConfig </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">_getConfig</span><span style="color: #F8F8F2">(</span><span style="color: #AE81FF">true</span><span style="color: #F8F8F2">);</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #88846F">/** </span><span style="color: #F92672">@var</span><span style="color: #88846F"> \Magento\Framework\DB\</span><span style="color: #66D9EF; font-style: italic">Transaction</span><span style="color: #88846F"> $deleteTransaction */</span></span>
<span class="line"><span style="color: #F8F8F2">        $deleteTransaction </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">_transactionFactory</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">create</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #88846F">/** </span><span style="color: #F92672">@var</span><span style="color: #88846F"> \Magento\Framework\DB\</span><span style="color: #66D9EF; font-style: italic">Transaction</span><span style="color: #88846F"> $saveTransaction */</span></span>
<span class="line"><span style="color: #F8F8F2">        $saveTransaction </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">_transactionFactory</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">create</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">        $changedPaths </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> [];</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #88846F">// Extends for old config data</span></span>
<span class="line"><span style="color: #F8F8F2">        $extraOldGroups </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> [];</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">foreach</span><span style="color: #F8F8F2"> ($groups </span><span style="color: #F92672">as</span><span style="color: #F8F8F2"> $groupId </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> $groupData) {</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">_processGroup</span><span style="color: #F8F8F2">(</span></span>
<span class="line"><span style="color: #F8F8F2">                $groupId,</span></span>
<span class="line"><span style="color: #F8F8F2">                $groupData,</span></span>
<span class="line"><span style="color: #F8F8F2">                $groups,</span></span>
<span class="line"><span style="color: #F8F8F2">                $sectionId,</span></span>
<span class="line"><span style="color: #F8F8F2">                $extraOldGroups,</span></span>
<span class="line"><span style="color: #F8F8F2">                $oldConfig,</span></span>
<span class="line"><span style="color: #F8F8F2">                $saveTransaction,</span></span>
<span class="line"><span style="color: #F8F8F2">                $deleteTransaction</span></span>
<span class="line"><span style="color: #F8F8F2">            );</span></span>
<span class="line"><span style="color: #F8F8F2">            $groupChangedPaths </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getChangedPaths</span><span style="color: #F8F8F2">($sectionId, $groupId, $groupData, $oldConfig, $extraOldGroups);</span></span>
<span class="line"><span style="color: #F8F8F2">            $changedPaths </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> \</span><span style="color: #66D9EF">array_merge</span><span style="color: #F8F8F2">($changedPaths, $groupChangedPaths);</span></span>
<span class="line"><span style="color: #F8F8F2">        }</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">try</span><span style="color: #F8F8F2"> {</span></span>
<span class="line"><span style="color: #F8F8F2">            $deleteTransaction</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">delete</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">            $saveTransaction</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">save</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #88846F">// re-init configuration</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">_appConfig</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">reinit</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #88846F">// website and store codes can be used in event implementation, so set them as well</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">_eventManager</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">dispatch</span><span style="color: #F8F8F2">(</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #E6DB74">&quot;admin_system_config_changed_section_{</span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getSection</span><span style="color: #E6DB74">()}&quot;</span><span style="color: #F8F8F2">,</span></span>
<span class="line"><span style="color: #F8F8F2">                [</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #E6DB74">&#39;website&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getWebsite</span><span style="color: #F8F8F2">(),</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #E6DB74">&#39;store&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getStore</span><span style="color: #F8F8F2">(),</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #E6DB74">&#39;changed_paths&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> $changedPaths,</span></span>
<span class="line"><span style="color: #F8F8F2">                ]</span></span>
<span class="line"><span style="color: #F8F8F2">            );</span></span>
<span class="line"><span style="color: #F8F8F2">        } </span><span style="color: #F92672">catch</span><span style="color: #F8F8F2"> (\</span><span style="color: #66D9EF; font-style: italic">Exception</span><span style="color: #F8F8F2"> $e) {</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #88846F">// re-init configuration</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">_appConfig</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">reinit</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #F92672">throw</span><span style="color: #F8F8F2"> $e;</span></span>
<span class="line"><span style="color: #F8F8F2">        }</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">return</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F8F8F2">;</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * Map field name if they were cloned</span></span>
<span class="line"><span style="color: #88846F">     *</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> </span><span style="color: #66D9EF; font-style: italic">Group</span><span style="color: #88846F"> $group</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> </span><span style="color: #F92672">string</span><span style="color: #88846F"> $fieldId</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@return</span><span style="color: #88846F"> </span><span style="color: #F92672">string</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">private</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">getOriginalFieldId</span><span style="color: #F8F8F2">(</span><span style="color: #66D9EF; font-style: italic">Group</span><span style="color: #F8F8F2"> $group, </span><span style="color: #F92672">string</span><span style="color: #F8F8F2"> $fieldId)</span><span style="color: #F92672">:</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">string</span></span>
<span class="line"><span style="color: #F8F8F2">    {</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> ($group</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">shouldCloneFields</span><span style="color: #F8F8F2">()) {</span></span>
<span class="line"><span style="color: #F8F8F2">            $cloneModel </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $group</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getCloneModel</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #88846F">/** </span><span style="color: #F92672">@var</span><span style="color: #88846F"> \Magento\Config\Model\Config\Structure\Element\</span><span style="color: #66D9EF; font-style: italic">Field</span><span style="color: #88846F"> $field */</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #F92672">foreach</span><span style="color: #F8F8F2"> ($group</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getChildren</span><span style="color: #F8F8F2">() </span><span style="color: #F92672">as</span><span style="color: #F8F8F2"> $field) {</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #F92672">foreach</span><span style="color: #F8F8F2"> ($cloneModel</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getPrefixes</span><span style="color: #F8F8F2">() </span><span style="color: #F92672">as</span><span style="color: #F8F8F2"> $prefix) {</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> ($prefix[</span><span style="color: #E6DB74">&#39;field&#39;</span><span style="color: #F8F8F2">] </span><span style="color: #F92672">.</span><span style="color: #F8F8F2"> $field</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getId</span><span style="color: #F8F8F2">() </span><span style="color: #F92672">===</span><span style="color: #F8F8F2"> $fieldId) {</span></span>
<span class="line"><span style="color: #F8F8F2">                        $fieldId </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $field</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getId</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">                        </span><span style="color: #F92672">break</span><span style="color: #F8F8F2">(</span><span style="color: #AE81FF">2</span><span style="color: #F8F8F2">);</span></span>
<span class="line"><span style="color: #F8F8F2">                    }</span></span>
<span class="line"><span style="color: #F8F8F2">                }</span></span>
<span class="line"><span style="color: #F8F8F2">            }</span></span>
<span class="line"><span style="color: #F8F8F2">        }</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">return</span><span style="color: #F8F8F2"> $fieldId;</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * Get field object</span></span>
<span class="line"><span style="color: #88846F">     *</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> </span><span style="color: #F92672">string</span><span style="color: #88846F"> $sectionId</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> </span><span style="color: #F92672">string</span><span style="color: #88846F"> $groupId</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> </span><span style="color: #F92672">string</span><span style="color: #88846F"> $fieldId</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@return</span><span style="color: #88846F"> </span><span style="color: #66D9EF; font-style: italic">Field</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">private</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">getField</span><span style="color: #F8F8F2">(</span><span style="color: #F92672">string</span><span style="color: #F8F8F2"> $sectionId, </span><span style="color: #F92672">string</span><span style="color: #F8F8F2"> $groupId, </span><span style="color: #F92672">string</span><span style="color: #F8F8F2"> $fieldId)</span><span style="color: #F92672">:</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">Field</span></span>
<span class="line"><span style="color: #F8F8F2">    {</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #88846F">/** </span><span style="color: #F92672">@var</span><span style="color: #88846F"> \Magento\Config\Model\Config\Structure\Element\</span><span style="color: #66D9EF; font-style: italic">Group</span><span style="color: #88846F"> $group */</span></span>
<span class="line"><span style="color: #F8F8F2">        $group </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">_configStructure</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getElement</span><span style="color: #F8F8F2">($sectionId </span><span style="color: #F92672">.</span><span style="color: #F8F8F2"> </span><span style="color: #E6DB74">&#39;/&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">.</span><span style="color: #F8F8F2"> $groupId);</span></span>
<span class="line"><span style="color: #F8F8F2">        $fieldPath </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $group</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getPath</span><span style="color: #F8F8F2">() </span><span style="color: #F92672">.</span><span style="color: #F8F8F2"> </span><span style="color: #E6DB74">&#39;/&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">.</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getOriginalFieldId</span><span style="color: #F8F8F2">($group, $fieldId);</span></span>
<span class="line"><span style="color: #F8F8F2">        $field </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">_configStructure</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getElement</span><span style="color: #F8F8F2">($fieldPath);</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">return</span><span style="color: #F8F8F2"> $field;</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * Get field path</span></span>
<span class="line"><span style="color: #88846F">     *</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> </span><span style="color: #66D9EF; font-style: italic">Field</span><span style="color: #88846F"> $field</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> </span><span style="color: #F92672">array</span><span style="color: #88846F"> &amp;$oldConfig Need for compatibility with _processGroup()</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> </span><span style="color: #F92672">array</span><span style="color: #88846F"> &amp;$extraOldGroups Need for compatibility with _processGroup()</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@return</span><span style="color: #88846F"> </span><span style="color: #F92672">string</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">private</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">getFieldPath</span><span style="color: #F8F8F2">(</span><span style="color: #66D9EF; font-style: italic">Field</span><span style="color: #F8F8F2"> $field, </span><span style="color: #F92672">array</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">&amp;</span><span style="color: #F8F8F2">$oldConfig, </span><span style="color: #F92672">array</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">&amp;</span><span style="color: #F8F8F2">$extraOldGroups)</span><span style="color: #F92672">:</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">string</span></span>
<span class="line"><span style="color: #F8F8F2">    {</span></span>
<span class="line"><span style="color: #F8F8F2">        $path </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $field</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getGroupPath</span><span style="color: #F8F8F2">() </span><span style="color: #F92672">.</span><span style="color: #F8F8F2"> </span><span style="color: #E6DB74">&#39;/&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">.</span><span style="color: #F8F8F2"> $field</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getId</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">         * Look for custom defined field path</span></span>
<span class="line"><span style="color: #88846F">         */</span></span>
<span class="line"><span style="color: #F8F8F2">        $configPath </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $field</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getConfigPath</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> ($configPath </span><span style="color: #F92672">&amp;&amp;</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF">strrpos</span><span style="color: #F8F8F2">($configPath, </span><span style="color: #E6DB74">&#39;/&#39;</span><span style="color: #F8F8F2">) </span><span style="color: #F92672">&gt;</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">0</span><span style="color: #F8F8F2">) {</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #88846F">// Extend old data with specified section group</span></span>
<span class="line"><span style="color: #F8F8F2">            $configGroupPath </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF">substr</span><span style="color: #F8F8F2">($configPath, </span><span style="color: #AE81FF">0</span><span style="color: #F8F8F2">, </span><span style="color: #66D9EF">strrpos</span><span style="color: #F8F8F2">($configPath, </span><span style="color: #E6DB74">&#39;/&#39;</span><span style="color: #F8F8F2">));</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> (</span><span style="color: #F92672">!</span><span style="color: #66D9EF">isset</span><span style="color: #F8F8F2">($extraOldGroups[$configGroupPath])) {</span></span>
<span class="line"><span style="color: #F8F8F2">                $oldConfig </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">extendConfig</span><span style="color: #F8F8F2">($configGroupPath, </span><span style="color: #AE81FF">true</span><span style="color: #F8F8F2">, $oldConfig);</span></span>
<span class="line"><span style="color: #F8F8F2">                $extraOldGroups[$configGroupPath] </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">true</span><span style="color: #F8F8F2">;</span></span>
<span class="line"><span style="color: #F8F8F2">            }</span></span>
<span class="line"><span style="color: #F8F8F2">            $path </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $configPath;</span></span>
<span class="line"><span style="color: #F8F8F2">        }</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">return</span><span style="color: #F8F8F2"> $path;</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * Check is config value changed</span></span>
<span class="line"><span style="color: #88846F">     *</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> </span><span style="color: #F92672">array</span><span style="color: #88846F"> $oldConfig</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> </span><span style="color: #F92672">string</span><span style="color: #88846F"> $path</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> </span><span style="color: #F92672">array</span><span style="color: #88846F"> $fieldData</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@return</span><span style="color: #88846F"> </span><span style="color: #F92672">bool</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">private</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">isValueChanged</span><span style="color: #F8F8F2">(</span><span style="color: #F92672">array</span><span style="color: #F8F8F2"> $oldConfig, </span><span style="color: #F92672">string</span><span style="color: #F8F8F2"> $path, </span><span style="color: #F92672">array</span><span style="color: #F8F8F2"> $fieldData)</span><span style="color: #F92672">:</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">bool</span></span>
<span class="line"><span style="color: #F8F8F2">    {</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> (</span><span style="color: #66D9EF">isset</span><span style="color: #F8F8F2">($oldConfig[$path][</span><span style="color: #E6DB74">&#39;value&#39;</span><span style="color: #F8F8F2">])) {</span></span>
<span class="line"><span style="color: #F8F8F2">            $result </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">!</span><span style="color: #66D9EF">isset</span><span style="color: #F8F8F2">($fieldData[</span><span style="color: #E6DB74">&#39;value&#39;</span><span style="color: #F8F8F2">]) </span><span style="color: #F92672">||</span><span style="color: #F8F8F2"> $oldConfig[$path][</span><span style="color: #E6DB74">&#39;value&#39;</span><span style="color: #F8F8F2">] </span><span style="color: #F92672">!==</span><span style="color: #F8F8F2"> $fieldData[</span><span style="color: #E6DB74">&#39;value&#39;</span><span style="color: #F8F8F2">];</span></span>
<span class="line"><span style="color: #F8F8F2">        } </span><span style="color: #F92672">else</span><span style="color: #F8F8F2"> {</span></span>
<span class="line"><span style="color: #F8F8F2">            $result </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF">empty</span><span style="color: #F8F8F2">($fieldData[</span><span style="color: #E6DB74">&#39;inherit&#39;</span><span style="color: #F8F8F2">]);</span></span>
<span class="line"><span style="color: #F8F8F2">        }</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">return</span><span style="color: #F8F8F2"> $result;</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * Get changed paths</span></span>
<span class="line"><span style="color: #88846F">     *</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> </span><span style="color: #F92672">string</span><span style="color: #88846F"> $sectionId</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> </span><span style="color: #F92672">string</span><span style="color: #88846F"> $groupId</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> </span><span style="color: #F92672">array</span><span style="color: #88846F"> $groupData</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> </span><span style="color: #F92672">array</span><span style="color: #88846F"> &amp;$oldConfig</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> </span><span style="color: #F92672">array</span><span style="color: #88846F"> &amp;$extraOldGroups</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@return</span><span style="color: #88846F"> </span><span style="color: #F92672">array</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">private</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">getChangedPaths</span><span style="color: #F8F8F2">(</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">string</span><span style="color: #F8F8F2"> $sectionId,</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">string</span><span style="color: #F8F8F2"> $groupId,</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">array</span><span style="color: #F8F8F2"> $groupData,</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">array</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">&amp;</span><span style="color: #F8F8F2">$oldConfig,</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">array</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">&amp;</span><span style="color: #F8F8F2">$extraOldGroups</span></span>
<span class="line"><span style="color: #F8F8F2">    )</span><span style="color: #F92672">:</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">array</span><span style="color: #F8F8F2"> {</span></span>
<span class="line"><span style="color: #F8F8F2">        $changedPaths </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> [];</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> (</span><span style="color: #66D9EF">isset</span><span style="color: #F8F8F2">($groupData[</span><span style="color: #E6DB74">&#39;fields&#39;</span><span style="color: #F8F8F2">])) {</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #F92672">foreach</span><span style="color: #F8F8F2"> ($groupData[</span><span style="color: #E6DB74">&#39;fields&#39;</span><span style="color: #F8F8F2">] </span><span style="color: #F92672">as</span><span style="color: #F8F8F2"> $fieldId </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> $fieldData) {</span></span>
<span class="line"><span style="color: #F8F8F2">                $field </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getField</span><span style="color: #F8F8F2">($sectionId, $groupId, $fieldId);</span></span>
<span class="line"><span style="color: #F8F8F2">                $path </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getFieldPath</span><span style="color: #F8F8F2">($field, $oldConfig, $extraOldGroups);</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> (</span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">isValueChanged</span><span style="color: #F8F8F2">($oldConfig, $path, $fieldData)) {</span></span>
<span class="line"><span style="color: #F8F8F2">                    $changedPaths[] </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $path;</span></span>
<span class="line"><span style="color: #F8F8F2">                }</span></span>
<span class="line"><span style="color: #F8F8F2">            }</span></span>
<span class="line"><span style="color: #F8F8F2">        }</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> (</span><span style="color: #66D9EF">isset</span><span style="color: #F8F8F2">($groupData[</span><span style="color: #E6DB74">&#39;groups&#39;</span><span style="color: #F8F8F2">])) {</span></span>
<span class="line"><span style="color: #F8F8F2">            $subSectionId </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $sectionId </span><span style="color: #F92672">.</span><span style="color: #F8F8F2"> </span><span style="color: #E6DB74">&#39;/&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">.</span><span style="color: #F8F8F2"> $groupId;</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #F92672">foreach</span><span style="color: #F8F8F2"> ($groupData[</span><span style="color: #E6DB74">&#39;groups&#39;</span><span style="color: #F8F8F2">] </span><span style="color: #F92672">as</span><span style="color: #F8F8F2"> $subGroupId </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> $subGroupData) {</span></span>
<span class="line"><span style="color: #F8F8F2">                $subGroupChangedPaths </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getChangedPaths</span><span style="color: #F8F8F2">(</span></span>
<span class="line"><span style="color: #F8F8F2">                    $subSectionId,</span></span>
<span class="line"><span style="color: #F8F8F2">                    $subGroupId,</span></span>
<span class="line"><span style="color: #F8F8F2">                    $subGroupData,</span></span>
<span class="line"><span style="color: #F8F8F2">                    $oldConfig,</span></span>
<span class="line"><span style="color: #F8F8F2">                    $extraOldGroups</span></span>
<span class="line"><span style="color: #F8F8F2">                );</span></span>
<span class="line"><span style="color: #F8F8F2">                $changedPaths </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> \</span><span style="color: #66D9EF">array_merge</span><span style="color: #F8F8F2">($changedPaths, $subGroupChangedPaths);</span></span>
<span class="line"><span style="color: #F8F8F2">            }</span></span>
<span class="line"><span style="color: #F8F8F2">        }</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">return</span><span style="color: #F8F8F2"> $changedPaths;</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">     * Process group data</span></span>
<span class="line"><span style="color: #88846F">     *</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> </span><span style="color: #F92672">string</span><span style="color: #88846F"> $groupId</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> </span><span style="color: #F92672">array</span><span style="color: #88846F"> $groupData</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> </span><span style="color: #F92672">array</span><span style="color: #88846F"> $groups</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> </span><span style="color: #F92672">string</span><span style="color: #88846F"> $sectionPath</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> </span><span style="color: #F92672">array</span><span style="color: #88846F"> &amp;$extraOldGroups</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> </span><span style="color: #F92672">array</span><span style="color: #88846F"> &amp;$oldConfig</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> \Magento\Framework\DB\</span><span style="color: #66D9EF; font-style: italic">Transaction</span><span style="color: #88846F"> $saveTransaction</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@param</span><span style="color: #88846F"> \Magento\Framework\DB\</span><span style="color: #66D9EF; font-style: italic">Transaction</span><span style="color: #88846F"> $deleteTransaction</span></span>
<span class="line"><span style="color: #88846F">     * </span><span style="color: #F92672">@return</span><span style="color: #88846F"> </span><span style="color: #F92672">void</span></span>
<span class="line"><span style="color: #88846F">     * @SuppressWarnings(PHPMD.CyclomaticComplexity)</span></span>
<span class="line"><span style="color: #88846F">     * @SuppressWarnings(PHPMD.NPathComplexity)</span></span>
<span class="line"><span style="color: #88846F">     */</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">protected</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">_processGroup</span><span style="color: #F8F8F2">(</span></span>
<span class="line"><span style="color: #F8F8F2">        $groupId,</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">array</span><span style="color: #F8F8F2"> $groupData,</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">array</span><span style="color: #F8F8F2"> $groups,</span></span>
<span class="line"><span style="color: #F8F8F2">        $sectionPath,</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">array</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">&amp;</span><span style="color: #F8F8F2">$extraOldGroups,</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">array</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">&amp;</span><span style="color: #F8F8F2">$oldConfig,</span></span>
<span class="line"><span style="color: #F8F8F2">        \Magento\Framework\DB\</span><span style="color: #66D9EF; font-style: italic">Transaction</span><span style="color: #F8F8F2"> $saveTransaction,</span></span>
<span class="line"><span style="color: #F8F8F2">        \Magento\Framework\DB\</span><span style="color: #66D9EF; font-style: italic">Transaction</span><span style="color: #F8F8F2"> $deleteTransaction</span></span>
<span class="line"><span style="color: #F8F8F2">    ) {</span></span>
<span class="line"><span style="color: #F8F8F2">        $groupPath </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $sectionPath </span><span style="color: #F92672">.</span><span style="color: #F8F8F2"> </span><span style="color: #E6DB74">&#39;/&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">.</span><span style="color: #F8F8F2"> $groupId;</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> (</span><span style="color: #66D9EF">isset</span><span style="color: #F8F8F2">($groupData[</span><span style="color: #E6DB74">&#39;fields&#39;</span><span style="color: #F8F8F2">])) {</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #88846F">/** </span><span style="color: #F92672">@var</span><span style="color: #88846F"> \Magento\Config\Model\Config\Structure\Element\</span><span style="color: #66D9EF; font-style: italic">Group</span><span style="color: #88846F"> $group */</span></span>
<span class="line"><span style="color: #F8F8F2">            $group </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">_configStructure</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getElement</span><span style="color: #F8F8F2">($groupPath);</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #88846F">// set value for group field entry by fieldname</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #88846F">// use extra memory</span></span>
<span class="line"><span style="color: #F8F8F2">            $fieldsetData </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> [];</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #F92672">foreach</span><span style="color: #F8F8F2"> ($groupData[</span><span style="color: #E6DB74">&#39;fields&#39;</span><span style="color: #F8F8F2">] </span><span style="color: #F92672">as</span><span style="color: #F8F8F2"> $fieldId </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> $fieldData) {</span></span>
<span class="line"><span style="color: #F8F8F2">                $fieldsetData[$fieldId] </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $fieldData[</span><span style="color: #E6DB74">&#39;value&#39;</span><span style="color: #F8F8F2">] </span><span style="color: #F92672">??</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">null</span><span style="color: #F8F8F2">;</span></span>
<span class="line"><span style="color: #F8F8F2">            }</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #F92672">foreach</span><span style="color: #F8F8F2"> ($groupData[</span><span style="color: #E6DB74">&#39;fields&#39;</span><span style="color: #F8F8F2">] </span><span style="color: #F92672">as</span><span style="color: #F8F8F2"> $fieldId </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> $fieldData) {</span></span>
<span class="line"><span style="color: #F8F8F2">                $isReadOnly </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">settingChecker</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">isReadOnly</span><span style="color: #F8F8F2">(</span></span>
<span class="line"><span style="color: #F8F8F2">                    $groupPath </span><span style="color: #F92672">.</span><span style="color: #F8F8F2"> </span><span style="color: #E6DB74">&#39;/&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">.</span><span style="color: #F8F8F2"> $fieldId,</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getScope</span><span style="color: #F8F8F2">(),</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getScopeCode</span><span style="color: #F8F8F2">()</span></span>
<span class="line"><span style="color: #F8F8F2">                );</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> ($isReadOnly) {</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #F92672">continue</span><span style="color: #F8F8F2">;</span></span>
<span class="line"><span style="color: #F8F8F2">                }</span></span>
<span class="line"><span style="color: #F8F8F2">                $field </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getField</span><span style="color: #F8F8F2">($sectionPath, $groupId, $fieldId);</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #88846F">/** </span><span style="color: #F92672">@var</span><span style="color: #88846F"> \Magento\Framework\App\Config\</span><span style="color: #66D9EF; font-style: italic">ValueInterface</span><span style="color: #88846F"> $backendModel */</span></span>
<span class="line"><span style="color: #F8F8F2">                $backendModel </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $field</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">hasBackendModel</span><span style="color: #F8F8F2">()</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #F92672">?</span><span style="color: #F8F8F2"> $field</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getBackendModel</span><span style="color: #F8F8F2">()</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #F92672">:</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">_configValueFactory</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">create</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> (</span><span style="color: #F92672">!</span><span style="color: #66D9EF">isset</span><span style="color: #F8F8F2">($fieldData[</span><span style="color: #E6DB74">&#39;value&#39;</span><span style="color: #F8F8F2">])) {</span></span>
<span class="line"><span style="color: #F8F8F2">                    $fieldData[</span><span style="color: #E6DB74">&#39;value&#39;</span><span style="color: #F8F8F2">] </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">null</span><span style="color: #F8F8F2">;</span></span>
<span class="line"><span style="color: #F8F8F2">                }</span></span>
<span class="line"><span style="color: #F8F8F2">                $data </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> [</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #E6DB74">&#39;field&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> $fieldId,</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #E6DB74">&#39;groups&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> $groups,</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #E6DB74">&#39;group_id&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> $group</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getId</span><span style="color: #F8F8F2">(),</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #E6DB74">&#39;scope&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getScope</span><span style="color: #F8F8F2">(),</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #E6DB74">&#39;scope_id&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getScopeId</span><span style="color: #F8F8F2">(),</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #E6DB74">&#39;scope_code&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getScopeCode</span><span style="color: #F8F8F2">(),</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #E6DB74">&#39;field_config&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> $field</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getData</span><span style="color: #F8F8F2">(),</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #E6DB74">&#39;fieldset_data&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> $fieldsetData,</span></span>
<span class="line"><span style="color: #F8F8F2">                ];</span></span>
<span class="line"><span style="color: #F8F8F2">                $backendModel</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">addData</span><span style="color: #F8F8F2">($data);</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">_checkSingleStoreMode</span><span style="color: #F8F8F2">($field, $backendModel);</span></span>
<span class="line"><span style="color: #F8F8F2">                $path </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getFieldPath</span><span style="color: #F8F8F2">($field, $extraOldGroups, $oldConfig);</span></span>
<span class="line"><span style="color: #F8F8F2">                $backendModel</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">setPath</span><span style="color: #F8F8F2">($path)</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">setValue</span><span style="color: #F8F8F2">($fieldData[</span><span style="color: #E6DB74">&#39;value&#39;</span><span style="color: #F8F8F2">]);</span></span>
<span class="line"><span style="color: #F8F8F2">                $inherit </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">!</span><span style="color: #66D9EF">empty</span><span style="color: #F8F8F2">($fieldData[</span><span style="color: #E6DB74">&#39;inherit&#39;</span><span style="color: #F8F8F2">]);</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> (</span><span style="color: #66D9EF">isset</span><span style="color: #F8F8F2">($oldConfig[$path])) {</span></span>
<span class="line"><span style="color: #F8F8F2">                    $backendModel</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">setConfigId</span><span style="color: #F8F8F2">($oldConfig[$path][</span><span style="color: #E6DB74">&#39;config_id&#39;</span><span style="color: #F8F8F2">]);</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">                     * Delete config data if inherit</span></span>
<span class="line"><span style="color: #88846F">                     */</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> (</span><span style="color: #F92672">!</span><span style="color: #F8F8F2">$inherit) {</span></span>
<span class="line"><span style="color: #F8F8F2">                        $saveTransaction</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">addObject</span><span style="color: #F8F8F2">($backendModel);</span></span>
<span class="line"><span style="color: #F8F8F2">                    } </span><span style="color: #F92672">else</span><span style="color: #F8F8F2"> {</span></span>
<span class="line"><span style="color: #F8F8F2">                        $deleteTransaction</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">addObject</span><span style="color: #F8F8F2">($backendModel);</span></span>
<span class="line"><span style="color: #F8F8F2">                    }</span></span>
<span class="line"><span style="color: #F8F8F2">                } </span><span style="color: #F92672">elseif</span><span style="color: #F8F8F2"> (</span><span style="color: #F92672">!</span><span style="color: #F8F8F2">$inherit) {</span></span>
<span class="line"><span style="color: #F8F8F2">                    $backendModel</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">unsConfigId</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">                    $saveTransaction</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">addObject</span><span style="color: #F8F8F2">($backendModel);</span></span>
<span class="line"><span style="color: #F8F8F2">                }</span></span>
<span class="line"><span style="color: #F8F8F2">            }</span></span>
<span class="line"><span style="color: #F8F8F2">        }</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> (</span><span style="color: #66D9EF">isset</span><span style="color: #F8F8F2">($groupData[</span><span style="color: #E6DB74">&#39;groups&#39;</span><span style="color: #F8F8F2">])) {</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #F92672">foreach</span><span style="color: #F8F8F2"> ($groupData[</span><span style="color: #E6DB74">&#39;groups&#39;</span><span style="color: #F8F8F2">] </span><span style="color: #F92672">as</span><span style="color: #F8F8F2"> $subGroupId </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> $subGroupData) {</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">_processGroup</span><span style="color: #F8F8F2">(</span></span>
<span class="line"><span style="color: #F8F8F2">                    $subGroupId,</span></span>
<span class="line"><span style="color: #F8F8F2">                    $subGroupData,</span></span>
<span class="line"><span style="color: #F8F8F2">                    $groups,</span></span>
<span class="line"><span style="color: #F8F8F2">                    $groupPath,</span></span>
<span class="line"><span style="color: #F8F8F2">                    $extraOldGroups,</span></span>
<span class="line"><span style="color: #F8F8F2">                    $oldConfig,</span></span>
<span class="line"><span style="color: #F8F8F2">                    $saveTransaction,</span></span>
<span class="line"><span style="color: #F8F8F2">                    $deleteTransaction</span></span>
<span class="line"><span style="color: #F8F8F2">                );</span></span>
<span class="line"><span style="color: #F8F8F2">            }</span></span>
<span class="line"><span style="color: #F8F8F2">        }</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span>
<span class="line"><span style="color: #F92672">...</span><span style="color: #F92672">.</span></span>
<span class="line"><span style="color: #F8F8F2">}</span></span></code></pre></div>



<p>As you can see, the save() method checks all groups of parameters sent to the server, and for each, it calls the _processGroup() method, while the final one calls the getField() method for each field.</p>



<p>The following happens in this method: the group of placeholders actually clones the same element for different EAV attributes that can implement the image. But at the same time, the getField method calls the getOriginalFieldId method, which returns the path catalog/placeholder/placeholder described in system.xml for any element.</p>



<p>This path will then be used to save the placeholder image in the core_config_data table. But this isn&#8217;t exactly what should be happening since the path to the placeholder configuration should be catalog/placeholder/image_placeholder for the default image, catalog/placeholder/small_image_placeholder for the listing image, etc.</p>



<div class="ufy-block">
<div class="ufy-block__wrapper">
<p class="ufy-block__label">Useful for you:</p>
<ul class="ufy-block__list">
<li class="ufy-block__item"><a href="https://web4pro.net/blog-news/broken-magento-shopping-cart-cause-and-solution/" target="_self" rel="noopener" data-wpel-link="internal">Broken Magento Shopping Cart: Cause and Solution</a></li>
<li><a href="https://web4pro.net/blog-news/managing-the-magento-2-2-4-category-tree-checkbox-bug/" target="_self" rel="noopener" data-wpel-link="internal">Managing the Magento 2.2.4 Category Tree Checkbox Bug</a></li>
<li><a href="https://web4pro.net/blog-news/amasty-rewards-1-5-0-fixing-a-checkout-bug/" target="_self" rel="noopener" data-wpel-link="internal">Amasty_Rewards 1.5.0. Fixing a Checkout Bug</a></li>
</ul>
</div>
</div>



<h2 class="wp-block-heading">Solution Using Plugin</h2>



<p>This problem needs to be solved, and the best way to do that is at the backend-model level. The back-end model in our case is implemented by the class Magento\Config\Model\Config\Backend\Image, which is inherited from Magento\Config\Model\Config\Backend\File. This is inherited from \Magento\Framework\App\Config\Value, which in turn is inherited from \Magento\Framework\Model\AbstractModel. But using the model&#8217;s event handler beforeSafe won&#8217;t work since the beforeSave method is redefined in the Magento\Config\Model\Config\Backend\File class without calling the parent method. So all that&#8217;s left is to implement the plugin as follows:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="&lt;type name=&quot;Magento\Config\Model\Config\Backend\Image&quot;&gt;
    &lt;plugin name=&quot;fix-placeholders&quot; type=&quot;Web4pro\Defaultproduct\Model\Plugin&quot; sortOrder=&quot;20&quot;/&gt;
&lt;/type&gt;" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki monokai" style="background-color: #272822" tabindex="0"><code><span class="line"><span style="color: #F8F8F2">&lt;</span><span style="color: #F92672">type</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">name</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;Magento\Config\Model\Config\Backend\Image&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">    &lt;</span><span style="color: #F92672">plugin</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">name</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;fix-placeholders&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">type</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;Web4pro\Defaultproduct\Model\Plugin&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">sortOrder</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;20&quot;</span><span style="color: #F8F8F2">/&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">&lt;/</span><span style="color: #F92672">type</span><span style="color: #F8F8F2">&gt;</span></span></code></pre></div>



<p>Plugin’s class will be the following:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="class Plugin
{
    public function beforeBeforeSave($subject){
        if(($f=$subject-&gt;getField())&amp;&amp;($subject-&gt;getPath()=='catalog/placeholder/placeholder')){
            $subject-&gt;setPath(str_replace('placeholder/placeholder','placeholder/'.$f,$subject-&gt;getPath()));
        }
        return array();
    }
}" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki monokai" style="background-color: #272822" tabindex="0"><code><span class="line"><span style="color: #66D9EF; font-style: italic">class</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E; text-decoration: underline">Plugin</span></span>
<span class="line"><span style="color: #F8F8F2">{</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">public</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">beforeBeforeSave</span><span style="color: #F8F8F2">($subject){</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">if</span><span style="color: #F8F8F2">(($f</span><span style="color: #F92672">=</span><span style="color: #F8F8F2">$subject</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getField</span><span style="color: #F8F8F2">())</span><span style="color: #F92672">&amp;&amp;</span><span style="color: #F8F8F2">($subject</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getPath</span><span style="color: #F8F8F2">()</span><span style="color: #F92672">==</span><span style="color: #E6DB74">&#39;catalog/placeholder/placeholder&#39;</span><span style="color: #F8F8F2">)){</span></span>
<span class="line"><span style="color: #F8F8F2">            $subject</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">setPath</span><span style="color: #F8F8F2">(</span><span style="color: #66D9EF">str_replace</span><span style="color: #F8F8F2">(</span><span style="color: #E6DB74">&#39;placeholder/placeholder&#39;</span><span style="color: #F8F8F2">,</span><span style="color: #E6DB74">&#39;placeholder/&#39;</span><span style="color: #F92672">.</span><span style="color: #F8F8F2">$f,$subject</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getPath</span><span style="color: #F8F8F2">()));</span></span>
<span class="line"><span style="color: #F8F8F2">        }</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">return</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF">array</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span>
<span class="line"><span style="color: #F8F8F2">}</span></span></code></pre></div>



<p>With this fix, the path to each placeholder in the core_config_data table will be unique and placeholders will be saved successfully by the site administrator.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Magento 1.x End of Life is June 2020 (Updated)</title>
		<link>https://web4pro.net/blog-news/magento-1-x-end-of-life-june-2020/</link>
		
		<dc:creator><![CDATA[web4pro_su]]></dc:creator>
		<pubDate>Mon, 18 Jun 2018 11:35:11 +0000</pubDate>
				<category><![CDATA[Magento 2]]></category>
		<category><![CDATA[eCommerce]]></category>
		<category><![CDATA[Magento]]></category>
		<category><![CDATA[platforms]]></category>
		<guid isPermaLink="false">https://web4pro.net/?p=4120</guid>

					<description><![CDATA[Magento 1.x support officially stops in June 2020. That means you need to prepare for changes and consider migration to Magento 2.]]></description>
										<content:encoded><![CDATA[<p>Friends, now read carefully, especially those, who owns the online store based on Magento®. A little bird told us (Twitter, to be exact) that a new Age of Magento was nearby. Yes, Magento 2 has all the chances to become the next strong foundation for your super-powerful online store. So you should start considering it as a new eCommerce tool right now.</p>
<p><b><img fetchpriority="high" decoding="async" class="aligncenter size-full wp-image-6846" src="https://s3.eu-central-1.amazonaws.com/web4pro.net-new/wp-content/uploads/2017/05/07083732/Screenshot1.png" alt="Magento Tweet. Support Update for Magento 1.x is June 2020" width="577" height="400" srcset="https://s3.eu-central-1.amazonaws.com/web4pro.net-new/wp-content/uploads/2017/05/07083732/Screenshot1.png 577w, https://s3.eu-central-1.amazonaws.com/web4pro.net-new/wp-content/uploads/2017/05/07083732/Screenshot1-300x208.png 300w" sizes="(max-width: 577px) 100vw, 577px" /><br />
June 2020. </b>Remember this time. It is when official Magento 1.x support will stop. And Magento 2 continues to conquer the market.<b><br />
</b></p>
<p><b>What does this mean for you?</b></p>
<ul>
<li>You should keep up to date because it will be the complete renewal of the eCommerce market: the new version is a future of technology, as always.</li>
<li>The official updates stop. Therefore, the risk of vulnerabilities in the system grows many times in case you use not an updated Magento version. Your website security requires much attention.</li>
<li>Magento community works on new extensions for Magento 2. Gradually, the number of modern solutions compatible with the Magento 1.x website will be not enough for your needs, while the number of Magento 2 extensions will increase on a daily basis.</li>
<li>You can now check the exact support dates for <a href="https://magento.com/sites/default/files/magento-open-source-software-maintenance-policy.pdf" target="_blank" rel="noopener">Open Source</a> and <a href="https://magento.com/legal/terms/enterprise-agreement?mkt_tok=eyJpIjoiT0dKbVkyRTJaalZsT0RWbCIsInQiOiI4Q0dhMUtSUkVKc3hIQjR5Zm4rMWRiMlwvWWZncDY1d0x3YmRKbjJ0dHFPOW93V2pqdGFoS2xWVTVCYXNTc3V6YittRTRWdTlQbTRWZ2Q1Uk9zemJmVlA3RjdJZFhYais0anhNRE5vWTdld0E3V0Y0anZvbzB2OGRuYWpGd3VMd1AifQ==#support" target="_blank" rel="noopener">Community</a> (Enterprise) editions and plan when it is better to upgrade your store.</li>
</ul>
<p><b>The main ideas you may come up with are the following:</b></p>
<ul>
<li>If you’re planning to get the eCommerce project developed, you should choose Magento 2 instead of Magento 1.x;</li>
<li>If you already have the Magento 1.x based eCommerce business, you can start migrating it to Magento 2.</li>
</ul>
<p><b>The questions are:</b> “Why?” and “What are the pros and difficulties you can meet?”</p>
<p>Let’s make it clear.</p>
<p>According to <a href="https://trends.builtwith.com/websitelist/Magento-2" target="_blank" rel="noopener">BuiltWith</a>, almost 20% of Magento based websites use Magento 2.x (68,207 websites). That means a significant number of eCommerce business owners have already made their choice on the side of Magento 2.x. Is it the right decision? Let’s consider the pros and other details.</p>
<p>That means most of the eCommerce business owners have already made their choice on the side of Magento 2.x. Is it the right decision? Let’s consider the pros and other details.</p>
<div class="ufy-block">
<div class="ufy-block__wrapper">
<p class="ufy-block__label">Useful for you:</p>
<ul class="ufy-block__list">
<li class="ufy-block__item"><a href="https://web4pro.net/blog-news/magento-1-9-to-magento-2-migration/" target="_self" rel="noopener" data-wpel-link="internal">Magento 1.9 to Magento 2 Migration: Our Client’s Experience</a></li>
</ul>
</div>
</div>
<h2>The Pros of Migration to Magento 2</h2>
<p>Though Magento 2 is not fully-equipped with many useful features that were presented in Magento 1, it’s still much more flexible. There are some features you’ll discover when working with Magento 2:</p>
<h3>Increased Flexibility of Magento 2</h3>
<p>Magento 2 is super-flexible and extendable when it comes to customization. It includes a lot of features. It’s all because of Magento 2 improved architecture and modular code base that broadens the limits for fast and efficient project development.</p>
<h3>Better Management of Magento 2</h3>
<p>Now administration of the online store is also more flexible. You can:</p>
<ul>
<li>include links to images and videos to your products;</li>
<li>work with the orders better, because you can see the various types of data related to the orders on the Dashboard, (such as lifetime sales, average orders, etc);</li>
<li>keep up with analytics (learn about best customers and sellers, view tax rates and quantities);</li>
<li>upload new products easily;</li>
<li>enjoy the user-friendly interface.</li>
</ul>
<p>title=&#8221;The Benefits of Magento Commerce 2.2 for B2B Business&#8221; link=&#8221;https://web4pro.net/blog-news/the-benefits-of-magento-commerce-2-2-for-b2b-business/&#8221;</p>
<div class="ufy-block">
<div class="ufy-block__wrapper">
<p class="ufy-block__label">Useful for you:</p>
<ul class="ufy-block__list">
<li class="ufy-block__item"><a href="https://web4pro.net/blog-news/the-benefits-of-magento-commerce-2-2-for-b2b-business/" target="_self" rel="noopener" data-wpel-link="internal">The Benefits of Magento Commerce 2.2 for B2B Business</a></li>
</ul>
</div>
</div>
<h3>Magento 2 API</h3>
<p>The huge advantage is that Magento 2 comes with a Rest and SOAP-based API, unlike Magento 1.x. Magento API is a functionality that allows the web developers to integrate Magento with the other third-party services. While Magento 1.x came with a SOAP and XML-RPC based API, it was more difficult to perform integrations: it required the separate configuration of access rights for each user’s role. REST and SOAP had a different business logic. Now, in Magento 2, REST and SOAP business logic is equivalent, and the Magento 2 REST API allows the browsers based access to API calls.</p>
<h3>Updating Magento 2 with Composer</h3>
<p>It could be a useful feature when you are going to update Magento 2 version. The steps you should make are the following:</p>
<ul>
<li>choose the version you need to upgrade via composer upgrade;</li>
<li>run the relevant command;</li>
<li>upgrade the database (don’t forget to backup).</li>
</ul>
<h2>Migration to Magento 2: Pitfalls</h2>
<p>As you can see, Magento 2 is quite a powerful and even a cool tool. But also, we can’t miss a fly in the ointment. The technical and hosting requirements are very high for Magento 2. Here are some of the most important of them.</p>
<h3>Magento 2 Technical Requirements</h3>
<ul>
<li>RAM 2GB</li>
<li>PHP 5.6</li>
<li>MySQL 5.6</li>
</ul>
<p>Also, if talk about hosting, SSL security certificate is required for HTTPS. SSH access is required for hosting anyway, otherwise, it will be impossible to install new extensions, themes etc.</p>
<p>You can look through the full list of technical requirements <span style="text-decoration: underline;"><a href="http://devdocs.magento.com/guides/v2.1/install-gde/system-requirements-tech.html" target="_blank" rel="noopener">here</a></span>.</p>
<p>The next thing is the cost. It’s not cheap to move from Magento 1.x to Magento 2 if your online store is complicated enough. Additionally, Magento 2 doesn’t support Magento 1 themes. These facts are not very pleasant, right? But we have good news for you: migration to Magento 2 is an easy-going process with an experienced team of Magento developers.</p>
<h2>How to Migrate from Magento 1 to Magento 2 and Why?</h2>
<p>We, at WEB4PRO, have already completed a lot of Magento 2 based projects. Most of the project involved the task to migrate from Magento 1.x. Of course, this process could be challenging, but we have a lot of experience and effective solutions to perform it at the highest level.</p>
<div class="ufy-block">
<div class="ufy-block__wrapper">
<p class="ufy-block__label">Useful for you:</p>
<ul class="ufy-block__list">
<li class="ufy-block__item"><a href="https://web4pro.net/blog-news/how-to-migrate-magento-1-to-magento-2/" target="_self" rel="noopener" data-wpel-link="internal">Migration from Magento 1 to Magento 2 Using Magento 2 Data Migration Tool</a></li>
</ul>
</div>
</div>
<p>Also, there are several good ready-made modules for migration from Magento 1 to Magento 2. So, it’s possible for sure! Now you are aware of the things that will happen in a year, and you can be completely ready for these changes.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Using Negative Values for the Product Quantity in Magento 2</title>
		<link>https://web4pro.net/blog-news/using-negative-values-product-quantity-in-magento-2/</link>
		
		<dc:creator><![CDATA[web4pro_su]]></dc:creator>
		<pubDate>Wed, 13 Sep 2017 14:49:37 +0000</pubDate>
				<category><![CDATA[Magento 2]]></category>
		<category><![CDATA[guide]]></category>
		<category><![CDATA[web development]]></category>
		<guid isPermaLink="false">https://web4pro.net/?p=4292</guid>

					<description><![CDATA[When we deal with back-order in Magento 2, we work with negative values for the product quantity. Look how it works.]]></description>
										<content:encoded><![CDATA[
<p>When we deal with product quantity in Magento® 2, and it&#8217;s less than zero, we face the challenge. Sometimes we need to order the products in the online stores when they are not available at the moment. These products are in stock in Magento 2 but Merchants order them from the manufacturers and shippers after we place the order. In eCommerce, we call this back-order or drop-ship. In this case, the number of product quantity in the online store inventory can be less than 0. Yet, the products are available for the ordering.</p>



<p>Magento 2 includes this functionality. We can turn on the support for Qty field values which are less than 0 in Inventory Management Configuration. But there is one small catch. If the product quantity in Magento 2 is less than zero, the online shop administrator can’t edit and resave this product. The following error will appear in Qty field:</p>



<p><em><strong>&#8220;Please enter a valid number in this field.&#8221;</strong></em></p>



<p>You can find the description of this issue and the possible solution to it on <a href="https://github.com/magento/magento2/issues/7401" target="_blank" rel="noopener">GitHub</a>. But you should know that it doesn&#8217;t work on the latest Magento versions (checked on Magento 2.1.7). We’ll cover the reason for this issues and the solution to it below.</p>



<p>The product editing form is implemented with UI-component. It is useful in case we need to do customization with different modules. For example, the form is claimed in the Catalog module. However, Cataloginventory module handles the quantity management.</p>



<h2 class="wp-block-heading">Cataloginventory&nbsp;Module for Product Quantity in Magento 2</h2>



<p>It&#8217;s possible to implement customization with classes-modifiers. They fit into Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool virtual type with di.xml.</p>



<p>If we take the Cataloginventory module, this modifier is claimed in the following way there:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="&lt;virtualType name=&quot;Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool&quot;&gt;
        &lt;arguments&gt;
            &lt;argument name=&quot;modifiers&quot; xsi:type=&quot;array&quot;&gt;
                &lt;item name=&quot;advancedInventory&quot; xsi:type=&quot;array&quot;&gt;
                    &lt;item name=&quot;class&quot; xsi:type=&quot;string&quot;&gt;Magento\CatalogInventory\Ui\DataProvider\Product\Form\Modifier\AdvancedInventory&lt;/item&gt;
                    &lt;item name=&quot;sortOrder&quot; xsi:type=&quot;number&quot;&gt;20&lt;/item&gt;
                &lt;/item&gt;
            &lt;/argument&gt;
        &lt;/arguments&gt;
    &lt;/virtualType&gt;" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki monokai" style="background-color: #272822" tabindex="0"><code><span class="line"><span style="color: #F8F8F2">&lt;</span><span style="color: #F92672">virtualType</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">name</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">        &lt;</span><span style="color: #F92672">arguments</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">            &lt;</span><span style="color: #F92672">argument</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">name</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;modifiers&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">xsi:type</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;array&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">                &lt;</span><span style="color: #F92672">item</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">name</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;advancedInventory&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">xsi:type</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;array&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">                    &lt;</span><span style="color: #F92672">item</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">name</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;class&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">xsi:type</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;string&quot;</span><span style="color: #F8F8F2">&gt;Magento\CatalogInventory\Ui\DataProvider\Product\Form\Modifier\AdvancedInventory&lt;/</span><span style="color: #F92672">item</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">                    &lt;</span><span style="color: #F92672">item</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">name</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;sortOrder&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">xsi:type</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;number&quot;</span><span style="color: #F8F8F2">&gt;20&lt;/</span><span style="color: #F92672">item</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">                &lt;/</span><span style="color: #F92672">item</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">            &lt;/</span><span style="color: #F92672">argument</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">        &lt;/</span><span style="color: #F92672">arguments</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">    &lt;/</span><span style="color: #F92672">virtualType</span><span style="color: #F8F8F2">&gt;</span></span></code></pre></div>



<p>The modifier class should implement \Magento\Ui\DataProvider\Modifier\ModifierInterface which must create two methods: modifyData($data) and modifyMeta($meta).</p>



<p>The component configuration is implemented in modifyMeta($meta) method, including its frontend part (javascript). In the solution from <a href="https://github.com/magento/magento2/issues/7401" target="_blank" rel="noopener">GitHub</a>, the developer recommended turning off the digital validation with a custom modifier. We can implement it in the following way:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="&lt;virtualType name=&quot;Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool&quot;&gt;
        &lt;arguments&gt;
            &lt;argument name=&quot;modifiers&quot; xsi:type=&quot;array&quot;&gt;
                &lt;item name=&quot;hf_quantity&quot; xsi:type=&quot;array&quot;&gt;
                    &lt;item name=&quot;class&quot; xsi:type=&quot;string&quot;&gt;Web4pro\Defaultproduct\Ui\DataProvider\Product\Modifier\Quantity&lt;/item&gt;
                    &lt;item name=&quot;sortOrder&quot; xsi:type=&quot;number&quot;&gt;10000000&lt;/item&gt;
                &lt;/item&gt;
            &lt;/argument&gt;
        &lt;/arguments&gt;
    &lt;/virtualType&gt;" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki monokai" style="background-color: #272822" tabindex="0"><code><span class="line"><span style="color: #F8F8F2">&lt;</span><span style="color: #F92672">virtualType</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">name</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">        &lt;</span><span style="color: #F92672">arguments</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">            &lt;</span><span style="color: #F92672">argument</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">name</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;modifiers&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">xsi:type</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;array&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">                &lt;</span><span style="color: #F92672">item</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">name</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;hf_quantity&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">xsi:type</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;array&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">                    &lt;</span><span style="color: #F92672">item</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">name</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;class&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">xsi:type</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;string&quot;</span><span style="color: #F8F8F2">&gt;Web4pro\Defaultproduct\Ui\DataProvider\Product\Modifier\Quantity&lt;/</span><span style="color: #F92672">item</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">                    &lt;</span><span style="color: #F92672">item</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">name</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;sortOrder&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">xsi:type</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;number&quot;</span><span style="color: #F8F8F2">&gt;10000000&lt;/</span><span style="color: #F92672">item</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">                &lt;/</span><span style="color: #F92672">item</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">            &lt;/</span><span style="color: #F92672">argument</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">        &lt;/</span><span style="color: #F92672">arguments</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">    &lt;/</span><span style="color: #F92672">virtualType</span><span style="color: #F8F8F2">&gt;</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="class Quantity implements \Magento\Ui\DataProvider\Modifier\ModifierInterface {

    protected $arrayManager;

    public function __construct(\Magento\Framework\Stdlib\ArrayManager $arrayManager){
        $this-&gt;arrayManager =$arrayManager;
    }

public function modifyMeta(array $meta)
{
    if ($path = $this-&gt;arrayManager-&gt;findPath('quantity_and_stock_status_qty', $meta, null, 'children')) {
        $this-&gt;arrayManager-&gt;remove(
            $path . '/children/qty/arguments/data/config/validation/validate-digits',
            $meta
        );
    }

    if ($path = $this-&gt;arrayManager-&gt;findPath('advanced_inventory_modal', $meta)) {
        $meta = $this-&gt;arrayManager-&gt;merge(
            $path . '/children/stock_data/children/qty/arguments/data/config',
            $meta,
            ['validation' =&gt; ['validate-digits' =&gt; false]]
        );
    }

    return $meta;
}


    public function modifyData(array $data){
        return $data;
    }
}" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki monokai" style="background-color: #272822" tabindex="0"><code><span class="line"><span style="color: #66D9EF; font-style: italic">class</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E; text-decoration: underline">Quantity</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">implements</span><span style="color: #F8F8F2"> \Magento\Ui\DataProvider\Modifier\</span><span style="color: #A6E22E; font-style: italic; text-decoration: underline">ModifierInterface</span><span style="color: #F8F8F2"> {</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">protected</span><span style="color: #F8F8F2"> $arrayManager;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">public</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF">__construct</span><span style="color: #F8F8F2">(\Magento\Framework\Stdlib\</span><span style="color: #66D9EF; font-style: italic">ArrayManager</span><span style="color: #F8F8F2"> $arrayManager){</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">arrayManager </span><span style="color: #F92672">=</span><span style="color: #F8F8F2">$arrayManager;</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F92672">public</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">modifyMeta</span><span style="color: #F8F8F2">(</span><span style="color: #F92672">array</span><span style="color: #F8F8F2"> $meta)</span></span>
<span class="line"><span style="color: #F8F8F2">{</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> ($path </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">arrayManager</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">findPath</span><span style="color: #F8F8F2">(</span><span style="color: #E6DB74">&#39;quantity_and_stock_status_qty&#39;</span><span style="color: #F8F8F2">, $meta, </span><span style="color: #AE81FF">null</span><span style="color: #F8F8F2">, </span><span style="color: #E6DB74">&#39;children&#39;</span><span style="color: #F8F8F2">)) {</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">arrayManager</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">remove</span><span style="color: #F8F8F2">(</span></span>
<span class="line"><span style="color: #F8F8F2">            $path </span><span style="color: #F92672">.</span><span style="color: #F8F8F2"> </span><span style="color: #E6DB74">&#39;/children/qty/arguments/data/config/validation/validate-digits&#39;</span><span style="color: #F8F8F2">,</span></span>
<span class="line"><span style="color: #F8F8F2">            $meta</span></span>
<span class="line"><span style="color: #F8F8F2">        );</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> ($path </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">arrayManager</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">findPath</span><span style="color: #F8F8F2">(</span><span style="color: #E6DB74">&#39;advanced_inventory_modal&#39;</span><span style="color: #F8F8F2">, $meta)) {</span></span>
<span class="line"><span style="color: #F8F8F2">        $meta </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">arrayManager</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">merge</span><span style="color: #F8F8F2">(</span></span>
<span class="line"><span style="color: #F8F8F2">            $path </span><span style="color: #F92672">.</span><span style="color: #F8F8F2"> </span><span style="color: #E6DB74">&#39;/children/stock_data/children/qty/arguments/data/config&#39;</span><span style="color: #F8F8F2">,</span></span>
<span class="line"><span style="color: #F8F8F2">            $meta,</span></span>
<span class="line"><span style="color: #F8F8F2">            [</span><span style="color: #E6DB74">&#39;validation&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> [</span><span style="color: #E6DB74">&#39;validate-digits&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">false</span><span style="color: #F8F8F2">]]</span></span>
<span class="line"><span style="color: #F8F8F2">        );</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">return</span><span style="color: #F8F8F2"> $meta;</span></span>
<span class="line"><span style="color: #F8F8F2">}</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">public</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">modifyData</span><span style="color: #F8F8F2">(</span><span style="color: #F92672">array</span><span style="color: #F8F8F2"> $data){</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">return</span><span style="color: #F8F8F2"> $data;</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span>
<span class="line"><span style="color: #F8F8F2">}</span></span></code></pre></div>



<p>In the latest Magento versions (Magento 2.1.7) this code will not work. The reason is the following. Magento has the implementation of support for integers and fractions. For example, the fractions work in case of product drop-shipping by weight.</p>



<h2 class="wp-block-heading">The Solution for Product Quantity in Magento 2</h2>



<p>Magento_CatalogInventory/js/components/qty-validator-changer component was implemented for the quantity validation. This is its code:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="define([
    'Magento_Ui/js/form/element/abstract'
], function (Abstract) {
    'use strict';

    return Abstract.extend({
        defaults: {
            valueUpdate: 'input'
        },

        /**
         * Change validator
         */
        handleChanges: function (value) {
            var isDigits = value !== 1;

            this.validation['validate-number'] = !isDigits;
            this.validation['validate-digits'] = isDigits;
            this.validation['less-than-equals-to'] = isDigits ? 99999999 : 99999999.9999;
            this.validate();
        }
    });
});" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki monokai" style="background-color: #272822" tabindex="0"><code><span class="line"><span style="color: #A6E22E">define</span><span style="color: #F8F8F2">([</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #E6DB74">&#39;Magento_Ui/js/form/element/abstract&#39;</span></span>
<span class="line"><span style="color: #F8F8F2">], </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> (</span><span style="color: #FD971F; font-style: italic">Abstract</span><span style="color: #F8F8F2">) {</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #E6DB74">&#39;use strict&#39;</span><span style="color: #F8F8F2">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">return</span><span style="color: #F8F8F2"> Abstract.</span><span style="color: #A6E22E">extend</span><span style="color: #F8F8F2">({</span></span>
<span class="line"><span style="color: #F8F8F2">        defaults: {</span></span>
<span class="line"><span style="color: #F8F8F2">            valueUpdate: </span><span style="color: #E6DB74">&#39;input&#39;</span></span>
<span class="line"><span style="color: #F8F8F2">        },</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #88846F">/**</span></span>
<span class="line"><span style="color: #88846F">         * Change validator</span></span>
<span class="line"><span style="color: #88846F">         */</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #A6E22E">handleChanges</span><span style="color: #F8F8F2">: </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> (</span><span style="color: #FD971F; font-style: italic">value</span><span style="color: #F8F8F2">) {</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #66D9EF; font-style: italic">var</span><span style="color: #F8F8F2"> isDigits </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> value </span><span style="color: #F92672">!==</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">1</span><span style="color: #F8F8F2">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #FD971F">this</span><span style="color: #F8F8F2">.validation[</span><span style="color: #E6DB74">&#39;validate-number&#39;</span><span style="color: #F8F8F2">] </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">!</span><span style="color: #F8F8F2">isDigits;</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #FD971F">this</span><span style="color: #F8F8F2">.validation[</span><span style="color: #E6DB74">&#39;validate-digits&#39;</span><span style="color: #F8F8F2">] </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> isDigits;</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #FD971F">this</span><span style="color: #F8F8F2">.validation[</span><span style="color: #E6DB74">&#39;less-than-equals-to&#39;</span><span style="color: #F8F8F2">] </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> isDigits </span><span style="color: #F92672">?</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">99999999</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">:</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">99999999.9999</span><span style="color: #F8F8F2">;</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #FD971F">this</span><span style="color: #F8F8F2">.</span><span style="color: #A6E22E">validate</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">        }</span></span>
<span class="line"><span style="color: #F8F8F2">    });</span></span>
<span class="line"><span style="color: #F8F8F2">});</span></span></code></pre></div>



<p>handleChanges method checks the configuration value transmitted to the component. If the integers are used for the quantity, we should apply validate-digits validator. If we deal with fractions, we should apply validate-number. So, it’s not enough to turn off the validate-digits validator. We also should set the needed value of handleChanges function’s parameter. It allows us to avoid choosing this validator by the other function.</p>



<p>We describe this function’s parameter in Magento\CatalogInventory\Ui\DataProvider\Product\Form\Modifier\AdvancedInventory modifier the following way:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="...
'imports' =&gt; [
                    'handleChanges' =&gt; '${$.provider}:data.product.stock_data.is_qty_decimal',
                ],
….

As we can see, we can get its values in both cases, whether we use integers or fractions for quantity. We set that in the configuration. So, let’s implement modifyMeta($meta) method in our modifier:

  public function modifyMeta(array $meta)
    {
        if ($path = $this-&gt;arrayManager-&gt;findPath('quantity_and_stock_status_qty', $meta, null, 'children')) {
            $this-&gt;arrayManager-&gt;remove(
                $path . '/children/qty/arguments/data/config/validation/validate-digits',
                $meta
            );
            $this-&gt;arrayManager-&gt;merge($path . '/children/qty/arguments/data/config/imports',$meta,
                                       array('handleChanges'=&gt;&quot;1&quot;));
        }

        if ($path = $this-&gt;arrayManager-&gt;findPath('advanced_inventory_modal', $meta)) {
            $meta = $this-&gt;arrayManager-&gt;merge(
                $path . '/children/stock_data/children/qty/arguments/data/config',
                $meta,
                ['validation' =&gt; ['validate-digits' =&gt; false],'imports'=&gt;['handleChanges'=&gt;'1']]
            );
        }

        return $meta;
    }" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki monokai" style="background-color: #272822" tabindex="0"><code><span class="line"><span style="color: #F92672">...</span></span>
<span class="line"><span style="color: #E6DB74">&#39;imports&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> [</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #E6DB74">&#39;handleChanges&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> </span><span style="color: #E6DB74">&#39;${$.provider}:data.product.stock_data.is_qty_decimal&#39;</span><span style="color: #F8F8F2">,</span></span>
<span class="line"><span style="color: #F8F8F2">                ],</span></span>
<span class="line"><span style="color: #AE81FF">…</span><span style="color: #F92672">.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F92672">As</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">we</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">can</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">see</span><span style="color: #F8F8F2">, </span><span style="color: #AE81FF">we</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">can</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">get</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">its</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">values</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">in</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">both</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">cases</span><span style="color: #F8F8F2">, </span><span style="color: #AE81FF">whether</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">we</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">use</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">integers</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">or</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">fractions</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">for</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">quantity</span><span style="color: #F8F8F2">. </span><span style="color: #66D9EF; font-style: italic">We</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">set</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">that</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">in</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">the</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">configuration</span><span style="color: #F8F8F2">. </span><span style="color: #66D9EF; font-style: italic">So</span><span style="color: #F8F8F2">, </span><span style="color: #66D9EF; font-style: italic">let’s</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">implement</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">modifyMeta</span><span style="color: #F8F8F2">($</span><span style="color: #66D9EF; font-style: italic">meta</span><span style="color: #F8F8F2">) </span><span style="color: #66D9EF; font-style: italic">method</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">in</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">our</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">modifier</span><span style="color: #F8F8F2">:</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F8F8F2">  </span><span style="color: #66D9EF; font-style: italic">public</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">modifyMeta</span><span style="color: #F8F8F2">(</span><span style="color: #66D9EF; font-style: italic">array</span><span style="color: #F8F8F2"> $</span><span style="color: #66D9EF; font-style: italic">meta</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">    {</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #66D9EF; font-style: italic">if</span><span style="color: #F8F8F2"> ($</span><span style="color: #66D9EF; font-style: italic">path</span><span style="color: #F8F8F2"> = $</span><span style="color: #66D9EF; font-style: italic">this</span><span style="color: #F8F8F2">-&gt;</span><span style="color: #66D9EF; font-style: italic">arrayManager</span><span style="color: #F8F8F2">-&gt;</span><span style="color: #66D9EF; font-style: italic">findPath</span><span style="color: #F8F8F2">(&#39;</span><span style="color: #66D9EF; font-style: italic">quantity_and_stock_status_qty</span><span style="color: #F8F8F2">&#39;, $</span><span style="color: #66D9EF; font-style: italic">meta</span><span style="color: #F8F8F2">, </span><span style="color: #66D9EF; font-style: italic">null</span><span style="color: #F8F8F2">, &#39;</span><span style="color: #66D9EF; font-style: italic">children</span><span style="color: #F8F8F2">&#39;)) {</span></span>
<span class="line"><span style="color: #F8F8F2">            $</span><span style="color: #66D9EF; font-style: italic">this</span><span style="color: #F8F8F2">-&gt;</span><span style="color: #66D9EF; font-style: italic">arrayManager</span><span style="color: #F8F8F2">-&gt;</span><span style="color: #66D9EF; font-style: italic">remove</span><span style="color: #F8F8F2">(</span></span>
<span class="line"><span style="color: #F8F8F2">                $</span><span style="color: #66D9EF; font-style: italic">path</span><span style="color: #F8F8F2"> . &#39;/</span><span style="color: #66D9EF; font-style: italic">children</span><span style="color: #F8F8F2">/</span><span style="color: #66D9EF; font-style: italic">qty</span><span style="color: #F8F8F2">/</span><span style="color: #66D9EF; font-style: italic">arguments</span><span style="color: #F8F8F2">/</span><span style="color: #66D9EF; font-style: italic">data</span><span style="color: #F8F8F2">/</span><span style="color: #66D9EF; font-style: italic">config</span><span style="color: #F8F8F2">/</span><span style="color: #66D9EF; font-style: italic">validation</span><span style="color: #F8F8F2">/</span><span style="color: #66D9EF; font-style: italic">validate</span><span style="color: #F8F8F2">-</span><span style="color: #66D9EF; font-style: italic">digits</span><span style="color: #F8F8F2">&#39;,</span></span>
<span class="line"><span style="color: #F8F8F2">                $</span><span style="color: #66D9EF; font-style: italic">meta</span></span>
<span class="line"><span style="color: #F8F8F2">            );</span></span>
<span class="line"><span style="color: #F8F8F2">            $</span><span style="color: #66D9EF; font-style: italic">this</span><span style="color: #F8F8F2">-&gt;</span><span style="color: #66D9EF; font-style: italic">arrayManager</span><span style="color: #F8F8F2">-&gt;</span><span style="color: #66D9EF; font-style: italic">merge</span><span style="color: #F8F8F2">($</span><span style="color: #66D9EF; font-style: italic">path</span><span style="color: #F8F8F2"> . &#39;/</span><span style="color: #66D9EF; font-style: italic">children</span><span style="color: #F8F8F2">/</span><span style="color: #66D9EF; font-style: italic">qty</span><span style="color: #F8F8F2">/</span><span style="color: #66D9EF; font-style: italic">arguments</span><span style="color: #F8F8F2">/</span><span style="color: #66D9EF; font-style: italic">data</span><span style="color: #F8F8F2">/</span><span style="color: #66D9EF; font-style: italic">config</span><span style="color: #F8F8F2">/</span><span style="color: #66D9EF; font-style: italic">imports</span><span style="color: #F8F8F2">&#39;,$</span><span style="color: #66D9EF; font-style: italic">meta</span><span style="color: #F8F8F2">,</span></span>
<span class="line"><span style="color: #F8F8F2">                                       </span><span style="color: #66D9EF; font-style: italic">array</span><span style="color: #F8F8F2">(&#39;</span><span style="color: #66D9EF; font-style: italic">handleChanges</span><span style="color: #F8F8F2">&#39;=&gt;&quot;1&quot;));</span></span>
<span class="line"><span style="color: #F8F8F2">        }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> ($path </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">arrayManager</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">findPath</span><span style="color: #F8F8F2">(</span><span style="color: #E6DB74">&#39;advanced_inventory_modal&#39;</span><span style="color: #F8F8F2">, $meta)) {</span></span>
<span class="line"><span style="color: #F8F8F2">            $meta </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">arrayManager</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">merge</span><span style="color: #F8F8F2">(</span></span>
<span class="line"><span style="color: #F8F8F2">                $path </span><span style="color: #F92672">.</span><span style="color: #F8F8F2"> </span><span style="color: #E6DB74">&#39;/children/stock_data/children/qty/arguments/data/config&#39;</span><span style="color: #F8F8F2">,</span></span>
<span class="line"><span style="color: #F8F8F2">                $meta,</span></span>
<span class="line"><span style="color: #F8F8F2">                [</span><span style="color: #E6DB74">&#39;validation&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> [</span><span style="color: #E6DB74">&#39;validate-digits&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">false</span><span style="color: #F8F8F2">],</span><span style="color: #E6DB74">&#39;imports&#39;</span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2">[</span><span style="color: #E6DB74">&#39;handleChanges&#39;</span><span style="color: #F92672">=&gt;</span><span style="color: #E6DB74">&#39;1&#39;</span><span style="color: #F8F8F2">]]</span></span>
<span class="line"><span style="color: #F8F8F2">            );</span></span>
<span class="line"><span style="color: #F8F8F2">        }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">return</span><span style="color: #F8F8F2"> $meta;</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span></code></pre></div>



<p>Finally, we have the next results:</p>



<ul class="wp-block-list">
<li>we turned off the validate-digits validator;</li>



<li>we set &#8216;handleChanges&#8217; equal to 1.</li>
</ul>



<p>It will cause the use of the right frontend validator. Furthermore, it won’t break the backend logic for the products which are on sales by item not by weight. We should repeat this twice because we can find the link under the Qty field. This link opens the advanced_inventory_modal pop-up.</p>



<p>As a result, the online store administrator will be able to save the products of which quantity is less than 0 without any problems.</p>



<p>This case is new to Magento 2. We make everything possible to make your journey with Magento 2 easier. If you have any questions regarding&nbsp;<a href="https://web4pro.net/service/magento-2-extension-development/">Magento 2 Extension Development</a>, please, contact us. We’ll take care of your project.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Extension Attributes for Total Model in Magento 2</title>
		<link>https://web4pro.net/blog-news/extension-attributes-for-total-model-in-magento-2/</link>
		
		<dc:creator><![CDATA[web4pro_su]]></dc:creator>
		<pubDate>Thu, 10 Aug 2017 13:39:19 +0000</pubDate>
				<category><![CDATA[Magento 2]]></category>
		<category><![CDATA[guide]]></category>
		<category><![CDATA[web development]]></category>
		<guid isPermaLink="false">https://web4pro.net/?p=4246</guid>

					<description><![CDATA[Learn how you can set extension attributes for the total model in Magento 2.]]></description>
										<content:encoded><![CDATA[
<p>We continue to set extension attributes in Magento® 2. Last time we were talking about the adding a custom attribute to the customer’s address. But what if we need to set these attributes for the total model? Today we’ll consider how we can do that step by step.</p>



<h2 class="wp-block-heading">Total Model</h2>



<p>Total model is a dynamic system used for collecting the shopping cart and the order total. It usually contains the elements which take part in calculating the total cost: final products total, discount, tax, shipping fee, and some other parameters.</p>



<h3 class="wp-block-heading">How It Works</h3>



<p>Imagine the online store. You buy some products there and add them to the shopping cart. When you view the shopping cart page, you can see something like this:</p>



<p><strong>Subtotal &#8211; X.XX$ </strong><i>final cost of products (the product’s cost multiplied by the number of products)</i></p>



<p><strong>Tax &nbsp;&#8211; X.XX$ </strong><i>(optionally)</i></p>



<p><strong>Shipping &nbsp;&#8211; X.XX$ </strong><i>(optionally)</i></p>



<p><strong>Discount</strong> <i>(optionally)</i></p>



<p><strong>Total &#8211; X.XX $</strong> (the final cost of the order)</p>



<p>Let’s take a look at VENROY online store (it’s Magento based) to see how it can work for you:</p>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" width="1024" height="484" src="https://s3.eu-central-1.amazonaws.com/web4pro.net-new/wp-content/uploads/2017/11/07084325/Shopping-Cart_q3bwwc_dcs879_iokvjr-1024x484.png" alt="Magento based online store" class="wp-image-4247" srcset="https://s3.eu-central-1.amazonaws.com/web4pro.net-new/wp-content/uploads/2017/11/07084325/Shopping-Cart_q3bwwc_dcs879_iokvjr-1024x484.png 1024w, https://s3.eu-central-1.amazonaws.com/web4pro.net-new/wp-content/uploads/2017/11/07084325/Shopping-Cart_q3bwwc_dcs879_iokvjr-300x142.png 300w, https://s3.eu-central-1.amazonaws.com/web4pro.net-new/wp-content/uploads/2017/11/07084325/Shopping-Cart_q3bwwc_dcs879_iokvjr-640x302.png 640w, https://s3.eu-central-1.amazonaws.com/web4pro.net-new/wp-content/uploads/2017/11/07084325/Shopping-Cart_q3bwwc_dcs879_iokvjr-768x363.png 768w, https://s3.eu-central-1.amazonaws.com/web4pro.net-new/wp-content/uploads/2017/11/07084325/Shopping-Cart_q3bwwc_dcs879_iokvjr.png 1545w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure></div>


<p>The whole system shown in this example is the Total model. Let’s move on.</p>



<h3 class="wp-block-heading">What We Need to Do</h3>



<p>First of all, we need to add the row before subtotal in the total model. The row will show the customer’s profit. The profit is a marketing element that shows how much money the customer saves using the offer. This profit should not be included in the final cost of the shopping cart and the order totals. It is calculated on the base of subtotal.</p>



<p>So, we can separate our task into two main problems:</p>



<ul class="wp-block-list">
<li>Add the row before Subtotal and don’t include its results to the total cost.</li>



<li>Make the extension and Magento 2 work right together.</li>
</ul>



<p>These both conditions must work correctly with each other.</p>



<p>In the end, we should get the result of this kind:</p>



<p><strong><i>You save</i>: </strong>(Our additional row)</p>



<p><strong>Subtotal</strong> &#8211; final cost of products (the product cost * the number of products)</p>



<p><strong>Tax</strong> <i>(optionally)</i></p>



<p><strong>Shipping </strong><i>(optionally)</i></p>



<p><strong>Discount </strong><i>(optionally)</i></p>



<p><b>Total</b> &#8211; the final cost of the order</p>



<p>Let’s go on to code!</p>



<h2 class="wp-block-heading">Preconditions</h2>



<p>There is a Magento 2 based online store. It is oriented on the retail and wholesale customers. Due to this fact, most of the products have the tier prices, as well as the retail prices. The types of store products are the simple products and configurable products. As we said before, we need to output the additional row before Subtotal on the shopping cart and the order pages. This row must show the total profit for the wholesale customer. While calculating the profit, we don&#8217;t include the extra-charge for product options. This row mustn&#8217;t influence the order final cost, as well as it mustn&#8217;t be copied to the order.</p>



<h2 class="wp-block-heading">Solution</h2>



<h3 class="wp-block-heading">Setting Magento 2 Extension Attributes</h3>



<p>Last time, we <span style="text-decoration: underline;"><a href="https://web4pro.net/blog-news/magento-2-add-custom-attribute-customers-address/">added the custom attribute to the customer address</a></span>. Let’s follow the same way. We’ll add the style_discount field with decimal(10,4) type to the address extension attributes table from the last example. Also, we’ll need to add the attribute to the extenson_attributes.xml file of our module. We should add it twice for two different interfaces.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="...
&lt;extension_attributes for=&quot;MagentoQuoteApiDataAddressInterface&quot;&gt;
        &lt;attribute code=&quot;type&quot; type=&quot;int&quot;&gt;
            &lt;join reference_table=&quot;web4pro_quote_address&quot; join_on_field=&quot;address_id&quot; reference_field=&quot;address_id&quot;&gt;
                &lt;field column=&quot;type&quot;&gt;type&lt;/field&gt;
            &lt;/join&gt;
        &lt;/attribute&gt;
        &lt;attribute code=&quot;style_discount&quot; type=&quot;float&quot;&gt;
            &lt;join reference_table=&quot;web4pro_quote_address&quot; join_on_field=&quot;address_id&quot; reference_field=&quot;address_id&quot;&gt;
                &lt;field column=&quot;style_discount&quot;&gt;style_discount&lt;/field&gt;
            &lt;/join&gt;
        &lt;/attribute&gt;
    &lt;/extension_attributes&gt;
    &lt;extension_attributes for=&quot;MagentoQuoteApiDataTotalsInterface&quot;&gt;
        &lt;attribute code=&quot;style_discount&quot; type=&quot;float&quot;/&gt;
    &lt;/extension_attributes&gt;
…" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki monokai" style="background-color: #272822" tabindex="0"><code><span class="line"><span style="color: #F8F8F2">...</span></span>
<span class="line"><span style="color: #F8F8F2">&lt;</span><span style="color: #F92672">extension_attributes</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">for</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;MagentoQuoteApiDataAddressInterface&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">        &lt;</span><span style="color: #F92672">attribute</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">code</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;type&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">type</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;int&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">            &lt;</span><span style="color: #F92672">join</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">reference_table</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;web4pro_quote_address&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">join_on_field</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;address_id&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">reference_field</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;address_id&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">                &lt;</span><span style="color: #F92672">field</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">column</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;type&quot;</span><span style="color: #F8F8F2">&gt;type&lt;/</span><span style="color: #F92672">field</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">            &lt;/</span><span style="color: #F92672">join</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">        &lt;/</span><span style="color: #F92672">attribute</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">        &lt;</span><span style="color: #F92672">attribute</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">code</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;style_discount&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">type</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;float&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">            &lt;</span><span style="color: #F92672">join</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">reference_table</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;web4pro_quote_address&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">join_on_field</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;address_id&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">reference_field</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;address_id&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">                &lt;</span><span style="color: #F92672">field</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">column</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;style_discount&quot;</span><span style="color: #F8F8F2">&gt;style_discount&lt;/</span><span style="color: #F92672">field</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">            &lt;/</span><span style="color: #F92672">join</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">        &lt;/</span><span style="color: #F92672">attribute</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">    &lt;/</span><span style="color: #F92672">extension_attributes</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">    &lt;</span><span style="color: #F92672">extension_attributes</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">for</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;MagentoQuoteApiDataTotalsInterface&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">        &lt;</span><span style="color: #F92672">attribute</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">code</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;style_discount&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">type</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;float&quot;</span><span style="color: #F8F8F2">/&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">    &lt;/</span><span style="color: #F92672">extension_attributes</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">…</span></span></code></pre></div>



<p>In the first case, we should specify the table which will store this attribute. In the second case, there is no necessity to do this, because the entity implemented with MagentoQuoteApiDataTotalsInterface is always formed from the address data along the way. Saving of this attribute will be performed in sales_quote_address_save_after event processor, which we described in the previous example.</p>



<p>Furthermore, we need to describe the total model. Let’s create an etc/sales.xml file in the module for these purposes. It looks like the following:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;config xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:noNamespaceSchemaLocation=&quot;urn:magento:module:Magento_Sales:etc/sales.xsd&quot;&gt;
    &lt;section name=&quot;quote&quot;&gt;
        &lt;group name=&quot;totals&quot;&gt;
            &lt;item name=&quot;style_discount&quot; instance=&quot;Web4proAjaxcartModelQuoteAddressStyle&quot; sort_order=&quot;110&quot;/&gt;
        &lt;/group&gt;
    &lt;/section&gt;
&lt;/config&gt;" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki monokai" style="background-color: #272822" tabindex="0"><code><span class="line"><span style="color: #F8F8F2">&lt;?</span><span style="color: #F92672">xml</span><span style="color: #A6E22E"> version</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;1.0&quot;</span><span style="color: #F8F8F2">?&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">&lt;</span><span style="color: #F92672">config</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">xmlns:xsi</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">xsi:noNamespaceSchemaLocation</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;urn:magento:module:Magento_Sales:etc/sales.xsd&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">    &lt;</span><span style="color: #F92672">section</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">name</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;quote&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">        &lt;</span><span style="color: #F92672">group</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">name</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;totals&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">            &lt;</span><span style="color: #F92672">item</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">name</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;style_discount&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">instance</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;Web4proAjaxcartModelQuoteAddressStyle&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">sort_order</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;110&quot;</span><span style="color: #F8F8F2">/&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">        &lt;/</span><span style="color: #F92672">group</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">    &lt;/</span><span style="color: #F92672">section</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">&lt;/</span><span style="color: #F92672">config</span><span style="color: #F8F8F2">&gt;</span></span></code></pre></div>



<p>We choose the sort_order parameter keeping in mind that calculations were performed after Subtotal had been calculated. In this case, the Product entity has already been initialized for all shopping cart elements.</p>



<h3 class="wp-block-heading">Implementing Total Model in Magento 2</h3>



<p>The total model must implement two methods: collect() method used for the calculation and fetch() method used for the output on request. You can implement the total by following this example:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="namespace Web4proAjaxcartModelQuoteAddress;
use MagentoQuoteModelQuoteAddressItem as AddressItem;

class Style extends MagentoQuoteModelQuoteAddressTotalAbstractTotal {

    protected $_objectManager;

    public function __construct(MagentoFrameworkObjectManagerInterface $objectManagerInterface){
        $this-&gt;_objectManager = $objectManagerInterface;
    }

    public function collect(
        MagentoQuoteModelQuote $quote,
        MagentoQuoteApiDataShippingAssignmentInterface $shippingAssignment,
        MagentoQuoteModelQuoteAddressTotal $total
    ) {
        parent::collect($quote,$shippingAssignment,$total);
        $items = $shippingAssignment-&gt;getItems();
        $address = $shippingAssignment-&gt;getShipping()-&gt;getAddress();
        $amount = 0;
        foreach($items as $item){
            if ($item-&gt;getParentItem()) {
                continue;
            }
            if ($item instanceof AddressItem) {
                $quoteItem = $item-&gt;getAddress()-&gt;getQuote()-&gt;getItemById($item
-&gt;getQuoteItemId());
            } else {
                $quoteItem = $item;
            }
            $product = $quoteItem-&gt;getData('product');
            $childProduct = $product;
            if($product-&gt;getTypeId()=='configurable'){
                $childProduct = $product-&gt;getCustomOption('simple_product')-&gt;getProduct();
            }
            $qty = $quoteItem-&gt;getQty();
            $amount =(float)($qty*($childProduct-&gt;getPriceModel()-&gt;getFinalPrice($qty,$childProduct)-$childProduct-&gt;getPriceModel()-&gt;getBasePrice($childProduct,1)));
        }
        $total-&gt;addTotalAmount($this-&gt;getCode(),$amount);
        $extensionAttr = $address-&gt;getExtensionAttributes();
        if(!$extensionAttr){
            $extensionAttr = $this-&gt;_objectManager
-&gt;create('MagentoQuoteApiDataAddressExtension');
        }
        $extensionAttr-&gt;setData($this-&gt;getCode(),$total-&gt;getTotalAmount($this-&gt;getCode()));
        $address-&gt;setExtensionAttributes($extensionAttr);
        return $this;
    }
    public function fetch(MagentoQuoteModelQuote $quote, MagentoQuoteModelQuoteAddressTotal $total)
    {
        $result = null;
        $amount = $total-&gt;getTotalAmount($this-&gt;getCode());

        if ($amount != 0) {
            $result = [
                'code' =&gt; $this-&gt;getCode(),
                'title' =&gt; __('Style Discount'),
                'value' =&gt; $amount
            ];
        }
        return $result;
    }
}" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki monokai" style="background-color: #272822" tabindex="0"><code><span class="line"><span style="color: #F92672">namespace</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E; text-decoration: underline">Web4proAjaxcartModelQuoteAddress</span><span style="color: #F8F8F2">;</span></span>
<span class="line"><span style="color: #F92672">use</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">MagentoQuoteModelQuoteAddressItem</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">as</span><span style="color: #F8F8F2"> AddressItem;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #66D9EF; font-style: italic">class</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E; text-decoration: underline">Style</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">extends</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E; font-style: italic; text-decoration: underline">MagentoQuoteModelQuoteAddressTotalAbstractTotal</span><span style="color: #F8F8F2"> {</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">protected</span><span style="color: #F8F8F2"> $_objectManager;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">public</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF">__construct</span><span style="color: #F8F8F2">(</span><span style="color: #66D9EF; font-style: italic">MagentoFrameworkObjectManagerInterface</span><span style="color: #F8F8F2"> $objectManagerInterface){</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">_objectManager </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $objectManagerInterface;</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">public</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">collect</span><span style="color: #F8F8F2">(</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #66D9EF; font-style: italic">MagentoQuoteModelQuote</span><span style="color: #F8F8F2"> $quote,</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #66D9EF; font-style: italic">MagentoQuoteApiDataShippingAssignmentInterface</span><span style="color: #F8F8F2"> $shippingAssignment,</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #66D9EF; font-style: italic">MagentoQuoteModelQuoteAddressTotal</span><span style="color: #F8F8F2"> $total</span></span>
<span class="line"><span style="color: #F8F8F2">    ) {</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #66D9EF; font-style: italic">parent</span><span style="color: #F92672">::</span><span style="color: #A6E22E">collect</span><span style="color: #F8F8F2">($quote,$shippingAssignment,$total);</span></span>
<span class="line"><span style="color: #F8F8F2">        $items </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $shippingAssignment</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getItems</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">        $address </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $shippingAssignment</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getShipping</span><span style="color: #F8F8F2">()</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getAddress</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">        $amount </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">0</span><span style="color: #F8F8F2">;</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">foreach</span><span style="color: #F8F8F2">($items </span><span style="color: #F92672">as</span><span style="color: #F8F8F2"> $item){</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> ($item</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getParentItem</span><span style="color: #F8F8F2">()) {</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #F92672">continue</span><span style="color: #F8F8F2">;</span></span>
<span class="line"><span style="color: #F8F8F2">            }</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> ($item </span><span style="color: #F92672">instanceof</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">AddressItem</span><span style="color: #F8F8F2">) {</span></span>
<span class="line"><span style="color: #F8F8F2">                $quoteItem </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $item</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getAddress</span><span style="color: #F8F8F2">()</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getQuote</span><span style="color: #F8F8F2">()</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getItemById</span><span style="color: #F8F8F2">($item</span></span>
<span class="line"><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getQuoteItemId</span><span style="color: #F8F8F2">());</span></span>
<span class="line"><span style="color: #F8F8F2">            } </span><span style="color: #F92672">else</span><span style="color: #F8F8F2"> {</span></span>
<span class="line"><span style="color: #F8F8F2">                $quoteItem </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $item;</span></span>
<span class="line"><span style="color: #F8F8F2">            }</span></span>
<span class="line"><span style="color: #F8F8F2">            $product </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $quoteItem</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getData</span><span style="color: #F8F8F2">(</span><span style="color: #E6DB74">&#39;product&#39;</span><span style="color: #F8F8F2">);</span></span>
<span class="line"><span style="color: #F8F8F2">            $childProduct </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $product;</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #F92672">if</span><span style="color: #F8F8F2">($product</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getTypeId</span><span style="color: #F8F8F2">()</span><span style="color: #F92672">==</span><span style="color: #E6DB74">&#39;configurable&#39;</span><span style="color: #F8F8F2">){</span></span>
<span class="line"><span style="color: #F8F8F2">                $childProduct </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $product</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getCustomOption</span><span style="color: #F8F8F2">(</span><span style="color: #E6DB74">&#39;simple_product&#39;</span><span style="color: #F8F8F2">)</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getProduct</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">            }</span></span>
<span class="line"><span style="color: #F8F8F2">            $qty </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $quoteItem</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getQty</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">            $amount </span><span style="color: #F92672">=</span><span style="color: #F8F8F2">(</span><span style="color: #66D9EF; font-style: italic">float</span><span style="color: #F8F8F2">)($qty</span><span style="color: #F92672">*</span><span style="color: #F8F8F2">($childProduct</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getPriceModel</span><span style="color: #F8F8F2">()</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getFinalPrice</span><span style="color: #F8F8F2">($qty,$childProduct)</span><span style="color: #F92672">-</span><span style="color: #F8F8F2">$childProduct</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getPriceModel</span><span style="color: #F8F8F2">()</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getBasePrice</span><span style="color: #F8F8F2">($childProduct,</span><span style="color: #AE81FF">1</span><span style="color: #F8F8F2">)));</span></span>
<span class="line"><span style="color: #F8F8F2">        }</span></span>
<span class="line"><span style="color: #F8F8F2">        $total</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">addTotalAmount</span><span style="color: #F8F8F2">(</span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getCode</span><span style="color: #F8F8F2">(),$amount);</span></span>
<span class="line"><span style="color: #F8F8F2">        $extensionAttr </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $address</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getExtensionAttributes</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">if</span><span style="color: #F8F8F2">(</span><span style="color: #F92672">!</span><span style="color: #F8F8F2">$extensionAttr){</span></span>
<span class="line"><span style="color: #F8F8F2">            $extensionAttr </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #F8F8F2">_objectManager</span></span>
<span class="line"><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">create</span><span style="color: #F8F8F2">(</span><span style="color: #E6DB74">&#39;MagentoQuoteApiDataAddressExtension&#39;</span><span style="color: #F8F8F2">);</span></span>
<span class="line"><span style="color: #F8F8F2">        }</span></span>
<span class="line"><span style="color: #F8F8F2">        $extensionAttr</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">setData</span><span style="color: #F8F8F2">(</span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getCode</span><span style="color: #F8F8F2">(),$total</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getTotalAmount</span><span style="color: #F8F8F2">(</span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getCode</span><span style="color: #F8F8F2">()));</span></span>
<span class="line"><span style="color: #F8F8F2">        $address</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">setExtensionAttributes</span><span style="color: #F8F8F2">($extensionAttr);</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">return</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F8F8F2">;</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">public</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">fetch</span><span style="color: #F8F8F2">(</span><span style="color: #66D9EF; font-style: italic">MagentoQuoteModelQuote</span><span style="color: #F8F8F2"> $quote, </span><span style="color: #66D9EF; font-style: italic">MagentoQuoteModelQuoteAddressTotal</span><span style="color: #F8F8F2"> $total)</span></span>
<span class="line"><span style="color: #F8F8F2">    {</span></span>
<span class="line"><span style="color: #F8F8F2">        $result </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">null</span><span style="color: #F8F8F2">;</span></span>
<span class="line"><span style="color: #F8F8F2">        $amount </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $total</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getTotalAmount</span><span style="color: #F8F8F2">(</span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getCode</span><span style="color: #F8F8F2">());</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> ($amount </span><span style="color: #F92672">!=</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">0</span><span style="color: #F8F8F2">) {</span></span>
<span class="line"><span style="color: #F8F8F2">            $result </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> [</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #E6DB74">&#39;code&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getCode</span><span style="color: #F8F8F2">(),</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #E6DB74">&#39;title&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">__</span><span style="color: #F8F8F2">(</span><span style="color: #E6DB74">&#39;Style Discount&#39;</span><span style="color: #F8F8F2">),</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #E6DB74">&#39;value&#39;</span><span style="color: #F8F8F2"> </span><span style="color: #F92672">=&gt;</span><span style="color: #F8F8F2"> $amount</span></span>
<span class="line"><span style="color: #F8F8F2">            ];</span></span>
<span class="line"><span style="color: #F8F8F2">        }</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">return</span><span style="color: #F8F8F2"> $result;</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span>
<span class="line"><span style="color: #F8F8F2">}</span></span></code></pre></div>



<h3 class="wp-block-heading">Copying Data to Total Model in Magento 2</h3>



<p>We need to provide copying the data from the address to the total model. It&#8217;s possible with the plugin from the previous example to MagentoFrameworkApiDataObjectHelper class. But note that we should work separately with address attributes and total model attributes. We copy the first ones to the order address and the second ones &#8211; to the total model. When trying to copy some data to the receiver which can’t receive the attribute, the exception will be thrown out. The method looks like this one:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="public function beforePopulateWithArray($helper,$dataObject, array $data, $interfaceName){
        switch($interfaceName){
            case 'MagentoSalesApiDataOrderAddressInterface':
                if($data['extension_attributes'] instanceof MagentoQuoteApiDataAddressExtensionInterface){
                    $data['extension_attributes'] = $data['extension_attributes']-&gt;__toArray();
                    if(isset($data['extension_attributes']['style_discount'])){
                        unset($data['extension_attributes']['style_discount']);
                    }
                }
            break;
            case 'MagentoCustomerApiDataAddressInterface':
                if(isset($data['extension_attributes'])&amp;&amp;($data['extension_attributes'] instanceof MagentoQuoteApiDataAddressExtensionInterface)){
                    $data['extension_attributes'] = $data['extension_attributes']-&gt;__toArray();
                    if(isset($data['extension_attributes']['type'])){
                        $data['type'] = $data['extension_attributes']['type'];
                    }
                }
                break;
            case 'MagentoQuoteApiDataTotalsInterface':
                if($data['extension_attributes'] instanceof MagentoFrameworkApiAbstractSimpleObject){
                    $data['extension_attributes'] = $data['extension_attributes']-&gt;__toArray();
                    if(isset($data['extension_attributes']['type'])){
                        unset($data['extension_attributes']['type']);
                    }
                }
                break;
        }
        return array($dataObject,$data,$interfaceName);
    }" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki monokai" style="background-color: #272822" tabindex="0"><code><span class="line"><span style="color: #F92672">public</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">beforePopulateWithArray</span><span style="color: #F8F8F2">($helper,$dataObject, </span><span style="color: #F92672">array</span><span style="color: #F8F8F2"> $data, $interfaceName){</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">switch</span><span style="color: #F8F8F2">($interfaceName){</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #F92672">case</span><span style="color: #F8F8F2"> </span><span style="color: #E6DB74">&#39;MagentoSalesApiDataOrderAddressInterface&#39;</span><span style="color: #F8F8F2">:</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #F92672">if</span><span style="color: #F8F8F2">($data[</span><span style="color: #E6DB74">&#39;extension_attributes&#39;</span><span style="color: #F8F8F2">] </span><span style="color: #F92672">instanceof</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">MagentoQuoteApiDataAddressExtensionInterface</span><span style="color: #F8F8F2">){</span></span>
<span class="line"><span style="color: #F8F8F2">                    $data[</span><span style="color: #E6DB74">&#39;extension_attributes&#39;</span><span style="color: #F8F8F2">] </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $data[</span><span style="color: #E6DB74">&#39;extension_attributes&#39;</span><span style="color: #F8F8F2">]</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">__toArray</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #F92672">if</span><span style="color: #F8F8F2">(</span><span style="color: #66D9EF">isset</span><span style="color: #F8F8F2">($data[</span><span style="color: #E6DB74">&#39;extension_attributes&#39;</span><span style="color: #F8F8F2">][</span><span style="color: #E6DB74">&#39;style_discount&#39;</span><span style="color: #F8F8F2">])){</span></span>
<span class="line"><span style="color: #F8F8F2">                        </span><span style="color: #66D9EF">unset</span><span style="color: #F8F8F2">($data[</span><span style="color: #E6DB74">&#39;extension_attributes&#39;</span><span style="color: #F8F8F2">][</span><span style="color: #E6DB74">&#39;style_discount&#39;</span><span style="color: #F8F8F2">]);</span></span>
<span class="line"><span style="color: #F8F8F2">                    }</span></span>
<span class="line"><span style="color: #F8F8F2">                }</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #F92672">break</span><span style="color: #F8F8F2">;</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #F92672">case</span><span style="color: #F8F8F2"> </span><span style="color: #E6DB74">&#39;MagentoCustomerApiDataAddressInterface&#39;</span><span style="color: #F8F8F2">:</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #F92672">if</span><span style="color: #F8F8F2">(</span><span style="color: #66D9EF">isset</span><span style="color: #F8F8F2">($data[</span><span style="color: #E6DB74">&#39;extension_attributes&#39;</span><span style="color: #F8F8F2">])</span><span style="color: #F92672">&amp;&amp;</span><span style="color: #F8F8F2">($data[</span><span style="color: #E6DB74">&#39;extension_attributes&#39;</span><span style="color: #F8F8F2">] </span><span style="color: #F92672">instanceof</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">MagentoQuoteApiDataAddressExtensionInterface</span><span style="color: #F8F8F2">)){</span></span>
<span class="line"><span style="color: #F8F8F2">                    $data[</span><span style="color: #E6DB74">&#39;extension_attributes&#39;</span><span style="color: #F8F8F2">] </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $data[</span><span style="color: #E6DB74">&#39;extension_attributes&#39;</span><span style="color: #F8F8F2">]</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">__toArray</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #F92672">if</span><span style="color: #F8F8F2">(</span><span style="color: #66D9EF">isset</span><span style="color: #F8F8F2">($data[</span><span style="color: #E6DB74">&#39;extension_attributes&#39;</span><span style="color: #F8F8F2">][</span><span style="color: #E6DB74">&#39;type&#39;</span><span style="color: #F8F8F2">])){</span></span>
<span class="line"><span style="color: #F8F8F2">                        $data[</span><span style="color: #E6DB74">&#39;type&#39;</span><span style="color: #F8F8F2">] </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $data[</span><span style="color: #E6DB74">&#39;extension_attributes&#39;</span><span style="color: #F8F8F2">][</span><span style="color: #E6DB74">&#39;type&#39;</span><span style="color: #F8F8F2">];</span></span>
<span class="line"><span style="color: #F8F8F2">                    }</span></span>
<span class="line"><span style="color: #F8F8F2">                }</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #F92672">break</span><span style="color: #F8F8F2">;</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #F92672">case</span><span style="color: #F8F8F2"> </span><span style="color: #E6DB74">&#39;MagentoQuoteApiDataTotalsInterface&#39;</span><span style="color: #F8F8F2">:</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #F92672">if</span><span style="color: #F8F8F2">($data[</span><span style="color: #E6DB74">&#39;extension_attributes&#39;</span><span style="color: #F8F8F2">] </span><span style="color: #F92672">instanceof</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">MagentoFrameworkApiAbstractSimpleObject</span><span style="color: #F8F8F2">){</span></span>
<span class="line"><span style="color: #F8F8F2">                    $data[</span><span style="color: #E6DB74">&#39;extension_attributes&#39;</span><span style="color: #F8F8F2">] </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> $data[</span><span style="color: #E6DB74">&#39;extension_attributes&#39;</span><span style="color: #F8F8F2">]</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">__toArray</span><span style="color: #F8F8F2">();</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #F92672">if</span><span style="color: #F8F8F2">(</span><span style="color: #66D9EF">isset</span><span style="color: #F8F8F2">($data[</span><span style="color: #E6DB74">&#39;extension_attributes&#39;</span><span style="color: #F8F8F2">][</span><span style="color: #E6DB74">&#39;type&#39;</span><span style="color: #F8F8F2">])){</span></span>
<span class="line"><span style="color: #F8F8F2">                        </span><span style="color: #66D9EF">unset</span><span style="color: #F8F8F2">($data[</span><span style="color: #E6DB74">&#39;extension_attributes&#39;</span><span style="color: #F8F8F2">][</span><span style="color: #E6DB74">&#39;type&#39;</span><span style="color: #F8F8F2">]);</span></span>
<span class="line"><span style="color: #F8F8F2">                    }</span></span>
<span class="line"><span style="color: #F8F8F2">                }</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #F92672">break</span><span style="color: #F8F8F2">;</span></span>
<span class="line"><span style="color: #F8F8F2">        }</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">return</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF">array</span><span style="color: #F8F8F2">($dataObject,$data,$interfaceName);</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span></code></pre></div>



<h3 class="wp-block-heading">Outputting Total on Shopping Cart Page</h3>



<p>Now we are going to output a new Total on the shopping cart page. It requires us to describe and implement Magento 2 knockout-component. It’s described in Layout file the next way:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="&lt;referenceBlock name=&quot;checkout.cart.totals&quot;&gt;
            &lt;arguments&gt;
                &lt;argument name=&quot;jsLayout&quot; xsi:type=&quot;array&quot;&gt;
                    &lt;item name=&quot;components&quot; xsi:type=&quot;array&quot;&gt;
                        &lt;item name=&quot;block-totals&quot; xsi:type=&quot;array&quot;&gt;
                            &lt;item name=&quot;children&quot; xsi:type=&quot;array&quot;&gt;
                                &lt;item name=&quot;style_discount&quot; xsi:type=&quot;array&quot;&gt;
                                    &lt;item name=&quot;component&quot;  xsi:type=&quot;string&quot;&gt;Web4pro_Ajaxcart/js/style&lt;/item&gt;
                                    &lt;item name=&quot;sortOrder&quot; xsi:type=&quot;string&quot;&gt;1&lt;/item&gt;
                                    &lt;item name=&quot;config&quot; xsi:type=&quot;array&quot;&gt;
                                        &lt;item name=&quot;template&quot; xsi:type=&quot;string&quot;&gt;Web4pro_Ajaxcart/checkout/cart/totals/style&lt;/item&gt;
                                        &lt;item name=&quot;title&quot; xsi:type=&quot;string&quot; translate=&quot;true&quot;&gt;&lt;![CDATA[Style Quantity Discount]]&gt;&lt;/item&gt;
                                    &lt;/item&gt;
                                &lt;/item&gt;
                            &lt;/item&gt;
                        &lt;/item&gt;
                    &lt;/item&gt;
                &lt;/argument&gt;
            &lt;/arguments&gt;
        &lt;/referenceBlock&gt;" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki monokai" style="background-color: #272822" tabindex="0"><code><span class="line"><span style="color: #F8F8F2">&lt;</span><span style="color: #F92672">referenceBlock</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">name</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;checkout.cart.totals&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">            &lt;</span><span style="color: #F92672">arguments</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">                &lt;</span><span style="color: #F92672">argument</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">name</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;jsLayout&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">xsi:type</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;array&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">                    &lt;</span><span style="color: #F92672">item</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">name</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;components&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">xsi:type</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;array&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">                        &lt;</span><span style="color: #F92672">item</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">name</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;block-totals&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">xsi:type</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;array&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">                            &lt;</span><span style="color: #F92672">item</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">name</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;children&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">xsi:type</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;array&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">                                &lt;</span><span style="color: #F92672">item</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">name</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;style_discount&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">xsi:type</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;array&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">                                    &lt;</span><span style="color: #F92672">item</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">name</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;component&quot;</span><span style="color: #F8F8F2">  </span><span style="color: #A6E22E">xsi:type</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;string&quot;</span><span style="color: #F8F8F2">&gt;Web4pro_Ajaxcart/js/style&lt;/</span><span style="color: #F92672">item</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">                                    &lt;</span><span style="color: #F92672">item</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">name</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;sortOrder&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">xsi:type</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;string&quot;</span><span style="color: #F8F8F2">&gt;1&lt;/</span><span style="color: #F92672">item</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">                                    &lt;</span><span style="color: #F92672">item</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">name</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;config&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">xsi:type</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;array&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">                                        &lt;</span><span style="color: #F92672">item</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">name</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;template&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">xsi:type</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;string&quot;</span><span style="color: #F8F8F2">&gt;Web4pro_Ajaxcart/checkout/cart/totals/style&lt;/</span><span style="color: #F92672">item</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">                                        &lt;</span><span style="color: #F92672">item</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">name</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;title&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">xsi:type</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;string&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">translate</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;true&quot;</span><span style="color: #F8F8F2">&gt;</span><span style="color: #E6DB74">&lt;![CDATA[Style Quantity Discount]]&gt;</span><span style="color: #F8F8F2">&lt;/</span><span style="color: #F92672">item</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">                                    &lt;/</span><span style="color: #F92672">item</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">                                &lt;/</span><span style="color: #F92672">item</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">                            &lt;/</span><span style="color: #F92672">item</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">                        &lt;/</span><span style="color: #F92672">item</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">                    &lt;/</span><span style="color: #F92672">item</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">                &lt;/</span><span style="color: #F92672">argument</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">            &lt;/</span><span style="color: #F92672">arguments</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">        &lt;/</span><span style="color: #F92672">referenceBlock</span><span style="color: #F8F8F2">&gt;</span></span></code></pre></div>



<p>We choose sort_order taking into consideration that the row is outputted before Subtotal. As you can see, the component consists of a template and a javascript file. The template is loaded asynchronously, and it’s filled with the content with JavaScript. This is how the template supposed to look like:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="&lt;tr class=&quot;totals&quot;&gt;
    &lt;th class=&quot;mark&quot; scope=&quot;row&quot; data-bind=&quot;text: title&quot;&gt;&lt;/th&gt;
    &lt;td data-bind=&quot;attr: {'data-th': title}&quot; class=&quot;amount&quot;&gt;
        &lt;span class=&quot;price&quot; data-bind=&quot;text: getValue()&quot;&gt;&lt;/span&gt;
    &lt;/td&gt;
&lt;/tr&gt;" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki monokai" style="background-color: #272822" tabindex="0"><code><span class="line"><span style="color: #F8F8F2">&lt;</span><span style="color: #F92672">tr</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">class</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;totals&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">    &lt;</span><span style="color: #F92672">th</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">class</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;mark&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">scope</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;row&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">data-bind</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;text: title&quot;</span><span style="color: #F8F8F2">&gt;&lt;/</span><span style="color: #F92672">th</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">    &lt;</span><span style="color: #F92672">td</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">data-bind</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;attr: {&#39;data-th&#39;: title}&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">class</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;amount&quot;</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">        &lt;</span><span style="color: #F92672">span</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">class</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;price&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">data-bind</span><span style="color: #F8F8F2">=</span><span style="color: #E6DB74">&quot;text: getValue()&quot;</span><span style="color: #F8F8F2">&gt;&lt;/</span><span style="color: #F92672">span</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">    &lt;/</span><span style="color: #F92672">td</span><span style="color: #F8F8F2">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">&lt;/</span><span style="color: #F92672">tr</span><span style="color: #F8F8F2">&gt;</span></span></code></pre></div>



<p>JavaScript code:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="define(
    [
        'Magento_Checkout/js/view/summary/abstract-total',
        'Magento_Checkout/js/model/quote'
    ],
    function (Component, quote) {
        &quot;use strict&quot;;
        return Component.extend({

            isDisplayed: function() {
                return this.getPureValue()!=0;
            },
            getPureValue: function() {
                var totals = quote.getTotals()();
                if (totals) {
                    if(typeof totals.style_discount=='undefined'){
                        quote.setTotals(window.checkoutConfig.totalsData);
                        totals = quote.getTotals()();
                    }
                    return totals.style_discount;
                }
                return quote.style_discount;
            },
            getValue: function() {
                    return this.getFormattedPrice(this.getPureValue());
            }
         });
    }
);" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki monokai" style="background-color: #272822" tabindex="0"><code><span class="line"><span style="color: #A6E22E">define</span><span style="color: #F8F8F2">(</span></span>
<span class="line"><span style="color: #F8F8F2">    [</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #E6DB74">&#39;Magento_Checkout/js/view/summary/abstract-total&#39;</span><span style="color: #F8F8F2">,</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #E6DB74">&#39;Magento_Checkout/js/model/quote&#39;</span></span>
<span class="line"><span style="color: #F8F8F2">    ],</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> (</span><span style="color: #FD971F; font-style: italic">Component</span><span style="color: #F8F8F2">, </span><span style="color: #FD971F; font-style: italic">quote</span><span style="color: #F8F8F2">) {</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #E6DB74">&quot;use strict&quot;</span><span style="color: #F8F8F2">;</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">return</span><span style="color: #F8F8F2"> Component.</span><span style="color: #A6E22E">extend</span><span style="color: #F8F8F2">({</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #A6E22E">isDisplayed</span><span style="color: #F8F8F2">: </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2">() {</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #F92672">return</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">this</span><span style="color: #F8F8F2">.</span><span style="color: #A6E22E">getPureValue</span><span style="color: #F8F8F2">()</span><span style="color: #F92672">!=</span><span style="color: #AE81FF">0</span><span style="color: #F8F8F2">;</span></span>
<span class="line"><span style="color: #F8F8F2">            },</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #A6E22E">getPureValue</span><span style="color: #F8F8F2">: </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2">() {</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #66D9EF; font-style: italic">var</span><span style="color: #F8F8F2"> totals </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> quote.</span><span style="color: #A6E22E">getTotals</span><span style="color: #F8F8F2">()();</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #F92672">if</span><span style="color: #F8F8F2"> (totals) {</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #F92672">if</span><span style="color: #F8F8F2">(</span><span style="color: #F92672">typeof</span><span style="color: #F8F8F2"> totals.style_discount</span><span style="color: #F92672">==</span><span style="color: #E6DB74">&#39;undefined&#39;</span><span style="color: #F8F8F2">){</span></span>
<span class="line"><span style="color: #F8F8F2">                        quote.</span><span style="color: #A6E22E">setTotals</span><span style="color: #F8F8F2">(window.checkoutConfig.totalsData);</span></span>
<span class="line"><span style="color: #F8F8F2">                        totals </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> quote.</span><span style="color: #A6E22E">getTotals</span><span style="color: #F8F8F2">()();</span></span>
<span class="line"><span style="color: #F8F8F2">                    }</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #F92672">return</span><span style="color: #F8F8F2"> totals.style_discount;</span></span>
<span class="line"><span style="color: #F8F8F2">                }</span></span>
<span class="line"><span style="color: #F8F8F2">                </span><span style="color: #F92672">return</span><span style="color: #F8F8F2"> quote.style_discount;</span></span>
<span class="line"><span style="color: #F8F8F2">            },</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #A6E22E">getValue</span><span style="color: #F8F8F2">: </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2">() {</span></span>
<span class="line"><span style="color: #F8F8F2">                    </span><span style="color: #F92672">return</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">this</span><span style="color: #F8F8F2">.</span><span style="color: #A6E22E">getFormattedPrice</span><span style="color: #F8F8F2">(</span><span style="color: #FD971F">this</span><span style="color: #F8F8F2">.</span><span style="color: #A6E22E">getPureValue</span><span style="color: #F8F8F2">());</span></span>
<span class="line"><span style="color: #F8F8F2">            }</span></span>
<span class="line"><span style="color: #F8F8F2">         });</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span>
<span class="line"><span style="color: #F8F8F2">);</span></span></code></pre></div>



<p>Pay attention to the <i>if </i>condition (type of totals.style_discount==&#8217;undefined&#8217;). It’s necessary because Magento 2 extension attributes (we checked &nbsp;2.1.2 version) are written to Total JavaScript object if only the asynchronous loading takes place (_SetTotals() method). It is not being written when the page is loaded from window.checkoutConfig.totalsData.</p>



<p>We can output this component to the order page by following the same routine.</p>



<h2 class="wp-block-heading">Pitfalls</h2>



<p>One of the moments we should keep in mind is that Total content is being added while calculating the Grand Total. It’s not good for our task. The reason lies in the implementation features of Grand Total calculation in MagentoQuoteModelQuoteAddressTotalGrand class. Take a look:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="public function collect(
        MagentoQuoteModelQuote $quote,
        MagentoQuoteApiDataShippingAssignmentInterface $shippingAssignment,
        MagentoQuoteModelQuoteAddressTotal $total
    ) {
        $totals = array_sum($total-&gt;getAllTotalAmounts());
        $baseTotals = array_sum($total-&gt;getAllBaseTotalAmounts());

        $total-&gt;setGrandTotal($totals);
        $total-&gt;setBaseGrandTotal($baseTotals);
        return $this;
    }" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki monokai" style="background-color: #272822" tabindex="0"><code><span class="line"><span style="color: #F92672">public</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">collect</span><span style="color: #F8F8F2">(</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #66D9EF; font-style: italic">MagentoQuoteModelQuote</span><span style="color: #F8F8F2"> $quote,</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #66D9EF; font-style: italic">MagentoQuoteApiDataShippingAssignmentInterface</span><span style="color: #F8F8F2"> $shippingAssignment,</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #66D9EF; font-style: italic">MagentoQuoteModelQuoteAddressTotal</span><span style="color: #F8F8F2"> $total</span></span>
<span class="line"><span style="color: #F8F8F2">    ) {</span></span>
<span class="line"><span style="color: #F8F8F2">        $totals </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF">array_sum</span><span style="color: #F8F8F2">($total</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getAllTotalAmounts</span><span style="color: #F8F8F2">());</span></span>
<span class="line"><span style="color: #F8F8F2">        $baseTotals </span><span style="color: #F92672">=</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF">array_sum</span><span style="color: #F8F8F2">($total</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">getAllBaseTotalAmounts</span><span style="color: #F8F8F2">());</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F8F8F2">        $total</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">setGrandTotal</span><span style="color: #F8F8F2">($totals);</span></span>
<span class="line"><span style="color: #F8F8F2">        $total</span><span style="color: #F92672">-&gt;</span><span style="color: #A6E22E">setBaseGrandTotal</span><span style="color: #F8F8F2">($baseTotals);</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">return</span><span style="color: #F8F8F2"> </span><span style="color: #FD971F">$this</span><span style="color: #F8F8F2">;</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span></code></pre></div>



<p>We can fix this out using a plugin which excludes our total from the sum.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="&lt;type name=&quot;MagentoQuoteModelQuoteAddressTotal&quot;&gt;
        &lt;plugin name=&quot;web4pro-remove-external-totals&quot; type=&quot;Web4proAjaxcartModelPlugin&quot; sortOrder=&quot;20&quot;/&gt;
    &lt;/type&gt;

public function afterGetAllTotalAmounts($total,$result){
        if(isset($result['style_discount'])){
            unset($result['style_discount']);
        }
        return $result;
    }" style="color:#F8F8F2;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki monokai" style="background-color: #272822" tabindex="0"><code><span class="line"><span style="color: #F92672">&lt;</span><span style="color: #AE81FF">type</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">name</span><span style="color: #F92672">=</span><span style="color: #E6DB74">&quot;MagentoQuoteModelQuoteAddressTotal&quot;</span><span style="color: #F92672">&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">&lt;</span><span style="color: #AE81FF">plugin</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">name</span><span style="color: #F92672">=</span><span style="color: #E6DB74">&quot;web4pro-remove-external-totals&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">type</span><span style="color: #F92672">=</span><span style="color: #E6DB74">&quot;Web4proAjaxcartModelPlugin&quot;</span><span style="color: #F8F8F2"> </span><span style="color: #AE81FF">sortOrder</span><span style="color: #F92672">=</span><span style="color: #E6DB74">&quot;20&quot;</span><span style="color: #F92672">/&gt;</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #F92672">&lt;/</span><span style="color: #AE81FF">type</span><span style="color: #F92672">&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F92672">public</span><span style="color: #F8F8F2"> </span><span style="color: #66D9EF; font-style: italic">function</span><span style="color: #F8F8F2"> </span><span style="color: #A6E22E">afterGetAllTotalAmounts</span><span style="color: #F8F8F2">($total,$result){</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">if</span><span style="color: #F8F8F2">(</span><span style="color: #66D9EF">isset</span><span style="color: #F8F8F2">($result[</span><span style="color: #E6DB74">&#39;style_discount&#39;</span><span style="color: #F8F8F2">])){</span></span>
<span class="line"><span style="color: #F8F8F2">            </span><span style="color: #66D9EF">unset</span><span style="color: #F8F8F2">($result[</span><span style="color: #E6DB74">&#39;style_discount&#39;</span><span style="color: #F8F8F2">]);</span></span>
<span class="line"><span style="color: #F8F8F2">        }</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #F92672">return</span><span style="color: #F8F8F2"> $result;</span></span>
<span class="line"><span style="color: #F8F8F2">    }</span></span></code></pre></div>



<h2 class="wp-block-heading">Conclusion</h2>



<p>Finally, we have coped with our task. Let’s summarise what we needed to do:</p>



<ul class="wp-block-list">
<li>add the style_discount field with decimal(10,4) type to the address extension attributes table;</li>



<li>add the attribute to the extenson_attributes.xml file of our module (twice for two different interfaces);</li>



<li>create the etc/sales.xml file in the module to describe the total model;</li>



<li>implement the total model;</li>



<li>provide copying the data from the address to the total model with the plugin (work separately with address attributes and total model attributes);</li>



<li>fix the adding of Total content while calculating the Grand Total with a special plugin;</li>



<li>output a new Total on the shopping cart and the order pages.</li>
</ul>



<p>This is how it works. We hope that our article answers your question about&nbsp;set extension attributes for the total model. However, if you have some issues regarding extensions at your store and you need assistance, we can provide you with&nbsp;<a href="https://web4pro.net/service/magento-2-extension-development/">Magento 2 Extension Development</a>.</p>



<p><strong>Wish you good luck with Total Models in Magento 2!</strong></p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
