-
Notifications
You must be signed in to change notification settings - Fork 1
/
localgov_step_by_step.module
321 lines (284 loc) · 11.7 KB
/
localgov_step_by_step.module
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
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
<?php
/**
* @file
* Module file.
*
* Implements hooks.
*/
declare(strict_types=1);
use Drupal\Core\Entity\Display\EntityFormDisplayInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\localgov_roles\RolesHelper;
/**
* Implements hook_theme().
*
* Provides the following themes:
* - Step by step navigation view's Prev/Next block.
*/
function localgov_step_by_step_theme() {
return [
'step_by_step_part_of_block' => [
'variables' => [
'label' => NULL,
'url' => NULL,
],
'render element' => 'children',
],
'views_view_list__localgov_step_by_step_navigation__prev_next' => [
'base hook' => 'views_view_list',
],
];
}
/**
* Implements hook_localgov_role_default().
*/
function localgov_step_by_step_localgov_roles_default() {
// Content editing permissions.
$perms = [
RolesHelper::EDITOR_ROLE => [
'create localgov_step_by_step_overview content',
'create localgov_step_by_step_page content',
'delete any localgov_step_by_step_overview content',
'delete any localgov_step_by_step_page content',
'delete localgov_step_by_step_overview revisions',
'delete localgov_step_by_step_page revisions',
'delete own localgov_step_by_step_overview content',
'delete own localgov_step_by_step_page content',
'edit any localgov_step_by_step_overview content',
'edit any localgov_step_by_step_page content',
'edit own localgov_step_by_step_overview content',
'edit own localgov_step_by_step_page content',
'revert localgov_step_by_step_overview revisions',
'revert localgov_step_by_step_page revisions',
'view localgov_step_by_step_overview revisions',
'view localgov_step_by_step_page revisions',
],
RolesHelper::AUTHOR_ROLE => [
'create localgov_step_by_step_overview content',
'create localgov_step_by_step_page content',
'delete own localgov_step_by_step_overview content',
'delete own localgov_step_by_step_page content',
'edit own localgov_step_by_step_overview content',
'edit own localgov_step_by_step_page content',
'revert localgov_step_by_step_overview revisions',
'revert localgov_step_by_step_page revisions',
'view localgov_step_by_step_overview revisions',
'view localgov_step_by_step_page revisions',
],
RolesHelper::CONTRIBUTOR_ROLE => [
'create localgov_step_by_step_overview content',
'create localgov_step_by_step_page content',
'delete own localgov_step_by_step_overview content',
'delete own localgov_step_by_step_page content',
'edit own localgov_step_by_step_overview content',
'edit own localgov_step_by_step_page content',
'view localgov_step_by_step_overview revisions',
'view localgov_step_by_step_page revisions',
],
];
// Content scheduling permissions required by localgov_workflows.
if (\Drupal::moduleHandler()->moduleExists('localgov_workflows')) {
$perms[RolesHelper::EDITOR_ROLE] = array_merge($perms[RolesHelper::EDITOR_ROLE], [
'add scheduled transitions node localgov_step_by_step_overview',
'add scheduled transitions node localgov_step_by_step_page',
'reschedule scheduled transitions node localgov_step_by_step_overview',
'reschedule scheduled transitions node localgov_step_by_step_page',
'view scheduled transitions node localgov_step_by_step_overview',
'view scheduled transitions node localgov_step_by_step_page',
]);
$perms[RolesHelper::AUTHOR_ROLE] = array_merge($perms[RolesHelper::AUTHOR_ROLE], [
'add scheduled transitions node localgov_step_by_step_overview',
'add scheduled transitions node localgov_step_by_step_page',
'reschedule scheduled transitions node localgov_step_by_step_overview',
'reschedule scheduled transitions node localgov_step_by_step_page',
'view scheduled transitions node localgov_step_by_step_overview',
'view scheduled transitions node localgov_step_by_step_page',
]);
$perms[RolesHelper::CONTRIBUTOR_ROLE] = array_merge($perms[RolesHelper::CONTRIBUTOR_ROLE], [
'add scheduled transitions node localgov_step_by_step_overview',
'add scheduled transitions node localgov_step_by_step_page',
'reschedule scheduled transitions node localgov_step_by_step_overview',
'reschedule scheduled transitions node localgov_step_by_step_page',
'view scheduled transitions node localgov_step_by_step_overview',
'view scheduled transitions node localgov_step_by_step_page',
]);
}
return $perms;
}
/**
* Implements hook_ENTITY_TYPE_insert().
*/
function localgov_step_by_step_node_insert(EntityInterface $entity) {
localgov_step_by_step_node_update($entity);
}
/**
* Implements hook_ENTITY_TYPE_update().
*
* The step_by_step_overview and step_by_step_page content types reference each
* other. When a step_by_step_page type node is updated, find its
* step_by_step_overview node. Then make sure this step_by_step_overview node
* refers back to the step_by_step_page node.
*/
function localgov_step_by_step_node_update(EntityInterface $entity) {
$is_not_step_by_step_page_node = ($entity->bundle() !== 'localgov_step_by_step_page');
if ($is_not_step_by_step_page_node) {
return;
}
$step_by_step_page_node = $entity;
$step_by_step_page_nid = $step_by_step_page_node->id();
$step_by_step_overview_node = $step_by_step_page_node->localgov_step_parent->entity ?? FALSE;
if (empty($step_by_step_overview_node)) {
return;
}
try {
$has_ref_to_this_step_by_step_page = array_filter($step_by_step_overview_node->localgov_step_by_step_pages->referencedEntities(), function (EntityInterface $page_node) use ($step_by_step_page_nid): bool {
return $page_node->id() === $step_by_step_page_nid;
});
if ($has_ref_to_this_step_by_step_page) {
return;
}
$step_by_step_overview_node->localgov_step_by_step_pages->appendItem($step_by_step_page_nid);
$step_by_step_overview_node->save();
}
catch (Exception $e) {
Drupal::service('logger.factory')->get('localgov-step-by-step')->error($e->getMessage());
}
}
/**
* Implements hook_preprocess_views_view_list().
*
* Marks the rows corresponding to the current, previous, and next nodes.
*/
function localgov_step_by_step_preprocess_views_view_list(array &$variables) {
$view = $variables['view'];
$view_id = $view->id();
$view_display_id = $view->current_display;
$is_step_by_step_nav = ($view_id === 'localgov_step_by_step_navigation');
$is_step_by_step_nav_block = ($view_display_id === 'steps');
$is_step_by_step_prev_next_block = ($view_display_id === 'prev_next');
$current_nid = $is_step_by_step_nav ? $view->args[0] : '';
if ($is_step_by_step_nav && $is_step_by_step_prev_next_block) {
_localgov_step_by_step_find_prev_next_steps($current_nid, $variables);
}
elseif ($is_step_by_step_nav && $is_step_by_step_nav_block) {
_localgov_step_by_step_mark_current_step($current_nid, $variables);
}
if ($is_step_by_step_nav) {
$variables['view']->element['#attached']['library'][] = 'localgov_step_by_step/step-by-step-nav';
}
}
/**
* Find previous and next steps.
*
* Find the previous and next Step by step page nodes relative to the current
* node. The current node is the one where we are displaying this block. Its
* node ID is treated as the first contextual argument of our View.
*/
function _localgov_step_by_step_find_prev_next_steps(string $current_nid, array &$variables): void {
$prev_step_index = -1;
$next_step_index = -1;
foreach ($variables['rows'] as $key => $row) {
$row_nid = $row['content']['#row']->node_field_data_node__localgov_step_by_step_pages_1_nid ?? '-1';
$is_current_step = ($row_nid === $current_nid);
if ($is_current_step) {
$prev_step_index = $key - 1;
$next_step_index = $key + 1;
break;
}
}
$variables['has_prev_step'] = array_key_exists($prev_step_index, $variables['rows']);
$variables['has_next_step'] = array_key_exists($next_step_index, $variables['rows']);
$variables['prev_step_nid'] = $variables['rows'][$prev_step_index]['content']['#row']->node_field_data_node__localgov_step_by_step_pages_1_nid ?? -1;
$variables['next_step_nid'] = $variables['rows'][$next_step_index]['content']['#row']->node_field_data_node__localgov_step_by_step_pages_1_nid ?? -1;
$variables['prev_step_link_text'] = t('Previous Step');
$variables['prev_step_index'] = $prev_step_index;
$variables['next_step_index'] = $next_step_index;
$is_first_step = ($next_step_index === 1);
$variables['next_step_link_text'] = $is_first_step ? t('Next Step') : t('Next Step');
$node_storage = \Drupal::entityTypeManager()->getStorage('node');
if ($variables['has_next_step']) {
$variables['next_step_title'] = $node_storage->load($variables['next_step_nid'])->title->value;
}
if ($variables['has_prev_step']) {
$variables['prev_step_title'] = $node_storage->load($variables['prev_step_nid'])->title->value;
}
}
/**
* Mark the row corresponding to the current Step by step page node.
*/
function _localgov_step_by_step_mark_current_step(string $current_nid, array &$variables): void {
foreach ($variables['rows'] as &$row) {
$row_nid = $row['content']['#row']->node_field_data_node__localgov_step_by_step_pages_1_nid ?? '-1';
$is_current_step = ($row_nid === $current_nid);
if ($is_current_step) {
$row['attributes']['class'][] = 'step--active';
$row['attributes']['aria-current'] = 'step';
break;
}
}
}
/**
* Implements hook_modules_installed().
*/
function localgov_step_by_step_modules_installed($modules) {
$services = in_array('localgov_services_navigation', $modules, TRUE);
$topics = in_array('localgov_topics', $modules, TRUE);
if ($services) {
\Drupal::service('config.installer')->installOptionalConfig(NULL, [
'config' => 'field.storage.node.localgov_services_parent',
]);
}
if ($topics) {
\Drupal::service('config.installer')->installOptionalConfig(NULL, [
'config' => 'field.storage.node.localgov_topic_classified',
]);
}
if ($services || $topics) {
localgov_step_by_step_optional_fields_settings($services, $topics);
}
}
/**
* Set form settings for optional services and topic fields on installation.
*
* @param bool $services
* If localgov_services is (being) installed.
* @param bool $topics
* If localgov_topics is (being) installed.
*/
function localgov_step_by_step_optional_fields_settings($services, $topics) {
$properties = [
'targetEntityType' => 'node',
'bundle' => 'localgov_step_by_step_overview',
];
if ($form_displays = \Drupal::entityTypeManager()->getStorage('entity_form_display')->loadByProperties($properties)) {
foreach ($form_displays as $form_display) {
assert($form_display instanceof EntityFormDisplayInterface);
if ($services && !$form_display->getComponent('localgov_services_parent')) {
$form_display->setComponent('localgov_services_parent', [
'type' => 'entity_reference_autocomplete',
'region' => 'content',
'settings' => [
'match_operator' => 'CONTAINS',
'size' => '60',
'placeholder' => '',
'match_limit' => 10,
],
'weight' => -1,
])->save();
}
if ($topics && !$form_display->getComponent('localgov_topic_classified')) {
$form_display->setComponent('localgov_topic_classified', [
'type' => 'entity_reference_autocomplete',
'region' => 'content',
'settings' => [
'match_operator' => 'CONTAINS',
'size' => '60',
'placeholder' => '',
'match_limit' => 10,
],
'weight' => 50,
])->save();
}
}
}
}