Repository: WordPress/WordPress-Coding-Standards (php)

Issue:
Remove deprecation Warning on sanitize_url()
## Bug Description

The use of sanitize_url() is still listed as deprecated, however as of WordPress 5.9 it has been **un** deprecated

## Minimal Code Snippet

Use sanitize_url() in a line of code.
ERROR   sanitize_url() has been deprecated since WordPress version 2.8.0. Use esc_url_raw() instead.
                  (WordPress.WP.DeprecatedFunctions.sanitize_urlFound)

This can be fixed by removing it from the deprecation list.

## Tested Against `develop` branch?

I have not tested against develop, but I did check here:

https://github.com/WordPress/WordPress-Coding-Standards/blob/develop/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php#L412

So it's still on the sniffs :)

Pull request:
Update the minimum_wp_version to WP 5.8
The minimum version should be three versions behind the latest WP release, so what with 6.1 being out, it should now be 5.8.

Includes adding a little more variation to the example code in the property docblock in the `MinimumWPVersionTrait`.

Includes updating the list of deprecated functions in the `WP.DeprecatedFunctions` sniff based on the WP 6.1.1 release. Input for this based on @JDGrimes's WP deprecated code scanner, though that is getting more and more difficult to run as it is no longer maintained and is throwing lots of errors.

Notes:
* The `sanitize_url()` function has been _un_deprecated in WP 5.9. See #2031.
* The replacement for the deprecated `wp_cache_reset()` function has been changed in WP Core.
    Ref: https://core.trac.wordpress.org/changeset/52705
* The `_filter_query_attachment_filenames()` function listed the wrong deprecation version in Core. WPCS now contains the correct version.
    A patch has been submitted to fix the listing in Core (and has since been committed and backported).
    Refs:
    - https://core.trac.wordpress.org/changeset/54524
    - https://core.trac.wordpress.org/ticket/56791#comment:10
* Other than the above, no verification has been executed on the newly added deprecated function information.

Includes minor tweak to make the generation of the test lines array a little more descriptive.

Previous: #1881

Closes #2031

---

### 🆕 WP/DeprecatedFunctions: temporarily exclude one test on PHP 8.2

The logic in the PHP 8.2 Tokenizer needs to be adjusted to allow for PHP 8.2 Disjunctive Normal Types in combination with `readonly` properties.

While PHP 8.2 still allows for the `readonly` keyword being used as a function call - see: https://3v4l.org/hL5da -, the PHPCS tokenizer has not been adjusted yet to allow for this in a way which is compatible with DNT.

Also see:
* The discussion about this in squizlabs/PHP_CodeSniffer 3667
* php/php-src 9512


