diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/relationship/GroupwiseMax.php b/core/modules/views/lib/Drupal/views/Plugin/views/relationship/GroupwiseMax.php
index 6f8f2f0..35b2bf6 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/relationship/GroupwiseMax.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/relationship/GroupwiseMax.php
@@ -88,7 +88,7 @@ public function buildOptionsForm(&$form, &$form_state) {
     parent::buildOptionsForm($form, $form_state);
 
     // Get the sorts that apply to our base.
-    $sorts = views_fetch_fields($this->definition['base'], 'sort');
+    $sorts = Views::viewsDataHelper()->fetchFields($this->definition['base'], 'sort');
     foreach ($sorts as $sort_id => $sort) {
       $sort_options[$sort_id] = "$sort[group]: $sort[title]";
     }
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php
index 6fa70c9..50a8215 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php
@@ -831,7 +831,7 @@ protected function defaultDisplayFiltersUser(array $form, array &$form_state) {
       // the base table for the view; the taxonomy vocabulary machine_name, for
       // example, is stored in taxonomy_vocabulary, not taxonomy_term_data.
       module_load_include('inc', 'views_ui', 'admin');
-      $fields = views_fetch_fields($this->base_table, 'filter');
+      $fields = Views::viewsDataHelper()->fetchFields($this->base_table, 'filter');
       if (isset($fields[$this->base_table . '.' . $bundle_key])) {
         $table = $this->base_table;
       }
diff --git a/core/modules/views/lib/Drupal/views/Tests/ViewTestData.php b/core/modules/views/lib/Drupal/views/Tests/ViewTestData.php
index a86e2b3..a574474 100644
--- a/core/modules/views/lib/Drupal/views/Tests/ViewTestData.php
+++ b/core/modules/views/lib/Drupal/views/Tests/ViewTestData.php
@@ -137,18 +137,18 @@ public static function schemaDefinition() {
   public static function viewsData() {
     // Declaration of the base table.
     $data['views_test_data']['table'] = array(
-      'group' => t('Views test'),
+      'group' => 'Views test',
       'base' => array(
         'field' => 'id',
-        'title' => t('Views test data'),
-        'help' => t('Users who have created accounts on your site.'),
+        'title' => 'Views test data',
+        'help' => 'Users who have created accounts on your site.',
       ),
     );
 
     // Declaration of fields.
     $data['views_test_data']['id'] = array(
-      'title' => t('ID'),
-      'help' => t('The test data ID'),
+      'title' => 'ID',
+      'help' => 'The test data ID',
       'field' => array(
         'id' => 'numeric',
       ),
@@ -163,8 +163,8 @@ public static function viewsData() {
       ),
     );
     $data['views_test_data']['name'] = array(
-      'title' => t('Name'),
-      'help' => t('The name of the person'),
+      'title' => 'Name',
+      'help' => 'The name of the person',
       'field' => array(
         'id' => 'standard',
       ),
@@ -179,8 +179,8 @@ public static function viewsData() {
       ),
     );
     $data['views_test_data']['age'] = array(
-      'title' => t('Age'),
-      'help' => t('The age of the person'),
+      'title' => 'Age',
+      'help' => 'The age of the person',
       'field' => array(
         'id' => 'numeric',
       ),
@@ -195,8 +195,8 @@ public static function viewsData() {
       ),
     );
     $data['views_test_data']['job'] = array(
-      'title' => t('Job'),
-      'help' => t('The job of the person'),
+      'title' => 'Job',
+      'help' => 'The job of the person',
       'field' => array(
         'id' => 'standard',
       ),
@@ -211,8 +211,8 @@ public static function viewsData() {
       ),
     );
     $data['views_test_data']['created'] = array(
-      'title' => t('Created'),
-      'help' => t('The creation date of this record'),
+      'title' => 'Created',
+      'help' => 'The creation date of this record',
       'field' => array(
         'id' => 'date',
       ),
diff --git a/core/modules/views/lib/Drupal/views/Tests/ViewsDataTest.php b/core/modules/views/lib/Drupal/views/Tests/ViewsDataTest.php
index 84cebb1..4fc1fc8 100644
--- a/core/modules/views/lib/Drupal/views/Tests/ViewsDataTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/ViewsDataTest.php
@@ -8,6 +8,7 @@
 namespace Drupal\views\Tests;
 
 use Drupal\Core\Cache\MemoryCounterBackend;
+use Drupal\Core\Language\LanguageManager;
 use Drupal\views\ViewsData;
 
 /**
@@ -231,7 +232,7 @@ public function testCacheRequests() {
    */
   protected function initViewsData() {
     $this->memoryCounterBackend->resetCounter();
-    $this->viewsData = new ViewsData($this->memoryCounterBackend, $this->container->get('config.factory'), $this->container->get('module_handler'));
+    $this->viewsData = new ViewsData($this->memoryCounterBackend, $this->container->get('config.factory'), $this->container->get('module_handler'), $this->container->get('language_manager'));
   }
 
   /**
@@ -267,7 +268,8 @@ protected function assertCountIncrement($increment = TRUE) {
   protected function viewsData() {
     $data = parent::viewsData();
 
-    // Tweak the views data to have a base for testing views_fetch_fields().
+    // Tweak the views data to have a base for testing
+    // \Drupal\views\ViewsDataHelper::fetchFields().
     unset($data['views_test_data']['id']['field']);
     unset($data['views_test_data']['name']['argument']);
     unset($data['views_test_data']['age']['filter']);
@@ -282,75 +284,6 @@ protected function viewsData() {
     return $data;
   }
 
-
-  /**
-   * Tests the views_fetch_fields function().
-   */
-  public function testViewsFetchFields() {
-    $this->enableModules(array('views_ui'));
-    $this->container->get('module_handler')->loadInclude('views_ui', 'inc', 'admin');
-
-    $expected = array(
-      'field' => array(
-        'name',
-        'age',
-        'job',
-        'created',
-      ),
-      'argument' => array(
-        'id',
-        'age',
-        'job',
-        'created',
-      ),
-      'filter' => array(
-        'id',
-        'name',
-        'job',
-        'created',
-      ),
-      'sort' => array(
-        'id',
-        'name',
-        'age',
-        'created',
-      ),
-      'area' => array(
-        'created',
-        'job',
-        'age'
-      ),
-      'header' => array(
-        'created',
-        'job',
-        'age'
-      ),
-      'footer' => array(
-        'created',
-        'job',
-      ),
-    );
-
-    $handler_types = array('field', 'argument', 'filter', 'sort', 'area');
-    foreach ($handler_types as $handler_type) {
-      $fields = views_fetch_fields('views_test_data', $handler_type);
-      $expected_keys = array_walk($expected[$handler_type], function(&$item) {
-        $item = "views_test_data.$item";
-      });
-      $this->assertEqual($expected_keys, array_keys($fields), format_string('Handlers of type @handler_type are listed as expected.', array('@handler_type' => $handler_type)));
-    }
-
-    // Check for subtype filtering, so header and footer.
-    foreach (array('header', 'footer') as $sub_type) {
-      $fields = views_fetch_fields('views_test_data', 'area', FALSE, $sub_type);
-
-      $expected_keys = array_walk($expected[$sub_type], function(&$item) {
-        $item = "views_test_data.$item";
-      });
-      $this->assertEqual($expected_keys, array_keys($fields), format_string('Sub_type @sub_type is filtered as expected.', array('@sub_type' => $sub_type)));
-    }
-  }
-
   /**
    * Tests the fetchBaseTables() method.
    */
diff --git a/core/modules/views/lib/Drupal/views/Views.php b/core/modules/views/lib/Drupal/views/Views.php
index 9af207c..e5d2d66 100644
--- a/core/modules/views/lib/Drupal/views/Views.php
+++ b/core/modules/views/lib/Drupal/views/Views.php
@@ -25,6 +25,16 @@ public static function viewsData() {
   }
 
   /**
+   * Returns the views data helper service.
+   *
+   * @return \Drupal\views\ViewsData
+   *   Returns a views data helper object.
+   */
+  public static function viewsDataHelper() {
+    return Drupal::service('views.views_data_helper');
+  }
+
+  /**
    * Returns the view executable factory service.
    *
    * @return \Drupal\views\ViewExecutableFactory
diff --git a/core/modules/views/lib/Drupal/views/ViewsData.php b/core/modules/views/lib/Drupal/views/ViewsData.php
index 887ae1e..2a1c2b2 100644
--- a/core/modules/views/lib/Drupal/views/ViewsData.php
+++ b/core/modules/views/lib/Drupal/views/ViewsData.php
@@ -11,6 +11,7 @@
 use Drupal\Core\Config\ConfigFactory;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Language\Language;
+use Drupal\Core\Language\LanguageManager;
 
 /**
  * Class to manage and lazy load cached views data.
@@ -72,6 +73,13 @@ class ViewsData {
   protected $moduleHandler;
 
   /**
+   * The language manager
+   *
+   * @var \Drupal\Core\Language\LanguageManager
+   */
+  protected $languageManager;
+
+  /**
    * Constructs this ViewsData object.
    *
    * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
@@ -80,12 +88,15 @@ class ViewsData {
    *   The configuration factory object to use.
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
    *   The module handler class to use for invoking hooks.
+   * @param \Drupal\Core\Language\LanguageManager $language_manager
+   *   The language manager.
    */
-  public function __construct(CacheBackendInterface $cache_backend, ConfigFactory $config, ModuleHandlerInterface $module_handler) {
+  public function __construct(CacheBackendInterface $cache_backend, ConfigFactory $config, ModuleHandlerInterface $module_handler, LanguageManager $language_manager) {
     $this->cacheBackend = $cache_backend;
     $this->moduleHandler = $module_handler;
+    $this->languageManager = $language_manager;
 
-    $this->langcode = language(Language::TYPE_INTERFACE)->langcode;
+    $this->langcode = $this->languageManager->getLanguage(Language::TYPE_INTERFACE)->langcode;
     $this->skipCache = $config->get('views.settings')->get('skip_cache');
   }
 
diff --git a/core/modules/views/lib/Drupal/views/ViewsDataHelper.php b/core/modules/views/lib/Drupal/views/ViewsDataHelper.php
new file mode 100644
index 0000000..b986746
--- /dev/null
+++ b/core/modules/views/lib/Drupal/views/ViewsDataHelper.php
@@ -0,0 +1,189 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\views\ViewsDataHelper.
+ */
+
+namespace Drupal\views;
+
+use Drupal\Component\Utility\Unicode;
+use Drupal\Component\Utility\String;
+
+/**
+ * Defines a helper class for stuff related to views data.
+ */
+class ViewsDataHelper {
+
+  /**
+   * The views data object, containing the cached information.
+   *
+   * @var \Drupal\views\ViewsData
+   */
+  protected $data;
+
+  /**
+   * A prepared list of all fields, keyed by base_table and handler type.
+   *
+   * @param array
+   */
+  protected $fields;
+
+  /**
+   * Constructs a ViewsData object.
+   *
+   * @param \Drupal\views\ViewsData $views_data
+   *   The views data object, containing the cached table information.
+   */
+  public function __construct(ViewsData $views_data) {
+    $this->data = $views_data;
+  }
+
+  /**
+   * Fetches a list of all fields available for a given base type.
+   *
+   * @param (array|string) $base
+   *   A list or a single base_table, for example node.
+   * @param string $type
+   *   The handler type, for example field or filter.
+   * @param bool $grouping
+   *   Should the result grouping by its 'group' label.
+   * @param string $sub_type
+   *   An optional sub type. E.g. Allows making an area plugin available for
+   *   header only, instead of header, footer, and empty regions.
+   *
+   * @return array
+   *   A keyed array of in the form of 'base_table' => 'Description'.
+   */
+  public function fetchFields($base, $type, $grouping = FALSE, $sub_type = NULL) {
+    if (!$this->fields) {
+      $data = $this->data->get();
+      // This constructs this ginormous multi dimensional array to
+      // collect the important data about fields. In the end,
+      // the structure looks a bit like this (using nid as an example)
+      // $strings['nid']['filter']['title'] = 'string'.
+      //
+      // This is constructed this way because the above referenced strings
+      // can appear in different places in the actual data structure so that
+      // the data doesn't have to be repeated a lot. This essentially lets
+      // each field have a cheap kind of inheritance.
+
+      foreach ($data as $table => $table_data) {
+        $bases = array();
+        $strings = array();
+        $skip_bases = array();
+        foreach ($table_data as $field => $info) {
+          // Collect table data from this table
+          if ($field == 'table') {
+            // calculate what tables this table can join to.
+            if (!empty($info['join'])) {
+              $bases = array_keys($info['join']);
+            }
+            // And it obviously joins to itself.
+            $bases[] = $table;
+            continue;
+          }
+          foreach (array('field', 'sort', 'filter', 'argument', 'relationship', 'area') as $key) {
+            if (!empty($info[$key])) {
+              if ($grouping && !empty($info[$key]['no group by'])) {
+                continue;
+              }
+              if ($sub_type && isset($info[$key]['sub_type']) && (!in_array($sub_type, (array) $info[$key]['sub_type']))) {
+                continue;
+              }
+              if (!empty($info[$key]['skip base'])) {
+                foreach ((array) $info[$key]['skip base'] as $base_name) {
+                  $skip_bases[$field][$key][$base_name] = TRUE;
+                }
+              }
+              elseif (!empty($info['skip base'])) {
+                foreach ((array) $info['skip base'] as $base_name) {
+                  $skip_bases[$field][$key][$base_name] = TRUE;
+                }
+              }
+              foreach (array('title', 'group', 'help', 'base', 'aliases') as $string) {
+                // First, try the lowest possible level
+                if (!empty($info[$key][$string])) {
+                  $strings[$field][$key][$string] = $info[$key][$string];
+                }
+                // Then try the field level
+                elseif (!empty($info[$string])) {
+                  $strings[$field][$key][$string] = $info[$string];
+                }
+                // Finally, try the table level
+                elseif (!empty($table_data['table'][$string])) {
+                  $strings[$field][$key][$string] = $table_data['table'][$string];
+                }
+                else {
+                  if ($string != 'base' && $string != 'base') {
+                    $strings[$field][$key][$string] = String::format("Error: missing @component", array('@component' => $string));
+                  }
+                }
+              }
+            }
+          }
+        }
+        foreach ($bases as $base_name) {
+          foreach ($strings as $field => $field_strings) {
+            foreach ($field_strings as $type_name => $type_strings) {
+              if (empty($skip_bases[$field][$type_name][$base_name])) {
+                $this->fields[$base_name][$type_name]["$table.$field"] = $type_strings;
+              }
+            }
+          }
+        }
+      }
+    }
+
+    // If we have an array of base tables available, go through them
+    // all and add them together. Duplicate keys will be lost and that's
+    // Just Fine.
+    if (is_array($base)) {
+      $strings = array();
+      foreach ($base as $base_table) {
+        if (isset($this->fields[$base_table][$type])) {
+          $strings += $this->fields[$base_table][$type];
+        }
+      }
+      uasort($strings, array('self', 'fetchedFieldSort'));
+      return $strings;
+    }
+
+    if (isset($this->fields[$base][$type])) {
+      uasort($this->fields[$base][$type], array($this, 'fetchedFieldSort'));
+      return $this->fields[$base][$type];
+    }
+    return array();
+  }
+
+  /**
+   * Sort function for fetched fields.
+   *
+   * @param array $a
+   *   First item for comparison. The compared items should be associative arrays
+   *   that include a 'group' and a 'title' key.
+   * @param array $b
+   *   Second item for comparison.
+   *
+   * @return int
+   *   Returns -1 if $a comes before $b, 1 other way round and 0 if it cannot be
+   *   decided.
+   */
+  protected static function fetchedFieldSort($a, $b) {
+    $a_group = Unicode::strtolower($a['group']);
+    $b_group = Unicode::strtolower($b['group']);
+    if ($a_group != $b_group) {
+      return $a_group < $b_group ? -1 : 1;
+    }
+
+    $a_title = Unicode::strtolower($a['title']);
+    $b_title = Unicode::strtolower($b['title']);
+    if ($a_title != $b_title) {
+      return $a_title < $b_title ? -1 : 1;
+    }
+
+    return 0;
+  }
+
+}
+
diff --git a/core/modules/views/tests/Drupal/views/Tests/ViewsDataHelperTest.php b/core/modules/views/tests/Drupal/views/Tests/ViewsDataHelperTest.php
new file mode 100644
index 0000000..43852e9
--- /dev/null
+++ b/core/modules/views/tests/Drupal/views/Tests/ViewsDataHelperTest.php
@@ -0,0 +1,129 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\views\Tests\ViewsDataHelperTest.
+ */
+
+namespace Drupal\views\Tests;
+
+use Drupal\Component\Utility\String;
+use Drupal\Tests\UnitTestCase;
+use Drupal\views\ViewsDataHelper;
+
+/**
+ * Tests the views data helper class.
+ *
+ * @see \Drupal\views\ViewsDataHelper
+ */
+class ViewsDataHelperTest extends UnitTestCase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Views data helper',
+      'description' => 'Tests the views data helper class.',
+      'group' => 'Views',
+    );
+  }
+
+  /**
+   * Returns the views data definition.
+   *
+   * @return array
+   */
+  protected function viewsData() {
+    $data = ViewTestData::viewsData();
+
+    // Tweak the views data to have a base for testing
+    // \Drupal\views\ViewsDataHelper::fetchFields().
+    unset($data['views_test_data']['id']['field']);
+    unset($data['views_test_data']['name']['argument']);
+    unset($data['views_test_data']['age']['filter']);
+    unset($data['views_test_data']['job']['sort']);
+    $data['views_test_data']['created']['area']['id'] = 'text';
+    $data['views_test_data']['age']['area']['id'] = 'text';
+    $data['views_test_data']['age']['area']['sub_type'] = 'header';
+    $data['views_test_data']['job']['area']['id'] = 'text';
+    $data['views_test_data']['job']['area']['sub_type'] = array('header', 'footer');
+
+    return $data;
+  }
+
+  /**
+   * Tests fetchFields.
+   */
+  public function testFetchFields() {
+    $views_data = $this->getMockBuilder('Drupal\views\ViewsData')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $views_data->expects($this->once())
+      ->method('get')
+      ->will($this->returnValue($this->viewsData()));
+
+    $data_helper = new ViewsDataHelper($views_data);
+
+    $expected = array(
+      'field' => array(
+        'age',
+        'created',
+        'job',
+        'name',
+      ),
+      'argument' => array(
+        'age',
+        'created',
+        'id',
+        'job',
+      ),
+      'filter' => array(
+        'created',
+        'id',
+        'job',
+        'name',
+      ),
+      'sort' => array(
+        'age',
+        'created',
+        'id',
+        'name',
+      ),
+      'area' => array(
+        'age',
+        'created',
+        'job',
+      ),
+      'header' => array(
+        'age',
+        'created',
+        'job',
+      ),
+      'footer' => array(
+        'age',
+        'created',
+        'job',
+      ),
+    );
+
+    $handler_types = array('field', 'argument', 'filter', 'sort', 'area');
+    foreach ($handler_types as $handler_type) {
+      $fields = $data_helper->fetchFields('views_test_data', $handler_type);
+      $expected_keys = $expected[$handler_type];
+      array_walk($expected_keys, function(&$item) {
+        $item = "views_test_data.$item";
+      });
+      $this->assertEquals($expected_keys, array_keys($fields), String::format('Handlers of type @handler_type are not listed as expected.', array('@handler_type' => $handler_type)));
+    }
+
+    // Check for subtype filtering, so header and footer.
+    foreach (array('header', 'footer') as $sub_type) {
+      $fields = $data_helper->fetchFields('views_test_data', 'area', FALSE, $sub_type);
+
+      $expected_keys = $expected[$sub_type];
+      array_walk($expected_keys, function(&$item) {
+        $item = "views_test_data.$item";
+      });
+      $this->assertEquals($expected_keys, array_keys($fields), String::format('Sub_type @sub_type is not filtered as expected.', array('@sub_type' => $sub_type)));
+    }
+  }
+
+}
diff --git a/core/modules/views/views.services.yml b/core/modules/views/views.services.yml
index 1629da5..22d4830 100644
--- a/core/modules/views/views.services.yml
+++ b/core/modules/views/views.services.yml
@@ -58,7 +58,10 @@ services:
     arguments: [wizard, '@container.namespaces']
   views.views_data:
     class: Drupal\views\ViewsData
-    arguments: ['@cache.views_info', '@config.factory', '@module_handler']
+    arguments: ['@cache.views_info', '@config.factory', '@module_handler', '@language_manager']
+  views.views_data_helper:
+    class: Drupal\views\ViewsDataHelper
+    arguments: ['@views.views_data']
   views.executable:
     class: Drupal\views\ViewExecutableFactory
   views.analyzer:
diff --git a/core/modules/views_ui/admin.inc b/core/modules/views_ui/admin.inc
index 02c62d8..192d0ca 100644
--- a/core/modules/views_ui/admin.inc
+++ b/core/modules/views_ui/admin.inc
@@ -408,141 +408,6 @@ function views_ui_build_form_url($form_state) {
   return $url;
 }
 
-function _views_sort_types($a, $b) {
-  $a_group = drupal_strtolower($a['group']);
-  $b_group = drupal_strtolower($b['group']);
-  if ($a_group != $b_group) {
-    return $a_group < $b_group ? -1 : 1;
-  }
-
-  $a_title = drupal_strtolower($a['title']);
-  $b_title = drupal_strtolower($b['title']);
-  if ($a_title != $b_title) {
-    return $a_title < $b_title ? -1 : 1;
-  }
-
-  return 0;
-}
-
-/**
- * Fetch a list of all fields available for a given base type.
- *
- * @param (array|string) $base
- *   A list or a single base_table, for example node.
- * @param string $type
- *   The handler type, for example field or filter.
- * @param bool $grouping
- *   Should the result grouping by its 'group' label.
- * @param string $sub_type
- *   An optional sub type. E.g. Allows making an area plugin available for
- *   header only, instead of header, footer, and empty regions.
- *
- * @return array
- *   A keyed array of in the form of 'base_table' => 'Description'.
- */
-function views_fetch_fields($base, $type, $grouping = FALSE, $sub_type = NULL) {
-  static $fields = array();
-  if (empty($fields)) {
-    $data = Views::viewsData()->get();
-    $start = microtime(TRUE);
-    // This constructs this ginormous multi dimensional array to
-    // collect the important data about fields. In the end,
-    // the structure looks a bit like this (using nid as an example)
-    // $strings['nid']['filter']['title'] = 'string'.
-    //
-    // This is constructed this way because the above referenced strings
-    // can appear in different places in the actual data structure so that
-    // the data doesn't have to be repeated a lot. This essentially lets
-    // each field have a cheap kind of inheritance.
-
-    foreach ($data as $table => $table_data) {
-      $bases = array();
-      $strings = array();
-      $skip_bases = array();
-      foreach ($table_data as $field => $info) {
-        // Collect table data from this table
-        if ($field == 'table') {
-          // calculate what tables this table can join to.
-          if (!empty($info['join'])) {
-            $bases = array_keys($info['join']);
-          }
-          // And it obviously joins to itself.
-          $bases[] = $table;
-          continue;
-        }
-        foreach (array('field', 'sort', 'filter', 'argument', 'relationship', 'area') as $key) {
-          if (!empty($info[$key])) {
-            if ($grouping && !empty($info[$key]['no group by'])) {
-              continue;
-            }
-            if ($sub_type && isset($info[$key]['sub_type']) && (!in_array($sub_type, (array) $info[$key]['sub_type']))) {
-              continue;
-            }
-            if (!empty($info[$key]['skip base'])) {
-              foreach ((array) $info[$key]['skip base'] as $base_name) {
-                $skip_bases[$field][$key][$base_name] = TRUE;
-              }
-            }
-            elseif (!empty($info['skip base'])) {
-              foreach ((array) $info['skip base'] as $base_name) {
-                $skip_bases[$field][$key][$base_name] = TRUE;
-              }
-            }
-            foreach (array('title', 'group', 'help', 'base', 'aliases') as $string) {
-              // First, try the lowest possible level
-              if (!empty($info[$key][$string])) {
-                $strings[$field][$key][$string] = $info[$key][$string];
-              }
-              // Then try the field level
-              elseif (!empty($info[$string])) {
-                $strings[$field][$key][$string] = $info[$string];
-              }
-              // Finally, try the table level
-              elseif (!empty($table_data['table'][$string])) {
-                $strings[$field][$key][$string] = $table_data['table'][$string];
-              }
-              else {
-                if ($string != 'base' && $string != 'base') {
-                  $strings[$field][$key][$string] = t("Error: missing @component", array('@component' => $string));
-                }
-              }
-            }
-          }
-        }
-      }
-      foreach ($bases as $base_name) {
-        foreach ($strings as $field => $field_strings) {
-          foreach ($field_strings as $type_name => $type_strings) {
-            if (empty($skip_bases[$field][$type_name][$base_name])) {
-              $fields[$base_name][$type_name]["$table.$field"] = $type_strings;
-            }
-          }
-        }
-      }
-    }
-  }
-
-  // If we have an array of base tables available, go through them
-  // all and add them together. Duplicate keys will be lost and that's
-  // Just Fine.
-  if (is_array($base)) {
-    $strings = array();
-    foreach ($base as $base_table) {
-      if (isset($fields[$base_table][$type])) {
-        $strings += $fields[$base_table][$type];
-      }
-    }
-    uasort($strings, '_views_sort_types');
-    return $strings;
-  }
-
-  if (isset($fields[$base][$type])) {
-    uasort($fields[$base][$type], '_views_sort_types');
-    return $fields[$base][$type];
-  }
-  return array();
-}
-
 /**
  * #process callback for a button; determines if a button is the form's triggering element.
  *
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/AddItem.php b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/AddItem.php
index 1c8d13e..a1907ab 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/AddItem.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/AddItem.php
@@ -9,6 +9,7 @@
 
 use Drupal\views\ViewExecutable;
 use Drupal\views\ViewStorageInterface;
+use Drupal\views\Views;
 
 /**
  * Provides a form for adding an item in the Views UI.
@@ -81,7 +82,7 @@ public function buildForm(array $form, array &$form_state) {
 
     // Figure out all the base tables allowed based upon what the relationships provide.
     $base_tables = $executable->getBaseTables();
-    $options = views_fetch_fields(array_keys($base_tables), $type, $display->useGroupBy(), $form_state['type']);
+    $options = Views::viewsDataHelper()->fetchFields(array_keys($base_tables), $type, $display->useGroupBy(), $form_state['type']);
 
     if (!empty($options)) {
       $form['override']['controls'] = array(
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigItem.php b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigItem.php
index b047507..3f17fc0 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigItem.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigItem.php
@@ -105,7 +105,7 @@ public function buildForm(array $form, array &$form_state) {
           // If this relationship is valid for this type, add it to the list.
           $data = Views::viewsData()->get($relationship['table']);
           $base = $data[$relationship['field']]['relationship']['base'];
-          $base_fields = views_fetch_fields($base, $form_state['type'], $executable->display_handler->useGroupBy());
+          $base_fields = Views::viewsDataHelper()->fetchFields($base, $form_state['type'], $executable->display_handler->useGroupBy());
           if (isset($base_fields[$item['table'] . '.' . $item['field']])) {
             $relationship_handler->init($executable, $executable->display_handler, $relationship);
             $relationship_options[$relationship['id']] = $relationship_handler->adminLabel();
@@ -115,7 +115,7 @@ public function buildForm(array $form, array &$form_state) {
         if (!empty($relationship_options)) {
           // Make sure the existing relationship is even valid. If not, force
           // it to none.
-          $base_fields = views_fetch_fields($view->get('base_table'), $form_state['type'], $executable->display_handler->useGroupBy());
+          $base_fields = Views::viewsDataHelper()->fetchFields($view->get('base_table'), $form_state['type'], $executable->display_handler->useGroupBy());
           if (isset($base_fields[$item['table'] . '.' . $item['field']])) {
             $relationship_options = array_merge(array('none' => t('Do not use a relationship')), $relationship_options);
           }
