ajax
2 years ago
capabilities
2 years ago
endpoints
2 years ago
exceptions
7 years ago
filters
2 years ago
formatter
2 years ago
google_search_console
2 years ago
import
2 years ago
listeners
8 years ago
menu
2 years ago
metabox
2 years ago
notifiers
3 years ago
pages
2 years ago
roles
2 years ago
services
5 years ago
statistics
2 years ago
taxonomy
2 years ago
tracking
2 years ago
views
2 years ago
watchers
2 years ago
admin-settings-changed-listener.php
2 years ago
ajax.php
2 years ago
class-admin-asset-analysis-worker-location.php
5 years ago
class-admin-asset-dev-server-location.php
2 years ago
class-admin-asset-location.php
8 years ago
class-admin-asset-manager.php
2 years ago
class-admin-asset-seo-location.php
4 years ago
class-admin-editor-specific-replace-vars.php
2 years ago
class-admin-gutenberg-compatibility-notification.php
2 years ago
class-admin-help-panel.php
5 years ago
class-admin-init.php
2 years ago
class-admin-recommended-replace-vars.php
2 years ago
class-admin-user-profile.php
2 years ago
class-admin-utils.php
2 years ago
class-admin.php
2 years ago
class-asset.php
2 years ago
class-bulk-description-editor-list-table.php
5 years ago
class-bulk-editor-list-table.php
2 years ago
class-bulk-title-editor-list-table.php
6 years ago
class-collector.php
2 years ago
class-config.php
2 years ago
class-customizer.php
2 years ago
class-database-proxy.php
2 years ago
class-export.php
2 years ago
class-expose-shortlinks.php
2 years ago
class-gutenberg-compatibility.php
2 years ago
class-meta-columns.php
2 years ago
class-my-yoast-proxy.php
2 years ago
class-option-tab.php
4 years ago
class-option-tabs-formatter.php
2 years ago
class-option-tabs.php
2 years ago
class-paper-presenter.php
5 years ago
class-plugin-availability.php
2 years ago
class-plugin-conflict.php
2 years ago
class-premium-popup.php
2 years ago
class-premium-upsell-admin-block.php
2 years ago
class-primary-term-admin.php
2 years ago
class-product-upsell-notice.php
2 years ago
class-remote-request.php
2 years ago
class-schema-person-upgrade-notification.php
2 years ago
class-suggested-plugins.php
2 years ago
class-wincher-dashboard-widget.php
2 years ago
class-yoast-columns.php
2 years ago
class-yoast-dashboard-widget.php
2 years ago
class-yoast-form.php
2 years ago
class-yoast-input-validation.php
2 years ago
class-yoast-network-admin.php
2 years ago
class-yoast-network-settings-api.php
4 years ago
class-yoast-notification-center.php
2 years ago
class-yoast-notification.php
2 years ago
class-yoast-notifications.php
2 years ago
class-yoast-plugin-conflict.php
2 years ago
index.php
10 years ago
interface-collection.php
7 years ago
interface-installable.php
8 years ago
class-yoast-input-validation.php
329 lines
| 1 | <?php |
| 2 | /** |
| 3 | * WPSEO plugin file. |
| 4 | * |
| 5 | * @package WPSEO\Admin |
| 6 | */ |
| 7 | |
| 8 | /** |
| 9 | * Implements server-side user input validation. |
| 10 | * |
| 11 | * @since 12.0 |
| 12 | */ |
| 13 | class Yoast_Input_Validation { |
| 14 | |
| 15 | /** |
| 16 | * The error descriptions. |
| 17 | * |
| 18 | * @since 12.1 |
| 19 | * |
| 20 | * @var array |
| 21 | */ |
| 22 | private static $error_descriptions = []; |
| 23 | |
| 24 | /** |
| 25 | * Check whether an option group is a Yoast SEO setting. |
| 26 | * |
| 27 | * The normal pattern is 'yoast' . $option_name . 'options'. |
| 28 | * |
| 29 | * @since 12.0 |
| 30 | * |
| 31 | * @param string $group_name The option group name. |
| 32 | * |
| 33 | * @return bool Whether or not it's an Yoast SEO option group. |
| 34 | */ |
| 35 | public static function is_yoast_option_group_name( $group_name ) { |
| 36 | return ( strpos( $group_name, 'yoast' ) !== false ); |
| 37 | } |
| 38 | |
| 39 | /** |
| 40 | * Adds an error message to the document title when submitting a settings |
| 41 | * form and errors are returned. |
| 42 | * |
| 43 | * Uses the WordPress `admin_title` filter in the WPSEO_Option subclasses. |
| 44 | * |
| 45 | * @since 12.0 |
| 46 | * |
| 47 | * @param string $admin_title The page title, with extra context added. |
| 48 | * |
| 49 | * @return string The modified or original admin title. |
| 50 | */ |
| 51 | public static function add_yoast_admin_document_title_errors( $admin_title ) { |
| 52 | $errors = get_settings_errors(); |
| 53 | $error_count = 0; |
| 54 | |
| 55 | foreach ( $errors as $error ) { |
| 56 | // For now, filter the admin title only in the Yoast SEO settings pages. |
| 57 | if ( self::is_yoast_option_group_name( $error['setting'] ) && $error['code'] !== 'settings_updated' ) { |
| 58 | ++$error_count; |
| 59 | } |
| 60 | } |
| 61 | |
| 62 | if ( $error_count > 0 ) { |
| 63 | return sprintf( |
| 64 | /* translators: %1$s: amount of errors, %2$s: the admin page title */ |
| 65 | _n( 'The form contains %1$s error. %2$s', 'The form contains %1$s errors. %2$s', $error_count, 'wordpress-seo' ), |
| 66 | number_format_i18n( $error_count ), |
| 67 | $admin_title |
| 68 | ); |
| 69 | } |
| 70 | |
| 71 | return $admin_title; |
| 72 | } |
| 73 | |
| 74 | /** |
| 75 | * Checks whether a specific form input field was submitted with an invalid value. |
| 76 | * |
| 77 | * @since 12.1 |
| 78 | * |
| 79 | * @param string $error_code Must be the same slug-name used for the field variable and for `add_settings_error()`. |
| 80 | * |
| 81 | * @return bool Whether or not the submitted input field contained an invalid value. |
| 82 | */ |
| 83 | public static function yoast_form_control_has_error( $error_code ) { |
| 84 | $errors = get_settings_errors(); |
| 85 | |
| 86 | foreach ( $errors as $error ) { |
| 87 | if ( $error['code'] === $error_code ) { |
| 88 | return true; |
| 89 | } |
| 90 | } |
| 91 | |
| 92 | return false; |
| 93 | } |
| 94 | |
| 95 | /** |
| 96 | * Sets the error descriptions. |
| 97 | * |
| 98 | * @since 12.1 |
| 99 | * |
| 100 | * @param array $descriptions An associative array of error descriptions. |
| 101 | * For each entry, the key must be the setting variable. |
| 102 | * |
| 103 | * @return void |
| 104 | */ |
| 105 | public static function set_error_descriptions( $descriptions = [] ) { |
| 106 | $defaults = [ |
| 107 | 'baiduverify' => sprintf( |
| 108 | /* translators: %s: additional message with the submitted invalid value */ |
| 109 | esc_html__( 'Baidu verification codes can only contain letters, numbers, hyphens, and underscores. %s', 'wordpress-seo' ), |
| 110 | self::get_dirty_value_message( 'baiduverify' ) |
| 111 | ), |
| 112 | 'facebook_site' => sprintf( |
| 113 | /* translators: %s: additional message with the submitted invalid value */ |
| 114 | esc_html__( 'Please check the format of the Facebook Page URL you entered. %s', 'wordpress-seo' ), |
| 115 | self::get_dirty_value_message( 'facebook_site' ) |
| 116 | ), |
| 117 | 'googleverify' => sprintf( |
| 118 | /* translators: %s: additional message with the submitted invalid value */ |
| 119 | esc_html__( 'Google verification codes can only contain letters, numbers, hyphens, and underscores. %s', 'wordpress-seo' ), |
| 120 | self::get_dirty_value_message( 'googleverify' ) |
| 121 | ), |
| 122 | 'instagram_url' => sprintf( |
| 123 | /* translators: %s: additional message with the submitted invalid value */ |
| 124 | esc_html__( 'Please check the format of the Instagram URL you entered. %s', 'wordpress-seo' ), |
| 125 | self::get_dirty_value_message( 'instagram_url' ) |
| 126 | ), |
| 127 | 'linkedin_url' => sprintf( |
| 128 | /* translators: %s: additional message with the submitted invalid value */ |
| 129 | esc_html__( 'Please check the format of the LinkedIn URL you entered. %s', 'wordpress-seo' ), |
| 130 | self::get_dirty_value_message( 'linkedin_url' ) |
| 131 | ), |
| 132 | 'msverify' => sprintf( |
| 133 | /* translators: %s: additional message with the submitted invalid value */ |
| 134 | esc_html__( 'Bing confirmation codes can only contain letters from A to F, numbers, hyphens, and underscores. %s', 'wordpress-seo' ), |
| 135 | self::get_dirty_value_message( 'msverify' ) |
| 136 | ), |
| 137 | 'myspace_url' => sprintf( |
| 138 | /* translators: %s: additional message with the submitted invalid value */ |
| 139 | esc_html__( 'Please check the format of the MySpace URL you entered. %s', 'wordpress-seo' ), |
| 140 | self::get_dirty_value_message( 'myspace_url' ) |
| 141 | ), |
| 142 | 'pinterest_url' => sprintf( |
| 143 | /* translators: %s: additional message with the submitted invalid value */ |
| 144 | esc_html__( 'Please check the format of the Pinterest URL you entered. %s', 'wordpress-seo' ), |
| 145 | self::get_dirty_value_message( 'pinterest_url' ) |
| 146 | ), |
| 147 | 'pinterestverify' => sprintf( |
| 148 | /* translators: %s: additional message with the submitted invalid value */ |
| 149 | esc_html__( 'Pinterest confirmation codes can only contain letters from A to F, numbers, hyphens, and underscores. %s', 'wordpress-seo' ), |
| 150 | self::get_dirty_value_message( 'pinterestverify' ) |
| 151 | ), |
| 152 | 'twitter_site' => sprintf( |
| 153 | /* translators: %s: additional message with the submitted invalid value */ |
| 154 | esc_html__( 'Twitter usernames can only contain letters, numbers, and underscores. %s', 'wordpress-seo' ), |
| 155 | self::get_dirty_value_message( 'twitter_site' ) |
| 156 | ), |
| 157 | 'wikipedia_url' => sprintf( |
| 158 | /* translators: %s: additional message with the submitted invalid value */ |
| 159 | esc_html__( 'Please check the format of the Wikipedia URL you entered. %s', 'wordpress-seo' ), |
| 160 | self::get_dirty_value_message( 'wikipedia_url' ) |
| 161 | ), |
| 162 | 'yandexverify' => sprintf( |
| 163 | /* translators: %s: additional message with the submitted invalid value */ |
| 164 | esc_html__( 'Yandex confirmation codes can only contain letters from A to F, numbers, hyphens, and underscores. %s', 'wordpress-seo' ), |
| 165 | self::get_dirty_value_message( 'yandexverify' ) |
| 166 | ), |
| 167 | 'youtube_url' => sprintf( |
| 168 | /* translators: %s: additional message with the submitted invalid value */ |
| 169 | esc_html__( 'Please check the format of the YouTube URL you entered. %s', 'wordpress-seo' ), |
| 170 | self::get_dirty_value_message( 'youtube_url' ) |
| 171 | ), |
| 172 | ]; |
| 173 | |
| 174 | $descriptions = wp_parse_args( $descriptions, $defaults ); |
| 175 | |
| 176 | self::$error_descriptions = $descriptions; |
| 177 | } |
| 178 | |
| 179 | /** |
| 180 | * Gets all the error descriptions. |
| 181 | * |
| 182 | * @since 12.1 |
| 183 | * |
| 184 | * @return array An associative array of error descriptions. |
| 185 | */ |
| 186 | public static function get_error_descriptions() { |
| 187 | return self::$error_descriptions; |
| 188 | } |
| 189 | |
| 190 | /** |
| 191 | * Gets a specific error description. |
| 192 | * |
| 193 | * @since 12.1 |
| 194 | * |
| 195 | * @param string $error_code Code of the error set via `add_settings_error()`, normally the variable name. |
| 196 | * |
| 197 | * @return string|null The error description. |
| 198 | */ |
| 199 | public static function get_error_description( $error_code ) { |
| 200 | if ( ! isset( self::$error_descriptions[ $error_code ] ) ) { |
| 201 | return null; |
| 202 | } |
| 203 | |
| 204 | return self::$error_descriptions[ $error_code ]; |
| 205 | } |
| 206 | |
| 207 | /** |
| 208 | * Gets the aria-invalid HTML attribute based on the submitted invalid value. |
| 209 | * |
| 210 | * @since 12.1 |
| 211 | * |
| 212 | * @param string $error_code Code of the error set via `add_settings_error()`, normally the variable name. |
| 213 | * |
| 214 | * @return string The aria-invalid HTML attribute or empty string. |
| 215 | */ |
| 216 | public static function get_the_aria_invalid_attribute( $error_code ) { |
| 217 | if ( self::yoast_form_control_has_error( $error_code ) ) { |
| 218 | return ' aria-invalid="true"'; |
| 219 | } |
| 220 | |
| 221 | return ''; |
| 222 | } |
| 223 | |
| 224 | /** |
| 225 | * Gets the aria-describedby HTML attribute based on the submitted invalid value. |
| 226 | * |
| 227 | * @since 12.1 |
| 228 | * |
| 229 | * @param string $error_code Code of the error set via `add_settings_error()`, normally the variable name. |
| 230 | * |
| 231 | * @return string The aria-describedby HTML attribute or empty string. |
| 232 | */ |
| 233 | public static function get_the_aria_describedby_attribute( $error_code ) { |
| 234 | if ( self::yoast_form_control_has_error( $error_code ) && self::get_error_description( $error_code ) ) { |
| 235 | return ' aria-describedby="' . esc_attr( $error_code ) . '-error-description"'; |
| 236 | } |
| 237 | |
| 238 | return ''; |
| 239 | } |
| 240 | |
| 241 | /** |
| 242 | * Gets the error description wrapped in a HTML paragraph. |
| 243 | * |
| 244 | * @since 12.1 |
| 245 | * |
| 246 | * @param string $error_code Code of the error set via `add_settings_error()`, normally the variable name. |
| 247 | * |
| 248 | * @return string The error description HTML or empty string. |
| 249 | */ |
| 250 | public static function get_the_error_description( $error_code ) { |
| 251 | $error_description = self::get_error_description( $error_code ); |
| 252 | |
| 253 | if ( self::yoast_form_control_has_error( $error_code ) && $error_description ) { |
| 254 | return '<p id="' . esc_attr( $error_code ) . '-error-description" class="yoast-input-validation__error-description">' . $error_description . '</p>'; |
| 255 | } |
| 256 | |
| 257 | return ''; |
| 258 | } |
| 259 | |
| 260 | /** |
| 261 | * Adds the submitted invalid value to the WordPress `$wp_settings_errors` global. |
| 262 | * |
| 263 | * @since 12.1 |
| 264 | * |
| 265 | * @param string $error_code Code of the error set via `add_settings_error()`, normally the variable name. |
| 266 | * @param string $dirty_value The submitted invalid value. |
| 267 | * |
| 268 | * @return void |
| 269 | */ |
| 270 | public static function add_dirty_value_to_settings_errors( $error_code, $dirty_value ) { |
| 271 | global $wp_settings_errors; |
| 272 | |
| 273 | if ( ! is_array( $wp_settings_errors ) ) { |
| 274 | return; |
| 275 | } |
| 276 | |
| 277 | foreach ( $wp_settings_errors as $index => $error ) { |
| 278 | if ( $error['code'] === $error_code ) { |
| 279 | // phpcs:ignore WordPress.WP.GlobalVariablesOverride -- This is a deliberate action. |
| 280 | $wp_settings_errors[ $index ]['yoast_dirty_value'] = $dirty_value; |
| 281 | } |
| 282 | } |
| 283 | } |
| 284 | |
| 285 | /** |
| 286 | * Gets an invalid submitted value. |
| 287 | * |
| 288 | * @since 12.1 |
| 289 | * |
| 290 | * @param string $error_code Code of the error set via `add_settings_error()`, normally the variable name. |
| 291 | * |
| 292 | * @return string The submitted invalid input field value. |
| 293 | */ |
| 294 | public static function get_dirty_value( $error_code ) { |
| 295 | $errors = get_settings_errors(); |
| 296 | |
| 297 | foreach ( $errors as $error ) { |
| 298 | if ( $error['code'] === $error_code && isset( $error['yoast_dirty_value'] ) ) { |
| 299 | return $error['yoast_dirty_value']; |
| 300 | } |
| 301 | } |
| 302 | |
| 303 | return ''; |
| 304 | } |
| 305 | |
| 306 | /** |
| 307 | * Gets a specific invalid value message. |
| 308 | * |
| 309 | * @since 12.1 |
| 310 | * |
| 311 | * @param string $error_code Code of the error set via `add_settings_error()`, normally the variable name. |
| 312 | * |
| 313 | * @return string The error invalid value message or empty string. |
| 314 | */ |
| 315 | public static function get_dirty_value_message( $error_code ) { |
| 316 | $dirty_value = self::get_dirty_value( $error_code ); |
| 317 | |
| 318 | if ( $dirty_value ) { |
| 319 | return sprintf( |
| 320 | /* translators: %s: form value as submitted. */ |
| 321 | esc_html__( 'The submitted value was: %s', 'wordpress-seo' ), |
| 322 | esc_html( $dirty_value ) |
| 323 | ); |
| 324 | } |
| 325 | |
| 326 | return ''; |
| 327 | } |
| 328 | } |
| 329 |