forked from backdrop-contrib/backdrop_upgrade_status
-
Notifications
You must be signed in to change notification settings - Fork 0
/
backdrop_upgrade_status.module
331 lines (294 loc) · 11.5 KB
/
backdrop_upgrade_status.module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
<?php
/**
* @file
* Checks to see if your installed modules are for upgrade to Backdrop CMS.
*/
/**
* Default version of core we want to query for.
*/
define('BACKDROP_UPGRADE_STATUS_CORE_VERSION', '8.x');
/**
* Project has a new release available, but it is not a security release.
*/
define('BACKDROP_UPGRADE_STATUS_DEVELOPMENT', 1000);
/**
* Project is available.
*/
define('BACKDROP_UPGRADE_STATUS_STABLE', 5);
/**
* Project has been moved into core.
*/
define('BACKDROP_UPGRADE_STATUS_CORE', 5000);
/**
* Project has become obsolete by an alternative.
*/
define('BACKDROP_UPGRADE_STATUS_OBSOLETE', 3000);
/**
* Default project release history URL.
*/
define('BACKDROP_UPGRADE_UPDATE_DEFAULT_URL', 'https://updates.backdropcms.org/release-history');
/**
* Implementation of hook_help().
*/
function backdrop_upgrade_status_help($path, $arg) {
switch ($path) {
case 'admin/help#module':
$file = drupal_get_path('module', 'backdrop_upgrade_status') .'/README.txt';
if (file_exists($file)) {
return _filter_autop(file_get_contents($file));
}
break;
}
}
/**
* Implements hook_cron().
*/
function backdrop_upgrade_status_cron() {
// If the minimum lifetime hasn't been passed, skip.
$lifetime = REQUEST_TIME - variable_get('backdrop_upgrade_status_last_check', 0);
if ($lifetime < variable_get('backdrop_upgrade_status_lifetime', 86400)) {
return;
}
module_load_include('inc', 'backdrop_upgrade_status', 'backdrop_upgrade_status.fetch');
backdrop_upgrade_status_manual_status();
variable_set('backdrop_upgrade_status_last_check', REQUEST_TIME);
}
/**
* Implementation of hook_menu().
*/
function backdrop_upgrade_status_menu() {
// Add update status page for Backdrop modules.
$items['admin/reports/updates/backdrop-upgrade'] = array(
'title' => 'Backdrop upgrade status',
'page callback' => 'backdrop_upgrade_status_status',
'access arguments' => array('administer site configuration'),
'type' => MENU_LOCAL_TASK,
'weight' => 10,
'file' => 'backdrop_upgrade_status.report.inc'
);
$items['admin/reports/updates/backdrop-upgrade/check'] = array(
'page callback' => 'backdrop_upgrade_status_manual_status',
'access arguments' => array('administer site configuration'),
'type' => MENU_CALLBACK,
'file' => 'backdrop_upgrade_status.fetch.inc'
);
// Add overview report.
$items['admin/reports/backdrop-upgrade'] = array(
'title' => 'Backdrop upgrade overview',
'description' => 'Report of site informaton useful in preparing for upgrade to Backdrop CMS.',
'page callback' => 'drupal_get_form',
'page arguments' => array('backdrop_upgrade_status_report'),
'access arguments' => array('administer site configuration'),
'type' => MENU_NORMAL_ITEM,
'file' => 'backdrop_upgrade_status.overview.inc'
);
return $items;
}
/**
* Implementation of hook_theme().
*/
function backdrop_upgrade_status_theme() {
return array(
'backdrop_upgrade_status_last_check' => array(
'variables' => array('last' => NULL),
),
'backdrop_upgrade_status_report' => array(
'variables' => array('data' => NULL),
'file' => 'backdrop_upgrade_status.report.inc',
),
'backdrop_upgrade_status_status_label' => array(
'variables' => array('status' => NULL, 'project' => NULL),
),
);
}
/**
* Tries to get update information from cache and refreshes it when necessary.
*
* In addition to checking the cache lifetime, this function also ensures that
* there are no .info files for enabled modules or themes that have a newer
* modification timestamp than the last time we checked for available update
* data. If any .info file was modified, it almost certainly means a new version
* of something was installed. Without fresh available update data, the logic in
* update_calculate_project_data() will be wrong and produce confusing, bogus
* results.
*
* @param $refresh
* (optional) Boolean to indicate if this method should refresh the cache
* automatically if there's no data. Defaults to FALSE.
*
* @return
* Array of data about available releases, keyed by project shortname.
*
* @see backdrop_upgrade_status_refresh()
* @see update_get_projects()
*/
function backdrop_upgrade_status_get_available($refresh = FALSE) {
module_load_include('inc', 'backdrop_upgrade_status', 'backdrop_upgrade_status.compare');
$needs_refresh = FALSE;
// Grab whatever data we currently have cached in the DB.
$available = _backdrop_upgrade_status_get_cached_available_releases();
$num_avail = count($available);
$projects = update_get_projects();
foreach ($projects as $key => $project) {
// If there's no data at all, we clearly need to fetch some.
if (empty($available[$key])) {
backdrop_upgrade_status_create_fetch_task($project);
$needs_refresh = TRUE;
continue;
}
// See if the .info file is newer than the last time we checked for data,
// and if so, mark this project's data as needing to be re-fetched. Any
// time an admin upgrades their local installation, the .info file will
// be changed, so this is the only way we can be sure we're not showing
// bogus information right after they upgrade.
if ($project['info']['_info_file_ctime'] > $available[$key]['last_fetch']) {
$available[$key]['fetch_status'] = UPDATE_FETCH_PENDING;
}
// If we have project data but no release data, we need to fetch. This
// can be triggered when we fail to contact a release history server.
if (empty($available[$key]['releases'])) {
$available[$key]['fetch_status'] = UPDATE_FETCH_PENDING;
}
// If we think this project needs to fetch, actually create the task now
// and remember that we think we're missing some data.
if (!empty($available[$key]['fetch_status']) && $available[$key]['fetch_status'] == UPDATE_FETCH_PENDING) {
backdrop_upgrade_status_create_fetch_task($project);
$needs_refresh = TRUE;
}
}
if ($needs_refresh && $refresh) {
// Attempt to drain the queue of fetch tasks.
backdrop_upgrade_status_fetch_data();
// After processing the queue, we've (hopefully) got better data, so pull
// the latest from the cache again and use that directly.
$available = _backdrop_upgrade_status_get_cached_available_releases();
}
return $available;
}
/**
* Creates a new fetch task after loading the necessary include file.
*
* @param $project
* Associative array of information about a project. See update_get_projects()
* for the keys used.
*
* @see _backdrop_upgrade_status_create_fetch_task()
*/
function backdrop_upgrade_status_create_fetch_task($project) {
module_load_include('inc', 'backdrop_upgrade_status', 'backdrop_upgrade_status.fetch');
return _backdrop_upgrade_status_create_fetch_task($project);
}
/**
* Refreshes the release data after loading the necessary include file.
*
* @see _backdrop_upgrade_status_refresh()
*/
function backdrop_upgrade_status_refresh() {
module_load_include('inc', 'backdrop_upgrade_status', 'backdrop_upgrade_status.fetch');
return _backdrop_upgrade_status_refresh();
}
/**
* Attempts to fetch update data after loading the necessary include file.
*
* @see _backdrop_upgrade_status_fetch_data()
*/
function backdrop_upgrade_status_fetch_data() {
module_load_include('inc', 'backdrop_upgrade_status', 'backdrop_upgrade_status.fetch');
return _backdrop_upgrade_status_fetch_data();
}
/**
* Returns all currently cached data about available releases for all projects.
*
* @return
* Array of data about available releases, keyed by project shortname.
*/
function _backdrop_upgrade_status_get_cached_available_releases() {
$data = array();
$cache_items = _update_get_cache_multiple('backdrop_upgrade_status_available_releases');
foreach ($cache_items as $cid => $cache) {
$cache->data['last_fetch'] = $cache->created;
if ($cache->expire < REQUEST_TIME) {
$cache->data['fetch_status'] = UPDATE_FETCH_PENDING;
}
// The project shortname is embedded in the cache ID, even if there's no
// data for this project in the DB at all, so use that for the indexes in
// the array.
$parts = explode('::', $cid, 2);
$data[$parts[1]] = $cache->data;
}
return $data;
}
/**
* Returns HTML for the last time we checked for update data.
*
* In addition to properly formatting the given timestamp, this function also
* provides a "Check manually" link that refreshes the available update and
* redirects back to the same page.
*
* @param $variables
* An associative array containing:
* - last: The timestamp when the site last checked for available updates.
*
* @see theme_backdrop_upgrade_status_report()
* @ingroup themeable
*/
function theme_backdrop_upgrade_status_last_check($variables) {
$last = $variables['last'];
$output = '<div class="update checked">';
$output .= $last ? t('Last checked: @time ago', array('@time' => format_interval(REQUEST_TIME - $last))) : t('Last checked: never');
$output .= ' <span class="check-manually">(' . l(t('Check manually'), 'admin/reports/updates/backdrop-upgrade/check', array('query' => drupal_get_destination())) . ')</span>';
$output .= "</div>\n";
return $output;
}
/**
* Return status and notice about modules moved into Core.
*
* Assign custom upgrade information for certain modules.
*
* @param $projects
* Array of projects from backdrop_upgrade_status_calculate_project_data(). This
* parameter is passed by reference, and metadata for the project can added
* to the $projects[$project] array for use later. Several additional keys are
* supported:
* - in_core_since: The major version where the project was added into core.
* - in_core_note: Note to display to the user. This should be succinct and
* describe:
* - If the project was "Moved", "Integrated", or "Replaced by" another.
* - What core system, module, or API replaces the project.
* - What minor version the project was added into.
* - in_core_complete: Boolean flag indicating whether the complete
* functionality of the project is in core. Set this to FALSE when the core
* replacement does not include the full functionality of the project.
* - in_core_warning:
* - If the 'in_core_complete' flag is false, what functionality of the
* project is not included in core.
* - Other things developers will need to know about updating this project.
*
* @param $project
* Project name to check.
*
* @return
* TRUE if project has been moved into core.
*
* @see _backdrop_upgrade_status_backdrop_core().
*/
function backdrop_upgrade_status_moved_into_core(&$projects, $project) {
// Only include in core statuses for the configured major version and below.
// Set the oldest version's data first, so that the latest version of core may
// update the previous version's information.
// @todo What about projects moved into core and then back out?
$core_version = variable_get('backdrop_upgrade_status_core_version', BACKDROP_UPGRADE_STATUS_CORE_VERSION);
switch ($core_version) {
case '7.x':
$core = _backdrop_upgrade_status_d7_core($projects, $project);
break;
case '8.x':
module_load_include('inc', 'backdrop_upgrade_status', 'backdrop_upgrade_status.d7core');
$d7_core = _backdrop_upgrade_status_d7_core($projects, $project);
module_load_include('inc', 'backdrop_upgrade_status', 'backdrop_upgrade_status.core');
$backdrop_core = _backdrop_upgrade_status_backdrop_core($projects, $project);
$core = $d7_core || $backdrop_core;
break;
}
return $core;
}