/** * Allows VideoPress, YouTube, and Vimeo videos to play inline on Facebook */ function enhanced_og_video($tags) { if (!is_singular() || post_password_required()) { return $tags; } global $post; // Always favor featured images. if (enhanced_og_has_featured_image($post->ID)) { return $tags; } $summary = Jetpack_Media_Summary::get($post->ID); if ('video' != $summary['type']) { if ($summary['count']['video'] > 0 && $summary['count']['image'] < 1) { $tags['og:image'] = $summary['image']; $tags['og:image:secure_url'] = $summary['secure']['image']; } return $tags; } $tags['og:image'] = $summary['image']; $tags['og:image:secure_url'] = $summary['secure']['image']; $tags['og:video:type'] = 'application/x-shockwave-flash'; $video_url = $summary['video']; $secure_video_url = $summary['secure']['video']; if (preg_match('/((youtube|vimeo)\\.com|youtu.be)/', $video_url)) { if (strstr($video_url, 'youtube')) { $id = jetpack_get_youtube_id($video_url); $video_url = 'http://www.youtube.com/v/' . $id . '?version=3&autohide=1'; $secure_video_url = 'https://www.youtube.com/v/' . $id . '?version=3&autohide=1'; } else { if (strstr($video_url, 'vimeo')) { preg_match('|vimeo\\.com/(\\d+)/?$|i', $video_url, $match); $id = (int) $match[1]; $video_url = 'http://vimeo.com/moogaloop.swf?clip_id=' . $id; $secure_video_url = 'https://vimeo.com/moogaloop.swf?clip_id=' . $id; } } } $tags['og:video'] = $video_url; $tags['og:video:secure_url'] = $secure_video_url; if (empty($post->post_title)) { $tags['og:title'] = sprintf(__('Video on %s', 'jetpack'), get_option('blogname')); } return $tags; }
/** * Converts a YouTube URL into an embedded YouTube video. */ function youtube_id($url) { if (!($id = jetpack_get_youtube_id($url))) { return '<!--YouTube Error: bad URL entered-->'; } $url = youtube_sanitize_url($url); $url = parse_url($url); if (!isset($url['query'])) { return false; } if (isset($url['fragment'])) { wp_parse_str($url['fragment'], $fargs); } else { $fargs = array(); } wp_parse_str($url['query'], $qargs); $qargs = array_merge($fargs, $qargs); // calculate the width and height, taking content_width into consideration global $content_width; $input_w = isset($qargs['w']) && intval($qargs['w']) ? intval($qargs['w']) : 0; $input_h = isset($qargs['h']) && intval($qargs['h']) ? intval($qargs['h']) : 0; $default_width = get_option('embed_size_w'); if (empty($default_width)) { if (!empty($content_width)) { $default_width = $content_width; } else { $default_width = 640; } } if ($input_w > 0 && $input_h > 0) { $w = $input_w; $h = $input_h; } elseif (0 == $input_w && 0 == $input_h) { if (isset($qargs['fmt']) && intval($qargs['fmt'])) { $w = !empty($content_width) ? min($content_width, 480) : 480; } else { $w = !empty($content_width) ? min($content_width, $default_width) : $default_width; $h = ceil($w / 16 * 9) + 30; } } elseif ($input_w > 0) { $w = $input_w; $h = ceil($w / 16 * 9) + 30; } else { if (isset($qargs['fmt']) && intval($qargs['fmt'])) { $w = !empty($content_width) ? min($content_width, 480) : 480; } else { $w = !empty($content_width) ? min($content_width, $default_width) : $default_width; $h = $input_h; } } /** * Filter the YouTube player width. * * @module shortcodes * * @since 1.1.0 * * @param int $w Width of the YouTube player in pixels. */ $w = (int) apply_filters('youtube_width', $w); /** * Filter the YouTube player height. * * @module shortcodes * * @since 1.1.0 * * @param int $h Height of the YouTube player in pixels. */ $h = (int) apply_filters('youtube_height', $h); $rel = isset($qargs['rel']) && 0 == $qargs['rel'] ? 0 : 1; $search = isset($qargs['showsearch']) && 1 == $qargs['showsearch'] ? 1 : 0; $info = isset($qargs['showinfo']) && 0 == $qargs['showinfo'] ? 0 : 1; $iv = isset($qargs['iv_load_policy']) && 3 == $qargs['iv_load_policy'] ? 3 : 1; $fmt = isset($qargs['fmt']) && intval($qargs['fmt']) ? '&fmt=' . (int) $qargs['fmt'] : ''; if (!isset($qargs['autohide']) || ($qargs['autohide'] < 0 || 2 < $qargs['autohide'])) { $autohide = '&autohide=2'; } else { $autohide = '&autohide=' . absint($qargs['autohide']); } $start = 0; if (isset($qargs['start'])) { $start = intval($qargs['start']); } else { if (isset($qargs['t'])) { $time_pieces = preg_split('/(?<=\\D)(?=\\d+)/', $qargs['t']); foreach ($time_pieces as $time_piece) { $int = (int) $time_piece; switch (substr($time_piece, -1)) { case 'h': $start += $int * 3600; break; case 'm': $start += $int * 60; break; case 's': $start += $int; break; } } } } $start = $start ? '&start=' . $start : ''; $end = isset($qargs['end']) && intval($qargs['end']) ? '&end=' . (int) $qargs['end'] : ''; $hd = isset($qargs['hd']) && intval($qargs['hd']) ? '&hd=' . (int) $qargs['hd'] : ''; $vq = isset($qargs['vq']) && in_array($qargs['vq'], array('hd720', 'hd1080')) ? '&vq=' . $qargs['vq'] : ''; $cc = isset($qargs['cc_load_policy']) ? '&cc_load_policy=1' : ''; $cc_lang = isset($qargs['cc_lang_pref']) ? '&cc_lang_pref=' . preg_replace('/[^_a-z0-9-]/i', '', $qargs['cc_lang_pref']) : ''; $wmode = isset($qargs['wmode']) && in_array(strtolower($qargs['wmode']), array('opaque', 'window', 'transparent')) ? $qargs['wmode'] : 'transparent'; $theme = isset($qargs['theme']) && in_array(strtolower($qargs['theme']), array('dark', 'light')) ? '&theme=' . $qargs['theme'] : ''; $autoplay = ''; /** * Allow YouTube videos to start playing automatically. * * @module shortcodes * * @since 2.2.2 * * @param bool false Enable autoplay for YouTube videos. */ if (apply_filters('jetpack_youtube_allow_autoplay', false) && isset($qargs['autoplay'])) { $autoplay = '&autoplay=' . (int) $qargs['autoplay']; } $alignmentcss = 'text-align:center;'; if (isset($qargs['align'])) { switch ($qargs['align']) { case 'left': $alignmentcss = "float:left; width:{$w}px; height:{$h}px; margin-right:10px; margin-bottom: 10px;"; break; case 'right': $alignmentcss = "float:right; width:{$w}px; height:{$h}px; margin-left:10px; margin-bottom: 10px;"; break; } } if (isset($url['path']) && '/videoseries' == $url['path'] || isset($qargs['list'])) { $html = "<span class='embed-youtube' style='{$alignmentcss} display: block;'><iframe class='youtube-player' type='text/html' width='{$w}' height='{$h}' src='" . esc_url(set_url_scheme("http://www.youtube.com/embed/videoseries?list={$id}&hl=en_US")) . "' frameborder='0' allowfullscreen='true'></iframe></span>"; } else { $html = "<span class='embed-youtube' style='{$alignmentcss} display: block;'><iframe class='youtube-player' type='text/html' width='{$w}' height='{$h}' src='" . esc_url(set_url_scheme("http://www.youtube.com/embed/{$id}?version=3&rel={$rel}&fs=1{$fmt}{$autohide}&showsearch={$search}&showinfo={$info}&iv_load_policy={$iv}{$start}{$end}{$hd}&wmode={$wmode}{$theme}{$autoplay}{$cc}{$cc_lang}")) . "' frameborder='0' allowfullscreen='true'></iframe></span>"; } /** * Filter the YouTube video HTML output. * * @module shortcodes * * @since 1.2.3 * * @param string $html YouTube video HTML output. */ $html = apply_filters('video_embed_html', $html); return $html; }
/** * Required for class.media-extractor.php to match expected function naming convention. * * @param $url Can be just the $url or the whole $atts array * @return bool|mixed The Youtube video ID via jetpack_get_youtube_id */ function jetpack_shortcode_get_youtube_id($url) { return jetpack_get_youtube_id($url); }
static function get($post_id, $blog_id = 0, $args = array()) { $defaults = array('max_words' => 16, 'max_chars' => 256); $args = wp_parse_args($args, $defaults); $switched = false; if (!empty($blog_id) && $blog_id != get_current_blog_id() && function_exists('switch_to_blog')) { switch_to_blog($blog_id); $switched = true; } else { $blog_id = get_current_blog_id(); } $post = get_post($post_id); $permalink = get_permalink($post_id); $return = array('type' => 'standard', 'permalink' => $permalink, 'image' => '', 'excerpt' => '', 'word_count' => 0, 'secure' => array('image' => ''), 'count' => array('image' => 0, 'video' => 0, 'word' => 0, 'link' => 0)); if (empty($post->post_password)) { $return['excerpt'] = self::get_excerpt($post->post_content, $post->post_excerpt, $args['max_words'], $args['max_chars']); $return['count']['word'] = self::get_word_count($post->post_content); $return['count']['word_remaining'] = self::get_word_remaining_count($post->post_content, $return['excerpt']); $return['count']['link'] = self::get_link_count($post->post_content); } $extract = Jetpack_Media_Meta_Extractor::extract($blog_id, $post_id, Jetpack_Media_Meta_Extractor::ALL); if (empty($extract['has'])) { return $return; } // Prioritize [some] video embeds if (!empty($extract['has']['shortcode'])) { foreach ($extract['shortcode'] as $type => $data) { switch ($type) { case 'wpvideo': if (0 == $return['count']['video']) { $return['type'] = 'video'; $return['video'] = esc_url_raw('http://s0.videopress.com/player.swf?guid=' . $extract['shortcode']['wpvideo']['id'][0] . '&isDynamicSeeking=true'); $return['image'] = self::get_video_poster('videopress', $extract['shortcode']['wpvideo']['id'][0]); $return['secure']['video'] = preg_replace('@http://[^\\.]+.videopress.com/@', 'https://v0.wordpress.com/', $return['video']); $return['secure']['image'] = str_replace('http://videos.videopress.com', 'https://videos.files.wordpress.com', $return['image']); } $return['count']['video']++; break; case 'youtube': if (0 == $return['count']['video']) { $return['type'] = 'video'; $return['video'] = esc_url_raw('http://www.youtube.com/watch?feature=player_embedded&v=' . $extract['shortcode']['youtube']['id'][0]); $return['image'] = self::get_video_poster('youtube', $extract['shortcode']['youtube']['id'][0]); $return['secure']['video'] = self::https($return['video']); $return['secure']['image'] = self::https($return['image']); } $return['count']['video']++; break; case 'vimeo': if (0 == $return['count']['video']) { $return['type'] = 'video'; $return['video'] = esc_url_raw('http://vimeo.com/' . $extract['shortcode']['vimeo']['id'][0]); $return['secure']['video'] = self::https($return['video']); $poster_image = get_post_meta($post_id, 'vimeo_poster_image', true); if (!empty($poster_image)) { $return['image'] = $poster_image; $poster_url_parts = parse_url($poster_image); $return['secure']['image'] = 'https://secure-a.vimeocdn.com' . $poster_url_parts['path']; } } $return['count']['video']++; break; } } } if (!empty($extract['has']['embed'])) { foreach ($extract['embed']['url'] as $embed) { if (preg_match('/((youtube|vimeo|dailymotion)\\.com|youtu.be)/', $embed)) { if (0 == $return['count']['video']) { $return['type'] = 'video'; $return['video'] = 'http://' . $embed; $return['secure']['video'] = self::https($return['video']); if (false !== strpos($embed, 'youtube')) { $return['image'] = self::get_video_poster('youtube', jetpack_get_youtube_id($return['video'])); $return['secure']['image'] = self::https($return['image']); } else { if (false !== strpos($embed, 'youtu.be')) { $youtube_id = jetpack_get_youtube_id($return['video']); $return['video'] = 'http://youtube.com/watch?v=' . $youtube_id . '&feature=youtu.be'; $return['secure']['video'] = self::https($return['video']); $return['image'] = self::get_video_poster('youtube', jetpack_get_youtube_id($return['video'])); $return['secure']['image'] = self::https($return['image']); } else { if (false !== strpos($embed, 'vimeo')) { $poster_image = get_post_meta($post_id, 'vimeo_poster_image', true); if (!empty($poster_image)) { $return['image'] = $poster_image; $poster_url_parts = parse_url($poster_image); $return['secure']['image'] = 'https://secure-a.vimeocdn.com' . $poster_url_parts['path']; } } else { if (false !== strpos($embed, 'dailymotion')) { $return['image'] = str_replace('dailymotion.com/video/', 'dailymotion.com/thumbnail/video/', $embed); $return['image'] = parse_url($return['image'], PHP_URL_SCHEME) === null ? 'http://' . $return['image'] : $return['image']; $return['secure']['image'] = self::https($return['image']); } } } } } $return['count']['video']++; } } } // Do we really want to make the video the primary focus of the post? if ('video' == $return['type']) { $content = wpautop(strip_tags($post->post_content)); $paragraphs = explode('</p>', $content); $number_of_paragraphs = 0; foreach ($paragraphs as $i => $paragraph) { // Don't include blank lines as a paragraph if ('' == trim($paragraph)) { unset($paragraphs[$i]); continue; } $number_of_paragraphs++; } $number_of_paragraphs = $number_of_paragraphs - $return['count']['video']; // subtract amount for videos.. // More than 2 paragraph? The video is not the primary focus so we can do some more analysis if ($number_of_paragraphs > 2) { $return['type'] = 'standard'; } } // If we don't have any prioritized embed... if ('standard' == $return['type']) { if ((!empty($extract['has']['gallery']) || !empty($extract['shortcode']['gallery']['count'])) && !empty($extract['image'])) { //... Then we prioritize galleries first (multiple images returned) $return['type'] = 'gallery'; $return['images'] = $extract['image']; foreach ($return['images'] as $image) { $return['secure']['images'][] = array('url' => self::ssl_img($image['url'])); $return['count']['image']++; } } else { if (!empty($extract['has']['image'])) { // ... Or we try and select a single image that would make sense $content = wpautop(strip_tags($post->post_content)); $paragraphs = explode('</p>', $content); $number_of_paragraphs = 0; foreach ($paragraphs as $i => $paragraph) { // Don't include 'actual' captions as a paragraph if (false !== strpos($paragraph, '[caption')) { unset($paragraphs[$i]); continue; } // Don't include blank lines as a paragraph if ('' == trim($paragraph)) { unset($paragraphs[$i]); continue; } $number_of_paragraphs++; } $return['image'] = $extract['image'][0]['url']; $return['secure']['image'] = self::ssl_img($return['image']); $return['count']['image']++; if ($number_of_paragraphs <= 2 && 1 == count($extract['image'])) { // If we have lots of text or images, let's not treat it as an image post, but return its first image $return['type'] = 'image'; } } } } if ($switched) { restore_current_blog(); } return $return; }
/** * @author enkrates * @covers ::jetpack_get_youtube_id * @since 3.2 */ public function test_jetpack_get_youtube_id_with_playlist_url() { $playlist_url = 'https://www.youtube.com/playlist?list=PL56C3506BBE979C1B'; $expected_id = 'PL56C3506BBE979C1B'; $youtube_id = jetpack_get_youtube_id($playlist_url); $this->assertEquals($expected_id, $youtube_id); }
static function get($post_id, $blog_id = 0, $args = array()) { $defaults = array('max_words' => 16, 'max_chars' => 256); $args = wp_parse_args($args, $defaults); $switched = false; if (!empty($blog_id) && $blog_id != get_current_blog_id() && function_exists('switch_to_blog')) { switch_to_blog($blog_id); $switched = true; } else { $blog_id = get_current_blog_id(); } if (!class_exists('Jetpack_Media_Meta_Extractor')) { jetpack_require_lib('class.media-extractor'); } $post = get_post($post_id); $permalink = get_permalink($post_id); $return = array('type' => 'standard', 'permalink' => $permalink, 'image' => '', 'excerpt' => '', 'word_count' => 0, 'secure' => array('image' => ''), 'count' => array('image' => 0, 'video' => 0, 'word' => 0, 'link' => 0)); if (empty($post->post_password)) { $return['excerpt'] = self::get_excerpt($post->post_content, $post->post_excerpt, $args['max_words'], $args['max_chars']); $return['count']['word'] = self::get_word_count($post->post_content); $return['count']['word_remaining'] = self::get_word_remaining_count($post->post_content, $return['excerpt']); $return['count']['link'] = self::get_link_count($post->post_content); } $extract = Jetpack_Media_Meta_Extractor::extract($blog_id, $post_id, Jetpack_Media_Meta_Extractor::ALL); if (empty($extract['has'])) { return $return; } // Prioritize [some] video embeds if (!empty($extract['has']['shortcode'])) { foreach ($extract['shortcode'] as $type => $data) { switch ($type) { case 'videopress': case 'wpvideo': if (0 == $return['count']['video']) { // If there is no id on the video, then let's just skip this if (!isset($data['id'][0])) { continue; } $guid = $data['id'][0]; $video_info = videopress_get_video_details($guid); // Only add the video tags if the guid returns a valid videopress object. if ($video_info instanceof stdClass) { // Continue early if we can't find a Video slug. if (empty($video_info->files->std->mp4)) { continue; } $url = sprintf('https://videos.files.wordpress.com/%1$s/%2$s', $guid, $video_info->files->std->mp4); $thumbnail = $video_info->poster; if (!empty($thumbnail)) { $return['image'] = $thumbnail; $return['secure']['image'] = $thumbnail; } $return['type'] = 'video'; $return['video'] = esc_url_raw($url); $return['video_type'] = 'video/mp4'; $return['secure']['video'] = $return['video']; } } $return['count']['video']++; break; case 'youtube': if (0 == $return['count']['video']) { $return['type'] = 'video'; $return['video'] = esc_url_raw('http://www.youtube.com/watch?feature=player_embedded&v=' . $extract['shortcode']['youtube']['id'][0]); $return['image'] = self::get_video_poster('youtube', $extract['shortcode']['youtube']['id'][0]); $return['secure']['video'] = self::https($return['video']); $return['secure']['image'] = self::https($return['image']); } $return['count']['video']++; break; case 'vimeo': if (0 == $return['count']['video']) { $return['type'] = 'video'; $return['video'] = esc_url_raw('http://vimeo.com/' . $extract['shortcode']['vimeo']['id'][0]); $return['secure']['video'] = self::https($return['video']); $poster_image = get_post_meta($post_id, 'vimeo_poster_image', true); if (!empty($poster_image)) { $return['image'] = $poster_image; $poster_url_parts = parse_url($poster_image); $return['secure']['image'] = 'https://secure-a.vimeocdn.com' . $poster_url_parts['path']; } } $return['count']['video']++; break; } } } if (!empty($extract['has']['embed'])) { foreach ($extract['embed']['url'] as $embed) { if (preg_match('/((youtube|vimeo|dailymotion)\\.com|youtu.be)/', $embed)) { if (0 == $return['count']['video']) { $return['type'] = 'video'; $return['video'] = 'http://' . $embed; $return['secure']['video'] = self::https($return['video']); if (false !== strpos($embed, 'youtube')) { $return['image'] = self::get_video_poster('youtube', jetpack_get_youtube_id($return['video'])); $return['secure']['image'] = self::https($return['image']); } else { if (false !== strpos($embed, 'youtu.be')) { $youtube_id = jetpack_get_youtube_id($return['video']); $return['video'] = 'http://youtube.com/watch?v=' . $youtube_id . '&feature=youtu.be'; $return['secure']['video'] = self::https($return['video']); $return['image'] = self::get_video_poster('youtube', jetpack_get_youtube_id($return['video'])); $return['secure']['image'] = self::https($return['image']); } else { if (false !== strpos($embed, 'vimeo')) { $poster_image = get_post_meta($post_id, 'vimeo_poster_image', true); if (!empty($poster_image)) { $return['image'] = $poster_image; $poster_url_parts = parse_url($poster_image); $return['secure']['image'] = 'https://secure-a.vimeocdn.com' . $poster_url_parts['path']; } } else { if (false !== strpos($embed, 'dailymotion')) { $return['image'] = str_replace('dailymotion.com/video/', 'dailymotion.com/thumbnail/video/', $embed); $return['image'] = parse_url($return['image'], PHP_URL_SCHEME) === null ? 'http://' . $return['image'] : $return['image']; $return['secure']['image'] = self::https($return['image']); } } } } } $return['count']['video']++; } } } // Do we really want to make the video the primary focus of the post? if ('video' == $return['type']) { $content = wpautop(strip_tags($post->post_content)); $paragraphs = explode('</p>', $content); $number_of_paragraphs = 0; foreach ($paragraphs as $i => $paragraph) { // Don't include blank lines as a paragraph if ('' == trim($paragraph)) { unset($paragraphs[$i]); continue; } $number_of_paragraphs++; } $number_of_paragraphs = $number_of_paragraphs - $return['count']['video']; // subtract amount for videos.. // More than 2 paragraph? The video is not the primary focus so we can do some more analysis if ($number_of_paragraphs > 2) { $return['type'] = 'standard'; } } // If we don't have any prioritized embed... if ('standard' == $return['type']) { if ((!empty($extract['has']['gallery']) || !empty($extract['shortcode']['gallery']['count'])) && !empty($extract['image'])) { //... Then we prioritize galleries first (multiple images returned) $return['type'] = 'gallery'; $return['images'] = $extract['image']; foreach ($return['images'] as $image) { $return['secure']['images'][] = array('url' => self::ssl_img($image['url'])); $return['count']['image']++; } } else { if (!empty($extract['has']['image'])) { // ... Or we try and select a single image that would make sense $content = wpautop(strip_tags($post->post_content)); $paragraphs = explode('</p>', $content); $number_of_paragraphs = 0; foreach ($paragraphs as $i => $paragraph) { // Don't include 'actual' captions as a paragraph if (false !== strpos($paragraph, '[caption')) { unset($paragraphs[$i]); continue; } // Don't include blank lines as a paragraph if ('' == trim($paragraph)) { unset($paragraphs[$i]); continue; } $number_of_paragraphs++; } $return['image'] = $extract['image'][0]['url']; $return['secure']['image'] = self::ssl_img($return['image']); $return['count']['image']++; if ($number_of_paragraphs <= 2 && 1 == count($extract['image'])) { // If we have lots of text or images, let's not treat it as an image post, but return its first image $return['type'] = 'image'; } } } } if ($switched) { restore_current_blog(); } /** * Allow a theme or plugin to inspect and ultimately change the media summary. * * @since 4.4.0 * * @param array $data The calculated media summary data. * @param int $post_id The id of the post this data applies to. */ $return = apply_filters('jetpack_media_summary_output', $return, $post_id); return $return; }