StatusInfoDrupal8.php

  1. 8.0.x lib/Drush/UpdateService/StatusInfoDrupal8.php
  2. 7.x lib/Drush/UpdateService/StatusInfoDrupal8.php
  3. master lib/Drush/UpdateService/StatusInfoDrupal8.php

Implementation of 'drupal' update_status engine for Drupal 8.

Namespace

Drush\UpdateService

Classes

Namesort descending Description
StatusInfoDrupal8

File

lib/Drush/UpdateService/StatusInfoDrupal8.php
View source
  1. <?php
  2. /**
  3. * @file
  4. * Implementation of 'drupal' update_status engine for Drupal 8.
  5. */
  6. namespace Drush\UpdateService;
  7. class StatusInfoDrupal8 implements StatusInfoInterface {
  8. /**
  9. * {@inheritdoc}
  10. */
  11. public function __construct($type, $engine, $config) {
  12. $this->engine_type = $type;
  13. $this->engine = $engine;
  14. $this->engine_config = $config;
  15. }
  16. /**
  17. * {@inheritdoc}
  18. */
  19. function lastCheck() {
  20. $last_check = \Drupal::state()->get('update.last_check') ?: 0;
  21. return $last_check;
  22. }
  23. /**
  24. * {@inheritdoc}
  25. */
  26. function refresh() {
  27. update_refresh();
  28. }
  29. /**
  30. * Perform adjustments before running get status.
  31. *
  32. * - Enforce check-disabled option on update module.
  33. */
  34. function beforeGetStatus(&$projects, $check_disabled) {
  35. // If check-disabled option was provided, alter Drupal settings temporarily.
  36. // There's no other way to hook into this.
  37. if (!is_null($check_disabled)) {
  38. $config = \Drupal::config('update.settings');
  39. $this->update_check_disabled = $config->get('check.disabled_extensions');
  40. $config->set('check.disabled_extensions', (bool)$check_disabled);
  41. }
  42. }
  43. /**
  44. * Get update information for all installed projects.
  45. *
  46. * @return
  47. * Array of update status information.
  48. */
  49. function getStatus($projects, $check_disabled) {
  50. $this->beforeGetStatus($projects, $check_disabled);
  51. $available = $this->getAvailableReleases();
  52. $update_info = $this->calculateUpdateStatus($available, $projects);
  53. $this->afterGetStatus($update_info, $projects, $check_disabled);
  54. return $update_info;
  55. }
  56. /**
  57. * Perform adjustments after running get status.
  58. *
  59. * - Restore check-disabled setting in update module.
  60. * - Adjust project type for disabled projects.
  61. */
  62. function afterGetStatus(&$update_info, $projects, $check_disabled) {
  63. // Restore Drupal settings.
  64. if (!is_null($check_disabled)) {
  65. \Drupal::config('update.settings')->set('check.disabled_extensions', $this->update_check_disabled);
  66. unset($this->update_check_disabled);
  67. }
  68. // update.module sets a different project type
  69. // for disabled projects. Here we normalize it.
  70. if ($check_disabled) {
  71. foreach ($update_info as $key => $project) {
  72. if (in_array($project['project_type'], array('module-disabled', 'theme-disabled'))) {
  73. $update_info[$key]['project_type'] = substr($project['project_type'], 0, strpos($project['project_type'], '-'));
  74. }
  75. }
  76. }
  77. }
  78. /**
  79. * Obtains release info for all installed projects via update.module.
  80. *
  81. * @see update_get_available().
  82. * @see \Drupal\update\Controller\UpdateController::updateStatusManually()
  83. */
  84. protected function getAvailableReleases() {
  85. // Force to invalidate some caches that are only cleared
  86. // when visiting update status report page. This allow to detect changes in
  87. // .info.yml files.
  88. \Drupal::keyValueExpirable('update')->deleteMultiple(array('update_project_projects', 'update_project_data'));
  89. // From update_get_available(): Iterate all projects and create a fetch task
  90. // for those we have no information or is obsolete.
  91. $available = \Drupal::keyValueExpirable('update_available_releases')->getAll();
  92. $update_projects = \Drupal::service('update.manager')->getProjects();
  93. foreach ($update_projects as $key => $project) {
  94. if (empty($available[$key])) {
  95. \Drupal::service('update.processor')->createFetchTask($project);
  96. continue;
  97. }
  98. if ($project['info']['_info_file_ctime'] > $available[$key]['last_fetch']) {
  99. $available[$key]['fetch_status'] = UPDATE_FETCH_PENDING;
  100. }
  101. if (empty($available[$key]['releases'])) {
  102. $available[$key]['fetch_status'] = UPDATE_FETCH_PENDING;
  103. }
  104. if (!empty($available[$key]['fetch_status']) && $available[$key]['fetch_status'] == UPDATE_FETCH_PENDING) {
  105. \Drupal::service('update.processor')->createFetchTask($project);
  106. }
  107. }
  108. // Set a batch to process all pending tasks.
  109. $batch = array(
  110. 'operations' => array(
  111. array(array(\Drupal::service('update.manager'), 'fetchDataBatch'), array()),
  112. ),
  113. 'finished' => 'update_fetch_data_finished',
  114. 'file' => drupal_get_path('module', 'update') . '/update.fetch.inc',
  115. );
  116. batch_set($batch);
  117. drush_backend_batch_process();
  118. // Clear any error set by a failed update fetch task. This avoid rollbacks.
  119. drush_clear_error();
  120. return \Drupal::keyValueExpirable('update_available_releases')->getAll();
  121. }
  122. /**
  123. * Calculates update status for all projects via update.module.
  124. */
  125. protected function calculateUpdateStatus($available, $projects) {
  126. module_load_include('inc', 'update', 'update.compare');
  127. $data = update_calculate_project_data($available);
  128. foreach ($data as $project_name => $project) {
  129. // Discard custom projects.
  130. if ($project['status'] == UPDATE_UNKNOWN) {
  131. unset($data[$project_name]);
  132. continue;
  133. }
  134. // Discard projects with unknown installation path.
  135. if ($project_name != 'drupal' && !isset($projects[$project_name]['path'])) {
  136. unset($data[$project_name]);
  137. continue;
  138. }
  139. // Add some info from the project to $data.
  140. $data[$project_name] += array(
  141. 'path' => isset($projects[$project_name]['path']) ? $projects[$project_name]['path'] : '',
  142. 'label' => $projects[$project_name]['label'],
  143. );
  144. // Store all releases, not just the ones selected by update.module.
  145. // We use it to allow the user to update to a specific version.
  146. if (isset($available[$project_name]['releases'])) {
  147. $data[$project_name]['releases'] = $available[$project_name]['releases'];
  148. }
  149. }
  150. return $data;
  151. }
  152. }