<?php
/**
 * Plugin Name: EduBox Public URL
 * Description: Adapts WordPress to the public URL used by the visitor, especially behind a reverse proxy.
 * Version: 1.0.0
 * Author: EduBox
 */

if (!defined('ABSPATH')) {
    exit;
}

// Trust forwarded headers from the EduBox reverse proxy
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
    if (strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https') {
        $_SERVER['HTTPS'] = 'on';
        if (!isset($_SERVER['SERVER_PORT']) || $_SERVER['SERVER_PORT'] == 80) {
            $_SERVER['SERVER_PORT'] = 443;
        }
    } elseif (strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'http') {
        $_SERVER['HTTPS'] = 'off';
    }
}

if (isset($_SERVER['HTTP_X_FORWARDED_HOST']) && !empty($_SERVER['HTTP_X_FORWARDED_HOST'])) {
    $_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
}

// Compute the public URL from the current request
$edubox_scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$edubox_host = $_SERVER['HTTP_HOST'] ?? 'localhost';
$edubox_public_url = $edubox_scheme . '://' . $edubox_host;

// Define WP_HOME/WP_SITEURL if not already hardcoded in wp-config.php
if (!defined('WP_HOME')) {
    define('WP_HOME', $edubox_public_url);
}
if (!defined('WP_SITEURL')) {
    define('WP_SITEURL', $edubox_public_url);
}

// Trust the forwarded port as well when present
if (isset($_SERVER['HTTP_X_FORWARDED_PORT']) && !empty($_SERVER['HTTP_X_FORWARDED_PORT'])) {
    $_SERVER['SERVER_PORT'] = $_SERVER['HTTP_X_FORWARDED_PORT'];
}

// Fallback filters in case options are stored with a different URL
add_filter('option_home', 'edubox_filter_public_url');
add_filter('option_siteurl', 'edubox_filter_public_url');
add_filter('home_url', 'edubox_filter_public_url');
add_filter('site_url', 'edubox_filter_public_url');
add_filter('admin_url', 'edubox_filter_public_url');
add_filter('includes_url', 'edubox_filter_public_url');
add_filter('content_url', 'edubox_filter_public_url');
add_filter('plugins_url', 'edubox_filter_public_url');
add_filter('wp_login_url', 'edubox_filter_public_url');
add_filter('wp_logout_url', 'edubox_filter_public_url');
add_filter('wp_redirect', 'edubox_filter_public_url');
add_filter('wp_redirect_location', 'edubox_filter_public_url');

function edubox_filter_public_url($url) {
    if (!is_string($url) || empty($url)) {
        return $url;
    }

    $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
    $host = $_SERVER['HTTP_HOST'] ?? 'localhost';
    $public = $scheme . '://' . $host;

    // Replace known internal bases with the public URL. Include localhost with
    // any port, as well as plain http://localhost (which WordPress sometimes
    // stores without port).
    if (preg_match('#^(https?)://localhost(:\d+)#i', $url, $matches)) {
        return $public . substr($url, strlen($matches[0]));
    }

    $internal_bases = [
        'http://localhost',
        'https://localhost',
    ];
    foreach ($internal_bases as $base) {
        if (strpos($url, $base) === 0) {
            return $public . substr($url, strlen($base));
        }
    }

    return $url;
}

// Ensure auth/secure cookies are marked Secure when served over HTTPS.
add_filter('cookie_secure', function ($secure) {
    if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') {
        return true;
    }
    return $secure;
}, 999);

// Force logged-in cookies to be secure as well.
add_filter('secure_logged_in_cookie', function ($secure) {
    if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') {
        return true;
    }
    return $secure;
}, 999);

add_filter('secure_auth_cookie', function ($secure) {
    if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') {
        return true;
    }
    return $secure;
}, 999);

// Help WordPress believe the request method is the real one (Next.js proxy
// preserves this, but some edge cases may benefit).
if (isset($_SERVER['HTTP_X_FORWARDED_METHOD']) && !empty($_SERVER['HTTP_X_FORWARDED_METHOD'])) {
    $_SERVER['REQUEST_METHOD'] = strtoupper($_SERVER['HTTP_X_FORWARDED_METHOD']);
}
