Skip to content

Instantly share code, notes, and snippets.

@PatelUtkarsh
Last active September 4, 2025 11:10
Show Gist options
  • Save PatelUtkarsh/25ad38beb327c1c54903d3b339eb8edd to your computer and use it in GitHub Desktop.
Save PatelUtkarsh/25ad38beb327c1c54903d3b339eb8edd to your computer and use it in GitHub Desktop.
Modifies Redirection plugin behavior to only redirect on 404s
<?php
/**
* Plugin Name: Redirects - 404 Only
* Description: Modifies Redirection plugin to only redirect on 404 errors
* Version: 1.0.0
* Author: Utkarsh
*
* This mu-plugin ensures that the Redirection plugin only performs
* redirects when a 404 error occurs, not on existing pages.
*/
namespace Utkarsh\Redirects;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class FourOhFourOnly
*
* Modifies Redirection plugin behavior to only redirect on 404s
*/
class FourOhFourOnly {
/**
* Initialize the plugin modifications
*/
public static function init() {
// Disable normal redirect behavior.
add_action( 'init', [ self::class, 'disable_normal_redirects' ], 1 );
// Re-enable redirects only for 404s.
add_action( 'template_redirect', [ self::class, 'handle_404_redirects' ], 5 );
}
/**
* Disable the Redirection plugin's normal redirect behavior
*
* @return void
*/
public static function disable_normal_redirects() {
global $wp_filter;
if ( ! isset( $wp_filter['init'] ) ) {
return;
}
foreach ( $wp_filter['init']->callbacks as $priority => $hooks ) {
foreach ( $hooks as $hook_key => $hook ) {
if ( self::is_redirection_init_hook( $hook ) ) {
remove_action( 'init', $hook['function'], $priority );
}
}
}
}
/**
* Check if a hook is the Redirection plugin's init method.
*
* @param array $hook The hook to check.
*
* @return bool
*/
private static function is_redirection_init_hook( $hook ) {
return is_array( $hook['function'] ) &&
is_object( $hook['function'][0] ) &&
get_class( $hook['function'][0] ) === 'WordPress_Module' &&
$hook['function'][1] === 'init';
}
/**
* Handle redirects only when a 404 occurs
*
* @return void
*/
public static function handle_404_redirects() {
// Only proceed if this is a 404.
if ( ! is_404() ) {
return;
}
// Check if Redirection plugin classes exist.
if ( ! class_exists( 'Red_Url_Request' ) || ! class_exists( 'Redirection_Request' ) ) {
return;
}
self::process_404_redirect();
}
/**
* Process the redirect for a 404 page
*
* @return void
*/
private static function process_404_redirect() {
// Get the current request URL.
$request = new \Red_Url_Request( \Redirection_Request::get_request_url() );
// Make sure it's a valid URL and not protected.
if ( ! $request->is_valid() || $request->is_protected_url() ) {
return;
}
// Get all redirects that match the URL.
$redirects = \Red_Item::get_for_url( $request->get_decoded_url() );
// Run through the redirects until one fires.
foreach ( (array) $redirects as $item ) {
$action = $item->get_match(
$request->get_decoded_url(),
$request->get_original_url()
);
if ( $action ) {
// Log the redirect if needed.
do_action(
'redirection_matched',
$request->get_decoded_url(),
$item,
$redirects
);
// Perform the redirect.
$action->run();
exit; // Stop execution after redirect.
}
}
}
}
// Initialize the plugin modifications.
FourOhFourOnly::init();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment