Last active
March 3, 2022 22:11
-
-
Save driskell/da8c1c6c97a565cc01a623bbc07c79ff to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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