Settings overhaul, part 2
Make Settings a controlled entity.
This commit is contained in:
parent
5727f12b6f
commit
aed854a17c
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
use App\Entity;
|
||||
|
||||
return [
|
||||
'groups' => [
|
||||
|
||||
|
@ -10,7 +8,7 @@ return [
|
|||
|
||||
'elements' => [
|
||||
|
||||
Entity\Settings::BACKUP_ENABLED => [
|
||||
'backupEnabled' => [
|
||||
'toggle',
|
||||
[
|
||||
'label' => __('Run Automatic Nightly Backups'),
|
||||
|
@ -22,7 +20,7 @@ return [
|
|||
],
|
||||
],
|
||||
|
||||
Entity\Settings::BACKUP_TIME => [
|
||||
'backupTimeCode' => [
|
||||
'PlaylistTime',
|
||||
[
|
||||
'label' => __('Scheduled Backup Time'),
|
||||
|
@ -31,7 +29,7 @@ return [
|
|||
],
|
||||
],
|
||||
|
||||
Entity\Settings::BACKUP_EXCLUDE_MEDIA => [
|
||||
'backupExcludeMedia' => [
|
||||
'toggle',
|
||||
[
|
||||
'label' => __('Exclude Media from Backups'),
|
||||
|
@ -43,7 +41,7 @@ return [
|
|||
],
|
||||
],
|
||||
|
||||
Entity\Settings::BACKUP_KEEP_COPIES => [
|
||||
'backupKeepCopies' => [
|
||||
'number',
|
||||
[
|
||||
'label' => __('Number of Backup Copies to Keep'),
|
||||
|
@ -55,7 +53,7 @@ return [
|
|||
],
|
||||
],
|
||||
|
||||
Entity\Settings::BACKUP_STORAGE_LOCATION => [
|
||||
'backupStorageLocation' => [
|
||||
'select',
|
||||
[
|
||||
'label' => __('Storage Location'),
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
use App\Entity;
|
||||
|
||||
return [
|
||||
'method' => 'post',
|
||||
|
||||
|
@ -10,7 +8,7 @@ return [
|
|||
'use_grid' => true,
|
||||
'elements' => [
|
||||
|
||||
Entity\Settings::PUBLIC_THEME => [
|
||||
'publicTheme' => [
|
||||
'radio',
|
||||
[
|
||||
'label' => __('Base Theme for Public Pages'),
|
||||
|
@ -24,7 +22,7 @@ return [
|
|||
],
|
||||
],
|
||||
|
||||
Entity\Settings::HIDE_ALBUM_ART => [
|
||||
'hideAlbumArt' => [
|
||||
'toggle',
|
||||
[
|
||||
'label' => __('Hide Album Art on Public Pages'),
|
||||
|
@ -36,7 +34,7 @@ return [
|
|||
],
|
||||
],
|
||||
|
||||
Entity\Settings::HOMEPAGE_REDIRECT_URL => [
|
||||
'homepageRedirectUrl' => [
|
||||
'text',
|
||||
[
|
||||
'label' => __('Homepage Redirect URL'),
|
||||
|
@ -46,7 +44,7 @@ return [
|
|||
],
|
||||
],
|
||||
|
||||
Entity\Settings::DEFAULT_ALBUM_ART_URL => [
|
||||
'defaultAlbumArtUrl' => [
|
||||
'text',
|
||||
[
|
||||
'label' => __('Default Album Art URL'),
|
||||
|
@ -56,7 +54,7 @@ return [
|
|||
],
|
||||
],
|
||||
|
||||
Entity\Settings::HIDE_PRODUCT_NAME => [
|
||||
'hideProductName' => [
|
||||
'toggle',
|
||||
[
|
||||
'label' => __('Hide AzuraCast Branding on Public Pages'),
|
||||
|
@ -68,7 +66,7 @@ return [
|
|||
],
|
||||
],
|
||||
|
||||
Entity\Settings::CUSTOM_CSS_PUBLIC => [
|
||||
'publicCustomCss' => [
|
||||
'textarea',
|
||||
[
|
||||
'label' => __('Custom CSS for Public Pages'),
|
||||
|
@ -82,7 +80,7 @@ return [
|
|||
],
|
||||
],
|
||||
|
||||
Entity\Settings::CUSTOM_JS_PUBLIC => [
|
||||
'publicCustomJs' => [
|
||||
'textarea',
|
||||
[
|
||||
'label' => __('Custom JS for Public Pages'),
|
||||
|
@ -96,7 +94,7 @@ return [
|
|||
],
|
||||
],
|
||||
|
||||
Entity\Settings::CUSTOM_CSS_INTERNAL => [
|
||||
'internalCustomCss' => [
|
||||
'textarea',
|
||||
[
|
||||
'label' => __('Custom CSS for Internal Pages'),
|
||||
|
|
|
@ -20,7 +20,7 @@ return [
|
|||
],
|
||||
],
|
||||
|
||||
App\Entity\Settings::GEOLITE_LICENSE_KEY => [
|
||||
'geoliteLicenseKey' => [
|
||||
'text',
|
||||
[
|
||||
'label' => __('MaxMind License Key'),
|
||||
|
|
|
@ -28,7 +28,7 @@ return [
|
|||
'tab' => 'system',
|
||||
|
||||
'elements' => [
|
||||
Entity\Settings::BASE_URL => [
|
||||
'baseUrl' => [
|
||||
'url',
|
||||
[
|
||||
'label' => __('Site Base URL'),
|
||||
|
@ -38,7 +38,7 @@ return [
|
|||
],
|
||||
],
|
||||
|
||||
Entity\Settings::INSTANCE_NAME => [
|
||||
'instanceName' => [
|
||||
'text',
|
||||
[
|
||||
'label' => __('AzuraCast Instance Name'),
|
||||
|
@ -47,7 +47,7 @@ return [
|
|||
],
|
||||
],
|
||||
|
||||
Entity\Settings::PREFER_BROWSER_URL => [
|
||||
'preferBrowserUrl' => [
|
||||
'toggle',
|
||||
[
|
||||
'label' => __('Prefer Browser URL (If Available)'),
|
||||
|
@ -59,7 +59,7 @@ return [
|
|||
],
|
||||
],
|
||||
|
||||
Entity\Settings::USE_RADIO_PROXY => [
|
||||
'useRadioProxy' => [
|
||||
'toggle',
|
||||
[
|
||||
'label' => __('Use Web Proxy for Radio'),
|
||||
|
@ -71,7 +71,7 @@ return [
|
|||
],
|
||||
],
|
||||
|
||||
Entity\Settings::HISTORY_KEEP_DAYS => [
|
||||
'historyKeepDays' => [
|
||||
'radio',
|
||||
[
|
||||
'label' => __('Days of Playback History to Keep'),
|
||||
|
@ -84,12 +84,12 @@ return [
|
|||
730 => __('Last 2 Years'),
|
||||
0 => __('Indefinitely'),
|
||||
],
|
||||
'default' => \App\Entity\SongHistory::DEFAULT_DAYS_TO_KEEP,
|
||||
'default' => App\Entity\SongHistory::DEFAULT_DAYS_TO_KEEP,
|
||||
'form_group_class' => 'col-sm-6',
|
||||
],
|
||||
],
|
||||
|
||||
Entity\Settings::NOWPLAYING_USE_WEBSOCKETS => [
|
||||
'enableWebsockets' => [
|
||||
'toggle',
|
||||
[
|
||||
'label' => __('Use WebSockets for Now Playing Updates'),
|
||||
|
@ -110,7 +110,7 @@ return [
|
|||
|
||||
'elements' => [
|
||||
|
||||
Entity\Settings::ALWAYS_USE_SSL => [
|
||||
'alwaysUseSsl' => [
|
||||
'toggle',
|
||||
[
|
||||
'label' => __('Always Use HTTPS'),
|
||||
|
@ -122,7 +122,7 @@ return [
|
|||
],
|
||||
],
|
||||
|
||||
Entity\Settings::API_ACCESS_CONTROL => [
|
||||
'apiAccessControl' => [
|
||||
'text',
|
||||
[
|
||||
'label' => __('API "Access-Control-Allow-Origin" header'),
|
||||
|
@ -141,7 +141,7 @@ return [
|
|||
'tab' => 'privacy',
|
||||
'elements' => [
|
||||
|
||||
Entity\Settings::LISTENER_ANALYTICS => [
|
||||
'analytics' => [
|
||||
'radio',
|
||||
[
|
||||
'label' => __('Listener Analytics Collection'),
|
||||
|
@ -174,7 +174,7 @@ return [
|
|||
],
|
||||
],
|
||||
|
||||
Entity\Settings::CENTRAL_UPDATES => [
|
||||
'checkForUpdates' => [
|
||||
'toggle',
|
||||
[
|
||||
'label' => __('Show Update Announcements'),
|
||||
|
|
|
@ -11,12 +11,12 @@ return [
|
|||
|
||||
// URL Router helper
|
||||
App\Http\Router::class => function (
|
||||
Environment $settings,
|
||||
Environment $environment,
|
||||
Slim\App $app,
|
||||
App\Entity\Repository\SettingsRepository $settingsRepo
|
||||
App\Entity\Settings $settings
|
||||
) {
|
||||
$route_parser = $app->getRouteCollector()->getRouteParser();
|
||||
return new App\Http\Router($settings, $route_parser, $settingsRepo);
|
||||
return new App\Http\Router($environment, $route_parser, $settings);
|
||||
},
|
||||
App\Http\RouterInterface::class => DI\Get(App\Http\Router::class),
|
||||
|
||||
|
@ -139,6 +139,11 @@ return [
|
|||
},
|
||||
Doctrine\ORM\EntityManagerInterface::class => DI\Get(App\Doctrine\DecoratedEntityManager::class),
|
||||
|
||||
// Database settings
|
||||
App\Entity\Settings::class => function (App\Entity\Repository\SettingsTableRepository $settingsTableRepo) {
|
||||
return $settingsTableRepo->readSettings(true);
|
||||
},
|
||||
|
||||
// Redis cache
|
||||
Redis::class => function (Environment $environment) {
|
||||
$redis_host = $environment->isDocker() ? 'redis' : 'localhost';
|
||||
|
|
|
@ -8,9 +8,9 @@ class Config
|
|||
{
|
||||
protected string $baseFolder;
|
||||
|
||||
public function __construct(Environment $settings)
|
||||
public function __construct(Environment $environment)
|
||||
{
|
||||
$this->baseFolder = $settings->getConfigDirectory();
|
||||
$this->baseFolder = $environment->getConfigDirectory();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
namespace App\Console\Command\Internal;
|
||||
|
||||
use App\Console\Command\CommandAbstract;
|
||||
use App\Entity;
|
||||
use App\Service\AzuraCastCentral;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
|
@ -11,7 +10,6 @@ class GetIpCommand extends CommandAbstract
|
|||
{
|
||||
public function __invoke(
|
||||
SymfonyStyle $io,
|
||||
Entity\Repository\SettingsRepository $settings_repo,
|
||||
AzuraCastCentral $acCentral
|
||||
): int {
|
||||
$io->write($acCentral->getIp());
|
||||
|
|
|
@ -11,7 +11,7 @@ class ListCommand extends CommandAbstract
|
|||
{
|
||||
public function __invoke(
|
||||
SymfonyStyle $io,
|
||||
Entity\Repository\SettingsRepository $settings_repo
|
||||
Entity\Repository\SettingsTableRepository $settingsTableRepo
|
||||
): int {
|
||||
$io->title(__('AzuraCast Settings'));
|
||||
|
||||
|
@ -21,7 +21,7 @@ class ListCommand extends CommandAbstract
|
|||
];
|
||||
$rows = [];
|
||||
|
||||
$all_settings = $settings_repo->fetchAll();
|
||||
$all_settings = $settingsTableRepo->readSettingsArray(false);
|
||||
foreach ($all_settings as $setting_key => $setting_value) {
|
||||
$value = print_r($setting_value, true);
|
||||
$value = Utilities::truncateText($value, 600);
|
||||
|
|
|
@ -10,14 +10,14 @@ class SetCommand extends CommandAbstract
|
|||
{
|
||||
public function __invoke(
|
||||
SymfonyStyle $io,
|
||||
Entity\Repository\SettingsRepository $settings_repo,
|
||||
Entity\Repository\SettingsTableRepository $settingsTableRepo,
|
||||
string $settingKey,
|
||||
string $settingValue
|
||||
): int {
|
||||
$io->title('AzuraCast Settings');
|
||||
|
||||
if (strtolower($settingValue) === 'null') {
|
||||
$settings_repo->deleteSetting($settingKey);
|
||||
$settingsTableRepo->writeSettings([$settingKey => null]);
|
||||
|
||||
$io->success(sprintf('Setting "%s" removed.', $settingKey));
|
||||
return 0;
|
||||
|
@ -27,7 +27,7 @@ class SetCommand extends CommandAbstract
|
|||
$settingValue = json_decode($settingValue, true, 512, JSON_THROW_ON_ERROR);
|
||||
}
|
||||
|
||||
$settings_repo->setSetting($settingKey, $settingValue);
|
||||
$settingsTableRepo->writeSettings([$settingKey => $settingValue]);
|
||||
|
||||
$io->success(sprintf('Setting "%s" updated.', $settingKey));
|
||||
|
||||
|
|
|
@ -17,7 +17,8 @@ class SetupCommand extends CommandAbstract
|
|||
OutputInterface $output,
|
||||
Environment $environment,
|
||||
ContainerInterface $di,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
Entity\Settings $settings,
|
||||
Entity\Repository\SettingsTableRepository $settingsTableRepo,
|
||||
Entity\Repository\StationRepository $stationRepo,
|
||||
AzuraCastCentral $acCentral,
|
||||
bool $update = false,
|
||||
|
@ -73,7 +74,7 @@ class SetupCommand extends CommandAbstract
|
|||
|
||||
$this->runCommand($output, 'queue:clear');
|
||||
|
||||
$settingsRepo->deleteSetting(Entity\Settings::NOWPLAYING);
|
||||
$settings->setNowplaying(null);
|
||||
$stationRepo->clearNowPlaying();
|
||||
|
||||
$io->newLine();
|
||||
|
@ -83,10 +84,14 @@ class SetupCommand extends CommandAbstract
|
|||
$this->runCommand($output, 'azuracast:radio:restart');
|
||||
|
||||
// Clear settings that should be reset upon update.
|
||||
$settingsRepo->setSetting(Entity\Settings::UPDATE_LAST_RUN, time());
|
||||
$settingsRepo->deleteSetting(Entity\Settings::UPDATE_RESULTS);
|
||||
$settingsRepo->deleteSetting(Entity\Settings::UNIQUE_IDENTIFIER);
|
||||
$settingsRepo->deleteSetting(Entity\Settings::EXTERNAL_IP);
|
||||
$settings->updateUpdateLastRun();
|
||||
$settings->setUpdateResults(null);
|
||||
$settings->setExternalIp(null);
|
||||
if (!$update) {
|
||||
$settings->setAppUniqueIdentifier(null);
|
||||
}
|
||||
|
||||
$settingsTableRepo->writeSettings($settings);
|
||||
|
||||
$io->newLine();
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ namespace App\Controller\Admin;
|
|||
|
||||
use App\Config;
|
||||
use App\Controller\AbstractLogViewerController;
|
||||
use App\Entity\Repository\SettingsRepository;
|
||||
use App\Entity\Repository\StorageLocationRepository;
|
||||
use App\Entity\Settings;
|
||||
use App\Entity\StorageLocation;
|
||||
|
@ -22,7 +21,7 @@ use Symfony\Component\Messenger\MessageBus;
|
|||
|
||||
class BackupsController extends AbstractLogViewerController
|
||||
{
|
||||
protected SettingsRepository $settingsRepo;
|
||||
protected Settings $settings;
|
||||
|
||||
protected StorageLocationRepository $storageLocationRepo;
|
||||
|
||||
|
@ -33,14 +32,14 @@ class BackupsController extends AbstractLogViewerController
|
|||
protected string $csrfNamespace = 'admin_backups';
|
||||
|
||||
public function __construct(
|
||||
SettingsRepository $settings_repo,
|
||||
StorageLocationRepository $storageLocationRepo,
|
||||
Settings $settings,
|
||||
RunBackupTask $backup_task,
|
||||
MessageBus $messageBus
|
||||
) {
|
||||
$this->settingsRepo = $settings_repo;
|
||||
$this->storageLocationRepo = $storageLocationRepo;
|
||||
|
||||
$this->settings = $settings;
|
||||
$this->backupTask = $backup_task;
|
||||
$this->messageBus = $messageBus;
|
||||
}
|
||||
|
@ -60,10 +59,10 @@ class BackupsController extends AbstractLogViewerController
|
|||
|
||||
return $request->getView()->renderToResponse($response, 'admin/backups/index', [
|
||||
'backups' => $backups,
|
||||
'is_enabled' => (bool)$this->settingsRepo->getSetting(Settings::BACKUP_ENABLED, false),
|
||||
'last_run' => $this->settingsRepo->getSetting(Settings::BACKUP_LAST_RUN, 0),
|
||||
'last_result' => $this->settingsRepo->getSetting(Settings::BACKUP_LAST_RESULT, 0),
|
||||
'last_output' => $this->settingsRepo->getSetting(Settings::BACKUP_LAST_OUTPUT, ''),
|
||||
'is_enabled' => $this->settings->isBackupEnabled(),
|
||||
'last_run' => $this->settings->getBackupLastRun(),
|
||||
'last_result' => $this->settings->getBackupLastResult(),
|
||||
'last_output' => $this->settings->getBackupLastOutput(),
|
||||
'csrf' => $request->getCsrf()->generate($this->csrfNamespace),
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace App\Controller\Admin;
|
||||
|
||||
use App\Entity\Repository\SettingsRepository;
|
||||
use App\Entity\Repository\SettingsTableRepository;
|
||||
use App\Entity\Settings;
|
||||
use App\Form\GeoLiteSettingsForm;
|
||||
use App\Http\Response;
|
||||
|
@ -52,12 +52,14 @@ class InstallGeoLiteController
|
|||
public function uninstallAction(
|
||||
ServerRequest $request,
|
||||
Response $response,
|
||||
SettingsRepository $settingsRepo,
|
||||
Settings $settings,
|
||||
SettingsTableRepository $settingsTableRepo,
|
||||
$csrf
|
||||
): ResponseInterface {
|
||||
$request->getCsrf()->verify($csrf, $this->csrf_namespace);
|
||||
|
||||
$settingsRepo->setSetting(Settings::GEOLITE_LICENSE_KEY, '');
|
||||
$settings->setGeoliteLicenseKey(null);
|
||||
$settingsTableRepo->writeSettings($settings);
|
||||
|
||||
@unlink(GeoLite::getDatabasePath());
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ use App\Http\ServerRequest;
|
|||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use OpenApi\Annotations as OA;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
||||
use Symfony\Component\Serializer\Serializer;
|
||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||
|
||||
|
@ -21,13 +20,14 @@ class SettingsController
|
|||
|
||||
protected ValidatorInterface $validator;
|
||||
|
||||
protected Entity\Repository\SettingsRepository $settings_repo;
|
||||
protected Entity\Repository\SettingsTableRepository $settingsTableRepo;
|
||||
|
||||
protected Entity\Api\Admin\Settings $api_settings;
|
||||
protected Entity\Settings $settings;
|
||||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Entity\Repository\SettingsRepository $settings_repo,
|
||||
Entity\Repository\SettingsTableRepository $settingsTableRepo,
|
||||
Entity\Settings $settings,
|
||||
Serializer $serializer,
|
||||
ValidatorInterface $validator
|
||||
) {
|
||||
|
@ -35,12 +35,8 @@ class SettingsController
|
|||
$this->serializer = $serializer;
|
||||
$this->validator = $validator;
|
||||
|
||||
$this->settings_repo = $settings_repo;
|
||||
$all_settings = $settings_repo->fetchAll();
|
||||
|
||||
/** @var Entity\Api\Admin\Settings $api_settings */
|
||||
$api_settings = $this->serializer->denormalize($all_settings, Entity\Api\Admin\Settings::class);
|
||||
$this->api_settings = $api_settings;
|
||||
$this->settingsTableRepo = $settingsTableRepo;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -48,7 +44,7 @@ class SettingsController
|
|||
* tags={"Administration: Settings"},
|
||||
* description="List the current values of all editable system settings.",
|
||||
* @OA\Response(response=200, description="Success",
|
||||
* @OA\JsonContent(ref="#/components/schemas/Api_Admin_Settings")
|
||||
* @OA\JsonContent(ref="#/components/schemas/Settings")
|
||||
* ),
|
||||
* @OA\Response(response=403, description="Access denied"),
|
||||
* security={{"api_key": {}}},
|
||||
|
@ -59,7 +55,7 @@ class SettingsController
|
|||
*/
|
||||
public function listAction(ServerRequest $request, Response $response): ResponseInterface
|
||||
{
|
||||
return $response->withJson($this->api_settings);
|
||||
return $response->withJson($this->serializer->normalize($this->settings, null));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -67,7 +63,7 @@ class SettingsController
|
|||
* tags={"Administration: Settings"},
|
||||
* description="Update settings to modify any settings provided.",
|
||||
* @OA\RequestBody(
|
||||
* @OA\JsonContent(ref="#/components/schemas/Api_Admin_Settings")
|
||||
* @OA\JsonContent(ref="#/components/schemas/Settings")
|
||||
* ),
|
||||
* @OA\Response(response=200, description="Success",
|
||||
* @OA\JsonContent(ref="#/components/schemas/Api_Status")
|
||||
|
@ -83,23 +79,7 @@ class SettingsController
|
|||
*/
|
||||
public function updateAction(ServerRequest $request, Response $response): ResponseInterface
|
||||
{
|
||||
$api_settings_obj = $this->serializer->denormalize(
|
||||
$request->getParsedBody(),
|
||||
Entity\Api\Admin\Settings::class,
|
||||
null,
|
||||
[
|
||||
AbstractNormalizer::OBJECT_TO_POPULATE => $this->api_settings,
|
||||
]
|
||||
);
|
||||
|
||||
$errors = $this->validator->validate($api_settings_obj);
|
||||
if (count($errors) > 0) {
|
||||
throw new ValidationException((string)$errors);
|
||||
}
|
||||
|
||||
$api_settings = $this->serializer->normalize($api_settings_obj);
|
||||
|
||||
$this->settings_repo->setSettings($api_settings);
|
||||
$this->settingsTableRepo->writeSettings($request->getParsedBody());
|
||||
|
||||
return $response->withJson(new Entity\Api\Status());
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ class NowplayingController implements EventSubscriberInterface
|
|||
{
|
||||
protected EntityManagerInterface $em;
|
||||
|
||||
protected Entity\Repository\SettingsRepository $settingsRepo;
|
||||
protected Entity\Settings $settings;
|
||||
|
||||
protected CacheInterface $cache;
|
||||
|
||||
|
@ -25,12 +25,12 @@ class NowplayingController implements EventSubscriberInterface
|
|||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
Entity\Settings $settings,
|
||||
CacheInterface $cache,
|
||||
EventDispatcher $dispatcher
|
||||
) {
|
||||
$this->em = $em;
|
||||
$this->settingsRepo = $settingsRepo;
|
||||
$this->settings = $settings;
|
||||
$this->cache = $cache;
|
||||
$this->dispatcher = $dispatcher;
|
||||
}
|
||||
|
@ -140,12 +140,12 @@ class NowplayingController implements EventSubscriberInterface
|
|||
|
||||
public function loadFromCache(LoadNowPlaying $event): void
|
||||
{
|
||||
$event->setNowPlaying((array)$this->cache->get(Entity\Settings::NOWPLAYING), 'redis');
|
||||
$event->setNowPlaying((array)$this->cache->get('nowplaying'), 'redis');
|
||||
}
|
||||
|
||||
public function loadFromSettings(LoadNowPlaying $event): void
|
||||
{
|
||||
$event->setNowPlaying((array)$this->settingsRepo->getSetting(Entity\Settings::NOWPLAYING), 'settings');
|
||||
$event->setNowPlaying((array)$this->settings->getNowplaying(), 'settings');
|
||||
}
|
||||
|
||||
public function loadFromStations(LoadNowPlaying $event): void
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace App\Controller\Frontend\Account;
|
||||
|
||||
use App\Entity\Repository\SettingsRepository;
|
||||
use App\Entity\Settings;
|
||||
use App\Entity\User;
|
||||
use App\Exception\RateLimitExceededException;
|
||||
|
@ -21,13 +20,13 @@ class LoginAction
|
|||
Response $response,
|
||||
EntityManagerInterface $em,
|
||||
RateLimit $rateLimit,
|
||||
SettingsRepository $settingsRepo
|
||||
Settings $settings
|
||||
): ResponseInterface {
|
||||
$auth = $request->getAuth();
|
||||
$acl = $request->getAcl();
|
||||
|
||||
// Check installation completion progress.
|
||||
if ($settingsRepo->getSetting(Settings::SETUP_COMPLETE, 0) === 0) {
|
||||
if (!$settings->isSetupComplete()) {
|
||||
$num_users = (int)$em->createQuery(
|
||||
<<<'DQL'
|
||||
SELECT COUNT(u.id) FROM App\Entity\User u
|
||||
|
@ -84,7 +83,7 @@ class LoginAction
|
|||
}
|
||||
|
||||
// Redirect to complete setup if it's not completed yet.
|
||||
if ($settingsRepo->getSetting(Settings::SETUP_COMPLETE, 0) === 0) {
|
||||
if (!$settings->isSetupComplete()) {
|
||||
$flash->addMessage(
|
||||
sprintf(
|
||||
'<b>%s</b><br>%s',
|
||||
|
|
|
@ -19,7 +19,7 @@ class DashboardController
|
|||
{
|
||||
protected EntityManagerInterface $em;
|
||||
|
||||
protected Entity\Repository\SettingsRepository $settingsRepo;
|
||||
protected Entity\Settings $settings;
|
||||
|
||||
protected Acl $acl;
|
||||
|
||||
|
@ -33,15 +33,15 @@ class DashboardController
|
|||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
Acl $acl,
|
||||
Entity\Settings $settings,
|
||||
CacheInterface $cache,
|
||||
Adapters $adapter_manager,
|
||||
EventDispatcher $dispatcher
|
||||
) {
|
||||
$this->em = $em;
|
||||
$this->settingsRepo = $settingsRepo;
|
||||
$this->acl = $acl;
|
||||
$this->settings = $settings;
|
||||
$this->cache = $cache;
|
||||
$this->adapter_manager = $adapter_manager;
|
||||
$this->dispatcher = $dispatcher;
|
||||
|
@ -116,10 +116,7 @@ class DashboardController
|
|||
}
|
||||
|
||||
// Detect current analytics level.
|
||||
$analytics_level = $this->settingsRepo->getSetting(
|
||||
Entity\Settings::LISTENER_ANALYTICS,
|
||||
Entity\Analytics::LEVEL_ALL
|
||||
);
|
||||
$analytics_level = $this->settings->getAnalytics();
|
||||
|
||||
if ($analytics_level === Entity\Analytics::LEVEL_NONE) {
|
||||
$metrics = null;
|
||||
|
|
|
@ -9,17 +9,13 @@ use Psr\Http\Message\ResponseInterface;
|
|||
|
||||
class IndexController
|
||||
{
|
||||
protected Entity\Repository\SettingsRepository $settings_repo;
|
||||
|
||||
public function __construct(Entity\Repository\SettingsRepository $settings_repo)
|
||||
{
|
||||
$this->settings_repo = $settings_repo;
|
||||
}
|
||||
|
||||
public function indexAction(ServerRequest $request, Response $response): ResponseInterface
|
||||
{
|
||||
public function indexAction(
|
||||
ServerRequest $request,
|
||||
Response $response,
|
||||
Entity\Settings $settings
|
||||
): ResponseInterface {
|
||||
// Redirect to complete setup, if it hasn't been completed yet.
|
||||
if ($this->settings_repo->getSetting(Entity\Settings::SETUP_COMPLETE, 0) === 0) {
|
||||
if (!$settings->isSetupComplete()) {
|
||||
return $response->withRedirect($request->getRouter()->named('setup:index'));
|
||||
}
|
||||
|
||||
|
@ -28,7 +24,7 @@ class IndexController
|
|||
|
||||
if (!($user instanceof Entity\User)) {
|
||||
// Redirect to a custom homepage URL if specified in settings.
|
||||
$homepage_redirect = trim($this->settings_repo->getSetting(Entity\Settings::HOMEPAGE_REDIRECT_URL));
|
||||
$homepage_redirect = trim($settings->getHomepageRedirectUrl());
|
||||
|
||||
if (!empty($homepage_redirect)) {
|
||||
return $response->withRedirect($homepage_redirect, 302);
|
||||
|
|
|
@ -17,17 +17,21 @@ class SetupController
|
|||
{
|
||||
protected EntityManagerInterface $em;
|
||||
|
||||
protected Entity\Repository\SettingsRepository $settingsRepo;
|
||||
protected Entity\Settings $settings;
|
||||
|
||||
protected Environment $settings;
|
||||
protected Entity\Repository\SettingsTableRepository $settingsTableRepo;
|
||||
|
||||
protected Environment $environment;
|
||||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Entity\Repository\SettingsRepository $settingsRepository,
|
||||
Environment $settings
|
||||
Entity\Repository\SettingsTableRepository $settingsRepository,
|
||||
Environment $environment,
|
||||
Entity\Settings $settings
|
||||
) {
|
||||
$this->em = $em;
|
||||
$this->settingsRepo = $settingsRepository;
|
||||
$this->settingsTableRepo = $settingsRepository;
|
||||
$this->environment = $environment;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
|
@ -50,7 +54,7 @@ class SetupController
|
|||
*/
|
||||
protected function getSetupStep(ServerRequest $request): string
|
||||
{
|
||||
if (0 !== (int)$this->settingsRepo->getSetting(Entity\Settings::SETUP_COMPLETE, 0)) {
|
||||
if ($this->settings->isSetupComplete()) {
|
||||
return 'complete';
|
||||
}
|
||||
|
||||
|
@ -110,7 +114,7 @@ class SetupController
|
|||
{
|
||||
// Verify current step.
|
||||
$current_step = $this->getSetupStep($request);
|
||||
if ($current_step !== 'register' && $this->settings->isProduction()) {
|
||||
if ($current_step !== 'register' && $this->environment->isProduction()) {
|
||||
return $response->withRedirect($request->getRouter()->named('setup:' . $current_step));
|
||||
}
|
||||
|
||||
|
@ -170,7 +174,7 @@ class SetupController
|
|||
): ResponseInterface {
|
||||
// Verify current step.
|
||||
$current_step = $this->getSetupStep($request);
|
||||
if ($current_step !== 'station' && $this->settings->isProduction()) {
|
||||
if ($current_step !== 'station' && $this->environment->isProduction()) {
|
||||
return $response->withRedirect($request->getRouter()->named('setup:' . $current_step));
|
||||
}
|
||||
|
||||
|
@ -199,12 +203,13 @@ class SetupController
|
|||
): ResponseInterface {
|
||||
// Verify current step.
|
||||
$current_step = $this->getSetupStep($request);
|
||||
if ($current_step !== 'settings' && $this->settings->isProduction()) {
|
||||
if ($current_step !== 'settings' && $this->environment->isProduction()) {
|
||||
return $response->withRedirect($request->getRouter()->named('setup:' . $current_step));
|
||||
}
|
||||
|
||||
if ($settingsForm->process($request)) {
|
||||
$this->settingsRepo->setSetting(Entity\Settings::SETUP_COMPLETE, time());
|
||||
$this->settings->updateSetupComplete();
|
||||
$this->settingsTableRepo->writeSettings($this->settings);
|
||||
|
||||
// Notify the user and redirect to homepage.
|
||||
$request->getFlash()->addMessage(
|
||||
|
|
|
@ -13,15 +13,12 @@ class ListenersController
|
|||
public function __invoke(
|
||||
ServerRequest $request,
|
||||
Response $response,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
Entity\Settings $settings,
|
||||
IpGeolocation $ipGeo
|
||||
): ResponseInterface {
|
||||
$view = $request->getView();
|
||||
|
||||
$analytics_level = $settingsRepo->getSetting(
|
||||
Entity\Settings::LISTENER_ANALYTICS,
|
||||
Entity\Analytics::LEVEL_ALL
|
||||
);
|
||||
$analytics_level = $settings->getAnalytics();
|
||||
|
||||
if ($analytics_level !== Entity\Analytics::LEVEL_ALL) {
|
||||
return $view->renderToResponse($response, 'stations/reports/restricted');
|
||||
|
|
|
@ -17,17 +17,17 @@ class OverviewController
|
|||
{
|
||||
protected EntityManagerInterface $em;
|
||||
|
||||
protected Entity\Repository\SettingsRepository $settingsRepo;
|
||||
protected Entity\Settings $settings;
|
||||
|
||||
protected Entity\Repository\AnalyticsRepository $analyticsRepo;
|
||||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
Entity\Settings $settings,
|
||||
Entity\Repository\AnalyticsRepository $analyticsRepo
|
||||
) {
|
||||
$this->em = $em;
|
||||
$this->settingsRepo = $settingsRepo;
|
||||
$this->settings = $settings;
|
||||
$this->analyticsRepo = $analyticsRepo;
|
||||
}
|
||||
|
||||
|
@ -37,10 +37,7 @@ class OverviewController
|
|||
$station_tz = $station->getTimezoneObject();
|
||||
|
||||
// Get current analytics level.
|
||||
$analytics_level = $this->settingsRepo->getSetting(
|
||||
Entity\Settings::LISTENER_ANALYTICS,
|
||||
Entity\Analytics::LEVEL_ALL
|
||||
);
|
||||
$analytics_level = $this->settings->getAnalytics();
|
||||
|
||||
if ($analytics_level === Entity\Analytics::LEVEL_NONE) {
|
||||
// The entirety of the dashboard can't be shown, so redirect user to the profile page.
|
||||
|
|
|
@ -17,16 +17,16 @@ class StreamersController
|
|||
|
||||
protected AzuraCastCentral $ac_central;
|
||||
|
||||
protected Entity\Repository\SettingsRepository $settingsRepo;
|
||||
protected Entity\Settings $settings;
|
||||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
AzuraCastCentral $ac_central,
|
||||
Entity\Repository\SettingsRepository $settingsRepo
|
||||
Entity\Settings $settings
|
||||
) {
|
||||
$this->em = $em;
|
||||
$this->ac_central = $ac_central;
|
||||
$this->settingsRepo = $settingsRepo;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
public function __invoke(ServerRequest $request, Response $response): ResponseInterface
|
||||
|
@ -61,7 +61,7 @@ class StreamersController
|
|||
$be_settings = $station->getBackendConfig();
|
||||
|
||||
return $view->renderToResponse($response, 'stations/streamers/index', [
|
||||
'server_url' => $this->settingsRepo->getSetting(Entity\Settings::BASE_URL, ''),
|
||||
'server_url' => $this->settings->getBaseUrl(),
|
||||
'stream_port' => $backend->getStreamPort($station),
|
||||
'ip' => $this->ac_central->getIp(),
|
||||
'dj_mount_point' => $be_settings['dj_mount_point'] ?? '/',
|
||||
|
|
|
@ -14,9 +14,14 @@ class Customization
|
|||
public const DEFAULT_LOCALE = 'en_US.UTF-8';
|
||||
public const DEFAULT_THEME = 'light';
|
||||
|
||||
public const THEME_LIGHT = 'light';
|
||||
public const THEME_DARK = 'dark';
|
||||
|
||||
protected ?Entity\User $user = null;
|
||||
|
||||
protected Entity\Repository\SettingsRepository $settingsRepo;
|
||||
protected Entity\Settings $settings;
|
||||
|
||||
protected Environment $environment;
|
||||
|
||||
protected string $locale = self::DEFAULT_LOCALE;
|
||||
|
||||
|
@ -27,11 +32,14 @@ class Customization
|
|||
protected string $instanceName = '';
|
||||
|
||||
public function __construct(
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
Entity\Settings $settings,
|
||||
Environment $environment,
|
||||
ServerRequestInterface $request
|
||||
) {
|
||||
$this->settingsRepo = $settingsRepo;
|
||||
$this->instanceName = (string)$this->settingsRepo->getSetting(Entity\Settings::INSTANCE_NAME, '');
|
||||
$this->settings = $settings;
|
||||
$this->environment = $environment;
|
||||
|
||||
$this->instanceName = $settings->getInstanceName() ?? '';
|
||||
|
||||
// Register current user
|
||||
$this->user = $request->getAttribute(ServerRequest::ATTR_USER);
|
||||
|
@ -44,7 +52,7 @@ class Customization
|
|||
if (!empty($queryParams['theme'])) {
|
||||
$this->publicTheme = $this->theme = $queryParams['theme'];
|
||||
} else {
|
||||
$this->publicTheme = $this->settingsRepo->getSetting(Entity\Settings::PUBLIC_THEME, $this->publicTheme);
|
||||
$this->publicTheme = $settings->getPublicTheme() ?? $this->publicTheme;
|
||||
|
||||
if (null !== $this->user && !empty($this->user->getTheme())) {
|
||||
$this->theme = (string)$this->user->getTheme();
|
||||
|
@ -74,9 +82,7 @@ class Customization
|
|||
*/
|
||||
protected function initLocale(?ServerRequestInterface $request = null): string
|
||||
{
|
||||
$settings = Environment::getInstance();
|
||||
|
||||
$supported_locales = $settings['locale']['supported'];
|
||||
$supported_locales = $this->environment['locale']['supported'];
|
||||
$try_locales = [];
|
||||
|
||||
// Prefer user-based profile locale.
|
||||
|
@ -160,7 +166,7 @@ class Customization
|
|||
*/
|
||||
public function getCustomPublicCss(): string
|
||||
{
|
||||
return (string)$this->settingsRepo->getSetting(Entity\Settings::CUSTOM_CSS_PUBLIC, '');
|
||||
return $this->settings->getPublicCustomCss() ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -168,7 +174,7 @@ class Customization
|
|||
*/
|
||||
public function getCustomPublicJs(): string
|
||||
{
|
||||
return (string)$this->settingsRepo->getSetting(Entity\Settings::CUSTOM_JS_PUBLIC, '');
|
||||
return $this->settings->getPublicCustomJs() ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -176,7 +182,7 @@ class Customization
|
|||
*/
|
||||
public function getCustomInternalCss(): string
|
||||
{
|
||||
return (string)$this->settingsRepo->getSetting(Entity\Settings::CUSTOM_CSS_INTERNAL, '');
|
||||
return $this->settings->getInternalCustomCss() ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -184,7 +190,7 @@ class Customization
|
|||
*/
|
||||
public function hideAlbumArt(): bool
|
||||
{
|
||||
return (bool)$this->settingsRepo->getSetting(Entity\Settings::HIDE_ALBUM_ART, false);
|
||||
return $this->settings->getHideAlbumArt();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -194,18 +200,16 @@ class Customization
|
|||
*/
|
||||
public function getPageTitle($title = null): string
|
||||
{
|
||||
$settings = Environment::getInstance();
|
||||
|
||||
if (!$this->hideProductName()) {
|
||||
if ($title) {
|
||||
$title .= ' - ' . $settings[Environment::APP_NAME];
|
||||
$title .= ' - ' . $this->environment[Environment::APP_NAME];
|
||||
} else {
|
||||
$title = $settings[Environment::APP_NAME];
|
||||
$title = $this->environment[Environment::APP_NAME];
|
||||
}
|
||||
}
|
||||
|
||||
if (!$settings->isProduction()) {
|
||||
$title = '(' . ucfirst($settings[Environment::APP_ENV]) . ') ' . $title;
|
||||
if (!$this->environment->isProduction()) {
|
||||
$title = '(' . ucfirst($this->environment[Environment::APP_ENV]) . ') ' . $title;
|
||||
}
|
||||
|
||||
return $title;
|
||||
|
@ -216,7 +220,7 @@ class Customization
|
|||
*/
|
||||
public function hideProductName(): bool
|
||||
{
|
||||
return (bool)$this->settingsRepo->getSetting(Entity\Settings::HIDE_PRODUCT_NAME, false);
|
||||
return $this->settings->getHideProductName();
|
||||
}
|
||||
|
||||
public function useWebSocketsForNowPlaying(): bool
|
||||
|
@ -225,7 +229,7 @@ class Customization
|
|||
return false;
|
||||
}
|
||||
|
||||
return (bool)$this->settingsRepo->getSetting(Entity\Settings::NOWPLAYING_USE_WEBSOCKETS, false);
|
||||
return $this->settings->getEnableWebsockets();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -20,19 +20,19 @@ class Repository
|
|||
|
||||
protected Serializer $serializer;
|
||||
|
||||
protected Environment $settings;
|
||||
protected Environment $environment;
|
||||
|
||||
protected LoggerInterface $logger;
|
||||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Serializer $serializer,
|
||||
Environment $settings,
|
||||
Environment $environment,
|
||||
LoggerInterface $logger
|
||||
) {
|
||||
$this->em = $em;
|
||||
$this->serializer = $serializer;
|
||||
$this->settings = $settings;
|
||||
$this->environment = $environment;
|
||||
$this->logger = $logger;
|
||||
|
||||
if (!isset($this->entityClass)) {
|
||||
|
|
|
@ -1,213 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Entity\Api\Admin;
|
||||
|
||||
use App\Entity;
|
||||
use OpenApi\Annotations as OA;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/**
|
||||
* @OA\Schema(type="object", schema="Api_Admin_Settings")
|
||||
*/
|
||||
class Settings
|
||||
{
|
||||
/**
|
||||
* Site Base URL
|
||||
*
|
||||
* @Assert\NotBlank
|
||||
* @OA\Property()
|
||||
* @var string
|
||||
*/
|
||||
public string $base_url;
|
||||
|
||||
/**
|
||||
* AzuraCast Instance Name
|
||||
*
|
||||
* @OA\Property()
|
||||
* @var string|null
|
||||
*/
|
||||
public ?string $instance_name;
|
||||
|
||||
/**
|
||||
* System Default Time Zone
|
||||
*
|
||||
* @OA\Property()
|
||||
* @var string|null
|
||||
*/
|
||||
public ?string $timezone = 'UTC';
|
||||
|
||||
/**
|
||||
* Prefer Browser URL (If Available)
|
||||
*
|
||||
* @OA\Property()
|
||||
* @Assert\Choice({0,1})
|
||||
* @var int
|
||||
*/
|
||||
public int $prefer_browser_url = 0;
|
||||
/**
|
||||
* Use Web Proxy for Radio
|
||||
*
|
||||
* @OA\Property()
|
||||
* @Assert\Choice({0,1})
|
||||
* @var int
|
||||
*/
|
||||
public int $use_radio_proxy = 0;
|
||||
/**
|
||||
* Days of Playback History to Keep
|
||||
*
|
||||
* @OA\Property()
|
||||
* @Assert\Choice({0,14,30,60,365,730})
|
||||
* @var int
|
||||
*/
|
||||
public int $history_keep_days = Entity\SongHistory::DEFAULT_DAYS_TO_KEEP;
|
||||
/**
|
||||
* Always Use HTTPS
|
||||
*
|
||||
* @OA\Property()
|
||||
* @Assert\Choice({0,1})
|
||||
* @var int
|
||||
*/
|
||||
public int $always_use_ssl = 0;
|
||||
/**
|
||||
* API "Access-Control-Allow-Origin" header
|
||||
*
|
||||
* @OA\Property()
|
||||
* @var string
|
||||
*/
|
||||
public string $api_access_control;
|
||||
/**
|
||||
* Listener Analytics Collection
|
||||
*
|
||||
* @OA\Property()
|
||||
* @Assert\Choice({Entity\Analytics::LEVEL_NONE, Entity\Analytics::LEVEL_NO_IP, Entity\Analytics::LEVEL_ALL})
|
||||
* @var string
|
||||
*/
|
||||
public string $analytics = Entity\Analytics::LEVEL_ALL;
|
||||
/**
|
||||
* Check for Updates and Announcements
|
||||
*
|
||||
* @OA\Property()
|
||||
* @Assert\Choice({
|
||||
* Entity\Settings::UPDATES_NONE,
|
||||
* Entity\Settings::UPDATES_RELEASE_ONLY,
|
||||
* Entity\Settings::UPDATES_ALL
|
||||
* })
|
||||
* @var int
|
||||
*/
|
||||
public int $central_updates_channel = Entity\Settings::UPDATES_RELEASE_ONLY;
|
||||
/**
|
||||
* Base Theme for Public Pages
|
||||
*
|
||||
* @OA\Property()
|
||||
* @Assert\Choice({"light", "dark"})
|
||||
* @var string
|
||||
*/
|
||||
public string $public_theme = 'light';
|
||||
/**
|
||||
* Hide Album Art on Public Pages
|
||||
*
|
||||
* @OA\Property()
|
||||
* @Assert\Choice({0,1})
|
||||
* @var int
|
||||
*/
|
||||
public int $hide_album_art = 0;
|
||||
/**
|
||||
* Homepage Redirect URL
|
||||
*
|
||||
* @OA\Property()
|
||||
* @var string|null
|
||||
*/
|
||||
public ?string $homepage_redirect_url;
|
||||
/**
|
||||
* Default Album Art URL
|
||||
*
|
||||
* @OA\Property()
|
||||
* @var string|null
|
||||
*/
|
||||
public ?string $default_album_art_url;
|
||||
/**
|
||||
* Hide AzuraCast Branding on Public Pages
|
||||
*
|
||||
* @OA\Property()
|
||||
* @Assert\Choice({0,1})
|
||||
* @var int
|
||||
*/
|
||||
public int $hide_product_name = 0;
|
||||
/**
|
||||
* Custom CSS for Public Pages
|
||||
*
|
||||
* @OA\Property()
|
||||
* @var string|null
|
||||
*/
|
||||
public ?string $custom_css_public;
|
||||
/**
|
||||
* Custom JS for Public Pages
|
||||
*
|
||||
* @OA\Property()
|
||||
* @var string|null
|
||||
*/
|
||||
public ?string $custom_js_public;
|
||||
/**
|
||||
* Custom CSS for Internal Pages
|
||||
*
|
||||
* @OA\Property()
|
||||
* @var string|null
|
||||
*/
|
||||
public ?string $custom_css_internal;
|
||||
|
||||
/**
|
||||
* @param int $prefer_browser_url
|
||||
*/
|
||||
public function setPreferBrowserUrl(int $prefer_browser_url): void
|
||||
{
|
||||
$this->prefer_browser_url = $prefer_browser_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $use_radio_proxy
|
||||
*/
|
||||
public function setUseRadioProxy(int $use_radio_proxy): void
|
||||
{
|
||||
$this->use_radio_proxy = $use_radio_proxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $history_keep_days
|
||||
*/
|
||||
public function setHistoryKeepDays(int $history_keep_days): void
|
||||
{
|
||||
$this->history_keep_days = $history_keep_days;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $always_use_ssl
|
||||
*/
|
||||
public function setAlwaysUseSsl(int $always_use_ssl): void
|
||||
{
|
||||
$this->always_use_ssl = $always_use_ssl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $central_updates_channel
|
||||
*/
|
||||
public function setCentralUpdatesChannel(int $central_updates_channel): void
|
||||
{
|
||||
$this->central_updates_channel = $central_updates_channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $hide_album_art
|
||||
*/
|
||||
public function setHideAlbumArt(int $hide_album_art): void
|
||||
{
|
||||
$this->hide_album_art = $hide_album_art;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $hide_product_name
|
||||
*/
|
||||
public function setHideProductName(int $hide_product_name): void
|
||||
{
|
||||
$this->hide_product_name = $hide_product_name;
|
||||
}
|
||||
}
|
|
@ -10,32 +10,36 @@ class Settings extends AbstractFixture
|
|||
{
|
||||
public function load(ObjectManager $em): void
|
||||
{
|
||||
$settings = [
|
||||
Entity\Settings::BASE_URL => getenv('INIT_BASE_URL') ?? 'docker.local',
|
||||
Entity\Settings::INSTANCE_NAME => getenv('INIT_INSTANCE_NAME') ?? 'local test',
|
||||
Entity\Settings::GEOLITE_LICENSE_KEY => getenv('INIT_GEOLITE_LICENSE_KEY') ?? '',
|
||||
Entity\Settings::PREFER_BROWSER_URL => 1,
|
||||
Entity\Settings::SETUP_COMPLETE => time(),
|
||||
Entity\Settings::USE_RADIO_PROXY => 1,
|
||||
Entity\Settings::CENTRAL_UPDATES => Entity\Settings::UPDATES_NONE,
|
||||
Entity\Settings::EXTERNAL_IP => '127.0.0.1',
|
||||
];
|
||||
$settings = new Entity\Settings();
|
||||
|
||||
$settings->setBaseUrl(getenv('INIT_BASE_URL') ?? 'docker.local');
|
||||
$settings->setInstanceName(getenv('INIT_INSTANCE_NAME') ?? 'local test');
|
||||
$settings->setGeoliteLicenseKey(getenv('INIT_GEOLITE_LICENSE_KEY') ?? '');
|
||||
$settings->setPreferBrowserUrl(true);
|
||||
$settings->updateSetupComplete();
|
||||
$settings->setUseRadioProxy(true);
|
||||
$settings->setCheckForUpdates(true);
|
||||
$settings->setExternalIp('127.0.0.1');
|
||||
|
||||
$isDemoMode = (!empty(getenv('INIT_DEMO_API_KEY') ?? ''));
|
||||
if ($isDemoMode) {
|
||||
$settings[Entity\Settings::LISTENER_ANALYTICS] = Entity\Analytics::LEVEL_NO_IP;
|
||||
$settings[Entity\Settings::CUSTOM_JS_PUBLIC] = <<<EOF
|
||||
$(function() {
|
||||
if ($('body').hasClass('login-content')) {
|
||||
$('input[name="username"]').val('demo@azuracast.com');
|
||||
$('input[name="password"]').val('demo');
|
||||
}
|
||||
});
|
||||
EOF;
|
||||
$settings->setAnalytics(Entity\Analytics::LEVEL_NO_IP);
|
||||
$settings->setPublicCustomJs(
|
||||
<<<'JS'
|
||||
$(function() {
|
||||
if ($('body').hasClass('login-content')) {
|
||||
$('input[name="username"]').val('demo@azuracast.com');
|
||||
$('input[name="password"]').val('demo');
|
||||
}
|
||||
});
|
||||
JS
|
||||
);
|
||||
}
|
||||
|
||||
$settings = json_decode(json_encode($settings), true);
|
||||
|
||||
foreach ($settings as $setting_key => $setting_value) {
|
||||
$record = new Entity\Settings($setting_key);
|
||||
$record = new Entity\SettingsTable($setting_key);
|
||||
$record->setSettingValue($setting_value);
|
||||
$em->persist($record);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Entity\Migration;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20201204043539 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Settings migration';
|
||||
}
|
||||
|
||||
public function preUp(Schema $schema): void
|
||||
{
|
||||
$settingsRaw = $this->connection->fetchAllAssociative('SELECT * FROM settings WHERE setting_value IS NOT NULL');
|
||||
|
||||
$settings = [];
|
||||
foreach ($settingsRaw as $row) {
|
||||
$settings[$row['setting_key']] = json_decode($row['setting_value'], true, 512, JSON_THROW_ON_ERROR);
|
||||
}
|
||||
|
||||
$newSettings = array_filter([
|
||||
'baseUrl' => $settings['base_url'] ?? null,
|
||||
'instanceName' => $settings['instance_name'] ?? null,
|
||||
'preferBrowserUrl' => $this->toBool($settings['prefer_browser_url'] ?? null),
|
||||
'useRadioProxy' => $this->toBool($settings['use_radio_proxy'] ?? null),
|
||||
'historyKeepDays' => $this->toInt($settings['history_keep_days'] ?? null),
|
||||
'alwaysUseSsl' => $this->toBool($settings['always_use_ssl'] ?? null),
|
||||
'apiAccessControl' => $settings['api_access_control'] ?? null,
|
||||
'enableWebsockets' => $this->toBool($settings['nowplaying_use_websockets'] ?? null),
|
||||
'analytics' => $settings['analytics'] ?? null,
|
||||
'checkForUpdates' => $this->toBool($settings['central_updates_channel'] ?? null),
|
||||
'appUniqueIdentifier' => $settings['central_app_uuid'] ?? null,
|
||||
'updateResults' => $settings['central_update_results'] ?? null,
|
||||
'updateLastRun' => $this->toInt($settings['central_update_last_run'] ?? null),
|
||||
'hideAlbumArt' => $this->toBool($settings['hide_album_art'] ?? null),
|
||||
'homepageRedirectUrl' => $settings['homepage_redirect_url'] ?? null,
|
||||
'defaultAlbumArtUrl' => $settings['default_album_art_url'] ?? null,
|
||||
'hideProductName' => $this->toBool($settings['hide_product_name'] ?? null),
|
||||
'publicTheme' => $settings['public_theme'] ?? null,
|
||||
'publicCustomCss' => $settings['custom_css_public'] ?? null,
|
||||
'publicCustomJs' => $settings['custom_js_public'] ?? null,
|
||||
'internalCustomCss' => $settings['custom_css_internal'] ?? null,
|
||||
'backupEnabled' => $this->toBool($settings['backup_enabled'] ?? null),
|
||||
'backupTimeCode' => $settings['backup_time'] ?? null,
|
||||
'backupExcludeMedia' => $this->toBool($settings['backup_exclude_media'] ?? null),
|
||||
'backupKeepCopies' => $settings['backup_keep_copies'] ?? null,
|
||||
'backupStorageLocation' => $this->toInt($settings['backup_storage_location'] ?? null),
|
||||
'backupLastRun' => $this->toInt($settings['backup_last_run'] ?? null),
|
||||
'backupLastResult' => $settings['backup_last_result'] ?? null,
|
||||
'backupLastOutput' => $settings['backup_last_output'] ?? null,
|
||||
'setupCompleteTime' => $this->toInt($settings['setup_complete'] ?? null),
|
||||
'nowplaying' => $settings['nowplaying'] ?? null,
|
||||
'syncNowplayingLastRun' => $this->toInt($settings['nowplaying_last_run'] ?? null),
|
||||
'syncShortLastRun' => $this->toInt($settings['sync_fast_last_run'] ?? null),
|
||||
'syncMediumLastRun' => $this->toInt($settings['sync_last_run'] ?? null),
|
||||
'syncLongLastRun' => $this->toInt($settings['sync_slow_last_run'] ?? null),
|
||||
'externalIp' => $settings['external_ip'] ?? null,
|
||||
'geoliteLicenseKey' => $settings['geolite_license_key'] ?? null,
|
||||
'geoliteLastRun' => $this->toInt($settings['geolite_last_run'] ?? null),
|
||||
], function ($value) {
|
||||
return null !== $value;
|
||||
});
|
||||
|
||||
$this->connection->delete('settings', [1 => 1]);
|
||||
|
||||
foreach ($newSettings as $settingKey => $settingValue) {
|
||||
$this->connection->insert('settings', [
|
||||
'setting_key' => $settingKey,
|
||||
'setting_value' => json_encode($settingValue, JSON_THROW_ON_ERROR),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
protected function toInt($value): ?int
|
||||
{
|
||||
return (null === $value) ? null : (int)$value;
|
||||
}
|
||||
|
||||
protected function toBool($value): ?bool
|
||||
{
|
||||
return (null === $value) ? null : (bool)$value;
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// Noop
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// Noop
|
||||
}
|
||||
}
|
|
@ -1,179 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Entity\Repository;
|
||||
|
||||
use App\Doctrine\Repository;
|
||||
use App\Entity;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
|
||||
class SettingsRepository extends Repository
|
||||
{
|
||||
protected static array $cachedSettings;
|
||||
|
||||
/**
|
||||
* @param array $settings
|
||||
*/
|
||||
public function setSettings(array $settings): void
|
||||
{
|
||||
$all_records_raw = $this->repository->findAll();
|
||||
|
||||
$all_records = [];
|
||||
foreach ($all_records_raw as $record) {
|
||||
/** @var Entity\Settings $record */
|
||||
$all_records[$record->getSettingKey()] = $record;
|
||||
}
|
||||
|
||||
$changes = [];
|
||||
|
||||
foreach ($settings as $setting_key => $setting_value) {
|
||||
if (isset($all_records[$setting_key])) {
|
||||
$record = $all_records[$setting_key];
|
||||
$prev = $record->getSettingValue();
|
||||
} else {
|
||||
$record = new Entity\Settings($setting_key);
|
||||
$prev = null;
|
||||
}
|
||||
|
||||
$record->setSettingValue($setting_value);
|
||||
$this->em->persist($record);
|
||||
|
||||
// Update cached value
|
||||
self::$cachedSettings[$setting_key] = $setting_value;
|
||||
|
||||
// Include change in audit log.
|
||||
if ($prev !== $setting_value) {
|
||||
$changes[$setting_key] = [$prev, $setting_value];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($changes)) {
|
||||
$auditLog = new Entity\AuditLog(
|
||||
Entity\AuditLog::OPER_UPDATE,
|
||||
Entity\Settings::class,
|
||||
'Settings',
|
||||
null,
|
||||
null,
|
||||
$changes
|
||||
);
|
||||
|
||||
$this->em->persist($auditLog);
|
||||
}
|
||||
|
||||
$this->em->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*/
|
||||
public function deleteSetting($key): void
|
||||
{
|
||||
$record = $this->repository->findOneBy(['setting_key' => $key]);
|
||||
|
||||
if ($record instanceof Entity\Settings) {
|
||||
$this->em->remove($record);
|
||||
$this->em->flush();
|
||||
}
|
||||
|
||||
unset(self::$cachedSettings[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
public function fetchAll(): array
|
||||
{
|
||||
$all_records_raw = $this->repository->findAll();
|
||||
|
||||
$all_records = [];
|
||||
foreach ($all_records_raw as $record) {
|
||||
/** @var Entity\Settings $record */
|
||||
$all_records[$record->getSettingKey()] = $record->getSettingValue();
|
||||
}
|
||||
|
||||
return $all_records;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force a clearing of the cache.
|
||||
*/
|
||||
public function clearCache(): void
|
||||
{
|
||||
// Regenerate cache and flush static value.
|
||||
$this->fetchArray(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $cached
|
||||
* @param null $order_by
|
||||
* @param string $order_dir
|
||||
*
|
||||
* @return mixed[]
|
||||
*/
|
||||
public function fetchArray($cached = true, $order_by = null, $order_dir = 'ASC'): array
|
||||
{
|
||||
if (!isset(self::$cachedSettings) || !$cached) {
|
||||
$settings_raw = $this->em->createQuery(
|
||||
<<<'DQL'
|
||||
SELECT s FROM App\Entity\Settings s ORDER BY s.setting_key ASC
|
||||
DQL
|
||||
)->getArrayResult();
|
||||
|
||||
self::$cachedSettings = [];
|
||||
foreach ($settings_raw as $setting) {
|
||||
self::$cachedSettings[$setting['setting_key']] = $setting['setting_value'];
|
||||
}
|
||||
}
|
||||
|
||||
return self::$cachedSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string A persistent unique identifier for this installation.
|
||||
*/
|
||||
public function getUniqueIdentifier(): string
|
||||
{
|
||||
$app_uuid = $this->getSetting(Entity\Settings::UNIQUE_IDENTIFIER);
|
||||
|
||||
if (!empty($app_uuid)) {
|
||||
return $app_uuid;
|
||||
}
|
||||
|
||||
$app_uuid = Uuid::uuid4()->toString();
|
||||
$this->setSetting(Entity\Settings::UNIQUE_IDENTIFIER, $app_uuid);
|
||||
|
||||
return $app_uuid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param mixed|null $default_value
|
||||
* @param bool $cached
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getSetting($key, $default_value = null, $cached = true)
|
||||
{
|
||||
$settings = $this->fetchArray($cached);
|
||||
return $settings[$key] ?? $default_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function setSetting($key, $value): void
|
||||
{
|
||||
$record = $this->repository->findOneBy(['setting_key' => $key]);
|
||||
|
||||
if (!$record instanceof Entity\Settings) {
|
||||
$record = new Entity\Settings($key);
|
||||
}
|
||||
|
||||
$record->setSettingValue($value);
|
||||
$this->em->persist($record);
|
||||
$this->em->flush();
|
||||
|
||||
// Update cached value
|
||||
self::$cachedSettings[$key] = $value;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
<?php
|
||||
|
||||
namespace App\Entity\Repository;
|
||||
|
||||
use App\Doctrine\Repository;
|
||||
use App\Entity;
|
||||
use App\Environment;
|
||||
use App\Exception\ValidationException;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
|
||||
use Symfony\Component\Serializer\Serializer;
|
||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||
|
||||
class SettingsTableRepository extends Repository
|
||||
{
|
||||
protected const CACHE_KEY = 'settings';
|
||||
|
||||
protected const CACHE_TTL = 600;
|
||||
|
||||
protected CacheInterface $cache;
|
||||
|
||||
protected ValidatorInterface $validator;
|
||||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Serializer $serializer,
|
||||
Environment $environment,
|
||||
LoggerInterface $logger,
|
||||
CacheInterface $cache,
|
||||
ValidatorInterface $validator
|
||||
) {
|
||||
parent::__construct($em, $serializer, $environment, $logger);
|
||||
|
||||
$this->cache = $cache;
|
||||
$this->validator = $validator;
|
||||
}
|
||||
|
||||
public function readSettings(bool $cached = true): Entity\Settings
|
||||
{
|
||||
if (Entity\Settings::hasInstance()) {
|
||||
return Entity\Settings::getInstance();
|
||||
} else {
|
||||
$settings = $this->arrayToObject($this->readSettingsArray($cached));
|
||||
Entity\Settings::setInstance($settings);
|
||||
|
||||
return $settings;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $cached
|
||||
*
|
||||
* @return mixed[]
|
||||
*/
|
||||
public function readSettingsArray(bool $cached = true): array
|
||||
{
|
||||
if ($cached && $this->cache->has(self::CACHE_KEY)) {
|
||||
return $this->cache->get(self::CACHE_KEY);
|
||||
}
|
||||
|
||||
$allRecords = [];
|
||||
foreach ($this->repository->findAll() as $record) {
|
||||
/** @var Entity\SettingsTable $record */
|
||||
$allRecords[$record->getSettingKey()] = $record->getSettingValue();
|
||||
}
|
||||
|
||||
$this->cache->set(self::CACHE_KEY, $allRecords, self::CACHE_TTL);
|
||||
|
||||
return $allRecords;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Entity\Settings|array $settingsObj
|
||||
*/
|
||||
public function writeSettings($settingsObj): void
|
||||
{
|
||||
if (is_array($settingsObj)) {
|
||||
$settingsObj = $this->arrayToObject($settingsObj, $this->readSettings(false));
|
||||
}
|
||||
|
||||
$errors = $this->validator->validate($settingsObj);
|
||||
if (count($errors) > 0) {
|
||||
$e = new ValidationException((string)$errors);
|
||||
$e->setDetailedErrors($errors);
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$settings = $this->objectToArray($settingsObj);
|
||||
|
||||
$this->cache->set(self::CACHE_KEY, $settings, self::CACHE_TTL);
|
||||
|
||||
$currentRecords = $this->repository->findAll();
|
||||
$allRecords = [];
|
||||
foreach ($currentRecords as $record) {
|
||||
/** @var Entity\SettingsTable $record */
|
||||
$allRecords[$record->getSettingKey()] = $record;
|
||||
}
|
||||
|
||||
$changes = [];
|
||||
foreach ($settings as $settingKey => $settingValue) {
|
||||
if (isset($allRecords[$settingKey])) {
|
||||
$record = $allRecords[$settingKey];
|
||||
$prev = $record->getSettingValue();
|
||||
} else {
|
||||
$record = new Entity\SettingsTable($settingKey);
|
||||
$prev = null;
|
||||
}
|
||||
|
||||
$record->setSettingValue($settingValue);
|
||||
$this->em->persist($record);
|
||||
|
||||
// Include change in audit log.
|
||||
if ($prev !== $settingValue) {
|
||||
$changes[$settingKey] = [$prev, $settingValue];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($changes)) {
|
||||
$auditLog = new Entity\AuditLog(
|
||||
Entity\AuditLog::OPER_UPDATE,
|
||||
Entity\SettingsTable::class,
|
||||
'Settings',
|
||||
null,
|
||||
null,
|
||||
$changes
|
||||
);
|
||||
|
||||
$this->em->persist($auditLog);
|
||||
}
|
||||
|
||||
$this->em->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Entity\Settings $settings
|
||||
*
|
||||
* @return mixed[]
|
||||
*/
|
||||
protected function objectToArray(Entity\Settings $settings): array
|
||||
{
|
||||
return $this->serializer->normalize($settings, null);
|
||||
}
|
||||
|
||||
protected function arrayToObject(array $settings, ?Entity\Settings $existingSettings = null): Entity\Settings
|
||||
{
|
||||
$settings = array_filter($settings, function ($value) {
|
||||
return null !== $value;
|
||||
});
|
||||
|
||||
$context = [];
|
||||
if (null !== $existingSettings) {
|
||||
$context[ObjectNormalizer::OBJECT_TO_POPULATE] = $existingSettings;
|
||||
}
|
||||
|
||||
return $this->serializer->denormalize($settings, Entity\Settings::class, null, $context);
|
||||
}
|
||||
}
|
|
@ -21,7 +21,7 @@ class SongHistoryRepository extends Repository
|
|||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Serializer $serializer,
|
||||
Environment $settings,
|
||||
Environment $environment,
|
||||
LoggerInterface $logger,
|
||||
ListenerRepository $listenerRepository,
|
||||
StationQueueRepository $stationQueueRepository
|
||||
|
@ -29,7 +29,7 @@ class SongHistoryRepository extends Repository
|
|||
$this->listenerRepository = $listenerRepository;
|
||||
$this->stationQueueRepository = $stationQueueRepository;
|
||||
|
||||
parent::__construct($em, $serializer, $settings, $logger);
|
||||
parent::__construct($em, $serializer, $environment, $logger);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -40,7 +40,7 @@ class StationMediaRepository extends Repository
|
|||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Serializer $serializer,
|
||||
Environment $settings,
|
||||
Environment $environment,
|
||||
LoggerInterface $logger,
|
||||
MetadataManagerInterface $metadataManager,
|
||||
CustomFieldRepository $customFieldRepo,
|
||||
|
@ -48,7 +48,7 @@ class StationMediaRepository extends Repository
|
|||
StorageLocationRepository $storageLocationRepo,
|
||||
FilesystemManager $filesystem
|
||||
) {
|
||||
parent::__construct($em, $serializer, $settings, $logger);
|
||||
parent::__construct($em, $serializer, $environment, $logger);
|
||||
|
||||
$this->customFieldRepo = $customFieldRepo;
|
||||
$this->spmRepo = $spmRepo;
|
||||
|
|
|
@ -19,11 +19,11 @@ class StationPlaylistMediaRepository extends Repository
|
|||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Serializer $serializer,
|
||||
Environment $settings,
|
||||
Environment $environment,
|
||||
LoggerInterface $logger,
|
||||
StationQueueRepository $queueRepo
|
||||
) {
|
||||
parent::__construct($em, $serializer, $settings, $logger);
|
||||
parent::__construct($em, $serializer, $environment, $logger);
|
||||
|
||||
$this->queueRepo = $queueRepo;
|
||||
}
|
||||
|
|
|
@ -32,32 +32,32 @@ class StationRepository extends Repository
|
|||
|
||||
protected CacheInterface $cache;
|
||||
|
||||
protected SettingsRepository $settingsRepo;
|
||||
|
||||
protected StorageLocationRepository $storageLocationRepo;
|
||||
|
||||
protected Entity\Settings $settings;
|
||||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Serializer $serializer,
|
||||
Environment $settings,
|
||||
SettingsRepository $settingsRepo,
|
||||
Environment $environment,
|
||||
StorageLocationRepository $storageLocationRepo,
|
||||
LoggerInterface $logger,
|
||||
CheckMediaTask $mediaSync,
|
||||
Adapters $adapters,
|
||||
Configuration $configuration,
|
||||
ValidatorInterface $validator,
|
||||
CacheInterface $cache
|
||||
CacheInterface $cache,
|
||||
Entity\Settings $settings
|
||||
) {
|
||||
$this->mediaSync = $mediaSync;
|
||||
$this->adapters = $adapters;
|
||||
$this->configuration = $configuration;
|
||||
$this->validator = $validator;
|
||||
$this->cache = $cache;
|
||||
$this->settingsRepo = $settingsRepo;
|
||||
$this->storageLocationRepo = $storageLocationRepo;
|
||||
$this->settings = $settings;
|
||||
|
||||
parent::__construct($em, $serializer, $settings, $logger);
|
||||
parent::__construct($em, $serializer, $environment, $logger);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -341,7 +341,7 @@ class StationRepository extends Repository
|
|||
}
|
||||
}
|
||||
|
||||
$custom_url = trim($this->settingsRepo->getSetting(Entity\Settings::DEFAULT_ALBUM_ART_URL));
|
||||
$custom_url = trim($this->settings->getDefaultAlbumArtUrl());
|
||||
|
||||
if (!empty($custom_url)) {
|
||||
return new Uri($custom_url);
|
||||
|
|
|
@ -21,11 +21,11 @@ class StationRequestRepository extends Repository
|
|||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Serializer $serializer,
|
||||
Environment $settings,
|
||||
Environment $environment,
|
||||
LoggerInterface $logger,
|
||||
StationMediaRepository $mediaRepo
|
||||
) {
|
||||
parent::__construct($em, $serializer, $settings, $logger);
|
||||
parent::__construct($em, $serializer, $environment, $logger);
|
||||
|
||||
$this->mediaRepo = $mediaRepo;
|
||||
}
|
||||
|
|
|
@ -19,11 +19,11 @@ class StationScheduleRepository extends Repository
|
|||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Serializer $serializer,
|
||||
Environment $settings,
|
||||
Environment $environment,
|
||||
LoggerInterface $logger,
|
||||
Scheduler $scheduler
|
||||
) {
|
||||
parent::__construct($em, $serializer, $settings, $logger);
|
||||
parent::__construct($em, $serializer, $environment, $logger);
|
||||
|
||||
$this->scheduler = $scheduler;
|
||||
}
|
||||
|
|
|
@ -23,13 +23,13 @@ class StationStreamerRepository extends Repository
|
|||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Serializer $serializer,
|
||||
Environment $settings,
|
||||
Environment $environment,
|
||||
LoggerInterface $logger,
|
||||
Scheduler $scheduler,
|
||||
StationStreamerBroadcastRepository $broadcastRepo,
|
||||
FilesystemManager $filesystem
|
||||
) {
|
||||
parent::__construct($em, $serializer, $settings, $logger);
|
||||
parent::__construct($em, $serializer, $environment, $logger);
|
||||
|
||||
$this->scheduler = $scheduler;
|
||||
$this->broadcastRepo = $broadcastRepo;
|
||||
|
|
|
@ -2,116 +2,706 @@
|
|||
|
||||
namespace App\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use App\Customization;
|
||||
use App\Entity;
|
||||
use App\Event\GetSyncTasks;
|
||||
use App\Traits\AvailableStaticallyTrait;
|
||||
use OpenApi\Annotations as OA;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/**
|
||||
* @ORM\Table(name="settings")
|
||||
* @ORM\Entity()
|
||||
* @OA\Schema(type="object", schema="Settings")
|
||||
*/
|
||||
class Settings
|
||||
{
|
||||
// Predefined settings constants.
|
||||
public const BASE_URL = 'base_url';
|
||||
public const INSTANCE_NAME = 'instance_name';
|
||||
|
||||
public const PREFER_BROWSER_URL = 'prefer_browser_url';
|
||||
public const USE_RADIO_PROXY = 'use_radio_proxy';
|
||||
public const HISTORY_KEEP_DAYS = 'history_keep_days';
|
||||
|
||||
public const ALWAYS_USE_SSL = 'always_use_ssl';
|
||||
public const API_ACCESS_CONTROL = 'api_access_control';
|
||||
public const NOWPLAYING_USE_WEBSOCKETS = 'nowplaying_use_websockets';
|
||||
|
||||
public const LISTENER_ANALYTICS = 'analytics';
|
||||
public const CENTRAL_UPDATES = 'central_updates_channel';
|
||||
|
||||
// Custom branding constants.
|
||||
public const PUBLIC_THEME = 'public_theme';
|
||||
public const HIDE_ALBUM_ART = 'hide_album_art';
|
||||
public const HOMEPAGE_REDIRECT_URL = 'homepage_redirect_url';
|
||||
public const DEFAULT_ALBUM_ART_URL = 'default_album_art_url';
|
||||
public const HIDE_PRODUCT_NAME = 'hide_product_name';
|
||||
public const CUSTOM_CSS_PUBLIC = 'custom_css_public';
|
||||
public const CUSTOM_JS_PUBLIC = 'custom_js_public';
|
||||
public const CUSTOM_CSS_INTERNAL = 'custom_css_internal';
|
||||
|
||||
// Backup settings
|
||||
public const BACKUP_ENABLED = 'backup_enabled';
|
||||
public const BACKUP_TIME = 'backup_time';
|
||||
public const BACKUP_EXCLUDE_MEDIA = 'backup_exclude_media';
|
||||
public const BACKUP_KEEP_COPIES = 'backup_keep_copies';
|
||||
public const BACKUP_STORAGE_LOCATION = 'backup_storage_location';
|
||||
|
||||
// Internal settings
|
||||
public const SETUP_COMPLETE = 'setup_complete';
|
||||
|
||||
public const NOWPLAYING_LAST_STARTED = 'nowplaying_last_started';
|
||||
public const NOWPLAYING_LAST_RUN = 'nowplaying_last_run';
|
||||
public const NOWPLAYING = 'nowplaying';
|
||||
|
||||
public const SHORT_SYNC_LAST_RUN = 'sync_fast_last_run';
|
||||
public const MEDIUM_SYNC_LAST_RUN = 'sync_last_run';
|
||||
public const LONG_SYNC_LAST_RUN = 'sync_slow_last_run';
|
||||
|
||||
public const UPDATES_NONE = 0;
|
||||
public const UPDATES_ALL = 1;
|
||||
public const UPDATES_RELEASE_ONLY = 2;
|
||||
|
||||
public const UNIQUE_IDENTIFIER = 'central_app_uuid';
|
||||
public const UPDATE_RESULTS = 'central_update_results';
|
||||
public const UPDATE_LAST_RUN = 'central_update_last_run';
|
||||
|
||||
public const EXTERNAL_IP = 'external_ip';
|
||||
|
||||
public const BACKUP_LAST_RUN = 'backup_last_run';
|
||||
public const BACKUP_LAST_RESULT = 'backup_last_result';
|
||||
public const BACKUP_LAST_OUTPUT = 'backup_last_output';
|
||||
|
||||
public const GEOLITE_LICENSE_KEY = 'geolite_license_key';
|
||||
public const GEOLITE_LAST_RUN = 'geolite_last_run';
|
||||
use AvailableStaticallyTrait;
|
||||
|
||||
/**
|
||||
* @ORM\Column(name="setting_key", type="string", length=64)
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue(strategy="NONE")
|
||||
* @OA\Property(example="https://your.azuracast.site")
|
||||
* @var string Site Base URL
|
||||
*/
|
||||
protected string $baseUrl = '';
|
||||
|
||||
public function getBaseUrl(): string
|
||||
{
|
||||
return $this->baseUrl;
|
||||
}
|
||||
|
||||
public function setBaseUrl(string $baseUrl): void
|
||||
{
|
||||
$this->baseUrl = $baseUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example="My AzuraCast Instance")
|
||||
* @var string|null AzuraCast Instance Name
|
||||
*/
|
||||
protected ?string $instanceName = null;
|
||||
|
||||
public function getInstanceName(): ?string
|
||||
{
|
||||
return $this->instanceName;
|
||||
}
|
||||
|
||||
public function setInstanceName(?string $instanceName): void
|
||||
{
|
||||
$this->instanceName = $instanceName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example="false")
|
||||
* @var bool Prefer Browser URL (If Available)
|
||||
*/
|
||||
protected bool $preferBrowserUrl = false;
|
||||
|
||||
public function getPreferBrowserUrl(): bool
|
||||
{
|
||||
return (bool)($this->preferBrowserUrl);
|
||||
}
|
||||
|
||||
public function setPreferBrowserUrl(bool $preferBrowserUrl): void
|
||||
{
|
||||
$this->preferBrowserUrl = $preferBrowserUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example="false")
|
||||
* @var bool Use Web Proxy for Radio
|
||||
*/
|
||||
protected bool $useRadioProxy = false;
|
||||
|
||||
public function getUseRadioProxy(): bool
|
||||
{
|
||||
return (bool)($this->useRadioProxy);
|
||||
}
|
||||
|
||||
public function setUseRadioProxy(bool $useRadioProxy): void
|
||||
{
|
||||
$this->useRadioProxy = $useRadioProxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property()
|
||||
* @Assert\Choice({0,14,30,60,365,730})
|
||||
* @var int Days of Playback History to Keep
|
||||
*/
|
||||
protected int $historyKeepDays = Entity\SongHistory::DEFAULT_DAYS_TO_KEEP;
|
||||
|
||||
public function getHistoryKeepDays(): int
|
||||
{
|
||||
return $this->historyKeepDays;
|
||||
}
|
||||
|
||||
public function setHistoryKeepDays(int $historyKeepDays): void
|
||||
{
|
||||
$this->historyKeepDays = $historyKeepDays;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example="false")
|
||||
* @var bool Always Use HTTPS
|
||||
*/
|
||||
protected bool $alwaysUseSsl = false;
|
||||
|
||||
public function getAlwaysUseSsl(): bool
|
||||
{
|
||||
return (bool)$this->alwaysUseSsl;
|
||||
}
|
||||
|
||||
public function setAlwaysUseSsl(bool $alwaysUseSsl): void
|
||||
{
|
||||
$this->alwaysUseSsl = $alwaysUseSsl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example="*")
|
||||
* @var string API "Access-Control-Allow-Origin" header
|
||||
*/
|
||||
protected string $apiAccessControl = '';
|
||||
|
||||
public function getApiAccessControl(): string
|
||||
{
|
||||
return $this->apiAccessControl;
|
||||
}
|
||||
|
||||
public function setApiAccessControl(string $apiAccessControl): void
|
||||
{
|
||||
$this->apiAccessControl = $apiAccessControl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example="false")
|
||||
* @var bool Whether to use Websockets for Now Playing data updates.
|
||||
*/
|
||||
protected bool $enableWebsockets = false;
|
||||
|
||||
public function getEnableWebsockets(): bool
|
||||
{
|
||||
return (bool)$this->enableWebsockets;
|
||||
}
|
||||
|
||||
public function setEnableWebsockets(bool $enableWebsockets): void
|
||||
{
|
||||
$this->enableWebsockets = $enableWebsockets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listener Analytics Collection
|
||||
*
|
||||
* @OA\Property()
|
||||
* @Assert\Choice({Entity\Analytics::LEVEL_NONE, Entity\Analytics::LEVEL_NO_IP, Entity\Analytics::LEVEL_ALL})
|
||||
* @var string
|
||||
*/
|
||||
protected $setting_key;
|
||||
protected string $analytics = Entity\Analytics::LEVEL_ALL;
|
||||
|
||||
/**
|
||||
* @ORM\Column(name="setting_value", type="json", nullable=true)
|
||||
* @var mixed
|
||||
*/
|
||||
protected $setting_value;
|
||||
|
||||
public function __construct(string $setting_key)
|
||||
public function getAnalytics(): string
|
||||
{
|
||||
$this->setting_key = $setting_key;
|
||||
return $this->analytics;
|
||||
}
|
||||
|
||||
public function getSettingKey(): string
|
||||
public function setAnalytics(string $analytics): void
|
||||
{
|
||||
return $this->setting_key;
|
||||
$this->analytics = $analytics;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* @OA\Property(example="true")
|
||||
* @var bool Check for Updates and Announcements
|
||||
*/
|
||||
public function getSettingValue()
|
||||
protected bool $checkForUpdates = true;
|
||||
|
||||
public function getCheckForUpdates(): bool
|
||||
{
|
||||
return $this->setting_value;
|
||||
return $this->checkForUpdates;
|
||||
}
|
||||
|
||||
public function setSettingValue($setting_value): void
|
||||
public function setCheckForUpdates(bool $checkForUpdates): void
|
||||
{
|
||||
$this->setting_value = $setting_value;
|
||||
$this->checkForUpdates = $checkForUpdates;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* @OA\Property(example="")
|
||||
* @var string|null The unique identifier for this installation (for update checks).
|
||||
*/
|
||||
public function getValue()
|
||||
protected ?string $appUniqueIdentifier = null;
|
||||
|
||||
public function getAppUniqueIdentifier(): ?string
|
||||
{
|
||||
return $this->setting_value;
|
||||
return $this->appUniqueIdentifier;
|
||||
}
|
||||
|
||||
public function setAppUniqueIdentifier(?string $appUniqueIdentifier): void
|
||||
{
|
||||
$this->appUniqueIdentifier = $appUniqueIdentifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example="")
|
||||
* @var mixed[]|null Results of the latest update check.
|
||||
*/
|
||||
protected ?array $updateResults;
|
||||
|
||||
/**
|
||||
* @return mixed[]|null
|
||||
*/
|
||||
public function getUpdateResults(): ?array
|
||||
{
|
||||
return $this->updateResults;
|
||||
}
|
||||
|
||||
public function setUpdateResults(?array $updateResults): void
|
||||
{
|
||||
$this->updateResults = $updateResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example=SAMPLE_TIMESTAMP)
|
||||
* @var int The UNIX timestamp when updates were last checked.
|
||||
*/
|
||||
protected int $updateLastRun = 0;
|
||||
|
||||
public function getUpdateLastRun(): int
|
||||
{
|
||||
return $this->updateLastRun;
|
||||
}
|
||||
|
||||
public function setUpdateLastRun(int $updateLastRun): void
|
||||
{
|
||||
$this->updateLastRun = $updateLastRun;
|
||||
}
|
||||
|
||||
public function updateUpdateLastRun(): void
|
||||
{
|
||||
$this->setUpdateLastRun(time());
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example=Customization::DEFAULT_THEME)
|
||||
* @Assert\Choice({Customization::THEME_LIGHT, Customization::THEME_DARK})
|
||||
* @var string Base Theme for Public Pages
|
||||
*/
|
||||
protected string $publicTheme = Customization::DEFAULT_THEME;
|
||||
|
||||
public function getPublicTheme(): string
|
||||
{
|
||||
return $this->publicTheme;
|
||||
}
|
||||
|
||||
public function setPublicTheme(string $publicTheme): void
|
||||
{
|
||||
$this->publicTheme = $publicTheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example="false")
|
||||
* @var bool Hide Album Art on Public Pages
|
||||
*/
|
||||
protected bool $hideAlbumArt = false;
|
||||
|
||||
public function getHideAlbumArt(): bool
|
||||
{
|
||||
return $this->hideAlbumArt;
|
||||
}
|
||||
|
||||
public function setHideAlbumArt(bool $hideAlbumArt): void
|
||||
{
|
||||
$this->hideAlbumArt = $hideAlbumArt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example="https://example.com/")
|
||||
* @var string|null Homepage Redirect URL
|
||||
*/
|
||||
protected ?string $homepageRedirectUrl = null;
|
||||
|
||||
public function getHomepageRedirectUrl(): ?string
|
||||
{
|
||||
return $this->homepageRedirectUrl;
|
||||
}
|
||||
|
||||
public function setHomepageRedirectUrl(?string $homepageRedirectUrl): void
|
||||
{
|
||||
$this->homepageRedirectUrl = $homepageRedirectUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example="https://example.com/image.jpg")
|
||||
* @var string|null Default Album Art URL
|
||||
*/
|
||||
protected ?string $defaultAlbumArtUrl = null;
|
||||
|
||||
public function getDefaultAlbumArtUrl(): ?string
|
||||
{
|
||||
return $this->defaultAlbumArtUrl;
|
||||
}
|
||||
|
||||
public function setDefaultAlbumArtUrl(?string $defaultAlbumArtUrl): void
|
||||
{
|
||||
$this->defaultAlbumArtUrl = $defaultAlbumArtUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example="false")
|
||||
* @var bool Hide AzuraCast Branding on Public Pages
|
||||
*/
|
||||
protected bool $hideProductName = false;
|
||||
|
||||
public function getHideProductName(): bool
|
||||
{
|
||||
return (bool)$this->hideProductName;
|
||||
}
|
||||
|
||||
public function setHideProductName(bool $hideProductName): void
|
||||
{
|
||||
$this->hideProductName = $hideProductName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example="")
|
||||
* @var string|null Custom CSS for Public Pages
|
||||
*/
|
||||
protected ?string $publicCustomCss = null;
|
||||
|
||||
public function getPublicCustomCss(): ?string
|
||||
{
|
||||
return $this->publicCustomCss;
|
||||
}
|
||||
|
||||
public function setPublicCustomCss(?string $publicCustomCss): void
|
||||
{
|
||||
$this->publicCustomCss = $publicCustomCss;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example="")
|
||||
* @var string|null Custom JS for Public Pages
|
||||
*/
|
||||
protected ?string $publicCustomJs = null;
|
||||
|
||||
public function getPublicCustomJs(): ?string
|
||||
{
|
||||
return $this->publicCustomJs;
|
||||
}
|
||||
|
||||
public function setPublicCustomJs(?string $publicCustomJs): void
|
||||
{
|
||||
$this->publicCustomJs = $publicCustomJs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example="")
|
||||
* @var string|null Custom CSS for Internal Pages
|
||||
*/
|
||||
protected ?string $internalCustomCss = null;
|
||||
|
||||
public function getInternalCustomCss(): ?string
|
||||
{
|
||||
return $this->internalCustomCss;
|
||||
}
|
||||
|
||||
public function setInternalCustomCss(?string $internalCustomCss): void
|
||||
{
|
||||
$this->internalCustomCss = $internalCustomCss;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example="false")
|
||||
* @var bool Whether backup is enabled.
|
||||
*/
|
||||
protected bool $backupEnabled = false;
|
||||
|
||||
public function isBackupEnabled(): bool
|
||||
{
|
||||
return $this->backupEnabled;
|
||||
}
|
||||
|
||||
public function setBackupEnabled(bool $backupEnabled): void
|
||||
{
|
||||
$this->backupEnabled = $backupEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example=400)
|
||||
* @var int|null The timecode (i.e. 400 for 4:00AM) when automated backups should run.
|
||||
*/
|
||||
protected ?int $backupTimeCode = null;
|
||||
|
||||
public function getBackupTimeCode(): ?int
|
||||
{
|
||||
return $this->backupTimeCode;
|
||||
}
|
||||
|
||||
public function setBackupTimeCode(?int $backupTimeCode): void
|
||||
{
|
||||
$this->backupTimeCode = $backupTimeCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example="false")
|
||||
* @var bool Whether to exclude media in automated backups.
|
||||
*/
|
||||
protected bool $backupExcludeMedia = false;
|
||||
|
||||
public function getBackupExcludeMedia(): bool
|
||||
{
|
||||
return $this->backupExcludeMedia;
|
||||
}
|
||||
|
||||
public function setBackupExcludeMedia(bool $backupExcludeMedia): void
|
||||
{
|
||||
$this->backupExcludeMedia = $backupExcludeMedia;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example=2)
|
||||
* @var int Number of backups to keep, or infinite if zero/null.
|
||||
*/
|
||||
protected int $backupKeepCopies = 0;
|
||||
|
||||
public function getBackupKeepCopies(): int
|
||||
{
|
||||
return $this->backupKeepCopies;
|
||||
}
|
||||
|
||||
public function setBackupKeepCopies(int $backupKeepCopies): void
|
||||
{
|
||||
$this->backupKeepCopies = $backupKeepCopies;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example=1)
|
||||
* @var int|null The storage location ID for automated backups.
|
||||
*/
|
||||
protected ?int $backupStorageLocation = null;
|
||||
|
||||
public function getBackupStorageLocation(): ?int
|
||||
{
|
||||
return $this->backupStorageLocation;
|
||||
}
|
||||
|
||||
public function setBackupStorageLocation(?int $backupStorageLocation): void
|
||||
{
|
||||
$this->backupStorageLocation = $backupStorageLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example=SAMPLE_TIMESTAMP)
|
||||
* @var int The UNIX timestamp when automated backup was last run.
|
||||
*/
|
||||
protected int $backupLastRun = 0;
|
||||
|
||||
public function getBackupLastRun(): int
|
||||
{
|
||||
return $this->backupLastRun;
|
||||
}
|
||||
|
||||
public function setBackupLastRun(int $backupLastRun): void
|
||||
{
|
||||
$this->backupLastRun = $backupLastRun;
|
||||
}
|
||||
|
||||
public function updateBackupLastRun(): void
|
||||
{
|
||||
$this->setBackupLastRun(time());
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example="")
|
||||
* @var string|null The result of the latest automated backup task.
|
||||
*/
|
||||
protected ?string $backupLastResult = null;
|
||||
|
||||
public function getBackupLastResult(): ?string
|
||||
{
|
||||
return $this->backupLastResult;
|
||||
}
|
||||
|
||||
public function setBackupLastResult(?string $backupLastResult): void
|
||||
{
|
||||
$this->backupLastResult = $backupLastResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example="")
|
||||
* @var string|null The output of the latest automated backup task.
|
||||
*/
|
||||
protected ?string $backupLastOutput = null;
|
||||
|
||||
public function getBackupLastOutput(): ?string
|
||||
{
|
||||
return $this->backupLastOutput;
|
||||
}
|
||||
|
||||
public function setBackupLastOutput(?string $backupLastOutput): void
|
||||
{
|
||||
$this->backupLastOutput = $backupLastOutput;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example=SAMPLE_TIMESTAMP)
|
||||
* @var int The UNIX timestamp when setup was last completed.
|
||||
*/
|
||||
protected int $setupCompleteTime = 0;
|
||||
|
||||
public function getSetupCompleteTime(): int
|
||||
{
|
||||
return $this->setupCompleteTime;
|
||||
}
|
||||
|
||||
public function isSetupComplete(): bool
|
||||
{
|
||||
return (0 !== $this->setupCompleteTime);
|
||||
}
|
||||
|
||||
public function setSetupCompleteTime(int $setupCompleteTime): void
|
||||
{
|
||||
$this->setupCompleteTime = $setupCompleteTime;
|
||||
}
|
||||
|
||||
public function updateSetupComplete(): void
|
||||
{
|
||||
$this->setSetupCompleteTime(time());
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example="")
|
||||
* @var mixed[]|null The current cached now playing data.
|
||||
*/
|
||||
protected ?array $nowplaying = null;
|
||||
|
||||
/**
|
||||
* @return mixed[]|null
|
||||
*/
|
||||
public function getNowplaying(): ?array
|
||||
{
|
||||
return $this->nowplaying;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Entity\Api\NowPlaying|array|null $nowplaying
|
||||
*/
|
||||
public function setNowplaying($nowplaying): void
|
||||
{
|
||||
if ($nowplaying instanceof Entity\Api\NowPlaying) {
|
||||
$nowplaying = json_decode(
|
||||
json_encode($nowplaying, JSON_THROW_ON_ERROR),
|
||||
true,
|
||||
512,
|
||||
JSON_THROW_ON_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
$this->nowplaying = $nowplaying;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example=SAMPLE_TIMESTAMP)
|
||||
* @var int The UNIX timestamp when the now playing sync task was last run.
|
||||
*/
|
||||
protected int $syncNowplayingLastRun = 0;
|
||||
|
||||
public function getSyncNowplayingLastRun(): int
|
||||
{
|
||||
return $this->syncNowplayingLastRun;
|
||||
}
|
||||
|
||||
public function setSyncNowplayingLastRun(int $syncNowplayingLastRun): void
|
||||
{
|
||||
$this->syncNowplayingLastRun = $syncNowplayingLastRun;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example=SAMPLE_TIMESTAMP)
|
||||
* @var int The UNIX timestamp when the 60-second "short" sync task was last run.
|
||||
*/
|
||||
protected int $syncShortLastRun = 0;
|
||||
|
||||
public function getSyncShortLastRun(): int
|
||||
{
|
||||
return $this->syncShortLastRun;
|
||||
}
|
||||
|
||||
public function setSyncShortLastRun(int $syncShortLastRun): void
|
||||
{
|
||||
$this->syncShortLastRun = $syncShortLastRun;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example=SAMPLE_TIMESTAMP)
|
||||
* @var int The UNIX timestamp when the 5-minute "medium" sync task was last run.
|
||||
*/
|
||||
protected int $syncMediumLastRun = 0;
|
||||
|
||||
public function getSyncMediumLastRun(): int
|
||||
{
|
||||
return $this->syncMediumLastRun;
|
||||
}
|
||||
|
||||
public function setSyncMediumLastRun(int $syncMediumLastRun): void
|
||||
{
|
||||
$this->syncMediumLastRun = $syncMediumLastRun;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example=SAMPLE_TIMESTAMP)
|
||||
* @var int The UNIX timestamp when the 1-hour "long" sync task was last run.
|
||||
*/
|
||||
protected int $syncLongLastRun = 0;
|
||||
|
||||
public function getSyncLongLastRun(): int
|
||||
{
|
||||
return $this->syncLongLastRun;
|
||||
}
|
||||
|
||||
public function setSyncLongLastRun(int $syncLongLastRun): void
|
||||
{
|
||||
$this->syncLongLastRun = $syncLongLastRun;
|
||||
}
|
||||
|
||||
public function getSyncLastRunTime(string $type): int
|
||||
{
|
||||
$timesByType = [
|
||||
GetSyncTasks::SYNC_NOWPLAYING => $this->syncNowplayingLastRun,
|
||||
GetSyncTasks::SYNC_SHORT => $this->syncShortLastRun,
|
||||
GetSyncTasks::SYNC_MEDIUM => $this->syncMediumLastRun,
|
||||
GetSyncTasks::SYNC_LONG => $this->syncLongLastRun,
|
||||
];
|
||||
|
||||
return $timesByType[$type] ?? 0;
|
||||
}
|
||||
|
||||
public function updateSyncLastRunTime(string $type): void
|
||||
{
|
||||
switch ($type) {
|
||||
case GetSyncTasks::SYNC_NOWPLAYING:
|
||||
$this->syncNowplayingLastRun = time();
|
||||
break;
|
||||
|
||||
case GetSyncTasks::SYNC_SHORT:
|
||||
$this->syncShortLastRun = time();
|
||||
break;
|
||||
|
||||
case GetSyncTasks::SYNC_MEDIUM:
|
||||
$this->syncMediumLastRun = time();
|
||||
break;
|
||||
|
||||
case GetSyncTasks::SYNC_LONG:
|
||||
$this->syncLongLastRun = time();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example="192.168.1.1")
|
||||
* @var string|null This installation's external IP.
|
||||
*/
|
||||
protected ?string $externalIp = null;
|
||||
|
||||
public function getExternalIp(): ?string
|
||||
{
|
||||
return $this->externalIp;
|
||||
}
|
||||
|
||||
public function setExternalIp(?string $externalIp): void
|
||||
{
|
||||
$this->externalIp = $externalIp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example="")
|
||||
* @var string|null The license key for the Maxmind Geolite download.
|
||||
*/
|
||||
protected ?string $geoliteLicenseKey = null;
|
||||
|
||||
public function getGeoliteLicenseKey(): ?string
|
||||
{
|
||||
return $this->geoliteLicenseKey;
|
||||
}
|
||||
|
||||
public function setGeoliteLicenseKey(?string $geoliteLicenseKey): void
|
||||
{
|
||||
$this->geoliteLicenseKey = $geoliteLicenseKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Property(example=SAMPLE_TIMESTAMP)
|
||||
* @var int The UNIX timestamp when the Maxmind Geolite was last downloaded.
|
||||
*/
|
||||
protected int $geoliteLastRun = 0;
|
||||
|
||||
public function getGeoliteLastRun(): int
|
||||
{
|
||||
return $this->geoliteLastRun;
|
||||
}
|
||||
|
||||
public function setGeoliteLastRun(int $geoliteLastRun): void
|
||||
{
|
||||
$this->geoliteLastRun = $geoliteLastRun;
|
||||
}
|
||||
|
||||
public function updateGeoliteLastRun(): void
|
||||
{
|
||||
$this->setGeoliteLastRun(time());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Table(name="settings")
|
||||
* @ORM\Entity()
|
||||
*/
|
||||
class SettingsTable
|
||||
{
|
||||
/**
|
||||
* @ORM\Column(name="setting_key", type="string", length=64)
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue(strategy="NONE")
|
||||
* @var string
|
||||
*/
|
||||
protected $setting_key;
|
||||
|
||||
/**
|
||||
* @ORM\Column(name="setting_value", type="json", nullable=true)
|
||||
* @var mixed
|
||||
*/
|
||||
protected $setting_value;
|
||||
|
||||
public function __construct(string $setting_key)
|
||||
{
|
||||
$this->setting_key = $setting_key;
|
||||
}
|
||||
|
||||
public function getSettingKey(): string
|
||||
{
|
||||
return $this->setting_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getSettingValue()
|
||||
{
|
||||
return $this->setting_value;
|
||||
}
|
||||
|
||||
public function setSettingValue($setting_value): void
|
||||
{
|
||||
$this->setting_value = $setting_value;
|
||||
}
|
||||
}
|
|
@ -11,21 +11,21 @@ abstract class AbstractSettingsForm extends Form
|
|||
{
|
||||
protected EntityManagerInterface $em;
|
||||
|
||||
protected Entity\Repository\SettingsRepository $settingsRepo;
|
||||
protected Entity\Repository\SettingsTableRepository $settingsTableRepo;
|
||||
|
||||
protected Environment $settings;
|
||||
protected Environment $environment;
|
||||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
Environment $settings,
|
||||
Entity\Repository\SettingsTableRepository $settingsTableRepo,
|
||||
Environment $environment,
|
||||
array $formConfig
|
||||
) {
|
||||
parent::__construct($formConfig);
|
||||
|
||||
$this->em = $em;
|
||||
$this->settings = $settings;
|
||||
$this->settingsRepo = $settingsRepo;
|
||||
$this->environment = $environment;
|
||||
$this->settingsTableRepo = $settingsTableRepo;
|
||||
}
|
||||
|
||||
public function getEntityManager(): EntityManagerInterface
|
||||
|
@ -33,25 +33,25 @@ abstract class AbstractSettingsForm extends Form
|
|||
return $this->em;
|
||||
}
|
||||
|
||||
public function getEntityRepository(): Entity\Repository\SettingsRepository
|
||||
public function getEntityRepository(): Entity\Repository\SettingsTableRepository
|
||||
{
|
||||
return $this->settingsRepo;
|
||||
return $this->settingsTableRepo;
|
||||
}
|
||||
|
||||
public function getSettings(): Environment
|
||||
public function getEnvironment(): Environment
|
||||
{
|
||||
return $this->settings;
|
||||
return $this->environment;
|
||||
}
|
||||
|
||||
public function process(ServerRequest $request): bool
|
||||
{
|
||||
// Populate the form with existing values (if they exist).
|
||||
$defaults = $this->settingsRepo->fetchArray(false);
|
||||
$defaults = $this->settingsTableRepo->readSettingsArray(false);
|
||||
|
||||
// Use current URI from request if the base URL isn't set.
|
||||
if (!isset($defaults[Entity\Settings::BASE_URL])) {
|
||||
if (!isset($defaults['baseUrl'])) {
|
||||
$currentUri = $request->getUri()->withPath('');
|
||||
$defaults[Entity\Settings::BASE_URL] = (string)$currentUri;
|
||||
$defaults['baseUrl'] = (string)$currentUri;
|
||||
}
|
||||
|
||||
$this->populate($defaults);
|
||||
|
@ -59,7 +59,7 @@ abstract class AbstractSettingsForm extends Form
|
|||
// Handle submission.
|
||||
if ('POST' === $request->getMethod() && $this->isValid($request->getParsedBody())) {
|
||||
$data = $this->getValues();
|
||||
$this->settingsRepo->setSettings($data);
|
||||
$this->settingsTableRepo->writeSettings($data);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,20 +11,20 @@ class BackupSettingsForm extends AbstractSettingsForm
|
|||
{
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
Entity\Repository\SettingsTableRepository $settingsTableRepo,
|
||||
Entity\Repository\StorageLocationRepository $storageLocationRepo,
|
||||
Environment $settings,
|
||||
Environment $environment,
|
||||
Config $config
|
||||
) {
|
||||
$formConfig = $config->get('forms/backup', [
|
||||
'settings' => $settings,
|
||||
'settings' => $environment,
|
||||
'storageLocations' => $storageLocationRepo->fetchSelectByType(Entity\StorageLocation::TYPE_BACKUP, true),
|
||||
]);
|
||||
|
||||
parent::__construct(
|
||||
$em,
|
||||
$settingsRepo,
|
||||
$settings,
|
||||
$settingsTableRepo,
|
||||
$environment,
|
||||
$formConfig
|
||||
);
|
||||
}
|
||||
|
|
|
@ -11,18 +11,18 @@ class BrandingSettingsForm extends AbstractSettingsForm
|
|||
{
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
Environment $settings,
|
||||
Entity\Repository\SettingsTableRepository $settingsRepo,
|
||||
Environment $environment,
|
||||
Config $config
|
||||
) {
|
||||
$formConfig = $config->get('forms/branding', [
|
||||
'settings' => $settings,
|
||||
'settings' => $environment,
|
||||
]);
|
||||
|
||||
parent::__construct(
|
||||
$em,
|
||||
$settingsRepo,
|
||||
$settings,
|
||||
$environment,
|
||||
$formConfig
|
||||
);
|
||||
}
|
||||
|
|
|
@ -14,8 +14,8 @@ class GeoLiteSettingsForm extends AbstractSettingsForm
|
|||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
Environment $settings,
|
||||
Entity\Repository\SettingsTableRepository $settingsRepo,
|
||||
Environment $environment,
|
||||
Config $config,
|
||||
UpdateGeoLiteTask $syncTask
|
||||
) {
|
||||
|
@ -24,7 +24,7 @@ class GeoLiteSettingsForm extends AbstractSettingsForm
|
|||
parent::__construct(
|
||||
$em,
|
||||
$settingsRepo,
|
||||
$settings,
|
||||
$environment,
|
||||
$formConfig
|
||||
);
|
||||
|
||||
|
|
|
@ -13,20 +13,20 @@ class SettingsForm extends AbstractSettingsForm
|
|||
{
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
Environment $settings,
|
||||
Entity\Repository\SettingsTableRepository $settingsRepo,
|
||||
Environment $environment,
|
||||
Version $version,
|
||||
Config $config
|
||||
) {
|
||||
$formConfig = $config->get('forms/settings', [
|
||||
'settings' => $settings,
|
||||
'settings' => $environment,
|
||||
'version' => $version,
|
||||
]);
|
||||
|
||||
parent::__construct(
|
||||
$em,
|
||||
$settingsRepo,
|
||||
$settings,
|
||||
$environment,
|
||||
$formConfig
|
||||
);
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ class SettingsForm extends AbstractSettingsForm
|
|||
public function process(ServerRequest $request): bool
|
||||
{
|
||||
if ('https' !== $request->getUri()->getScheme()) {
|
||||
$alwaysUseSsl = $this->getField(Entity\Settings::ALWAYS_USE_SSL);
|
||||
$alwaysUseSsl = $this->getField('alwaysUseSsl');
|
||||
$alwaysUseSsl->setAttribute('disabled', 'disabled');
|
||||
$alwaysUseSsl->setOption(
|
||||
'description',
|
||||
|
|
|
@ -35,7 +35,7 @@ class StationCloneForm extends StationForm
|
|||
Configuration $configuration,
|
||||
CheckMediaTask $media_sync,
|
||||
Config $config,
|
||||
Environment $settings,
|
||||
Environment $environment,
|
||||
FilesystemManager $filesystem
|
||||
) {
|
||||
parent::__construct(
|
||||
|
@ -46,7 +46,7 @@ class StationCloneForm extends StationForm
|
|||
$storageLocationRepo,
|
||||
$acl,
|
||||
$config,
|
||||
$settings
|
||||
$environment
|
||||
);
|
||||
|
||||
$form_config = $config->get('forms/station_clone');
|
||||
|
|
|
@ -21,7 +21,7 @@ class StationForm extends EntityForm
|
|||
|
||||
protected Acl $acl;
|
||||
|
||||
protected Environment $settings;
|
||||
protected Environment $environment;
|
||||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
|
@ -31,13 +31,13 @@ class StationForm extends EntityForm
|
|||
Entity\Repository\StorageLocationRepository $storageLocationRepo,
|
||||
Acl $acl,
|
||||
Config $config,
|
||||
Environment $settings
|
||||
Environment $environment
|
||||
) {
|
||||
$this->acl = $acl;
|
||||
$this->entityClass = Entity\Station::class;
|
||||
$this->station_repo = $station_repo;
|
||||
$this->storageLocationRepo = $storageLocationRepo;
|
||||
$this->settings = $settings;
|
||||
$this->environment = $environment;
|
||||
|
||||
$form_config = $config->get('forms/station');
|
||||
parent::__construct($em, $serializer, $validator, $form_config);
|
||||
|
@ -46,7 +46,7 @@ class StationForm extends EntityForm
|
|||
public function configure(array $options): void
|
||||
{
|
||||
// Hide "advanced" fields if advanced features are hidden on this installation.
|
||||
if (!$this->settings->enableAdvancedFeatures()) {
|
||||
if (!$this->environment->enableAdvancedFeatures()) {
|
||||
foreach ($options['groups'] as $groupId => $group) {
|
||||
foreach ($group['elements'] as $elementKey => $element) {
|
||||
$elementOptions = (array)$element[1];
|
||||
|
|
|
@ -22,7 +22,7 @@ class StationWebhookForm extends EntityForm
|
|||
EntityManagerInterface $em,
|
||||
Serializer $serializer,
|
||||
ValidatorInterface $validator,
|
||||
Environment $settings,
|
||||
Environment $environment,
|
||||
Config $config,
|
||||
Router $router
|
||||
) {
|
||||
|
@ -32,7 +32,7 @@ class StationWebhookForm extends EntityForm
|
|||
$config_injections = [
|
||||
'router' => $router,
|
||||
'triggers' => $webhook_config['triggers'],
|
||||
'app_settings' => $settings,
|
||||
'app_settings' => $environment,
|
||||
];
|
||||
|
||||
foreach ($webhook_config['webhooks'] as $webhook_key => $webhook_info) {
|
||||
|
|
|
@ -18,10 +18,10 @@ class UserProfileForm extends EntityForm
|
|||
Serializer $serializer,
|
||||
ValidatorInterface $validator,
|
||||
Config $config,
|
||||
Environment $settings
|
||||
Environment $environment
|
||||
) {
|
||||
$form_config = $config->get('forms/profile', [
|
||||
'settings' => $settings,
|
||||
'settings' => $environment,
|
||||
]);
|
||||
parent::__construct($em, $serializer, $validator, $form_config);
|
||||
|
||||
|
|
|
@ -33,18 +33,18 @@ class ErrorHandler extends \Slim\Handlers\ErrorHandler
|
|||
|
||||
protected ViewFactory $viewFactory;
|
||||
|
||||
protected Environment $settings;
|
||||
protected Environment $environment;
|
||||
|
||||
public function __construct(
|
||||
App $app,
|
||||
Logger $logger,
|
||||
Router $router,
|
||||
ViewFactory $viewFactory,
|
||||
Environment $settings
|
||||
Environment $environment
|
||||
) {
|
||||
parent::__construct($app->getCallableResolver(), $app->getResponseFactory(), $logger);
|
||||
|
||||
$this->settings = $settings;
|
||||
$this->environment = $environment;
|
||||
$this->viewFactory = $viewFactory;
|
||||
$this->router = $router;
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ class ErrorHandler extends \Slim\Handlers\ErrorHandler
|
|||
$this->loggerLevel = LogLevel::WARNING;
|
||||
}
|
||||
|
||||
$this->showDetailed = (!$this->settings->isProduction() && !in_array(
|
||||
$this->showDetailed = (!$this->environment->isProduction() && !in_array(
|
||||
$this->loggerLevel,
|
||||
[LogLevel::DEBUG, LogLevel::INFO, LogLevel::NOTICE],
|
||||
true
|
||||
|
@ -80,7 +80,7 @@ class ErrorHandler extends \Slim\Handlers\ErrorHandler
|
|||
{
|
||||
$xhr = $req->getHeaderLine('X-Requested-With') === 'XMLHttpRequest';
|
||||
|
||||
if ($xhr || $this->settings->isCli() || $this->settings->isTesting()) {
|
||||
if ($xhr || $this->environment->isCli() || $this->environment->isTesting()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,18 +17,18 @@ class Router implements RouterInterface
|
|||
{
|
||||
protected RouteParserInterface $routeParser;
|
||||
|
||||
protected Environment $settings;
|
||||
protected Environment $environment;
|
||||
|
||||
protected ?ServerRequestInterface $currentRequest = null;
|
||||
|
||||
protected Entity\Repository\SettingsRepository $settingsRepo;
|
||||
protected Entity\Settings $settings;
|
||||
|
||||
public function __construct(
|
||||
Environment $settings,
|
||||
Environment $environment,
|
||||
RouteParserInterface $routeParser,
|
||||
Entity\Repository\SettingsRepository $settingsRepo
|
||||
Entity\Settings $settings
|
||||
) {
|
||||
$this->settingsRepo = $settingsRepo;
|
||||
$this->environment = $environment;
|
||||
$this->settings = $settings;
|
||||
$this->routeParser = $routeParser;
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ class Router implements RouterInterface
|
|||
|
||||
public function getBaseUrl(bool $useRequest = true): UriInterface
|
||||
{
|
||||
$settingsBaseUrl = $this->settingsRepo->getSetting(Entity\Settings::BASE_URL, '');
|
||||
$settingsBaseUrl = $this->settings->getBaseUrl();
|
||||
if (!empty($settingsBaseUrl)) {
|
||||
if (strpos($settingsBaseUrl, 'http') !== 0) {
|
||||
$settingsBaseUrl = 'http://' . $settingsBaseUrl;
|
||||
|
@ -165,7 +165,7 @@ class Router implements RouterInterface
|
|||
$baseUrl = new Uri('');
|
||||
}
|
||||
|
||||
$useHttps = (bool)$this->settingsRepo->getSetting(Entity\Settings::ALWAYS_USE_SSL, 0);
|
||||
$useHttps = $this->settings->getAlwaysUseSsl();
|
||||
|
||||
if ($useRequest && $this->currentRequest instanceof ServerRequestInterface) {
|
||||
$currentUri = $this->currentRequest->getUri();
|
||||
|
@ -174,7 +174,7 @@ class Router implements RouterInterface
|
|||
$useHttps = true;
|
||||
}
|
||||
|
||||
$preferBrowserUrl = (bool)$this->settingsRepo->getSetting(Entity\Settings::PREFER_BROWSER_URL, 0);
|
||||
$preferBrowserUrl = $this->settings->getPreferBrowserUrl();
|
||||
if ($preferBrowserUrl || $baseUrl->getHost() === '') {
|
||||
$ignoredHosts = ['web', 'nginx', 'localhost'];
|
||||
if (!in_array($currentUri->getHost(), $ignoredHosts, true)) {
|
||||
|
|
|
@ -19,18 +19,18 @@ class EnforceSecurity implements MiddlewareInterface
|
|||
{
|
||||
protected ResponseFactoryInterface $responseFactory;
|
||||
|
||||
protected Entity\Repository\SettingsRepository $settings_repo;
|
||||
|
||||
protected Assets $assets;
|
||||
|
||||
protected Entity\Settings $settings;
|
||||
|
||||
public function __construct(
|
||||
App $app,
|
||||
Entity\Repository\SettingsRepository $settings_repo,
|
||||
Assets $assets
|
||||
Assets $assets,
|
||||
Entity\Settings $settings
|
||||
) {
|
||||
$this->responseFactory = $app->getResponseFactory();
|
||||
$this->settings_repo = $settings_repo;
|
||||
$this->assets = $assets;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -39,7 +39,7 @@ class EnforceSecurity implements MiddlewareInterface
|
|||
*/
|
||||
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||
{
|
||||
$always_use_ssl = (bool)$this->settings_repo->getSetting('always_use_ssl', 0);
|
||||
$always_use_ssl = $this->settings->getAlwaysUseSsl();
|
||||
$internal_api_url = mb_stripos($request->getUri()->getPath(), '/api/internal') === 0;
|
||||
|
||||
// Assemble Content Security Policy (CSP)
|
||||
|
|
|
@ -19,18 +19,18 @@ class GetCurrentUser implements MiddlewareInterface
|
|||
{
|
||||
protected Entity\Repository\UserRepository $userRepo;
|
||||
|
||||
protected Entity\Repository\SettingsRepository $settingsRepo;
|
||||
protected Entity\Settings $settings;
|
||||
|
||||
protected Environment $environment;
|
||||
|
||||
public function __construct(
|
||||
Entity\Repository\UserRepository $userRepo,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
Environment $environment
|
||||
Environment $environment,
|
||||
Entity\Settings $settings
|
||||
) {
|
||||
$this->userRepo = $userRepo;
|
||||
$this->settingsRepo = $settingsRepo;
|
||||
$this->environment = $environment;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||
|
@ -49,7 +49,7 @@ class GetCurrentUser implements MiddlewareInterface
|
|||
->withAttribute('is_logged_in', (null !== $user));
|
||||
|
||||
// Initialize Customization (timezones, locales, etc) based on the current logged in user.
|
||||
$customization = new Customization($this->settingsRepo, $request);
|
||||
$customization = new Customization($this->settings, $this->environment, $request);
|
||||
|
||||
$request = $request
|
||||
->withAttribute('locale', $customization->getLocale())
|
||||
|
|
|
@ -20,14 +20,14 @@ class InjectSession implements MiddlewareInterface
|
|||
{
|
||||
protected SessionPersistenceInterface $sessionPersistence;
|
||||
|
||||
protected Environment $settings;
|
||||
protected Environment $environment;
|
||||
|
||||
public function __construct(
|
||||
SessionPersistenceInterface $sessionPersistence,
|
||||
Environment $settings
|
||||
Environment $environment
|
||||
) {
|
||||
$this->sessionPersistence = $sessionPersistence;
|
||||
$this->settings = $settings;
|
||||
$this->environment = $environment;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,7 +38,7 @@ class InjectSession implements MiddlewareInterface
|
|||
{
|
||||
$session = new LazySession($this->sessionPersistence, $request);
|
||||
|
||||
$csrf = new Csrf($session, $this->settings);
|
||||
$csrf = new Csrf($session, $this->environment);
|
||||
Csrf::setInstance($csrf);
|
||||
|
||||
$flash = new Flash($session);
|
||||
|
|
|
@ -16,14 +16,14 @@ class Api
|
|||
{
|
||||
protected Entity\Repository\ApiKeyRepository $api_repo;
|
||||
|
||||
protected Entity\Repository\SettingsRepository $settings_repo;
|
||||
protected Entity\Settings $settings;
|
||||
|
||||
public function __construct(
|
||||
Entity\Repository\ApiKeyRepository $apiKeyRepository,
|
||||
Entity\Repository\SettingsRepository $settingsRepository
|
||||
Entity\Settings $settings
|
||||
) {
|
||||
$this->api_repo = $apiKeyRepository;
|
||||
$this->settings_repo = $settingsRepository;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
public function __invoke(ServerRequest $request, RequestHandlerInterface $handler): ResponseInterface
|
||||
|
@ -40,12 +40,12 @@ class Api
|
|||
}
|
||||
|
||||
// Set default cache control for API pages.
|
||||
$prefer_browser_url = (bool)$this->settings_repo->getSetting(Entity\Settings::PREFER_BROWSER_URL, 0);
|
||||
$prefer_browser_url = $this->settings->getPreferBrowserUrl();
|
||||
|
||||
$response = $handler->handle($request);
|
||||
|
||||
// Check for a user-set CORS header override.
|
||||
$acao_header = trim($this->settings_repo->getSetting(Entity\Settings::API_ACCESS_CONTROL));
|
||||
$acao_header = trim($this->settings->getApiAccessControl());
|
||||
if (!empty($acao_header)) {
|
||||
if ('*' === $acao_header) {
|
||||
$response = $response->withHeader('Access-Control-Allow-Origin', '*');
|
||||
|
@ -55,7 +55,7 @@ class Api
|
|||
|
||||
if (!empty($origin)) {
|
||||
$rawOrigins = array_map('trim', explode(',', $acao_header));
|
||||
$rawOrigins[] = $this->settings_repo->getSetting(Entity\Settings::BASE_URL);
|
||||
$rawOrigins[] = $this->settings->getBaseUrl();
|
||||
|
||||
$origins = [];
|
||||
foreach ($rawOrigins as $rawOrigin) {
|
||||
|
|
|
@ -15,12 +15,12 @@ class ReopenEntityManagerMiddleware implements MiddlewareInterface
|
|||
{
|
||||
protected DecoratedEntityManager $em;
|
||||
|
||||
protected Environment $settings;
|
||||
protected Environment $environment;
|
||||
|
||||
public function __construct(DecoratedEntityManager $em, Environment $settings)
|
||||
public function __construct(DecoratedEntityManager $em, Environment $environment)
|
||||
{
|
||||
$this->em = $em;
|
||||
$this->settings = $settings;
|
||||
$this->environment = $environment;
|
||||
}
|
||||
|
||||
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||
|
@ -30,7 +30,7 @@ class ReopenEntityManagerMiddleware implements MiddlewareInterface
|
|||
try {
|
||||
return $handler->handle($request);
|
||||
} finally {
|
||||
if (!$this->settings->isTesting()) {
|
||||
if (!$this->environment->isTesting()) {
|
||||
$this->em->getConnection()->close();
|
||||
}
|
||||
|
||||
|
|
|
@ -11,14 +11,14 @@ use Carbon\CarbonImmutable;
|
|||
|
||||
class RecentBackupCheck
|
||||
{
|
||||
protected Entity\Repository\SettingsRepository $settingsRepo;
|
||||
protected Entity\Settings $settings;
|
||||
|
||||
protected Environment $appSettings;
|
||||
protected Environment $environment;
|
||||
|
||||
public function __construct(Entity\Repository\SettingsRepository $settingsRepo, Environment $appSettings)
|
||||
public function __construct(Entity\Settings $settings, Environment $environment)
|
||||
{
|
||||
$this->settingsRepo = $settingsRepo;
|
||||
$this->appSettings = $appSettings;
|
||||
$this->settings = $settings;
|
||||
$this->environment = $environment;
|
||||
}
|
||||
|
||||
public function __invoke(GetNotifications $event): void
|
||||
|
@ -30,19 +30,19 @@ class RecentBackupCheck
|
|||
return;
|
||||
}
|
||||
|
||||
if (!$this->appSettings->isProduction()) {
|
||||
if (!$this->environment->isProduction()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$threshold = CarbonImmutable::now()->subWeeks(2)->getTimestamp();
|
||||
|
||||
// Don't show backup warning for freshly created installations.
|
||||
$setupComplete = (int)$this->settingsRepo->getSetting(Entity\Settings::SETUP_COMPLETE, 0);
|
||||
$setupComplete = $this->settings->getSetupCompleteTime();
|
||||
if ($setupComplete >= $threshold) {
|
||||
return;
|
||||
}
|
||||
|
||||
$backupLastRun = $this->settingsRepo->getSetting(Entity\Settings::BACKUP_LAST_RUN, 0);
|
||||
$backupLastRun = $this->settings->getBackupLastRun();
|
||||
|
||||
if ($backupLastRun < $threshold) {
|
||||
$router = $request->getRouter();
|
||||
|
|
|
@ -12,14 +12,14 @@ class SyncTaskCheck
|
|||
{
|
||||
protected Runner $syncRunner;
|
||||
|
||||
protected Entity\Repository\SettingsRepository $settingsRepo;
|
||||
protected Entity\Settings $settings;
|
||||
|
||||
public function __construct(
|
||||
Runner $syncRunner,
|
||||
Entity\Repository\SettingsRepository $settingsRepo
|
||||
Entity\Settings $settings
|
||||
) {
|
||||
$this->syncRunner = $syncRunner;
|
||||
$this->settingsRepo = $settingsRepo;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
public function __invoke(GetNotifications $event): void
|
||||
|
@ -31,7 +31,7 @@ class SyncTaskCheck
|
|||
return;
|
||||
}
|
||||
|
||||
$setupComplete = (int)$this->settingsRepo->getSetting(Entity\Settings::SETUP_COMPLETE, 0);
|
||||
$setupComplete = $this->settings->isSetupComplete();
|
||||
$syncTasks = $this->syncRunner->getSyncTimes();
|
||||
|
||||
foreach ($syncTasks as $taskKey => $task) {
|
||||
|
|
|
@ -10,13 +10,13 @@ use App\Version;
|
|||
|
||||
class UpdateCheck
|
||||
{
|
||||
protected Entity\Repository\SettingsRepository $settingsRepo;
|
||||
protected Entity\Settings $settings;
|
||||
|
||||
protected Version $version;
|
||||
|
||||
public function __construct(Entity\Repository\SettingsRepository $settingsRepo, Version $version)
|
||||
public function __construct(Entity\Settings $settings, Version $version)
|
||||
{
|
||||
$this->settingsRepo = $settingsRepo;
|
||||
$this->settings = $settings;
|
||||
$this->version = $version;
|
||||
}
|
||||
|
||||
|
@ -29,12 +29,12 @@ class UpdateCheck
|
|||
return;
|
||||
}
|
||||
|
||||
$checkForUpdates = (bool)$this->settingsRepo->getSetting(Entity\Settings::CENTRAL_UPDATES, 1);
|
||||
$checkForUpdates = $this->settings->getCheckForUpdates();
|
||||
if (!$checkForUpdates) {
|
||||
return;
|
||||
}
|
||||
|
||||
$updateData = $this->settingsRepo->getSetting(Entity\Settings::UPDATE_RESULTS);
|
||||
$updateData = $this->settings->getUpdateResults();
|
||||
if (empty($updateData)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ abstract class AbstractFrontend extends AbstractAdapter
|
|||
|
||||
protected Router $router;
|
||||
|
||||
protected Entity\Repository\SettingsRepository $settingsRepo;
|
||||
protected Entity\Settings $settings;
|
||||
|
||||
protected Entity\Repository\StationMountRepository $stationMountRepo;
|
||||
|
||||
|
@ -38,8 +38,8 @@ abstract class AbstractFrontend extends AbstractAdapter
|
|||
AdapterFactory $adapterFactory,
|
||||
Client $client,
|
||||
Router $router,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
Entity\Repository\StationMountRepository $stationMountRepo
|
||||
Entity\Repository\StationMountRepository $stationMountRepo,
|
||||
Entity\Settings $settings
|
||||
) {
|
||||
parent::__construct($em, $supervisor, $dispatcher);
|
||||
|
||||
|
@ -47,8 +47,8 @@ abstract class AbstractFrontend extends AbstractAdapter
|
|||
$this->http_client = $client;
|
||||
$this->router = $router;
|
||||
|
||||
$this->settingsRepo = $settingsRepo;
|
||||
$this->stationMountRepo = $stationMountRepo;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -149,7 +149,7 @@ abstract class AbstractFrontend extends AbstractAdapter
|
|||
$base_url = $this->router->getBaseUrl();
|
||||
}
|
||||
|
||||
$use_radio_proxy = $this->settingsRepo->getSetting('use_radio_proxy', 0);
|
||||
$use_radio_proxy = $this->settings->getUseRadioProxy();
|
||||
|
||||
if (
|
||||
$use_radio_proxy
|
||||
|
|
|
@ -106,7 +106,7 @@ class Icecast extends AbstractFrontend
|
|||
$config_dir = $station->getRadioConfigDir();
|
||||
$environment = Environment::getInstance();
|
||||
|
||||
$settingsBaseUrl = $this->settingsRepo->getSetting(Entity\Settings::BASE_URL, 'http://localhost');
|
||||
$settingsBaseUrl = $this->settings->getBaseUrl() ?: 'http://localhost';
|
||||
if (strpos($settingsBaseUrl, 'http') !== 0) {
|
||||
$settingsBaseUrl = 'http://' . $settingsBaseUrl;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ abstract class AbstractRemote
|
|||
{
|
||||
protected EntityManagerInterface $em;
|
||||
|
||||
protected Entity\Repository\SettingsRepository $settingsRepo;
|
||||
protected Entity\Settings $settings;
|
||||
|
||||
protected Client $http_client;
|
||||
|
||||
|
@ -25,13 +25,13 @@ abstract class AbstractRemote
|
|||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
Entity\Settings $settings,
|
||||
Client $http_client,
|
||||
Logger $logger,
|
||||
AdapterFactory $adapterFactory
|
||||
) {
|
||||
$this->em = $em;
|
||||
$this->settingsRepo = $settingsRepo;
|
||||
$this->settings = $settings;
|
||||
$this->http_client = $http_client;
|
||||
$this->logger = $logger;
|
||||
$this->adapterFactory = $adapterFactory;
|
||||
|
|
|
@ -67,7 +67,7 @@ class AzuraRelay extends AbstractRemote
|
|||
$fe_config = $station->getFrontendConfig();
|
||||
$radio_port = $fe_config->getPort();
|
||||
|
||||
$use_radio_proxy = $this->settingsRepo->getSetting('use_radio_proxy', 0);
|
||||
$use_radio_proxy = $this->settings->getUseRadioProxy();
|
||||
|
||||
if (
|
||||
$use_radio_proxy
|
||||
|
|
|
@ -9,12 +9,12 @@ class RateLimit
|
|||
{
|
||||
protected Redis $redis;
|
||||
|
||||
protected Environment $settings;
|
||||
protected Environment $environment;
|
||||
|
||||
public function __construct(Redis $redis, Environment $settings)
|
||||
public function __construct(Redis $redis, Environment $environment)
|
||||
{
|
||||
$this->redis = $redis;
|
||||
$this->settings = $settings;
|
||||
$this->environment = $environment;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -31,7 +31,7 @@ class RateLimit
|
|||
int $timeout = 5,
|
||||
int $interval = 2
|
||||
): bool {
|
||||
if ($this->settings->isTesting() || $this->settings->isCli()) {
|
||||
if ($this->environment->isTesting() || $this->environment->isCli()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ use App\Version;
|
|||
use Exception;
|
||||
use GuzzleHttp\Client;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
|
||||
class AzuraCastCentral
|
||||
{
|
||||
|
@ -17,24 +18,28 @@ class AzuraCastCentral
|
|||
|
||||
protected Client $httpClient;
|
||||
|
||||
protected Entity\Repository\SettingsRepository $settingsRepo;
|
||||
protected Entity\Settings $settings;
|
||||
|
||||
protected Entity\Repository\SettingsTableRepository $settingsTableRepo;
|
||||
|
||||
protected Version $version;
|
||||
|
||||
protected LoggerInterface $logger;
|
||||
|
||||
public function __construct(
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
Environment $environment,
|
||||
Version $version,
|
||||
Client $httpClient,
|
||||
LoggerInterface $logger
|
||||
LoggerInterface $logger,
|
||||
Entity\Settings $settings,
|
||||
Entity\Repository\SettingsTableRepository $settingsTableRepo
|
||||
) {
|
||||
$this->settingsRepo = $settingsRepo;
|
||||
$this->environment = $environment;
|
||||
$this->version = $version;
|
||||
$this->httpClient = $httpClient;
|
||||
$this->logger = $logger;
|
||||
$this->settings = $settings;
|
||||
$this->settingsTableRepo = $settingsTableRepo;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -44,10 +49,8 @@ class AzuraCastCentral
|
|||
*/
|
||||
public function checkForUpdates(): ?array
|
||||
{
|
||||
$app_uuid = $this->settingsRepo->getUniqueIdentifier();
|
||||
|
||||
$request_body = [
|
||||
'id' => $app_uuid,
|
||||
'id' => $this->getUniqueIdentifier(),
|
||||
'is_docker' => $this->environment->isDocker(),
|
||||
'environment' => $this->environment[Environment::APP_ENV],
|
||||
'release_channel' => $this->version->getReleaseChannel(),
|
||||
|
@ -78,6 +81,20 @@ class AzuraCastCentral
|
|||
return null;
|
||||
}
|
||||
|
||||
public function getUniqueIdentifier(): string
|
||||
{
|
||||
$appUuid = $this->settings->getAppUniqueIdentifier();
|
||||
|
||||
if (empty($appUuid)) {
|
||||
$appUuid = Uuid::uuid4()->toString();
|
||||
|
||||
$this->settings->setAppUniqueIdentifier($appUuid);
|
||||
$this->settingsTableRepo->writeSettings($this->settings);
|
||||
}
|
||||
|
||||
return $appUuid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ping the AzuraCast Central server to retrieve this installation's likely public-facing IP.
|
||||
*
|
||||
|
@ -86,7 +103,7 @@ class AzuraCastCentral
|
|||
public function getIp(bool $cached = true): ?string
|
||||
{
|
||||
$ip = ($cached)
|
||||
? $this->settingsRepo->getSetting(Entity\Settings::EXTERNAL_IP)
|
||||
? $this->settings->getExternalIp()
|
||||
: null;
|
||||
|
||||
if (empty($ip)) {
|
||||
|
@ -106,7 +123,8 @@ class AzuraCastCentral
|
|||
}
|
||||
|
||||
if (!empty($ip) && $cached) {
|
||||
$this->settingsRepo->setSetting(Entity\Settings::EXTERNAL_IP, $ip);
|
||||
$this->settings->setExternalIp($ip);
|
||||
$this->settingsTableRepo->writeSettings($this->settings);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,12 +16,12 @@ class Csrf
|
|||
|
||||
protected SessionInterface $session;
|
||||
|
||||
protected Environment $settings;
|
||||
protected Environment $environment;
|
||||
|
||||
public function __construct(SessionInterface $session, Environment $settings)
|
||||
public function __construct(SessionInterface $session, Environment $environment)
|
||||
{
|
||||
$this->session = $session;
|
||||
$this->settings = $settings;
|
||||
$this->environment = $environment;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -56,7 +56,7 @@ class Csrf
|
|||
*/
|
||||
public function verify(string $key, string $namespace = self::DEFAULT_NAMESPACE): void
|
||||
{
|
||||
if ($this->settings->isTesting()) {
|
||||
if ($this->environment->isTesting()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace App\Sync;
|
||||
|
||||
use App\Entity;
|
||||
use App\Entity\Repository\SettingsRepository;
|
||||
use App\Entity\Repository\SettingsTableRepository;
|
||||
use App\Environment;
|
||||
use App\Event\GetSyncTasks;
|
||||
use App\EventDispatcher;
|
||||
|
@ -17,19 +17,23 @@ class Runner
|
|||
{
|
||||
protected Logger $logger;
|
||||
|
||||
protected SettingsRepository $settingsRepo;
|
||||
protected Entity\Settings $settings;
|
||||
|
||||
protected SettingsTableRepository $settingsTableRepo;
|
||||
|
||||
protected LockFactory $lockFactory;
|
||||
|
||||
protected EventDispatcher $eventDispatcher;
|
||||
|
||||
public function __construct(
|
||||
SettingsRepository $settingsRepo,
|
||||
SettingsTableRepository $settingsRepo,
|
||||
Entity\Settings $settings,
|
||||
Logger $logger,
|
||||
LockFactory $lockFactory,
|
||||
EventDispatcher $eventDispatcher
|
||||
) {
|
||||
$this->settingsRepo = $settingsRepo;
|
||||
$this->settingsTableRepo = $settingsRepo;
|
||||
$this->settings = $settings;
|
||||
$this->logger = $logger;
|
||||
$this->lockFactory = $lockFactory;
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
|
@ -38,7 +42,7 @@ class Runner
|
|||
public function runSyncTask(string $type, bool $force = false): void
|
||||
{
|
||||
// Immediately halt if setup is not complete.
|
||||
if ($this->settingsRepo->getSetting(Entity\Settings::SETUP_COMPLETE, 0) == 0) {
|
||||
if (!$this->settings->isSetupComplete()) {
|
||||
die('Setup not complete; halting synchronized task.');
|
||||
}
|
||||
|
||||
|
@ -98,7 +102,8 @@ class Runner
|
|||
));
|
||||
}
|
||||
|
||||
$this->settingsRepo->setSetting($syncInfo['lastRunSetting'], time());
|
||||
$this->settings->updateSyncLastRunTime($type);
|
||||
$this->settingsTableRepo->writeSettings($this->settings);
|
||||
} finally {
|
||||
$lock->release();
|
||||
}
|
||||
|
@ -109,8 +114,6 @@ class Runner
|
|||
*/
|
||||
public function getSyncTimes(): array
|
||||
{
|
||||
$this->settingsRepo->clearCache();
|
||||
|
||||
$shortTaskTimeout = $_ENV['SYNC_SHORT_EXECUTION_TIME'] ?? 600;
|
||||
$longTaskTimeout = $_ENV['SYNC_LONG_EXECUTION_TIME'] ?? 1800;
|
||||
|
||||
|
@ -120,7 +123,6 @@ class Runner
|
|||
'contents' => [
|
||||
__('Now Playing Data'),
|
||||
],
|
||||
'lastRunSetting' => Entity\Settings::NOWPLAYING_LAST_RUN,
|
||||
'timeout' => $shortTaskTimeout,
|
||||
'interval' => 15,
|
||||
],
|
||||
|
@ -129,7 +131,6 @@ class Runner
|
|||
'contents' => [
|
||||
__('Song Requests Queue'),
|
||||
],
|
||||
'lastRunSetting' => Entity\Settings::SHORT_SYNC_LAST_RUN,
|
||||
'timeout' => $shortTaskTimeout,
|
||||
'interval' => 60,
|
||||
],
|
||||
|
@ -138,7 +139,6 @@ class Runner
|
|||
'contents' => [
|
||||
__('Check Media Folders'),
|
||||
],
|
||||
'lastRunSetting' => Entity\Settings::MEDIUM_SYNC_LAST_RUN,
|
||||
'timeout' => $shortTaskTimeout,
|
||||
'interval' => 300,
|
||||
],
|
||||
|
@ -148,14 +148,13 @@ class Runner
|
|||
__('Analytics/Statistics'),
|
||||
__('Cleanup'),
|
||||
],
|
||||
'lastRunSetting' => Entity\Settings::LONG_SYNC_LAST_RUN,
|
||||
'timeout' => $longTaskTimeout,
|
||||
'interval' => 3600,
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($syncs as &$sync_info) {
|
||||
$sync_info['latest'] = $this->settingsRepo->getSetting($sync_info['lastRunSetting'], 0);
|
||||
foreach ($syncs as $task => &$sync_info) {
|
||||
$sync_info['latest'] = $this->settings->getSyncLastRunTime($task);
|
||||
$sync_info['diff'] = time() - $sync_info['latest'];
|
||||
}
|
||||
|
||||
|
|
|
@ -10,18 +10,18 @@ abstract class AbstractTask
|
|||
{
|
||||
protected EntityManagerInterface $em;
|
||||
|
||||
protected Entity\Repository\SettingsRepository $settingsRepo;
|
||||
|
||||
protected LoggerInterface $logger;
|
||||
|
||||
protected Entity\Settings $settings;
|
||||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
LoggerInterface $logger
|
||||
LoggerInterface $logger,
|
||||
Entity\Settings $settings
|
||||
) {
|
||||
$this->em = $em;
|
||||
$this->settingsRepo = $settingsRepo;
|
||||
$this->logger = $logger;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
abstract public function run(bool $force = false): void;
|
||||
|
|
|
@ -16,12 +16,12 @@ class BuildQueueTask extends AbstractTask
|
|||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
LoggerInterface $logger,
|
||||
Entity\Settings $settings,
|
||||
AutoDJ $autoDJ,
|
||||
LockFactory $lockFactory
|
||||
) {
|
||||
parent::__construct($em, $settingsRepo, $logger);
|
||||
parent::__construct($em, $logger, $settings);
|
||||
|
||||
$this->autoDJ = $autoDJ;
|
||||
$this->lockFactory = $lockFactory;
|
||||
|
|
|
@ -18,13 +18,13 @@ class CheckFolderPlaylistsTask extends AbstractTask
|
|||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
LoggerInterface $logger,
|
||||
Entity\Settings $settings,
|
||||
Entity\Repository\StationPlaylistMediaRepository $spmRepo,
|
||||
Entity\Repository\StationPlaylistFolderRepository $folderRepo,
|
||||
FilesystemManager $filesystem
|
||||
) {
|
||||
parent::__construct($em, $settingsRepo, $logger);
|
||||
parent::__construct($em, $logger, $settings);
|
||||
|
||||
$this->spmRepo = $spmRepo;
|
||||
$this->folderRepo = $folderRepo;
|
||||
|
|
|
@ -31,15 +31,15 @@ class CheckMediaTask extends AbstractTask
|
|||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
LoggerInterface $logger,
|
||||
Entity\Settings $settings,
|
||||
Entity\Repository\StationMediaRepository $mediaRepo,
|
||||
Entity\Repository\StorageLocationRepository $storageLocationRepo,
|
||||
FilesystemManager $filesystem,
|
||||
MessageBus $messageBus,
|
||||
QueueManager $queueManager
|
||||
) {
|
||||
parent::__construct($em, $settingsRepo, $logger);
|
||||
parent::__construct($em, $logger, $settings);
|
||||
|
||||
$this->storageLocationRepo = $storageLocationRepo;
|
||||
$this->mediaRepo = $mediaRepo;
|
||||
|
|
|
@ -20,13 +20,13 @@ class CheckRequests extends AbstractTask
|
|||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
LoggerInterface $logger,
|
||||
Entity\Settings $settings,
|
||||
Entity\Repository\StationRequestRepository $requestRepo,
|
||||
Adapters $adapters,
|
||||
EventDispatcher $dispatcher
|
||||
) {
|
||||
parent::__construct($em, $settingsRepo, $logger);
|
||||
parent::__construct($em, $logger, $settings);
|
||||
|
||||
$this->requestRepo = $requestRepo;
|
||||
$this->dispatcher = $dispatcher;
|
||||
|
|
|
@ -15,21 +15,25 @@ class CheckUpdatesTask extends AbstractTask
|
|||
|
||||
protected AzuraCastCentral $azuracastCentral;
|
||||
|
||||
protected Entity\Repository\SettingsTableRepository $settingsTableRepo;
|
||||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
LoggerInterface $logger,
|
||||
Entity\Settings $settings,
|
||||
Entity\Repository\SettingsTableRepository $settingsTableRepo,
|
||||
AzuraCastCentral $azuracastCentral
|
||||
) {
|
||||
parent::__construct($em, $settingsRepo, $logger);
|
||||
parent::__construct($em, $logger, $settings);
|
||||
|
||||
$this->settingsTableRepo = $settingsTableRepo;
|
||||
$this->azuracastCentral = $azuracastCentral;
|
||||
}
|
||||
|
||||
public function run(bool $force = false): void
|
||||
{
|
||||
if (!$force) {
|
||||
$update_last_run = (int)$this->settingsRepo->getSetting(Entity\Settings::UPDATE_LAST_RUN, 0);
|
||||
$update_last_run = $this->settings->getUpdateLastRun();
|
||||
|
||||
if ($update_last_run > (time() - self::UPDATE_THRESHOLD)) {
|
||||
$this->logger->debug('Not checking for updates; checked too recently.');
|
||||
|
@ -46,7 +50,9 @@ class CheckUpdatesTask extends AbstractTask
|
|||
$updates = $this->azuracastCentral->checkForUpdates();
|
||||
|
||||
if (!empty($updates)) {
|
||||
$this->settingsRepo->setSetting(Entity\Settings::UPDATE_RESULTS, $updates);
|
||||
$this->settings->setUpdateResults($updates);
|
||||
$this->settingsTableRepo->writeSettings($this->settings);
|
||||
|
||||
$this->logger->info('Successfully checked for updates.', ['results' => $updates]);
|
||||
} else {
|
||||
$this->logger->error('Error parsing update data response from AzuraCast central.');
|
||||
|
@ -56,6 +62,7 @@ class CheckUpdatesTask extends AbstractTask
|
|||
return;
|
||||
}
|
||||
|
||||
$this->settingsRepo->setSetting(Entity\Settings::UPDATE_LAST_RUN, time());
|
||||
$this->settings->updateUpdateLastRun();
|
||||
$this->settingsTableRepo->writeSettings($this->settings);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,12 +14,12 @@ class CleanupHistoryTask extends AbstractTask
|
|||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
LoggerInterface $logger,
|
||||
Entity\Settings $settings,
|
||||
Entity\Repository\SongHistoryRepository $historyRepo,
|
||||
Entity\Repository\ListenerRepository $listenerRepo
|
||||
) {
|
||||
parent::__construct($em, $settingsRepo, $logger);
|
||||
parent::__construct($em, $logger, $settings);
|
||||
|
||||
$this->historyRepo = $historyRepo;
|
||||
$this->listenerRepo = $listenerRepo;
|
||||
|
@ -27,10 +27,7 @@ class CleanupHistoryTask extends AbstractTask
|
|||
|
||||
public function run(bool $force = false): void
|
||||
{
|
||||
$daysToKeep = (int)$this->settingsRepo->getSetting(
|
||||
Entity\Settings::HISTORY_KEEP_DAYS,
|
||||
Entity\SongHistory::DEFAULT_DAYS_TO_KEEP
|
||||
);
|
||||
$daysToKeep = $this->settings->getHistoryKeepDays();
|
||||
|
||||
if ($daysToKeep !== 0) {
|
||||
$this->historyRepo->cleanup($daysToKeep);
|
||||
|
|
|
@ -15,11 +15,11 @@ class CleanupStorageTask extends AbstractTask
|
|||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
LoggerInterface $logger,
|
||||
Entity\Settings $settings,
|
||||
FilesystemManager $filesystem
|
||||
) {
|
||||
parent::__construct($em, $settingsRepo, $logger);
|
||||
parent::__construct($em, $logger, $settings);
|
||||
|
||||
$this->filesystem = $filesystem;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,8 @@ class NowPlayingTask extends AbstractTask implements EventSubscriberInterface
|
|||
|
||||
protected Entity\Repository\ListenerRepository $listenerRepo;
|
||||
|
||||
protected Entity\Repository\SettingsTableRepository $settingsTableRepo;
|
||||
|
||||
protected LockFactory $lockFactory;
|
||||
|
||||
protected Entity\ApiGenerator\NowPlayingApiGenerator $nowPlayingApiGenerator;
|
||||
|
@ -51,8 +53,8 @@ class NowPlayingTask extends AbstractTask implements EventSubscriberInterface
|
|||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Entity\Repository\SettingsRepository $settingsRepository,
|
||||
LoggerInterface $logger,
|
||||
Entity\Settings $settings,
|
||||
Adapters $adapters,
|
||||
AutoDJ $autodj,
|
||||
CacheInterface $cache,
|
||||
|
@ -62,9 +64,10 @@ class NowPlayingTask extends AbstractTask implements EventSubscriberInterface
|
|||
RouterInterface $router,
|
||||
Entity\Repository\ListenerRepository $listenerRepository,
|
||||
Entity\Repository\StationQueueRepository $queueRepo,
|
||||
Entity\Repository\SettingsTableRepository $settingsTableRepo,
|
||||
Entity\ApiGenerator\NowPlayingApiGenerator $nowPlayingApiGenerator
|
||||
) {
|
||||
parent::__construct($em, $settingsRepository, $logger);
|
||||
parent::__construct($em, $logger, $settings);
|
||||
|
||||
$this->adapters = $adapters;
|
||||
$this->autodj = $autodj;
|
||||
|
@ -76,10 +79,11 @@ class NowPlayingTask extends AbstractTask implements EventSubscriberInterface
|
|||
|
||||
$this->listenerRepo = $listenerRepository;
|
||||
$this->queueRepo = $queueRepo;
|
||||
$this->settingsTableRepo = $settingsTableRepo;
|
||||
|
||||
$this->nowPlayingApiGenerator = $nowPlayingApiGenerator;
|
||||
|
||||
$this->analyticsLevel = (string)$settingsRepository->getSetting('analytics', Entity\Analytics::LEVEL_ALL);
|
||||
$this->analyticsLevel = $settings->getAnalytics();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,8 +107,10 @@ class NowPlayingTask extends AbstractTask implements EventSubscriberInterface
|
|||
{
|
||||
$nowplaying = $this->loadNowPlaying($force);
|
||||
|
||||
$this->cache->set(Entity\Settings::NOWPLAYING, $nowplaying, 120);
|
||||
$this->settingsRepo->setSetting(Entity\Settings::NOWPLAYING, $nowplaying);
|
||||
$this->cache->set('nowplaying', $nowplaying, 120);
|
||||
|
||||
$this->settings->setNowplaying($nowplaying);
|
||||
$this->settingsTableRepo->writeSettings($this->settings);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -12,11 +12,11 @@ class ReactivateStreamerTask extends AbstractTask
|
|||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
LoggerInterface $logger,
|
||||
Entity\Settings $settings,
|
||||
Entity\Repository\StationStreamerRepository $streamerRepo
|
||||
) {
|
||||
parent::__construct($em, $settingsRepo, $logger);
|
||||
parent::__construct($em, $logger, $settings);
|
||||
|
||||
$this->streamerRepo = $streamerRepo;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ use Symfony\Component\Finder\Finder;
|
|||
|
||||
class RotateLogsTask extends AbstractTask
|
||||
{
|
||||
protected Environment $appSettings;
|
||||
protected Environment $environment;
|
||||
|
||||
protected Adapters $adapters;
|
||||
|
||||
|
@ -23,16 +23,16 @@ class RotateLogsTask extends AbstractTask
|
|||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
LoggerInterface $logger,
|
||||
Environment $appSettings,
|
||||
Entity\Settings $settings,
|
||||
Environment $environment,
|
||||
Adapters $adapters,
|
||||
Supervisor $supervisor,
|
||||
Entity\Repository\StorageLocationRepository $storageLocationRepo
|
||||
) {
|
||||
parent::__construct($em, $settingsRepo, $logger);
|
||||
parent::__construct($em, $logger, $settings);
|
||||
|
||||
$this->appSettings = $appSettings;
|
||||
$this->environment = $environment;
|
||||
$this->adapters = $adapters;
|
||||
$this->supervisor = $supervisor;
|
||||
$this->storageLocationRepo = $storageLocationRepo;
|
||||
|
@ -57,19 +57,16 @@ class RotateLogsTask extends AbstractTask
|
|||
}
|
||||
|
||||
// Rotate the main AzuraCast log.
|
||||
$rotate = new Rotate\Rotate($this->appSettings->getTempDirectory() . '/app.log');
|
||||
$rotate = new Rotate\Rotate($this->environment->getTempDirectory() . '/app.log');
|
||||
$rotate->keep(5);
|
||||
$rotate->size('5MB');
|
||||
$rotate->run();
|
||||
|
||||
// Rotate the automated backups.
|
||||
$backups_to_keep = (int)$this->settingsRepo->getSetting(Entity\Settings::BACKUP_KEEP_COPIES, 0);
|
||||
$backups_to_keep = $this->settings->getBackupKeepCopies();
|
||||
|
||||
if ($backups_to_keep > 0) {
|
||||
$backupStorageId = (int)$this->settingsRepo->getSetting(
|
||||
Entity\Settings::BACKUP_STORAGE_LOCATION,
|
||||
null
|
||||
);
|
||||
$backupStorageId = (int)$this->settings->getBackupStorageLocation();
|
||||
|
||||
if ($backupStorageId > 0) {
|
||||
$storageLocation = $this->storageLocationRepo->findByType(
|
||||
|
|
|
@ -17,13 +17,13 @@ class RunAnalyticsTask extends AbstractTask
|
|||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
LoggerInterface $logger,
|
||||
Entity\Settings $settings,
|
||||
Entity\Repository\AnalyticsRepository $analyticsRepo,
|
||||
Entity\Repository\ListenerRepository $listenerRepo,
|
||||
Entity\Repository\SongHistoryRepository $historyRepo
|
||||
) {
|
||||
parent::__construct($em, $settingsRepo, $logger);
|
||||
parent::__construct($em, $logger, $settings);
|
||||
|
||||
$this->analyticsRepo = $analyticsRepo;
|
||||
$this->listenerRepo = $listenerRepo;
|
||||
|
@ -32,7 +32,7 @@ class RunAnalyticsTask extends AbstractTask
|
|||
|
||||
public function run(bool $force = false): void
|
||||
{
|
||||
$analytics_level = $this->settingsRepo->getSetting('analytics', Entity\Analytics::LEVEL_ALL);
|
||||
$analytics_level = $this->settings->getAnalytics();
|
||||
|
||||
switch ($analytics_level) {
|
||||
case Entity\Analytics::LEVEL_NONE:
|
||||
|
|
|
@ -20,12 +20,12 @@ class RunAutomatedAssignmentTask extends AbstractTask
|
|||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
LoggerInterface $logger,
|
||||
Entity\Settings $settings,
|
||||
Entity\Repository\StationMediaRepository $mediaRepo,
|
||||
Adapters $adapters
|
||||
) {
|
||||
parent::__construct($em, $settingsRepo, $logger);
|
||||
parent::__construct($em, $logger, $settings);
|
||||
|
||||
$this->mediaRepo = $mediaRepo;
|
||||
$this->adapters = $adapters;
|
||||
|
|
|
@ -19,17 +19,21 @@ class RunBackupTask extends AbstractTask
|
|||
|
||||
protected Application $console;
|
||||
|
||||
protected Entity\Repository\SettingsTableRepository $settingsTableRepo;
|
||||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
LoggerInterface $logger,
|
||||
Entity\Settings $settings,
|
||||
MessageBus $messageBus,
|
||||
Application $console
|
||||
Application $console,
|
||||
Entity\Repository\SettingsTableRepository $settingsTableRepo
|
||||
) {
|
||||
parent::__construct($em, $settingsRepo, $logger);
|
||||
parent::__construct($em, $logger, $settings);
|
||||
|
||||
$this->messageBus = $messageBus;
|
||||
$this->console = $console;
|
||||
$this->settingsTableRepo = $settingsTableRepo;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -40,7 +44,8 @@ class RunBackupTask extends AbstractTask
|
|||
public function __invoke(Message\AbstractMessage $message): void
|
||||
{
|
||||
if ($message instanceof Message\BackupMessage) {
|
||||
$this->settingsRepo->setSetting(Entity\Settings::BACKUP_LAST_RUN, time());
|
||||
$this->settings->updateBackupLastRun();
|
||||
$this->settingsTableRepo->writeSettings($this->settings);
|
||||
|
||||
[$result_code, $result_output] = $this->runBackup(
|
||||
$message->path,
|
||||
|
@ -49,8 +54,9 @@ class RunBackupTask extends AbstractTask
|
|||
$message->storageLocationId
|
||||
);
|
||||
|
||||
$this->settingsRepo->setSetting(Entity\Settings::BACKUP_LAST_RESULT, $result_code);
|
||||
$this->settingsRepo->setSetting(Entity\Settings::BACKUP_LAST_OUTPUT, $result_output);
|
||||
$this->settings->setBackupLastResult($result_code);
|
||||
$this->settings->setBackupLastOutput($result_output);
|
||||
$this->settingsTableRepo->writeSettings($this->settings);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,7 +94,7 @@ class RunBackupTask extends AbstractTask
|
|||
|
||||
public function run(bool $force = false): void
|
||||
{
|
||||
$backup_enabled = (bool)$this->settingsRepo->getSetting(Entity\Settings::BACKUP_ENABLED, false);
|
||||
$backup_enabled = $this->settings->isBackupEnabled();
|
||||
if (!$backup_enabled) {
|
||||
$this->logger->debug('Automated backups disabled; skipping...');
|
||||
return;
|
||||
|
@ -97,11 +103,11 @@ class RunBackupTask extends AbstractTask
|
|||
$now_utc = CarbonImmutable::now('UTC');
|
||||
|
||||
$threshold = $now_utc->subDay()->getTimestamp();
|
||||
$last_run = $this->settingsRepo->getSetting(Entity\Settings::BACKUP_LAST_RUN, 0);
|
||||
$last_run = $this->settings->getBackupLastRun();
|
||||
|
||||
if ($last_run <= $threshold) {
|
||||
// Check if the backup time matches (if it's set).
|
||||
$backupTimecode = $this->settingsRepo->getSetting(Entity\Settings::BACKUP_TIME, null);
|
||||
$backupTimecode = $this->settings->getBackupTimeCode();
|
||||
|
||||
if (null !== $backupTimecode && '' !== $backupTimecode) {
|
||||
$isWithinTimecode = false;
|
||||
|
@ -128,10 +134,7 @@ class RunBackupTask extends AbstractTask
|
|||
}
|
||||
|
||||
// Trigger a new backup.
|
||||
$storageLocationId = (int)$this->settingsRepo->getSetting(
|
||||
Entity\Settings::BACKUP_STORAGE_LOCATION,
|
||||
0
|
||||
);
|
||||
$storageLocationId = (int)($this->settings->getBackupStorageLocation() ?? 0);
|
||||
if ($storageLocationId <= 0) {
|
||||
$storageLocationId = null;
|
||||
}
|
||||
|
@ -139,7 +142,7 @@ class RunBackupTask extends AbstractTask
|
|||
$message = new Message\BackupMessage();
|
||||
$message->storageLocationId = $storageLocationId;
|
||||
$message->path = 'automatic_backup.zip';
|
||||
$message->excludeMedia = (bool)$this->settingsRepo->getSetting(Entity\Settings::BACKUP_EXCLUDE_MEDIA, 0);
|
||||
$message->excludeMedia = $this->settings->getBackupExcludeMedia();
|
||||
|
||||
$this->messageBus->dispatch($message);
|
||||
}
|
||||
|
|
|
@ -21,23 +21,27 @@ class UpdateGeoLiteTask extends AbstractTask
|
|||
|
||||
protected IpGeolocation $geoLite;
|
||||
|
||||
protected Entity\Repository\SettingsTableRepository $settingsTableRepo;
|
||||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
Entity\Repository\SettingsRepository $settingsRepo,
|
||||
LoggerInterface $logger,
|
||||
Entity\Settings $settings,
|
||||
Client $httpClient,
|
||||
IpGeolocation $geoLite
|
||||
IpGeolocation $geoLite,
|
||||
Entity\Repository\SettingsTableRepository $settingsTableRepo
|
||||
) {
|
||||
parent::__construct($em, $settingsRepo, $logger);
|
||||
parent::__construct($em, $logger, $settings);
|
||||
|
||||
$this->httpClient = $httpClient;
|
||||
$this->geoLite = $geoLite;
|
||||
$this->settingsTableRepo = $settingsTableRepo;
|
||||
}
|
||||
|
||||
public function run(bool $force = false): void
|
||||
{
|
||||
if (!$force) {
|
||||
$lastRun = (int)$this->settingsRepo->getSetting(Entity\Settings::GEOLITE_LAST_RUN, 0);
|
||||
$lastRun = $this->settings->getGeoliteLastRun();
|
||||
|
||||
if ($lastRun > (time() - self::UPDATE_THRESHOLD)) {
|
||||
$this->logger->debug('Not checking for updates; checked too recently.');
|
||||
|
@ -55,12 +59,13 @@ class UpdateGeoLiteTask extends AbstractTask
|
|||
]);
|
||||
}
|
||||
|
||||
$this->settingsRepo->setSetting(Entity\Settings::GEOLITE_LAST_RUN, time());
|
||||
$this->settings->updateGeoliteLastRun();
|
||||
$this->settingsTableRepo->writeSettings($this->settings);
|
||||
}
|
||||
|
||||
public function updateDatabase(): void
|
||||
{
|
||||
$licenseKey = trim($this->settingsRepo->getSetting(Entity\Settings::GEOLITE_LICENSE_KEY));
|
||||
$licenseKey = trim($this->settings->getGeoliteLicenseKey());
|
||||
|
||||
if (empty($licenseKey)) {
|
||||
$this->logger->info('Not checking for GeoLite updates; no license key provided.');
|
||||
|
|
|
@ -15,6 +15,13 @@ trait AvailableStaticallyTrait
|
|||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public static function hasInstance(): bool
|
||||
{
|
||||
return isset(self::$instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param static $instance
|
||||
*/
|
||||
|
|
|
@ -23,18 +23,22 @@ class LocalWebhookHandler
|
|||
|
||||
protected CacheInterface $cache;
|
||||
|
||||
protected Entity\Repository\SettingsRepository $settingsRepo;
|
||||
protected Entity\Settings $settings;
|
||||
|
||||
protected Entity\Repository\SettingsTableRepository $settingsTableRepo;
|
||||
|
||||
public function __construct(
|
||||
Logger $logger,
|
||||
Client $httpClient,
|
||||
CacheInterface $cache,
|
||||
Entity\Repository\SettingsRepository $settingsRepo
|
||||
Entity\Settings $settings,
|
||||
Entity\Repository\SettingsTableRepository $settingsTableRepo
|
||||
) {
|
||||
$this->logger = $logger;
|
||||
$this->httpClient = $httpClient;
|
||||
$this->cache = $cache;
|
||||
$this->settingsRepo = $settingsRepo;
|
||||
$this->settings = $settings;
|
||||
$this->settingsTableRepo = $settingsTableRepo;
|
||||
}
|
||||
|
||||
public function dispatch(SendWebhooks $event): void
|
||||
|
@ -46,7 +50,7 @@ class LocalWebhookHandler
|
|||
// Replace the relevant station information in the cache and database.
|
||||
$this->logger->debug('Updating NowPlaying cache...');
|
||||
|
||||
$np_full = $this->cache->get('api_nowplaying_data');
|
||||
$np_full = $this->cache->get('nowplaying');
|
||||
|
||||
if ($np_full) {
|
||||
$np_new = [];
|
||||
|
@ -59,8 +63,10 @@ class LocalWebhookHandler
|
|||
}
|
||||
}
|
||||
|
||||
$this->cache->set('api_nowplaying_data', $np_new, 120);
|
||||
$this->settingsRepo->setSetting('nowplaying', $np_new);
|
||||
$this->cache->set('nowplaying', $np_new, 120);
|
||||
|
||||
$this->settings->setNowplaying($np_new);
|
||||
$this->settingsTableRepo->writeSettings($this->settings);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ $this->layout('minimal', [
|
|||
<?php if ($customization->hideProductName()): ?>
|
||||
<?=__('Welcome!')?>
|
||||
<?php else: ?>
|
||||
<?=sprintf(__('Welcome to %s!'), $settings['name'])?>
|
||||
<?=sprintf(__('Welcome to %s!'), $environment['name'])?>
|
||||
<?php endif; ?>
|
||||
</h2>
|
||||
<h3 class="text-center">
|
||||
|
|
|
@ -153,7 +153,7 @@ $user = $request->getUser();
|
|||
|
||||
<footer id="footer" <?php if (empty($sidebar)): ?>class="footer-alt"<?php endif; ?> role="contentinfo">
|
||||
<?=__('Powered by %s',
|
||||
'<a href="https://www.azuracast.com/" target="_blank">' . $settings['name'] . '</a> • ' . $version->getVersionText() . ' • ' . ($environment->isDocker() ? 'Docker' : 'Ansible') . ' • PHP ' . \PHP_MAJOR_VERSION . '.' . \PHP_MINOR_VERSION)?>
|
||||
'<a href="https://www.azuracast.com/" target="_blank">' . $environment['name'] . '</a> • ' . $version->getVersionText() . ' • ' . ($environment->isDocker() ? 'Docker' : 'Ansible') . ' • PHP ' . \PHP_MAJOR_VERSION . '.' . \PHP_MINOR_VERSION)?>
|
||||
<br>
|
||||
<?=__('Like our software? <a href="%s" target="_blank">Donate to support AzuraCast!</a>',
|
||||
'https://www.azuracast.com/donate.html')?>
|
||||
|
|
|
@ -46,7 +46,7 @@ $page_class .= ' theme-' . $customization->getPublicTheme();
|
|||
<?php if (!$customization->hideProductName() && !$hide_footer): ?>
|
||||
<footer id="footer" class="footer-alt" role="contentinfo">
|
||||
<?=sprintf(__('Powered by %s'),
|
||||
'<a href="https://azuracast.com/" target="_blank">' . $settings['name'] . '</a>' . ' ')?><br>
|
||||
'<a href="https://azuracast.com/" target="_blank">' . $environment['name'] . '</a>' . ' ')?><br>
|
||||
<?=sprintf(__('Mascot designed by %s'),
|
||||
'<a href="https://tysontan.deviantart.com/" target="_blank">Tyson Tan</a>')?>
|
||||
</footer>
|
||||
|
|
|
@ -5,7 +5,7 @@ $props = [
|
|||
'locale' => substr($customization->getLocale(), 0, 2),
|
||||
'filesUrl' => $router->fromHere('stations:files:index'),
|
||||
'stationTimeZone' => $station_tz,
|
||||
'enableAdvancedFeatures' => $settings->enableAdvancedFeatures(),
|
||||
'enableAdvancedFeatures' => $environment->enableAdvancedFeatures(),
|
||||
]
|
||||
?>
|
||||
var station_playlists;
|
||||
|
@ -19,4 +19,4 @@ $(function () {
|
|||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -10,7 +10,7 @@ abstract class CestAbstract
|
|||
|
||||
protected App\Environment $environment;
|
||||
|
||||
protected Entity\Repository\SettingsRepository $settingsRepo;
|
||||
protected Entity\Repository\SettingsTableRepository $settingsTableRepo;
|
||||
|
||||
protected Entity\Repository\StationRepository $stationRepo;
|
||||
|
||||
|
@ -25,7 +25,7 @@ abstract class CestAbstract
|
|||
$this->di = $tests_module->container;
|
||||
$this->em = $tests_module->em;
|
||||
|
||||
$this->settingsRepo = $this->di->get(Entity\Repository\SettingsRepository::class);
|
||||
$this->settingsTableRepo = $this->di->get(Entity\Repository\SettingsTableRepository::class);
|
||||
$this->stationRepo = $this->di->get(Entity\Repository\StationRepository::class);
|
||||
$this->environment = $this->di->get(App\Environment::class);
|
||||
}
|
||||
|
@ -48,7 +48,10 @@ abstract class CestAbstract
|
|||
{
|
||||
$I->wantTo('Start with an incomplete setup.');
|
||||
|
||||
$this->settingsRepo->setSetting('setup_complete', 0);
|
||||
$settings = $this->settingsTableRepo->readSettings(false);
|
||||
$settings->setSetupCompleteTime(0);
|
||||
$this->settingsTableRepo->writeSettings($settings);
|
||||
|
||||
$this->_cleanTables();
|
||||
}
|
||||
|
||||
|
@ -89,8 +92,10 @@ abstract class CestAbstract
|
|||
$this->test_station = $this->stationRepo->create($test_station);
|
||||
|
||||
// Set settings.
|
||||
$this->settingsRepo->setSetting('setup_complete', time());
|
||||
$this->settingsRepo->setSetting('base_url', 'localhost');
|
||||
$settings = $this->settingsTableRepo->readSettings(false);
|
||||
$settings->updateSetupComplete();
|
||||
$settings->setBaseUrl('localhost');
|
||||
$this->settingsTableRepo->writeSettings($settings);
|
||||
}
|
||||
|
||||
protected function getTestStation(): Entity\Station
|
||||
|
|
Loading…
Reference in New Issue