-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathosulp.theme
More file actions
322 lines (277 loc) · 10.2 KB
/
osulp.theme
File metadata and controls
322 lines (277 loc) · 10.2 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
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
322
<?php
declare(strict_types=1);
/**
* @file
* Functions to support theming in the OSULP theme.
*/
/**
* Implements hook_preprocess_HOOK() for all templates.
*/
function osulp_preprocess(array &$variables): void {
$node = \Drupal::routeMatch()->getParameter('node') ?? $variables['node'] ?? null;
$group = \Drupal::routeMatch()->getParameter('group');
if ($node) {
// add the node to twig variables
$variables['page_node'] = $node;
$variables['groups'] = getGroupsByEntity($node);
} else if ($group) {
$variables['groups'] = [$group];
}
}
/**
* Implements hook_preprocess_HOOK() for html.html.twig.
*/
function osulp_preprocess_html(array &$variables): void {
}
/**
* Implements hook_preprocess_HOOK() for page.html.twig.
*/
function osulp_preprocess_page(array &$variables): void {
}
/**
* Implements hook_preprocess_HOOK() for node.html.twig.
*/
function osulp_preprocess_node(array &$variables): void {
// $uid = \Drupal::currentUser()->id();
// $author_id = $variables['node']->getOwner()->id();
// $variables['is_author'] = $author_id == $uid;
}
/**
* Implements hook_preprocess_HOOK() for block.html.twig.
*/
function osulp_preprocess_block(array &$variables): void {
// Do libcal hours stuff if this is an hours block
if (isset($variables['bundle']) && $variables['bundle'] == 'hours') {
$group = strtolower($variables['content']['field_library'][0]['#title']);
// Add LibCal location hours data to template variables
$variables['libcal_data'] = libcal_location_data();
$variables['hours'] = format_this_weeks_dates($variables['libcal_data'][$group][0]['dates']);
}
}
/**
* Implements hook_preprocess_HOOK() for field.html.twig.
*/
function osulp_preprocess_field(array &$variables): void {
// $uid = \Drupal::currentUser()->id();
// $author_id = $variables['element']['#object']->getOwner()->id();
// $variables['is_author'] = $author_id == $uid;
}
/**
* Implements hook_preprocess_HOOK() for page.html.twig.
*/
function osulp_preprocess_form__views_exposed_form(array &$variables): void {
if ($variables['attributes']['action'] == '/news') {
$variables['attributes']['class'] = array_merge($variables['attributes']['class'], [
'pt-4',
'border-top',
]);
}
}
/**
* Prepares variables views-style-views-organization-chart.html.twig template.
* This is to remove people from the org chart. Specifically Kerri & AMD since they're final parents to all departments
*/
function osulp_preprocess_views_style_views_organization_chart(&$variables): void {
$view = $variables['view'];
$chartId = $variables['chart_id'];
# List of all ids in the results set
$result_ids = array_column($variables['view']->element['#attached']['drupalSettings'][$chartId]['nodes'], 'id');
# Loop through render data and remove any users not in the results set
foreach($variables['view']->element['#attached']['drupalSettings'][$chartId]['data'] as $key => $user_pair) {
if (!in_array($user_pair[0], $result_ids)) {
unset($variables['view']->element['#attached']['drupalSettings'][$chartId]['data'][$key]);
}
}
# Reset the key ordering of the render set
$variables['view']->element['#attached']['drupalSettings'][$chartId]['data'] = array_values($variables['view']->element['#attached']['drupalSettings'][$chartId]['data']);
}
/**
* Implements hook_preprocess_HOOK() for regions.
*/
function osulp_preprocess_region(array &$variables): void {
// check for title block image and set uri as twig variable if it exists
if (isset($variables['page_node']->field_page_image[0]) ) {
$variables['image_uri'] = $variables['page_node']->field_page_image[0]->entity->field_media_image->entity->createFileUrl();
} else if (isset($variables['groups'][0]->field_hero_image[0])) {
$variables['image_uri'] = $variables['groups'][0]->field_hero_image[0]->entity->field_media_image->entity->createFileUrl();
}
try {
$variables['is_front'] = \Drupal::service('path.matcher')->isFrontPage();
}
catch (Exception $e) {
$variables['is_front'] = FALSE;
}
}
/**
* Retrieve all group module Group Entity an entity is in
*/
function getGroupsByEntity($entity): array {
$groups = array();
if (!$entity) return $groups;
$relations = \Drupal\group\Entity\GroupRelationship::loadByEntity($entity);
foreach ($relations as $rel) {
if ($rel->getEntity()->getEntityTypeId() == 'node') {
$groups[] = $rel->getGroup();
}
}
return $groups;
}
/**
* Fetch LibCal hours data for all locations from cache or source
*
* @return array Array JSON of objects for LibCal location hours data
*/
function libcal_location_data(): array {
// LIBCAL_LOCATIONS is a list of library location ids as json. eg:
// [
// {
// 1234 => 'valley',
// 5678 => 'guin',
// 9012 => 'cascades',
// }
// ]
// This takes just the interior hash
$libcal_location_ids = json_decode(getenv('LIBCAL_LOCATIONS'), true)[0];
// returned valley, cascades, and guin data
$data = [];
// Invalidate every 6 hours
// Now + 60 seconds * 60 minutes * 6 hours
$invalid_time = time() + 60 * 60 * 6;
// Shared instance of the Drupal Cache
$cache = \Drupal::cache();
// Iterate locations and retrieve/cache LibCal data
foreach ($libcal_location_ids as $loc_id => $group) {
$cid = "osulp_libcal_$loc_id";
// Check Drupal cache for this location's data
if ($cache_data = $cache->get($cid)) {
$data[$group] = $cache_data->data;
} else { // Else retreive from LibCal source
// HTTP Client with pre-filled LibCal bearer token. Either an existing one or a new instance
$client = $client ?? authorized_libcal_client($cache);
// Fetch remote data and cache for later
$data[$group] = fetch_libcal_data($client, $loc_id);
$cache->set($cid, $data[$group], $invalid_time);
}
}
return $data;
}
/**
* Create a \GuzzleHttp\Client with a valid LibCal bearer token
*
* @param \Drupal::cache Current Drupal Cache object
* @return \GuzzleHttp\Client Client with bearer token
*/
function authorized_libcal_client($cache): \GuzzleHttp\Client {
// Check Drupal cache for an active token
if ($cache_data = $cache->get('libcal_access_token')) {
$access_token = $cache_data->data;
} else { // Else retreive token from LibCal
$access_token = libcal_bearer_token();
// Expire after 3400 seconds
// LibCal tokens are valid for 3600 seconds so lets leave some wiggle room
$cache->set('libcal_access_token', $access_token, time() + 3400);
}
return new \GuzzleHttp\Client([
'headers' => [
'Authorization' => "Bearer $access_token",
],
]);
}
/**
* Fetch from source the LibCal hours data for a location ID
*
* @param \GuzzleHttp\Client Client with bearer token
* @param integer Location ID
* @return array JSON of libcal location hours data
*/
function fetch_libcal_data($client, $location_id): array {
// Start of last week
$start_day = new DateTime('Sunday last week');
$start_day = $start_day->format('Y-m-d');
// End of next week
$end_day = new DateTime('Saturday next week');
$end_day = $end_day->format('Y-m-d');
// Retrieve data for $location_id (LibCal ID for Library), for time period $start_day - $end_day
$response = $client->get("https://oregonstate.libcal.com/api/1.1/hours/$location_id?from=$start_day&to=$end_day");
$result = json_decode((string)$response->getBody(), TRUE);
return $result;
}
/**
* Retrieve new LibCal bearer token
*
* @return string New libcal bearer token
*/
function libcal_bearer_token(): string {
$client = \Drupal::httpClient();
$response = $client->post("https://oregonstate.libcal.com/api/1.1/oauth/token",[
'form_params' => [
'client_id' => getenv('LIBCAL_CLIENT_ID'),
'client_secret' => getenv('LIBCAL_CLIENT_SECRET'),
'grant_type' => 'client_credentials',
],
]);
$result = json_decode((string) $response->getBody());
return $result->access_token;
}
/**
* Narrow libcal data to next 7 days and format data for use in twig
*
* @param Array JSON of libcal location hours data
*
* @return Array Well formatted libcal data
*/
function format_this_weeks_dates($libcal_dates): array {
if (empty($libcal_dates)) {
return [];
}
// $dates will be our return data, a list of libcal hours for each day
$dates = [];
// Get the libcal data for a week, starting with today
// Stuff these into a $date associative array in the form [ Y-m-d => libcal_data ]
for ($i = 0; $i < 7; ++$i) {
// Add $i days to get to the correct future day. When $i = 0 it will be today
$start_day = new DateTime('Today');
$start_day->modify("+$i days");
$date = $start_day->format('Y-m-d');
// If we don't have data for every single day, the data in LibCal is incomplete and we can't properly display the hours
if ($libcal_dates[$date] == null) return [];
// Add the libcal data for the day to $dates
$dates[$date] = format_libcal_date($libcal_dates[$date]);
// Add the human readable name of day, eg: "Monday"
$dates[$date]['day'] = $start_day->format('l');
// Add whether today is open or closed
$dates[$date]['open'] = strtolower($libcal_dates[$date]['status'] ?? '') == 'open';
}
return $dates;
}
/**
* Turn one days worth of libcal data into a twig-ready formatted Hash
*
* @param Array JSON of libcal location hours data for one day
*
* @return Array Twig variable formatted libcal data for one day
*/
function format_libcal_date($libcal_day_data) {
if (!isset($libcal_day_data['hours'])) {
// If the day is a closure exception, just get the 'note' from the exception
return ['message' => $libcal_day_data['note'] ?? ''];
}
// From and to time for this day
$from = $libcal_day_data['hours'][0]['from'];
$to = $libcal_day_data['hours'][0]['to'];
// Convert that to unix timestamp
$from_unix = strtotime($from);
$to_unix = strtotime($to);
// If the closing hour is less than the opening hour, it actually closes the next day
if ($to_unix < $from_unix) $to_unix = strtotime("$to + 1 day");
// Structure the open/close hours for <time> datetime attribute
$from_structured = date('Y-m-d H:i', $from_unix);
$to_structured = date('Y-m-d H:i', $to_unix);
// Wrap it all together for a twig variable
return [
'from' => $from,
'from_structured' => $from_structured,
'to' => $to,
'to_structured' => $to_structured,
];
}