Post ID: 1053
Title: Advanced Redirect Strategies
Slug: advanced-redirect-strategies
Publication Date: 2024-12-24
Author: Admin
Status: Published
Comment Status: Open
Excerpt: Master complex redirect scenarios with custom PHP and JavaScript.
Category
- Primary: Tutorials (7)
Tags
- Tutorials (137)
- Redirects (113)
- PHP (143)
- Advanced (144)
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('attributes_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('attributes_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('attributes_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('attributes_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('attributes_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('attributes_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('attributes_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('attributes_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('attributes_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('attributes_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('attributes_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;
}
Testing Checklist
- 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