Advanced Redirect Strategies
Master complex redirect scenarios with custom PHP and JavaScript.
Overview
Implement sophisticated redirect logic based on multiple conditions, user attributes, and dynamic data. This tutorial covers conditional redirects, dynamic URLs, custom PHP code, and integration with third-party plugins.
Scenario 1: Multi-Condition Redirects
Redirect based on role AND subscription status.
Implementation
/**
* Redirect VIP members with active subscriptions to exclusive dashboard
* Redirect VIP members with expired subscriptions to renewal page
* Others follow normal redirect rules
*/
add_filter('attrua_login_redirect', 'multi_condition_redirect', 10, 3);
function multi_condition_redirect($redirect_to, $user_id, $user) {
// Check if user has VIP role
if (in_array('vip_member', $user->roles)) {
// Check subscription status
$subscription_status = get_user_meta($user_id, 'subscription_status', true);
if ($subscription_status === 'active') {
// Active VIP - exclusive dashboard
return home_url('/vip-dashboard/');
} elseif ($subscription_status === 'expired') {
// Expired VIP - renewal page
return home_url('/renew-subscription/?user_id=' . $user_id);
}
}
// Return default redirect
return $redirect_to;
}
Scenario 2: Time-Based Redirects
Redirect users based on time of day or day of week.
Example: Weekend Special Access
/**
* VIP members get weekend-only content access
*/
add_filter('attrua_login_redirect', 'weekend_special_redirect', 10, 3);
function weekend_special_redirect($redirect_to, $user_id, $user) {
// Only for VIP members
if (!in_array('vip_member', $user->roles)) {
return $redirect_to;
}
// Get current day (0=Sunday, 6=Saturday)
$current_day = date('w');
// Weekend check
if ($current_day == 0 || $current_day == 6) {
return home_url('/weekend-specials/');
}
return $redirect_to;
}
/**
* Business hours redirect for staff
*/
add_filter('attrua_login_redirect', 'business_hours_redirect', 10, 3);
function business_hours_redirect($redirect_to, $user_id, $user) {
if (!in_array('staff', $user->roles)) {
return $redirect_to;
}
$current_hour = intval(date('G')); // 0-23
// Business hours: 9 AM - 5 PM
if ($current_hour >= 9 && $current_hour < 17) {
return home_url('/staff-dashboard/');
} else {
// After hours - limited access portal
return home_url('/after-hours-portal/');
}
}
Scenario 3: User Meta-Based Redirects
Redirect based on custom user meta fields.
Onboarding Completion Check
/**
* Redirect new users to onboarding if not completed
*/
add_filter('attrua_login_redirect', 'onboarding_redirect', 10, 3);
function onboarding_redirect($redirect_to, $user_id, $user) {
// Check if onboarding is complete
$onboarding_complete = get_user_meta($user_id, 'onboarding_complete', true);
if (!$onboarding_complete) {
// Get current onboarding step
$current_step = get_user_meta($user_id, 'onboarding_step', true);
$current_step = $current_step ? intval($current_step) : 1;
return home_url('/onboarding/step-' . $current_step . '/');
}
return $redirect_to;
}
/**
* Department-based redirect from user profile
*/
add_filter('attrua_login_redirect', 'department_redirect', 10, 3);
function department_redirect($redirect_to, $user_id, $user) {
$department = get_user_meta($user_id, 'department', true);
$department_pages = array(
'sales' => '/sales-portal/',
'marketing' => '/marketing-hub/',
'support' => '/support-dashboard/',
'hr' => '/hr-portal/',
'it' => '/it-center/'
);
if (isset($department_pages[$department])) {
return home_url($department_pages[$department]);
}
return $redirect_to;
}
Scenario 4: Last Visited Page Redirect
Return users to their last visited page after login.
Implementation with Cookie
/**
* Track last visited page before login
*/
add_action('wp_footer', 'track_last_page');
function track_last_page() {
if (!is_user_logged_in()) {
// Store current URL in cookie (expires in 1 hour)
$current_url = home_url(add_query_arg(array()));
setcookie('last_page_before_login', $current_url, time() + 3600, '/');
}
}
/**
* Redirect to last visited page after login
*/
add_filter('attrua_login_redirect', 'last_page_redirect', 10, 3);
function last_page_redirect($redirect_to, $user_id, $user) {
if (isset($_COOKIE['last_page_before_login'])) {
$last_page = $_COOKIE['last_page_before_login'];
// Clear the cookie
setcookie('last_page_before_login', '', time() - 3600, '/');
// Validate URL is from our site
$site_url = home_url();
if (strpos($last_page, $site_url) === 0) {
return $last_page;
}
}
return $redirect_to;
}
Scenario 5: Query Parameter Redirects
Dynamic redirects based on URL parameters.
Affiliate and Campaign Tracking
/**
* Redirect with campaign tracking
*/
add_filter('attrua_login_redirect', 'campaign_redirect', 10, 3);
function campaign_redirect($redirect_to, $user_id, $user) {
// Check for campaign parameter
if (isset($_GET['campaign'])) {
$campaign = sanitize_text_field($_GET['campaign']);
// Log campaign attribution
update_user_meta($user_id, 'last_campaign', $campaign);
// Redirect to campaign landing page
$campaign_pages = array(
'summer-sale' => '/promotions/summer-sale/',
'new-member' => '/welcome-new-members/',
'referral' => '/referral-rewards/'
);
if (isset($campaign_pages[$campaign])) {
return home_url($campaign_pages[$campaign]);
}
}
// Check for affiliate ID
if (isset($_GET['aff'])) {
$affiliate_id = sanitize_text_field($_GET['aff']);
update_user_meta($user_id, 'affiliate_source', $affiliate_id);
return home_url('/affiliate-welcome/?aff=' . $affiliate_id);
}
return $redirect_to;
}
Scenario 6: WooCommerce Integration
Redirect based on purchase history and cart status.
Purchase-Based Redirects
/**
* Redirect wholesale customers who have purchased specific products
*/
add_filter('attrua_login_redirect', 'woocommerce_purchase_redirect', 10, 3);
function woocommerce_purchase_redirect($redirect_to, $user_id, $user) {
// Check if WooCommerce is active
if (!function_exists('wc_get_customer_orders')) {
return $redirect_to;
}
// Get customer orders
$customer_orders = wc_get_customer_orders($user_id, 1); // Last order
if (!empty($customer_orders)) {
$last_order = reset($customer_orders);
// Check order total
$order_total = $last_order->get_total();
if ($order_total > 1000 && in_array('wholesale', $user->roles)) {
// High-value wholesale customer
return home_url('/wholesale-vip-portal/');
}
}
// Check if customer has items in cart
$cart_count = WC()->cart->get_cart_contents_count();
if ($cart_count > 0) {
// Return to cart
return wc_get_cart_url();
}
return $redirect_to;
}
Scenario 7: Location-Based Redirects
Redirect based on user's geographic location.
IP-Based Country Detection
/**
* Redirect based on country (requires GeoIP database)
*/
add_filter('attrua_login_redirect', 'location_redirect', 10, 3);
function location_redirect($redirect_to, $user_id, $user) {
// Get user IP
$user_ip = $_SERVER['REMOTE_ADDR'];
// Get country from IP (example using ipapi.co)
$country_code = get_country_from_ip($user_ip);
// Region-specific redirects
$region_pages = array(
'US' => '/us-portal/',
'CA' => '/canada-portal/',
'GB' => '/uk-portal/',
'AU' => '/australia-portal/',
'EU' => '/europe-portal/'
);
if (isset($region_pages[$country_code])) {
return home_url($region_pages[$country_code]);
}
return $redirect_to;
}
function get_country_from_ip($ip) {
// Cache country for 24 hours
$cache_key = 'country_' . md5($ip);
$cached = get_transient($cache_key);
if ($cached !== false) {
return $cached;
}
// Use free API (rate limits apply)
$response = wp_remote_get('https://ipapi.co/' . $ip . '/country/');
if (!is_wp_error($response)) {
$country = wp_remote_retrieve_body($response);
set_transient($cache_key, $country, DAY_IN_SECONDS);
return $country;
}
return 'XX'; // Unknown
}
Preventing Redirect Loops
Loop Detection and Prevention
/**
* Prevent redirect loops with counter
*/
add_filter('attrua_login_redirect', 'prevent_redirect_loop', 999, 3);
function prevent_redirect_loop($redirect_to, $user_id, $user) {
// Check redirect counter
$redirect_count = get_transient('redirect_count_' . $user_id);
if ($redirect_count && $redirect_count > 3) {
// Too many redirects - break the loop
error_log('Redirect loop detected for user ' . $user_id);
delete_transient('redirect_count_' . $user_id);
// Fallback to home
return home_url('/');
}
// Increment counter (expires in 1 minute)
set_transient('redirect_count_' . $user_id, ($redirect_count + 1), 60);
return $redirect_to;
}
JavaScript Client-Side Redirects
When server-side redirects are insufficient.
Delayed Redirect with Message
<script>
// Show message then redirect after 3 seconds
jQuery(document).ready(function($) {
var $message = $('.login-success-message');
if ($message.length) {
setTimeout(function() {
var redirect_url = $message.data('redirect');
window.location.href = redirect_url;
}, 3000);
}
});
</script>
Testing and Debugging
Debugging Redirects
/**
* Log redirect decisions for debugging
*/
add_filter('attrua_login_redirect', 'debug_redirects', 999, 3);
function debug_redirects($redirect_to, $user_id, $user) {
if (defined('WP_DEBUG') && WP_DEBUG) {
error_log(sprintf(
'User %d (%s) redirecting to: %s',
$user_id,
$user->user_login,
$redirect_to
));
}
return $redirect_to;
}
- Test each condition independently
- Verify redirect priority/order
- Check for redirect loops
- Test with different user roles
- Validate URL security
- Monitor error logs
- Test fallback scenarios
Best Practices
- Priority Management: Use filter priority (10, 20, 999) to control execution order
- URL Validation: Always validate redirect URLs are from your domain
- Performance: Cache external API calls, minimize database queries
- Fallbacks: Always provide a default redirect path
- Logging: Log redirect decisions in WP_DEBUG mode
- Security: Sanitize all user input and URL parameters
Something missing or out of date? Tell support.