update.install 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <?php
  2. /**
  3. * @file
  4. * Install, update, and uninstall functions for the Update Manager module.
  5. */
  6. use Drupal\Core\Url;
  7. /**
  8. * Implements hook_requirements().
  9. *
  10. * @return
  11. * An array describing the status of the site regarding available updates. If
  12. * there is no update data, only one record will be returned, indicating that
  13. * the status of core can't be determined. If data is available, there will be
  14. * two records: one for core, and another for all of contrib (assuming there
  15. * are any contributed modules or themes enabled on the site). In addition to
  16. * the fields expected by hook_requirements ('value', 'severity', and
  17. * optionally 'description'), this array will contain a 'reason' attribute,
  18. * which is an integer constant to indicate why the given status is being
  19. * returned (UPDATE_NOT_SECURE, UPDATE_NOT_CURRENT, or UPDATE_UNKNOWN). This
  20. * is used for generating the appropriate email notification messages during
  21. * update_cron(), and might be useful for other modules that invoke
  22. * update_requirements() to find out if the site is up to date or not.
  23. *
  24. * @see _update_message_text()
  25. * @see _update_cron_notify()
  26. */
  27. function update_requirements($phase) {
  28. $requirements = [];
  29. if ($phase == 'runtime') {
  30. if ($available = update_get_available(FALSE)) {
  31. module_load_include('inc', 'update', 'update.compare');
  32. $data = update_calculate_project_data($available);
  33. // First, populate the requirements for core:
  34. $requirements['update_core'] = _update_requirement_check($data['drupal'], 'core');
  35. // We don't want to check drupal a second time.
  36. unset($data['drupal']);
  37. if (!empty($data)) {
  38. // Now, sort our $data array based on each project's status. The
  39. // status constants are numbered in the right order of precedence, so
  40. // we just need to make sure the projects are sorted in ascending
  41. // order of status, and we can look at the first project we find.
  42. uasort($data, '_update_project_status_sort');
  43. $first_project = reset($data);
  44. $requirements['update_contrib'] = _update_requirement_check($first_project, 'contrib');
  45. }
  46. }
  47. else {
  48. $requirements['update_core']['title'] = t('Drupal core update status');
  49. $requirements['update_core']['value'] = t('No update data available');
  50. $requirements['update_core']['severity'] = REQUIREMENT_WARNING;
  51. $requirements['update_core']['reason'] = UPDATE_UNKNOWN;
  52. $requirements['update_core']['description'] = _update_no_data();
  53. }
  54. }
  55. return $requirements;
  56. }
  57. /**
  58. * Implements hook_install().
  59. */
  60. function update_install() {
  61. $queue = \Drupal::queue('update_fetch_tasks', TRUE);
  62. $queue->createQueue();
  63. }
  64. /**
  65. * Implements hook_uninstall().
  66. */
  67. function update_uninstall() {
  68. \Drupal::state()->delete('update.last_check');
  69. \Drupal::state()->delete('update.last_email_notification');
  70. $queue = \Drupal::queue('update_fetch_tasks');
  71. $queue->deleteQueue();
  72. }
  73. /**
  74. * Fills in the requirements array.
  75. *
  76. * This is shared for both core and contrib to generate the right elements in
  77. * the array for hook_requirements().
  78. *
  79. * @param $project
  80. * Array of information about the project we're testing as returned by
  81. * update_calculate_project_data().
  82. * @param $type
  83. * What kind of project this is ('core' or 'contrib').
  84. *
  85. * @return
  86. * An array to be included in the nested $requirements array.
  87. *
  88. * @see hook_requirements()
  89. * @see update_requirements()
  90. * @see update_calculate_project_data()
  91. */
  92. function _update_requirement_check($project, $type) {
  93. $requirement = [];
  94. if ($type == 'core') {
  95. $requirement['title'] = t('Drupal core update status');
  96. }
  97. else {
  98. $requirement['title'] = t('Module and theme update status');
  99. }
  100. $status = $project['status'];
  101. if ($status != UPDATE_CURRENT) {
  102. $requirement['reason'] = $status;
  103. $requirement['severity'] = REQUIREMENT_ERROR;
  104. // When updates are available, append the available updates link to the
  105. // message from _update_message_text(), and format the two translated
  106. // strings together in a single paragraph.
  107. $requirement['description'][] = ['#markup' => _update_message_text($type, $status)];
  108. if (!in_array($status, [UPDATE_UNKNOWN, UPDATE_NOT_CHECKED, UPDATE_NOT_FETCHED, UPDATE_FETCH_PENDING])) {
  109. if (_update_manager_access()) {
  110. $requirement['description'][] = ['#prefix' => ' ', '#markup' => t('See the <a href=":available_updates">available updates</a> page for more information and to install your missing updates.', [':available_updates' => \Drupal::url('update.report_update')])];
  111. }
  112. else {
  113. $requirement['description'][] = ['#prefix' => ' ', '#markup' => t('See the <a href=":available_updates">available updates</a> page for more information.', [':available_updates' => \Drupal::url('update.status')])];
  114. }
  115. }
  116. }
  117. switch ($status) {
  118. case UPDATE_NOT_SECURE:
  119. $requirement_label = t('Not secure!');
  120. break;
  121. case UPDATE_REVOKED:
  122. $requirement_label = t('Revoked!');
  123. break;
  124. case UPDATE_NOT_SUPPORTED:
  125. $requirement_label = t('Unsupported release');
  126. break;
  127. case UPDATE_NOT_CURRENT:
  128. $requirement_label = t('Out of date');
  129. $requirement['severity'] = REQUIREMENT_WARNING;
  130. break;
  131. case UPDATE_UNKNOWN:
  132. case UPDATE_NOT_CHECKED:
  133. case UPDATE_NOT_FETCHED:
  134. case UPDATE_FETCH_PENDING:
  135. $requirement_label = isset($project['reason']) ? $project['reason'] : t('Can not determine status');
  136. $requirement['severity'] = REQUIREMENT_WARNING;
  137. break;
  138. default:
  139. $requirement_label = t('Up to date');
  140. }
  141. if ($status != UPDATE_CURRENT && $type == 'core' && isset($project['recommended'])) {
  142. $requirement_label .= ' ' . t('(version @version available)', ['@version' => $project['recommended']]);
  143. }
  144. $requirement['value'] = \Drupal::l($requirement_label, new Url(_update_manager_access() ? 'update.report_update' : 'update.status'));
  145. return $requirement;
  146. }
  147. /**
  148. * Rebuild the router to ensure admin/reports/updates/check has CSRF protection.
  149. */
  150. function update_update_8001() {
  151. // Empty update forces a call to drupal_flush_all_caches() which rebuilds the
  152. // router.
  153. // Use hook_post_update_NAME() instead to clear the cache.The use
  154. // of hook_update_N to clear the cache has been deprecated see
  155. // https://www.drupal.org/node/2960601 for more details.
  156. }