8

I am using Magento 2.2.5

have a look on file

vendor\magento\module-sales\etc\di.xml

<type name="Magento\Payment\Model\Checks\SpecificationFactory">
    <arguments>
        <argument name="mapping" xsi:type="array">
            <item name="country" xsi:type="object">Magento\Payment\Model\Checks\CanUseForCountry</item>
            <item name="currency" xsi:type="object">Magento\Payment\Model\Checks\CanUseForCurrency</item>
            <item name="checkout" xsi:type="object">Magento\Payment\Model\Checks\CanUseCheckout</item>
            <item name="internal" xsi:type="object">Magento\Payment\Model\Checks\CanUseInternal</item>
            <item name="total" xsi:type="object">Magento\Payment\Model\Checks\TotalMinMax</item>
            <item name="zero_total" xsi:type="object">Magento\Payment\Model\Checks\ZeroTotal</item>
        </argument>
    </arguments>
</type>

there is a node having a name "mapping". Does anyone have any idea about its use?

I have read the question Magento 2 - What case I use di.xml and How to use di.xml for a module? and Alan storm's article "Magento 2 Object Manager Argument Replacement"

Thanks

2

When you check Magento\Payment\Model\Checks\SpecificationFactory of the construt

public function __construct(\Magento\Payment\Model\Checks\CompositeFactory $compositeFactory, array $mapping)
    {
        $this->compositeFactory = $compositeFactory;
        $this->mapping = $mapping;
    }

Second argument array $mapping in the array you will get all your argument which you defined in di.xml

EDIT

from the construct $this->mapping you will find all of the objects in the array which you defined in di.xml.

For example If you set <argument name="mappingtest" xsi:type="array"> then you need to define construct as

 public function __construct(
\Magento\Payment\Model\Checks\CompositeFactory $compositeFactory, array $mappingytest
) {
    $this->compositeFactory = $compositeFactory;
    $this->mapping = $mapping;
}

Here $mappingytest

| improve this answer | |
  • I have seen this, but unable to understand the logic of this file. You mean to say if we use mapping node, It'll add an array parameter in respective type class here 'Magento\Payment\Model\Checks\SpecificationFactory'. – Knight017 Dec 24 '18 at 13:06
  • Is this related to the last argument we pass in all model's constructor the array $data = []? – Knight017 Dec 24 '18 at 13:09
  • Yes, it is related to last parameter as mentioned in my answer mapping – Keyur Shah Dec 24 '18 at 13:11
  • Still you have any query? @Knight017 :) – Keyur Shah Dec 25 '18 at 11:38
  • No, actually I have concluded the answer by editing your answer. But somehow it is not showing now. – Knight017 Dec 25 '18 at 12:09
2

The object manager injects the Magento\Core\Model\Url implementation class wherever there is a request for the Magento\Core\Model\UrlInterface in the global scope.

Multiple validation for different modules with filed.

<argument name="mapping" xsi:type="array">
                <item name="country" xsi:type="object">Magento\Payment\Model\Checks\CanUseForCountry</item>
                <item name="currency" xsi:type="object">Magento\Payment\Model\Checks\CanUseForCurrency</item>
                <item name="checkout" xsi:type="object">Magento\Payment\Model\Checks\CanUseCheckout</item>
                <item name="internal" xsi:type="object">Magento\Payment\Model\Checks\CanUseInternal</item>
                <item name="total" xsi:type="object">Magento\Payment\Model\Checks\TotalMinMax</item>
                <item name="zero_total" xsi:type="object">Magento\Payment\Model\Checks\ZeroTotal</item>
            </argument>

Now check SpecificationFactory file for Business logic.

vendor/magento/module-payment/Model/Checks/SpecificationFactory.php

class SpecificationFactory
{
    /**
     * Composite Factory
     *
     * @var \Magento\Payment\Model\Checks\CompositeFactory
     */
    protected $compositeFactory;

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

    /**
     * Construct
     *
     * @param \Magento\Payment\Model\Checks\CompositeFactory $compositeFactory
     * @param array $mapping
     */
    public function __construct(\Magento\Payment\Model\Checks\CompositeFactory $compositeFactory, array $mapping)
    {
        $this->compositeFactory = $compositeFactory;
        $this->mapping = $mapping;
    }

    /**
     * Creates new instances of payment method models
     *
     * @param array $data
     * @return Composite
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function create($data)
    {
        $specifications = array_intersect_key($this->mapping, array_flip((array)$data));
        return $this->compositeFactory->create(['list' => $specifications]);
    }
}

It validates the mapping data module wise.

$specifications = array_intersect_key($this->mapping, array_flip((array)$data));
| improve this answer | |
0

Conclusion

The conversation with @Keyur Shah and the suggestion of @Jignesh Khunt conclude that you can add configurations in di.xml and can access in type class here Magento\Payment\Model\Checks\SpecificationFactory. In last param array $mapping in below files constructor.

vendor\magento\module-payment\Model\Checks\SpecificationFactory.php

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Magento\Payment\Model\Checks;

/**
 * Creates complex specification.
 *
 * Use this class to register predefined list of specifications that should be added to any complex specification.
 *
 * @api
 * @since 100.0.2
 */
class SpecificationFactory
{
    /**
     * Composite Factory
     *
     * @var \Magento\Payment\Model\Checks\CompositeFactory
     */
    protected $compositeFactory;

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

    /**
     * Construct
     *
     * @param \Magento\Payment\Model\Checks\CompositeFactory $compositeFactory
     * @param array $mapping
     */
    public function __construct(\Magento\Payment\Model\Checks\CompositeFactory $compositeFactory, array $mapping)
    {
        $this->compositeFactory = $compositeFactory;
        $this->mapping = $mapping;
    }

    /**
     * Creates new instances of payment method models
     *
     * @param array $data
     * @return Composite
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function create($data)
    {
        $specifications = array_intersect_key($this->mapping, array_flip((array)$data));
        return $this->compositeFactory->create(['list' => $specifications]);
    }
}

The argument node (here "$mapping") must be member variable of the type class(Magento\Payment\Model\Checks\SpecificationFactory).

Then the data you pass in di.xml will be accessible and usable in your factory class and you can customize the logic. I have used to initialize dynamic class according to data available in $mapping array (without rewrite or plugin/prefrence) using this feature.

| improve this answer | |

Your Answer

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

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