Skip to content

Commit 1a86cdf

Browse files
committed
Only ping deindexed URLs once.
1 parent 2665535 commit 1a86cdf

File tree

2 files changed

+112
-6
lines changed

2 files changed

+112
-6
lines changed

inc/namespace.php

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,24 @@ function get_post_ping_urls( $post ) {
253253
return $ping_urls;
254254
}
255255

256+
/**
257+
* Get the last URL pinged for the post.
258+
*
259+
* This returns the most recently pinged URL from the post meta
260+
* for sending a deindexing request to IndexNow.
261+
*
262+
* @param \WP_Post|int $post The post ID or object.
263+
* @return string|null The last URL pinged, or null if none found.
264+
*/
265+
function get_last_post_ping_url( $post ) {
266+
$urls = get_post_ping_urls( $post );
267+
if ( empty( $urls ) || ! is_array( $urls ) ) {
268+
return null;
269+
}
270+
271+
return array_pop( $urls );
272+
}
273+
256274
/**
257275
* Add a URL or URLs to the post's ping URLs.
258276
*
@@ -269,15 +287,18 @@ function add_post_ping_urls( $post, $urls ) {
269287
return;
270288
}
271289

272-
$ping_urls = get_post_ping_urls( $post );
290+
$ping_urls = array_values( get_post_ping_urls( $post ) );
273291
$old_ping_urls = $ping_urls;
274292
$urls = (array) $urls;
275-
$ping_urls = array_merge( $ping_urls, $urls );
276-
$ping_urls = array_unique( $ping_urls );
277-
sort( $ping_urls );
293+
294+
// Remove new $urls from $ping_urls to prevent duplicates.
295+
$ping_urls = array_diff( $ping_urls, $urls );
296+
297+
// Append new URLs.
298+
$ping_urls = array_merge( array_values( $ping_urls ), array_values( $urls ) );
278299

279300
// If the URLs haven't changed, do nothing.
280-
if ( empty( array_diff( $ping_urls, $old_ping_urls ) ) ) {
301+
if ( $old_ping_urls === $ping_urls ) {
281302
return;
282303
}
283304

@@ -296,7 +317,11 @@ function ping_indexnow( $post ) {
296317
return;
297318
}
298319

299-
$url_list = get_post_ping_urls( $post );
320+
$previous_url = get_last_post_ping_url( $post );
321+
$url_list = array();
322+
if ( $previous_url ) {
323+
$url_list[] = $previous_url;
324+
}
300325
$current_url = get_permalink( $post );
301326

302327
/*

tests/class-test-indexnow-pings.php

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
namespace PWCC\SimpleSearchSubmission\Tests;
99

10+
use PWCC\SimpleSearchSubmission;
1011
use WP_UnitTestCase;
1112
use WP_UnitTest_Factory;
1213

@@ -242,4 +243,84 @@ public function test_no_ping_on_custom_private_post_status() {
242243
unset( $wp_post_statuses['custom_private'] );
243244
$this->assertNotPing( get_permalink( $post_id ), 'Custom private post status should not ping.' );
244245
}
246+
247+
/**
248+
* Ensure de-indexed urls are pinged once only.
249+
*/
250+
public function test_no_duplicate_pings_on_deindexed_url() {
251+
$post_id = self::$post_ids['publish'];
252+
253+
// Update the post slug.
254+
wp_update_post(
255+
array(
256+
'ID' => $post_id,
257+
'post_name' => 'updated-test-post-publish',
258+
)
259+
);
260+
261+
// Ensure both old and new URLs are pinged.
262+
$this->assertPing( home_url( '/2025/test-post-publish/' ), 'Ping should include the old post URL after slug change.' );
263+
$this->assertPing( home_url( '/2025/updated-test-post-publish/' ), 'Ping should include the new post URL after slug change.' );
264+
// Ensure last ping URL is the updated URL.
265+
$last_ping_url = SimpleSearchSubmission\get_last_post_ping_url( $post_id );
266+
$this->assertSame( home_url( '/2025/updated-test-post-publish/' ), $last_ping_url, 'Last ping URL should be the updated URL.' );
267+
268+
// Clear the ping list.
269+
$this->pings = array();
270+
271+
// Update the post content.
272+
wp_update_post(
273+
array(
274+
'ID' => $post_id,
275+
'post_content' => 'Another update to Test Post',
276+
)
277+
);
278+
279+
// Ensure only the new URL is pinged again.
280+
$this->assertNotPing( home_url( '/2025/test-post-publish/' ), 'Old post URL should not be pinged again after content update.' );
281+
$this->assertPing( home_url( '/2025/updated-test-post-publish/' ), 'New post URL should be pinged again after content update.' );
282+
// Ensure last ping URL is the updated URL.
283+
$last_ping_url = SimpleSearchSubmission\get_last_post_ping_url( $post_id );
284+
$this->assertSame( home_url( '/2025/updated-test-post-publish/' ), $last_ping_url, 'Last ping URL should be the updated URL after the second ping.' );
285+
}
286+
287+
/**
288+
* Ensure updating the pinged URLs lists appends the new URLs correctly.
289+
*/
290+
public function test_update_post_ping_urls_appends_correctly() {
291+
$post_id = self::$post_ids['publish'];
292+
293+
// Update the post slug for the first time.
294+
wp_update_post(
295+
array(
296+
'ID' => $post_id,
297+
'post_name' => 'first-update-test-post-publish',
298+
)
299+
);
300+
301+
$last_ping_url = SimpleSearchSubmission\get_last_post_ping_url( $post_id );
302+
$this->assertSame( home_url( '/2025/first-update-test-post-publish/' ), $last_ping_url, 'Last ping URL should be the first updated URL.' );
303+
304+
// Update the post slug for the second time.
305+
wp_update_post(
306+
array(
307+
'ID' => $post_id,
308+
'post_name' => 'second-update-test-post-publish',
309+
)
310+
);
311+
312+
$last_ping_url = SimpleSearchSubmission\get_last_post_ping_url( $post_id );
313+
$this->assertSame( home_url( '/2025/second-update-test-post-publish/' ), $last_ping_url, 'Last ping URL should be the second updated URL.' );
314+
315+
// Restore the first updated URL.
316+
wp_update_post(
317+
array(
318+
'ID' => $post_id,
319+
'post_name' => 'first-update-test-post-publish',
320+
)
321+
);
322+
323+
$last_ping_url = SimpleSearchSubmission\get_last_post_ping_url( $post_id );
324+
$this->assertSame( home_url( '/2025/first-update-test-post-publish/' ), $last_ping_url, 'Last ping URL should be the restored first updated URL.' );
325+
}
245326
}

0 commit comments

Comments
 (0)