(dev/core#2258) SMTP Password - If CRED_KEYS is defined during upgrade, use it
[civicrm-core.git] / CRM / Upgrade / DispatchPolicy.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
10 */
11
12 /**
13 *
14 * @package CRM
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
16 */
17 class CRM_Upgrade_DispatchPolicy {
18
19 /**
20 * Determine the dispatch policy
21 *
22 * @param string $phase
23 * Ex: 'upgrade.main' or 'upgrade.finish'.
24 * @return array
25 * @see \Civi\Core\CiviEventDispatcher::setDispatchPolicy()
26 */
27 public static function get($phase) {
28
29 // Should hooks dispatch while applying CiviCRM DB upgrades? The answer is
30 // mixed: it depends on the specific hook and the specific upgrade-step.
31 //
32 // Some example considerations:
33 //
34 // - If the "log_civicrm_*" tables and triggers are to be reconciled during
35 // the upgrade, then one probably needs access to the list of tables and
36 // triggers defined by extensions. These are provided by hooks.
37 // - If a hook fires while the DB has stale schema, and if the hook's logic
38 // has a direct (SQL) or indirect (BAO/API) dependency on the schema, then
39 // the hook is prone to fail. (Ex: CiviCRM 4.x and the migration from
40 // civicrm_domain.config_backend to civicrm_setting.)
41 // - If *any* hook from an extension is called, then it may use classes
42 // from the same extension, so the classloader / include-path / hook_config
43 // should be operational.
44 // - If there is a general system flush at the end of the upgrade (to rebuild
45 // important data-structures -- routing tables, container cache, metadata
46 // cache, etc), then there's a huge number of hooks that should fire.
47 // - When hooks (or variations like "rules") are used to define business-logic,
48 // they probably are not intended to fire during DB upgrade. Then again,
49 // upgrade-logic is usually written with lower-level semantics that avoid firing hooks.
50 //
51 // To balance these mixed considerations, the upgrade runs in two phases:
52 //
53 // - Defensive/conservative/closed phase ("upgrade.main"): Likely mismatch
54 // between schema+code. Low-confidence in most services (APIs/hooks/etc).
55 // Ignore caches/indices/etc. Only perform low-level schema revisions.
56 // - Constructive/liberal/open phase ("upgrade.finish"): Schema+code match.
57 // Higher confidence in most services (APIs/hooks/etc).
58 // Rehydrate caches/indices/etc.
59 //
60 // Related discussions:
61 //
62 // - https://github.com/civicrm/civicrm-core/pull/17126
63 // - https://github.com/civicrm/civicrm-core/pull/13551
64 // - https://lab.civicrm.org/dev/core/issues/1449
65 // - https://lab.civicrm.org/dev/core/issues/1460
66
67 $strict = getenv('CIVICRM_UPGRADE_STRICT') || CRM_Utils_Constant::value('CIVICRM_UPGRADE_STRICT');
68 $policies = [];
69
70 // The "upgrade.main" policy applies during the planning and incremental revisions.
71 // It's more restrictive, preventing interference from unexpected callpaths.
72 $policies['upgrade.main'] = [
73 'hook_civicrm_config' => 'run',
74 // cleanupPermissions() in some UF's can be destructive. Running prematurely could be actively harmful.
75 'hook_civicrm_permission' => 'fail',
76 'hook_civicrm_crypto' => 'drop',
77 '/^hook_civicrm_(pre|post)$/' => 'drop',
78 '/^hook_civicrm_/' => $strict ? 'warn-drop' : 'drop',
79 '/^civi\./' => 'run',
80 '/./' => $strict ? 'warn-drop' : 'drop',
81 ];
82
83 // The "upgrade.finish" policy applies at the end while performing the final clear/rebuild.
84 // It's more permissive, allowing more data-structures to rehydrate correctly.
85 $policies['upgrade.finish'] = [
86 '/^hook_civicrm_(pre|post)$/' => 'drop',
87 '/./' => 'run',
88 ];
89
90 // For comparison, "upgrade.old" is an estimation of the previous policy. It
91 // was applied at all times during the upgrade.
92 $policies['upgrade.old'] = [
93 'hook_civicrm_alterSettingsFolders' => 'run',
94 'hook_civicrm_alterSettingsMetaData' => 'run',
95 'hook_civicrm_triggerInfo' => 'run',
96 'hook_civicrm_alterLogTables' => 'run',
97 'hook_civicrm_container' => 'run',
98 'hook_civicrm_permission' => 'run',
99 'hook_civicrm_managed' => 'run',
100 'hook_civicrm_config' => 'run',
101 '/^hook_civicrm_(pre|post)$/' => 'drop',
102 '/^hook_civicrm_/' => 'drop',
103 '/^civi\./' => 'run',
104 '/./' => 'run',
105 ];
106
107 // return $policies['upgrade.old'];
108 return $policies[$phase];
109 }
110
111 }