From cbc03163b937bd6c5de70ed88cee062286680431 Mon Sep 17 00:00:00 2001
From: effulgentsia <alex.bronstein@acquia.com>
Date: Fri, 17 Apr 2015 16:05:59 -0700
Subject: [PATCH] Issue #2281989 by stefan.r: Add a fast and simple way to get
 module name from the module handler

---
 core/includes/module.inc                      |  2 +-
 .../Drupal/Core/Extension/ModuleHandler.php   |  4 +--
 .../Core/Extension/ModuleHandlerInterface.php |  3 +-
 .../Core/Menu/Form/MenuLinkDefaultForm.php    | 29 +-----------------
 core/modules/field/field.module               |  6 ++--
 .../help/src/Controller/HelpController.php    | 14 ++++-----
 core/modules/system/system.module             | 30 ++++++++++++++-----
 core/modules/user/src/PermissionHandler.php   |  3 +-
 .../src/Plugin/views/access/Permission.php    | 20 +++++++++----
 .../user/src/Plugin/views/field/UserData.php  | 20 +++++++++----
 .../src/Plugin/views/filter/Permissions.php   | 19 ++++++++----
 11 files changed, 83 insertions(+), 67 deletions(-)

diff --git a/core/includes/module.inc b/core/includes/module.inc
index f65f0b877ff5..0f1b0d8cda27 100644
--- a/core/includes/module.inc
+++ b/core/includes/module.inc
@@ -45,7 +45,7 @@ function system_list($type) {
     \Drupal::cache('bootstrap')->set('system_list', $lists);
   }
   // To avoid a separate database lookup for the filepath, prime the
-  // drupal_get_filename() static cache with all enabled modules and themes.
+  // drupal_get_filename() static cache with all enabled themes.
   foreach ($lists['filepaths'] as $item) {
     system_register($item['type'], $item['name'], $item['filepath']);
   }
diff --git a/core/lib/Drupal/Core/Extension/ModuleHandler.php b/core/lib/Drupal/Core/Extension/ModuleHandler.php
index bb79ae493634..93ca06684a52 100644
--- a/core/lib/Drupal/Core/Extension/ModuleHandler.php
+++ b/core/lib/Drupal/Core/Extension/ModuleHandler.php
@@ -710,8 +710,8 @@ public function getModuleDirectories() {
    * {@inheritdoc}
    */
   public function getName($module) {
-    $module_data = system_rebuild_module_data();
-    return $module_data[$module]->info['name'];
+    $info = system_get_info('module', $module);
+    return isset($info['name']) ? $info['name'] : $module;
   }
 
 }
diff --git a/core/lib/Drupal/Core/Extension/ModuleHandlerInterface.php b/core/lib/Drupal/Core/Extension/ModuleHandlerInterface.php
index 9d12df606f3e..43e3b5e5c672 100644
--- a/core/lib/Drupal/Core/Extension/ModuleHandlerInterface.php
+++ b/core/lib/Drupal/Core/Extension/ModuleHandlerInterface.php
@@ -307,7 +307,8 @@ public function getModuleDirectories();
    *   The machine name of the module which title should be shown.
    *
    * @return string
-   *   Returns the human readable name of the module.
+   *   Returns the human readable name of the module or the machine name passed
+   *   in if no matching module is found.
    */
   public function getName($module);
 
diff --git a/core/lib/Drupal/Core/Menu/Form/MenuLinkDefaultForm.php b/core/lib/Drupal/Core/Menu/Form/MenuLinkDefaultForm.php
index bf86365bb345..1062b2beac93 100644
--- a/core/lib/Drupal/Core/Menu/Form/MenuLinkDefaultForm.php
+++ b/core/lib/Drupal/Core/Menu/Form/MenuLinkDefaultForm.php
@@ -108,7 +108,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
     $provider = $this->menuLink->getProvider();
     $form['info'] = array(
       '#type' => 'item',
-      '#title' => $this->t('This link is provided by the @name module. The title and path cannot be edited.', array('@name' => $this->getModuleName($provider))),
+      '#title' => $this->t('This link is provided by the @name module. The title and path cannot be edited.', array('@name' => $this->moduleHandler->getName($provider))),
     );
     $link = array(
       '#type' => 'link',
@@ -187,31 +187,4 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s
     return $this->menuLinkManager->updateDefinition($this->menuLink->getPluginId(), $new_definition);
   }
 
