Skip to content

Instantly share code, notes, and snippets.

@driskell
Last active March 3, 2022 22:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save driskell/da8c1c6c97a565cc01a623bbc07c79ff to your computer and use it in GitHub Desktop.
Save driskell/da8c1c6c97a565cc01a623bbc07c79ff to your computer and use it in GitHub Desktop.
<?php
/**
* Load a playlist's videos from the API, or return from the playlist if EXPLICIT
*
* @param \Drupal\brightcove\BrightcovePlaylistInterface<mixed> $entity
* @return array<\Drupal\brightcove\BrightcoveVideoInterface<mixed>>
*/
function load_brightcove_playlist_videos(\Drupal\brightcove\BrightcovePlaylistInterface $entity): array {
// Only perform API lookup for smart playlists - for others the display will render the explicitly linked videos
if ($entity->getType() === 'EXPLICIT') {
/** @var \Drupal\Core\Field\EntityReferenceFieldItemListInterface<mixed> $entityReference */
$entityReference = $entity->get('videos');
/** @var array<\Drupal\brightcove\BrightcoveVideoInterface<mixed>> $referencedEntities */
$referencedEntities = $entityReference->referencedEntities();
return $referencedEntities;
}
// Use the Brightcove API to grab the current set of videos on this playlist
/** @var string $apiClientId */
$apiClientId = $entity->get('api_client')->entity->id();
$playlistId = $entity->get('playlist_id')->value;
$cmsApi = \Drupal\brightcove\BrightcoveUtil::getCmsApi($apiClientId);
$videoIds = [];
foreach ($cmsApi->getVideosInPlaylist($playlistId) as $videoEntry) {
$videoIds[] = $videoEntry->getId();
}
// Lookup the Drupal video IDs using the brightcove IDs
$videoStorage = \Drupal::entityTypeManager()->getStorage('brightcove_video');
$drupalVideoIds = $videoStorage
->getQuery()
->condition('video_id', $videoIds, 'IN')
->execute();
if (empty($drupalVideoIds)) {
return [];
}
/** @var array<\Drupal\brightcove\BrightcoveVideoInterface<mixed>> $loadedEntities */
$loadedEntities = $videoStorage->loadMultiple($drupalVideoIds);
return $loadedEntities;
}
/**
* Download video list for SMART playlists and render in place of videos
*
* @param array $build
* @param array $context
* @return void
* @phpstan-ignore-next-line Ignore build and context iterable types as they are complex arrays
*/
function hook_entity_display_build_alter(array &$build, array $context): void {
/** @var \Drupal\brightcove\BrightcovePlaylistInterface<mixed> $entity */
$entity = $context['entity'];
if ($entity->getEntityTypeId() !== 'brightcove_playlist') {
return;
}
// Ignore if EXPLICIT as it means the videos are already referenced in the videos field and already rendered
if ($entity->getType() === 'EXPLICIT') {
return;
}
// Nothing needed if we are not rendering the videos field
/** @var \Drupal\Core\Entity\Display\EntityDisplayInterface $display */
$display = $context['display'];
$videosComponent = $display->getComponent('videos');
if (!$videosComponent) {
return;
}
// Add the cache tags to ensure that if ANY video change occurs, we rerender and generate the playlist
// This is similar to how we would do this when rendering any list in Drupal as any change to a video could change this playlist's output
$videoEntityType = \Drupal::entityTypeManager()->getDefinition('brightcove_video');
if (!$videoEntityType) {
throw new \RuntimeException('Unable to load brightcove_video entity type');
}
$build['#cache']['contexts'] = array_merge($build['#cache']['contexts'] ?? [], $videoEntityType->getListCacheContexts());
$build['#cache']['tags'] = array_merge($build['#cache']['tags'] ?? [], $videoEntityType->getListCacheTags());
// Clone the field list and add to it - this won't affect the source - and store in it the API loaded results
$items = clone $entity->get('videos');
$items->setValue(load_brightcove_playlist_videos($entity));
// Render the video reference list using the same field configuration
$viewBuilder = \Drupal::entityTypeManager()->getViewBuilder($entity->getEntityTypeId());
$build['videos'] = $viewBuilder->viewField($items, $videosComponent);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment