module_missing_message_fixer.module 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <?php
  2. /**
  3. * @file
  4. * The Missing Module Message Fixer Module file.
  5. */
  6. /**
  7. * Implements hook_permission().
  8. */
  9. function module_missing_message_fixer_permission() {
  10. return array(
  11. 'administer module missing message fixer' => array(
  12. 'title' => t('Administer Module Missing Message Fixer'),
  13. ),
  14. );
  15. }
  16. /**
  17. * Implements hook_menu().
  18. */
  19. function module_missing_message_fixer_menu() {
  20. $items = array();
  21. $items['admin/config/system/module-missing-message-fixer'] = array(
  22. 'title' => 'Missing Module Message Fixer',
  23. 'description' => 'This module display a list of missing module that appear after the Drupal 7.50 release and lets you fix the entries.',
  24. 'type' => MENU_NORMAL_ITEM,
  25. 'page callback' => 'drupal_get_form',
  26. 'page arguments' => array('module_missing_message_fixer_form'),
  27. 'access arguments' => array('administer module missing message fixer'),
  28. 'file' => 'includes/module_missing_message_fixer.admin.inc',
  29. );
  30. return $items;
  31. }
  32. /**
  33. * @return string[]
  34. * Format: $[$column_key] = $cell
  35. */
  36. function _module_missing_message_fixer_get_table_header() {
  37. return array(
  38. 'name' => 'Name',
  39. 'type' => 'Type',
  40. 'filename' => 'Filename',
  41. );
  42. }
  43. /**
  44. * Produces one table row for each missing module.
  45. *
  46. * The table rows are suitable for drush and for the admin UI.
  47. *
  48. * @return array[]
  49. * Format: $[$extension_name][$column_key] = $cell
  50. */
  51. function _module_missing_message_fixer_get_table_rows() {
  52. // These are special modules that have their own patches already.
  53. // This will help eliminate some of the brute force of this module.
  54. $special = array(
  55. 'adminimal_theme' => 'https://www.drupal.org/node/2763581',
  56. 'content' => 'https://www.drupal.org/node/2763555',
  57. 'field_collection_table' => 'https://www.drupal.org/node/2764331',
  58. );
  59. // Grab all the modules in the system table.
  60. /** @var \DatabaseStatementBase|\DatabaseStatementInterface $query */
  61. $query = db_query("SELECT filename, type, name FROM {system}");
  62. $rows = array();
  63. // Go through the query and check to see if the module exists in the directory.
  64. foreach ($query->fetchAll() as $record) {
  65. if ($record->name === 'default') {
  66. continue;
  67. }
  68. // Add exception to this since content module seems to be ubercart sad only.
  69. if ($record->name === 'content' && !module_exists('ubercart')) {
  70. $rows[$record->name] = array(
  71. 'name' => $record->name,
  72. 'type' => $record->type,
  73. 'filename' => $record->filename,
  74. );
  75. continue;
  76. }
  77. if (array_key_exists($record->name, $special)) {
  78. // Everyone else fails into here.
  79. // Set the message.
  80. $msg = t('The @module module has a patch. See <a href="@link" target="_blank">this issue</a> for more information. It <strong>WILL NOT</strong> be removed by Module Missing Message Fixer.', array(
  81. '@module' => $record->name,
  82. '@link' => $special[$record->name],
  83. ));
  84. // Now print it!
  85. drupal_set_message($msg, 'status', FALSE);
  86. continue;
  87. }
  88. // Grab the checker.
  89. $filename = drupal_get_filename(
  90. $record->type,
  91. $record->name,
  92. $record->filename,
  93. FALSE);
  94. if ($filename === NULL) {
  95. // Report this module in the table.
  96. $rows[$record->name] = array(
  97. 'name' => $record->name,
  98. 'type' => $record->type,
  99. 'filename' => $record->filename,
  100. );
  101. continue;
  102. }
  103. $message = NULL;
  104. $replacements = array(
  105. '@name' => $record->name,
  106. '@type' => $record->type,
  107. '@file' => $filename,
  108. );
  109. if (!file_exists($filename)) {
  110. // This case is unexpected, because drupal_get_filename() should take care
  111. // of it already.
  112. $message = 'The file @file for @name @type is missing.';
  113. }
  114. elseif (!is_readable($filename)) {
  115. // This case is unexpected, because drupal_get_filename() should take care
  116. // of it already.
  117. $message = 'The file @file for @name @type is not readable.';
  118. }
  119. else {
  120. // Verify if *.info file exists. See https://www.drupal.org/node/2789993#comment-12306555
  121. $info_filename = dirname($filename) . '/' . $record->name . '.info';
  122. $replacements['@info_file'] = $info_filename;
  123. if (!file_exists($info_filename)) {
  124. $message = 'The *.info file @info_file for @name @type is missing.';
  125. }
  126. elseif (!is_readable($info_filename)) {
  127. $message = 'The *.info file @info_file for @name @type is not readable.';
  128. }
  129. }
  130. if ($message !== NULL) {
  131. // This case should never occur.
  132. drupal_set_message(
  133. t($message, $replacements),
  134. 'warning',
  135. FALSE);
  136. }
  137. }
  138. return $rows;
  139. }