229 lines
7.2 KiB
PHP
229 lines
7.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Entity\Repository;
|
|
|
|
use App\Entity;
|
|
use Carbon\CarbonImmutable;
|
|
use Carbon\CarbonInterface;
|
|
use Doctrine\ORM\Query;
|
|
use Doctrine\ORM\QueryBuilder;
|
|
|
|
/**
|
|
* @extends AbstractStationBasedRepository<Entity\StationQueue>
|
|
*/
|
|
final class StationQueueRepository extends AbstractStationBasedRepository
|
|
{
|
|
public function clearForMediaAndPlaylist(Entity\StationMedia $media, Entity\StationPlaylist $playlist): void
|
|
{
|
|
$this->em->createQuery(
|
|
<<<'DQL'
|
|
DELETE FROM App\Entity\StationQueue sq
|
|
WHERE sq.media = :media
|
|
AND sq.playlist = :playlist
|
|
AND sq.is_played = 0
|
|
DQL
|
|
)->setParameter('media', $media)
|
|
->setParameter('playlist', $playlist)
|
|
->execute();
|
|
}
|
|
|
|
public function getNextVisible(Entity\Station $station): ?Entity\StationQueue
|
|
{
|
|
return $this->getUnplayedBaseQuery($station)
|
|
->andWhere('sq.is_visible = 1')
|
|
->getQuery()
|
|
->setMaxResults(1)
|
|
->getOneOrNullResult();
|
|
}
|
|
|
|
public function trackPlayed(
|
|
Entity\Station $station,
|
|
Entity\StationQueue $row
|
|
): void {
|
|
$this->em->createQuery(
|
|
<<<'DQL'
|
|
UPDATE App\Entity\StationQueue sq
|
|
SET sq.timestamp_played = :timestamp
|
|
WHERE sq.station = :station
|
|
AND sq.id = :id
|
|
DQL
|
|
)->setParameter('timestamp', time())
|
|
->setParameter('station', $station)
|
|
->setParameter('id', $row->getIdRequired())
|
|
->execute();
|
|
|
|
$this->em->createQuery(
|
|
<<<'DQL'
|
|
UPDATE App\Entity\StationQueue sq
|
|
SET sq.is_played=1, sq.sent_to_autodj=1
|
|
WHERE sq.station = :station
|
|
AND sq.is_played = 0
|
|
AND (sq.id = :id OR sq.timestamp_cued < :cued)
|
|
DQL
|
|
)->setParameter('station', $station)
|
|
->setParameter('id', $row->getIdRequired())
|
|
->setParameter('cued', $row->getTimestampCued())
|
|
->execute();
|
|
}
|
|
|
|
public function isPlaylistRecentlyPlayed(
|
|
Entity\StationPlaylist $playlist,
|
|
?int $playPerSongs = null
|
|
): bool {
|
|
$playPerSongs ??= $playlist->getPlayPerSongs();
|
|
|
|
$recentPlayedQuery = $this->em->createQuery(
|
|
<<<'DQL'
|
|
SELECT sq.playlist_id
|
|
FROM App\Entity\StationQueue sq
|
|
WHERE sq.station = :station
|
|
AND sq.playlist_id IS NOT NULL
|
|
AND (sq.playlist = :playlist OR sq.is_visible = 1)
|
|
ORDER BY sq.id DESC
|
|
DQL
|
|
)->setParameters([
|
|
'station' => $playlist->getStation(),
|
|
'playlist' => $playlist,
|
|
])->setMaxResults($playPerSongs);
|
|
|
|
$recentPlayedPlaylists = $recentPlayedQuery->getSingleColumnResult();
|
|
return in_array($playlist->getIdRequired(), (array)$recentPlayedPlaylists, true);
|
|
}
|
|
|
|
/**
|
|
* @return mixed[]
|
|
*/
|
|
public function getRecentlyPlayedByTimeRange(
|
|
Entity\Station $station,
|
|
CarbonInterface $now,
|
|
int $minutes
|
|
): array {
|
|
$threshold = $now->subMinutes($minutes)->getTimestamp();
|
|
|
|
return $this->em->createQuery(
|
|
<<<'DQL'
|
|
SELECT sq.song_id, sq.timestamp_played, sq.title, sq.artist
|
|
FROM App\Entity\StationQueue sq
|
|
WHERE sq.station = :station
|
|
AND (sq.is_played = 0 OR sq.timestamp_played >= :threshold)
|
|
ORDER BY sq.timestamp_played DESC
|
|
DQL
|
|
)->setParameter('station', $station)
|
|
->setParameter('threshold', $threshold)
|
|
->getArrayResult();
|
|
}
|
|
|
|
/**
|
|
* @param Entity\Station $station
|
|
* @return Entity\StationQueue[]
|
|
*/
|
|
public function getUnplayedQueue(Entity\Station $station): array
|
|
{
|
|
return $this->getUnplayedQuery($station)->execute();
|
|
}
|
|
|
|
public function getUnplayedQuery(Entity\Station $station): Query
|
|
{
|
|
return $this->getUnplayedBaseQuery($station)->getQuery();
|
|
}
|
|
|
|
public function clearUpcomingQueue(Entity\Station $station): void
|
|
{
|
|
$this->em->createQuery(
|
|
<<<'DQL'
|
|
DELETE FROM App\Entity\StationQueue sq
|
|
WHERE sq.station = :station
|
|
AND sq.sent_to_autodj = 0
|
|
DQL
|
|
)->setParameter('station', $station)
|
|
->execute();
|
|
}
|
|
|
|
public function getNextToSendToAutoDj(Entity\Station $station): ?Entity\StationQueue
|
|
{
|
|
return $this->getBaseQuery($station)
|
|
->andWhere('sq.sent_to_autodj = 0')
|
|
->orderBy('sq.timestamp_cued', 'ASC')
|
|
->getQuery()
|
|
->setMaxResults(1)
|
|
->getOneOrNullResult();
|
|
}
|
|
|
|
public function findRecentlyCuedSong(
|
|
Entity\Station $station,
|
|
Entity\Interfaces\SongInterface $song
|
|
): ?Entity\StationQueue {
|
|
return $this->getUnplayedBaseQuery($station)
|
|
->andWhere('sq.sent_to_autodj = 1')
|
|
->andWhere('sq.song_id = :song_id')
|
|
->setParameter('song_id', $song->getSongId())
|
|
->getQuery()
|
|
->setMaxResults(1)
|
|
->getOneOrNullResult();
|
|
}
|
|
|
|
public function hasCuedPlaylistMedia(Entity\StationPlaylist $playlist): bool
|
|
{
|
|
$station = $playlist->getStation();
|
|
|
|
$cuedPlaylistContentCountQuery = $this->getUnplayedBaseQuery($station)
|
|
->select('count(sq.id)')
|
|
->andWhere('sq.playlist = :playlist')
|
|
->setParameter('playlist', $playlist)
|
|
->getQuery();
|
|
|
|
$cuedPlaylistContentCount = $cuedPlaylistContentCountQuery->getSingleScalarResult();
|
|
return $cuedPlaylistContentCount > 0;
|
|
}
|
|
|
|
private function getUnplayedBaseQuery(Entity\Station $station): QueryBuilder
|
|
{
|
|
return $this->getBaseQuery($station)
|
|
->andWhere('sq.is_played = 0')
|
|
->orderBy('sq.sent_to_autodj', 'DESC')
|
|
->addOrderBy('sq.timestamp_cued', 'ASC');
|
|
}
|
|
|
|
private function getBaseQuery(Entity\Station $station): QueryBuilder
|
|
{
|
|
return $this->em->createQueryBuilder()
|
|
->select('sq, sm, sp')
|
|
->from(Entity\StationQueue::class, 'sq')
|
|
->leftJoin('sq.media', 'sm')
|
|
->leftJoin('sq.playlist', 'sp')
|
|
->where('sq.station = :station')
|
|
->setParameter('station', $station);
|
|
}
|
|
|
|
public function clearUnplayed(?Entity\Station $station = null): void
|
|
{
|
|
$qb = $this->em->createQueryBuilder()
|
|
->delete(Entity\StationQueue::class, 'sq')
|
|
->where('sq.is_played = 0');
|
|
|
|
if (null !== $station) {
|
|
$qb->andWhere('sq.station = :station')
|
|
->setParameter('station', $station);
|
|
}
|
|
|
|
$qb->getQuery()->execute();
|
|
}
|
|
|
|
public function cleanup(int $daysToKeep): void
|
|
{
|
|
$threshold = CarbonImmutable::now()
|
|
->subDays($daysToKeep)
|
|
->getTimestamp();
|
|
|
|
$this->em->createQuery(
|
|
<<<'DQL'
|
|
DELETE FROM App\Entity\StationQueue sq
|
|
WHERE sq.timestamp_cued <= :threshold
|
|
DQL
|
|
)->setParameter('threshold', $threshold)
|
|
->execute();
|
|
}
|
|
}
|