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