Magento2 – How to Get Module Version Outside of the Setup Directory

-setupadminhtmlconfigurationmagento2

I am trying to get the version of my Magento 2 module outside of the Setup folder to display in the admin store config area under "current version". I have some code like this. I've tried this using both DI for the ModuleContextVersion class and calling the object manager directly, both results give the same error. Code:

<?php

namespace SalesIgniter\Rental\Block\Adminhtml\Form\Renderer\Config;

//use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Config\Block\System\Config\Form\Field;
use Magento\Framework\Data\Form\Element\AbstractElement;


class Version extends Field
{

    /**
     * @param AbstractElement $element
     * @return string
     */
    protected function _getElementHtml(AbstractElement $element)
    {
        $om = \Magento\Framework\App\ObjectManager::getInstance();
        $context = $om->get('\Magento\Framework\Setup\ModuleContextInterface');;
        return $context->getVersion();
    }

This is the system.xml code I have which doesn't really have to do with the error message, but you'll see what I'm trying to do:

<group id="current_version" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="1"
               showInStore="1">
            <label>Current Version Installed</label>
            <field id="version" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1"
                   showInStore="1">
                <label>Current Version</label>
                <frontend_model>SalesIgniter\Rental\Block\Adminhtml\Form\Renderer\Config\Version</frontend_model>
            </field>
        </group>

The error it gives me using either DI or calling object manager is:

Fatal error: Uncaught Error: Cannot instantiate interface Magento\Framework\Setup\ModuleContextInterface in vendor\magento\framework\ObjectManager\Factory\Dynamic\Developer.php on line 73

Best Answer

Try \Magento\Framework\Module\ResourceInterface::getDbVersion('Module_Key').

And use a backend model, rather than a frontend model/input renderer.

Like so:

<?php

namespace SalesIgniter\Rental\Model\Config;

/**
 * Config backend model for version display.
 */
class Version extends \Magento\Framework\App\Config\Value
{
    /**
     * @var \Magento\Framework\Module\ResourceInterface
     */
    protected $moduleResource;

    /**
     * @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\Framework\Module\ResourceInterface $moduleResource
     * @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\Framework\Module\ResourceInterface $moduleResource,
        \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
        \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
        array $data = []
    ) {
        $this->moduleResource = $moduleResource;

        parent::__construct(
            $context,
            $registry,
            $config,
            $cacheTypeList,
            $resource,
            $resourceCollection,
            $data
        );
    }

    /**
     * Inject current installed module version as the config value.
     *
     * @return void
     */
    public function afterLoad()
    {
        $version = $this->moduleResource->getDbVersion('SalesIgniter_Rental');

        $this->setValue($version);
    }
}

And your system.xml setting definition will look like:

        <group id="current_version" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
            <label>Current Version Installed</label>
            <field id="version" translate="label" type="label" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
                <label>Current Version</label>
                <backend_model>SalesIgniter\Rental\Model\Config\Version</backend_model>
            </field>
        </group>
Related Topic