2017-01-17 08:46:43 +00:00
|
|
|
<?php
|
2020-10-14 22:19:31 +00:00
|
|
|
|
2018-08-04 22:05:14 +00:00
|
|
|
namespace App\Entity\Repository;
|
2017-01-17 08:46:43 +00:00
|
|
|
|
2020-12-22 07:10:03 +00:00
|
|
|
use App\Doctrine\ReloadableEntityManagerInterface;
|
2020-03-29 07:16:41 +00:00
|
|
|
use App\Doctrine\Repository;
|
2019-08-07 04:33:55 +00:00
|
|
|
use App\Entity;
|
2020-12-03 04:18:06 +00:00
|
|
|
use App\Environment;
|
2018-08-04 22:05:14 +00:00
|
|
|
use App\Radio\Adapters;
|
|
|
|
use App\Radio\Configuration;
|
2018-12-27 08:24:07 +00:00
|
|
|
use App\Radio\Frontend\AbstractFrontend;
|
2019-09-04 18:00:51 +00:00
|
|
|
use App\Utilities;
|
|
|
|
use Closure;
|
|
|
|
use Exception;
|
2020-07-10 04:15:27 +00:00
|
|
|
use GuzzleHttp\Psr7\Uri;
|
|
|
|
use Psr\Http\Message\UriInterface;
|
2019-09-29 07:50:24 +00:00
|
|
|
use Psr\Log\LoggerInterface;
|
|
|
|
use Symfony\Component\Serializer\Serializer;
|
2019-04-09 09:06:44 +00:00
|
|
|
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
2017-01-17 08:46:43 +00:00
|
|
|
|
2018-11-12 16:59:15 +00:00
|
|
|
class StationRepository extends Repository
|
2017-01-17 08:46:43 +00:00
|
|
|
{
|
2019-09-29 07:50:24 +00:00
|
|
|
public function __construct(
|
2021-05-08 10:07:33 +00:00
|
|
|
protected SettingsRepository $settingsRepo,
|
|
|
|
protected StorageLocationRepository $storageLocationRepo,
|
|
|
|
protected LoggerInterface $logger,
|
|
|
|
protected Adapters $adapters,
|
|
|
|
protected Configuration $configuration,
|
|
|
|
protected ValidatorInterface $validator,
|
2020-12-22 07:10:03 +00:00
|
|
|
ReloadableEntityManagerInterface $em,
|
2019-09-29 07:50:24 +00:00
|
|
|
Serializer $serializer,
|
2020-12-04 08:41:55 +00:00
|
|
|
Environment $environment,
|
2019-09-29 07:50:24 +00:00
|
|
|
) {
|
2020-12-04 08:41:55 +00:00
|
|
|
parent::__construct($em, $serializer, $environment, $logger);
|
2019-09-29 07:50:24 +00:00
|
|
|
}
|
|
|
|
|
2019-09-19 02:31:13 +00:00
|
|
|
/**
|
|
|
|
* @param string $identifier A numeric or string identifier for a station.
|
|
|
|
*/
|
|
|
|
public function findByIdentifier(string $identifier): ?Entity\Station
|
|
|
|
{
|
|
|
|
return is_numeric($identifier)
|
2019-09-29 07:50:24 +00:00
|
|
|
? $this->repository->find($identifier)
|
|
|
|
: $this->repository->findOneBy(['short_name' => $identifier]);
|
2019-09-19 02:31:13 +00:00
|
|
|
}
|
|
|
|
|
2017-01-17 08:46:43 +00:00
|
|
|
/**
|
|
|
|
*/
|
2021-04-23 02:16:00 +00:00
|
|
|
public function fetchAll(): mixed
|
2017-01-17 08:46:43 +00:00
|
|
|
{
|
2020-12-02 00:36:09 +00:00
|
|
|
return $this->em->createQuery(
|
|
|
|
<<<'DQL'
|
|
|
|
SELECT s FROM App\Entity\Station s ORDER BY s.name ASC
|
|
|
|
DQL
|
|
|
|
)->execute();
|
2017-01-17 08:46:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-08-31 22:32:30 +00:00
|
|
|
* @param bool|string $add_blank
|
2019-09-04 18:00:51 +00:00
|
|
|
* @param Closure|NULL $display
|
2017-01-17 08:46:43 +00:00
|
|
|
* @param string $pk
|
|
|
|
* @param string $order_by
|
2019-09-20 16:44:38 +00:00
|
|
|
*
|
2020-10-14 22:19:31 +00:00
|
|
|
* @return mixed[]
|
2017-01-17 08:46:43 +00:00
|
|
|
*/
|
2019-09-29 07:50:24 +00:00
|
|
|
public function fetchSelect($add_blank = false, Closure $display = null, $pk = 'id', $order_by = 'name'): array
|
2017-01-17 08:46:43 +00:00
|
|
|
{
|
2017-01-24 00:35:16 +00:00
|
|
|
$select = [];
|
2017-01-17 08:46:43 +00:00
|
|
|
|
|
|
|
// Specify custom text in the $add_blank parameter to override.
|
2017-01-24 00:35:16 +00:00
|
|
|
if ($add_blank !== false) {
|
|
|
|
$select[''] = ($add_blank === true) ? 'Select...' : $add_blank;
|
|
|
|
}
|
2017-01-17 08:46:43 +00:00
|
|
|
|
|
|
|
// Build query for records.
|
|
|
|
// Assemble select values and, if necessary, call $display callback.
|
2021-06-08 06:40:49 +00:00
|
|
|
foreach ($this->fetchArray() as $result) {
|
2017-01-17 08:46:43 +00:00
|
|
|
$key = $result[$pk];
|
2021-06-08 06:40:49 +00:00
|
|
|
$select[$key] = ($display === null) ? $result['name'] : $display($result);
|
2017-01-17 08:46:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return $select;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-01-31 17:54:17 +00:00
|
|
|
* @param string $short_code
|
2017-01-17 08:46:43 +00:00
|
|
|
*/
|
2021-04-23 22:12:47 +00:00
|
|
|
public function findByShortCode(string $short_code): ?Entity\Station
|
2017-01-17 08:46:43 +00:00
|
|
|
{
|
2019-09-29 07:50:24 +00:00
|
|
|
return $this->repository->findOneBy(['short_name' => $short_code]);
|
2017-01-17 08:46:43 +00:00
|
|
|
}
|
|
|
|
|
2019-01-26 20:38:36 +00:00
|
|
|
/**
|
2020-11-10 03:06:48 +00:00
|
|
|
* @param Entity\Station $station
|
2019-01-26 20:38:36 +00:00
|
|
|
*/
|
2020-11-10 03:06:48 +00:00
|
|
|
public function edit(Entity\Station $station): Entity\Station
|
2019-01-26 20:38:36 +00:00
|
|
|
{
|
2020-11-10 03:06:48 +00:00
|
|
|
$original_record = $this->em->getUnitOfWork()->getOriginalEntityData($station);
|
|
|
|
|
2021-01-19 21:16:32 +00:00
|
|
|
$this->configuration->initializeConfiguration($station);
|
2020-11-10 03:06:48 +00:00
|
|
|
|
|
|
|
// Delete media-related items if the media storage is changed.
|
|
|
|
/** @var Entity\StorageLocation|null $oldMediaStorage */
|
|
|
|
$oldMediaStorage = $original_record['media_storage_location'];
|
|
|
|
$newMediaStorage = $station->getMediaStorageLocation();
|
|
|
|
|
|
|
|
if (null === $oldMediaStorage || $oldMediaStorage->getId() !== $newMediaStorage->getId()) {
|
|
|
|
$this->flushRelatedMedia($station);
|
|
|
|
}
|
2019-01-26 20:38:36 +00:00
|
|
|
|
2019-04-09 09:06:44 +00:00
|
|
|
// Get the original values to check for changes.
|
|
|
|
$old_frontend = $original_record['frontend_type'];
|
|
|
|
$old_backend = $original_record['backend_type'];
|
2019-01-26 20:38:36 +00:00
|
|
|
|
2020-11-10 03:06:48 +00:00
|
|
|
$frontend_changed = ($old_frontend !== $station->getFrontendType());
|
|
|
|
$backend_changed = ($old_backend !== $station->getBackendType());
|
2019-01-26 20:38:36 +00:00
|
|
|
$adapter_changed = $frontend_changed || $backend_changed;
|
|
|
|
|
|
|
|
if ($frontend_changed) {
|
2020-11-10 03:06:48 +00:00
|
|
|
$frontend = $this->adapters->getFrontendAdapter($station);
|
|
|
|
$this->resetMounts($station, $frontend);
|
2019-01-26 20:38:36 +00:00
|
|
|
}
|
|
|
|
|
2021-01-19 21:16:32 +00:00
|
|
|
if ($adapter_changed) {
|
|
|
|
$this->configuration->writeConfiguration($station, true);
|
|
|
|
}
|
2019-01-26 20:38:36 +00:00
|
|
|
|
2020-11-10 03:06:48 +00:00
|
|
|
return $station;
|
2019-01-26 20:38:36 +00:00
|
|
|
}
|
|
|
|
|
2019-09-04 18:00:51 +00:00
|
|
|
/**
|
|
|
|
* Reset mount points to their adapter defaults (in the event of an adapter change).
|
|
|
|
*
|
|
|
|
* @param Entity\Station $station
|
|
|
|
* @param AbstractFrontend $frontend_adapter
|
|
|
|
*/
|
|
|
|
public function resetMounts(Entity\Station $station, AbstractFrontend $frontend_adapter): void
|
|
|
|
{
|
|
|
|
foreach ($station->getMounts() as $mount) {
|
2019-09-29 07:50:24 +00:00
|
|
|
$this->em->remove($mount);
|
2019-09-04 18:00:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Create default mountpoints if station supports them.
|
2021-01-19 17:52:45 +00:00
|
|
|
if ($frontend_adapter->supportsMounts()) {
|
2019-09-04 18:00:51 +00:00
|
|
|
// Create default mount points.
|
2021-06-08 06:40:49 +00:00
|
|
|
foreach ($frontend_adapter->getDefaultMounts() as $mount_point) {
|
2019-09-04 18:00:51 +00:00
|
|
|
$mount_record = new Entity\StationMount($station);
|
|
|
|
$this->fromArray($mount_record, $mount_point);
|
|
|
|
|
2019-09-29 07:50:24 +00:00
|
|
|
$this->em->persist($mount_record);
|
2019-09-04 18:00:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-29 07:50:24 +00:00
|
|
|
$this->em->flush();
|
2020-10-16 09:22:06 +00:00
|
|
|
$this->em->refresh($station);
|
2019-09-04 18:00:51 +00:00
|
|
|
}
|
|
|
|
|
2020-11-10 03:06:48 +00:00
|
|
|
protected function flushRelatedMedia(Entity\Station $station): void
|
|
|
|
{
|
2020-12-02 00:36:09 +00:00
|
|
|
$this->em->createQuery(
|
|
|
|
<<<'DQL'
|
|
|
|
UPDATE App\Entity\SongHistory sh SET sh.media = null
|
|
|
|
WHERE sh.station = :station
|
|
|
|
DQL
|
|
|
|
)->setParameter('station', $station)
|
2020-11-10 03:06:48 +00:00
|
|
|
->execute();
|
|
|
|
|
2020-12-02 00:36:09 +00:00
|
|
|
$this->em->createQuery(
|
|
|
|
<<<'DQL'
|
|
|
|
DELETE FROM App\Entity\StationPlaylistMedia spm
|
|
|
|
WHERE spm.playlist_id IN (
|
|
|
|
SELECT sp.id FROM App\Entity\StationPlaylist sp WHERE sp.station = :station
|
|
|
|
)
|
|
|
|
DQL
|
|
|
|
)->setParameter('station', $station)
|
2020-11-10 03:06:48 +00:00
|
|
|
->execute();
|
|
|
|
|
2020-12-02 00:36:09 +00:00
|
|
|
$this->em->createQuery(
|
|
|
|
<<<'DQL'
|
|
|
|
DELETE FROM App\Entity\StationQueue sq WHERE sq.station = :station
|
|
|
|
DQL
|
|
|
|
)->setParameter('station', $station)
|
2020-11-10 03:06:48 +00:00
|
|
|
->execute();
|
|
|
|
|
2020-12-02 00:36:09 +00:00
|
|
|
$this->em->createQuery(
|
|
|
|
<<<'DQL'
|
|
|
|
DELETE FROM App\Entity\StationRequest sr WHERE sr.station = :station
|
|
|
|
DQL
|
|
|
|
)->setParameter('station', $station)
|
2020-11-10 03:06:48 +00:00
|
|
|
->execute();
|
|
|
|
}
|
|
|
|
|
2017-01-17 08:46:43 +00:00
|
|
|
/**
|
2019-04-09 09:06:44 +00:00
|
|
|
* Handle tasks necessary to a station's creation.
|
2017-01-17 08:46:43 +00:00
|
|
|
*
|
2019-04-09 09:06:44 +00:00
|
|
|
* @param Entity\Station $station
|
2017-01-17 08:46:43 +00:00
|
|
|
*/
|
2020-01-30 01:21:15 +00:00
|
|
|
public function create(Entity\Station $station): Entity\Station
|
2017-01-17 08:46:43 +00:00
|
|
|
{
|
2021-01-19 17:52:45 +00:00
|
|
|
$station->generateAdapterApiKey();
|
2020-01-30 00:22:21 +00:00
|
|
|
|
2021-05-08 10:07:33 +00:00
|
|
|
$this->configuration->initializeConfiguration($station);
|
2017-01-17 08:46:43 +00:00
|
|
|
|
|
|
|
// Create default mountpoints if station supports them.
|
2021-01-19 17:52:45 +00:00
|
|
|
$frontend_adapter = $this->adapters->getFrontendAdapter($station);
|
2018-02-01 11:49:40 +00:00
|
|
|
$this->resetMounts($station, $frontend_adapter);
|
2017-01-17 08:46:43 +00:00
|
|
|
|
2020-01-30 01:21:15 +00:00
|
|
|
return $station;
|
2017-01-17 08:46:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Entity\Station $station
|
2019-09-20 16:44:38 +00:00
|
|
|
*
|
2019-09-04 18:00:51 +00:00
|
|
|
* @throws Exception
|
2017-01-17 08:46:43 +00:00
|
|
|
*/
|
2019-01-26 20:38:36 +00:00
|
|
|
public function destroy(Entity\Station $station): void
|
2017-01-17 08:46:43 +00:00
|
|
|
{
|
2018-12-05 07:15:51 +00:00
|
|
|
$this->configuration->removeConfiguration($station);
|
2017-01-17 08:46:43 +00:00
|
|
|
|
|
|
|
// Remove media folders.
|
|
|
|
$radio_dir = $station->getRadioBaseDir();
|
2020-12-11 02:43:58 +00:00
|
|
|
Utilities\File::rmdirRecursive($radio_dir);
|
2017-01-17 08:46:43 +00:00
|
|
|
|
|
|
|
// Save changes and continue to the last setup step.
|
2020-06-25 18:44:26 +00:00
|
|
|
$this->em->flush();
|
2020-11-10 03:06:48 +00:00
|
|
|
|
2021-06-14 04:49:17 +00:00
|
|
|
foreach ($station->getAllStorageLocations() as $storageLocation) {
|
2020-11-10 03:06:48 +00:00
|
|
|
$stations = $this->storageLocationRepo->getStationsUsingLocation($storageLocation);
|
|
|
|
if (1 === count($stations)) {
|
|
|
|
$this->em->remove($storageLocation);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-29 07:50:24 +00:00
|
|
|
$this->em->remove($station);
|
2020-06-25 18:44:26 +00:00
|
|
|
$this->em->flush();
|
2019-01-26 20:38:36 +00:00
|
|
|
}
|
2020-04-01 06:01:32 +00:00
|
|
|
|
2020-07-10 04:15:27 +00:00
|
|
|
/**
|
|
|
|
* Return the URL to use for songs with no specified album artwork, when artwork is displayed.
|
|
|
|
*
|
|
|
|
* @param Entity\Station|null $station
|
|
|
|
*/
|
|
|
|
public function getDefaultAlbumArtUrl(?Entity\Station $station = null): UriInterface
|
|
|
|
{
|
2021-06-08 06:40:49 +00:00
|
|
|
if (null !== $station) {
|
2020-07-10 04:15:27 +00:00
|
|
|
$stationCustomUrl = trim($station->getDefaultAlbumArtUrl());
|
|
|
|
|
|
|
|
if (!empty($stationCustomUrl)) {
|
|
|
|
return new Uri($stationCustomUrl);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-10 22:46:03 +00:00
|
|
|
$settings = $this->settingsRepo->readSettings();
|
|
|
|
$custom_url = trim($settings->getDefaultAlbumArtUrl());
|
2020-07-10 04:15:27 +00:00
|
|
|
|
|
|
|
if (!empty($custom_url)) {
|
|
|
|
return new Uri($custom_url);
|
|
|
|
}
|
|
|
|
|
|
|
|
return new Uri('/static/img/generic_song.jpg');
|
|
|
|
}
|
2018-08-04 22:05:14 +00:00
|
|
|
}
|