Projet

Général

Profil

Paste
Télécharger (12,2 ko) Statistiques
| Branche: | Révision:

root / drupal7 / modules / update / update.report.inc @ 01dfd3b5

1
<?php
2

    
3
/**
4
 * @file
5
 * Code required only when rendering the available updates report.
6
 */
7

    
8
/**
9
 * Page callback: Generates a page about the update status of projects.
10
 *
11
 * @see update_menu()
12
 */
13
function update_status() {
14
  if ($available = update_get_available(TRUE)) {
15
    module_load_include('inc', 'update', 'update.compare');
16
    $data = update_calculate_project_data($available);
17
    return theme('update_report', array('data' => $data));
18
  }
19
  else {
20
    return theme('update_report', array('data' => _update_no_data()));
21
  }
22
}
23

    
24
/**
25
 * Returns HTML for the project status report.
26
 *
27
 * @param array $variables
28
 *   An associative array containing:
29
 *   - data: An array of data about each project's status.
30
 *
31
 * @ingroup themeable
32
 */
33
function theme_update_report($variables) {
34
  $data = $variables['data'];
35

    
36
  $last = variable_get('update_last_check', 0);
37
  $output = theme('update_last_check', array('last' => $last));
38

    
39
  if (!is_array($data)) {
40
    $output .= '<p>' . $data . '</p>';
41
    return $output;
42
  }
43

    
44
  $header = array();
45
  $rows = array();
46

    
47
  $notification_level = variable_get('update_notification_threshold', 'all');
48

    
49
  // Create an array of status values keyed by module or theme name, since
50
  // we'll need this while generating the report if we have to cross reference
51
  // anything (e.g. subthemes which have base themes missing an update).
52
  foreach ($data as $project) {
53
    foreach ($project['includes'] as $key => $name) {
54
      $status[$key] = $project['status'];
55
    }
56
  }
57

    
58
  foreach ($data as $project) {
59
    switch ($project['status']) {
60
      case UPDATE_CURRENT:
61
        $class = 'ok';
62
        $icon = theme('image', array('path' => 'misc/watchdog-ok.png', 'width' => 18, 'height' => 18, 'alt' => t('ok'), 'title' => t('ok')));
63
        break;
64
      case UPDATE_UNKNOWN:
65
      case UPDATE_FETCH_PENDING:
66
      case UPDATE_NOT_FETCHED:
67
        $class = 'unknown';
68
        $icon = theme('image', array('path' => 'misc/watchdog-warning.png', 'width' => 18, 'height' => 18, 'alt' => t('warning'), 'title' => t('warning')));
69
        break;
70
      case UPDATE_NOT_SECURE:
71
      case UPDATE_REVOKED:
72
      case UPDATE_NOT_SUPPORTED:
73
        $class = 'error';
74
        $icon = theme('image', array('path' => 'misc/watchdog-error.png', 'width' => 18, 'height' => 18, 'alt' => t('error'), 'title' => t('error')));
75
        break;
76
      case UPDATE_NOT_CHECKED:
77
      case UPDATE_NOT_CURRENT:
78
      default:
79
        $class = 'warning';
80
        $icon = theme('image', array('path' => 'misc/watchdog-warning.png', 'width' => 18, 'height' => 18, 'alt' => t('warning'), 'title' => t('warning')));
81
        break;
82
    }
83

    
84
    $row = '<div class="version-status">';
85
    $status_label = theme('update_status_label', array('status' => $project['status']));
86
    $row .= !empty($status_label) ? $status_label : check_plain($project['reason']);
87
    $row .= '<span class="icon">' . $icon . '</span>';
88
    $row .= "</div>\n";
89

    
90
    $row .= '<div class="project">';
91
    if (isset($project['title'])) {
92
      if (isset($project['link'])) {
93
        $row .= l($project['title'], $project['link']);
94
      }
95
      else {
96
        $row .= check_plain($project['title']);
97
      }
98
    }
99
    else {
100
      $row .= check_plain($project['name']);
101
    }
102
    $row .= ' ' . check_plain($project['existing_version']);
103
    if ($project['install_type'] == 'dev' && !empty($project['datestamp'])) {
104
      $row .= ' <span class="version-date">(' . format_date($project['datestamp'], 'custom', 'Y-M-d') . ')</span>';
105
    }
106
    $row .= "</div>\n";
107

    
108
    $versions_inner = '';
109
    $security_class = array();
110
    $version_class = array();
111
    if (isset($project['recommended'])) {
112
      if ($project['status'] != UPDATE_CURRENT || $project['existing_version'] !== $project['recommended']) {
113

    
114
        // First, figure out what to recommend.
115
        // If there's only 1 security update and it has the same version we're
116
        // recommending, give it the same CSS class as if it was recommended,
117
        // but don't print out a separate "Recommended" line for this project.
118
        if (!empty($project['security updates']) && count($project['security updates']) == 1 && $project['security updates'][0]['version'] === $project['recommended']) {
119
          $security_class[] = 'version-recommended';
120
          $security_class[] = 'version-recommended-strong';
121
        }
122
        else {
123
          $version_class[] = 'version-recommended';
124
          // Apply an extra class if we're displaying both a recommended
125
          // version and anything else for an extra visual hint.
126
          if ($project['recommended'] !== $project['latest_version']
127
              || !empty($project['also'])
128
              || ($project['install_type'] == 'dev'
129
                && isset($project['dev_version'])
130
                && $project['latest_version'] !== $project['dev_version']
131
                && $project['recommended'] !== $project['dev_version'])
132
              || (isset($project['security updates'][0])
133
                && $project['recommended'] !== $project['security updates'][0])
134
              ) {
135
            $version_class[] = 'version-recommended-strong';
136
          }
137
          $versions_inner .= theme('update_version', array('version' => $project['releases'][$project['recommended']], 'tag' => t('Recommended version:'), 'class' => $version_class));
138
        }
139

    
140
        // Now, print any security updates.
141
        if (!empty($project['security updates'])) {
142
          $security_class[] = 'version-security';
143
          foreach ($project['security updates'] as $security_update) {
144
            $versions_inner .= theme('update_version', array('version' => $security_update, 'tag' => t('Security update:'), 'class' => $security_class));
145
          }
146
        }
147
      }
148

    
149
      if ($project['recommended'] !== $project['latest_version']) {
150
        $versions_inner .= theme('update_version', array('version' => $project['releases'][$project['latest_version']], 'tag' => t('Latest version:'), 'class' => array('version-latest')));
151
      }
152
      if ($project['install_type'] == 'dev'
153
          && $project['status'] != UPDATE_CURRENT
154
          && isset($project['dev_version'])
155
          && $project['recommended'] !== $project['dev_version']) {
156
        $versions_inner .= theme('update_version', array('version' => $project['releases'][$project['dev_version']], 'tag' => t('Development version:'), 'class' => array('version-latest')));
157
      }
158
    }
159

    
160
    if (isset($project['also'])) {
161
      foreach ($project['also'] as $also) {
162
        $versions_inner .= theme('update_version', array('version' => $project['releases'][$also], 'tag' => t('Also available:'), 'class' => array('version-also-available')));
163
      }
164
    }
165

    
166
    if (!empty($versions_inner)) {
167
      $row .= "<div class=\"versions\">\n" . $versions_inner . "</div>\n";
168
    }
169
    $row .= "<div class=\"info\">\n";
170
    if (!empty($project['extra'])) {
171
      $row .= '<div class="extra">' . "\n";
172
      foreach ($project['extra'] as $key => $value) {
173
        $row .= '<div class="' . implode(' ', $value['class']) . '">';
174
        $row .= check_plain($value['label']) . ': ';
175
        $row .= drupal_placeholder($value['data']);
176
        $row .= "</div>\n";
177
      }
178
      $row .= "</div>\n";  // extra div.
179
    }
180

    
181
    $row .= '<div class="includes">';
182
    sort($project['includes']);
183
    if (!empty($project['disabled'])) {
184
      sort($project['disabled']);
185
      // Make sure we start with a clean slate for each project in the report.
186
      $includes_items = array();
187
      $row .= t('Includes:');
188
      $includes_items[] = t('Enabled: %includes', array('%includes' => implode(', ', $project['includes'])));
189
      $includes_items[] = t('Disabled: %disabled', array('%disabled' => implode(', ', $project['disabled'])));
190
      $row .= theme('item_list', array('items' => $includes_items));
191
    }
192
    else {
193
      $row .= t('Includes: %includes', array('%includes' => implode(', ', $project['includes'])));
194
    }
195
    $row .= "</div>\n";
196

    
197
    if (!empty($project['base_themes'])) {
198
      $row .= '<div class="basethemes">';
199
      asort($project['base_themes']);
200
      $base_themes = array();
201
      foreach ($project['base_themes'] as $base_key => $base_theme) {
202
        switch ($status[$base_key]) {
203
          case UPDATE_NOT_SECURE:
204
          case UPDATE_REVOKED:
205
          case UPDATE_NOT_SUPPORTED:
206
            $base_themes[] = t('%base_theme (!base_label)', array('%base_theme' => $base_theme, '!base_label' => theme('update_status_label', array('status' => $status[$base_key]))));
207
            break;
208

    
209
          default:
210
            $base_themes[] = drupal_placeholder($base_theme);
211
        }
212
      }
213
      $row .= t('Depends on: !basethemes', array('!basethemes' => implode(', ', $base_themes)));
214
      $row .= "</div>\n";
215
    }
216

    
217
    if (!empty($project['sub_themes'])) {
218
      $row .= '<div class="subthemes">';
219
      sort($project['sub_themes']);
220
      $row .= t('Required by: %subthemes', array('%subthemes' => implode(', ', $project['sub_themes'])));
221
      $row .= "</div>\n";
222
    }
223

    
224
    $row .= "</div>\n"; // info div.
225

    
226
    if (!isset($rows[$project['project_type']])) {
227
      $rows[$project['project_type']] = array();
228
    }
229
    $row_key = isset($project['title']) ? drupal_strtolower($project['title']) : drupal_strtolower($project['name']);
230
    $rows[$project['project_type']][$row_key] = array(
231
      'class' => array($class),
232
      'data' => array($row),
233
    );
234
  }
235

    
236
  $project_types = array(
237
    'core' => t('Drupal core'),
238
    'module' => t('Modules'),
239
    'theme' => t('Themes'),
240
    'module-disabled' => t('Disabled modules'),
241
    'theme-disabled' => t('Disabled themes'),
242
  );
243
  foreach ($project_types as $type_name => $type_label) {
244
    if (!empty($rows[$type_name])) {
245
      ksort($rows[$type_name]);
246
      $output .= "\n<h3>" . $type_label . "</h3>\n";
247
      $output .= theme('table', array('header' => $header, 'rows' => $rows[$type_name], 'attributes' => array('class' => array('update'))));
248
    }
249
  }
250
  drupal_add_css(drupal_get_path('module', 'update') . '/update.css');
251
  return $output;
252
}
253

    
254
/**
255
 * Returns HTML for a label to display for a project's update status.
256
 *
257
 * @param array $variables
258
 *   An associative array containing:
259
 *   - status: The integer code for a project's current update status.
260
 *
261
 * @see update_calculate_project_data()
262
 * @ingroup themeable
263
 */
