Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
0.00% |
0 / 1 |
|
33.33% |
1 / 3 |
CRAP | |
70.97% |
44 / 62 |
| ViewsDataHelper | |
0.00% |
0 / 1 |
|
33.33% |
1 / 3 |
70.50 | |
70.97% |
44 / 62 |
| __construct | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
| fetchFields | |
0.00% |
0 / 1 |
60.67 | |
68.63% |
35 / 51 |
|||
| fetchedFieldSort | |
0.00% |
0 / 1 |
5.27 | |
77.78% |
7 / 9 |
|||
| <?php | |
| /** | |
| * @file | |
| * Contains \Drupal\views\ViewsDataHelper. | |
| */ | |
| namespace Drupal\views; | |
| use Drupal\Component\Utility\Unicode; | |
| use Drupal\Component\Utility\SafeMarkup; | |
| /** | |
| * 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]; | |
| } | |
| // We don't have any help provided for this field. If a better | |
| // description should be used for the Views UI you use | |
| // hook_views_data_alter() in module.views.inc or implement a | |
| // custom entity views_data handler. | |
| // @see hook_views_data_alter() | |
| // @see \Drupal\node\NodeViewsData | |
| elseif ($string == 'help') { | |
| $strings[$field][$key][$string] = ''; | |
| } | |
| else { | |
| if ($string != 'base') { | |
| $strings[$field][$key][$string] = SafeMarkup::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; | |
| } | |
| } | |