tv-1.0.x-dev/src/Service/TvChannelService.php
src/Service/TvChannelService.php
<?php
namespace Drupal\tv\Service;
use DateTime;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\media\Entity\Media;
use Drupal\node\NodeInterface;
use Drupal\tv\Timestamp;
use Drupal\user\UserDataInterface;
class TvChannelService implements TvChannelServiceInterface {
private UserDataInterface $userData;
private AccountProxyInterface $user;
private ModuleHandlerInterface $moduleHandler;
public function __construct(AccountProxyInterface $user, UserDataInterface $userData) {
$this->user = $user;
$this->userData = $userData;
$this->moduleHandler = \Drupal::service('module_handler');
}
public function getItems(NodeInterface $node): array
{
$channelItems = [];
$channelTids = array_column($node->get('field_tags')->getValue(), 'target_id');
if (empty($channelTids)) {
return $channelItems;
}
// Select videos with having all the tags the channel has.
// @todo add support for `video` bundle: $bundles[] = 'video';
$bundles[] = 'remote_video';
$query = \Drupal::entityQuery('media')
->condition('bundle', $bundles, 'IN')
->condition('field_duration', 0, '>')
->condition('field_description', NULL, 'IS NOT NULL')
->condition('field_thumbnail', NULL, 'IS NOT NULL')
->condition('status', 1)
->sort('field_weight')
->sort('created', 'DESC')
->accessCheck();
// Each video must have all the tags the channel has.
foreach ($channelTids as $id) {
$query->condition($query->andConditionGroup()
->condition('field_tags', $id));
}
$mediaIds = $query->execute();
// @todo Move videos the user has watched to the end of the playlist.
// $completedVideoIds = $this->getCompletedVideoIds();
// Create the playlist.
foreach ($mediaIds as $mid) {
$video = Media::load($mid);
$url = $video->get('field_media_oembed_video')->first()->getValue()['value'];
$channelItems[] = [
'id' => $video->id(),
'name' => $video->getName(),
'url' => $url,
// @todo 'posterUrl' => $video->get('field_poster')->first()->getValue()['uri'],
'posterUrl' => $video->get('field_thumbnail')->first()->getValue()['uri'],
'thumbnailUrl' => $video->get('field_thumbnail')->first()->getValue()['uri'],
'createdDt' => (new DateTime())->setTimestamp($video->getCreatedTime())->format('c'),
'startedDt' => $this->getStartedDateTime($video)?->format('c'),
'startTs' => $this->getStartTimestamp($video),
'endTs' => $this->getEndTimestamp($video),
'duration' => $video->get('field_duration')->first()->getValue()['value'],
'progress' => 0,
];
}
// Allow other modules to modify the items.
$this->moduleHandler->alter('tv_channel_items', $channelItems, $node);
return $channelItems;
}
private function getStartedDateTime(Media $video): ?\DateTime
{
// @todo return when the user started watching the video.
return NULL;
}
private function getCompletedDateTime(Media $video): ?\DateTime
{
// @todo return when the user completed watching the video.
return NULL;
}
private function getStartTimestamp(Media $video): ?string
{
// @todo return the timestamp where the video should start.
return new Timestamp();
}
private function getEndTimestamp(Media $video): ?string
{
// @todo return the timestamp where the video should end.
return NULL;
}
private function getCompletedVideoIds(): array
{
// @todo return the ids of the videos the user has completed.
// $uid = $this->user->id();
// $userData->set('tv', $uid, 'history', []);
// $history = $userData->get('tv', $uid, 'history') ?? [];
return [];
}
public function getAutoPlayPreference(): bool
{
return $this->userData->get('tv', $this->user->id(), 'autoplay') ?? FALSE;
}
public function getMutePreference(): bool
{
return $this->userData->get('tv', $this->user->id(), 'mute') ?? TRUE;
}
}
