class-wpseo-option-social.php 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. <?php
  2. /**
  3. * WPSEO plugin file.
  4. *
  5. * @package WPSEO\Internals\Options
  6. */
  7. /**
  8. * Option: wpseo_social.
  9. */
  10. class WPSEO_Option_Social extends WPSEO_Option {
  11. /**
  12. * @var string Option name.
  13. */
  14. public $option_name = 'wpseo_social';
  15. /**
  16. * @var array Array of defaults for the option.
  17. * Shouldn't be requested directly, use $this->get_defaults();
  18. */
  19. protected $defaults = array(
  20. // Form fields.
  21. 'facebook_site' => '', // Text field.
  22. 'instagram_url' => '',
  23. 'linkedin_url' => '',
  24. 'myspace_url' => '',
  25. 'og_default_image' => '', // Text field.
  26. 'og_frontpage_title' => '', // Text field.
  27. 'og_frontpage_desc' => '', // Text field.
  28. 'og_frontpage_image' => '', // Text field.
  29. 'opengraph' => true,
  30. 'pinterest_url' => '',
  31. 'pinterestverify' => '',
  32. 'plus-publisher' => '', // Text field.
  33. 'twitter' => true,
  34. 'twitter_site' => '', // Text field.
  35. 'twitter_card_type' => 'summary_large_image',
  36. 'youtube_url' => '',
  37. 'google_plus_url' => '',
  38. // Form field, but not always available.
  39. 'fbadminapp' => '', // Facebook app ID.
  40. );
  41. /**
  42. * @var array Array of sub-options which should not be overloaded with multi-site defaults.
  43. */
  44. public $ms_exclude = array(
  45. /* Privacy. */
  46. 'pinterestverify',
  47. 'fbadminapp',
  48. );
  49. /**
  50. * @var array Array of allowed twitter card types.
  51. * While we only have the options summary and summary_large_image in the
  52. * interface now, we might change that at some point.
  53. *
  54. * {@internal Uncomment any of these to allow them in validation *and* automatically
  55. * add them as a choice in the options page.}}
  56. */
  57. public static $twitter_card_types = array(
  58. 'summary' => '',
  59. 'summary_large_image' => '',
  60. // 'photo' => '',
  61. // 'gallery' => '',
  62. // 'app' => '',
  63. // 'player' => '',
  64. // 'product' => '',
  65. );
  66. /**
  67. * Get the singleton instance of this class.
  68. *
  69. * @return object
  70. */
  71. public static function get_instance() {
  72. if ( ! ( self::$instance instanceof self ) ) {
  73. self::$instance = new self();
  74. }
  75. return self::$instance;
  76. }
  77. /**
  78. * Translate/set strings used in the option defaults.
  79. *
  80. * @return void
  81. */
  82. public function translate_defaults() {
  83. self::$twitter_card_types['summary'] = __( 'Summary', 'wordpress-seo' );
  84. self::$twitter_card_types['summary_large_image'] = __( 'Summary with large image', 'wordpress-seo' );
  85. }
  86. /**
  87. * Validate the option.
  88. *
  89. * @param array $dirty New value for the option.
  90. * @param array $clean Clean value for the option, normally the defaults.
  91. * @param array $old Old value of the option.
  92. *
  93. * @return array Validated clean value for the option to be saved to the database.
  94. */
  95. protected function validate_option( $dirty, $clean, $old ) {
  96. foreach ( $clean as $key => $value ) {
  97. switch ( $key ) {
  98. /* text fields */
  99. case 'og_frontpage_desc':
  100. case 'og_frontpage_title':
  101. if ( isset( $dirty[ $key ] ) && $dirty[ $key ] !== '' ) {
  102. $clean[ $key ] = WPSEO_Utils::sanitize_text_field( $dirty[ $key ] );
  103. }
  104. break;
  105. /* URL text fields - no ftp allowed. */
  106. case 'facebook_site':
  107. case 'instagram_url':
  108. case 'linkedin_url':
  109. case 'myspace_url':
  110. case 'pinterest_url':
  111. case 'plus-publisher':
  112. case 'og_default_image':
  113. case 'og_frontpage_image':
  114. case 'youtube_url':
  115. case 'google_plus_url':
  116. $this->validate_url( $key, $dirty, $old, $clean );
  117. break;
  118. case 'pinterestverify':
  119. $this->validate_verification_string( $key, $dirty, $old, $clean );
  120. break;
  121. /* twitter user name */
  122. case 'twitter_site':
  123. if ( isset( $dirty[ $key ] ) && $dirty[ $key ] !== '' ) {
  124. $twitter_id = sanitize_text_field( ltrim( $dirty[ $key ], '@' ) );
  125. /**
  126. * From the Twitter documentation about twitter screen names:
  127. * Typically a maximum of 15 characters long, but some historical accounts
  128. * may exist with longer names.
  129. * A username can only contain alphanumeric characters (letters A-Z, numbers 0-9)
  130. * with the exception of underscores.
  131. *
  132. * @link https://support.twitter.com/articles/101299-why-can-t-i-register-certain-usernames
  133. * @link https://dev.twitter.com/docs/platform-objects/users
  134. */
  135. if ( preg_match( '`^[A-Za-z0-9_]{1,25}$`', $twitter_id ) ) {
  136. $clean[ $key ] = $twitter_id;
  137. }
  138. elseif ( preg_match( '`^http(?:s)?://(?:www\.)?twitter\.com/(?P<handle>[A-Za-z0-9_]{1,25})/?$`', $twitter_id, $matches ) ) {
  139. $clean[ $key ] = $matches['handle'];
  140. }
  141. else {
  142. if ( isset( $old[ $key ] ) && $old[ $key ] !== '' ) {
  143. $twitter_id = sanitize_text_field( ltrim( $old[ $key ], '@' ) );
  144. if ( preg_match( '`^[A-Za-z0-9_]{1,25}$`', $twitter_id ) ) {
  145. $clean[ $key ] = $twitter_id;
  146. }
  147. }
  148. if ( function_exists( 'add_settings_error' ) ) {
  149. add_settings_error(
  150. $this->group_name, // Slug title of the setting.
  151. '_' . $key, // Suffix-id for the error message box.
  152. sprintf(
  153. /* translators: %s expands to a twitter user name. */
  154. __( '%s does not seem to be a valid Twitter user-id. Please correct.', 'wordpress-seo' ),
  155. '<strong>' . esc_html( sanitize_text_field( $dirty[ $key ] ) ) . '</strong>'
  156. ), // The error message.
  157. 'error' // Error type, either 'error' or 'updated'.
  158. );
  159. }
  160. }
  161. unset( $twitter_id );
  162. }
  163. break;
  164. case 'twitter_card_type':
  165. if ( isset( $dirty[ $key ], self::$twitter_card_types[ $dirty[ $key ] ] ) && $dirty[ $key ] !== '' ) {
  166. $clean[ $key ] = $dirty[ $key ];
  167. }
  168. break;
  169. /* boolean fields */
  170. case 'opengraph':
  171. case 'twitter':
  172. $clean[ $key ] = ( isset( $dirty[ $key ] ) ? WPSEO_Utils::validate_bool( $dirty[ $key ] ) : false );
  173. break;
  174. case 'fbadminapp':
  175. if ( isset( $dirty[ $key ] ) && ! empty( $dirty[ $key ] ) ) {
  176. $clean[ $key ] = $dirty[ $key ];
  177. }
  178. break;
  179. }
  180. }
  181. return $clean;
  182. }
  183. /**
  184. * Clean a given option value.
  185. *
  186. * @param array $option_value Old (not merged with defaults or filtered) option value to
  187. * clean according to the rules for this option.
  188. * @param string $current_version Optional. Version from which to upgrade, if not set,
  189. * version specific upgrades will be disregarded.
  190. * @param array $all_old_option_values Optional. Only used when importing old options to have
  191. * access to the real old values, in contrast to the saved ones.
  192. *
  193. * @return array Cleaned option.
  194. */
  195. protected function clean_option( $option_value, $current_version = null, $all_old_option_values = null ) {
  196. /* Move options from very old option to this one. */
  197. $old_option = null;
  198. if ( isset( $all_old_option_values ) ) {
  199. // Ok, we have an import.
  200. if ( isset( $all_old_option_values['wpseo_indexation'] ) && is_array( $all_old_option_values['wpseo_indexation'] ) && $all_old_option_values['wpseo_indexation'] !== array() ) {
  201. $old_option = $all_old_option_values['wpseo_indexation'];
  202. }
  203. }
  204. else {
  205. $old_option = get_option( 'wpseo_indexation' );
  206. }
  207. if ( is_array( $old_option ) && $old_option !== array() ) {
  208. $move = array(
  209. 'opengraph',
  210. );
  211. foreach ( $move as $key ) {
  212. if ( isset( $old_option[ $key ] ) && ! isset( $option_value[ $key ] ) ) {
  213. $option_value[ $key ] = $old_option[ $key ];
  214. }
  215. }
  216. unset( $move, $key );
  217. }
  218. unset( $old_option );
  219. return $option_value;
  220. }
  221. }