From 45c293479553e53d99c077dc3406546c159a7d89 Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Mon, 8 Sep 2025 13:08:53 +1000 Subject: [PATCH 1/9] Start on noindex functionality. --- inc/seo-compat.php | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 inc/seo-compat.php diff --git a/inc/seo-compat.php b/inc/seo-compat.php new file mode 100644 index 0000000..6969d65 --- /dev/null +++ b/inc/seo-compat.php @@ -0,0 +1,31 @@ +ID ); + if ( '1' === $meta_value ) { + return true; + } + } + +} From 8afe95ba4a419237aca50c7802326086dcf6bc33 Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Sun, 14 Sep 2025 11:07:40 +1000 Subject: [PATCH 2/9] Helper for Yoast SEO to determine noindex status. --- inc/seo-compat.php | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/inc/seo-compat.php b/inc/seo-compat.php index 6969d65..5e842ec 100644 --- a/inc/seo-compat.php +++ b/inc/seo-compat.php @@ -19,13 +19,33 @@ function is_noindex( $post ) { return true; // No post found, treat as noindex. } + // Check for Yoast SEO noindex. + if ( is_yoast_noindex( $post ) ) { + return true; + } + + return false; // Default to not noindex. +} + +/** + * Check Yoast SEO noindex status. + * + * @param \WP_Post|int $post The post object or ID. + * @return bool True if Yoast SEO sets the post to noindex, false otherwise. + */ +function is_yoast_noindex( $post ) { + if ( ! function_exists( 'YoastSEO' ) ) { + return false; // Yoast SEO is not active. + } + + $post = get_post( $post ); + $post_id = $post->ID; + + $robots = YoastSEO()->meta->for_post( $post_id )->robots; - if ( class_exists( 'WPSEO_Meta' ) ) { - // Yoast SEO. - $meta_value = \WPSEO_Meta::get_value( 'meta-robots-noindex', $post->ID ); - if ( '1' === $meta_value ) { - return true; - } + if ( ! isset( $robots['index'] ) ) { + return false; // No index directive found. } + return 'noindex' === $robots['index']; } From 0ad89620fc2b500db6d836df48b8ffa48d87d715 Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Sun, 14 Sep 2025 11:09:57 +1000 Subject: [PATCH 3/9] Helper for AIOSEO to determine noindex status. --- inc/seo-compat.php | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/inc/seo-compat.php b/inc/seo-compat.php index 5e842ec..804ab13 100644 --- a/inc/seo-compat.php +++ b/inc/seo-compat.php @@ -24,6 +24,11 @@ function is_noindex( $post ) { return true; } + // Check All in One SEO noindex. + if ( is_aioseo_noindex( $post ) ) { + return true; + } + return false; // Default to not noindex. } @@ -49,3 +54,26 @@ function is_yoast_noindex( $post ) { return 'noindex' === $robots['index']; } + +/** + * Check All in One SEO noindex status. + * + * @param \WP_Post|int $post The post object or ID. + * @return bool True if AIOSEO sets the post to noindex, false otherwise. + */ +function is_aioseo_noindex( $post ) { + if ( ! function_exists( 'aioseo' ) ) { + return false; // AIOSEO is not active. + } + + $post = get_post( $post ); + $post_id = $post->ID; + + $post_meta = aioseo()->meta->metaData->getMetaData( $post_id ); + + if ( ! $post_meta->robots_default && isset( $post_meta->robots_noindex ) ) { + return $post_meta->robots_noindex; + } + + return aioseo()->helpers->isPostTypeNoindexed( get_post_type( $post ) ); +} From ce9f5926a7ec8b29f71d5adea846c2cb13f29a70 Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Sun, 14 Sep 2025 11:10:26 +1000 Subject: [PATCH 4/9] Include SEO Compat functions. --- simple-search-submission.php | 1 + 1 file changed, 1 insertion(+) diff --git a/simple-search-submission.php b/simple-search-submission.php index b428d8e..775e995 100644 --- a/simple-search-submission.php +++ b/simple-search-submission.php @@ -39,6 +39,7 @@ namespace PWCC\SimpleSearchSubmission; require_once __DIR__ . '/inc/namespace.php'; +require_once __DIR__ . '/inc/seo-compat.php'; // Run late to give themes and plugins a chance to set up asynchronous pings. add_action( 'after_setup_theme', __NAMESPACE__ . '\\bootstrap', 20 ); From 1b6941f817ceaa3cf0f8f84add195dbbf8ca6e29 Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Sun, 14 Sep 2025 11:21:11 +1000 Subject: [PATCH 5/9] Note ordering logic. --- inc/seo-compat.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/inc/seo-compat.php b/inc/seo-compat.php index 804ab13..4a3a04e 100644 --- a/inc/seo-compat.php +++ b/inc/seo-compat.php @@ -19,12 +19,21 @@ function is_noindex( $post ) { return true; // No post found, treat as noindex. } - // Check for Yoast SEO noindex. + /* + * Check in order of number of active installs. + * + * To optimize performance for the majority of users, the + * checks are ordered by the popularity of the SEO plugins. + * + * Popularity data from the WordPress plugin repository. + */ + + // Check for Yoast SEO noindex (10 million+). if ( is_yoast_noindex( $post ) ) { return true; } - // Check All in One SEO noindex. + // Check All in One SEO noindex (3 million+). if ( is_aioseo_noindex( $post ) ) { return true; } From d1eb16bc9e40b03fd6e99f4f18d4d9bf6c807a31 Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Sun, 14 Sep 2025 11:39:10 +1000 Subject: [PATCH 6/9] Do not ping for no-indexed posts. --- inc/namespace.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/inc/namespace.php b/inc/namespace.php index 1bd2250..1d4d146 100644 --- a/inc/namespace.php +++ b/inc/namespace.php @@ -211,6 +211,16 @@ function maybe_ping_indexnow( $new_status, $old_status, $post ): void { return; } + /* + * Skip for noindexed posts that have never pinged IndexNow. + * + * Previously pinged URLs are still pinged to encourage removal from + * search engines. + */ + if ( SEOCompat\is_noindex( $post ) && empty( get_post_ping_urls( $post ) ) ) { + return; + } + /* * Prevent double pings for block editor legacy meta boxes. */ From 44748e10746862a54077b49a614d2118347b43c6 Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Fri, 3 Oct 2025 11:10:49 +1000 Subject: [PATCH 7/9] Do not add newly noindexed URLs to the ping list. --- inc/namespace.php | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/inc/namespace.php b/inc/namespace.php index 1d4d146..e708e14 100644 --- a/inc/namespace.php +++ b/inc/namespace.php @@ -335,15 +335,12 @@ function ping_indexnow( $post ) { $current_url = get_permalink( $post ); /* - * Only add the current URL if it is publicly viewable. + * Only add the current URL if it is publicly viewable and indexed. * - * This prevents unnecessary pings for private or draft posts in - * which the current URL will 404. If the URL has been previously - * pinged, it will be included in the list of URLs to ping as IndexNow - * allows for new 404s to be pinged to encourage search engines - * to remove the URL from their index. + * This prevents unnecessary pings for new URLs that are either not + * viewable (ie, will 404) or noindexed by an SEO plugin. */ - if ( is_post_publicly_viewable( $post ) && ! in_array( $current_url, $url_list, true ) ) { + if ( is_post_publicly_viewable( $post ) && ! SEOCompat\is_noindex( $post ) && ! in_array( $current_url, $url_list, true ) ) { $url_list[] = get_permalink( $post ); } From 77e3b9e6b49c3ea1ddd32971f24859b9907f0590 Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Fri, 3 Oct 2025 11:11:36 +1000 Subject: [PATCH 8/9] Allow async ping delay to be filtered, increase default to 10 seconds. --- inc/namespace.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/inc/namespace.php b/inc/namespace.php index e708e14..0f41576 100644 --- a/inc/namespace.php +++ b/inc/namespace.php @@ -449,7 +449,17 @@ function async_ping_indexnow( $post ) { $post_id = $post->ID; + /** + * Filter the delay (in seconds) before the asynchronous ping runs. + * + * @param int $delay The delay in seconds. Default is 10 seconds. + */ + $delay = apply_filters( 'simple_search_submission_async_wait', 10, $post ); + + // Revert delay to default if it isn't numeric. + $delay = is_numeric( $delay ) ? (int) $delay : 10; + if ( ! wp_next_scheduled( 'simple_search_submission_async_ping', array( $post_id ) ) ) { - wp_schedule_single_event( time() + 5, 'simple_search_submission_async_ping', array( $post_id ) ); + wp_schedule_single_event( time() + $delay, 'simple_search_submission_async_ping', array( $post_id ) ); } } From f7c30d355f347035e3ef156b7c9523f3cad58ac0 Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Fri, 3 Oct 2025 11:15:14 +1000 Subject: [PATCH 9/9] Expand comment. --- inc/namespace.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/inc/namespace.php b/inc/namespace.php index 0f41576..06065c3 100644 --- a/inc/namespace.php +++ b/inc/namespace.php @@ -339,6 +339,10 @@ function ping_indexnow( $post ) { * * This prevents unnecessary pings for new URLs that are either not * viewable (ie, will 404) or noindexed by an SEO plugin. + * + * If the URL has been previously sent to IndexNow it will still be + * pinged to encourage search engines to de-index the page from their + * search engine, either because it's a 404 or should not be listed. */ if ( is_post_publicly_viewable( $post ) && ! SEOCompat\is_noindex( $post ) && ! in_array( $current_url, $url_list, true ) ) { $url_list[] = get_permalink( $post );