Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
0a06f41
Fixed rest_handle_doing_it_wrong to manage debug messages properly - …
ilclaudio Mar 25, 2026
6c3e353
Fixed rest_handle_doing_it_wrong: added headers check
ilclaudio Mar 25, 2026
610ac74
REST API: Use with 'PHP Notice:' prefix in rest_handle_doing_it_wron…
ilclaudio Mar 26, 2026
6c7c2d4
Merge remote-tracking branch 'upstream/trunk' into fix/64260-rest-doi…
ilclaudio Apr 6, 2026
8bb3815
REST API: Add caller location to rest_handle_doing_it_wrong() error log
ilclaudio Apr 6, 2026
40c4f98
Merge branch 'trunk' into fix/64260-rest-doing-it-wrong-log
westonruter May 14, 2026
0a98d18
Update src/wp-includes/rest-api.php
ilclaudio May 15, 2026
922b735
Update src/wp-includes/rest-api.php
ilclaudio May 15, 2026
043f126
Merge branch 'trunk' into fix/64260-rest-doing-it-wrong-log
ilclaudio Jun 1, 2026
82e4919
Merge remote-tracking branch 'upstream/trunk' into fix/64260-rest-doi…
ilclaudio Jun 6, 2026
3829aed
Update src/wp-includes/rest-api.php
ilclaudio Jun 6, 2026
9b55875
Update src/wp-includes/rest-api.php
ilclaudio Jun 6, 2026
db266e1
Merge branch 'fix/64260-rest-doing-it-wrong-log' of https://github.co…
ilclaudio Jun 6, 2026
d6e9fa5
Merge branch 'trunk' into fix/64260-rest-doing-it-wrong-log
ilclaudio Jun 6, 2026
5777f1a
REST API: Fix path comparison and backtrace depth in rest_handle_doin…
ilclaudio Jun 6, 2026
dca14ad
Merge branch 'fix/64260-rest-doing-it-wrong-log' of https://github.co…
ilclaudio Jun 6, 2026
8943b90
Merge remote-tracking branch 'upstream/trunk' into fix/64260-rest-doi…
ilclaudio Jun 7, 2026
33550a9
Merge remote-tracking branch 'upstream/trunk' into fix/64260-rest-doi…
ilclaudio Jun 10, 2026
a4076db
REST API: Extend debug logging to deprecated function and argument ha…
ilclaudio Jun 10, 2026
8329da1
REST API: Fix case-insensitive path comparison in _rest_get_debug_bac…
ilclaudio Jun 10, 2026
62deb78
Merge branch 'trunk' into fix/64260-rest-doing-it-wrong-log
ilclaudio Jun 10, 2026
3b7826d
Update src/wp-includes/rest-api.php
ilclaudio Jun 14, 2026
b714964
Update src/wp-includes/rest-api.php
ilclaudio Jun 14, 2026
546dc07
Update src/wp-includes/rest-api.php
ilclaudio Jun 14, 2026
8fce388
Update src/wp-includes/rest-api.php
ilclaudio Jun 14, 2026
d88a269
Update src/wp-includes/rest-api.php
ilclaudio Jun 14, 2026
19b5c38
Merge remote-tracking branch 'upstream/trunk' into fix/64260-rest-doi…
ilclaudio Jun 14, 2026
2f6ed99
REST API: Remove strtolower() from path comparison in _rest_get_debug…
ilclaudio Jun 14, 2026
aac1be5
Merge branch 'trunk' into fix/64260-rest-doing-it-wrong-log
ilclaudio Jun 17, 2026
7047c58
Merge branch 'trunk' into fix/64260-rest-doing-it-wrong-log
ilclaudio Jun 18, 2026
8b390d3
Merge branch 'trunk' into fix/64260-rest-doing-it-wrong-log
ilclaudio Jun 24, 2026
6ac2753
Merge branch 'trunk' into fix/64260-rest-doing-it-wrong-log
ilclaudio Jun 28, 2026
7ea0fe5
Merge remote-tracking branch 'upstream/trunk' into fix/64260-rest-doi…
ilclaudio Jun 28, 2026
0a725d2
Merge branch 'trunk' into fix/64260-rest-doing-it-wrong-log
ilclaudio Jul 3, 2026
9ab0838
Merge branch 'trunk' into fix/64260-rest-doing-it-wrong-log
ilclaudio Jul 4, 2026
1e238ce
Robots: Use `admin_url()` for the `robots.txt` admin paths.
westonruter Jul 4, 2026
ec8b004
Site Health: Remove redundant `function_exists( 'ini_get' )` checks.
Jul 4, 2026
93b45f4
Docs: Modernize and improve specificity of types in `WP_Error` class.
westonruter Jul 5, 2026
f01bda1
Filesystem: Fix subdirectory recursion in `WP_Filesystem_Direct::chgr…
westonruter Jul 5, 2026
2252f6d
Filesystem API: Improve type safety across the transport classes.
westonruter Jul 5, 2026
b0cb5a9
Merge remote-tracking branch 'upstream/trunk' into fix/64260-rest-doi…
ilclaudio Jul 5, 2026
90681fc
Merge branch 'trunk' into fix/64260-rest-doing-it-wrong-log
ilclaudio Jul 9, 2026
2b93ef5
Merge branch 'trunk' into fix/64260-rest-doing-it-wrong-log
t-hamano Jul 27, 2026
eca6644
Update src/wp-includes/rest-api.php
ilclaudio Aug 2, 2026
de314b8
Merge branch 'fix/64260-rest-doing-it-wrong-log' of https://github.co…
ilclaudio Aug 2, 2026
9338584
Merge remote-tracking branch 'upstream/trunk' into fix/64260-rest-doi…
ilclaudio Aug 2, 2026
687db29
REST API: Prefix the REST debug backtrace helper and harden caller de…
ilclaudio Aug 2, 2026
16326f6
Changed milestone as required by the reviewer
ilclaudio Aug 2, 2026
1ef636c
Merge branch 'trunk' into fix/64260-rest-doing-it-wrong-log
ilclaudio Sep 4, 2026
0f1ef94
Merge branch 'trunk' into fix/64260-rest-doing-it-wrong-log
ilclaudio Sep 27, 2026
2f9f38f
Tests: Add coverage for `_wp_rest_get_debug_backtrace_caller()`.
rvpatel Oct 19, 2026
20e8b97
Merge pull request #1 from rvpatel/64260-rest-backtrace-caller-tests
ilclaudio Oct 19, 2026
98a350a
Merge branch 'trunk' into fix/64260-rest-doing-it-wrong-log
ilclaudio Oct 19, 2026
a82c2c2
Merge branch 'trunk' into fix/64260-rest-doing-it-wrong-log
ilclaudio Oct 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 93 additions & 6 deletions src/wp-includes/rest-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,75 @@ function rest_ensure_response( $response ) {
return new WP_REST_Response( $response );
}

/**
* Returns a formatted caller location string for REST API debug log entries.
*
* Searches the call stack for the first frame whose file lives inside WP_CONTENT_DIR,
* identifying the plugin or theme that triggered the notice. Used by the REST API
* debug handlers to append actionable location info to error_log() output.
*
* @since 7.2.0
* @access private
*
* @return string Formatted string such as ' called from my_func() in /path/plugin.php on line 8',
* or ' called from (anonymous function) in /path/plugin.php on line 8' for closures,
* or empty string when no plugin/theme frame is found in the call stack.
*/
function _wp_rest_get_debug_backtrace_caller(): string {
$backtrace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS );
$normalized_content_dir = trailingslashit( wp_normalize_path( WP_CONTENT_DIR ) );

foreach ( $backtrace as $i => $frame ) {
if ( ! isset( $frame['file'] ) ) {
continue;
}

$normalized_file = wp_normalize_path( $frame['file'] );
if ( ! str_starts_with( $normalized_file, $normalized_content_dir ) ) {
continue;
}

$location = ' in ' . $normalized_file;
if ( isset( $frame['line'] ) ) {
$location .= ' on line ' . $frame['line'];
}

/*
* The next frame holds the function that contains the offending call.
* PHP represents closures as '{closure}' (< 8.4) or '{closure:file:line}' (>= 8.4),
* both starting with '{'. These are replaced with a readable label.
*/
$next = $backtrace[ $i + 1 ] ?? null;
if ( $next ) {
if ( empty( $next['function'] ) ) {
return $location;
}

if ( str_starts_with( $next['function'], '{' ) ) {
return ' called from (anonymous function)' . $location;
}
Comment thread
ilclaudio marked this conversation as resolved.

/*
* A call made from a file's global scope has no enclosing function; PHP
* reports the include/require pseudo-function that loaded the file instead.
* In that case only the location is meaningful.
*/
if ( in_array( $next['function'], array( 'require', 'require_once', 'include', 'include_once' ), true ) ) {
return $location;
}
$caller_func = $next['function'];
if ( isset( $next['class'] ) ) {
$caller_func = $next['class'] . $next['type'] . $caller_func;
}
return ' called from ' . $caller_func . '()' . $location;
}

return $location;
}

return '';
}

/**
* Handles _deprecated_function() errors.
*
Expand All @@ -739,7 +808,7 @@ function rest_ensure_response( $response ) {
* @param string $version Version.
*/
function rest_handle_deprecated_function( $function_name, $replacement, $version ) {
if ( ! WP_DEBUG || headers_sent() ) {
if ( ! WP_DEBUG ) {
return;
}
if ( ! empty( $replacement ) ) {
Expand All @@ -750,7 +819,13 @@ function rest_handle_deprecated_function( $function_name, $replacement, $version
$string = sprintf( __( '%1$s (since %2$s; no alternative available)' ), $function_name, $version );
}

header( sprintf( 'X-WP-DeprecatedFunction: %s', $string ) );
if ( ! headers_sent() ) {
header( sprintf( 'X-WP-DeprecatedFunction: %s', $string ) );
}

if ( WP_DEBUG_LOG && ( error_reporting() & E_USER_DEPRECATED ) ) {
error_log( 'PHP Deprecated: ' . wp_strip_all_tags( $string ) . _wp_rest_get_debug_backtrace_caller() );
}
}

/**
Expand All @@ -763,7 +838,7 @@ function rest_handle_deprecated_function( $function_name, $replacement, $version
* @param string $version Version.
*/
function rest_handle_deprecated_argument( $function_name, $message, $version ) {
if ( ! WP_DEBUG || headers_sent() ) {
if ( ! WP_DEBUG ) {
return;
}
if ( $message ) {
Expand All @@ -774,7 +849,13 @@ function rest_handle_deprecated_argument( $function_name, $message, $version ) {
$string = sprintf( __( '%1$s (since %2$s; no alternative available)' ), $function_name, $version );
}

header( sprintf( 'X-WP-DeprecatedParam: %s', $string ) );
if ( ! headers_sent() ) {
header( sprintf( 'X-WP-DeprecatedParam: %s', $string ) );
}

if ( WP_DEBUG_LOG && ( error_reporting() & E_USER_DEPRECATED ) ) {
error_log( 'PHP Deprecated: ' . wp_strip_all_tags( $string ) . _wp_rest_get_debug_backtrace_caller() );
}
}

/**
Expand All @@ -787,7 +868,7 @@ function rest_handle_deprecated_argument( $function_name, $message, $version ) {
* @param string|null $version The version of WordPress where the message was added.
*/
function rest_handle_doing_it_wrong( $function_name, $message, $version ) {
if ( ! WP_DEBUG || headers_sent() ) {
if ( ! WP_DEBUG ) {
return;
}

Expand All @@ -801,7 +882,13 @@ function rest_handle_doing_it_wrong( $function_name, $message, $version ) {
$string = sprintf( $string, $function_name, $message );
}

header( sprintf( 'X-WP-DoingItWrong: %s', $string ) );
if ( ! headers_sent() ) {
header( sprintf( 'X-WP-DoingItWrong: %s', $string ) );
}

if ( WP_DEBUG_LOG && ( error_reporting() & E_USER_NOTICE ) ) {
error_log( 'PHP Notice: ' . wp_strip_all_tags( $string ) . _wp_rest_get_debug_backtrace_caller() );
}
Comment thread
ilclaudio marked this conversation as resolved.
}

/**
Expand Down
Loading
Loading