AzuraCast/src/Customization.php

248 lines
6.9 KiB
PHP
Raw Normal View History

<?php
namespace App;
use App\Entity;
use App\Http\ServerRequest;
use App\Service\NChan;
use Gettext\Translator;
2019-09-04 18:00:51 +00:00
use Locale;
use Psr\Http\Message\ServerRequestInterface;
class Customization
{
public const DEFAULT_LOCALE = 'en_US.UTF-8';
2019-03-14 01:49:19 +00:00
public const DEFAULT_THEME = 'light';
public const THEME_LIGHT = 'light';
public const THEME_DARK = 'dark';
protected ?Entity\User $user = null;
protected Entity\Settings $settings;
protected Environment $environment;
2020-07-10 08:17:51 +00:00
protected string $locale = self::DEFAULT_LOCALE;
protected string $theme = self::DEFAULT_THEME;
protected string $publicTheme = self::DEFAULT_THEME;
2020-07-10 08:17:51 +00:00
protected string $instanceName = '';
public function __construct(
Entity\Repository\SettingsRepository $settingsRepo,
Environment $environment,
ServerRequestInterface $request
) {
$this->settings = $settingsRepo->readSettings();
$this->environment = $environment;
$this->instanceName = $this->settings->getInstanceName() ?? '';
2019-09-04 18:00:51 +00:00
// Register current user
$this->user = $request->getAttribute(ServerRequest::ATTR_USER);
$this->locale = $this->initLocale($request);
2020-07-10 08:17:51 +00:00
// Register current theme
$queryParams = $request->getQueryParams();
if (!empty($queryParams['theme'])) {
$this->publicTheme = $this->theme = $queryParams['theme'];
} else {
$this->publicTheme = $this->settings->getPublicTheme() ?? $this->publicTheme;
if (null !== $this->user && !empty($this->user->getTheme())) {
$this->theme = (string)$this->user->getTheme();
}
2020-07-10 08:17:51 +00:00
}
// Set up the PHP translator
$translator = new Translator();
$locale_base = $environment->getBaseDirectory() . '/resources/locale/compiled';
2019-09-04 18:00:51 +00:00
$locale_path = $locale_base . '/' . $this->locale . '.php';
if (file_exists($locale_path)) {
$translator->loadTranslations($locale_path);
}
$translator->register();
// Register translation superglobal functions
2019-09-04 18:00:51 +00:00
setlocale(LC_ALL, $this->locale);
}
/**
* Return the user-customized, browser-specified or system default locale.
*
2020-10-25 09:53:52 +00:00
* @param ServerRequestInterface|null $request
*/
2020-10-25 09:53:52 +00:00
protected function initLocale(?ServerRequestInterface $request = null): string
{
$supported_locales = $this->environment->getSupportedLocales();
$try_locales = [];
// Prefer user-based profile locale.
if ($this->user !== null && !empty($this->user->getLocale()) && 'default' !== $this->user->getLocale()) {
$try_locales[] = $this->user->getLocale();
}
// Attempt to load from browser headers.
2020-10-25 09:53:52 +00:00
if ($request instanceof ServerRequestInterface) {
$server_params = $request->getServerParams();
2019-09-04 18:00:51 +00:00
$browser_locale = Locale::acceptFromHttp($server_params['HTTP_ACCEPT_LANGUAGE'] ?? null);
if (!empty($browser_locale)) {
if (2 === strlen($browser_locale)) {
$browser_locale = strtolower($browser_locale) . '_' . strtoupper($browser_locale);
}
2019-09-04 18:00:51 +00:00
$try_locales[] = substr($browser_locale, 0, 5) . '.UTF-8';
}
}
// Attempt to load from environment variable.
$envLocale = $this->environment->getLang();
if (!empty($envLocale)) {
$try_locales[] = substr($envLocale, 0, 5) . '.UTF-8';
}
2019-09-04 18:00:51 +00:00
foreach ($try_locales as $exact_locale) {
// Prefer exact match.
if (isset($supported_locales[$exact_locale])) {
return $exact_locale;
}
// Use approximate match if available.
foreach ($supported_locales as $lang_code => $lang_name) {
if (strpos($exact_locale, substr($lang_code, 0, 2)) === 0) {
return $lang_code;
}
}
}
// Default to system option.
return self::DEFAULT_LOCALE;
}
2019-03-14 01:49:19 +00:00
public function getLocale(): string
{
2020-07-10 08:17:51 +00:00
return $this->locale;
}
/**
* @return string A shortened locale (minus .UTF-8) for use in Vue.
*/
public function getVueLocale(): string
{
2020-07-08 07:03:50 +00:00
return json_encode(substr($this->getLocale(), 0, 5), JSON_THROW_ON_ERROR);
}
/**
* Returns the user-customized or system default theme.
*/
2020-07-08 07:03:50 +00:00
public function getTheme(): string
{
2020-07-10 08:17:51 +00:00
return $this->theme;
}
/**
* Get the instance name for this AzuraCast instance.
*/
2020-07-10 08:17:51 +00:00
public function getInstanceName(): string
{
2020-07-10 08:17:51 +00:00
return $this->instanceName;
}
/**
* Get the theme name to be used in public (non-logged-in) pages.
*/
2019-03-14 01:49:19 +00:00
public function getPublicTheme(): string
{
return $this->publicTheme;
}
/**
* Return the administrator-supplied custom CSS for public (minimal layout) pages, if specified.
*/
2020-07-08 07:03:50 +00:00
public function getCustomPublicCss(): string
{
return $this->settings->getPublicCustomCss() ?? '';
}
/**
* Return the administrator-supplied custom JS for public (minimal layout) pages, if specified.
*/
2020-07-08 07:03:50 +00:00
public function getCustomPublicJs(): string
{
return $this->settings->getPublicCustomJs() ?? '';
}
/**
* Return the administrator-supplied custom CSS for internal (full layout) pages, if specified.
*/
2020-07-08 07:03:50 +00:00
public function getCustomInternalCss(): string
{
return $this->settings->getInternalCustomCss() ?? '';
}
/**
* Return whether to show or hide album art on public pages.
*/
public function hideAlbumArt(): bool
{
return $this->settings->getHideAlbumArt();
}
/**
* Return the calculated page title given branding settings and the application environment.
*
* @param string|null $title
*/
public function getPageTitle($title = null): string
{
if (!$this->hideProductName()) {
if ($title) {
$title .= ' - ' . $this->environment->getAppName();
} else {
$title = $this->environment->getAppName();
}
}
if (!$this->environment->isProduction()) {
$title = '(' . ucfirst($this->environment->getAppEnvironment()) . ') ' . $title;
}
return $title;
}
/**
2019-09-04 18:00:51 +00:00
* Return whether to show or hide the AzuraCast name from public-facing pages.
*/
2019-09-04 18:00:51 +00:00
public function hideProductName(): bool
{
return $this->settings->getHideProductName();
}
2019-09-04 18:00:51 +00:00
public function useWebSocketsForNowPlaying(): bool
{
2019-09-04 18:00:51 +00:00
if (!NChan::isSupported()) {
return false;
}
return $this->settings->getEnableWebsockets();
}
/**
* Initialize the CLI without instantiating the Doctrine DB stack (allowing cache clearing, etc.).
*/
public static function initCli(): void
{
$translator = new Translator();
$translator->register();
}
}