From 4ef1036e69e4b19391e8f7808b770f13a094b42b Mon Sep 17 00:00:00 2001 From: Drew Jaynes Date: Fri, 25 Aug 2023 03:24:00 +0000 Subject: [PATCH] Introduce a `_deprecated_class()` function. Similar to other function in the `_deprecated_*` series, `_deprecated_class()` comes with two new hooks: `deprecated_class_run` and `deprecated_class_trigger_error`. Support has also been added for setting class deprecation expectations in tests. Props jrf, wvega, ohryan. See #41125. git-svn-id: https://develop.svn.wordpress.org/trunk@56467 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/functions.php | 58 ++++++++++++++++++++ tests/phpunit/includes/abstract-testcase.php | 19 +++++++ 2 files changed, 77 insertions(+) diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index 16a32dd7bf..1f5bbffd1d 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -5595,6 +5595,64 @@ function _deprecated_constructor( $class_name, $version, $parent_class = '' ) { } +/** + * Marks a class as deprecated and informs when it has been used. + * + * There is a {@see 'deprecated_class_run'} hook that will be called that can be used + * to get the backtrace up to what file and function called the + * deprecated class. + * + * The current behavior is to trigger a user error if `WP_DEBUG` is true. + * + * This function is to be used in the class constructor for every deprecated class. + * See {@see _deprecated_constructor()} for deprecating PHP4 style constructors. + * + * @since 6.4.0 + * + * @param string $class The class being instantiated + * @param string $version The version of WordPress that deprecated the class. + * @param string $replacement Optional. The class or function that should have been called. + * Default empty string. + */ +function _deprecated_class( $class, $version, $replacement = '' ) { + + /** + * Fires when a deprecated class is called. + * + * @since 6.4.0 + * + * @param string $class The class being instantiated + * @param string $replacement The class or function that should have been called. + * @param string $version The version of WordPress that deprecated the class. + */ + do_action( 'deprecated_class_run', $class, $replacement, $version ); + + /** + * Filters whether to trigger an error for a deprecated class. + * + * @since 6.4.0 + * + * @param bool $trigger Whether to trigger an error for a deprecated class. Default true. + */ + if ( WP_DEBUG && apply_filters( 'deprecated_class_trigger_error', true ) ) { + if ( function_exists( '__' ) ) { + if ( ! is_null( $replacement ) ) { + /* translators: 1: PHP class name, 2: version number, 3: alternative clas or function name */ + trigger_error( sprintf( __('Class %1$s is deprecated since version %2$s! Use %3$s instead.'), $class, $version, $replacement ), E_USER_DEPRECATED ); + } else { + /* translators: 1: PHP class name, 2: version number */ + trigger_error( sprintf( __('Class %1$s is deprecated since version %2$s with no alternative available.'), $class, $version ), E_USER_DEPRECATED ); + } + } else { + if ( ! is_null( $replacement ) ) { + trigger_error( sprintf( 'Class %1$s is deprecated since version %2$s! Use %3$s instead.', $class, $version, $replacement ), E_USER_DEPRECATED ); + } else { + trigger_error( sprintf( 'Class %1$s is deprecated since version %2$s with no alternative available.', $class, $version ), E_USER_DEPRECATED ); + } + } + } +} + /** * Marks a file as deprecated and inform when it has been used. * diff --git a/tests/phpunit/includes/abstract-testcase.php b/tests/phpunit/includes/abstract-testcase.php index 251d187a25..129943f274 100644 --- a/tests/phpunit/includes/abstract-testcase.php +++ b/tests/phpunit/includes/abstract-testcase.php @@ -568,12 +568,14 @@ abstract class WP_UnitTestCase_Base extends PHPUnit_Adapter_TestCase { add_action( 'deprecated_function_run', array( $this, 'deprecated_function_run' ), 10, 3 ); add_action( 'deprecated_argument_run', array( $this, 'deprecated_function_run' ), 10, 3 ); + add_action( 'deprecated_class_run', array( $this, 'deprecated_function_run' ), 10, 3 ); add_action( 'deprecated_file_included', array( $this, 'deprecated_function_run' ), 10, 4 ); add_action( 'deprecated_hook_run', array( $this, 'deprecated_function_run' ), 10, 4 ); add_action( 'doing_it_wrong_run', array( $this, 'doing_it_wrong_run' ), 10, 3 ); add_action( 'deprecated_function_trigger_error', '__return_false' ); add_action( 'deprecated_argument_trigger_error', '__return_false' ); + add_action( 'deprecated_class_trigger_error', '__return_false' ); add_action( 'deprecated_file_trigger_error', '__return_false' ); add_action( 'deprecated_hook_trigger_error', '__return_false' ); add_action( 'doing_it_wrong_trigger_error', '__return_false' ); @@ -746,6 +748,23 @@ abstract class WP_UnitTestCase_Base extends PHPUnit_Adapter_TestCase { } break; + case 'deprecated_class_run': + if ( $replacement ) { + $message = sprintf( + 'Class %1$s is deprecated since version %2$s! Use %3$s instead.', + $function_name, + $version, + $replacement + ); + } else { + $message = sprintf( + 'Class %1$s is deprecated since version %2$s with no alternative available.', + $function_name, + $version + ); + } + break; + case 'deprecated_file_included': if ( $replacement ) { $message = sprintf(