Commit 06cfb95a authored by catch's avatar catch
Browse files

Issue #3250585 by Spokje, ankithashetty, karishmaamin, quietone, catch, Gábor...

Issue #3250585 by Spokje, ankithashetty, karishmaamin, quietone, catch, Gábor Hojtsy, longwave, daffie, xjm, andypost, benjifisher, bbrala, larowlan: Highlight deprecated modules and themes at admin/reports/status page, providing warning and link with explanation

(cherry picked from commit 54f08fba)
parent f5dc2cbd
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -192,4 +192,21 @@ public function __wakeup() {
    $this->root = $container && $container->hasParameter('app.root') ? $container->getParameter('app.root') : DRUPAL_ROOT;
  }

  /**
   * Checks if an extension is marked as experimental.
   *
   * @return bool
   *   TRUE if an extension is marked as experimental, FALSE otherwise.
   */
  public function isExperimental(): bool {
    // Currently, this function checks for both the key/value pairs
    // 'experimental: true' and 'lifecycle: experimental' to determine if an
    // extension is marked as experimental.
    // @todo Remove the check for 'experimental: true' as part of
    // https://www.drupal.org/node/3250342
    return (isset($this->info['experimental']) && $this->info['experimental'])
    || (isset($this->info[ExtensionLifecycle::LIFECYCLE_IDENTIFIER])
        && $this->info[ExtensionLifecycle::LIFECYCLE_IDENTIFIER] === ExtensionLifecycle::EXPERIMENTAL);
  }

}
+2 −3
Original line number Diff line number Diff line
@@ -225,7 +225,6 @@ public function themesPage() {
      }
      $theme->is_default = ($theme->getName() == $theme_default);
      $theme->is_admin = ($theme->getName() == $admin_theme || ($theme->is_default && empty($admin_theme)));
      $theme->is_experimental = isset($theme->info['experimental']) && $theme->info['experimental'];

      // Identify theme screenshot.
      $theme->screenshot = NULL;
