8

I see in the di.xml files from the core that some of the arguments have the type init_parameter but the values of the parameters are all constants.

<type name="Magento\Framework\View\Page\Config\Renderer">
    <arguments>
        <argument name="appMode" xsi:type="init_parameter">Magento\Framework\App\State::PARAM_MODE</argument>
    </arguments>
</type>

or this one

<type name="Magento\Framework\App\Cache\State">
    <arguments>
        <argument name="banAll" xsi:type="init_parameter">Magento\Framework\App\Cache\State::PARAM_BAN_CACHE</argument>
    </arguments>
</type>

and many others.
But from what I see in the interpreter associated to init_parameter, the constant interpreter is used Magento\Framework\App\Arguments\ArgumentInterpreter::evaluate

public function evaluate(array $data)
{
    return ['argument' => $this->constInterpreter->evaluate($data)];
}

But the result is a bit different from the Magento\Framework\Data\Argument\Interpreter\Constant::evaluate

 public function evaluate(array $data)
{
    if (!isset($data['value']) || !defined($data['value'])) {
        throw new \InvalidArgumentException('Constant name is expected.');
    }
    return constant($data['value']);
}

Can someone explain please how the init_parameter type works and how everything happens under the hood?

17

Found it.
For const the value of the specified constant is used.
For init_parameter, the value provided must be a constant name but the actual value used is the value of $_SERVER[constant value here].

In the method Magento\Framework\ObjectManager\Factory\AbstractFactory::resolveArgument metohod you will find this

    else if ($argument === (array)$argument) {
        if (isset($argument['argument'])) {
            if (isset($this->globalArguments[$argument['argument']])) {
                $argument = $this->globalArguments[$argument['argument']];
            } else {
                $argument = $paramDefault;
            }
        } else if (!empty($argument)) {
            $this->parseArray($argument);
        }
    }

$argument['argument'] looks very similar to what the init parameter interpreter returns.
And if there is a value with the key $argument['argument'] in the globalArguments member that one is returned.
globalArguments member is populated with the arguments with which the bootstrap class is initialized.
So for the web application these arguments are $_SERVER. (see index.php).

Conclusion:

<argument name="appMode" xsi:type="init_parameter">Magento\Framework\App\State::PARAM_MODE</argument>

means that the parameter named appMode will have the value $_SERVER[Magento\Framework\App\State::PARAM_MODE] if it is set.
Which means $_SERVER['MAGE_MODE']

| improve this answer | |
  • 2
    I think this information should be added to the official documentation. Thanks for the detailed exploration. :) – Siarhey Uchukhlebau May 3 '18 at 6:21
1

What are all the allowed `xsi:type` values in the xml's from Magento2

http://devdocs.magento.com/guides/v2.0/extension-dev-guide/build/di-xml-file.html

enter image description here

Node format: <argument xsi:type="init_parameter">{Constant::NAME}</argument>
Description: Global argument of an application represented by Constant::NAME is looked up and passed as an argument.
Possible values: Constant the global argumentcontaining name

Node format: <argument xsi:type="const">{Constant::NAME}</argument>
Description: Constant::NAME passed as an argument.
Possible values: All constant names are possible.

Let's take below example.

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

<type name="Magento\Store\Model\StoreResolver">
    <arguments>
        <argument name="cache" xsi:type="object">Magento\Framework\App\Cache\Type\Config</argument>
        <argument name="runMode" xsi:type="init_parameter">Magento\Store\Model\StoreManager::PARAM_RUN_TYPE</argument>
        <argument name="scopeCode" xsi:type="init_parameter">Magento\Store\Model\StoreManager::PARAM_RUN_CODE</argument>
    </arguments>
</type>

magento\vendor\magento\module-store\Model\StoreResolver.php

/**
 * @var string
 */
protected $runMode;

/**
 * @var string
 */
protected $scopeCode;

/**
 * @param \Magento\Store\Api\StoreRepositoryInterface $storeRepository
 * @param StoreCookieManagerInterface $storeCookieManager
 * @param \Magento\Framework\App\RequestInterface $request
 * @param \Magento\Framework\Cache\FrontendInterface $cache
 * @param StoreResolver\ReaderList $readerList
 * @param string $runMode
 * @param null $scopeCode
 */
public function __construct(
    \Magento\Store\Api\StoreRepositoryInterface $storeRepository,
    StoreCookieManagerInterface $storeCookieManager,
    \Magento\Framework\App\RequestInterface $request,
    \Magento\Framework\Cache\FrontendInterface $cache,
    StoreResolver\ReaderList $readerList,
    $runMode = ScopeInterface::SCOPE_STORE,
    $scopeCode = null
) {
    $this->storeRepository = $storeRepository;
    $this->storeCookieManager = $storeCookieManager;
    $this->request = $request;
    $this->cache = $cache;
    $this->readerList = $readerList;
    $this->runMode = $scopeCode ? $runMode : ScopeInterface::SCOPE_WEBSITE;
    $this->scopeCode = $scopeCode;
}

Idea is simple. You can directly pass your variables & it's value from di.xml file. Instead of defining that values in ur Model.

So u just need to initialize ur variables & u will get value from ur di.xml

Hope it helps

| improve this answer | |
  • It doens't really help because it does not answer my question. I asked for the difference between const and init_parameter in behavior. – Marius Feb 21 '17 at 5:56

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.