mirror of
https://github.com/AzuraCast/AzuraCast.git
synced 2024-06-18 15:07:05 +00:00
Closes #38 - Implement support for several new playlist types: scheduled, once per x songs, once per x minutes, once per day at time x.
This commit is contained in:
parent
d8b7d0c2e5
commit
5928005176
|
@ -72,7 +72,9 @@ class Automation
|
|||
|
||||
foreach($station->playlists as $playlist)
|
||||
{
|
||||
if ($playlist->include_in_automation)
|
||||
if ($playlist->is_enabled &&
|
||||
$playlist->type == 'default' &&
|
||||
$playlist->include_in_automation == true)
|
||||
{
|
||||
// Clear all related media.
|
||||
foreach($playlist->media as $media)
|
||||
|
|
|
@ -44,16 +44,17 @@ class LiquidSoap extends AdapterAbstract
|
|||
@unlink($playlist_path.'/'.$list);
|
||||
|
||||
// Write new playlists.
|
||||
$playlist_weights = array();
|
||||
$playlist_vars = array();
|
||||
$playlists_by_type = array();
|
||||
|
||||
$ls_config[] = '# Playlists';
|
||||
|
||||
foreach($this->station->playlists as $playlist)
|
||||
foreach($this->station->playlists as $playlist_raw)
|
||||
{
|
||||
$playlist_file = array();
|
||||
if (!$playlist_raw->is_enabled)
|
||||
continue;
|
||||
|
||||
foreach($playlist->media as $media_file)
|
||||
$playlist_file = array();
|
||||
foreach($playlist_raw->media as $media_file)
|
||||
{
|
||||
$media_file_path = $media_path.'/'.$media_file->path;
|
||||
$playlist_file[] = $media_file_path;
|
||||
|
@ -61,31 +62,108 @@ class LiquidSoap extends AdapterAbstract
|
|||
|
||||
$playlist_file_contents = implode("\n", $playlist_file);
|
||||
|
||||
$playlist_var_name = 'playlist_'.$playlist->getShortName();
|
||||
$playlist_file_path = $playlist_path.'/'.$playlist_var_name.'.pls';
|
||||
$playlist = $playlist_raw->toArray();
|
||||
|
||||
file_put_contents($playlist_file_path, $playlist_file_contents);
|
||||
$playlist['var_name'] = 'playlist_'.$playlist_raw->getShortName();
|
||||
$playlist['file_path'] = $playlist_path.'/'.$playlist['var_name'].'.pls';
|
||||
|
||||
$ls_config[] = $playlist_var_name.' = playlist(reload=1800,"'.$playlist_file_path.'")';
|
||||
file_put_contents($playlist['file_path'], $playlist_file_contents);
|
||||
|
||||
$playlist_weights[] = $playlist->weight;
|
||||
$playlist_vars[] = $playlist_var_name;
|
||||
$ls_config[] = $playlist['var_name'].' = playlist(reload=1800,"'.$playlist['file_path'].'")';
|
||||
|
||||
$playlist_type = $playlist['type'] ?: 'default';
|
||||
$playlists_by_type[$playlist_type][] = $playlist;
|
||||
}
|
||||
|
||||
$ls_config[] = '';
|
||||
$ls_config[] = '# Build Radio Station';
|
||||
$ls_config[] = 'radio = random(weights = ['.implode(', ', $playlist_weights).'],['.implode(', ', $playlist_vars).']);';
|
||||
|
||||
$ls_config[] = '';
|
||||
|
||||
// Cannot build a LiquidSoap playlist with
|
||||
if (count($playlists_by_type['default']) == 0)
|
||||
return false;
|
||||
|
||||
// Build "default" type playlists.
|
||||
$playlist_weights = array();
|
||||
$playlist_vars = array();
|
||||
|
||||
foreach($playlists_by_type['default'] as $playlist)
|
||||
{
|
||||
$playlist_weights[] = $playlist['weight'];
|
||||
$playlist_vars[] = $playlist['var_name'];
|
||||
}
|
||||
|
||||
$ls_config[] = '# Standard Playlists';
|
||||
$ls_config[] = 'radio = random(weights=['.implode(', ', $playlist_weights).'], ['.implode(', ', $playlist_vars).']);';
|
||||
$ls_config[] = '';
|
||||
|
||||
// Once per X songs playlists
|
||||
if (count($playlists_by_type['once_per_x_songs']) > 0)
|
||||
{
|
||||
$ls_config[] = '# Once per x Songs Playlists';
|
||||
|
||||
foreach($playlists_by_type['once_per_x_songs'] as $playlist)
|
||||
{
|
||||
$ls_config[] = 'radio = rotate(weights=[1,' . $playlist['play_per_songs'] . '], [' . $playlist['var_name'] . ', radio])';
|
||||
}
|
||||
|
||||
$ls_config[] = '';
|
||||
}
|
||||
|
||||
// Once per X minutes playlists
|
||||
if (count($playlists_by_type['once_per_x_minutes']) > 0)
|
||||
{
|
||||
$ls_config[] = '# Once per x Minutes Playlists';
|
||||
|
||||
foreach($playlists_by_type['once_per_x_minutes'] as $playlist)
|
||||
{
|
||||
$delay_seconds = $playlist['play_per_minutes']*60;
|
||||
$ls_config[] = 'delay_'.$playlist['var_name'].' = delay('.$delay_seconds.'., '.$playlist['var_name'].')';
|
||||
$ls_config[] = 'radio = fallback([delay_'.$playlist['var_name'].', radio])';
|
||||
}
|
||||
|
||||
$ls_config[] = '';
|
||||
}
|
||||
|
||||
// Set up "switch" conditionals
|
||||
$switches = [];
|
||||
|
||||
// Scheduled playlists
|
||||
if (count($playlists_by_type['scheduled']) > 0)
|
||||
{
|
||||
foreach($playlists_by_type['scheduled'] as $playlist)
|
||||
{
|
||||
$play_time = $this->_getTime($playlist['schedule_start_time']).'-'.$this->_getTime($playlist['schedule_end_time']);
|
||||
$switches[] = '({ ' . $play_time . ' }, ' . $playlist['var_name'] . ')';
|
||||
}
|
||||
}
|
||||
|
||||
// Once per day playlists
|
||||
if (count($playlists_by_type['once_per_day']) > 0)
|
||||
{
|
||||
foreach($playlists_by_type['once_per_day'] as $playlist)
|
||||
{
|
||||
$play_time = $this->_getTime($playlist['play_once_time']);
|
||||
$switches[] = '({ ' . $play_time . ' }, ' . $playlist['var_name'] . ')';
|
||||
}
|
||||
}
|
||||
|
||||
// Add fallback error file.
|
||||
$error_song_path = APP_INCLUDE_ROOT.'/resources/error.mp3';
|
||||
|
||||
$ls_config[] = '';
|
||||
$ls_config[] = '# Fallback Media File';
|
||||
$ls_config[] = '# Assemble Fallback';
|
||||
// $ls_config[] = 'security = single("'.$error_song_path.'")';
|
||||
$ls_config[] = 'requests = request.queue(id="requests")';
|
||||
|
||||
$fallbacks = [];
|
||||
$fallbacks[] = 'requests';
|
||||
|
||||
$switches[] = '({ true }, radio)';
|
||||
$fallbacks[] = 'switch([ '.implode(', ', $switches).' ])';
|
||||
$fallbacks[] = 'blank(duration=2.)';
|
||||
|
||||
// $ls_config[] = 'radio = fallback(track_sensitive = true, [playlists, security])';
|
||||
$ls_config[] = 'radio = fallback(track_sensitive = true, [requests, radio, blank(duration=2.)])';
|
||||
$ls_config[] = 'radio = fallback(track_sensitive = true, ['.implode(', ', $fallbacks).'])';
|
||||
|
||||
$ls_config[] = '';
|
||||
$ls_config[] = '# Crossfading';
|
||||
|
@ -125,6 +203,32 @@ class LiquidSoap extends AdapterAbstract
|
|||
return true;
|
||||
}
|
||||
|
||||
protected function _getTime($time_code)
|
||||
{
|
||||
$hours = floor($time_code / 100);
|
||||
$mins = $time_code % 100;
|
||||
|
||||
$system_time_zone = \App\Utilities::getSystemTimeZone();
|
||||
$system_tz = new \DateTimeZone($system_time_zone);
|
||||
$system_dt = new \DateTime('now', $system_tz);
|
||||
$system_offset = $system_tz->getOffset($system_dt);
|
||||
|
||||
$app_tz = new \DateTimeZone(date_default_timezone_get());
|
||||
$app_dt = new \DateTime('now', $app_tz);
|
||||
$app_offset = $app_tz->getOffset($app_dt);
|
||||
|
||||
$offset = $system_offset - $app_offset;
|
||||
$offset_hours = floor($offset / 3600);
|
||||
|
||||
$hours += $offset_hours;
|
||||
|
||||
$hours = $hours % 24;
|
||||
if ($hours < 0)
|
||||
$hours += 24;
|
||||
|
||||
return $hours.'h'.$mins.'m';
|
||||
}
|
||||
|
||||
public function isRunning()
|
||||
{
|
||||
$config_path = $this->station->getRadioConfigDir();
|
||||
|
|
|
@ -1042,4 +1042,37 @@ class Utilities
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the system time zone.
|
||||
* @return string
|
||||
*/
|
||||
public static function getSystemTimeZone()
|
||||
{
|
||||
if (file_exists('/etc/timezone'))
|
||||
{
|
||||
// Ubuntu / Debian.
|
||||
$data = file_get_contents('/etc/timezone');
|
||||
if ($data)
|
||||
return trim($data);
|
||||
}
|
||||
elseif (is_link('/etc/localtime'))
|
||||
{
|
||||
// Mac OS X (and older Linuxes)
|
||||
// /etc/localtime is a symlink to the
|
||||
// timezone in /usr/share/zoneinfo.
|
||||
$filename = readlink('/etc/localtime');
|
||||
if (strpos($filename, '/usr/share/zoneinfo/') === 0)
|
||||
return substr($filename, 20);
|
||||
}
|
||||
elseif (file_exists('/etc/sysconfig/clock'))
|
||||
{
|
||||
// RHEL / CentOS
|
||||
$data = parse_ini_file('/etc/sysconfig/clock');
|
||||
if (!empty($data['ZONE']))
|
||||
return trim($data['ZONE']);
|
||||
}
|
||||
|
||||
return 'UTC';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -176,7 +176,7 @@ class Station extends \App\Doctrine\Entity
|
|||
|
||||
/**
|
||||
* @OneToMany(targetEntity="StationPlaylist", mappedBy="station")
|
||||
* @OrderBy({"weight" = "DESC"})
|
||||
* @OrderBy({"type" = "ASC","weight" = "DESC"})
|
||||
*/
|
||||
protected $playlists;
|
||||
|
||||
|
|
|
@ -12,8 +12,11 @@ class StationPlaylist extends \App\Doctrine\Entity
|
|||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->include_in_automation = false;
|
||||
$this->type = 'default';
|
||||
$this->weight = 3;
|
||||
$this->is_enabled = 1;
|
||||
|
||||
$this->include_in_automation = false;
|
||||
|
||||
$this->media = new ArrayCollection;
|
||||
}
|
||||
|
@ -36,6 +39,42 @@ class StationPlaylist extends \App\Doctrine\Entity
|
|||
return Station::getStationShortName($this->name);
|
||||
}
|
||||
|
||||
/** @Column(name="type", type="string", length=50) */
|
||||
protected $type;
|
||||
|
||||
/** @Column(name="is_enabled", type="boolean", nullable=false) */
|
||||
protected $is_enabled;
|
||||
|
||||
/** @Column(name="play_per_songs", type="smallint") */
|
||||
protected $play_per_songs;
|
||||
|
||||
/** @Column(name="play_per_minutes", type="smallint") */
|
||||
protected $play_per_minutes;
|
||||
|
||||
/** @Column(name="schedule_start_time", type="smallint") */
|
||||
protected $schedule_start_time;
|
||||
|
||||
public function getScheduleStartTimeText()
|
||||
{
|
||||
return self::formatTimeCode($this->schedule_start_time);
|
||||
}
|
||||
|
||||
/** @Column(name="schedule_end_time", type="smallint") */
|
||||
protected $schedule_end_time;
|
||||
|
||||
public function getScheduleEndTimeText()
|
||||
{
|
||||
return self::formatTimeCode($this->schedule_end_time);
|
||||
}
|
||||
|
||||
/** @Column(name="play_once_time", type="smallint") */
|
||||
protected $play_once_time;
|
||||
|
||||
public function getPlayOnceTimeText()
|
||||
{
|
||||
return self::formatTimeCode($this->play_once_time);
|
||||
}
|
||||
|
||||
/** @Column(name="weight", type="smallint") */
|
||||
protected $weight;
|
||||
|
||||
|
@ -54,4 +93,25 @@ class StationPlaylist extends \App\Doctrine\Entity
|
|||
* @ManyToMany(targetEntity="StationMedia", mappedBy="playlists", fetch="EXTRA_LAZY")
|
||||
*/
|
||||
protected $media;
|
||||
|
||||
/**
|
||||
* Given a time code i.e. "2300", return a time i.e. "11:00 PM"
|
||||
* @param $time_code
|
||||
*/
|
||||
public static function formatTimeCode($time_code)
|
||||
{
|
||||
$hours = floor($time_code / 100);
|
||||
$mins = $time_code % 100;
|
||||
|
||||
$ampm = ($hours < 12) ? 'AM' : 'PM';
|
||||
|
||||
if ($hours == 0)
|
||||
$hours_text = '12';
|
||||
elseif ($hours > 12)
|
||||
$hours_text = $hours-12;
|
||||
else
|
||||
$hours_text = $hours;
|
||||
|
||||
return $hours_text.':'.str_pad($mins, 2, '0', STR_PAD_LEFT).' '.$ampm;
|
||||
}
|
||||
}
|
|
@ -1,47 +1,179 @@
|
|||
<?php
|
||||
$hour_select = [];
|
||||
for($hr = 0; $hr <= 23; $hr++)
|
||||
{
|
||||
foreach([0, 15, 30, 45] as $min)
|
||||
{
|
||||
$time_num = $hr*100 + $min;
|
||||
$hour_select[$time_num] = \Entity\StationPlaylist::formatTimeCode($time_num);
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'method' => 'post',
|
||||
'enctype' => 'multipart/form-data',
|
||||
|
||||
'elements' => [
|
||||
'groups' => [
|
||||
|
||||
'name' => ['text', [
|
||||
'label' => 'Playlist Name',
|
||||
'required' => true,
|
||||
]],
|
||||
'basic_info' => [
|
||||
'elements' => [
|
||||
|
||||
'name' => ['text', [
|
||||
'label' => 'Playlist Name',
|
||||
'required' => true,
|
||||
]],
|
||||
|
||||
'is_enabled' => ['radio', [
|
||||
'label' => 'Enable Playlist',
|
||||
'required' => true,
|
||||
'description' => 'If set to "No", the playlist will not be included in radio playback, but can still be managed.',
|
||||
'options' => [
|
||||
1 => 'Yes',
|
||||
0 => 'No',
|
||||
],
|
||||
'default' => 1,
|
||||
]],
|
||||
|
||||
'type' => ['radio', [
|
||||
'label' => 'Playlist Type',
|
||||
'options' => [
|
||||
'default' => '<b>Standard:</b> Plays all day, shuffles with other standard playlists based on weight.',
|
||||
'scheduled' => '<b>Scheduled:</b> Play during a scheduled time range. Useful for mood-based time playlists.',
|
||||
'once_per_x_songs' => '<b>Once per x Songs:</b> Play exactly once every <i>x</i> songs. Useful for station ID/jingles.',
|
||||
'once_per_x_minutes' => '<b>Once Per x Minutes:</b> Play exactly once every <i>x</i> minutes. Useful for station ID/jingles.',
|
||||
'once_per_day' => '<b>Daily</b>: Play once per day at the specified time. Useful for timely reminders.',
|
||||
],
|
||||
'default' => 'default',
|
||||
'required' => true,
|
||||
]],
|
||||
|
||||
'weight' => ['radio', [
|
||||
'label' => 'Playlist Weight',
|
||||
'description' => 'How often the playlist\'s songs will be played. 1 is the most infrequent, 5 is the most frequent.',
|
||||
'default' => 3,
|
||||
'required' => true,
|
||||
'class' => 'inline',
|
||||
'options' => [
|
||||
1 => '1 - Lowest',
|
||||
2 => '2',
|
||||
3 => '3 - Default',
|
||||
4 => '4',
|
||||
5 => '5 - Highest',
|
||||
],
|
||||
]],
|
||||
],
|
||||
|
||||
'type_default' => [
|
||||
'legend' => 'Standard Playlist',
|
||||
'class' => 'type_fieldset',
|
||||
'elements' => [
|
||||
|
||||
'weight' => ['radio', [
|
||||
'label' => 'Playlist Weight',
|
||||
'description' => 'How often the playlist\'s songs will be played. 1 is the most infrequent, 5 is the most frequent.',
|
||||
'default' => 3,
|
||||
'required' => true,
|
||||
'class' => 'inline',
|
||||
'options' => [
|
||||
1 => '1 - Lowest',
|
||||
2 => '2',
|
||||
3 => '3 - Default',
|
||||
4 => '4',
|
||||
5 => '5 - Highest',
|
||||
],
|
||||
]],
|
||||
|
||||
'include_in_automation' => ['radio', [
|
||||
'label' => 'Include in Automated Assignment',
|
||||
'description' => 'If auto-assignment is enabled, use this playlist as one of the targets for songs to be redistributed into. This will overwrite the existing contents of this playlist.',
|
||||
'required' => true,
|
||||
'default' => '0',
|
||||
'options' => [
|
||||
0 => 'No',
|
||||
1 => 'Yes',
|
||||
],
|
||||
]],
|
||||
|
||||
'include_in_automation' => ['radio', [
|
||||
'label' => 'Include in Automated Assignment',
|
||||
'description' => 'If auto-assignment is enabled, use this playlist as one of the targets for songs to be redistributed into. This will overwrite the existing contents of this playlist.',
|
||||
'required' => true,
|
||||
'default' => '0',
|
||||
'options' => [
|
||||
0 => 'No',
|
||||
1 => 'Yes',
|
||||
],
|
||||
]],
|
||||
],
|
||||
|
||||
'submit' => ['submit', [
|
||||
'type' => 'submit',
|
||||
'label' => 'Save Changes',
|
||||
'helper' => 'formButton',
|
||||
'class' => 'ui-button btn-lg btn-primary',
|
||||
]],
|
||||
'type_scheduled' => [
|
||||
'legend' => 'Scheduled Playlist',
|
||||
'class' => 'type_fieldset',
|
||||
'elements' => [
|
||||
|
||||
'schedule_start_time' => ['select', [
|
||||
'label' => 'Start Time',
|
||||
'description' => 'Current server time is <b>'.date('g:ia').'.</b>',
|
||||
'options' => $hour_select,
|
||||
]],
|
||||
|
||||
'schedule_end_time' => ['select', [
|
||||
'label' => 'End Time',
|
||||
'description' => 'If the end time is before the start time, the playlist will play overnight until this time on the next day.',
|
||||
'options' => $hour_select,
|
||||
]],
|
||||
|
||||
],
|
||||
],
|
||||
|
||||
'type_once_per_x_songs' => [
|
||||
'legend' => 'Once per x Songs Playlist',
|
||||
'class' => 'type_fieldset',
|
||||
'elements' => [
|
||||
|
||||
'play_per_songs' => ['radio', [
|
||||
'label' => 'Number of Songs Between Plays',
|
||||
'description' => 'This playlist will play every $x songs, where $x is specified below.',
|
||||
'options' => \App\Utilities::pairs([
|
||||
5,
|
||||
10,
|
||||
15,
|
||||
20,
|
||||
25,
|
||||
50,
|
||||
100
|
||||
]),
|
||||
]],
|
||||
|
||||
],
|
||||
],
|
||||
|
||||
'type_once_per_x_minutes' => [
|
||||
'legend' => 'Once per x Minutes Playlist',
|
||||
'class' => 'type_fieldset',
|
||||
'elements' => [
|
||||
|
||||
'play_per_minutes' => ['radio', [
|
||||
'label' => 'Number of Minutes Between Plays',
|
||||
'description' => 'This playlist will play every $x minutes, where $x is specified below.',
|
||||
'options' => \App\Utilities::pairs([
|
||||
5,
|
||||
10,
|
||||
15,
|
||||
30,
|
||||
45,
|
||||
60,
|
||||
120,
|
||||
240,
|
||||
]),
|
||||
]],
|
||||
|
||||
],
|
||||
],
|
||||
|
||||
'type_once_per_day' => [
|
||||
'legend' => 'Daily Playlist',
|
||||
'class' => 'type_fieldset',
|
||||
'elements' => [
|
||||
|
||||
'play_once_time' => ['select', [
|
||||
'label' => 'Scheduled Play Time',
|
||||
'description' => 'Current server time is <b>'.date('g:ia').'.</b>',
|
||||
'options' => $hour_select,
|
||||
]],
|
||||
|
||||
],
|
||||
],
|
||||
|
||||
'grp_submit' => [
|
||||
'elements' => [
|
||||
|
||||
'submit' => ['submit', [
|
||||
'type' => 'submit',
|
||||
'label' => 'Save Changes',
|
||||
'helper' => 'formButton',
|
||||
'class' => 'ui-button btn-lg btn-primary',
|
||||
]],
|
||||
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
|
@ -12,13 +12,19 @@ class PlaylistsController extends BaseController
|
|||
|
||||
$total_weights = 0;
|
||||
foreach($all_playlists as $playlist)
|
||||
$total_weights += $playlist->weight;
|
||||
{
|
||||
if ($playlist->is_enabled && $playlist->type == 'default')
|
||||
$total_weights += $playlist->weight;
|
||||
}
|
||||
|
||||
$playlists = array();
|
||||
foreach($all_playlists as $playlist)
|
||||
{
|
||||
$playlist_row = $playlist->toArray();
|
||||
$playlist_row['probability'] = round(($playlist->weight / $total_weights) * 100, 1).'%';
|
||||
|
||||
if ($playlist->is_enabled && $playlist->type == 'default')
|
||||
$playlist_row['probability'] = round(($playlist->weight / $total_weights) * 100, 1).'%';
|
||||
|
||||
$playlist_row['num_songs'] = count($playlist->media);
|
||||
|
||||
$playlists[$playlist->id] = $playlist_row;
|
||||
|
@ -62,16 +68,15 @@ class PlaylistsController extends BaseController
|
|||
$record->fromArray($data);
|
||||
$record->save();
|
||||
|
||||
if ($reload_station)
|
||||
$this->_reloadStation();
|
||||
$this->_reloadStation();
|
||||
|
||||
$this->alert('<b>Stream updated!</b>', 'green');
|
||||
|
||||
return $this->redirectFromHere(['action' => 'index', 'id' => NULL]);
|
||||
}
|
||||
|
||||
$title = (($this->hasParam('id')) ? 'Edit' : 'Add').' Playlist';
|
||||
return $this->renderForm($form, 'edit', $title);
|
||||
$this->view->form = $form;
|
||||
$this->view->title = (($this->hasParam('id')) ? 'Edit' : 'Add').' Playlist';
|
||||
}
|
||||
|
||||
public function deleteAction()
|
||||
|
|
31
app/modules/stations/views/scripts/playlists/edit.phtml
Normal file
31
app/modules/stations/views/scripts/playlists/edit.phtml
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?php $this->layout('main', ['manual' => true]) ?>
|
||||
|
||||
<div class="block-header">
|
||||
<h2><?=$station->name ?></h2>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header ch-alt">
|
||||
<h2><?=$title ?></h2>
|
||||
|
||||
<?=$this->insert('system/form') ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
|
||||
showFieldset($('form #field_type input:checked').val());
|
||||
|
||||
$('form #field_type input').on('change', function() {
|
||||
showFieldset($(this).val());
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function showFieldset(fieldset_id)
|
||||
{
|
||||
$('form fieldset.type_fieldset').hide();
|
||||
$('form fieldset#type_'+fieldset_id).show();
|
||||
}
|
||||
</script>
|
|
@ -15,16 +15,14 @@
|
|||
<colgroup>
|
||||
<col width="25%">
|
||||
<col width="30%">
|
||||
<col width="15%">
|
||||
<col width="15%">
|
||||
<col width="30%">
|
||||
<col width="15%">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Actions</th>
|
||||
<th>Playlist</th>
|
||||
<th>Weight</th>
|
||||
<th><abbr title="The likelihood that this playlist will be the source of the next song.">Probability</abbr></th>
|
||||
<th>Type</th>
|
||||
<th># Songs</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -41,8 +39,25 @@
|
|||
<br><span class="label label-success">Auto-Assigned</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?=$row['weight'] ?></td>
|
||||
<td><?=$row['probability'] ?></td>
|
||||
<td>
|
||||
<?php if (!$row['is_enabled']): ?>
|
||||
Disabled
|
||||
<?php elseif ($row['type'] == 'default'): ?>
|
||||
Standard Playlist<br>
|
||||
Weight: <?=$row['weight'] ?> (<?=$row['probability'] ?>)
|
||||
<?php elseif ($row['type'] == 'scheduled'): ?>
|
||||
Scheduled Playlist<br>
|
||||
Plays between <?=\Entity\StationPlaylist::formatTimeCode($row['schedule_start_time']) ?>
|
||||
and <?=\Entity\StationPlaylist::formatTimeCode($row['schedule_end_time']) ?>
|
||||
<?php elseif ($row['type'] == 'once_per_x_songs'): ?>
|
||||
Once per <?=$row['play_per_songs'] ?> Songs
|
||||
<?php elseif ($row['type'] == 'once_per_x_minutes'): ?>
|
||||
Once per <?=$row['play_per_minutes'] ?> Minutes
|
||||
<?php elseif ($row['type'] == 'once_per_day'): ?>
|
||||
Once per Day<br>
|
||||
Plays at <?=\Entity\StationPlaylist::formatTimeCode($row['play_once_time']) ?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?=$row['num_songs'] ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
|
|
|
@ -3,22 +3,26 @@ $options = $form->getOptions();
|
|||
$inner_form = $form->getForm();
|
||||
?>
|
||||
|
||||
|
||||
<?=$inner_form->openForm() ?>
|
||||
<?=$inner_form->renderHidden() ?>
|
||||
|
||||
<?php foreach($options['groups'] as $fieldset_id => $fieldset): ?>
|
||||
|
||||
<?php if (!empty($fieldset['legend'])): ?>
|
||||
<fieldset id="<?=$fieldset_id ?>">
|
||||
<fieldset id="<?=$fieldset_id ?>" <?php if (!empty($fieldset['class'])): ?>class="<?=$fieldset['class'] ?>"<?php endif; ?>>
|
||||
<legend><?=$fieldset['legend'] ?></legend>
|
||||
|
||||
<?php if (!empty($fieldset['description'])): ?>
|
||||
<p><?=$fieldset['description'] ?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
<?php foreach($fieldset['elements'] as $element_id => $element_info): ?>
|
||||
<?php if ($element_info[0] == 'submit'): ?>
|
||||
<input type="submit" value="Save Changes" class="btn btn-lg btn-primary" />
|
||||
<?php else: ?>
|
||||
<div class="form-group">
|
||||
<div class="form-group" id="field_<?=$element_id ?>">
|
||||
<?=$inner_form->renderLabel($element_id) ?>
|
||||
<?php if (!empty($element_info[1]['description'])): ?>
|
||||
<small class="help-block"><?=$element_info[1]['description'] ?></small>
|
||||
|
|
Loading…
Reference in New Issue
Block a user