From 315fdb5d754a4e5c0ace7742e67cc6d0ad5a208c Mon Sep 17 00:00:00 2001
From: Mark Carver <mark.carver@me.com>
Date: Sat, 13 Jan 2018 02:22:38 -0600
Subject: [PATCH] Issue #2901106 by markcarver: Multilingual dropbutton links
 do not contain correct language identifier

Signed-off-by: Mark Carver <mark.carver@me.com>
---
 src/Plugin/Preprocess/BootstrapDropdown.php | 34 ++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/src/Plugin/Preprocess/BootstrapDropdown.php b/src/Plugin/Preprocess/BootstrapDropdown.php
index 5ccff87..315e022 100644
--- a/src/Plugin/Preprocess/BootstrapDropdown.php
+++ b/src/Plugin/Preprocess/BootstrapDropdown.php
@@ -12,6 +12,7 @@ use Drupal\bootstrap\Utility\Unicode;
 use Drupal\bootstrap\Utility\Variables;
 use Drupal\Component\Utility\Html;
 use Drupal\Component\Utility\NestedArray;
+use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Url;
 
 /**
@@ -73,6 +74,20 @@ class BootstrapDropdown extends PreprocessBase implements PreprocessInterface {
             $element['url'] = Url::fromRoute('<none>');
           }
 
+          $attributes = isset($element['attributes']) ? $element['attributes'] : [];
+          $wrapper_attributes = isset($element['wrapper_attributes']) ? $element['wrapper_attributes'] : [];
+
+          if (isset($element['language']) && $element['language'] instanceof LanguageInterface) {
+            $attributes['hreflang'] = $element['language']->getId();
+            $wrapper_attributes['hreflang'] = $element['language']->getId();
+
+            // Ensure the Url language is set on the object itself.
+            // @todo Possibly a core bug?
+            if (empty($element['url']->getOption('language'))) {
+              $element['url']->setOption('language', $element['language']);
+            }
+          }
+
           // Preserve query parameters (if any)
           if (!empty($element['query'])) {
             $url_query = $element['url']->getOption('query') ?: [];
@@ -85,7 +100,8 @@ class BootstrapDropdown extends PreprocessBase implements PreprocessInterface {
             '#title' => $element['title'],
             '#url' => $element['url'],
             '#ajax' => isset($element['ajax']) ? $element['ajax'] : [],
-            '#attributes' => isset($element['attributes']) ? $element['attributes'] : [],
+            '#attributes' => $attributes,
+            '#wrapper_attributes' => $wrapper_attributes,
           ];
         }
       }
@@ -115,14 +131,10 @@ class BootstrapDropdown extends PreprocessBase implements PreprocessInterface {
           $primary_action = $child->addClass('hidden');
         }
 
-        // If actually a "link", add it to the items array directly.
-        if ($child->isType('link')) {
-          $items->$key->link = $child->getArrayCopy();
-        }
-        // Otherwise, convert into a proper link.
-        else {
+        // Convert into a proper link.
+        if (!$child->isType('link')) {
           // Hide the original element
-          $items->$key->element = $child->addClass('hidden')->getArrayCopy();
+          $element = $child->addClass('hidden')->getArrayCopy();
 
           // Retrieve any set HTML identifier for the link, generating a new
           // one if necessary.
@@ -132,7 +144,7 @@ class BootstrapDropdown extends PreprocessBase implements PreprocessInterface {
             $child->setAttribute('id', $id);
           }
 
-          $items->$key->link = Element::createStandalone([
+          $child = Element::createStandalone([
             '#type' => 'link',
             '#title' => $child->getProperty('value', $child->getProperty('title', $child->getProperty('text'))),
             '#url' => Url::fromUserInput('#'),
@@ -141,9 +153,11 @@ class BootstrapDropdown extends PreprocessBase implements PreprocessInterface {
 
           // Also hide the real link if it's the primary action.
           if ($i === 0) {
-            $items->$key->link->addClass('hidden');
+            $child->addClass('hidden');
           }
         }
+
+        $items->$key = $child->getArrayCopy();
       }
 
       // Create a toggle button, extracting relevant info from primary action.
-- 
2.15.1

