/**
  * 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;
 }