@@ -330,7 +329,7 @@ public function themesPage() {
              'attributes' => ['title' => $this->t('Set @theme as default theme', ['@theme' => $theme->info['name']])],
            ];
          }
          $admin_theme_options[$theme->getName()] = $theme->info['name'] . ($theme->is_experimental ? ' (' . t('Experimental') . ')' : '');
          $admin_theme_options[$theme->getName()] = $theme->info['name'] . ($theme->isExperimental() ? ' (' . t('Experimental') . ')' : '');
        }
        else {
          $theme->operations[] = [
@@ -357,7 +356,7 @@ public function themesPage() {
      if ($theme->is_admin) {
        $theme->notes[] = $this->t('administration theme');
      }
      if ($theme->is_experimental) {
      if ($theme->isExperimental()) {
        $theme->notes[] = $this->t('experimental theme');
      }

+1 −1
Original line number Diff line number Diff line
@@ -187,7 +187,7 @@ protected function willInstallExperimentalTheme($theme) {
    $themes_to_enable = array_merge([$theme], $dependencies);

    foreach ($themes_to_enable as $name) {
      if (!empty($all_themes[$name]->info['experimental']) && $all_themes[$name]->status === 0) {
      if (isset($all_themes[$name]) && $all_themes[$name]->isExperimental() && $all_themes[$name]->status === 0) {
        return TRUE;
      }
    }
+1 −1
Original line number Diff line number Diff line
@@ -104,7 +104,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    $dependencies = array_keys($all_themes[$theme]->requires);
    $themes = array_merge([$theme], $dependencies);
    $is_experimental = function ($theme) use ($all_themes) {
      return isset($all_themes[$theme]) && isset($all_themes[$theme]->info['experimental']) && $all_themes[$theme]->info['experimental'];
      return isset($all_themes[$theme]) && $all_themes[$theme]->isExperimental();
    };
    $get_label = function ($theme) use ($all_themes) {
      return $all_themes[$theme]->info['name'];
+96 −18
Original line number Diff line number Diff line
@@ -33,8 +33,12 @@
function system_requirements($phase) {
  global $install_state;
  // Reset the extension lists.
  \Drupal::service('extension.list.module')->reset();
  \Drupal::service('extension.list.theme')->reset();
  /** @var \Drupal\Core\Extension\ModuleExtensionList $module_extension_list */
  $module_extension_list = \Drupal::service('extension.list.module');
  $module_extension_list->reset();
  /** @var \Drupal\Core\Extension\ThemeExtensionList $theme_extension_list */
  $theme_extension_list = \Drupal::service('extension.list.theme');
  $theme_extension_list->reset();
  $requirements = [];

  // Report Drupal version
@@ -50,7 +54,7 @@ function system_requirements($phase) {
    // is not running the default installation profile.
    $profile = \Drupal::installProfile();
    if ($profile != 'standard') {
      $info = \Drupal::service('extension.list.module')->getExtensionInfo($profile);
      $info = $module_extension_list->getExtensionInfo($profile);
      $requirements['install_profile'] = [
        'title' => t('Installation profile'),
        'value' => t('%profile_name (%profile-%version)', [
@@ -63,15 +67,27 @@ function system_requirements($phase) {
      ];
    }

    // Warn if any experimental modules are installed.
    // Gather all obsolete and experimental modules being enabled.
    $obsolete_extensions = [];
    $deprecated_modules = [];
    $experimental_modules = [];
    $enabled_modules = \Drupal::moduleHandler()->getModuleList();
    foreach ($enabled_modules as $module => $data) {
      $info = \Drupal::service('extension.list.module')->getExtensionInfo($module);
      if (isset($info[ExtensionLifecycle::LIFECYCLE_IDENTIFIER]) && $info[ExtensionLifecycle::LIFECYCLE_IDENTIFIER] === ExtensionLifecycle::EXPERIMENTAL) {
      $info = $module_extension_list->getExtensionInfo($module);
      if (isset($info[ExtensionLifecycle::LIFECYCLE_IDENTIFIER])) {
        if ($info[ExtensionLifecycle::LIFECYCLE_IDENTIFIER] === ExtensionLifecycle::EXPERIMENTAL) {
          $experimental_modules[$module] = $info['name'];
        }
        elseif ($info[ExtensionLifecycle::LIFECYCLE_IDENTIFIER] === ExtensionLifecycle::DEPRECATED) {
          $deprecated_modules[] = ['name' => $info['name'], 'lifecycle_link' => $info['lifecycle_link']];
        }
        elseif ($info[ExtensionLifecycle::LIFECYCLE_IDENTIFIER] === ExtensionLifecycle::OBSOLETE) {
          $obsolete_extensions[$module] = ['name' => $info['name'], 'lifecycle_link' => $info['lifecycle_link']];
        }
      }
    }

    // Warn if any experimental modules are installed.
    if (!empty($experimental_modules)) {
      $requirements['experimental_modules'] = [
        'title' => t('Experimental modules enabled'),
@@ -79,14 +95,48 @@ function system_requirements($phase) {
        'severity' => REQUIREMENT_WARNING,
      ];
    }
    // Warn if any experimental themes are installed.
    // Warn if any deprecated modules are installed.
    if (!empty($deprecated_modules)) {
      foreach ($deprecated_modules as $deprecated_module) {
        $deprecated_modules_link_list[] = (string) Link::fromTextAndUrl($deprecated_module['name'], Url::fromUri($deprecated_module['lifecycle_link']))->toString();
      }
      $requirements['deprecated_modules'] = [
        'title' => t('Deprecated modules enabled'),
        'value' => t('Deprecated modules found: %module_list.', [
          '%module_list' => t(implode(',', $deprecated_modules_link_list)),
        ]),
        'severity' => REQUIREMENT_WARNING,
      ];
    }

    // Gather all obsolete and experimental themes being enabled.
    $experimental_themes = [];
    $deprecated_themes = [];
    $installed_themes = \Drupal::service('theme_handler')->listInfo();
    foreach ($installed_themes as $theme => $data) {
      $info = $theme_extension_list->getExtensionInfo($theme);
      if (isset($info[ExtensionLifecycle::LIFECYCLE_IDENTIFIER])) {
        if ($info[ExtensionLifecycle::LIFECYCLE_IDENTIFIER] === ExtensionLifecycle::EXPERIMENTAL) {
          $experimental_themes[$theme] = $info['name'];
        }
        elseif ($info[ExtensionLifecycle::LIFECYCLE_IDENTIFIER] === ExtensionLifecycle::DEPRECATED) {
          $deprecated_themes[] = ['name' => $info['name'], 'lifecycle_link' => $info['lifecycle_link']];
        }
        elseif ($info[ExtensionLifecycle::LIFECYCLE_IDENTIFIER] === ExtensionLifecycle::OBSOLETE) {
          $obsolete_extensions[$theme] = ['name' => $info['name'], 'lifecycle_link' => $info['lifecycle_link']];
        }
      }
      // Currently, we check for both the key/value pairs 'experimental: true'
      // and 'lifecycle: experimental' to determine if an extension is marked as
      // experimental.
      // @todo Remove the check for 'experimental: true' as part of
      // https://www.drupal.org/node/3250342
      if (isset($data->info['experimental']) && $data->info['experimental']) {
        $experimental_themes[$theme] = $data->info['name'];
      }
    }

    // Warn if any experimental themes are enabled.
    if (!empty($experimental_themes)) {
      $requirements['experimental_themes'] = [
        'title' => t('Experimental themes enabled'),
@@ -94,6 +144,35 @@ function system_requirements($phase) {
        'severity' => REQUIREMENT_WARNING,
      ];
    }

    // Warn if any deprecated themes are enabled.
    if (!empty($deprecated_themes)) {
      foreach ($deprecated_themes as $deprecated_theme) {
        $deprecated_themes_link_list[] = (string) Link::fromTextAndUrl($deprecated_theme['name'], Url::fromUri($deprecated_theme['lifecycle_link']))->toString();

      }
      $requirements['deprecated_themes'] = [
        'title' => t('Deprecated themes enabled'),
        'value' => t('Deprecated themes found: %theme_list.', [
          '%theme_list' => t(implode(',', $deprecated_themes_link_list)),
        ]),
        'severity' => REQUIREMENT_WARNING,
      ];
    }

    // Warn if any obsolete extensions (themes or modules) are enabled.
    if (!empty($obsolete_extensions)) {
      foreach ($obsolete_extensions as $obsolete_extension) {
        $obsolete_extensions_link_list[] = (string) Link::fromTextAndUrl($obsolete_extension['name'], Url::fromUri($obsolete_extension['lifecycle_link']))->toString();
      }
      $requirements['obsolete_extensions'] = [
        'title' => t('Obsolete extensions enabled'),
        'value' => t('Obsolete extensions found: %extensions. Obsolete extensions are provided only so that they can be uninstalled cleanly. You should immediately uninstall these extensions since they may be removed in a future release.', [
          '%extension_list' => t(implode(', ', $obsolete_extensions_link_list)),
        ]),
        'severity' => REQUIREMENT_WARNING,
      ];
    }
    _system_advisories_requirements($requirements);
  }

@@ -931,8 +1010,8 @@ function system_requirements($phase) {
      ];
    };
    $profile = \Drupal::installProfile();
    $files = \Drupal::service('extension.list.module')->getList();
    $files += \Drupal::service('extension.list.theme')->getList();
    $files = $module_extension_list->getList();
    $files += $theme_extension_list->getList();
    $core_incompatible_extensions = [];
    $php_incompatible_extensions = [];
    foreach ($files as $extension_name => $file) {
@@ -1048,10 +1127,8 @@ function system_requirements($phase) {

    // Look for invalid modules.
    $extension_config = \Drupal::configFactory()->get('core.extension');
    /** @var \Drupal\Core\Extension\ExtensionList $extension_list */
    $extension_list = \Drupal::service('extension.list.module');
    $is_missing_extension = function ($extension_name) use (&$extension_list) {
      return !$extension_list->exists($extension_name);
    $is_missing_extension = function ($extension_name) use (&$module_extension_list) {
      return !$module_extension_list->exists($extension_name);
    };

    $invalid_modules = array_filter(array_keys($extension_config->get('module')), $is_missing_extension);
@@ -1073,8 +1150,10 @@ function system_requirements($phase) {
    }

    // Look for invalid themes.
    $extension_list = \Drupal::service('extension.list.theme');
    $invalid_themes = array_filter(array_keys($extension_config->get('theme')), $is_missing_extension);
    $is_missing_theme = function ($extension_name) use (&$theme_extension_list) {
      return !$theme_extension_list->exists($extension_name);
    };
    $invalid_themes = array_filter(array_keys($extension_config->get('theme')), $is_missing_theme);
    if (!empty($invalid_themes)) {
      $requirements['invalid_theme'] = $create_extension_incompatibility_list(
        $invalid_themes,
@@ -1283,7 +1362,7 @@ function system_requirements($phase) {
      if ($last_removed && $last_removed > $update_registry->getInstalledVersion($module)) {

        /** @var \Drupal\Core\Extension\Extension $module_info */
        $module_info = \Drupal::service('extension.list.module')->get($module);
        $module_info = $module_extension_list->get($module);
        $module_list[$module] = [
          'name' => $module_info->info['name'],
          'last_removed' => $last_removed,
@@ -1327,7 +1406,6 @@ function system_requirements($phase) {
      $existing_updates = \Drupal::service('keyvalue')->get('post_update')->get('existing_updates', []);
      $post_update_registry = \Drupal::service('update.post_update_registry');
      $modules = \Drupal::moduleHandler()->getModuleList();
      $module_extension_list = \Drupal::service('extension.list.module');
      foreach ($modules as $module => $extension) {
        $module_info = $module_extension_list->get($module);
        $removed_post_updates = $post_update_registry->getRemovedPostUpdates($module);
Loading