/[drupal]/contributions/modules/upgrade_status/upgrade_status.admin.inc
ViewVC logotype

Contents of /contributions/modules/upgrade_status/upgrade_status.admin.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.9 - (show annotations) (download) (as text)
Sun Aug 2 01:36:45 2009 UTC (3 months, 3 weeks ago) by sun
Branch: MAIN
CVS Tags: HEAD
Changes since 1.8: +27 -24 lines
File MIME type: text/x-php
#297335 by naught101, Rob Loach, sun: Ported to 6.x.
1 <?php
2 // $Id: upgrade_status.admin.inc,v 1.8 2008/12/09 21:05:17 sun Exp $
3
4 /**
5 * @file
6 * Checks to see if your installed modules are available for the next major
7 * release of Drupal.
8 */
9
10 /**
11 * Default version of core we want to query for.
12 */
13 define('UPGRADE_STATUS_CORE_VERSION', '7.x');
14
15 /**
16 * URL to check updates at, if a given project doesn't define its own.
17 */
18 define('UPGRADE_STATUS_DEFAULT_URL', 'http://updates.drupal.org/release-history');
19
20 /**
21 * Project has not been ported yet.
22 */
23 define('UPGRADE_STATUS_NOT_PORTED', 3);
24
25 /**
26 * Project has a new release available, but it is not a security release.
27 */
28 define('UPGRADE_STATUS_DEVELOPMENT', 4);
29
30 /**
31 * Project is available.
32 */
33 define('UPGRADE_STATUS_STABLE', 5);
34
35 /**
36 * Project has been moved into core.
37 */
38 define('UPGRADE_STATUS_CORE', 6);
39
40
41 /**
42 * Menu callback. Generate a page about the upgrade status of projects.
43 */
44 function upgrade_status_status() {
45 if ($available = upgrade_status_get_available()) {
46 $data = upgrade_status_calculate_project_data($available);
47 return theme('upgrade_status_report', $data);
48 }
49 else {
50 return theme('upgrade_status_report', t('No information is available about potential new releases for currently installed modules. To check for updates, you can <a href="@check_manually">check manually</a>. Please note that checking for available updates can take a long time, so please be patient.', array(
51 '@check_manually' => url('admin/reports/updates/check', array('query' => array('query' => $destination))),
52 )));
53 }
54 }
55
56 /**
57 * Menu callback to manually check the upgrade status.
58 */
59 function upgrade_status_manual_status() {
60 if (upgrade_status_refresh()) {
61 drupal_set_message(t('Fetched information about all available upgrades.'));
62 }
63 else {
64 drupal_set_message(t('Unable to fetch any information on available upgrades.'), 'error');
65 }
66 drupal_goto('admin/reports/updates/upgrade');
67 }
68
69 /**
70 * Given the installed projects and the available release data retrieved from
71 * remote servers, calculate the current status.
72 *
73 * This function is the heart of the update status feature. It iterates over
74 * every currently installed project. For each one, it first checks if the
75 * project has been flagged with a special status like "unsupported" or
76 * "insecure", or if the project node itself has been unpublished. In any of
77 * those cases, the project is marked with an error and the next project is
78 * considered.
79 *
80 * @param $available
81 * Array of data about available project releases.
82 *
83 * @see upgrade_status_get_available()
84 * @see update_status_get_projects()
85 * @see update_status_process_project_info()
86 */
87 function upgrade_status_calculate_project_data($available) {
88
89 // Retrieve the projects from cache, if present.
90 $projects = upgrade_status_project_cache('upgrade_status_data');
91 // If $projects is empty, then the cache must be rebuilt.
92 // Otherwise, return the cached data and skip the rest of the function.
93 if (!empty($projects)) {
94 return $projects;
95 }
96
97 module_load_include('inc', 'update', 'update.compare');
98 $projects = update_get_projects();
99 update_process_project_info($projects);
100 $settings = variable_get('upgrade_status_settings', array());
101 foreach ($projects as $project => $project_info) {
102 if (isset($available[$project])) {
103 // If the project status is marked as something bad, there's nothing
104 // else to consider.
105 if (isset($available[$project]['project_status'])) {
106 switch ($available[$project]['project_status']) {
107 case 'unpublished':
108 case 'revoked':
109 case 'unsupported':
110 $projects[$project]['status'] = UPDATE_STATUS_NOT_SUPPORTED;
111 if (empty($projects[$project]['extra'])) {
112 $projects[$project]['extra'] = array();
113 }
114 $projects[$project]['extra'][] = array(
115 'class' => 'project-not-supported',
116 'label' => t('Project not supported'),
117 'data' => t('This project is no longer supported, and is no longer available for download. Disabling everything included by this project is strongly recommended!'),
118 );
119 break;
120 }
121 }
122
123 if (!empty($projects[$project]['status'])) {
124 // We already know the status for this project, so there's nothing
125 // else to compute. Just record everything else we fetched from the
126 // XML file into our projects array and move to the next project.
127 $projects[$project] += $available[$project];
128 continue;
129 }
130
131 // Figure out the target major version.
132 $existing_major = $project_info['existing_major'];
133 $supported_majors = array();
134 if (isset($available[$project]['supported_majors'])) {
135 $supported_majors = explode(',', $available[$project]['supported_majors']);
136 }
137
138 if (isset($available[$project]['recommended_major'])) {
139 $target_major = $available[$project]['recommended_major'];
140 }
141 elseif (isset($available[$project]['default_major'])) {
142 // Older release history XML file without recommended, so recommend
143 // the currently defined "default_major" version.
144 $target_major = $available[$project]['default_major'];
145 }
146 else {
147 // Malformed XML file? Stick with the current version.
148 $target_major = $existing_major;
149 }
150
151 $version_patch_changed = '';
152 $patch = '';
153
154 // Defend ourselves from XML history files that contain no releases.
155 if (empty($available[$project]['releases'])) {
156 $projects[$project]['status'] = UPDATE_STATUS_UNKNOWN;
157 $projects[$project]['reason'] = t('No available releases found');
158 continue;
159 }
160 foreach ($available[$project]['releases'] as $version => $release) {
161 // Otherwise, ignore unpublished, insecure, or unsupported releases.
162 if ($release['status'] == 'unpublished' ||
163 (isset($release['terms']['Release type']) &&
164 (in_array('Insecure', $release['terms']['Release type']) ||
165 in_array('Unsupported', $release['terms']['Release type'])))) {
166 continue;
167 }
168
169 // See if this is a higher major version than our target and yet still
170 // supported. If so, record it as an "Also available" release.
171 if ($release['version_major'] > $target_major) {
172 if (in_array($release['version_major'], $supported_majors)) {
173 if (!isset($available[$project]['also'])) {
174 $available[$project]['also'] = array();
175 }
176 if (!isset($available[$project]['also'][$release['version_major']])) {
177 $available[$project]['also'][$release['version_major']] = $version;
178 }
179 }
180 // Otherwise, this release can't matter to us, since it's neither
181 // from the release series we're currently using nor the recommended
182 // release. We don't even care about security updates for this
183 // branch, since if a project maintainer puts out a security release
184 // at a higher major version and not at the lower major version,
185 // they must change the default major release at the same time, in
186 // which case we won't hit this code.
187 continue;
188 }
189
190 // Look for the 'latest version' if we haven't found it yet. Latest is
191 // defined as the most recent version for the target major version.
192 if (!isset($available[$project]['latest_version'])
193 && $release['version_major'] == $target_major) {
194 $available[$project]['latest_version'] = $version;
195 }
196
197 // Look for the development snapshot release for this branch.
198 if (!isset($available[$project]['dev_version'])
199 && isset($release['version_extra'])
200 && $release['version_extra'] == 'dev') {
201 $available[$project]['dev_version'] = $version;
202 }
203
204 // Look for the 'recommended' version if we haven't found it yet (see
205 // phpdoc at the top of this function for the definition).
206 if (!isset($available[$project]['recommended'])
207 && $release['version_major'] == $target_major
208 && isset($release['version_patch'])) {
209 if ($patch != $release['version_patch']) {
210 $patch = $release['version_patch'];
211 $version_patch_changed = $release['version'];
212 }
213 if (empty($release['version_extra']) && $patch == $release['version_patch']) {
214 $available[$project]['recommended'] = $version_patch_changed;
215 }
216 }
217 }
218
219 // If we were unable to find a recommended version, then make the latest
220 // version the recommended version if possible.
221 if (!isset($available[$project]['recommended']) && isset($available[$project]['latest_version'])) {
222 $available[$project]['recommended'] = $available[$project]['latest_version'];
223 $projects[$project]['status'] = UPGRADE_STATUS_DEVELOPMENT;
224 $projects[$project]['reason'] = t('In development');
225 }
226
227 // Stash the info about available releases into our $projects array.
228 $projects[$project] += $available[$project];
229
230 if (isset($projects[$project]['status'])) {
231 // If we already know the status, we're done.
232 continue;
233 }
234
235 // If we don't know what to recommend, there's nothing we can report.
236 // Bail out early.
237 if (!isset($projects[$project]['recommended'])) {
238 $projects[$project]['status'] = UPDATE_STATUS_UNKNOWN;
239 $projects[$project]['reason'] = t('No available releases found');
240 continue;
241 }
242
243 // Figure out the status, based on what we've seen and the install type.
244 // Note: If we were not yet able to assign a status, this project already
245 // provides a stable release.
246 switch ($projects[$project]['type']) {
247 case 'official':
248 case 'dev':
249 $projects[$project]['status'] = UPGRADE_STATUS_STABLE;
250 $projects[$project]['reason'] = t('Available');
251 break;
252
253 default:
254 $projects[$project]['status'] = UPDATE_STATUS_UNKNOWN;
255 $projects[$project]['reason'] = t('Invalid info');
256 }
257 }
258 elseif (!upgrade_status_moved_into_core($projects, $project)) {
259 $projects[$project]['status'] = UPGRADE_STATUS_NOT_PORTED;
260 $projects[$project]['reason'] = t('Not ported yet');
261 }
262 }
263 cache_set('upgrade_status_data', $projects, 'cache', time() + (60 * 60));
264 return $projects;
265 }
266
267 /**
268 * Return status and notice about modules moved into Core.
269 *
270 * Assign custom upgrade information for certain modules.
271 *
272 * @param $projects
273 * Array of projects from upgrade_status_calculate_project_data().
274 * @param $project
275 * Project name to check.
276 * @return
277 * TRUE if module has been moved into core.
278 */
279 function upgrade_status_moved_into_core(&$projects, $project) {
280 $core = TRUE;
281 switch ($project) {
282 case 'actions':
283 $projects[$project]['in_core_since'] = '6.x';
284 $projects[$project]['in_core_note'] = t('Please note that the syntax for actions used by the 5.x-1.x and 4.7 versions of Actions module are different to triggers in Drupal 6.x. For further information please refer to the <a href="!project-url">Actions</a> module project page.', array('!project-url' => 'http://drupal.org/project/actions'));
285 break;
286
287 case 'ahah_forms':
288 $projects[$project]['in_core_since'] = '6.x';
289 break;
290
291 case 'autolocale':
292 $projects[$project]['in_core_since'] = '6.x';
293 break;
294
295 case 'book_bridge':
296 $projects[$project]['in_core_since'] = '6.x';
297 break;
298
299 case 'find_path':
300 $projects[$project]['in_core_since'] = '6.x';
301 break;
302
303 case 'html_to_text':
304 $projects[$project]['in_core_since'] = '6.x';
305 break;
306
307 case 'htmlcorrector':
308 $projects[$project]['in_core_since'] = '6.x';
309 break;
310
311 case 'javascript_aggregator':
312 $projects[$project]['in_core_since'] = '6.x';
313 $projects[$project]['in_core_note'] = t('Please note that there is a version of <a href="!project-url">JavaScript Aggregator</a> module for Drupal 6.x, which additionally minifies JavaScript.', array('!project-url' => 'http://drupal.org/project/javascript_aggregator'));
314 break;
315
316 case 'openid':
317 $projects[$project]['in_core_since'] = '6.x';
318 break;
319
320 case 'themesettingsapi':
321 $projects[$project]['in_core_since'] = '6.x';
322 break;
323
324 case 'update_status':
325 $projects[$project]['in_core_since'] = '6.x';
326 $projects[$project]['in_core_note'] = t('Please note that some of the advanced settings in the 5.x version of Update status are not present in the update.module in 6.x core, and have been moved into the <a href="!project-url">Update status advanced settings</a> module for Drupal 6.x and beyond.', array('!project-url' => 'http://drupal.org/project/update_advanced'));
327 break;
328
329 case 'user_status':
330 $projects[$project]['in_core_since'] = '6.x';
331 $projects[$project]['in_core_note'] = t('There is no database upgrade path for sites that used the 5.x version of the user_status module to migrate the message templates to the new settings in core. Furthermore, the place-holders available in these templates are different in 6.x core. Therefore, users will have to re-enter their message templates into the core settings at admin/user/settings.');
332 break;
333
334 default:
335 $core = FALSE;
336 }
337 if ($core) {
338 $projects[$project]['status'] = UPGRADE_STATUS_CORE;
339 }
340 return $core;
341 }
342
343 /**
344 * Theme project status report.
345 */
346 function theme_upgrade_status_report($data) {
347 $last = variable_get('upgrade_status_last', 0);
348 $current_data = update_get_available(TRUE);
349
350 $output = '<p>'. t("Clicking on any of the modules' boxes will expand the area and show you a link to download the new version of the project, as well as read its release notes.") .'</p>';
351 $output .= '<div class="upgrade-status checked"><p>'. t('Last checked: ') . ($last ? format_interval(time() - $last) .' '. t('ago') : t('Never'));
352 $output .= ' <span class="check-manually">('. l(t('Check manually'), 'admin/reports/updates/upgrade/check') .')</span>';
353 $output .= "</p></div>\n";
354
355 $output .= drupal_get_form('upgrade_status_core_version_form');
356
357 if (!is_array($data)) {
358 $output .= '<p>'. $data .'</p>';
359 return $output;
360 }
361
362 // Move 'drupal' to the top.
363 $data = array('drupal' => $data['drupal']) + $data;
364
365 $header = array();
366 $rows = array();
367
368 foreach ($data as $project) {
369 // Skip upgrade_status. Doesn't make sense to display it.
370 if ($project['name'] == 'upgrade_status') {
371 continue;
372 }
373 switch ($project['status']) {
374 case UPGRADE_STATUS_STABLE:
375 $class = 'ok';
376 $icon = theme('image', 'misc/watchdog-ok.png', t('ok'), t('ok'));
377 break;
378
379 case UPDATE_STATUS_REVOKED:
380 case UPGRADE_STATUS_NOT_PORTED:
381 $class = 'error';
382 $icon = theme('image', 'misc/watchdog-error.png', t('error'), t('error'));
383 break;
384
385 case UPGRADE_STATUS_DEVELOPMENT:
386 default:
387 $class = 'warning';
388 $icon = theme('image', 'misc/watchdog-warning.png', t('warning'), t('warning'));
389 break;
390 }
391 // Special handling for project moved into core.
392 if ($project['status'] == UPGRADE_STATUS_CORE) {
393 $class = 'ok';
394 if (!empty($project['in_core_note'])) {
395 $icon = theme('image', 'misc/watchdog-warning.png', t('warning'), t('warning'));
396 }
397 else {
398 $icon = theme('image', 'misc/watchdog-ok.png', t('ok'), t('ok'));
399 }
400 }
401
402 // Compact layout. 31/05/2008 sun
403 $row = '<div class="project">';
404 $row .= '<div class="version-status">';
405 switch ($project['status']) {
406 case UPDATE_STATUS_REVOKED:
407 $row .= '<span class="revoked">'. t('Revoked!') .'</span>';
408 break;
409 case UPGRADE_STATUS_NOT_PORTED:
410 $row .= '<span class="not-supported">'. t('Not ported yet') .'</span>';
411 break;
412 case UPGRADE_STATUS_DEVELOPMENT:
413 $row .= '<span class="not-current">'. t('In development') .'</span>';
414 break;
415 case UPGRADE_STATUS_STABLE:
416 case UPGRADE_STATUS_CORE:
417 $row .= '<span class="current">'. t('Available') .'</span>';
418 break;
419 default:
420 $row .= check_plain($project['reason']);
421 break;
422 }
423
424 $row .= '<span class="icon">'. $icon .'</span>';
425 $row .= "</div>\n";
426
427 // Collapse-trigger icon.
428 $row .= theme('image', 'misc/menu-collapsed.png', '', '', array('class' => 'collapse-icon'));
429
430 $row .= '<span class="project-title">';
431 if (isset($project['title'])) {
432 if (isset($project['link'])) {
433 $row .= l($project['title'], $project['link']);
434 }
435 else {
436 $row .= check_plain($project['title']);
437 }
438 }
439 // Couldn't find this project's data for the next version of Drupal core.
440 // Let's try the current one instead.
441 elseif (isset($current_data[$project['name']]) && isset($current_data[$project['name']]['title'])) {
442 if (isset($current_data[$project['name']]['link'])) {
443 $row .= l($current_data[$project['name']]['title'], $current_data[$project['name']]['link']);
444 }
445 else {
446 $row .= check_plain($current_data[$project_name]['title']);
447 }
448 }
449 // Otherwise, just print the name.
450 else {
451 $row .= check_plain($project['name']);
452 }
453 $row .= '</span>';
454 $row .= '<span class="existing-version">';
455 $row .= ' '. check_plain($project['existing_version']);
456 if ($project['type'] == 'dev' && !empty($project['datestamp'])) {
457 $row .= ' <span class="version-date">('. format_date($project['datestamp'], 'custom', 'Y-M-d') .')</span>';
458 }
459 $row .= '</span>';
460
461 // Compact layout. 31/05/2008 sun
462 $row .= "<div class=\"details-wrapper\">\n";
463 if ($project['status'] == UPGRADE_STATUS_CORE) {
464 $row .= "<div class=\"core-notice\">\n";
465 $row .= '<p>'. t('In Drupal core since @version', array('@version' => $project['in_core_since'])) .'</p>';
466 $row .= '<p>'. $project['in_core_note'] .'</p>';
467 $row .= '</div>';
468 }
469 $row .= "<div class=\"versions\">\n";
470
471 if (isset($project['recommended'])) {
472 if ($project['status'] != UPDATE_STATUS_CURRENT || $project['existing_version'] != $project['recommended']) {
473
474 // First, figure out what to recommend.
475 // If there's only 1 security update and it has the same version we're
476 // recommending, give it the same CSS class as if it was recommended,
477 // but don't print out a separate "Recommended" line for this project.
478 if (!empty($project['security updates']) && count($project['security updates']) == 1 && $project['security updates'][0]['version'] == $project['recommended']) {
479 $security_class = ' version-recommended version-recommended-strong';
480 }
481 else {
482 $security_class = '';
483 $version_class = 'version-recommended';
484 // Apply an extra class if we're displaying both a recommended
485 // version and anything else for an extra visual hint.
486 if ($project['recommended'] != $project['latest_version']
487 || !empty($project['also'])
488 || ($project['type'] == 'dev'
489 && isset($project['dev_version'])
490 && $project['latest_version'] != $project['dev_version']
491 && $project['recommended'] != $project['dev_version'])
492 || (isset($project['security updates'][0])
493 && $project['recommended'] != $project['security updates'][0])
494 ) {
495 $version_class .= ' version-recommended-strong';
496 }
497 $row .= theme('upgrade_status_version', $project['releases'][$project['recommended']], t('Recommended version:'), $version_class);
498 }
499
500 // Now, print any security updates.
501 if (!empty($project['security updates'])) {
502 foreach ($project['security updates'] as $security_update) {
503 $row .= theme('upgrade_status_version', $security_update, t('Security update:'), 'version-security'. $security_class);
504 }
505 }
506 }
507
508 if ($project['recommended'] != $project['latest_version']) {
509 $row .= theme('upgrade_status_version', $project['releases'][$project['latest_version']], t('Latest version:'), 'version-latest');
510 }
511 if ($project['type'] == 'dev'
512 && $project['status'] != UPDATE_STATUS_CURRENT
513 && isset($project['dev_version'])
514 && $project['recommended'] != $project['dev_version']) {
515 $row .= theme('upgrade_status_version', $project['releases'][$project['dev_version']], t('Development version:'), 'version-latest');
516 }
517 }
518
519 if (isset($project['also'])) {
520 foreach ($project['also'] as $also) {
521 $row .= theme('upgrade_status_version', $project['releases'][$also], t('Also available:'), 'version-also-available');
522 }
523 }
524
525 $row .= "</div>\n"; // versions div.
526
527 $row .= "<div class=\"info\">\n";
528 if (!empty($project['notes'])) {
529 $row .= '<div class="notes">';
530 $row .= t('Administrator note: %notes', array('%notes' => $project['notes']));
531 $row .= "</div>\n";
532 }
533
534 $row .= '<div class="modules">';
535 $row .= t('Includes: %modules', array('%modules' => implode(', ', $project['includes'])));
536 $row .= "</div>\n";
537
538 $row .= "</div>\n"; // info div.
539 $row .= "</div>\n"; // wrapper div.
540 $row .= "</div>\n"; // project div.
541
542 $rows[] = array(
543 'class' => $class,
544 'data' => array($row),
545 );
546 }
547
548 $output .= theme('table', $header, $rows, array('class' => 'upgrade-status'));
549 drupal_add_css(drupal_get_path('module', 'upgrade_status') .'/upgrade_status.css');
550 drupal_add_js(drupal_get_path('module', 'upgrade_status') .'/upgrade_status.js');
551 return $output;
552 }
553
554 function theme_upgrade_status_version($version, $tag, $class) {
555 $output = '';
556 $output .= '<table class="version '. $class .'">';
557 $output .= '<tr>';
558 $output .= '<td class="version-title">'. $tag ."</td>\n";
559 $output .= '<td class="version-details">';
560 $output .= l($version['version'], $version['release_link']);
561 $output .= ' <span class="version-date">('. format_date($version['date'], 'custom', 'Y-M-d') .')</span>';
562 $output .= "</td>\n";
563 $output .= '<td class="version-links">';
564 $output .= l(t('Download'), $version['download_link']) .' ยท '. l(t('Release notes'), $version['release_link']);
565 $output .= '</td>';
566 $output .= '</tr>';
567 $output .= "</table>\n";
568 return $output;
569 }
570
571 /**
572 * Fetch project info via XML from a central server.
573 */
574 function upgrade_status_refresh() {
575 global $base_url;
576
577 @set_time_limit(240);
578
579 // Since we're fetching new available update data, we want to clear
580 // everything in our cache, to ensure we recompute the status. Note that
581 // this does not cause update_status_get_projects() to be recomputed twice
582 // in the same page load (e.g. when manually checking) since that function
583 // stashes its answer in a static array.
584 upgrade_status_invalidate_cache();
585
586 $available = array();
587 $data = array();
588 $version = variable_get('upgrade_status_core_version', UPGRADE_STATUS_CORE_VERSION);
589
590 module_load_include('inc', 'update', 'update.compare');
591 $projects = update_get_projects();
592 foreach ($projects as $key => $project) {
593 // No site key to avoid hi-jacking module usage statistics.
594 $url = _upgrade_status_build_fetch_url($project, $version);
595 $xml = drupal_http_request($url);
596 if (isset($xml->data)) {
597 $data[] = $xml->data;
598 }
599 }
600
601 if ($data) {
602 module_load_include('inc', 'update', 'update.fetch');
603 $parser = new update_xml_parser;
604 $available = $parser->parse($data);
605 cache_set('upgrade_status_info', $available);
606 variable_set('upgrade_status_last', time());
607 watchdog('upgrade_status', 'Fetched information about all available new releases and updates.', array(), WATCHDOG_NOTICE, l('view', 'admin/reports/updates'));
608 }
609 else {
610 watchdog('upgrade_status', 'Unable to fetch any information on available new releases and updates.', array(), WATCHDOG_ERROR, l('view', 'admin/reports/updates'));
611 }
612 return $available;
613 }
614
615 /**
616 * Generates the URL to fetch information about project updates.
617 *
618 * This figures out the right URL to use, based on the project's .info file
619 * and the global defaults. Appends optional query arguments when the site is
620 * configured to report usage stats.
621 *
622 * @param $project
623 * The array of project information from update_status_get_projects().
624 * @param $version
625 * The target version of Drupal core you wish to query.
626 *
627 * @see upgrade_status_refresh()
628 * @see update_status_get_projects()
629 */
630 function _upgrade_status_build_fetch_url($project, $version) {
631 $default_url = variable_get('upgrade_status_fetch_url', UPGRADE_STATUS_DEFAULT_URL);
632 if (!isset($project['info']['project status url'])) {
633 $project['info']['project status url'] = $default_url;
634 }
635 $name = $project['name'];
636 $url = $project['info']['project status url'];
637 $url .= '/'. $name .'/'. $version;
638 return $url;
639 }
640
641 /**
642 * Internal helper to try to get the update information from the cache
643 * if possible, and to refresh the cache when necessary.
644 *
645 * @param $refresh
646 * Boolean to indicate if this method should refresh the cache automatically
647 * if there's no data.
648 */
649 function upgrade_status_get_available($refresh = FALSE) {
650 $available = array();
651 if (!$refresh && $cache = cache_get('upgrade_status_info', 'cache')) {
652 $available = $cache->data;
653 }
654 else {
655 $available = upgrade_status_refresh();
656 }
657 return $available;
658 }
659
660 /**
661 * Invalidates any cached data relating to update status.
662 */
663 function upgrade_status_invalidate_cache() {
664 cache_clear_all('upgrade_status_', 'cache', TRUE);
665 }
666
667 /**
668 * Retrieve data from {cache} or empty the cache when necessary.
669 *
670 * Two very expensive arrays computed by this module are the list of all
671 * installed modules (and .info data, project associations, etc), and the
672 * current status of the site relative to the currently available
673 * releases. These two arrays are cached in the {cache} table and used
674 * whenever possible. The cache is cleared whenever the administrator visits
675 * the status report, available updates report, or the module administration
676 * pages, since we should always recompute the most current values on any of
677 * those pages.
678 *
679 * @param $cid
680 * The cache id of data to return from the cache. Valid options are
681 * 'upgrade_status_data' and 'update_status_projects'.
682 *
683 * @return
684 * The cached value of the $projects array generated by
685 * upgrade_status_calculate_project_data() or update_status_get_projects(),
686 * or an empty array when the cache is cleared.
687 */
688 function upgrade_status_project_cache($cid) {
689 $projects = array();
690 if ($cache = cache_get($cid, 'cache')) {
691 if (!empty($cache->data) && $cache->expire > time()) {
692 $projects = $cache->data;
693 }
694 }
695 return $projects;
696 }
697
698 /**
699 * Form to display Drupal core version selection.
700 */
701 function upgrade_status_core_version_form(&$form_state) {
702 $form['upgrade_status_core_version'] = array(
703 '#type' => 'select',
704 '#title' => t('Target version of Drupal core'),
705 '#options' => drupal_map_assoc(array('7.x', '8.x')),
706 '#default_value' => variable_get('upgrade_status_core_version', UPGRADE_STATUS_CORE_VERSION),
707 '#description' => t('Select the version of Drupal core you wish to check for project status.'),
708 );
709 $form['submit'] = array(
710 '#type' => 'submit',
711 '#value' => t('Change'),
712 );
713 return $form;
714 }
715
716 /**
717 * Set the new Drupal core version in a variable; refresh project data.
718 */
719 function upgrade_status_core_version_form_submit($form, &$form_state) {
720 // Refresh status if a different version than the default has been selected.
721 if ($form_state['values']['upgrade_status_core_version'] != UPGRADE_STATUS_CORE_VERSION) {
722 variable_set('upgrade_status_core_version', $form_state['values']['upgrade_status_core_version']);
723 upgrade_status_refresh();
724 }
725 // Refresh status if the default version has been selected, but only if it
726 // was not selected before (noob protection).
727 else if (variable_get('upgrade_status_core_version', UPGRADE_STATUS_CORE_VERSION) != UPGRADE_STATUS_CORE_VERSION) {
728 variable_del('upgrade_status_core_version');
729 upgrade_status_refresh();
730 }
731 // ...or just ensure that we've got no stale variable set.
732 else {
733 variable_del('upgrade_status_core_version');
734 }
735 }
736

  ViewVC Help
Powered by ViewVC 1.1.2