Move Settings and Logging to static system-wide functions.

This commit is contained in:
Buster "Silver Eagle" Neece 2019-09-12 00:31:01 -05:00
parent abc9930472
commit daf78fa738
No known key found for this signature in database
GPG Key ID: 6D9E12FF03411F4E
69 changed files with 331 additions and 359 deletions

28
composer.lock generated
View File

@ -8,16 +8,16 @@
"packages": [
{
"name": "aws/aws-sdk-php",
"version": "3.111.0",
"version": "3.111.2",
"source": {
"type": "git",
"url": "https://github.com/aws/aws-sdk-php.git",
"reference": "a31376012346118b2b88df6d2f0c185af71e3096"
"reference": "5e80d4bec17e197be494af4f38e1fcd17f728138"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/a31376012346118b2b88df6d2f0c185af71e3096",
"reference": "a31376012346118b2b88df6d2f0c185af71e3096",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/5e80d4bec17e197be494af4f38e1fcd17f728138",
"reference": "5e80d4bec17e197be494af4f38e1fcd17f728138",
"shasum": ""
},
"require": {
@ -87,7 +87,7 @@
"s3",
"sdk"
],
"time": "2019-09-09T18:13:28+00:00"
"time": "2019-09-11T18:16:47+00:00"
},
{
"name": "azuracast/azuracore",
@ -95,12 +95,12 @@
"source": {
"type": "git",
"url": "https://github.com/AzuraCast/azuracore.git",
"reference": "7fae6fe42c33350d2c16425512450aeac3fa939b"
"reference": "3f31357e03e91249c4284d579cf593891e206412"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/AzuraCast/azuracore/zipball/7fae6fe42c33350d2c16425512450aeac3fa939b",
"reference": "7fae6fe42c33350d2c16425512450aeac3fa939b",
"url": "https://api.github.com/repos/AzuraCast/azuracore/zipball/3f31357e03e91249c4284d579cf593891e206412",
"reference": "3f31357e03e91249c4284d579cf593891e206412",
"shasum": ""
},
"require": {
@ -154,7 +154,7 @@
}
],
"description": "A lightweight core application framework.",
"time": "2019-09-10T17:41:01+00:00"
"time": "2019-09-12T04:10:12+00:00"
},
{
"name": "azuracast/azuraforms",
@ -3650,16 +3650,16 @@
},
{
"name": "paragonie/sodium_compat",
"version": "v1.10.1",
"version": "v1.11.0",
"source": {
"type": "git",
"url": "https://github.com/paragonie/sodium_compat.git",
"reference": "5115fa44886d1c2785d2f135ef4626db868eac4b"
"reference": "fee1b6ea9c83dac7b4a17febf58fb712ada7dd6e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/sodium_compat/zipball/5115fa44886d1c2785d2f135ef4626db868eac4b",
"reference": "5115fa44886d1c2785d2f135ef4626db868eac4b",
"url": "https://api.github.com/repos/paragonie/sodium_compat/zipball/fee1b6ea9c83dac7b4a17febf58fb712ada7dd6e",
"reference": "fee1b6ea9c83dac7b4a17febf58fb712ada7dd6e",
"shasum": ""
},
"require": {
@ -3728,7 +3728,7 @@
"secret-key cryptography",
"side-channel resistant"
],
"time": "2019-07-12T16:36:59+00:00"
"time": "2019-09-11T23:58:35+00:00"
},
{
"name": "php-di/invoker",

View File

@ -1,4 +1,6 @@
<?php
use App\Settings;
use Psr\Http\Message\ServerRequestInterface as Request;
/**
@ -26,7 +28,7 @@ return [
'files' => [
'js' => [
[
'src' => 'dist/lib/vue/' . (APP_IN_PRODUCTION ? 'vue.min.js' : 'vue.js'),
'src' => 'dist/lib/vue/' . (Settings::getInstance()->isProduction() ? 'vue.min.js' : 'vue.js'),
],
],
],

View File

@ -3,7 +3,7 @@
* PHP-DI Services
*/
use Azura\Settings;
use App\Settings;
use Doctrine\ORM\EntityManager;
use Psr\Container\ContainerInterface;

View File

@ -23,12 +23,5 @@ parameters:
# Supervisor functions that do exist but aren't annotated properly in the connector lib.
- '#Call to an undefined method Supervisor\\Supervisor::reloadConfig().#'
dynamicConstantNames:
- APP_IS_COMMAND_LINE
- APP_INSIDE_DOCKER
- APP_TESTING_MODE
- APP_APPLICATION_ENV
- APP_IN_PRODUCTION
includes:
- vendor/phpstan/phpstan-doctrine/extension.neon

View File

@ -7,22 +7,36 @@ use Azura\App;
use Azura\Exception;
use Azura\Http\Factory\ResponseFactory;
use Azura\Http\Factory\ServerRequestFactory;
use Azura\Settings;
use Azura\Logger;
use Doctrine\Common\Annotations\AnnotationRegistry;
use DI;
use Psr\Log\LoggerInterface;
class AppFactory extends \Azura\AppFactory
{
/**
* @inheritDoc
*/
public static function create($autoloader = null, $settings = [], $diDefinitions = []): App
public static function create($autoloader = null, $appSettings = [], $diDefinitions = []): App
{
// Register Annotation autoloader
if (null !== $autoloader) {
AnnotationRegistry::registerLoader([$autoloader, 'loadClass']);
}
$settings = self::buildSettings($settings);
$settings = new Settings(self::buildSettings($appSettings));
Settings::setInstance($settings);
self::applyPhpSettings($settings);
// Helper constants for annotations.
/** @noinspection SummerTimeUnsafeTimeManipulationInspection */
define('SAMPLE_TIMESTAMP', random_int(time() - 86400, time() + 86400));
// Override DI definitions for settings.
$diDefinitions[Settings::class] = $settings;
$diDefinitions[\Azura\Settings::class] = DI\get(Settings::class);
$diDefinitions['settings'] = DI\get(Settings::class);
self::applyPhpSettings($settings);
@ -38,6 +52,8 @@ class AppFactory extends \Azura\AppFactory
$di = self::buildContainer($settings, $diDefinitions);
Logger::setInstance($di->get(LoggerInterface::class));
// Set Response/Request decoratorclasses.
ServerRequestFactory::setServerRequestClass(ServerRequest::class);
ResponseFactory::setResponseClass(Response::class);
@ -49,15 +65,10 @@ class AppFactory extends \Azura\AppFactory
self::updateRouteHandling($app);
self::buildRoutes($app);
$settings = $di->get(Settings::class);
define('APP_APPLICATION_ENV', $settings[Settings::APP_ENV]);
define('APP_IN_PRODUCTION', $settings->isProduction());
return $app;
}
protected static function buildSettings($settings): Settings
protected static function buildSettings(array $settings): array
{
if (!isset($settings[Settings::BASE_DIR])) {
throw new Exception\BootstrapException('No base directory specified!');
@ -65,22 +76,11 @@ class AppFactory extends \Azura\AppFactory
$settings[Settings::TEMP_DIR] = dirname($settings[Settings::BASE_DIR]) . '/www_tmp';
// Define the "helper" constants used by AzuraCast.
define('APP_IS_COMMAND_LINE', PHP_SAPI === 'cli');
$settings[Settings::IS_DOCKER] = file_exists(dirname($settings[Settings::BASE_DIR]) . '/.docker');
$settings[Settings::DOCKER_REVISION] = getenv('AZURACAST_DC_REVISION') ?? 1;
define('APP_INCLUDE_ROOT', $settings[Settings::BASE_DIR]);
define('APP_INCLUDE_TEMP', $settings[Settings::TEMP_DIR]);
define('APP_INSIDE_DOCKER', file_exists(dirname($settings[Settings::BASE_DIR]) . '/.docker'));
define('APP_DOCKER_REVISION', getenv('AZURACAST_DC_REVISION') ?? 1);
$settings[Settings::IS_DOCKER] = APP_INSIDE_DOCKER;
define('APP_TESTING_MODE',
(isset($settings[Settings::APP_ENV]) && Settings::ENV_TESTING === $settings[Settings::APP_ENV]));
// Constants used in annotations
define('SAMPLE_TIMESTAMP', rand(time() - 86400, time() + 86400));
$settings[Settings::CONFIG_DIR] = $settings[Settings::BASE_DIR].'/config';
$settings[Settings::VIEWS_DIR] = $settings[Settings::BASE_DIR].'/templates';
return parent::buildSettings($settings);
}

View File

@ -7,7 +7,7 @@ use App\Exception\NotLoggedInException;
use Azura\Exception;
use Azura\Session;
use Azura\Session\NamespaceInterface;
use Azura\Settings;
use App\Settings;
use Doctrine\ORM\EntityManager;
class Auth
@ -21,9 +21,6 @@ class Auth
/** @var NamespaceInterface */
protected $session_namespace;
/** @var Settings */
protected $settings;
/** @var UserRepository */
protected $user_repo;
@ -36,19 +33,15 @@ class Auth
/**
* @param Session $session
* @param EntityManager $em
* @param Settings $settings
*/
public function __construct(
Session $session,
EntityManager $em,
Settings $settings
EntityManager $em
) {
$this->user_repo = $em->getRepository(User::class);
$this->session = $session;
$this->session_namespace = $this->session->get('auth');
$this->settings = $settings;
}
/**
@ -134,7 +127,7 @@ class Auth
*/
public function isLoggedIn(): bool
{
if (APP_IS_COMMAND_LINE && !APP_TESTING_MODE) {
if (Settings::getInstance()->isCli() && !Settings::getInstance()->isTesting()) {
return false;
}

View File

@ -3,7 +3,7 @@ namespace App\Console\Command;
use App\Version;
use Azura\Console\Command\CommandAbstract;
use Azura\Settings;
use App\Settings;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

View File

@ -2,7 +2,7 @@
namespace App\Console\Command;
use Azura\Console\Command\CommandAbstract;
use Azura\Settings;
use App\Settings;
use Gettext\Translations;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;

View File

@ -2,7 +2,7 @@
namespace App\Console\Command;
use Azura\Console\Command\CommandAbstract;
use Azura\Settings;
use App\Settings;
use Gettext\Translations;
use Symfony\Component\Console\Style\SymfonyStyle;

View File

@ -2,7 +2,7 @@
namespace App\Console\Command;
use Azura\Console\Command\CommandAbstract;
use Azura\Settings;
use App\Settings;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

View File

@ -4,7 +4,7 @@ namespace App\Console\Command;
use App\Entity;
use App\Service\AzuraCastCentral;
use Azura\Console\Command\CommandAbstract;
use Azura\Settings;
use App\Settings;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;

View File

@ -3,7 +3,7 @@ namespace App\Console\Command;
use App\Entity\Station;
use Azura\Console\Command\CommandAbstract;
use Azura\Settings;
use App\Settings;
use Cake\Chronos\Chronos;
use Doctrine\Common\DataFixtures\Executor\ORMExecutor;
use Doctrine\Common\DataFixtures\Loader;

View File

@ -2,7 +2,7 @@
namespace App\Console\Command;
use Azura\Console\Command\CommandAbstract;
use Azura\Settings;
use App\Settings;
use InfluxDB\Database;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

View File

@ -5,7 +5,7 @@ use App\Form\SettingsForm;
use App\Http\Response;
use App\Http\ServerRequest;
use Azura\Config;
use Azura\Settings;
use App\Settings;
use Doctrine\ORM\EntityManager;
use Psr\Http\Message\ResponseInterface;

View File

@ -6,6 +6,7 @@ use App\Http\Response;
use App\Http\ServerRequest;
use App\Radio\Quota;
use App\Sync\Runner;
use App\Settings;
use Brick\Math\BigInteger;
use Monolog\Handler\TestHandler;
use Monolog\Logger;
@ -54,7 +55,7 @@ class IndexController
]);
}
$stations_base_dir = dirname(APP_INCLUDE_ROOT) . '/stations';
$stations_base_dir = Settings::getInstance()->getStationDirectory();
$space_total = BigInteger::of(disk_total_space($stations_base_dir));
$space_free = BigInteger::of(disk_free_space($stations_base_dir));

View File

@ -6,6 +6,7 @@ use App\Http\Response;
use App\Http\ServerRequest;
use App\Radio\Frontend\SHOUTcast;
use Azura\Config;
use App\Settings;
use Exception;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\UploadedFileInterface;
@ -40,7 +41,7 @@ class InstallShoutcastController
if ('POST' === $request->getMethod() && $form->isValid($_POST)) {
try {
$sc_base_dir = dirname(APP_INCLUDE_ROOT) . '/servers/shoutcast2';
$sc_base_dir = Settings::getInstance()->getParentDirectory() . '/servers/shoutcast2';
$files = $request->getUploadedFiles();
/** @var UploadedFileInterface $import_file */

View File

@ -5,6 +5,7 @@ use App\Controller\Traits\LogViewerTrait;
use App\Entity;
use App\Http\Response;
use App\Http\ServerRequest;
use App\Settings;
use Azura\Exception;
use Doctrine\ORM\EntityManager;
use Psr\Http\Message\ResponseInterface;
@ -45,38 +46,39 @@ class LogsController
protected function _getGlobalLogs(): array
{
$log_paths = [];
$tempDir = Settings::getInstance()->getTempDirectory();
$logPaths = [];
$log_paths['azuracast_log'] = [
$logPaths['azuracast_log'] = [
'name' => __('AzuraCast Application Log'),
'path' => APP_INCLUDE_TEMP . '/app.log',
'path' => $tempDir . '/app.log',
'tail' => true,
];
if (!APP_INSIDE_DOCKER) {
$log_paths['nginx_access'] = [
if (!Settings::getInstance()->isDocker()) {
$logPaths['nginx_access'] = [
'name' => __('Nginx Access Log'),
'path' => APP_INCLUDE_TEMP . '/access.log',
'path' => $tempDir . '/access.log',
'tail' => true,
];
$log_paths['nginx_error'] = [
$logPaths['nginx_error'] = [
'name' => __('Nginx Error Log'),
'path' => APP_INCLUDE_TEMP . '/error.log',
'path' => $tempDir . '/error.log',
'tail' => true,
];
$log_paths['php'] = [
$logPaths['php'] = [
'name' => __('PHP Application Log'),
'path' => APP_INCLUDE_TEMP . '/php_errors.log',
'path' => $tempDir . '/php_errors.log',
'tail' => true,
];
$log_paths['supervisord'] = [
$logPaths['supervisord'] = [
'name' => __('Supervisord Log'),
'path' => APP_INCLUDE_TEMP . '/supervisord.log',
'path' => $tempDir . '/supervisord.log',
'tail' => true,
];
}
return $log_paths;
return $logPaths;
}
public function viewAction(ServerRequest $request, Response $response, $station_id, $log): ResponseInterface

View File

@ -4,7 +4,7 @@ namespace App\Controller\Api;
use App\Http\Response;
use App\Http\ServerRequest;
use App\Version;
use Azura\Settings;
use App\Settings;
use Psr\Http\Message\ResponseInterface;
use function OpenApi\scan;

View File

@ -7,7 +7,7 @@ use App\Form\Form;
use App\Http\Response;
use App\Http\ServerRequest;
use Azura\Config;
use Azura\Settings;
use App\Settings;
use AzuraForms\Field\AbstractField;
use BaconQrCode;
use Doctrine\ORM\EntityManager;

View File

@ -9,6 +9,7 @@ use App\Form\Form;
use App\Form\StationForm;
use App\Http\Response;
use App\Http\ServerRequest;
use App\Settings;
use Azura\Config;
use Doctrine\ORM\EntityManager;
use Psr\Http\Message\ResponseInterface;
@ -30,25 +31,31 @@ class SetupController
/** @var array */
protected $settings_form_config;
/** @var Settings */
protected $settings;
/**
* @param EntityManager $em
* @param Auth $auth
* @param Acl $acl
* @param StationForm $station_form
* @param Config $config
* @param Settings $settings
*/
public function __construct(
EntityManager $em,
Auth $auth,
Acl $acl,
StationForm $station_form,
Config $config
Config $config,
Settings $settings
) {
$this->em = $em;
$this->auth = $auth;
$this->acl = $acl;
$this->station_form = $station_form;
$this->settings_form_config = $config->get('forms/settings');
$this->settings = $settings;
}
/**
@ -126,7 +133,7 @@ class SetupController
{
// Verify current step.
$current_step = $this->_getSetupStep();
if ($current_step !== 'register' && APP_IN_PRODUCTION) {
if ($current_step !== 'register' && $this->settings->isProduction()) {
return $response->withRedirect($request->getRouter()->named('setup:' . $current_step));
}
@ -179,7 +186,7 @@ class SetupController
{
// Verify current step.
$current_step = $this->_getSetupStep();
if ($current_step !== 'station' && APP_IN_PRODUCTION) {
if ($current_step !== 'station' && $this->settings->isProduction()) {
return $response->withRedirect($request->getRouter()->named('setup:' . $current_step));
}
@ -204,7 +211,7 @@ class SetupController
{
// Verify current step.
$current_step = $this->_getSetupStep();
if ($current_step !== 'settings' && APP_IN_PRODUCTION) {
if ($current_step !== 'settings' && $this->settings->isProduction()) {
return $response->withRedirect($request->getRouter()->named('setup:' . $current_step));
}

View File

@ -6,7 +6,7 @@ use App\Http\Response;
use App\Http\ServerRequest;
use App\Sync\Task\RadioAutomation;
use Azura\Config;
use Azura\Settings;
use App\Settings;
use Doctrine\ORM\EntityManager;
use Exception;
use Psr\Http\Message\ResponseInterface;

View File

@ -3,7 +3,6 @@ namespace App;
use App\Entity;
use App\Service\NChan;
use Azura\Settings;
use Doctrine\ORM\EntityManager;
use Gettext\Translator;
use GuzzleHttp\Psr7\Uri;
@ -18,33 +17,21 @@ class Customization
public const DEFAULT_LOCALE = 'en_US.UTF-8';
public const DEFAULT_THEME = 'light';
/** @var Settings */
protected $app_settings;
/** @var Entity\User|null */
protected $user;
/** @var Entity\Repository\SettingsRepository */
protected $settings_repo;
protected $settingsRepo;
/** @var string|null */
protected $locale;
public function __construct(Settings $app_settings, EntityManager $em)
public function __construct(EntityManager $em)
{
/** @var Entity\Repository\SettingsRepository $settings_repo */
$settings_repo = $em->getRepository(Entity\Settings::class);
$this->app_settings = $app_settings;
$this->settings_repo = $settings_repo;
}
/**
* @param null $locale
*/
public static function setGlobalValues($locale = null): void
{
$this->settingsRepo = $settings_repo;
}
/**
@ -70,7 +57,7 @@ class Customization
// Set up the PHP translator
$translator = new Translator();
$locale_base = $this->app_settings[Settings::BASE_DIR] . '/resources/locale/compiled';
$locale_base = Settings::getInstance()->getBaseDirectory() . '/resources/locale/compiled';
$locale_path = $locale_base . '/' . $this->locale . '.php';
if (file_exists($locale_path)) {
@ -98,11 +85,12 @@ class Customization
*/
protected function initLocale(?Request $request = null): ?string
{
if ($this->app_settings->isTesting()) {
$settings = Settings::getInstance();
if ($settings->isTesting()) {
return self::DEFAULT_LOCALE;
}
$supported_locales = $this->app_settings['locale']['supported'];
$supported_locales = $settings['locale']['supported'];
$try_locales = [];
// Prefer user-based profile locale.
@ -176,7 +164,7 @@ class Customization
static $instance_name;
if ($instance_name === null) {
$instance_name = $this->settings_repo->getSetting(Entity\Settings::INSTANCE_NAME, '');
$instance_name = $this->settingsRepo->getSetting(Entity\Settings::INSTANCE_NAME, '');
}
return $instance_name;
@ -189,7 +177,7 @@ class Customization
*/
public function getPublicTheme(): string
{
return $this->settings_repo->getSetting(Entity\Settings::PUBLIC_THEME, self::DEFAULT_THEME);
return $this->settingsRepo->getSetting(Entity\Settings::PUBLIC_THEME, self::DEFAULT_THEME);
}
/**
@ -199,7 +187,7 @@ class Customization
*/
public function getCustomPublicCss()
{
return (string)$this->settings_repo->getSetting(Entity\Settings::CUSTOM_CSS_PUBLIC, '');
return (string)$this->settingsRepo->getSetting(Entity\Settings::CUSTOM_CSS_PUBLIC, '');
}
/**
@ -209,7 +197,7 @@ class Customization
*/
public function getCustomPublicJs()
{
return (string)$this->settings_repo->getSetting(Entity\Settings::CUSTOM_JS_PUBLIC, '');
return (string)$this->settingsRepo->getSetting(Entity\Settings::CUSTOM_JS_PUBLIC, '');
}
/**
@ -219,7 +207,7 @@ class Customization
*/
public function getCustomInternalCss()
{
return (string)$this->settings_repo->getSetting(Entity\Settings::CUSTOM_CSS_INTERNAL, '');
return (string)$this->settingsRepo->getSetting(Entity\Settings::CUSTOM_CSS_INTERNAL, '');
}
/**
@ -229,7 +217,7 @@ class Customization
*/
public function hideAlbumArt(): bool
{
return (bool)$this->settings_repo->getSetting(Entity\Settings::HIDE_ALBUM_ART, false);
return (bool)$this->settingsRepo->getSetting(Entity\Settings::HIDE_ALBUM_ART, false);
}
/**
@ -239,7 +227,7 @@ class Customization
*/
public function getDefaultAlbumArtUrl(): UriInterface
{
$custom_url = trim($this->settings_repo->getSetting(Entity\Settings::DEFAULT_ALBUM_ART_URL));
$custom_url = trim($this->settingsRepo->getSetting(Entity\Settings::DEFAULT_ALBUM_ART_URL));
if (!empty($custom_url)) {
return new Uri($custom_url);
@ -256,16 +244,18 @@ class Customization
*/
public function getPageTitle($title = null): string
{
$settings = Settings::getInstance();
if (!$this->hideProductName()) {
if ($title) {
$title .= ' - ' . $this->app_settings[Settings::APP_NAME];
$title .= ' - ' . $settings[Settings::APP_NAME];
} else {
$title = $this->app_settings[Settings::APP_NAME];
$title = $settings[Settings::APP_NAME];
}
}
if (!$this->app_settings->isProduction()) {
$title = '(' . ucfirst($this->app_settings[Settings::APP_ENV]) . ') ' . $title;
if (!$settings->isProduction()) {
$title = '(' . ucfirst($settings[Settings::APP_ENV]) . ') ' . $title;
}
return $title;
@ -278,7 +268,7 @@ class Customization
*/
public function hideProductName(): bool
{
return (bool)$this->settings_repo->getSetting(Entity\Settings::HIDE_PRODUCT_NAME, false);
return (bool)$this->settingsRepo->getSetting(Entity\Settings::HIDE_PRODUCT_NAME, false);
}
/**
@ -290,7 +280,7 @@ class Customization
return false;
}
return (bool)$this->settings_repo->getSetting(Entity\Settings::NOWPLAYING_USE_WEBSOCKETS, false);
return (bool)$this->settingsRepo->getSetting(Entity\Settings::NOWPLAYING_USE_WEBSOCKETS, false);
}
}

View File

@ -5,6 +5,7 @@ use App\Entity;
use App\Radio\Adapters;
use App\Radio\Configuration;
use App\Radio\Frontend\AbstractFrontend;
use App\Settings;
use App\Sync\Task\Media;
use App\Utilities;
use Azura\Doctrine\Repository;
@ -156,7 +157,7 @@ class StationRepository extends Repository
public function create(Entity\Station $station): void
{
// Create path for station.
$station_base_dir = dirname(APP_INCLUDE_ROOT) . '/stations';
$station_base_dir = Settings::getInstance()->getStationDirectory();
$station_dir = $station_base_dir . '/' . $station->getShortName();
$station->setRadioBaseDir($station_dir);

View File

@ -3,6 +3,7 @@ namespace App\Form;
use App\Entity\Station;
use App\Http\ServerRequest;
use App\Settings;
use Azura\Doctrine\Repository;
use Azura\Exception;
use Azura\Normalizer\DoctrineEntityNormalizer;
@ -22,9 +23,6 @@ use Symfony\Component\Validator\Validator\ValidatorInterface;
*/
class EntityForm extends Form
{
/** @var EntityManager */
protected $em;
/** @var Serializer */
protected $serializer;
@ -142,7 +140,7 @@ class EntityForm extends Form
$this->em->flush($record);
// Intentionally refresh the station entity in case it didn't refresh elsewhere.
if ($this->station instanceof Station && APP_TESTING_MODE) {
if ($this->station instanceof Station && Settings::getInstance()->isTesting()) {
$this->em->refresh($this->station);
}

View File

@ -34,6 +34,7 @@ class EntityFormManager
$this->em = $em;
$this->serializer = $serializer;
$this->validator = $validator;
$this->custom_forms = $custom_forms;
}
@ -43,6 +44,7 @@ class EntityFormManager
*
* @param string $entity_class
* @param array|null $form_config
* @param array|null $defaults
* @return EntityForm
*/
public function getForm($entity_class, array $form_config = null, array $defaults = null): EntityForm

View File

@ -3,6 +3,7 @@ namespace App\Form;
use App\Entity;
use App\Http\ServerRequest;
use App\Settings;
use Azura\Config;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Serializer\Serializer;

View File

@ -5,6 +5,7 @@ use App\Acl;
use App\Entity;
use App\Http\ServerRequest;
use App\Radio\Configuration;
use App\Settings;
use App\Sync\Task\Media;
use Azura\Config;
use DeepCopy;
@ -23,7 +24,6 @@ class StationCloneForm extends StationForm
protected $media_sync;
/**
* StationCloneForm constructor.
* @param EntityManager $em
* @param Serializer $serializer
* @param ValidatorInterface $validator
@ -168,7 +168,7 @@ class StationCloneForm extends StationForm
}
// Set new radio base directory
$station_base_dir = dirname(APP_INCLUDE_ROOT) . '/stations';
$station_base_dir = Settings::getInstance()->getStationDirectory();
$new_record->setRadioBaseDir($station_base_dir . '/' . $new_record->getShortName());
// Persist all newly created records (and relations).

View File

@ -5,6 +5,7 @@ use App\Acl;
use App\Entity;
use App\Http\ServerRequest;
use App\Radio\Frontend\SHOUTcast;
use App\Settings;
use Azura\Config;
use Azura\Doctrine\Repository;
use Doctrine\ORM\EntityManager;

View File

@ -5,6 +5,7 @@ use App\Entity;
use App\Entity\Station;
use App\Http\ServerRequest;
use App\Radio\Adapters;
use App\Settings;
use Azura\Config;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Serializer\Serializer;
@ -19,12 +20,14 @@ class StationMountForm extends EntityForm
* @param EntityManager $em
* @param Serializer $serializer
* @param ValidatorInterface $validator
* @param Settings $settings
* @param Config $config
*/
public function __construct(
EntityManager $em,
Serializer $serializer,
ValidatorInterface $validator,
Settings $settings,
Config $config
) {
$form_configs = [
@ -32,7 +35,7 @@ class StationMountForm extends EntityForm
Adapters::FRONTEND_SHOUTCAST => $config->get('forms/mount/shoutcast2'),
];
parent::__construct($em, $serializer, $validator);
parent::__construct($em, $serializer, $validator, $settings);
$this->entityClass = Entity\StationMount::class;
$this->form_configs = $form_configs;

View File

@ -5,6 +5,7 @@ use App\Customization;
use App\Entity;
use App\Http\ServerRequest;
use App\Radio\PlaylistParser;
use App\Settings;
use Azura\Config;
use AzuraForms\Field\Markup;
use Cake\Chronos\Chronos;
@ -17,7 +18,7 @@ use Symfony\Component\Validator\Validator\ValidatorInterface;
class StationPlaylistForm extends EntityForm
{
/** @var Entity\Repository\StationPlaylistMediaRepository */
protected $playlist_media_repo;
protected $playlistMediaRepo;
/**
* @param EntityManager $em
@ -40,7 +41,7 @@ class StationPlaylistForm extends EntityForm
parent::__construct($em, $serializer, $validator, $form_config);
$this->entityClass = Entity\StationPlaylist::class;
$this->playlist_media_repo = $em->getRepository(Entity\StationPlaylistMedia::class);
$this->playlistMediaRepo = $em->getRepository(Entity\StationPlaylistMedia::class);
}
public function process(ServerRequest $request, $record = null)
@ -147,13 +148,13 @@ class StationPlaylistForm extends EntityForm
->setParameter('matched_ids', $matches)
->execute();
$weight = $this->playlist_media_repo->getHighestSongWeight($playlist);
$weight = $this->playlistMediaRepo->getHighestSongWeight($playlist);
foreach ($matched_media as $media) {
$weight++;
/** @var Entity\StationMedia $media */
$this->playlist_media_repo->addMediaToPlaylist($media, $playlist, $weight);
$this->playlistMediaRepo->addMediaToPlaylist($media, $playlist, $weight);
}
$this->em->flush();

View File

@ -5,7 +5,6 @@ use App\Entity;
use App\Http\Router;
use App\Http\ServerRequest;
use Azura\Config;
use Azura\Settings;
use Doctrine\ORM\EntityManager;
use InvalidArgumentException;
use Symfony\Component\Serializer\Serializer;
@ -25,22 +24,19 @@ class StationWebhookForm extends EntityForm
* @param ValidatorInterface $validator
* @param Config $config
* @param Router $router
* @param Settings $settings
*/
public function __construct(
EntityManager $em,
Serializer $serializer,
ValidatorInterface $validator,
Config $config,
Router $router,
Settings $settings
Router $router
) {
$webhook_config = $config->get('webhooks');
$webhook_forms = [];
$config_injections = [
'router' => $router,
'app_settings' => $settings,
'triggers' => $webhook_config['triggers'],
];
foreach ($webhook_config['webhooks'] as $webhook_key => $webhook_info) {

View File

@ -7,7 +7,7 @@ use App\Exception\PermissionDeniedException;
use App\Service\Sentry;
use Azura\Exception;
use Azura\Session;
use Azura\Settings;
use App\Settings;
use Azura\View;
use Gettext\Translator;
use Monolog\Logger;

View File

@ -2,7 +2,7 @@
namespace App\Http;
use App\Entity;
use Azura\Settings;
use App\Settings;
use Doctrine\ORM\EntityManager;
use GuzzleHttp\Psr7\Uri;
use Psr\Http\Message\ServerRequestInterface;

View File

@ -4,7 +4,7 @@ namespace App\Notification;
use App\Acl;
use App\Entity;
use App\Event\GetNotifications;
use Azura\Settings;
use App\Settings;
use Doctrine\ORM\EntityManager;
use Monolog\Logger;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

View File

@ -5,10 +5,11 @@ use App\Entity;
use App\Exception\Supervisor\AlreadyRunningException;
use App\Exception\Supervisor\BadNameException;
use App\Exception\Supervisor\NotRunningException;
use App\Settings;
use Azura\EventDispatcher;
use Azura\Logger;
use Doctrine\ORM\EntityManager;
use fXmlRpc\Exception\FaultException;
use Monolog\Logger;
use Supervisor\Process;
use Supervisor\Supervisor;
@ -20,27 +21,21 @@ abstract class AbstractAdapter
/** @var Supervisor */
protected $supervisor;
/** @var Logger */
protected $logger;
/** @var EventDispatcher */
protected $dispatcher;
/**
* @param EntityManager $em
* @param Supervisor $supervisor
* @param Logger $logger
* @param EventDispatcher $dispatcher
*/
public function __construct(
EntityManager $em,
Supervisor $supervisor,
Logger $logger,
EventDispatcher $dispatcher
) {
$this->em = $em;
$this->supervisor = $supervisor;
$this->logger = $logger;
$this->dispatcher = $dispatcher;
}
@ -98,7 +93,7 @@ abstract class AbstractAdapter
*/
public function hasCommand(Entity\Station $station): bool
{
if (APP_TESTING_MODE || !$station->isEnabled()) {
if (Settings::getInstance()->isTesting() || !$station->isEnabled()) {
return false;
}
@ -152,7 +147,7 @@ abstract class AbstractAdapter
try {
$this->supervisor->stopProcess($program_name);
$this->logger->info('Adapter "' . get_called_class() . '" stopped.',
Logger::getInstance()->info('Adapter "' . get_called_class() . '" stopped.',
['station_id' => $station->getId(), 'station_name' => $station->getName()]);
} catch (FaultException $e) {
$this->_handleSupervisorException($e, $program_name, $station);
@ -245,7 +240,7 @@ abstract class AbstractAdapter
try {
$this->supervisor->startProcess($program_name);
$this->logger->info('Adapter "' . get_called_class() . '" started.',
Logger::getInstance()->info('Adapter "' . get_called_class() . '" started.',
['station_id' => $station->getId(), 'station_name' => $station->getName()]);
} catch (FaultException $e) {
$this->_handleSupervisorException($e, $program_name, $station);
@ -268,15 +263,4 @@ abstract class AbstractAdapter
return $config_dir . '/' . strtolower($class_name) . '.log';
}
/**
*
*
* @param array $clients
* @return array
*/
protected function _filterClients(array $clients): array
{
}
}

View File

@ -7,10 +7,11 @@ use App\Event\Radio\WriteLiquidsoapConfiguration;
use App\Radio\Adapters;
use App\Radio\AutoDJ;
use App\Radio\Filesystem;
use App\Settings;
use Azura\EventDispatcher;
use Azura\Logger;
use Doctrine\ORM\EntityManager;
use Exception;
use Monolog\Logger;
use Psr\Http\Message\UriInterface;
use Supervisor\Supervisor;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
@ -31,7 +32,6 @@ class Liquidsoap extends AbstractBackend implements EventSubscriberInterface
/**
* @param EntityManager $em
* @param Supervisor $supervisor
* @param Logger $logger
* @param EventDispatcher $dispatcher
* @param AutoDJ $autodj
* @param Filesystem $filesystem
@ -39,12 +39,11 @@ class Liquidsoap extends AbstractBackend implements EventSubscriberInterface
public function __construct(
EntityManager $em,
Supervisor $supervisor,
Logger $logger,
EventDispatcher $dispatcher,
AutoDJ $autodj,
Filesystem $filesystem
) {
parent::__construct($em, $supervisor, $logger, $dispatcher);
parent::__construct($em, $supervisor, $dispatcher);
$this->autodj = $autodj;
$this->filesystem = $filesystem;
@ -103,7 +102,7 @@ class Liquidsoap extends AbstractBackend implements EventSubscriberInterface
'set("log.stdout", true)',
'set("log.file", false)',
'set("server.telnet",true)',
'set("server.telnet.bind_addr","' . (APP_INSIDE_DOCKER ? '0.0.0.0' : '127.0.0.1') . '")',
'set("server.telnet.bind_addr","' . (Settings::getInstance()->isDocker() ? '0.0.0.0' : '127.0.0.1') . '")',
'set("server.telnet.port", ' . $this->_getTelnetPort($station) . ')',
'set("harbor.bind_addrs",["0.0.0.0"])',
'',
@ -421,9 +420,9 @@ class Liquidsoap extends AbstractBackend implements EventSubscriberInterface
]);
}
$error_file = APP_INSIDE_DOCKER
$error_file = Settings::getInstance()->isDocker()
? '/usr/local/share/icecast/web/error.mp3'
: APP_INCLUDE_ROOT . '/resources/error.mp3';
: Settings::getInstance()->getBaseDirectory() . '/resources/error.mp3';
$event->appendLines([
'requests = audio_to_stereo(request.queue(id="' . $this->_getVarName('requests', $station) . '"))',
@ -486,7 +485,7 @@ class Liquidsoap extends AbstractBackend implements EventSubscriberInterface
try {
$this->command($station, $playlist_var_name . '.reload');
} catch (Exception $e) {
$this->logger->error('Could not reload playlist with AutoDJ.', [
Logger::getInstance()->error('Could not reload playlist with AutoDJ.', [
'message' => $e->getMessage(),
'playlist' => $playlist_var_name,
'station' => $station->getId(),
@ -507,7 +506,7 @@ class Liquidsoap extends AbstractBackend implements EventSubscriberInterface
*/
public function command(Entity\Station $station, $command_str)
{
$fp = stream_socket_client('tcp://' . (APP_INSIDE_DOCKER ? 'stations' : 'localhost') . ':' . $this->_getTelnetPort($station),
$fp = stream_socket_client('tcp://' . (Settings::getInstance()->isDocker() ? 'stations' : 'localhost') . ':' . $this->_getTelnetPort($station),
$errno, $errstr, 20);
if (!$fp) {
@ -627,12 +626,14 @@ class Liquidsoap extends AbstractBackend implements EventSubscriberInterface
*/
protected function _getApiUrlCommand(Entity\Station $station, $endpoint, $params = []): string
{
$settings = Settings::getInstance();
// Docker cURL-based API URL call with API authentication.
if (APP_INSIDE_DOCKER) {
if ($settings->isDocker()) {
$params = (array)$params;
$params['api_auth'] = '"' . $station->getAdapterApiKey() . '"';
$service_uri = (APP_DOCKER_REVISION >= 5) ? 'web' : 'nginx';
$service_uri = ($settings[Settings::DOCKER_REVISION] >= 5) ? 'web' : 'nginx';
$api_url = 'http://' . $service_uri . '/api/internal/' . $station->getId() . '/' . $endpoint;
$command = 'curl -s --request POST --url ' . $api_url;
foreach ($params as $param_key => $param_val) {
@ -640,7 +641,7 @@ class Liquidsoap extends AbstractBackend implements EventSubscriberInterface
}
} else {
// Ansible shell-script call.
$shell_path = '/usr/bin/php ' . APP_INCLUDE_ROOT . '/bin/azuracast';
$shell_path = '/usr/bin/php ' . $settings->getBaseDirectory() . '/bin/azuracast';
$shell_args = [];
$shell_args[] = 'azuracast:internal:' . $endpoint;
@ -962,7 +963,9 @@ class Liquidsoap extends AbstractBackend implements EventSubscriberInterface
public static function getBinary()
{
// Docker revisions 3 and later use the `radio` container.
if (APP_INSIDE_DOCKER && APP_DOCKER_REVISION < 3) {
$settings = Settings::getInstance();
if ($settings->isDocker() && $settings[Settings::DOCKER_REVISION] < 3) {
return '/var/azuracast/.opam/system/bin/liquidsoap';
}
@ -1053,7 +1056,7 @@ class Liquidsoap extends AbstractBackend implements EventSubscriberInterface
$streamer = $streamer_repo->authenticate($station, $user, $pass);
if ($streamer instanceof Entity\StationStreamer) {
$this->logger->debug('DJ successfully authenticated.', ['username' => $user]);
Logger::getInstance()->debug('DJ successfully authenticated.', ['username' => $user]);
try {
// Successful authentication: update current streamer on station.
@ -1061,7 +1064,7 @@ class Liquidsoap extends AbstractBackend implements EventSubscriberInterface
$this->em->persist($station);
$this->em->flush();
} catch (Exception $e) {
$this->logger->error('Error when calling post-DJ-authentication functions.', [
Logger::getInstance()->error('Error when calling post-DJ-authentication functions.', [
'file' => $e->getFile(),
'line' => $e->getLine(),
'code' => $e->getCode(),

View File

@ -2,6 +2,7 @@
namespace App\Radio;
use App\Entity\Station;
use App\Settings;
use Azura\Exception;
use Doctrine\ORM\EntityManager;
use fXmlRpc\Exception\FaultException;
@ -55,7 +56,7 @@ class Configuration
*/
public function writeConfiguration(Station $station, $regen_auth_key = false, $force_restart = false): void
{
if (APP_TESTING_MODE) {
if (Settings::getInstance()->isTesting()) {
return;
}
@ -408,7 +409,7 @@ class Configuration
*/
public function removeConfiguration(Station $station): void
{
if (APP_TESTING_MODE) {
if (Settings::getInstance()->isTesting()) {
return;
}

View File

@ -4,12 +4,13 @@ namespace App\Radio\Frontend;
use App\Entity;
use App\Http\Router;
use App\Radio\AbstractAdapter;
use App\Settings;
use App\Xml\Reader;
use Azura\EventDispatcher;
use Azura\Logger;
use Doctrine\ORM\EntityManager;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Uri;
use Monolog\Logger;
use NowPlaying\Adapter\AdapterAbstract;
use Psr\Http\Message\UriInterface;
use Supervisor\Supervisor;
@ -25,12 +26,11 @@ abstract class AbstractFrontend extends AbstractAdapter
public function __construct(
EntityManager $em,
Supervisor $supervisor,
Logger $logger,
EventDispatcher $dispatcher,
Client $client,
Router $router
) {
parent::__construct($em, $supervisor, $logger, $dispatcher);
parent::__construct($em, $supervisor, $dispatcher);
$this->http_client = $client;
$this->router = $router;
@ -146,7 +146,7 @@ abstract class AbstractFrontend extends AbstractAdapter
$use_radio_proxy = $settings_repo->getSetting('use_radio_proxy', 0);
if ($use_radio_proxy
|| (!APP_IN_PRODUCTION && !APP_INSIDE_DOCKER)
|| (!Settings::getInstance()->isProduction() && !Settings::getInstance()->isDocker())
|| 'https' === $base_url->getScheme()) {
// Web proxy support.
return $base_url
@ -223,7 +223,7 @@ abstract class AbstractFrontend extends AbstractAdapter
$np['listeners']['clients'] = [];
}
$this->logger->debug('Response for mount point', ['mount' => $mount->getName(), 'response' => $np]);
Logger::getInstance()->debug('Response for mount point', ['mount' => $mount->getName(), 'response' => $np]);
$mount->setListenersTotal($np['listeners']['total']);
$mount->setListenersUnique($np['listeners']['unique']);

View File

@ -2,9 +2,11 @@
namespace App\Radio\Frontend;
use App\Entity;
use App\Settings;
use App\Utilities;
use App\Xml\Reader;
use App\Xml\Writer;
use Azura\Logger;
use NowPlaying\Adapter\AdapterAbstract;
use NowPlaying\Exception;
use Psr\Http\Message\UriInterface;
@ -21,7 +23,7 @@ class Icecast extends AbstractFrontend
$fe_config = (array)$station->getFrontendConfig();
$radio_port = $fe_config['port'];
$base_url = 'http://' . (APP_INSIDE_DOCKER ? 'stations' : 'localhost') . ':' . $radio_port;
$base_url = 'http://' . (Settings::getInstance()->isDocker() ? 'stations' : 'localhost') . ':' . $radio_port;
$np_adapter = new \NowPlaying\Adapter\Icecast($base_url, $this->http_client);
$np_adapter->setAdminPassword($fe_config['admin_pw']);
@ -40,9 +42,9 @@ class Icecast extends AbstractFrontend
);
}
$this->logger->debug('Aggregated NowPlaying response', ['response' => $np_final]);
Logger::getInstance()->debug('Aggregated NowPlaying response', ['response' => $np_final]);
} catch (Exception $e) {
$this->logger->error(sprintf('NowPlaying adapter error: %s', $e->getMessage()));
Logger::getInstance()->error(sprintf('NowPlaying adapter error: %s', $e->getMessage()));
}
return $np_final;
@ -129,7 +131,7 @@ class Icecast extends AbstractFrontend
'logging' => [
'accesslog' => 'icecast_access.log',
'errorlog' => '/dev/stderr',
'loglevel' => (APP_IN_PRODUCTION) ? self::LOGLEVEL_WARN : self::LOGLEVEL_INFO,
'loglevel' => Settings::getInstance()->isProduction() ? self::LOGLEVEL_WARN : self::LOGLEVEL_INFO,
'logsize' => 10000,
],
'security' => [
@ -138,7 +140,9 @@ class Icecast extends AbstractFrontend
];
// Allow all sources to set the X-Forwarded-For header
if (APP_INSIDE_DOCKER && APP_DOCKER_REVISION >= 3) {
$settings = Settings::getInstance();
if ($settings->isDocker() && $settings[Settings::DOCKER_REVISION] >= 3) {
$defaults['paths']['all-x-forwarded-for'] = '1';
}
@ -318,7 +322,7 @@ class Icecast extends AbstractFrontend
$new_path = '/usr/local/bin/icecast';
$legacy_path = '/usr/bin/icecast2';
if (APP_INSIDE_DOCKER || file_exists($new_path)) {
if (Settings::getInstance()->isDocker() || file_exists($new_path)) {
return $new_path;
} elseif (file_exists($legacy_path)) {
return $legacy_path;

View File

@ -2,6 +2,7 @@
namespace App\Radio\Frontend;
use App\Entity;
use App\Settings;
use App\Utilities;
use NowPlaying\Adapter\AdapterAbstract;
use NowPlaying\Adapter\SHOUTcast2;
@ -34,10 +35,11 @@ class SHOUTcast extends AbstractFrontend
public static function getBinary()
{
$new_path = dirname(APP_INCLUDE_ROOT) . '/servers/shoutcast2/sc_serv';
$new_path = '/var/azuracast/servers/shoutcast2/sc_serv';
// Docker versions before 3 included the SC binary across the board.
if (APP_INSIDE_DOCKER && APP_DOCKER_REVISION < 3) {
$settings = Settings::getInstance();
if ($settings->isDocker() && $settings[Settings::DOCKER_REVISION] < 3) {
return $new_path;
}
@ -51,7 +53,7 @@ class SHOUTcast extends AbstractFrontend
$fe_config = (array)$station->getFrontendConfig();
$radio_port = $fe_config['port'];
$base_url = 'http://' . (APP_INSIDE_DOCKER ? 'stations' : 'localhost') . ':' . $radio_port;
$base_url = 'http://' . (Settings::getInstance()->isDocker() ? 'stations' : 'localhost') . ':' . $radio_port;
$np_adapter = new SHOUTcast2($base_url, $this->http_client);
$np_adapter->setAdminPassword($fe_config['admin_pw']);

View File

@ -2,6 +2,7 @@
namespace App\Radio\Remote;
use App\Entity;
use App\Settings;
use Doctrine\ORM\EntityManager;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Uri;

View File

@ -2,6 +2,7 @@
namespace App\Radio\Remote;
use App\Entity;
use App\Settings;
use GuzzleHttp\Psr7\Uri;
use InvalidArgumentException;
@ -59,7 +60,7 @@ class AzuraRelay extends AbstractRemote
$use_radio_proxy = $settings_repo->getSetting('use_radio_proxy', 0);
if ($use_radio_proxy
|| (!APP_IN_PRODUCTION && !APP_INSIDE_DOCKER)
|| (!Settings::getInstance()->isProduction() && !Settings::getInstance()->isDocker())
|| 'https' === $base_url->getScheme()) {
// Web proxy support.
return (string)$base_url

View File

@ -3,7 +3,7 @@ namespace App\Service;
use App\Entity;
use App\Version;
use Azura\Settings;
use App\Settings;
use Doctrine\ORM\EntityManager;
use GuzzleHttp\Client;

View File

@ -5,7 +5,7 @@ use App\Acl;
use App\Entity;
use App\Http\Router;
use App\Utilities;
use Azura\Settings;
use App\Settings;
use Doctrine\ORM\EntityManager;
use Psr\Log\LoggerInterface;
use RuntimeException;

View File

@ -1,6 +1,8 @@
<?php
namespace App\Service;
use App\Settings;
/**
* Utility class for managing NChan, the nginx websocket/SSE/long-polling module.
*/
@ -11,12 +13,14 @@ class NChan
*/
public static function isSupported(): bool
{
if (APP_TESTING_MODE) {
$settings = Settings::getInstance();
if ($settings->isTesting()) {
return false;
}
if (APP_INSIDE_DOCKER) {
return APP_DOCKER_REVISION >= 5;
if ($settings->isDocker()) {
return $settings[Settings::DOCKER_REVISION] >= 5;
}
$os_details = self::getOperatingSystemDetails();

View File

@ -5,7 +5,7 @@ use App\Entity;
use App\Exception\SupervisorException;
use App\Version;
use Azura\Exception;
use Azura\Settings;
use App\Settings;
use Doctrine\DBAL\Exception\TableNotFoundException;
use Doctrine\ORM\EntityManager;
use fXmlRpc\Exception\FaultException;
@ -72,7 +72,7 @@ class Sentry
return;
}
if (APP_TESTING_MODE) {
if ($this->app_settings->isTesting()) {
return;
}

25
src/Settings.php Normal file
View File

@ -0,0 +1,25 @@
<?php
namespace App;
class Settings extends \Azura\Settings
{
public const DOCKER_REVISION = 'docker_revision';
/**
* @return string The parent directory the application is within, i.e. `/var/azuracast`.
*/
public function getParentDirectory(): string
{
return dirname($this->getBaseDirectory());
}
/**
* @return string The default directory where station data is stored.
*/
public function getStationDirectory(): string
{
return $this->getParentDirectory().'/stations';
}
}

View File

@ -3,6 +3,7 @@ namespace App\Sync;
use App\Entity;
use App\Entity\Repository\SettingsRepository;
use App\Settings;
use Monolog\Logger;
use Pimple\ServiceIterator;
@ -15,7 +16,7 @@ class Runner
protected $logger;
/** @var SettingsRepository */
protected $settings;
protected $settingsRepo;
/** @var Task\AbstractTask[] */
protected $tasks_nowplaying;
@ -30,14 +31,14 @@ class Runner
protected $tasks_long;
public function __construct(
SettingsRepository $settings,
SettingsRepository $settingsRepo,
Logger $logger,
array $tasks_nowplaying,
array $tasks_short,
array $tasks_medium,
array $tasks_long
) {
$this->settings = $settings;
$this->settingsRepo = $settingsRepo;
$this->logger = $logger;
$this->tasks_nowplaying = $tasks_nowplaying;
@ -59,14 +60,14 @@ class Runner
$this->_initSync(10);
// Prevent nowplaying from running on top of itself.
$last_start = $this->settings->getSetting(Entity\Settings::NOWPLAYING_LAST_STARTED, 0);
$last_end = $this->settings->getSetting(Entity\Settings::NOWPLAYING_LAST_RUN, 0);
$last_start = $this->settingsRepo->getSetting(Entity\Settings::NOWPLAYING_LAST_STARTED, 0);
$last_end = $this->settingsRepo->getSetting(Entity\Settings::NOWPLAYING_LAST_RUN, 0);
if ($last_start > $last_end && $last_start >= (time() - 10) && !$force) {
return;
}
$this->settings->setSetting(Entity\Settings::NOWPLAYING_LAST_STARTED, time());
$this->settingsRepo->setSetting(Entity\Settings::NOWPLAYING_LAST_STARTED, time());
foreach ($this->tasks_nowplaying as $task) {
$this->_runTimer(get_class($task), function () use ($task, $force) {
@ -75,20 +76,20 @@ class Runner
});
}
$this->settings->setSetting(Entity\Settings::NOWPLAYING_LAST_RUN, time());
$this->settingsRepo->setSetting(Entity\Settings::NOWPLAYING_LAST_RUN, time());
}
protected function _initSync($script_timeout = 60)
{
// Immediately halt if setup is not complete.
if ($this->settings->getSetting(Entity\Settings::SETUP_COMPLETE, 0) == 0) {
if ($this->settingsRepo->getSetting(Entity\Settings::SETUP_COMPLETE, 0) == 0) {
die('Setup not complete; halting synchronized task.');
}
set_time_limit($script_timeout);
ini_set('memory_limit', '256M');
if (APP_IS_COMMAND_LINE) {
if (Settings::getInstance()->isCli()) {
error_reporting(E_ALL & ~E_STRICT & ~E_NOTICE);
ini_set('display_errors', 1);
ini_set('log_errors', 1);
@ -129,7 +130,7 @@ class Runner
});
}
$this->settings->setSetting(Entity\Settings::SHORT_SYNC_LAST_RUN, time());
$this->settingsRepo->setSetting(Entity\Settings::SHORT_SYNC_LAST_RUN, time());
}
/**
@ -150,7 +151,7 @@ class Runner
});
}
$this->settings->setSetting(Entity\Settings::MEDIUM_SYNC_LAST_RUN, time());
$this->settingsRepo->setSetting(Entity\Settings::MEDIUM_SYNC_LAST_RUN, time());
}
/**
@ -171,38 +172,38 @@ class Runner
});
}
$this->settings->setSetting(Entity\Settings::LONG_SYNC_LAST_RUN, time());
$this->settingsRepo->setSetting(Entity\Settings::LONG_SYNC_LAST_RUN, time());
}
public function getSyncTimes()
{
$this->settings->clearCache();
$this->settingsRepo->clearCache();
$syncs = [
'nowplaying' => [
'name' => __('Now Playing Data'),
'latest' => $this->settings->getSetting(Entity\Settings::NOWPLAYING_LAST_RUN, 0),
'latest' => $this->settingsRepo->getSetting(Entity\Settings::NOWPLAYING_LAST_RUN, 0),
'contents' => [
__('Now Playing Data'),
],
],
'short' => [
'name' => __('1-Minute Sync'),
'latest' => $this->settings->getSetting(Entity\Settings::SHORT_SYNC_LAST_RUN, 0),
'latest' => $this->settingsRepo->getSetting(Entity\Settings::SHORT_SYNC_LAST_RUN, 0),
'contents' => [
__('Song Requests Queue'),
],
],
'medium' => [
'name' => __('5-Minute Sync'),
'latest' => $this->settings->getSetting(Entity\Settings::MEDIUM_SYNC_LAST_RUN, 0),
'latest' => $this->settingsRepo->getSetting(Entity\Settings::MEDIUM_SYNC_LAST_RUN, 0),
'contents' => [
__('Check Media Folders'),
],
],
'long' => [
'name' => __('1-Hour Sync'),
'latest' => $this->settings->getSetting(Entity\Settings::LONG_SYNC_LAST_RUN, 0),
'latest' => $this->settingsRepo->getSetting(Entity\Settings::LONG_SYNC_LAST_RUN, 0),
'contents' => [
__('Analytics/Statistics'),
__('Cleanup'),

View File

@ -1,26 +1,24 @@
<?php
namespace App\Sync\Task;
use App\Entity;
use Doctrine\ORM\EntityManager;
use Interop\Container\ContainerInterface;
use Monolog\Logger;
abstract class AbstractTask
{
/** @var EntityManager */
protected $em;
/** @var Logger */
protected $logger;
/** @var Entity\Repository\SettingsRepository */
protected $settingsRepo;
/**
* @param EntityManager $em
* @param Logger $logger
*/
public function __construct(EntityManager $em, Logger $logger)
public function __construct(EntityManager $em)
{
$this->em = $em;
$this->logger = $logger;
$this->settingsRepo = $em->getRepository(Entity\Settings::class);
}
abstract public function run($force = false): void;

View File

@ -2,6 +2,7 @@
namespace App\Sync\Task;
use App\Entity;
use App\Settings;
use Doctrine\ORM\EntityManager;
use InfluxDB\Database;
use Monolog\Logger;
@ -13,22 +14,18 @@ class Analytics extends AbstractTask
/**
* @param EntityManager $em
* @param Logger $logger
* @param Database $influx
*/
public function __construct(EntityManager $em, Logger $logger, Database $influx)
public function __construct(EntityManager $em, Database $influx)
{
parent::__construct($em, $logger);
parent::__construct($em);
$this->influx = $influx;
}
public function run($force = false): void
{
/** @var Entity\Repository\SettingsRepository $settings_repo */
$settings_repo = $this->em->getRepository(Entity\Settings::class);
$analytics_level = $settings_repo->getSetting('analytics', Entity\Analytics::LEVEL_ALL);
$analytics_level = $this->settingsRepo->getSetting('analytics', Entity\Analytics::LEVEL_ALL);
if ($analytics_level === Entity\Analytics::LEVEL_NONE) {
$this->_purgeAnalytics();

View File

@ -4,6 +4,7 @@ namespace App\Sync\Task;
use App\Entity;
use App\Message;
use App\MessageQueue;
use App\Settings;
use Azura\Console\Application;
use Cake\Chronos\Chronos;
use Doctrine\ORM\EntityManager;
@ -13,32 +14,25 @@ class Backup extends AbstractTask
{
public const BASE_DIR = '/var/azuracast/backups';
/** @var Entity\Repository\SettingsRepository */
protected $settings_repo;
/** @var MessageQueue */
protected $message_queue;
protected $messageQueue;
/** @var Application */
protected $console;
/**
* @param EntityManager $em
* @param Logger $logger
* @param MessageQueue $message_queue
* @param Application $console
*/
public function __construct(
EntityManager $em,
Logger $logger,
MessageQueue $message_queue,
Application $console
) {
parent::__construct($em, $logger);
parent::__construct($em);
$this->settings_repo = $em->getRepository(Entity\Settings::class);
$this->message_queue = $message_queue;
$this->messageQueue = $message_queue;
$this->console = $console;
}
@ -56,9 +50,9 @@ class Backup extends AbstractTask
$message->exclude_media
);
$this->settings_repo->setSetting(Entity\Settings::BACKUP_LAST_RUN, time());
$this->settings_repo->setSetting(Entity\Settings::BACKUP_LAST_RESULT, $result_code);
$this->settings_repo->setSetting(Entity\Settings::BACKUP_LAST_OUTPUT, $result_output);
$this->settingsRepo->setSetting(Entity\Settings::BACKUP_LAST_RUN, time());
$this->settingsRepo->setSetting(Entity\Settings::BACKUP_LAST_RESULT, $result_code);
$this->settingsRepo->setSetting(Entity\Settings::BACKUP_LAST_OUTPUT, $result_output);
}
}
@ -77,7 +71,7 @@ class Backup extends AbstractTask
$input_params['--exclude-media'] = true;
}
return $this->console->runCommand('azuracast:backup', $input_params);
return $this->console->runCommandWithArgs('azuracast:backup', $input_params);
}
/**
@ -85,20 +79,20 @@ class Backup extends AbstractTask
*/
public function run($force = false): void
{
$backup_enabled = (bool)$this->settings_repo->getSetting(Entity\Settings::BACKUP_ENABLED, 0);
$backup_enabled = (bool)$this->settingsRepo->getSetting(Entity\Settings::BACKUP_ENABLED, 0);
if (!$backup_enabled) {
$this->logger->debug('Automated backups disabled; skipping...');
\Azura\Logger::getInstance()->debug('Automated backups disabled; skipping...');
return;
}
$now_utc = Chronos::now('UTC');
$threshold = $now_utc->subDay()->getTimestamp();
$last_run = $this->settings_repo->getSetting(Entity\Settings::BACKUP_LAST_RUN, 0);
$last_run = $this->settingsRepo->getSetting(Entity\Settings::BACKUP_LAST_RUN, 0);
if ($last_run <= $threshold) {
// Check if the backup time matches (if it's set).
$backup_timecode = (int)$this->settings_repo->getSetting(Entity\Settings::BACKUP_TIME);
$backup_timecode = (int)$this->settingsRepo->getSetting(Entity\Settings::BACKUP_TIME);
if (0 !== $backup_timecode) {
$current_timecode = (int)$now_utc->format('Hi');
@ -110,8 +104,8 @@ class Backup extends AbstractTask
// Trigger a new backup.
$message = new Message\BackupMessage;
$message->path = 'automatic_backup.zip';
$message->exclude_media = (bool)$this->settings_repo->getSetting(Entity\Settings::BACKUP_EXCLUDE_MEDIA, 0);
$this->message_queue->produce($message);
$message->exclude_media = (bool)$this->settingsRepo->getSetting(Entity\Settings::BACKUP_EXCLUDE_MEDIA, 0);
$this->messageQueue->produce($message);
}
}
}

View File

@ -3,7 +3,7 @@ namespace App\Sync\Task;
use App\Entity;
use App\Service\AzuraCastCentral;
use Azura\Settings;
use App\Settings;
use Doctrine\ORM\EntityManager;
use GuzzleHttp\Exception\TransferException;
use Monolog\Logger;
@ -12,68 +12,57 @@ class CheckForUpdates extends AbstractTask
{
protected const UPDATE_THRESHOLD = 3780;
/** @var Entity\Repository\SettingsRepository */
protected $settings_repo;
/** @var Settings */
protected $app_settings;
/** @var AzuraCastCentral */
protected $azuracast_central;
protected $azuracastCentral;
/**
* @param EntityManager $em
* @param Logger $logger
* @param Settings $app_settings
* @param AzuraCastCentral $azuracast_central
* @param AzuraCastCentral $azuracastCentral
*/
public function __construct(
EntityManager $em,
Logger $logger,
Settings $app_settings,
AzuraCastCentral $azuracast_central
AzuraCastCentral $azuracastCentral
) {
parent::__construct($em, $logger);
parent::__construct($em);
$this->settings_repo = $em->getRepository(Entity\Settings::class);
$this->app_settings = $app_settings;
$this->azuracast_central = $azuracast_central;
$this->azuracastCentral = $azuracastCentral;
}
public function run($force = false): void
{
$logger = \Azura\Logger::getInstance();
if (!$force) {
$update_last_run = (int)$this->settings_repo->getSetting(Entity\Settings::UPDATE_LAST_RUN, 0);
$update_last_run = (int)$this->settingsRepo->getSetting(Entity\Settings::UPDATE_LAST_RUN, 0);
if ($update_last_run > (time() - self::UPDATE_THRESHOLD)) {
$this->logger->debug('Not checking for updates; checked too recently.');
$logger->debug('Not checking for updates; checked too recently.');
return;
}
}
$check_for_updates = (int)$this->settings_repo->getSetting(Entity\Settings::CENTRAL_UPDATES,
$check_for_updates = (int)$this->settingsRepo->getSetting(Entity\Settings::CENTRAL_UPDATES,
Entity\Settings::UPDATES_RELEASE_ONLY);
if (Entity\Settings::UPDATES_NONE === $check_for_updates || $this->app_settings->isTesting()) {
$this->logger->info('Update checks are currently disabled for this AzuraCast instance.');
if (Entity\Settings::UPDATES_NONE === $check_for_updates || Settings::getInstance()->isTesting()) {
$logger->info('Update checks are currently disabled for this AzuraCast instance.');
return;
}
try {
$updates = $this->azuracast_central->checkForUpdates();
$updates = $this->azuracastCentral->checkForUpdates();
if (!empty($updates)) {
$this->settings_repo->setSetting(Entity\Settings::UPDATE_RESULTS, $updates);
$this->logger->info('Successfully checked for updates.', ['results' => $updates]);
$this->settingsRepo->setSetting(Entity\Settings::UPDATE_RESULTS, $updates);
$logger->info('Successfully checked for updates.', ['results' => $updates]);
} else {
$this->logger->error('Error parsing update data response from AzuraCast central.');
$logger->error('Error parsing update data response from AzuraCast central.');
}
} catch (TransferException $e) {
$this->logger->error(sprintf('Error from AzuraCast Central (%d): %s', $e->getCode(), $e->getMessage()));
$logger->error(sprintf('Error from AzuraCast Central (%d): %s', $e->getCode(), $e->getMessage()));
return;
}
$this->settings_repo->setSetting(Entity\Settings::UPDATE_LAST_RUN, time());
$this->settingsRepo->setSetting(Entity\Settings::UPDATE_LAST_RUN, time());
}
}

View File

@ -6,6 +6,7 @@ use App\Message;
use App\MessageQueue;
use App\Radio\Filesystem;
use App\Radio\Quota;
use App\Settings;
use Bernard\Envelope;
use Brick\Math\BigInteger;
use Doctrine\Common\Persistence\Mapping\MappingException;
@ -19,24 +20,22 @@ class Media extends AbstractTask
protected $filesystem;
/** @var MessageQueue */
protected $message_queue;
protected $messageQueue;
/**
* @param EntityManager $em
* @param Logger $logger
* @param Filesystem $filesystem
* @param MessageQueue $message_queue
* @param MessageQueue $messageQueue
*/
public function __construct(
EntityManager $em,
Logger $logger,
Filesystem $filesystem,
MessageQueue $message_queue
MessageQueue $messageQueue
) {
parent::__construct($em, $logger);
parent::__construct($em);
$this->filesystem = $filesystem;
$this->message_queue = $message_queue;
$this->messageQueue = $messageQueue;
}
/**
@ -128,7 +127,7 @@ class Media extends AbstractTask
$queued_media_updates = [];
$queued_new_files = [];
$queue = $this->message_queue->getGlobalQueue();
$queue = $this->messageQueue->getGlobalQueue();
$queue_position = 0;
$queue_iteration = 20;
@ -195,7 +194,7 @@ class Media extends AbstractTask
$message->media_id = $media_row->getId();
$message->force = $force_reprocess;
$this->message_queue->produce($message);
$this->messageQueue->produce($message);
$stats['updated']++;
} else {
@ -232,7 +231,7 @@ class Media extends AbstractTask
$message->station_id = $station->getId();
$message->path = $new_music_file['path'];
$this->message_queue->produce($message);
$this->messageQueue->produce($message);
$stats['created']++;
}
@ -240,7 +239,7 @@ class Media extends AbstractTask
$fs->flushAllCaches(true);
$this->logger->debug(sprintf('Media processed for station "%s".', $station->getName()), $stats);
\Azura\Logger::getInstance()->debug(sprintf('Media processed for station "%s".', $station->getName()), $stats);
}
/**

View File

@ -9,6 +9,7 @@ use App\Message;
use App\MessageQueue;
use App\Radio\Adapters;
use App\Radio\AutoDJ;
use App\Settings;
use Azura\EventDispatcher;
use Doctrine\ORM\EntityManager;
use Exception;
@ -41,6 +42,9 @@ class NowPlaying extends AbstractTask implements EventSubscriberInterface
/** @var MessageQueue */
protected $message_queue;
/** @var Logger */
protected $logger;
/** @var ApiUtilities */
protected $api_utils;
@ -61,27 +65,27 @@ class NowPlaying extends AbstractTask implements EventSubscriberInterface
/**
* @param EntityManager $em
* @param Logger $logger
* @param Adapters $adapters
* @param ApiUtilities $api_utils
* @param AutoDJ $autodj
* @param CacheInterface $cache
* @param Database $influx
* @param Logger $logger
* @param EventDispatcher $event_dispatcher
* @param MessageQueue $message_queue
*/
public function __construct(
EntityManager $em,
Logger $logger,
Adapters $adapters,
ApiUtilities $api_utils,
AutoDJ $autodj,
CacheInterface $cache,
Database $influx,
Logger $logger,
EventDispatcher $event_dispatcher,
MessageQueue $message_queue
) {
parent::__construct($em, $logger);
parent::__construct($em);
$this->adapters = $adapters;
$this->api_utils = $api_utils;
@ -90,6 +94,7 @@ class NowPlaying extends AbstractTask implements EventSubscriberInterface
$this->event_dispatcher = $event_dispatcher;
$this->message_queue = $message_queue;
$this->influx = $influx;
$this->logger = $logger;
$this->history_repo = $em->getRepository(Entity\SongHistory::class);
$this->song_repo = $em->getRepository(Entity\Song::class);
@ -104,7 +109,7 @@ class NowPlaying extends AbstractTask implements EventSubscriberInterface
public static function getSubscribedEvents()
{
if (APP_TESTING_MODE) {
if (Settings::getInstance()->isTesting()) {
return [];
}

View File

@ -17,12 +17,11 @@ class RadioAutomation extends AbstractTask
/**
* @param EntityManager $em
* @param Logger $logger
* @param Adapters $adapters
*/
public function __construct(EntityManager $em, Logger $logger, Adapters $adapters)
public function __construct(EntityManager $em, Adapters $adapters)
{
parent::__construct($em, $logger);
parent::__construct($em);
$this->adapters = $adapters;
}

View File

@ -5,8 +5,8 @@ use App\Entity;
use App\Event\Radio\AnnotateNextSong;
use App\Radio\Adapters;
use Azura\EventDispatcher;
use Azura\Logger;
use Doctrine\ORM\EntityManager;
use Monolog\Logger;
class RadioRequests extends AbstractTask
{
@ -18,17 +18,15 @@ class RadioRequests extends AbstractTask
/**
* @param EntityManager $em
* @param Logger $logger
* @param Adapters $adapters
* @param EventDispatcher $dispatcher
*/
public function __construct(
EntityManager $em,
Logger $logger,
Adapters $adapters,
EventDispatcher $dispatcher
) {
parent::__construct($em, $logger);
parent::__construct($em);
$this->dispatcher = $dispatcher;
$this->adapters = $adapters;
@ -117,10 +115,10 @@ class RadioRequests extends AbstractTask
$track = $event->buildAnnotations();
// Queue request with Liquidsoap.
$this->logger->debug('Submitting request to AutoDJ.', ['track' => $track]);
Logger::getInstance()->debug('Submitting request to AutoDJ.', ['track' => $track]);
$response = $backend->request($station, $track);
$this->logger->debug('AutoDJ request response', ['response' => $response]);
Logger::getInstance()->debug('AutoDJ request response', ['response' => $response]);
// Log the request as played.
$request->setPlayedAt(time());

View File

@ -3,8 +3,9 @@ namespace App\Sync\Task;
use App\Entity;
use App\Radio\Adapters;
use App\Settings;
use Azura\Logger;
use Doctrine\ORM\EntityManager;
use Monolog\Logger;
use studio24\Rotate;
use Supervisor\Supervisor;
use Symfony\Component\Finder\Finder;
@ -20,22 +21,17 @@ class RotateLogs extends AbstractTask
/** @var Supervisor */
protected $supervisor;
/** @var Logger */
protected $logger;
/**
* @param EntityManager $em
* @param Logger $logger
* @param Adapters $adapters
* @param Supervisor $supervisor
*/
public function __construct(
EntityManager $em,
Logger $logger,
Adapters $adapters,
Supervisor $supervisor
) {
parent::__construct($em, $logger);
parent::__construct($em);
$this->adapters = $adapters;
$this->supervisor = $supervisor;
@ -51,7 +47,7 @@ class RotateLogs extends AbstractTask
if (!empty($stations)) {
foreach ($stations as $station) {
/** @var Entity\Station $station */
$this->logger->info('Processing logs for station.',
Logger::getInstance()->info('Processing logs for station.',
['id' => $station->getId(), 'name' => $station->getName()]);
$this->rotateStationLogs($station);
@ -59,7 +55,7 @@ class RotateLogs extends AbstractTask
}
// Rotate the main AzuraCast log.
$rotate = new Rotate\Rotate(APP_INCLUDE_TEMP . '/app.log');
$rotate = new Rotate\Rotate(Settings::getInstance()->getTempDirectory() . '/app.log');
$rotate->keep(5);
$rotate->size('5MB');
$rotate->run();

View File

@ -213,27 +213,6 @@ class Utilities
return rmdir($source);
}
/**
* Attempt to fetch the most likely "external" IP for this instance.
*
* @return false|string
*/
public static function getPublicIp()
{
if (APP_INSIDE_DOCKER) {
if (APP_IN_PRODUCTION) {
$public_ip = @file_get_contents('http://ipecho.net/plain');
if (!empty($public_ip)) {
return $public_ip;
}
}
return 'localhost';
}
return gethostbyname(gethostname()) ?? 'localhost';
}
/**
* Flatten an array from format:
* [

View File

@ -1,7 +1,7 @@
<?php
namespace App;
use Azura\Settings;
use App\Settings;
use DateTime;
use DateTimeZone;
use Psr\SimpleCache\CacheInterface;

View File

@ -4,6 +4,7 @@ namespace App\Webhook\Connector;
use App\Entity;
use App\Event\SendWebhooks;
use App\Service\NChan;
use App\Settings;
use Doctrine\ORM\EntityManager;
use GuzzleHttp\Client;
use InfluxDB\Database;
@ -111,7 +112,7 @@ class Local
// Write JSON file to disk so nginx can serve it without calling the PHP stack at all.
$this->logger->debug('Writing static nowplaying text file...');
$static_np_dir = APP_INCLUDE_TEMP . '/nowplaying';
$static_np_dir = Settings::getInstance()->getTempDirectory() . '/nowplaying';
if (!is_dir($static_np_dir) && !mkdir($static_np_dir) && !is_dir($static_np_dir)) {
throw new RuntimeException(sprintf('Directory "%s" was not created', $static_np_dir));
}

View File

@ -3,6 +3,7 @@ namespace App\Webhook;
use App\Entity;
use App\Event\SendWebhooks;
use App\Settings;
use Azura\Exception;
use InvalidArgumentException;
use Monolog\Handler\TestHandler;
@ -33,7 +34,7 @@ class Dispatcher implements EventSubscriberInterface
public static function getSubscribedEvents()
{
if (APP_TESTING_MODE) {
if (Settings::getInstance()->isTesting()) {
return [];
}
@ -64,7 +65,7 @@ class Dispatcher implements EventSubscriberInterface
*/
public function dispatch(SendWebhooks $event): void
{
if (APP_TESTING_MODE) {
if (Settings::getInstance()->isTesting()) {
$this->logger->info('In testing mode; no webhooks dispatched.');
return;
}

View File

@ -66,7 +66,7 @@ $assets
<div class="card-body">
<p class="card-text"><?=__('To restore a backup from your host computer, run:') ?></p>
<?php if (APP_INSIDE_DOCKER): ?>
<?php if (\App\Settings::getInstance()->isDocker()): ?>
<pre><code>./docker.sh restore path_to_backup.zip</code></pre>
<?php else: ?>
<pre><code>/var/azuracast/www/bin/azuracast azuracast:restore path_to_backup.zip</code></pre>

View File

@ -12,7 +12,7 @@ $this->layout('main', [
<h2 class="card-title"><?=__('System Logs') ?></h2>
</div>
<div class="card-body">
<?php if (APP_INSIDE_DOCKER): ?>
<?php if (\App\Settings::getInstance()->isDocker()): ?>
<p><?=__('Because you are running Docker, some system logs can only be accessed from a shell session on the host computer. You can run <code>%s</code> to access container logs from the terminal.', 'docker-compose logs -f (nginx|web|stations|...)') ?></p>
<?php endif; ?>
</div>

View File

@ -1,4 +1,3 @@
<!DOCTYPE html>
<?php
/**
* @var \League\Plates\Template\Template $this
@ -15,6 +14,7 @@
$user = $request->getUser();
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
@ -148,7 +148,7 @@ echo $assets->js();
</section>
<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> &bull; '.$version->getVersionText().' &bull; '.(APP_INSIDE_DOCKER ? 'Docker' : 'Ansible').' &bull; PHP '.\PHP_MAJOR_VERSION.'.'.\PHP_MINOR_VERSION) ?><br>
<?=__('Powered by %s', '<a href="https://www.azuracast.com/" target="_blank">'.$settings['name'].'</a> &bull; '.$version->getVersionText().' &bull; '.(\App\Settings::getInstance()->isDocker() ? 'Docker' : 'Ansible').' &bull; 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') ?>
</footer>

View File

@ -2,7 +2,8 @@
// Icons generated by:
// http://www.favicon-generator.org/
$icon_base = '/static/icons/'.APP_APPLICATION_ENV;
/** @var \App\Settings $settings */
$icon_base = '/static/icons/'.$settings[\App\Settings::APP_ENV];
?>
<link rel="apple-touch-icon" sizes="180x180" href="<?=$icon_base ?>/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="<?=$icon_base ?>/favicon-32x32.png">

View File

@ -7,7 +7,7 @@
<p><?=__('If you\'re experiencing a bug or error, you can submit a GitHub issue using the link below.') ?></p>
<p><?=__('Your current installation type is <b>%s</b>. Be sure to include this when creating a new issue.', (APP_INSIDE_DOCKER ? 'Docker' : 'Ansible')) ?></p>
<p><?=__('Your current installation type is <b>%s</b>. Be sure to include this when creating a new issue.', (\App\Settings::getInstance()->isDocker() ? 'Docker' : 'Ansible')) ?></p>
</div>
<div class="card-actions">
<a class="btn btn-outline-primary" role="button" href="https://github.com/AzuraCast/AzuraCast/issues/new/choose" target="_blank">

View File

@ -12,7 +12,7 @@ class C05_Station_AutomationCest extends CestAbstract
$I->wantTo('Test station automation.');
// Set up automation preconditions.
$song_src = APP_INCLUDE_ROOT.'/resources/error.mp3';
$song_src = '/var/azuracast/www/resources/error.mp3';
$song_dest = $this->test_station->getRadioMediaDir().'/test.mp3';
copy($song_src, $song_dest);

View File

@ -16,7 +16,7 @@ class D02_Api_RequestsCest extends CestAbstract
$this->em->flush();
// Upload a test song.
$song_src = APP_INCLUDE_ROOT.'/resources/error.mp3';
$song_src = '/var/azuracast/www/resources/error.mp3';
$song_dest = $this->test_station->getRadioMediaDir().'/test.mp3';
copy($song_src, $song_dest);

View File

@ -3,20 +3,17 @@
* PHPStan Bootstrap File
*/
// Register gettext to avoid related errors
$translator = new \Gettext\Translator();
$translator->register();
error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT);
ini_set('display_errors', 1);
// Define APP_ constants used by AzuraCast.
define('APP_IS_COMMAND_LINE', true);
define('APP_INCLUDE_ROOT', dirname(__DIR__));
define('APP_INCLUDE_TEMP', dirname(APP_INCLUDE_ROOT).'/www_tmp');
$autoloader = require dirname(__DIR__).'/vendor/autoload.php';
define('APP_INSIDE_DOCKER', true);
define('APP_DOCKER_REVISION', 1);
$app = App\AppFactory::create($autoloader, [
Azura\Settings::BASE_DIR => dirname(__DIR__),
]);
define('APP_TESTING_MODE', true);
define('SAMPLE_TIMESTAMP', rand(time() - 86400, time() + 86400));
$di = $app->getContainer();
define('APP_APPLICATION_ENV', 'testing');
define('APP_IN_PRODUCTION', false);
/** @var App\Customization $customization */
$customization = $di->get(App\Customization::class);
$customization->init();