From 8ea1c48ee907fa4bb6e8a92d269a9d6c787a4b84 Mon Sep 17 00:00:00 2001
From: Nathaniel Catchpole <catch@35733.no-reply.drupal.org>
Date: Thu, 8 Nov 2018 15:50:48 +0000
Subject: [PATCH] Issue #2902412 by Jo Fitzgerald, andypost, mfernea, andriyun:
 Fix 'Drupal.Strings.UnnecessaryStringConcat' coding standard

---
 core/lib/Drupal/Core/Asset/AssetResolver.php  |  2 +-
 .../lib/Drupal/Core/Command/DbDumpCommand.php | 11 ++-
 .../Drupal/Core/Entity/EntityTypeManager.php  |  2 +-
 core/lib/Drupal/Core/Render/theme.api.php     |  2 +-
 core/modules/config/config.module             |  2 +-
 .../src/Functional/ConfigExportUITest.php     |  2 +-
 .../src/Plugin/migrate/process/FieldLink.php  |  2 +-
 .../theme_suggestions_test.module             |  6 +-
 .../modules/theme_test/theme_test.module      |  2 +-
 .../src/Functional/Mail/HtmlToTextTest.php    | 86 ++++++++++---------
 .../user/src/Plugin/views/field/Roles.php     |  4 +-
 core/phpcs.xml.dist                           |  1 +
 12 files changed, 67 insertions(+), 55 deletions(-)

diff --git a/core/lib/Drupal/Core/Asset/AssetResolver.php b/core/lib/Drupal/Core/Asset/AssetResolver.php
index d90506e4a060..c0b0f26fa75e 100644
--- a/core/lib/Drupal/Core/Asset/AssetResolver.php
+++ b/core/lib/Drupal/Core/Asset/AssetResolver.php
@@ -312,7 +312,7 @@ public function getJsAssets(AttachedAssetsInterface $assets, $optimize) {
         $settings = $this->getJsSettingsAssets($assets);
         // Allow modules to add cached JavaScript settings.
         foreach ($this->moduleHandler->getImplementations('js_settings_build') as $module) {
-          $function = $module . '_' . 'js_settings_build';
+          $function = $module . '_js_settings_build';
           $function($settings, $assets);
         }
       }
diff --git a/core/lib/Drupal/Core/Command/DbDumpCommand.php b/core/lib/Drupal/Core/Command/DbDumpCommand.php
index 26b4363cdd3c..b5db61251750 100644
--- a/core/lib/Drupal/Core/Command/DbDumpCommand.php
+++ b/core/lib/Drupal/Core/Command/DbDumpCommand.php
@@ -418,10 +418,13 @@ protected function getTableScript($table, array $schema, array $data) {
       foreach ($data as $record) {
         $insert .= "->values(" . Variable::export($record) . ")\n";
       }
-      $output .= "\$connection->insert('" . $table . "')\n"
-        . "->fields(" . Variable::export(array_keys($schema['fields'])) . ")\n"
-        . $insert
-        . "->execute();\n\n";
+      $fields = Variable::export(array_keys($schema['fields']));
+      $output .= <<<EOT
+\$connection->insert('$table')
+->fields($fields)
+{$insert}->execute();
+
+EOT;
     }
     return $output;
   }
