How to Get Composer Version of Installed Modules in Magento 2

composermagento2

How can I get, code wise, the list of the installed modules and their version listed in composer?

I need something like this (format is just as an example. It's not really important):

array(
    array(
        'name' => 'magento/module-catalog',
        'version' => '101.1.0'
    ),
    array(
        'name' => 'magento/module-cms',
        'version' => '101.1.0'
    ),
....
)

I tried \Magento\Framework\Composer\ComposerInformation::getInstalledMagentoPackages() and getSystemPackages(), but both return and empty array.

I suspect this might happen because I didn't install Magento 2 via composer. I just cloned the guthub repo.

But this is not a solution. I need something that will work on both install methods (composers and clone repo).

Best Answer

Maybe my code can be useful for you (tested in the observer):

/**
 * @var \Magento\Framework\App\DeploymentConfig
 */
protected $deploymentConfig;

/**
 * @var \Magento\Framework\Component\ComponentRegistrarInterface
 */
protected $componentRegistrar;

/**
 * @var \Magento\Framework\Filesystem\Directory\ReadFactory
 */
protected $readFactory;

/**
 * @param \Magento\Framework\App\DeploymentConfig $deploymentConfig
 * @param \Magento\Framework\Component\ComponentRegistrarInterface $componentRegistrar
 * @param \Magento\Framework\Filesystem\Directory\ReadFactory $readFactory
 */
public function __construct(
    \Magento\Framework\App\DeploymentConfig $deploymentConfig,
    \Magento\Framework\Component\ComponentRegistrarInterface $componentRegistrar,
    \Magento\Framework\Filesystem\Directory\ReadFactory $readFactory
) {
    $this->deploymentConfig = $deploymentConfig;
    $this->componentRegistrar = $componentRegistrar;
    $this->readFactory = $readFactory;
}

/**
 * Get module composer version
 *
 * @param $moduleName
 * @return \Magento\Framework\Phrase|string|void
 */
public function getModuleVersion($moduleName)
{
    $path = $this->componentRegistrar->getPath(
        \Magento\Framework\Component\ComponentRegistrar::MODULE,
        $moduleName
    );
    $directoryRead = $this->readFactory->create($path);
    $composerJsonData = $directoryRead->readFile('composer.json');
    $data = json_decode($composerJsonData);

    return !empty($data->version) ? $data->version : __('Read error!');
}

/**
 * Collect enabled modules version
 *
 * @param Observer $observer
 */
public function execute(Observer $observer)
{
    $modules = $this->deploymentConfig->get('modules');
    $modulesWithVersion = [];
    foreach ($modules as $moduleName => $isEnabled) {
        if (!$isEnabled) {
            continue;
        }

        $modulesWithVersion[$moduleName] = $this->getModuleVersion($moduleName);
    }
}
  1. Collects all enabled module names from the config
  2. Reads their composer.json one-by-one and saves version

Result (in debug):

Result

Related Topic