From 1003490b9936ad5ad9403fa2ab4fa27c6af17efe Mon Sep 17 00:00:00 2001
From: Nathaniel Catchpole <catch@35733.no-reply.drupal.org>
Date: Thu, 28 Apr 2016 21:46:32 +0100
Subject: [PATCH] Issue #2707261 by alexpott, jhodgdon: Calling moduleInvokeAll
 in Help block is wrong

---
 .../help/src/Plugin/Block/HelpBlock.php       | 19 +++++++++++-------
 core/modules/help/src/Tests/HelpBlockTest.php |  8 +++++++-
 .../help_page_test/help_page_test.module      |  2 ++
 .../help_page_test/help_page_test.routing.yml |  7 +++++++
 .../src/HelpPageTestController.php            | 10 ++++++++++
 .../more_help_page_test.info.yml              |  7 +++++++
 .../more_help_page_test.module                | 20 +++++++++++++++++++
 7 files changed, 65 insertions(+), 8 deletions(-)
 create mode 100644 core/modules/help/tests/modules/more_help_page_test/more_help_page_test.info.yml
 create mode 100644 core/modules/help/tests/modules/more_help_page_test/more_help_page_test.module

diff --git a/core/modules/help/src/Plugin/Block/HelpBlock.php b/core/modules/help/src/Plugin/Block/HelpBlock.php
index cf6467effa08..17dd88e95ee0 100644
--- a/core/modules/help/src/Plugin/Block/HelpBlock.php
+++ b/core/modules/help/src/Plugin/Block/HelpBlock.php
@@ -88,14 +88,19 @@ public function build() {
       return [];
     }
 
-    $help = $this->moduleHandler->invokeAll('help', array($this->routeMatch->getRouteName(), $this->routeMatch));
+    $implementations = $this->moduleHandler->getImplementations('help');
     $build = [];
-
-    // Remove any empty strings from $help.
-    foreach (array_filter($help) as $item) {
-      // Convert strings to #markup render arrays so that they will XSS admin
-      // filtered.
-      $build[] = is_array($item) ? $item : ['#markup' => $item];
+    $args = [
+      $this->routeMatch->getRouteName(),
+      $this->routeMatch,
+    ];
+    foreach ($implementations as $module) {
+      // Don't add empty strings to $build array.
+      if ($help = $this->moduleHandler->invoke($module, 'help', $args)) {
+        // Convert strings to #markup render arrays so that they will XSS admin
+        // filtered.
+        $build[] = is_array($help) ? $help : ['#markup' => $help];
+      }
     }
     return $build;
   }
