public function viewAction() { $id = $this->getParam('id'); $station = Station::find($id); if ($station->is_active) { throw new \DF\Exception\DisplayOnly('This station has already been reviewed and is active.'); } $station_form = new \DF\Form($this->module_config['frontend']->forms->submit_station); $station_form->populate($station->toArray()); $form = new \DF\Form($this->current_module_config->forms->vote); if ($_POST && $form->isValid($_POST)) { $data = $form->getValues(); $data['name'] = $this->vote_name; $intake_votes = (array) $station->intake_votes; if ($data['decision'] == 'Abstain') { unset($intake_votes[$this->vote_hash]); } else { $intake_votes[$this->vote_hash] = $data; } $station->intake_votes = $intake_votes; $station->save(); $this->alert('Your vote has been submitted. Thank you for your feedback.', 'green'); $this->redirectFromHere(array('action' => 'index', 'id' => NULL)); return; } $this->view->station_form = $station_form; $this->view->form = $form; }
public function deleteAction() { $record = Record::find($this->getParam('id')); if ($record) { $record->delete(); } $this->alert('Record deleted.', 'green'); $this->redirectFromHere(array('action' => 'index', 'id' => NULL, 'csrf' => NULL)); }
public function preDispatch() { parent::preDispatch(); $station_id = (int) $this->getParam('id'); if ($station_id) { $this->station_id = $station_id; $this->station = Station::find($station_id); $this->view->station_id = $station_id; $this->view->station = $this->station; } }
public function indexAction() { if ($this->hasParam('station')) { $record = Station::findByShortCode($this->getParam('station')); } elseif ($this->hasParam('id')) { $id = (int) $this->getParam('id'); $record = Station::find($id); } else { $this->dispatcher->forward(array('controller' => 'station', 'action' => 'list')); return false; } if (!$record instanceof Station || $record->deleted_at) { return $this->returnError('Station not found.'); } return $this->returnSuccess(Station::api($record)); }
public function upcomingAction() { $this->_initStations(); $this->_initEvents(); $id = $this->view->station_id; $station = Station::find($id); if (!$station instanceof Station) { throw new \DF\Exception\DisplayOnly('Station not found!'); } $this->view->station = $station; // Filter events from master events list. $events_by_day = $this->view->events_by_day; $station_events = array(); foreach ($events_by_day as $day_date => $day_info) { $day_events = array(); foreach ($day_info['events'] as $event) { if ($event['station_id'] == $id) { $day_events[] = $event; } } $day_info['events'] = $day_events; if (!empty($day_info['events'])) { $station_events[$day_date] = $day_info; } } $this->view->station_events = $station_events; }
public static function run($force_run = false) { $di = \Phalcon\Di::getDefault(); $em = $di->get('em'); $config = $di->get('config'); // Set up Google Client. $gclient_api_key = $config->apis->google_apis_key; $gclient_app_name = $config->application->name; if (empty($gclient_api_key)) { return null; } $gclient = new \Google_Client(); $gclient->setApplicationName($gclient_app_name); $gclient->setDeveloperKey($gclient_api_key); $gcal = new \Google_Service_Calendar($gclient); // Prevent running repeatedly in too short of a time (avoid API limits). $last_run = Settings::getSetting('schedule_manager_last_run', 0); if ($last_run > time() - 60 && !$force_run) { return null; } $schedule_items = array(); $schedule_records = array(); $stations = $em->createQuery('SELECT s FROM Entity\\Station s WHERE (s.gcal_url IS NOT NULL AND s.gcal_url != \'\') AND s.is_active = 1')->getArrayResult(); $active_stations = Utilities::ipull($stations, 'id'); // Clear all invalid station records. $em->createQuery('DELETE FROM Entity\\Schedule s WHERE (s.station_id IS NOT NULL) AND (s.station_id NOT IN (:station_ids))')->setParameter('station_ids', $active_stations)->execute(); foreach ($stations as $station) { if ($station['gcal_url']) { $schedule_items[] = array('name' => $station['name'], 'url' => $station['gcal_url'], 'type' => 'station', 'station_id' => $station['id'], 'image_url' => \DF\Url::content($station['image_url'])); } } Debug::startTimer('Get Calendar Records'); // Time boundaries for calendar entries. $threshold_start = date(\DateTime::RFC3339, strtotime('-1 week')); $threshold_end = date(\DateTime::RFC3339, strtotime('+1 year')); foreach ($schedule_items as $item) { // Get the "calendar_id" from the URL provided by the user. $orig_url_parts = parse_url($item['url']); $url_path_parts = explode('/', $orig_url_parts['path']); $calendar_id = urldecode($url_path_parts[3]); if (empty($calendar_id)) { continue; } // Call the external Google Calendar client. try { $all_events = $gcal->events->listEvents($calendar_id, array('timeMin' => $threshold_start, 'timeMax' => $threshold_end, 'singleEvents' => 'true', 'orderBy' => 'startTime', 'maxResults' => '300')); } catch (\Exception $e) { continue; } // Process each individual event. foreach ($all_events as $event_orig) { $title = $event_orig->summary; $body = $event_orig->description; $location = $event_orig->location; $web_url = $event_orig->htmlLink; $banner_url = null; $is_all_day = false; $start_time_obj = $event_orig->start; if ($start_time_obj->date) { $is_all_day = true; $start_time = strtotime($start_time_obj->date . ' 00:00:00'); } else { $start_time = strtotime($start_time_obj->dateTime); } $end_time_obj = $event_orig->end; if ($end_time_obj->date) { $is_all_day = true; $end_time = strtotime($end_time_obj->date . ' 00:00:00'); } elseif ($end_time_obj) { $end_time = strtotime($end_time_obj->dateTime); } else { $end_time = $start_time; } // Detect URLs for link. if ($body && !$web_url) { preg_match('@((https?://)?([-\\w]+\\.[-\\w\\.]+)+\\w(:\\d+)?(/([-\\w/_\\.]*(\\?\\S+)?)?)*)@', $body, $urls); if (count($urls) > 0) { $web_url = $urls[0]; } } // Detect URLs for photo. if ($location) { preg_match('@((https?://)?([-\\w]+\\.[-\\w\\.]+)+\\w(:\\d+)?(/([-\\w/_\\.]*(\\?\\S+)?)?)*)@', $location, $urls); if (count($urls) > 0) { $banner_url = $urls[0]; } } $guid = md5(implode('|', array($event_orig->id, $start_time, $end_time, $title, $location))); $schedule_record = array('guid' => $guid, 'type' => $item['type'], 'start_time' => $start_time, 'end_time' => $end_time, 'is_all_day' => $is_all_day, 'title' => $title, 'location' => $location, 'body' => \DF\Utilities::truncateText(strip_tags($body), 300), 'banner_url' => $banner_url, 'web_url' => $web_url); \PVL\Debug::print_r($schedule_record); $schedule_records[$item['station_id']][$guid] = $schedule_record; } } Debug::endTimer('Get Calendar Records'); if (count($schedule_records) == 0) { Debug::log('Error: No calendar records loaded'); return; } // Add/Remove all differential records. Debug::startTimer('Sync DB Records'); foreach ($schedule_records as $station_id => $station_records) { $station = Station::find($station_id); if ($station_id == 0) { $existing_guids_raw = $em->createQuery('SELECT s.guid FROM Entity\\Schedule s WHERE s.station_id IS NULL')->getArrayResult(); } else { $existing_guids_raw = $em->createQuery('SELECT s.guid FROM Entity\\Schedule s WHERE s.station_id = :sid')->setParameter('sid', $station_id)->getArrayResult(); } $existing_guids = array(); foreach ($existing_guids_raw as $i) { $existing_guids[] = $i['guid']; } $new_guids = array_keys($station_records); $guids_to_delete = array_diff($existing_guids, $new_guids); if ($guids_to_delete) { $em->createQuery('DELETE FROM Entity\\Schedule s WHERE s.guid IN (:guids)')->setParameter('guids', $guids_to_delete)->execute(); } $guids_to_add = array_diff($new_guids, $existing_guids); if ($guids_to_add) { foreach ($guids_to_add as $guid) { $schedule_record = $station_records[$guid]; $record = new Schedule(); $record->station = $station; $record->fromArray($schedule_record); $em->persist($record); } } $em->flush(); $em->clear(); } Debug::endTimer('Sync DB Records'); Settings::setSetting('schedule_manager_last_run', time()); }
public function songconfirmAction() { // Handle files submitted directly to page. $ignore_files = (int) $this->getParam('ignore_files'); $request = $this->di->get('request'); if ($request->hasFiles() && !$ignore_files) { $this->_processSongUpload(); } // Validate song identifier token. $token = $this->_getSongHashToken(); if (!$this->_validateSongHash($token)) { return $this->redirectFromHere(array('action' => 'song')); } // Check that any stations were selected if (!$this->hasParam('stations')) { throw new \DF\Exception\DisplayOnly('You did not specify any stations!'); } // Check for uploaded songs. $temp_dir_name = 'song_uploads'; $temp_dir = DF_INCLUDE_TEMP . DIRECTORY_SEPARATOR . $temp_dir_name; $all_files = glob($temp_dir . DIRECTORY_SEPARATOR . $token . '*.mp3'); if (empty($all_files)) { throw new \DF\Exception\DisplayOnly('No files were uploaded!'); } $songs = array(); $getId3 = new GetId3(); $getId3->encoding = 'UTF-8'; foreach ($all_files as $song_file_base) { $song_file_path = $temp_dir . DIRECTORY_SEPARATOR . basename($song_file_base); // Attempt to analyze the MP3. $audio = $getId3->analyze($song_file_path); if (isset($audio['error'])) { @unlink($song_file_path); throw new \DF\Exception\DisplayOnly(sprintf('Error at reading audio properties with GetId3: %s.', $audio['error'][0])); } if (isset($audio['tags']['id3v1']['title'])) { $song_data = array('title' => $audio['tags']['id3v1']['title'][0], 'artist' => $audio['tags']['id3v1']['artist'][0]); } elseif (isset($audio['tags']['id3v2']['title'])) { $song_data = array('title' => $audio['tags']['id3v2']['title'][0], 'artist' => $audio['tags']['id3v2']['artist'][0]); } else { @unlink($song_file_path); continue; } // Check if existing submission exists. $song = Song::getOrCreate($song_data); $existing_submission = SongSubmission::getRepository()->findOneBy(array('hash' => $song->id)); if ($existing_submission instanceof SongSubmission) { @unlink($song_file_path); continue; } // Create record in database. $metadata = array('File Format' => strtoupper($audio['fileformat']), 'Play Time' => $audio['playtime_string'], 'Bitrate' => round($audio['audio']['bitrate'] / 1024) . 'kbps', 'Bitrate Mode' => strtoupper($audio['audio']['bitrate_mode']), 'Channels' => $audio['audio']['channels'], 'Sample Rate' => $audio['audio']['sample_rate']); $record = new SongSubmission(); $record->song = $song; $auth = $this->di->get('auth'); $record->user = $auth->getLoggedInUser(); $record->title = $song_data['title']; $record->artist = $song_data['artist']; $record->song_metadata = $metadata; $record->stations = $this->getParam('stations'); $song_download_url = $record->uploadSong($song_file_path); $record->save(); // Append information to e-mail to stations. $song_row = array('Download URL' => '<a href="' . $song_download_url . '" target="_blank">' . $song_download_url . '</a>', 'Title' => $song_data['title'], 'Artist' => $song_data['artist']) + $metadata; $songs[] = $song_row; } if (!empty($songs)) { // Notify all existing managers. $network_administrators = Action::getUsersWithAction('administer all'); $email_to = Utilities::ipull($network_administrators, 'email'); // Pull list of station managers for the specified stations. $station_managers = array(); $short_names = Station::getShortNameLookup(); foreach ($this->getParam('stations') as $station_key) { if (isset($short_names[$station_key])) { $station_id = $short_names[$station_key]['id']; $station = Station::find($station_id); foreach ($station->managers as $manager) { $station_managers[] = $manager->email; } } } $email_to = array_merge($email_to, $station_managers); // Trigger e-mail notice. if (!empty($email_to)) { \DF\Messenger::send(array('to' => $email_to, 'subject' => 'New Song(s) Submitted to Station', 'template' => 'newsong', 'vars' => array('songs' => $songs))); } } // Have to manually call view because a view was already rendered (e-mail was sent). // TODO: Fix this. It's dumb. $this->view->songs = $songs; return $this->view->render('submit', 'songconfirm'); }