* @copyright Copyright (c) 2008 - 2015, Justin Tadlock * @link http://themehybrid.com/hybrid-core * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html */ if ( ! function_exists( 'hybrid_media_grabber' ) ) { /** * Wrapper function for the Hybrid_Media_Grabber class. Returns the HTML output for the found media. * * @param array * * @return string * @since 1.6.0 * @access public */ function hybrid_media_grabber( $args = array() ) { $media = new Hybrid_Media_Grabber( $args ); return $media->get_media(); } } if ( ! class_exists( 'Hybrid_Media_Grabber' ) ) { /** * Grabs media related to the post. * * @return void * @since 1.6.0 * @access public */ class Hybrid_Media_Grabber { /** * The HTML version of the media to return. * * @since 1.6.0 * @access public * @var string */ public $media = ''; /** * The original media taken from the post content. * * @since 1.6.0 * @access public * @var string */ public $original_media = ''; /** * The type of media to get. Current supported types are 'audio' and 'video'. * * @since 1.6.0 * @access public * @var string */ public $type = 'video'; /** * Arguments passed into the class and parsed with the defaults. * * @since 1.6.0 * @access public * @var array */ public $args = array(); /** * The content to search for embedded media within. * * @since 1.6.0 * @access public * @var string */ public $content = ''; /** * Constructor method. Sets up the media grabber. * * @return void * @global object $wp_embed * @global int $content_width * @since 1.6.0 * @access public */ public function __construct( $args = array() ) { global $wp_embed, $content_width; // Use WP's embed functionality to handle the [embed] shortcode and autoembeds. add_filter( 'hybrid_media_grabber_embed_shortcode_media', array( $wp_embed, 'run_shortcode' ) ); add_filter( 'hybrid_media_grabber_autoembed_media', array( $wp_embed, 'autoembed' ) ); // Don't return a link if embeds don't work. Need media or nothing at all. add_filter( 'embed_maybe_make_link', '__return_false' ); // Set up the default arguments. $defaults = array( 'post_id' => get_the_ID(), // post ID (assumes within The Loop by default) 'type' => 'video', // audio|video 'before' => '', // HTML before the output 'after' => '', // HTML after the output 'split_media' => false, // Splits the media from the post content 'width' => $content_width, // Custom width. Defaults to the theme's content width. ); // Set the object properties. $this->args = apply_filters( 'hybrid_media_grabber_args', wp_parse_args( $args, $defaults ) ); $this->content = get_post_field( 'post_content', $this->args['post_id'], 'raw' ); $this->type = isset( $this->args['type'] ) && in_array( $this->args['type'], array( 'audio', 'video' ) ) ? $this->args['type'] : 'video'; // Find the media related to the post. $this->set_media(); } /** * Destructor method. Removes filters we needed to add. * * @return void * @since 1.6.0 * @access public */ public function __destruct() { remove_filter( 'embed_maybe_make_link', '__return_false' ); remove_filter( 'the_content', array( $this, 'split_media' ), 5 ); } /** * Basic method for returning the media found. * * @return string * @since 1.6.0 * @access public */ public function get_media() { return apply_filters( 'hybrid_media_grabber_media', $this->media, $this ); } /** * Tries several methods to find media related to the post. Returns the found media. * * @return void * @since 1.6.0 * @access public */ public function set_media() { // Get the media if the post type is an attachment. if ( 'attachment' === get_post_type( $this->args['post_id'] ) ) { $this->do_attachment_media(); } // Find media in the post content based on WordPress' media-related shortcodes. if ( empty( $this->media ) ) { $this->do_shortcode_media(); } // If no media is found and autoembeds are enabled, check for autoembeds. if ( empty( $this->media ) && get_option( 'embed_autourls' ) ) { $this->do_autoembed_media(); } // If no media is found, check for media HTML within the post content. if ( empty( $this->media ) ) { $this->do_embedded_media(); } // If no media is found, check for media attached to the post. if ( empty( $this->media ) ) { $this->do_attached_media(); } // If media is found, let's run a few things. if ( ! empty( $this->media ) ) { // Add the before HTML. if ( isset( $this->args['before'] ) ) { $this->media = $this->args['before'] . $this->media; } // Add the after HTML. if ( isset( $this->args['after'] ) ) { $this->media .= $this->args['after']; } // Split the media from the content. if ( true === $this->args['split_media'] && ! empty( $this->original_media ) ) { add_filter( 'the_content', array( $this, 'split_media' ), 5 ); } // Filter the media dimensions. $this->media = $this->filter_dimensions( $this->media ); } } /** * WordPress has a few shortcodes for handling embedding media: [audio], [video], and [embed]. This * method figures out the shortcode used in the content. Once it's found, the appropriate method for * the shortcode is executed. * * @return void * @since 1.6.0 * @access public */ public function do_shortcode_media() { // Finds matches for shortcodes in the content. preg_match_all( '/' . get_shortcode_regex() . '/s', $this->content, $matches, PREG_SET_ORDER ); // If matches are found, loop through them and check if they match one of WP's media shortcodes. if ( ! empty( $matches ) ) { foreach ( $matches as $shortcode ) { // Call the method related to the specific shortcode found and break out of the loop. if ( in_array( $shortcode[2], array( 'playlist', 'embed', $this->type ) ) ) { call_user_func( array( $this, "do_{$shortcode[2]}_shortcode_media" ), $shortcode ); break; } // Check for Jetpack audio/video shortcodes. elseif ( in_array( $shortcode[2], array( 'blip.tv', 'dailymotion', 'flickr', 'ted', 'vimeo', 'vine', 'youtube', 'wpvideo', 'soundcloud', 'bandcamp' ) ) ) { $this->do_jetpack_shortcode_media( $shortcode ); break; } } } } /** * Handles the output of the WordPress playlist feature. This searches for the [playlist] shortcode * if it's used in the content. * * @return void * @since 2.0.0 * @access public */ public function do_playlist_shortcode_media( $shortcode ) { $this->original_media = array_shift( $shortcode ); $this->media = do_shortcode( $this->original_media ); } /** * Handles the HTML when the [embed] shortcode is used. * * @param array $shortcode * * @return void * @since 1.6.0 * @access public */ public function do_embed_shortcode_media( $shortcode ) { $this->original_media = array_shift( $shortcode ); $this->media = apply_filters( 'hybrid_media_grabber_embed_shortcode_media', $this->original_media ); } /** * Handles the HTML when the [audio] shortcode is used. * * @param array $shortcode * * @return void * @since 1.6.0 * @access public */ public function do_audio_shortcode_media( $shortcode ) { $this->original_media = array_shift( $shortcode ); $this->media = do_shortcode( $this->original_media ); } /** * Handles the HTML when the [video] shortcode is used. * * @param array $shortcode * * @return void * @since 1.6.0 * @access public */ public function do_video_shortcode_media( $shortcode ) { $this->original_media = array_shift( $shortcode ); // Need to filter dimensions here to overwrite WP's
surrounding the [video] shortcode. $this->media = do_shortcode( $this->filter_dimensions( $this->original_media ) ); } /** * Handles the output of audio/video shortcodes included with the Jetpack plugin (or Jetpack * Slim) via the Shortcode Embeds feature. * * @return void * @since 2.0.0 * @access public */ public function do_jetpack_shortcode_media( $shortcode ) { $this->original_media = array_shift( $shortcode ); $this->media = do_shortcode( $this->original_media ); } /** * Uses WordPress' autoembed feature to automatically to handle media that's just input as a URL. * * @return void * @since 1.6.0 * @access public */ public function do_autoembed_media() { preg_match_all( '|^\s*(https?://[^\s"]+)\s*$|im', $this->content, $matches, PREG_SET_ORDER ); // If URL matches are found, loop through them to see if we can get an embed. if ( is_array( $matches ) ) { foreach ( $matches as $value ) { // Let WP work its magic with the 'autoembed' method. $embed = trim( apply_filters( 'hybrid_media_grabber_autoembed_media', $value[0] ) ); if ( ! empty( $embed ) ) { $this->original_media = $value[0]; $this->media = $embed; break; } } } } /** * Grabs media embbeded into the content within