public function batch_enable() { if (!isset($_REQUEST['episode_asset'])) { return; } $podcast = Model\Podcast::get(); $asset = Model\EpisodeAsset::find_by_id($_REQUEST['episode_asset']); $episodes = Model\Episode::all(); foreach ($episodes as $episode) { $post_id = $episode->post_id; $post = get_post($post_id); // skip deleted podcasts if (!in_array($post->post_status, array('pending', 'draft', 'publish', 'future'))) { continue; } // skip versions if ($post->post_type != 'podcast') { continue; } $file = Model\MediaFile::find_by_episode_id_and_episode_asset_id($episode->id, $asset->id); if ($file === NULL) { $file = new Model\MediaFile(); $file->episode_id = $episode->id; $file->episode_asset_id = $asset->id; $file->save(); } } $this->redirect('index', NULL, array('message' => 'media_file_batch_enabled_notice')); }
private function get_raw_chapters_string() { $asset_assignment = Model\AssetAssignment::get_instance(); $cache_key = 'podlove_chapters_string_' . $this->episode->id; if (($chapters_string = get_transient($cache_key)) !== FALSE) { return $chapters_string; } else { if ($asset_assignment->chapters == 'manual') { return $this->episode->chapters; } else { if (!($chapters_asset = Model\EpisodeAsset::find_one_by_id($asset_assignment->chapters))) { return ''; } if (!($chapters_file = Model\MediaFile::find_by_episode_id_and_episode_asset_id($this->episode->id, $chapters_asset->id))) { return ''; } $chapters_string = wp_remote_get($chapters_file->get_file_url()); if (is_wp_error($chapters_string)) { return ''; } set_transient($cache_key, $chapters_string['body'], 60 * 60 * 24 * 365); // 1 year, we devalidate manually return $chapters_string['body']; } } }
/** * Fetch form data for EpisodeAssets multiselect. * * @param \Podlove\Model\Episode $episode * @return array */ public static function episode_assets_form($episode) { $episode_assets = Model\EpisodeAsset::all(); // field to generate option list $asset_options = array(); // values for option list $asset_values = array(); foreach ($episode_assets as $asset) { if (!($file_type = $asset->file_type())) { continue; } // get formats configured for this show $asset_options[$asset->id] = $asset->title; // find out which formats are active $asset_values[$asset->id] = NULL !== Model\MediaFile::find_by_episode_id_and_episode_asset_id($episode->id, $asset->id); } // FIXME: empty checkbox -> no file id // solution: when one checks the box, an AJAX request has to create and validate the file $episode_assets_form = array('label' => __('Media Files', 'podlove'), 'description' => '', 'options' => $asset_options, 'default' => true, 'multi_values' => $asset_values, 'multiselect_callback' => function ($asset_id) use($episode) { $asset = \Podlove\Model\EpisodeAsset::find_by_id($asset_id); $format = $asset->file_type(); $file = \Podlove\Model\MediaFile::find_by_episode_id_and_episode_asset_id($episode->id, $asset->id); $attributes = array('data-template' => $asset->url_template, 'data-extension' => $format->extension, 'data-size' => is_object($file) ? $file->size : 0, 'data-episode-asset-id' => $asset->id, 'data-episode-id' => $episode->id); if ($file) { $attributes['data-id'] = $file->id; } $out = ''; foreach ($attributes as $key => $value) { $out .= sprintf('%s="%s" ', $key, $value); } return $out; }); if (empty($asset_options)) { $episode_assets_form['description'] = sprintf('<span style="color: red">%s</span>', __('You need to configure feeds for this show. No feeds, no fun.', 'podlove')) . ' ' . sprintf('<a href="%s">%s</a>', admin_url('admin.php?page=podlove_shows_settings_handle&action=edit&show=' . $show->id), __('Edit this show', 'podlove')); } return $episode_assets_form; }
/** * Get playable files for player, based on episode and player assignments. * * @param array $formats array of formats like mp3, mp3, ogg, opus, webm * @param string $media_type audio or video * @return array of \Podlove\Model\MediaFile */ private function get_playable_files($formats, $media_type) { $playable_files = array(); foreach ($formats as $format) { if (!isset($this->player_format_assignments[$media_type][$format])) { continue; } $episode_asset = EpisodeAsset::find_by_id($this->player_format_assignments[$media_type][$format]); if (!$episode_asset) { continue; } $media_file = MediaFile::find_by_episode_id_and_episode_asset_id($this->episode->id, $episode_asset->id); if ($media_file && $media_file->is_valid()) { $playable_files[] = $media_file; } } return $playable_files; }
public function refetch_files() { $valid_files = array(); foreach (EpisodeAsset::all() as $asset) { if ($file = MediaFile::find_by_episode_id_and_episode_asset_id($this->id, $asset->id)) { $file->determine_file_size(); $file->save(); if ($file->is_valid()) { $valid_files[] = $file->id; } } } if (empty($valid_files) && get_post_status($this->post_id) == 'publish') { Log::get()->addAlert('All assets for this episode are invalid!', array('episode_id' => $this->id)); } }
/** * Fetch form data for EpisodeAssets multiselect. * * @param \Podlove\Model\Episode $episode * @return array */ public static function episode_assets_form($episode) { $episode_assets = Model\EpisodeAsset::all(); // field to generate option list $asset_options = array(); // values for option list $asset_values = array(); foreach ($episode_assets as $asset) { if (!($file_type = $asset->file_type())) { continue; } // get formats configured for this show $asset_options[$asset->id] = $asset->title; // find out which formats are active $asset_values[$asset->id] = NULL !== Model\MediaFile::find_by_episode_id_and_episode_asset_id($episode->id, $asset->id); } // FIXME: empty checkbox -> no file id // solution: when one checks the box, an AJAX request has to create and validate the file $episode_assets_form = array('label' => __('Media Files', 'podlove'), 'description' => '', 'options' => $asset_options, 'default' => true, 'multi_values' => $asset_values, 'before' => function () { ?> <table class='media_file_table' border="0" cellspacing="0"> <tr> <th><?php echo __('Enable', 'podlove'); ?> </th> <th><?php echo __('Asset', 'podlove'); ?> </th> <th><?php echo __('Asset File Name', 'podlove'); ?> </th> <th><?php echo __('Filesize', 'podlove'); ?> </th> <th><?php echo __('Status', 'podlove'); ?> </th> <th></th> </tr> <?php }, 'after' => function () { ?> </table> <p> <span class="description"> <?php echo __('Media File Base URL', 'podlove') . ': ' . \Podlove\Model\Podcast::get()->media_file_base_uri; ?> </span> </p> <?php }, 'around_each' => function ($callback) { ?> <tr class="media_file_row"> <td class="enable"> </td> <td class="asset"> <?php call_user_func($callback); ?> </td> <td class="url"></td> <td class="size"></td> <td class="status"></td> <td class="update"></td> </tr> <?php }, 'multiselect_callback' => function ($asset_id) use($episode) { $asset = \Podlove\Model\EpisodeAsset::find_by_id($asset_id); $format = $asset->file_type(); $file = \Podlove\Model\MediaFile::find_by_episode_id_and_episode_asset_id($episode->id, $asset->id); $size = is_object($file) ? (int) $file->size : 0; if ($size === 1) { $size = "unknown"; } $attributes = array('data-template' => \Podlove\Model\Podcast::get()->get_url_template(), 'data-size' => $size, 'data-episode-asset-id' => $asset->id, 'data-episode-id' => $episode->id, 'data-file-url' => is_object($file) ? $file->get_file_url() : ''); if ($file) { $attributes['data-id'] = $file->id; } $out = ''; foreach ($attributes as $key => $value) { $out .= sprintf('%s="%s" ', $key, $value); } return $out; }); if (empty($asset_options)) { $episode_assets_form['description'] = sprintf('<span style="color: red">%s</span>', __('You need to configure assets for this show. No assets, no fun.', 'podlove')) . ' ' . sprintf('<a href="%s">%s</a>', admin_url('admin.php?page=podlove_episode_assets_settings_handle'), __('Configure Assets', 'podlove')); } return $episode_assets_form; }
/** * Provides shortcode to display web player. * * Right now there is only audio support. * * Usage: * [podlove-web-player] * * @param array $options * @return string */ function webplayer_shortcode($options) { global $post; $episode = Model\Episode::find_or_create_by_post_id($post->ID); $podcast = Model\Podcast::get_instance(); $formats_data = get_option('podlove_webplayer_formats'); if (!count($formats_data)) { return; } $available_formats = array(); $audio_formats = array('mp3', 'mp4', 'ogg'); foreach ($audio_formats as $audio_format) { $episode_asset = Model\EpisodeAsset::find_by_id($formats_data['audio'][$audio_format]); if (!$episode_asset) { continue; } $media_file = Model\MediaFile::find_by_episode_id_and_episode_asset_id($episode->id, $episode_asset->id); if ($media_file) { $available_formats[] = sprintf('%s="%s"', $audio_format, $media_file->get_file_url()); } } $chapters = ''; if ($episode->chapters) { $chapters = 'chapters="_podlove_chapters"'; } return do_shortcode('[podloveaudio ' . implode(' ', $available_formats) . ' ' . $chapters . ']'); }
/** * Get playable files for player, based on episode and player assignments. * * @param array $formats array of formats like mp3, mp3, ogg, opus, webm * @param string $media_type audio or video * @return array of \Podlove\Model\MediaFile */ private function get_playable_files($formats, $media_type) { $playable_files = []; $player_format_assignments = get_option('podlove_webplayer_formats'); if (empty($player_format_assignments)) { error_log(print_r("Podlove Web Player: No assets are assigned.", true)); return []; } foreach ($formats as $format) { if (!isset($player_format_assignments[$media_type][$format])) { continue; } $episode_asset = EpisodeAsset::find_by_id($player_format_assignments[$media_type][$format]); if (!$episode_asset) { continue; } $media_file = MediaFile::find_by_episode_id_and_episode_asset_id($this->episode->id, $episode_asset->id); if ($media_file && $media_file->is_valid()) { $playable_files[] = $media_file; } } return $playable_files; }
function override_feed_entry($hook, $podcast, $feed, $format) { add_action($hook, function () use($podcast, $feed, $format) { global $post; $cache = \Podlove\Cache\TemplateCache::get_instance(); echo $cache->cache_for('feed_item_' . $feed->slug . '_' . $post->ID, function () use($podcast, $feed, $format, $post) { $xml = ""; $episode = Model\Episode::find_one_by_post_id($post->ID); $asset = $feed->episode_asset(); $file = Model\MediaFile::find_by_episode_id_and_episode_asset_id($episode->id, $asset->id); $asset_assignment = Model\AssetAssignment::get_instance(); if (!$file) { return; } $enclosure_file_size = $file->size; $cover_art_url = ""; if ($cover_art = $episode->cover_art()) { $cover_art_url = $cover_art->url(); } if (isset($_REQUEST['tracking']) && $_REQUEST['tracking'] == 'no') { $enclosure_url = $episode->enclosure_url($feed->episode_asset(), null, null); } else { $enclosure_url = $episode->enclosure_url($feed->episode_asset(), "feed", $feed->slug); } $deep_link = Model\Feed::get_link_tag(array('prefix' => 'atom', 'rel' => 'http://podlove.org/deep-link', 'type' => '', 'title' => '', 'href' => get_permalink() . "#")); $xml .= apply_filters('podlove_deep_link', $deep_link, $feed); $xml .= apply_filters('podlove_feed_enclosure', '', $enclosure_url, $enclosure_file_size, $format->mime_type, $file); $duration = sprintf('<itunes:duration>%s</itunes:duration>', $episode->get_duration('HH:MM:SS')); $xml .= apply_filters('podlove_feed_itunes_duration', $duration); $author = apply_filters('podlove_feed_content', $podcast->author_name); $author = sprintf('<itunes:author>%s</itunes:author>', $author); $xml .= apply_filters('podlove_feed_itunes_author', $author); $subtitle = apply_filters('podlove_feed_content', \Podlove\PHP\escape_shortcodes(strip_tags($episode->subtitle))); $subtitle = sprintf('<itunes:subtitle>%s</itunes:subtitle>', $subtitle); $xml .= apply_filters('podlove_feed_itunes_subtitle', $subtitle); $summary = apply_filters('podlove_feed_content', \Podlove\PHP\escape_shortcodes(strip_tags($episode->summary))); $summary = sprintf('<itunes:summary>%s</itunes:summary>', $summary); $xml .= apply_filters('podlove_feed_itunes_summary', $summary); if (\Podlove\get_setting('metadata', 'enable_episode_explicit')) { $itunes_explicit = apply_filters('podlove_feed_content', $episode->explicit_text()); $itunes_explicit = sprintf('<itunes:explicit>%s</itunes:explicit>', $itunes_explicit); $xml .= apply_filters('podlove_feed_itunes_explicit', $itunes_explicit); } if ($cover_art_url) { $cover_art = sprintf('<itunes:image href="%s" />', $cover_art_url); } else { $cover_art = ''; } $xml .= apply_filters('podlove_feed_itunes_image', $cover_art); if ($feed->embed_content_encoded) { add_filter('the_content_feed', function ($content, $feed_type) { return preg_replace('#<style(.*?)>(.*?)</style>#is', '', $content); }, 10, 2); $content_encoded = '<content:encoded><![CDATA[' . get_the_content_feed('rss2') . ']]></content:encoded>'; $xml .= apply_filters('podlove_feed_content_encoded', $content_encoded); } ob_start(); do_action('podlove_append_to_feed_entry', $podcast, $episode, $feed, $format); $xml .= ob_get_contents(); ob_end_clean(); return $xml; }, 15 * MINUTE_IN_SECONDS); }, 11); }
function override_feed_entry($hook, $podcast, $feed, $format) { add_action($hook, function () use($podcast, $feed, $format) { global $post; $episode = \Podlove\Model\Episode::find_one_by_post_id($post->ID); $asset = $feed->episode_asset(); $file = \Podlove\Model\MediaFile::find_by_episode_id_and_episode_asset_id($episode->id, $asset->id); if (!$file) { return; } $enclosure_duration = $episode->duration; $enclosure_file_size = $file->size; $file_slug = $episode->slug; $cover_art_url = $episode->get_cover_art(); // fall back to podcast cover image if (!$cover_art_url) { $cover_art_url = $podcast->cover_image; } $enclosure_url = $episode->enclosure_url($feed->episode_asset()); echo apply_filters('podlove_feed_enclosure', '', $enclosure_url, $enclosure_file_size, $format->mime_type); $duration = sprintf('<itunes:duration>%s</itunes:duration>', $enclosure_duration); echo apply_filters('podlove_feed_itunes_duration', $duration); $author = sprintf('<itunes:author>%s</itunes:author>', $podcast->author_name); echo apply_filters('podlove_feed_itunes_author', $author); $subtitle = sprintf('<itunes:subtitle>%s</itunes:subtitle>', htmlspecialchars(strip_tags($episode->subtitle))); echo apply_filters('podlove_feed_itunes_subtitle', $subtitle); $summary = sprintf('<itunes:summary>%s</itunes:summary>', htmlspecialchars(strip_tags($episode->summary))); echo apply_filters('podlove_feed_itunes_summary', $summary); if ($cover_art_url) { $cover_art = sprintf('<itunes:image href="%s" />', $cover_art_url); } else { $cover_art = ''; } echo apply_filters('podlove_feed_itunes_image', $cover_art); }); }