diff --git a/core/modules/help/src/Tests/HelpBlockTest.php b/core/modules/help/src/Tests/HelpBlockTest.php
index 3a7a1723b0a9..f1ba62295bb1 100644
--- a/core/modules/help/src/Tests/HelpBlockTest.php
+++ b/core/modules/help/src/Tests/HelpBlockTest.php
@@ -14,7 +14,7 @@ class HelpBlockTest extends WebTestBase {
   /**
    * {@inheritdoc}
    */
-  public static $modules = ['help', 'help_page_test', 'block'];
+  public static $modules = ['help', 'help_page_test', 'block', 'more_help_page_test'];
 
   /**
    * The help block instance.
@@ -39,6 +39,12 @@ public function testHelp() {
     $this->drupalGet('help_page_test/no_help');
     // The help block should not appear when there is no help.
     $this->assertNoText($this->helpBlock->label());
+
+    // Ensure that if two hook_help() implementations both return a render array
+    // the output is as expected.
+    $this->drupalGet('help_page_test/test_array');
+    $this->assertText('Help text from more_help_page_test_help module.');
+    $this->assertText('Help text from help_page_test_help module.');
   }
 
 }
diff --git a/core/modules/help/tests/modules/help_page_test/help_page_test.module b/core/modules/help/tests/modules/help_page_test/help_page_test.module
index 2ad72255a837..67bcac33a832 100644
--- a/core/modules/help/tests/modules/help_page_test/help_page_test.module
+++ b/core/modules/help/tests/modules/help_page_test/help_page_test.module
@@ -19,6 +19,8 @@ function help_page_test_help($route_name, RouteMatchInterface $route_match) {
       return t('Read the <a href=":url">online documentation for the Help Page Test module</a>.', [':url' => 'http://www.example.com']);
     case 'help_page_test.has_help':
       return t('I have help!');
+    case 'help_page_test.test_array':
+      return ['#markup' => 'Help text from help_page_test_help module.'];
   }
 
   // Ensure that hook_help() can return an empty string and not cause the block
diff --git a/core/modules/help/tests/modules/help_page_test/help_page_test.routing.yml b/core/modules/help/tests/modules/help_page_test/help_page_test.routing.yml
index 7450e58869cd..54cbf26a929a 100644
--- a/core/modules/help/tests/modules/help_page_test/help_page_test.routing.yml
+++ b/core/modules/help/tests/modules/help_page_test/help_page_test.routing.yml
@@ -11,3 +11,10 @@ help_page_test.no_help:
     _controller: '\Drupal\help_page_test\HelpPageTestController::noHelp'
   requirements:
     _access: 'TRUE'
+
+help_page_test.test_array:
+  path: '/help_page_test/test_array'
+  defaults:
+    _controller: '\Drupal\help_page_test\HelpPageTestController::testArray'
+  requirements:
+    _access: 'TRUE'
diff --git a/core/modules/help/tests/modules/help_page_test/src/HelpPageTestController.php b/core/modules/help/tests/modules/help_page_test/src/HelpPageTestController.php
index 02c4e65fcd54..da499d6f12dc 100644
--- a/core/modules/help/tests/modules/help_page_test/src/HelpPageTestController.php
+++ b/core/modules/help/tests/modules/help_page_test/src/HelpPageTestController.php
@@ -27,4 +27,14 @@ public function noHelp() {
     return ['#markup' => 'A route without help.'];
   }
 
+  /**
+   * Provides a route which has multiple array returns from hook_help().
+   *
+   * @return array
+   *   A render array.
+   */
+  public function testArray() {
+    return ['#markup' => 'A route which has multiple array returns from hook_help().'];
+  }
+
 }
diff --git a/core/modules/help/tests/modules/more_help_page_test/more_help_page_test.info.yml b/core/modules/help/tests/modules/more_help_page_test/more_help_page_test.info.yml
new file mode 100644
index 000000000000..cc15ce4b322a
--- /dev/null
+++ b/core/modules/help/tests/modules/more_help_page_test/more_help_page_test.info.yml
@@ -0,0 +1,7 @@
+name: 'More Help Page Test'
+type: module
+description: 'Module to test the help page.'
+package: Testing
+version: VERSION
+core: 8.x
+hidden: true
diff --git a/core/modules/help/tests/modules/more_help_page_test/more_help_page_test.module b/core/modules/help/tests/modules/more_help_page_test/more_help_page_test.module
new file mode 100644
index 000000000000..60eb4fc83034
--- /dev/null
+++ b/core/modules/help/tests/modules/more_help_page_test/more_help_page_test.module
@@ -0,0 +1,20 @@
+<?php
+
+/**
+ * @file
+ * More Help Page Test module to test the help blocks.
+ */
+
+use \Drupal\Core\Routing\RouteMatchInterface;
+
+/**
+ * Implements hook_help().
+ */
+function more_help_page_test_help($route_name, RouteMatchInterface $route_match) {
+
+  switch ($route_name) {
+    // Return help for the same route as the help_page_test module.
+    case 'help_page_test.test_array':
+      return ['#markup' => 'Help text from more_help_page_test_help module.'];
+  }
+}
-- 
GitLab