/** * Analyse a video shortcode from the plugin for usable video information * * @param string $full_shortcode Full shortcode as found in the post content * @param string $sc Shortcode found * @param array $atts Shortcode attributes - already decoded if needed * @param string $content The shortcode content, i.e. the bit between [sc]content[/sc] * * @return array An array with the usable information found or else an empty array */ public function get_info_from_shortcode($full_shortcode, $sc, $atts = array(), $content = '') { $vid = array(); $validated_int = WPSEO_Video_Wrappers::yoast_wpseo_video_validate_int($atts['id']); if (isset($atts['id']) && !empty($atts['id']) && $validated_int !== false) { $vid = $this->get_info_for_post_type((int) $atts['id'], 'flowplayer5', null, true); } else { // Old flowplayer shortcode format if (isset($atts['webm']) && (is_string($atts['webm']) && $atts['webm'] !== '')) { $vid['url'] = $atts['webm']; } elseif (isset($atts['mp4']) && (is_string($atts['mp4']) && $atts['mp4'] !== '')) { $vid['url'] = $atts['mp4']; } elseif (isset($atts['ogg']) && (is_string($atts['ogg']) && $atts['ogg'] !== '')) { $vid['url'] = $atts['ogg']; } if (isset($vid['url'])) { $vid['content_loc'] = $vid['url']; $vid['maybe_local'] = true; if (isset($atts['splash']) && (is_string($atts['splash']) && $atts['splash'] !== '')) { $vid['thumbnail_loc'] = $atts['splash']; } $vid['type'] = 'flowplayer'; $vid = $this->maybe_get_dimensions($vid, $atts, true); } } return $vid; }
/** * Analyse a video shortcode from the plugin for usable video information * * @param string $full_shortcode Full shortcode as found in the post content * @param string $sc Shortcode found * @param array $atts Shortcode attributes - already decoded if needed * @param string $content The shortcode content, i.e. the bit between [sc]content[/sc] * * @return array An array with the usable information found or else an empty array */ public function get_info_from_shortcode($full_shortcode, $sc, $atts = array(), $content = '') { $vid = array(); if (isset($atts['mediaid'])) { $mediaid = WPSEO_Video_Wrappers::yoast_wpseo_video_validate_int($atts['mediaid']); if ($mediaid !== false && $mediaid > 0) { $content_loc = wp_get_attachment_url($mediaid); // @todo should we maybe use JWP6_Plugin::url_from_post( $mediaid ) to stay in line ? if ($content_loc !== false) { $vid['content_loc'] = $content_loc; } $duration = get_post_meta($mediaid, 'jwplayermodule_duration', true); if ($duration !== '') { $vid['duration'] = $duration; } $thumbnail_loc = get_post_meta($mediaid, 'jwplayermodule_thumbnail_url', true); if ($thumbnail_loc !== '') { $vid['thumbnail_loc'] = $thumbnail_loc; } } unset($mediaid, $content_loc, $duration, $thumbnail_loc); } // @todo [JRF] Does this really belong with this plugin ? can't find documentation for this plugin on the html5_file or file attributes if (!isset($vid['content_loc'])) { if (isset($atts['html5_file']) && (is_string($atts['html5_file']) && $atts['html5_file'] !== '')) { $vid['content_loc'] = $atts['html5_file']; } elseif (isset($atts['file']) && (is_string($atts['file']) && $atts['file'] !== '')) { $vid['content_loc'] = $atts['file']; } if (isset($vid['content_loc'], $atts['image']) && (is_string($atts['image']) && $atts['image'] !== '')) { $vid['thumbnail_loc'] = $atts['image']; } } if ($vid !== array()) { $vid['type'] = 'jwplayer'; // @todo - should this be added ? or should we believe the jwplayer plugin info to be good enough (though incomplete) ? //$vid['url'] = $vid['content_loc']; //$vid['maybe_local'] = true; $vid = $this->maybe_get_dimensions($vid, $atts); } return $vid; }
/** * Outputs the admin panel for the Video Sitemaps on the XML Sitemaps page with the WP SEO admin * * @since 0.1 */ public function admin_panel() { $options = get_option('wpseo_video'); $xmlopt = get_option('wpseo_xml'); WPSEO_Video_Wrappers::admin_header(true, $this->option_instance->group_name, $this->option_instance->option_name, false); if (isset($_POST['reindex'])) { /** * Load the reindex page, shows a progressbar and sents ajax calls to the server with * small amounts of posts to reindex. */ require plugin_dir_path(__FILE__) . 'views/reindex_page.php'; } else { if ($xmlopt['enablexmlsitemap'] !== true) { echo '<p>' . sprintf(esc_html__('Please enable the XML sitemap under the SEO -> %sXML Sitemaps settings%s', 'yoast-video-seo'), '<a href="' . esc_url(add_query_arg(array('page' => 'wpseo_xml'), admin_url('admin.php'))) . '">', '</a>') . '</p>'; } else { echo '<h2>' . esc_html__('General Settings', 'yoast-video-seo') . '</h2>'; if (is_array($options['videositemap_posttypes']) && $options['videositemap_posttypes'] !== array()) { // Use fields => ids to limit the overhead of fetching entire post objects, // fetch only an array of ids instead to count $args = array('post_type' => $options['videositemap_posttypes'], 'post_status' => 'publish', 'posts_per_page' => -1, 'meta_key' => '_yoast_wpseo_video_meta', 'meta_compare' => '!=', 'meta_value' => 'none', 'fields' => 'ids'); $video_ids = get_posts($args); $count = count($video_ids); $n = $count > $this->max_entries ? (int) ceil($count / $this->max_entries) : ''; $video_lastest = str_replace('sitemap.xml', 'sitemap' . $n . '.xml', $this->sitemap_url()); echo '<p>' . esc_html__('Please find your video sitemap here:', 'yoast-video-seo') . ' <a class="button" target="_blank" href="' . esc_url($video_lastest) . '">' . esc_html__('Video Sitemap', 'yoast-video-seo') . '</a></p>'; } else { echo '<p>' . esc_html__('Select at least one post type to enable the video sitemap', 'yoast-video-seo') . '</p>'; } echo WPSEO_Video_Wrappers::checkbox('cloak_sitemap', esc_html__('Hide the sitemap from normal visitors?', 'yoast-video-seo')); echo WPSEO_Video_Wrappers::checkbox('disable_rss', esc_html__('Disable Media RSS Enhancement', 'yoast-video-seo')); echo WPSEO_Video_Wrappers::textinput('custom_fields', esc_html__('Custom fields', 'yoast-video-seo')); echo '<p class="clear description">' . esc_html__('Custom fields the plugin should check for video content (comma separated)', 'yoast-video-seo') . '</p>'; echo WPSEO_Video_Wrappers::textinput('embedly_api_key', esc_html__('(Optional) Embedly API Key', 'yoast-video-seo')); echo '<p class="clear description">' . sprintf(esc_html__('The video SEO plugin provides where possible enriched information about your videos. A lot of %1$svideo services%2$s are supported by default. For those services which aren\'t supported, we can try to retrieve enriched video information using %3$sEmbedly%2$s. If you want to use this option, you\'ll need to sign up for a (free) %3$sEmbedly%2$s account and provide the API key you receive.', 'yoast-video-seo'), '<a href="http://kb.yoast.com/article/95-supported-video-hosting-platforms-for-video-seo-plugin">', '</a>', '<a href="http://embed.ly/">') . '</p>'; echo '<br class="clear"/>'; echo '<h2>' . esc_html__('Embed Settings', 'yoast-video-seo') . '</h2>'; echo WPSEO_Video_Wrappers::checkbox('facebook_embed', esc_html__('Allow videos to be played directly on Facebook.', 'yoast-video-seo')); echo WPSEO_Video_Wrappers::checkbox('fitvids', sprintf(esc_html__('Try to make videos responsive using %sFitVids.js%s?', 'yoast-video-seo'), '<a href="http://fitvidsjs.com/">', '</a>')); echo WPSEO_Video_Wrappers::textinput('content_width', esc_html__('Content width', 'yoast-video-seo')); echo '<p class="clear description">' . esc_html__('This defaults to your themes content width, but if it\'s empty, setting a value here will make sure videos are embedded in the right width.', 'yoast-video-seo') . '</p>'; echo WPSEO_Video_Wrappers::textinput('vzaar_domain', esc_html__('Vzaar domain', 'yoast-video-seo')); echo '<p class="clear description">' . esc_html__('If you use Vzaar, set this to the domain name you use for your Vzaar videos, no http: or slashes needed.', 'yoast-video-seo') . '</p>'; echo WPSEO_Video_Wrappers::textinput('wistia_domain', esc_html__('Wistia domain', 'yoast-video-seo')); echo '<p class="clear description">' . esc_html__('If you use Wistia in combination with a custom domain, set this to the domain name you use for your Wistia videos, no http: or slashes needed.', 'yoast-video-seo') . '</p>'; echo '<br class="clear"/>'; echo '<h2>' . esc_html__('Post Types to include in XML Video Sitemap', 'yoast-video-seo') . '</h2>'; echo '<p>' . esc_html__('Determine which post types on your site might contain video.', 'yoast-video-seo') . '</p>'; $post_types = get_post_types(array('public' => true), 'objects'); if (is_array($post_types) && $post_types !== array()) { foreach ($post_types as $posttype) { $sel = ''; if (is_array($options['videositemap_posttypes']) && in_array($posttype->name, $options['videositemap_posttypes'])) { $sel = 'checked="checked" '; } echo '<input class="checkbox double" id="' . esc_attr('include' . $posttype->name) . '" type="checkbox" ' . 'name="wpseo_video[videositemap_posttypes][' . esc_attr($posttype->name) . ']" ' . $sel . 'value="' . esc_attr($posttype->name) . '"/> ' . '<label for="' . esc_attr('include' . $posttype->name) . '">' . esc_html($posttype->labels->name) . '</label><br class="clear">'; } } unset($post_types); echo '<h2>' . esc_html__('Taxonomies to include in XML Video Sitemap', 'yoast-video-seo') . '</h2>'; echo '<p>' . esc_html__('You can also include your taxonomy archives, for instance, if you have videos on a category page.', 'yoast-video-seo') . '</p>'; $taxonomies = get_taxonomies(array('public' => true), 'objects'); if (is_array($taxonomies) && $taxonomies !== array()) { foreach ($taxonomies as $tax) { $sel = ''; if (is_array($options['videositemap_taxonomies']) && in_array($tax->name, $options['videositemap_taxonomies'])) { $sel = 'checked="checked" '; } echo '<input class="checkbox double" id="' . esc_attr('include' . $tax->name) . '" type="checkbox" ' . 'name="wpseo_video[videositemap_taxonomies][' . esc_attr($tax->name) . ']" ' . $sel . 'value="' . esc_attr($tax->name) . '"/> ' . '<label for="' . esc_attr('include' . $tax->name) . '">' . esc_html($tax->labels->name) . '</label><br class="clear">'; } } unset($taxonomies); } echo '<br class="clear"/>'; ?> <div class="submit"> <input type="submit" class="button-primary" name="submit" value="<?php esc_attr_e('Save Settings', 'yoast-video-seo'); ?> " /> </div> </form> <h2><?php esc_html_e('Indexation of videos in your content', 'yoast-video-seo'); ?> </h2> <p style="max-width: 600px;"><?php esc_html_e('This process goes through all the post types specified by you, as well as the terms of each taxonomy, to check for videos in the content. If the plugin finds a video, it updates the meta data for that piece of content, so it can add that meta data and content to the XML Video Sitemap.', 'yoast-video-seo'); ?> </p> <p style="max-width: 600px;"><?php esc_html_e('By default the plugin only checks content that hasn\'t been checked yet. However, if you check \'Force Re-Index\', it will re-check all content. This is particularly interesting if you want to check for a video embed code that wasn\'t supported before, of if you want to update thumbnail images en masse.', 'yoast-video-seo'); ?> </p> <form method="post" action=""> <input class="checkbox double" type="checkbox" name="force" id="force"> <label for="force"><?php esc_html_e("Force reindex of already indexed videos.", 'yoast-video-seo'); ?> </label><br /> <br /> <input type="submit" class="button" name="reindex" value="<?php esc_html_e('Re-Index Videos', 'yoast-video-seo'); ?> " /> </form> <?php } // Add debug info WPSEO_Video_Wrappers::admin_footer(false, false); }
/** * Validate the option * * @param array $dirty New value for the option * @param array $clean Clean value for the option, normally the defaults * @param array $old Old value of the option * * @return array Validated clean value for the option to be saved to the database */ protected function validate_option($dirty, $clean, $old) { foreach ($clean as $key => $value) { switch ($key) { case 'dbversion': $clean[$key] = WPSEO_VIDEO_VERSION; break; case 'videositemap_posttypes': $clean[$key] = array(); $valid_post_types = get_post_types(array('public' => true)); if (isset($dirty[$key]) && (is_array($dirty[$key]) && $dirty[$key] !== array())) { foreach ($dirty[$key] as $k => $v) { if (in_array($k, $valid_post_types, true)) { $clean[$key][$k] = $v; } elseif (sanitize_title_with_dashes($k) === $k) { // Allow post types which may not be registered yet $clean[$key][$k] = $v; } } } break; case 'videositemap_taxonomies': $clean[$key] = array(); $valid_taxonomies = get_taxonomies(array('public' => true)); if (isset($dirty[$key]) && (is_array($dirty[$key]) && $dirty[$key] !== array())) { foreach ($dirty[$key] as $k => $v) { if (in_array($k, $valid_taxonomies, true)) { $clean[$key][$k] = $v; } elseif (sanitize_title_with_dashes($k) === $k) { // Allow taxonomies which may not be registered yet $clean[$key][$k] = $v; } } } break; /* text field - may not be in form */ /* @todo - validate custom fields against meta table ? */ /* text field - may not be in form */ /* @todo - validate custom fields against meta table ? */ case 'custom_fields': if (isset($dirty[$key]) && $dirty[$key] !== '') { $clean[$key] = sanitize_text_field($dirty[$key]); } break; /* @todo - validate domains in some way ? */ /* @todo - validate domains in some way ? */ case 'vzaar_domain': case 'wistia_domain': if (isset($dirty[$key]) && $dirty[$key] !== '') { $clean[$key] = sanitize_text_field(urldecode($dirty[$key])); $clean[$key] = preg_replace(array('`^http[s]?://`', '`^//`', '`/$`'), '', $clean[$key]); } break; case 'embedly_api_key': if (isset($dirty[$key]) && $dirty[$key] !== '' && preg_match('`^[a-f0-9]{32}$`', $dirty[$key])) { $clean[$key] = sanitize_text_field($dirty[$key]); } break; /* numeric text field - may not be in form */ /* numeric text field - may not be in form */ case 'content_width': if (isset($dirty[$key]) && $dirty[$key] !== '') { $int = WPSEO_Video_Wrappers::yoast_wpseo_video_validate_int($dirty[$key]); if ($int !== false && $int > 0) { $clean[$key] = $int; } } break; /* boolean (checkbox) field - may not be in form */ /* boolean (checkbox) field - may not be in form */ case 'cloak_sitemap': case 'disable_rss': case 'facebook_embed': case 'fitvids': if (isset($dirty[$key])) { $clean[$key] = WPSEO_Video_Wrappers::validate_bool($dirty[$key]); } else { $clean[$key] = false; } break; } } return $clean; }
/** * Analyse the video shortcode as used in WP core for usable video information * * @param string $full_shortcode Full shortcode as found in the post content * @param string $sc Shortcode found * @param array $atts Shortcode attributes - already decoded if needed * @param string $content The shortcode content, i.e. the bit between [sc]content[/sc] * * @return array An array with the usable information found or else an empty array */ public function get_info_from_shortcode_video($full_shortcode, $sc, $atts = array(), $content = '') { $vid = array(); if (preg_match($this->att_regex, $full_shortcode, $match)) { $vid['type'] = 'mediaelement-js'; $vid['url'] = $match[2]; $vid['maybe_local'] = true; // If a poster image was specified, use that, otherwise, try and find a suitable .jpg if (isset($atts['poster']) && is_string($atts['poster']) && $atts['poster'] !== '') { if (WPSEO_Video_Wrappers::yoast_wpseo_video_is_url_relative($atts['poster']) === true) { $info = parse_url(get_site_url()); // @todo should we surround this with a file_exists check ? $vid['thumbnail_loc'] = $info['scheme'] . '://' . $info['host'] . $atts['poster']; } else { $vid['thumbnail_loc'] = $atts['poster']; } } $vid = $this->maybe_get_dimensions($vid, $atts); } return $vid; }
/** * Sanitize the video duration post meta * * @static * * @param mixed $clean Potentially pre-cleaned version of the new meta value * @param mixed $meta_value The new value * @param string $field_def The field definition for the current meta field * * @return string Cleaned value */ public static function sanitize_duration($clean, $meta_value, $field_def) { $field_def = WPSEO_Meta::get_meta_field_defs('video'); $field_def = $field_def['videositemap-duration']; $clean = $field_def['default_value']; $int = WPSEO_Video_Wrappers::yoast_wpseo_video_validate_int($meta_value); if ($int !== false && $int > 0) { $clean = strval($int); } return $clean; }