-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathosulp.theme
283 lines (249 loc) · 8.8 KB
/
osulp.theme
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
<?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');
$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',
]);
}
}
/**
* 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']) && $variables['page_node'] && $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 ($variables['groups'][0] && $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_time = new DateTime('midnight last week - 1 day');
$start_time = $start_time->format('Y-m-d');
// End of next week
$end_time = new DateTime('midnight next week + 5 days');
$end_time = $end_time->format('Y-m-d');
// Retrieve data for $location_id (LibCal ID for Library), for time period $start_time - $end_time
$response = $client->get("https://oregonstate.libcal.com/api/1.1/hours/$location_id?from=$start_time&to=$end_time");
$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 this week 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 (!isset($libcal_dates)) {
return [];
}
$dates = [];
$today = date('Y-m-d');
// End of last week. We'll be adding 1 day to this seven times to get this week's data
$start_time = new DateTime('midnight this week - 2 day');
// Get the date and day of the week for each day of this week
for ($i = 0; $i < 7; ++$i) {
// Add a day to get to the next day in the week
$start_time->modify("+1 days");
$date = $start_time->format('Y-m-d');
if (isset($libcal_dates[$date]['hours'])) {
// From and to time for this day
$from = $libcal_dates[$date]['hours'][0]['from'];
$to = $libcal_dates[$date]['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
$dates[$date] = [
'from' => $from,
'from_structured' => $from_structured,
'to' => $to,
'to_structured' => $to_structured,
];
} else { // If this is an exception just get the message or a default
$dates[$date] = [
'message' => $libcal_dates[$date]['note'] ?: '',
];
}
// Add some consistent information
$dates[$date]['day'] = $start_time->format('l');
$dates[$date]['status'] = $libcal_dates[$date]['status'];
}
// Add today's info as a unique element
array_unshift($dates, $dates[$today]);
return $dates;
}