From 9bafdc8e4f62adbb11a03a2f84e5d634a7f2dd62 Mon Sep 17 00:00:00 2001 From: Ion Eftodii Date: Wed, 4 Sep 2024 15:41:01 +0300 Subject: [PATCH 01/60] YOR-11: Create Events Calendar Functional --- .../ViewsBasicDefaultFormatter.php | 65 +++-- .../src/Service/EventsCalendar.php | 268 ++++++++++++++++++ .../src/Service/EventsCalendarInterface.php | 102 +++++++ .../ys_views_basic/src/ViewsBasicManager.php | 5 + .../views-basic-events-calendar.html.twig | 5 + .../ys_views_basic/ys_views_basic.module | 5 + .../ys_views_basic.services.yml | 4 + 7 files changed, 432 insertions(+), 22 deletions(-) create mode 100644 web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Service/EventsCalendar.php create mode 100644 web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Service/EventsCalendarInterface.php create mode 100644 web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/templates/views-basic-events-calendar.html.twig diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldFormatter/ViewsBasicDefaultFormatter.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldFormatter/ViewsBasicDefaultFormatter.php index 3428c952e7..f1a2986836 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldFormatter/ViewsBasicDefaultFormatter.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldFormatter/ViewsBasicDefaultFormatter.php @@ -7,6 +7,7 @@ use Drupal\Core\Field\FormatterBase; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Render\Renderer; +use Drupal\ys_views_basic\Service\EventsCalendarInterface; use Drupal\ys_views_basic\ViewsBasicManager; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -37,6 +38,13 @@ class ViewsBasicDefaultFormatter extends FormatterBase implements ContainerFacto */ protected $rendererService; + /** + * The Events Calendar service. + * + * @var \Drupal\ys_views_basic\Service\EventsCalendarInterface + */ + protected EventsCalendarInterface $eventsCalendar; + /** * Constructs an views basic default formatter object. * @@ -54,14 +62,16 @@ class ViewsBasicDefaultFormatter extends FormatterBase implements ContainerFacto * The view mode. * @param array $third_party_settings * Any third party settings. - * @param \Drupal\ys_views_basic\Plugin\ViewsBasicManager $viewsBasicManager + * @param \Drupal\ys_views_basic\ViewsBasicManager $viewsBasicManager * The views basic manager service. * @param \Drupal\Core\Render\Renderer $renderer_service * Drupal Core renderer service. + * @param \Drupal\ys_views_basic\Service\EventsCalendarInterface $eventsCalendar + * The Events Calendar service. */ public function __construct( string $plugin_id, - $plugin_definition, + $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, string $label, @@ -69,6 +79,7 @@ public function __construct( array $third_party_settings, ViewsBasicManager $viewsBasicManager, Renderer $renderer_service, + EventsCalendarInterface $eventsCalendar, ) { parent::__construct( $plugin_id, @@ -81,17 +92,13 @@ public function __construct( $this->rendererService = $renderer_service, ); $this->viewsBasicManager = $viewsBasicManager; + $this->eventsCalendar = $eventsCalendar; } /** * {@inheritdoc} */ - public static function create( - ContainerInterface $container, - array $configuration, - $plugin_id, - $plugin_definition, - ) { + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { return new static( $plugin_id, $plugin_definition, @@ -102,6 +109,7 @@ public static function create( $configuration['third_party_settings'], $container->get('ys_views_basic.views_basic_manager'), $container->get('renderer'), + $container->get('ys_views_basic.events_calendar') ); } @@ -111,23 +119,36 @@ public static function create( public function viewElements(FieldItemListInterface $items, $langcode) { $elements = []; + foreach ($items as $delta => $item) { + // Get decoded parameters. + $paramsDecoded = json_decode($item->getValue()['params'], TRUE); - $view = $this->viewsBasicManager->getView('rendered', $item->getValue()['params']); + if ($paramsDecoded['filters']['types'][0] === 'event' && $paramsDecoded['view_mode'] === 'calendar') { + $events_calendar = $this->eventsCalendar + ->getCalendar(date('m'), date('Y')); - $elements[$delta] = [ - '#theme' => 'views_basic_formatter_default', - '#view' => $view, - // Extract exposed filters from the view and place them separately. - // This is necessary because we are conditionally displaying - // specific exposed filters based on field configuration. - // By placing the exposed filters outside of the view rendering - // context, we ensure that they do not get re-rendered - // when AJAX operations are performed on the view, - // allowing for better control over which filters are displayed - // and maintaining the expected user interface behavior. - '#exposed' => $view['#view']->exposed_widgets, - ]; + $elements[$delta] = [ + '#theme' => 'views_basic_events_calendar', + '#month_data' => $events_calendar, + ]; + } + else { + $view = $this->viewsBasicManager->getView('rendered', $item->getValue()['params']); + $elements[$delta] = [ + '#theme' => 'views_basic_formatter_default', + '#view' => $view, + // Extract exposed filters from the view and place them separately. + // This is necessary because we are conditionally displaying + // specific exposed filters based on field configuration. + // By placing the exposed filters outside of the view rendering + // context, we ensure that they do not get re-rendered + // when AJAX operations are performed on the view, + // allowing for better control over which filters are displayed + // and maintaining the expected user interface behavior. + '#exposed' => $view['#view']->exposed_widgets, + ]; + } } return $elements; diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Service/EventsCalendar.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Service/EventsCalendar.php new file mode 100644 index 0000000000..179c0586e0 --- /dev/null +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Service/EventsCalendar.php @@ -0,0 +1,268 @@ +entityTypeManager = $entity_type_manager; + $this->aliasManager = $alias_manager; + $this->nodeStorage = $entity_type_manager->getStorage('node'); + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container): static { + return new static( + $container->get('entity_type.manager'), + $container->get('path_alias.manager') + ); + } + + /** + * {@inheritdoc} + */ + public function getCalendar(string $month, string $year): array { + // Create a date object for the first day of the given month and year. + $firstDayOfMonth = new DrupalDateTime("$year-$month-01"); + $totalDaysInMonth = (int) $firstDayOfMonth->format('t'); + $startDayOfWeek = (int) $firstDayOfMonth->format('w'); + $lastDayOfMonth = new DrupalDateTime("$year-$month-$totalDaysInMonth"); + $endDayOfWeek = (int) $lastDayOfMonth->format('w'); + + $paddingStart = $startDayOfWeek; + $paddingEnd = 6 - $endDayOfWeek; + $totalCells = $totalDaysInMonth + $paddingStart + $paddingEnd; + $totalRows = (int) ceil($totalCells / 7); + $calendarRows = []; + + // Calculate the previous month and year. + $previousMonthDate = clone $firstDayOfMonth; + $previousMonthDate->modify('-1 month'); + $daysInPreviousMonth = (int) $previousMonthDate->format('t'); + $previousMonth = $previousMonthDate->format('m'); + $previousYear = $previousMonthDate->format('Y'); + + // Calculate the next month and year. + $nextMonthDate = clone $lastDayOfMonth; + $nextMonthDate->modify('+1 month'); + $nextMonth = $nextMonthDate->format('m'); + $nextYear = $nextMonthDate->format('Y'); + + // Load all events for the given month and year. + $monthlyEvents = $this->loadMonthlyEvents($month, $year); + + $currentDay = 1; + + for ($row = 0; $row < $totalRows; $row++) { + $calendarRows[$row] = []; + for ($cell = 0; $cell < 7; $cell++) { + if ($row == 0 && $cell < $paddingStart) { + // Fill in days from the previous month. + $day = $daysInPreviousMonth - ($paddingStart - $cell - 1); + $calendarRows[$row][] = $this->createCalendarCell($day, $previousMonth, $previousYear, $monthlyEvents); + } + elseif ($row == $totalRows - 1 && $cell > $endDayOfWeek) { + // Fill in days from the next month. + $day = $cell - $endDayOfWeek; + $calendarRows[$row][] = $this->createCalendarCell($day, $nextMonth, $nextYear, $monthlyEvents); + } + else { + // Normal date cell within the current month. + $calendarRows[$row][] = $this->createCalendarCell($currentDay, $month, $year, $monthlyEvents); + $currentDay++; + } + } + } + + return $calendarRows; + } + + /** + * {@inheritdoc} + */ + public function createCalendarCell(int $day, string $month, string $year, array $events): array { + return [ + 'date' => [ + 'day' => str_pad($day, 2, '0', STR_PAD_LEFT), + 'month' => $month, + 'year' => $year, + ], + 'events' => $this->getEvents($day, $month, $year, $events), + ]; + } + + /** + * {@inheritdoc} + */ + public function getEvents(int $day, string $month, string $year, array $events): array { + $startDate = new DrupalDateTime("$year-$month-$day 00:00:00"); + $endDate = new DrupalDateTime("$year-$month-$day 23:59:59"); + + $startTimestamp = $startDate->getTimestamp(); + $endTimestamp = $endDate->getTimestamp(); + + $events_data = []; + foreach ($events as $event) { + if (!$event->get('field_event_date')->isEmpty()) { + // Handle recurrence rules if present. + if ($event->field_event_date?->rrule) { + + /** @var \Drupal\smart_date_recur\Entity\SmartDateRule $rule */ + $rule = $this->entityTypeManager->getStorage('smart_date_rule') + ->load($event->field_event_date->rrule); + + if ($rule instanceof SmartDateRule) { + // Iterate over the stored instances to find occurrences for the + // current day. + foreach ($rule->getStoredInstances() as $instance) { + $instanceStartTimestamp = $instance['value']; + $instanceEndTimestamp = $instance['end_value']; + + // Check if the instance overlaps with the current day. + if ($instanceStartTimestamp <= $endTimestamp && $instanceEndTimestamp >= $startTimestamp) { + $time = $this->isAllDay($instanceStartTimestamp, $instanceEndTimestamp) + ? 'All Day' + : date('g:iA', $instanceStartTimestamp) . ' to ' . date('g:iA', $instanceEndTimestamp); + + $events_data[] = $this->createEventArray($event, $time, $instanceStartTimestamp); + } + } + } + } + else { + // Iterate through the nodes to extract event details. + foreach ($event->get('field_event_date')->getValue() as $eventDate) { + $eventStartTimestamp = $eventDate['value']; + $eventEndTimestamp = $eventDate['end_value']; + + // Check if the event overlaps with the current day. + if ($eventStartTimestamp <= $endTimestamp && $eventEndTimestamp >= $startTimestamp) { + $time = $this->isAllDay($eventStartTimestamp, $eventEndTimestamp) + ? 'All Day' + : date('g:iA', $eventStartTimestamp) . ' to ' . date('g:iA', $eventEndTimestamp); + + // Add event to the list if it overlaps with the current day. + $events_data[] = $this->createEventArray($event, $time, $eventStartTimestamp); + } + } + } + } + } + + // Sort events by the start timestamp. + usort($events_data, function ($a, $b) { + return $a['timestamp'] <=> $b['timestamp']; + }); + + return $events_data; + } + + /** + * {@inheritdoc} + */ + public function createEventArray($node, string $time, int $timestamp): array { + // Extract the event's categories. + $categories = implode(' | ', array_map(function ($term) { + return $term->label(); + }, $node->get('field_category')->referencedEntities())); + + // Extract the event's tags. + $tags = implode(' | ', array_map(function ($term) { + return $term->label(); + }, $node->get('field_tags')->referencedEntities())); + + // Build and return the event array. + return [ + 'category' => $categories, + 'title' => $node->label(), + 'url' => $this->aliasManager->getAliasByPath('/node/' . $node->id()), + 'time' => $time, + 'type' => $tags, + 'timestamp' => $timestamp, + ]; + } + + /** + * {@inheritdoc} + */ + public function isAllDay(int $start_ts, int $end_ts, string $timezone = NULL): bool { + if ($timezone) { + $default_tz = date_default_timezone_get(); + date_default_timezone_set($timezone); + } + + $temp_start = date('H:i', $start_ts); + $temp_end = date('H:i', $end_ts); + + if ($timezone) { + date_default_timezone_set($default_tz); + } + + return $temp_start == '00:00' && $temp_end == '23:59'; + } + + /** + * {@inheritdoc} + */ + public function loadMonthlyEvents(string $month, string $year): array { + $startDate = new DrupalDateTime("$year-$month-01 00:00:00"); + $endDate = clone $startDate; + $endDate->modify('last day of this month 23:59:59'); + + // Query to fetch event nodes that overlap with the given month. + $query = $this->nodeStorage->getQuery() + ->accessCheck() + ->condition('type', 'event') + ->condition('status', 1) + ->condition('field_event_date.value', $endDate->getTimestamp(), '<=') + ->condition('field_event_date.end_value', $startDate->getTimestamp(), '>='); + + $nids = $query->execute(); + return $this->nodeStorage->loadMultiple($nids); + } + +} diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Service/EventsCalendarInterface.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Service/EventsCalendarInterface.php new file mode 100644 index 0000000000..b97fd40b27 --- /dev/null +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Service/EventsCalendarInterface.php @@ -0,0 +1,102 @@ + '/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/assets/icons/display-type-condensed.svg', 'img_alt' => 'Icon showing 3 generic list items one on top of the other with no images on the items.', ], + 'calendar' => [ + 'label' => 'Calendar', + 'img' => '/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/assets/icons/content-type-event.svg', + 'img_alt' => 'Calendar', + ], ], 'sort_by' => [ 'field_publish_date:DESC' => 'Publish Date - newer first', diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/templates/views-basic-events-calendar.html.twig b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/templates/views-basic-events-calendar.html.twig new file mode 100644 index 0000000000..7d089c2a19 --- /dev/null +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/templates/views-basic-events-calendar.html.twig @@ -0,0 +1,5 @@ +{{ attach_library('atomic/calendar') }} + +{% include "@organisms/calendar/yds-calendar.twig" with { + month:month_data +} %} diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/ys_views_basic.module b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/ys_views_basic.module index 1ceecec9d0..1718c5664e 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/ys_views_basic.module +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/ys_views_basic.module @@ -30,6 +30,11 @@ function ys_views_basic_theme($existing, $type, $theme, $path): array { 'contentType' => NULL, ], ], + 'views_basic_events_calendar' => [ + 'variables' => [ + 'month_data' => [], + ], + ], ]; } diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/ys_views_basic.services.yml b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/ys_views_basic.services.yml index 4039bf8a2f..0a37a9f47d 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/ys_views_basic.services.yml +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/ys_views_basic.services.yml @@ -3,3 +3,7 @@ services: ys_views_basic.views_basic_manager: class: Drupal\ys_views_basic\ViewsBasicManager arguments: ['@entity_type.manager', '@entity_display.repository'] + + ys_views_basic.events_calendar: + class: Drupal\ys_views_basic\Service\EventsCalendar + arguments: ['@entity_type.manager', '@path_alias.manager'] From 534708ced817839bfcfe40ee959ba02af8e576f0 Mon Sep 17 00:00:00 2001 From: Ion Eftodii Date: Wed, 4 Sep 2024 15:46:01 +0300 Subject: [PATCH 02/60] YOR-11: Remove the unused renderer service --- .../ViewsBasicDefaultFormatter.php | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldFormatter/ViewsBasicDefaultFormatter.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldFormatter/ViewsBasicDefaultFormatter.php index f1a2986836..10119a4599 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldFormatter/ViewsBasicDefaultFormatter.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldFormatter/ViewsBasicDefaultFormatter.php @@ -6,7 +6,6 @@ use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Field\FormatterBase; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; -use Drupal\Core\Render\Renderer; use Drupal\ys_views_basic\Service\EventsCalendarInterface; use Drupal\ys_views_basic\ViewsBasicManager; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -29,14 +28,7 @@ class ViewsBasicDefaultFormatter extends FormatterBase implements ContainerFacto * * @var \Drupal\ys_views_basic\ViewsBasicManager */ - protected $viewsBasicManager; - - /** - * The renderer service. - * - * @var \Drupal\Core\Render\Renderer - */ - protected $rendererService; + protected ViewsBasicManager $viewsBasicManager; /** * The Events Calendar service. @@ -64,21 +56,18 @@ class ViewsBasicDefaultFormatter extends FormatterBase implements ContainerFacto * Any third party settings. * @param \Drupal\ys_views_basic\ViewsBasicManager $viewsBasicManager * The views basic manager service. - * @param \Drupal\Core\Render\Renderer $renderer_service - * Drupal Core renderer service. * @param \Drupal\ys_views_basic\Service\EventsCalendarInterface $eventsCalendar * The Events Calendar service. */ public function __construct( string $plugin_id, - $plugin_definition, + $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, string $label, string $view_mode, array $third_party_settings, ViewsBasicManager $viewsBasicManager, - Renderer $renderer_service, EventsCalendarInterface $eventsCalendar, ) { parent::__construct( @@ -89,7 +78,6 @@ public function __construct( $label, $view_mode, $third_party_settings, - $this->rendererService = $renderer_service, ); $this->viewsBasicManager = $viewsBasicManager; $this->eventsCalendar = $eventsCalendar; @@ -108,7 +96,6 @@ public static function create(ContainerInterface $container, array $configuratio $configuration['view_mode'], $configuration['third_party_settings'], $container->get('ys_views_basic.views_basic_manager'), - $container->get('renderer'), $container->get('ys_views_basic.events_calendar') ); } @@ -116,7 +103,7 @@ public static function create(ContainerInterface $container, array $configuratio /** * Define how the field type is showed. */ - public function viewElements(FieldItemListInterface $items, $langcode) { + public function viewElements(FieldItemListInterface $items, $langcode): array { $elements = []; From d2a265650d1bd1dd432b97cd11a0552e9b6a3aba Mon Sep 17 00:00:00 2001 From: Rodica Ciorba Date: Fri, 6 Sep 2024 18:16:24 +0300 Subject: [PATCH 03/60] YOR-11: Deliver tags as an array in the calendar templates --- .../custom/ys_views_basic/src/Service/EventsCalendar.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Service/EventsCalendar.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Service/EventsCalendar.php index 179c0586e0..2eb2331858 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Service/EventsCalendar.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Service/EventsCalendar.php @@ -211,9 +211,7 @@ public function createEventArray($node, string $time, int $timestamp): array { }, $node->get('field_category')->referencedEntities())); // Extract the event's tags. - $tags = implode(' | ', array_map(function ($term) { - return $term->label(); - }, $node->get('field_tags')->referencedEntities())); + $tags = array_map(fn($term) => $term->label(), $node->get('field_tags')->referencedEntities()); // Build and return the event array. return [ From 4b72ecd0530bb966e1f536c17e924e8e0077c56a Mon Sep 17 00:00:00 2001 From: Constantin Marjina Date: Wed, 11 Sep 2024 18:06:04 +0300 Subject: [PATCH 04/60] YOR-11: Add ajax events controller --- .../Controller/EventsCalendarController.php | 66 +++++++++++++++++++ .../ViewsBasicDefaultFormatter.php | 11 ++++ .../ys_views_basic/src/ViewsBasicManager.php | 10 +-- .../ys_views_basic/ys_views_basic.routing.yml | 7 ++ 4 files changed, 89 insertions(+), 5 deletions(-) create mode 100644 web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Controller/EventsCalendarController.php create mode 100644 web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/ys_views_basic.routing.yml diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Controller/EventsCalendarController.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Controller/EventsCalendarController.php new file mode 100644 index 0000000000..e43e8968db --- /dev/null +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Controller/EventsCalendarController.php @@ -0,0 +1,66 @@ +get('ys_views_basic.events_calendar'), + ); + } + + /** + * Builds the response. + */ + public function __invoke(Request $request): AjaxResponse { + $response = new AjaxResponse(); + + if (!$request->request->has('calendar_id') || !$request->request->has('month') || !$request->request->has('year')) { + return $response; + } + + // Calendar wrapper that needs to be updated. + $calendar_id = $request->request->get('calendar_id'); + $month = $request->request->get('month'); + $year = $request->request->get('year'); + + $events_calendar = $this->eventsCalendar + ->getCalendar($month, $year); + + $calendar = [ + '#theme' => 'views_basic_events_calendar', + '#month_data' => $events_calendar, + '#cache' => [ + 'tags' => ['node_list:event'], + ], + ]; + + $response->addCommand(new ReplaceCommand($calendar_id, $calendar)); + + return $response; + } + +} diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldFormatter/ViewsBasicDefaultFormatter.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldFormatter/ViewsBasicDefaultFormatter.php index 10119a4599..56ffeb9444 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldFormatter/ViewsBasicDefaultFormatter.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldFormatter/ViewsBasicDefaultFormatter.php @@ -112,12 +112,23 @@ public function viewElements(FieldItemListInterface $items, $langcode): array { $paramsDecoded = json_decode($item->getValue()['params'], TRUE); if ($paramsDecoded['filters']['types'][0] === 'event' && $paramsDecoded['view_mode'] === 'calendar') { + // Calculate the remaining time until the end of the current month. + $now = new \DateTime(); + $end_of_month = new \DateTime('last day of this month 23:59:59'); + $remaining_time_in_seconds = $end_of_month->getTimestamp() - $now->getTimestamp(); + $events_calendar = $this->eventsCalendar ->getCalendar(date('m'), date('Y')); $elements[$delta] = [ '#theme' => 'views_basic_events_calendar', '#month_data' => $events_calendar, + '#cache' => [ + 'tags' => ['node_list:event'], + // Set max-age to the remaining time until the end of the month. + 'max-age' => $remaining_time_in_seconds, + 'contexts' => ['timezone'], + ], ]; } else { diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/ViewsBasicManager.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/ViewsBasicManager.php index a074fc6a01..157d4d5a8c 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/ViewsBasicManager.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/ViewsBasicManager.php @@ -56,11 +56,6 @@ class ViewsBasicManager extends ControllerBase implements ContainerInjectionInte 'img' => '/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/assets/icons/display-type-condensed.svg', 'img_alt' => 'Icon showing 3 generic list items one on top of the other with no images on the items.', ], - 'calendar' => [ - 'label' => 'Calendar', - 'img' => '/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/assets/icons/content-type-event.svg', - 'img_alt' => 'Calendar', - ], ], 'sort_by' => [ 'field_publish_date:DESC' => 'Publish Date - newer first', @@ -87,6 +82,11 @@ class ViewsBasicManager extends ControllerBase implements ContainerInjectionInte 'img' => '/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/assets/icons/display-type-condensed.svg', 'img_alt' => 'Icon showing 3 generic list items one on top of the other with no images on the items.', ], + 'calendar' => [ + 'label' => 'Calendar', + 'img' => '/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/assets/icons/content-type-event.svg', + 'img_alt' => 'Calendar', + ], ], 'sort_by' => [ 'field_event_date:DESC' => 'Event Date - newer first', diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/ys_views_basic.routing.yml b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/ys_views_basic.routing.yml new file mode 100644 index 0000000000..818b81880f --- /dev/null +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/ys_views_basic.routing.yml @@ -0,0 +1,7 @@ +ys_views_basic.events_calendar: + path: '/events-calendar' + defaults: + _title: 'Events Calendar' + _controller: '\Drupal\ys_views_basic\Controller\EventsCalendarController' + requirements: + _permission: 'access content' From addba4ccd0026640f49e71d828deff377654bed8 Mon Sep 17 00:00:00 2001 From: Ion Eftodii Date: Thu, 12 Sep 2024 16:55:30 +0300 Subject: [PATCH 05/60] YOR-49: Add conditional logic to Views block for Calendar display type --- .../FieldWidget/ViewsBasicDefaultWidget.php | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldWidget/ViewsBasicDefaultWidget.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldWidget/ViewsBasicDefaultWidget.php index 292c2364d5..a55186b52f 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldWidget/ViewsBasicDefaultWidget.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldWidget/ViewsBasicDefaultWidget.php @@ -219,6 +219,11 @@ public function formElement( '#suffix' => '', ]; + // Define the state for when the view mode is 'calendar' once. + $calendarViewInvisibleState = [ + $formSelectors['view_mode_input_selector'] => ['value' => 'calendar'], + ]; + $fieldOptionValue = ($items[$delta]->params) ? $this->viewsBasicManager->getDefaultParamValue('field_options', $items[$delta]->params) : []; $form['group_user_selection']['entity_and_view_mode']['field_options'] = [ '#type' => 'checkboxes', @@ -230,6 +235,7 @@ public function formElement( '#title' => $this->t('Field Display Options'), '#tree' => TRUE, '#default_value' => empty($fieldOptionValue) ? ['show_thumbnail'] : $fieldOptionValue, + '#states' => ['invisible' => $calendarViewInvisibleState], 'show_thumbnail' => [ '#states' => [ 'visible' => [ @@ -252,14 +258,9 @@ public function formElement( '#title' => $this->t('Exposed Filter Options'), '#tree' => TRUE, '#default_value' => ($items[$delta]->params) ? $this->viewsBasicManager->getDefaultParamValue('exposed_filter_options', $items[$delta]->params) : [], + '#states' => ['invisible' => $calendarViewInvisibleState], 'show_year_filter' => [ - '#states' => [ - 'visible' => [ - $formSelectors['entity_types_ajax'] => [ - 'value' => 'post', - ], - ], - ], + '#states' => ['visible' => [$formSelectors['entity_types_ajax'] => ['value' => 'post']]], ], ]; @@ -269,9 +270,8 @@ public function formElement( '#description' => $this->t("Enter a custom label for the Category Filter. This label will be displayed to users as the filter's name. If left blank, the default label Category will be used."), '#default_value' => ($items[$delta]->params) ? $this->viewsBasicManager->getDefaultParamValue('category_filter_label', $items[$delta]->params) : NULL, '#states' => [ - 'visible' => [ - $formSelectors['show_category_filter_selector'] => ['checked' => TRUE], - ], + 'visible' => [$formSelectors['show_category_filter_selector'] => ['checked' => TRUE]], + 'invisible' => $calendarViewInvisibleState, ], ]; @@ -287,9 +287,8 @@ public function formElement( '#prefix' => '
', '#suffix' => '
', '#states' => [ - 'visible' => [ - $formSelectors['show_category_filter_selector'] => ['checked' => TRUE], - ], + 'visible' => [$formSelectors['show_category_filter_selector'] => ['checked' => TRUE]], + 'invisible' => $calendarViewInvisibleState, ], ]; @@ -302,6 +301,7 @@ public function formElement( '#tags' => TRUE, '#target_type' => 'taxonomy_term', '#default_value' => ($items[$delta]->params) ? $this->viewsBasicManager->getDefaultParamValue('terms_include', $items[$delta]->params) : [], + '#states' => ['invisible' => $calendarViewInvisibleState], ]; $form['group_user_selection']['filter_and_sort']['terms_exclude'] = [ @@ -313,6 +313,7 @@ public function formElement( '#tags' => TRUE, '#target_type' => 'taxonomy_term', '#default_value' => ($items[$delta]->params) ? $this->viewsBasicManager->getDefaultParamValue('terms_exclude', $items[$delta]->params) : [], + '#states' => ['invisible' => $calendarViewInvisibleState], ]; $form['group_user_selection']['filter_and_sort']['term_operator'] = [ @@ -329,7 +330,7 @@ public function formElement( 'term-operator-item', ], ], - + '#states' => ['invisible' => $calendarViewInvisibleState], ]; // Gets the view mode options based on Ajax callbacks or initial load. @@ -345,6 +346,7 @@ public function formElement( '#validated' => 'true', '#prefix' => '
', '#suffix' => '
', + '#states' => ['invisible' => $calendarViewInvisibleState], ]; $form['group_user_selection']['entity_specific']['event_time_period'] = [ @@ -357,11 +359,8 @@ public function formElement( ], '#default_value' => ($items[$delta]->params) ? $this->viewsBasicManager->getDefaultParamValue('event_time_period', $items[$delta]->params) : 'future', '#states' => [ - 'visible' => [ - $formSelectors['entity_types_ajax'] => [ - 'value' => 'event', - ], - ], + 'visible' => [$formSelectors['entity_types_ajax'] => ['value' => 'event']], + 'invisible' => $calendarViewInvisibleState, ], ]; @@ -377,6 +376,7 @@ public function formElement( 'limit' => $this->t('Limit to'), 'pager' => $this->t('Pagination after'), ], + '#states' => ['invisible' => $calendarViewInvisibleState], ]; $limitTitle = $this->t('Items'); @@ -397,6 +397,7 @@ public function formElement( '#required' => TRUE, '#prefix' => '
', '#suffix' => '
', + '#states' => ['invisible' => $calendarViewInvisibleState], ]; $form['group_user_selection']['options']['offset'] = [ @@ -408,6 +409,7 @@ public function formElement( '#attributes' => [ 'placeholder' => 0, ], + '#states' => ['invisible' => $calendarViewInvisibleState], ]; $element['group_params']['params'] = [ @@ -420,6 +422,7 @@ public function formElement( 'views-basic--params', ], ], + '#states' => ['invisible' => $calendarViewInvisibleState], ]; $form['#attached']['library'][] = 'ys_views_basic/ys_views_basic'; From 185a6c1bdd9e8578b3232a8a90d67728e36d33e3 Mon Sep 17 00:00:00 2001 From: Ion Eftodii Date: Sun, 15 Sep 2024 14:13:26 +0300 Subject: [PATCH 06/60] YOR-49: Fix visibility of Event Time Period --- .../ys_views_basic/assets/js/views-basic.js | 22 +++++++++++++++++++ .../FieldWidget/ViewsBasicDefaultWidget.php | 6 ++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/assets/js/views-basic.js b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/assets/js/views-basic.js index c6a8580b13..8dbcc3a121 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/assets/js/views-basic.js +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/assets/js/views-basic.js @@ -75,6 +75,28 @@ displayElement.addEventListener('change', updateLimitElement); updateLimitElement(); } + + // Unified selectors to handle both cases + const entityTypesSelector = 'input[name="settings[block_form][group_user_selection][entity_and_view_mode][entity_types]"], input[name="block_form[group_user_selection][entity_and_view_mode][entity_types]"]'; + const viewModeSelector = 'input[name="settings[block_form][group_user_selection][entity_and_view_mode][view_mode]"], input[name="block_form[group_user_selection][entity_and_view_mode][view_mode]"]'; + const eventTimePeriod = document.querySelector('#edit-event-time-period'); + + const entityTypes = document.querySelectorAll(entityTypesSelector); + const viewModes = document.querySelectorAll(viewModeSelector); + + // Function to handle visibility based on conditions + function updateVisibility() { + const entityType = Array.from(entityTypes).find(input => input.checked)?.value; + const viewMode = Array.from(viewModes).find(input => input.checked)?.value; + + if (eventTimePeriod) { + eventTimePeriod.style.display = (entityType === 'event' && viewMode === 'calendar') ? 'none' : ''; + } + } + + entityTypes.forEach(input => input.addEventListener('change', updateVisibility)); + viewModes.forEach(input => input.addEventListener('change', updateVisibility)); + updateVisibility(); }, }; })(Drupal); diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldWidget/ViewsBasicDefaultWidget.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldWidget/ViewsBasicDefaultWidget.php index a55186b52f..1510d3fb67 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldWidget/ViewsBasicDefaultWidget.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldWidget/ViewsBasicDefaultWidget.php @@ -358,10 +358,8 @@ public function formElement( 'all' => $this->t('All Events') . 'All Events icon showing a calendar.', ], '#default_value' => ($items[$delta]->params) ? $this->viewsBasicManager->getDefaultParamValue('event_time_period', $items[$delta]->params) : 'future', - '#states' => [ - 'visible' => [$formSelectors['entity_types_ajax'] => ['value' => 'event']], - 'invisible' => $calendarViewInvisibleState, - ], + '#prefix' => '
', + '#suffix' => '
', ]; $displayValue = ($items[$delta]->params) ? $this->viewsBasicManager->getDefaultParamValue('display', $items[$delta]->params) : 'all'; From 1aba53ff3ad3a3b12de4056c4ed97a28d7cfab6d Mon Sep 17 00:00:00 2001 From: Ion Eftodii Date: Tue, 17 Sep 2024 14:45:14 +0300 Subject: [PATCH 07/60] YOR-48: Event Calendar - Add Multi-day-Event string --- .../src/Service/EventsCalendar.php | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Service/EventsCalendar.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Service/EventsCalendar.php index 2eb2331858..7566d4e903 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Service/EventsCalendar.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Service/EventsCalendar.php @@ -6,6 +6,7 @@ use Drupal\Core\Datetime\DrupalDateTime; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\path_alias\AliasManagerInterface; use Drupal\smart_date_recur\Entity\SmartDateRule; @@ -14,6 +15,8 @@ */ class EventsCalendar implements EventsCalendarInterface { + use StringTranslationTrait; + /** * The entity type manager service. * @@ -165,8 +168,11 @@ public function getEvents(int $day, string $month, string $year, array $events): // Check if the instance overlaps with the current day. if ($instanceStartTimestamp <= $endTimestamp && $instanceEndTimestamp >= $startTimestamp) { $time = $this->isAllDay($instanceStartTimestamp, $instanceEndTimestamp) - ? 'All Day' - : date('g:iA', $instanceStartTimestamp) . ' to ' . date('g:iA', $instanceEndTimestamp); + ? $this->t('All Day') + : $this->t('@start to @end', [ + '@start' => date('g:iA', $instanceStartTimestamp), + '@end' => date('g:iA', $instanceEndTimestamp), + ]); $events_data[] = $this->createEventArray($event, $time, $instanceStartTimestamp); } @@ -181,9 +187,17 @@ public function getEvents(int $day, string $month, string $year, array $events): // Check if the event overlaps with the current day. if ($eventStartTimestamp <= $endTimestamp && $eventEndTimestamp >= $startTimestamp) { - $time = $this->isAllDay($eventStartTimestamp, $eventEndTimestamp) - ? 'All Day' - : date('g:iA', $eventStartTimestamp) . ' to ' . date('g:iA', $eventEndTimestamp); + if (date('Y-m-d', $eventStartTimestamp) !== date('Y-m-d', $eventEndTimestamp)) { + $time = $this->t('Multi-day Event'); + } + else { + $time = $this->isAllDay($eventStartTimestamp, $eventEndTimestamp) + ? $this->t('All Day') + : $this->t('@start to @end', [ + '@start' => date('g:iA', $eventStartTimestamp), + '@end' => date('g:iA', $eventEndTimestamp), + ]); + } // Add event to the list if it overlaps with the current day. $events_data[] = $this->createEventArray($event, $time, $eventStartTimestamp); From ba773714881a92ca56d591471c077b3d88e73886 Mon Sep 17 00:00:00 2001 From: Nathan Plowman Date: Tue, 17 Sep 2024 08:49:27 -0600 Subject: [PATCH 08/60] Fixed comment that got mangled after merging code from develop. --- .../src/Plugin/Field/FieldWidget/ViewsBasicDefaultWidget.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldWidget/ViewsBasicDefaultWidget.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldWidget/ViewsBasicDefaultWidget.php index bfe6b79f61..22f69921ac 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldWidget/ViewsBasicDefaultWidget.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldWidget/ViewsBasicDefaultWidget.php @@ -226,8 +226,8 @@ public function formElement( $fieldOptionValue = ($items[$delta]->params) ? $this->viewsBasicManager->getDefaultParamValue('field_options', $items[$delta]->params) : []; $isNewForm = str_contains($formState->getCompleteForm()['#id'], 'layout-builder-add-block'); - // Set the default value for 'field_options' to ' - nail' + // Set the default value for 'field_options' to 'show_thumbnnail'. + // when creating a new block. $form['group_user_selection']['entity_and_view_mode']['field_options'] = [ '#type' => 'checkboxes', From 77e420ad6190bfa254ec9992e31ab775b81fc0e0 Mon Sep 17 00:00:00 2001 From: Nathan Plowman Date: Tue, 17 Sep 2024 08:58:09 -0600 Subject: [PATCH 09/60] Fixed code sniffer errors. --- .../src/Plugin/Field/FieldWidget/ViewsBasicDefaultWidget.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldWidget/ViewsBasicDefaultWidget.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldWidget/ViewsBasicDefaultWidget.php index 22f69921ac..e821fca424 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldWidget/ViewsBasicDefaultWidget.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/Field/FieldWidget/ViewsBasicDefaultWidget.php @@ -226,8 +226,7 @@ public function formElement( $fieldOptionValue = ($items[$delta]->params) ? $this->viewsBasicManager->getDefaultParamValue('field_options', $items[$delta]->params) : []; $isNewForm = str_contains($formState->getCompleteForm()['#id'], 'layout-builder-add-block'); - // Set the default value for 'field_options' to 'show_thumbnnail'. - + // Set the default value for 'field_options' to 'show_thumbnail' // when creating a new block. $form['group_user_selection']['entity_and_view_mode']['field_options'] = [ '#type' => 'checkboxes', From 0f49d894f067e45456f0f94b02063ec1a5e401bd Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Mon, 23 Sep 2024 10:44:01 -0400 Subject: [PATCH 10/60] chore(YSP-650): fix linting issues --- .../custom/ys_core/src/Plugin/Action/ModeratedPublish.php | 2 +- .../custom/ys_core/src/Plugin/Action/ModeratedUnpublish.php | 2 +- .../modules/custom/ys_layouts/src/Service/LayoutUpdater.php | 2 +- .../modules/custom/ys_localist/src/MetaFieldsManager.php | 2 +- .../src/Plugin/migrate_plus/data_parser/LocalistJson.php | 2 +- .../yalesites_profile/modules/custom/ys_themes/ys_themes.module | 2 +- .../ys_views_basic/src/Plugin/views/filter/PostYearFilter.php | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_core/src/Plugin/Action/ModeratedPublish.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_core/src/Plugin/Action/ModeratedPublish.php index 65cb92234d..039c6f77a9 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_core/src/Plugin/Action/ModeratedPublish.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_core/src/Plugin/Action/ModeratedPublish.php @@ -27,7 +27,7 @@ public function execute($entity = NULL) { /** * {@inheritdoc} */ - public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) { + public function access($object, ?AccountInterface $account = NULL, $return_as_object = FALSE) { $key = $object->getEntityType()->getKey('published'); /** @var \Drupal\Core\Entity\EntityInterface $object */ diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_core/src/Plugin/Action/ModeratedUnpublish.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_core/src/Plugin/Action/ModeratedUnpublish.php index 20325818bb..460b10bbc5 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_core/src/Plugin/Action/ModeratedUnpublish.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_core/src/Plugin/Action/ModeratedUnpublish.php @@ -27,7 +27,7 @@ public function execute($entity = NULL) { /** * {@inheritdoc} */ - public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) { + public function access($object, ?AccountInterface $account = NULL, $return_as_object = FALSE) { $key = $object->getEntityType()->getKey('published'); /** @var \Drupal\Core\Entity\EntityInterface $object */ diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_layouts/src/Service/LayoutUpdater.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_layouts/src/Service/LayoutUpdater.php index 2bcaf6660d..a75694c344 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_layouts/src/Service/LayoutUpdater.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_layouts/src/Service/LayoutUpdater.php @@ -2,7 +2,6 @@ namespace Drupal\ys_layouts\Service; -use Drupal\block_content\Entity\BlockContent; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Database\Connection; use Drupal\Core\Entity\EntityFieldManager; @@ -10,6 +9,7 @@ use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; +use Drupal\block_content\Entity\BlockContent; use Drupal\node\NodeInterface; use Psr\Log\LoggerInterface; diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_localist/src/MetaFieldsManager.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_localist/src/MetaFieldsManager.php index 7df6cb1ae2..5b2cfa4dc6 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_localist/src/MetaFieldsManager.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_localist/src/MetaFieldsManager.php @@ -2,11 +2,11 @@ namespace Drupal\ys_localist; -use Drupal\calendar_link\Twig\CalendarLinkTwigExtension; use Drupal\Core\Datetime\DateFormatter; use Drupal\Core\Entity\EntityTypeManager; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Url; +use Drupal\calendar_link\Twig\CalendarLinkTwigExtension; use Drupal\node\NodeInterface; use Symfony\Component\DependencyInjection\ContainerInterface; diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_localist/src/Plugin/migrate_plus/data_parser/LocalistJson.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_localist/src/Plugin/migrate_plus/data_parser/LocalistJson.php index c1d7ca7ab7..094fd64fdc 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_localist/src/Plugin/migrate_plus/data_parser/LocalistJson.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_localist/src/Plugin/migrate_plus/data_parser/LocalistJson.php @@ -49,7 +49,7 @@ protected function getSourceData(string $url): array { // If json_decode() has returned NULL, it might be that the data isn't // valid utf8 see http://php.net/manual/en/function.json-decode.php#86997. if (is_null($source_data)) { - $utf8response = utf8_encode($response); + $utf8response = mb_convert_encoding($response, 'UTF-8', 'ISO-8859-1'); $source_data = json_decode($utf8response, TRUE, 512, JSON_THROW_ON_ERROR); } diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_themes/ys_themes.module b/web/profiles/custom/yalesites_profile/modules/custom/ys_themes/ys_themes.module index d675ad1140..0d4db3f42e 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_themes/ys_themes.module +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_themes/ys_themes.module @@ -25,7 +25,7 @@ use Drupal\field\Entity\FieldStorageConfig; * * @see options_allowed_values() */ -function ys_themes_allowed_values_function(FieldStorageConfig $definition, ContentEntityInterface $entity = NULL, $cacheable) { +function ys_themes_allowed_values_function(FieldStorageConfig $definition, ?ContentEntityInterface $entity = NULL, $cacheable) { $options = []; $config = \Drupal::config('ys_themes.component_overrides'); diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/views/filter/PostYearFilter.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/views/filter/PostYearFilter.php index bb9dc2b371..5c9b2f9abc 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/views/filter/PostYearFilter.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Plugin/views/filter/PostYearFilter.php @@ -56,7 +56,7 @@ public static function create(ContainerInterface $container, array $configuratio /** * {@inheritdoc} */ - public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) { + public function init(ViewExecutable $view, DisplayPluginBase $display, ?array &$options = NULL) { parent::init($view, $display, $options); $this->valueTitle = $this->t('Post Year Filter'); From b31853dc5f95b0951e256ce95d1337f11766ea8d Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Mon, 23 Sep 2024 14:09:31 -0400 Subject: [PATCH 11/60] feat(YSP-680): add dials for media size --- ...lay.block_content.image_banner.default.yml | 7 +++++++ ...lay.block_content.image_banner.default.yml | 10 +++++++++ ...ent.image_banner.field_style_variation.yml | 21 +++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 web/profiles/custom/yalesites_profile/config/sync/field.field.block_content.image_banner.field_style_variation.yml diff --git a/web/profiles/custom/yalesites_profile/config/sync/core.entity_form_display.block_content.image_banner.default.yml b/web/profiles/custom/yalesites_profile/config/sync/core.entity_form_display.block_content.image_banner.default.yml index a3492304ad..c842ca6fd8 100644 --- a/web/profiles/custom/yalesites_profile/config/sync/core.entity_form_display.block_content.image_banner.default.yml +++ b/web/profiles/custom/yalesites_profile/config/sync/core.entity_form_display.block_content.image_banner.default.yml @@ -5,6 +5,7 @@ dependencies: config: - block_content.type.image_banner - field.field.block_content.image_banner.field_media + - field.field.block_content.image_banner.field_style_variation module: - media_library - media_library_edit @@ -22,6 +23,12 @@ content: third_party_settings: media_library_edit: show_edit: '1' + field_style_variation: + type: options_select + weight: 11 + region: content + settings: { } + third_party_settings: { } info: type: string_textfield weight: 0 diff --git a/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.block_content.image_banner.default.yml b/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.block_content.image_banner.default.yml index e7362d3b0c..7db3299c63 100644 --- a/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.block_content.image_banner.default.yml +++ b/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.block_content.image_banner.default.yml @@ -5,6 +5,9 @@ dependencies: config: - block_content.type.image_banner - field.field.block_content.image_banner.field_media + - field.field.block_content.image_banner.field_style_variation + module: + - options id: block_content.image_banner.default targetEntityType: block_content bundle: image_banner @@ -19,5 +22,12 @@ content: third_party_settings: { } weight: 0 region: content + field_style_variation: + type: list_key + label: hidden + settings: { } + third_party_settings: { } + weight: 5 + region: content hidden: search_api_excerpt: true diff --git a/web/profiles/custom/yalesites_profile/config/sync/field.field.block_content.image_banner.field_style_variation.yml b/web/profiles/custom/yalesites_profile/config/sync/field.field.block_content.image_banner.field_style_variation.yml new file mode 100644 index 0000000000..f95053e5cc --- /dev/null +++ b/web/profiles/custom/yalesites_profile/config/sync/field.field.block_content.image_banner.field_style_variation.yml @@ -0,0 +1,21 @@ +uuid: 746c6e8d-b767-4afe-bc09-8bf928f39ae4 +langcode: en +status: true +dependencies: + config: + - block_content.type.image_banner + - field.storage.block_content.field_style_variation + module: + - options +id: block_content.image_banner.field_style_variation +field_name: field_style_variation +entity_type: block_content +bundle: image_banner +label: 'Media Size' +description: '' +required: true +translatable: false +default_value: { } +default_value_callback: ys_themes_default_value_function +settings: { } +field_type: list_string From f04bb279ec761a8d7e1f06b920b832d26e435266 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Mon, 23 Sep 2024 14:11:09 -0400 Subject: [PATCH 12/60] feat(YSP-680): add component override for image-banner --- .../config/sync/ys_themes.component_overrides.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/web/profiles/custom/yalesites_profile/config/sync/ys_themes.component_overrides.yml b/web/profiles/custom/yalesites_profile/config/sync/ys_themes.component_overrides.yml index d9d548e0bd..1e3655c953 100644 --- a/web/profiles/custom/yalesites_profile/config/sync/ys_themes.component_overrides.yml +++ b/web/profiles/custom/yalesites_profile/config/sync/ys_themes.component_overrides.yml @@ -254,3 +254,9 @@ video: left: Left center: Center default: left +image_banner: + field_style_variation: + values: + large: Large + small: Small + default: large From d44d33bdd64de38081df2c1702e86611d335d20c Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Tue, 24 Sep 2024 11:03:06 -0400 Subject: [PATCH 13/60] fix(YSP-680): fix deprecation warning on first load It looks as if there is a deprecation warning on first load regarding the placement of $cachable and $entity on the ys_themes_allowed_values_function in ys_themes. I am attempting to switch the order of the variables to squelch this deprecation warning on first load for sites. The deprecation warning: Deprecated: Optional parameter $entity declared before required parameter $cacheable is implicitly treated as a required parameter in /code/web/profiles/custom/yalesites_profile/modules/custom/ys_themes/ys_themes.module on line 28 --- .../modules/custom/ys_themes/ys_themes.module | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_themes/ys_themes.module b/web/profiles/custom/yalesites_profile/modules/custom/ys_themes/ys_themes.module index 0d4db3f42e..77b7a6f85a 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_themes/ys_themes.module +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_themes/ys_themes.module @@ -15,17 +15,17 @@ use Drupal\field\Entity\FieldStorageConfig; * * @param \Drupal\field\Entity\FieldStorageConfig $definition * The field definition. - * @param \Drupal\Core\Entity\ContentEntityInterface|null $entity - * The entity being created, if applicable. * @param bool $cacheable * Boolean indicating if the results are cache-able. + * @param \Drupal\Core\Entity\ContentEntityInterface|null $entity + * The entity being created, if applicable. * * @return array * An array of possible key and value options. * * @see options_allowed_values() */ -function ys_themes_allowed_values_function(FieldStorageConfig $definition, ?ContentEntityInterface $entity = NULL, $cacheable) { +function ys_themes_allowed_values_function(FieldStorageConfig $definition, $cacheable, ?ContentEntityInterface $entity = NULL) { $options = []; $config = \Drupal::config('ys_themes.component_overrides'); From 0ebbcde4c5218a852646d907f2885afc09f3cc31 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Tue, 24 Sep 2024 11:48:28 -0400 Subject: [PATCH 14/60] Revert "fix(YSP-680): fix deprecation warning on first load" This reverts commit d44d33bdd64de38081df2c1702e86611d335d20c. --- .../modules/custom/ys_themes/ys_themes.module | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_themes/ys_themes.module b/web/profiles/custom/yalesites_profile/modules/custom/ys_themes/ys_themes.module index 77b7a6f85a..0d4db3f42e 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_themes/ys_themes.module +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_themes/ys_themes.module @@ -15,17 +15,17 @@ use Drupal\field\Entity\FieldStorageConfig; * * @param \Drupal\field\Entity\FieldStorageConfig $definition * The field definition. - * @param bool $cacheable - * Boolean indicating if the results are cache-able. * @param \Drupal\Core\Entity\ContentEntityInterface|null $entity * The entity being created, if applicable. + * @param bool $cacheable + * Boolean indicating if the results are cache-able. * * @return array * An array of possible key and value options. * * @see options_allowed_values() */ -function ys_themes_allowed_values_function(FieldStorageConfig $definition, $cacheable, ?ContentEntityInterface $entity = NULL) { +function ys_themes_allowed_values_function(FieldStorageConfig $definition, ?ContentEntityInterface $entity = NULL, $cacheable) { $options = []; $config = \Drupal::config('ys_themes.component_overrides'); From 310b35dedd99337ff4381d2fadef44a93fc2e0ba Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Tue, 24 Sep 2024 13:44:08 -0400 Subject: [PATCH 15/60] feat(YSP-680): change large/small to tall/short --- .../config/sync/ys_themes.component_overrides.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/config/sync/ys_themes.component_overrides.yml b/web/profiles/custom/yalesites_profile/config/sync/ys_themes.component_overrides.yml index 1e3655c953..aa97e20d67 100644 --- a/web/profiles/custom/yalesites_profile/config/sync/ys_themes.component_overrides.yml +++ b/web/profiles/custom/yalesites_profile/config/sync/ys_themes.component_overrides.yml @@ -257,6 +257,6 @@ video: image_banner: field_style_variation: values: - large: Large - small: Small - default: large + tall: Tall + short: Short + default: tall From 5ec97ec846f7c19c10d4db8e7c47f4659fcd3a8a Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Tue, 24 Sep 2024 13:57:25 -0400 Subject: [PATCH 16/60] feat(YSP-680): image banner media defaults to images --- ...entity_form_display.block_content.image_banner.default.yml | 4 +++- .../field.field.block_content.image_banner.field_media.yml | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/config/sync/core.entity_form_display.block_content.image_banner.default.yml b/web/profiles/custom/yalesites_profile/config/sync/core.entity_form_display.block_content.image_banner.default.yml index c842ca6fd8..d328a37a37 100644 --- a/web/profiles/custom/yalesites_profile/config/sync/core.entity_form_display.block_content.image_banner.default.yml +++ b/web/profiles/custom/yalesites_profile/config/sync/core.entity_form_display.block_content.image_banner.default.yml @@ -19,7 +19,9 @@ content: weight: 1 region: content settings: - media_types: { } + media_types: + - image + - background_video third_party_settings: media_library_edit: show_edit: '1' diff --git a/web/profiles/custom/yalesites_profile/config/sync/field.field.block_content.image_banner.field_media.yml b/web/profiles/custom/yalesites_profile/config/sync/field.field.block_content.image_banner.field_media.yml index ed5e599347..7431310e3a 100644 --- a/web/profiles/custom/yalesites_profile/config/sync/field.field.block_content.image_banner.field_media.yml +++ b/web/profiles/custom/yalesites_profile/config/sync/field.field.block_content.image_banner.field_media.yml @@ -27,5 +27,5 @@ settings: field: _none direction: ASC auto_create: true - auto_create_bundle: background_video + auto_create_bundle: image field_type: entity_reference From 9c1bf64ae218eab36efe4e27a2580507ae90ce91 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Tue, 24 Sep 2024 14:48:56 -0400 Subject: [PATCH 17/60] feat(YSP-680): use default image for banner --- ...e.entity_view_display.block_content.image_banner.default.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.block_content.image_banner.default.yml b/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.block_content.image_banner.default.yml index 7db3299c63..733e1b8063 100644 --- a/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.block_content.image_banner.default.yml +++ b/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.block_content.image_banner.default.yml @@ -17,7 +17,7 @@ content: type: entity_reference_entity_view label: hidden settings: - view_mode: banner_16_5 + view_mode: default link: false third_party_settings: { } weight: 0 From 5d7e8d067b05dd2345b9b38c9fe23e81e729986f Mon Sep 17 00:00:00 2001 From: Nathan Plowman Date: Wed, 25 Sep 2024 09:40:22 -0600 Subject: [PATCH 18/60] Fixed code sniffer errors. --- .../custom/ys_views_basic/src/Service/EventsCalendar.php | 2 +- .../ys_views_basic/src/Service/EventsCalendarInterface.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Service/EventsCalendar.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Service/EventsCalendar.php index 7566d4e903..9f54e55849 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Service/EventsCalendar.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Service/EventsCalendar.php @@ -241,7 +241,7 @@ public function createEventArray($node, string $time, int $timestamp): array { /** * {@inheritdoc} */ - public function isAllDay(int $start_ts, int $end_ts, string $timezone = NULL): bool { + public function isAllDay(int $start_ts, int $end_ts, ?string $timezone = NULL): bool { if ($timezone) { $default_tz = date_default_timezone_get(); date_default_timezone_set($timezone); diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Service/EventsCalendarInterface.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Service/EventsCalendarInterface.php index b97fd40b27..4c46404786 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Service/EventsCalendarInterface.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_views_basic/src/Service/EventsCalendarInterface.php @@ -84,7 +84,7 @@ public function createEventArray(NodeInterface $node, string $time, int $timesta * @return bool * TRUE if the event is all day, FALSE otherwise. */ - public function isAllDay(int $start_ts, int $end_ts, string $timezone = NULL): bool; + public function isAllDay(int $start_ts, int $end_ts, ?string $timezone = NULL): bool; /** * Get monthly events nodes. From e7314bd22b49d30743be341841afb9e5ac2314b7 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Mon, 30 Sep 2024 15:44:17 -0400 Subject: [PATCH 19/60] fix(YSP-690): fix parameter deprecation We had a $cachable which was not even in the signature of options_allowed_values, yet we were passing something in that then wasn't even being used. This lets it match the signature found at: https://api.drupal.org/api/drupal/core%21modules%21options%21options.module/function/options_allowed_values/10 --- .../modules/custom/ys_themes/ys_themes.module | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_themes/ys_themes.module b/web/profiles/custom/yalesites_profile/modules/custom/ys_themes/ys_themes.module index 0d4db3f42e..af8277d0fc 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_themes/ys_themes.module +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_themes/ys_themes.module @@ -17,15 +17,13 @@ use Drupal\field\Entity\FieldStorageConfig; * The field definition. * @param \Drupal\Core\Entity\ContentEntityInterface|null $entity * The entity being created, if applicable. - * @param bool $cacheable - * Boolean indicating if the results are cache-able. * * @return array * An array of possible key and value options. * * @see options_allowed_values() */ -function ys_themes_allowed_values_function(FieldStorageConfig $definition, ?ContentEntityInterface $entity = NULL, $cacheable) { +function ys_themes_allowed_values_function(FieldStorageConfig $definition, ?ContentEntityInterface $entity = NULL) { $options = []; $config = \Drupal::config('ys_themes.component_overrides'); From 5217ec0a73d877718596548741ad9909bcff9908 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Sat, 21 Sep 2024 06:50:41 -0400 Subject: [PATCH 20/60] feat(YSP-346): add pronouns field to profiles --- ...tity_form_display.node.profile.default.yml | 14 +++++++++++-- ....entity_view_display.node.profile.card.yml | 2 ++ ...ty_view_display.node.profile.condensed.yml | 8 +++++++ ...tity_view_display.node.profile.default.yml | 9 ++++++++ ...ty_view_display.node.profile.directory.yml | 9 ++++++++ ...ty_view_display.node.profile.list_item.yml | 2 ++ ...iew_display.node.profile.search_result.yml | 9 ++++++++ ...ntity_view_display.node.profile.single.yml | 8 +++++++ ...ntity_view_display.node.profile.teaser.yml | 8 +++++++ ...ield.field.node.profile.field_pronouns.yml | 19 +++++++++++++++++ .../field.storage.node.field_pronouns.yml | 21 +++++++++++++++++++ 11 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 web/profiles/custom/yalesites_profile/config/sync/field.field.node.profile.field_pronouns.yml create mode 100644 web/profiles/custom/yalesites_profile/config/sync/field.storage.node.field_pronouns.yml diff --git a/web/profiles/custom/yalesites_profile/config/sync/core.entity_form_display.node.profile.default.yml b/web/profiles/custom/yalesites_profile/config/sync/core.entity_form_display.node.profile.default.yml index f6e3a6e54c..c5aecefb5b 100644 --- a/web/profiles/custom/yalesites_profile/config/sync/core.entity_form_display.node.profile.default.yml +++ b/web/profiles/custom/yalesites_profile/config/sync/core.entity_form_display.node.profile.default.yml @@ -15,6 +15,7 @@ dependencies: - field.field.node.profile.field_media - field.field.node.profile.field_metatags - field.field.node.profile.field_position + - field.field.node.profile.field_pronouns - field.field.node.profile.field_subtitle - field.field.node.profile.field_tags - field.field.node.profile.field_teaser_media @@ -107,6 +108,7 @@ third_party_settings: - field_first_name - field_last_name - field_honorific_prefix + - field_pronouns - field_position - field_subtitle - field_department @@ -164,7 +166,7 @@ content: third_party_settings: { } field_department: type: string_textfield - weight: 33 + weight: 34 region: content settings: size: 60 @@ -235,6 +237,14 @@ content: use_details: true third_party_settings: { } field_position: + type: string_textfield + weight: 32 + region: content + settings: + size: 60 + placeholder: '' + third_party_settings: { } + field_pronouns: type: string_textfield weight: 31 region: content @@ -244,7 +254,7 @@ content: third_party_settings: { } field_subtitle: type: text_textfield - weight: 32 + weight: 33 region: content settings: size: 60 diff --git a/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.card.yml b/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.card.yml index 344f6fc635..7db4d41818 100644 --- a/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.card.yml +++ b/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.card.yml @@ -16,6 +16,7 @@ dependencies: - field.field.node.profile.field_media - field.field.node.profile.field_metatags - field.field.node.profile.field_position + - field.field.node.profile.field_pronouns - field.field.node.profile.field_subtitle - field.field.node.profile.field_tags - field.field.node.profile.field_teaser_media @@ -128,6 +129,7 @@ hidden: field_last_name: true field_login_required: true field_metatags: true + field_pronouns: true field_telephone: true layout_builder__layout: true links: true diff --git a/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.condensed.yml b/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.condensed.yml index 1ad780139e..258573abef 100644 --- a/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.condensed.yml +++ b/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.condensed.yml @@ -16,6 +16,7 @@ dependencies: - field.field.node.profile.field_media - field.field.node.profile.field_metatags - field.field.node.profile.field_position + - field.field.node.profile.field_pronouns - field.field.node.profile.field_subtitle - field.field.node.profile.field_tags - field.field.node.profile.field_teaser_media @@ -47,6 +48,11 @@ targetEntityType: node bundle: profile mode: condensed content: + content_moderation_control: + settings: { } + third_party_settings: { } + weight: -20 + region: content field_external_source: type: link_separate label: hidden @@ -78,6 +84,7 @@ hidden: field_login_required: true field_media: true field_metatags: true + field_pronouns: true field_subtitle: true field_tags: true field_teaser_media: true @@ -87,3 +94,4 @@ hidden: layout_builder__layout: true links: true search_api_excerpt: true + workflow_buttons: true diff --git a/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.default.yml b/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.default.yml index 77771730b1..8b0cdfa720 100644 --- a/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.default.yml +++ b/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.default.yml @@ -15,6 +15,7 @@ dependencies: - field.field.node.profile.field_media - field.field.node.profile.field_metatags - field.field.node.profile.field_position + - field.field.node.profile.field_pronouns - field.field.node.profile.field_subtitle - field.field.node.profile.field_tags - field.field.node.profile.field_teaser_media @@ -323,6 +324,14 @@ content: third_party_settings: { } weight: 107 region: content + field_pronouns: + type: string + label: above + settings: + link_to_entity: false + third_party_settings: { } + weight: 119 + region: content field_subtitle: type: text_default label: above diff --git a/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.directory.yml b/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.directory.yml index 7ea14769c7..8ea2fb6955 100644 --- a/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.directory.yml +++ b/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.directory.yml @@ -16,6 +16,7 @@ dependencies: - field.field.node.profile.field_media - field.field.node.profile.field_metatags - field.field.node.profile.field_position + - field.field.node.profile.field_pronouns - field.field.node.profile.field_subtitle - field.field.node.profile.field_tags - field.field.node.profile.field_teaser_media @@ -27,6 +28,7 @@ dependencies: module: - layout_builder - layout_builder_restrictions + - link - text - user third_party_settings: @@ -47,6 +49,11 @@ targetEntityType: node bundle: profile mode: directory content: + content_moderation_control: + settings: { } + third_party_settings: { } + weight: -20 + region: content field_affiliation: type: entity_reference_label label: hidden @@ -130,9 +137,11 @@ hidden: field_last_name: true field_login_required: true field_metatags: true + field_pronouns: true field_tags: true field_teaser_text: true field_teaser_title: true layout_builder__layout: true links: true search_api_excerpt: true + workflow_buttons: true diff --git a/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.list_item.yml b/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.list_item.yml index b797a59601..9ad2bca6fb 100644 --- a/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.list_item.yml +++ b/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.list_item.yml @@ -16,6 +16,7 @@ dependencies: - field.field.node.profile.field_media - field.field.node.profile.field_metatags - field.field.node.profile.field_position + - field.field.node.profile.field_pronouns - field.field.node.profile.field_subtitle - field.field.node.profile.field_tags - field.field.node.profile.field_teaser_media @@ -128,6 +129,7 @@ hidden: field_last_name: true field_login_required: true field_metatags: true + field_pronouns: true field_telephone: true layout_builder__layout: true links: true diff --git a/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.search_result.yml b/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.search_result.yml index 8ca5f5fdef..c4154d40db 100644 --- a/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.search_result.yml +++ b/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.search_result.yml @@ -16,6 +16,7 @@ dependencies: - field.field.node.profile.field_media - field.field.node.profile.field_metatags - field.field.node.profile.field_position + - field.field.node.profile.field_pronouns - field.field.node.profile.field_subtitle - field.field.node.profile.field_tags - field.field.node.profile.field_teaser_media @@ -26,6 +27,7 @@ dependencies: - node.type.profile module: - layout_builder + - link - text - user third_party_settings: @@ -37,6 +39,11 @@ targetEntityType: node bundle: profile mode: search_result content: + content_moderation_control: + settings: { } + third_party_settings: { } + weight: -20 + region: content field_external_source: type: link_separate label: hidden @@ -73,6 +80,7 @@ hidden: field_media: true field_metatags: true field_position: true + field_pronouns: true field_subtitle: true field_tags: true field_teaser_media: true @@ -80,3 +88,4 @@ hidden: field_telephone: true layout_builder__layout: true links: true + workflow_buttons: true diff --git a/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.single.yml b/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.single.yml index 518a1cb1fa..6c7a65ee20 100644 --- a/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.single.yml +++ b/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.single.yml @@ -16,6 +16,7 @@ dependencies: - field.field.node.profile.field_media - field.field.node.profile.field_metatags - field.field.node.profile.field_position + - field.field.node.profile.field_pronouns - field.field.node.profile.field_subtitle - field.field.node.profile.field_tags - field.field.node.profile.field_teaser_media @@ -163,6 +164,11 @@ targetEntityType: node bundle: profile mode: single content: + content_moderation_control: + settings: { } + third_party_settings: { } + weight: -20 + region: content field_address: type: text_default label: hidden @@ -288,7 +294,9 @@ content: hidden: field_login_required: true field_metatags: true + field_pronouns: true field_tags: true layout_builder__layout: true links: true search_api_excerpt: true + workflow_buttons: true diff --git a/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.teaser.yml b/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.teaser.yml index eabe3d2873..3a21a64a51 100644 --- a/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.teaser.yml +++ b/web/profiles/custom/yalesites_profile/config/sync/core.entity_view_display.node.profile.teaser.yml @@ -16,6 +16,7 @@ dependencies: - field.field.node.profile.field_media - field.field.node.profile.field_metatags - field.field.node.profile.field_position + - field.field.node.profile.field_pronouns - field.field.node.profile.field_subtitle - field.field.node.profile.field_tags - field.field.node.profile.field_teaser_media @@ -31,6 +32,11 @@ targetEntityType: node bundle: profile mode: teaser content: + content_moderation_control: + settings: { } + third_party_settings: { } + weight: -20 + region: content links: settings: { } third_party_settings: { } @@ -49,6 +55,7 @@ hidden: field_media: true field_metatags: true field_position: true + field_pronouns: true field_subtitle: true field_tags: true field_teaser_media: true @@ -57,3 +64,4 @@ hidden: field_telephone: true layout_builder__layout: true search_api_excerpt: true + workflow_buttons: true diff --git a/web/profiles/custom/yalesites_profile/config/sync/field.field.node.profile.field_pronouns.yml b/web/profiles/custom/yalesites_profile/config/sync/field.field.node.profile.field_pronouns.yml new file mode 100644 index 0000000000..751f6fef47 --- /dev/null +++ b/web/profiles/custom/yalesites_profile/config/sync/field.field.node.profile.field_pronouns.yml @@ -0,0 +1,19 @@ +uuid: 47bd0833-5f70-4c13-a2d9-25b0f01dcfff +langcode: en +status: true +dependencies: + config: + - field.storage.node.field_pronouns + - node.type.profile +id: node.profile.field_pronouns +field_name: field_pronouns +entity_type: node +bundle: profile +label: Pronouns +description: '' +required: false +translatable: false +default_value: { } +default_value_callback: '' +settings: { } +field_type: string diff --git a/web/profiles/custom/yalesites_profile/config/sync/field.storage.node.field_pronouns.yml b/web/profiles/custom/yalesites_profile/config/sync/field.storage.node.field_pronouns.yml new file mode 100644 index 0000000000..dd884e313a --- /dev/null +++ b/web/profiles/custom/yalesites_profile/config/sync/field.storage.node.field_pronouns.yml @@ -0,0 +1,21 @@ +uuid: 78b31208-ff3a-404a-ba52-8fba4c418766 +langcode: en +status: true +dependencies: + module: + - node +id: node.field_pronouns +field_name: field_pronouns +entity_type: node +type: string +settings: + max_length: 255 + case_sensitive: false + is_ascii: false +module: core +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false From f8b8047c5c08ef5fe0a3c7619dcd49aa9a7210ed Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Sat, 21 Sep 2024 06:51:05 -0400 Subject: [PATCH 21/60] feat(YSP-346): pronouns included in meta block data --- .../custom/ys_layouts/src/Plugin/Block/ProfileMetaBlock.php | 4 ++++ .../modules/custom/ys_layouts/ys_layouts.module | 1 + 2 files changed, 5 insertions(+) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_layouts/src/Plugin/Block/ProfileMetaBlock.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_layouts/src/Plugin/Block/ProfileMetaBlock.php index 31e97bde96..e8cc91ff9c 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_layouts/src/Plugin/Block/ProfileMetaBlock.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_layouts/src/Plugin/Block/ProfileMetaBlock.php @@ -101,6 +101,7 @@ public function build() { $position = NULL; $subtitle = NULL; $department = NULL; + $pronouns = NULL; $mediaId = NULL; $request = $this->requestStack->getCurrentRequest(); @@ -125,6 +126,7 @@ public function build() { $position = $node->get('field_position')->getValue()[0]['value'] ?? NULL; $subtitle = $node->get('field_subtitle')->getValue()[0]['value'] ?? NULL; $department = $node->get('field_department')->getValue()[0]['value'] ?? NULL; + $pronouns = $node->get('field_pronouns')->getValue()[0]['value'] ?? NULL; $mediaId = $node->get('field_media')->getValue()[0]['target_id'] ?? NULL; } @@ -134,10 +136,12 @@ public function build() { '#profile_meta__title_line' => $position, '#profile_meta__subtitle_line' => $subtitle, '#profile_meta__department' => $department, + '#profile_meta__pronouns' => $pronouns, '#media_id' => $mediaId, '#profile_meta__image_orientation' => $this->configuration['image_orientation'] ?? 'portrait', '#profile_meta__image_style' => $this->configuration['image_style'] ?? 'inline', '#profile_meta__image_alignment' => $this->configuration['image_alignment'] ?? 'left', + ]; } diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_layouts/ys_layouts.module b/web/profiles/custom/yalesites_profile/modules/custom/ys_layouts/ys_layouts.module index ade2e3546d..b029a58559 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_layouts/ys_layouts.module +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_layouts/ys_layouts.module @@ -57,6 +57,7 @@ function ys_layouts_theme($existing, $type, $theme, $path): array { 'profile_meta__title_line' => NULL, 'profile_meta__subtitle_line' => NULL, 'profile_meta__department' => NULL, + 'profile_meta__pronouns' => NULL, 'media_id' => NULL, 'profile_meta__image_orientation' => NULL, 'profile_meta__image_style' => NULL, From 7e45ec452742e73f081ac587dce30dd2db2f6386 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Wed, 14 Aug 2024 16:25:51 -0400 Subject: [PATCH 22/60] feat(YSP-593): add a working block creation --- .../modules/custom/ys_servicenow/README.md | 0 ...ervicenow_knowledge_base_article_block.yml | 50 +++++ .../servicenow_knowledge_base_articles.yml | 52 +++++ ...rvicenow_knowledge_base_layout_builder.yml | 43 ++++ .../src/Controller/RunMigrations.php | 83 ++++++++ .../src/Form/ServiceNowSettings.php | 163 +++++++++++++++ .../ys_servicenow/src/MetaFieldsManager.php | 0 .../migrate/process/LayoutBuilderSections.php | 89 ++++++++ .../ys_servicenow/src/ServiceNowManager.php | 195 ++++++++++++++++++ .../ys_servicenow/ys_servicenow.info.yml | 9 + .../ys_servicenow.links.menu.yml | 6 + .../custom/ys_servicenow/ys_servicenow.module | 7 + .../ys_servicenow.permissions.yml | 4 + .../ys_servicenow/ys_servicenow.routing.yml | 14 ++ .../ys_servicenow/ys_servicenow.services.yml | 5 + 15 files changed, 720 insertions(+) create mode 100644 web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/README.md create mode 100644 web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_article_block.yml create mode 100644 web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml create mode 100644 web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_layout_builder.yml create mode 100644 web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Controller/RunMigrations.php create mode 100644 web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Form/ServiceNowSettings.php create mode 100644 web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/MetaFieldsManager.php create mode 100644 web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate/process/LayoutBuilderSections.php create mode 100644 web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php create mode 100644 web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.info.yml create mode 100644 web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.links.menu.yml create mode 100644 web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.module create mode 100644 web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.permissions.yml create mode 100644 web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.routing.yml create mode 100644 web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.services.yml diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/README.md b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/README.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_article_block.yml b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_article_block.yml new file mode 100644 index 0000000000..b34b4c6fb9 --- /dev/null +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_article_block.yml @@ -0,0 +1,50 @@ +id: servicenow_knowledge_base_article_block +label: 'ServiceNow knowledge base article blocks' +source: + plugin: url + data_fetcher_plugin: http + data_parser_plugin: json + headers: + Accept: 'application/json; charset=utf-8' + Content-Type: application/json + authentication: + plugin: basic + username: USERNAME + password: PASSWORD + track_changes: true + urls: https://yaledevelopment.service-now.com/api/now/table/kb_knowledge?sysparm_query=workflow_state%3Dpublished%5Ekb_category.label!%3DNews%5Ecan_read_user_criteriaLIKEfd81a4dadbb6030043565bc0cf961905%5Eu_kb_ai_ready%3Dtrue&sysparm_display_value=true&sysparm_fields=sys_name%2Ctext%2Ctopic%2Cu_service_offering%2Cnumber%2Csys_created_on%2Ccan_read_user_criteria%2Cpublished%2Ckb_knowledge_base%2Cdescription%2Cvalid_to%2Csys_view_count%2Cshort_description%2Ckb_category&sysparm_limit=10 + item_selector: result + fields: + - name: servicenow_number + label: 'ServiceNow number' + selector: number + - name: servicenow_title + label: 'ServiceNow title' + selector: short_description + - name: servicenow_text + label: 'ServiceNow text' + selector: text + ids: + servicenow_number: + type: string +process: + field_text/value: servicenow_text + field_text/format: + plugin: default_value + default_value: basic_html + info: servicenow_title + reusable: + plugin: default_value + default_value: 0 +destination: + plugin: 'entity:block_content' + default_bundle: text + overwrite_properties: + - field_text + - info +dependencies: + enforced: + module: + - migrate_plus + - migrate_tools + - layout_builder diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml new file mode 100644 index 0000000000..acd34a1a65 --- /dev/null +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml @@ -0,0 +1,52 @@ +id: servicenow_knowledge_base_articles +label: 'ServiceNow knowledge base articles' +source: + plugin: url + data_fetcher_plugin: http + data_parser_plugin: json + headers: + Accept: 'application/json; charset=utf-8' + Content-Type: application/json + authentication: + plugin: basic + username: USERNAME + password: PASSWORD + track_changes: true + urls: https://yaledevelopment.service-now.com/api/now/table/kb_knowledge?sysparm_query=workflow_state%3Dpublished%5Ekb_category.label!%3DNews%5Ecan_read_user_criteriaLIKEfd81a4dadbb6030043565bc0cf961905%5Eu_kb_ai_ready%3Dtrue&sysparm_display_value=true&sysparm_fields=sys_name%2Ctext%2Ctopic%2Cu_service_offering%2Cnumber%2Csys_created_on%2Ccan_read_user_criteria%2Cpublished%2Ckb_knowledge_base%2Cdescription%2Cvalid_to%2Csys_view_count%2Cshort_description%2Ckb_category&sysparm_limit=10 + item_selector: result + fields: + - name: servicenow_number + label: 'ServiceNow number' + selector: number + - name: servicenow_title + label: 'ServiceNow title' + selector: short_description + - name: servicenow_text + label: 'ServiceNow text' + selector: text + ids: + servicenow_number: + type: string +process: + title: servicenow_title + block_id: + plugin: migration_lookup + migration: servicenow_knowledge_base_article_block + source: servicenow_number + layout_builder__layout: + source: servicenow_title + plugin: layout_builder_sections +destination: + plugin: 'entity:node' + default_bundle: page + overwrite_properties: + - title +migration_dependencies: + required: + - servicenow_knowledge_base_article_block +dependencies: + enforced: + module: + - migrate_plus + - migrate_tools + - layout_builder diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_layout_builder.yml b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_layout_builder.yml new file mode 100644 index 0000000000..d93214e601 --- /dev/null +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_layout_builder.yml @@ -0,0 +1,43 @@ +id: servicenow_knowledge_base_layout_builder +label: 'ServiceNow knowledge base articles' +source: + plugin: url + data_fetcher_plugin: http + data_parser_plugin: json + headers: + Accept: 'application/json; charset=utf-8' + Content-Type: application/json + authentication: + plugin: basic + username: USERNAME + password: PASSWORD + track_changes: true + urls: https://yaledevelopment.service-now.com/api/now/table/kb_knowledge?sysparm_query=workflow_state%3Dpublished%5Ekb_category.label!%3DNews%5Ecan_read_user_criteriaLIKEfd81a4dadbb6030043565bc0cf961905%5Eu_kb_ai_ready%3Dtrue&sysparm_display_value=true&sysparm_fields=sys_name%2Ctext%2Ctopic%2Cu_service_offering%2Cnumber%2Csys_created_on%2Ccan_read_user_criteria%2Cpublished%2Ckb_knowledge_base%2Cdescription%2Cvalid_to%2Csys_view_count%2Cshort_description%2Ckb_category&sysparm_limit=10 + item_selector: result + fields: + - name: servicenow_number + label: 'ServiceNow number' + selector: number + ids: + servicenow_number: + type: string +process: + id: servicenow_number + field_text: servicenow_content + block: + plugin: migration_lookup + migration: servicenow_knowledge_base_article_block + source: servicenow_number + node: + plugin: migration_lookup + migration: servicenow_knowledge_base_articles + source: servicenow_number +destination: + plugin: append_block_to_node + source: servicenow_number +dependencies: + enforced: + module: + - migrate_plus + - migrate_tools + - layout_builder diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Controller/RunMigrations.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Controller/RunMigrations.php new file mode 100644 index 0000000000..33bf45b569 --- /dev/null +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Controller/RunMigrations.php @@ -0,0 +1,83 @@ +servicenowConfig = $config_factory->get('ys_servicenow.settings'); + $this->servicenowManager = $servicenow_manager; + $this->messenger = $messenger; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('config.factory'), + $container->get('ys_servicenow.manager'), + $container->get('messenger'), + ); + + } + + /** + * Runs all ServiceNow migrations. + */ + public function runAllMigrations() { + if ($this->servicenowConfig->get('enable_servicenow_sync')) { + $this->messenger->addMessage('Running ServiceNow migrations...'); + $this->servicenowManager->runAllMigrations(); + $this->messenger->addMessage('ServiceNow migrations complete.'); + } + else { + $this->messenger->addMessage('ServiceNow sync is disabled. No sync was performed.'); + } + + $redirectUrl = Url::fromRoute('ys_servicenow.settings')->toString(); + $response = new RedirectResponse($redirectUrl); + return $response; + } + +} diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Form/ServiceNowSettings.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Form/ServiceNowSettings.php new file mode 100644 index 0000000000..c286acda11 --- /dev/null +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Form/ServiceNowSettings.php @@ -0,0 +1,163 @@ +entityTypeManager = $entity_type_manager; + $this->servicenowManager = $servicenow_manager; + $this->currentUserSession = $current_user_session; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('config.factory'), + $container->get('entity_type.manager'), + $container->get('ys_servicenow.manager'), + $container->get('current_user'), + ); + } + + /** + * {@inheritdoc} + */ + public function getFormId() { + return 'ys_servicenow_settings'; + } + + /** + * {@inheritdoc} + */ + protected function getEditableConfigNames() { + return ['ys_servicenow.settings']; + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, FormStateInterface $form_state) { + $config = $this->config('ys_servicenow.settings'); + + $allowSecretItems = function_exists('ys_core_allow_secret_items') ? ys_core_allow_secret_items($this->currentUserSession) : FALSE; + + if ( + $config->get('enable_servicenow_sync') && + $config->get('servicenow_endpoint') + ) { + $form['sync_now_button'] = [ + '#type' => 'markup', + '#markup' => 'Sync now', + ]; + } + + $form['enable_servicenow_sync'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Enable ServiceNow sync'), + '#description' => $this->t('Once enabled, ServiceNow data will sync knowledge base articles roughly every hour.'), + '#default_value' => $config->get('enable_servicenow_sync') ?: FALSE, + '#disabled' => !$allowSecretItems, + ]; + + $form['servicenow_endpoint'] = [ + '#type' => 'url', + '#title' => $this->t('ServiceNow endpoint base URL'), + '#description' => $this->t('Ex: https://apiendpoint'), + '#default_value' => $config->get('servicenow_endpoint') ?: '', + '#disabled' => !$allowSecretItems, + ]; + + return parent::buildForm($form, $form_state); + } + + /** + * {@inheritdoc} + */ + public function validateForm(array &$form, FormStateInterface $form_state) { + $enabled = $form_state->getValue('enable_servicenow_sync'); + if ($enabled) { + $requiredFields = [ + 'servicenow_endpoint', + ]; + + foreach ($requiredFields as $field) { + if (!$form_state->getValue($field)) { + $form_state->setErrorByName( + $field, + $this->t("%required_field is required.", ['%required_field' => $form_state->getCompleteForm()[$field]['#title']->__toString()]) + ); + } + } + + } + + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + + $this->configFactory->getEditable('ys_servicenow.settings') + // Set the submitted configuration setting. + ->set('enable_servicenow_sync', $form_state->getValue('enable_servicenow_sync')) + ->set('servicenow_endpoint', rtrim($form_state->getValue('servicenow_endpoint'), "/")) + ->save(); + + parent::submitForm($form, $form_state); + } + +} diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/MetaFieldsManager.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/MetaFieldsManager.php new file mode 100644 index 0000000000..e69de29bb2 diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate/process/LayoutBuilderSections.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate/process/LayoutBuilderSections.php new file mode 100644 index 0000000000..f82a519a11 --- /dev/null +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate/process/LayoutBuilderSections.php @@ -0,0 +1,89 @@ +addMessage("Value: " . $value, 'status', TRUE); + + if ($value == NULL) { + \Drupal::messenger()->addError("value is NULL", 'status', TRUE); + return NULL; + } + + // Setup some variables we'll need: + // - components holds all the components to be written into our section + // - generator connects to the uuid generator service. + $components = []; + $generator = \Drupal::service('uuid'); + $entityTypeManager = \Drupal::entityTypeManager(); + $entityQuery = $entityTypeManager->getStorage('block_content')->getQuery(); + $entityQuery->condition('info', $value) + ->accessCheck(FALSE); + $ids = $entityQuery->execute(); + + $block_content = NULL; + if (!empty($ids)) { + $block_content = $entityTypeManager->getStorage('block_content')->load(reset($ids)); + } + + if (is_null($block_content)) { + \Drupal::messenger()->addError("Could not load " . $value . ' ???', 'status', TRUE); + return NULL; + } + + \Drupal::messenger()->addMessage("Got a block content"); + + $config = [ + 'id' => 'inline_block:text', + 'label' => $block_content->label(), + 'provider' => 'layout_builder', + 'label_display' => FALSE, + 'view_mode' => 'full', + 'block_revision_id' => $block_content->getRevisionId(), + 'block_serialized' => serialize($block_content), + 'context_mapping' => [], + ]; + + $components[] = new SectionComponent($generator->generate(), 'content', $config); + + \Drupal::messenger()->addMessage("Made a section component"); + + // If you were doing multiple sections, you'd want this to be an array + // somehow. @TODO figure out how to do that ;) + // PARAMS: $layout_id, $layout_settings, $components. + $sections = new Section('layout_onecol', [], $components); + + \Drupal::messenger()->addMessage("Made a section"); + + return $sections; + } + + /** + * {@inheritdoc} + */ + public function multiple() { + // Perhaps if multiple() returned TRUE this would help allow + // multiple Sections. ;) + return FALSE; + } + +} diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php new file mode 100644 index 0000000000..dba002520c --- /dev/null +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php @@ -0,0 +1,195 @@ +servicenowConfig = $config_factory->get('ys_servicenow.settings'); + $this->httpClient = $http_client; + $this->entityTypeManager = $entity_type_manager; + $this->migrationManager = $migration_manager; + $this->moduleHandler = $module_handler; + $this->time = $time; + $this->messenger = $messenger; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('config.factory'), + $container->get('http_client'), + $container->get('entity_type.manager'), + $container->get('plugin.manager.migration'), + $container->get('module_handler'), + $container->get('date.formatter'), + $container->get('messenger'), + ); + + } + + /** + * Runs specific migration. + * + * @param string $migration + * The migration ID. + */ + public function runMigration($migration) { + // Loop over the list of the migrations and check if they require + // execution. + // Prevent non-existent migrations from breaking cron. + $migrationInstance = $this->migrationManager->createInstance($migration); + if ($migrationInstance) { + // Check if the migration status is IDLE, if not, make it so. + $status = $migrationInstance->getStatus(); + if ($status !== MigrationInterface::STATUS_IDLE) { + $migrationInstance->setStatus(MigrationInterface::STATUS_IDLE); + } + + /* + * @todo Possibly implement the following flags, if needed. + * Runs migration with the --update flag. + * $migration_update = $migration->getIdMap(); + * $migration_update->prepareUpdate(); + * Runs migration with the --sync flag. + * The problem here is if editor adds layout builder, this will wipe those + * changes out before recreating. So, this not be a good idea. + * $migrationInstance->set('syncSource', TRUE); + */ + + $message = new MigrateMessage(); + $executable = new MigrateExecutable($migrationInstance, $message); + $executable->import(); + + /* If using migrate_plus module, update the migrate_last_imported value + * for the migration. + */ + + if ($this->moduleHandler->moduleExists('migrate_plus')) { + $migrate_last_imported_store = $this->keyValue('migrate_last_imported'); + $migrate_last_imported_store->set($migrationInstance->id(), round($this->time->getCurrentMicroTime() * 1000)); + } + } + } + + /** + * Gets the migration status such as number of items imported. + * + * @return int + * For now, just the number of items imported. + */ + public function getMigrationStatus($migration_id) { + $migration = $this->migrationManager->createInstance($migration_id); + $map = $migration->getIdMap(); + $imported = $map->importedCount(); + return $imported; + } + + /** + * Runs all Localist migrations. + * + * @return array + * Array of status of all migrations run. + */ + public function runAllMigrations() { + foreach (self::SERVICENOW_MIGRATIONS as $migration) { + $this->runMigration($migration); + $messageData[$migration] = [ + 'imported' => $this->getMigrationStatus($migration), + ]; + } + return $messageData; + } + +} diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.info.yml b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.info.yml new file mode 100644 index 0000000000..7806a85b9b --- /dev/null +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.info.yml @@ -0,0 +1,9 @@ +name: 'YS ServiceNow' +type: module +description: 'Provides integration with the ServiceNow knowledge base platform' +package: YaleSites +core_version_requirement: ^10 +dependencies: + - drupal:migrate + - migrate_plus:migrate_plus + - migrate_tools:migrate_tools diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.links.menu.yml b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.links.menu.yml new file mode 100644 index 0000000000..29996dbfff --- /dev/null +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.links.menu.yml @@ -0,0 +1,6 @@ +ys_servicenow.settings: + title: 'ServiceNow settings' + description: 'Configure ServiceNow sync settings' + route_name: ys_servicenow.settings + parent: ys_core.admin_yalesites + weight: 0 diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.module b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.module new file mode 100644 index 0000000000..f4587d9d82 --- /dev/null +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.module @@ -0,0 +1,7 @@ + Date: Thu, 15 Aug 2024 12:29:23 -0400 Subject: [PATCH 23/60] feat(YSP-593): create keys-based basic auth plugin --- .../migrate_plus/authentication/BasicKeys.php | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate_plus/authentication/BasicKeys.php diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate_plus/authentication/BasicKeys.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate_plus/authentication/BasicKeys.php new file mode 100644 index 0000000000..4072741fa5 --- /dev/null +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate_plus/authentication/BasicKeys.php @@ -0,0 +1,79 @@ +getKey('ServiceNow'); + + $key_object = $this->getKeyValues($key); + + $username = $key_object->username; + $password = $key_object->password; + + // Get the key from keys module called "ServiceNow". + return [ + 'auth' => [ + $username, + $password, + ], + ]; + } + + /** + * Given a key ID, return the key object. + * + * @param string $key_id + * The key ID. + * + * @return \Drupal\key\KeyInterface + * The key object + */ + protected function getKey($key_id) { + $key = \Drupal::service('key.repository')->getKey($key_id); + + if (!$key) { + throw new \Exception("Key '$key_id' not found"); + } + + return $key; + } + + /** + * Given a key, return the key values. + * + * @param \Drupal\key\KeyInterface $key + * The key object. + * + * @return object + * The key values. + */ + protected function getKeyValues($key) { + $json_key = $key->getKeyValue(); + + if (!$json_key) { + throw new \Exception("Key 'ServiceNow' has no value"); + } + + return json_decode($json_key); + } + +} From 7b266bba5d49410218f3aa3424dce2967bd846b5 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Thu, 15 Aug 2024 13:34:41 -0400 Subject: [PATCH 24/60] feat(YSP-593): successfully use keys to provide auth --- ...ervicenow_knowledge_base_article_block.yml | 4 +--- .../servicenow_knowledge_base_articles.yml | 4 +--- ...rvicenow_knowledge_base_layout_builder.yml | 4 +--- .../migrate_plus/authentication/BasicKeys.php | 21 +++++++------------ 4 files changed, 11 insertions(+), 22 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_article_block.yml b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_article_block.yml index b34b4c6fb9..de136f3483 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_article_block.yml +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_article_block.yml @@ -8,9 +8,7 @@ source: Accept: 'application/json; charset=utf-8' Content-Type: application/json authentication: - plugin: basic - username: USERNAME - password: PASSWORD + plugin: basic_keys track_changes: true urls: https://yaledevelopment.service-now.com/api/now/table/kb_knowledge?sysparm_query=workflow_state%3Dpublished%5Ekb_category.label!%3DNews%5Ecan_read_user_criteriaLIKEfd81a4dadbb6030043565bc0cf961905%5Eu_kb_ai_ready%3Dtrue&sysparm_display_value=true&sysparm_fields=sys_name%2Ctext%2Ctopic%2Cu_service_offering%2Cnumber%2Csys_created_on%2Ccan_read_user_criteria%2Cpublished%2Ckb_knowledge_base%2Cdescription%2Cvalid_to%2Csys_view_count%2Cshort_description%2Ckb_category&sysparm_limit=10 item_selector: result diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml index acd34a1a65..4eb1b0a885 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml @@ -8,9 +8,7 @@ source: Accept: 'application/json; charset=utf-8' Content-Type: application/json authentication: - plugin: basic - username: USERNAME - password: PASSWORD + plugin: basic_keys track_changes: true urls: https://yaledevelopment.service-now.com/api/now/table/kb_knowledge?sysparm_query=workflow_state%3Dpublished%5Ekb_category.label!%3DNews%5Ecan_read_user_criteriaLIKEfd81a4dadbb6030043565bc0cf961905%5Eu_kb_ai_ready%3Dtrue&sysparm_display_value=true&sysparm_fields=sys_name%2Ctext%2Ctopic%2Cu_service_offering%2Cnumber%2Csys_created_on%2Ccan_read_user_criteria%2Cpublished%2Ckb_knowledge_base%2Cdescription%2Cvalid_to%2Csys_view_count%2Cshort_description%2Ckb_category&sysparm_limit=10 item_selector: result diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_layout_builder.yml b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_layout_builder.yml index d93214e601..4da52b9c96 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_layout_builder.yml +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_layout_builder.yml @@ -8,9 +8,7 @@ source: Accept: 'application/json; charset=utf-8' Content-Type: application/json authentication: - plugin: basic - username: USERNAME - password: PASSWORD + plugin: basic_keys track_changes: true urls: https://yaledevelopment.service-now.com/api/now/table/kb_knowledge?sysparm_query=workflow_state%3Dpublished%5Ekb_category.label!%3DNews%5Ecan_read_user_criteriaLIKEfd81a4dadbb6030043565bc0cf961905%5Eu_kb_ai_ready%3Dtrue&sysparm_display_value=true&sysparm_fields=sys_name%2Ctext%2Ctopic%2Cu_service_offering%2Cnumber%2Csys_created_on%2Ccan_read_user_criteria%2Cpublished%2Ckb_knowledge_base%2Cdescription%2Cvalid_to%2Csys_view_count%2Cshort_description%2Ckb_category&sysparm_limit=10 item_selector: result diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate_plus/authentication/BasicKeys.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate_plus/authentication/BasicKeys.php index 4072741fa5..93c68f3a3d 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate_plus/authentication/BasicKeys.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate_plus/authentication/BasicKeys.php @@ -1,39 +1,34 @@ getKey('ServiceNow'); + $key = $this->getKey('servicenow'); $key_object = $this->getKeyValues($key); - $username = $key_object->username; - $password = $key_object->password; - - // Get the key from keys module called "ServiceNow". return [ 'auth' => [ - $username, - $password, + $key_object->username, + $key_object->password, ], ]; } From 9eda713648af7540ecd8105cdf192747173407f8 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Thu, 15 Aug 2024 13:43:24 -0400 Subject: [PATCH 25/60] feat(YSP-593): make key selectable --- .../ys_servicenow/src/Form/ServiceNowSettings.php | 7 +++++++ .../Plugin/migrate_plus/authentication/BasicKeys.php | 11 +++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Form/ServiceNowSettings.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Form/ServiceNowSettings.php index c286acda11..e9a98bdc08 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Form/ServiceNowSettings.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Form/ServiceNowSettings.php @@ -120,6 +120,12 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#disabled' => !$allowSecretItems, ]; + $form['servicenow_auth_key'] = [ + '#type' => 'key_select', + '#title' => $this->t('ServiceNow Authentication Credentials'), + '#default_value' => $config->get('servicenow_auth_key') ?: '', + ]; + return parent::buildForm($form, $form_state); } @@ -155,6 +161,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { // Set the submitted configuration setting. ->set('enable_servicenow_sync', $form_state->getValue('enable_servicenow_sync')) ->set('servicenow_endpoint', rtrim($form_state->getValue('servicenow_endpoint'), "/")) + ->set('servicenow_auth_key', $form_state->getValue('servicenow_auth_key')) ->save(); parent::submitForm($form, $form_state); diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate_plus/authentication/BasicKeys.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate_plus/authentication/BasicKeys.php index 93c68f3a3d..cd151facb2 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate_plus/authentication/BasicKeys.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate_plus/authentication/BasicKeys.php @@ -8,7 +8,7 @@ use Drupal\migrate_plus\AuthenticationPluginBase; /** - * Provides basic authentication for the HTTP resource. + * Provides basic authentication using keys module for the HTTP resource. * * @Authentication( * id = "basic_keys", @@ -21,7 +21,14 @@ class BasicKeys extends AuthenticationPluginBase implements ContainerFactoryPlug * {@inheritdoc} */ public function getAuthenticationOptions(): array { - $key = $this->getKey('servicenow'); + $servicenow_config = \Drupal::config('ys_servicenow.settings'); + $servicenow_key_id = $servicenow_config->get('servicenow_auth_key'); + + if (!$servicenow_key_id) { + throw new \Exception("ServiceNow key not set"); + } + + $key = $this->getKey($servicenow_key_id); $key_object = $this->getKeyValues($key); From be6e315e8a57d88e9b2796cc0cb7271f7ad4a74a Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Thu, 15 Aug 2024 13:44:51 -0400 Subject: [PATCH 26/60] feat(YSP-593): rely on key module --- .../modules/custom/ys_servicenow/ys_servicenow.info.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.info.yml b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.info.yml index 7806a85b9b..7a3d69928d 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.info.yml +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.info.yml @@ -7,3 +7,4 @@ dependencies: - drupal:migrate - migrate_plus:migrate_plus - migrate_tools:migrate_tools + - drupal:key From be8b29de306aa087cbfb41098e4a6b0095a0c389 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Thu, 15 Aug 2024 14:19:50 -0400 Subject: [PATCH 27/60] feat(YSP-593): create abstraction for reusable key auth In case we need to use this in the future, we now have a way to do this without specifying servicenow specifically. --- ...ervicenow_knowledge_base_article_block.yml | 2 +- .../servicenow_knowledge_base_articles.yml | 2 +- ...rvicenow_knowledge_base_layout_builder.yml | 2 +- .../BasicKeys.php => BasicAuthWithKeys.php} | 51 +++++++++++++------ .../authentication/ServiceNowAuth.php | 31 +++++++++++ 5 files changed, 70 insertions(+), 18 deletions(-) rename web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/{Plugin/migrate_plus/authentication/BasicKeys.php => BasicAuthWithKeys.php} (55%) create mode 100644 web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate_plus/authentication/ServiceNowAuth.php diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_article_block.yml b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_article_block.yml index de136f3483..80814ebee0 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_article_block.yml +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_article_block.yml @@ -8,7 +8,7 @@ source: Accept: 'application/json; charset=utf-8' Content-Type: application/json authentication: - plugin: basic_keys + plugin: servicenow_auth track_changes: true urls: https://yaledevelopment.service-now.com/api/now/table/kb_knowledge?sysparm_query=workflow_state%3Dpublished%5Ekb_category.label!%3DNews%5Ecan_read_user_criteriaLIKEfd81a4dadbb6030043565bc0cf961905%5Eu_kb_ai_ready%3Dtrue&sysparm_display_value=true&sysparm_fields=sys_name%2Ctext%2Ctopic%2Cu_service_offering%2Cnumber%2Csys_created_on%2Ccan_read_user_criteria%2Cpublished%2Ckb_knowledge_base%2Cdescription%2Cvalid_to%2Csys_view_count%2Cshort_description%2Ckb_category&sysparm_limit=10 item_selector: result diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml index 4eb1b0a885..addf1a2bf4 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml @@ -8,7 +8,7 @@ source: Accept: 'application/json; charset=utf-8' Content-Type: application/json authentication: - plugin: basic_keys + plugin: servicenow_auth track_changes: true urls: https://yaledevelopment.service-now.com/api/now/table/kb_knowledge?sysparm_query=workflow_state%3Dpublished%5Ekb_category.label!%3DNews%5Ecan_read_user_criteriaLIKEfd81a4dadbb6030043565bc0cf961905%5Eu_kb_ai_ready%3Dtrue&sysparm_display_value=true&sysparm_fields=sys_name%2Ctext%2Ctopic%2Cu_service_offering%2Cnumber%2Csys_created_on%2Ccan_read_user_criteria%2Cpublished%2Ckb_knowledge_base%2Cdescription%2Cvalid_to%2Csys_view_count%2Cshort_description%2Ckb_category&sysparm_limit=10 item_selector: result diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_layout_builder.yml b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_layout_builder.yml index 4da52b9c96..0158119268 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_layout_builder.yml +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_layout_builder.yml @@ -8,7 +8,7 @@ source: Accept: 'application/json; charset=utf-8' Content-Type: application/json authentication: - plugin: basic_keys + plugin: servicenow_auth track_changes: true urls: https://yaledevelopment.service-now.com/api/now/table/kb_knowledge?sysparm_query=workflow_state%3Dpublished%5Ekb_category.label!%3DNews%5Ecan_read_user_criteriaLIKEfd81a4dadbb6030043565bc0cf961905%5Eu_kb_ai_ready%3Dtrue&sysparm_display_value=true&sysparm_fields=sys_name%2Ctext%2Ctopic%2Cu_service_offering%2Cnumber%2Csys_created_on%2Ccan_read_user_criteria%2Cpublished%2Ckb_knowledge_base%2Cdescription%2Cvalid_to%2Csys_view_count%2Cshort_description%2Ckb_category&sysparm_limit=10 item_selector: result diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate_plus/authentication/BasicKeys.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/BasicAuthWithKeys.php similarity index 55% rename from web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate_plus/authentication/BasicKeys.php rename to web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/BasicAuthWithKeys.php index cd151facb2..cc8f66410b 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate_plus/authentication/BasicKeys.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/BasicAuthWithKeys.php @@ -2,10 +2,7 @@ declare(strict_types=1); -namespace Drupal\ys_servicenow\Plugin\migrate_plus\authentication; - -use Drupal\Core\Plugin\ContainerFactoryPluginInterface; -use Drupal\migrate_plus\AuthenticationPluginBase; +namespace Drupal\ys_servicenow; /** * Provides basic authentication using keys module for the HTTP resource. @@ -15,23 +12,47 @@ * title = @Translation("Basic Keys") * ) */ -class BasicKeys extends AuthenticationPluginBase implements ContainerFactoryPluginInterface { +class BasicAuthWithKeys { /** - * {@inheritdoc} + * The key ID. + * + * @var string */ - public function getAuthenticationOptions(): array { - $servicenow_config = \Drupal::config('ys_servicenow.settings'); - $servicenow_key_id = $servicenow_config->get('servicenow_auth_key'); + protected $keyId; - if (!$servicenow_key_id) { - throw new \Exception("ServiceNow key not set"); - } + /** + * The configuration. + * + * @var \Drupal\Core\Config\Config + */ + protected $configuration; - $key = $this->getKey($servicenow_key_id); + /** + * Constructs a new BasicAuthWithKeys object. + * + * @param \Drupal\Core\Config\Config $configuration + * The configuration. + * @param string $key_id + * The key ID. + */ + public function __construct($configuration, $key_id) { + $this->keyId = $key_id; + $this->configuration = $configuration; + } + /** + * Get the authentication options. + * + * @return array + * The authentication options. + */ + public function getAuthenticationOptions() { + if (!$this->keyId) { + throw new \Exception("Key not set"); + } + $key = $this->getKey($this->keyId); $key_object = $this->getKeyValues($key); - return [ 'auth' => [ $key_object->username, @@ -72,7 +93,7 @@ protected function getKeyValues($key) { $json_key = $key->getKeyValue(); if (!$json_key) { - throw new \Exception("Key 'ServiceNow' has no value"); + throw new \Exception("Key has no value"); } return json_decode($json_key); diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate_plus/authentication/ServiceNowAuth.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate_plus/authentication/ServiceNowAuth.php new file mode 100644 index 0000000000..b4b4f1d530 --- /dev/null +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate_plus/authentication/ServiceNowAuth.php @@ -0,0 +1,31 @@ +get('servicenow_auth_key'); + $basicAuthWithKeys = new BasicAuthWithKeys($servicenow_config, $servicenow_key_id); + return $basicAuthWithKeys->getAuthenticationOptions(); + } + +} From 661e6f3e22584c87898221b0bf754d4a312b2065 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Mon, 19 Aug 2024 12:37:00 -0400 Subject: [PATCH 28/60] feat(YSP-593): set sync source so we recreate layout builder A byproduct of setting syncSource is that the layout builder items need to be recreated. This is a benefit to us I believe in that we don't need to figure out if it needs updating, we just add a new block with the new content. My only worry is that database data is not being deleted when this happens; I need to look more into this. --- .../src/Plugin/migrate/process/LayoutBuilderSections.php | 4 ++++ .../modules/custom/ys_servicenow/src/ServiceNowManager.php | 3 +++ 2 files changed, 7 insertions(+) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate/process/LayoutBuilderSections.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate/process/LayoutBuilderSections.php index f82a519a11..e1cb2a34b3 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate/process/LayoutBuilderSections.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate/process/LayoutBuilderSections.php @@ -11,6 +11,10 @@ /** * Process plugin to migrate a source field into a Layout Builder Section. * + * Inspiration/references: + * https://github.com/dsasser/d8-migrate-paragraphs-layout-builder/blob/master/web/modules/custom/d8_migrations/src/LayoutBase.php + * https://github.com/chrisfromredfin/dcon21-milb/blob/main/web/modules/custom/my_migrations/src/Plugin/migrate/process/LayoutBuilderSectionsPages.php. + * * @MigrateProcessPlugin( * id = "layout_builder_sections", * ) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php index dba002520c..a13c30740a 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php @@ -148,6 +148,9 @@ public function runMigration($migration) { * $migrationInstance->set('syncSource', TRUE); */ + $migrationInstance->set('syncSource', TRUE); + $migration_update = $migrationInstance->getIdMap(); + $migration_update->prepareUpdate(); $message = new MigrateMessage(); $executable = new MigrateExecutable($migrationInstance, $message); $executable->import(); From 4c01afb3e8a1ba4be850d350e6f34cdd4b741851 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Wed, 21 Aug 2024 16:09:24 -0400 Subject: [PATCH 29/60] feat(YSP-593): give platform admins access to servicenow --- .../yalesites_profile/config/sync/user.role.platform_admin.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web/profiles/custom/yalesites_profile/config/sync/user.role.platform_admin.yml b/web/profiles/custom/yalesites_profile/config/sync/user.role.platform_admin.yml index bc661139ee..ae57a86a06 100644 --- a/web/profiles/custom/yalesites_profile/config/sync/user.role.platform_admin.yml +++ b/web/profiles/custom/yalesites_profile/config/sync/user.role.platform_admin.yml @@ -79,6 +79,7 @@ dependencies: - ys_alert - ys_core - ys_localist + - ys_servicenow id: platform_admin label: 'Platform administrator' weight: -5 @@ -411,4 +412,5 @@ permissions: - 'view unpublished paragraphs' - 'yalesites manage alerts' - 'yalesites manage localist' + - 'yalesites manage servicenow' - 'yalesites manage settings' From 5022beef9f70d6fb828cad67f95549817110ea0e Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Wed, 21 Aug 2024 16:09:49 -0400 Subject: [PATCH 30/60] fix(YSP-593): remove endpoint Remove the endpoint since it's hardcoded into the YAML. --- .../custom/ys_servicenow/src/Form/ServiceNowSettings.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Form/ServiceNowSettings.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Form/ServiceNowSettings.php index e9a98bdc08..0b74b2715b 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Form/ServiceNowSettings.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Form/ServiceNowSettings.php @@ -112,14 +112,6 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#disabled' => !$allowSecretItems, ]; - $form['servicenow_endpoint'] = [ - '#type' => 'url', - '#title' => $this->t('ServiceNow endpoint base URL'), - '#description' => $this->t('Ex: https://apiendpoint'), - '#default_value' => $config->get('servicenow_endpoint') ?: '', - '#disabled' => !$allowSecretItems, - ]; - $form['servicenow_auth_key'] = [ '#type' => 'key_select', '#title' => $this->t('ServiceNow Authentication Credentials'), @@ -160,7 +152,6 @@ public function submitForm(array &$form, FormStateInterface $form_state) { $this->configFactory->getEditable('ys_servicenow.settings') // Set the submitted configuration setting. ->set('enable_servicenow_sync', $form_state->getValue('enable_servicenow_sync')) - ->set('servicenow_endpoint', rtrim($form_state->getValue('servicenow_endpoint'), "/")) ->set('servicenow_auth_key', $form_state->getValue('servicenow_auth_key')) ->save(); From 3b8906599141d337f26473543661aecb953b0244 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Wed, 21 Aug 2024 16:15:23 -0400 Subject: [PATCH 31/60] feat(YSP-593): only sync block data --- .../custom/ys_servicenow/src/ServiceNowManager.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php index a13c30740a..175a805099 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php @@ -148,9 +148,12 @@ public function runMigration($migration) { * $migrationInstance->set('syncSource', TRUE); */ - $migrationInstance->set('syncSource', TRUE); - $migration_update = $migrationInstance->getIdMap(); - $migration_update->prepareUpdate(); + // We choose to use syncSource since we want to recreate the block for update. + if ($migration === 'servicenow_knowledge_base_article_block') { + $migrationInstance->set('syncSource', TRUE); + $migration_update = $migrationInstance->getIdMap(); + $migration_update->prepareUpdate(); + } $message = new MigrateMessage(); $executable = new MigrateExecutable($migrationInstance, $message); $executable->import(); From f7e39162ba4c0058b9b0cb5a3d393f0d120cdb83 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Wed, 21 Aug 2024 16:21:46 -0400 Subject: [PATCH 32/60] fix(YSP-593): enable servicenow --- .../custom/yalesites_profile/config/sync/core.extension.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/web/profiles/custom/yalesites_profile/config/sync/core.extension.yml b/web/profiles/custom/yalesites_profile/config/sync/core.extension.yml index 9cd2218d72..86a2966cd4 100644 --- a/web/profiles/custom/yalesites_profile/config/sync/core.extension.yml +++ b/web/profiles/custom/yalesites_profile/config/sync/core.extension.yml @@ -148,6 +148,7 @@ module: ys_localist: 0 ys_mail: 0 ys_node_access: 0 + ys_servicenow: 0 ys_starterkit: 0 ys_toolbar: 0 ys_views_basic: 0 From 273b19eca8be43203f054f12e11e0eeef5d9964b Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Wed, 21 Aug 2024 16:24:12 -0400 Subject: [PATCH 33/60] fix(YSP-593): move servicenow to admin --- .../modules/custom/ys_servicenow/ys_servicenow.links.menu.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.links.menu.yml b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.links.menu.yml index 29996dbfff..e8c0c1e650 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.links.menu.yml +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.links.menu.yml @@ -2,5 +2,5 @@ ys_servicenow.settings: title: 'ServiceNow settings' description: 'Configure ServiceNow sync settings' route_name: ys_servicenow.settings - parent: ys_core.admin_yalesites + parent: system.admin_config weight: 0 From b457df69670ad2245cd8ea66321bfa8141a2633d Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Wed, 21 Aug 2024 16:25:33 -0400 Subject: [PATCH 34/60] fix(YSP-593): remove permission for platform admins --- .../yalesites_profile/config/sync/user.role.platform_admin.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/config/sync/user.role.platform_admin.yml b/web/profiles/custom/yalesites_profile/config/sync/user.role.platform_admin.yml index ae57a86a06..bc661139ee 100644 --- a/web/profiles/custom/yalesites_profile/config/sync/user.role.platform_admin.yml +++ b/web/profiles/custom/yalesites_profile/config/sync/user.role.platform_admin.yml @@ -79,7 +79,6 @@ dependencies: - ys_alert - ys_core - ys_localist - - ys_servicenow id: platform_admin label: 'Platform administrator' weight: -5 @@ -412,5 +411,4 @@ permissions: - 'view unpublished paragraphs' - 'yalesites manage alerts' - 'yalesites manage localist' - - 'yalesites manage servicenow' - 'yalesites manage settings' From 1c4b6e56294446f8a2cc51bca8f4833d175606ee Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Wed, 21 Aug 2024 16:29:35 -0400 Subject: [PATCH 35/60] fix(YSP-593): don't validate deleted element --- .../custom/ys_servicenow/src/Form/ServiceNowSettings.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Form/ServiceNowSettings.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Form/ServiceNowSettings.php index 0b74b2715b..12946eb8fb 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Form/ServiceNowSettings.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Form/ServiceNowSettings.php @@ -127,9 +127,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { public function validateForm(array &$form, FormStateInterface $form_state) { $enabled = $form_state->getValue('enable_servicenow_sync'); if ($enabled) { - $requiredFields = [ - 'servicenow_endpoint', - ]; + $requiredFields = []; foreach ($requiredFields as $field) { if (!$form_state->getValue($field)) { From 5fb694ce6eb35de0260592428e96428118c3072b Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Wed, 21 Aug 2024 16:31:02 -0400 Subject: [PATCH 36/60] fix(YSP-593): use credentials as sync condition --- .../custom/ys_servicenow/src/Form/ServiceNowSettings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Form/ServiceNowSettings.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Form/ServiceNowSettings.php index 12946eb8fb..f68b3af086 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Form/ServiceNowSettings.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Form/ServiceNowSettings.php @@ -96,7 +96,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { if ( $config->get('enable_servicenow_sync') && - $config->get('servicenow_endpoint') + $config->get('servicenow_auth_key') ) { $form['sync_now_button'] = [ '#type' => 'markup', From ed8b1edec343d0aefff49de51c11736781a51e0f Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Wed, 21 Aug 2024 16:33:42 -0400 Subject: [PATCH 37/60] feat(YSP-593): make imported items published --- .../migrations/servicenow_knowledge_base_articles.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml index addf1a2bf4..e5b8ac0931 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml @@ -34,11 +34,15 @@ process: layout_builder__layout: source: servicenow_title plugin: layout_builder_sections + moderation_state: + plugin: default_value + default_value: 'published' destination: plugin: 'entity:node' default_bundle: page overwrite_properties: - title + - moderation_state migration_dependencies: required: - servicenow_knowledge_base_article_block From b51993c52b7e6bce7aadca4e370d71301b9d506c Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Wed, 21 Aug 2024 16:42:58 -0400 Subject: [PATCH 38/60] docs(YSP-539): add some useful documentation --- .../modules/custom/ys_servicenow/README.md | 19 +++++++++++++++++++ .../ys_servicenow/src/ServiceNowManager.php | 3 ++- .../custom/ys_servicenow/ys_servicenow.module | 1 - 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/README.md b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/README.md index e69de29bb2..f8f9b83c98 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/README.md +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/README.md @@ -0,0 +1,19 @@ +# YaleSites ServiceNow + +This is a YaleSites integration to allow ServiceNow knowledge base articles to import into the platform. The ultimate goal of this is to allow it to then go through our AI pipeline so that you can ask questions that will consider the articles synced. + +## Features + +Features include: + +- Key-based authentication +- Block-based syncing + +## Usage + +1. Install the module +2. Create a new key in the keys module with the ServiceNow endpoint username and password credentials +3. Visit the ServiceNow Settings under Configuration +4. Enable the module and select the key you created +5. Save +6. Upon reload, you'll notice a Sync button; click this button to do a manual sync diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php index 175a805099..80c7f76107 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php @@ -148,7 +148,8 @@ public function runMigration($migration) { * $migrationInstance->set('syncSource', TRUE); */ - // We choose to use syncSource since we want to recreate the block for update. + // We choose to use syncSource since we want to recreate the block for + // update. if ($migration === 'servicenow_knowledge_base_article_block') { $migrationInstance->set('syncSource', TRUE); $migration_update = $migrationInstance->getIdMap(); diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.module b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.module index f4587d9d82..303cbfcb4d 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.module +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.module @@ -4,4 +4,3 @@ * @file * Primary module hooks for YS ServiceNow module. */ - From 3ed2f6295c8da3ddf67cb94c42a744b6a3111065 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Thu, 22 Aug 2024 10:43:03 -0400 Subject: [PATCH 39/60] fix(YSP-593): save node so that update pipelines can run It seems when migrations happen, they skip the callbacks that items would normally have. In our case, it's not triggering our ai module hook to update. This is an attempt to save them so that it can pick it up. --- .../custom/ys_servicenow/src/ServiceNowManager.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php index 80c7f76107..e3c62dea67 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php @@ -196,6 +196,17 @@ public function runAllMigrations() { 'imported' => $this->getMigrationStatus($migration), ]; } + + $articleMigration = 'servicenow_knowledge_base_articles'; + + $migration = $this->migrationManager->createInstance($articleMigration); + $map = $migration->getIdMap(); + foreach ($map->fetchLastImported() as $id) { + $node = $this->entityTypeManager->getStorage('node')->load($id); + // Save the node so that proper hooks can be called on resulting data. + $node->save(); + } + return $messageData; } From 2132a6760075c931fc0f1cbec8abbbf89e2e5fc0 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Thu, 22 Aug 2024 10:53:36 -0400 Subject: [PATCH 40/60] fix(YSP-593): Do dirty update (revert later) --- .../custom/ys_servicenow/src/ServiceNowManager.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php index e3c62dea67..9441f42eb8 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php @@ -201,10 +201,12 @@ public function runAllMigrations() { $migration = $this->migrationManager->createInstance($articleMigration); $map = $migration->getIdMap(); - foreach ($map->fetchLastImported() as $id) { - $node = $this->entityTypeManager->getStorage('node')->load($id); - // Save the node so that proper hooks can be called on resulting data. - $node->save(); + + // Get each node from the map. + $ids = $map->lookupDestinationIds(); + foreach ($ids as $id) { + $entity = $this->entityTypeManager->getStorage('node')->load($id); + \Drupal::service('ai_engine_embedding.entity_update')->update($entity); } return $messageData; From 3eb29c2d5e24cc3ae615f4f7bb8f27bfc01d6e9a Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Thu, 22 Aug 2024 10:57:30 -0400 Subject: [PATCH 41/60] revert(YSP-593): revert dumb fixes for pipeline --- .../custom/ys_servicenow/src/ServiceNowManager.php | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php index 9441f42eb8..23a60b549a 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php @@ -197,18 +197,6 @@ public function runAllMigrations() { ]; } - $articleMigration = 'servicenow_knowledge_base_articles'; - - $migration = $this->migrationManager->createInstance($articleMigration); - $map = $migration->getIdMap(); - - // Get each node from the map. - $ids = $map->lookupDestinationIds(); - foreach ($ids as $id) { - $entity = $this->entityTypeManager->getStorage('node')->load($id); - \Drupal::service('ai_engine_embedding.entity_update')->update($entity); - } - return $messageData; } From 0d364fccc9914b342ce964b154c379a06e266bef Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Thu, 5 Sep 2024 09:34:26 -0400 Subject: [PATCH 42/60] fix(YSP-593): remove limit from servicenow endpoint --- .../migrations/servicenow_knowledge_base_article_block.yml | 2 +- .../migrations/servicenow_knowledge_base_articles.yml | 2 +- .../migrations/servicenow_knowledge_base_layout_builder.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_article_block.yml b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_article_block.yml index 80814ebee0..dd3412b22d 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_article_block.yml +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_article_block.yml @@ -10,7 +10,7 @@ source: authentication: plugin: servicenow_auth track_changes: true - urls: https://yaledevelopment.service-now.com/api/now/table/kb_knowledge?sysparm_query=workflow_state%3Dpublished%5Ekb_category.label!%3DNews%5Ecan_read_user_criteriaLIKEfd81a4dadbb6030043565bc0cf961905%5Eu_kb_ai_ready%3Dtrue&sysparm_display_value=true&sysparm_fields=sys_name%2Ctext%2Ctopic%2Cu_service_offering%2Cnumber%2Csys_created_on%2Ccan_read_user_criteria%2Cpublished%2Ckb_knowledge_base%2Cdescription%2Cvalid_to%2Csys_view_count%2Cshort_description%2Ckb_category&sysparm_limit=10 + urls: https://yaledevelopment.service-now.com/api/now/table/kb_knowledge?sysparm_query=workflow_state%3Dpublished%5Ekb_category.label!%3DNews%5Ecan_read_user_criteriaLIKEfd81a4dadbb6030043565bc0cf961905%5Eu_kb_ai_ready%3Dtrue&sysparm_display_value=true&sysparm_fields=sys_name%2Ctext%2Ctopic%2Cu_service_offering%2Cnumber%2Csys_created_on%2Ccan_read_user_criteria%2Cpublished%2Ckb_knowledge_base%2Cdescription%2Cvalid_to%2Csys_view_count%2Cshort_description%2Ckb_category item_selector: result fields: - name: servicenow_number diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml index e5b8ac0931..f9ab601d87 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml @@ -10,7 +10,7 @@ source: authentication: plugin: servicenow_auth track_changes: true - urls: https://yaledevelopment.service-now.com/api/now/table/kb_knowledge?sysparm_query=workflow_state%3Dpublished%5Ekb_category.label!%3DNews%5Ecan_read_user_criteriaLIKEfd81a4dadbb6030043565bc0cf961905%5Eu_kb_ai_ready%3Dtrue&sysparm_display_value=true&sysparm_fields=sys_name%2Ctext%2Ctopic%2Cu_service_offering%2Cnumber%2Csys_created_on%2Ccan_read_user_criteria%2Cpublished%2Ckb_knowledge_base%2Cdescription%2Cvalid_to%2Csys_view_count%2Cshort_description%2Ckb_category&sysparm_limit=10 + urls: https://yaledevelopment.service-now.com/api/now/table/kb_knowledge?sysparm_query=workflow_state%3Dpublished%5Ekb_category.label!%3DNews%5Ecan_read_user_criteriaLIKEfd81a4dadbb6030043565bc0cf961905%5Eu_kb_ai_ready%3Dtrue&sysparm_display_value=true&sysparm_fields=sys_name%2Ctext%2Ctopic%2Cu_service_offering%2Cnumber%2Csys_created_on%2Ccan_read_user_criteria%2Cpublished%2Ckb_knowledge_base%2Cdescription%2Cvalid_to%2Csys_view_count%2Cshort_description%2Ckb_category item_selector: result fields: - name: servicenow_number diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_layout_builder.yml b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_layout_builder.yml index 0158119268..5a2a577b62 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_layout_builder.yml +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_layout_builder.yml @@ -10,7 +10,7 @@ source: authentication: plugin: servicenow_auth track_changes: true - urls: https://yaledevelopment.service-now.com/api/now/table/kb_knowledge?sysparm_query=workflow_state%3Dpublished%5Ekb_category.label!%3DNews%5Ecan_read_user_criteriaLIKEfd81a4dadbb6030043565bc0cf961905%5Eu_kb_ai_ready%3Dtrue&sysparm_display_value=true&sysparm_fields=sys_name%2Ctext%2Ctopic%2Cu_service_offering%2Cnumber%2Csys_created_on%2Ccan_read_user_criteria%2Cpublished%2Ckb_knowledge_base%2Cdescription%2Cvalid_to%2Csys_view_count%2Cshort_description%2Ckb_category&sysparm_limit=10 + urls: https://yaledevelopment.service-now.com/api/now/table/kb_knowledge?sysparm_query=workflow_state%3Dpublished%5Ekb_category.label!%3DNews%5Ecan_read_user_criteriaLIKEfd81a4dadbb6030043565bc0cf961905%5Eu_kb_ai_ready%3Dtrue&sysparm_display_value=true&sysparm_fields=sys_name%2Ctext%2Ctopic%2Cu_service_offering%2Cnumber%2Csys_created_on%2Ccan_read_user_criteria%2Cpublished%2Ckb_knowledge_base%2Cdescription%2Cvalid_to%2Csys_view_count%2Cshort_description%2Ckb_category item_selector: result fields: - name: servicenow_number From a5853e541e441d5e02226e70d8ca9e921ba7d5df Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Fri, 6 Sep 2024 11:38:59 -0400 Subject: [PATCH 43/60] feat(YSP-593): config ignore servicenow settings --- .../yalesites_profile/config/sync/config_ignore.settings.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/web/profiles/custom/yalesites_profile/config/sync/config_ignore.settings.yml b/web/profiles/custom/yalesites_profile/config/sync/config_ignore.settings.yml index 814e7b3bd3..007ac237c4 100644 --- a/web/profiles/custom/yalesites_profile/config/sync/config_ignore.settings.yml +++ b/web/profiles/custom/yalesites_profile/config/sync/config_ignore.settings.yml @@ -8,3 +8,4 @@ ignored_config_entities: - ys_themes.theme_settings - 'ys_localist*' - 'ai_engine*' + - 'ys_servicenow*' From f522f7c32a22fa229f7e8cab76918fd8aaa7c91c Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Wed, 11 Sep 2024 11:05:38 -0400 Subject: [PATCH 44/60] feat(YSP-593): enable cron job --- .../custom/ys_servicenow/ys_servicenow.module | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.module b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.module index 303cbfcb4d..f0c6134097 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.module +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.module @@ -4,3 +4,22 @@ * @file * Primary module hooks for YS ServiceNow module. */ + +/** + * Implements hook_cron(). + */ +function ys_servicenow_cron() { + $config = \Drupal::config('ys_servicenow.settings'); + if ($config->get('enable_servicenow_sync')) { + + $state = \Drupal::state(); + + $next_execution_time = $state->get("servicenow_migrations", 0); + $current_time = \Drupal::time()->getRequestTime(); + if ($current_time > $next_execution_time) { + $state->set("servicenow_migrations", $current_time + 3600); + $servicenowManager = \Drupal::service('ys_servicenow.manager'); + $servicenowManager->runAllMigrations(); + } + } +} From 463f78e2af38105af1200122475fc35da5e896b2 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Wed, 11 Sep 2024 12:24:01 -0400 Subject: [PATCH 45/60] feat(YSP-593): use configurable endpoint for migration call --- ...servicenow_knowledge_base_article_block.yml | 3 ++- .../servicenow_knowledge_base_articles.yml | 3 ++- ...ervicenow_knowledge_base_layout_builder.yml | 3 ++- .../src/Form/ServiceNowSettings.php | 13 ++++++++++++- .../migrate/process/LayoutBuilderSections.php | 9 --------- .../custom/ys_servicenow/ys_servicenow.module | 18 ++++++++++++++++++ 6 files changed, 36 insertions(+), 13 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_article_block.yml b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_article_block.yml index dd3412b22d..20d4459b56 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_article_block.yml +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_article_block.yml @@ -10,7 +10,8 @@ source: authentication: plugin: servicenow_auth track_changes: true - urls: https://yaledevelopment.service-now.com/api/now/table/kb_knowledge?sysparm_query=workflow_state%3Dpublished%5Ekb_category.label!%3DNews%5Ecan_read_user_criteriaLIKEfd81a4dadbb6030043565bc0cf961905%5Eu_kb_ai_ready%3Dtrue&sysparm_display_value=true&sysparm_fields=sys_name%2Ctext%2Ctopic%2Cu_service_offering%2Cnumber%2Csys_created_on%2Ccan_read_user_criteria%2Cpublished%2Ckb_knowledge_base%2Cdescription%2Cvalid_to%2Csys_view_count%2Cshort_description%2Ckb_category + urls: + callback: ys_servicenow_url_endpoint item_selector: result fields: - name: servicenow_number diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml index f9ab601d87..7079d9ae88 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml @@ -10,7 +10,8 @@ source: authentication: plugin: servicenow_auth track_changes: true - urls: https://yaledevelopment.service-now.com/api/now/table/kb_knowledge?sysparm_query=workflow_state%3Dpublished%5Ekb_category.label!%3DNews%5Ecan_read_user_criteriaLIKEfd81a4dadbb6030043565bc0cf961905%5Eu_kb_ai_ready%3Dtrue&sysparm_display_value=true&sysparm_fields=sys_name%2Ctext%2Ctopic%2Cu_service_offering%2Cnumber%2Csys_created_on%2Ccan_read_user_criteria%2Cpublished%2Ckb_knowledge_base%2Cdescription%2Cvalid_to%2Csys_view_count%2Cshort_description%2Ckb_category + urls: + callback: ys_servicenow_url_endpoint item_selector: result fields: - name: servicenow_number diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_layout_builder.yml b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_layout_builder.yml index 5a2a577b62..b9dd565276 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_layout_builder.yml +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_layout_builder.yml @@ -10,7 +10,8 @@ source: authentication: plugin: servicenow_auth track_changes: true - urls: https://yaledevelopment.service-now.com/api/now/table/kb_knowledge?sysparm_query=workflow_state%3Dpublished%5Ekb_category.label!%3DNews%5Ecan_read_user_criteriaLIKEfd81a4dadbb6030043565bc0cf961905%5Eu_kb_ai_ready%3Dtrue&sysparm_display_value=true&sysparm_fields=sys_name%2Ctext%2Ctopic%2Cu_service_offering%2Cnumber%2Csys_created_on%2Ccan_read_user_criteria%2Cpublished%2Ckb_knowledge_base%2Cdescription%2Cvalid_to%2Csys_view_count%2Cshort_description%2Ckb_category + urls: + callback: ys_servicenow_url_endpoint item_selector: result fields: - name: servicenow_number diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Form/ServiceNowSettings.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Form/ServiceNowSettings.php index f68b3af086..3a81b8d2df 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Form/ServiceNowSettings.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Form/ServiceNowSettings.php @@ -96,6 +96,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { if ( $config->get('enable_servicenow_sync') && + $config->get('servicenow_endpoint') && $config->get('servicenow_auth_key') ) { $form['sync_now_button'] = [ @@ -112,6 +113,12 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#disabled' => !$allowSecretItems, ]; + $form['servicenow_endpoint'] = [ + '#type' => 'textarea', + '#title' => $this->t('ServiceNow Endpoint'), + '#default_value' => $config->get('servicenow_endpoint') ?: '', + ]; + $form['servicenow_auth_key'] = [ '#type' => 'key_select', '#title' => $this->t('ServiceNow Authentication Credentials'), @@ -127,7 +134,10 @@ public function buildForm(array $form, FormStateInterface $form_state) { public function validateForm(array &$form, FormStateInterface $form_state) { $enabled = $form_state->getValue('enable_servicenow_sync'); if ($enabled) { - $requiredFields = []; + $requiredFields = [ + 'servicenow_auth_key', + 'servicenow_endpoint', + ]; foreach ($requiredFields as $field) { if (!$form_state->getValue($field)) { @@ -151,6 +161,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { // Set the submitted configuration setting. ->set('enable_servicenow_sync', $form_state->getValue('enable_servicenow_sync')) ->set('servicenow_auth_key', $form_state->getValue('servicenow_auth_key')) + ->set('servicenow_endpoint', $form_state->getValue('servicenow_endpoint')) ->save(); parent::submitForm($form, $form_state); diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate/process/LayoutBuilderSections.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate/process/LayoutBuilderSections.php index e1cb2a34b3..a361b5b327 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate/process/LayoutBuilderSections.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/Plugin/migrate/process/LayoutBuilderSections.php @@ -26,10 +26,7 @@ class LayoutBuilderSections extends ProcessPluginBase { */ public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { - \Drupal::messenger()->addMessage("Value: " . $value, 'status', TRUE); - if ($value == NULL) { - \Drupal::messenger()->addError("value is NULL", 'status', TRUE); return NULL; } @@ -54,8 +51,6 @@ public function transform($value, MigrateExecutableInterface $migrate_executable return NULL; } - \Drupal::messenger()->addMessage("Got a block content"); - $config = [ 'id' => 'inline_block:text', 'label' => $block_content->label(), @@ -69,15 +64,11 @@ public function transform($value, MigrateExecutableInterface $migrate_executable $components[] = new SectionComponent($generator->generate(), 'content', $config); - \Drupal::messenger()->addMessage("Made a section component"); - // If you were doing multiple sections, you'd want this to be an array // somehow. @TODO figure out how to do that ;) // PARAMS: $layout_id, $layout_settings, $components. $sections = new Section('layout_onecol', [], $components); - \Drupal::messenger()->addMessage("Made a section"); - return $sections; } diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.module b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.module index f0c6134097..b01c6f2710 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.module +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.module @@ -5,6 +5,8 @@ * Primary module hooks for YS ServiceNow module. */ +use Drupal\migrate\Plugin\MigrationInterface; + /** * Implements hook_cron(). */ @@ -23,3 +25,19 @@ function ys_servicenow_cron() { } } } + +/** + * Provide the URL endpoint for migrations in servicenow from config. + */ +function ys_servicenow_url_endpoint(MigrationInterface $migration): array { + // Get the servicenow configuration. + $servicenow_config = \Drupal::config('ys_servicenow.settings'); + // Get the endpoint type from the migration. + $endpoint = $servicenow_config->get('servicenow_endpoint'); + + if ($endpoint) { + return [$endpoint]; + } + + return []; +} From bd825c62904f8b41121decb6ef199e10a33afd60 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Wed, 11 Sep 2024 16:04:06 -0400 Subject: [PATCH 46/60] fix(YSP-593): guard against invalid JSON --- ...rvicenow_knowledge_base_layout_builder.yml | 42 ------------------- .../ys_servicenow/src/BasicAuthWithKeys.php | 8 +++- 2 files changed, 7 insertions(+), 43 deletions(-) delete mode 100644 web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_layout_builder.yml diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_layout_builder.yml b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_layout_builder.yml deleted file mode 100644 index b9dd565276..0000000000 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_layout_builder.yml +++ /dev/null @@ -1,42 +0,0 @@ -id: servicenow_knowledge_base_layout_builder -label: 'ServiceNow knowledge base articles' -source: - plugin: url - data_fetcher_plugin: http - data_parser_plugin: json - headers: - Accept: 'application/json; charset=utf-8' - Content-Type: application/json - authentication: - plugin: servicenow_auth - track_changes: true - urls: - callback: ys_servicenow_url_endpoint - item_selector: result - fields: - - name: servicenow_number - label: 'ServiceNow number' - selector: number - ids: - servicenow_number: - type: string -process: - id: servicenow_number - field_text: servicenow_content - block: - plugin: migration_lookup - migration: servicenow_knowledge_base_article_block - source: servicenow_number - node: - plugin: migration_lookup - migration: servicenow_knowledge_base_articles - source: servicenow_number -destination: - plugin: append_block_to_node - source: servicenow_number -dependencies: - enforced: - module: - - migrate_plus - - migrate_tools - - layout_builder diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/BasicAuthWithKeys.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/BasicAuthWithKeys.php index cc8f66410b..3e3d72d3ad 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/BasicAuthWithKeys.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/BasicAuthWithKeys.php @@ -96,7 +96,13 @@ protected function getKeyValues($key) { throw new \Exception("Key has no value"); } - return json_decode($json_key); + $decoded_object = json_decode($json_key); + + if (!$decoded_object) { + throw new \Exception("Key value is not valid JSON. Could you have accidentally used single quotes vs double?"); + } + + return $decoded_object; } } From 5a2c43835430bdb6734ecd3e400022ea65b963cd Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Thu, 12 Sep 2024 15:00:26 -0400 Subject: [PATCH 47/60] feat(YSP-593): use workflow_state to drive publish status --- .../servicenow_knowledge_base_articles.yml | 8 ++++++-- .../custom/ys_servicenow/ys_servicenow.module | 13 +++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml index 7079d9ae88..ebc6d2053e 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/migrations/servicenow_knowledge_base_articles.yml @@ -23,6 +23,9 @@ source: - name: servicenow_text label: 'ServiceNow text' selector: text + - name: servicenow_workflow_state + label: 'ServiceNow workflow state' + selector: workflow_state ids: servicenow_number: type: string @@ -36,8 +39,9 @@ process: source: servicenow_title plugin: layout_builder_sections moderation_state: - plugin: default_value - default_value: 'published' + plugin: callback + callable: ys_servicenow_moderation_state_transformation + source: servicenow_workflow_state destination: plugin: 'entity:node' default_bundle: page diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.module b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.module index b01c6f2710..5609e3bc6a 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.module +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.module @@ -41,3 +41,16 @@ function ys_servicenow_url_endpoint(MigrationInterface $migration): array { return []; } + +/** + * Any state other than "Published" is unpublished. + */ +function ys_servicenow_moderation_state_transformation($value) { + $unpublished_state = 'archive'; + + $published_states = [ + 'Published' => 'published', + ]; + + return $published_states[$value] ?? $unpublished_state; +} From fd221db1f20512c579c06ed9f8fcc9d13248dccd Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Fri, 13 Sep 2024 11:42:25 -0400 Subject: [PATCH 48/60] docs(YSP-593): add supporting docs for usage --- .../modules/custom/ys_servicenow/README.md | 29 ++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/README.md b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/README.md index f8f9b83c98..e560f49ab6 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/README.md +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/README.md @@ -12,8 +12,29 @@ Features include: ## Usage 1. Install the module -2. Create a new key in the keys module with the ServiceNow endpoint username and password credentials +2. Create a new key in the keys module with the ServiceNow endpoint username and password credentials (see pantheon secrets below) 3. Visit the ServiceNow Settings under Configuration -4. Enable the module and select the key you created -5. Save -6. Upon reload, you'll notice a Sync button; click this button to do a manual sync +4. Enable the module +5. Select the key you created from the drop down +6. Enter the endpoint URL you were given by the ServiceNow Team + 1. Ensure that the following fields are present in the JSON output: + 1. number: The KB article number + 2. short_description: The title of the article + 3. text: The body of the article + 4. workflow_state: The state of the article (Published, etc) +7. Save +8. Upon reload, you'll notice a Sync button; click this button to do a manual sync + +The service once turned on will attempt to sync hourly. + +## Pantheon Secrets + +Pantheon secrets can be used with their Drupal module to interact with the keys module. To do this you'd want to add a pantheon secret at the site level first with empty data: + +`terminus secrets:site:set --scope web,user servicenow_auth ""` + +From there, you can then specify the multidev specific information. The key must ultimately be a JSON payload of the following: + +`terminus secrets:site:set . servicenow_auth '{"username":"username","password":"password"}'` + +Then simply sync pantheon secrets in the keys configuration to bring in the key; remember that there is a time delay on when that becomes available for sync. From 05623e09f0938d9738e998f2912485e9461b39a3 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Wed, 25 Sep 2024 15:03:40 -0400 Subject: [PATCH 49/60] fix(YSP-593): do not overwrite old data each time Marc has written about this, and it looks as if when an item is no longer present in the payload that it gets wiped, which we do not want. So we removed this; more testing needs to be done on the effects of changing the data and how it updates. --- .../custom/ys_servicenow/src/ServiceNowManager.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php index 23a60b549a..c2fe83ef3a 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/src/ServiceNowManager.php @@ -150,11 +150,11 @@ public function runMigration($migration) { // We choose to use syncSource since we want to recreate the block for // update. - if ($migration === 'servicenow_knowledge_base_article_block') { - $migrationInstance->set('syncSource', TRUE); - $migration_update = $migrationInstance->getIdMap(); - $migration_update->prepareUpdate(); - } + /*if ($migration === 'servicenow_knowledge_base_article_block') {*/ + /* $migrationInstance->set('syncSource', TRUE);*/ + /* $migration_update = $migrationInstance->getIdMap();*/ + /* $migration_update->prepareUpdate();*/ + /*}*/ $message = new MigrateMessage(); $executable = new MigrateExecutable($migrationInstance, $message); $executable->import(); From 3a1a597c83d92cac2bbe4e30d6fc74ff4563c2c6 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Fri, 27 Sep 2024 08:14:34 -0400 Subject: [PATCH 50/60] feat(YSP-593): move servicenow to web services configuration links --- .../modules/custom/ys_servicenow/ys_servicenow.links.menu.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.links.menu.yml b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.links.menu.yml index e8c0c1e650..c97fc72830 100644 --- a/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.links.menu.yml +++ b/web/profiles/custom/yalesites_profile/modules/custom/ys_servicenow/ys_servicenow.links.menu.yml @@ -2,5 +2,5 @@ ys_servicenow.settings: title: 'ServiceNow settings' description: 'Configure ServiceNow sync settings' route_name: ys_servicenow.settings - parent: system.admin_config + parent: system.admin_config_services weight: 0 From 958e94f84ded7d329df770d8dc2c4ed7703a2ef9 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Fri, 27 Sep 2024 08:18:42 -0400 Subject: [PATCH 51/60] feat(YSP-593): add ys_servicenow to config ignore --- .../yalesites_profile/config/sync/config_ignore.settings.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/web/profiles/custom/yalesites_profile/config/sync/config_ignore.settings.yml b/web/profiles/custom/yalesites_profile/config/sync/config_ignore.settings.yml index 007ac237c4..50fe0d9570 100644 --- a/web/profiles/custom/yalesites_profile/config/sync/config_ignore.settings.yml +++ b/web/profiles/custom/yalesites_profile/config/sync/config_ignore.settings.yml @@ -7,5 +7,4 @@ ignored_config_entities: - 'ys_core*' - ys_themes.theme_settings - 'ys_localist*' - - 'ai_engine*' - 'ys_servicenow*' From 391cfcf7123cd591d8a5569cff8c01c12beeb253 Mon Sep 17 00:00:00 2001 From: Vincent Massaro Date: Wed, 2 Oct 2024 15:50:14 -0400 Subject: [PATCH 52/60] feat: update atomic to 1.37.0 --- web/profiles/custom/yalesites_profile/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/profiles/custom/yalesites_profile/composer.json b/web/profiles/custom/yalesites_profile/composer.json index 7128dde846..09efbd40ff 100644 --- a/web/profiles/custom/yalesites_profile/composer.json +++ b/web/profiles/custom/yalesites_profile/composer.json @@ -106,7 +106,7 @@ "laminas/laminas-escaper": "2.12", "northernco/ckeditor5-anchor-drupal": "0.4.0", "yalesites-org/ai_engine": "1.2.4", - "yalesites-org/atomic": "1.36.0", + "yalesites-org/atomic": "1.37.0", "yalesites-org/yale_cas": "1.0.4" }, "minimum-stability": "dev", From acf0912ac5bc732e0d9f991a99bfc745105ff578 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Thu, 3 Oct 2024 10:09:50 -0400 Subject: [PATCH 53/60] feat(YSP-693): increase max chars on spotlights to 650 This increases the maximum character limit on spotlights from 500 to 650 characters. --- ...ity_form_display.block_content.content_spotlight.default.yml | 2 +- ...display.block_content.content_spotlight_portrait.default.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/web/profiles/custom/yalesites_profile/config/sync/core.entity_form_display.block_content.content_spotlight.default.yml b/web/profiles/custom/yalesites_profile/config/sync/core.entity_form_display.block_content.content_spotlight.default.yml index d967b1cae3..6dbfdbe027 100644 --- a/web/profiles/custom/yalesites_profile/config/sync/core.entity_form_display.block_content.content_spotlight.default.yml +++ b/web/profiles/custom/yalesites_profile/config/sync/core.entity_form_display.block_content.content_spotlight.default.yml @@ -140,7 +140,7 @@ content: hide_help: '1' hide_guidelines: '1' maxlength: - maxlength_js: 500 + maxlength_js: 650 maxlength_js_label: 'Content limited to @limit characters, remaining: @remaining' maxlength_js_enforce: true info: diff --git a/web/profiles/custom/yalesites_profile/config/sync/core.entity_form_display.block_content.content_spotlight_portrait.default.yml b/web/profiles/custom/yalesites_profile/config/sync/core.entity_form_display.block_content.content_spotlight_portrait.default.yml index e06663272f..fcc3f2d1d2 100644 --- a/web/profiles/custom/yalesites_profile/config/sync/core.entity_form_display.block_content.content_spotlight_portrait.default.yml +++ b/web/profiles/custom/yalesites_profile/config/sync/core.entity_form_display.block_content.content_spotlight_portrait.default.yml @@ -136,7 +136,7 @@ content: hide_help: '1' hide_guidelines: '1' maxlength: - maxlength_js: 500 + maxlength_js: 650 maxlength_js_label: 'Content limited to @limit characters, remaining: @remaining' maxlength_js_enforce: true info: From 71cbbf8be799ba755c6ea3ba5e8d66b0fb9911c2 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Thu, 3 Oct 2024 13:07:08 -0400 Subject: [PATCH 54/60] feat(YSP-693): set landscape max characters to 600 --- ...ity_form_display.block_content.content_spotlight.default.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/profiles/custom/yalesites_profile/config/sync/core.entity_form_display.block_content.content_spotlight.default.yml b/web/profiles/custom/yalesites_profile/config/sync/core.entity_form_display.block_content.content_spotlight.default.yml index 6dbfdbe027..c41eaf9021 100644 --- a/web/profiles/custom/yalesites_profile/config/sync/core.entity_form_display.block_content.content_spotlight.default.yml +++ b/web/profiles/custom/yalesites_profile/config/sync/core.entity_form_display.block_content.content_spotlight.default.yml @@ -140,7 +140,7 @@ content: hide_help: '1' hide_guidelines: '1' maxlength: - maxlength_js: 650 + maxlength_js: 600 maxlength_js_label: 'Content limited to @limit characters, remaining: @remaining' maxlength_js_enforce: true info: From 0883320476507766597a2e50675dfb04ddc1ac89 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Mon, 7 Oct 2024 09:13:18 -0400 Subject: [PATCH 55/60] chore(YSP-697): for multidev only --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 807a633a9f..c6a2e54959 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ The YaleSites platform empowers the Yale community to create digital experiences ## Common Scripts These are the most common npm scripts you may find yourself using: -(Each is prefixed with `npm run `) +(Each is prefixed with `npm run`) ### PR Reviews @@ -41,3 +41,4 @@ _Notes:_ - `confim` Imports the current config files to your database. - `local:theme-link` Run this script once to establish `npm link`s to all of the frontend-related repositories. - `local:cl-dev` Enables a frontend developer to work across all of the repositories (`yalesites-project`, `atomic`, and `component-library-twig`) in an environment configured to support both Storybook development, and have the changes reflected in the Drupal instance. Note: This also wires up the Tokens repo, but if you want to watch for changes there, you'll have to run the `npm run develop` script inside the Tokens directory. +- From 027b1748a4094e77a326f68b229e6c4c09518d2b Mon Sep 17 00:00:00 2001 From: David Blankenship <128765777+dblanken-yale@users.noreply.github.com> Date: Mon, 7 Oct 2024 13:47:03 -0400 Subject: [PATCH 56/60] Revert "YSP-697: Image Banner not respecting focal point" --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index c6a2e54959..807a633a9f 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ The YaleSites platform empowers the Yale community to create digital experiences ## Common Scripts These are the most common npm scripts you may find yourself using: -(Each is prefixed with `npm run`) +(Each is prefixed with `npm run `) ### PR Reviews @@ -41,4 +41,3 @@ _Notes:_ - `confim` Imports the current config files to your database. - `local:theme-link` Run this script once to establish `npm link`s to all of the frontend-related repositories. - `local:cl-dev` Enables a frontend developer to work across all of the repositories (`yalesites-project`, `atomic`, and `component-library-twig`) in an environment configured to support both Storybook development, and have the changes reflected in the Drupal instance. Note: This also wires up the Tokens repo, but if you want to watch for changes there, you'll have to run the `npm run develop` script inside the Tokens directory. -- From 1f9a25fc401ae1c954d9513746460cfee3882160 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Mon, 7 Oct 2024 14:43:05 -0400 Subject: [PATCH 57/60] feat: update atomic to 1.37.1 --- web/profiles/custom/yalesites_profile/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/profiles/custom/yalesites_profile/composer.json b/web/profiles/custom/yalesites_profile/composer.json index 09efbd40ff..6810930249 100644 --- a/web/profiles/custom/yalesites_profile/composer.json +++ b/web/profiles/custom/yalesites_profile/composer.json @@ -106,7 +106,7 @@ "laminas/laminas-escaper": "2.12", "northernco/ckeditor5-anchor-drupal": "0.4.0", "yalesites-org/ai_engine": "1.2.4", - "yalesites-org/atomic": "1.37.0", + "yalesites-org/atomic": "1.37.1", "yalesites-org/yale_cas": "1.0.4" }, "minimum-stability": "dev", From 636997b48708be1d099c824695b458d4bf599860 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Wed, 9 Oct 2024 10:57:57 -0400 Subject: [PATCH 58/60] feat: update atomic to 1.38.0 --- web/profiles/custom/yalesites_profile/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/profiles/custom/yalesites_profile/composer.json b/web/profiles/custom/yalesites_profile/composer.json index 6810930249..192465d0e6 100644 --- a/web/profiles/custom/yalesites_profile/composer.json +++ b/web/profiles/custom/yalesites_profile/composer.json @@ -106,7 +106,7 @@ "laminas/laminas-escaper": "2.12", "northernco/ckeditor5-anchor-drupal": "0.4.0", "yalesites-org/ai_engine": "1.2.4", - "yalesites-org/atomic": "1.37.1", + "yalesites-org/atomic": "1.38.0", "yalesites-org/yale_cas": "1.0.4" }, "minimum-stability": "dev", From 35e1fa6cbc9e8f715b68bfdd0cd0f381f498c214 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Wed, 9 Oct 2024 12:01:59 -0400 Subject: [PATCH 59/60] feat(ai_engine): config ignore ai_engine again --- .../config/sync/ai_engine_chat.settings.yml | 7 ------- .../config/sync/ai_engine_metadata.settings.yml | 3 --- .../config/sync/config_ignore.settings.yml | 1 + 3 files changed, 1 insertion(+), 10 deletions(-) delete mode 100644 web/profiles/custom/yalesites_profile/config/sync/ai_engine_chat.settings.yml delete mode 100644 web/profiles/custom/yalesites_profile/config/sync/ai_engine_metadata.settings.yml diff --git a/web/profiles/custom/yalesites_profile/config/sync/ai_engine_chat.settings.yml b/web/profiles/custom/yalesites_profile/config/sync/ai_engine_chat.settings.yml deleted file mode 100644 index c678f9ba23..0000000000 --- a/web/profiles/custom/yalesites_profile/config/sync/ai_engine_chat.settings.yml +++ /dev/null @@ -1,7 +0,0 @@ -_core: - default_config_hash: 2UNzD8lgl2QZFwoEWDqXPOjnX-1xrj2WOUPOyV36X4w -enable: false -azure_base_url: '' -initial_questions: { } -disclaimer: '' -footer: '' diff --git a/web/profiles/custom/yalesites_profile/config/sync/ai_engine_metadata.settings.yml b/web/profiles/custom/yalesites_profile/config/sync/ai_engine_metadata.settings.yml deleted file mode 100644 index d48968cc55..0000000000 --- a/web/profiles/custom/yalesites_profile/config/sync/ai_engine_metadata.settings.yml +++ /dev/null @@ -1,3 +0,0 @@ -_core: - default_config_hash: _M8zK1JzYowovWvVZ0BNgS8MXJ_VkFi1KuUjskwJ2h8 -enable: false diff --git a/web/profiles/custom/yalesites_profile/config/sync/config_ignore.settings.yml b/web/profiles/custom/yalesites_profile/config/sync/config_ignore.settings.yml index 50fe0d9570..e3bde278d4 100644 --- a/web/profiles/custom/yalesites_profile/config/sync/config_ignore.settings.yml +++ b/web/profiles/custom/yalesites_profile/config/sync/config_ignore.settings.yml @@ -8,3 +8,4 @@ ignored_config_entities: - ys_themes.theme_settings - 'ys_localist*' - 'ys_servicenow*' + - 'ai_engine*' From 470e530b6021fb5647e04d7a946fa2b183b82343 Mon Sep 17 00:00:00 2001 From: David Blankenship Date: Wed, 9 Oct 2024 12:18:19 -0400 Subject: [PATCH 60/60] chore(config_ignore): make edit to see if changes propigate --- .../yalesites_profile/config/sync/config_ignore.settings.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/profiles/custom/yalesites_profile/config/sync/config_ignore.settings.yml b/web/profiles/custom/yalesites_profile/config/sync/config_ignore.settings.yml index e3bde278d4..007ac237c4 100644 --- a/web/profiles/custom/yalesites_profile/config/sync/config_ignore.settings.yml +++ b/web/profiles/custom/yalesites_profile/config/sync/config_ignore.settings.yml @@ -7,5 +7,5 @@ ignored_config_entities: - 'ys_core*' - ys_themes.theme_settings - 'ys_localist*' - - 'ys_servicenow*' - 'ai_engine*' + - 'ys_servicenow*'