/** * Process RSS feed and return results. * * @param $feed_url * @param null $cache_name * @param int $cache_expires * @return array|mixed */ public static function getNewsFeed($feed_url, $cache_name = NULL, $cache_expires = 900) { if (!is_null($cache_name)) { $feed_cache = Cache::get('feed_' . $cache_name); } else { $feed_cache = null; } if ($feed_cache) { return $feed_cache; } // Catch the occasional error when the RSS feed is malformed or the HTTP request times out. try { $news_feed = Reader::import($feed_url); } catch (\Exception $e) { $news_feed = NULL; } if (!is_null($news_feed)) { $latest_news = array(); $article_num = 0; foreach ($news_feed as $item) { $article_num++; $news_item = array('num' => $article_num, 'title' => $item->getTitle(), 'timestamp' => $item->getDateModified()->getTimestamp(), 'description' => trim($item->getDescription()), 'link' => $item->getLink(), 'categories' => $item->getCategories()->getValues()); $latest_news[] = $news_item; } $latest_news = array_slice($latest_news, 0, 10); if (!is_null($cache_name)) { Cache::set($latest_news, 'feed_' . $cache_name, array('feeds', $cache_name), $cache_expires); } return $latest_news; } }
/** * Static Functions */ public static function fetchFeatured() { $news = \DF\Cache::get('homepage_featured_news'); if (!$news) { $news = self::fetch(); \DF\Cache::save($news, 'homepage_featured_news', null, 300); } return $news; }
public static function getTypeTotals() { $totals = \DF\Cache::get('artist_totals'); if (!$totals) { $totals = array(); $records = self::fetchAll(); foreach ($records as $record) { $totals['types'][$record->id] = array('name' => $record->name, 'icon' => $record->icon, 'count' => count($record->artists)); } $totals['overall'] = array('count' => count(Artist::fetchArray())); \DF\Cache::save($totals, 'artist_totals', array(), 600); } return $totals; }
public function listAction() { $return = \DF\Cache::get('api_songs'); if (!$return) { ini_set('memory_limit', '-1'); $all_songs = Song::fetchArray(); $return = array(); foreach ($all_songs as $song) { $return[$song['id']] = Song::api($song); } \DF\Cache::save($return, 'api_songs', array(), 60); } return $this->returnSuccess($return); }
public function viewAction() { $id = (int) $this->getParam('id'); $record = Artist::find($id); if (!$record instanceof Artist) { throw new \DF\Exception\DisplayOnly('Artist Not Found'); } $this->view->artist = $record; // Generate statistics. $cache_key = 'artist_' . $record->id . '_stats'; $stats = \DF\Cache::get($cache_key); if (empty($stats)) { $stats = array('plays_per_day' => array(), 'song_lists' => array('most_played' => array('label' => 'Most Played Songs', 'songs' => array()), 'most_liked' => array('label' => 'Most Liked Songs', 'songs' => array()), 'most_recent' => array('label' => 'Most Recently Played', 'songs' => array()))); $active_streams = \Entity\StationStream::getMainRadioStreams(); $songs = $this->em->createQuery('SELECT s, sh FROM Entity\\Song s LEFT JOIN s.history sh WHERE s.artist LIKE :artist_q AND sh.stream_id IN (:streams) ORDER BY s.title, sh.timestamp DESC')->setParameter('artist_q', '%' . $record->name . '%')->setParameter('streams', $active_streams)->getArrayResult(); $plays_per_day = array(); foreach ($songs as &$song) { foreach ((array) $song['history'] as $i => $history) { // Get day of song play, incremenet counter. $day = strtotime(date('Y-m-d', $history['timestamp']) . ' 00:00:00') * 1000; $plays_per_day[$day] += 1; // Increment votes. $song['score_likes'] += $history['score_likes']; $song['score_dislikes'] += $history['score_dislikes']; } unset($song['history']); // Increment vote totals. $song['score_total'] = $song['score_likes'] - $song['score_dislikes']; $song['votes'] = $song['score_likes'] + $song['score_dislikes']; } // Remove current day, as it will always be lower. $current_day = strtotime(date('Y-m-d') . ' 00:00:00') * 1000; unset($plays_per_day[$current_day]); ksort($plays_per_day); foreach ($plays_per_day as $plays_day => $plays_total) { $stats['plays_per_day'][] = array($plays_day, $plays_total); } $stats['song_lists']['most_played']['songs'] = array_slice(Utilities::irsort($songs, 'play_count'), 0, 10); $stats['song_lists']['most_liked']['songs'] = array_slice(Utilities::irsort($songs, 'score_total'), 0, 10); $stats['song_lists']['most_recent']['songs'] = array_slice(Utilities::irsort($songs, 'last_played'), 0, 10); \DF\Cache::save($stats, $cache_key, array(), 300); } $this->view->stats = $stats; }
public static function getTotals() { $totals = \DF\Cache::get('archive_genre_totals'); if (!$totals) { $em = self::getEntityManager(); $conn = $em->getConnection(); $totals_raw = $conn->fetchAll('SELECT ag.id, ag.name, COUNT(ashg.song_id) AS songs FROM archive_genre AS ag LEFT JOIN archive_song_has_genre AS ashg ON ashg.genre_id = ag.id GROUP BY ag.id ORDER BY ag.name ASC'); $totals = array(); foreach ($totals_raw as $row) { $totals[$row['id']] = array('name' => $row['name'], 'total' => $row['songs']); } \DF\Cache::save($totals, 'archive_genre_totals', array(), 600); } return $totals; }
public static function fetchArray($cached = true) { static $settings; if (!$settings || !$cached) { $settings = \DF\Cache::get('all_settings'); if (!$settings || !$cached) { $em = self::getEntityManager(); $settings_raw = $em->createQuery('SELECT s FROM ' . __CLASS__ . ' s ORDER BY s.setting_key ASC')->getArrayResult(); $settings = array(); foreach ((array) $settings_raw as $setting) { $settings[$setting['setting_key']] = $setting['setting_value']; } \DF\Cache::save($settings, 'all_settings', array(), 8640); } } return $settings; }
public function indexAction() { $this->setCacheLifetime(15); // Pull from cache, or load from flatfile otherwise. $np = \DF\Cache::get('api_nowplaying_data', function () { $file_path_api = \PVL\Service\AmazonS3::path('api/nowplaying_api.json'); $np_raw = file_get_contents($file_path_api); $np_arr = @json_decode($np_raw, TRUE); $np = $np_arr['result']; return $np; }); // Sanity check for now playing data. if (empty($np)) { return $this->returnError('Now Playing data has not loaded into the cache. Wait for file reload.'); } if ($this->hasParam('id') || $this->hasParam('station')) { if ($this->hasParam('id')) { $id = (int) $this->getParam('id'); foreach ($np as $key => $np_row) { if ($np_row['station']['id'] == $id) { $sc = $key; break; } } if (empty($sc)) { return $this->returnError('Station not found!'); } } elseif ($this->hasParam('station')) { $sc = $this->getParam('station'); } if (isset($np[$sc])) { return $this->returnSuccess($np[$sc]); } else { return $this->returnError('Station not found!'); } } elseif ($this->hasParam('category')) { $type = $this->getParam('category'); $np = array_filter($np, function ($station_row) use($type) { return $station_row['station']['category'] == $type; }); return $this->returnSuccess($np); } else { return $this->returnSuccess($np); } }
/** * Static Functions */ public static function fetch($only_approved = true) { $cache_name = 'pvlive_affiliates_' . ($only_approved ? 'approved' : 'all'); $records = \DF\Cache::get($cache_name); if (!$records) { $records = self::fetchArray(); if ($only_approved) { $records = array_filter($records, function ($record) { return $record['is_approved']; }); } // Add affiliate tracking info. foreach ($records as &$record) { $record['web_url'] = \PVL\AnalyticsManager::addTracking($record['web_url'], array('source' => 'pvliveaffiliate')); } \DF\Cache::set($records, $cache_name, array(), 60); } shuffle($records); return $records; }
public function indexAction() { if ($this->hasParam('id')) { $id = (int) $this->getParam('id'); $record = $this->em->createQuery('SELECT p, s, pe FROM Entity\\Podcast p LEFT JOIN p.stations s LEFT JOIN p.episodes pe WHERE p.is_approved = 1 AND p.id = :id')->setParameter('id', $id)->execute(); if ($record[0] instanceof Podcast) { $return = Podcast::api($record[0], TRUE); return $this->returnSuccess($return); } else { return $this->returnError('Show not found!'); } } else { $return = \DF\Cache::get('api_shows'); if (!$return) { $records = $this->em->createQuery('SELECT p, s, pe FROM Entity\\Podcast p LEFT JOIN p.stations s LEFT JOIN p.episodes pe WHERE p.is_approved = 1 ORDER BY p.name ASC')->getArrayResult(); $return = array(); foreach ($records as $record) { $return[] = Podcast::api($record, 10); } \DF\Cache::set($return, 'api_shows', array(), 60); } return $this->returnSuccess($return); } }
public function feedAction() { $this->doNotRender(); if ($this->hasParam('id')) { $id = (int) $this->getParam('id'); $record = Podcast::find($id); if (!$record instanceof Podcast) { throw new \DF\Exception\DisplayOnly('Show record not found!'); } $feed_title = $record->name; $feed_desc = $record->description ? $record->description : 'A Ponyville Live! Show.'; $cache_name = 'podcasts_' . $id . '_feed'; $q = $this->em->createQuery('SELECT pe, p FROM Entity\\PodcastEpisode pe JOIN pe.podcast p WHERE p.is_approved = 1 AND p.id = :id ORDER BY pe.timestamp DESC')->setParameter('id', $id); } else { $feed_title = 'Ponyville Live! Shows'; $feed_desc = 'The partner shows of the Ponyville Live! network, including commentary, interviews, episode reviews, convention coverage, and more.'; $cache_name = 'podcasts_all_feed'; $q = $this->em->createQuery('SELECT pe, p FROM Entity\\PodcastEpisode pe JOIN pe.podcast p WHERE p.is_approved = 1 AND pe.timestamp >= :threshold ORDER BY pe.timestamp DESC')->setParameter('threshold', strtotime('-3 months')); } $rss = \DF\Cache::get($cache_name); if (!$rss) { $records = $q->getArrayResult(); // Initial RSS feed setup. $feed = new \Zend\Feed\Writer\Feed(); $feed->setTitle($feed_title); $feed->setLink('http://ponyvillelive.com/'); $feed->setDescription($feed_desc); $feed->addAuthor(array('name' => 'Ponyville Live!', 'email' => '*****@*****.**', 'uri' => 'http://ponyvillelive.com')); $feed->setDateModified(time()); foreach ((array) $records as $episode) { try { $podcast = $episode['podcast']; $title = $episode['title']; // Check for podcast name preceding episode name. if (substr($title, 0, strlen($podcast['name'])) == $podcast['name']) { $title = substr($title, strlen($podcast['name'])); } $title = trim($title, " :-\t\n\r\v"); $title = $podcast['name'] . ' - ' . $title; // Create record. $entry = $feed->createEntry(); $entry->setTitle($title); $entry->setLink($episode['web_url']); $entry->addAuthor(array('name' => $podcast['name'], 'uri' => $podcast['web_url'])); $entry->setDateModified($episode['timestamp']); $entry->setDateCreated($episode['timestamp']); if ($podcast['description']) { $entry->setDescription($podcast['description']); } if ($episode['body']) { $entry->setContent($episode['body']); } $feed->addEntry($entry); } catch (\Exception $e) { } } // Export feed. $rss = $feed->export('rss'); \DF\Cache::set($rss, $cache_name, array(), 60 * 15); } header("Content-Type: application/rss+xml"); echo $rss; }
public function indexAction() { // Get calendar name. $short_names = Station::getShortNameLookup(); $station_shortcode = $this->getParam('station', 'all'); if ($station_shortcode != "all") { $station = $short_names[$station_shortcode]; $calendar_name = $station['name']; } else { $calendar_name = 'Ponyville Live!'; } // Get timestamp boundaries. if ($this->hasParam('month')) { $show = $this->getParam('month'); $calendar = new \DF\Calendar($show); $timestamps = $calendar->getTimestamps(); $start_timestamp = $timestamps['start']; $end_timestamp = $timestamps['end']; $use_cache = true; $cache_name = 'month_' . $show; $calendar_name .= ' - ' . date('F Y', $timestamps['mid']); } elseif ($this->hasParam('start')) { $start_timestamp = (int) $this->getParam('start'); $end_timestamp = (int) $this->getParam('end'); $use_cache = false; $cache_name = null; // $cache_name = 'range_'.$start_timestamp.'_'.$end_timestamp; $calendar_name .= ' - ' . date('F j, Y', $start_timestamp) . ' to ' . date('F j, Y', $end_timestamp); } else { $start_timestamp = time(); $end_timestamp = time() + 86400 * 30; $use_cache = true; $cache_name = 'upcoming'; $calendar_name .= ' - Upcoming'; } // Load from cache or regenerate. if ($use_cache) { $cache_name = 'api_sched_' . $station_shortcode . '_' . $cache_name; $events = \DF\Cache::get($cache_name); } else { $events = null; } if (!$events) { if ($station_shortcode != "all") { $station = $short_names[$station_shortcode]; $events_raw = $this->em->createQuery('SELECT s FROM Entity\\Schedule s WHERE (s.station_id = :sid) AND (s.start_time <= :end AND s.end_time >= :start) ORDER BY s.start_time ASC')->setParameter('sid', $station['id'])->setParameter('start', $start_timestamp)->setParameter('end', $end_timestamp)->getArrayResult(); } else { $events_raw = $this->em->createQuery('SELECT s, st FROM Entity\\Schedule s LEFT JOIN s.station st WHERE (s.start_time <= :end AND s.end_time >= :start) ORDER BY s.start_time ASC')->setParameter('start', $start_timestamp)->setParameter('end', $end_timestamp)->getArrayResult(); } $events = array(); foreach ((array) $events_raw as $event) { $events[] = Schedule::api($event); } if ($use_cache) { \DF\Cache::save($events, $cache_name, array(), 300); } } $format = strtolower($this->getParam('format', 'json')); switch ($format) { case "ics": case "ical": return $this->_printCalendar($events, $calendar_name, $cache_name); break; case "json": default: return $this->returnSuccess($events); break; } }
public function indexAction() { $influx = $this->di->get('influx'); $influx->setDatabase('pvlive_analytics'); set_time_limit(300); ini_set('memory_limit', '256M'); $stats = \DF\Cache::get('admin_api_calls'); if (!$stats) { $threshold = time() - 86400 * 2.5; $seconds_in_threshold = time() - $threshold; $minutes_in_threshold = round($seconds_in_threshold / 60); $stats = array('speed_by_function' => array(), 'calls_by_function' => array(), 'calls_by_client' => array(), 'calls_by_useragent' => array(), 'calls_by_ip' => array(), 'calls_by_hour' => array()); // Speed and Calls by Function try { $stats_by_func = $influx->query('SELECT count(value) AS total_calls, mean(requesttime) AS request_time, controller FROM api_calls GROUP BY controller', 's'); $stats_by_func = array_pop($stats_by_func); } catch (\Exception $e) { $stats_by_func = array(); } $total_calls = 0; foreach ($stats_by_func as $func_row) { $func = $func_row['controller']; $total_calls += $func_row['total_calls']; $stats['speed_by_function'][$func] = round($func_row['request_time'] * 1000, 2); $stats['calls_by_function'][$func] = $func_row['total_calls']; } // Calls per client try { $stats_by_client = $influx->query('SELECT count(value) AS num_calls, client FROM api_calls GROUP BY client'); $stats_by_client = array_pop($stats_by_client); } catch (\Exception $e) { $stats_by_client = array(); } foreach ($stats_by_client as $row) { $stats['calls_by_client'][$row['client']] = $row['num_calls']; } // Calls per user-agent try { $stats_by_ua = $influx->query('SELECT count(value) AS num_calls, useragent FROM api_calls GROUP BY useragent'); $stats_by_ua = array_pop($stats_by_ua); } catch (\Exception $e) { $stats_by_ua = array(); } foreach ($stats_by_ua as $row) { $stats['calls_by_useragent'][$row['useragent']] = $row['num_calls']; } // Calls per IP try { $stats_by_ip = $influx->query('SELECT count(value) AS num_calls, ip FROM api_calls GROUP BY ip'); $stats_by_ip = array_pop($stats_by_ip); } catch (\Exception $e) { $stats_by_ip = array(); } foreach ($stats_by_ip as $row) { $stats['calls_by_ip'][$row['ip']] = $row['num_calls']; } /* // Calls by hour */ foreach ($stats as $stat_category => &$stat_items) { arsort($stat_items); $stat_items = array_slice($stat_items, 0, 10); foreach ($stat_items as $stat_key => &$stat_value) { $stat_value = array('total' => $stat_value, 'percentage' => round($stat_value / $total_calls * 100, 2)); } } $stats['meta'] = array('threshold' => $threshold, 'total_calls' => $total_calls, 'calls_per_minute' => round($total_calls / $minutes_in_threshold, 3)); \DF\Cache::save($stats, 'admin_api_calls', array(), 300); } $this->view->statistics = $stats; }
protected function _getIgnoredSongs() { $song_hashes = \DF\Cache::get('station_center_ignored_songs'); if (!$song_hashes) { $ignored_phrases = array('Offline', 'Sweeper', 'Bumper', 'Unknown'); $qb = $this->em->createQueryBuilder(); $qb->select('s.id')->from('Entity\\Song', 's'); foreach ($ignored_phrases as $i => $phrase) { $qb->orWhere('s.text LIKE ?' . ($i + 1)); $qb->setParameter($i + 1, '%' . $phrase . '%'); } $song_hashes_raw = $qb->getQuery()->getArrayResult(); $song_hashes = array(); foreach ($song_hashes_raw as $row) { $song_hashes[$row['id']] = $row['id']; } \DF\Cache::save($song_hashes, 'station_center_ignored_songs', array(), 86400); } return $song_hashes; }
protected function _initEvents() { $event_info = Cache::get('pvlive_events'); if (!$event_info) { $events_raw = $this->em->createQuery('SELECT s, st FROM Entity\\Schedule s JOIN s.station st WHERE (s.end_time >= :current AND s.start_time <= :future) ORDER BY s.start_time ASC')->setParameter('current', time())->setParameter('future', strtotime('+4 days'))->getArrayResult(); $all_events = array(); $events_by_day = array(); for ($i = 0; $i < 6; $i++) { $day_timestamp = mktime(0, 0, 1, date('n'), (int) date('j') + $i); $day_date = date('Y-m-d', $day_timestamp); $is_today = $day_date == date('Y-m-d'); $events_by_day[$day_date] = array('day_name' => $is_today ? 'Today' : date('l', $day_timestamp), 'timestamp' => $day_timestamp, 'is_today' => $is_today, 'events' => array()); } foreach ($events_raw as $event) { $event['image_url'] = \PVL\Url::upload(Schedule::getRowImageUrl($event)); $event['status'] = $event['start_time'] <= time() ? 'now' : 'upcoming'; $event['range'] = Schedule::getRangeText($event['start_time'], $event['end_time'], $event['is_all_day']); if ($event['station_id']) { $sid = $event['station_id']; if (isset($this->stations[$sid])) { $station = $this->stations[$sid]; unset($station['nowplaying_data'], $station['streams'], $station['intake_votes']); $event['station'] = $station; } } $all_events[] = $event; for ($i = $event['start_time']; $i <= $event['end_time']; $i += 86400) { $event_date = date('Y-m-d', $i); if (isset($events_by_day[$event_date])) { $events_by_day[$event_date]['events'][] = $event; } } } $event_info = array('all' => $all_events, 'by_day' => $events_by_day); Cache::save($event_info, 'pvlive_events', array(), 60); } $this->view->all_events = $event_info['all']; $this->view->events_by_day = $event_info['by_day']; }
/** * Main display. */ public function indexAction() { // Inject all stations. $stations = \Entity\Station::fetchAll(); $this->view->stations = $stations; // Inject all podcasts. $podcasts = \Entity\Podcast::fetchAll(); $this->view->podcasts = $podcasts; // Pull cached statistic charts if available. $metrics = \DF\Cache::get('admin_metrics'); if (!$metrics) { // Statistics by day. $influx = $this->di->get('influx'); $station_averages = array(); $network_data = array('PVL Network' => array('ranges' => array(), 'averages' => array())); $daily_stats = $influx->setDatabase('pvlive_stations')->query('SELECT * FROM /1d.*/ WHERE time > now() - 180d', 'm'); foreach ($daily_stats as $stat_series => $stat_rows) { $series_split = explode('.', $stat_series); if ($series_split[1] == 'all') { $network_name = 'PVL Network'; foreach ($stat_rows as $stat_row) { $network_data[$network_name]['ranges'][$stat_row['time']] = array($stat_row['time'], $stat_row['min'], $stat_row['max']); $network_data[$network_name]['averages'][$stat_row['time']] = array($stat_row['time'], round($stat_row['value'], 2)); } } else { $station_id = $series_split[2]; foreach ($stat_rows as $stat_row) { $station_averages[$station_id][$stat_row['time']] = array($stat_row['time'], round($stat_row['value'], 2)); } } } $network_metrics = array(); foreach ($network_data as $network_name => $data_charts) { if (isset($data_charts['ranges'])) { $metric_row = new \stdClass(); $metric_row->name = $network_name . ' Listener Range'; $metric_row->type = 'arearange'; ksort($data_charts['ranges']); $metric_row->data = array_values($data_charts['ranges']); $network_metrics[] = $metric_row; } if (isset($data_charts['averages'])) { $metric_row = new \stdClass(); $metric_row->name = $network_name . ' Daily Average'; $metric_row->type = 'spline'; ksort($data_charts['averages']); $metric_row->data = array_values($data_charts['averages']); $network_metrics[] = $metric_row; } } $station_metrics = array(); foreach ($stations as $station) { $station_id = $station['id']; if (isset($station_averages[$station_id])) { $series_obj = new \stdClass(); $series_obj->name = $station['name']; $series_obj->type = 'spline'; ksort($station_averages[$station_id]); $series_obj->data = array_values($station_averages[$station_id]); $station_metrics[] = $series_obj; } } // Podcast and API Call Metrics $analytics_raw = $influx->setDatabase('pvlive_analytics')->query('SELECT * FROM /1h.*/', 'm'); $raw_metrics = array(); foreach ($analytics_raw as $series_name => $series_stats) { $series_parts = explode('.', $series_name); if ($series_parts[1] == 'api_calls') { $metric_section = 'api'; } else { $metric_section = 'podcast'; } foreach ($series_stats as $stat_row) { if (!isset($raw_metrics[$metric_section][$stat_row['time']])) { $raw_metrics[$metric_section][$stat_row['time']] = 0; } $raw_metrics[$metric_section][$stat_row['time']] += $stat_row['count']; } } // Reformat for highcharts. $refined_metrics = array(); foreach ($raw_metrics as $metric_type => $metric_rows) { ksort($metric_rows); foreach ($metric_rows as $row_timestamp => $row_value) { $refined_metrics[$metric_type][] = array($row_timestamp, $row_value); } } // API call object $series_obj = new \stdClass(); $series_obj->name = 'API Calls'; $series_obj->type = 'spline'; $series_obj->data = $refined_metrics['api']; $api_metrics = array($series_obj); // Podcast object $series_obj = new \stdClass(); $series_obj->name = 'Podcast Clicks'; $series_obj->type = 'spline'; $series_obj->data = $refined_metrics['podcast']; $podcast_metrics = array($series_obj); $metrics = array('network' => json_encode($network_metrics), 'station' => json_encode($station_metrics), 'api' => json_encode($api_metrics), 'podcast' => json_encode($podcast_metrics)); \DF\Cache::save($metrics, 'admin_metrics', array(), 600); } $this->view->metrics = $metrics; // Synchronization statuses if ($this->acl->isAllowed('administer all')) { $this->view->sync_times = \PVL\SyncManager::getSyncTimes(); } // PVLNode service stats. $this->view->pvlnode_stats = \PVL\Service\PvlNode::fetch(); }
public static function fetchArray($cached = true) { $podcasts = \DF\Cache::get('podcasts'); if (!$podcasts || !$cached) { $em = self::getEntityManager(); $podcasts = $em->createQuery('SELECT p FROM ' . __CLASS__ . ' p WHERE p.is_approved = 1 ORDER BY p.name ASC')->getArrayResult(); \DF\Cache::save($podcasts, 'podcasts', array(), 60); } return $podcasts; }
/** * Static Functions */ public static function getAllConventions() { $all_cons = \DF\Cache::get('homepage_conventions'); if (!$all_cons) { $all_cons = array('upcoming' => self::getUpcomingConventions(), 'archived' => self::getConventionsWithArchives()); \DF\Cache::save($all_cons, 'homepage_conventions', array(), 1800); } return $all_cons; }
public static function fetchArray($cached = true) { $stations = \DF\Cache::get('stations'); if (!$stations || !$cached) { $em = self::getEntityManager(); $stations = $em->createQuery('SELECT s, ss FROM ' . __CLASS__ . ' s LEFT JOIN s.streams ss WHERE s.is_active = 1 AND s.category IN (:types) ORDER BY s.category ASC, s.weight ASC')->setParameter('types', array('audio', 'video'))->getArrayResult(); foreach ($stations as &$station) { $station['short_name'] = self::getStationShortName($station['name']); foreach ((array) $station['streams'] as $stream) { if ($stream['is_default']) { $station['default_stream_id'] = $stream['id']; $station['stream_url'] = $stream['stream_url']; } } } \DF\Cache::save($stations, 'stations', array(), 60); } return $stations; }