updated core and modules

This commit is contained in:
Bachir Soussi Chiadmi
2017-09-09 16:27:51 +02:00
parent 027aa99b32
commit 41863f872c
7810 changed files with 318922 additions and 83631 deletions
@@ -44,9 +44,9 @@ class UpdateController extends ControllerBase {
* A build array with the update status of projects.
*/
public function updateStatus() {
$build = array(
$build = [
'#theme' => 'update_report'
);
];
if ($available = update_get_available(TRUE)) {
$this->moduleHandler()->loadInclude('update', 'compare.inc');
$build['#data'] = update_calculate_project_data($available);
@@ -59,15 +59,15 @@ class UpdateController extends ControllerBase {
*/
public function updateStatusManually() {
$this->updateManager->refreshUpdateData();
$batch = array(
'operations' => array(
array(array($this->updateManager, 'fetchDataBatch'), array()),
),
$batch = [
'operations' => [
[[$this->updateManager, 'fetchDataBatch'], []],
],
'finished' => 'update_fetch_data_finished',
'title' => t('Checking available update data'),
'progress_message' => t('Trying to check available update data ...'),
'error_message' => t('Error checking available update data.'),
);
];
batch_set($batch);
return batch_process('admin/reports/updates');
}
@@ -79,41 +79,41 @@ class UpdateManagerInstall extends FormBase {
return $form;
}
$form['help_text'] = array(
$form['help_text'] = [
'#prefix' => '<p>',
'#markup' => $this->t('You can find <a href=":module_url">modules</a> and <a href=":theme_url">themes</a> on <a href=":drupal_org_url">drupal.org</a>. The following file extensions are supported: %extensions.', array(
'#markup' => $this->t('You can find <a href=":module_url">modules</a> and <a href=":theme_url">themes</a> on <a href=":drupal_org_url">drupal.org</a>. The following file extensions are supported: %extensions.', [
':module_url' => 'https://www.drupal.org/project/modules',
':theme_url' => 'https://www.drupal.org/project/themes',
':drupal_org_url' => 'https://www.drupal.org',
'%extensions' => archiver_get_extensions(),
)),
]),
'#suffix' => '</p>',
);
];
$form['project_url'] = array(
$form['project_url'] = [
'#type' => 'url',
'#title' => $this->t('Install from a URL'),
'#description' => $this->t('For example: %url', array('%url' => 'http://ftp.drupal.org/files/projects/name.tar.gz')),
);
'#description' => $this->t('For example: %url', ['%url' => 'http://ftp.drupal.org/files/projects/name.tar.gz']),
];
$form['information'] = array(
$form['information'] = [
'#prefix' => '<strong>',
'#markup' => $this->t('Or'),
'#suffix' => '</strong>',
);
];
$form['project_upload'] = array(
$form['project_upload'] = [
'#type' => 'file',
'#title' => $this->t('Upload a module or theme archive to install'),
'#description' => $this->t('For example: %filename from your local computer', array('%filename' => 'name.tar.gz')),
);
'#description' => $this->t('For example: %filename from your local computer', ['%filename' => 'name.tar.gz']),
];
$form['actions'] = array('#type' => 'actions');
$form['actions']['submit'] = array(
$form['actions'] = ['#type' => 'actions'];
$form['actions']['submit'] = [
'#type' => 'submit',
'#button_type' => 'primary',
'#value' => $this->t('Install'),
);
];
return $form;
}
@@ -136,12 +136,12 @@ class UpdateManagerInstall extends FormBase {
if ($form_state->getValue('project_url')) {
$local_cache = update_manager_file_get($form_state->getValue('project_url'));
if (!$local_cache) {
drupal_set_message($this->t('Unable to retrieve Drupal project from %url.', array('%url' => $form_state->getValue('project_url'))), 'error');
drupal_set_message($this->t('Unable to retrieve Drupal project from %url.', ['%url' => $form_state->getValue('project_url')]), 'error');
return;
}
}
elseif ($_FILES['files']['name']['project_upload']) {
$validators = array('file_validate_extensions' => array(archiver_get_extensions()));
$validators = ['file_validate_extensions' => [archiver_get_extensions()]];
if (!($finfo = file_save_upload('project_upload', $validators, NULL, 0, FILE_EXISTS_REPLACE))) {
// Failed to upload the file. file_save_upload() calls
// drupal_set_message() on failure.
@@ -170,7 +170,7 @@ class UpdateManagerInstall extends FormBase {
// MODULE/) and others list an actual file (i.e., MODULE/README.TXT).
$project = strtok($files[0], '/\\');
$archive_errors = $this->moduleHandler->invokeAll('verify_update_archive', array($project, $local_cache, $directory));
$archive_errors = $this->moduleHandler->invokeAll('verify_update_archive', [$project, $local_cache, $directory]);
if (!empty($archive_errors)) {
drupal_set_message(array_shift($archive_errors), 'error');
// @todo: Fix me in D8: We need a way to set multiple errors on the same
@@ -204,20 +204,20 @@ class UpdateManagerInstall extends FormBase {
}
if (!$project_title) {
drupal_set_message($this->t('Unable to determine %project name.', array('%project' => $project)), 'error');
drupal_set_message($this->t('Unable to determine %project name.', ['%project' => $project]), 'error');
}
if ($updater->isInstalled()) {
drupal_set_message($this->t('%project is already installed.', array('%project' => $project_title)), 'error');
drupal_set_message($this->t('%project is already installed.', ['%project' => $project_title]), 'error');
return;
}
$project_real_location = drupal_realpath($project_location);
$arguments = array(
$arguments = [
'project' => $project,
'updater_name' => get_class($updater),
'local_url' => $project_real_location,
);
];
// This process is inherently difficult to test therefore use a state flag.
$test_authorize = FALSE;
@@ -232,7 +232,7 @@ class UpdateManagerInstall extends FormBase {
if (fileowner($project_real_location) == fileowner($this->sitePath) && !$test_authorize) {
$this->moduleHandler->loadInclude('update', 'inc', 'update.authorize');
$filetransfer = new Local($this->root);
$response = call_user_func_array('update_authorize_run_install', array_merge(array($filetransfer), $arguments));
$response = call_user_func_array('update_authorize_run_install', array_merge([$filetransfer], $arguments));
if ($response instanceof Response) {
$form_state->setResponse($response);
}
@@ -64,13 +64,13 @@ class UpdateManagerUpdate extends FormBase {
public function buildForm(array $form, FormStateInterface $form_state) {
$this->moduleHandler->loadInclude('update', 'inc', 'update.manager');
$last_markup = array(
$last_markup = [
'#theme' => 'update_last_check',
'#last' => $this->state->get('update.last_check') ?: 0,
);
$form['last_check'] = array(
];
$form['last_check'] = [
'#markup' => drupal_render($last_markup),
);
];
if (!_update_manager_check_backends($form, 'update')) {
return $form;
@@ -78,9 +78,9 @@ class UpdateManagerUpdate extends FormBase {
$available = update_get_available(TRUE);
if (empty($available)) {
$form['message'] = array(
$form['message'] = [
'#markup' => $this->t('There was a problem getting update information. Try again later.'),
);
];
return $form;
}
@@ -91,11 +91,11 @@ class UpdateManagerUpdate extends FormBase {
// manual updates, such as core). Then, each subarray is an array of
// projects of that type, indexed by project short name, and containing an
// array of data for cells in that project's row in the appropriate table.
$projects = array();
$projects = [];
// This stores the actual download link we're going to update from for each
// project in the form, regardless of if it's enabled or disabled.
$form['project_downloads'] = array('#tree' => TRUE);
$form['project_downloads'] = ['#tree' => TRUE];
$this->moduleHandler->loadInclude('update', 'inc', 'update.compare');
$project_data = update_calculate_project_data($available);
foreach ($project_data as $name => $project) {
@@ -134,25 +134,25 @@ class UpdateManagerUpdate extends FormBase {
$recommended_version .= '<div title="{{ major_update_warning_title }}" class="update-major-version-warning">{{ major_update_warning_text }}</div>';
}
$recommended_version = array(
$recommended_version = [
'#type' => 'inline_template',
'#template' => $recommended_version,
'#context' => array(
'#context' => [
'release_version' => $recommended_release['version'],
'release_link' => $recommended_release['release_link'],
'project_title' => $this->t('Release notes for @project_title', array('@project_title' => $project['title'])),
'project_title' => $this->t('Release notes for @project_title', ['@project_title' => $project['title']]),
'major_update_warning_title' => $this->t('Major upgrade warning'),
'major_update_warning_text' => $this->t('This update is a major version update which means that it may not be backwards compatible with your currently running version. It is recommended that you read the release notes and proceed at your own risk.'),
'release_notes' => $this->t('Release notes'),
),
);
],
];
// Create an entry for this project.
$entry = array(
$entry = [
'title' => $project_name,
'installed_version' => $project['existing_version'],
'recommended_version' => array('data' => $recommended_version),
);
'recommended_version' => ['data' => $recommended_version],
];
switch ($project['status']) {
case UPDATE_NOT_SECURE:
@@ -181,11 +181,11 @@ class UpdateManagerUpdate extends FormBase {
}
// Use the project title for the tableselect checkboxes.
$entry['title'] = array('data' => array(
$entry['title'] = ['data' => [
'#title' => $entry['title'],
'#markup' => $entry['title'],
));
$entry['#attributes'] = array('class' => array('update-' . $type));
]];
$entry['#attributes'] = ['class' => ['update-' . $type]];
// Drupal core needs to be upgraded manually.
$needs_manual = $project['project_type'] == 'core';
@@ -198,15 +198,15 @@ class UpdateManagerUpdate extends FormBase {
unset($entry['#weight']);
$attributes = $entry['#attributes'];
unset($entry['#attributes']);
$entry = array(
$entry = [
'data' => $entry,
) + $attributes;
] + $attributes;
}
else {
$form['project_downloads'][$name] = array(
$form['project_downloads'][$name] = [
'#type' => 'value',
'#value' => $recommended_release['download_link'],
);
];
}
// Based on what kind of project this is, save the entry into the
@@ -230,62 +230,62 @@ class UpdateManagerUpdate extends FormBase {
}
if (empty($projects)) {
$form['message'] = array(
$form['message'] = [
'#markup' => $this->t('All of your projects are up to date.'),
);
];
return $form;
}
$headers = array(
'title' => array(
$headers = [
'title' => [
'data' => $this->t('Name'),
'class' => array('update-project-name'),
),
'class' => ['update-project-name'],
],
'installed_version' => $this->t('Installed version'),
'recommended_version' => $this->t('Recommended version'),
);
];
if (!empty($projects['enabled'])) {
$form['projects'] = array(
$form['projects'] = [
'#type' => 'tableselect',
'#header' => $headers,
'#options' => $projects['enabled'],
);
];
if (!empty($projects['disabled'])) {
$form['projects']['#prefix'] = '<h2>' . $this->t('Enabled') . '</h2>';
}
}
if (!empty($projects['disabled'])) {
$form['disabled_projects'] = array(
$form['disabled_projects'] = [
'#type' => 'tableselect',
'#header' => $headers,
'#options' => $projects['disabled'],
'#weight' => 1,
'#prefix' => '<h2>' . $this->t('Disabled') . '</h2>',
);
];
}
// If either table has been printed yet, we need a submit button and to
// validate the checkboxes.
if (!empty($projects['enabled']) || !empty($projects['disabled'])) {
$form['actions'] = array('#type' => 'actions');
$form['actions']['submit'] = array(
$form['actions'] = ['#type' => 'actions'];
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Download these updates'),
);
];
}
if (!empty($projects['manual'])) {
$prefix = '<h2>' . $this->t('Manual updates required') . '</h2>';
$prefix .= '<p>' . $this->t('Updates of Drupal core are not supported at this time.') . '</p>';
$form['manual_updates'] = array(
$form['manual_updates'] = [
'#type' => 'table',
'#header' => $headers,
'#rows' => $projects['manual'],
'#prefix' => $prefix,
'#weight' => 120,
);
];
}
return $form;
@@ -311,29 +311,29 @@ class UpdateManagerUpdate extends FormBase {
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->moduleHandler->loadInclude('update', 'inc', 'update.manager');
$projects = array();
foreach (array('projects', 'disabled_projects') as $type) {
$projects = [];
foreach (['projects', 'disabled_projects'] as $type) {
if (!$form_state->isValueEmpty($type)) {
$projects = array_merge($projects, array_keys(array_filter($form_state->getValue($type))));
}
}
$operations = array();
$operations = [];
foreach ($projects as $project) {
$operations[] = array(
$operations[] = [
'update_manager_batch_project_get',
array(
[
$project,
$form_state->getValue(array('project_downloads', $project)),
),
);
$form_state->getValue(['project_downloads', $project]),
],
];
}
$batch = array(
$batch = [
'title' => $this->t('Downloading updates'),
'init_message' => $this->t('Preparing to download selected updates'),
'operations' => $operations,
'finished' => 'update_manager_download_batch_finished',
'file' => drupal_get_path('module', 'update') . '/update.manager.inc',
);
];
batch_set($batch);
}
+13 -13
View File
@@ -42,7 +42,7 @@ class UpdateReady extends FormBase {
*
* @var string
*/
protected $sitePath;
protected $sitePath;
/**
* Constructs a new UpdateReady object.
@@ -91,23 +91,23 @@ class UpdateReady extends FormBase {
return $form;
}
$form['backup'] = array(
$form['backup'] = [
'#prefix' => '<strong>',
'#markup' => $this->t('Back up your database and site before you continue. <a href=":backup_url">Learn how</a>.', array(':backup_url' => 'https://www.drupal.org/node/22281')),
'#markup' => $this->t('Back up your database and site before you continue. <a href=":backup_url">Learn how</a>.', [':backup_url' => 'https://www.drupal.org/node/22281']),
'#suffix' => '</strong>',
);
];
$form['maintenance_mode'] = array(
$form['maintenance_mode'] = [
'#title' => $this->t('Perform updates with site in maintenance mode (strongly recommended)'),
'#type' => 'checkbox',
'#default_value' => TRUE,
);
];
$form['actions'] = array('#type' => 'actions');
$form['actions']['submit'] = array(
$form['actions'] = ['#type' => 'actions'];
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Continue'),
);
];
return $form;
}
@@ -126,7 +126,7 @@ class UpdateReady extends FormBase {
// Make sure the Updater registry is loaded.
drupal_get_updaters();
$updates = array();
$updates = [];
$directory = _update_manager_extract_directory();
$projects = $_SESSION['update_manager_update_projects'];
@@ -137,11 +137,11 @@ class UpdateReady extends FormBase {
$project_location = $directory . '/' . $project;
$updater = Updater::factory($project_location, $this->root);
$project_real_location = drupal_realpath($project_location);
$updates[] = array(
$updates[] = [
'project' => $project,
'updater_name' => get_class($updater),
'local_url' => $project_real_location,
);
];
}
// If the owner of the last directory we extracted is the same as the
@@ -164,7 +164,7 @@ class UpdateReady extends FormBase {
// The page title must be passed here to ensure it is initially used
// when authorize.php loads for the first time with the FTP/SSH
// credentials form.
system_authorized_init('update_authorize_run_update', __DIR__ . '/../../update.authorize.inc', array($updates), $this->t('Update manager'));
system_authorized_init('update_authorize_run_update', __DIR__ . '/../../update.authorize.inc', [$updates], $this->t('Update manager'));
$form_state->setRedirectUrl(system_authorized_get_url());
}
}
@@ -2,6 +2,8 @@
namespace Drupal\update\Tests;
@trigger_error(__NAMESPACE__ . '\UpdateTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\update\Functional\UpdateTestBase', E_USER_DEPRECATED);
use Drupal\Core\DrupalKernel;
use Drupal\Core\Url;
use Drupal\simpletest\WebTestBase;
@@ -22,6 +24,9 @@ use Drupal\simpletest\WebTestBase;
* (via the 'update_test_xml_map' variable), and then performs a series of
* assertions that the report matches our expectations given the specific
* initial state and availability scenario.
*
* @deprecated Scheduled for removal in Drupal 9.0.0.
* Use \Drupal\Tests\update\Functional\UpdateTestBase instead.
*/
abstract class UpdateTestBase extends WebTestBase {
@@ -58,12 +63,12 @@ abstract class UpdateTestBase extends WebTestBase {
* (optional) A string containing the URL to fetch update data from.
* Defaults to 'update-test'.
*
* @see Drupal\update_test\Controller\UpdateTestController::updateTest()
* @see \Drupal\update_test\Controller\UpdateTestController::updateTest()
*/
protected function refreshUpdateStatus($xml_map, $url = 'update-test') {
// Tell the Update Manager module to fetch from the URL provided by
// update_test module.
$this->config('update.settings')->set('fetch.url', Url::fromUri('base:' . $url, array('absolute' => TRUE))->toString())->save();
$this->config('update.settings')->set('fetch.url', Url::fromUri('base:' . $url, ['absolute' => TRUE])->toString())->save();
// Save the map for UpdateTestController::updateTest() to use.
$this->config('update_test.settings')->set('xml_map', $xml_map)->save();
// Manually check the update status.
+1 -1
View File
@@ -62,7 +62,7 @@ class UpdateFetcher implements UpdateFetcherInterface {
$data = '';
try {
$data = (string) $this->httpClient
->get($url, array('headers' => array('Accept' => 'text/xml')))
->get($url, ['headers' => ['Accept' => 'text/xml']])
->getBody();
}
catch (RequestException $exception) {
@@ -7,6 +7,26 @@ namespace Drupal\update;
*/
interface UpdateFetcherInterface {
/**
* Project's status cannot be checked.
*/
const NOT_CHECKED = -1;
/**
* No available update data was found for project.
*/
const UNKNOWN = -2;
/**
* There was a failure fetching available update data for this project.
*/
const NOT_FETCHED = -3;
/**
* We need to (re)fetch available update data for this project.
*/
const FETCH_PENDING = -4;
/**
* Returns the base of the URL to fetch available update data for a project.
*
+7 -7
View File
@@ -91,7 +91,7 @@ class UpdateManager implements UpdateManagerInterface {
$this->keyValueStore = $key_value_expirable_factory->get('update');
$this->themeHandler = $theme_handler;
$this->availableReleasesTempStore = $key_value_expirable_factory->get('update_available_releases');
$this->projects = array();
$this->projects = [];
}
/**
@@ -151,11 +151,11 @@ class UpdateManager implements UpdateManagerInterface {
* {@inheritdoc}
*/
public function projectStorage($key) {
$projects = array();
$projects = [];
// On certain paths, we should clear the data and recompute the projects for
// update status of the site to avoid presenting stale information.
$route_names = array(
$route_names = [
'update.theme_update',
'system.modules_list',
'system.theme_install',
@@ -169,12 +169,12 @@ class UpdateManager implements UpdateManagerInterface {
'update.manual_status',
'update.confirmation_page',
'system.themes_page',
);
];
if (in_array(\Drupal::routeMatch()->getRouteName(), $route_names)) {
$this->keyValueStore->delete($key);
}
else {
$projects = $this->keyValueStore->get($key, array());
$projects = $this->keyValueStore->get($key, []);
}
return $projects;
}
@@ -198,10 +198,10 @@ class UpdateManager implements UpdateManagerInterface {
if ($item = $this->updateProcessor->claimQueueItem()) {
if ($this->updateProcessor->processFetchTask($item->data)) {
$context['results']['updated']++;
$context['message'] = $this->t('Checked available update data for %title.', array('%title' => $item->data['info']['name']));
$context['message'] = $this->t('Checked available update data for %title.', ['%title' => $item->data['info']['name']]);
}
else {
$context['message'] = $this->t('Failed to check available update data for %title.', array('%title' => $item->data['info']['name']));
$context['message'] = $this->t('Failed to check available update data for %title.', ['%title' => $item->data['info']['name']]);
$context['results']['failures']++;
}
$context['sandbox']['progress']++;
@@ -7,6 +7,31 @@ namespace Drupal\update;
*/
interface UpdateManagerInterface {
/**
* Project is missing security update(s).
*/
const NOT_SECURE = 1;
/**
* Current release has been unpublished and is no longer available.
*/
const REVOKED = 2;
/**
* Current release is no longer supported by the project maintainer.
*/
const NOT_SUPPORTED = 3;
/**
* Project has a new release available, but it is not a security release.
*/
const NOT_CURRENT = 4;
/**
* Project is up to date.
*/
const CURRENT = 5;
/**
* Fetches an array of installed and enabled projects.
*
+8 -8
View File
@@ -104,8 +104,8 @@ class UpdateProcessor implements UpdateProcessorInterface {
$this->availableReleasesTempStore = $key_value_expirable_factory->get('update_available_releases');
$this->stateStore = $state_store;
$this->privateKey = $private_key;
$this->fetchTasks = array();
$this->failed = array();
$this->fetchTasks = [];
$this->failed = [];
}
/**
@@ -151,7 +151,7 @@ class UpdateProcessor implements UpdateProcessorInterface {
$max_fetch_attempts = $this->updateSettings->get('fetch.max_attempts');
$success = FALSE;
$available = array();
$available = [];
$site_key = Crypt::hmacBase64($base_url, $this->privateKey->get());
$fetch_url_base = $this->updateFetcher->getFetchBaseUrl($project);
$project_name = $project['name'];
@@ -219,23 +219,23 @@ class UpdateProcessor implements UpdateProcessorInterface {
if (!isset($xml->short_name)) {
return NULL;
}
$data = array();
$data = [];
foreach ($xml as $k => $v) {
$data[$k] = (string) $v;
}
$data['releases'] = array();
$data['releases'] = [];
if (isset($xml->releases)) {
foreach ($xml->releases->children() as $release) {
$version = (string) $release->version;
$data['releases'][$version] = array();
$data['releases'][$version] = [];
foreach ($release->children() as $k => $v) {
$data['releases'][$version][$k] = (string) $v;
}
$data['releases'][$version]['terms'] = array();
$data['releases'][$version]['terms'] = [];
if ($release->terms) {
foreach ($release->terms->children() as $term) {
if (!isset($data['releases'][$version]['terms'][(string) $term->name])) {
$data['releases'][$version]['terms'][(string) $term->name] = array();
$data['releases'][$version]['terms'][(string) $term->name] = [];
}
$data['releases'][$version]['terms'][(string) $term->name][] = (string) $term->value;
}
+18 -18
View File
@@ -59,42 +59,42 @@ class UpdateSettingsForm extends ConfigFormBase implements ContainerInjectionInt
public function buildForm(array $form, FormStateInterface $form_state) {
$config = $this->config('update.settings');
$form['update_check_frequency'] = array(
$form['update_check_frequency'] = [
'#type' => 'radios',
'#title' => t('Check for updates'),
'#default_value' => $config->get('check.interval_days'),
'#options' => array(
'#options' => [
'1' => t('Daily'),
'7' => t('Weekly'),
),
],
'#description' => t('Select how frequently you want to automatically check for new releases of your currently installed modules and themes.'),
);
];
$form['update_check_disabled'] = array(
$form['update_check_disabled'] = [
'#type' => 'checkbox',
'#title' => t('Check for updates of uninstalled modules and themes'),
'#default_value' => $config->get('check.disabled_extensions'),
);
];
$notification_emails = $config->get('notification.emails');
$form['update_notify_emails'] = array(
$form['update_notify_emails'] = [
'#type' => 'textarea',
'#title' => t('Email addresses to notify when updates are available'),
'#rows' => 4,
'#default_value' => implode("\n", $notification_emails),
'#description' => t('Whenever your site checks for available updates and finds new releases, it can notify a list of users via email. Put each address on a separate line. If blank, no emails will be sent.'),
);
];
$form['update_notification_threshold'] = array(
$form['update_notification_threshold'] = [
'#type' => 'radios',
'#title' => t('Email notification threshold'),
'#default_value' => $config->get('notification.threshold'),
'#options' => array(
'#options' => [
'all' => t('All newer versions'),
'security' => t('Only security updates'),
),
'#description' => t('You can choose to send email only if a security update is available, or to be notified about all newer versions. If there are updates available of Drupal core or any of your installed modules and themes, your site will always print a message on the <a href=":status_report">status report</a> page, and will also display an error message on administration pages if there is a security update.', array(':status_report' => $this->url('system.status')))
);
],
'#description' => t('You can choose to send email only if a security update is available, or to be notified about all newer versions. If there are updates available of Drupal core or any of your installed modules and themes, your site will always print a message on the <a href=":status_report">status report</a> page, and will also display an error message on administration pages if there is a security update.', [':status_report' => $this->url('system.status')])
];
return parent::buildForm($form, $form_state);
}
@@ -105,8 +105,8 @@ class UpdateSettingsForm extends ConfigFormBase implements ContainerInjectionInt
public function validateForm(array &$form, FormStateInterface $form_state) {
$form_state->set('notify_emails', []);
if (!$form_state->isValueEmpty('update_notify_emails')) {
$valid = array();
$invalid = array();
$valid = [];
$invalid = [];
foreach (explode("\n", trim($form_state->getValue('update_notify_emails'))) as $email) {
$email = trim($email);
if (!empty($email)) {
@@ -122,10 +122,10 @@ class UpdateSettingsForm extends ConfigFormBase implements ContainerInjectionInt
$form_state->set('notify_emails', $valid);
}
elseif (count($invalid) == 1) {
$form_state->setErrorByName('update_notify_emails', $this->t('%email is not a valid email address.', array('%email' => reset($invalid))));
$form_state->setErrorByName('update_notify_emails', $this->t('%email is not a valid email address.', ['%email' => reset($invalid)]));
}
else {
$form_state->setErrorByName('update_notify_emails', $this->t('%emails are not valid email addresses.', array('%emails' => implode(', ', $invalid))));
$form_state->setErrorByName('update_notify_emails', $this->t('%emails are not valid email addresses.', ['%emails' => implode(', ', $invalid)]));
}
}
@@ -137,7 +137,7 @@ class UpdateSettingsForm extends ConfigFormBase implements ContainerInjectionInt
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$config = $this->config('update.settings');
// See if the update_check_disabled setting is being changed, and if so,
// See if the update_check_disabled setting is being changed, and if so,
// invalidate all update status data.
if ($form_state->getValue('update_check_disabled') != $config->get('check.disabled_extensions')) {
update_storage_clear();
@@ -5,8 +5,8 @@ package: Testing
# version: VERSION
# core: 8.x
# Information added by Drupal.org packaging script on 2016-08-03
version: '8.1.8'
# Information added by Drupal.org packaging script on 2017-08-16
version: '8.3.7'
core: '8.x'
project: 'drupal'
datestamp: 1470233790
datestamp: 1502903957
@@ -5,8 +5,8 @@ package: Testing
# version: VERSION
# core: 8.x
# Information added by Drupal.org packaging script on 2016-08-03
version: '8.1.8'
# Information added by Drupal.org packaging script on 2017-08-16
version: '8.3.7'
core: '8.x'
project: 'drupal'
datestamp: 1470233790
datestamp: 1502903957
@@ -5,8 +5,8 @@ package: Testing
# version: VERSION
# core: 8.x
# Information added by Drupal.org packaging script on 2016-08-03
version: '8.1.8'
# Information added by Drupal.org packaging script on 2017-08-16
version: '8.3.7'
core: '8.x'
project: 'drupal'
datestamp: 1470233790
datestamp: 1502903957
@@ -5,8 +5,8 @@ package: Testing
# version: VERSION
# core: 8.x
# Information added by Drupal.org packaging script on 2016-08-03
version: '8.1.8'
# Information added by Drupal.org packaging script on 2017-08-16
version: '8.3.7'
core: '8.x'
project: 'drupal'
datestamp: 1470233790
datestamp: 1502903957
@@ -64,7 +64,7 @@ class UpdateTestController extends ControllerBase {
}
$file = __DIR__ . "/../../$project_name.$availability_scenario.xml";
$headers = array('Content-Type' => 'text/xml; charset=utf-8');
$headers = ['Content-Type' => 'text/xml; charset=utf-8'];
if (!is_file($file)) {
// Return an empty response.
return new Response('', 200, $headers);
@@ -32,7 +32,7 @@ class UpdateTestArchiver implements ArchiverInterface {
/**
* {@inheritdoc}
*/
public function extract($path, array $files = array()) {
public function extract($path, array $files = []) {
return $this;
}
@@ -40,7 +40,7 @@ class UpdateTestArchiver implements ArchiverInterface {
* {@inheritdoc}
*/
public function listContents() {
return array();
return [];
}
}
@@ -29,11 +29,11 @@ class TestFileTransferWithSettingsForm extends Local {
* Returns a settings form with a text field to input a username.
*/
public function getSettingsForm() {
$form = array();
$form['update_test_username'] = array(
$form = [];
$form['update_test_username'] = [
'#type' => 'textfield',
'#title' => t('Update Test Username'),
);
];
return $form;
}
@@ -5,8 +5,8 @@ package: Testing
# version: VERSION
# core: 8.x
# Information added by Drupal.org packaging script on 2016-08-03
version: '8.1.8'
# Information added by Drupal.org packaging script on 2017-08-16
version: '8.3.7'
core: '8.x'
project: 'drupal'
datestamp: 1470233790
datestamp: 1502903957
@@ -20,7 +20,7 @@ use Drupal\Core\Extension\Extension;
*/
function update_test_system_info_alter(&$info, Extension $file) {
$setting = \Drupal::config('update_test.settings')->get('system_info');
foreach (array('#all', $file->getName()) as $id) {
foreach (['#all', $file->getName()] as $id) {
if (!empty($setting[$id])) {
foreach ($setting[$id] as $key => $value) {
$info[$key] = $value;
@@ -44,7 +44,7 @@ function update_test_update_status_alter(&$projects) {
$setting = \Drupal::config('update_test.settings')->get('update_status');
if (!empty($setting)) {
foreach ($projects as $project_name => &$project) {
foreach (array('#all', $project_name) as $id) {
foreach (['#all', $project_name] as $id) {
if (!empty($setting[$id])) {
foreach ($setting[$id] as $key => $value) {
$project[$key] = $value;
@@ -62,11 +62,11 @@ function update_test_filetransfer_info() {
// Define a test file transfer method, to ensure that there will always be at
// least one method available in the user interface (regardless of the
// environment in which the update manager tests are run).
return array(
'system_test' => array(
return [
'system_test' => [
'title' => t('Update Test FileTransfer'),
'class' => 'Drupal\update_test\TestFileTransferWithSettingsForm',
'weight' => -20,
),
);
],
];
}
@@ -0,0 +1,58 @@
<?php
namespace Drupal\Tests\update\Functional;
/**
* Tests the Update Manager module upload via authorize.php functionality.
*
* @group update
*/
class FileTransferAuthorizeFormTest extends UpdateTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['update', 'update_test'];
protected function setUp() {
parent::setUp();
$admin_user = $this->drupalCreateUser(['administer modules', 'administer software updates', 'administer site configuration']);
$this->drupalLogin($admin_user);
// Create a local cache so the module is not downloaded from drupal.org.
$cache_directory = _update_manager_cache_directory(TRUE);
$validArchiveFile = __DIR__ . '/../../update_test_new_module/8.x-1.0/update_test_new_module.tar.gz';
copy($validArchiveFile, $cache_directory . '/update_test_new_module.tar.gz');
}
/**
* Tests the Update Manager module upload via authorize.php functionality.
*/
public function testViaAuthorize() {
// Ensure the that we can select which file transfer backend to use.
\Drupal::state()->set('test_uploaders_via_prompt', TRUE);
// Ensure the module does not already exist.
$this->drupalGet('admin/modules');
$this->assertNoText('Update test new module');
$edit = [
// This project has been cached in the test's setUp() method.
'project_url' => 'https://ftp.drupal.org/files/projects/update_test_new_module.tar.gz',
];
$this->drupalPostForm('admin/modules/install', $edit, t('Install'));
$edit = [
'connection_settings[authorize_filetransfer_default]' => 'system_test',
'connection_settings[system_test][update_test_username]' => $this->randomMachineName(),
];
$this->drupalPostForm(NULL, $edit, t('Continue'));
$this->assertText(t('Installation was completed successfully.'));
// Ensure the module is available to install.
$this->drupalGet('admin/modules');
$this->assertText('Update test new module');
}
}
@@ -0,0 +1,441 @@
<?php
namespace Drupal\Tests\update\Functional;
use Drupal\Core\Url;
use Drupal\Core\Utility\ProjectInfo;
/**
* Tests how the Update Manager module handles contributed modules and themes in
* a series of functional tests using mock XML data.
*
* @group update
*/
class UpdateContribTest extends UpdateTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['update_test', 'update', 'aaa_update_test', 'bbb_update_test', 'ccc_update_test'];
protected function setUp() {
parent::setUp();
$admin_user = $this->drupalCreateUser(['administer site configuration']);
$this->drupalLogin($admin_user);
}
/**
* Tests when there is no available release data for a contrib module.
*/
public function testNoReleasesAvailable() {
$system_info = [
'#all' => [
'version' => '8.0.0',
],
'aaa_update_test' => [
'project' => 'aaa_update_test',
'version' => '8.x-1.0',
'hidden' => FALSE,
],
];
$this->config('update_test.settings')->set('system_info', $system_info)->save();
$this->refreshUpdateStatus(['drupal' => '0.0', 'aaa_update_test' => 'no-releases']);
$this->drupalGet('admin/reports/updates');
// Cannot use $this->standardTests() because we need to check for the
// 'No available releases found' string.
$this->assertRaw('<h3>' . t('Drupal core') . '</h3>');
$this->assertRaw(\Drupal::l(t('Drupal'), Url::fromUri('http://example.com/project/drupal')));
$this->assertText(t('Up to date'));
$this->assertRaw('<h3>' . t('Modules') . '</h3>');
$this->assertNoText(t('Update available'));
$this->assertText(t('No available releases found'));
$this->assertNoRaw(\Drupal::l(t('AAA Update test'), Url::fromUri('http://example.com/project/aaa_update_test')));
$available = update_get_available();
$this->assertFalse(isset($available['aaa_update_test']['fetch_status']), 'Results are cached even if no releases are available.');
}
/**
* Tests the basic functionality of a contrib module on the status report.
*/
public function testUpdateContribBasic() {
$project_link = \Drupal::l(t('AAA Update test'), Url::fromUri('http://example.com/project/aaa_update_test'));
$system_info = [
'#all' => [
'version' => '8.0.0',
],
'aaa_update_test' => [
'project' => 'aaa_update_test',
'version' => '8.x-1.0',
'hidden' => FALSE,
],
];
$this->config('update_test.settings')->set('system_info', $system_info)->save();
$this->refreshUpdateStatus(
[
'drupal' => '0.0',
'aaa_update_test' => '1_0',
]
);
$this->standardTests();
$this->assertText(t('Up to date'));
$this->assertRaw('<h3>' . t('Modules') . '</h3>');
$this->assertNoText(t('Update available'));
$this->assertRaw($project_link, 'Link to aaa_update_test project appears.');
// Since aaa_update_test is installed the fact it is hidden and in the
// Testing package means it should not appear.
$system_info['aaa_update_test']['hidden'] = TRUE;
$this->config('update_test.settings')->set('system_info', $system_info)->save();
$this->refreshUpdateStatus(
[
'drupal' => '0.0',
'aaa_update_test' => '1_0',
]
);
$this->assertNoRaw($project_link, 'Link to aaa_update_test project does not appear.');
// A hidden and installed project not in the Testing package should appear.
$system_info['aaa_update_test']['package'] = 'aaa_update_test';
$this->config('update_test.settings')->set('system_info', $system_info)->save();
$this->refreshUpdateStatus(
[
'drupal' => '0.0',
'aaa_update_test' => '1_0',
]
);
$this->assertRaw($project_link, 'Link to aaa_update_test project appears.');
}
/**
* Tests that contrib projects are ordered by project name.
*
* If a project contains multiple modules, we want to make sure that the
* available updates report is sorted by the parent project names, not by the
* names of the modules included in each project. In this test case, we have
* two contrib projects, "BBB Update test" and "CCC Update test". However, we
* have a module called "aaa_update_test" that's part of the "CCC Update test"
* project. We need to make sure that we see the "BBB" project before the
* "CCC" project, even though "CCC" includes a module that's processed first
* if you sort alphabetically by module name (which is the order we see things
* inside system_rebuild_module_data() for example).
*/
public function testUpdateContribOrder() {
// We want core to be version 8.0.0.
$system_info = [
'#all' => [
'version' => '8.0.0',
],
// All the rest should be visible as contrib modules at version 8.x-1.0.
// aaa_update_test needs to be part of the "CCC Update test" project,
// which would throw off the report if we weren't properly sorting by
// the project names.
'aaa_update_test' => [
'project' => 'ccc_update_test',
'version' => '8.x-1.0',
'hidden' => FALSE,
],
// This should be its own project, and listed first on the report.
'bbb_update_test' => [
'project' => 'bbb_update_test',
'version' => '8.x-1.0',
'hidden' => FALSE,
],
// This will contain both aaa_update_test and ccc_update_test, and
// should come after the bbb_update_test project.
'ccc_update_test' => [
'project' => 'ccc_update_test',
'version' => '8.x-1.0',
'hidden' => FALSE,
],
];
$this->config('update_test.settings')->set('system_info', $system_info)->save();
$this->refreshUpdateStatus(['drupal' => '0.0', '#all' => '1_0']);
$this->standardTests();
// We're expecting the report to say all projects are up to date.
$this->assertText(t('Up to date'));
$this->assertNoText(t('Update available'));
// We want to see all 3 module names listed, since they'll show up either
// as project names or as modules under the "Includes" listing.
$this->assertText(t('AAA Update test'));
$this->assertText(t('BBB Update test'));
$this->assertText(t('CCC Update test'));
// We want aaa_update_test included in the ccc_update_test project, not as
// its own project on the report.
$this->assertNoRaw(\Drupal::l(t('AAA Update test'), Url::fromUri('http://example.com/project/aaa_update_test')), 'Link to aaa_update_test project does not appear.');
// The other two should be listed as projects.
$this->assertRaw(\Drupal::l(t('BBB Update test'), Url::fromUri('http://example.com/project/bbb_update_test')), 'Link to bbb_update_test project appears.');
$this->assertRaw(\Drupal::l(t('CCC Update test'), Url::fromUri('http://example.com/project/ccc_update_test')), 'Link to bbb_update_test project appears.');
// We want to make sure we see the BBB project before the CCC project.
// Instead of just searching for 'BBB Update test' or something, we want
// to use the full markup that starts the project entry itself, so that
// we're really testing that the project listings are in the right order.
$bbb_project_link = '<div class="project-update__title"><a href="http://example.com/project/bbb_update_test">BBB Update test</a>';
$ccc_project_link = '<div class="project-update__title"><a href="http://example.com/project/ccc_update_test">CCC Update test</a>';
$this->assertTrue(strpos($this->getRawContent(), $bbb_project_link) < strpos($this->getRawContent(), $ccc_project_link), "'BBB Update test' project is listed before the 'CCC Update test' project");
}
/**
* Tests that subthemes are notified about security updates for base themes.
*/
public function testUpdateBaseThemeSecurityUpdate() {
// @todo https://www.drupal.org/node/2338175 base themes have to be
// installed.
// Only install the subtheme, not the base theme.
\Drupal::service('theme_handler')->install(['update_test_subtheme']);
// Define the initial state for core and the subtheme.
$system_info = [
// We want core to be version 8.0.0.
'#all' => [
'version' => '8.0.0',
],
// Show the update_test_basetheme
'update_test_basetheme' => [
'project' => 'update_test_basetheme',
'version' => '8.x-1.0',
'hidden' => FALSE,
],
// Show the update_test_subtheme
'update_test_subtheme' => [
'project' => 'update_test_subtheme',
'version' => '8.x-1.0',
'hidden' => FALSE,
],
];
$this->config('update_test.settings')->set('system_info', $system_info)->save();
$xml_mapping = [
'drupal' => '0.0',
'update_test_subtheme' => '1_0',
'update_test_basetheme' => '1_1-sec',
];
$this->refreshUpdateStatus($xml_mapping);
$this->assertText(t('Security update required!'));
$this->assertRaw(\Drupal::l(t('Update test base theme'), Url::fromUri('http://example.com/project/update_test_basetheme')), 'Link to the Update test base theme project appears.');
}
/**
* Tests that disabled themes are only shown when desired.
*
* @todo https://www.drupal.org/node/2338175 extensions can not be hidden and
* base themes have to be installed.
*/
public function testUpdateShowDisabledThemes() {
$update_settings = $this->config('update.settings');
// Make sure all the update_test_* themes are disabled.
$extension_config = $this->config('core.extension');
foreach ($extension_config->get('theme') as $theme => $weight) {
if (preg_match('/^update_test_/', $theme)) {
$extension_config->clear("theme.$theme");
}
}
$extension_config->save();
// Define the initial state for core and the test contrib themes.
$system_info = [
// We want core to be version 8.0.0.
'#all' => [
'version' => '8.0.0',
],
// The update_test_basetheme should be visible and up to date.
'update_test_basetheme' => [
'project' => 'update_test_basetheme',
'version' => '8.x-1.1',
'hidden' => FALSE,
],
// The update_test_subtheme should be visible and up to date.
'update_test_subtheme' => [
'project' => 'update_test_subtheme',
'version' => '8.x-1.0',
'hidden' => FALSE,
],
];
// When there are contributed modules in the site's file system, the
// total number of attempts made in the test may exceed the default value
// of update_max_fetch_attempts. Therefore this variable is set very high
// to avoid test failures in those cases.
$update_settings->set('fetch.max_attempts', 99999)->save();
$this->config('update_test.settings')->set('system_info', $system_info)->save();
$xml_mapping = [
'drupal' => '0.0',
'update_test_subtheme' => '1_0',
'update_test_basetheme' => '1_1-sec',
];
$base_theme_project_link = \Drupal::l(t('Update test base theme'), Url::fromUri('http://example.com/project/update_test_basetheme'));
$sub_theme_project_link = \Drupal::l(t('Update test subtheme'), Url::fromUri('http://example.com/project/update_test_subtheme'));
foreach ([TRUE, FALSE] as $check_disabled) {
$update_settings->set('check.disabled_extensions', $check_disabled)->save();
$this->refreshUpdateStatus($xml_mapping);
// In neither case should we see the "Themes" heading for installed
// themes.
$this->assertNoText(t('Themes'));
if ($check_disabled) {
$this->assertText(t('Uninstalled themes'));
$this->assertRaw($base_theme_project_link, 'Link to the Update test base theme project appears.');
$this->assertRaw($sub_theme_project_link, 'Link to the Update test subtheme project appears.');
}
else {
$this->assertNoText(t('Uninstalled themes'));
$this->assertNoRaw($base_theme_project_link, 'Link to the Update test base theme project does not appear.');
$this->assertNoRaw($sub_theme_project_link, 'Link to the Update test subtheme project does not appear.');
}
}
}
/**
* Tests updates with a hidden base theme.
*/
public function testUpdateHiddenBaseTheme() {
module_load_include('compare.inc', 'update');
// Install the subtheme.
\Drupal::service('theme_handler')->install(['update_test_subtheme']);
// Add a project and initial state for base theme and subtheme.
$system_info = [
// Hide the update_test_basetheme.
'update_test_basetheme' => [
'project' => 'update_test_basetheme',
'hidden' => TRUE,
],
// Show the update_test_subtheme.
'update_test_subtheme' => [
'project' => 'update_test_subtheme',
'hidden' => FALSE,
],
];
$this->config('update_test.settings')->set('system_info', $system_info)->save();
$projects = \Drupal::service('update.manager')->getProjects();
$theme_data = \Drupal::service('theme_handler')->rebuildThemeData();
$project_info = new ProjectInfo();
$project_info->processInfoList($projects, $theme_data, 'theme', TRUE);
$this->assertTrue(!empty($projects['update_test_basetheme']), 'Valid base theme (update_test_basetheme) was found.');
}
/**
* Makes sure that if we fetch from a broken URL, sane things happen.
*/
public function testUpdateBrokenFetchURL() {
$system_info = [
'#all' => [
'version' => '8.0.0',
],
'aaa_update_test' => [
'project' => 'aaa_update_test',
'version' => '8.x-1.0',
'hidden' => FALSE,
],
'bbb_update_test' => [
'project' => 'bbb_update_test',
'version' => '8.x-1.0',
'hidden' => FALSE,
],
'ccc_update_test' => [
'project' => 'ccc_update_test',
'version' => '8.x-1.0',
'hidden' => FALSE,
],
];
$this->config('update_test.settings')->set('system_info', $system_info)->save();
// Ensure that the update information is correct before testing.
$this->drupalGet('admin/reports/updates');
$xml_mapping = [
'drupal' => '0.0',
'aaa_update_test' => '1_0',
'bbb_update_test' => 'does-not-exist',
'ccc_update_test' => '1_0',
];
$this->refreshUpdateStatus($xml_mapping);
$this->assertText(t('Up to date'));
// We're expecting the report to say most projects are up to date, so we
// hope that 'Up to date' is not unique.
$this->assertNoUniqueText(t('Up to date'));
// It should say we failed to get data, not that we're missing an update.
$this->assertNoText(t('Update available'));
// We need to check that this string is found as part of a project row, not
// just in the "Failed to get available update data" message at the top of
// the page.
$this->assertRaw('<div class="project-update__status">' . t('Failed to get available update data'));
// We should see the output messages from fetching manually.
$this->assertUniqueText(t('Checked available update data for 3 projects.'));
$this->assertUniqueText(t('Failed to get available update data for one project.'));
// The other two should be listed as projects.
$this->assertRaw(\Drupal::l(t('AAA Update test'), Url::fromUri('http://example.com/project/aaa_update_test')), 'Link to aaa_update_test project appears.');
$this->assertNoRaw(\Drupal::l(t('BBB Update test'), Url::fromUri('http://example.com/project/bbb_update_test')), 'Link to bbb_update_test project does not appear.');
$this->assertRaw(\Drupal::l(t('CCC Update test'), Url::fromUri('http://example.com/project/ccc_update_test')), 'Link to bbb_update_test project appears.');
}
/**
* Checks that hook_update_status_alter() works to change a status.
*
* We provide the same external data as if aaa_update_test 8.x-1.0 were
* installed and that was the latest release. Then we use
* hook_update_status_alter() to try to mark this as missing a security
* update, then assert if we see the appropriate warnings on the right pages.
*/
public function testHookUpdateStatusAlter() {
$update_test_config = $this->config('update_test.settings');
$update_admin_user = $this->drupalCreateUser(['administer site configuration', 'administer software updates']);
$this->drupalLogin($update_admin_user);
$system_info = [
'#all' => [
'version' => '8.0.0',
],
'aaa_update_test' => [
'project' => 'aaa_update_test',
'version' => '8.x-1.0',
'hidden' => FALSE,
],
];
$update_test_config->set('system_info', $system_info)->save();
$update_status = [
'aaa_update_test' => [
'status' => UPDATE_NOT_SECURE,
],
];
$update_test_config->set('update_status', $update_status)->save();
$this->refreshUpdateStatus(
[
'drupal' => '0.0',
'aaa_update_test' => '1_0',
]
);
$this->drupalGet('admin/reports/updates');
$this->assertRaw('<h3>' . t('Modules') . '</h3>');
$this->assertText(t('Security update required!'));
$this->assertRaw(\Drupal::l(t('AAA Update test'), Url::fromUri('http://example.com/project/aaa_update_test')), 'Link to aaa_update_test project appears.');
// Visit the reports page again without the altering and make sure the
// status is back to normal.
$update_test_config->set('update_status', [])->save();
$this->drupalGet('admin/reports/updates');
$this->assertRaw('<h3>' . t('Modules') . '</h3>');
$this->assertNoText(t('Security update required!'));
$this->assertRaw(\Drupal::l(t('AAA Update test'), Url::fromUri('http://example.com/project/aaa_update_test')), 'Link to aaa_update_test project appears.');
// Turn the altering back on and visit the Update manager UI.
$update_test_config->set('update_status', $update_status)->save();
$this->drupalGet('admin/modules/update');
$this->assertText(t('Security update'));
// Turn the altering back off and visit the Update manager UI.
$update_test_config->set('update_status', [])->save();
$this->drupalGet('admin/modules/update');
$this->assertNoText(t('Security update'));
}
}
@@ -0,0 +1,376 @@
<?php
namespace Drupal\Tests\update\Functional;
use Drupal\Core\Url;
use Drupal\Tests\Traits\Core\CronRunTrait;
/**
* Tests the Update Manager module through a series of functional tests using
* mock XML data.
*
* @group update
*/
class UpdateCoreTest extends UpdateTestBase {
use CronRunTrait;
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['update_test', 'update', 'language', 'block'];
protected function setUp() {
parent::setUp();
$admin_user = $this->drupalCreateUser(['administer site configuration', 'administer modules', 'administer themes']);
$this->drupalLogin($admin_user);
$this->drupalPlaceBlock('local_actions_block');
}
/**
* Sets the version to x.x.x when no project-specific mapping is defined.
*
* @param string $version
* The version.
*/
protected function setSystemInfo($version) {
$setting = [
'#all' => [
'version' => $version,
],
];
$this->config('update_test.settings')->set('system_info', $setting)->save();
}
/**
* Tests the Update Manager module when no updates are available.
*/
public function testNoUpdatesAvailable() {
foreach ([0, 1] as $minor_version) {
foreach ([0, 1] as $patch_version) {
foreach (['-alpha1', '-beta1', ''] as $extra_version) {
$this->setSystemInfo("8.$minor_version.$patch_version" . $extra_version);
$this->refreshUpdateStatus(['drupal' => "$minor_version.$patch_version" . $extra_version]);
$this->standardTests();
$this->assertText(t('Up to date'));
$this->assertNoText(t('Update available'));
$this->assertNoText(t('Security update required!'));
$this->assertRaw('check.svg', 'Check icon was found.');
}
}
}
}
/**
* Tests the Update Manager module when one normal update is available.
*/
public function testNormalUpdateAvailable() {
$this->setSystemInfo('8.0.0');
// Ensure that the update check requires a token.
$this->drupalGet('admin/reports/updates/check');
$this->assertResponse(403, 'Accessing admin/reports/updates/check without a CSRF token results in access denied.');
foreach ([0, 1] as $minor_version) {
foreach (['-alpha1', '-beta1', ''] as $extra_version) {
$this->refreshUpdateStatus(['drupal' => "$minor_version.1" . $extra_version]);
$this->standardTests();
$this->drupalGet('admin/reports/updates');
$this->clickLink(t('Check manually'));
$this->checkForMetaRefresh();
$this->assertNoText(t('Security update required!'));
$this->assertRaw(\Drupal::l("8.$minor_version.1" . $extra_version, Url::fromUri("http://example.com/drupal-8-$minor_version-1$extra_version-release")), 'Link to release appears.');
$this->assertRaw(\Drupal::l(t('Download'), Url::fromUri("http://example.com/drupal-8-$minor_version-1$extra_version.tar.gz")), 'Link to download appears.');
$this->assertRaw(\Drupal::l(t('Release notes'), Url::fromUri("http://example.com/drupal-8-$minor_version-1$extra_version-release")), 'Link to release notes appears.');
switch ($minor_version) {
case 0:
// Both stable and unstable releases are available.
// A stable release is the latest.
if ($extra_version == '') {
$this->assertNoText(t('Up to date'));
$this->assertText(t('Update available'));
$this->assertText(t('Recommended version:'));
$this->assertNoText(t('Latest version:'));
$this->assertRaw('warning.svg', 'Warning icon was found.');
}
// Only unstable releases are available.
// An unstable release is the latest.
else {
$this->assertText(t('Up to date'));
$this->assertNoText(t('Update available'));
$this->assertNoText(t('Recommended version:'));
$this->assertText(t('Latest version:'));
$this->assertRaw('check.svg', 'Check icon was found.');
}
break;
case 1:
// Both stable and unstable releases are available.
// A stable release is the latest.
if ($extra_version == '') {
$this->assertNoText(t('Up to date'));
$this->assertText(t('Update available'));
$this->assertText(t('Recommended version:'));
$this->assertNoText(t('Latest version:'));
$this->assertRaw('warning.svg', 'Warning icon was found.');
}
// Both stable and unstable releases are available.
// An unstable release is the latest.
else {
$this->assertNoText(t('Up to date'));
$this->assertText(t('Update available'));
$this->assertText(t('Recommended version:'));
$this->assertText(t('Latest version:'));
$this->assertRaw('warning.svg', 'Warning icon was found.');
}
break;
}
}
}
}
/**
* Tests the Update Manager module when a major update is available.
*/
public function testMajorUpdateAvailable() {
foreach ([0, 1] as $minor_version) {
foreach ([0, 1] as $patch_version) {
foreach (['-alpha1', '-beta1', ''] as $extra_version) {
$this->setSystemInfo("8.$minor_version.$patch_version" . $extra_version);
$this->refreshUpdateStatus(['drupal' => '9']);
$this->standardTests();
$this->drupalGet('admin/reports/updates');
$this->clickLink(t('Check manually'));
$this->checkForMetaRefresh();
$this->assertNoText(t('Security update required!'));
$this->assertRaw(\Drupal::l('9.0.0', Url::fromUri("http://example.com/drupal-9-0-0-release")), 'Link to release appears.');
$this->assertRaw(\Drupal::l(t('Download'), Url::fromUri("http://example.com/drupal-9-0-0.tar.gz")), 'Link to download appears.');
$this->assertRaw(\Drupal::l(t('Release notes'), Url::fromUri("http://example.com/drupal-9-0-0-release")), 'Link to release notes appears.');
$this->assertNoText(t('Up to date'));
$this->assertText(t('Not supported!'));
$this->assertText(t('Recommended version:'));
$this->assertNoText(t('Latest version:'));
$this->assertRaw('error.svg', 'Error icon was found.');
}
}
}
}
/**
* Tests the Update Manager module when a security update is available.
*/
public function testSecurityUpdateAvailable() {
foreach ([0, 1] as $minor_version) {
$this->setSystemInfo("8.$minor_version.0");
$this->refreshUpdateStatus(['drupal' => "$minor_version.2-sec"]);
$this->standardTests();
$this->assertNoText(t('Up to date'));
$this->assertNoText(t('Update available'));
$this->assertText(t('Security update required!'));
$this->assertRaw(\Drupal::l("8.$minor_version.2", Url::fromUri("http://example.com/drupal-8-$minor_version-2-release")), 'Link to release appears.');
$this->assertRaw(\Drupal::l(t('Download'), Url::fromUri("http://example.com/drupal-8-$minor_version-2.tar.gz")), 'Link to download appears.');
$this->assertRaw(\Drupal::l(t('Release notes'), Url::fromUri("http://example.com/drupal-8-$minor_version-2-release")), 'Link to release notes appears.');
$this->assertRaw('error.svg', 'Error icon was found.');
}
}
/**
* Ensures proper results where there are date mismatches among modules.
*/
public function testDatestampMismatch() {
$system_info = [
'#all' => [
// We need to think we're running a -dev snapshot to see dates.
'version' => '8.1.0-dev',
'datestamp' => time(),
],
'block' => [
// This is 2001-09-09 01:46:40 GMT, so test for "2001-Sep-".
'datestamp' => '1000000000',
],
];
$this->config('update_test.settings')->set('system_info', $system_info)->save();
$this->refreshUpdateStatus(['drupal' => 'dev']);
$this->assertNoText(t('2001-Sep-'));
$this->assertText(t('Up to date'));
$this->assertNoText(t('Update available'));
$this->assertNoText(t('Security update required!'));
}
/**
* Checks that running cron updates the list of available updates.
*/
public function testModulePageRunCron() {
$this->setSystemInfo('8.0.0');
$this->config('update.settings')
->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString())
->save();
$this->config('update_test.settings')
->set('xml_map', ['drupal' => '0.0'])
->save();
$this->cronRun();
$this->drupalGet('admin/modules');
$this->assertNoText(t('No update information available.'));
}
/**
* Checks the messages at admin/modules when the site is up to date.
*/
public function testModulePageUpToDate() {
$this->setSystemInfo('8.0.0');
// Instead of using refreshUpdateStatus(), set these manually.
$this->config('update.settings')
->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString())
->save();
$this->config('update_test.settings')
->set('xml_map', ['drupal' => '0.0'])
->save();
$this->drupalGet('admin/reports/updates');
$this->clickLink(t('Check manually'));
$this->checkForMetaRefresh();
$this->assertText(t('Checked available update data for one project.'));
$this->drupalGet('admin/modules');
$this->assertNoText(t('There are updates available for your version of Drupal.'));
$this->assertNoText(t('There is a security update available for your version of Drupal.'));
}
/**
* Checks the messages at admin/modules when an update is missing.
*/
public function testModulePageRegularUpdate() {
$this->setSystemInfo('8.0.0');
// Instead of using refreshUpdateStatus(), set these manually.
$this->config('update.settings')
->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString())
->save();
$this->config('update_test.settings')
->set('xml_map', ['drupal' => '0.1'])
->save();
$this->drupalGet('admin/reports/updates');
$this->clickLink(t('Check manually'));
$this->checkForMetaRefresh();
$this->assertText(t('Checked available update data for one project.'));
$this->drupalGet('admin/modules');
$this->assertText(t('There are updates available for your version of Drupal.'));
$this->assertNoText(t('There is a security update available for your version of Drupal.'));
}
/**
* Checks the messages at admin/modules when a security update is missing.
*/
public function testModulePageSecurityUpdate() {
$this->setSystemInfo('8.0.0');
// Instead of using refreshUpdateStatus(), set these manually.
$this->config('update.settings')
->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString())
->save();
$this->config('update_test.settings')
->set('xml_map', ['drupal' => '0.2-sec'])
->save();
$this->drupalGet('admin/reports/updates');
$this->clickLink(t('Check manually'));
$this->checkForMetaRefresh();
$this->assertText(t('Checked available update data for one project.'));
$this->drupalGet('admin/modules');
$this->assertNoText(t('There are updates available for your version of Drupal.'));
$this->assertText(t('There is a security update available for your version of Drupal.'));
// Make sure admin/appearance warns you you're missing a security update.
$this->drupalGet('admin/appearance');
$this->assertNoText(t('There are updates available for your version of Drupal.'));
$this->assertText(t('There is a security update available for your version of Drupal.'));
// Make sure duplicate messages don't appear on Update status pages.
$this->drupalGet('admin/reports/status');
// We're expecting "There is a security update..." inside the status report
// itself, but the drupal_set_message() appears as an li so we can prefix
// with that and search for the raw HTML.
$this->assertNoRaw('<li>' . t('There is a security update available for your version of Drupal.'));
$this->drupalGet('admin/reports/updates');
$this->assertNoText(t('There is a security update available for your version of Drupal.'));
$this->drupalGet('admin/reports/updates/settings');
$this->assertNoText(t('There is a security update available for your version of Drupal.'));
}
/**
* Tests the Update Manager module when the update server returns 503 errors.
*/
public function testServiceUnavailable() {
$this->refreshUpdateStatus([], '503-error');
// Ensure that no "Warning: SimpleXMLElement..." parse errors are found.
$this->assertNoText('SimpleXMLElement');
$this->assertUniqueText(t('Failed to get available update data for one project.'));
}
/**
* Tests that exactly one fetch task per project is created and not more.
*/
public function testFetchTasks() {
$projecta = [
'name' => 'aaa_update_test',
];
$projectb = [
'name' => 'bbb_update_test',
];
$queue = \Drupal::queue('update_fetch_tasks');
$this->assertEqual($queue->numberOfItems(), 0, 'Queue is empty');
update_create_fetch_task($projecta);
$this->assertEqual($queue->numberOfItems(), 1, 'Queue contains one item');
update_create_fetch_task($projectb);
$this->assertEqual($queue->numberOfItems(), 2, 'Queue contains two items');
// Try to add project a again.
update_create_fetch_task($projecta);
$this->assertEqual($queue->numberOfItems(), 2, 'Queue still contains two items');
// Clear storage and try again.
update_storage_clear();
update_create_fetch_task($projecta);
$this->assertEqual($queue->numberOfItems(), 2, 'Queue contains two items');
}
/**
* Checks language module in core package at admin/reports/updates.
*/
public function testLanguageModuleUpdate() {
$this->setSystemInfo('8.0.0');
// Instead of using refreshUpdateStatus(), set these manually.
$this->config('update.settings')
->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString())
->save();
$this->config('update_test.settings')
->set('xml_map', ['drupal' => '0.1'])
->save();
$this->drupalGet('admin/reports/updates');
$this->assertText(t('Language'));
}
/**
* Ensures that the local actions appear.
*/
public function testLocalActions() {
$admin_user = $this->drupalCreateUser(['administer site configuration', 'administer modules', 'administer software updates', 'administer themes']);
$this->drupalLogin($admin_user);
$this->drupalGet('admin/modules');
$this->clickLink(t('Install new module'));
$this->assertUrl('admin/modules/install');
$this->drupalGet('admin/appearance');
$this->clickLink(t('Install new theme'));
$this->assertUrl('admin/theme/install');
$this->drupalGet('admin/reports/updates');
$this->clickLink(t('Install new module or theme'));
$this->assertUrl('admin/reports/updates/install');
}
}
@@ -0,0 +1,47 @@
<?php
namespace Drupal\Tests\update\Functional;
/**
* Tests the update_delete_file_if_stale() function.
*
* @group update
*/
class UpdateDeleteFileIfStaleTest extends UpdateTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['update'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
}
/**
* Tests the deletion of stale files.
*/
public function testUpdateDeleteFileIfStale() {
$file_name = file_unmanaged_save_data($this->randomMachineName());
$this->assertNotNull($file_name);
// During testing the file change and the stale checking occurs in the same
// request, so the beginning of request will be before the file changes and
// REQUEST_TIME - $filectime is negative. Set the maximum age to a number
// even smaller than that.
$this->config('system.file')
->set('temporary_maximum_age', -100000)
->save();
$file_path = drupal_realpath($file_name);
update_delete_file_if_stale($file_path);
$this->assertFalse(is_file($file_path));
}
}
@@ -0,0 +1,84 @@
<?php
namespace Drupal\Tests\update\Functional;
use Drupal\Core\DrupalKernel;
use Drupal\Core\Url;
use Drupal\Tests\BrowserTestBase;
/**
* Defines some shared functions used by all update tests.
*
* The overarching methodology of these tests is we need to compare a given
* state of installed modules and themes (e.g., version, project grouping,
* timestamps, etc) against a current state of what the release history XML
* files we fetch say is available. We have dummy XML files (in the
* core/modules/update/tests directory) that describe various scenarios of
* what's available for different test projects, and we have dummy .info file
* data (specified via hook_system_info_alter() in the update_test helper
* module) describing what's currently installed. Each test case defines a set
* of projects to install, their current state (via the
* 'update_test_system_info' variable) and the desired available update data
* (via the 'update_test_xml_map' variable), and then performs a series of
* assertions that the report matches our expectations given the specific
* initial state and availability scenario.
*/
abstract class UpdateTestBase extends BrowserTestBase {
protected function setUp() {
parent::setUp();
// Change the root path which Update Manager uses to install and update
// projects to be inside the testing site directory. See
// \Drupal\update\UpdateRootFactory::get() for equivalent changes to the
// test child site.
$request = \Drupal::request();
$update_root = $this->container->get('update.root') . '/' . DrupalKernel::findSitePath($request);
$this->container->set('update.root', $update_root);
\Drupal::setContainer($this->container);
// Create the directories within the root path within which the Update
// Manager will install projects.
foreach (drupal_get_updaters() as $updater_info) {
$updater = $updater_info['class'];
$install_directory = $update_root . '/' . $updater::getRootDirectoryRelativePath();
if (!is_dir($install_directory)) {
mkdir($install_directory);
}
}
}
/**
* Refreshes the update status based on the desired available update scenario.
*
* @param $xml_map
* Array that maps project names to availability scenarios to fetch. The key
* '#all' is used if a project-specific mapping is not defined.
* @param $url
* (optional) A string containing the URL to fetch update data from.
* Defaults to 'update-test'.
*
* @see \Drupal\update_test\Controller\UpdateTestController::updateTest()
*/
protected function refreshUpdateStatus($xml_map, $url = 'update-test') {
// Tell the Update Manager module to fetch from the URL provided by
// update_test module.
$this->config('update.settings')->set('fetch.url', Url::fromUri('base:' . $url, ['absolute' => TRUE])->toString())->save();
// Save the map for UpdateTestController::updateTest() to use.
$this->config('update_test.settings')->set('xml_map', $xml_map)->save();
// Manually check the update status.
$this->drupalGet('admin/reports/updates');
$this->clickLink(t('Check manually'));
$this->checkForMetaRefresh();
}
/**
* Runs a series of assertions that are applicable to all update statuses.
*/
protected function standardTests() {
$this->assertRaw('<h3>' . t('Drupal core') . '</h3>');
$this->assertRaw(\Drupal::l(t('Drupal'), Url::fromUri('http://example.com/project/drupal')), 'Link to the Drupal project appears.');
$this->assertNoText(t('No available releases found'));
}
}
@@ -0,0 +1,200 @@
<?php
namespace Drupal\Tests\update\Functional;
use Drupal\Core\Extension\InfoParserDynamic;
use Drupal\Core\Updater\Updater;
use Drupal\Core\Url;
use Drupal\Tests\TestFileCreationTrait;
/**
* Tests the Update Manager module's upload and extraction functionality.
*
* @group update
*/
class UpdateUploadTest extends UpdateTestBase {
use TestFileCreationTrait {
getTestFiles as drupalGetTestFiles;
}
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['update', 'update_test'];
protected function setUp() {
parent::setUp();
$admin_user = $this->drupalCreateUser(['administer modules', 'administer software updates', 'administer site configuration']);
$this->drupalLogin($admin_user);
}
/**
* Tests upload, extraction, and update of a module.
*/
public function testUploadModule() {
// Ensure that the update information is correct before testing.
update_get_available(TRUE);
// Images are not valid archives, so get one and try to install it. We
// need an extra variable to store the result of drupalGetTestFiles()
// since reset() takes an argument by reference and passing in a constant
// emits a notice in strict mode.
$imageTestFiles = $this->drupalGetTestFiles('image');
$invalidArchiveFile = reset($imageTestFiles);
$edit = [
'files[project_upload]' => $invalidArchiveFile->uri,
];
// This also checks that the correct archive extensions are allowed.
$this->drupalPostForm('admin/modules/install', $edit, t('Install'));
$this->assertText(t('Only files with the following extensions are allowed: @archive_extensions.', ['@archive_extensions' => archiver_get_extensions()]), 'Only valid archives can be uploaded.');
$this->assertUrl('admin/modules/install');
// Check to ensure an existing module can't be reinstalled. Also checks that
// the archive was extracted since we can't know if the module is already
// installed until after extraction.
$validArchiveFile = __DIR__ . '/../../aaa_update_test.tar.gz';
$edit = [
'files[project_upload]' => $validArchiveFile,
];
$this->drupalPostForm('admin/modules/install', $edit, t('Install'));
$this->assertText(t('@module_name is already installed.', ['@module_name' => 'AAA Update test']), 'Existing module was extracted and not reinstalled.');
$this->assertUrl('admin/modules/install');
// Ensure that a new module can be extracted and installed.
$updaters = drupal_get_updaters();
$moduleUpdater = $updaters['module']['class'];
$installedInfoFilePath = $this->container->get('update.root') . '/' . $moduleUpdater::getRootDirectoryRelativePath() . '/update_test_new_module/update_test_new_module.info.yml';
$this->assertFalse(file_exists($installedInfoFilePath), 'The new module does not exist in the filesystem before it is installed with the Update Manager.');
$validArchiveFile = __DIR__ . '/../../update_test_new_module/8.x-1.0/update_test_new_module.tar.gz';
$edit = [
'files[project_upload]' => $validArchiveFile,
];
$this->drupalPostForm('admin/modules/install', $edit, t('Install'));
// Check that submitting the form takes the user to authorize.php.
$this->assertUrl('core/authorize.php');
$this->assertTitle('Update manager | Drupal');
// Check for a success message on the page, and check that the installed
// module now exists in the expected place in the filesystem.
$this->assertRaw(t('Installed %project_name successfully', ['%project_name' => 'update_test_new_module']));
$this->assertTrue(file_exists($installedInfoFilePath), 'The new module exists in the filesystem after it is installed with the Update Manager.');
// Ensure the links are relative to the site root and not
// core/authorize.php.
$this->assertLink(t('Install another module'));
$this->assertLinkByHref(Url::fromRoute('update.module_install')->toString());
$this->assertLink(t('Enable newly added modules'));
$this->assertLinkByHref(Url::fromRoute('system.modules_list')->toString());
$this->assertLink(t('Administration pages'));
$this->assertLinkByHref(Url::fromRoute('system.admin')->toString());
// Ensure we can reach the "Install another module" link.
$this->clickLink(t('Install another module'));
$this->assertResponse(200);
$this->assertUrl('admin/modules/install');
// Check that the module has the correct version before trying to update
// it. Since the module is installed in sites/simpletest, which only the
// child site has access to, standard module API functions won't find it
// when called here. To get the version, the info file must be parsed
// directly instead.
$info_parser = new InfoParserDynamic();
$info = $info_parser->parse($installedInfoFilePath);
$this->assertEqual($info['version'], '8.x-1.0');
// Enable the module.
$this->drupalPostForm('admin/modules', ['modules[update_test_new_module][enable]' => TRUE], t('Install'));
// Define the update XML such that the new module downloaded above needs an
// update from 8.x-1.0 to 8.x-1.1.
$update_test_config = $this->config('update_test.settings');
$system_info = [
'update_test_new_module' => [
'project' => 'update_test_new_module',
],
];
$update_test_config->set('system_info', $system_info)->save();
$xml_mapping = [
'update_test_new_module' => '1_1',
];
$this->refreshUpdateStatus($xml_mapping);
// Run the updates for the new module.
$this->drupalPostForm('admin/reports/updates/update', ['projects[update_test_new_module]' => TRUE], t('Download these updates'));
$this->drupalPostForm(NULL, ['maintenance_mode' => FALSE], t('Continue'));
$this->assertText(t('Update was completed successfully.'));
$this->assertRaw(t('Installed %project_name successfully', ['%project_name' => 'update_test_new_module']));
// Parse the info file again to check that the module has been updated to
// 8.x-1.1.
$info = $info_parser->parse($installedInfoFilePath);
$this->assertEqual($info['version'], '8.x-1.1');
}
/**
* Ensures that archiver extensions are properly merged in the UI.
*/
public function testFileNameExtensionMerging() {
$this->drupalGet('admin/modules/install');
// Make sure the bogus extension supported by update_test.module is there.
$this->assertPattern('/file extensions are supported:.*update-test-extension/', "Found 'update-test-extension' extension.");
// Make sure it didn't clobber the first option from core.
$this->assertPattern('/file extensions are supported:.*tar/', "Found 'tar' extension.");
}
/**
* Checks the messages on update manager pages when missing a security update.
*/
public function testUpdateManagerCoreSecurityUpdateMessages() {
$setting = [
'#all' => [
'version' => '8.0.0',
],
];
$this->config('update_test.settings')
->set('system_info', $setting)
->set('xml_map', ['drupal' => '0.2-sec'])
->save();
$this->config('update.settings')
->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString())
->save();
// Initialize the update status.
$this->drupalGet('admin/reports/updates');
// Now, make sure none of the Update manager pages have duplicate messages
// about core missing a security update.
$this->drupalGet('admin/modules/install');
$this->assertNoText(t('There is a security update available for your version of Drupal.'));
$this->drupalGet('admin/modules/update');
$this->assertNoText(t('There is a security update available for your version of Drupal.'));
$this->drupalGet('admin/appearance/install');
$this->assertNoText(t('There is a security update available for your version of Drupal.'));
$this->drupalGet('admin/appearance/update');
$this->assertNoText(t('There is a security update available for your version of Drupal.'));
$this->drupalGet('admin/reports/updates/install');
$this->assertNoText(t('There is a security update available for your version of Drupal.'));
$this->drupalGet('admin/reports/updates/update');
$this->assertNoText(t('There is a security update available for your version of Drupal.'));
$this->drupalGet('admin/update/ready');
$this->assertNoText(t('There is a security update available for your version of Drupal.'));
}
/**
* Tests only an *.info.yml file are detected without supporting files.
*/
public function testUpdateDirectory() {
$type = Updater::getUpdaterFromDirectory(\Drupal::root() . '/core/modules/update/tests/modules/aaa_update_test');
$this->assertEqual($type, 'Drupal\\Core\\Updater\\Module', 'Detected a Module');
$type = Updater::getUpdaterFromDirectory(\Drupal::root() . '/core/modules/update/tests/themes/update_test_basetheme');
$this->assertEqual($type, 'Drupal\\Core\\Updater\\Theme', 'Detected a Theme.');
}
}
@@ -2,7 +2,7 @@
namespace Drupal\Tests\update\Kernel\Migrate\d6;
use Drupal\config\Tests\SchemaCheckTestTrait;
use Drupal\Tests\SchemaCheckTestTrait;
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
/**
@@ -17,7 +17,7 @@ class MigrateUpdateConfigsTest extends MigrateDrupal6TestBase {
/**
* {@inheritdoc}
*/
public static $modules = array('update');
public static $modules = ['update'];
/**
* {@inheritdoc}
@@ -35,7 +35,7 @@ class MigrateUpdateConfigsTest extends MigrateDrupal6TestBase {
$this->assertIdentical(2, $config->get('fetch.max_attempts'));
$this->assertIdentical('http://updates.drupal.org/release-history', $config->get('fetch.url'));
$this->assertIdentical('all', $config->get('notification.threshold'));
$this->assertIdentical(array(), $config->get('notification.emails'));
$this->assertIdentical([], $config->get('notification.emails'));
$this->assertIdentical(7, $config->get('check.interval_days'));
$this->assertConfigSchema(\Drupal::service('config.typed'), 'update.settings', $config->get());
}
@@ -12,7 +12,7 @@ use Drupal\Tests\Core\Menu\LocalTaskIntegrationTestBase;
class UpdateLocalTasksTest extends LocalTaskIntegrationTestBase {
protected function setUp() {
$this->directoryList = array('update' => 'core/modules/update');
$this->directoryList = ['update' => 'core/modules/update'];
parent::setUp();
}
@@ -22,20 +22,20 @@ class UpdateLocalTasksTest extends LocalTaskIntegrationTestBase {
* @dataProvider getUpdateReportRoutes
*/
public function testUpdateReportLocalTasks($route) {
$this->assertLocalTasks($route, array(
0 => array('update.status', 'update.settings', 'update.report_update'),
));
$this->assertLocalTasks($route, [
0 => ['update.status', 'update.settings', 'update.report_update'],
]);
}
/**
* Provides a list of report routes to test.
*/
public function getUpdateReportRoutes() {
return array(
array('update.status'),
array('update.settings'),
array('update.report_update'),
);
return [
['update.status'],
['update.settings'],
['update.report_update'],
];
}
/**
@@ -44,9 +44,9 @@ class UpdateLocalTasksTest extends LocalTaskIntegrationTestBase {
* @dataProvider getUpdateModuleRoutes
*/
public function testUpdateModuleLocalTasks($route) {
$this->assertLocalTasks($route, array(
0 => array('update.module_update'),
));
$this->assertLocalTasks($route, [
0 => ['update.module_update'],
]);
;
}
@@ -54,9 +54,9 @@ class UpdateLocalTasksTest extends LocalTaskIntegrationTestBase {
* Provides a list of module routes to test.
*/
public function getUpdateModuleRoutes() {
return array(
array('update.module_update'),
);
return [
['update.module_update'],
];
}
/**
@@ -65,9 +65,9 @@ class UpdateLocalTasksTest extends LocalTaskIntegrationTestBase {
* @dataProvider getUpdateThemeRoutes
*/
public function testUpdateThemeLocalTasks($route) {
$this->assertLocalTasks($route, array(
0 => array('update.theme_update'),
));
$this->assertLocalTasks($route, [
0 => ['update.theme_update'],
]);
;
}
@@ -75,9 +75,9 @@ class UpdateLocalTasksTest extends LocalTaskIntegrationTestBase {
* Provides a list of theme routes to test.
*/
public function getUpdateThemeRoutes() {
return array(
array('update.theme_update'),
);
return [
['update.theme_update'],
];
}
}
@@ -27,7 +27,7 @@ class UpdateFetcherTest extends UnitTestCase {
* {@inheritdoc}
*/
protected function setUp() {
$config_factory = $this->getConfigFactoryStub(array('update.settings' => array('fetch_url' => 'http://www.example.com')));
$config_factory = $this->getConfigFactoryStub(['update.settings' => ['fetch_url' => 'http://www.example.com']]);
$http_client_mock = $this->getMock('\GuzzleHttp\ClientInterface');
$this->updateFetcher = new UpdateFetcher($config_factory, $http_client_mock);
}
@@ -62,25 +62,25 @@ class UpdateFetcherTest extends UnitTestCase {
* - 'expected' - The expected url from UpdateFetcher::buildFetchUrl().
*/
public function providerTestUpdateBuildFetchUrl() {
$data = array();
$data = [];
// First test that we didn't break the trivial case.
$project['name'] = 'update_test';
$project['project_type'] = '';
$project['info']['version'] = '';
$project['info']['project status url'] = 'http://www.example.com';
$project['includes'] = array('module1' => 'Module 1', 'module2' => 'Module 2');
$project['includes'] = ['module1' => 'Module 1', 'module2' => 'Module 2'];
$site_key = '';
$expected = 'http://www.example.com/' . $project['name'] . '/' . DRUPAL_CORE_COMPATIBILITY;
$data[] = array($project, $site_key, $expected);
$data[] = [$project, $site_key, $expected];
// For disabled projects it shouldn't add the site key either.
$site_key = 'site_key';
$project['project_type'] = 'disabled';
$expected = 'http://www.example.com/' . $project['name'] . '/' . DRUPAL_CORE_COMPATIBILITY;
$data[] = array($project, $site_key, $expected);
$data[] = [$project, $site_key, $expected];
// For enabled projects, test adding the site key.
$project['project_type'] = '';
@@ -88,7 +88,7 @@ class UpdateFetcherTest extends UnitTestCase {
$expected .= '?site_key=site_key';
$expected .= '&list=' . rawurlencode('module1,module2');
$data[] = array($project, $site_key, $expected);
$data[] = [$project, $site_key, $expected];
// Test when the URL contains a question mark.
$project['info']['project status url'] = 'http://www.example.com/?project=';
@@ -96,7 +96,7 @@ class UpdateFetcherTest extends UnitTestCase {
$expected .= '&site_key=site_key';
$expected .= '&list=' . rawurlencode('module1,module2');
$data[] = array($project, $site_key, $expected);
$data[] = [$project, $site_key, $expected];
return $data;
}
@@ -4,8 +4,8 @@ description: 'Test theme which acts as a base theme for other test subthemes.'
# version: VERSION
# core: 8.x
# Information added by Drupal.org packaging script on 2016-08-03
version: '8.1.8'
# Information added by Drupal.org packaging script on 2017-08-16
version: '8.3.7'
core: '8.x'
project: 'drupal'
datestamp: 1470233790
datestamp: 1502903957
@@ -5,8 +5,8 @@ description: 'Test theme which uses update_test_basetheme as the base theme.'
# core: 8.x
base theme: update_test_basetheme
# Information added by Drupal.org packaging script on 2016-08-03
version: '8.1.8'
# Information added by Drupal.org packaging script on 2017-08-16
version: '8.3.7'
core: '8.x'
project: 'drupal'
datestamp: 1470233790
datestamp: 1502903957
+12 -12
View File
@@ -32,7 +32,7 @@
* examples of how to populate the array with real values.
*
* @see \Drupal\Update\UpdateManager::getProjects()
* @see \Drupal\Core\Utility\ProjectInfo->processInfoList()
* @see \Drupal\Core\Utility\ProjectInfo::processInfoList()
*/
function hook_update_projects_alter(&$projects) {
// Hide a site-specific module from the list.
@@ -40,11 +40,11 @@ function hook_update_projects_alter(&$projects) {
// Add a disabled module to the list.
// The key for the array should be the machine-readable project "short name".
$projects['disabled_project_name'] = array(
$projects['disabled_project_name'] = [
// Machine-readable project short name (same as the array key above).
'name' => 'disabled_project_name',
// Array of values from the main .info.yml file for this project.
'info' => array(
'info' => [
'name' => 'Some disabled module',
'description' => 'A module not enabled on the site that you want to see in the available updates report.',
'version' => '8.x-1.0',
@@ -52,7 +52,7 @@ function hook_update_projects_alter(&$projects) {
// The maximum file change time (the "ctime" returned by the filectime()
// PHP method) for all of the .info.yml files included in this project.
'_info_file_ctime' => 1243888165,
),
],
// The date stamp when the project was released, if known. If the disabled
// project was an officially packaged release from drupal.org, this will
// be included in the .info.yml file as the 'datestamp' field. This only
@@ -62,15 +62,15 @@ function hook_update_projects_alter(&$projects) {
// Any modules (or themes) included in this project. Keyed by machine-
// readable "short name", value is the human-readable project name printed
// in the UI.
'includes' => array(
'includes' => [
'disabled_project' => 'Disabled module',
'disabled_project_helper' => 'Disabled module helper module',
'disabled_project_foo' => 'Disabled module foo add-on module',
),
],
// Does this project contain a 'module', 'theme', 'disabled-module', or
// 'disabled-theme'?
'project_type' => 'disabled-module',
);
];
}
/**
@@ -92,11 +92,11 @@ function hook_update_status_alter(&$projects) {
$projects[$project]['status'] = UPDATE_NOT_CHECKED;
$projects[$project]['reason'] = t('Ignored from settings');
if (!empty($settings[$project]['notes'])) {
$projects[$project]['extra'][] = array(
'class' => array('admin-note'),
$projects[$project]['extra'][] = [
'class' => ['admin-note'],
'label' => t('Administrator note'),
'data' => $settings[$project]['notes'],
);
];
}
}
}
@@ -120,9 +120,9 @@ function hook_update_status_alter(&$projects) {
* @ingroup update_manager_file
*/
function hook_verify_update_archive($project, $archive_file, $directory) {
$errors = array();
$errors = [];
if (!file_exists($directory)) {
$errors[] = t('The %directory does not exist.', array('%directory' => $directory));
$errors[] = t('The %directory does not exist.', ['%directory' => $directory]);
}
// Add other checks on the archive integrity here.
return $errors;
+35 -35
View File
@@ -36,25 +36,25 @@ use Drupal\Core\Url;
* should use that response for the current page request.
*/
function update_authorize_run_update($filetransfer, $projects) {
$operations = array();
$operations = [];
foreach ($projects as $project_info) {
$operations[] = array(
$operations[] = [
'update_authorize_batch_copy_project',
array(
[
$project_info['project'],
$project_info['updater_name'],
$project_info['local_url'],
$filetransfer,
),
);
],
];
}
$batch = array(
$batch = [
'init_message' => t('Preparing to update your site'),
'operations' => $operations,
'finished' => 'update_authorize_update_batch_finished',
'file' => drupal_get_path('module', 'update') . '/update.authorize.inc',
);
];
batch_set($batch);
// Since authorize.php has its own method for setting the page title, set it
@@ -91,30 +91,30 @@ function update_authorize_run_update($filetransfer, $projects) {
* should use that response for the current page request.
*/
function update_authorize_run_install($filetransfer, $project, $updater_name, $local_url) {
$operations[] = array(
$operations[] = [
'update_authorize_batch_copy_project',
array(
[
$project,
$updater_name,
$local_url,
$filetransfer,
),
);
],
];
// @todo Instantiate our Updater to set the human-readable title?
$batch = array(
$batch = [
'init_message' => t('Preparing to install'),
'operations' => $operations,
// @todo Use a different finished callback for different messages?
'finished' => 'update_authorize_install_batch_finished',
'file' => drupal_get_path('module', 'update') . '/update.authorize.inc',
);
];
batch_set($batch);
// Since authorize.php has its own method for setting the page title, set it
// manually here rather than passing it in to batch_set() as would normally
// be done.
$_SESSION['authorize_page_title'] = t('Installing %project', array('%project' => $project));
$_SESSION['authorize_page_title'] = t('Installing %project', ['%project' => $project]);
// Invoke the batch via authorize.php.
return system_authorized_batch_process();
@@ -142,14 +142,14 @@ function update_authorize_batch_copy_project($project, $updater_name, $local_url
// Initialize some variables in the Batch API $context array.
if (!isset($context['results']['log'])) {
$context['results']['log'] = array();
$context['results']['log'] = [];
}
if (!isset($context['results']['log'][$project])) {
$context['results']['log'][$project] = array();
$context['results']['log'][$project] = [];
}
if (!isset($context['results']['tasks'])) {
$context['results']['tasks'] = array();
$context['results']['tasks'] = [];
}
// The batch API uses a session, and since all the arguments are serialized
@@ -184,7 +184,7 @@ function update_authorize_batch_copy_project($project, $updater_name, $local_url
return;
}
_update_batch_create_message($context['results']['log'][$project], t('Installed %project_name successfully', array('%project_name' => $project)));
_update_batch_create_message($context['results']['log'][$project], t('Installed %project_name successfully', ['%project_name' => $project]));
if (!empty($tasks)) {
$context['results']['tasks'] += $tasks;
}
@@ -221,29 +221,29 @@ function update_authorize_update_batch_finished($success, $results) {
// Take the site out of maintenance mode if it was previously that way.
if ($offline && isset($_SESSION['maintenance_mode']) && $_SESSION['maintenance_mode'] == FALSE) {
\Drupal::state()->set('system.maintenance_mode', FALSE);
$page_message = array(
$page_message = [
'message' => t('Update was completed successfully. Your site has been taken out of maintenance mode.'),
'type' => 'status',
);
];
}
else {
$page_message = array(
$page_message = [
'message' => t('Update was completed successfully.'),
'type' => 'status',
);
];
}
}
elseif (!$offline) {
$page_message = array(
$page_message = [
'message' => t('Update failed! See the log below for more information.'),
'type' => 'error',
);
];
}
else {
$page_message = array(
$page_message = [
'message' => t('Update failed! See the log below for more information. Your site is still in maintenance mode.'),
'type' => 'error',
);
];
}
// Since we're doing an update of existing code, always add a task for
// running update.php.
@@ -300,29 +300,29 @@ function update_authorize_install_batch_finished($success, $results) {
// Take the site out of maintenance mode if it was previously that way.
if ($offline && isset($_SESSION['maintenance_mode']) && $_SESSION['maintenance_mode'] == FALSE) {
\Drupal::state()->set('system.maintenance_mode', FALSE);
$page_message = array(
$page_message = [
'message' => t('Installation was completed successfully. Your site has been taken out of maintenance mode.'),
'type' => 'status',
);
];
}
else {
$page_message = array(
$page_message = [
'message' => t('Installation was completed successfully.'),
'type' => 'status',
);
];
}
}
elseif (!$success && !$offline) {
$page_message = array(
$page_message = [
'message' => t('Installation failed! See the log below for more information.'),
'type' => 'error',
);
];
}
else {
$page_message = array(
$page_message = [
'message' => t('Installation failed! See the log below for more information. Your site is still in maintenance mode.'),
'type' => 'error',
);
];
}
// Unset the variable since it is no longer needed.
@@ -348,7 +348,7 @@ function update_authorize_install_batch_finished($success, $results) {
* if there were errors. Defaults to TRUE.
*/
function _update_batch_create_message(&$project_results, $message, $success = TRUE) {
$project_results[] = array('message' => $message, 'success' => $success);
$project_results[] = ['message' => $message, 'success' => $success];
}
/**
+21 -21
View File
@@ -32,7 +32,7 @@ function update_process_project_info(&$projects) {
// Figure out what the currently installed major version is. We need
// to handle both contribution (e.g. "5.x-1.3", major = 1) and core
// (e.g. "5.1", major = 5) version strings.
$matches = array();
$matches = [];
if (preg_match('/^(\d+\.x-)?(\d+)\..*$/', $info['version'], $matches)) {
$info['major'] = $matches[2];
}
@@ -171,7 +171,7 @@ function update_calculate_project_data($available) {
* Data about available project releases of a specific project.
*/
function update_calculate_project_update_status(&$project_data, $available) {
foreach (array('title', 'link') as $attribute) {
foreach (['title', 'link'] as $attribute) {
if (!isset($project_data[$attribute]) && isset($available[$attribute])) {
$project_data[$attribute] = $available[$attribute];
}
@@ -184,33 +184,33 @@ function update_calculate_project_update_status(&$project_data, $available) {
case 'insecure':
$project_data['status'] = UPDATE_NOT_SECURE;
if (empty($project_data['extra'])) {
$project_data['extra'] = array();
$project_data['extra'] = [];
}
$project_data['extra'][] = array(
$project_data['extra'][] = [
'label' => t('Project not secure'),
'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!'),
);
];
break;
case 'unpublished':
case 'revoked':
$project_data['status'] = UPDATE_REVOKED;
if (empty($project_data['extra'])) {
$project_data['extra'] = array();
$project_data['extra'] = [];
}
$project_data['extra'][] = array(
$project_data['extra'][] = [
'label' => t('Project revoked'),
'data' => t('This project has been revoked, and is no longer available for download. Disabling everything included by this project is strongly recommended!'),
);
];
break;
case 'unsupported':
$project_data['status'] = UPDATE_NOT_SUPPORTED;
if (empty($project_data['extra'])) {
$project_data['extra'] = array();
$project_data['extra'] = [];
}
$project_data['extra'][] = array(
$project_data['extra'][] = [
'label' => t('Project not supported'),
'data' => t('This project is no longer supported, and is no longer available for download. Disabling everything included by this project is strongly recommended!'),
);
];
break;
case 'not-fetched':
$project_data['status'] = UPDATE_NOT_FETCHED;
@@ -233,7 +233,7 @@ function update_calculate_project_update_status(&$project_data, $available) {
// Figure out the target major version.
$existing_major = $project_data['existing_major'];
$supported_majors = array();
$supported_majors = [];
if (isset($available['supported_majors'])) {
$supported_majors = explode(',', $available['supported_majors']);
}
@@ -303,25 +303,25 @@ function update_calculate_project_update_status(&$project_data, $available) {
elseif ($release['status'] == 'unpublished') {
$project_data['status'] = UPDATE_REVOKED;
if (empty($project_data['extra'])) {
$project_data['extra'] = array();
$project_data['extra'] = [];
}
$project_data['extra'][] = array(
'class' => array('release-revoked'),
$project_data['extra'][] = [
'class' => ['release-revoked'],
'label' => t('Release revoked'),
'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!'),
);
];
}
elseif (isset($release['terms']['Release type']) &&
in_array('Unsupported', $release['terms']['Release type'])) {
$project_data['status'] = UPDATE_NOT_SUPPORTED;
if (empty($project_data['extra'])) {
$project_data['extra'] = array();
$project_data['extra'] = [];
}
$project_data['extra'][] = array(
'class' => array('release-not-supported'),
$project_data['extra'][] = [
'class' => ['release-not-supported'],
'label' => t('Release not supported'),
'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!'),
);
];
}
}
@@ -341,7 +341,7 @@ function update_calculate_project_update_status(&$project_data, $available) {
if (isset($release['version_major']) && $release['version_major'] > $target_major) {
if (in_array($release['version_major'], $supported_majors)) {
if (!isset($project_data['also'])) {
$project_data['also'] = array();
$project_data['also'] = [];
}
if (!isset($project_data['also'][$release['version_major']])) {
$project_data['also'][$release['version_major']] = $version;
+2 -2
View File
@@ -18,9 +18,9 @@ function _update_cron_notify() {
$update_config = \Drupal::config('update.settings');
module_load_install('update');
$status = update_requirements('runtime');
$params = array();
$params = [];
$notify_all = ($update_config->get('notification.threshold') == 'all');
foreach (array('core', 'contrib') as $report_type) {
foreach (['core', 'contrib'] as $report_type) {
$type = 'update_' . $report_type;
if (isset($status[$type]['severity'])
&& ($status[$type]['severity'] == REQUIREMENT_ERROR || ($notify_all && $status[$type]['reason'] == UPDATE_NOT_CURRENT))) {
+3 -3
View File
@@ -8,8 +8,8 @@ configure: update.settings
dependencies:
- file
# Information added by Drupal.org packaging script on 2016-08-03
version: '8.1.8'
# Information added by Drupal.org packaging script on 2017-08-16
version: '8.3.7'
core: '8.x'
project: 'drupal'
datestamp: 1470233790
datestamp: 1502903957
+3 -12
View File
@@ -28,7 +28,7 @@ use Drupal\Core\Url;
* @see _update_cron_notify()
*/
function update_requirements($phase) {
$requirements = array();
$requirements = [];
if ($phase == 'runtime') {
if ($available = update_get_available(FALSE)) {
module_load_include('inc', 'update', 'update.compare');
@@ -97,7 +97,7 @@ function update_uninstall() {
* @see update_calculate_project_data()
*/
function _update_requirement_check($project, $type) {
$requirement = array();
$requirement = [];
if ($type == 'core') {
$requirement['title'] = t('Drupal core update status');
}
@@ -143,17 +143,12 @@ function _update_requirement_check($project, $type) {
$requirement_label = t('Up to date');
}
if ($status != UPDATE_CURRENT && $type == 'core' && isset($project['recommended'])) {
$requirement_label .= ' ' . t('(version @version available)', array('@version' => $project['recommended']));
$requirement_label .= ' ' . t('(version @version available)', ['@version' => $project['recommended']]);
}
$requirement['value'] = \Drupal::l($requirement_label, new Url(_update_manager_access() ? 'update.report_update' : 'update.status'));
return $requirement;
}
/**
* @addtogroup updates-8.1.x
* @{
*/
/**
* Rebuild the router to ensure admin/reports/updates/check has CSRF protection.
*/
@@ -161,7 +156,3 @@ function update_update_8001() {
// Empty update forces a call to drupal_flush_all_caches() which rebuilds the
// router.
}
/**
* @} End of "addtogroup updates-8.1.x".
*/
+22 -22
View File
@@ -48,11 +48,11 @@ use Symfony\Component\HttpFoundation\RedirectResponse;
*/
function update_manager_download_batch_finished($success, $results) {
if (!empty($results['errors'])) {
$item_list = array(
$item_list = [
'#theme' => 'item_list',
'#title' => t('Downloading updates failed:'),
'#items' => $results['errors'],
);
];
drupal_set_message(drupal_render($item_list), 'error');
}
elseif ($success) {
@@ -91,45 +91,45 @@ function _update_manager_check_backends(&$form, $operation) {
}
// Otherwise, show the available backends.
$form['available_backends'] = array(
$form['available_backends'] = [
'#prefix' => '<p>',
'#suffix' => '</p>',
);
];
$available_backends = drupal_get_filetransfer_info();
if (empty($available_backends)) {
if ($operation == 'update') {
$form['available_backends']['#markup'] = t('Your server does not support updating modules and themes from this interface. Instead, update modules and themes by uploading the new versions directly to the server, as described in the <a href=":handbook_url">handbook</a>.', array(':handbook_url' => 'https://www.drupal.org/getting-started/install-contrib'));
$form['available_backends']['#markup'] = t('Your server does not support updating modules and themes from this interface. Instead, update modules and themes by uploading the new versions directly to the server, as documented in <a href=":doc_url">Extending Drupal 8</a>.', [':doc_url' => 'https://www.drupal.org/docs/8/extending-drupal-8/overview']);
}
else {
$form['available_backends']['#markup'] = t('Your server does not support installing modules and themes from this interface. Instead, install modules and themes by uploading them directly to the server, as described in the <a href=":handbook_url">handbook</a>.', array(':handbook_url' => 'https://www.drupal.org/getting-started/install-contrib'));
$form['available_backends']['#markup'] = t('Your server does not support installing modules and themes from this interface. Instead, install modules and themes by uploading them directly to the server, as documented in <a href=":doc_url">Extending Drupal 8</a>.', [':doc_url' => 'https://www.drupal.org/docs/8/extending-drupal-8/overview']);
}
return FALSE;
}
$backend_names = array();
$backend_names = [];
foreach ($available_backends as $backend) {
$backend_names[] = $backend['title'];
}
if ($operation == 'update') {
$form['available_backends']['#markup'] = \Drupal::translation()->formatPlural(
count($available_backends),
'Updating modules and themes requires <strong>@backends access</strong> to your server. See the <a href=":handbook_url">handbook</a> for other update methods.',
'Updating modules and themes requires access to your server via one of the following methods: <strong>@backends</strong>. See the <a href=":handbook_url">handbook</a> for other update methods.',
array(
'Updating modules and themes requires <strong>@backends access</strong> to your server. See <a href=":doc_url">Extending Drupal 8</a> for other update methods.',
'Updating modules and themes requires access to your server via one of the following methods: <strong>@backends</strong>. See <a href=":doc_url">Extending Drupal 8</a> for other update methods.',
[
'@backends' => implode(', ', $backend_names),
':handbook_url' => 'https://www.drupal.org/getting-started/install-contrib',
));
':doc_url' => 'https://www.drupal.org/docs/8/extending-drupal-8/overview',
]);
}
else {
$form['available_backends']['#markup'] = \Drupal::translation()->formatPlural(
count($available_backends),
'Installing modules and themes requires <strong>@backends access</strong> to your server. See the <a href=":handbook_url">handbook</a> for other installation methods.',
'Installing modules and themes requires access to your server via one of the following methods: <strong>@backends</strong>. See the <a href=":handbook_url">handbook</a> for other installation methods.',
array(
'Installing modules and themes requires <strong>@backends access</strong> to your server. See <a href=":doc_url">Extending Drupal 8</a> for other installation methods.',
'Installing modules and themes requires access to your server via one of the following methods: <strong>@backends</strong>. See <a href=":doc_url">Extending Drupal 8</a> for other installation methods.',
[
'@backends' => implode(', ', $backend_names),
':handbook_url' => 'https://www.drupal.org/getting-started/install-contrib',
));
':doc_url' => 'https://www.drupal.org/docs/8/extending-drupal-8/overview',
]);
}
return TRUE;
}
@@ -150,7 +150,7 @@ function _update_manager_check_backends(&$form, $operation) {
function update_manager_archive_extract($file, $directory) {
$archiver = archiver_get_archiver($file);
if (!$archiver) {
throw new Exception(t('Cannot extract %file, not a valid archive.', array ('%file' => $file)));
throw new Exception(t('Cannot extract %file, not a valid archive.', ['%file' => $file]));
}
// Remove the directory if it exists, otherwise it might contain a mixture of
@@ -189,7 +189,7 @@ function update_manager_archive_extract($file, $directory) {
* are no errors, it will be an empty array.
*/
function update_manager_archive_verify($project, $archive_file, $directory) {
return \Drupal::moduleHandler()->invokeAll('verify_update_archive', array($project, $archive_file, $directory));
return \Drupal::moduleHandler()->invokeAll('verify_update_archive', [$project, $archive_file, $directory]);
}
/**
@@ -205,7 +205,7 @@ function update_manager_archive_verify($project, $archive_file, $directory) {
*/
function update_manager_file_get($url) {
$parsed_url = parse_url($url);
$remote_schemes = array('http', 'https', 'ftp', 'ftps', 'smb', 'nfs');
$remote_schemes = ['http', 'https', 'ftp', 'ftps', 'smb', 'nfs'];
if (!isset($parsed_url['scheme']) || !in_array($parsed_url['scheme'], $remote_schemes)) {
// This is a local file, just return the path.
return drupal_realpath($url);
@@ -245,14 +245,14 @@ function update_manager_batch_project_get($project, $url, &$context) {
// This is here to show the user that we are in the process of downloading.
if (!isset($context['sandbox']['started'])) {
$context['sandbox']['started'] = TRUE;
$context['message'] = t('Downloading %project', array('%project' => $project));
$context['message'] = t('Downloading %project', ['%project' => $project]);
$context['finished'] = 0;
return;
}
// Actually try to download the file.
if (!($local_cache = update_manager_file_get($url))) {
$context['results']['errors'][$project] = t('Failed to download %project from %url', array('%project' => $project, '%url' => $url));
$context['results']['errors'][$project] = t('Failed to download %project from %url', ['%project' => $project, '%url' => $url]);
return;
}
+78 -51
View File
@@ -20,46 +20,73 @@ use Drupal\Core\Site\Settings;
/**
* Project is missing security update(s).
*
* @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0.
* Use \Drupal\update\UpdateManagerInterface::NOT_SECURE instead.
*/
const UPDATE_NOT_SECURE = 1;
/**
* Current release has been unpublished and is no longer available.
*
* @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0.
* Use \Drupal\update\UpdateManagerInterface::REVOKED instead.
*/
const UPDATE_REVOKED = 2;
/**
* Current release is no longer supported by the project maintainer.
*
* @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0.
* Use \Drupal\update\UpdateManagerInterface::NOT_SUPPORTED instead.
*/
const UPDATE_NOT_SUPPORTED = 3;
/**
* Project has a new release available, but it is not a security release.
*
* @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0.
* Use \Drupal\update\UpdateManagerInterface::NOT_CURRENT instead.
*/
const UPDATE_NOT_CURRENT = 4;
/**
* Project is up to date.
*
* @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0.
* Use \Drupal\update\UpdateManagerInterface::CURRENT instead.
*/
const UPDATE_CURRENT = 5;
/**
* Project's status cannot be checked.
*
* @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0.
* Use \Drupal\update\UpdateFetcherInterface::NOT_CHECKED instead.
*/
const UPDATE_NOT_CHECKED = -1;
/**
* No available update data was found for project.
*
* @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0.
* Use \Drupal\update\UpdateFetcherInterface::UNKNOWN instead.
*/
const UPDATE_UNKNOWN = -2;
/**
* There was a failure fetching available update data for this project.
*
* @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0.
* Use \Drupal\update\UpdateFetcherInterface::NOT_FETCHED instead.
*/
const UPDATE_NOT_FETCHED = -3;
/**
* We need to (re)fetch available update data for this project.
*
* @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0.
* Use \Drupal\update\UpdateFetcherInterface::FETCH_PENDING instead.
*/
const UPDATE_FETCH_PENDING = -4;
@@ -71,7 +98,7 @@ function update_help($route_name, RouteMatchInterface $route_match) {
case 'help.page.update':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('The Update Manager module periodically checks for new versions of your site\'s software (including contributed modules and themes), and alerts administrators to available updates. The Update Manager system is also used by some other modules to manage updates and downloads; for example, the Interface Translation module uses the Update Manager to download translations from the localization server. Note that whenever the Update Manager system is used, anonymous usage statistics are sent to Drupal.org. If desired, you may disable the Update Manager module from the <a href=":modules">Extend page</a>; if you do so, functionality that depends on the Update Manager system will not work. For more information, see the <a href=":update">online documentation for the Update Manager module</a>.', array(':update' => 'https://www.drupal.org/documentation/modules/update', ':modules' => \Drupal::url('system.modules_list'))) . '</p>';
$output .= '<p>' . t('The Update Manager module periodically checks for new versions of your site\'s software (including contributed modules and themes), and alerts administrators to available updates. The Update Manager system is also used by some other modules to manage updates and downloads; for example, the Interface Translation module uses the Update Manager to download translations from the localization server. Note that whenever the Update Manager system is used, anonymous usage statistics are sent to Drupal.org. If desired, you may disable the Update Manager module from the <a href=":modules">Extend page</a>; if you do so, functionality that depends on the Update Manager system will not work. For more information, see the <a href=":update">online documentation for the Update Manager module</a>.', [':update' => 'https://www.drupal.org/documentation/modules/update', ':modules' => \Drupal::url('system.modules_list')]) . '</p>';
// Only explain the Update manager if it has not been disabled.
if (_update_manager_access()) {
$output .= '<p>' . t('The Update Manager also allows administrators to update and install modules and themes through the administration interface.') . '</p>';
@@ -79,13 +106,13 @@ function update_help($route_name, RouteMatchInterface $route_match) {
$output .= '<h3>' . t('Uses') . '</h3>';
$output .= '<dl>';
$output .= '<dt>' . t('Checking for available updates') . '</dt>';
$output .= '<dd>' . t('The <a href=":update-report">Available updates report</a> displays core, contributed modules, and themes for which there are new releases available for download. On the report page, you can also check manually for updates. You can configure the frequency of update checks, which are performed during cron runs, and whether notifications are sent on the <a href=":update-settings">Update Manager settings page</a>.', array(':update-report' => \Drupal::url('update.status'), ':update-settings' => \Drupal::url('update.settings'))) . '</dd>';
$output .= '<dd>' . t('The <a href=":update-report">Available updates report</a> displays core, contributed modules, and themes for which there are new releases available for download. On the report page, you can also check manually for updates. You can configure the frequency of update checks, which are performed during cron runs, and whether notifications are sent on the <a href=":update-settings">Update Manager settings page</a>.', [':update-report' => \Drupal::url('update.status'), ':update-settings' => \Drupal::url('update.settings')]) . '</dd>';
// Only explain the Update manager if it has not been disabled.
if (_update_manager_access()) {
$output .= '<dt>' . t('Performing updates through the Update page') . '</dt>';
$output .= '<dd>' . t('The Update Manager module allows administrators to perform updates directly from the <a href=":update-page">Update page</a>. It lists all available updates, and you can confirm whether you want to download them. If you don\'t have sufficient access rights to your web server, you could be prompted for your FTP/SSH password. Afterwards the files are transferred into your site installation, overwriting your old files. Direct links to the Update page are also displayed on the <a href=":modules_page">Extend page</a> and the <a href=":themes_page">Appearance page</a>.', array(':modules_page' => \Drupal::url('system.modules_list'), ':themes_page' => \Drupal::url('system.themes_page'), ':update-page' => \Drupal::url('update.report_update'))) . '</dd>';
$output .= '<dd>' . t('The Update Manager module allows administrators to perform updates directly from the <a href=":update-page">Update page</a>. It lists all available updates, and you can confirm whether you want to download them. If you don\'t have sufficient access rights to your web server, you could be prompted for your FTP/SSH password. Afterwards the files are transferred into your site installation, overwriting your old files. Direct links to the Update page are also displayed on the <a href=":modules_page">Extend page</a> and the <a href=":themes_page">Appearance page</a>.', [':modules_page' => \Drupal::url('system.modules_list'), ':themes_page' => \Drupal::url('system.themes_page'), ':update-page' => \Drupal::url('update.report_update')]) . '</dd>';
$output .= '<dt>' . t('Installing new modules and themes through the Install page') . '</dt>';
$output .= '<dd>' . t('You can also install new modules and themes in the same fashion, through the <a href=":install">Install page</a>, or by clicking the <em>Install new module/theme</em> links at the top of the <a href=":modules_page">Extend page</a> and the <a href=":themes_page">Appearance page</a>. In this case, you are prompted to provide either the URL to the download, or to upload a packaged release file from your local computer.', array(':modules_page' => \Drupal::url('system.modules_list'), ':themes_page' => \Drupal::url('system.themes_page'), ':install' => \Drupal::url('update.report_install'))) . '</dd>';
$output .= '<dd>' . t('You can also install new modules and themes in the same fashion, through the <a href=":install">Install page</a>, or by clicking the <em>Install new module/theme</em> links at the top of the <a href=":modules_page">Extend page</a> and the <a href=":themes_page">Appearance page</a>. In this case, you are prompted to provide either the URL to the download, or to upload a packaged release file from your local computer.', [':modules_page' => \Drupal::url('system.modules_list'), ':themes_page' => \Drupal::url('system.themes_page'), ':install' => \Drupal::url('update.report_install')]) . '</dd>';
}
$output .= '</dl>';
return $output;
@@ -95,10 +122,10 @@ function update_help($route_name, RouteMatchInterface $route_match) {
case 'system.modules_list':
if (_update_manager_access()) {
$output = '<p>' . t('Regularly review and install <a href=":updates">available updates</a> to maintain a secure and current site. Always run the <a href=":update-php">update script</a> each time a module is updated.', array(':update-php' => \Drupal::url('system.db_update'), ':updates' => \Drupal::url('update.status'))) . '</p>';
$output = '<p>' . t('Regularly review and install <a href=":updates">available updates</a> to maintain a secure and current site. Always run the <a href=":update-php">update script</a> each time a module is updated.', [':update-php' => \Drupal::url('system.db_update'), ':updates' => \Drupal::url('update.status')]) . '</p>';
}
else {
$output = '<p>' . t('Regularly review <a href=":updates">available updates</a> to maintain a secure and current site. Always run the <a href=":update-php">update script</a> each time a module is updated.', array(':update-php' => \Drupal::url('system.db_update'), ':updates' => \Drupal::url('update.status'))) . '</p>';
$output = '<p>' . t('Regularly review <a href=":updates">available updates</a> to maintain a secure and current site. Always run the <a href=":update-php">update script</a> each time a module is updated.', [':update-php' => \Drupal::url('system.db_update'), ':updates' => \Drupal::url('update.status')]) . '</p>';
}
return $output;
}
@@ -137,7 +164,7 @@ function update_page_top() {
}
module_load_install('update');
$status = update_requirements('runtime');
foreach (array('core', 'contrib') as $report_type) {
foreach (['core', 'contrib'] as $report_type) {
$type = 'update_' . $report_type;
// hook_requirements() supports render arrays therefore we need to render
// them before using drupal_set_message().
@@ -185,25 +212,25 @@ function _update_manager_access() {
* Implements hook_theme().
*/
function update_theme() {
return array(
'update_last_check' => array(
'variables' => array('last' => 0),
),
'update_report' => array(
'variables' => array('data' => NULL),
return [
'update_last_check' => [
'variables' => ['last' => 0],
],
'update_report' => [
'variables' => ['data' => NULL],
'file' => 'update.report.inc',
),
'update_project_status' => array(
'variables' => array('project' => array()),
],
'update_project_status' => [
'variables' => ['project' => []],
'file' => 'update.report.inc',
),
],
// We are using template instead of '#type' => 'table' here to keep markup
// out of preprocess and allow for easier changes to markup.
'update_version' => array(
'variables' => array('version' => NULL, 'title' => NULL, 'attributes' => array()),
'update_version' => [
'variables' => ['version' => NULL, 'title' => NULL, 'attributes' => []],
'file' => 'update.report.inc',
),
);
],
];
}
/**
@@ -285,10 +312,10 @@ function update_storage_clear_submit($form, FormStateInterface $form_state) {
*/
function _update_no_data() {
$destination = \Drupal::destination()->getAsArray();
return t('No update information available. <a href=":run_cron">Run cron</a> or <a href=":check_manually">check manually</a>.', array(
return t('No update information available. <a href=":run_cron">Run cron</a> or <a href=":check_manually">check manually</a>.', [
':run_cron' => \Drupal::url('system.run_cron', [], ['query' => $destination]),
':check_manually' => \Drupal::url('update.manual_status', [], ['query' => $destination]),
));
]);
}
/**
@@ -393,7 +420,7 @@ function update_refresh() {
* @see \Drupal\update\UpdateProcessor::fetchData()
*/
function update_fetch_data() {
\Drupal::service('update.processor')->fetchData();
\Drupal::service('update.processor')->fetchData();
}
/**
@@ -444,20 +471,20 @@ function update_fetch_data_finished($success, $results) {
function update_mail($key, &$message, $params) {
$langcode = $message['langcode'];
$language = \Drupal::languageManager()->getLanguage($langcode);
$message['subject'] .= t('New release(s) available for @site_name', array('@site_name' => \Drupal::config('system.site')->get('name')), array('langcode' => $langcode));
$message['subject'] .= t('New release(s) available for @site_name', ['@site_name' => \Drupal::config('system.site')->get('name')], ['langcode' => $langcode]);
foreach ($params as $msg_type => $msg_reason) {
$message['body'][] = _update_message_text($msg_type, $msg_reason, $langcode);
}
$message['body'][] = t('See the available updates page for more information:', array(), array('langcode' => $langcode)) . "\n" . \Drupal::url('update.status', [], ['absolute' => TRUE, 'language' => $language]);
$message['body'][] = t('See the available updates page for more information:', [], ['langcode' => $langcode]) . "\n" . \Drupal::url('update.status', [], ['absolute' => TRUE, 'language' => $language]);
if (_update_manager_access()) {
$message['body'][] = t('You can automatically install your missing updates using the Update manager:', array(), array('langcode' => $langcode)) . "\n" . \Drupal::url('update.report_update', [], ['absolute' => TRUE, 'language' => $language]);
$message['body'][] = t('You can automatically install your missing updates using the Update manager:', [], ['langcode' => $langcode]) . "\n" . \Drupal::url('update.report_update', [], ['absolute' => TRUE, 'language' => $language]);
}
$settings_url = \Drupal::url('update.settings', [], ['absolute' => TRUE]);
if (\Drupal::config('update.settings')->get('notification.threshold') == 'all') {
$message['body'][] = t('Your site is currently configured to send these emails when any updates are available. To get notified only for security updates, @url.', array('@url' => $settings_url));
$message['body'][] = t('Your site is currently configured to send these emails when any updates are available. To get notified only for security updates, @url.', ['@url' => $settings_url]);
}
else {
$message['body'][] = t('Your site is currently configured to send these emails only when security updates are available. To get notified for any available updates, @url.', array('@url' => $settings_url));
$message['body'][] = t('Your site is currently configured to send these emails only when security updates are available. To get notified for any available updates, @url.', ['@url' => $settings_url]);
}
}
@@ -484,37 +511,37 @@ function _update_message_text($msg_type, $msg_reason, $langcode = NULL) {
switch ($msg_reason) {
case UPDATE_NOT_SECURE:
if ($msg_type == 'core') {
$text = t('There is a security update available for your version of Drupal. To ensure the security of your server, you should update immediately!', array(), array('langcode' => $langcode));
$text = t('There is a security update available for your version of Drupal. To ensure the security of your server, you should update immediately!', [], ['langcode' => $langcode]);
}
else {
$text = t('There are security updates available for one or more of your modules or themes. To ensure the security of your server, you should update immediately!', array(), array('langcode' => $langcode));
$text = t('There are security updates available for one or more of your modules or themes. To ensure the security of your server, you should update immediately!', [], ['langcode' => $langcode]);
}
break;
case UPDATE_REVOKED:
if ($msg_type == 'core') {
$text = t('Your version of Drupal has been revoked and is no longer available for download. Upgrading is strongly recommended!', array(), array('langcode' => $langcode));
$text = t('Your version of Drupal has been revoked and is no longer available for download. Upgrading is strongly recommended!', [], ['langcode' => $langcode]);
}
else {
$text = t('The installed version of at least one of your modules or themes has been revoked and is no longer available for download. Upgrading or disabling is strongly recommended!', array(), array('langcode' => $langcode));
$text = t('The installed version of at least one of your modules or themes has been revoked and is no longer available for download. Upgrading or disabling is strongly recommended!', [], ['langcode' => $langcode]);
}
break;
case UPDATE_NOT_SUPPORTED:
if ($msg_type == 'core') {
$text = t('Your version of Drupal is no longer supported. Upgrading is strongly recommended!', array(), array('langcode' => $langcode));
$text = t('Your version of Drupal is no longer supported. Upgrading is strongly recommended!', [], ['langcode' => $langcode]);
}
else {
$text = t('The installed version of at least one of your modules or themes is no longer supported. Upgrading or disabling is strongly recommended. See the project homepage for more details.', array(), array('langcode' => $langcode));
$text = t('The installed version of at least one of your modules or themes is no longer supported. Upgrading or disabling is strongly recommended. See the project homepage for more details.', [], ['langcode' => $langcode]);
}
break;
case UPDATE_NOT_CURRENT:
if ($msg_type == 'core') {
$text = t('There are updates available for your version of Drupal. To ensure the proper functioning of your site, you should update as soon as possible.', array(), array('langcode' => $langcode));
$text = t('There are updates available for your version of Drupal. To ensure the proper functioning of your site, you should update as soon as possible.', [], ['langcode' => $langcode]);
}
else {
$text = t('There are updates available for one or more of your modules or themes. To ensure the proper functioning of your site, you should update as soon as possible.', array(), array('langcode' => $langcode));
$text = t('There are updates available for one or more of your modules or themes. To ensure the proper functioning of your site, you should update as soon as possible.', [], ['langcode' => $langcode]);
}
break;
@@ -523,10 +550,10 @@ function _update_message_text($msg_type, $msg_reason, $langcode = NULL) {
case UPDATE_NOT_FETCHED:
case UPDATE_FETCH_PENDING:
if ($msg_type == 'core') {
$text = t('There was a problem checking <a href=":update-report">available updates</a> for Drupal.', array(':update-report' => \Drupal::url('update.status')), array('langcode' => $langcode));
$text = t('There was a problem checking <a href=":update-report">available updates</a> for Drupal.', [':update-report' => \Drupal::url('update.status')], ['langcode' => $langcode]);
}
else {
$text = t('There was a problem checking <a href=":update-report">available updates</a> for your modules or themes.', array(':update-report' => \Drupal::url('update.status')), array('langcode' => $langcode));
$text = t('There was a problem checking <a href=":update-report">available updates</a> for your modules or themes.', [':update-report' => \Drupal::url('update.status')], ['langcode' => $langcode]);
}
break;
}
@@ -566,7 +593,7 @@ function _update_project_status_sort($a, $b) {
*/
function template_preprocess_update_last_check(&$variables) {
$variables['time'] = \Drupal::service('date.formatter')->formatTimeDiffSince($variables['last']);
$variables['link'] = \Drupal::l(t('Check manually'), new Url('update.manual_status', array(), array('query' => \Drupal::destination()->getAsArray())));
$variables['link'] = \Drupal::l(t('Check manually'), new Url('update.manual_status', [], ['query' => \Drupal::destination()->getAsArray()]));
}
/**
@@ -583,7 +610,7 @@ function template_preprocess_update_last_check(&$variables) {
* @see _system_rebuild_module_data()
*/
function update_verify_update_archive($project, $archive_file, $directory) {
$errors = array();
$errors = [];
// Make sure this isn't a tarball of Drupal core.
if (
@@ -593,9 +620,9 @@ function update_verify_update_archive($project, $archive_file, $directory) {
&& file_exists("$directory/$project/core/modules/node/node.module")
&& file_exists("$directory/$project/core/modules/system/system.module")
) {
return array(
'no-core' => t('Automatic updating of Drupal core is not supported. See the <a href=":upgrade-guide">upgrade guide</a> for information on how to update Drupal core manually.', array(':upgrade-guide' => 'https://www.drupal.org/upgrade')),
);
return [
'no-core' => t('Automatic updating of Drupal core is not supported. See the <a href=":upgrade-guide">upgrade guide</a> for information on how to update Drupal core manually.', [':upgrade-guide' => 'https://www.drupal.org/upgrade']),
];
}
// Parse all the .info.yml files and make sure at least one is compatible with
@@ -604,8 +631,8 @@ function update_verify_update_archive($project, $archive_file, $directory) {
// with some out-of-date modules that are not necessary for its overall
// functionality).
$compatible_project = FALSE;
$incompatible = array();
$files = file_scan_directory("$directory/$project", '/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info.yml$/', array('key' => 'name', 'min_depth' => 0));
$incompatible = [];
$files = file_scan_directory("$directory/$project", '/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info.yml$/', ['key' => 'name', 'min_depth' => 0]);
foreach ($files as $file) {
// Get the .info.yml file for the module or theme this file belongs to.
$info = \Drupal::service('info_parser')->parse($file->uri);
@@ -621,14 +648,14 @@ function update_verify_update_archive($project, $archive_file, $directory) {
}
if (empty($files)) {
$errors[] = t('%archive_file does not contain any .info.yml files.', array('%archive_file' => drupal_basename($archive_file)));
$errors[] = t('%archive_file does not contain any .info.yml files.', ['%archive_file' => drupal_basename($archive_file)]);
}
elseif (!$compatible_project) {
$errors[] = \Drupal::translation()->formatPlural(
count($incompatible),
'%archive_file contains a version of %names that is not compatible with Drupal @version.',
'%archive_file contains versions of modules or themes that are not compatible with Drupal @version: %names',
array('@version' => \Drupal::CORE_COMPATIBILITY, '%archive_file' => drupal_basename($archive_file), '%names' => implode(', ', $incompatible))
['@version' => \Drupal::CORE_COMPATIBILITY, '%archive_file' => drupal_basename($archive_file), '%names' => implode(', ', $incompatible)]
);
}
@@ -707,14 +734,14 @@ function _update_manager_cache_directory($create = TRUE) {
function update_clear_update_disk_cache() {
// List of update module cache directories. Do not create the directories if
// they do not exist.
$directories = array(
$directories = [
_update_manager_cache_directory(FALSE),
_update_manager_extract_directory(FALSE),
);
];
// Search for files and directories in base folder only without recursion.
foreach ($directories as $directory) {
file_scan_directory($directory, '/.*/', array('callback' => 'update_delete_file_if_stale', 'recurse' => FALSE));
file_scan_directory($directory, '/.*/', ['callback' => 'update_delete_file_if_stale', 'recurse' => FALSE]);
}
}
+42 -42
View File
@@ -23,36 +23,36 @@ function template_preprocess_update_report(&$variables) {
$last = \Drupal::state()->get('update.last_check') ?: 0;
$variables['last_checked'] = array(
$variables['last_checked'] = [
'#theme' => 'update_last_check',
'#last' => $last,
// Attach the library to a variable that gets printed always.
'#attached' => array(
'library' => array(
'#attached' => [
'library' => [
'update/drupal.update.admin',
),
)
);
],
]
];
// For no project update data, populate no data message.
if (empty($data)) {
$variables['no_updates_message'] = _update_no_data();
}
$rows = array();
$rows = [];
foreach ($data as $project) {
$project_status = array(
$project_status = [
'#theme' => 'update_project_status',
'#project' => $project,
);
];
// Build project rows.
if (!isset($rows[$project['project_type']])) {
$rows[$project['project_type']] = array(
$rows[$project['project_type']] = [
'#type' => 'table',
'#attributes' => array('class' => array('update')),
);
'#attributes' => ['class' => ['update']],
];
}
$row_key = !empty($project['title']) ? Unicode::strtolower($project['title']) : Unicode::strtolower($project['name']);
@@ -62,7 +62,7 @@ function template_preprocess_update_report(&$variables) {
// Add project status class attribute to the table row.
switch ($project['status']) {
case UPDATE_CURRENT:
$rows[$project['project_type']][$row_key]['#attributes'] = array('class' => array('color-success'));
$rows[$project['project_type']][$row_key]['#attributes'] = ['class' => ['color-success']];
break;
case UPDATE_UNKNOWN:
case UPDATE_FETCH_PENDING:
@@ -70,32 +70,32 @@ function template_preprocess_update_report(&$variables) {
case UPDATE_NOT_SECURE:
case UPDATE_REVOKED:
case UPDATE_NOT_SUPPORTED:
$rows[$project['project_type']][$row_key]['#attributes'] = array('class' => array('color-error'));
$rows[$project['project_type']][$row_key]['#attributes'] = ['class' => ['color-error']];
break;
case UPDATE_NOT_CHECKED:
case UPDATE_NOT_CURRENT:
default:
$rows[$project['project_type']][$row_key]['#attributes'] = array('class' => array('color-warning'));
$rows[$project['project_type']][$row_key]['#attributes'] = ['class' => ['color-warning']];
break;
}
}
$project_types = array(
$project_types = [
'core' => t('Drupal core'),
'module' => t('Modules'),
'theme' => t('Themes'),
'module-disabled' => t('Uninstalled modules'),
'theme-disabled' => t('Uninstalled themes'),
);
];
$variables['project_types'] = array();
$variables['project_types'] = [];
foreach ($project_types as $type_name => $type_label) {
if (!empty($rows[$type_name])) {
ksort($rows[$type_name]);
$variables['project_types'][] = array(
$variables['project_types'][] = [
'label' => $type_label,
'table' => $rows[$type_name],
);
];
}
}
}
@@ -124,9 +124,9 @@ function template_preprocess_update_project_status(&$variables) {
$variables['existing_version'] = $project['existing_version'];
$versions_inner = array();
$security_class = array();
$version_class = array();
$versions_inner = [];
$security_class = [];
$version_class = [];
if (isset($project['recommended'])) {
if ($project['status'] != UPDATE_CURRENT || $project['existing_version'] !== $project['recommended']) {
@@ -156,57 +156,57 @@ function template_preprocess_update_project_status(&$variables) {
) {
$version_class[] = 'project-update__version--recommended-strong';
}
$versions_inner[] = array(
$versions_inner[] = [
'#theme' => 'update_version',
'#version' => $project['releases'][$project['recommended']],
'#title' => t('Recommended version:'),
'#attributes' => array('class' => $version_class),
);
'#attributes' => ['class' => $version_class],
];
}
// Now, print any security updates.
if (!empty($project['security updates'])) {
$security_class[] = 'version-security';
foreach ($project['security updates'] as $security_update) {
$versions_inner[] = array(
$versions_inner[] = [
'#theme' => 'update_version',
'#version' => $security_update,
'#title' => t('Security update:'),
'#attributes' => array('class' => $security_class),
);
'#attributes' => ['class' => $security_class],
];
}
}
}
if ($project['recommended'] !== $project['latest_version']) {
$versions_inner[] = array(
$versions_inner[] = [
'#theme' => 'update_version',
'#version' => $project['releases'][$project['latest_version']],
'#title' => t('Latest version:'),
'#attributes' => array('class' => array('version-latest')),
);
'#attributes' => ['class' => ['version-latest']],
];
}
if ($project['install_type'] == 'dev'
&& $project['status'] != UPDATE_CURRENT
&& isset($project['dev_version'])
&& $project['recommended'] !== $project['dev_version']) {
$versions_inner[] = array(
$versions_inner[] = [
'#theme' => 'update_version',
'#version' => $project['releases'][$project['dev_version']],
'#title' => t('Development version:'),
'#attributes' => array('class' => array('version-latest')),
);
'#attributes' => ['class' => ['version-latest']],
];
}
}
if (isset($project['also'])) {
foreach ($project['also'] as $also) {
$versions_inner[] = array(
$versions_inner[] = [
'#theme' => 'update_version',
'#version' => $project['releases'][$also],
'#title' => t('Also available:'),
'#attributes' => array('class' => array('version-also-available')),
);
'#attributes' => ['class' => ['version-also-available']],
];
}
}
@@ -222,10 +222,10 @@ function template_preprocess_update_project_status(&$variables) {
sort($project['includes']);
$variables['includes'] = $project['includes'];
$variables['extras'] = array();
$variables['extras'] = [];
if (!empty($project['extra'])) {
foreach ($project['extra'] as $value) {
$extra_item = array();
$extra_item = [];
$extra_item['attributes'] = new Attribute();
$extra_item['label'] = $value['label'];
$extra_item['data'] = [
@@ -285,12 +285,12 @@ function template_preprocess_update_project_status(&$variables) {
break;
}
$variables['status']['icon'] = array(
$variables['status']['icon'] = [
'#theme' => 'image',
'#width' => 18,
'#height' => 18,
'#uri' => $uri,
'#alt' => $text,
'#title' => $text,
);
];
}