Mercurial > defr > drupal > core
comparison modules/update/update.compare.inc @ 1:c1f4ac30525a 6.0
Drupal 6.0
author | Franck Deroche <webmaster@defr.org> |
---|---|
date | Tue, 23 Dec 2008 14:28:28 +0100 |
parents | |
children | acef7ccb09b5 |
comparison
equal
deleted
inserted
replaced
0:5a113a1c4740 | 1:c1f4ac30525a |
---|---|
1 <?php | |
2 // $Id: update.compare.inc,v 1.8 2008/02/03 19:34:02 goba Exp $ | |
3 | |
4 /** | |
5 * @file | |
6 * Code required only when comparing available updates to existing data. | |
7 */ | |
8 | |
9 /** | |
10 * Fetch an array of installed and enabled projects. | |
11 * | |
12 * This is only responsible for generating an array of projects (taking into | |
13 * account projects that include more than one module or theme). Other | |
14 * information like the specific version and install type (official release, | |
15 * dev snapshot, etc) is handled later in update_process_project_info() since | |
16 * that logic is only required when preparing the status report, not for | |
17 * fetching the available release data. | |
18 * | |
19 * @see update_process_project_info() | |
20 * @see update_calculate_project_data() | |
21 * | |
22 */ | |
23 function update_get_projects() { | |
24 static $projects = array(); | |
25 if (empty($projects)) { | |
26 // Retrieve the projects from cache, if present. | |
27 $projects = update_project_cache('update_project_projects'); | |
28 if (empty($projects)) { | |
29 // Still empty, so we have to rebuild the cache. | |
30 _update_process_info_list($projects, module_rebuild_cache(), 'module'); | |
31 _update_process_info_list($projects, system_theme_data(), 'theme'); | |
32 // Set the projects array into the cache table. | |
33 cache_set('update_project_projects', $projects, 'cache_update', time() + 3600); | |
34 } | |
35 } | |
36 return $projects; | |
37 } | |
38 | |
39 /** | |
40 * Populate an array of project data. | |
41 */ | |
42 function _update_process_info_list(&$projects, $list, $project_type) { | |
43 foreach ($list as $file) { | |
44 if (empty($file->status)) { | |
45 // Skip disabled modules or themes. | |
46 continue; | |
47 } | |
48 | |
49 // Skip if the .info file is broken. | |
50 if (empty($file->info)) { | |
51 continue; | |
52 } | |
53 | |
54 // If the .info doesn't define the 'project', try to figure it out. | |
55 if (!isset($file->info['project'])) { | |
56 $file->info['project'] = update_get_project_name($file); | |
57 } | |
58 | |
59 // If we still don't know the 'project', give up. | |
60 if (empty($file->info['project'])) { | |
61 continue; | |
62 } | |
63 | |
64 // If we don't already know it, grab the change time on the .info file | |
65 // itself. Note: we need to use the ctime, not the mtime (modification | |
66 // time) since many (all?) tar implementations will go out of their way to | |
67 // set the mtime on the files it creates to the timestamps recorded in the | |
68 // tarball. We want to see the last time the file was changed on disk, | |
69 // which is left alone by tar and correctly set to the time the .info file | |
70 // was unpacked. | |
71 if (!isset($file->info['_info_file_ctime'])) { | |
72 $info_filename = dirname($file->filename) .'/'. $file->name .'.info'; | |
73 $file->info['_info_file_ctime'] = filectime($info_filename); | |
74 } | |
75 | |
76 $project_name = $file->info['project']; | |
77 if (!isset($projects[$project_name])) { | |
78 // Only process this if we haven't done this project, since a single | |
79 // project can have multiple modules or themes. | |
80 $projects[$project_name] = array( | |
81 'name' => $project_name, | |
82 'info' => $file->info, | |
83 'datestamp' => isset($file->info['datestamp']) ? $file->info['datestamp'] : 0, | |
84 'includes' => array($file->name => $file->info['name']), | |
85 'project_type' => $project_name == 'drupal' ? 'core' : $project_type, | |
86 ); | |
87 } | |
88 else { | |
89 $projects[$project_name]['includes'][$file->name] = $file->info['name']; | |
90 $projects[$project_name]['info']['_info_file_ctime'] = max($projects[$project_name]['info']['_info_file_ctime'], $file->info['_info_file_ctime']); | |
91 } | |
92 } | |
93 } | |
94 | |
95 /** | |
96 * Given a $file object (as returned by system_get_files_database()), figure | |
97 * out what project it belongs to. | |
98 * | |
99 * @see system_get_files_database() | |
100 */ | |
101 function update_get_project_name($file) { | |
102 $project_name = ''; | |
103 if (isset($file->info['project'])) { | |
104 $project_name = $file->info['project']; | |
105 } | |
106 elseif (isset($file->info['package']) && (strpos($file->info['package'], 'Core -') !== FALSE)) { | |
107 $project_name = 'drupal'; | |
108 } | |
109 elseif (in_array($file->name, array('bluemarine', 'chameleon', 'garland', 'marvin', 'minnelli', 'pushbutton'))) { | |
110 // Unfortunately, there's no way to tell if a theme is part of core, | |
111 // so we must hard-code a list here. | |
112 $project_name = 'drupal'; | |
113 } | |
114 return $project_name; | |
115 } | |
116 | |
117 /** | |
118 * Process the list of projects on the system to figure out the currently | |
119 * installed versions, and other information that is required before we can | |
120 * compare against the available releases to produce the status report. | |
121 * | |
122 * @param $projects | |
123 * Array of project information from update_get_projects(). | |
124 */ | |
125 function update_process_project_info(&$projects) { | |
126 foreach ($projects as $key => $project) { | |
127 // Assume an official release until we see otherwise. | |
128 $install_type = 'official'; | |
129 | |
130 $info = $project['info']; | |
131 | |
132 if (isset($info['version'])) { | |
133 // Check for development snapshots | |
134 if (preg_match('@(dev|HEAD)@', $info['version'])) { | |
135 $install_type = 'dev'; | |
136 } | |
137 | |
138 // Figure out what the currently installed major version is. We need | |
139 // to handle both contribution (e.g. "5.x-1.3", major = 1) and core | |
140 // (e.g. "5.1", major = 5) version strings. | |
141 $matches = array(); | |
142 if (preg_match('/^(\d+\.x-)?(\d+)\..*$/', $info['version'], $matches)) { | |
143 $info['major'] = $matches[2]; | |
144 } | |
145 elseif (!isset($info['major'])) { | |
146 // This would only happen for version strings that don't follow the | |
147 // drupal.org convention. We let contribs define "major" in their | |
148 // .info in this case, and only if that's missing would we hit this. | |
149 $info['major'] = -1; | |
150 } | |
151 } | |
152 else { | |
153 // No version info available at all. | |
154 $install_type = 'unknown'; | |
155 $info['version'] = t('Unknown'); | |
156 $info['major'] = -1; | |
157 } | |
158 | |
159 // Finally, save the results we care about into the $projects array. | |
160 $projects[$key]['existing_version'] = $info['version']; | |
161 $projects[$key]['existing_major'] = $info['major']; | |
162 $projects[$key]['install_type'] = $install_type; | |
163 unset($projects[$key]['info']); | |
164 } | |
165 } | |
166 | |
167 /** | |
168 * Given the installed projects and the available release data retrieved from | |
169 * remote servers, calculate the current status. | |
170 * | |
171 * This function is the heart of the update status feature. It iterates over | |
172 * every currently installed project. For each one, it first checks if the | |
173 * project has been flagged with a special status like "unsupported" or | |
174 * "insecure", or if the project node itself has been unpublished. In any of | |
175 * those cases, the project is marked with an error and the next project is | |
176 * considered. | |
177 * | |
178 * If the project itself is valid, the function decides what major release | |
179 * series to consider. The project defines what the currently supported major | |
180 * versions are for each version of core, so the first step is to make sure | |
181 * the current version is still supported. If so, that's the target version. | |
182 * If the current version is unsupported, the project maintainer's recommended | |
183 * major version is used. There's also a check to make sure that this function | |
184 * never recommends an earlier release than the currently installed major | |
185 * version. | |
186 * | |
187 * Given a target major version, it scans the available releases looking for | |
188 * the specific release to recommend (avoiding beta releases and development | |
189 * snapshots if possible). This is complicated to describe, but an example | |
190 * will help clarify. For the target major version, find the highest patch | |
191 * level. If there is a release at that patch level with no extra ("beta", | |
192 * etc), then we recommend the release at that patch level with the most | |
193 * recent release date. If every release at that patch level has extra (only | |
194 * betas), then recommend the latest release from the previous patch | |
195 * level. For example: | |
196 * | |
197 * 1.6-bugfix <-- recommended version because 1.6 already exists. | |
198 * 1.6 | |
199 * | |
200 * or | |
201 * | |
202 * 1.6-beta | |
203 * 1.5 <-- recommended version because no 1.6 exists. | |
204 * 1.4 | |
205 * | |
206 * It also looks for the latest release from the same major version, even a | |
207 * beta release, to display to the user as the "Latest version" option. | |
208 * Additionally, it finds the latest official release from any higher major | |
209 * versions that have been released to provide a set of "Also available" | |
210 * options. | |
211 * | |
212 * Finally, and most importantly, it keeps scanning the release history until | |
213 * it gets to the currently installed release, searching for anything marked | |
214 * as a security update. If any security updates have been found between the | |
215 * recommended release and the installed version, all of the releases that | |
216 * included a security fix are recorded so that the site administrator can be | |
217 * warned their site is insecure, and links pointing to the release notes for | |
218 * each security update can be included (which, in turn, will link to the | |
219 * official security announcements for each vulnerability). | |
220 * | |
221 * This function relies on the fact that the .xml release history data comes | |
222 * sorted based on major version and patch level, then finally by release date | |
223 * if there are multiple releases such as betas from the same major.patch | |
224 * version (e.g. 5.x-1.5-beta1, 5.x-1.5-beta2, and 5.x-1.5). Development | |
225 * snapshots for a given major version are always listed last. | |
226 * | |
227 * @param $available | |
228 * Array of data about available project releases. | |
229 * | |
230 * @see update_get_available() | |
231 * @see update_get_projects() | |
232 * @see update_process_project_info() | |
233 */ | |
234 function update_calculate_project_data($available) { | |
235 // Retrieve the projects from cache, if present. | |
236 $projects = update_project_cache('update_project_data'); | |
237 // If $projects is empty, then the cache must be rebuilt. | |
238 // Otherwise, return the cached data and skip the rest of the function. | |
239 if (!empty($projects)) { | |
240 return $projects; | |
241 } | |
242 $projects = update_get_projects(); | |
243 update_process_project_info($projects); | |
244 foreach ($projects as $project => $project_info) { | |
245 if (isset($available[$project])) { | |
246 | |
247 // If the project status is marked as something bad, there's nothing | |
248 // else to consider. | |
249 if (isset($available[$project]['project_status'])) { | |
250 switch ($available[$project]['project_status']) { | |
251 case 'insecure': | |
252 $projects[$project]['status'] = UPDATE_NOT_SECURE; | |
253 if (empty($projects[$project]['extra'])) { | |
254 $projects[$project]['extra'] = array(); | |
255 } | |
256 $projects[$project]['extra'][] = array( | |
257 'class' => 'project-not-secure', | |
258 'label' => t('Project not secure'), | |
259 '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!'), | |
260 ); | |
261 break; | |
262 case 'unpublished': | |
263 case 'revoked': | |
264 $projects[$project]['status'] = UPDATE_REVOKED; | |
265 if (empty($projects[$project]['extra'])) { | |
266 $projects[$project]['extra'] = array(); | |
267 } | |
268 $projects[$project]['extra'][] = array( | |
269 'class' => 'project-revoked', | |
270 'label' => t('Project revoked'), | |
271 'data' => t('This project has been revoked, and is no longer available for download. Disabling everything included by this project is strongly recommended!'), | |
272 ); | |
273 break; | |
274 case 'unsupported': | |
275 $projects[$project]['status'] = UPDATE_NOT_SUPPORTED; | |
276 if (empty($projects[$project]['extra'])) { | |
277 $projects[$project]['extra'] = array(); | |
278 } | |
279 $projects[$project]['extra'][] = array( | |
280 'class' => 'project-not-supported', | |
281 'label' => t('Project not supported'), | |
282 'data' => t('This project is no longer supported, and is no longer available for download. Disabling everything included by this project is strongly recommended!'), | |
283 ); | |
284 break; | |
285 default: | |
286 // Assume anything else (e.g. 'published') is valid and we should | |
287 // perform the rest of the logic in this function. | |
288 break; | |
289 } | |
290 } | |
291 | |
292 if (!empty($projects[$project]['status'])) { | |
293 // We already know the status for this project, so there's nothing | |
294 // else to compute. Just record everything else we fetched from the | |
295 // XML file into our projects array and move to the next project. | |
296 $projects[$project] += $available[$project]; | |
297 continue; | |
298 } | |
299 | |
300 // Figure out the target major version. | |
301 $existing_major = $project_info['existing_major']; | |
302 $supported_majors = array(); | |
303 if (isset($available[$project]['supported_majors'])) { | |
304 $supported_majors = explode(',', $available[$project]['supported_majors']); | |
305 } | |
306 elseif (isset($available[$project]['default_major'])) { | |
307 // Older release history XML file without supported or recommended. | |
308 $supported_majors[] = $available[$project]['default_major']; | |
309 } | |
310 | |
311 if (in_array($existing_major, $supported_majors)) { | |
312 // Still supported, stay at the current major version. | |
313 $target_major = $existing_major; | |
314 } | |
315 elseif (isset($available[$project]['recommended_major'])) { | |
316 // Since 'recommended_major' is defined, we know this is the new XML | |
317 // format. Therefore, we know the current release is unsupported since | |
318 // its major version was not in the 'supported_majors' list. We should | |
319 // find the best release from the recommended major version. | |
320 $target_major = $available[$project]['recommended_major']; | |
321 $projects[$project]['status'] = UPDATE_NOT_SUPPORTED; | |
322 } | |
323 elseif (isset($available[$project]['default_major'])) { | |
324 // Older release history XML file without recommended, so recommend | |
325 // the currently defined "default_major" version. | |
326 $target_major = $available[$project]['default_major']; | |
327 } | |
328 else { | |
329 // Malformed XML file? Stick with the current version. | |
330 $target_major = $existing_major; | |
331 } | |
332 | |
333 // Make sure we never tell the admin to downgrade. If we recommended an | |
334 // earlier version than the one they're running, they'd face an | |
335 // impossible data migration problem, since Drupal never supports a DB | |
336 // downgrade path. In the unfortunate case that what they're running is | |
337 // unsupported, and there's nothing newer for them to upgrade to, we | |
338 // can't print out a "Recommended version", but just have to tell them | |
339 // what they have is unsupported and let them figure it out. | |
340 $target_major = max($existing_major, $target_major); | |
341 | |
342 $version_patch_changed = ''; | |
343 $patch = ''; | |
344 | |
345 // Defend ourselves from XML history files that contain no releases. | |
346 if (empty($available[$project]['releases'])) { | |
347 $projects[$project]['status'] = UPDATE_UNKNOWN; | |
348 $projects[$project]['reason'] = t('No available releases found'); | |
349 continue; | |
350 } | |
351 foreach ($available[$project]['releases'] as $version => $release) { | |
352 // First, if this is the existing release, check a few conditions. | |
353 if ($projects[$project]['existing_version'] == $version) { | |
354 if (isset($release['terms']['Release type']) && | |
355 in_array('Insecure', $release['terms']['Release type'])) { | |
356 $projects[$project]['status'] = UPDATE_NOT_SECURE; | |
357 } | |
358 elseif ($release['status'] == 'unpublished') { | |
359 $projects[$project]['status'] = UPDATE_REVOKED; | |
360 if (empty($projects[$project]['extra'])) { | |
361 $projects[$project]['extra'] = array(); | |
362 } | |
363 $projects[$project]['extra'][] = array( | |
364 'class' => 'release-revoked', | |
365 'label' => t('Release revoked'), | |
366 '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!'), | |
367 ); | |
368 } | |
369 elseif (isset($release['terms']['Release type']) && | |
370 in_array('Unsupported', $release['terms']['Release type'])) { | |
371 $projects[$project]['status'] = UPDATE_NOT_SUPPORTED; | |
372 if (empty($projects[$project]['extra'])) { | |
373 $projects[$project]['extra'] = array(); | |
374 } | |
375 $projects[$project]['extra'][] = array( | |
376 'class' => 'release-not-supported', | |
377 'label' => t('Release not supported'), | |
378 '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!'), | |
379 ); | |
380 } | |
381 } | |
382 | |
383 // Otherwise, ignore unpublished, insecure, or unsupported releases. | |
384 if ($release['status'] == 'unpublished' || | |
385 (isset($release['terms']['Release type']) && | |
386 (in_array('Insecure', $release['terms']['Release type']) || | |
387 in_array('Unsupported', $release['terms']['Release type'])))) { | |
388 continue; | |
389 } | |
390 | |
391 // See if this is a higher major version than our target and yet still | |
392 // supported. If so, record it as an "Also available" release. | |
393 if ($release['version_major'] > $target_major) { | |
394 if (in_array($release['version_major'], $supported_majors)) { | |
395 if (!isset($available[$project]['also'])) { | |
396 $available[$project]['also'] = array(); | |
397 } | |
398 if (!isset($available[$project]['also'][$release['version_major']])) { | |
399 $available[$project]['also'][$release['version_major']] = $version; | |
400 } | |
401 } | |
402 // Otherwise, this release can't matter to us, since it's neither | |
403 // from the release series we're currently using nor the recommended | |
404 // release. We don't even care about security updates for this | |
405 // branch, since if a project maintainer puts out a security release | |
406 // at a higher major version and not at the lower major version, | |
407 // they must remove the lower version from the supported major | |
408 // versions at the same time, in which case we won't hit this code. | |
409 continue; | |
410 } | |
411 | |
412 // Look for the 'latest version' if we haven't found it yet. Latest is | |
413 // defined as the most recent version for the target major version. | |
414 if (!isset($available[$project]['latest_version']) | |
415 && $release['version_major'] == $target_major) { | |
416 $available[$project]['latest_version'] = $version; | |
417 } | |
418 | |
419 // Look for the development snapshot release for this branch. | |
420 if (!isset($available[$project]['dev_version']) | |
421 && $release['version_major'] == $target_major | |
422 && isset($release['version_extra']) | |
423 && $release['version_extra'] == 'dev') { | |
424 $available[$project]['dev_version'] = $version; | |
425 } | |
426 | |
427 // Look for the 'recommended' version if we haven't found it yet (see | |
428 // phpdoc at the top of this function for the definition). | |
429 if (!isset($available[$project]['recommended']) | |
430 && $release['version_major'] == $target_major | |
431 && isset($release['version_patch'])) { | |
432 if ($patch != $release['version_patch']) { | |
433 $patch = $release['version_patch']; | |
434 $version_patch_changed = $release['version']; | |
435 } | |
436 if (empty($release['version_extra']) && $patch == $release['version_patch']) { | |
437 $available[$project]['recommended'] = $version_patch_changed; | |
438 } | |
439 } | |
440 | |
441 // Stop searching once we hit the currently installed version. | |
442 if ($projects[$project]['existing_version'] == $version) { | |
443 break; | |
444 } | |
445 | |
446 // If we're running a dev snapshot and have a timestamp, stop | |
447 // searching for security updates once we hit an official release | |
448 // older than what we've got. Allow 100 seconds of leeway to handle | |
449 // differences between the datestamp in the .info file and the | |
450 // timestamp of the tarball itself (which are usually off by 1 or 2 | |
451 // seconds) so that we don't flag that as a new release. | |
452 if ($projects[$project]['install_type'] == 'dev') { | |
453 if (empty($projects[$project]['datestamp'])) { | |
454 // We don't have current timestamp info, so we can't know. | |
455 continue; | |
456 } | |
457 elseif (isset($release['date']) && ($projects[$project]['datestamp'] + 100 > $release['date'])) { | |
458 // We're newer than this, so we can skip it. | |
459 continue; | |
460 } | |
461 } | |
462 | |
463 // See if this release is a security update. | |
464 if (isset($release['terms']['Release type']) | |
465 && in_array('Security update', $release['terms']['Release type'])) { | |
466 $projects[$project]['security updates'][] = $release; | |
467 } | |
468 } | |
469 | |
470 // If we were unable to find a recommended version, then make the latest | |
471 // version the recommended version if possible. | |
472 if (!isset($available[$project]['recommended']) && isset($available[$project]['latest_version'])) { | |
473 $available[$project]['recommended'] = $available[$project]['latest_version']; | |
474 } | |
475 | |
476 // Stash the info about available releases into our $projects array. | |
477 $projects[$project] += $available[$project]; | |
478 | |
479 // | |
480 // Check to see if we need an update or not. | |
481 // | |
482 | |
483 if (!empty($projects[$project]['security updates'])) { | |
484 // If we found security updates, that always trumps any other status. | |
485 $projects[$project]['status'] = UPDATE_NOT_SECURE; | |
486 } | |
487 | |
488 if (isset($projects[$project]['status'])) { | |
489 // If we already know the status, we're done. | |
490 continue; | |
491 } | |
492 | |
493 // If we don't know what to recommend, there's nothing we can report. | |
494 // Bail out early. | |
495 if (!isset($projects[$project]['recommended'])) { | |
496 $projects[$project]['status'] = UPDATE_UNKNOWN; | |
497 $projects[$project]['reason'] = t('No available releases found'); | |
498 continue; | |
499 } | |
500 | |
501 // If we're running a dev snapshot, compare the date of the dev snapshot | |
502 // with the latest official version, and record the absolute latest in | |
503 // 'latest_dev' so we can correctly decide if there's a newer release | |
504 // than our current snapshot. | |
505 if ($projects[$project]['install_type'] == 'dev') { | |
506 if (isset($available[$project]['dev_version']) && $available[$project]['releases'][$available[$project]['dev_version']]['date'] > $available[$project]['releases'][$available[$project]['latest_version']]['date']) { | |
507 $projects[$project]['latest_dev'] = $available[$project]['dev_version']; | |
508 } | |
509 else { | |
510 $projects[$project]['latest_dev'] = $available[$project]['latest_version']; | |
511 } | |
512 } | |
513 | |
514 // Figure out the status, based on what we've seen and the install type. | |
515 switch ($projects[$project]['install_type']) { | |
516 case 'official': | |
517 if ($projects[$project]['existing_version'] == $projects[$project]['recommended'] || $projects[$project]['existing_version'] == $projects[$project]['latest_version']) { | |
518 $projects[$project]['status'] = UPDATE_CURRENT; | |
519 } | |
520 else { | |
521 $projects[$project]['status'] = UPDATE_NOT_CURRENT; | |
522 } | |
523 break; | |
524 | |
525 case 'dev': | |
526 $latest = $available[$project]['releases'][$projects[$project]['latest_dev']]; | |
527 if (empty($projects[$project]['datestamp'])) { | |
528 $projects[$project]['status'] = UPDATE_NOT_CHECKED; | |
529 $projects[$project]['reason'] = t('Unknown release date'); | |
530 } | |
531 elseif (($projects[$project]['datestamp'] + 100 > $latest['date'])) { | |
532 $projects[$project]['status'] = UPDATE_CURRENT; | |
533 } | |
534 else { | |
535 $projects[$project]['status'] = UPDATE_NOT_CURRENT; | |
536 } | |
537 break; | |
538 | |
539 default: | |
540 $projects[$project]['status'] = UPDATE_UNKNOWN; | |
541 $projects[$project]['reason'] = t('Invalid info'); | |
542 } | |
543 } | |
544 else { | |
545 $projects[$project]['status'] = UPDATE_UNKNOWN; | |
546 $projects[$project]['reason'] = t('No available releases found'); | |
547 } | |
548 } | |
549 // Give other modules a chance to alter the status (for example, to allow a | |
550 // contrib module to provide fine-grained settings to ignore specific | |
551 // projects or releases). | |
552 drupal_alter('update_status', $projects); | |
553 | |
554 // Set the projects array into the cache table. | |
555 cache_set('update_project_data', $projects, 'cache_update', time() + 3600); | |
556 return $projects; | |
557 } | |
558 | |
559 /** | |
560 * Retrieve data from {cache_update} or empty the cache when necessary. | |
561 * | |
562 * Two very expensive arrays computed by this module are the list of all | |
563 * installed modules and themes (and .info data, project associations, etc), | |
564 * and the current status of the site relative to the currently available | |
565 * releases. These two arrays are cached in the {cache_update} table and used | |
566 * whenever possible. The cache is cleared whenever the administrator visits | |
567 * the status report, available updates report, or the module or theme | |
568 * administration pages, since we should always recompute the most current | |
569 * values on any of those pages. | |
570 * | |
571 * @param $cid | |
572 * The cache id of data to return from the cache. Valid options are | |
573 * 'update_project_data' and 'update_project_projects'. | |
574 * | |
575 * @return | |
576 * The cached value of the $projects array generated by | |
577 * update_calculate_project_data() or update_get_projects(), or an empty | |
578 * array when the cache is cleared. | |
579 */ | |
580 function update_project_cache($cid) { | |
581 $projects = array(); | |
582 | |
583 // In some cases, we must clear the cache. Rather than do so on a time | |
584 // basis, we check for specific paths. | |
585 $q = $_GET['q']; | |
586 $paths = array('admin/build/modules', 'admin/build/themes', 'admin/reports', 'admin/reports/updates', 'admin/reports/status', 'admin/reports/updates/check'); | |
587 if (in_array($q, $paths)) { | |
588 cache_clear_all($cid, 'cache_update'); | |
589 } | |
590 else { | |
591 $cache = cache_get($cid, 'cache_update'); | |
592 if (!empty($cache->data) && $cache->expire > time()) { | |
593 $projects = $cache->data; | |
594 } | |
595 } | |
596 return $projects; | |
597 } |