From ba704efd5440cd0718ab938ae31814965ce248e2 Mon Sep 17 00:00:00 2001
From: M Parker <mparker17@536298.no-reply.drupal.org>
Date: Wed, 26 Aug 2015 09:26:44 -0400
Subject: [PATCH] 1742438-52

---
 includes/form.inc                         | 37 ++++++++++++++++--
 modules/simpletest/tests/form.test        | 43 +++++++++++++++++++++
 modules/simpletest/tests/form_test.module | 63 +++++++++++++++++++++++++++++++
 3 files changed, 139 insertions(+), 4 deletions(-)

diff --git a/includes/form.inc b/includes/form.inc
index f1691ad..0f9084f 100644
--- a/includes/form.inc
+++ b/includes/form.inc
@@ -3871,11 +3871,40 @@ function form_process_vertical_tabs($element, &$form_state) {
  */
 function theme_vertical_tabs($variables) {
   $element = $variables['element'];
-  // Add required JavaScript and Stylesheet.
-  drupal_add_library('system', 'drupal.vertical-tabs');
 
-  $output = '<h2 class="element-invisible">' . t('Vertical Tabs') . '</h2>';
-  $output .= '<div class="vertical-tabs-panes">' . $element['#children'] . '</div>';
+  // Even if there are no tabs the element will still have a child element for
+  // the active tab. We need to iterate over the tabs to ascertain if any
+  // are visible before showing the wrapper and h2.
+  $visible_tab = FALSE;
+  $output = '';
+  // First, look for any elements attached via #group (and thus in ['group']).
+  foreach (element_children($element['group']) as $tab_index) {
+    if (!isset($element['group'][$tab_index]['#access']) ||
+        !empty($element['group'][$tab_index]['#access'])) {
+      $visible_tab = TRUE;
+      break;
+    }
+  }
+  // If no #group elements are found, check for direct fieldset children.
+  if (!$visible_tab) {
+    foreach (element_children($element) as $child_index) {
+      if ($child_index != 'group' &&
+          $element[$child_index]['#type'] == 'fieldset' &&
+          (!isset($element[$child_index]['#access']) ||
+           !empty($element[$child_index]['#access']))) {
+        $visible_tab = TRUE;
+        break;
+      }
+    }
+  }
+
+  if ($visible_tab) {
+    // Add required JavaScript and Stylesheet.
+    drupal_add_library('system', 'drupal.vertical-tabs');
+
+    $output = '<h2 class="element-invisible">' . t('Vertical Tabs') . '</h2>';
+    $output .= '<div class="vertical-tabs-panes">' . $element['#children'] . '</div>';
+  }
   return $output;
 }
 
diff --git a/modules/simpletest/tests/form.test b/modules/simpletest/tests/form.test
index 0bf6c8c..ce3deab 100644
--- a/modules/simpletest/tests/form.test
+++ b/modules/simpletest/tests/form.test
@@ -1051,6 +1051,10 @@ class FormsElementsVerticalTabsFunctionalTest extends DrupalWebTestCase {
 
   function setUp() {
     parent::setUp('form_test');
+
+    $this->admin_user = $this->drupalCreateUser(array('access vertical_tab_test tabs'));
+    $this->web_user = $this->drupalCreateUser();
+    $this->drupalLogin($this->admin_user);
   }
 
   /**
@@ -1064,6 +1068,45 @@ class FormsElementsVerticalTabsFunctionalTest extends DrupalWebTestCase {
     $position2 = strpos($this->content, 'misc/collapse.js');
     $this->assertTrue($position1 !== FALSE && $position2 !== FALSE && $position1 < $position2, 'vertical-tabs.js is included before collapse.js');
   }
+
+  /**
+   * Ensures that the vertical-tabs wrapper markup is not shown if the user
+   * does not have access to any of the tabs.
+   */
+  function testWrapperNotShownWhenEmpty() {
+    // Test admin user can see vertical tabs and wrapper.
+    $this->drupalGet('form_test/vertical-tabs');
+    $wrapper = $this->xpath("//div[@class='vertical-tabs-panes']");
+    $this->assertTrue(isset($wrapper[0]), 'Vertical tab panes found.');
+
+    // Test wrapper markup not present for non-privileged web user.
+    $this->drupalLogin($this->web_user);
+    $this->drupalGet('form_test/vertical-tabs');
+    $wrapper = $this->xpath("//div[@class='vertical-tabs-panes']");
+    $this->assertFalse(isset($wrapper[0]), 'Vertical tab wrappers are not displayed to unprivileged users.');
+  }
+
+  /**
+   * Ensures that fieldset tabs show if:
+   * 1. They are non-children of the wrapper with #group set.
+   * 2. They are children of the wrapper with #group set.
+   * 3. They are children of the wrapper with no #group set for any child.
+   */
+  function testTabsShowForChildOrGroup() {
+    // Test we can see a non-child with #group set.
+    $this->drupalGet('form_test/vertical-tabs');
+    $tab1 = $this->xpath("//div[@class='vertical-tabs-panes']/fieldset[@id='edit-tab1']");
+    $this->assertTrue(isset($tab1[0]), 'Non-child with #group found.');
+
+    // Test we can see a child with #group set.
+    $tab3 = $this->xpath("//div[@class='vertical-tabs-panes']/fieldset[@id='edit-tab3']");
+    $this->assertTrue(isset($tab3[0]), 'Child with #group found.');
+
+    // Test we can see children without #group set.
+    $this->drupalGet('form_test/vertical-tabs-2');
+    $tab2 = $this->xpath("//div[@class='vertical-tabs-panes']/fieldset[@id='edit-tab2']");
+    $this->assertTrue(isset($tab2[0]), 'Children with no #group found.');
+  }
 }
 
 /**
diff --git a/modules/simpletest/tests/form_test.module b/modules/simpletest/tests/form_test.module
index 602b409..ea204c3 100644
--- a/modules/simpletest/tests/form_test.module
+++ b/modules/simpletest/tests/form_test.module
@@ -82,6 +82,14 @@ function form_test_menu() {
     'type' => MENU_CALLBACK,
   );
 
+  $items['form_test/vertical-tabs-2'] = array(
+    'title' => 'Vertical tabs tests',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('_form_test_vertical_tabs_2_form'),
+    'access arguments' => array('access content'),
+    'type' => MENU_CALLBACK,
+  );
+
   $items['form_test/form-storage'] = array(
     'title' => 'Form storage test',
     'page callback' => 'drupal_get_form',
@@ -251,6 +259,18 @@ function form_test_menu() {
 }
 
 /**
+ * Implements hook_permission().
+ */
+function form_test_permission() {
+  $perms = array(
+    'access vertical_tab_test tabs' => array(
+      'title' => t('Access vertical_tab_test tabs'),
+    ),
+  );
+  return $perms;
+}
+
+/**
  * Form submit handler to return form values as JSON.
  */
 function _form_test_submit_values_json($form, &$form_state) {
@@ -679,6 +699,7 @@ function _form_test_vertical_tabs_form($form, &$form_state) {
     '#title' => t('Tab 1'),
     '#collapsible' => TRUE,
     '#group' => 'vertical_tabs',
+    '#access' => user_access('access vertical_tab_test tabs')
   );
   $form['tab1']['field1'] = array(
     '#title' => t('Field 1'),
@@ -689,11 +710,53 @@ function _form_test_vertical_tabs_form($form, &$form_state) {
     '#title' => t('Tab 2'),
     '#collapsible' => TRUE,
     '#group' => 'vertical_tabs',
+    '#access' => user_access('access vertical_tab_test tabs')
   );
   $form['tab2']['field2'] = array(
     '#title' => t('Field 2'),
     '#type' => 'textfield',
   );
+  $form['vertical_tabs']['tab3'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Tab 3'),
+    '#collapsible' => TRUE,
+    '#group' => 'vertical_tabs',
+    '#access' => user_access('access vertical_tab_test tabs')
+  );
+  $form['vertical_tabs']['tab3']['field3'] = array(
+    '#title' => t('Field 3'),
+    '#type' => 'textfield',
+  );
+  return $form;
+}
+
+/**
+ * Tests functionality of vertical tabs - children without an explicit #group.
+ */
+function _form_test_vertical_tabs_2_form($form, &$form_state) {
+  $form['vertical_tabs'] = array(
+    '#type' => 'vertical_tabs',
+  );
+  $form['vertical_tabs']['tab1'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Tab 1'),
+    '#collapsible' => TRUE,
+    '#access' => user_access('access vertical_tab_test tabs')
+  );
+  $form['vertical_tabs']['tab1']['field1'] = array(
+    '#title' => t('Field 1'),
+    '#type' => 'textfield',
+  );
+  $form['vertical_tabs']['tab2'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Tab 2'),
+    '#collapsible' => TRUE,
+    '#access' => user_access('access vertical_tab_test tabs')
+  );
+  $form['vertical_tabs']['tab2']['field2'] = array(
+    '#title' => t('Field 2'),
+    '#type' => 'textfield',
+  );
   return $form;
 }
 
-- 
2.5.0

