Mercurial > hg > cmmr2012-drupal-site
comparison core/modules/views/src/ViewsDataHelper.php @ 0:c75dbcec494b
Initial commit from drush-created site
author | Chris Cannam |
---|---|
date | Thu, 05 Jul 2018 14:24:15 +0000 |
parents | |
children | a9cd425dd02b |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c75dbcec494b |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\views; | |
4 | |
5 use Drupal\Component\Utility\Unicode; | |
6 use Drupal\Component\Utility\SafeMarkup; | |
7 | |
8 /** | |
9 * Defines a helper class for stuff related to views data. | |
10 */ | |
11 class ViewsDataHelper { | |
12 | |
13 /** | |
14 * The views data object, containing the cached information. | |
15 * | |
16 * @var \Drupal\views\ViewsData | |
17 */ | |
18 protected $data; | |
19 | |
20 /** | |
21 * A prepared list of all fields, keyed by base_table and handler type. | |
22 * | |
23 * @var array | |
24 */ | |
25 protected $fields; | |
26 | |
27 /** | |
28 * Constructs a ViewsData object. | |
29 * | |
30 * @param \Drupal\views\ViewsData $views_data | |
31 * The views data object, containing the cached table information. | |
32 */ | |
33 public function __construct(ViewsData $views_data) { | |
34 $this->data = $views_data; | |
35 } | |
36 | |
37 /** | |
38 * Fetches a list of all fields available for a given base type. | |
39 * | |
40 * @param array|string $base | |
41 * A list or a single base_table, for example node. | |
42 * @param string $type | |
43 * The handler type, for example field or filter. | |
44 * @param bool $grouping | |
45 * Should the result grouping by its 'group' label. | |
46 * @param string $sub_type | |
47 * An optional sub type. E.g. Allows making an area plugin available for | |
48 * header only, instead of header, footer, and empty regions. | |
49 * | |
50 * @return array | |
51 * A keyed array of in the form of 'base_table' => 'Description'. | |
52 */ | |
53 public function fetchFields($base, $type, $grouping = FALSE, $sub_type = NULL) { | |
54 if (!$this->fields) { | |
55 $data = $this->data->get(); | |
56 // This constructs this ginormous multi dimensional array to | |
57 // collect the important data about fields. In the end, | |
58 // the structure looks a bit like this (using nid as an example) | |
59 // $strings['nid']['filter']['title'] = 'string'. | |
60 // | |
61 // This is constructed this way because the above referenced strings | |
62 // can appear in different places in the actual data structure so that | |
63 // the data doesn't have to be repeated a lot. This essentially lets | |
64 // each field have a cheap kind of inheritance. | |
65 | |
66 foreach ($data as $table => $table_data) { | |
67 $bases = []; | |
68 $strings = []; | |
69 $skip_bases = []; | |
70 foreach ($table_data as $field => $info) { | |
71 // Collect table data from this table | |
72 if ($field == 'table') { | |
73 // calculate what tables this table can join to. | |
74 if (!empty($info['join'])) { | |
75 $bases = array_keys($info['join']); | |
76 } | |
77 // And it obviously joins to itself. | |
78 $bases[] = $table; | |
79 continue; | |
80 } | |
81 foreach (['field', 'sort', 'filter', 'argument', 'relationship', 'area'] as $key) { | |
82 if (!empty($info[$key])) { | |
83 if ($grouping && !empty($info[$key]['no group by'])) { | |
84 continue; | |
85 } | |
86 if ($sub_type && isset($info[$key]['sub_type']) && (!in_array($sub_type, (array) $info[$key]['sub_type']))) { | |
87 continue; | |
88 } | |
89 if (!empty($info[$key]['skip base'])) { | |
90 foreach ((array) $info[$key]['skip base'] as $base_name) { | |
91 $skip_bases[$field][$key][$base_name] = TRUE; | |
92 } | |
93 } | |
94 elseif (!empty($info['skip base'])) { | |
95 foreach ((array) $info['skip base'] as $base_name) { | |
96 $skip_bases[$field][$key][$base_name] = TRUE; | |
97 } | |
98 } | |
99 foreach (['title', 'group', 'help', 'base', 'aliases'] as $string) { | |
100 // First, try the lowest possible level | |
101 if (!empty($info[$key][$string])) { | |
102 $strings[$field][$key][$string] = $info[$key][$string]; | |
103 } | |
104 // Then try the field level | |
105 elseif (!empty($info[$string])) { | |
106 $strings[$field][$key][$string] = $info[$string]; | |
107 } | |
108 // Finally, try the table level | |
109 elseif (!empty($table_data['table'][$string])) { | |
110 $strings[$field][$key][$string] = $table_data['table'][$string]; | |
111 } | |
112 // We don't have any help provided for this field. If a better | |
113 // description should be used for the Views UI you use | |
114 // hook_views_data_alter() in module.views.inc or implement a | |
115 // custom entity views_data handler. | |
116 // @see hook_views_data_alter() | |
117 // @see \Drupal\node\NodeViewsData | |
118 elseif ($string == 'help') { | |
119 $strings[$field][$key][$string] = ''; | |
120 } | |
121 else { | |
122 if ($string != 'base') { | |
123 $strings[$field][$key][$string] = SafeMarkup::format("Error: missing @component", ['@component' => $string]); | |
124 } | |
125 } | |
126 } | |
127 } | |
128 } | |
129 } | |
130 foreach ($bases as $base_name) { | |
131 foreach ($strings as $field => $field_strings) { | |
132 foreach ($field_strings as $type_name => $type_strings) { | |
133 if (empty($skip_bases[$field][$type_name][$base_name])) { | |
134 $this->fields[$base_name][$type_name]["$table.$field"] = $type_strings; | |
135 } | |
136 } | |
137 } | |
138 } | |
139 } | |
140 } | |
141 | |
142 // If we have an array of base tables available, go through them | |
143 // all and add them together. Duplicate keys will be lost and that's | |
144 // Just Fine. | |
145 if (is_array($base)) { | |
146 $strings = []; | |
147 foreach ($base as $base_table) { | |
148 if (isset($this->fields[$base_table][$type])) { | |
149 $strings += $this->fields[$base_table][$type]; | |
150 } | |
151 } | |
152 uasort($strings, ['self', 'fetchedFieldSort']); | |
153 return $strings; | |
154 } | |
155 | |
156 if (isset($this->fields[$base][$type])) { | |
157 uasort($this->fields[$base][$type], [$this, 'fetchedFieldSort']); | |
158 return $this->fields[$base][$type]; | |
159 } | |
160 return []; | |
161 } | |
162 | |
163 /** | |
164 * Sort function for fetched fields. | |
165 * | |
166 * @param array $a | |
167 * First item for comparison. The compared items should be associative arrays | |
168 * that include a 'group' and a 'title' key. | |
169 * @param array $b | |
170 * Second item for comparison. | |
171 * | |
172 * @return int | |
173 * Returns -1 if $a comes before $b, 1 other way round and 0 if it cannot be | |
174 * decided. | |
175 */ | |
176 protected static function fetchedFieldSort($a, $b) { | |
177 $a_group = Unicode::strtolower($a['group']); | |
178 $b_group = Unicode::strtolower($b['group']); | |
179 if ($a_group != $b_group) { | |
180 return $a_group < $b_group ? -1 : 1; | |
181 } | |
182 | |
183 $a_title = Unicode::strtolower($a['title']); | |
184 $b_title = Unicode::strtolower($b['title']); | |
185 if ($a_title != $b_title) { | |
186 return $a_title < $b_title ? -1 : 1; | |
187 } | |
188 | |
189 return 0; | |
190 } | |
191 | |
192 } |