264
function theme_update_status_label($variables) {
265
  switch ($variables['status']) {
266
    case UPDATE_NOT_SECURE:
267
      return '<span class="security-error">' . t('Security update required!') . '</span>';
268

    
269
    case UPDATE_REVOKED:
270
      return '<span class="revoked">' . t('Revoked!') . '</span>';
271

    
272
    case UPDATE_NOT_SUPPORTED:
273
      return '<span class="not-supported">' . t('Not supported!') . '</span>';
274

    
275
    case UPDATE_NOT_CURRENT:
276
      return '<span class="not-current">' . t('Update available') . '</span>';
277

    
278
    case UPDATE_CURRENT:
279
      return '<span class="current">' . t('Up to date') . '</span>';
280

    
281
  }
282
}
283

    
284
/**
285
 * Returns HTML for the version display of a project.
286
 *
287
 * @param array $variables
288
 *   An associative array containing:
289
 *   - version: An array of data about the latest released version, containing:
290
 *     - version: The version number.
291
 *     - release_link: The URL for the release notes.
292
 *     - date: The date of the release.
293
 *     - download_link: The URL for the downloadable file.
294
 *   - tag: The title of the project.
295
 *   - class: A string containing extra classes for the wrapping table.
296
 *
297
 * @ingroup themeable
298
 */
299
function theme_update_version($variables) {
300
  $version = $variables['version'];
301
  $tag = $variables['tag'];
302
  $class = implode(' ', $variables['class']);
303

    
304
  $output = '';
305
  $output .= '<table class="version ' . $class . '">';
306
  $output .= '<tr>';
307
  $output .= '<td class="version-title">' . $tag . "</td>\n";
308
  $output .= '<td class="version-details">';
309
  $output .= l($version['version'], $version['release_link']);
310
  $output .= ' <span class="version-date">(' . format_date($version['date'], 'custom', 'Y-M-d') . ')</span>';
311
  $output .= "</td>\n";
312
  $output .= '<td class="version-links">';
313
  $links = array();
314
  $links['update-download'] = array(
315
    'title' => t('Download'),
316
    'href' => $version['download_link'],
317
  );
318
  $links['update-release-notes'] = array(
319
    'title' => t('Release notes'),
320
    'href' => $version['release_link'],
321
  );
322
  $output .= theme('links__update_version', array('links' => $links));
323
  $output .= '</td>';
324
  $output .= '</tr>';
325
  $output .= "</table>\n";
326
  return $output;
327
}