PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 28.5
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v28.5
28.5 28.4 28.3 28.2 28.1 28.0 27.9 27.8 27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 19.0 All 129 releases
← All changes | admin/ajax.php +144 -37 18.628.5 View file →
@@ -14,32 +14,40 @@
14 14 /**
15 15 * Convenience function to JSON encode and echo results and then die.
16 16 *
17 17 * @param array $results Results array for encoding.
18 + *
19 + * @return void
18 20 */
19 21 function wpseo_ajax_json_echo_die( $results ) {
20 22 // phpcs:ignore WordPress.Security.EscapeOutput -- Reason: WPSEO_Utils::format_json_encode is safe.
21 23 echo WPSEO_Utils::format_json_encode( $results );
22 - die();
24 + exit();
23 25 }
24 26
25 27 /**
26 28 * Function used from AJAX calls, takes it variables from $_POST, dies on exit.
29 + *
30 + * @return void
27 31 */
28 32 function wpseo_set_option() {
29 33 if ( ! current_user_can( 'manage_options' ) ) {
30 - die( '-1' );
34 + exit( '-1' );
31 35 }
32 36
33 37 check_ajax_referer( 'wpseo-setoption' );
34 38
35 - $option = sanitize_text_field( filter_input( INPUT_POST, 'option' ) );
39 + if ( ! isset( $_POST['option'] ) || ! is_string( $_POST['option'] ) ) {
40 + exit( '-1' );
41 + }
42 +
43 + $option = sanitize_text_field( wp_unslash( $_POST['option'] ) );
36 44 if ( $option !== 'page_comments' ) {
37 - die( '-1' );
45 + exit( '-1' );
38 46 }
39 47
40 48 update_option( $option, 0 );
41 - die( '1' );
49 + exit( '1' );
42 50 }
43 51
44 52 add_action( 'wp_ajax_wpseo_set_option', 'wpseo_set_option' );
45 53
@@ -49,20 +57,26 @@
49 57 add_action( 'wp_ajax_yoast_dismiss_notification', [ 'Yoast_Notification_Center', 'ajax_dismiss_notification' ] );
50 58
51 59 /**
52 60 * Function used to remove the admin notices for several purposes, dies on exit.
61 + *
62 + * @return void
53 63 */
54 64 function wpseo_set_ignore() {
55 65 if ( ! current_user_can( 'manage_options' ) ) {
56 - die( '-1' );
66 + exit( '-1' );
57 67 }
58 68
59 69 check_ajax_referer( 'wpseo-ignore' );
60 70
61 - $ignore_key = sanitize_text_field( filter_input( INPUT_POST, 'option' ) );
71 + if ( ! isset( $_POST['option'] ) || ! is_string( $_POST['option'] ) ) {
72 + exit( '-1' );
73 + }
74 +
75 + $ignore_key = sanitize_text_field( wp_unslash( $_POST['option'] ) );
62 76 WPSEO_Options::set( 'ignore_' . $ignore_key, true );
63 77
64 - die( '1' );
78 + exit( '1' );
65 79 }
66 80
67 81 add_action( 'wp_ajax_wpseo_set_ignore', 'wpseo_set_ignore' );
68 82
@@ -67,10 +81,16 @@
67 81 add_action( 'wp_ajax_wpseo_set_ignore', 'wpseo_set_ignore' );
68 82
69 83 /**
70 84 * Save an individual SEO title from the Bulk Editor.
85 + *
86 + * @deprecated 28.1
87 + * @codeCoverageIgnore
88 + *
89 + * @return void
71 90 */
72 91 function wpseo_save_title() {
92 + _deprecated_function( __FUNCTION__, 'Yoast SEO 28.1' );
73 93 wpseo_save_what( 'title' );
74 94 }
75 95
76 96 add_action( 'wp_ajax_wpseo_save_title', 'wpseo_save_title' );
@@ -76,10 +96,16 @@
76 96 add_action( 'wp_ajax_wpseo_save_title', 'wpseo_save_title' );
77 97
78 98 /**
79 99 * Save an individual meta description from the Bulk Editor.
100 + *
101 + * @deprecated 28.1
102 + * @codeCoverageIgnore
103 + *
104 + * @return void
80 105 */
81 106 function wpseo_save_description() {
107 + _deprecated_function( __FUNCTION__, 'Yoast SEO 28.1' );
82 108 wpseo_save_what( 'metadesc' );
83 109 }
84 110
85 111 add_action( 'wp_ajax_wpseo_save_metadesc', 'wpseo_save_description' );
@@ -86,17 +112,31 @@
86 112
87 113 /**
88 114 * Save titles & descriptions.
89 115 *
116 + * @deprecated 28.1
117 + * @codeCoverageIgnore
118 + *
90 119 * @param string $what Type of item to save (title, description).
120 + *
121 + * @return void
91 122 */
92 123 function wpseo_save_what( $what ) {
93 124 check_ajax_referer( 'wpseo-bulk-editor' );
94 125
95 - $new = filter_input( INPUT_POST, 'new_value' );
96 - $post_id = intval( filter_input( INPUT_POST, 'wpseo_post_id' ) );
97 - $original = filter_input( INPUT_POST, 'existing_value' );
126 + if ( ! isset( $_POST['new_value'], $_POST['wpseo_post_id'], $_POST['existing_value'] ) || ! is_string( $_POST['new_value'] ) || ! is_string( $_POST['existing_value'] ) ) {
127 + exit( '-1' );
128 + }
98 129
130 + $new = sanitize_text_field( wp_unslash( $_POST['new_value'] ) );
131 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Reason: We are casting the unsafe value to an integer.
132 + $post_id = (int) wp_unslash( $_POST['wpseo_post_id'] );
133 + $original = sanitize_text_field( wp_unslash( $_POST['existing_value'] ) );
134 +
135 + if ( $post_id === 0 ) {
136 + exit( '-1' );
137 + }
138 +
99 139 $results = wpseo_upsert_new( $what, $post_id, $new, $original );
100 140
101 141 wpseo_ajax_json_echo_die( $results );
102 142 }
@@ -104,8 +144,11 @@
104 144 /**
105 145 * Helper function to update a post's meta data, returning relevant information
106 146 * about the information updated and the results or the meta update.
107 147 *
148 + * @deprecated 28.1
149 + * @codeCoverageIgnore
150 + *
108 151 * @param int $post_id Post ID.
109 152 * @param string $new_meta_value New meta value to record.
110 153 * @param string $orig_meta_value Original meta value.
111 154 * @param string $meta_key Meta key string.
@@ -110,13 +153,13 @@
110 153 * @param string $orig_meta_value Original meta value.
111 154 * @param string $meta_key Meta key string.
112 155 * @param string $return_key Return key string to use in results.
113 156 *
114 - * @return string
157 + * @return array
115 158 */
116 159 function wpseo_upsert_meta( $post_id, $new_meta_value, $orig_meta_value, $meta_key, $return_key ) {
117 160
118 - $post_id = intval( $post_id );
161 + $post_id = (int) $post_id;
119 162 $sanitized_new_meta_value = wp_strip_all_tags( $new_meta_value );
120 163 $orig_meta_value = wp_strip_all_tags( $orig_meta_value );
121 164
122 165 $upsert_results = [
@@ -141,9 +184,9 @@
141 184 $upsert_results['status'] = 'failure';
142 185 $upsert_results['results'] = sprintf(
143 186 /* translators: %s expands to post type. */
144 187 __( 'Post has an invalid Content Type: %s.', 'wordpress-seo' ),
145 - $the_post->post_type
188 + $the_post->post_type,
146 189 );
147 190
148 191 return $upsert_results;
149 192 }
@@ -153,9 +196,9 @@
153 196 $upsert_results['status'] = 'failure';
154 197 $upsert_results['results'] = sprintf(
155 198 /* translators: %s expands to post type name. */
156 199 __( 'You can\'t edit %s.', 'wordpress-seo' ),
157 - $post_type_object->label
200 + $post_type_object->label,
158 201 );
159 202
160 203 return $upsert_results;
161 204 }
@@ -165,9 +208,9 @@
165 208 $upsert_results['status'] = 'failure';
166 209 $upsert_results['results'] = sprintf(
167 210 /* translators: %s expands to the name of a post type (plural). */
168 211 __( 'You can\'t edit %s that aren\'t yours.', 'wordpress-seo' ),
169 - $post_type_object->label
212 + $post_type_object->label,
170 213 );
171 214
172 215 return $upsert_results;
173 216 }
@@ -188,10 +231,16 @@
188 231 }
189 232
190 233 /**
191 234 * Save all titles sent from the Bulk Editor.
235 + *
236 + * @deprecated 28.1
237 + * @codeCoverageIgnore
238 + *
239 + * @return void
192 240 */
193 241 function wpseo_save_all_titles() {
242 + _deprecated_function( __FUNCTION__, 'Yoast SEO 28.1' );
194 243 wpseo_save_all( 'title' );
195 244 }
196 245
197 246 add_action( 'wp_ajax_wpseo_save_all_titles', 'wpseo_save_all_titles' );
@@ -197,10 +246,16 @@
197 246 add_action( 'wp_ajax_wpseo_save_all_titles', 'wpseo_save_all_titles' );
198 247
199 248 /**
200 249 * Save all description sent from the Bulk Editor.
250 + *
251 + * @deprecated 28.1
252 + * @codeCoverageIgnore
253 + *
254 + * @return void
201 255 */
202 256 function wpseo_save_all_descriptions() {
257 + _deprecated_function( __FUNCTION__, 'Yoast SEO 28.1' );
203 258 wpseo_save_all( 'metadesc' );
204 259 }
205 260
206 261 add_action( 'wp_ajax_wpseo_save_all_descriptions', 'wpseo_save_all_descriptions' );
@@ -207,9 +262,14 @@
207 262
208 263 /**
209 264 * Utility function to save values.
210 265 *
266 + * @deprecated 28.1
267 + * @codeCoverageIgnore
268 + *
211 269 * @param string $what Type of item so save.
270 + *
271 + * @return void
212 272 */
213 273 function wpseo_save_all( $what ) {
214 274 check_ajax_referer( 'wpseo-bulk-editor' );
215 275
@@ -231,8 +291,11 @@
231 291
232 292 /**
233 293 * Insert a new value.
234 294 *
295 + * @deprecated 28.1
296 + * @codeCoverageIgnore
297 + *
235 298 * @param string $what Item type (such as title).
236 299 * @param int $post_id Post ID.
237 300 * @param string $new_value New value to record.
238 301 * @param string $original Original value.
@@ -245,34 +308,65 @@
245 308 return wpseo_upsert_meta( $post_id, $new_value, $original, $meta_key, $what );
246 309 }
247 310
248 311 /**
249 - * Retrieves the keyword for the keyword doubles.
312 + * Retrieves the post ids where the keyword is used before as well as the types of those posts.
313 + *
314 + * @return void
250 315 */
251 -function ajax_get_keyword_usage() {
252 - $post_id = filter_input( INPUT_POST, 'post_id' );
253 - $keyword = filter_input( INPUT_POST, 'keyword' );
316 +function ajax_get_keyword_usage_and_post_types() {
317 + check_ajax_referer( 'wpseo-keyword-usage-and-post-types', 'nonce' );
254 318
255 - if ( ! current_user_can( 'edit_post', $post_id ) ) {
256 - die( '-1' );
319 + if ( ! isset( $_POST['post_id'], $_POST['keyword'] ) || ! is_string( $_POST['keyword'] ) ) {
320 + exit( '-1' );
257 321 }
258 322
323 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- We are casting to an integer.
324 + $post_id = (int) wp_unslash( $_POST['post_id'] );
325 +
326 + if ( $post_id === 0 || ! current_user_can( 'edit_post', $post_id ) ) {
327 + exit( '-1' );
328 + }
329 +
330 + $keyword = sanitize_text_field( wp_unslash( $_POST['keyword'] ) );
331 +
332 + $post_ids = WPSEO_Meta::keyword_usage( $keyword, $post_id );
333 +
334 + $return_object = [
335 + 'keyword_usage' => $post_ids,
336 + 'post_types' => WPSEO_Meta::post_types_for_ids( $post_ids ),
337 + ];
338 +
259 339 wp_die(
260 340 // phpcs:ignore WordPress.Security.EscapeOutput -- Reason: WPSEO_Utils::format_json_encode is safe.
261 - WPSEO_Utils::format_json_encode( WPSEO_Meta::keyword_usage( $keyword, $post_id ) )
341 + WPSEO_Utils::format_json_encode( $return_object ),
262 342 );
263 343 }
264 344
265 -add_action( 'wp_ajax_get_focus_keyword_usage', 'ajax_get_keyword_usage' );
345 +add_action( 'wp_ajax_get_focus_keyword_usage_and_post_types', 'ajax_get_keyword_usage_and_post_types' );
266 346
267 347 /**
268 348 * Retrieves the keyword for the keyword doubles of the termpages.
349 + *
350 + * @return void
269 351 */
270 352 function ajax_get_term_keyword_usage() {
271 - $post_id = filter_input( INPUT_POST, 'post_id' );
272 - $keyword = filter_input( INPUT_POST, 'keyword' );
273 - $taxonomy_name = filter_input( INPUT_POST, 'taxonomy' );
353 + check_ajax_referer( 'wpseo-keyword-usage', 'nonce' );
274 354
355 + if ( ! isset( $_POST['post_id'], $_POST['keyword'], $_POST['taxonomy'] ) || ! is_string( $_POST['keyword'] ) || ! is_string( $_POST['taxonomy'] ) ) {
356 + wp_die( -1 );
357 + }
358 +
359 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Reason: We are casting the unsafe input to an integer.
360 + $post_id = (int) wp_unslash( $_POST['post_id'] );
361 +
362 + if ( $post_id === 0 ) {
363 + wp_die( -1 );
364 + }
365 +
366 + $keyword = sanitize_text_field( wp_unslash( $_POST['keyword'] ) );
367 + $taxonomy_name = sanitize_text_field( wp_unslash( $_POST['taxonomy'] ) );
368 +
275 369 $taxonomy = get_taxonomy( $taxonomy_name );
276 370
277 371 if ( ! $taxonomy ) {
278 372 wp_die( 0 );
@@ -283,14 +377,14 @@
283 377 }
284 378
285 379 $usage = WPSEO_Taxonomy_Meta::get_keyword_usage( $keyword, $post_id, $taxonomy_name );
286 380
287 - // Normalize the result so it it the same as the post keyword usage AJAX request.
381 + // Normalize the result so it is the same as the post keyword usage AJAX request.
288 382 $usage = $usage[ $keyword ];
289 383
290 384 wp_die(
291 385 // phpcs:ignore WordPress.Security.EscapeOutput -- Reason: WPSEO_Utils::format_json_encode is safe.
292 - WPSEO_Utils::format_json_encode( $usage )
386 + WPSEO_Utils::format_json_encode( $usage ),
293 387 );
294 388 }
295 389
296 390 add_action( 'wp_ajax_get_term_keyword_usage', 'ajax_get_term_keyword_usage' );
@@ -316,17 +410,30 @@
316 410
317 411 /* ********************* DEPRECATED FUNCTIONS ********************* */
318 412
319 413 /**
320 - * Hides the default tagline notice for a specific user.
414 + * Retrieves the keyword for the keyword doubles.
321 415 *
322 - * @deprecated 13.2
323 - * @codeCoverageIgnore
416 + * @return void
324 417 */
325 -function wpseo_dismiss_tagline_notice() {
326 - if ( ! current_user_can( 'manage_options' ) ) {
327 - die( '-1' );
418 +function ajax_get_keyword_usage() {
419 + _deprecated_function( __METHOD__, 'WPSEO 20.4' );
420 + check_ajax_referer( 'wpseo-keyword-usage', 'nonce' );
421 +
422 + if ( ! isset( $_POST['post_id'], $_POST['keyword'] ) || ! is_string( $_POST['keyword'] ) ) {
423 + exit( '-1' );
328 424 }
329 425
330 - _deprecated_function( __FUNCTION__, 'WPSEO 13.2', 'This method is deprecated.' );
331 - wpseo_ajax_json_echo_die( '' );
426 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- We are casting to an integer.
427 + $post_id = (int) wp_unslash( $_POST['post_id'] );
428 +
429 + if ( $post_id === 0 || ! current_user_can( 'edit_post', $post_id ) ) {
430 + exit( '-1' );
431 + }
432 +
433 + $keyword = sanitize_text_field( wp_unslash( $_POST['keyword'] ) );
434 +
435 + wp_die(
436 + // phpcs:ignore WordPress.Security.EscapeOutput -- Reason: WPSEO_Utils::format_json_encode is safe.
437 + WPSEO_Utils::format_json_encode( WPSEO_Meta::keyword_usage( $keyword, $post_id ) ),
438 + );
332 439 }