Sequence of Magento 2 Install / Upgrade / Recurring scripts

Sequence of Magento 2 Install / Upgrade / Recurring scripts

Preamble

In one of my last tasks I had to write an upgrade script in which an assignment of a newly created frontend theme to some of the stores should be implemented.

The following code-part describes what I did here:

/**
 *
 */
protected function assignNewThemeToSelectedStores()
{
    $storeIdsForNewTheme = [];

    foreach ($this->storesCodesWithNewTheme as $storeCode) {
        $storeIdsForNewTheme[] = $this->storeRepository->get($storeCode)->getId();
    }

    /** @var \Magento\Theme\Model\ResourceModel\Theme\Collection $themes */
    $themes = $this->themeCollectionFactory->create()->loadRegisteredThemes();
    /**
     * @var \Magento\Theme\Model\Theme $theme
     */
    foreach ($themes as $theme) {
       if ($theme->getCode() === 'Mynewly/createdtheme') {
       $this->themeConfig->assignToStore(
           $theme,
           $storeIdsForNewTheme
       );
       }
    }
}

As I already had an InstallData Script in the module and it already has run on some dev machines and staging systems, I put the following code to the newly created UpgradeData script.

The problem

The code in the upgrade script did not take any effect after running php bin/magento setup:upgrade. I found out that I could force it to take effect only after deleting the module entry from setup_module table an re-running setup:upgrade command.

The reason

Debugging of the setup:upgrade command revealed the fact, that at the moment of the first execution of my UpgradeData script, the new theme was not registered in the “theme” Magento DB table. It looked strange for me, because I’ve added a dependency to “Magento_Theme” module in my module.xml, as I obviously relied on this module’s code and data.

I then found out, that the registration of newly added themes is implemented in the following script:

vendor/magento/module-theme/Setup/RecurringData.php

After debugging and analyzing the setup:upgrade command code, I came to the following result: in Magento the Setup Scripts are executed in the following order:

  • InstallSchema & UpgradeSchema
  • Recurring (Schema)
  • InstallData & UpgradeData
  • RecurringData

In this scopes the dependencies of the modules affect the sequence of the script execution, but if your module’s script depends on the code which is executed in a script of another module in a later scope than the scope of your script, your code will not work.

The solution

As my script depends on the latest scope “RecurringData” I had no choice than to put my code also in a “RecurringData” script. As recurring means it is executed on each setup:upgrade run, I made some checks in my script, in order to execute some performance critical tasks only if the right theme isn’t already set for the relevant stores.

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *