public function register_page()
    {
        $podcast = \Podlove\Model\Podcast::get();
        $form_attributes = array('context' => 'podlove_podcast', 'action' => $this->get_url());
        ?>
		<p>
			<?php 
        echo __('You may provide additional information about your podcast that may or may not be used by podcast directories like iTunes.', 'podlove');
        ?>
		</p>
		<?php 
        \Podlove\Form\build_for($podcast, $form_attributes, function ($form) {
            $wrapper = new \Podlove\Form\Input\TableWrapper($form);
            $podcast = $form->object;
            $wrapper->string('author_name', array('label' => __('Author Name', 'podlove'), 'description' => __('Publicly displayed in Podcast directories.', 'podlove'), 'html' => array('class' => 'regular-text podlove-check-input')));
            $wrapper->string('publisher_name', array('label' => __('Publisher Name', 'podlove'), 'description' => __('', 'podlove'), 'html' => array('class' => 'regular-text podlove-check-input')));
            $wrapper->string('publisher_url', array('label' => __('Publisher URL', 'podlove'), 'description' => __('', 'podlove'), 'html' => array('class' => 'regular-text podlove-check-input', 'data-podlove-input-type' => 'url')));
            $wrapper->string('owner_name', array('label' => __('Owner Name', 'podlove'), 'description' => __('Used by iTunes and other Podcast directories to contact you.', 'podlove'), 'html' => array('class' => 'regular-text podlove-check-input')));
            $wrapper->string('owner_email', array('label' => __('Owner Email', 'podlove'), 'description' => __('Used by iTunes and other Podcast directories to contact you.', 'podlove'), 'html' => array('class' => 'regular-text podlove-check-input', 'data-podlove-input-type' => 'email')));
            $wrapper->string('keywords', array('label' => __('Keywords', 'podlove'), 'description' => __('List of keywords. Separate with commas.', 'podlove'), 'html' => array('class' => 'regular-text podlove-check-input')));
            $wrapper->select('category_1', array('label' => __('iTunes Categories', 'podlove'), 'description' => '', 'type' => 'select', 'options' => \Podlove\Itunes\categories()));
            $wrapper->select('category_2', array('label' => '', 'description' => '', 'type' => 'select', 'options' => \Podlove\Itunes\categories()));
            $wrapper->select('category_3', array('label' => '', 'description' => '<br>' . __('For placement within the older, text-based browse system, podcast feeds may list up to 3 category/subcategory pairs. (For example, "Music" counts as 1, as does "Business > Careers.") For placement within the newer browse system based on Category links, however, and for placement within the Top Podcasts and Top Episodes lists that appear in the right column of most podcast pages, only the first category listed in the feed is used.') . ' (<a href="http://www.apple.com/itunes/podcasts/specs.html#category" target="_blank">http://www.apple.com/itunes/podcasts/specs.html#category</a>)', 'options' => \Podlove\Itunes\categories()));
            $wrapper->select('explicit', array('label' => __('Explicit Content?', 'podlove'), 'description' => __('', 'podlove'), 'type' => 'checkbox', 'options' => array(0 => 'no', 1 => 'yes', 2 => 'clean')));
            $wrapper->checkbox('complete', array('label' => __('Podcast complete?', 'podlove'), 'description' => __('Shows that this Podcast is finished and no further episodes will be added.', 'podlove'), 'default' => false));
        });
    }
