2016-10-07 02:41:04 +00:00
|
|
|
<?php
|
2018-08-04 22:05:14 +00:00
|
|
|
namespace App;
|
2016-10-07 02:41:04 +00:00
|
|
|
|
2018-11-28 13:45:17 +00:00
|
|
|
use Azura\Settings;
|
|
|
|
use App\Entity;
|
2018-07-03 22:51:05 +00:00
|
|
|
use App\Http\Request;
|
2018-03-19 01:31:43 +00:00
|
|
|
use Gettext\Translator;
|
2018-10-04 23:12:12 +00:00
|
|
|
use GuzzleHttp\Psr7\Uri;
|
|
|
|
use Psr\Http\Message\UriInterface;
|
2016-10-07 02:41:04 +00:00
|
|
|
|
|
|
|
class Customization
|
|
|
|
{
|
2018-11-28 13:45:17 +00:00
|
|
|
/** @var Settings */
|
2017-07-19 00:09:29 +00:00
|
|
|
protected $app_settings;
|
2016-10-07 02:41:04 +00:00
|
|
|
|
2018-02-01 11:49:40 +00:00
|
|
|
/** @var Entity\User */
|
|
|
|
protected $user = null;
|
2016-10-07 02:41:04 +00:00
|
|
|
|
2017-07-19 00:09:29 +00:00
|
|
|
/** @var Entity\Repository\SettingsRepository */
|
|
|
|
protected $settings_repo;
|
2016-10-07 02:41:04 +00:00
|
|
|
|
2018-11-28 13:45:17 +00:00
|
|
|
public function __construct(Settings $app_settings, Entity\Repository\SettingsRepository $settings_repo)
|
2016-10-07 02:41:04 +00:00
|
|
|
{
|
2017-07-19 00:09:29 +00:00
|
|
|
$this->app_settings = $app_settings;
|
|
|
|
$this->settings_repo = $settings_repo;
|
2016-10-07 02:41:04 +00:00
|
|
|
}
|
|
|
|
|
2018-02-01 11:49:40 +00:00
|
|
|
/**
|
2018-07-03 22:51:05 +00:00
|
|
|
* Initialize timezone and locale settings for the current user, and write them as attributes to the request.
|
|
|
|
*
|
|
|
|
* @param Request $request
|
|
|
|
* @return Request
|
2018-02-01 11:49:40 +00:00
|
|
|
*/
|
2018-07-03 22:51:05 +00:00
|
|
|
public function init(Request $request): Request
|
2018-02-01 11:49:40 +00:00
|
|
|
{
|
2018-07-03 22:51:05 +00:00
|
|
|
$timezone = $this->getTimeZone();
|
|
|
|
|
2018-11-28 13:45:17 +00:00
|
|
|
if (!$this->app_settings->isCli() || $this->app_settings->isTesting()) {
|
2018-02-01 11:49:40 +00:00
|
|
|
// Set time zone.
|
2018-07-03 22:51:05 +00:00
|
|
|
date_default_timezone_set($timezone);
|
2018-02-01 11:49:40 +00:00
|
|
|
|
|
|
|
// Localization
|
|
|
|
$locale = $this->getLocale();
|
2018-03-19 01:31:43 +00:00
|
|
|
} else {
|
|
|
|
$locale = $this->app_settings['locale']['default'];
|
|
|
|
}
|
|
|
|
|
|
|
|
$translator = new Translator();
|
|
|
|
|
2018-11-28 13:45:17 +00:00
|
|
|
$locale_base = $this->app_settings[Settings::BASE_DIR].'/resources/locale/compiled';
|
2018-03-19 01:31:43 +00:00
|
|
|
$locale_path = $locale_base.'/'.$locale.'.php';
|
2018-02-01 11:49:40 +00:00
|
|
|
|
2018-03-19 01:31:43 +00:00
|
|
|
if (file_exists($locale_path)) {
|
|
|
|
$translator->loadTranslations($locale_path);
|
2018-02-01 11:49:40 +00:00
|
|
|
}
|
2018-03-19 01:31:43 +00:00
|
|
|
|
|
|
|
// Register translation superglobal functions
|
|
|
|
$translator->register();
|
|
|
|
|
|
|
|
putenv("LANG=" . $locale);
|
2018-11-28 13:45:17 +00:00
|
|
|
setlocale(\LC_ALL, $locale);
|
2018-07-03 22:51:05 +00:00
|
|
|
|
2018-08-04 22:05:14 +00:00
|
|
|
return $request
|
|
|
|
->withAttribute('locale', $locale)
|
|
|
|
->withAttribute('timezone', $timezone);
|
2018-02-01 11:49:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the currently active/logged in user.
|
|
|
|
*
|
|
|
|
* @param Entity\User $user
|
|
|
|
*/
|
2018-09-04 22:08:16 +00:00
|
|
|
public function setUser(Entity\User $user = null): void
|
2018-02-01 11:49:40 +00:00
|
|
|
{
|
|
|
|
$this->user = $user;
|
|
|
|
}
|
|
|
|
|
2016-10-07 02:41:04 +00:00
|
|
|
/**
|
|
|
|
* Get the user's custom time zone or the system default.
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
2018-09-04 22:08:16 +00:00
|
|
|
public function getTimeZone(): string
|
2016-10-07 02:41:04 +00:00
|
|
|
{
|
2017-08-17 18:28:48 +00:00
|
|
|
if ($this->user !== null && !empty($this->user->getTimezone())) {
|
|
|
|
return $this->user->getTimezone();
|
2017-01-24 00:35:16 +00:00
|
|
|
}
|
2018-02-01 11:49:40 +00:00
|
|
|
|
2018-09-04 22:08:16 +00:00
|
|
|
return $this->getDefaultTimeZone();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return either the configured global default timezone or the system's regular default.
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getDefaultTimeZone(): string
|
|
|
|
{
|
2018-11-28 13:45:17 +00:00
|
|
|
$global_tz = $this->settings_repo->getSetting(Entity\Settings::TIMEZONE);
|
2018-09-04 22:08:16 +00:00
|
|
|
|
|
|
|
if (!empty($global_tz)) {
|
|
|
|
return $global_tz;
|
|
|
|
}
|
|
|
|
|
2018-02-01 11:49:40 +00:00
|
|
|
return date_default_timezone_get();
|
2016-10-07 02:41:04 +00:00
|
|
|
}
|
|
|
|
|
2017-12-14 18:04:58 +00:00
|
|
|
/**
|
|
|
|
* Format the given UNIX timestamp into a locale-friendly time.
|
|
|
|
*
|
|
|
|
* @param $timestamp
|
2018-03-28 06:07:56 +00:00
|
|
|
* @param bool $use_utc
|
2017-12-14 18:04:58 +00:00
|
|
|
* @param bool $show_timezone_abbr
|
|
|
|
* @return string Formatted time for presentation.
|
|
|
|
*/
|
2018-03-28 06:07:56 +00:00
|
|
|
public function formatTime($timestamp = null, $use_utc = false, $show_timezone_abbr = false)
|
2017-12-14 18:04:58 +00:00
|
|
|
{
|
|
|
|
$timestamp = $timestamp ?? time();
|
|
|
|
|
|
|
|
$time_formats = $this->app_settings['time_formats'];
|
|
|
|
$locale = $this->getLocale();
|
|
|
|
|
|
|
|
$time_format = $time_formats[$locale] ?? $time_formats['default'];
|
|
|
|
|
|
|
|
if ($show_timezone_abbr) {
|
2018-03-28 06:07:56 +00:00
|
|
|
$time_format .= ($use_utc) ? ' \U\T\C' : ' T';
|
2017-12-14 18:04:58 +00:00
|
|
|
}
|
|
|
|
|
2018-03-28 06:07:56 +00:00
|
|
|
return ($use_utc) ? gmdate($time_format, $timestamp) : date($time_format, $timestamp);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Format a date/time using PHP's IntlDateFormatter constants.
|
|
|
|
*
|
|
|
|
* @param $timestamp
|
|
|
|
* @param bool $use_utc
|
|
|
|
* @param int|null $date_display One of:
|
|
|
|
* IntlDateFormatter::NONE - Do not include
|
|
|
|
* IntlDateFormatter::FULL - (Tuesday, April 12, 1952 AD or 3:30:42pm PST)
|
|
|
|
* IntlDateFormatter::LONG (default) - (January 12, 1952 or 3:30:32pm)
|
|
|
|
* IntlDateFormatter::MEDIUM - (Jan 12, 1952)
|
|
|
|
* IntlDateFormatter::SHORT - (12/13/52 or 3:30pm)
|
|
|
|
* @param int|null $time_display One of the above.
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function formatDateTime($timestamp, $use_utc = false, $date_display = \IntlDateFormatter::LONG, $time_display = \IntlDateFormatter::LONG)
|
|
|
|
{
|
|
|
|
$timezone = ($use_utc) ? 'UTC' : date_default_timezone_get();
|
|
|
|
$locale = str_replace('.UTF-8', '', $this->getLocale());
|
|
|
|
|
|
|
|
$fmt = new \IntlDateFormatter(
|
|
|
|
$locale,
|
|
|
|
$date_display,
|
|
|
|
$time_display,
|
|
|
|
$timezone,
|
|
|
|
\IntlDateFormatter::GREGORIAN
|
|
|
|
);
|
|
|
|
|
|
|
|
return $fmt->format($timestamp);
|
2017-12-14 18:04:58 +00:00
|
|
|
}
|
|
|
|
|
2016-10-07 02:41:04 +00:00
|
|
|
/**
|
|
|
|
* Return the user-customized, browser-specified or system default locale.
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
2018-11-24 18:05:23 +00:00
|
|
|
public function getLocale(): ?string
|
2016-10-07 02:41:04 +00:00
|
|
|
{
|
2017-12-14 18:04:58 +00:00
|
|
|
static $locale = null;
|
|
|
|
|
2018-11-24 18:05:23 +00:00
|
|
|
if (null !== $locale) {
|
|
|
|
return $locale;
|
|
|
|
}
|
|
|
|
|
|
|
|
$supported_locales = $this->app_settings['locale']['supported'];
|
2016-10-07 02:41:04 +00:00
|
|
|
|
2018-11-24 18:05:23 +00:00
|
|
|
// Prefer user-based profile locale.
|
|
|
|
if ($this->user !== null && !empty($this->user->getLocale()) && $this->user->getLocale() !== 'default') {
|
|
|
|
if (isset($supported_locales[$this->user->getLocale()])) {
|
|
|
|
$locale = $this->user->getLocale();
|
|
|
|
return $locale;
|
2017-01-24 00:35:16 +00:00
|
|
|
}
|
2018-11-24 18:05:23 +00:00
|
|
|
}
|
2016-10-07 02:41:04 +00:00
|
|
|
|
2018-11-24 18:05:23 +00:00
|
|
|
// Attempt to load from browser headers.
|
|
|
|
$browser_locale = \Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']);
|
2016-10-07 02:41:04 +00:00
|
|
|
|
2018-11-24 18:05:23 +00:00
|
|
|
// Prefer exact match.
|
|
|
|
$exact_locale = substr($browser_locale, 0, 5).'.UTF-8';
|
|
|
|
|
|
|
|
if (isset($supported_locales[$exact_locale])) {
|
|
|
|
$locale = $exact_locale;
|
|
|
|
return $locale;
|
|
|
|
}
|
2016-10-07 02:41:04 +00:00
|
|
|
|
2018-11-24 18:05:23 +00:00
|
|
|
// Use approximate match if available.
|
|
|
|
foreach ($supported_locales as $lang_code => $lang_name) {
|
|
|
|
if (strcmp(substr($browser_locale, 0, 2), substr($lang_code, 0, 2)) == 0) {
|
|
|
|
$locale = $lang_code;
|
|
|
|
return $locale;
|
2017-12-14 18:04:58 +00:00
|
|
|
}
|
2017-01-24 00:35:16 +00:00
|
|
|
}
|
2016-10-07 02:41:04 +00:00
|
|
|
|
2018-11-24 18:05:23 +00:00
|
|
|
// Default to system option.
|
|
|
|
$locale = $this->app_settings['locale']['default'];
|
2016-10-07 02:41:04 +00:00
|
|
|
return $locale;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the user-customized or system default theme.
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getTheme()
|
|
|
|
{
|
2017-08-17 18:28:48 +00:00
|
|
|
if ($this->user !== null && !empty($this->user->getTheme())) {
|
2017-07-19 00:09:29 +00:00
|
|
|
$available_themes = $this->app_settings['themes']['available'];
|
2018-03-19 07:31:35 +00:00
|
|
|
if (in_array($this->user->getTheme(), $available_themes)) {
|
2017-08-17 18:28:48 +00:00
|
|
|
return $this->user->getTheme();
|
2017-01-24 00:35:16 +00:00
|
|
|
}
|
2016-10-07 02:41:04 +00:00
|
|
|
}
|
|
|
|
|
2017-07-19 00:09:29 +00:00
|
|
|
return $this->app_settings['themes']['default'];
|
2016-10-07 02:41:04 +00:00
|
|
|
}
|
2017-05-21 04:27:34 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the instance name for this AzuraCast instance.
|
|
|
|
*
|
|
|
|
* @return string|null
|
|
|
|
*/
|
|
|
|
public function getInstanceName()
|
|
|
|
{
|
|
|
|
static $instance_name;
|
|
|
|
|
|
|
|
if ($instance_name === null) {
|
2018-11-28 13:45:17 +00:00
|
|
|
$instance_name = $this->settings_repo->getSetting(Entity\Settings::INSTANCE_NAME, '');
|
2017-05-21 04:27:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return $instance_name;
|
|
|
|
}
|
2017-09-20 02:10:06 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the theme name to be used in public (non-logged-in) pages.
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getPublicTheme()
|
|
|
|
{
|
2018-11-28 13:45:17 +00:00
|
|
|
$public_theme = $this->settings_repo->getSetting(Entity\Settings::PUBLIC_THEME, null);
|
2018-03-23 19:56:48 +00:00
|
|
|
|
2018-03-24 08:03:32 +00:00
|
|
|
if ($public_theme && in_array($public_theme, $this->app_settings['themes']['available'], true)) {
|
2018-03-23 19:56:48 +00:00
|
|
|
return $public_theme;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this->app_settings['themes']['default'];
|
2017-09-20 02:10:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the administrator-supplied custom CSS for public (minimal layout) pages, if specified.
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getCustomPublicCss()
|
|
|
|
{
|
2018-11-28 13:45:17 +00:00
|
|
|
return (string)$this->settings_repo->getSetting(Entity\Settings::CUSTOM_CSS_PUBLIC, '');
|
2017-09-20 02:10:06 +00:00
|
|
|
}
|
|
|
|
|
2018-02-28 15:25:33 +00:00
|
|
|
/**
|
|
|
|
* Return the administrator-supplied custom JS for public (minimal layout) pages, if specified.
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getCustomPublicJs()
|
|
|
|
{
|
2018-11-28 13:45:17 +00:00
|
|
|
return (string)$this->settings_repo->getSetting(Entity\Settings::CUSTOM_JS_PUBLIC, '');
|
2018-02-28 15:25:33 +00:00
|
|
|
}
|
|
|
|
|
2017-09-20 02:10:06 +00:00
|
|
|
/**
|
|
|
|
* Return the administrator-supplied custom CSS for internal (full layout) pages, if specified.
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getCustomInternalCss()
|
|
|
|
{
|
2018-11-28 13:45:17 +00:00
|
|
|
return (string)$this->settings_repo->getSetting(Entity\Settings::CUSTOM_CSS_INTERNAL, '');
|
2017-09-20 02:10:06 +00:00
|
|
|
}
|
2018-02-04 13:20:23 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Return whether to show or hide the AzuraCast name from public-facing pages.
|
|
|
|
*
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function hideProductName(): bool
|
|
|
|
{
|
2018-11-28 13:45:17 +00:00
|
|
|
return (bool)$this->settings_repo->getSetting(Entity\Settings::HIDE_PRODUCT_NAME, false);
|
2018-02-04 13:20:23 +00:00
|
|
|
}
|
2018-03-04 12:06:50 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Return whether to show or hide album art on public pages.
|
|
|
|
*
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function hideAlbumArt(): bool
|
|
|
|
{
|
2018-11-28 13:45:17 +00:00
|
|
|
return (bool)$this->settings_repo->getSetting(Entity\Settings::HIDE_ALBUM_ART, false);
|
2018-03-04 12:06:50 +00:00
|
|
|
}
|
2018-03-17 02:40:34 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the URL to use for songs with no specified album artwork, when artwork is displayed.
|
|
|
|
*
|
2018-10-04 23:12:12 +00:00
|
|
|
* @return UriInterface
|
2018-03-17 02:40:34 +00:00
|
|
|
*/
|
2018-10-04 23:12:12 +00:00
|
|
|
public function getDefaultAlbumArtUrl(): UriInterface
|
2018-03-17 02:40:34 +00:00
|
|
|
{
|
2018-11-28 13:45:17 +00:00
|
|
|
$custom_url = trim($this->settings_repo->getSetting(Entity\Settings::DEFAULT_ALBUM_ART_URL));
|
2018-03-17 02:40:34 +00:00
|
|
|
|
|
|
|
if (!empty($custom_url)) {
|
2018-10-04 23:12:12 +00:00
|
|
|
return new Uri($custom_url);
|
2018-03-17 02:40:34 +00:00
|
|
|
}
|
|
|
|
|
2018-10-04 23:12:12 +00:00
|
|
|
return new Uri('/static/img/generic_song.jpg');
|
2018-03-17 02:40:34 +00:00
|
|
|
}
|
2018-10-17 03:50:14 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the calculated page title given branding settings and the application environment.
|
|
|
|
*
|
|
|
|
* @param string|null $title
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getPageTitle($title = null): string
|
|
|
|
{
|
|
|
|
if (!$this->hideProductName()) {
|
|
|
|
if ($title) {
|
2018-11-28 13:45:17 +00:00
|
|
|
$title .= ' - '.$this->app_settings[Settings::APP_NAME];
|
2018-10-17 03:50:14 +00:00
|
|
|
} else {
|
2018-11-28 13:45:17 +00:00
|
|
|
$title = $this->app_settings[Settings::APP_NAME];
|
2018-10-17 03:50:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-28 13:45:17 +00:00
|
|
|
if (!$this->app_settings->isProduction()) {
|
|
|
|
$title = '('.ucfirst($this->app_settings[Settings::APP_ENV]).') '.$title;
|
2018-10-17 03:50:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return $title;
|
|
|
|
}
|
2018-02-28 15:25:33 +00:00
|
|
|
}
|