-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathReportHookData.php
More file actions
255 lines (218 loc) · 6.48 KB
/
ReportHookData.php
File metadata and controls
255 lines (218 loc) · 6.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
<?php
/**
* @file
* Contains DrupalCodeBuilder\Task\ReportHookData.
*/
namespace DrupalCodeBuilder\Task;
use DrupalCodeBuilder\Definition\OptionDefinition;
use MutableTypedData\Definition\OptionSetDefininitionInterface;
use DrupalCodeBuilder\Definition\VariantMappingProviderInterface;
use DrupalCodeBuilder\Task\Report\SectionReportInterface;
/**
* Task handler for reporting on hook data.
*
* TODO: revisit some of these and clean up names / clean up how many we have.
*/
class ReportHookData extends ReportHookDataFolder
implements OptionSetDefininitionInterface, VariantMappingProviderInterface, SectionReportInterface {
/**
* The sanity level this task requires to operate.
*/
protected $sanity_level = 'component_data_processed';
protected $declarations;
/**
* {@inheritdoc}
*/
public function getInfo(): array {
return [
'key' => 'hooks',
'label' => 'Hooks',
'weight' => 0,
];
}
/**
* {@inheritdoc}
*/
public function getDataSummary(): array {
$data = $this->listHookData();
$list = [];
$count = 0;
foreach ($data as $file => $hooks) {
$list_group = [];
foreach ($hooks as $key => $hook) {
$list_group[$hook['name']] = $hook['description'];
}
$count += count($hooks);
$list["Group $file:"] = $list_group;
}
return $list;
}
/**
* {@inheritdoc}
*/
public function getCount(): int {
$count = 0;
foreach ($this->getDataSummary() as $group) {
$count+= count($group);
}
return $count;
}
/**
* The cached hook data.
*
* @var array
*/
protected $hook_data;
/**
* Get the list of hook data.
*
* @return
* The processed hook data.
*/
function listHookData() {
// We may come here several times, so cache this.
if (!empty($this->hook_data)) {
return $this->hook_data;
}
$this->hook_data = $this->environment->getStorage()->retrieve('hooks');
return $this->hook_data;
}
/**
* Get just hook names.
*
* @param $style
* Whether to return hook names as just 'init' or 'hook_init'. One of:
* - 'short': Return short names, i.e., 'init'.
* - 'full': Return full hook names, i.e., 'hook_init'.
*
* @return
* A flat array of strings.
*/
function listHookNames($style = 'full') {
$data = $this->getHookDeclarations();
$names = array_keys($data);
if ($style == 'short') {
foreach ($names as $key => $hook_name) {
$names[$key] = str_replace('hook_', '', $hook_name);
}
}
return $names;
}
/**
* {@inheritdoc}
*/
public function getOptions(): array {
$options = [];
$data = $this->listHookData();
foreach ($data as $group => $hooks) {
foreach ($hooks as $key => $hook) {
if (!empty($hook['core']) && isset($hook['original_file_path'])) {
$url = 'https://api.drupal.org/api/drupal/' .
str_replace('/', '!', $hook['original_file_path']) .
'/function/' .
$hook['name'] .
'/' . $this->environment->getCoreMajorVersion();
}
$options[$hook['name']] = OptionDefinition::create(
$hook['name'],
$hook['name'],
description: $hook['description'] ?? '',
api_url: $url ?? NULL,
);
}
}
return $options;
}
/**
* {@inheritdoc}
*/
public function getVariantMapping(): array {
$mapping = [];
$data = $this->listHookData();
foreach ($data as $group => $hooks) {
foreach ($hooks as $key => $hook) {
$mapping[$key] = preg_match('@[[:upper:]]@', $key) ? 'tokenized' : 'literal';
}
}
// Special case for hook_update_N(): the uppercase 'N' is not a token, as
// it's derived automatically.
$mapping['hook_update_N'] = 'literal';
return $mapping;
}
/**
* Get hooks as a list of options.
*
* @deprecated Use getOptions() instead.
*
* @return
* An array of hooks as options suitable for FormAPI, where each key is a
* full hook name, and each value is a description.
*/
function listHookNamesOptions() {
$data = $this->getHookDeclarations();
$return = [];
foreach ($data as $hook_name => $hook_info) {
$return[$hook_name] = $hook_info['description'];
}
return $return;
}
/**
* Get hooks as a grouped list with data about each item.
*
* @return
* An array keyed by hook group, whose items are in turn arrays keyed by
* hook name standardized to lowercase, and whose items in turn are arrays
* with the following properties:
* - 'name': The hook name in the original case.
* - 'type' One of 'hook' or 'callback'.
* - 'description' The first line from the hook definition's docblock.
*/
public function listHookOptionsStructured() {
$data = $this->getHookDeclarations();
$return = [];
foreach ($data as $hook_name => $hook_info) {
$return[$hook_info['group']][$hook_name] = [
'name' => $hook_info['name'],
'description' => $hook_info['description'],
'type' => $hook_info['type'],
'core' => $hook_info['core'],
];
}
return $return;
}
/**
* Get stored hook declarations, keyed by hook name, with destination.
*
* @return
* An array of hook information, keyed by the full name of the hook
* standardized to lower case.
* Each item has the keys:
* - 'type': One of 'hook' or 'callback'.
* - 'name': The full name of the hook in the original case,
* eg 'hook_form_FORM_ID_alter'.
* - 'definition': The full function declaration.
* - 'description': The first line of the hook docblock.
* - 'destination': The file this hook should be placed in, as a module file
* pattern such as '%module.module'.
* - 'dependencies': An array of other hooks and callbacks which should also
* be generated if this hook is generated.
* - 'group': Erm write this later.
* - 'file_path': The absolute path of the file this definition was taken
* from.
* - 'body': The hook function body, taken from the API file.
*/
function getHookDeclarations() {
if (!isset($this->declarations)) {
$data = $this->listHookData();
$this->declarations = [];
foreach ($data as $group => $hooks) {
foreach ($hooks as $key => $hook) {
// Standardize to lowercase.
$hook_name = strtolower($hook['name']);
$this->declarations[$hook_name] = $hook;
}
}
}
return $this->declarations;
}
}