/**
  * Validate the post meta values
  *
  * @static
  *
  * @param  mixed  $meta_value The new value.
  * @param  string $meta_key   The full meta key (including prefix).
  *
  * @return string             Validated meta value
  */
 public static function sanitize_post_meta($meta_value, $meta_key)
 {
     $field_def = self::$meta_fields[self::$fields_index[$meta_key]['subset']][self::$fields_index[$meta_key]['key']];
     $clean = self::$defaults[$meta_key];
     switch (true) {
         case $meta_key === self::$meta_prefix . 'linkdex':
             $int = WPSEO_Utils::validate_int($meta_value);
             if ($int !== false && $int >= 0) {
                 $clean = strval($int);
                 // Convert to string to make sure default check works.
             }
             break;
         case $field_def['type'] === 'checkbox':
             // Only allow value if it's one of the predefined options.
             if (in_array($meta_value, array('on', 'off'), true)) {
                 $clean = $meta_value;
             }
             break;
         case $field_def['type'] === 'select' || $field_def['type'] === 'radio':
             // Only allow value if it's one of the predefined options.
             if (isset($field_def['options'][$meta_value])) {
                 $clean = $meta_value;
             }
             break;
         case $field_def['type'] === 'multiselect' && $meta_key === self::$meta_prefix . 'meta-robots-adv':
             $clean = self::validate_meta_robots_adv($meta_value);
             break;
         case $field_def['type'] === 'text' && $meta_key === self::$meta_prefix . 'canonical':
         case $field_def['type'] === 'text' && $meta_key === self::$meta_prefix . 'redirect':
             // Validate as url(-part).
             $url = WPSEO_Utils::sanitize_url($meta_value);
             if ($url !== '') {
                 $clean = $url;
             }
             break;
         case $field_def['type'] === 'upload' && $meta_key === self::$meta_prefix . 'opengraph-image':
             // Validate as url.
             $url = WPSEO_Utils::sanitize_url($meta_value, array('http', 'https', 'ftp', 'ftps'));
             if ($url !== '') {
                 $clean = $url;
             }
             break;
         case $field_def['type'] === 'textarea':
             if (is_string($meta_value)) {
                 // Remove line breaks and tabs.
                 // @todo [JRF => Yoast] verify that line breaks and the likes aren't allowed/recommended in meta header fields.
                 $meta_value = str_replace(array("\n", "\r", "\t", '  '), ' ', $meta_value);
                 $clean = WPSEO_Utils::sanitize_text_field(trim($meta_value));
             }
             break;
         case 'multiselect' === $field_def['type']:
             $clean = $meta_value;
             break;
         case $field_def['type'] === 'text':
         default:
             if (is_string($meta_value)) {
                 $clean = WPSEO_Utils::sanitize_text_field(trim($meta_value));
             }
             if ($meta_key === self::$meta_prefix . 'focuskw') {
                 $clean = str_replace(array('&lt;', '&gt;', '&quot', '&#96', '<', '>', '"', '`'), '', $clean);
             }
             break;
     }
     $clean = apply_filters('wpseo_sanitize_post_meta_' . $meta_key, $clean, $meta_value, $field_def, $meta_key);
     return $clean;
 }
 /**
  * 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) {
             /* Automagic Facebook connect key */
             case 'fbconnectkey':
                 if (isset($old[$key]) && $old[$key] !== '' && preg_match('`^[a-f0-9]{32}$`', $old[$key]) > 0) {
                     $clean[$key] = $old[$key];
                 } else {
                     $clean[$key] = self::get_fbconnectkey();
                 }
                 break;
                 /* Will not always exist in form */
             /* Will not always exist in form */
             case 'fb_admins':
                 if (isset($dirty[$key]) && is_array($dirty[$key])) {
                     if ($dirty[$key] === array()) {
                         $clean[$key] = array();
                     } else {
                         foreach ($dirty[$key] as $user_id => $fb_array) {
                             /*
                              * @todo [JRF/JRF => Yoast/whomever] add user_id validation -
                              * are these WP user-ids or FB user-ids ? Probably FB user-ids,
                              * if so, find out the rules for FB user-ids
                              */
                             if (is_array($fb_array) && $fb_array !== array()) {
                                 foreach ($fb_array as $fb_key => $fb_value) {
                                     switch ($fb_key) {
                                         case 'name':
                                             /**
                                              * @todo [JRF => whomever] add validation for name based
                                              * on rules if there are any
                                              * Input comes from: $_GET['userrealname']
                                              */
                                             $clean[$key][$user_id][$fb_key] = sanitize_text_field($fb_value);
                                             break;
                                         case 'link':
                                             $clean[$key][$user_id][$fb_key] = WPSEO_Utils::sanitize_url($fb_value);
                                             break;
                                     }
                                 }
                             }
                         }
                         unset($user_id, $fb_array, $fb_key, $fb_value);
                     }
                 } elseif (isset($old[$key]) && is_array($old[$key])) {
                     $clean[$key] = $old[$key];
                 }
                 break;
                 /* text fields */
             /* text fields */
             case 'og_frontpage_desc':
             case 'og_frontpage_title':
                 if (isset($dirty[$key]) && $dirty[$key] !== '') {
                     $clean[$key] = WPSEO_Utils::sanitize_text_field($dirty[$key]);
                 }
                 break;
                 /* url text fields - no ftp allowed */
             /* url text fields - no ftp allowed */
             case 'facebook_site':
             case 'instagram_url':
             case 'linkedin_url':
             case 'myspace_url':
             case 'pinterest_url':
             case 'plus-publisher':
             case 'og_default_image':
             case 'og_frontpage_image':
             case 'youtube_url':
             case 'google_plus_url':
                 $this->validate_url($key, $dirty, $old, $clean);
                 break;
             case 'pinterestverify':
                 $this->validate_verification_string($key, $dirty, $old, $clean);
                 break;
                 /* twitter user name */
             /* twitter user name */
             case 'twitter_site':
                 if (isset($dirty[$key]) && $dirty[$key] !== '') {
                     $twitter_id = sanitize_text_field(ltrim($dirty[$key], '@'));
                     /**
                      * From the Twitter documentation about twitter screen names:
                      * Typically a maximum of 15 characters long, but some historical accounts
                      * may exist with longer names.
                      * A username can only contain alphanumeric characters (letters A-Z, numbers 0-9)
                      * with the exception of underscores
                      *
                      * @link https://support.twitter.com/articles/101299-why-can-t-i-register-certain-usernames
                      * @link https://dev.twitter.com/docs/platform-objects/users
                      */
                     if (preg_match('`^[A-Za-z0-9_]{1,25}$`', $twitter_id)) {
                         $clean[$key] = $twitter_id;
                     } elseif (preg_match('`^http(?:s)?://(?:www\\.)?twitter\\.com/(?P<handle>[A-Za-z0-9_]{1,25})/?$`', $twitter_id, $matches)) {
                         $clean[$key] = $matches['handle'];
                     } else {
                         if (isset($old[$key]) && $old[$key] !== '') {
                             $twitter_id = sanitize_text_field(ltrim($old[$key], '@'));
                             if (preg_match('`^[A-Za-z0-9_]{1,25}$`', $twitter_id)) {
                                 $clean[$key] = $twitter_id;
                             }
                         }
                         if (function_exists('add_settings_error')) {
                             add_settings_error($this->group_name, '_' . $key, sprintf(__('%s does not seem to be a valid Twitter user-id. Please correct.', 'wordpress-seo'), '<strong>' . esc_html(sanitize_text_field($dirty[$key])) . '</strong>'), 'error');
                         }
                     }
                     unset($twitter_id);
                 }
                 break;
             case 'twitter_card_type':
                 if (isset($dirty[$key], self::$twitter_card_types[$dirty[$key]]) && $dirty[$key] !== '') {
                     $clean[$key] = $dirty[$key];
                 }
                 break;
                 /* boolean fields */
             /* boolean fields */
             case 'opengraph':
             case 'twitter':
                 $clean[$key] = isset($dirty[$key]) ? WPSEO_Utils::validate_bool($dirty[$key]) : false;
                 break;
         }
     }
     /**
      * Only validate 'fbadminapp', so leave the clean default.
      */
     if (isset($dirty['fbadminapp']) && !empty($dirty['fbadminapp'])) {
         $clean['fbadminapp'] = $dirty['fbadminapp'];
     }
     return $clean;
 }
 /**
  * Sanitize a url for saving to the database
  * Not to be confused with the old native WP function
  *
  * @deprecated 1.5.6.1
  * @deprecated use WPSEO_Utils::sanitize_url()
  * @see        WPSEO_Utils::sanitize_url()
  *
  * @param  string $value             URL string to sanitize.
  * @param  array  $allowed_protocols Set of allowed protocols.
  *
  * @return  string
  */
 public static function sanitize_url($value, $allowed_protocols = array('http', 'https'))
 {
     _deprecated_function(__FUNCTION__, 'WPSEO 1.5.6.1', 'WPSEO_Utils::sanitize_url()');
     return WPSEO_Utils::sanitize_url($value, $allowed_protocols);
 }
 /**
  * Fallback funciton for WP SEO functionality, sanitize_url
  *
  * @param $string
  *
  * @return mixed
  */
 public static function yoast_wpseo_video_sanitize_url($string)
 {
     if (method_exists('WPSEO_Utils', 'sanitize_url')) {
         return WPSEO_Utils::sanitize_url($string, array('http', 'https', 'ftp', 'ftps'));
     }
     return WPSEO_Option::sanitize_url($string, array('http', 'https', 'ftp', 'ftps'));
 }
 /**
  * Validate the meta data for one individual term and removes default values (no need to save those)
  *
  * @static
  *
  * @param  array $meta_data New values
  * @param  array $old_meta  The original values
  *
  * @return  array        Validated and filtered value
  */
 public static function validate_term_meta_data($meta_data, $old_meta)
 {
     $clean = self::$defaults_per_term;
     $meta_data = array_map(array('WPSEO_Utils', 'trim_recursive'), $meta_data);
     if (!is_array($meta_data) || $meta_data === array()) {
         return $clean;
     }
     foreach ($clean as $key => $value) {
         switch ($key) {
             case 'wpseo_noindex':
                 if (isset($meta_data[$key])) {
                     if (isset(self::$no_index_options[$meta_data[$key]])) {
                         $clean[$key] = $meta_data[$key];
                     }
                 } elseif (isset($old_meta[$key])) {
                     // Retain old value if field currently not in use
                     $clean[$key] = $old_meta[$key];
                 }
                 break;
             case 'wpseo_sitemap_include':
                 if (isset($meta_data[$key], self::$sitemap_include_options[$meta_data[$key]])) {
                     $clean[$key] = $meta_data[$key];
                 }
                 break;
             case 'wpseo_canonical':
                 if (isset($meta_data[$key]) && $meta_data[$key] !== '') {
                     $url = WPSEO_Utils::sanitize_url($meta_data[$key]);
                     if ($url !== '') {
                         $clean[$key] = $url;
                     }
                     unset($url);
                 }
                 break;
             case 'wpseo_metakey':
             case 'wpseo_bctitle':
                 if (isset($meta_data[$key])) {
                     $clean[$key] = WPSEO_Utils::sanitize_text_field(stripslashes($meta_data[$key]));
                 } elseif (isset($old_meta[$key])) {
                     // Retain old value if field currently not in use
                     $clean[$key] = $old_meta[$key];
                 }
                 break;
             case 'wpseo_title':
             case 'wpseo_desc':
             default:
                 if (isset($meta_data[$key]) && is_string($meta_data[$key])) {
                     $clean[$key] = WPSEO_Utils::sanitize_text_field(stripslashes($meta_data[$key]));
                 }
                 break;
         }
         $clean[$key] = apply_filters('wpseo_sanitize_tax_meta_' . $key, $clean[$key], isset($meta_data[$key]) ? $meta_data[$key] : null, isset($old_meta[$key]) ? $old_meta[$key] : null);
     }
     // Only save the non-default values
     return array_diff_assoc($clean, self::$defaults_per_term);
 }