This patch fixes an upgrade bug where `CachedCiviContainer` has stale data after an upgrade.
To do this, it removes an edge-case where two overlapping functions disagree.
Steps to Reproduce
------------------
1. Create a new/empty WP build
2. Install CiviCRM 5.30.1 from zipball
3. Install Mosaico 2.5
4. Download+extract new 5.32.1 zipball
5. Navigate to the GUI upgrade screen. Execute upgrade
6. Click to go back to the CiviCRM dashboard.
7. Receive error about the service 'mosaico_graphics'
Discussion
----------
The problem is created while running the upgrade GUI (step 5). The GUI sends several HTTP
requests (`civicrm/upgrade`, `civicrm/upgrade/queue/ajax/runNext`, etc). At the end, there is
an HTTP request for `civicrm/ajax/l10n-js/en_US`. The `l10n-js` request creates a flawed copy
of `CachedCiviContainer` which is responsible for subsequent errors.
This shouldn't happen - there are defensive mechanism which prevent it from happening (e.g.
during `civicrm/upgrade`). What makes `civicrm/ajax/l10n-js/en_US` different? It turns on
the implementation of `isUpgradeMode()` which activates the defensive mechanisms.
Before
------
There are two implementations of `isUpgradeMode()` (via `CRM_Core_Config` and
`CRM_Utils_System`). They often agree, but not always.
Some defensive measures trigger on `CRM_Core_Config::isUpgradeMode()` and others trigger on
`CRM_Utils_System::isUpgradeMode()`. They often trigger together, but not always.
Let's see how these can playout in a few HTTP requests:
1. `civicrm/dashboard`: The functions agree -- it's a regular page, not an upgrade. Therefore:
* (a) It allows extensions to run fully.
* (b) It enables `CachedCiviContainer` (read or write automatically).
* (a+b) It puts good/full information in the cache.
2. `civicrm/upgrade`: The functions agree -- it's an upgrade. Therefore:
* (a) It runs in paranoid mode (suspended extensions).
* (b) It disables `CachedCiviContainer`.
* (a+b) It puts no information in the cache.
3. `civicrm/ajax/l10n-js/en_US`: The functions *disagree*. In this case:
* (a) It runs in paranoid mode (suspended extensions).
* (b) It enables `CachedCiviContainer` (read or write automatically).
* (a+b) It puts bad/incomplete information in the cache.
After
-----
There is one implementation of `isUpgradeMode()`. It may be called through
either class (`CRM_Core_Config` or `CRM_Utils_System`), but the results will
always agree.
This produces the same appropriate outcome for cases of agreement (1) (2), and it fixes the
wonky/mismatched behavior in (3).
return TRUE;
}
+ $upgradeInProcess = CRM_Core_Session::singleton()->get('isUpgradePending');
+ if ($upgradeInProcess) {
+ return TRUE;
+ }
+
if (!$path) {
// note: do not re-initialize config here, since this function is part of
// config initialization itself
* Is in upgrade mode.
*
* @return bool
+ * @deprecated
+ * @see CRM_Core_Config::isUpgradeMode()
*/
public static function isInUpgradeMode() {
- $args = explode('/', CRM_Utils_Array::value('q', $_GET));
- $upgradeInProcess = CRM_Core_Session::singleton()->get('isUpgradePending');
- if ((isset($args[1]) && $args[1] == 'upgrade') || $upgradeInProcess) {
- return TRUE;
- }
- else {
- return FALSE;
- }
+ return CRM_Core_Config::isUpgradeMode();
}
/**