Chris@0: get('update.last_check') ?: 0; Chris@0: Chris@0: $variables['last_checked'] = [ Chris@0: '#theme' => 'update_last_check', Chris@0: '#last' => $last, Chris@0: // Attach the library to a variable that gets printed always. Chris@0: '#attached' => [ Chris@0: 'library' => [ Chris@0: 'update/drupal.update.admin', Chris@0: ], Chris@17: ], Chris@0: ]; Chris@0: Chris@0: // For no project update data, populate no data message. Chris@0: if (empty($data)) { Chris@0: $variables['no_updates_message'] = _update_no_data(); Chris@0: } Chris@0: Chris@0: $rows = []; Chris@0: Chris@0: foreach ($data as $project) { Chris@0: $project_status = [ Chris@0: '#theme' => 'update_project_status', Chris@0: '#project' => $project, Chris@0: ]; Chris@0: Chris@0: // Build project rows. Chris@0: if (!isset($rows[$project['project_type']])) { Chris@0: $rows[$project['project_type']] = [ Chris@0: '#type' => 'table', Chris@0: '#attributes' => ['class' => ['update']], Chris@0: ]; Chris@0: } Chris@17: $row_key = !empty($project['title']) ? mb_strtolower($project['title']) : mb_strtolower($project['name']); Chris@0: Chris@0: // Add the project status row and details. Chris@0: $rows[$project['project_type']][$row_key]['status'] = $project_status; Chris@0: Chris@0: // Add project status class attribute to the table row. Chris@0: switch ($project['status']) { Chris@0: case UPDATE_CURRENT: Chris@0: $rows[$project['project_type']][$row_key]['#attributes'] = ['class' => ['color-success']]; Chris@0: break; Chris@0: case UPDATE_UNKNOWN: Chris@0: case UPDATE_FETCH_PENDING: Chris@0: case UPDATE_NOT_FETCHED: Chris@0: case UPDATE_NOT_SECURE: Chris@0: case UPDATE_REVOKED: Chris@0: case UPDATE_NOT_SUPPORTED: Chris@0: $rows[$project['project_type']][$row_key]['#attributes'] = ['class' => ['color-error']]; Chris@0: break; Chris@0: case UPDATE_NOT_CHECKED: Chris@0: case UPDATE_NOT_CURRENT: Chris@0: default: Chris@0: $rows[$project['project_type']][$row_key]['#attributes'] = ['class' => ['color-warning']]; Chris@0: break; Chris@0: } Chris@0: } Chris@0: Chris@0: $project_types = [ Chris@0: 'core' => t('Drupal core'), Chris@0: 'module' => t('Modules'), Chris@0: 'theme' => t('Themes'), Chris@0: 'module-disabled' => t('Uninstalled modules'), Chris@0: 'theme-disabled' => t('Uninstalled themes'), Chris@0: ]; Chris@0: Chris@0: $variables['project_types'] = []; Chris@0: foreach ($project_types as $type_name => $type_label) { Chris@0: if (!empty($rows[$type_name])) { Chris@0: ksort($rows[$type_name]); Chris@0: $variables['project_types'][] = [ Chris@0: 'label' => $type_label, Chris@0: 'table' => $rows[$type_name], Chris@0: ]; Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Prepares variables for update project status templates. Chris@0: * Chris@0: * Default template: update-project-status.html.twig. Chris@0: * Chris@0: * @param array $variables Chris@0: * An associative array containing: Chris@0: * - project: An array of information about the project. Chris@0: */ Chris@0: function template_preprocess_update_project_status(&$variables) { Chris@0: // Storing by reference because we are sorting the project values. Chris@0: $project = &$variables['project']; Chris@0: Chris@0: // Set the project title and URL. Chris@0: $variables['title'] = (isset($project['title'])) ? $project['title'] : $project['name']; Chris@0: $variables['url'] = (isset($project['link'])) ? Url::fromUri($project['link'])->toString() : NULL; Chris@0: Chris@0: $variables['install_type'] = $project['install_type']; Chris@0: if ($project['install_type'] == 'dev' && !empty($project['datestamp'])) { Chris@18: $variables['datestamp'] = \Drupal::service('date.formatter')->format($project['datestamp'], 'custom', 'Y-M-d'); Chris@0: } Chris@0: Chris@0: $variables['existing_version'] = $project['existing_version']; Chris@0: Chris@0: $versions_inner = []; Chris@0: $security_class = []; Chris@0: $version_class = []; Chris@0: if (isset($project['recommended'])) { Chris@0: if ($project['status'] != UPDATE_CURRENT || $project['existing_version'] !== $project['recommended']) { Chris@0: Chris@0: // First, figure out what to recommend. Chris@0: // If there's only 1 security update and it has the same version we're Chris@0: // recommending, give it the same CSS class as if it was recommended, Chris@0: // but don't print out a separate "Recommended" line for this project. Chris@0: if (!empty($project['security updates']) Chris@0: && count($project['security updates']) == 1 Chris@0: && $project['security updates'][0]['version'] === $project['recommended'] Chris@0: ) { Chris@0: $security_class[] = 'project-update__version--recommended'; Chris@0: $security_class[] = 'project-update__version---strong'; Chris@0: } Chris@0: else { Chris@0: $version_class[] = 'project-update__version--recommended'; Chris@0: // Apply an extra class if we're displaying both a recommended Chris@0: // version and anything else for an extra visual hint. Chris@0: if ($project['recommended'] !== $project['latest_version'] Chris@0: || !empty($project['also']) Chris@0: || ($project['install_type'] == 'dev' Chris@0: && isset($project['dev_version']) Chris@0: && $project['latest_version'] !== $project['dev_version'] Chris@0: && $project['recommended'] !== $project['dev_version']) Chris@0: || (isset($project['security updates'][0]) Chris@0: && $project['recommended'] !== $project['security updates'][0]) Chris@0: ) { Chris@0: $version_class[] = 'project-update__version--recommended-strong'; Chris@0: } Chris@0: $versions_inner[] = [ Chris@0: '#theme' => 'update_version', Chris@0: '#version' => $project['releases'][$project['recommended']], Chris@0: '#title' => t('Recommended version:'), Chris@0: '#attributes' => ['class' => $version_class], Chris@0: ]; Chris@0: } Chris@0: Chris@0: // Now, print any security updates. Chris@0: if (!empty($project['security updates'])) { Chris@0: $security_class[] = 'version-security'; Chris@0: foreach ($project['security updates'] as $security_update) { Chris@0: $versions_inner[] = [ Chris@0: '#theme' => 'update_version', Chris@0: '#version' => $security_update, Chris@0: '#title' => t('Security update:'), Chris@0: '#attributes' => ['class' => $security_class], Chris@0: ]; Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: if ($project['recommended'] !== $project['latest_version']) { Chris@0: $versions_inner[] = [ Chris@0: '#theme' => 'update_version', Chris@0: '#version' => $project['releases'][$project['latest_version']], Chris@0: '#title' => t('Latest version:'), Chris@0: '#attributes' => ['class' => ['version-latest']], Chris@0: ]; Chris@0: } Chris@0: if ($project['install_type'] == 'dev' Chris@0: && $project['status'] != UPDATE_CURRENT Chris@0: && isset($project['dev_version']) Chris@0: && $project['recommended'] !== $project['dev_version']) { Chris@0: $versions_inner[] = [ Chris@0: '#theme' => 'update_version', Chris@0: '#version' => $project['releases'][$project['dev_version']], Chris@0: '#title' => t('Development version:'), Chris@0: '#attributes' => ['class' => ['version-latest']], Chris@0: ]; Chris@0: } Chris@0: } Chris@0: Chris@0: if (isset($project['also'])) { Chris@0: foreach ($project['also'] as $also) { Chris@0: $versions_inner[] = [ Chris@0: '#theme' => 'update_version', Chris@0: '#version' => $project['releases'][$also], Chris@0: '#title' => t('Also available:'), Chris@0: '#attributes' => ['class' => ['version-also-available']], Chris@0: ]; Chris@0: } Chris@0: } Chris@0: Chris@0: if (!empty($versions_inner)) { Chris@0: $variables['versions'] = $versions_inner; Chris@0: } Chris@0: Chris@0: if (!empty($project['disabled'])) { Chris@0: sort($project['disabled']); Chris@0: $variables['disabled'] = $project['disabled']; Chris@0: } Chris@0: Chris@0: sort($project['includes']); Chris@0: $variables['includes'] = $project['includes']; Chris@0: Chris@0: $variables['extras'] = []; Chris@0: if (!empty($project['extra'])) { Chris@0: foreach ($project['extra'] as $value) { Chris@0: $extra_item = []; Chris@0: $extra_item['attributes'] = new Attribute(); Chris@0: $extra_item['label'] = $value['label']; Chris@0: $extra_item['data'] = [ Chris@0: '#prefix' => '', Chris@0: '#markup' => $value['data'], Chris@17: '#suffix' => '', Chris@0: ]; Chris@0: $variables['extras'][] = $extra_item; Chris@0: } Chris@0: } Chris@0: Chris@0: // Set the project status details. Chris@0: $status_label = NULL; Chris@0: switch ($project['status']) { Chris@0: case UPDATE_NOT_SECURE: Chris@0: $status_label = t('Security update required!'); Chris@0: break; Chris@0: case UPDATE_REVOKED: Chris@0: $status_label = t('Revoked!'); Chris@0: break; Chris@0: case UPDATE_NOT_SUPPORTED: Chris@0: $status_label = t('Not supported!'); Chris@0: break; Chris@0: case UPDATE_NOT_CURRENT: Chris@0: $status_label = t('Update available'); Chris@0: break; Chris@0: case UPDATE_CURRENT: Chris@0: $status_label = t('Up to date'); Chris@0: break; Chris@0: } Chris@0: $variables['status']['label'] = $status_label; Chris@0: $variables['status']['attributes'] = new Attribute(); Chris@0: $variables['status']['reason'] = (isset($project['reason'])) ? $project['reason'] : NULL; Chris@0: Chris@0: switch ($project['status']) { Chris@0: case UPDATE_CURRENT: Chris@0: $uri = 'core/misc/icons/73b355/check.svg'; Chris@0: $text = t('Ok'); Chris@0: break; Chris@0: case UPDATE_UNKNOWN: Chris@0: case UPDATE_FETCH_PENDING: Chris@0: case UPDATE_NOT_FETCHED: Chris@0: $uri = 'core/misc/icons/e29700/warning.svg'; Chris@0: $text = t('Warning'); Chris@0: break; Chris@0: case UPDATE_NOT_SECURE: Chris@0: case UPDATE_REVOKED: Chris@0: case UPDATE_NOT_SUPPORTED: Chris@0: $uri = 'core/misc/icons/e32700/error.svg'; Chris@0: $text = t('Error'); Chris@0: break; Chris@0: case UPDATE_NOT_CHECKED: Chris@0: case UPDATE_NOT_CURRENT: Chris@0: default: Chris@0: $uri = 'core/misc/icons/e29700/warning.svg'; Chris@0: $text = t('Warning'); Chris@0: break; Chris@0: } Chris@0: Chris@0: $variables['status']['icon'] = [ Chris@0: '#theme' => 'image', Chris@0: '#width' => 18, Chris@0: '#height' => 18, Chris@0: '#uri' => $uri, Chris@0: '#alt' => $text, Chris@0: '#title' => $text, Chris@0: ]; Chris@0: }