: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
namespace Yoast\WP\SEO\Helpers;
* Class Crawl_Cleanup_Helper.
* Used by the Crawl_Cleanup_Permalinks class.
class Crawl_Cleanup_Helper {
* The current page helper
* @var Current_Page_Helper
private $current_page_helper;
private $redirect_helper;
* Crawl Cleanup Basic integration constructor.
* @param Current_Page_Helper $current_page_helper The current page helper.
* @param Options_Helper $options_helper The option helper.
* @param Url_Helper $url_helper The URL helper.
* @param Redirect_Helper $redirect_helper The Redirect Helper.
public function __construct(
Current_Page_Helper $current_page_helper,
Options_Helper $options_helper,
Redirect_Helper $redirect_helper
$this->current_page_helper = $current_page_helper;
$this->options_helper = $options_helper;
$this->url_helper = $url_helper;
$this->redirect_helper = $redirect_helper;
* Checks if the current URL is not robots, sitemap, empty or user is logged in.
* @return bool True if the current URL is a valid URL.
public function should_avoid_redirect() {
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- We're not processing anything yet...
if ( \is_robots() || \get_query_var( 'sitemap' ) || empty( $_GET ) || \is_user_logged_in() ) {
* Returns the list of the allowed extra vars.
* @return array The list of the allowed extra vars.
public function get_allowed_extravars() {
$default_allowed_extravars = [
* Filter: 'Yoast\WP\SEO\allowlist_permalink_vars' - Allows plugins to register their own variables not to clean.
* @param array $allowed_extravars The list of the allowed vars (empty by default).
$allowed_extravars = \apply_filters( 'Yoast\WP\SEO\allowlist_permalink_vars', $default_allowed_extravars );
$clean_permalinks_extra_variables = $this->options_helper->get( 'clean_permalinks_extra_variables' );
if ( $clean_permalinks_extra_variables !== '' ) {
$allowed_extravars = \array_merge( $allowed_extravars, \explode( ',', $clean_permalinks_extra_variables ) );
return $allowed_extravars;
* Gets the allowed query vars from the current URL.
* @param string $current_url The current URL.
* @return array is_allowed and allowed_query.
public function allowed_params( $current_url ) {
// This is a Premium plugin-only function: Allows plugins to register their own variables not to clean.
$allowed_extravars = $this->get_allowed_extravars();
$parsed_url = \wp_parse_url( $current_url, \PHP_URL_QUERY );
$query = $this->url_helper->parse_str_params( $parsed_url );
if ( ! empty( $allowed_extravars ) ) {
foreach ( $allowed_extravars as $get ) {
if ( isset( $query[ $get ] ) ) {
$allowed_query[ $get ] = \rawurlencode_deep( $query[ $get ] );
'allowed_query' => $allowed_query,
* Returns the proper URL for singular pages.
* @return string The proper URL.
public function singular_url() {
$proper_url = \get_permalink( $post->ID );
$page = \get_query_var( 'page' );
if ( $page && $page !== 1 ) {
$the_post = \get_post( $post->ID );
$page_count = \substr_count( $the_post->post_content, '<!--nextpage-->' );
$proper_url = \user_trailingslashit( \trailingslashit( $proper_url ) . $page );
if ( $page > ( $page_count + 1 ) ) {
$proper_url = \user_trailingslashit( \trailingslashit( $proper_url ) . ( $page_count + 1 ) );
// Fix reply to comment links, whoever decided this should be a GET variable?
// phpcs:ignore WordPress.Security -- We know this is scary.
if ( isset( $_SERVER['REQUEST_URI'] ) && \preg_match( '`(\?replytocom=[^&]+)`', \sanitize_text_field( $_SERVER['REQUEST_URI'] ), $matches ) ) {
$proper_url .= \str_replace( '?replytocom=', '#comment-', $matches[0] );
* Returns the proper URL for front page.
* @return string The proper URL.
public function front_page_url() {
if ( $this->current_page_helper->is_home_posts_page() ) {
if ( $this->current_page_helper->is_home_static_page() ) {
return \get_permalink( $GLOBALS['post']->ID );
* Returns the proper URL for 404 page.
* @param string $current_url The current URL.
* @return string The proper URL.
public function page_not_found_url( $current_url ) {
if ( ! \is_multisite() || \is_subdomain_install() || ! \is_main_site() ) {
if ( $current_url !== \home_url() . '/blog/' && $current_url !== \home_url() . '/blog' ) {
if ( $this->current_page_helper->is_home_static_page() ) {
return \get_permalink( \get_option( 'page_for_posts' ) );
* Returns the proper URL for taxonomy page.
* @return string The proper URL.
public function taxonomy_url() {
$term = $wp_query->get_queried_object();
return \get_term_feed_link( $term->term_id, $term->taxonomy );
return \get_term_link( $term, $term->taxonomy );
* Returns the proper URL for search page.
* @return string The proper URL.
public function search_url() {
$s = \get_search_query();
return \home_url() . '/?s=' . \rawurlencode( $s );
* Returns the proper URL for url with page param.
* @param string $proper_url The proper URL.
* @return string The proper URL.
public function query_var_page_url( $proper_url ) {
if ( \is_search( $proper_url ) ) {
return \home_url() . '/page/' . $wp_query->query_vars['paged'] . '/?s=' . \rawurlencode( \get_search_query() );
return \user_trailingslashit( \trailingslashit( $proper_url ) . 'page/' . $wp_query->query_vars['paged'] );
* Returns true if query is with page param.
* @param string $proper_url The proper URL.
* @return bool is query with page param.
public function is_query_var_page( $proper_url ) {
if ( empty( $proper_url ) || $wp_query->query_vars['paged'] === 0 || $wp_query->post_count === 0 ) {
* Redirects clean permalink.
* @param string $proper_url The proper URL.
public function do_clean_redirect( $proper_url ) {
$this->redirect_helper->set_header( 'Content-Type: redirect', true );
$this->redirect_helper->remove_header( 'Content-Type' );
$this->redirect_helper->remove_header( 'Last-Modified' );
$this->redirect_helper->remove_header( 'X-Pingback' );
/* translators: %1$s: Yoast SEO */
\__( '%1$s: unregistered URL parameter removed. See %2$s', 'wordpress-seo' ),
'https://yoa.st/advanced-crawl-settings'
$this->redirect_helper->do_safe_redirect( $proper_url, 301, $message );
* @return string The type of URL.
public function get_url_type() {
if ( \is_front_page() ) {
if ( $this->current_page_helper->is_posts_page() ) {
return 'page_for_posts_url';
if ( \is_category() || \is_tag() || \is_tax() ) {
return 'page_not_found_url';
* Returns the proper URL for posts page.
* @return string The proper URL.
public function page_for_posts_url() {
return \get_permalink( \get_option( 'page_for_posts' ) );