Example #1
0
 private function html()
 {
     if (!count($this->args['data']['feeds'])) {
         return '';
     }
     $dataAccessor = 'podcastData' . self::get_random_string();
     $dom = new \Podlove\DomDocumentFragment();
     $script_data_tag = $dom->createElement('script');
     $script_data_tag->appendChild($dom->createTextNode(sprintf("window.{$dataAccessor} = %s;", json_encode($this->args['data']))));
     $script_button_tag = $dom->createElement('script');
     $script_button_tag->setAttribute('class', 'podlove-subscribe-button');
     $script_button_tag->setAttribute('src', 'https://cdn.podlove.org/subscribe-button/javascripts/app.js');
     $script_button_tag->setAttribute('data-json-data', $dataAccessor);
     $script_button_tag->setAttribute('data-language', self::language($this->args['language']));
     $script_button_tag->setAttribute('data-size', self::size($this->args['size'], $this->args['width']));
     if ($this->args['colors']) {
         $script_button_tag->setAttribute('data-colors', $this->args['colors']);
     }
     if ($this->args['buttonid']) {
         $script_button_tag->setAttribute('data-buttonid', $this->args['buttonid']);
     }
     if ($this->args['hide'] && in_array($args['hide'], [1, '1', true, 'true', 'on'])) {
         $script_button_tag->setAttribute('data-hide', true);
     }
     // ensure there is a closing script tag
     $script_button_tag->appendChild($dom->createTextNode(' '));
     $dom->appendChild($script_data_tag);
     $dom->appendChild($script_button_tag);
     return (string) $dom;
 }
Example #2
0
 /**
  * Get HTML image tag for resized image.
  * 
  * Examples
  * 
  * 	$image->image(); // returns image tag
  * 
  * @param  array $args List of arguments
  * 		- id: Set image tag "id" attribute.
  * 		- class: Set image tag "class" attribute.
  * 		- style: Set image tag "style" attribute.
  * 		- alt: Set image tag "alt" attribute.
  * 		- title: Set image tag "title" attribute.
  *      - width: Image width. Set width and leave height blank to keep the orinal aspect ratio.
  * 		- height: Image height. Set height and leave width blank to keep the orinal aspect ratio.
  *   	- attributes: List of other HTML attributes, for example: ['data-foo' => 'bar']
  * @return string HTML image tag
  */
 public function image($args = [])
 {
     $defaults = ['id' => '', 'class' => '', 'style' => '', 'alt' => '', 'title' => '', 'width' => $this->width, 'height' => $this->height, 'attributes' => []];
     $args = wp_parse_args($args, $defaults);
     // put everything in 'attributes' for easy iteration
     foreach (['id', 'class', 'style', 'alt', 'title', 'width', 'height'] as $attr) {
         if ($args[$attr]) {
             $args['attributes'][$attr] = $args[$attr];
         }
     }
     $dom = new \Podlove\DomDocumentFragment();
     $img = $dom->createElement('img');
     foreach ($args['attributes'] as $key => $value) {
         $img->setAttribute($key, $value);
     }
     $img->setAttribute('src', $this->url());
     if ($this->retina && ($srcset = $this->srcset())) {
         $img->setAttribute('srcset', $srcset);
     }
     $dom->appendChild($img);
     return (string) $dom;
 }