diff --git a/core/lib/Drupal/Core/Entity/EntityTypeManager.php b/core/lib/Drupal/Core/Entity/EntityTypeManager.php
index 9d7fdc5e9294..69c2736232f0 100644
--- a/core/lib/Drupal/Core/Entity/EntityTypeManager.php
+++ b/core/lib/Drupal/Core/Entity/EntityTypeManager.php
@@ -108,7 +108,7 @@ protected function findDefinitions() {
     // Directly call the hook implementations to pass the definitions to them
     // by reference, so new entity types can be added.
     foreach ($this->moduleHandler->getImplementations('entity_type_build') as $module) {
-      $function = $module . '_' . 'entity_type_build';
+      $function = $module . '_entity_type_build';
       $function($definitions);
     }
     foreach ($definitions as $plugin_id => $definition) {
diff --git a/core/lib/Drupal/Core/Render/theme.api.php b/core/lib/Drupal/Core/Render/theme.api.php
index 2bb2eb9aa8fd..d52a7c3da956 100644
--- a/core/lib/Drupal/Core/Render/theme.api.php
+++ b/core/lib/Drupal/Core/Render/theme.api.php
@@ -715,7 +715,7 @@ function hook_theme_suggestions_alter(array &$suggestions, array $variables, $ho
  */
 function hook_theme_suggestions_HOOK_alter(array &$suggestions, array $variables) {
   if (empty($variables['header'])) {
-    $suggestions[] = 'hookname__' . 'no_header';
+    $suggestions[] = 'hookname__no_header';
   }
 }
 
diff --git a/core/modules/config/config.module b/core/modules/config/config.module
index b280fe84fa28..c47cf300ca4b 100644
--- a/core/modules/config/config.module
+++ b/core/modules/config/config.module
@@ -70,7 +70,7 @@ function config_file_download($uri) {
       $date = DateTime::createFromFormat('U', $request->server->get('REQUEST_TIME'));
       $date_string = $date->format('Y-m-d-H-i');
       $hostname = str_replace('.', '-', $request->getHttpHost());
-      $filename = 'config' . '-' . $hostname . '-' . $date_string . '.tar.gz';
+      $filename = 'config-' . $hostname . '-' . $date_string . '.tar.gz';
       $disposition = 'attachment; filename="' . $filename . '"';
       return [
         'Content-disposition' => $disposition,
diff --git a/core/modules/config/tests/src/Functional/ConfigExportUITest.php b/core/modules/config/tests/src/Functional/ConfigExportUITest.php
index d92071e89de4..4cd23acf56ce 100644
--- a/core/modules/config/tests/src/Functional/ConfigExportUITest.php
+++ b/core/modules/config/tests/src/Functional/ConfigExportUITest.php
@@ -57,7 +57,7 @@ public function testExport() {
     $this->assertTrue($header_match, "Header with filename matches the expected format.");
 
     // Extract the archive and verify it's not empty.
-    $file_path = file_directory_temp() . '/' . 'config.tar.gz';
+    $file_path = file_directory_temp() . '/config.tar.gz';
     $archiver = new Tar($file_path);
     $archive_contents = $archiver->listContents();
     $this->assert(!empty($archive_contents), 'Downloaded archive file is not empty.');
diff --git a/core/modules/link/src/Plugin/migrate/process/FieldLink.php b/core/modules/link/src/Plugin/migrate/process/FieldLink.php
index 4d3d7eec6745..680049ce5088 100644
--- a/core/modules/link/src/Plugin/migrate/process/FieldLink.php
+++ b/core/modules/link/src/Plugin/migrate/process/FieldLink.php
@@ -85,7 +85,7 @@ protected function canonicalizeUri($uri) {
       $anchor = "(?:#[a-z0-9" . $link_ichars . "_\-\.~+%=&,$'():;*@\[\]\/\?]*)";
 
       // The rest of the path for a standard URL.
-      $end = $directories . '?' . $query . '?' . $anchor . '?' . '$/i';
+      $end = $directories . '?' . $query . '?' . $anchor . '?$/i';
 
       if (!preg_match($internal_pattern . $end, $uri)) {
         $link_domains = '[a-z][a-z0-9-]{1,62}';
diff --git a/core/modules/system/tests/modules/theme_suggestions_test/theme_suggestions_test.module b/core/modules/system/tests/modules/theme_suggestions_test/theme_suggestions_test.module
index cbc5b380206a..5d4420270a8a 100644
--- a/core/modules/system/tests/modules/theme_suggestions_test/theme_suggestions_test.module
+++ b/core/modules/system/tests/modules/theme_suggestions_test/theme_suggestions_test.module
@@ -32,21 +32,21 @@ function theme_suggestions_test_theme_suggestions_alter(array &$suggestions, arr
  */
 function theme_suggestions_test_theme_suggestions_theme_test_suggestions_alter(array &$suggestions, array $variables) {
   \Drupal::messenger()->addStatus(__FUNCTION__ . '() executed.');
-  $suggestions[] = 'theme_test_suggestions__' . 'module_override';
+  $suggestions[] = 'theme_test_suggestions__module_override';
 }
 
 /**
  * Implements hook_theme_suggestions_HOOK_alter().
  */
 function theme_suggestions_test_theme_suggestions_theme_test_function_suggestions_alter(array &$suggestions, array $variables) {
-  $suggestions[] = 'theme_test_function_suggestions__' . 'module_override';
+  $suggestions[] = 'theme_test_function_suggestions__module_override';
 }
 
 /**
  * Implements hook_theme_suggestions_HOOK_alter().
  */
 function theme_suggestions_test_theme_suggestions_theme_test_specific_suggestions_alter(array &$suggestions, array $variables) {
-  $suggestions[] = 'theme_test_specific_suggestions__' . 'variant__foo';
+  $suggestions[] = 'theme_test_specific_suggestions__variant__foo';
 }
 
 /**
diff --git a/core/modules/system/tests/modules/theme_test/theme_test.module b/core/modules/system/tests/modules/theme_test/theme_test.module
index 901449696caf..701f033666dd 100644
--- a/core/modules/system/tests/modules/theme_test/theme_test.module
+++ b/core/modules/system/tests/modules/theme_test/theme_test.module
@@ -171,7 +171,7 @@ function theme_theme_test_function_suggestions($variables) {
  * Implements hook_theme_suggestions_HOOK().
  */
 function theme_test_theme_suggestions_theme_test_suggestion_provided(array $variables) {
-  return ['theme_test_suggestion_provided__' . 'foo'];
+  return ['theme_test_suggestion_provided__foo'];
 }
 
 /**
diff --git a/core/modules/system/tests/src/Functional/Mail/HtmlToTextTest.php b/core/modules/system/tests/src/Functional/Mail/HtmlToTextTest.php
index 02bfca844126..97092232d76e 100644
--- a/core/modules/system/tests/src/Functional/Mail/HtmlToTextTest.php
+++ b/core/modules/system/tests/src/Functional/Mail/HtmlToTextTest.php
@@ -54,8 +54,8 @@ protected function assertHtmlToText($html, $text, $message, $allowed_tags = NULL
     $result = MailFormatHelper::htmlToText($html, $allowed_tags);
     $pass = $this->assertEqual($result, $text, Html::escape($message));
     $verbose = 'html = <pre>' . $this->stringToHtml($html)
-      . '</pre><br />' . 'result = <pre>' . $this->stringToHtml($result)
-      . '</pre><br />' . 'expected = <pre>' . $this->stringToHtml($text)
+      . '</pre><br />result = <pre>' . $this->stringToHtml($result)
+      . '</pre><br />expected = <pre>' . $this->stringToHtml($text)
       . '</pre>';
     $this->verbose($verbose);
     if (!$pass) {
@@ -212,27 +212,30 @@ public function testDrupalHtmltoTextCollapsesWhitespace() {
    * (at least) a newline in the plaintext version.
    */
   public function testDrupalHtmlToTextBlockTagToNewline() {
-    $input = '[text]'
-      . '<blockquote>[blockquote]</blockquote>'
-      . '<br />[br]'
-      . '<dl><dt>[dl-dt]</dt>'
-      . '<dt>[dt]</dt>'
-      . '<dd>[dd]</dd>'
-      . '<dd>[dd-dl]</dd></dl>'
-      . '<h1>[h1]</h1>'
-      . '<h2>[h2]</h2>'
-      . '<h3>[h3]</h3>'
-      . '<h4>[h4]</h4>'
-      . '<h5>[h5]</h5>'
-      . '<h6>[h6]</h6>'
-      . '<hr />[hr]'
-      . '<ol><li>[ol-li]</li>'
-      . '<li>[li]</li>'
-      . '<li>[li-ol]</li></ol>'
-      . '<p>[p]</p>'
-      . '<ul><li>[ul-li]</li>'
-      . '<li>[li-ul]</li></ul>'
-      . '[text]';
+    $input = <<<'EOT'
+[text]
+<blockquote>[blockquote]</blockquote>
+<br />[br]
+<dl><dt>[dl-dt]</dt>
+<dt>[dt]</dt>
+<dd>[dd]</dd>
+<dd>[dd-dl]</dd></dl>
+<h1>[h1]</h1>
+<h2>[h2]</h2>
+<h3>[h3]</h3>
+<h4>[h4]</h4>
+<h5>[h5]</h5>
+<h6>[h6]</h6>
+<hr />[hr]
+<ol><li>[ol-li]</li>
+<li>[li]</li>
+<li>[li-ol]</li></ol>
+<p>[p]</p>
+<ul><li>[ul-li]</li>
+<li>[li-ul]</li></ul>
+[text]
+EOT;
+    $input = str_replace(["\r", "\n"], '', $input);
     $output = MailFormatHelper::htmlToText($input);
     $pass = $this->assertFalse(
       preg_match('/\][^\n]*\[/s', $output),
@@ -288,23 +291,28 @@ public function testHeaderSeparation() {
    */
   public function testFootnoteReferences() {
     global $base_path, $base_url;
-    $source = '<a href="http://www.example.com/node/1">Host and path</a>'
-      . '<br /><a href="http://www.example.com">Host, no path</a>'
-      . '<br /><a href="' . $base_path . 'node/1">Path, no host</a>'
-      . '<br /><a href="node/1">Relative path</a>';
+    $source = <<<EOT
+<a href="http://www.example.com/node/1">Host and path</a>
+<br /><a href="http://www.example.com">Host, no path</a>
+<br /><a href="{$base_path}node/1">Path, no host</a>
+<br /><a href="node/1">Relative path</a>
+EOT;
+    $source = str_replace(["\r", "\n"], '', $source);
     // @todo Footnote URLs should be absolute.
-    $tt = "Host and path [1]"
-      . "\nHost, no path [2]"
-      // @todo The following two references should be combined.
-      . "\nPath, no host [3]"
-      . "\nRelative path [4]"
-      . "\n"
-      . "\n[1] http://www.example.com/node/1"
-      . "\n[2] http://www.example.com"
-      // @todo The following two references should be combined.
-      . "\n[3] $base_url/node/1"
-      . "\n[4] node/1\n";
-    $this->assertHtmlToText($source, $tt, 'Footnotes');
+    // @todo The last two references should be combined.
+    $text = <<<EOT
+Host and path [1]
+Host, no path [2]
+Path, no host [3]
+Relative path [4]
+
+[1] http://www.example.com/node/1
+[2] http://www.example.com
+[3] $base_url/node/1
+[4] node/1
+
+EOT;
+    $this->assertHtmlToText($source, $text, 'Footnotes');
   }
 
   /**
diff --git a/core/modules/user/src/Plugin/views/field/Roles.php b/core/modules/user/src/Plugin/views/field/Roles.php
index eec26f88ac21..c1cd8969e898 100644
--- a/core/modules/user/src/Plugin/views/field/Roles.php
+++ b/core/modules/user/src/Plugin/views/field/Roles.php
@@ -101,8 +101,8 @@ protected function documentSelfTokens(&$tokens) {
 
   protected function addSelfTokens(&$tokens, $item) {
     if (!empty($item['role'])) {
-      $tokens['{{ ' . $this->options['id'] . '__role' . ' }}'] = $item['role'];
-      $tokens['{{ ' . $this->options['id'] . '__rid' . ' }}'] = $item['rid'];
+      $tokens['{{ ' . $this->options['id'] . '__role }}'] = $item['role'];
+      $tokens['{{ ' . $this->options['id'] . '__rid }}'] = $item['rid'];
     }
   }
 
diff --git a/core/phpcs.xml.dist b/core/phpcs.xml.dist
index 2427d3441238..b5f3f4847b88 100644
--- a/core/phpcs.xml.dist
+++ b/core/phpcs.xml.dist
@@ -130,6 +130,7 @@
   <rule ref="Drupal.Semantics.PregSecurity"/>
   <rule ref="Drupal.Semantics.TInHookMenu"/>
   <rule ref="Drupal.Semantics.TInHookSchema"/>
+  <rule ref="Drupal.Strings.UnnecessaryStringConcat"/>
   <rule ref="Drupal.WhiteSpace.CloseBracketSpacing"/>
   <rule ref="Drupal.WhiteSpace.Comma"/>
   <rule ref="Drupal.WhiteSpace.EmptyLines"/>
-- 
GitLab