00001 <?php
00002
00003
00023 function update_get_projects() {
00024 static $projects = array();
00025 if (empty($projects)) {
00026
00027 $projects = update_project_cache('update_project_projects');
00028 if (empty($projects)) {
00029
00030 _update_process_info_list($projects, module_rebuild_cache(), 'module');
00031 _update_process_info_list($projects, system_theme_data(), 'theme');
00032
00033 cache_set('update_project_projects', $projects, 'cache_update', time() + 3600);
00034 }
00035 }
00036 return $projects;
00037 }
00038
00042 function _update_process_info_list(&$projects, $list, $project_type) {
00043 foreach ($list as $file) {
00044 if (empty($file->status)) {
00045
00046 continue;
00047 }
00048
00049
00050 if (empty($file->info)) {
00051 continue;
00052 }
00053
00054
00055 if (!isset($file->info['project'])) {
00056 $file->info['project'] = update_get_project_name($file);
00057 }
00058
00059
00060 if (empty($file->info['project'])) {
00061 continue;
00062 }
00063
00064
00065
00066
00067
00068
00069
00070
00071 if (!isset($file->info['_info_file_ctime'])) {
00072 $info_filename = dirname($file->filename) . '/' . $file->name . '.info';
00073 $file->info['_info_file_ctime'] = filectime($info_filename);
00074 }
00075
00076 $project_name = $file->info['project'];
00077 if (!isset($projects[$project_name])) {
00078
00079
00080 $projects[$project_name] = array(
00081 'name' => $project_name,
00082 'info' => $file->info,
00083 'datestamp' => isset($file->info['datestamp']) ? $file->info['datestamp'] : 0,
00084 'includes' => array($file->name => $file->info['name']),
00085 'project_type' => $project_name == 'drupal' ? 'core' : $project_type,
00086 );
00087 }
00088 else {
00089 $projects[$project_name]['includes'][$file->name] = $file->info['name'];
00090 $projects[$project_name]['info']['_info_file_ctime'] = max($projects[$project_name]['info']['_info_file_ctime'], $file->info['_info_file_ctime']);
00091 }
00092 }
00093 }
00094
00101 function update_get_project_name($file) {
00102 $project_name = '';
00103 if (isset($file->info['project'])) {
00104 $project_name = $file->info['project'];
00105 }
00106 elseif (isset($file->info['package']) && (strpos($file->info['package'], 'Core -') !== FALSE)) {
00107 $project_name = 'drupal';
00108 }
00109 elseif (in_array($file->name, array('bluemarine', 'chameleon', 'garland', 'marvin', 'minnelli', 'pushbutton'))) {
00110
00111
00112 $project_name = 'drupal';
00113 }
00114 return $project_name;
00115 }
00116
00125 function update_process_project_info(&$projects) {
00126 foreach ($projects as $key => $project) {
00127
00128 $install_type = 'official';
00129
00130 $info = $project['info'];
00131
00132 if (isset($info['version'])) {
00133
00134 if (preg_match('@(dev|HEAD)@', $info['version'])) {
00135 $install_type = 'dev';
00136 }
00137
00138
00139
00140
00141 $matches = array();
00142 if (preg_match('/^(\d+\.x-)?(\d+)\..*$/', $info['version'], $matches)) {
00143 $info['major'] = $matches[2];
00144 }
00145 elseif (!isset($info['major'])) {
00146
00147
00148
00149 $info['major'] = -1;
00150 }
00151 }
00152 else {
00153
00154 $install_type = 'unknown';
00155 $info['version'] = t('Unknown');
00156 $info['major'] = -1;
00157 }
00158
00159
00160 $projects[$key]['existing_version'] = $info['version'];
00161 $projects[$key]['existing_major'] = $info['major'];
00162 $projects[$key]['install_type'] = $install_type;
00163 unset($projects[$key]['info']);
00164 }
00165 }
00166
00234 function update_calculate_project_data($available) {
00235
00236 $projects = update_project_cache('update_project_data');
00237
00238
00239 if (!empty($projects)) {
00240 return $projects;
00241 }
00242 $projects = update_get_projects();
00243 update_process_project_info($projects);
00244 foreach ($projects as $project => $project_info) {
00245 if (isset($available[$project])) {
00246
00247
00248
00249 if (isset($available[$project]['project_status'])) {
00250 switch ($available[$project]['project_status']) {
00251 case 'insecure':
00252 $projects[$project]['status'] = UPDATE_NOT_SECURE;
00253 if (empty($projects[$project]['extra'])) {
00254 $projects[$project]['extra'] = array();
00255 }
00256 $projects[$project]['extra'][] = array(
00257 'class' => 'project-not-secure',
00258 'label' => t('Project not secure'),
00259 'data' => t('This project has been labeled insecure by the Drupal security team, and is no longer available for download. Immediately disabling everything included by this project is strongly recommended!'),
00260 );
00261 break;
00262 case 'unpublished':
00263 case 'revoked':
00264 $projects[$project]['status'] = UPDATE_REVOKED;
00265 if (empty($projects[$project]['extra'])) {
00266 $projects[$project]['extra'] = array();
00267 }
00268 $projects[$project]['extra'][] = array(
00269 'class' => 'project-revoked',
00270 'label' => t('Project revoked'),
00271 'data' => t('This project has been revoked, and is no longer available for download. Disabling everything included by this project is strongly recommended!'),
00272 );
00273 break;
00274 case 'unsupported':
00275 $projects[$project]['status'] = UPDATE_NOT_SUPPORTED;
00276 if (empty($projects[$project]['extra'])) {
00277 $projects[$project]['extra'] = array();
00278 }
00279 $projects[$project]['extra'][] = array(
00280 'class' => 'project-not-supported',
00281 'label' => t('Project not supported'),
00282 'data' => t('This project is no longer supported, and is no longer available for download. Disabling everything included by this project is strongly recommended!'),
00283 );
00284 break;
00285 default:
00286
00287
00288 break;
00289 }
00290 }
00291
00292 if (!empty($projects[$project]['status'])) {
00293
00294
00295
00296 $projects[$project] += $available[$project];
00297 continue;
00298 }
00299
00300
00301 $existing_major = $project_info['existing_major'];
00302 $supported_majors = array();
00303 if (isset($available[$project]['supported_majors'])) {
00304 $supported_majors = explode(',', $available[$project]['supported_majors']);
00305 }
00306 elseif (isset($available[$project]['default_major'])) {
00307
00308 $supported_majors[] = $available[$project]['default_major'];
00309 }
00310
00311 if (in_array($existing_major, $supported_majors)) {
00312
00313 $target_major = $existing_major;
00314 }
00315 elseif (isset($available[$project]['recommended_major'])) {
00316
00317
00318
00319
00320 $target_major = $available[$project]['recommended_major'];
00321 $projects[$project]['status'] = UPDATE_NOT_SUPPORTED;
00322 }
00323 elseif (isset($available[$project]['default_major'])) {
00324
00325
00326 $target_major = $available[$project]['default_major'];
00327 }
00328 else {
00329
00330 $target_major = $existing_major;
00331 }
00332
00333
00334
00335
00336
00337
00338
00339
00340 $target_major = max($existing_major, $target_major);
00341
00342 $version_patch_changed = '';
00343 $patch = '';
00344
00345
00346 if (empty($available[$project]['releases'])) {
00347 $projects[$project]['status'] = UPDATE_UNKNOWN;
00348 $projects[$project]['reason'] = t('No available releases found');
00349 continue;
00350 }
00351 foreach ($available[$project]['releases'] as $version => $release) {
00352
00353 if ($projects[$project]['existing_version'] == $version) {
00354 if (isset($release['terms']['Release type']) &&
00355 in_array('Insecure', $release['terms']['Release type'])) {
00356 $projects[$project]['status'] = UPDATE_NOT_SECURE;
00357 }
00358 elseif ($release['status'] == 'unpublished') {
00359 $projects[$project]['status'] = UPDATE_REVOKED;
00360 if (empty($projects[$project]['extra'])) {
00361 $projects[$project]['extra'] = array();
00362 }
00363 $projects[$project]['extra'][] = array(
00364 'class' => 'release-revoked',
00365 'label' => t('Release revoked'),
00366 'data' => t('Your currently installed release has been revoked, and is no longer available for download. Disabling everything included in this release or upgrading is strongly recommended!'),
00367 );
00368 }
00369 elseif (isset($release['terms']['Release type']) &&
00370 in_array('Unsupported', $release['terms']['Release type'])) {
00371 $projects[$project]['status'] = UPDATE_NOT_SUPPORTED;
00372 if (empty($projects[$project]['extra'])) {
00373 $projects[$project]['extra'] = array();
00374 }
00375 $projects[$project]['extra'][] = array(
00376 'class' => 'release-not-supported',
00377 'label' => t('Release not supported'),
00378 'data' => t('Your currently installed release is now unsupported, and is no longer available for download. Disabling everything included in this release or upgrading is strongly recommended!'),
00379 );
00380 }
00381 }
00382
00383
00384 if ($release['status'] == 'unpublished' ||
00385 (isset($release['terms']['Release type']) &&
00386 (in_array('Insecure', $release['terms']['Release type']) ||
00387 in_array('Unsupported', $release['terms']['Release type'])))) {
00388 continue;
00389 }
00390
00391
00392
00393 if ($release['version_major'] > $target_major) {
00394 if (in_array($release['version_major'], $supported_majors)) {
00395 if (!isset($available[$project]['also'])) {
00396 $available[$project]['also'] = array();
00397 }
00398 if (!isset($available[$project]['also'][$release['version_major']])) {
00399 $available[$project]['also'][$release['version_major']] = $version;
00400 }
00401 }
00402
00403
00404
00405
00406
00407
00408
00409 continue;
00410 }
00411
00412
00413
00414 if (!isset($available[$project]['latest_version'])
00415 && $release['version_major'] == $target_major) {
00416 $available[$project]['latest_version'] = $version;
00417 }
00418
00419
00420 if (!isset($available[$project]['dev_version'])
00421 && $release['version_major'] == $target_major
00422 && isset($release['version_extra'])
00423 && $release['version_extra'] == 'dev') {
00424 $available[$project]['dev_version'] = $version;
00425 }
00426
00427
00428
00429 if (!isset($available[$project]['recommended'])
00430 && $release['version_major'] == $target_major
00431 && isset($release['version_patch'])) {
00432 if ($patch != $release['version_patch']) {
00433 $patch = $release['version_patch'];
00434 $version_patch_changed = $release['version'];
00435 }
00436 if (empty($release['version_extra']) && $patch == $release['version_patch']) {
00437 $available[$project]['recommended'] = $version_patch_changed;
00438 }
00439 }
00440
00441
00442 if ($projects[$project]['existing_version'] == $version) {
00443 break;
00444 }
00445
00446
00447
00448
00449
00450
00451
00452 if ($projects[$project]['install_type'] == 'dev') {
00453 if (empty($projects[$project]['datestamp'])) {
00454
00455 continue;
00456 }
00457 elseif (isset($release['date']) && ($projects[$project]['datestamp'] + 100 > $release['date'])) {
00458
00459 continue;
00460 }
00461 }
00462
00463
00464 if (isset($release['terms']['Release type'])
00465 && in_array('Security update', $release['terms']['Release type'])) {
00466 $projects[$project]['security updates'][] = $release;
00467 }
00468 }
00469
00470
00471
00472 if (!isset($available[$project]['recommended']) && isset($available[$project]['latest_version'])) {
00473 $available[$project]['recommended'] = $available[$project]['latest_version'];
00474 }
00475
00476
00477 $projects[$project] += $available[$project];
00478
00479
00480
00481
00482
00483 if (!empty($projects[$project]['security updates'])) {
00484
00485 $projects[$project]['status'] = UPDATE_NOT_SECURE;
00486 }
00487
00488 if (isset($projects[$project]['status'])) {
00489
00490 continue;
00491 }
00492
00493
00494
00495 if (!isset($projects[$project]['recommended'])) {
00496 $projects[$project]['status'] = UPDATE_UNKNOWN;
00497 $projects[$project]['reason'] = t('No available releases found');
00498 continue;
00499 }
00500
00501
00502
00503
00504
00505 if ($projects[$project]['install_type'] == 'dev') {
00506 if (isset($available[$project]['dev_version']) && $available[$project]['releases'][$available[$project]['dev_version']]['date'] > $available[$project]['releases'][$available[$project]['latest_version']]['date']) {
00507 $projects[$project]['latest_dev'] = $available[$project]['dev_version'];
00508 }
00509 else {
00510 $projects[$project]['latest_dev'] = $available[$project]['latest_version'];
00511 }
00512 }
00513
00514
00515 switch ($projects[$project]['install_type']) {
00516 case 'official':
00517 if ($projects[$project]['existing_version'] == $projects[$project]['recommended'] || $projects[$project]['existing_version'] == $projects[$project]['latest_version']) {
00518 $projects[$project]['status'] = UPDATE_CURRENT;
00519 }
00520 else {
00521 $projects[$project]['status'] = UPDATE_NOT_CURRENT;
00522 }
00523 break;
00524
00525 case 'dev':
00526 $latest = $available[$project]['releases'][$projects[$project]['latest_dev']];
00527 if (empty($projects[$project]['datestamp'])) {
00528 $projects[$project]['status'] = UPDATE_NOT_CHECKED;
00529 $projects[$project]['reason'] = t('Unknown release date');
00530 }
00531 elseif (($projects[$project]['datestamp'] + 100 > $latest['date'])) {
00532 $projects[$project]['status'] = UPDATE_CURRENT;
00533 }
00534 else {
00535 $projects[$project]['status'] = UPDATE_NOT_CURRENT;
00536 }
00537 break;
00538
00539 default:
00540 $projects[$project]['status'] = UPDATE_UNKNOWN;
00541 $projects[$project]['reason'] = t('Invalid info');
00542 }
00543 }
00544 else {
00545 $projects[$project]['status'] = UPDATE_UNKNOWN;
00546 $projects[$project]['reason'] = t('No available releases found');
00547 }
00548 }
00549
00550
00551
00552 drupal_alter('update_status', $projects);
00553
00554
00555 cache_set('update_project_data', $projects, 'cache_update', time() + 3600);
00556 return $projects;
00557 }
00558
00580 function update_project_cache($cid) {
00581 $projects = array();
00582
00583
00584
00585 $q = $_GET['q'];
00586 $paths = array('admin/build/modules', 'admin/build/themes', 'admin/reports', 'admin/reports/updates', 'admin/reports/status', 'admin/reports/updates/check');
00587 if (in_array($q, $paths)) {
00588 cache_clear_all($cid, 'cache_update');
00589 }
00590 else {
00591 $cache = cache_get($cid, 'cache_update');
00592 if (!empty($cache->data) && $cache->expire > time()) {
00593 $projects = $cache->data;
00594 }
00595 }
00596 return $projects;
00597 }