-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Pings/Trackbacks: Disable pings in non-production environments #11476
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Changes from all commits
f63e409
efa3dfb
4c0cc64
77f3c4f
d574730
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -3163,6 +3163,87 @@ function generic_ping( $post_id = 0 ) { | |||||||||||||
| return $post_id; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Determines whether pings should be disabled for the current environment. | ||||||||||||||
| * | ||||||||||||||
| * By default, all pings (outgoing pingbacks, trackbacks, and ping service | ||||||||||||||
| * notifications, as well as incoming pingbacks and trackbacks) are disabled | ||||||||||||||
| * for non-production environments ('local', 'development', 'staging'). | ||||||||||||||
| * | ||||||||||||||
| * @since 7.1.0 | ||||||||||||||
| * | ||||||||||||||
| * @return bool True if pings should be disabled, false otherwise. | ||||||||||||||
| */ | ||||||||||||||
| function wp_should_disable_pings_for_environment() { | ||||||||||||||
| $environment_type = wp_get_environment_type(); | ||||||||||||||
| $should_disable = 'production' !== $environment_type; | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Filters whether pings should be disabled for the current environment. | ||||||||||||||
| * | ||||||||||||||
| * Returning false re-enables pings in non-production environments. | ||||||||||||||
| * Returning true disables pings even in production. | ||||||||||||||
| * | ||||||||||||||
| * @since 7.1.0 | ||||||||||||||
| * | ||||||||||||||
| * @param bool $should_disable Whether pings should be disabled. Default true | ||||||||||||||
| * for non-production environments, false for production. | ||||||||||||||
| * @param string $environment_type The current environment type as returned by | ||||||||||||||
| * wp_get_environment_type(). | ||||||||||||||
| */ | ||||||||||||||
| return apply_filters( 'wp_should_disable_pings_for_environment', $should_disable, $environment_type ); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Removes outgoing ping callbacks in non-production environments. | ||||||||||||||
| * | ||||||||||||||
| * Hooked to `do_all_pings` at priority 1 so it runs before the default | ||||||||||||||
| * priority 10 callbacks. Does not remove `do_all_enclosures`. | ||||||||||||||
| * | ||||||||||||||
| * @since 7.1.0 | ||||||||||||||
| * @access private | ||||||||||||||
| */ | ||||||||||||||
| function wp_disable_outgoing_pings_for_environment() { | ||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The function name assumes we'll inevitably disable pings. But it does it conditionally, based on the environment. Should we reflect that in the function name? E.g. We could also remove the |
||||||||||||||
| if ( wp_should_disable_pings_for_environment() ) { | ||||||||||||||
| remove_action( 'do_all_pings', 'do_all_pingbacks', 10 ); | ||||||||||||||
| remove_action( 'do_all_pings', 'do_all_trackbacks', 10 ); | ||||||||||||||
| remove_action( 'do_all_pings', 'generic_ping', 10 ); | ||||||||||||||
|
Comment on lines
+3208
to
+3210
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Rejects incoming trackbacks in non-production environments. | ||||||||||||||
| * | ||||||||||||||
| * Hooked to `pre_trackback_post` which fires in `wp-trackback.php` before the | ||||||||||||||
| * trackback is processed. Calls `trackback_response()` which sends an XML error | ||||||||||||||
| * response and terminates the request. | ||||||||||||||
| * | ||||||||||||||
| * @since 7.1.0 | ||||||||||||||
| * @access private | ||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also not really private. Let's make sure to fix that across the board in this PR. |
||||||||||||||
| */ | ||||||||||||||
| function wp_disable_trackback_for_environment() { | ||||||||||||||
| if ( wp_should_disable_pings_for_environment() ) { | ||||||||||||||
| trackback_response( 1, __( 'Trackbacks are disabled in non-production environments.' ) ); | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Removes the pingback XML-RPC method in non-production environments. | ||||||||||||||
| * | ||||||||||||||
| * @since 7.1.0 | ||||||||||||||
| * @access private | ||||||||||||||
| * | ||||||||||||||
| * @param string[] $methods An array of XML-RPC methods, keyed by their methodName. | ||||||||||||||
| * @return string[] Modified array of XML-RPC methods. | ||||||||||||||
| */ | ||||||||||||||
| function wp_disable_xmlrpc_pingback_for_environment( $methods ) { | ||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same "maybe" nit on the function naming as above. |
||||||||||||||
| if ( wp_should_disable_pings_for_environment() ) { | ||||||||||||||
| unset( $methods['pingback.ping'] ); | ||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are we intentionally leaving the readonly |
||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| return $methods; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Pings back the links found in a post. | ||||||||||||||
| * | ||||||||||||||
|
|
||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -421,6 +421,12 @@ | |
| add_action( 'do_all_pings', 'do_all_enclosures', 10, 0 ); | ||
| add_action( 'do_all_pings', 'do_all_trackbacks', 10, 0 ); | ||
| add_action( 'do_all_pings', 'generic_ping', 10, 0 ); | ||
|
|
||
| // Disable pings (pingbacks, trackbacks, and ping service notifications) in non-production environments. | ||
| add_action( 'do_all_pings', 'wp_disable_outgoing_pings_for_environment', 1, 0 ); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Worth checking if there are any major plugins tinkering with this filter, and re-adding these callbacks before/at the default priority of |
||
| add_action( 'pre_trackback_post', 'wp_disable_trackback_for_environment', 10, 0 ); | ||
| add_filter( 'xmlrpc_methods', 'wp_disable_xmlrpc_pingback_for_environment' ); | ||
|
|
||
| add_action( 'do_robots', 'do_robots' ); | ||
| add_action( 'do_favicon', 'do_favicon' ); | ||
| add_action( 'wp_before_include_template', 'wp_start_template_enhancement_output_buffer', 1000 ); // Late priority to let `wp_template_enhancement_output_buffer` filters and `wp_finalized_template_enhancement_output_buffer` actions be registered. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,254 @@ | ||
| <?php | ||
|
|
||
| /** | ||
| * Tests for disabling pings in non-production environments. | ||
| * | ||
| * @group comment | ||
| * @covers ::wp_should_disable_pings_for_environment | ||
| * @covers ::wp_disable_outgoing_pings_for_environment | ||
| * @covers ::wp_disable_trackback_for_environment | ||
| * @covers ::wp_disable_xmlrpc_pingback_for_environment | ||
| * | ||
| * @ticket 64837 | ||
| */ | ||
| class Tests_Comment_DisablePingsForEnvironment extends WP_UnitTestCase { | ||
|
|
||
| /** | ||
| * Stores the original WP_ENVIRONMENT_TYPE env value for cleanup. | ||
| * | ||
| * @var string|false | ||
| */ | ||
| private $original_env; | ||
|
|
||
| public function set_up() { | ||
| parent::set_up(); | ||
| $this->original_env = getenv( 'WP_ENVIRONMENT_TYPE' ); | ||
| } | ||
|
|
||
| public function tear_down() { | ||
| if ( false === $this->original_env ) { | ||
| putenv( 'WP_ENVIRONMENT_TYPE' ); | ||
| } else { | ||
| putenv( 'WP_ENVIRONMENT_TYPE=' . $this->original_env ); | ||
| } | ||
| parent::tear_down(); | ||
| } | ||
|
|
||
| /** | ||
| * @ticket 64837 | ||
| */ | ||
| public function test_should_disable_returns_true_for_local() { | ||
| putenv( 'WP_ENVIRONMENT_TYPE=local' ); | ||
| $this->assertTrue( wp_should_disable_pings_for_environment() ); | ||
| } | ||
|
|
||
| /** | ||
| * @ticket 64837 | ||
| */ | ||
| public function test_should_disable_returns_true_for_development() { | ||
| putenv( 'WP_ENVIRONMENT_TYPE=development' ); | ||
| $this->assertTrue( wp_should_disable_pings_for_environment() ); | ||
| } | ||
|
|
||
| /** | ||
| * @ticket 64837 | ||
| */ | ||
| public function test_should_disable_returns_true_for_staging() { | ||
| putenv( 'WP_ENVIRONMENT_TYPE=staging' ); | ||
| $this->assertTrue( wp_should_disable_pings_for_environment() ); | ||
| } | ||
|
|
||
| /** | ||
| * @ticket 64837 | ||
| */ | ||
| public function test_should_disable_returns_false_for_production() { | ||
| putenv( 'WP_ENVIRONMENT_TYPE=production' ); | ||
| $this->assertFalse( wp_should_disable_pings_for_environment() ); | ||
| } | ||
|
|
||
| /** | ||
| * @ticket 64837 | ||
| */ | ||
| public function test_filter_can_enable_pings_in_non_production() { | ||
| putenv( 'WP_ENVIRONMENT_TYPE=local' ); | ||
| add_filter( 'wp_should_disable_pings_for_environment', '__return_false' ); | ||
|
|
||
| $this->assertFalse( wp_should_disable_pings_for_environment() ); | ||
| } | ||
|
|
||
| /** | ||
| * @ticket 64837 | ||
| */ | ||
| public function test_filter_can_disable_pings_in_production() { | ||
| putenv( 'WP_ENVIRONMENT_TYPE=production' ); | ||
| add_filter( 'wp_should_disable_pings_for_environment', '__return_true' ); | ||
|
|
||
| $this->assertTrue( wp_should_disable_pings_for_environment() ); | ||
| } | ||
|
|
||
| /** | ||
| * @ticket 64837 | ||
| */ | ||
| public function test_filter_receives_environment_type() { | ||
| putenv( 'WP_ENVIRONMENT_TYPE=staging' ); | ||
|
|
||
| $received_type = null; | ||
| add_filter( | ||
| 'wp_should_disable_pings_for_environment', | ||
| function ( $should_disable, $environment_type ) use ( &$received_type ) { | ||
| $received_type = $environment_type; | ||
| return $should_disable; | ||
| }, | ||
| 10, | ||
| 2 | ||
| ); | ||
|
|
||
| wp_should_disable_pings_for_environment(); | ||
|
|
||
| $this->assertSame( 'staging', $received_type ); | ||
| } | ||
|
|
||
| /** | ||
| * @ticket 64837 | ||
| */ | ||
| public function test_outgoing_pingbacks_removed_in_non_production() { | ||
| putenv( 'WP_ENVIRONMENT_TYPE=development' ); | ||
|
|
||
| // Re-register the defaults to ensure a clean state. | ||
| add_action( 'do_all_pings', 'do_all_pingbacks', 10, 0 ); | ||
|
|
||
| // Fire the priority-1 callback. | ||
| wp_disable_outgoing_pings_for_environment(); | ||
|
|
||
| $this->assertFalse( has_action( 'do_all_pings', 'do_all_pingbacks' ) ); | ||
| } | ||
|
|
||
| /** | ||
| * @ticket 64837 | ||
| */ | ||
| public function test_outgoing_trackbacks_removed_in_non_production() { | ||
| putenv( 'WP_ENVIRONMENT_TYPE=development' ); | ||
|
|
||
| add_action( 'do_all_pings', 'do_all_trackbacks', 10, 0 ); | ||
|
|
||
| wp_disable_outgoing_pings_for_environment(); | ||
|
|
||
| $this->assertFalse( has_action( 'do_all_pings', 'do_all_trackbacks' ) ); | ||
| } | ||
|
|
||
| /** | ||
| * @ticket 64837 | ||
| */ | ||
| public function test_outgoing_generic_ping_removed_in_non_production() { | ||
| putenv( 'WP_ENVIRONMENT_TYPE=development' ); | ||
|
|
||
| add_action( 'do_all_pings', 'generic_ping', 10, 0 ); | ||
|
|
||
| wp_disable_outgoing_pings_for_environment(); | ||
|
|
||
| $this->assertFalse( has_action( 'do_all_pings', 'generic_ping' ) ); | ||
| } | ||
|
|
||
| /** | ||
| * @ticket 64837 | ||
| */ | ||
| public function test_enclosures_not_removed_in_non_production() { | ||
| putenv( 'WP_ENVIRONMENT_TYPE=development' ); | ||
|
|
||
| add_action( 'do_all_pings', 'do_all_enclosures', 10, 0 ); | ||
|
|
||
| wp_disable_outgoing_pings_for_environment(); | ||
|
|
||
| $this->assertSame( 10, has_action( 'do_all_pings', 'do_all_enclosures' ) ); | ||
| } | ||
|
|
||
| /** | ||
| * @ticket 64837 | ||
| */ | ||
| public function test_outgoing_pings_preserved_in_production() { | ||
| putenv( 'WP_ENVIRONMENT_TYPE=production' ); | ||
|
|
||
| add_action( 'do_all_pings', 'do_all_pingbacks', 10, 0 ); | ||
| add_action( 'do_all_pings', 'do_all_trackbacks', 10, 0 ); | ||
| add_action( 'do_all_pings', 'generic_ping', 10, 0 ); | ||
|
|
||
| wp_disable_outgoing_pings_for_environment(); | ||
|
|
||
| $this->assertSame( 10, has_action( 'do_all_pings', 'do_all_pingbacks' ), 'do_all_pingbacks should still be hooked.' ); | ||
| $this->assertSame( 10, has_action( 'do_all_pings', 'do_all_trackbacks' ), 'do_all_trackbacks should still be hooked.' ); | ||
| $this->assertSame( 10, has_action( 'do_all_pings', 'generic_ping' ), 'generic_ping should still be hooked.' ); | ||
| } | ||
|
|
||
| /** | ||
| * @ticket 64837 | ||
| */ | ||
| public function test_trackback_hook_is_registered() { | ||
| $this->assertSame( 10, has_action( 'pre_trackback_post', 'wp_disable_trackback_for_environment' ) ); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above about how we test the priority. |
||
| } | ||
|
|
||
| /** | ||
| * @ticket 64837 | ||
| */ | ||
| public function test_pings_open_unaffected_by_environment() { | ||
| putenv( 'WP_ENVIRONMENT_TYPE=local' ); | ||
|
|
||
| $post = self::factory()->post->create_and_get( | ||
| array( 'ping_status' => 'open' ) | ||
| ); | ||
|
|
||
| $this->assertTrue( pings_open( $post ) ); | ||
| } | ||
|
|
||
| /** | ||
| * @ticket 64837 | ||
| */ | ||
| public function test_xmlrpc_pingback_removed_in_non_production() { | ||
| putenv( 'WP_ENVIRONMENT_TYPE=development' ); | ||
|
|
||
| $methods = array( | ||
| 'pingback.ping' => 'this:pingback_ping', | ||
| 'pingback.extensions.getPingbacks' => 'this:pingback_extensions_getPingbacks', | ||
| 'wp.getUsersBlogs' => 'this:wp_getUsersBlogs', | ||
| ); | ||
|
|
||
| $filtered = wp_disable_xmlrpc_pingback_for_environment( $methods ); | ||
|
|
||
| $this->assertArrayNotHasKey( 'pingback.ping', $filtered ); | ||
| } | ||
|
|
||
| /** | ||
| * @ticket 64837 | ||
| */ | ||
| public function test_xmlrpc_pingback_preserved_in_production() { | ||
| putenv( 'WP_ENVIRONMENT_TYPE=production' ); | ||
|
|
||
| $methods = array( | ||
| 'pingback.ping' => 'this:pingback_ping', | ||
| 'wp.getUsersBlogs' => 'this:wp_getUsersBlogs', | ||
| ); | ||
|
|
||
| $filtered = wp_disable_xmlrpc_pingback_for_environment( $methods ); | ||
|
|
||
| $this->assertArrayHasKey( 'pingback.ping', $filtered ); | ||
| } | ||
|
|
||
| /** | ||
| * @ticket 64837 | ||
| */ | ||
| public function test_xmlrpc_other_methods_preserved_in_non_production() { | ||
| putenv( 'WP_ENVIRONMENT_TYPE=development' ); | ||
|
|
||
| $methods = array( | ||
| 'pingback.ping' => 'this:pingback_ping', | ||
| 'pingback.extensions.getPingbacks' => 'this:pingback_extensions_getPingbacks', | ||
| 'wp.getUsersBlogs' => 'this:wp_getUsersBlogs', | ||
| 'wp.getPost' => 'this:wp_getPost', | ||
| ); | ||
|
|
||
| $filtered = wp_disable_xmlrpc_pingback_for_environment( $methods ); | ||
|
|
||
| $this->assertArrayHasKey( 'pingback.extensions.getPingbacks', $filtered ); | ||
| $this->assertArrayHasKey( 'wp.getUsersBlogs', $filtered ); | ||
| $this->assertArrayHasKey( 'wp.getPost', $filtered ); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't seem
privateto me - all non-namespaced functions in PHP are global and public.