From 30a012d94a966bcedb9727be697c7c0105c6f511 Mon Sep 17 00:00:00 2001
From: Roman Paska <roman.paska@gmail.com>
Date: Wed, 10 Jun 2020 10:43:23 +0300
Subject: [PATCH] fix(OptionsTSniff): Fix false positive '#options' property
 have to run through t() on non form element (#3062766 by zarabatana, Taran2L)

---
 .../Sniffs/General/OptionsTSniff.php            | 17 ++++++++++++++++-
 .../DrupalPractice/General/OptionsTUnitTest.inc | 14 ++++++++++++++
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/coder_sniffer/DrupalPractice/Sniffs/General/OptionsTSniff.php b/coder_sniffer/DrupalPractice/Sniffs/General/OptionsTSniff.php
index 09fdae7..49506c4 100644
--- a/coder_sniffer/DrupalPractice/Sniffs/General/OptionsTSniff.php
+++ b/coder_sniffer/DrupalPractice/Sniffs/General/OptionsTSniff.php
@@ -81,6 +81,21 @@ class OptionsTSniff implements Sniff
             $statementEnd = $tokens[$arrayToken]['bracket_closer'];
         }
 
+        // We want to find if the element "#options" belongs to a form element.
+        // Array with selectable options for a form element.
+        $formElements = [
+          "'checkboxes'",
+          "'radios'",
+          "'select'",
+          "'tableselect'",
+        ];
+        // Find beggining of the array containing "#options" element.
+        $startArray = $phpcsFile->findPrevious(T_EQUAL, $stackPtr, null, false, "=");
+        // Find next element on array of "#type".
+        $findType = $phpcsFile->findNext(T_CONSTANT_ENCAPSED_STRING, ($startArray + 1), null, false, "'#type'");
+        // Get the value of "#type".
+        $valueType = $phpcsFile->findNext(T_CONSTANT_ENCAPSED_STRING, ($findType + 1), null, false);
+
         // Go through the array by examining stuff after "=>".
         $arrow = $phpcsFile->findNext(T_DOUBLE_ARROW, ($arrayToken + 1), $statementEnd, false, null, true);
         while ($arrow !== false) {
@@ -95,7 +110,7 @@ class OptionsTSniff implements Sniff
             // and more than 3 characters long.
             if ($tokens[$arrayValue]['code'] === T_CONSTANT_ENCAPSED_STRING
                 && is_numeric(substr($tokens[$arrayValue]['content'], 1, -1)) === false
-                && strlen($tokens[$arrayValue]['content']) > 5
+                && strlen($tokens[$arrayValue]['content']) > 5 && in_array($tokens[$valueType]['content'], $formElements) === true
                 // Make sure that we don't check stuff in nested arrays within
                 // t() for example.
                 && $valueNestedParenthesis === $nestedParenthesis
diff --git a/tests/DrupalPractice/General/OptionsTUnitTest.inc b/tests/DrupalPractice/General/OptionsTUnitTest.inc
index 5714550..b4f7f67 100644
--- a/tests/DrupalPractice/General/OptionsTUnitTest.inc
+++ b/tests/DrupalPractice/General/OptionsTUnitTest.inc
@@ -56,3 +56,17 @@ $form['display']['hide_thumbnail'] = [
     '0' => t('No', [], ['context' => 'test']),
   ],
 ];
+
+$form['link'] = [
+  '#type' => 'link',
+  '#title' => t('Download'),
+  '#url' => Url::fromUri('internal:/'),
+  '#options' => [
+    'attributes' => [
+      'target' => '_blank',
+      'class' => [
+        'home',
+      ],
+    ],
+  ],
+];
-- 
2.26.2