function override_feed_head($hook, $podcast, $feed, $format)
{
    $filter_hooks = array('podlove_feed_itunes_author', 'podlove_feed_itunes_owner', 'podlove_feed_itunes_subtitle', 'podlove_feed_itunes_keywords', 'podlove_feed_itunes_summary', 'podlove_feed_itunes_complete', 'podlove_feed_itunes_explicit');
    foreach ($filter_hooks as $filter) {
        add_filter($filter, 'convert_chars');
    }
    add_filter('podlove_feed_content', '\\Podlove\\Feeds\\prepare_for_feed');
    remove_action($hook, 'the_generator');
    add_action($hook, function () use($hook) {
        switch ($hook) {
            case 'rss2_head':
                $gen = '<generator>' . \Podlove\get_plugin_header('Name') . ' v' . \Podlove\get_plugin_header('Version') . '</generator>';
                break;
            case 'atom_head':
                $gen = '<generator uri="' . \Podlove\get_plugin_header('PluginURI') . '" version="' . \Podlove\get_plugin_header('Version') . '">' . \Podlove\get_plugin_header('Name') . '</generator>';
                break;
        }
        echo $gen;
    });
    add_action($hook, function () use($feed) {
        echo $feed->get_self_link();
        echo $feed->get_alternate_links();
    }, 9);
    // add rss image
    add_action($hook, function () use($podcast, $hook) {
        $image = ['url' => $podcast->cover_art()->url(), 'title' => $podcast->title, 'link' => apply_filters('podlove_feed_link', \Podlove\get_landing_page_url())];
        $image = apply_filters('podlove_feed_image', $image);
        if (!$image['url']) {
            return;
        }
        // remove WordPress provided favicon
        remove_action($hook, 'rss2_site_icon');
        // generate our own image tag
        $dom = new \Podlove\DomDocumentFragment();
        $image_tag = $dom->createElement('image');
        foreach ($image as $tag_name => $tag_text) {
            if ($tag_text) {
                $tag = $dom->createElement($tag_name);
                $tag_text = $dom->createTextNode($tag_text);
                $tag->appendChild($tag_text);
                $image_tag->appendChild($tag);
            }
        }
        $dom->appendChild($image_tag);
        echo (string) $dom;
    }, 5);
    // let it run early so we can stop the `rss2_site_icon` call
    add_action($hook, function () use($podcast, $feed, $format) {
        echo PHP_EOL;
        $author = "\t" . sprintf('<itunes:author>%s</itunes:author>', $podcast->author_name);
        echo apply_filters('podlove_feed_itunes_author', $author);
        echo PHP_EOL;
        $summary = "\t" . sprintf('<itunes:summary>%s</itunes:summary>', $podcast->summary);
        echo apply_filters('podlove_feed_itunes_summary', $summary);
        echo PHP_EOL;
        $categories = \Podlove\Itunes\categories(false);
        $category_html = '';
        for ($i = 1; $i <= 3; $i++) {
            $category_id = $podcast->{'category_' . $i};
            if (!$category_id) {
                continue;
            }
            list($cat, $subcat) = explode('-', $category_id);
            if ($subcat == '00') {
                $category_html .= sprintf('<itunes:category text="%s"></itunes:category>', htmlspecialchars($categories[$category_id]));
            } else {
                $category_html .= sprintf('<itunes:category text="%s"><itunes:category text="%s"></itunes:category></itunes:category>', htmlspecialchars($categories[$cat . '-00']), htmlspecialchars($categories[$category_id]));
            }
        }
        echo apply_filters('podlove_feed_itunes_categories', $category_html);
        echo PHP_EOL;
        $owner = sprintf('
	<itunes:owner>
		<itunes:name>%s</itunes:name>
		<itunes:email>%s</itunes:email>
	</itunes:owner>', $podcast->owner_name, $podcast->owner_email);
        echo "\t" . apply_filters('podlove_feed_itunes_owner', $owner);
        echo PHP_EOL;
        if ($podcast->cover_art()->url()) {
            $coverimage = sprintf('<itunes:image href="%s" />', $podcast->cover_art()->url());
        } else {
            $coverimage = '';
        }
        echo "\t" . apply_filters('podlove_feed_itunes_image', $coverimage);
        echo PHP_EOL;
        $subtitle = sprintf('<itunes:subtitle>%s</itunes:subtitle>', $podcast->subtitle);
        echo "\t" . apply_filters('podlove_feed_itunes_subtitle', $subtitle);
        echo PHP_EOL;
        $keywords = sprintf('<itunes:keywords>%s</itunes:keywords>', $podcast->keywords);
        echo "\t" . apply_filters('podlove_feed_itunes_keywords', $keywords);
        echo PHP_EOL;
        $block = sprintf('<itunes:block>%s</itunes:block>', $feed->enable ? 'no' : 'yes');
        echo "\t" . apply_filters('podlove_feed_itunes_block', $block);
        echo PHP_EOL;
        $explicit = sprintf('<itunes:explicit>%s</itunes:explicit>', $podcast->explicit == 2 ? 'clean' : ($podcast->explicit ? 'yes' : 'no'));
        echo "\t" . apply_filters('podlove_feed_itunes_explicit', $explicit);
        echo PHP_EOL;
        $complete = sprintf('<itunes:complete>%s</itunes:complete>', $podcast->complete ? 'yes' : 'no');
        echo apply_filters('podlove_feed_itunes_complete', $podcast->complete ? "\t{$complete}" : '');
        echo PHP_EOL;
        do_action('podlove_append_to_feed_head', $podcast, $feed, $format);
    });
}
 public static function prepare_feed($feed_slug)
 {
     global $wp_query;
     add_action('rss2_ns', function () {
         echo 'xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" ';
         echo 'xmlns:psc="http://podlove.org/simple-chapters" ';
         echo 'xmlns:content="http://purl.org/rss/1.0/modules/content/" ';
         echo 'xmlns:fh="http://purl.org/syndication/history/1.0" ';
     });
     $podcast = Model\Podcast::get();
     if (!($feed = Model\Feed::find_one_by_slug($feed_slug))) {
         self::wp_404();
     }
     if (!($episode_asset = $feed->episode_asset())) {
         self::wp_404();
     }
     $file_type = $episode_asset->file_type();
     add_filter('podlove_feed_enclosure', function ($enclosure, $enclosure_url, $enclosure_file_size, $mime_type, $media_file) {
         if ($enclosure_file_size < 0) {
             $enclosure_file_size = 0;
         }
         $dom = new \Podlove\DomDocumentFragment();
         $element = $dom->createElement('enclosure');
         $attributes = ['url' => $enclosure_url, 'length' => $enclosure_file_size, 'type' => $mime_type];
         $attributes = apply_filters('podlove_feed_enclosure_attributes', $attributes, $media_file);
         foreach ($attributes as $k => $v) {
             $element->setAttribute($k, $v);
         }
         $dom->appendChild($element);
         return (string) $dom;
     }, 10, 5);
     override_feed_title($feed);
     override_feed_description($feed);
     override_feed_language($feed);
     override_feed_head('rss2_head', $podcast, $feed, $file_type);
     override_feed_entry('rss2_item', $podcast, $feed, $file_type);
     add_action('rss2_item', function () {
         if (apply_filters('podlove_feed_show_summary', true)) {
             echo "<description><![CDATA[";
             \Podlove\Feeds\the_description();
             echo "]]></description>";
         }
     }, 9);
     add_action('rss2_head', function () use($podcast, $feed) {
         global $wp_query;
         $current_page = get_query_var('paged') ? get_query_var('paged') : 1;
         $feed_url_for_page = function ($page) use($feed) {
             $url = $feed->get_subscribe_url();
             if ($page > 0) {
                 $url .= '?paged=' . $page;
             }
             return $url;
         };
         if ($current_page < $wp_query->max_num_pages) {
             echo "\n\t" . sprintf('<atom:link rel="next" href="%s" />', $feed_url_for_page($current_page + 1));
         }
         if ($current_page > 2) {
             echo "\n\t" . sprintf('<atom:link rel="prev" href="%s" />', $feed_url_for_page($current_page - 1));
         } elseif ($current_page == 2) {
             echo "\n\t" . sprintf('<atom:link rel="prev" href="%s" />', $feed_url_for_page(0));
         }
         echo "\n\t" . sprintf('<atom:link rel="first" href="%s" />', $feed_url_for_page(0));
         if ($wp_query->max_num_pages > 1) {
             echo "\n\t" . sprintf('<atom:link rel="last" href="%s" />', $feed_url_for_page($wp_query->max_num_pages));
         }
         if ($podcast->language) {
             echo "\n\t" . '<language>' . $podcast->language . '</language>';
         }
         do_action('podlove_rss2_head', $feed);
     }, 9);
     $posts_per_page = $feed->limit_items == 0 ? get_option('posts_per_rss') : $feed->limit_items;
     if ($posts_per_page == Model\Feed::ITEMS_GLOBAL_LIMIT) {
         $posts_per_page = $podcast->limit_items;
     }
     // now override the option so WP core functions accessing the option get the "correct" value
     add_filter('pre_option_posts_per_rss', function ($_) use($posts_per_page) {
         return $posts_per_page;
     });
     $args = array('post_type' => 'podcast', 'post__in' => $feed->post_ids(), 'posts_per_page' => $posts_per_page);
     # The theme "getnoticed" globally overrides post_types in pre_get_posts.
     # Fix: hook in after the theme and override it again.
     # It's not bad practice because I *really* only want episodes in this feed.
     add_action('pre_get_posts', function ($query) {
         $query->set('post_type', 'podcast');
     }, 20);
     /**
      * In feeds, WordPress ignores the 'posts_per_page' parameter 
      * and overrides it with the 'posts_per_rss' option. So we need to
      * override that option.
      */
     add_filter('post_limits', function ($limits) use($feed) {
         $page = get_query_var('paged') ? (int) get_query_var('paged') : 1;
         $max = $feed->get_post_limit_sql();
         $start = $max * ($page - 1);
         if ($max > 0) {
             return 'LIMIT ' . $start . ', ' . $max;
         } else {
             return '';
         }
     });
     $args = array_merge($wp_query->query_vars, $args);
     query_posts($args);
 }