-  /**
-   * Gets the name of the module.
-   *
-   * @param string $module
-   *   The machine name of a module.
-   *
-   * @todo This function is horrible, but core has nothing better until we add a
-   * a method to the ModuleHandler that handles this nicely.
-   * https://drupal.org/node/2281989
-   *
-   * @return string
-   *   The human-readable, localized module name, or the machine name passed in
-   *   if no matching module is found.
-   */
-  protected function getModuleName($module) {
-    // Gather module data.
-    if (!isset($this->moduleData)) {
-      $this->moduleData = system_get_info('module');
-    }
-    // If the module exists, return its human-readable name.
-    if (isset($this->moduleData[$module])) {
-      return $this->t($this->moduleData[$module]['name']);
-    }
-    // Otherwise, return the machine name.
-    return $module;
-  }
-
 }
diff --git a/core/modules/field/field.module b/core/modules/field/field.module
index d8be77658da2..91ec6b9dc172 100644
--- a/core/modules/field/field.module
+++ b/core/modules/field/field.module
@@ -92,7 +92,7 @@ function field_help($route_name, RouteMatchInterface $route_match) {
       // enabled, ordered by displayed module name (module names are not
       // translated).
       $items = array();
-      $info = system_get_info('module');
+      $modules = \Drupal::moduleHandler()->getModuleList();
       $widgets = \Drupal::service('plugin.manager.field.widget')->getDefinitions();
       $field_types = \Drupal::service('plugin.manager.field.field_type')->getUiDefinitions();
       $formatters = \Drupal::service('plugin.manager.field.formatter')->getDefinitions();
@@ -105,8 +105,8 @@ function field_help($route_name, RouteMatchInterface $route_match) {
       foreach ($providers as $provider) {
         // Skip plugins provided by core components as they do not implement
         // hook_help().
-        if (isset($info[$provider]['name'])) {
-          $display = $info[$provider]['name'];
+        if (isset($modules[$provider])) {
+          $display = \Drupal::moduleHandler()->getName($provider);
           if (\Drupal::moduleHandler()->implementsHook($provider, 'help')) {
             $items[] = \Drupal::l($display, new Url('help.page', array('name' => $provider)));
           }
diff --git a/core/modules/help/src/Controller/HelpController.php b/core/modules/help/src/Controller/HelpController.php
index 53c3eb85a070..3561fde58e80 100644
--- a/core/modules/help/src/Controller/HelpController.php
+++ b/core/modules/help/src/Controller/HelpController.php
@@ -66,12 +66,10 @@ public function helpMain() {
    *   A string containing the formatted list.
    */
   protected function helpLinksAsList() {
-    $module_info = system_rebuild_module_data();
-
     $modules = array();
     foreach ($this->moduleHandler()->getImplementations('help') as $module) {
       if ($this->moduleHandler()->invoke($module, 'help', array("help.page.$module", $this->routeMatch))) {
-        $modules[$module] = $module_info[$module]->info['name'];
+        $modules[$module] = $this->moduleHandler->getName($module);
       }
     }
     asort($modules);
@@ -118,12 +116,12 @@ protected function helpLinksAsList() {
   public function helpPage($name) {
     $build = array();
     if ($this->moduleHandler()->implementsHook($name, 'help')) {
-      $info = system_get_info('module');
-      $build['#title'] = SafeMarkup::checkPlain($info[$name]['name']);
+      $module_name =  $this->moduleHandler()->getName($name);
+      $build['#title'] = SafeMarkup::checkPlain($module_name);
 
       $temp = $this->moduleHandler()->invoke($name, 'help', array("help.page.$name", $this->routeMatch));
       if (empty($temp)) {
-        $build['top']['#markup'] = $this->t('No help is available for module %module.', array('%module' => $info[$name]['name']));
+        $build['top']['#markup'] = $this->t('No help is available for module %module.', array('%module' => $module_name));
       }
       else {
         $build['top']['#markup'] = $temp;
@@ -131,7 +129,7 @@ public function helpPage($name) {
 
       // Only print list of administration pages if the module in question has
       // any such pages associated to it.
-      $admin_tasks = system_get_module_admin_tasks($name, $info[$name]);
+      $admin_tasks = system_get_module_admin_tasks($name, system_get_info('module', $name));
       if (!empty($admin_tasks)) {
         $links = array();
         foreach ($admin_tasks as $task) {
@@ -142,7 +140,7 @@ public function helpPage($name) {
         $build['links']['#links'] = array(
           '#heading' => array(
             'level' => 'h3',
-            'text' => $this->t('@module administration pages', array('@module' => $info[$name]['name'])),
+            'text' => $this->t('@module administration pages', array('@module' => $module_name)),
           ),
           '#links' => $links,
         );
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 88f9023d921f..17148bee832c 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -852,16 +852,29 @@ function system_check_directory($form_element, FormStateInterface $form_state) {
  * @see \Drupal\Core\Extension\ThemeHandlerInterface::rebuildThemeData()
  */
 function system_get_info($type, $name = NULL) {
-  $info = array();
   if ($type == 'module') {
-    $data = system_rebuild_module_data();
-    foreach (\Drupal::moduleHandler()->getModuleList() as $module => $filename) {
-      if (isset($data[$module])) {
-        $info[$module] = $data[$module]->info;
+    $info = &drupal_static(__FUNCTION__);
+    if (!isset($info)) {
+      if ($cache = \Drupal::cache()->get('system.module.info')) {
+        $info = $cache->data;
+      }
+      else {
+        $data = system_rebuild_module_data();
+        foreach (\Drupal::moduleHandler()->getModuleList() as $module => $filename) {
+          if (isset($data[$module])) {
+            $info[$module] = $data[$module]->info;
+          }
+        }
+        // Store the module information in cache. This cache is cleared by
+        // calling system_rebuild_module_data(), for example, when listing
+        // modules, (un)installing modules, importing configuration, updating
+        // the site and when flushing all the caches.
+        \Drupal::cache()->set('system.module.info', $info);
       }
     }
   }
   else {
+    $info = array();
     $list = system_list($type);
     foreach ($list as $shortname => $item) {
       if (!empty($item->status)) {
@@ -999,9 +1012,12 @@ function system_rebuild_module_data() {
     $modules = \Drupal::moduleHandler()->buildModuleDependencies($modules);
     $modules_cache = $modules;
 
-    // Store filenames to allow system_list() and drupal_get_filename() to
-    // retrieve them without having to rebuild or scan the filesystem.
+    // Store filenames to allow drupal_get_filename() to retrieve them without
+    // having to rebuild or scan the filesystem.
     \Drupal::state()->set('system.module.files', $files);
+    // Clear the module info cache.
+    \Drupal::cache()->delete('system.module.info');
+    drupal_static_reset('system_get_info');
   }
   return $modules_cache;
 }
diff --git a/core/modules/user/src/PermissionHandler.php b/core/modules/user/src/PermissionHandler.php
index 2bb4523bfd2e..ac6e9bb69485 100644
--- a/core/modules/user/src/PermissionHandler.php
+++ b/core/modules/user/src/PermissionHandler.php
@@ -227,9 +227,8 @@ protected function sortPermissions(array $all_permissions = array()) {
    */
   protected function getModuleNames() {
     $modules = array();
-    $module_info = $this->systemRebuildModuleData();
     foreach (array_keys($this->moduleHandler->getModuleList()) as $module) {
-      $modules[$module] = $module_info[$module]->info['name'];
+      $modules[$module] = $this->moduleHandler->getName($module);
     }
     asort($modules);
     return $modules;
diff --git a/core/modules/user/src/Plugin/views/access/Permission.php b/core/modules/user/src/Plugin/views/access/Permission.php
index 6dca9bd3e795..4caab18c826d 100644
--- a/core/modules/user/src/Plugin/views/access/Permission.php
+++ b/core/modules/user/src/Plugin/views/access/Permission.php
@@ -8,6 +8,7 @@
 namespace Drupal\user\Plugin\views\access;
 
 use Drupal\Component\Utility\SafeMarkup;
+use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\user\PermissionHandlerInterface;
@@ -40,6 +41,13 @@ class Permission extends AccessPluginBase {
    */
   protected $permissionHandler;
 
+  /**
+   * The module handler.
+   *
+   * @var \Drupal\Core\Extension\ModuleHandlerInterface
+   */
+  protected $moduleHandler;
+
   /**
    * Constructs a Permission object.
    *
@@ -51,10 +59,13 @@ class Permission extends AccessPluginBase {
    *   The plugin implementation definition.
    * @param \Drupal\user\PermissionHandlerInterface $permission_handler
    *   The permission handler.
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler.
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, PermissionHandlerInterface $permission_handler) {
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, PermissionHandlerInterface $permission_handler, ModuleHandlerInterface $module_handler) {
     parent::__construct($configuration, $plugin_id, $plugin_definition);
     $this->permissionHandler = $permission_handler;
+    $this->moduleHandler = $module_handler;
   }
 
   /**
@@ -65,7 +76,8 @@ public static function create(ContainerInterface $container, array $configuratio
       $configuration,
       $plugin_id,
       $plugin_definition,
-      $container->get('user.permissions')
+      $container->get('user.permissions'),
+      $container->get('module_handler')
     );
   }
 
@@ -102,14 +114,12 @@ protected function defineOptions() {
 
   public function buildOptionsForm(&$form, FormStateInterface $form_state) {
     parent::buildOptionsForm($form, $form_state);
-    $module_info = system_get_info('module');
-
     // Get list of permissions
     $perms = [];
     $permissions = $this->permissionHandler->getPermissions();
     foreach ($permissions as $perm => $perm_item) {
       $provider = $perm_item['provider'];
-      $display_name = $module_info[$provider]['name'];
+      $display_name = $this->moduleHandler->getName($provider);
       $perms[$display_name][$perm] = SafeMarkup::checkPlain(strip_tags($perm_item['title']));
     }
 
diff --git a/core/modules/user/src/Plugin/views/field/UserData.php b/core/modules/user/src/Plugin/views/field/UserData.php
index ce3f92739434..7c001868b9ca 100644
--- a/core/modules/user/src/Plugin/views/field/UserData.php
+++ b/core/modules/user/src/Plugin/views/field/UserData.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\user\Plugin\views\field;
 
+use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\views\Plugin\views\display\DisplayPluginBase;
 use Drupal\views\Plugin\views\field\FieldPluginBase;
@@ -33,20 +34,29 @@ class UserData extends FieldPluginBase {
    */
   protected $userData;
 
+  /**
+   * The module handler.
+   *
+   * @var \Drupal\Core\Extension\ModuleHandlerInterface
+   */
+  protected $moduleHandler;
+
+
   /**
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static($configuration, $plugin_id, $plugin_definition, $container->get('user.data'));
+    return new static($configuration, $plugin_id, $plugin_definition, $container->get('user.data'), $container->get('module_handler'));
   }
 
   /**
    * Constructs a UserData object.
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, UserDataInterface $user_data) {
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, UserDataInterface $user_data, ModuleHandlerInterface $module_handler) {
     parent::__construct($configuration, $plugin_id, $plugin_definition);
 
     $this->userData = $user_data;
+    $this->moduleHandler = $module_handler;
   }
 
   /**
@@ -67,10 +77,10 @@ protected function defineOptions() {
   public function buildOptionsForm(&$form, FormStateInterface $form_state) {
     parent::buildOptionsForm($form, $form_state);
 
-    $modules = system_get_info('module');
+    $modules = $this->moduleHandler->getModuleList();
     $names = array();
-    foreach ($modules as $name => $module) {
-      $names[$name] = $module['name'];
+    foreach (array_keys($modules) as $name) {
+      $names[$name] = $this->moduleHandler->getName($name);
     }
 
     $form['data_module'] = array(
diff --git a/core/modules/user/src/Plugin/views/filter/Permissions.php b/core/modules/user/src/Plugin/views/filter/Permissions.php
index 8b1015c676d5..418dd3151d7c 100644
--- a/core/modules/user/src/Plugin/views/filter/Permissions.php
+++ b/core/modules/user/src/Plugin/views/filter/Permissions.php
@@ -29,6 +29,13 @@ class Permissions extends ManyToOne {
    */
   protected $permissionHandler;
 
+  /**
+   * The module handler.
+   *
+   * @var \Drupal\Core\Extension\ModuleHandlerInterface
+   */
+  protected $moduleHandler;
+
   /**
    * Constructs a Permissions object.
    *
@@ -40,11 +47,14 @@ class Permissions extends ManyToOne {
    *   The plugin implementation definition.
    * @param \Drupal\user\PermissionHandlerInterface $permission_handler
    *   The permission handler.
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler.
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, PermissionHandlerInterface $permission_handler) {
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, PermissionHandlerInterface $permission_handler, ModuleHandlerInterface $module_handler) {
     parent::__construct($configuration, $plugin_id, $plugin_definition);
 
     $this->permissionHandler = $permission_handler;
+    $this->moduleHandler = $module_handler;
   }
 
   /**
@@ -55,18 +65,17 @@ public static function create(ContainerInterface $container, array $configuratio
       $configuration,
       $plugin_id,
       $plugin_definition,
-      $container->get('user.permissions')
+      $container->get('user.permissions'),
+      $container->get('module_handler')
     );
   }
 
   public function getValueOptions() {
     if (!isset($this->valueOptions)) {
-      $module_info = system_get_info('module');
-
       $permissions = $this->permissionHandler->getPermissions();
       foreach ($permissions as $perm => $perm_item) {
         $provider = $perm_item['provider'];
-        $display_name = $module_info[$provider]['name'];
+        $display_name = $this->moduleHandler->getName($provider);
         $this->valueOptions[$display_name][$perm] = SafeMarkup::checkPlain(strip_tags($perm_item['title']));
       }
     }
-- 
GitLab