function override_feed_language($feed)
{
    add_filter('pre_option_rss_language', function ($language) use($feed) {
        $podcast = Model\Podcast::get();
        return apply_filters('podlove_feed_language', $podcast->language ? $podcast->language : $language);
    });
}
 /**
  * Insert HTML meta tags into site head.
  */
 public function insert_twitter_card_metadata()
 {
     $post_id = get_the_ID();
     if (!$post_id) {
         return;
     }
     $episode = \Podlove\Model\Episode::find_one_by_post_id($post_id);
     if (!$episode) {
         return;
     }
     $podcast = Model\Podcast::get();
     $cover_art_url = $episode->cover_art_with_fallback()->url();
     // define meta tags
     $data = array(array('name' => 'twitter:card', 'content' => 'summary'), array('name' => 'twitter:url', 'content' => get_permalink()), array('name' => 'twitter:title', 'content' => get_the_title()), array('name' => 'twitter:description', 'content' => $episode->description()));
     if ($site = $this->get_module_option('site')) {
         $data[] = array('name' => 'twitter:site', 'content' => $site);
     }
     if ($creator = $this->get_module_option('creator')) {
         $data[] = array('name' => 'twitter:creator', 'content' => $creator);
     }
     if ($cover_art_url) {
         $data[] = array('name' => 'twitter:image', 'content' => $cover_art_url);
     }
     // print meta tags
     $dom = new DomDocumentFragment();
     foreach ($data as $meta_element) {
         $element = $dom->createElement('meta');
         foreach ($meta_element as $attribute => $value) {
             $element->setAttribute($attribute, $value);
         }
         $dom->appendChild($element);
     }
     echo $dom;
 }
    public function register_page()
    {
        $podcast = \Podlove\Model\Podcast::get();
        $form_attributes = array('context' => 'podlove_flattr', 'action' => $this->get_url());
        ?>
		<p>
			<?php 
        echo __('This Flattr account will be associated with your Podcast. Flattr donations for e.g. new episodes
							will be linked with this account.', 'podlove');
        ?>
		</p>
		<style type="text/css">
		/* add linebreak after each radio button+label */
		input[type="radio"] + label::after {
		  content: " ";
		  display: block;
		}
		</style>
		<?php 
        \Podlove\Form\build_for((object) Flattr::get_setting(), $form_attributes, function ($form) {
            $wrapper = new \Podlove\Form\Input\TableWrapper($form);
            $podcast = $form->object;
            $wrapper->string('account', ['label' => __('Flattr Account', 'podlove'), 'html' => ['class' => 'regular-text required podlove-check-input']]);
            if (\Podlove\Modules\Base::is_active('contributors')) {
                $wrapper->radio('contributor_shortcode_default', ['label' => __('Default Parameter in Contributors Shortcodes', 'podlove'), 'description' => '<br>' . __('You can override this setting individually by passing along the <code>flattr="yes"</code> or <code>flattr="no"</code> parameter to the shortcodes.', 'podlove'), 'options' => ['yes' => 'yes, show Flattr buttons by default', 'no' => 'no, do not show Flattr buttons by default'], 'default' => 'no']);
            }
        });
    }
 /**
  * Insert HTML meta tags into site head.
  *
  * @todo  caching
  * @todo  let user choose what's in og:description: subtitle, excerpt, ...
  * @todo  handle multiple releases per episode
  */
 public static function get_open_graph_metadata()
 {
     $post_id = get_the_ID();
     if (!$post_id) {
         return;
     }
     $episode = \Podlove\Model\Episode::find_one_by_post_id($post_id);
     if (!$episode) {
         return;
     }
     $podcast = Model\Podcast::get();
     $cover_art_url = $episode->cover_art_with_fallback()->url();
     // determine featured image (thumbnail)
     $thumbnail = NULL;
     if (has_post_thumbnail()) {
         $post_thumbnail_id = get_post_thumbnail_id($post_id);
         $thumbnailInfo = wp_get_attachment_image_src($post_thumbnail_id);
         if (is_array($thumbnailInfo)) {
             list($thumbnail, $width, $height) = $thumbnailInfo;
         }
     }
     $description = NULL;
     if ($episode->summary && $episode->subtitle) {
         $description = $episode->subtitle . "\n" . $episode->summary;
     } elseif ($episode->summary) {
         $description = $episode->summary;
     } elseif ($episode->subtitle) {
         $description = $episode->subtitle;
     }
     // define meta tags
     $data = array(array('property' => 'og:type', 'content' => 'website'), array('property' => 'og:site_name', 'content' => $podcast->title ? $podcast->title : get_the_title()), array('property' => 'og:title', 'content' => get_the_title()), array('property' => 'og:url', 'content' => get_permalink()));
     if ($description) {
         $data[] = array('property' => 'og:description', 'content' => $description);
     }
     if ($cover_art_url) {
         $data[] = array('property' => 'og:image', 'content' => $cover_art_url);
     }
     if (isset($thumbnail)) {
         $data[] = array('property' => 'og:image', 'content' => $thumbnail);
     }
     foreach ($episode->media_files() as $media_file) {
         $mime_type = $media_file->episode_asset()->file_type()->mime_type;
         if (stripos($mime_type, 'audio') !== false) {
             $data[] = array('property' => 'og:audio', 'content' => $media_file->get_file_url());
             $data[] = array('property' => 'og:audio:type', 'content' => $mime_type);
         }
     }
     // print meta tags
     $dom = new DomDocumentFragment();
     foreach ($data as $meta_element) {
         $element = $dom->createElement('meta');
         foreach ($meta_element as $attribute => $value) {
             $element->setAttribute($attribute, $value);
         }
         $dom->appendChild($element);
     }
     return $dom;
 }
 public function widget($args, $instance)
 {
     $podcast = \Podlove\Model\Podcast::get();
     echo $args['before_widget'];
     if (!empty($instance['title'])) {
         echo $args['before_title'] . apply_filters('widget_title', $instance['title']) . $args['after_title'];
     }
     echo $podcast->get_license_html();
     echo $args['after_widget'];
 }
 public function widget($args, $instance)
 {
     $podcast = \Podlove\Model\Podcast::get();
     echo $args['before_widget'];
     if (!empty($instance['title'])) {
         echo $args['before_title'] . apply_filters('widget_title', $instance['title']) . $args['after_title'];
     }
     echo do_shortcode('[podlove-template template="' . $instance['template'] . '" autop="' . ($instance['autop'] ? 'yes' : 'no') . '"]');
     echo $args['after_widget'];
 }
 /**
  * Apply Twig to given template
  * 
  * @param  string $html File path or HTML string.
  * @param  array  $vars optional variables for Twig context
  * @return string       rendered template string
  */
 public static function apply_to_html($html, $vars = array())
 {
     // file loader for internal use
     $file_loader = new \Twig_Loader_Filesystem();
     $file_loader->addPath(implode(DIRECTORY_SEPARATOR, array(\Podlove\PLUGIN_DIR, 'templates')), 'core');
     // other modules can register their own template directories/namespaces
     $file_loader = apply_filters('podlove_twig_file_loader', $file_loader);
     // database loader for user templates
     $db_loader = new TwigLoaderPodloveDatabase();
     $loaders = array($file_loader, $db_loader);
     $loaders = apply_filters('podlove_twig_loaders', $loaders);
     $loader = new \Twig_Loader_Chain($loaders);
     $twig = new \Twig_Environment($loader, array('autoescape' => false));
     $twig->addExtension(new \Twig_Extensions_Extension_I18n());
     $twig->addExtension(new \Twig_Extensions_Extension_Date());
     $formatBytesFilter = new \Twig_SimpleFilter('formatBytes', function ($string) {
         return \Podlove\format_bytes($string, 0);
     });
     $padLeftFilter = new \Twig_SimpleFilter('padLeft', function ($string, $padChar, $length) {
         while (strlen($string) < $length) {
             $string = $padChar . $string;
         }
         return $string;
     });
     $twig->addFilter($formatBytesFilter);
     $twig->addFilter($padLeftFilter);
     // add functions
     foreach (self::$template_tags as $tag) {
         $func = new \Twig_SimpleFunction($tag, function () use($tag) {
             return $tag();
         });
         $twig->addFunction($func);
     }
     $context = ['option' => $vars];
     // add podcast to global context
     $context = array_merge($context, ['podcast' => new Podcast(Model\Podcast::get())]);
     // Apply filters to twig templates
     $context = apply_filters('podlove_templates_global_context', $context);
     // add podcast to global context if we are in an episode
     if ($episode = Model\Episode::find_one_by_property('post_id', get_the_ID())) {
         $context = array_merge($context, array('episode' => new Episode($episode)));
     }
     try {
         return $twig->render($html, $context);
     } catch (\Twig_Error $e) {
         $message = $e->getRawMessage();
         $line = $e->getTemplateLine();
         $template = $e->getTemplateFile();
         \Podlove\Log::get()->addError($message, ['type' => 'twig', 'line' => $line, 'template' => $template]);
     }
     return "";
 }
 /**
  * Fetch all Pocasts in the current list
  */
 public function podcasts()
 {
     $podcasts = json_decode($this->podcasts);
     $podcast_objects = array();
     foreach ($podcasts as $podcast) {
         switch ($podcast->type) {
             default:
             case 'wplist':
                 $podcast_objects[] = Podcast::get($podcast->podcast);
                 break;
         }
     }
     return $podcast_objects;
 }
 public function get_current_episode($post_id)
 {
     if (get_post_status($post_id) !== 'publish' || get_post_type($post_id) !== 'podcast') {
         // If post is not public, 404 will be replied
         status_header(404);
         return;
     }
     $episode = \Podlove\Model\Episode::find_one_by_post_id($post_id);
     $podcast = \Podlove\Model\Podcast::get();
     $permalink = get_permalink($post_id);
     $player_width = "560px";
     $player_height = "140px";
     return array('version' => '1.0', 'type' => 'rich', 'width' => $player_width, 'height' => $player_height, 'title' => $episode->full_title(), 'url' => get_permalink($post_id), 'author_name' => $podcast->full_title(), 'author_url' => site_url(), 'thumbnail_url' => $episode->cover_art_with_fallback()->url(), 'html' => '<iframe width="' . $player_width . '" height="' . $player_height . '" src="' . $permalink . (strpos($permalink, '?') === FALSE ? "?" : "&amp;") . 'standalonePlayer"></iframe>');
 }
 public function getHtml()
 {
     if ($this->type == 'cc') {
         return "\n\t\t\t<div class=\"podlove_cc_license\">\n\t\t\t\t<img src=\"" . $this->getPictureUrl() . "\" alt=\"License\" />\n\t\t\t\t<p>\n\t\t\t\t\tThis work is licensed under a <a rel=\"license\" href=\"" . $this->getUrl() . "\">" . $this->getName() . "</a>.\n\t\t\t\t</p>\n\t\t\t</div>";
     }
     if ($this->type == 'other') {
         return "\n\t\t\t<div class=\"podlove_license\">\n\t\t\t\t<p>\n\t\t\t\t\t" . sprintf(__('This work is licensed under the %s license.', 'podlove'), '<a rel="license" href="' . $this->url . '">' . $this->name . '</a>') . "\n\t\t\t\t</p>\n\t\t\t</div>";
     }
     // episodes fall back to podcast licenses
     if ($this->scope == 'episode') {
         return Podcast::get()->get_license_html();
     }
     // ... otherwise, a license is missing
     return "\n\t\t<div class=\"podlove_license\">\n\t\t\t\t<p style='color: red;'>\n\t\t\t\t\t" . __('This work is (not yet) licensed, as no license was chosen.', 'podlove') . "\n\t\t\t\t</p>\n\t\t</div>";
 }
    public function register_page()
    {
        $podcast = \Podlove\Model\Podcast::get();
        $form_attributes = array('context' => 'podlove_podcast', 'action' => $this->get_url(), 'is_table' => false);
        ?>
		<p>
			<?php 
        echo sprintf(__('These are the current social media acccount of your podcast. Display this list using the shortcode %s', 'podlove'), '<code>[podlove-podcast-social-media-list]</code>');
        ?>
		</p>
		<?php 
        \Podlove\Form\build_for($podcast, $form_attributes, function ($form) {
            $wrapper = new \Podlove\Form\Input\DivWrapper($form);
            $podcast = $form->object;
            $wrapper->callback('services', array('callback' => array(__CLASS__, 'podcast_form_extension_form')));
        });
    }
 /**
  * Fetch all podcasts for Publisher blogs, ordered
  */
 public static function podcasts($sortby = "title", $sort = 'ASC')
 {
     $podcast_blog_ids = Network::podcast_blog_ids();
     if (empty($podcast_blog_ids)) {
         return [];
     }
     foreach ($podcast_blog_ids as $blog_id) {
         $podcasts[$blog_id] = Podcast::get($blog_id);
     }
     uasort($podcasts, function ($a, $b) use($sortby, $sort) {
         return strnatcmp($a->{$sortby}, $b->{$sortby});
     });
     if ($sort == 'DESC') {
         krsort($podcasts);
     }
     return $podcasts;
 }
 public function column_limit($feed)
 {
     // FIXME: Feeds verschwinden beim Speichern!!!
     $podlove_feed_limit = \Podlove\Model\Podcast::get()->limit_items;
     switch ($feed->limit_items) {
         case '0':
             return get_option('posts_per_rss') . ' (WordPress default)';
             break;
         case '-1':
             return 'unlimited';
             break;
         case '-2':
             return ($podlove_feed_limit == '-1' ? 'unlimited' : ($podlove_feed_limit == '0' ? get_option('posts_per_rss') . ' (WordPress default)' : $podlove_feed_limit)) . ' (global default)';
             break;
         default:
             return $feed->limit_items;
             break;
     }
 }
    public function register_page()
    {
        $podcast = \Podlove\Model\Podcast::get();
        $form_attributes = array('context' => 'podlove_podcast', 'action' => $this->get_url());
        ?>
		<p>
			<?php 
        echo __('The Podlove Publisher expects all your media files to be in the same <strong>Upload Location</strong>.
					It should be a publicly readable directory containing all media files.
					You should not create a separate directory for each episode.', 'podlove');
        ?>
		</p>
		<?php 
        \Podlove\Form\build_for($podcast, $form_attributes, function ($form) {
            $wrapper = new \Podlove\Form\Input\TableWrapper($form);
            $podcast = $form->object;
            $wrapper->string('media_file_base_uri', array('label' => __('Upload Location', 'podlove'), 'description' => __('Example: http://cdn.example.com/pod/', 'podlove'), 'html' => array('class' => 'regular-text required podlove-check-input', 'data-podlove-input-type' => 'url')));
        });
    }
/**
 * Adds feed discover links to WordPress head.
 */
function podlove_add_feed_discoverability()
{
    if (is_admin()) {
        return;
    }
    if (!function_exists('\\Podlove\\Feeds\\prepare_for_feed')) {
        require_once \Podlove\PLUGIN_DIR . 'lib/feeds/base.php';
    }
    $cache = \Podlove\Cache\TemplateCache::get_instance();
    echo $cache->cache_for('feed_discoverability', function () {
        $feeds = \Podlove\Model\Podcast::get()->feeds();
        $html = '';
        foreach ($feeds as $feed) {
            if ($feed->discoverable) {
                $html .= '<link rel="alternate" type="' . $feed->get_content_type() . '" title="' . \Podlove\Feeds\prepare_for_feed($feed->title_for_discovery()) . '" href="' . $feed->get_subscribe_url() . "\" />\n";
            }
        }
        return $html;
    });
}
    private static function get_styles()
    {
        ob_start();
        $podcast_ids = self::podcast_ids();
        $podcast_ids = array_filter($podcast_ids, function ($id) {
            return Podcast::get($id)->has_cover_art();
        });
        $blavatar_classes = implode(", ", array_map(function ($id) {
            return "#wp-admin-bar-blog-{$id} .blavatar";
        }, $podcast_ids));
        $blavatar_before_classes = implode(", ", array_map(function ($id) {
            return "#wpadminbar .quicklinks li#wp-admin-bar-blog-{$id} .blavatar:before";
        }, $podcast_ids));
        $cover_styles = implode("\n", array_map(function ($id) {
            return "#wp-admin-bar-blog-{$id} .blavatar { background-image: url(" . Podcast::get($id)->cover_art()->setWidth(40)->url() . "); }";
        }, $podcast_ids));
        echo $cover_styles;
        echo $blavatar_classes;
        ?>
 {
	background-size: 100% 100%;
	margin-right: 5px;
	width: 20px;
	height: 20px;
	position: relative;
	top: 4px;
	left: -3px;
}

<?php 
        echo $blavatar_before_classes;
        ?>
 {
	content: none;
}
		<?php 
        $html = ob_get_contents();
        ob_end_clean();
        return $html;
    }
 public static function content()
 {
     global $wpdb;
     $sql = "\n\t\tSELECT\n\t\t\tp.post_status,\n\t\t\tmf.episode_id,\n\t\t\tmf.episode_asset_id,\n\t\t\tmf.size,\n\t\t\tmf.id media_file_id\n\t\tFROM\n\t\t\t`" . Model\MediaFile::table_name() . "` mf\n\t\t\tJOIN `" . Model\Episode::table_name() . "` e ON e.id = mf.`episode_id`\n\t\t\tJOIN `" . $wpdb->posts . "` p ON e.`post_id` = p.`ID`\n\t\tWHERE\n\t\t\tp.`post_type` = 'podcast'\n\t\t\tAND p.post_status in ('private', 'draft', 'publish', 'pending', 'future')\n\t\t";
     $rows = $wpdb->get_results($sql, ARRAY_A);
     $media_files = [];
     foreach ($rows as $row) {
         if (!isset($media_files[$row['episode_id']])) {
             $media_files[$row['episode_id']] = ['post_status' => $row["post_status"]];
         }
         $media_files[$row['episode_id']][$row['episode_asset_id']] = ['size' => $row['size'], 'media_file_id' => $row['media_file_id']];
     }
     $podcast = Model\Podcast::get();
     $episodes = $podcast->episodes();
     $assets = Model\EpisodeAsset::all();
     $header = [__('Episode', 'podlove')];
     foreach ($assets as $asset) {
         $header[] = $asset->title;
     }
     $header[] = __('Status', 'podlove');
     \Podlove\load_template('settings/dashboard/file_validation', ['episodes' => $episodes, 'assets' => $assets, 'media_files' => $media_files, 'header' => $header]);
 }
    public function register_page()
    {
        $podcast = \Podlove\Model\Podcast::get();
        $form_attributes = array('context' => 'podlove_podcast', 'action' => $this->get_url());
        ?>
		<p>
			<?php 
        echo __('These are the three most important fields describing your podcast.
					<strong>Title</strong> is the title of the podcast that is the primary field to be used to represent the podcast in directories, lists and other uses.
					The <strong>subtitle</strong> is an extension to the title. The subtitle is meant to clarify what the podcast is about. While a title can be anything, a subtitle should be more descriptive in what the content actually wants to convey and what the most important information is, you want everybody want to know about the offering.
					A <strong>summary</strong> is a much more precise and elaborate description of the podcast\'s content. While title and subtitle are rather concise, a summary is meant to consist of one or more sentences that form a paragraph or more.', 'podlove');
        ?>
		</p>
		<?php 
        \Podlove\Form\build_for($podcast, $form_attributes, function ($form) {
            $wrapper = new \Podlove\Form\Input\TableWrapper($form);
            $podcast = $form->object;
            $wrapper->string('title', array('label' => __('Title', 'podlove'), 'html' => array('class' => 'regular-text required podlove-check-input')));
            $wrapper->string('subtitle', array('label' => __('Subtitle', 'podlove'), 'description' => __('Extension to the title. Clarify what the podcast is about.', 'podlove'), 'html' => array('class' => 'regular-text podlove-check-input')));
            $wrapper->text('summary', array('label' => __('Summary', 'podlove'), 'description' => __('Elaborate description of the podcast\'s content.', 'podlove'), 'html' => array('rows' => 3, 'cols' => 40, 'class' => 'autogrow podlove-check-input')));
            $wrapper->upload('cover_image', array('label' => __('Cover Art URL', 'podlove'), 'description' => __('JPEG or PNG. At least 1400 x 1400 pixels.', 'podlove'), 'html' => array('class' => 'regular-text podlove-check-input', 'data-podlove-input-type' => 'url'), 'media_button_text' => __("Use for Podcast Cover Art", 'podlove')));
            $wrapper->select('language', array('label' => __('Language', 'podlove'), 'description' => __('', 'podlove'), 'default' => get_bloginfo('language'), 'options' => \Podlove\Locale\locales()));
        });
    }
 /**
  * Podcast
  * 
  * @accessor
  */
 public function podcast()
 {
     return new \Podlove\Template\Podcast(\Podlove\Model\Podcast::get($this->episode->get_blog_id()));
 }
 /**
  * Render player
  * 
  * @param  string $context (optional) player context for tracking. Set to NULL for auto-detection. Default: NULL
  * @return string
  */
 public function render($context = NULL)
 {
     if (count($this->player_format_assignments) == 0) {
         return '';
     }
     // build main audio/video tag
     $xml = new \SimpleXMLElement('<' . $this->get_media_tag() . '/>');
     $xml->addAttribute('id', $this->get_html_id());
     $xml->addAttribute('controls', 'controls');
     $xml->addAttribute('preload', 'none');
     $width = strtolower(trim($this->get_webplayer_setting($this->get_media_tag(), 'width')));
     $height = strtolower(trim($this->get_webplayer_setting($this->get_media_tag(), 'height')));
     if ($this->is_video) {
         $xml->addAttribute('poster', $this->episode->cover_art_with_fallback()->url());
         $xml->addAttribute('width', $width);
         $xml->addAttribute('height', $height);
     } else {
         $xml->addAttribute('style', sprintf('width: %s; height: %s', empty($width) || $width == 'auto' ? '100%' : $width . 'px', empty($height) ? '30px' : $height));
     }
     // get all relevant info about media files
     $media_files = array();
     foreach ($this->files as $file) {
         $asset = $file->episode_asset();
         $mime = $asset->file_type()->mime_type;
         $media_files[$mime] = array('file' => $file, 'mime_type' => $mime, 'url' => $file->get_file_url(), 'publicUrl' => $file->get_public_file_url("webplayer", is_null($context) ? $this->get_tracking_context() : $context), 'assetTitle' => $asset->title());
     }
     if (!count($media_files)) {
         return "";
     }
     // sort files bases on mime type so preferred get output first
     $sorted_files = array();
     $preferred_order = array('audio/mp4', 'audio/aac', 'audio/opus', 'audio/ogg', 'audio/vorbis');
     foreach ($preferred_order as $order_key) {
         if (isset($media_files[$order_key]) && $media_files[$order_key]) {
             $sorted_files[] = $media_files[$order_key];
             unset($media_files[$order_key]);
         }
     }
     foreach ($media_files as $file) {
         $sorted_files[] = $file;
     }
     // add all sources
     $flash_fallback_func = function (&$xml) {
     };
     foreach ($sorted_files as $file) {
         $mime_type = $file['mime_type'];
         $source = $xml->addChild('source');
         $source->addAttribute('src', $file['publicUrl']);
         $source->addAttribute('type', $mime_type);
         if ($mime_type == 'audio/mpeg') {
             $flash_fallback_func = function (&$xml) use($file) {
                 $flash_fallback = $xml->addChild('object');
                 $flash_fallback->addAttribute('type', 'application/x-shockwave-flash');
                 $flash_fallback->addAttribute('data', plugins_url('player/podlove-web-player/static/', __FILE__) . 'flashmediaelement.swf');
                 $params = array(array('name' => 'movie', 'value' => plugins_url('player/podlove-web-player/static/', __FILE__) . 'flashmediaelement.swf'), array('name' => 'flashvars', 'value' => 'controls=true&file=' . $file['url']));
                 foreach ($params as $param) {
                     $p = $flash_fallback->addChild('param');
                     $p->addAttribute('name', $param['name']);
                     $p->addAttribute('value', $param['value']);
                 }
             };
         }
     }
     // add flash fallback after all <source>s
     $flash_fallback_func($xml);
     // prettify and prepare to render
     $xml_string = $xml->asXML();
     $xml_string = $this->format_xml($xml_string);
     $xml_string = $this->remove_xml_header($xml_string);
     // get podcast object
     $podcast = Podcast::get();
     if ($this->episode->license_name && $this->episode->license_url) {
         $license_name = $this->episode->license_name;
         $license_url = $this->episode->license_url;
     } else {
         $license_name = $podcast->license_name;
         $license_url = $podcast->license_url;
     }
     // set JavaScript options
     $truthy = array(true, 'true', 'on', 1, "1");
     $init_options = array('pluginPath' => plugins_url('player/podlove-web-player/static/', __FILE__), 'alwaysShowHours' => true, 'alwaysShowControls' => true, 'timecontrolsVisible' => false, 'summaryVisible' => false, 'hidetimebutton' => in_array($this->get_webplayer_setting('buttons_time'), $truthy, true), 'hidedownloadbutton' => in_array($this->get_webplayer_setting('buttons_download'), $truthy, true), 'hidesharebutton' => in_array($this->get_webplayer_setting('buttons_share'), $truthy, true), 'sharewholeepisode' => in_array($this->get_webplayer_setting('buttons_sharemode'), $truthy, true), 'loop' => false, 'chapterlinks' => 'all', 'permalink' => get_permalink($this->post->ID), 'title' => get_the_title($this->post->ID), 'subtitle' => wptexturize(convert_chars(trim($this->episode->subtitle))), 'summary' => nl2br(wptexturize(convert_chars(trim($this->episode->summary)))), 'publicationDate' => mysql2date("c", $this->post->post_date), 'poster' => $this->episode->cover_art_with_fallback()->setWidth(200)->url(), 'showTitle' => $podcast->title, 'showSubtitle' => $podcast->subtitle, 'showSummary' => $podcast->summary, 'showPoster' => $podcast->cover_art()->setWidth(200)->url(), 'show' => array('title' => $podcast->title, 'subtitle' => $podcast->subtitle, 'summary' => $podcast->summary, 'poster' => $podcast->cover_art()->setWidth(200)->url(), 'url' => \Podlove\get_landing_page_url()), 'license' => array('name' => $license_name, 'url' => $license_url), 'downloads' => array_map(function ($mf) {
         return array('assetTitle' => $mf['assetTitle'], 'downloadUrl' => $mf['publicUrl'], 'url' => $mf['url']);
     }, array_values($sorted_files)), 'duration' => $this->episode->get_duration(), 'chaptersVisible' => in_array(\Podlove\get_webplayer_setting('chaptersVisible'), $truthy, true), 'features' => array("current", "progress", "duration", "tracks", "fullscreen", "volume"));
     if ($chapters = $this->episode->get_chapters('json')) {
         $init_options['chapters'] = json_decode($chapters);
     }
     $xml_string .= "\n" . "\n<script>\n" . "jQuery('#" . $this->get_html_id() . "').podlovewebplayer(" . json_encode($init_options) . ");" . "\n</script>\n";
     return $xml_string;
 }
 public static function button($args)
 {
     return (new Button(Model\Podcast::get()))->render($args);
 }
/**
 * Find and run migration for given version number.
 *
 * @todo  move migrations into separate files
 * 
 * @param  int $version
 */
function run_migrations_for_version($version)
{
    global $wpdb;
    switch ($version) {
        case 10:
            $sql = sprintf('ALTER TABLE `%s` ADD COLUMN `summary` TEXT', \Podlove\Model\Episode::table_name());
            $wpdb->query($sql);
            break;
        case 11:
            $sql = sprintf('ALTER TABLE `%s` ADD COLUMN `downloadable` INT', \Podlove\Model\EpisodeAsset::table_name());
            $wpdb->query($sql);
            break;
        case 12:
            $sql = sprintf('UPDATE `%s` SET `downloadable` = 1', \Podlove\Model\EpisodeAsset::table_name());
            $wpdb->query($sql);
            break;
        case 13:
            $opus = array('name' => 'Opus Audio', 'type' => 'audio', 'mime_type' => 'audio/opus', 'extension' => 'opus');
            $f = new \Podlove\Model\FileType();
            foreach ($opus as $key => $value) {
                $f->{$key} = $value;
            }
            $f->save();
            break;
        case 14:
            $sql = sprintf('ALTER TABLE `%s` RENAME TO `%s`', $wpdb->prefix . 'podlove_medialocation', \Podlove\Model\EpisodeAsset::table_name());
            $wpdb->query($sql);
            break;
        case 15:
            $sql = sprintf('ALTER TABLE `%s` CHANGE `media_location_id` `episode_asset_id` INT', \Podlove\Model\MediaFile::table_name());
            $wpdb->query($sql);
            break;
        case 16:
            $sql = sprintf('ALTER TABLE `%s` CHANGE `media_location_id` `episode_asset_id` INT', \Podlove\Model\Feed::table_name());
            $wpdb->query($sql);
            break;
        case 17:
            $sql = sprintf('ALTER TABLE `%s` RENAME TO `%s`', $wpdb->prefix . 'podlove_mediaformat', \Podlove\Model\FileType::table_name());
            $wpdb->query($sql);
            break;
        case 18:
            $sql = sprintf('ALTER TABLE `%s` CHANGE `media_format_id` `file_type_id` INT', \Podlove\Model\EpisodeAsset::table_name());
            $wpdb->query($sql);
            break;
        case 19:
            \Podlove\Model\Template::build();
            break;
        case 20:
            $sql = sprintf('ALTER TABLE `%s` ADD COLUMN `suffix` VARCHAR(255)', \Podlove\Model\EpisodeAsset::table_name());
            $wpdb->query($sql);
            $sql = sprintf('ALTER TABLE `%s` DROP COLUMN `url_template`', \Podlove\Model\EpisodeAsset::table_name());
            $wpdb->query($sql);
            break;
        case 21:
            $podcast = Model\Podcast::get();
            $podcast->url_template = '%media_file_base_url%%episode_slug%%suffix%.%format_extension%';
            $podcast->save();
            break;
        case 22:
            $sql = sprintf('ALTER TABLE `%s` ADD COLUMN `redirect_http_status` INT AFTER `redirect_url`', Model\Feed::table_name());
            $wpdb->query($sql);
            break;
        case 23:
            $sql = sprintf('ALTER TABLE `%s` DROP COLUMN `show_description`', Model\Feed::table_name());
            $wpdb->query($sql);
            break;
        case 24:
            $podcast = Model\Podcast::get();
            update_option('podlove_asset_assignment', array('image' => $podcast->supports_cover_art, 'chapters' => $podcast->chapter_file));
            break;
        case 25:
            // rename meta podlove_guid to _podlove_guid
            $episodes = Model\Episode::all();
            foreach ($episodes as $episode) {
                $post = get_post($episode->post_id);
                // skip revisions
                if ($post->post_status == 'inherit') {
                    continue;
                }
                $guid = get_post_meta($episode->post_id, 'podlove_guid', true);
                if (!$guid) {
                    $guid = $post->guid;
                }
                delete_post_meta($episode->post_id, 'podlove_guid');
                update_post_meta($episode->post_id, '_podlove_guid', $guid);
            }
            break;
        case 26:
            $wpdb->query(sprintf('ALTER TABLE `%s` MODIFY COLUMN `subtitle` TEXT', Model\Episode::table_name()));
            break;
        case 27:
            $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `record_date` DATETIME AFTER `chapters`', Model\Episode::table_name()));
            $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `publication_date` DATETIME AFTER `record_date`', Model\Episode::table_name()));
            break;
        case 28:
            $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `position` FLOAT AFTER `downloadable`', Model\EpisodeAsset::table_name()));
            $wpdb->query(sprintf('UPDATE `%s` SET position = id', Model\EpisodeAsset::table_name()));
            break;
        case 29:
            $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `embed_content_encoded` INT AFTER `limit_items`', Model\Feed::table_name()));
            break;
        case 30:
            $wpdb->query(sprintf('ALTER TABLE `%s` MODIFY `autoinsert` VARCHAR(255)', Model\Template::table_name()));
            break;
        case 32:
            flush_rewrite_rules();
            break;
        case 33:
            $apd = array('name' => 'Auphonic Production Description', 'type' => 'metadata', 'mime_type' => 'application/json', 'extension' => 'json');
            $f = new \Podlove\Model\FileType();
            foreach ($apd as $key => $value) {
                $f->{$key} = $value;
            }
            $f->save();
            break;
        case 34:
            $options = get_option('podlove', array());
            if (!array_key_exists('episode_archive', $options)) {
                $options['episode_archive'] = 'on';
            }
            if (!array_key_exists('episode_archive_slug', $options)) {
                $options['episode_archive_slug'] = '/podcast/';
            }
            if (!array_key_exists('use_post_permastruct', $options)) {
                $options['use_post_permastruct'] = 'off';
            }
            if (!array_key_exists('custom_episode_slug', $options)) {
                $options['custom_episode_slug'] = '/podcast/%podcast%/';
            } else {
                $options['custom_episode_slug'] = preg_replace('#/+#', '/', '/' . str_replace('#', '', $options['custom_episode_slug']));
            }
            update_option('podlove', $options);
            break;
        case 35:
            Model\Feed::build_indices();
            Model\FileType::build_indices();
            Model\EpisodeAsset::build_indices();
            Model\MediaFile::build_indices();
            Model\Episode::build_indices();
            Model\Template::build_indices();
            break;
        case 36:
            $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `etag` VARCHAR(255)', Model\MediaFile::table_name()));
            break;
        case 37:
            \Podlove\Modules\Base::activate('asset_validation');
            break;
        case 38:
            \Podlove\Modules\Base::activate('logging');
            break;
        case 39:
            // migrate previous template autoinsert settings
            $assignments = Model\TemplateAssignment::get_instance();
            $results = $wpdb->get_results(sprintf('SELECT * FROM `%s`', Model\Template::table_name()));
            foreach ($results as $template) {
                if ($template->autoinsert == 'beginning') {
                    $assignments->top = $template->id;
                } elseif ($template->autoinsert == 'end') {
                    $assignments->bottom = $template->id;
                }
            }
            $assignments->save();
            // remove template autoinsert column
            $sql = sprintf('ALTER TABLE `%s` DROP COLUMN `autoinsert`', \Podlove\Model\Template::table_name());
            $wpdb->query($sql);
            break;
        case 40:
            $wpdb->query(sprintf('UPDATE `%s` SET position = id WHERE position IS NULL', Model\EpisodeAsset::table_name()));
            break;
        case 41:
            $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `position` FLOAT AFTER `slug`', Model\Feed::table_name()));
            $wpdb->query(sprintf('UPDATE `%s` SET position = id', Model\Feed::table_name()));
            break;
        case 42:
            $wpdb->query('DELETE FROM `' . $wpdb->options . '` WHERE option_name LIKE "%podlove_chapters_string_%"');
            break;
        case 43:
            $podlove_options = get_option('podlove', array());
            $podlove_website = array('merge_episodes' => isset($podlove_options['merge_episodes']) ? $podlove_options['merge_episodes'] : false, 'hide_wp_feed_discovery' => isset($podlove_options['hide_wp_feed_discovery']) ? $podlove_options['hide_wp_feed_discovery'] : false, 'use_post_permastruct' => isset($podlove_options['use_post_permastruct']) ? $podlove_options['use_post_permastruct'] : false, 'custom_episode_slug' => isset($podlove_options['custom_episode_slug']) ? $podlove_options['custom_episode_slug'] : '/episode/%podcast%', 'episode_archive' => isset($podlove_options['episode_archive']) ? $podlove_options['episode_archive'] : false, 'episode_archive_slug' => isset($podlove_options['episode_archive_slug']) ? $podlove_options['episode_archive_slug'] : '/podcast/', 'url_template' => isset($podlove_options['url_template']) ? $podlove_options['url_template'] : '%media_file_base_url%%episode_slug%%suffix%.%format_extension%');
            $podlove_metadata = array('enable_episode_record_date' => isset($podlove_options['enable_episode_record_date']) ? $podlove_options['enable_episode_record_date'] : false, 'enable_episode_publication_date' => isset($podlove_options['enable_episode_publication_date']) ? $podlove_options['enable_episode_publication_date'] : false);
            $podlove_redirects = array('podlove_setting_redirect' => isset($podlove_options['podlove_setting_redirect']) ? $podlove_options['podlove_setting_redirect'] : array());
            add_option('podlove_website', $podlove_website);
            add_option('podlove_metadata', $podlove_metadata);
            add_option('podlove_redirects', $podlove_redirects);
            break;
        case 44:
            $wpdb->query('DELETE FROM `' . $wpdb->postmeta . '` WHERE meta_key = "last_validated_at"');
            break;
        case 45:
            delete_transient('podlove_auphonic_user');
            delete_transient('podlove_auphonic_presets');
            break;
        case 46:
            if (\Podlove\Modules\Base::is_active('contributors')) {
                // manually trigger activation if the old module was active
                $module = \Podlove\Modules\Contributors\Contributors::instance();
                $module->was_activated('contributors');
                // then, migrate existing contributors
                // register old taxonomy so it can be queried
                $args = array('hierarchical' => false, 'labels' => array(), 'show_ui' => true, 'show_tagcloud' => true, 'query_var' => true, 'rewrite' => array('slug' => 'contributor'));
                register_taxonomy('podlove-contributors', 'podcast', $args);
                $contributor_settings = get_option('podlove_contributors', array());
                $contributors = get_terms('podlove-contributors', array('hide_empty' => 0));
                if ($contributors && !is_wp_error($contributors) && \Podlove\Modules\Contributors\Model\Contributor::count() == 0) {
                    foreach ($contributors as $contributor) {
                        // create new contributor
                        $new = new \Podlove\Modules\Contributors\Model\Contributor();
                        $new->publicname = $contributor->name;
                        $new->realname = $contributor->name;
                        $new->slug = $contributor->slug;
                        $new->showpublic = true;
                        if (isset($contributor_settings[$contributor->term_id]['contributor_email'])) {
                            $email = $contributor_settings[$contributor->term_id]['contributor_email'];
                            if ($email) {
                                $new->privateemail = $email;
                                $new->avatar = $email;
                            }
                        }
                        $new->save();
                        // create contributions
                        $query = new \WP_Query(array('posts_per_page' => -1, 'post_type' => 'podcast', 'tax_query' => array(array('taxonomy' => 'podlove-contributors', 'field' => 'slug', 'terms' => $contributor->slug))));
                        while ($query->have_posts()) {
                            $post = $query->next_post();
                            $contribution = new \Podlove\Modules\Contributors\Model\EpisodeContribution();
                            $contribution->contributor_id = $new->id;
                            $contribution->episode_id = Model\Episode::find_one_by_post_id($post->ID)->id;
                            $contribution->save();
                        }
                    }
                }
            }
            break;
        case 47:
            $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `protected` TINYINT(1) NULL', \Podlove\Model\Feed::table_name()));
            $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `protection_type` TINYINT(1)', \Podlove\Model\Feed::table_name()));
            $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `protection_user` VARCHAR(60)', \Podlove\Model\Feed::table_name()));
            $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `protection_password` VARCHAR(64)', \Podlove\Model\Feed::table_name()));
            break;
        case 48:
            $podcast = Model\Podcast::get();
            $podcast->limit_items = '-1';
            $podcast->save();
            break;
        case 49:
            $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `explicit` TINYINT', Model\Episode::table_name()));
            break;
        case 50:
            $podcast = Model\Podcast::get();
            $podcast->license_type = 'other';
            $podcast->save();
            $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `license_type` VARCHAR(255) AFTER `publication_date`', Model\Episode::table_name()));
            $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `license_name` TEXT AFTER `license_type`', Model\Episode::table_name()));
            $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `license_url` TEXT AFTER `license_name`', Model\Episode::table_name()));
            $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `license_cc_allow_modifications` TEXT AFTER `license_url`', Model\Episode::table_name()));
            $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `license_cc_allow_commercial_use` TEXT AFTER `license_cc_allow_modifications`', Model\Episode::table_name()));
            $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `license_cc_license_jurisdiction` TEXT AFTER `license_cc_allow_commercial_use`', Model\Episode::table_name()));
            break;
        case 51:
            if (\Podlove\Modules\Base::is_active('contributors')) {
                \Podlove\Modules\Contributors\Model\ContributorGroup::build();
                $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `group_id` VARCHAR(255) AFTER `role_id`', \Podlove\Modules\Contributors\Model\EpisodeContribution::table_name()));
                $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `group_id` VARCHAR(255) AFTER `role_id`', \Podlove\Modules\Contributors\Model\ShowContribution::table_name()));
                $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `paypal` VARCHAR(255) AFTER `flattr`', \Podlove\Modules\Contributors\Model\Contributor::table_name()));
                $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `bitcoin` VARCHAR(255) AFTER `paypal`', \Podlove\Modules\Contributors\Model\Contributor::table_name()));
                $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `litecoin` VARCHAR(255) AFTER `bitcoin`', \Podlove\Modules\Contributors\Model\Contributor::table_name()));
                $wpdb->query(sprintf('ALTER TABLE `%s` DROP COLUMN `permanentcontributor`', \Podlove\Modules\Contributors\Model\Contributor::table_name()));
                $wpdb->query(sprintf('ALTER TABLE `%s` DROP COLUMN `role`', \Podlove\Modules\Contributors\Model\Contributor::table_name()));
            }
            break;
        case 52:
            if (\Podlove\Modules\Base::is_active('contributors')) {
                $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `jobtitle` VARCHAR(255) AFTER `department`', \Podlove\Modules\Contributors\Model\Contributor::table_name()));
            }
            break;
        case 53:
            // set all Episode as published (fix for ADN Module)
            $episodes = Model\Episode::all();
            foreach ($episodes as $episode) {
                $post = get_post($episode->post_id);
                if ($post->post_status == 'publish') {
                    update_post_meta($episode->post_id, '_podlove_episode_was_published', true);
                }
            }
            break;
        case 54:
            if (\Podlove\Modules\Base::is_active('contributors')) {
                $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `googleplus` TEXT AFTER `ADN`', \Podlove\Modules\Contributors\Model\Contributor::table_name()));
                $wpdb->query(sprintf('ALTER TABLE `%s` CHANGE COLUMN `showpublic` `visibility` TINYINT(1)', \Podlove\Modules\Contributors\Model\Contributor::table_name()));
            }
            break;
        case 55:
            if (\Podlove\Modules\Base::is_active('contributors')) {
                \Podlove\Modules\Contributors\Model\DefaultContribution::build();
                $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `comment` TEXT AFTER `position`', \Podlove\Modules\Contributors\Model\EpisodeContribution::table_name()));
                $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `comment` TEXT AFTER `position`', \Podlove\Modules\Contributors\Model\ShowContribution::table_name()));
            }
            break;
        case 56:
            // migrate Podcast Contributors to Default Contributors
            if (\Podlove\Modules\Base::is_active('contributors')) {
                $podcast_contributors = \Podlove\Modules\Contributors\Model\ShowContribution::all();
                foreach ($podcast_contributors as $podcast_contributor_key => $podcast_contributor) {
                    $new = new \Podlove\Modules\Contributors\Model\DefaultContribution();
                    $new->contributor_id = $podcast_contributor->contributor_id;
                    $new->group_id = $podcast_contributor->group_id;
                    $new->role_id = $podcast_contributor->role_id;
                    $new->position = $podcast_contributor->positon;
                    $new->save();
                }
            }
            break;
        case 57:
            $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `append_name_to_podcast_title` TINYINT(1) NULL AFTER `embed_content_encoded`', \Podlove\Model\Feed::table_name()));
            break;
        case 58:
            // if contributors module is active, activate social module
            if (\Podlove\Modules\Base::is_active('contributors')) {
                \Podlove\Modules\Base::activate('social');
            }
            break;
        case 59:
            if (\Podlove\Modules\Base::is_active('bitlove')) {
                $wpdb->query(sprintf("ALTER TABLE `%s` ADD COLUMN `bitlove` TINYINT(1) DEFAULT '0'", \Podlove\Model\Feed::table_name()));
            }
            break;
        case 60:
            \Podlove\Modules\Base::activate('oembed');
            \Podlove\Modules\Base::activate('feed_validation');
            break;
        case 61:
            $wpdb->query(sprintf('ALTER TABLE `%s` DROP COLUMN `publication_date`', Model\Episode::table_name()));
            break;
        case 62:
            // rename column
            $wpdb->query(sprintf('ALTER TABLE `%s` CHANGE COLUMN `record_date` `recording_date` DATETIME', Model\Episode::table_name()));
            // update settings
            $meta = get_option('podlove_metadata');
            if (isset($meta['enable_episode_publication_date'])) {
                unset($meta['enable_episode_publication_date']);
            }
            if (isset($meta['enable_episode_record_date'])) {
                $meta['enable_episode_recording_date'] = $meta['enable_episode_record_date'];
                unset($meta['enable_episode_record_date']);
            }
            update_option('podlove_metadata', $meta);
            break;
        case 63:
            if (\Podlove\Modules\Base::is_active('social')) {
                $tumblr_service = \Podlove\Modules\Social\Model\Service::find_one_by_property('title', 'Tumblr');
                $tumblr_service->url_scheme = 'http://%account-placeholder%.tumblr.com/';
                $tumblr_service->save();
            }
            break;
        case 64:
            if (\Podlove\Modules\Base::is_active('social')) {
                $services = array(array('title' => '500px', 'type' => 'social', 'description' => '500px Account', 'logo' => '500px-128.png', 'url_scheme' => 'https://500px.com/%account-placeholder%'), array('title' => 'Last.fm', 'type' => 'social', 'description' => 'Last.fm Account', 'logo' => 'lastfm-128.png', 'url_scheme' => 'https://www.lastfm.de/user/%account-placeholder%'), array('title' => 'OpenStreetMap', 'type' => 'social', 'description' => 'OpenStreetMap Account', 'logo' => 'openstreetmap-128.png', 'url_scheme' => 'https://www.openstreetmap.org/user/%account-placeholder%'), array('title' => 'Soup', 'type' => 'social', 'description' => 'Soup Account', 'logo' => 'soup-128.png', 'url_scheme' => 'http://%account-placeholder%.soup.io'));
                foreach ($services as $service_key => $service) {
                    $c = new \Podlove\Modules\Social\Model\Service();
                    $c->title = $service['title'];
                    $c->type = $service['type'];
                    $c->description = $service['description'];
                    $c->logo = $service['logo'];
                    $c->url_scheme = $service['url_scheme'];
                    $c->save();
                }
            }
            break;
        case 65:
            if (\Podlove\Modules\Base::is_active('social')) {
                $flattr_service = \Podlove\Modules\Social\Model\Service::find_one_by_where("`title` = 'Flattr' AND `type` = 'donation'");
                if ($flattr_service) {
                    $contributor_flattr_donations_accounts = \Podlove\Modules\Social\Model\ContributorService::find_all_by_property('service_id', $flattr_service->id);
                    foreach ($contributor_flattr_donations_accounts as $contributor_flattr_donations_account) {
                        $contributor = \Podlove\Modules\Contributors\Model\Contributor::find_by_id($contributor_flattr_donations_account->contributor_id);
                        if ($contributor && is_null($contributor->flattr)) {
                            $contributor->flattr = $contributor_flattr_donations_account->value;
                            $contributor->save();
                        }
                        $contributor_flattr_donations_account->delete();
                    }
                    $flattr_service->delete();
                }
            }
            break;
        case 66:
            // Temporary add license_type and CC license fields to episode model
            \Podlove\Model\Episode::property('license_type', 'VARCHAR(255)');
            \Podlove\Model\Episode::property('license_cc_allow_modifications', 'VARCHAR(255)');
            \Podlove\Model\Episode::property('license_cc_allow_commercial_use', 'VARCHAR(255)');
            \Podlove\Model\Episode::property('license_cc_license_jurisdiction', 'VARCHAR(255)');
            $podcast = \Podlove\Model\Podcast::get();
            $episodes = \Podlove\Model\Episode::all();
            // Migration for Podcast
            if ($podcast->license_type == 'cc' && $podcast->license_cc_allow_commercial_use !== '' && $podcast->license_cc_allow_modifications !== '' && $podcast->license_cc_license_jurisdiction !== '') {
                $license = array('version' => '3.0', 'commercial_use' => $podcast->license_cc_allow_commercial_use, 'modification' => $podcast->license_cc_allow_modifications, 'jurisdiction' => $podcast->license_cc_license_jurisdiction);
                $podcast->license_url = \Podlove\Model\License::get_url_from_license($license);
                $podcast->license_name = \Podlove\Model\License::get_name_from_license($license);
                $podcast->save();
            }
            // Migration for Episodes
            foreach ($episodes as $episode) {
                if ($episode->license_type == 'other' || $episode->license_cc_allow_commercial_use == '' || $episode->license_cc_allow_modifications == '' || $episode->license_cc_license_jurisdiction == '') {
                    continue;
                }
                $license = array('version' => '3.0', 'commercial_use' => $episode->license_cc_allow_commercial_use, 'modification' => $episode->license_cc_allow_modifications, 'jurisdiction' => $episode->license_cc_license_jurisdiction);
                $episode->license_url = \Podlove\Model\License::get_url_from_license($license);
                $episode->license_name = \Podlove\Model\License::get_name_from_license($license);
                $episode->save();
            }
            break;
        case 67:
            if (\Podlove\Modules\Base::is_active('social')) {
                $instagram_service = \Podlove\Modules\Social\Model\Service::find_one_by_where("`title` = 'Instagram' AND `type` = 'social'");
                if ($instagram_service) {
                    $instagram_service->url_scheme = 'https://instagram.com/%account-placeholder%';
                    $instagram_service->save();
                }
            }
            break;
        case 68:
            // Do that ADN module fix again, as we forgot to mark all episodes as published if the ADN module is activated
            $episodes = Model\Episode::all();
            foreach ($episodes as $episode) {
                $post = get_post($episode->post_id);
                if ($post->post_status == 'publish' && !get_post_meta($episode->post_id, '_podlove_episode_was_published', true)) {
                    update_post_meta($episode->post_id, '_podlove_episode_was_published', true);
                }
            }
            break;
        case 69:
            if (\Podlove\Modules\Base::is_active('app_dot_net')) {
                $adn = \Podlove\Modules\AppDotNet\App_Dot_Net::instance();
                if ($adn->get_module_option('adn_auth_key')) {
                    $adn->update_module_option('adn_automatic_announcement', 'on');
                }
            }
            break;
        case 70:
            \Podlove\Model\DownloadIntent::build();
            \Podlove\Model\UserAgent::build();
            break;
        case 71:
            // update for everyone, so even those with inactive service tables get updated
            $wpdb->query(sprintf('ALTER TABLE `%s` CHANGE COLUMN `type` `category` VARCHAR(255)', \Podlove\Modules\Social\Model\Service::table_name()));
            $wpdb->query(sprintf("ALTER TABLE `%s` ADD COLUMN `type` VARCHAR(255) AFTER `category`", \Podlove\Modules\Social\Model\Service::table_name()));
            $services = \Podlove\Modules\Social\Model\Service::all();
            foreach ($services as $service) {
                $service->type = strtolower($service->title);
                $service->save();
            }
            break;
        case 72:
            if (\Podlove\Modules\Base::is_active('social')) {
                $services = array(array('title' => 'Vimeo', 'type' => 'vimeo', 'category' => 'social', 'description' => 'Vimeo Account', 'logo' => 'vimeo-128.png', 'url_scheme' => 'http://vimeo.com/%account-placeholder%'), array('title' => 'about.me', 'type' => 'about.me', 'category' => 'social', 'description' => 'about.me Account', 'logo' => 'aboutme-128.png', 'url_scheme' => 'http://about.me/%account-placeholder%'), array('title' => 'Gittip', 'type' => 'gittip', 'category' => 'donation', 'description' => 'Gittip Account', 'logo' => 'gittip-128.png', 'url_scheme' => 'https://www.gittip.com/%account-placeholder%'));
                foreach ($services as $service_key => $service) {
                    $c = new \Podlove\Modules\Social\Model\Service();
                    $c->title = $service['title'];
                    $c->type = $service['type'];
                    $c->category = $service['category'];
                    $c->description = $service['description'];
                    $c->logo = $service['logo'];
                    $c->url_scheme = $service['url_scheme'];
                    $c->save();
                }
            }
            break;
        case 73:
            if (\Podlove\Modules\Base::is_active('social')) {
                $jabber_service = \Podlove\Modules\Social\Model\Service::find_one_by_where("`type` = 'jabber' AND `category` = 'social'");
                if ($jabber_service) {
                    $jabber_service->url_scheme = 'jabber:%account-placeholder%';
                    $jabber_service->save();
                }
            }
            break;
        case 74:
            Model\GeoArea::build();
            Model\GeoAreaName::build();
            \Podlove\Geo_Ip::register_updater_cron();
            break;
        case 75:
            $tracking = get_option('podlove_tracking');
            $tracking['mode'] = 0;
            update_option('podlove_tracking', $tracking);
            break;
        case 76:
            set_transient('podlove_needs_to_flush_rewrite_rules', true);
            break;
        case 77:
            // delete empty user agents
            $userAgentTable = Model\UserAgent::table_name();
            $downloadIntentTable = Model\DownloadIntent::table_name();
            $sql = "SELECT\n\t\t\t\tdi.id\n\t\t\tFROM\n\t\t\t\t{$downloadIntentTable} di\n\t\t\t\tJOIN {$userAgentTable} ua ON ua.id = di.user_agent_id\n\t\t\tWHERE\n\t\t\t\tua.user_agent IS NULL";
            $ids = $wpdb->get_col($sql);
            if (is_array($ids) && count($ids)) {
                $sql = "UPDATE {$downloadIntentTable} SET user_agent_id = NULL WHERE id IN (" . implode(",", $ids) . ")";
                $wpdb->query($sql);
                $sql = "DELETE FROM {$userAgentTable} WHERE user_agent IS NULL";
                $wpdb->query($sql);
            }
            break;
        case 78:
            if (\Podlove\Modules\Base::is_active('social')) {
                $c = new \Podlove\Modules\Social\Model\Service();
                $c->title = 'Auphonic Credits';
                $c->category = 'donation';
                $c->type = 'auphonic credits';
                $c->description = 'Auphonic Account';
                $c->logo = 'auphonic-128.png';
                $c->url_scheme = 'https://auphonic.com/donate_credits?user=%account-placeholder%';
                $c->save();
            }
            break;
        case 79:
            set_transient('podlove_needs_to_flush_rewrite_rules', true);
            $cache = \Podlove\Cache\TemplateCache::get_instance();
            $cache->setup_purge();
            break;
        case 80:
            $sql = sprintf('ALTER TABLE `%s` ADD COLUMN `httprange` VARCHAR(255)', \Podlove\Model\DownloadIntent::table_name());
            $wpdb->query($sql);
            break;
        case 81:
            // remove all caches with old namespace
            $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE \"_transient_podlove_cache%\"");
            break;
        case 82:
            // set all redirect entries to active
            $redirect_settings = \Podlove\get_setting('redirects', 'podlove_setting_redirect');
            foreach ($redirect_settings as $index => $data) {
                $redirect_settings[$index]['active'] = 'active';
            }
            update_option('podlove_redirects', array('podlove_setting_redirect' => $redirect_settings));
            break;
        case 83:
            \Podlove\Model\DownloadIntentClean::build();
            $alterations = array('ALTER TABLE `%s` ADD COLUMN `bot` TINYINT', 'ALTER TABLE `%s` ADD COLUMN `client_name` VARCHAR(255)', 'ALTER TABLE `%s` ADD COLUMN `client_version` VARCHAR(255)', 'ALTER TABLE `%s` ADD COLUMN `client_type` VARCHAR(255)', 'ALTER TABLE `%s` ADD COLUMN `os_name` VARCHAR(255)', 'ALTER TABLE `%s` ADD COLUMN `os_version` VARCHAR(255)', 'ALTER TABLE `%s` ADD COLUMN `device_brand` VARCHAR(255)', 'ALTER TABLE `%s` ADD COLUMN `device_model` VARCHAR(255)');
            foreach ($alterations as $sql) {
                $wpdb->query(sprintf($sql, Model\UserAgent::table_name()));
            }
            Model\UserAgent::reparse_all();
            break;
        case 84:
            delete_option('podlove_tpl_cache_keys');
            break;
        case 85:
            add_option('podlove_tracking_delete_head_requests', 1);
            break;
        case 86:
            if (\Podlove\Modules\Base::is_active('social')) {
                $c = new \Podlove\Modules\Social\Model\Service();
                $c->title = 'Foursquare';
                $c->category = 'social';
                $c->type = 'foursquare';
                $c->description = 'Foursquare Account';
                $c->logo = 'foursquare-128.png';
                $c->url_scheme = 'https://foursquare.com/%account-placeholder%';
                $c->save();
                $services = array(array('title' => 'ResearchGate', 'name' => 'researchgate', 'category' => 'social', 'description' => 'ResearchGate URL', 'logo' => 'researchgate-128.png', 'url_scheme' => '%account-placeholder%'), array('title' => 'ORCiD', 'name' => 'orcid', 'category' => 'social', 'description' => 'ORCiD', 'logo' => 'orcid-128.png', 'url_scheme' => 'https://orcid.org/%account-placeholder%'), array('title' => 'Scopus', 'name' => 'scous', 'category' => 'social', 'description' => 'Scopus Author ID', 'logo' => 'scopus-128.png', 'url_scheme' => 'https://www.scopus.com/authid/detail.url?authorId=%account-placeholder%'));
                foreach ($services as $service_key => $service) {
                    $c = new \Podlove\Modules\Social\Model\Service();
                    $c->title = $service['title'];
                    $c->category = $service['category'];
                    $c->type = $service['name'];
                    $c->description = $service['description'];
                    $c->logo = $service['logo'];
                    $c->url_scheme = $service['url_scheme'];
                    $c->save();
                }
            }
            break;
        case 87:
            if (\Podlove\Modules\Base::is_active('app_dot_net')) {
                $adn = \Podlove\Modules\AppDotNet\App_Dot_Net::instance();
                if ($adn->get_module_option('adn_auth_key')) {
                    $adn->update_module_option('adn_poster_image_fallback', 'on');
                }
            }
            break;
        case 88:
            $service = new \Podlove\Modules\Social\Model\Service();
            $service->title = 'Email';
            $service->category = 'social';
            $service->type = 'email';
            $service->description = 'Email';
            $service->logo = 'email-128.png';
            $service->url_scheme = 'mailto:%account-placeholder%';
            $service->save();
            break;
        case 89:
            $email_service = \Podlove\Modules\Social\Model\Service::find_one_by_type('email');
            foreach (\Podlove\Modules\Contributors\Model\Contributor::all() as $contributor) {
                if (!$contributor->publicemail) {
                    continue;
                }
                $contributor_service = new \Podlove\Modules\Social\Model\ContributorService();
                $contributor_service->contributor_id = $contributor->id;
                $contributor_service->service_id = $email_service->id;
                $contributor_service->value = $contributor->publicemail;
                $contributor_service->save();
            }
            break;
        case 90:
            \Podlove\Modules\Base::activate('subscribe_button');
            break;
        case 91:
            $c = new \Podlove\Modules\Social\Model\Service();
            $c->title = 'Miiverse';
            $c->category = 'social';
            $c->type = 'miiverse';
            $c->description = 'Miiverse Account';
            $c->logo = 'miiverse-128.png';
            $c->url_scheme = 'https://miiverse.nintendo.net/users/%account-placeholder%';
            $c->save();
            break;
        case 92:
            $c = new \Podlove\Modules\Social\Model\Service();
            $c->title = 'Prezi';
            $c->category = 'social';
            $c->type = 'prezi';
            $c->description = 'Prezis';
            $c->logo = 'prezi-128.png';
            $c->url_scheme = 'http://prezi.com/user/%account-placeholder%';
            $c->save();
            break;
        case 93:
            // podlove_init_user_agent_refresh();
            // do nothing instead, because see 94 below
            break;
        case 94:
            // this is a duplicate of migration 83 but it looks like that didn't work.
            Model\DownloadIntentClean::build();
            $alterations = array('ALTER TABLE `%s` ADD COLUMN `bot` TINYINT', 'ALTER TABLE `%s` ADD COLUMN `client_name` VARCHAR(255)', 'ALTER TABLE `%s` ADD COLUMN `client_version` VARCHAR(255)', 'ALTER TABLE `%s` ADD COLUMN `client_type` VARCHAR(255)', 'ALTER TABLE `%s` ADD COLUMN `os_name` VARCHAR(255)', 'ALTER TABLE `%s` ADD COLUMN `os_version` VARCHAR(255)', 'ALTER TABLE `%s` ADD COLUMN `device_brand` VARCHAR(255)', 'ALTER TABLE `%s` ADD COLUMN `device_model` VARCHAR(255)');
            foreach ($alterations as $sql) {
                $wpdb->query(sprintf($sql, Model\UserAgent::table_name()));
            }
            podlove_init_user_agent_refresh();
            // manually trigger intent cron after user agents are parsed
            // parameter to make sure WP does not skip it due to 10 minute rule
            wp_schedule_single_event(time() + 120, 'podlove_cleanup_download_intents', ['really' => true]);
            // manually trigger average cron after intents are calculated
            wp_schedule_single_event(time() + 240, 'recalculate_episode_download_average', ['really' => true]);
            break;
        case 95:
            // add missing flattr column
            $wpdb->query(sprintf('ALTER TABLE `%s` ADD COLUMN `flattr` VARCHAR(255) AFTER `avatar`', \Podlove\Modules\Contributors\Model\Contributor::table_name()));
            break;
        case 96:
            \Podlove\DeleteHeadRequests::init();
            break;
        case 97:
            // recalculate all downloads average data
            $wpdb->query(sprintf('DELETE FROM `%s` WHERE `meta_key` LIKE "_podlove_eda%%"', $wpdb->postmeta));
            break;
        case 98:
            delete_transient('podlove_dashboard_stats_contributors');
            break;
        case 99:
            // Activate network module for migrating users.
            // Core modules are automatically activated for _new_ setups and
            // whenever modules change. Since this can't be guaranteed for
            // existing setups, it must be triggered manually.
            \Podlove\Modules\Networks\Networks::instance()->was_activated();
            break;
        case 101:
            // add patreon
            if (\Podlove\Modules\Social\Model\Service::table_exists()) {
                \Podlove\Modules\Social\RepairSocial::fix_missing_services();
            }
            break;
        case 102:
            // update logos
            if (\Podlove\Modules\Social\Model\Service::table_exists()) {
                \Podlove\Modules\Social\Social::update_existing_services();
            }
            break;
        case 103:
            $assignment = get_option('podlove_template_assignment', []);
            if ($assignment['top'] && is_numeric($assignment['top'])) {
                $assignment['top'] = Model\Template::find_by_id($assignment['top'])->title;
            }
            if ($assignment['bottom'] && is_numeric($assignment['bottom'])) {
                $assignment['bottom'] = Model\Template::find_by_id($assignment['bottom'])->title;
            }
            update_option('podlove_template_assignment', $assignment);
            break;
        case 104:
            \Podlove\unschedule_events(\Podlove\Cache\TemplateCache::CRON_PURGE_HOOK);
            break;
        case 105:
            // activate flattr plugin
            \Podlove\Modules\Base::activate('flattr');
            // migrate flattr data
            $podcast = Model\Podcast::get();
            $settings = get_option('podlove_flattr', []);
            $settings['account'] = $podcast->flattr;
            $settings['contributor_shortcode_default'] = 'yes';
            update_option('podlove_flattr', $settings);
            break;
        case 106:
            podlove_init_user_agent_refresh();
            break;
        case 107:
            // skipped
            break;
        case 108:
            podlove_init_user_agent_refresh();
            break;
        case 109:
            \podlove_init_capabilities();
            break;
        case 110:
            if (\Podlove\Modules\Social\Model\Service::table_exists()) {
                \Podlove\Modules\Social\Social::update_existing_services();
                \Podlove\Modules\Social\Social::build_missing_services();
            }
            break;
        case 111:
            if (\Podlove\Modules\Social\Model\Service::table_exists()) {
                \Podlove\Modules\Social\Social::update_existing_services();
                \Podlove\Modules\Social\Social::build_missing_services();
            }
            break;
    }
}
 public function cover_art()
 {
     return $this->with_blog_scope(function () {
         $podcast = Podcast::get();
         $asset_assignment = AssetAssignment::get_instance();
         if (!$asset_assignment->image) {
             return false;
         }
         if ($asset_assignment->image == 'manual') {
             $cover_art = trim($this->cover_art);
             if (empty($cover_art)) {
                 return false;
             } else {
                 return new Image($cover_art, $this->title());
             }
         }
         $cover_art_file_id = $asset_assignment->image;
         if (!($asset = EpisodeAsset::find_one_by_id($cover_art_file_id))) {
             return false;
         }
         if (!($file = MediaFile::find_by_episode_id_and_episode_asset_id($this->id, $asset->id))) {
             return false;
         }
         return $file->size > 0 ? new Image($file->get_file_url(), $this->title()) : false;
     });
 }
 /**
  * Return real file URL
  *
  * For public facing URLs, use ::get_public_file_url().
  *
  * @return string
  */
 public function get_file_url()
 {
     return $this->with_blog_scope(function () {
         $podcast = Podcast::get();
         $episode = $this->episode();
         $episode_asset = EpisodeAsset::find_by_id($this->episode_asset_id);
         $file_type = FileType::find_by_id($episode_asset->file_type_id);
         if (!$episode_asset || !$file_type || !$episode) {
             return '';
         }
         $template = $podcast->get_url_template();
         $template = apply_filters('podlove_file_url_template', $template);
         $template = str_replace('%media_file_base_url%', trailingslashit($podcast->media_file_base_uri), $template);
         $template = str_replace('%episode_slug%', \Podlove\slugify($episode->slug), $template);
         $template = str_replace('%suffix%', $episode_asset->suffix, $template);
         $template = str_replace('%format_extension%', $file_type->extension, $template);
         return trim($template);
     });
 }
    private function form_template($episode_asset, $action, $button_text = NULL)
    {
        $raw_formats = \Podlove\Model\FileType::all();
        $formats = array();
        foreach ($raw_formats as $format) {
            $formats[$format->id] = array('title' => $format->title(), 'name' => $format->name, 'extension' => $format->extension, 'type' => $format->type);
        }
        $format_optionlist = array_map(function ($f) {
            return array('value' => $f['title'], 'attributes' => 'data-type="' . $f['type'] . '" data-extension="' . $f['extension'] . '" data-name="' . $f['name'] . '"');
        }, $formats);
        $form_args = array('context' => 'podlove_episode_asset', 'hidden' => array('episode_asset' => $episode_asset->id, 'action' => $action), 'attributes' => array('id' => 'podlove_episode_assets'), 'submit_button' => false, 'form_end' => function () {
            echo "<p>";
            submit_button(__('Save Changes'), 'primary', 'submit', false);
            echo " ";
            submit_button(__('Save Changes and Continue Editing', 'podlove'), 'secondary', 'submit_and_stay', false);
            echo "</p>";
        });
        \Podlove\Form\build_for($episode_asset, $form_args, function ($form) use($format_optionlist) {
            $f = new \Podlove\Form\Input\TableWrapper($form);
            if ($form->object->file_type_id) {
                $current_file_type = Model\FileType::find_by_id($form->object->file_type_id)->type;
            } else {
                $current_file_type = '';
            }
            ?>
			<tr class="row_podlove_episode_asset_type">
				<th scope="row" valign="top">
					<label for="podlove_episode_asset_type"><?php 
            echo __('Asset Type', 'podlove');
            ?>
</label>
				</th>
				<td>
					<select name="podlove_episode_asset_type" id="podlove_episode_asset_type">
						<option><?php 
            echo __('Please choose ...', 'podlove');
            ?>
</option>
						<?php 
            foreach (Model\FileType::get_types() as $type) {
                ?>
							<option value="<?php 
                echo $type;
                ?>
" <?php 
                selected($type, $current_file_type);
                ?>
><?php 
                echo $type;
                ?>
</option>	
						<?php 
            }
            ?>
					</select>
					<div id="option_storage" style="display:none"></div>
				</td>
			</tr>
			<?php 
            $f->select('file_type_id', array('label' => __('File Format', 'podlove'), 'description' => __('', 'podlove'), 'options' => $format_optionlist));
            $f->string('title', array('label' => __('Title', 'podlove'), 'description' => __('Description to identify the media file type to the user in download buttons.', 'podlove'), 'html' => array('class' => 'regular-text required podlove-check-input')));
            $f->checkbox('downloadable', array('label' => __('Downloadable', 'podlove'), 'description' => sprintf('Allow downloads for users.', 'podlove'), 'default' => true));
            ?>
			<tr>
				<th colspan="2">
					<h3><?php 
            echo __('Asset File Name', 'podlove');
            ?>
</h3>
				</th>
			</tr>
			<?php 
            $f->string('suffix', array('label' => __('File Name Suffix', 'podlove'), 'description' => __('Optional. Is appended to file name after episode slug.', 'podlove'), 'html' => array('class' => 'regular-text required podlove-check-input')));
            ?>
			<tr class="row_podlove_asset_url_preview">
				<th>
					<?php 
            echo __('URL Preview', 'podlove');
            ?>
				</th>
				<td>
					<div id="url_preview" style="font-size: 1.5em"></div>
					<div id="url_template" style="display: none;"><?php 
            echo Model\Podcast::get()->get_url_template();
            ?>
</div>
				</td>
			</tr>
			<?php 
        });
        // hidden fields for JavaScript
        ?>
		<input type="hidden" id="podlove_show_media_file_base_uri" value="<?php 
        echo Model\Podcast::get()->media_file_base_uri;
        ?>
">
		<?php 
    }
 public function __construct(Episode $episode)
 {
     $this->episode = $episode;
     $this->post = get_post($episode->post_id);
     $this->podcast = Podcast::get();
 }
function podlove_episode_license_extend_form($form_data, $episode)
{
    $podcast = Model\Podcast::get();
    $license = $episode->get_license();
    $form_data[] = array('type' => 'string', 'key' => 'license_name', 'options' => array('label' => __('License Name', 'podlove')), 'position' => 525);
    $form_data[] = array('type' => 'string', 'key' => 'license_url', 'options' => array('label' => __('License URL', 'podlove'), 'description' => __('Example: http://creativecommons.org/licenses/by/3.0/', 'podlove')), 'position' => 524);
    $form_data[] = array('type' => 'callback', 'key' => 'license_url', 'options' => array('label' => '
				<span id="podlove_cc_license_selector_toggle">
					<span class="_podlove_episode_list_triangle">&#9658;</span>
					<span class="_podlove_episode_list_triangle_expanded">&#9660;</span>
					' . __('License Selector', 'podlove') . '
				</span>
				', 'callback' => function () {
    }), 'position' => 523);
    $form_data[] = array('type' => 'callback', 'key' => 'podlove_cc_license_selector', 'options' => array('label' => '', 'callback' => function () {
        ?>
				<div class="row_podlove_cc_license_selector">
					<div>
						<label for="license_cc_version" class="podlove_cc_license_selector_label">Version</label>
						<select id="license_cc_version">
							<option value="cc0">Public Domain</option>
							<option value="pdmark">Public Domain Mark</option>
							<option value="cc3">Creative Commons 3.0 and earlier</option>
							<option value="cc4">Creative Commons 4.0</option>
						</select>
					</div>
					<div class="podlove-hide">
						<label for="license_cc_allow_modifications" class="podlove_cc_license_selector_label">Allow modifications of your work?</label>
						<select id="license_cc_allow_modifications">
							<option value="yes">Yes</option>
							<option value="yesbutshare">Yes, as long as others share alike</option>
							<option value="no">No</option>
						</select>
					</div>
					<div class="podlove-hide">
						<label for="license_cc_allow_commercial_use" class="podlove_cc_license_selector_label">Allow commercial uses of your work?</label>
						<select id="license_cc_allow_commercial_use">
							<option value="yes">Yes</option>
							<option value="no">No</option>
						</select>
					</div>
					<div class="podlove-hide">
						<label for="license_cc_license_jurisdiction" class="podlove_cc_license_selector_label">License Jurisdiction</label>
						<select id="license_cc_license_jurisdiction">
							<?php 
        foreach (\Podlove\License\locales_cc() as $locale_key => $locale_description) {
            echo "<option value='" . $locale_key . "' " . ($locale_key == 'international' ? "selected='selected'" : '') . ">" . $locale_description . "</option>\n";
        }
        ?>
						</select>
					</div>
				</div>
				<?php 
    }), 'position' => 522);
    $form_data[] = array('type' => 'callback', 'key' => 'podlove_podcast_license_preview', 'options' => array('label' => '', 'callback' => function () {
        ?>
				<div class="row_podlove_podcast_license_preview">
						<span><label for="podlove_podcast_subtitle">License Preview</label></span>
						<p class="podlove_podcast_license_image"></p>
						<div class="podlove_license">
							<p>
								This work is licensed under the 
								<a class="podlove-license-link" rel="license" href=""></a>.
							</p>
						</div>
				</div>
				<?php 
    }), 'position' => 521);
    return $form_data;
}
示例#29
0
 public function podcast()
 {
     $podcast = Model\Podcast::get();
     $podcast_data = array();
     foreach ($podcast->property_names() as $property) {
         $podcast_data[$property] = $podcast->{$property};
     }
     self::respond_with_json($podcast_data);
 }
    /**
     * 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;
    }