Patch:
diff --git a/WordPress/Helpers/MinimumWPVersionTrait.php b/WordPress/Helpers/MinimumWPVersionTrait.php
index 96810d35..5b98351f 100644
--- a/WordPress/Helpers/MinimumWPVersionTrait.php
+++ b/WordPress/Helpers/MinimumWPVersionTrait.php
@@ -48,15 +48,15 @@ trait MinimumWPVersionTrait {
 	 * Example usage:
 	 * <rule ref="WordPress.WP.DeprecatedClasses">
 	 *  <properties>
-	 *   <property name="minimum_wp_version" value="4.3"/>
+	 *   <property name="minimum_wp_version" value="4.9"/>
 	 *  </properties>
 	 * </rule>
 	 *
 	 * Alternatively, the value can be passed in one go for all sniffs using it via
 	 * the command line or by setting a `<config>` value in a custom phpcs.xml ruleset.
 	 *
-	 * CL: `phpcs --runtime-set minimum_wp_version 4.5`
-	 * Ruleset: `<config name="minimum_wp_version" value="4.5"/>`
+	 * CL:      `phpcs --runtime-set minimum_wp_version 5.7`
+	 * Ruleset: `<config name="minimum_wp_version" value="6.0"/>`
 	 *
 	 * @since 0.14.0 Previously the individual sniffs each contained this property.
 	 * @since 3.0.0  - Moved from the Sniff class to this dedicated Trait.
@@ -68,7 +68,7 @@ trait MinimumWPVersionTrait {
 	 *
 	 * @var string WordPress version.
 	 */
-	public $minimum_wp_version = '5.1';
+	public $minimum_wp_version = '5.8';
 
 	/**
 	 * Overrule the minimum supported WordPress version with a command-line/config value.
diff --git a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php
index 2e5968d0..b7aabb5a 100644
--- a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php
+++ b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php
@@ -410,10 +410,6 @@ class DeprecatedFunctionsSniff extends AbstractFunctionRestrictionsSniff {
 			'alt'     => 'wp_register_widget_control()',
 			'version' => '2.8.0',
 		),
-		'sanitize_url' => array(
-			'alt'     => 'esc_url_raw()',
-			'version' => '2.8.0',
-		),
 		'the_author_aim' => array(
 			'alt'     => 'the_author_meta(\'aim\')',
 			'version' => '2.8.0',
@@ -988,7 +984,7 @@ class DeprecatedFunctionsSniff extends AbstractFunctionRestrictionsSniff {
 			'version' => '3.5.0',
 		),
 		'wp_cache_reset' => array(
-			'alt'     => 'WP_Object_Cache::reset()',
+			'alt'     => 'wp_cache_switch_to_blog()',
 			'version' => '3.5.0',
 		),
 		'wp_create_thumbnail' => array(
@@ -1369,6 +1365,137 @@ class DeprecatedFunctionsSniff extends AbstractFunctionRestrictionsSniff {
 			'alt'     => 'wp_get_user_request()',
 			'version' => '5.4.0',
 		),
+
+		// WP 5.5.0.
+		'_wp_register_meta_args_whitelist' => array(
+			'alt'     => '_wp_register_meta_args_allowed_list()',
+			'version' => '5.5.0',
+		),
+		'add_option_whitelist' => array(
+			'alt'     => 'add_allowed_options()',
+			'version' => '5.5.0',
+		),
+		'remove_option_whitelist' => array(
+			'alt'     => 'remove_allowed_options()',
+			'version' => '5.5.0',
+		),
+		'wp_blacklist_check' => array(
+			'alt'     => 'wp_check_comment_disallowed_list()',
+			'version' => '5.5.0',
+		),
+		'wp_make_content_images_responsive' => array(
+			'alt'     => 'wp_filter_content_tags()',
+			'version' => '5.5.0',
+		),
+		'wp_unregister_GLOBALS' => array(
+			'alt'     => '',
+			'version' => '5.5.0',
+		),
+
+		// WP 5.7.0.
+		'noindex' => array(
+			'alt'     => 'wp_robots_noindex()',
+			'version' => '5.7.0',
+		),
+		'wp_no_robots' => array(
+			'alt'     => 'wp_robots_no_robots()',
+			'version' => '5.7.0',
+		),
+		'wp_sensitive_page_meta' => array(
+			'alt'     => 'wp_robots_sensitive_page()',
+			'version' => '5.7.0',
+		),
+
+		// WP 5.8.0.
+		'_excerpt_render_inner_columns_blocks' => array(
+			'alt'     => '_excerpt_render_inner_blocks()',
+			'version' => '5.8.0',
+		),
+
+		// WP 5.9.0.
+		'readonly' => array(
+			'alt'     => 'wp_readonly()',
+			'version' => '5.9.0',
+		),
+
+		// WP 5.9.1.
+		'wp_render_duotone_filter_preset' => array(
+			'alt'     => 'wp_get_duotone_filter_property()',
+			'version' => '5.9.1',
+		),
+
+		// WP 6.0.0.
+		'image_attachment_fields_to_save' => array(
+			'alt'     => '',
+			'version' => '6.0.0',
+		),
+		'wp_add_iframed_editor_assets_html' => array(
+			'alt'     => '',
+			'version' => '6.0.0',
+		),
+		'wp_skip_border_serialization' => array(
+			'alt'     => 'wp_should_skip_block_supports_serialization()',
+			'version' => '6.0.0',
+		),
+		'wp_skip_dimensions_serialization' => array(
+			'alt'     => 'wp_should_skip_block_supports_serialization()',
+			'version' => '6.0.0',
+		),
+		'wp_skip_spacing_serialization' => array(
+			'alt'     => 'wp_should_skip_block_supports_serialization()',
+			'version' => '6.0.0',
+		),
+
+		// WP 6.0.2.
+		'the_meta' => array(
+			'alt'     => 'get_post_meta()',
+			'version' => '6.0.2',
+		),
+
+		// WP 6.0.3.
+		// Verified; see https://core.trac.wordpress.org/ticket/56791#comment:10.
+		'_filter_query_attachment_filenames' => array(
+			'alt'     => 'add_filter( "wp_allow_query_attachment_by_filename", "__return_true" )',
+			'version' => '6.0.3',
+		),
+
+		// WP 6.1.0.
+		'_get_path_to_translation' => array(
+			'alt'     => 'WP_Textdomain_Registry',
+			'version' => '6.1.0',
+		),
+		'_get_path_to_translation_from_lang_dir' => array(
+			'alt'     => 'WP_Textdomain_Registry',
+			'version' => '6.1.0',
+		),
+		'_wp_multiple_block_styles' => array(
+			'alt'     => '',
+			'version' => '6.1.0',
+		),
+		'global_terms' => array(
+			'alt'     => '',
+			'version' => '6.1.0',
+		),
+		'global_terms_enabled' => array(
+			'alt'     => '',
+			'version' => '6.1.0',
+		),
+		'install_global_terms' => array(
+			'alt'     => '',
+			'version' => '6.1.0',
+		),
+		'sync_category_tag_slugs' => array(
+			'alt'     => '',
+			'version' => '6.1.0',
+		),
+		'wp_get_attachment_thumb_file' => array(
+			'alt'     => '',
+			'version' => '6.1.0',
+		),
+		'wp_typography_get_css_variable_inline_style' => array(
+			'alt'     => 'wp_style_engine_get_styles()',
+			'version' => '6.1.0',
+		),
 	);
 
 	/**


Test patch:
diff --git a/WordPress/Tests/WP/DeprecatedClassesUnitTest.inc b/WordPress/Tests/WP/DeprecatedClassesUnitTest.inc
index 02f3dad1..b9b8814f 100644
--- a/WordPress/Tests/WP/DeprecatedClassesUnitTest.inc
+++ b/WordPress/Tests/WP/DeprecatedClassesUnitTest.inc
@@ -16,9 +16,5 @@ $a = (new WP_User_Search())->query();
 /* ============ WP 4.9 ============ */
 class Prefix_Menu_section extends Customize_New_Menu_Section {}
 WP_Customize_New_Menu_Control::foo();
-
-/*
- * Warning.
- */
 /* ============ WP 5.3 ============ */
 $json = new Services_JSON;
diff --git a/WordPress/Tests/WP/DeprecatedClassesUnitTest.php b/WordPress/Tests/WP/DeprecatedClassesUnitTest.php
index e5abbb46..2dace9a7 100644
--- a/WordPress/Tests/WP/DeprecatedClassesUnitTest.php
+++ b/WordPress/Tests/WP/DeprecatedClassesUnitTest.php
@@ -27,10 +27,12 @@ class DeprecatedClassesUnitTest extends AbstractSniffUnitTest {
 	 * @return array <int line number> => <int number of errors>
 	 */
 	public function getErrorList() {
-		$errors = array_fill( 9, 10, 1 );
+		$start_line = 9;
+		$end_line   = 20;
+		$errors     = array_fill( $start_line, ( ( $end_line - $start_line ) + 1 ), 1 );
 
 		// Unset the lines related to version comments.
-		unset( $errors[16] );
+		unset( $errors[16], $errors[19] );
 
 		return $errors;
 	}
@@ -41,7 +43,7 @@ class DeprecatedClassesUnitTest extends AbstractSniffUnitTest {
 	 * @return array <int line number> => <int number of warnings>
 	 */
 	public function getWarningList() {
-		return array_fill( 24, 1, 1 );
+		return array();
 	}
 
 }
diff --git a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc
index 3990ad6c..ee728576 100644
--- a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc
+++ b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc
@@ -99,7 +99,7 @@ get_the_author_yim();
 js_escape();
 register_sidebar_widget();
 register_widget_control();
-sanitize_url();
+sanitize_url(); // Undeprecated as of WP 5.9. See #2031.
 the_author_aim();
 the_author_description();
 the_author_email();
@@ -334,10 +334,6 @@ get_shortcut_link();
 is_user_option_local();
 wp_ajax_press_this_add_category();
 wp_ajax_press_this_save_post();
-
-/*
- * Warning.
- */
 /* ============ WP 5.1 ============ */
 insert_blog();
 install_blog();
@@ -347,3 +343,44 @@ _wp_privacy_requests_screen_options();
 update_user_status();
 /* ============ WP 5.4 ============ */
 wp_get_user_request_data();
+/* ============ WP 5.5 ============ */
+_wp_register_meta_args_whitelist();
+add_option_whitelist();
+remove_option_whitelist();
+wp_blacklist_check();
+wp_make_content_images_responsive();
+wp_unregister_GLOBALS();
+/* ============ WP 5.7 ============ */
+noindex();
+wp_no_robots();
+wp_sensitive_page_meta();
+
+/*
+ * Warning.
+ */
+/* ============ WP 5.8 ============ */
+_excerpt_render_inner_columns_blocks();
+/* ============ WP 5.9 ============ */
+readonly();
+/* ============ WP 5.9.1 ============ */
+wp_render_duotone_filter_preset();
+/* ============ WP 6.0 ============ */
+image_attachment_fields_to_save();
+wp_add_iframed_editor_assets_html();
+wp_skip_border_serialization();
+wp_skip_dimensions_serialization();
+wp_skip_spacing_serialization();
+/* ============ WP 6.0.2 ============ */
+the_meta();
+/* ============ WP 6.0.3 ============ */
+_filter_query_attachment_filenames();
+/* ============ WP 6.1 ============ */
+_get_path_to_translation();
+_get_path_to_translation_from_lang_dir();
+_wp_multiple_block_styles();
+global_terms();
+global_terms_enabled();
+install_global_terms();
+sync_category_tag_slugs();
+wp_get_attachment_thumb_file();
+wp_typography_get_css_variable_inline_style();
diff --git a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php
index 979807e3..8133019e 100644
--- a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php
+++ b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php
@@ -27,8 +27,9 @@ class DeprecatedFunctionsUnitTest extends AbstractSniffUnitTest {
 	 * @return array <int line number> => <int number of errors>
 	 */
 	public function getErrorList() {
-
-		$errors = array_fill( 8, 329, 1 );
+		$start_line = 8;
+		$end_line   = 356;
+		$errors     = array_fill( $start_line, ( ( $end_line - $start_line ) + 1 ), 1 );
 
 		// Unset the lines related to version comments.
 		unset(
@@ -43,6 +44,7 @@ class DeprecatedFunctionsUnitTest extends AbstractSniffUnitTest {
 			$errors[73],
 			$errors[76],
 			$errors[80],
+			$errors[102], // Undeprecated function.
 			$errors[118],
 			$errors[125],
 			$errors[162],
@@ -63,7 +65,12 @@ class DeprecatedFunctionsUnitTest extends AbstractSniffUnitTest {
 			$errors[319],
 			$errors[323],
 			$errors[330],
-			$errors[332]
+			$errors[332],
+			$errors[337],
+			$errors[340],
+			$errors[344],
+			$errors[346],
+			$errors[353]
 		);
 
 		return $errors;
@@ -75,15 +82,25 @@ class DeprecatedFunctionsUnitTest extends AbstractSniffUnitTest {
 	 * @return array <int line number> => <int number of warnings>
 	 */
 	public function getWarningList() {
-
-		$warnings = array_fill( 342, 8, 1 );
+		$start_line = 362;
+		$end_line   = 386;
+		$warnings   = array_fill( $start_line, ( ( $end_line - $start_line ) + 1 ), 1 );
 
 		// Unset the lines related to version comments.
 		unset(
-			$warnings[344],
-			$warnings[348]
+			$warnings[363],
+			$warnings[365],
+			$warnings[367],
+			$warnings[373],
+			$warnings[375],
+			$warnings[377]
 		);
 
+		// Temporarily until PHPCS supports PHP 8.2.
+		if ( PHP_VERSION_ID >= 80200 ) {
+			unset( $warnings[364] ); // Function call to readonly.
+		}
+
 		return $warnings;
 	}