'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; } } }