/** * VideoPress Shortcode Handler * * This file may or may not be included from the Jetpack VideoPress module. */ class VideoPress_Shortcode { /** @var VideoPress_Shortcode */ protected static $instance; protected function __construct() { // By explicitly declaring the provider here, we can speed things up by not relying on oEmbed discovery. wp_oembed_add_provider( '#^https?://videopress.com/v/.*#', 'http://public-api.wordpress.com/oembed/1.0/', true ); add_shortcode( 'videopress', array( $this, 'shortcode_callback' ) ); add_shortcode( 'wpvideo', array( $this, 'shortcode_callback' ) ); add_filter('wp_video_shortcode_override', array( $this, 'video_shortcode_override' ), 10, 4); add_filter( 'oembed_fetch_url', array( $this, 'add_oembed_for_parameter' ) ); $this->add_video_embed_hander(); } /** * @return VideoPress_Shortcode */ public static function initialize() { if ( ! isset ( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Translate a 'videopress' or 'wpvideo' shortcode and arguments into a video player display. * * Expected input formats: * * [videopress OcobLTqC] * [wpvideo OcobLTqC] * * @link http://codex.wordpress.org/Shortcode_API Shortcode API * @param array $attr shortcode attributes * @return string HTML markup or blank string on fail */ public function shortcode_callback( $attr ) { global $content_width; /** * We only accept GUIDs as a first unnamed argument. */ $guid = isset( $attr[0] ) ? $attr[0] : null; if ( isset( $attr['postid'] ) ) { $guid = get_post_meta( $attr['postid'], 'videopress_guid', true ); } /** * Make sure the GUID passed in matches how actual GUIDs are formatted. */ if ( ! videopress_is_valid_guid( $guid ) ) { return ''; } /** * Set the defaults */ $defaults = array( 'w' => 0, // Width of the video player, in pixels 'at' => 0, // How many seconds in to initially seek to 'hd' => true, // Whether to display a high definition version 'loop' => false, // Whether to loop the video repeatedly 'freedom' => false, // Whether to use only free/libre codecs 'autoplay' => false, // Whether to autoplay the video on load 'permalink' => true, // Whether to display the permalink to the video 'flashonly' => false, // Whether to support the Flash player exclusively 'defaultlangcode' => false, // Default language code ); $attr = shortcode_atts( $defaults, $attr, 'videopress' ); /** * Cast the attributes, post-input. */ $attr['width'] = absint( $attr['w'] ); $attr['hd'] = (bool) $attr['hd']; $attr['freedom'] = (bool) $attr['freedom']; /** * If the provided width is less than the minimum allowed * width, or greater than `$content_width` ignore. */ if ( $attr['width'] < VIDEOPRESS_MIN_WIDTH ) { $attr['width'] = 0; } elseif ( isset( $content_width ) && $content_width > VIDEOPRESS_MIN_WIDTH && $attr['width'] > $content_width ) { $attr['width'] = 0; } /** * If there was an invalid or unspecified width, set the width equal to the theme's `$content_width`. */ if ( 0 === $attr['width'] && isset( $content_width ) && $content_width >= VIDEOPRESS_MIN_WIDTH ) { $attr['width'] = $content_width; } /** * If the width isn't an even number, reduce it by one (making it even). */ if ( 1 === ( $attr['width'] % 2 ) ) { $attr['width'] --; } /** * Filter the default VideoPress shortcode options. * * @module videopress * * @since 2.5.0 * * @param array $args Array of VideoPress shortcode options. */ $options = apply_filters( 'videopress_shortcode_options', array( 'at' => (int) $attr['at'], 'hd' => $attr['hd'], 'loop' => $attr['loop'], 'freedom' => $attr['freedom'], 'autoplay' => $attr['autoplay'], 'permalink' => $attr['permalink'], 'force_flash' => (bool) $attr['flashonly'], 'defaultlangcode' => $attr['defaultlangcode'], 'forcestatic' => false, // This used to be a displayed option, but now is only // accessible via the `videopress_shortcode_options` filter. ) ); // Register VideoPress scripts wp_register_script( 'videopress', 'https://v0.wordpress.com/js/videopress.js', array( 'jquery', 'swfobject' ), '1.09' ); require_once( dirname( __FILE__ ) . '/class.videopress-video.php' ); require_once( dirname( __FILE__ ) . '/class.videopress-player.php' ); $player = new VideoPress_Player( $guid, $attr['width'], $options ); if ( is_feed() ) { return $player->asXML(); } else { return $player->asHTML(); } } /** * Override the standard video short tag to also process videopress files as well. * * This will, parse the src given, and if it is a videopress file, it will parse as the * VideoPress shortcode instead. * * @param string $html Empty variable to be replaced with shortcode markup. * @param array $attr Attributes of the video shortcode. * @param string $content Video shortcode content. * @param int $instance Unique numeric ID of this video shortcode instance. * * @return string */ public function video_shortcode_override($html, $attr, $content, $instance) { $videopress_guid = null; if ( isset( $attr['videopress_guid'] ) ) { $videopress_guid = $attr['videopress_guid']; } else { // Handle the different possible url attributes $url_keys = array( 'src', 'mp4' ); foreach ( $url_keys as $key ) { if ( isset ( $attr[ $key ] ) ) { $url = $attr[ $key ]; if ( preg_match( '@videos.(videopress\.com|files\.wordpress\.com)/([a-z0-9]{8})/@i', $url, $matches ) ) { $videopress_guid = $matches[2]; } // Also test for videopress oembed url, which is used by the Video Media Widget. if ( ! $videopress_guid && preg_match( '@https://videopress.com/v/([a-z0-9]{8})@i', $url, $matches ) ) { $videopress_guid = $matches[1]; } break; } } } if ( $videopress_guid ) { $videopress_attr = array( $videopress_guid ); if ( isset( $attr['width'] ) ) { $videopress_attr['w'] = (int) $attr['width']; } if ( isset( $attr['autoplay'] ) ) { $videopress_attr['autoplay'] = $attr['autoplay']; } if ( isset( $attr['loop'] ) ) { $videopress_attr['loop'] = $attr['loop']; } // Then display the VideoPress version of the stored GUID! return $this->shortcode_callback( $videopress_attr ); } return ''; } /** * Adds a `for` query parameter to the oembed provider request URL. * * @param String $oembed_provider * @return String $ehnanced_oembed_provider */ public function add_oembed_for_parameter( $oembed_provider ) { if ( false === stripos( $oembed_provider, 'videopress.com' ) ) { return $oembed_provider; } return add_query_arg( 'for', parse_url( home_url(), PHP_URL_HOST ), $oembed_provider ); } /** * Register a VideoPress handler for direct links to .mov files (and potential other non-handled types later). */ public function add_video_embed_hander() { // These are the video extensions that VideoPress can transcode and considers video as well (even if core does not). $extensions = array( 'mov' ); $override_extensions = implode( '|', $extensions ); $regex = "#^https?://videos.(videopress.com|files.wordpress.com)/.+?.($override_extensions)$#i"; /** This filter is already documented in core/wp-includes/embed.php */ $filter = apply_filters( 'wp_video_embed_handler', 'wp_embed_handler_video' ); wp_embed_register_handler( 'video', $regex, $filter, 10 ); } } VideoPress_Shortcode::initialize(); /** * An SEO expert walks into a bar, bars, pub, public house, Irish pub, drinks, beer, wine, liquor, Grey Goose, Cristal... */ class Jetpack_SEO { public function __construct() { add_action( 'init', array( $this, 'init' ) ); } public function init() { /** * Can be used to prevent SEO tools from inserting custom meta tags. * * @module seo-tools * * @since 4.4.0 * * @param bool true Should Jetpack's SEO Meta Tags be enabled. Defaults to true. */ if ( apply_filters( 'jetpack_seo_meta_tags_enabled', true ) ) { add_action( 'wp_head', array( $this, 'meta_tags' ) ); // Add support for editing page excerpts in pages, regardless of theme support. add_post_type_support( 'page', 'excerpt' ); } /** * Can be used to prevent SEO tools form modifying site titles. * * @module seo-tools * * @since 4.4.0 * * @param bool true Should Jetpack SEO modify site titles. Defaults to true. */ if ( apply_filters( 'jetpack_seo_custom_titles', true ) ) { // Overwrite page title with custom SEO meta title for themes that support title-tag. add_filter( 'pre_get_document_title', array( 'Jetpack_SEO_Titles', 'get_custom_title' ) ); // Add overwrite support for themes that don't support title-tag. add_filter( 'wp_title', array( 'Jetpack_SEO_Titles', 'get_custom_title' ) ); } add_filter( 'jetpack_open_graph_tags', array( $this, 'set_custom_og_tags' ) ); } private function get_authors() { global $wp_query; $authors = array(); foreach ( $wp_query->posts as $post ) { $authors[] = get_the_author_meta( 'display_name', (int) $post->post_author ); } $authors = array_unique( $authors ); return $authors; } public function set_custom_og_tags( $tags ) { $custom_title = Jetpack_SEO_Titles::get_custom_title(); if ( ! empty( $custom_title ) ) { $tags['og:title'] = $custom_title; } $post_custom_description = Jetpack_SEO_Posts::get_post_custom_description( get_post() ); $front_page_meta = Jetpack_SEO_Utils::get_front_page_meta_description(); if ( is_front_page() && ! empty( $front_page_meta ) ) { $tags['og:description'] = $front_page_meta; } else { if ( ! empty( $post_custom_description ) ) { $tags['og:description'] = $post_custom_description; } } return $tags; } public function meta_tags() { global $wp_query; $period = ''; $template = ''; $meta = array(); /** * Can be used to specify a list of themes that set their own meta tags. * * If current site is using one of the themes listed as conflicting, inserting Jetpack SEO * meta tags will be prevented. * * @module seo-tools * * @since 4.4.0 * * @param array List of conflicted theme names. Defaults to empty array. */ $conflicted_themes = apply_filters( 'jetpack_seo_meta_tags_conflicted_themes', array() ); if ( isset( $conflicted_themes[ get_option( 'template' ) ] ) ) { return; } $front_page_meta = Jetpack_SEO_Utils::get_front_page_meta_description(); $description = $front_page_meta ? $front_page_meta : get_bloginfo( 'description' ); $meta['description'] = trim( $description ); // Try to target things if we're on a "specific" page of any kind. if ( is_singular() ) { // Business users can overwrite the description. if ( ! ( is_front_page() && Jetpack_SEO_Utils::get_front_page_meta_description() ) ) { $description = Jetpack_SEO_Posts::get_post_description( get_post() ); if ( $description ) { $description = wp_trim_words( strip_shortcodes( wp_kses( $description, array() ) ) ); $meta['description'] = $description; } } } elseif ( is_author() ) { $obj = get_queried_object(); $meta['description'] = sprintf( _x( 'Read all of the posts by %1$s on %2$s', 'Read all of the posts by Author Name on Blog Title', 'jetpack' ), $obj->display_name, get_bloginfo( 'title' ) ); } elseif ( is_tag() || is_category() || is_tax() ) { $obj = get_queried_object(); $description = get_term_field( 'description', $obj->term_id, $obj->taxonomy, 'raw' ); if ( ! is_wp_error( $description ) && '' != $description ) { $meta['description'] = wp_trim_words( $description ); } else { $authors = $this->get_authors(); $meta['description'] = wp_sprintf( _x( 'Posts about %1$s written by %2$l', 'Posts about Category written by John and Bob', 'jetpack' ), single_term_title( '', false ), $authors ); } } elseif ( is_date() ) { if ( is_year() ) { $period = get_query_var( 'year' ); $template = _nx( '%1$s post published by %2$l in the year %3$s', // singular '%1$s posts published by %2$l in the year %3$s', // plural count( $wp_query->posts ), // number '10 posts published by John in the year 2012', // context 'jetpack' ); } elseif ( is_month() ) { $period = date( 'F Y', mktime( 0, 0, 0, get_query_var( 'monthnum' ), 1, get_query_var( 'year' ) ) ); $template = _nx( '%1$s post published by %2$l during %3$s', // singular '%1$s posts published by %2$l during %3$s', // plural count( $wp_query->posts ), // number '10 posts publishes by John during May 2012', // context 'jetpack' ); } elseif ( is_day() ) { $period = date( 'F j, Y', mktime( 0, 0, 0, get_query_var( 'monthnum' ), get_query_var( 'day' ), get_query_var( 'year' ) ) ); $template = _nx( '%1$s post published by %2$l on %3$s', // singular '%1$s posts published by %2$l on %3$s', // plural count( $wp_query->posts ), // number '10 posts published by John on May 30, 2012', // context 'jetpack' ); } $authors = $this->get_authors(); $meta['description'] = wp_sprintf( $template, count( $wp_query->posts ), $authors, $period ); } /** * Can be used to edit the default SEO tools meta tags. * * @module seo-tools * * @since 4.4.0 * * @param array Array that consists of meta name and meta content pairs. */ $meta = apply_filters( 'jetpack_seo_meta_tags', $meta ); // Output them foreach ( $meta as $name => $content ) { if ( ! empty( $content ) ) { echo '' . "\n"; } } } }