Skip to content

Commit

Permalink
8.2.3
Browse files Browse the repository at this point in the history
  • Loading branch information
pookmish authored Mar 16, 2023
2 parents 7b7f6f5 + da19e20 commit b3fe843
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 42 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Stanford Fields

8.2.3
--------------------------------------------------------------------------------
_Release Date: 2023-03-16_

- Provide a graceful fallback for Localist field widget if the API fails.

8.2.2
--------------------------------------------------------------------------------
_Release Date: 2023-02-27_
Expand Down
74 changes: 35 additions & 39 deletions src/Plugin/Field/FieldWidget/LocalistUrlWidget.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,7 @@ public function validateUrl(array &$element, FormStateInterface $form_state, arr
}
try {
$response = $this->client->request('GET', '/api/2/events', ['base_uri' => $input]);
$response = json_decode((string) $response->getBody(), TRUE);

if (!is_array($response)) {
throw new \Exception('Invalid response');
}
json_decode((string) $response->getBody(), TRUE, 512, JSON_THROW_ON_ERROR);
}
catch (\Throwable $e) {
$form_state->setError($element, $this->t('URL is not a Localist domain.'));
Expand Down Expand Up @@ -160,6 +156,16 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
if (!$this->getSetting('base_url')) {
return $element;
}

try {
$this->getApiData();
}
catch (\Throwable $e) {
$this->messenger()
->addError('Unable to fetch data from the system to provide easy to use field options. Please try again later.');
return $element;
}

$element['uri']['#access'] = FALSE;
$element['title']['#access'] = FALSE;
$element['attributes']['#access'] = FALSE;
Expand Down Expand Up @@ -263,8 +269,6 @@ protected static function flattenValues(array $array): array {
* Form element render array.
*/
protected function getFilters(array $default_value = []): array {
$this->getApiData();

$element = [];
foreach ($this->apiData['events/filters'] ?? [] as $filter_key => $options) {
$filter_options = [];
Expand Down Expand Up @@ -295,7 +299,6 @@ protected function getFilters(array $default_value = []): array {
* Form element render array.
*/
protected function getGroups(?string $default_value = NULL): array {
$this->getApiData();
$element = [
'#type' => 'select',
'#title' => $this->t('Departments/Groups'),
Expand Down Expand Up @@ -324,7 +327,6 @@ protected function getGroups(?string $default_value = NULL): array {
* Form element render array.
*/
protected function getPlaces(?string $default_value = NULL): array {
$this->getApiData();
$element = [
'#type' => 'select',
'#title' => $this->t('Venues'),
Expand All @@ -341,11 +343,8 @@ protected function getPlaces(?string $default_value = NULL): array {

/**
* Get the data from the localist API.
*
* @return array
* API Data.
*/
protected function getApiData(): array {
protected function getApiData() {
// Data was already fetched.
if ($this->apiData) {
return $this->apiData;
Expand All @@ -364,7 +363,15 @@ protected function getApiData(): array {
}
}

return $this->fetchApiData();
try {
$this->fetchApiData();
}
catch (\Throwable $e) {
if (!$this->apiData) {
throw $e;
}
}

}

/**
Expand All @@ -381,20 +388,14 @@ protected function fetchApiData(): array {
'query' => ['pp' => 1],
];

try {
$promises = [
'groups' => $this->client->requestAsync('GET', '/api/2/groups', $options),
'departments' => $this->client->requestAsync('GET', '/api/2/departments', $options),
'places' => $this->client->requestAsync('GET', '/api/2/places', $options),
'events/filters' => $this->client->requestAsync('GET', '/api/2/events/filters', $options),
'events/labels' => $this->client->requestAsync('GET', '/api/2/events/labels', $options),
];
$results = self::unwrapAsyncRequests($promises);
}
catch (\Exception $e) {
$this->messenger()->addError('Unable to fetch data to populate the field options. Please try again later.');
return $this->apiData;
}
$promises = [
'groups' => $this->client->requestAsync('GET', '/api/2/groups', $options),
'departments' => $this->client->requestAsync('GET', '/api/2/departments', $options),
'places' => $this->client->requestAsync('GET', '/api/2/places', $options),
'events/filters' => $this->client->requestAsync('GET', '/api/2/events/filters', $options),
'events/labels' => $this->client->requestAsync('GET', '/api/2/events/labels', $options),
];
$results = self::unwrapAsyncRequests($promises);

foreach ($results as $key => $response) {
if (empty($response['page']['total'])) {
Expand All @@ -404,6 +405,7 @@ protected function fetchApiData(): array {

$this->apiData[$key] = $this->fetchPagedApiData($key, $response['page']['total']);
}

$this->cache->set("localist_api:$base_url", [
'data' => $this->apiData,
'expires' => time() + 60 * 60,
Expand Down Expand Up @@ -432,17 +434,11 @@ protected function fetchPagedApiData($endpoint, $total_count): array {
];

$number_of_pages = ceil($total_count / 100);
try {
for ($i = 1; $i <= $number_of_pages; $i++) {
$options['query']['page'] = $i;
$paged_data[$i] = $this->client->requestAsync('GET', '/api/2/' . $endpoint, $options);
}
$paged_data = self::unwrapAsyncRequests($paged_data);
}
catch (\Exception $e) {
$this->messenger()->addError('Unable to fetch data to populate the field options. Please try again later.');
return [];
for ($i = 1; $i <= $number_of_pages; $i++) {
$options['query']['page'] = $i;
$paged_data[$i] = $this->client->requestAsync('GET', '/api/2/' . $endpoint, $options);
}
$paged_data = self::unwrapAsyncRequests($paged_data);

$data = [];
foreach ($paged_data as $page) {
Expand All @@ -466,7 +462,7 @@ protected static function unwrapAsyncRequests(array $promises): array {
$promises = Utils::unwrap($promises);
/** @var \GuzzleHttp\Psr7\Response $response */
foreach ($promises as &$response) {
$response = json_decode((string) $response->getBody(), TRUE);
$response = json_decode((string) $response->getBody(), TRUE, 512, JSON_THROW_ON_ERROR);
}

return $promises;
Expand Down
2 changes: 1 addition & 1 deletion stanford_fields.info.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ type: module
description: 'Field types, widgets and formatters to enhance Drupal and Contrib.'
core_version_requirement: ^9 || ^10
package: Stanford
version: 8.2.1
version: 8.2.3
dependencies:
- drupal:field
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,7 @@ public function testWidgetForm() {
$entity_form_display->buildForm($node, $form, $form_state);
$widget_value = $form['su_localist_url']['widget'];

$this->assertIsArray($widget_value[0]['filters']['venue_id']);
$this->assertEmpty($widget_value[0]['filters']['venue_id']['#options']);
$this->assertArrayNotHasKey('filters', $widget_value[0]);

\Drupal::cache()->set('localist_api:https://events.stanford.edu', [
'data' => ['places' => [['place' => ['id' => 12345, 'name' => 'foobar']]]],
Expand Down

0 comments on commit b3fe843

Please sign in to comment.