sintonia/legacy/application/models/Preference.php
Thomas Göttgens 170d09545e
feat(legacy): disable public radio page and redirect to login (#2903)
### Description

Many people don't need the public page and use libretime purely for
playout management. This adds the ability to have libretime publicly
available but only present the login page to the user.

**I have updated the documentation to reflect these changes**:

no, but i will add documentation if this PR is accepted.

### Testing Notes

**What I did:**

Toggle the new ceckbox on the general settings, log out and back in and
check behaviour.

note: this may have conflicts with the trim overbooked PR since the
toggle sits in the same place. If both are accepted this needs to be
formatted nicely :-)

---------

Co-authored-by: Thomas Göttgens <tgoettgens@mail.com>
Co-authored-by: Jonas L. <jooola@users.noreply.github.com>
Co-authored-by: Kyle Robbertze <paddatrapper@users.noreply.github.com>
Co-authored-by: jo <ljonas@riseup.net>
2024-02-02 19:04:12 +01:00

1592 lines
45 KiB
PHP

<?php
class Application_Model_Preference
{
private static function getUserId()
{
// pass in true so the check is made with the autoloader
// we need this check because saas calls this function from outside Zend
if (!class_exists('Zend_Session', true) || !Zend_Session::isStarted() || !class_exists('Zend_Auth', true) || !Zend_Auth::getInstance()->hasIdentity()) {
$userId = null;
} else {
$auth = Zend_Auth::getInstance();
$userId = $auth->getIdentity()->id;
}
return $userId;
}
/**
* @param bool $isUserValue is true when we are setting a value for the current user
* @param mixed $key
* @param mixed $value
*/
private static function setValue($key, $value, $isUserValue = false)
{
$con = Propel::getConnection(CcPrefPeer::DATABASE_NAME);
// We are using row-level locking in Postgres via "FOR UPDATE" instead of a transaction here
// because sometimes this function needs to be called while a transaction is already started.
try {
/* Comment this out while we reevaluate it in favor of a unique constraint
static::_lock($con); */
$userId = self::getUserId();
if ($isUserValue && is_null($userId)) {
throw new Exception("User id can't be null for a user preference {$key}.");
}
// Check if key already exists
$sql = 'SELECT valstr FROM cc_pref'
. ' WHERE keystr = :key';
$paramMap = [];
$paramMap[':key'] = $key;
// For user specific preference, check if id matches as well
if ($isUserValue) {
$sql .= ' AND subjid = :id';
$paramMap[':id'] = $userId;
}
$sql .= ' FOR UPDATE';
$result = Application_Common_Database::prepareAndExecute(
$sql,
$paramMap,
Application_Common_Database::ROW_COUNT,
PDO::FETCH_ASSOC,
$con
);
$paramMap = [];
if ($result > 1) {
// this case should not happen.
$caller = debug_backtrace()[1]['function'];
throw new Exception('Invalid number of results returned. Should be ' .
"0 or 1, but is '{$result}' instead, caller={$caller}");
}
if ($result == 1) {
// result found
if (!$isUserValue) {
// system pref
$sql = 'UPDATE cc_pref'
. ' SET subjid = NULL, valstr = :value'
. ' WHERE keystr = :key';
} else {
// user pref
$sql = 'UPDATE cc_pref'
. ' SET valstr = :value'
. ' WHERE keystr = :key AND subjid = :id';
$paramMap[':id'] = $userId;
}
} else {
// result not found
if (!$isUserValue) {
// system pref
$sql = 'INSERT INTO cc_pref (keystr, valstr)'
. ' VALUES (:key, :value)';
} else {
// user pref
$sql = 'INSERT INTO cc_pref (subjid, keystr, valstr)'
. ' VALUES (:id, :key, :value)';
$paramMap[':id'] = $userId;
}
}
$paramMap[':key'] = $key;
$paramMap[':value'] = $value;
Application_Common_Database::prepareAndExecute(
$sql,
$paramMap,
Application_Common_Database::EXECUTE,
PDO::FETCH_ASSOC,
$con
);
} catch (Exception $e) {
header('HTTP/1.0 503 Service Unavailable');
Logging::info('Database error: ' . $e->getMessage());
exit;
}
}
/**
* Given a PDO connection, lock the cc_pref table for the current transaction.
*
* Creates a table level lock, which defaults to ACCESS EXCLUSIVE mode;
* see https://www.postgresql.org/docs/9.1/static/explicit-locking.html
*
* @param PDO $con
*/
private static function _lock($con)
{
// If we're not in a transaction, a lock is pointless
if (!$con->inTransaction()) {
return;
}
// Don't specify NOWAIT here; we should block on obtaining this lock
// in case we're handling simultaneous requests.
// Locks only last until the end of the transaction, so we shouldn't have to
// worry about this causing any noticeable difference in request processing speed
$sql = 'LOCK TABLE cc_pref';
$st = $con->prepare($sql);
$st->execute();
}
/**
* @param string $key the preference key string
* @param bool|false $isUserValue select the preference for the current user
* @param bool|false $forceDefault only look for default (no user ID) values
*
* @return mixed the preference value
*/
private static function getValue($key, $isUserValue = false, $forceDefault = false)
{
try {
$userId = null;
if ($isUserValue) {
// This is nested in here because so we can still use getValue() when the session hasn't started yet.
$userId = self::getUserId();
if (is_null($userId)) {
throw new Exception("User id can't be null for a user preference.");
}
}
// Check if key already exists
$sql = 'SELECT COUNT(*) FROM cc_pref'
. ' WHERE keystr = :key';
$paramMap = [];
$paramMap[':key'] = $key;
// For user specific preference, check if id matches as well
if ($isUserValue) {
$sql .= ' AND subjid = :id';
$paramMap[':id'] = $userId;
} elseif ($forceDefault) {
$sql .= ' AND subjid IS NULL';
}
$result = Application_Common_Database::prepareAndExecute($sql, $paramMap, Application_Common_Database::COLUMN);
// return an empty string if the result doesn't exist.
if ($result == 0) {
$res = '';
} else {
$sql = 'SELECT valstr FROM cc_pref'
. ' WHERE keystr = :key';
$paramMap = [];
$paramMap[':key'] = $key;
// For user specific preference, check if id matches as well
if ($isUserValue) {
$sql .= ' AND subjid = :id';
$paramMap[':id'] = $userId;
}
$result = Application_Common_Database::prepareAndExecute($sql, $paramMap, Application_Common_Database::COLUMN);
$res = ($result !== false) ? $result : '';
}
return $res;
} catch (Exception $e) {
header('HTTP/1.0 503 Service Unavailable');
Logging::info('Could not connect to database: ' . $e);
exit;
}
}
public static function GetHeadTitle()
{
$title = self::getValue('station_name');
if (empty($title)) {
$title = PRODUCT_NAME;
}
return $title;
}
public static function SetHeadTitle($title, $view = null)
{
self::setValue('station_name', $title);
// in case this is called from airtime-saas script
if ($view !== null) {
// set session variable to new station name so that html title is updated.
// should probably do this in a view helper to keep this controller as minimal as possible.
$view->headTitle()->exchangeArray([]); // clear headTitle ArrayObject
$view->headTitle(self::GetHeadTitle());
}
$eventType = 'update_station_name';
$md = ['station_name' => $title];
Application_Model_RabbitMq::SendMessageToPypo($eventType, $md);
}
/**
* Set the furthest date that a never-ending show
* should be populated until.
*
* @param DateTime $dateTime
* A row from cc_show_days table
*/
public static function SetShowsPopulatedUntil($dateTime)
{
$dateTime->setTimezone(new DateTimeZone('UTC'));
self::setValue('shows_populated_until', $dateTime->format(DEFAULT_TIMESTAMP_FORMAT));
}
/**
* Get the furthest date that a never-ending show
* should be populated until.
*
* Returns null if the value hasn't been set, otherwise returns
* a DateTime object representing the date.
*
* @return DateTime (in UTC Timezone)
*/
public static function GetShowsPopulatedUntil()
{
$date = self::getValue('shows_populated_until');
if ($date == '') {
return null;
}
return new DateTime($date, new DateTimeZone('UTC'));
}
public static function SetDefaultCrossfadeDuration($duration)
{
self::setValue('default_crossfade_duration', $duration);
}
public static function GetDefaultCrossfadeDuration()
{
$duration = self::getValue('default_crossfade_duration');
if ($duration === '') {
// the default value of the fade is 00.5
return '0';
}
return $duration;
}
public static function SetDefaultFadeIn($fade)
{
self::setValue('default_fade_in', $fade);
}
public static function GetDefaultFadeIn()
{
$fade = self::getValue('default_fade_in');
if ($fade === '') {
// the default value of the fade is 00.5
return '0.5';
}
return $fade;
}
public static function SetDefaultFadeOut($fade)
{
self::setValue('default_fade_out', $fade);
}
public static function GetDefaultFadeOut()
{
$fade = self::getValue('default_fade_out');
if ($fade === '') {
// the default value of the fade is 0.5
return '0.5';
}
return $fade;
}
public static function SetDefaultFade($fade)
{
self::setValue('default_fade', $fade);
}
public static function SetDefaultTransitionFade($fade)
{
self::setValue('default_transition_fade', $fade);
$eventType = 'update_transition_fade';
$md = ['transition_fade' => $fade];
Application_Model_RabbitMq::SendMessageToPypo($eventType, $md);
}
public static function GetDefaultTransitionFade()
{
$transition_fade = self::getValue('default_transition_fade');
return ($transition_fade == '') ? '0.000' : $transition_fade;
}
public static function SetStreamLabelFormat($type)
{
self::setValue('stream_label_format', $type);
$eventType = 'update_stream_format';
$md = ['stream_format' => $type];
Application_Model_RabbitMq::SendMessageToPypo($eventType, $md);
}
public static function GetStreamLabelFormat()
{
return self::getValue('stream_label_format');
}
public static function getOffAirMeta()
{
return self::getValue('off_air_meta');
}
public static function setOffAirMeta($offAirMeta)
{
self::setValue('off_air_meta', $offAirMeta);
Application_Model_RabbitMq::SendMessageToPypo(
'update_message_offline',
['message_offline' => $offAirMeta]
);
}
public static function GetStationName()
{
return self::getValue('station_name');
}
public static function SetStationName($station_name)
{
self::setValue('station_name', $station_name);
}
public static function SetAllow3rdPartyApi($bool)
{
self::setValue('third_party_api', $bool);
}
public static function GetAllow3rdPartyApi()
{
$val = self::getValue('third_party_api');
return (strlen($val) == 0) ? '1' : $val;
}
public static function SetPodcastAlbumOverride($bool)
{
self::setValue('podcast_album_override', $bool);
}
public static function GetPodcastAlbumOverride()
{
$val = self::getValue('podcast_album_override');
return $val === '1' ? true : false;
}
public static function SetPodcastAutoSmartblock($bool)
{
self::setValue('podcast_auto_smartblock', $bool);
}
public static function GetPodcastAutoSmartblock()
{
$val = self::getValue('podcast_auto_smartblock');
return $val === '1' ? true : false;
}
public static function SetTrackTypeDefault($tracktype)
{
self::setValue('tracktype_default', $tracktype);
}
public static function GetTrackTypeDefault()
{
return self::getValue('tracktype_default');
}
public static function GetIntroPlaylist()
{
return self::getValue('intro_playlist');
}
public static function GetOutroPlaylist()
{
return self::getValue('outro_playlist');
}
public static function SetIntroPlaylist($playlist)
{
self::setValue('intro_playlist', $playlist);
}
public static function SetOutroPlaylist($playlist)
{
self::setValue('outro_playlist', $playlist);
}
public static function SetPhone($phone)
{
self::setValue('phone', $phone);
}
public static function GetPhone()
{
return self::getValue('phone');
}
public static function SetEmail($email)
{
self::setValue('email', $email);
}
public static function GetEmail()
{
return self::getValue('email');
}
public static function SetStationWebSite($site)
{
self::setValue('station_website', $site);
}
public static function GetStationWebSite()
{
return self::getValue('station_website');
}
public static function SetSupportFeedback($feedback)
{
self::setValue('support_feedback', $feedback);
}
public static function GetSupportFeedback()
{
return self::getValue('support_feedback');
}
public static function SetPublicise($publicise)
{
self::setValue('publicise', $publicise);
}
public static function GetPublicise()
{
return self::getValue('publicise');
}
public static function SetRegistered($registered)
{
self::setValue('registered', $registered);
}
public static function GetRegistered()
{
return self::getValue('registered');
}
public static function SetStationCountry($country)
{
self::setValue('country', $country);
}
public static function GetStationCountry()
{
return self::getValue('country');
}
public static function SetStationCity($city)
{
self::setValue('city', $city);
}
public static function GetStationCity()
{
return self::getValue('city');
}
public static function SetStationDescription($description)
{
self::setValue('description', $description);
}
public static function GetStationDescription()
{
$description = self::getValue('description');
if (!empty($description)) {
return $description;
}
return sprintf(_('Powered by %s'), SAAS_PRODUCT_BRANDING_NAME);
}
// Returns station default timezone (from preferences)
public static function GetDefaultTimezone()
{
return Config::get('general.timezone');
}
public static function SetUserTimezone($timezone = null)
{
self::setValue('user_timezone', $timezone, true);
}
public static function GetUserTimezone()
{
$timezone = self::getValue('user_timezone', true);
if (!$timezone) {
return self::GetDefaultTimezone();
}
return $timezone;
}
// Always attempts to returns the current user's personal timezone setting
public static function GetTimezone()
{
$userId = self::getUserId();
if (!is_null($userId)) {
return self::GetUserTimezone();
}
return self::GetDefaultTimezone();
}
// This is the language setting on preferences page
public static function SetDefaultLocale($locale)
{
self::setValue('locale', $locale);
}
public static function GetDefaultLocale()
{
return self::getValue('locale');
}
public static function GetUserLocale()
{
$locale = self::getValue('user_locale', true);
// empty() checks for null and empty strings - more robust than !val
if (empty($locale)) {
return self::GetDefaultLocale();
}
return $locale;
}
public static function SetUserLocale($locale = null)
{
// When a new user is created they will get the default locale
// setting which the admin sets on preferences page
if (is_null($locale)) {
$locale = self::GetDefaultLocale();
}
self::setValue('user_locale', $locale, true);
}
public static function GetLocale()
{
$userId = self::getUserId();
if (!is_null($userId)) {
return self::GetUserLocale();
}
return self::GetDefaultLocale();
}
public static function SetStationLogo($imagePath)
{
if (empty($imagePath)) {
Logging::info('Removed station logo');
}
$image = @file_get_contents($imagePath);
$image = base64_encode($image);
self::setValue('logoImage', $image);
}
public static function GetStationLogo()
{
$logoImage = self::getValue('logoImage');
if (!empty($logoImage)) {
return $logoImage;
}
// We return the Airtime logo if no logo is set in the database.
// airtime_logo.png is stored under the public directory
$image = @file_get_contents(ROOT_PATH . '/public/' . DEFAULT_LOGO_FILE);
return base64_encode($image);
}
public static function SetUniqueId($id)
{
self::setValue('uniqueId', $id);
}
public static function GetUniqueId()
{
return self::getValue('uniqueId');
}
public static function GetCountryList()
{
$sql = 'SELECT * FROM cc_country';
$res = Application_Common_Database::prepareAndExecute($sql, []);
$out = [];
$out[''] = _('Select Country');
foreach ($res as $r) {
$out[$r['isocode']] = $r['name'];
}
return $out;
}
public static function GetSystemInfo($returnArray = false, $p_testing = false)
{
exec('/usr/bin/airtime-check-system --no-color', $output);
$output = preg_replace('/\s+/', ' ', $output);
$systemInfoArray = [];
foreach ($output as $key => &$out) {
$info = explode('=', $out);
if (isset($info[1])) {
$key = str_replace(' ', '_', trim($info[0]));
$key = strtoupper($key);
if (
$key == 'WEB_SERVER' || $key == 'CPU' || $key == 'OS' || $key == 'TOTAL_RAM'
|| $key == 'FREE_RAM' || $key == 'AIRTIME_VERSION' || $key == 'KERNAL_VERSION'
|| $key == 'MACHINE_ARCHITECTURE' || $key == 'TOTAL_MEMORY_MBYTES' || $key == 'TOTAL_SWAP_MBYTES'
|| $key == 'PLAYOUT_ENGINE_CPU_PERC'
) {
if ($key == 'AIRTIME_VERSION') {
// remove hash tag on the version string
$version = explode('+', $info[1]);
$systemInfoArray[$key] = $version[0];
} else {
$systemInfoArray[$key] = $info[1];
}
}
}
}
$outputArray = [];
$outputArray['LIVE_DURATION'] = Application_Model_LiveLog::GetLiveShowDuration($p_testing);
$outputArray['SCHEDULED_DURATION'] = Application_Model_LiveLog::GetScheduledDuration($p_testing);
$outputArray['STATION_NAME'] = self::GetStationName();
$outputArray['PHONE'] = self::GetPhone();
$outputArray['EMAIL'] = self::GetEmail();
$outputArray['STATION_WEB_SITE'] = self::GetStationWebSite();
$outputArray['STATION_COUNTRY'] = self::GetStationCountry();
$outputArray['STATION_CITY'] = self::GetStationCity();
$outputArray['STATION_DESCRIPTION'] = self::GetStationDescription();
// get web server info
if (isset($systemInfoArray['AIRTIME_VERSION_URL'])) {
$url = $systemInfoArray['AIRTIME_VERSION_URL'];
$index = strpos($url, '/api/');
$url = substr($url, 0, $index);
$headerInfo = get_headers(trim($url), 1);
$outputArray['WEB_SERVER'] = $headerInfo['Server'][0];
}
$outputArray['NUM_OF_USERS'] = Application_Model_User::getUserCount();
$outputArray['NUM_OF_SONGS'] = Application_Model_StoredFile::getFileCount();
$outputArray['NUM_OF_PLAYLISTS'] = Application_Model_Playlist::getPlaylistCount();
$outputArray['NUM_OF_SCHEDULED_PLAYLISTS'] = Application_Model_Schedule::getSchduledPlaylistCount();
$outputArray['NUM_OF_PAST_SHOWS'] = Application_Model_ShowInstance::GetShowInstanceCount(gmdate(DEFAULT_TIMESTAMP_FORMAT));
$outputArray['UNIQUE_ID'] = self::GetUniqueId();
$outputArray['INSTALL_METHOD'] = self::GetInstallMethod();
$outputArray['NUM_OF_STREAMS'] = self::GetNumOfStreams();
$outputArray['STREAM_INFO'] = Application_Model_StreamSetting::getStreamInfoForDataCollection();
$outputArray = array_merge($systemInfoArray, $outputArray);
$outputString = "\n";
foreach ($outputArray as $key => $out) {
if ($key == 'STREAM_INFO') {
$outputString .= $key . " :\n";
foreach ($out as $s_info) {
foreach ($s_info as $k => $v) {
$outputString .= "\t" . strtoupper($k) . ' : ' . $v . "\n";
}
}
} else {
$outputString .= $key . ' : ' . $out . "\n";
}
}
if ($returnArray) {
$outputArray['PROMOTE'] = self::GetPublicise();
$outputArray['LOGOIMG'] = self::GetStationLogo();
return $outputArray;
}
return $outputString;
}
public static function GetInstallMethod()
{
$easy_install = file_exists('/usr/bin/airtime-easy-setup');
$debian_install = file_exists('/var/lib/dpkg/info/airtime.config');
if ($debian_install) {
if ($easy_install) {
return 'easy_install';
}
return 'debian_install';
}
return 'manual_install';
}
public static function SetRemindMeDate($p_never = false)
{
if ($p_never) {
self::setValue('remindme', -1);
} else {
$weekAfter = mktime(0, 0, 0, gmdate('m'), gmdate('d') + 7, gmdate('Y'));
self::setValue('remindme', $weekAfter);
}
}
public static function GetRemindMeDate()
{
return self::getValue('remindme');
}
public static function SetImportTimestamp()
{
$now = time();
if (self::GetImportTimestamp() + 5 < $now) {
self::setValue('import_timestamp', $now);
}
}
public static function GetImportTimestamp()
{
return (int) self::getValue('import_timestamp');
}
public static function SetPrivacyPolicyCheck($flag)
{
self::setValue('privacy_policy', $flag);
}
public static function GetPrivacyPolicyCheck()
{
return self::getValue('privacy_policy');
}
public static function GetNumOfStreams()
{
return count(Config::get('stream.outputs.merged'));
}
public static function SetEnableStreamConf($bool)
{
self::setValue('enable_stream_conf', $bool);
}
public static function GetEnableStreamConf()
{
if (self::getValue('enable_stream_conf') == null) {
return 'true';
}
return self::getValue('enable_stream_conf');
}
public static function GetSchemaVersion()
{
CcPrefPeer::clearInstancePool(); // Ensure we don't get a cached Propel object (cached DB results)
// because we're updating this version number within this HTTP request as well.
// New versions use schema_version
$pref = CcPrefQuery::create()
->filterByKeystr('schema_version')
->findOne();
if (empty($pref)) {
// Pre-2.5.2 releases all used this ambiguous "system_version" key to represent both the code and schema versions...
$pref = CcPrefQuery::create()
->filterByKeystr('system_version')
->findOne();
}
return $pref->getValStr();
}
public static function SetSchemaVersion($version)
{
self::setValue('schema_version', $version);
}
public static function GetLatestVersion()
{
$config = Config::getConfig();
$latest = json_decode(self::getValue('latest_version'));
$nextCheck = self::getValue('latest_version_nextcheck');
if ($latest && $nextCheck > time()) {
return $latest;
}
$rss = new SimplePie();
$rss->set_feed_url([LIBRETIME_UPDATE_FEED]);
$rss->enable_cache(false);
$rss->init();
$rss->handle_content_type();
// get all available versions ut to default github api limit
$versions = [];
foreach ($rss->get_items() as $item) {
$versions[] = $item->get_title();
}
$latest = $versions;
self::setValue('latest_version_nextcheck', strtotime('+1 week'));
if (empty($latest)) {
return [$config['airtime_version']];
}
self::setValue('latest_version', json_encode($latest));
return $latest;
}
public static function SetLatestVersion($version)
{
$pattern = '/^[0-9]+\.[0-9]+\.[0-9]+/';
if (preg_match($pattern, $version)) {
self::setValue('latest_version', $version);
}
}
public static function GetLatestLink()
{
$link = self::getValue('latest_link');
if ($link == null || strlen($link) == 0) {
return LIBRETIME_WHATS_NEW_URL;
}
return $link;
}
public static function SetLatestLink($link)
{
$pattern = '#^(http|https|ftp)://' .
'([a-zA-Z0-9]+\.)*[a-zA-Z0-9]+' .
'(/[a-zA-Z0-9\-\.\_\~\:\?\#\[\]\@\!\$\&\'\(\)\*\+\,\;\=]+)*/?$#';
if (preg_match($pattern, $link)) {
self::setValue('latest_link', $link);
}
}
public static function SetWeekStartDay($day)
{
self::setValue('week_start_day', $day);
}
public static function GetWeekStartDay()
{
$val = self::getValue('week_start_day');
return (strlen($val) == 0) ? '0' : $val;
}
/**
* Stores the last timestamp of user updating stream setting.
*/
public static function SetStreamUpdateTimestamp()
{
$now = time();
self::setValue('stream_update_timestamp', $now);
}
/**
* Gets the last timestamp of user updating stream setting.
*/
public static function GetStreamUpdateTimestemp()
{
$update_time = self::getValue('stream_update_timestamp');
return ($update_time == null) ? 0 : $update_time;
}
public static function GetClientId()
{
return self::getValue('client_id');
}
public static function SetClientId($id)
{
if (is_numeric($id)) {
self::setValue('client_id', $id);
} else {
Logging::warn("Attempting to set client_id to invalid value: {$id}");
}
}
// User specific preferences start
/**
* Sets the time scale preference (agendaDay/agendaWeek/month) in Calendar.
*
* @param $timeScale new time scale
*/
public static function SetCalendarTimeScale($timeScale)
{
self::setValue('calendar_time_scale', $timeScale, true /* user specific */);
}
/**
* Retrieves the time scale preference for the current user.
* Defaults to month if no entry exists.
*/
public static function GetCalendarTimeScale()
{
$val = self::getValue('calendar_time_scale', true /* user specific */);
if (strlen($val) == 0) {
$val = 'month';
}
return $val;
}
/**
* Sets the number of entries to show preference in library under Playlist Builder.
*
* @param $numEntries new number of entries to show
*/
public static function SetLibraryNumEntries($numEntries)
{
self::setValue('library_num_entries', $numEntries, true /* user specific */);
}
/**
* Retrieves the number of entries to show preference in library under Playlist Builder.
* Defaults to 10 if no entry exists.
*/
public static function GetLibraryNumEntries()
{
$val = self::getValue('library_num_entries', true /* user specific */);
if (strlen($val) == 0) {
$val = '10';
}
return $val;
}
/**
* Sets the time interval preference in Calendar.
*
* @param $timeInterval new time interval
*/
public static function SetCalendarTimeInterval($timeInterval)
{
self::setValue('calendar_time_interval', $timeInterval, true /* user specific */);
}
/**
* Retrieves the time interval preference for the current user.
* Defaults to 30 min if no entry exists.
*/
public static function GetCalendarTimeInterval()
{
$val = self::getValue('calendar_time_interval', true /* user specific */);
return (strlen($val) == 0) ? '30' : $val;
}
public static function SetDiskQuota($value)
{
self::setValue('disk_quota', $value, false);
}
public static function GetDiskQuota()
{
$val = self::getValue('disk_quota');
return empty($val) ? 2147483648 : $val; // If there is no value for disk quota, return 2GB
}
public static function SetLiveStreamMasterUsername($value)
{
self::setValue('live_stream_master_username', $value, false);
}
public static function GetLiveStreamMasterUsername()
{
return self::getValue('live_stream_master_username');
}
public static function SetLiveStreamMasterPassword($value)
{
self::setValue('live_stream_master_password', $value, false);
}
public static function GetLiveStreamMasterPassword()
{
return self::getValue('live_stream_master_password');
}
public static function SetSourceStatus($sourcename, $status)
{
self::setValue($sourcename, $status, false);
}
public static function GetSourceStatus($sourcename)
{
$value = self::getValue($sourcename);
return !($value == null || $value == 'false');
}
public static function SetSourceSwitchStatus($sourcename, $status)
{
self::setValue($sourcename . '_switch', $status, false);
}
public static function GetSourceSwitchStatus($sourcename)
{
// Scheduled play switch should always be "on".
// Even though we've hidden this element in the dashboard we should
// always make sure it's on or else a station's stream could go offline.
if ($sourcename == 'scheduled_play') {
return 'on';
}
$value = self::getValue($sourcename . '_switch');
return ($value == null || $value == 'off') ? 'off' : 'on';
}
public static function GetMasterDJSourceConnectionURL()
{
if (Config::has('stream.inputs.main.public_url') && Config::get('stream.inputs.main.public_url')) {
return Config::get('stream.inputs.main.public_url');
}
$host = Config::get('general.public_url_raw')->getHost();
$port = Application_Model_StreamSetting::getMasterLiveStreamPort();
$mount = Application_Model_StreamSetting::getMasterLiveStreamMountPoint();
$secure = Application_Model_StreamSetting::getMasterLiveStreamSecure();
$scheme = $secure ? 'https' : 'http';
return "{$scheme}://{$host}:{$port}/{$mount}";
}
public static function GetLiveDJSourceConnectionURL()
{
if (Config::has('stream.inputs.show.public_url') && Config::get('stream.inputs.show.public_url')) {
return Config::get('stream.inputs.show.public_url');
}
$host = Config::get('general.public_url_raw')->getHost();
$port = Application_Model_StreamSetting::getDjLiveStreamPort();
$mount = Application_Model_StreamSetting::getDjLiveStreamMountPoint();
$secure = Application_Model_StreamSetting::getDjLiveStreamSecure();
$scheme = $secure ? 'https' : 'http';
return "{$scheme}://{$host}:{$port}/{$mount}";
}
public static function SetAutoTransition($value)
{
self::setValue('auto_transition', $value, false);
}
public static function GetAutoTransition()
{
return self::getValue('auto_transition');
}
public static function SetAutoSwitch($value)
{
self::setValue('auto_switch', $value, false);
}
public static function GetAutoSwitch()
{
return self::getValue('auto_switch');
}
// User specific preferences end
public static function ShouldShowPopUp()
{
$today = mktime(0, 0, 0, gmdate('m'), gmdate('d'), gmdate('Y'));
$remindDate = Application_Model_Preference::GetRemindMeDate();
$retVal = false;
if (is_null($remindDate) || ($remindDate != -1 && $today >= $remindDate)) {
$retVal = true;
}
return $retVal;
}
public static function getOrderingMap($pref_param)
{
$v = self::getValue($pref_param, true);
$id = function ($x) {
return $x;
};
if ($v === '') {
return $id;
}
$ds = unserialize($v);
if (is_null($ds) || !is_array($ds)) {
return $id;
}
if (!array_key_exists('ColReorder', $ds)) {
return $id;
}
return function ($x) use ($ds) {
if (array_key_exists($x, $ds['ColReorder'])) {
return $ds['ColReorder'][$x];
}
/*For now we just have this hack for debugging. We should not
rely on this behaviour in case of failure*/
Logging::warn("Index {$x} does not exist preferences");
Logging::warn('Defaulting to identity and printing preferences');
Logging::warn($ds);
return $x;
};
}
public static function getCurrentLibraryTableColumnMap()
{
return self::getOrderingMap('library_datatable');
}
public static function setCurrentLibraryTableSetting($settings)
{
$data = serialize($settings);
self::setValue('library_datatable', $data, true);
}
public static function getCurrentLibraryTableSetting()
{
$data = self::getValue('library_datatable', true);
return ($data != '') ? unserialize($data) : null;
}
public static function setTimelineDatatableSetting($settings)
{
$data = serialize($settings);
self::setValue('timeline_datatable', $data, true);
}
public static function getTimelineDatatableSetting()
{
$data = self::getValue('timeline_datatable', true);
return ($data != '') ? unserialize($data) : null;
}
public static function setNowPlayingScreenSettings($settings)
{
$data = serialize($settings);
self::setValue('nowplaying_screen', $data, true);
}
public static function getNowPlayingScreenSettings()
{
$data = self::getValue('nowplaying_screen', true);
return ($data != '') ? unserialize($data) : null;
}
public static function setLibraryScreenSettings($settings)
{
$data = serialize($settings);
self::setValue('library_screen', $data, true);
}
public static function getLibraryScreenSettings()
{
$data = self::getValue('library_screen', true);
return ($data != '') ? unserialize($data) : null;
}
public static function SetEnableReplayGain($value)
{
self::setValue('enable_replay_gain', $value, false);
}
public static function GetEnableReplayGain()
{
return self::getValue('enable_replay_gain', false);
}
public static function getReplayGainModifier()
{
$rg_modifier = self::getValue('replay_gain_modifier');
if ($rg_modifier === '') {
return '0';
}
return $rg_modifier;
}
public static function setReplayGainModifier($rg_modifier)
{
self::setValue('replay_gain_modifier', $rg_modifier, true);
}
public static function SetHistoryItemTemplate($value)
{
self::setValue('history_item_template', $value);
}
public static function GetHistoryItemTemplate()
{
return self::getValue('history_item_template');
}
public static function SetHistoryFileTemplate($value)
{
self::setValue('history_file_template', $value);
}
public static function GetHistoryFileTemplate()
{
return self::getValue('history_file_template');
}
public static function getDiskUsage()
{
$val = self::getValue('disk_usage');
return (strlen($val) == 0) ? 0 : $val;
}
public static function setDiskUsage($value)
{
self::setValue('disk_usage', $value);
}
public static function updateDiskUsage($filesize)
{
$currentDiskUsage = self::getDiskUsage();
if (empty($currentDiskUsage)) {
$currentDiskUsage = 0;
}
self::setDiskUsage($currentDiskUsage + $filesize);
}
public static function setTuneinEnabled($value)
{
self::setValue('tunein_enabled', $value);
}
public static function getTuneinEnabled()
{
return self::getValue('tunein_enabled');
}
public static function setTuneinPartnerKey($value)
{
self::setValue('tunein_partner_key', $value);
}
public static function getTuneinPartnerKey()
{
return self::getValue('tunein_partner_key');
}
public static function setTuneinPartnerId($value)
{
self::setValue('tunein_partner_id', $value);
}
public static function getTuneinPartnerId()
{
return self::getValue('tunein_partner_id');
}
public static function setTuneinStationId($value)
{
self::setValue('tunein_station_id', $value);
}
public static function getTuneinStationId()
{
return self::getValue('tunein_station_id');
}
public static function geLastTuneinMetadataUpdate()
{
return self::getValue('last_tunein_metadata_update');
}
public static function setLastTuneinMetadataUpdate($value)
{
self::setValue('last_tunein_metadata_update', $value);
}
// TaskManager Lock Timestamp
public static function getTaskManagerLock()
{
return self::getValue('task_manager_lock');
}
public static function setTaskManagerLock($value)
{
self::setValue('task_manager_lock', $value);
}
// SAAS-876 - Toggle indicating whether user is using custom stream settings
public static function getUsingCustomStreamSettings()
{
$val = self::getValue('using_custom_stream_settings');
return empty($val) ? false : $val;
}
public static function setUsingCustomStreamSettings($value)
{
self::setValue('using_custom_stream_settings', $value);
}
// SAAS-876 - Store the default Icecast password to restore when switching
// back to Airtime Pro streaming settings
public static function getRadioPageDisplayLoginButton()
{
return self::getValue('radio_page_display_login_button');
}
public static function setRadioPageDisplayLoginButton($value)
{
self::setValue('radio_page_display_login_button', $value);
}
public static function getRadioPageDisabled()
{
return boolval(self::getValue('radio_page_disabled', false));
}
public static function setRadioPageDisabled($value)
{
self::setValue('radio_page_disabled', $value);
}
public static function getLangTimezoneSetupComplete()
{
return self::getValue('lang_tz_setup_complete');
}
public static function setLangTimezoneSetupComplete($value)
{
self::setValue('lang_tz_setup_complete', $value);
}
public static function getWhatsNewDialogViewed()
{
$val = self::getValue('whats_new_dialog_viewed', true);
if (empty($val)) {
// Check the default (no user ID) value if the user value is empty
// This is so that new stations won't see the popup
$val = self::getValue('whats_new_dialog_viewed', false, true);
}
return empty($val) ? false : $val;
}
public static function setWhatsNewDialogViewed($value)
{
self::setValue('whats_new_dialog_viewed', $value, true);
}
public static function getAutoPlaylistPollLock()
{
return self::getValue('autoplaylist_poll_lock');
}
public static function setAutoPlaylistPollLock($value)
{
self::setValue('autoplaylist_poll_lock', $value);
}
public static function getPodcastPollLock()
{
return self::getValue('podcast_poll_lock');
}
public static function setPodcastPollLock($value)
{
self::setValue('podcast_poll_lock', $value);
}
public static function getStationPodcastId()
{
// Create the Station podcast if it doesn't exist.
$stationPodcastId = self::getValue('station_podcast_id');
if (empty($stationPodcastId)) {
$stationPodcastId = Application_Service_PodcastService::createStationPodcast();
}
return $stationPodcastId;
}
public static function setStationPodcastId($value)
{
self::setValue('station_podcast_id', $value);
}
// SAAS-1081 - Implement a universal download key for downloading episodes from the station podcast
// Store and increment the download counter, resetting every month
public static function getStationPodcastDownloadKey()
{
return self::getValue('station_podcast_download_key');
}
public static function setStationPodcastDownloadKey($value = null)
{
$value = empty($value) ? (new Application_Model_Auth())->generateRandomString() : $value;
self::setValue('station_podcast_download_key', $value);
}
public static function getStationPodcastDownloadResetTimer()
{
return self::getValue('station_podcast_download_reset_timer');
}
public static function setStationPodcastDownloadResetTimer($value)
{
self::setValue('station_podcast_download_reset_timer', $value);
}
public static function getStationPodcastDownloadCounter()
{
return self::getValue('station_podcast_download_counter');
}
public static function resetStationPodcastDownloadCounter()
{
self::setValue('station_podcast_download_counter', 0);
}
public static function incrementStationPodcastDownloadCounter()
{
$c = self::getStationPodcastDownloadCounter();
self::setValue('station_podcast_download_counter', empty($c) ? 1 : ++$c);
}
// For fail cases, we may need to decrement the download counter
public static function decrementStationPodcastDownloadCounter()
{
$c = self::getStationPodcastDownloadCounter();
self::setValue('station_podcast_download_counter', empty($c) ? 0 : --$c);
}
/**
* @return int either 0 (public) or 1 (private)
*/
public static function getStationPodcastPrivacy()
{
return self::getValue('station_podcast_privacy');
}
public static function setStationPodcastPrivacy($value)
{
self::setValue('station_podcast_privacy', $value);
}
/**
* Getter for feature preview mode.
*
* @return bool
*/
public static function GetFeaturePreviewMode()
{
return self::getValue('feature_preview_mode') === '1';
}
/**
* Setter for feature preview mode.
*
* @param bool $value
*/
public static function SetFeaturePreviewMode($value)
{
return self::setValue('feature_preview_mode', $value);
}
/*
* Stores liquidsoap status if $boot_time > save time.
* save time is the time that user clicked save on stream setting page
*/
public static function setLiquidsoapError($stream_id, $msg, $boot_time = null)
{
$update_time = Application_Model_Preference::GetStreamUpdateTimestemp();
if ($boot_time == null || $boot_time > $update_time) {
$stream_id = trim($stream_id, 's');
self::setValue("stream_liquidsoap_status:{$stream_id}", $msg);
}
}
public static function getLiquidsoapError($stream_id)
{
$result = self::getValue("stream_liquidsoap_status:{$stream_id}");
return ($result !== false) ? $result : null;
}
public static function GetAllListenerStatErrors()
{
$sql = <<<'SQL'
SELECT *
FROM cc_pref
WHERE keystr LIKE 'stream_stats_status:%'
SQL;
return Application_Common_Database::prepareAndExecute($sql, []);
}
public static function SetListenerStatError($stream_id, $value)
{
$stream_id = trim($stream_id, 's');
self::setValue("stream_stats_status:{$stream_id}", $value);
}
}