'Station',
'description' => 'Change settings for the Station module.',
'page callback' => 'drupal_get_form',
'page arguments' => array('station_admin_settings'),
'file' => 'station.admin.inc',
'access arguments' => array('administer site configuration'),
);
$items['admin/settings/station/main'] = array(
'title' => 'Core',
'page callback' => 'drupal_get_form',
'page arguments' => array('station_admin_settings'),
'file' => 'station.admin.inc',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => '-10',
);
$items['station'] = array(
'title' => 'Station',
'page callback' => 'station_page',
'access arguments' => array('access content'),
);
return $items;
}
/**
* Implementation of hook_theme().
*/
function station_theme() {
return array(
'station_block_current_program' => array(
'arguments' => array('schedule' => NULL, 'program' => NULL),
),
'station_hour' => array(
'arguments' => array('time' => NULL),
'file' => 'dayhour.inc',
),
'station_hour_duration' => array(
'arguments' => array('start' => NULL, 'finish' => NULL),
'file' => 'dayhour.inc',
),
'station_day' => array(
'arguments' => array('time' => NULL),
'file' => 'dayhour.inc',
),
'station_dayhour' => array(
'arguments' => array('time' => NULL),
'file' => 'dayhour.inc',
),
'station_dayhour_range' => array(
'arguments' => array('start' => NULL, 'finish' => NULL),
'file' => 'dayhour.inc',
),
'station_hour_range' => array(
'arguments' => array('start' => NULL, 'finish' => NULL),
'file' => 'dayhour.inc',
),
'station_streams' => array(
'arguments' => array('streams' => NULL),
),
);
}
/**
* Implementation of hook_block().
*/
function station_block($op = 'list', $delta = 0, $edit = array()) {
switch ($op) {
case 'view':
if (user_access('view station schedule content')) {
switch ($delta) {
case 0:
return array(
'subject' => t('On Air'),
'content' => station_block_current_program(),
);
}
}
return;
case 'list':
$blocks[0] = array(
'info' => t('Station: Current Program'),
'status' => TRUE,
'region' => 'left',
'cache' => BLOCK_NO_CACHE,
);
return $blocks;
}
}
function station_page() {
$output = '';
if ($content = system_admin_menu_block(menu_get_item())) {
$output = theme('admin_block_content', $content);
}
return $output;
}
/**
* AJAX form handler.
*/
function station_ajax_form_handler() {
$form_state = array('storage' => NULL, 'submitted' => FALSE);
$form_build_id = $_POST['form_build_id'];
// Get the form from the cache.
$form = form_get_cache($form_build_id, $form_state);
$args = $form['#parameters'];
$form_id = array_shift($args);
// We need to process the form, prepare for that by setting a few internals.
$form_state['post'] = $form['#post'] = $_POST;
$form['#programmed'] = $form['#redirect'] = FALSE;
// Build, validate and if possible, submit the form.
drupal_process_form($form_id, $form, $form_state);
// If validation fails, force form submission.
if (form_get_errors()) {
form_execute_handlers('submit', $form, $form_state);
}
// This call recreates the form relying solely on the form_state that the
// drupal_process_form set up.
$form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
return $form;
}
/**
* Determine if we have a station archive module running locally or access to a
* remote one.
*
* @return boolean
*/
function station_has_archive() {
return (module_exists('station_archive') || variable_get('station_remote_archive_url', FALSE));
}
/**
* Determine if we have a station schedule module running locally or access to a
* remote one.
*
* @return boolean
*/
function station_has_schedule() {
return (module_exists('station_schedule') || variable_get('station_remote_schedule_url', FALSE));
}
/**
* If there's an archive, return the URL.
*
* @return FALSE or string URL.
*/
function station_get_archive_url() {
if (module_exists('station_archive')) {
return 'station/archives/';
}
elseif ($url = variable_get('station_remote_archive_url', FALSE)) {
return $url .'station/archives/';
}
return FALSE;
}
/**
* Return a list of schedules.
*
* The list of schedules is cached between calls.
*
* @return Array keyed to nid of schedules or FALSE on error.
*/
function station_get_schedules() {
static $schedules;
if (!isset($schedules)) {
if (module_exists('station_schedule')) {
$schedules = station_schedule_get_list();
}
else {
// If they haven't provided a URL we can't retreive any data.
$url = variable_get('station_remote_schedule_url', '');
if (empty($url)) {
return FALSE;
}
// Try to load the schedules from the cache.
$cacheid = 'station_remote:schedules_'. $url;
if ($cache = cache_get($cacheid, 'cache')) {
$schedules = $cache->data;
}
else {
$schedules = xmlrpc(check_url($url .'/xmlrpc.php'), 'station.schedule.get.list');
if (xmlrpc_errno()) {
watchdog('station', 'Failed to load schedule info remotely. Error %code : %message', array('%code' => xmlrpc_errno(), '%message' => xmlrpc_error_msg()), WATCHDOG_ERROR);
return FALSE;
}
// Save the value for the next call.
cache_set($cacheid, $schedules, 'cache', CACHE_TEMPORARY);
}
}
}
return $schedules;
}
/**
* Return the default schedule.
*
* @return Array with schedule info, or NULL if no schedules are available.
*/
function station_default_schedule() {
if (module_exists('station_schedule')) {
$id = variable_get('station_schedule_default', 0);
}
else {
$id = variable_get('station_remote_schedule_nid', 0);
}
$schedules = station_get_schedules();
// Return the default schedule if one has been selected, if not just use the
// first one.
if (isset($schedules[$id])) {
return $schedules[$id];
}
if (is_array($schedules)) {
return reset($schedules);
}
return NULL;
}
/**
* Return an object for the current program from the local machine or RPC if
* that's not available.
*
* @param $time
* A GMT timestamp.
* @param $schedule_nid
* Schedule Id, 0 will load the default schedule.
* @return
* FALSE if there was an error loading the data, NULL if nothing could be
* found, or, a program object if everything worked out.
*/
function station_get_program_at($timestamp, $schedule_nid) {
// If no schedule was provided, use the default.
if (empty($schedule_nid)) {
$schedule = station_default_schedule();
$schedule_nid = $schedule['nid'];
}
// Force the params to integers, the xmlrpc() call gets pissy if an int isn't
// typed as an int.
$schedule_nid = (int) $schedule_nid;
$timestamp = (int) $timestamp;
// Use the local schedule if one is available.
if (module_exists('station_schedule')) {
if ($program = station_schedule_program_get_at($timestamp, $schedule_nid)) {
if (!empty($program->nid)) {
return $program;
}
}
}
else {
// Try to connect to a remote schedule via XMLRPC for program information.
// The info will be cached to cut down on repeated RPC calls.
// If they haven't provided a url we can't retreive any data
$url = variable_get('station_remote_schedule_url', '');
if (empty($url)) {
return FALSE;
}
// add in our magic offset
$timestamp += 60 * variable_get('station_remote_schedule_offset', 0);
// round the time to the nearest 15 minute increment so we can do some
// caching
$parts = getdate($timestamp);
$minutes = $parts['minutes'];
if ($minutes < 15)
$minutes = 0;
elseif ($minutes < 30)
$minutes = 15;
elseif ($minutes < 45)
$minutes = 30;
else
$minutes = 45;
$timestamp = mktime($parts['hours'], $minutes, 0, $parts['mon'], $parts['mday'], $parts['year']);
// try to grab it from the cache
$cacheid = 'station_remote:program_at_'. $timestamp;
if ($cache = cache_get($cacheid, 'cache')) {
$program = $cache->data;
}
else {
// if it isn't cached get the program info from the server
$program = xmlrpc(check_url($url .'/xmlrpc.php'), 'station.program.get.at', $timestamp, $schedule_nid);
if (xmlrpc_errno()) {
watchdog('station', 'Failed to load program info remotely. Error %code : %message', array('%code' => xmlrpc_errno(), '%message' => xmlrpc_error_msg()), WATCHDOG_ERROR);
return FALSE;
}
// save it to the cache
cache_set($cacheid, $program, 'cache', CACHE_TEMPORARY);
}
// program returned by XMLRPC is an array
if ($program['nid']) {
return (object) $program;
}
}
return NULL;
}
/**
* Return HTML body of the block listing the current program.
*
* @return string
*/
function station_block_current_program() {
$schedule = station_default_schedule();
$program = station_get_program_at(time(), $schedule['nid']);
return theme('station_block_current_program', $schedule, $program);
}
/**
* Theme the current program block.
*
* @param $schedule
* Schedule array returned by station_default_schedule().
* @param $program
* Program node object.
* @return string
*/
function theme_station_block_current_program($schedule, $program) {
// Program or unscheduled...
if ($program) {
$output = l($program->title, $program->node_url) .'
';
}
else {
$output = check_plain($schedule['unscheduled_message']) .'
';
}
// Streams
$output .= theme('station_streams', $schedule['streams']);
return $output;
}
/**
* Theme a schedule's web streams.
*
* @param $nid
* A station schedule node id (might be on a remote site).
* @param $streams
* Schedule's streams.
*/
function theme_station_streams($streams) {
$items = array();
foreach ((array) $streams as $key => $stream) {
$items[] = l($stream['name'], $stream['m3u_url'], array('title' => $stream['description']));
}
if (count($items)) {
return t('Tune in:') .' '. station_ored_list($items);
}
}
/**
* Convert an array to a comma separates list with an 'add' between the last
* terms.
*
* @param $array array of items
*/
function station_anded_list($array) {
switch (count($array)) {
case 0:
return '';
case 1:
return array_pop($array);
default:
$last = array_pop($array);
return t('!list-items and !last-item', array('!list-items' => implode(', ', $array), '!last-item' => $last));
}
}
/**
* Convert an array to a comma separates list with an 'or' between the last
* terms.
*
* @param $array array of items
*/
function station_ored_list($array) {
switch (count($array)) {
case 0:
return '';
case 1:
return array_pop($array);
default:
$last = array_pop($array);
return t('!list-items or !last-item', array('!list-items' => implode(', ', $array), '!last-item' => $last));
}
}
/**
* Return a timezone corrected timestamp.
*/
function station_local_ts($ts = FALSE) {
$ts = ($ts === FALSE) ? time() : $ts;
return ($ts - date('Z', $ts)) + variable_get('date_default_timezone', 0);
}
/**
* Return the timezone corrected day of the week (1-7).
*/
function station_today() {
return date('w', station_local_ts());
}
/**
* Function to send notices of station changes via hook_station_notices.
*/
function _station_send_notice($type, $op, $data) {
module_invoke_all('station_notice', $type, $op, $data);
}
/**
* Implementation of hook_station_notices to display simple notices about
* station changes.
*
* @param $type 'dj' or 'schedule'
* @param $op 'add', 'remove', 'change' - Change only applies to schedule
* items.
* @param $data associative array with details like: nid, sid, uid.
*/
# Renamed this since it's basically just for debugging.
function _station_station_notice($type, $op, $data) {
if ($type == 'dj') {
$pid = $data['program_nid'];
$uid = $data['uid'];
switch ($op) {
case 'add':
drupal_set_message("$sid adding $uid to $nid");
break;
case 'remove':
drupal_set_message("$sid removing $uid from $nid");
break;
}
}
elseif ($type == 'schedule') {
$iid = $data['iid'];
$sid = $data['schedule_nid'];
$pid = $data['program_nid'];
switch ($op) {
case 'add':
drupal_set_message("$sid adding $iid to $pid");
break;
case 'change':
drupal_set_message("$sid changing $iid on $pid");
break;
case 'remove':
drupal_set_message("$sid removing $iid from $pid");
break;
}
}
}