Issue #1962234 by dawehner, damiankloip, alexpott: Move views_fetch_fields() into an autoloadable class.
parent
a93de78702
commit
b15e92136a
|
@ -88,7 +88,7 @@ class GroupwiseMax extends RelationshipPluginBase {
|
|||
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]";
|
||||
}
|
||||
|
|
|
@ -831,7 +831,7 @@ abstract class WizardPluginBase extends PluginBase implements WizardInterface {
|
|||
// 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;
|
||||
}
|
||||
|
|
|
@ -137,18 +137,18 @@ class ViewTestData {
|
|||
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 @@ class ViewTestData {
|
|||
),
|
||||
);
|
||||
$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 @@ class ViewTestData {
|
|||
),
|
||||
);
|
||||
$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 @@ class ViewTestData {
|
|||
),
|
||||
);
|
||||
$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 @@ class ViewTestData {
|
|||
),
|
||||
);
|
||||
$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',
|
||||
),
|
||||
|
|
|
@ -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 @@ class ViewsDataTest extends ViewUnitTestBase {
|
|||
*/
|
||||
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 @@ class ViewsDataTest extends ViewUnitTestBase {
|
|||
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 @@ class ViewsDataTest extends ViewUnitTestBase {
|
|||
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.
|
||||
*/
|
||||
|
|
|
@ -24,6 +24,16 @@ class Views {
|
|||
return Drupal::service('views.views_data');
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
|
|
|
@ -11,6 +11,7 @@ use Drupal\Core\Cache\CacheBackendInterface;
|
|||
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.
|
||||
|
@ -71,6 +72,13 @@ class ViewsData {
|
|||
*/
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* The language manager
|
||||
*
|
||||
* @var \Drupal\Core\Language\LanguageManager
|
||||
*/
|
||||
protected $languageManager;
|
||||
|
||||
/**
|
||||
* Constructs this ViewsData object.
|
||||
*
|
||||
|
@ -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');
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
<?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',
|
||||
'status',
|
||||
),
|
||||
'argument' => array(
|
||||
'age',
|
||||
'created',
|
||||
'id',
|
||||
'job',
|
||||
),
|
||||
'filter' => array(
|
||||
'created',
|
||||
'id',
|
||||
'job',
|
||||
'name',
|
||||
'status',
|
||||
),
|
||||
'sort' => array(
|
||||
'age',
|
||||
'created',
|
||||
'id',
|
||||
'name',
|
||||
'status',
|
||||
),
|
||||
'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)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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:
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace Drupal\views_ui\Form\Ajax;
|
|||
|
||||
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 @@ class AddItem extends ViewsFormBase {
|
|||
|
||||
// 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(
|
||||
|
|
|
@ -105,7 +105,7 @@ class ConfigItem extends ViewsFormBase {
|
|||
// 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 @@ class ConfigItem extends ViewsFormBase {
|
|||
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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue