* Handles updates of Drupal core and contributed projects.
*
* The module checks for available updates of Drupal core and any installed
* contributed modules and themes. It warns site administrators if newer
* releases are available via the system status report (admin/reports/status),
* the module and theme pages, and optionally via email. It also provides the
* ability to install contributed modules and themes via an user interface.
*/
use Drupal\Core\Url;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Site\Settings;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
// These are internally used constants for this code, do not modify.
/**
* Project is missing security update(s).
*/
const UPDATE_NOT_SECURE = 1;
/**
* Current release has been unpublished and is no longer available.
*/
const UPDATE_REVOKED = 2;
/**
* Current release is no longer supported by the project maintainer.
*/
const UPDATE_NOT_SUPPORTED = 3;
/**
* Project has a new release available, but it is not a security release.
*/
const UPDATE_NOT_CURRENT = 4;
/**
* Project is up to date.
*/
const UPDATE_CURRENT = 5;
/**
* Project's status cannot be checked.
*/
const UPDATE_NOT_CHECKED = -1;
/**
* No available update data was found for project.
*/
const UPDATE_UNKNOWN = -2;
/**
* There was a failure fetching available update data for this project.
*/
const UPDATE_NOT_FETCHED = -3;
/**
* We need to (re)fetch available update data for this project.
*/
const UPDATE_FETCH_PENDING = -4;
/**
* Implements hook_help().
*/
function update_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
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 <a href="!update">the online documentation for the Update Manager module</a>.', array('!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.
$output .= '<p>' . t('The Update Manager also allows administrators to update and install modules and themes through the administration interface.') . '</p>';
}
$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>';
// Only explain the Update manager if it has not been disabled.
$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 .= '<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 .= '</dl>';
return $output;
case 'update.status':
return '<p>' . t('Here you can find information about available updates for your installed modules and themes. Note that each module or theme is part of a "project", which may or may not have the same name, and might include multiple modules or themes within it.') . '</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.', array('!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>';
* Batch callback: Performs actions when all fetch tasks have been completed.
*
* @param $success
* TRUE if the batch operation was successful; FALSE if there were errors.
* @param $results
* An associative array of results from the batch operation, including the key
* 'updated' which holds the total number of projects we fetched available
* update data for.
*/
function update_fetch_data_finished($success, $results) {
if ($success) {
if (!empty($results)) {
if (!empty($results['updated'])) {
drupal_set_message(\Drupal::translation()->formatPlural($results['updated'], 'Checked available update data for one project.', 'Checked available update data for @count projects.'));
}
if (!empty($results['failures'])) {
drupal_set_message(\Drupal::translation()->formatPlural($results['failures'], 'Failed to get available update data for one project.', 'Failed to get available update data for @count projects.'), 'error');
}
}
}
else {
drupal_set_message(t('An error occurred trying to get available update data.'), 'error');
}
}
/**
* Implements hook_mail().
*
* Constructs the email notification message when the site is out of date.
*
* @param $key
* Unique key to indicate what message to build, always 'status_notify'.
* @param $message
* Reference to the message array being built.
* @param $params
* Array of parameters to indicate what kind of text to include in the message
* body. This is a keyed array of message type ('core' or 'contrib') as the
* keys, and the status reason constant (UPDATE_NOT_SECURE, etc) for the
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));
}
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));
}
}
/**
* Returns the appropriate message text when site is out of date or not secure.
*
* These error messages are shared by both update_requirements() for the
* site-wide status report at admin/reports/status and in the body of the
* notification email messages generated by update_cron().
*
* @param $msg_type
* String to indicate what kind of message to generate. Can be either 'core'
* or 'contrib'.
* @param $msg_reason
* Integer constant specifying why message is generated.
* @param $langcode
* (optional) A language code to use. Defaults to NULL.
*
* @return
* The properly translated error message for the given key.
$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));
}
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));
}
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));
}
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));
}
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));
}
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));
}
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));
}
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));
}
break;
case UPDATE_UNKNOWN:
case UPDATE_NOT_CHECKED:
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));
}
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));
'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')),
);
}
// Parse all the .info.yml files and make sure at least one is compatible with
// this version of Drupal core. If one is compatible, then the project as a
// whole is considered compatible (since, for example, the project may ship
// with some out-of-date modules that are not necessary for its overall