Commit | Line | Data |
---|---|---|
31236900 TO |
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 | * The revisions trait automatically enqueues any functions named 'upgrade_NNNN()' | |
14 | * (where NNNN is taken to be a revision number). | |
15 | */ | |
16 | trait CRM_Extension_Upgrader_RevisionsTrait { | |
17 | ||
18 | /** | |
19 | * @return string | |
20 | */ | |
21 | abstract public function getExtensionKey(); | |
22 | ||
23 | abstract protected function appendTask(string $title, string $funcName, ...$options); | |
24 | ||
25 | /** | |
26 | * @var array | |
27 | * sorted numerically | |
28 | */ | |
29 | private $revisions; | |
30 | ||
31 | /** | |
32 | * @var bool | |
33 | * Flag to clean up extension revision data in civicrm_setting | |
34 | */ | |
35 | private $revisionStorageIsDeprecated = FALSE; | |
36 | ||
37 | /** | |
38 | * Determine if there are any pending revisions. | |
39 | * | |
40 | * @return bool | |
41 | */ | |
42 | public function hasPendingRevisions() { | |
43 | $revisions = $this->getRevisions(); | |
44 | $currentRevision = $this->getCurrentRevision(); | |
45 | ||
46 | if (empty($revisions)) { | |
47 | return FALSE; | |
48 | } | |
49 | if (empty($currentRevision)) { | |
50 | return TRUE; | |
51 | } | |
52 | ||
53 | return ($currentRevision < max($revisions)); | |
54 | } | |
55 | ||
56 | /** | |
57 | * Add any pending revisions to the queue. | |
58 | */ | |
59 | public function enqueuePendingRevisions() { | |
60 | $currentRevision = $this->getCurrentRevision(); | |
61 | foreach ($this->getRevisions() as $revision) { | |
62 | if ($revision > $currentRevision) { | |
63 | $title = ts('Upgrade %1 to revision %2', [ | |
64 | 1 => $this->getExtensionKey(), | |
65 | 2 => $revision, | |
66 | ]); | |
67 | ||
68 | // note: don't use addTask() because it sets weight=-1 | |
69 | ||
70 | $this->appendTask($title, 'upgrade_' . $revision); | |
71 | $this->appendTask($title, 'setCurrentRevision', $revision); | |
72 | } | |
73 | } | |
74 | } | |
75 | ||
76 | /** | |
77 | * Get a list of revisions. | |
78 | * | |
79 | * @return array | |
80 | * revisionNumbers sorted numerically | |
81 | */ | |
82 | public function getRevisions() { | |
83 | if (!is_array($this->revisions)) { | |
84 | $this->revisions = []; | |
85 | ||
86 | $clazz = new \ReflectionClass(get_class($this)); | |
87 | $methods = $clazz->getMethods(); | |
88 | foreach ($methods as $method) { | |
89 | if (preg_match('/^upgrade_(.*)/', $method->name, $matches)) { | |
90 | $this->revisions[] = $matches[1]; | |
91 | } | |
92 | } | |
93 | sort($this->revisions, SORT_NUMERIC); | |
94 | } | |
95 | ||
96 | return $this->revisions; | |
97 | } | |
98 | ||
99 | public function getCurrentRevision() { | |
100 | $revision = CRM_Core_BAO_Extension::getSchemaVersion($this->getExtensionKey()); | |
101 | if (!$revision) { | |
102 | $revision = $this->getCurrentRevisionDeprecated(); | |
103 | } | |
104 | return $revision; | |
105 | } | |
106 | ||
107 | private function getCurrentRevisionDeprecated() { | |
108 | $key = $this->getExtensionKey() . ':version'; | |
109 | if ($revision = \Civi::settings()->get($key)) { | |
110 | $this->revisionStorageIsDeprecated = TRUE; | |
111 | } | |
112 | return $revision; | |
113 | } | |
114 | ||
115 | public function setCurrentRevision($revision) { | |
116 | CRM_Core_BAO_Extension::setSchemaVersion($this->getExtensionKey(), $revision); | |
117 | // clean up legacy schema version store (CRM-19252) | |
118 | $this->deleteDeprecatedRevision(); | |
119 | return TRUE; | |
120 | } | |
121 | ||
122 | private function deleteDeprecatedRevision() { | |
123 | if ($this->revisionStorageIsDeprecated) { | |
124 | $setting = new \CRM_Core_BAO_Setting(); | |
125 | $setting->name = $this->getExtensionKey() . ':version'; | |
126 | $setting->delete(); | |
127 | CRM_Core_Error::debug_log_message("Migrated extension schema revision ID for {$this->getExtensionKey()} from civicrm_setting (deprecated) to civicrm_extension.\n"); | |
128 | } | |
129 | } | |
130 | ||
131 | } |