Skip to content

Instantly share code, notes, and snippets.

@mihdan
Forked from butlerblog/functions.php
Created February 18, 2018 19:07
Show Gist options
  • Save mihdan/f386a84104ace8938de0f6a83107885b to your computer and use it in GitHub Desktop.
Save mihdan/f386a84104ace8938de0f6a83107885b to your computer and use it in GitHub Desktop.
SMTP using wp-config.php for settings
<?php // Don't use this line.
/**
* This function will connect wp_mail to your authenticated
* SMTP server. This improves reliability of wp_mail, and
* avoids many potential problems.
*
* Values are constants set in wp-config.php
*/
add_action( 'phpmailer_init', 'send_smtp_email' );
function send_smtp_email( $phpmailer ) {
$phpmailer->isSMTP();
$phpmailer->Host = SMTP_HOST;
$phpmailer->SMTPAuth = SMTP_AUTH;
$phpmailer->Port = SMTP_PORT;
$phpmailer->Username = SMTP_USER;
$phpmailer->Password = SMTP_PASS;
$phpmailer->SMTPSecure = SMTP_SECURE;
$phpmailer->From = SMTP_FROM;
$phpmailer->FromName = SMTP_NAME;
}
<?php // Don't use this line.
/**
* Set the following constants in wp-config.php
* These should be added somewhere BEFORE the
* constant ABSPATH is defined.
*/
define( 'SMTP_USER', '[email protected]' ); // Username to use for SMTP authentication
define( 'SMTP_PASS', 'smtp password' ); // Password to use for SMTP authentication
define( 'SMTP_HOST', 'smtp.example.com' ); // The hostname of the mail server
define( 'SMTP_FROM', '[email protected]' ); // SMTP From email address
define( 'SMTP_NAME', 'e.g Website Name' ); // SMTP From name
define( 'SMTP_PORT', '25' ); // SMTP port number - likely to be 25, 465 or 587
define( 'SMTP_SECURE', 'tls' ); // Encryption system to use - ssl or tls
define( 'SMTP_AUTH', true ); // Use SMTP authentication (true|false)
define( 'SMTP_DEBUG', 0 ); // for debugging purposes only set to 1 or 2
@nicholaskelly762-blip
Copy link

   REDIRECT_URL=https://example.com
   [email protected]
   SMTP_USER=smtpuser
   SMTP_PASS=smtppass
   SMTP_HOST=smtp.example.com
   SMTP_PORT=587
   SMTP_FROM_NAME=Consent Logger

Replace the values with your actual SMTP credentials and redirect URL.

The Complete Code

Here’s the fully functional PHP script:

<?php
// This script requires PHPMailer and phpdotenv.
// Ensure they are installed via Composer: composer require vlucas/phpdotenv phpmailer/phpmailer

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
use Dotenv\Dotenv;

require __DIR__ . '/vendor/autoload.php';

// Load environment variables from the .env file
$dotenv = Dotenv::createImmutable(__DIR__);
$dotenv->load();

// --- Configuration (loaded from .env for security) ---
define('REDIRECT_URL', $_ENV['REDIRECT_URL']); // URL to redirect after denial
define('CONSENT_COOKIE_DENY_NAME', 'sec_logger_consent_deny'); // Cookie name
define('CONSENT_COOKIE_EXPIRY', 365 * 24 * 60 * 60); // Cookie expiry: 1 year in seconds
define('LOG_FILE', __DIR__ . '/security_log.txt'); // Log file path
define('EMAIL_TO', $_ENV['EMAIL_TO']); // Recipient email
define('SMTP_USER', $_ENV['SMTP_USER']); // SMTP username
define('SMTP_PASS', $_ENV['SMTP_PASS']); // SMTP password
define('SMTP_HOST', $_ENV['SMTP_HOST']); // SMTP host
define('SMTP_PORT', $_ENV['SMTP_PORT']); // SMTP port
define('SMTP_FROM_NAME', $_ENV['SMTP_FROM_NAME']); // Sender name

// --- Functions ---

/**
 * Safely retrieves a server variable, returning a default if not found.
 * @param string $key The key for the $_SERVER variable
 * @param string $default The default value if key is not found
 * @return string The server variable value or default
 */
function get_server_var(string $key, string $default = 'UNKNOWN'): string {
    return $_SERVER[$key] ?? $default;
}

/**
 * Anonymizes an IP address by setting the last octet to 0.
 * @param string $ip The IP address to anonymize
 * @return string The anonymized IP address
 */
function anonymizeIp(string $ip): string {
    return preg_replace('/\.\d+$/', '.0', $ip);
}

/**
 * Retrieves user location based on IP using ipinfo.io.
 * @param string $ip The IP address to look up
 * @return string The location or a default if lookup fails
 */
function get_user_location(string $ip): string {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "http://ipinfo.io/{$ip}/json");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 5);
    $response = curl_exec($ch);
    curl_close($ch);

    if ($response === false) {
        return 'Unknown Location';
    }

    $data = json_decode($response, true);
    if (isset($data['city'], $data['region'], $data['country'])) {
        return "{$data['city']}, {$data['region']}, {$data['country']}";
    }
    return 'Unknown Location';
}

/**
 * Sends an email with the logged entry.
 * @param string $entry The log entry to send
 */
function send_email(string $entry): void {
    $mail = new PHPMailer(true);
    try {
        $mail->isSMTP();
        $mail->Host = SMTP_HOST;
        $mail->SMTPAuth = true;
        $mail->Username = SMTP_USER;
        $mail->Password = SMTP_PASS;
        $mail->SMTPSecure = 'tls';
        $mail->Port = SMTP_PORT;
        $mail->setFrom(SMTP_USER, SMTP_FROM_NAME);
        $mail->addAddress(EMAIL_TO);
        $mail->Subject = 'New Consent Denied Visitor';
        $mail->Body = $entry;
        $mail->send();
    } catch (Exception $e) {
        error_log("Email failed to send. Error: {$mail->ErrorInfo}");
    }
}

// --- Main Logic ---
$trace = isset($_GET['trace']) && $_GET['trace'] === 'yes'; // Enable location tracing with ?trace=yes
$hasDenied = isset($_COOKIE[CONSENT_COOKIE_DENY_NAME]) && $_COOKIE[CONSENT_COOKIE_DENY_NAME] === 'yes';

if ($hasDenied) {
    // Gather request details
    $ip = get_server_var('REMOTE_ADDR');
    $userAgent = get_server_var('HTTP_USER_AGENT');
    $referrer = get_server_var('HTTP_REFERER', 'NONE');
    $method = get_server_var('REQUEST_METHOD');
    $protocol = get_server_var('SERVER_PROTOCOL');
    $time = date('Y-m-d H:i:s');

    // Anonymize IP and get location (if tracing enabled)
    $anonIp = anonymizeIp($ip);
    $location = $trace ? get_user_location($ip) : 'N/A';

    // Create log entry
    $entry = "Time: $time\nIP: $anonIp\nUser-Agent: $userAgent\nReferrer: $referrer\nMethod: $method\nProtocol: $protocol\nLocation: $location\n\n";

    // Log to file and send email
    file_put_contents(LOG_FILE, $entry, FILE_APPEND | LOCK_EX);
    send_email($entry);

    // Redirect user
    header("Location: " . REDIRECT_URL);
    exit();
}
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Consent</title>
    <style>
        body { margin: 0; padding: 0; }
        .consent-banner {
            position: fixed;
            bottom: 0;
            width: 100%;
            background: #333;
            color: #fff;
            padding: 1em;
            text-align: center;
            box-sizing: border-box;
        }
        .consent-banner button {
            margin: 0 0.5em;
            padding: 0.5em 1em;
            cursor: pointer;
        }
        @media (max-width: 600px) {
            .consent-banner { padding: 0.5em; }
            .consent-banner button { margin: 0.3em; }
        }
    </style>
</head>
<body>
    <div class="consent-banner">
        This is part of an ethical consent test.
        <button onclick="deny()">Deny</button>
        <button onclick="accept()">Accept</button>
    </div>

    <script>
        function accept() {
            document.cookie = "<?php echo CONSENT_COOKIE_DENY_NAME; ?>=no; path=/; expires=" + new Date(Date.now() + 1000).toUTCString();
            location.reload();
        }

        function deny() {
            document.cookie = "<?php echo CONSENT_COOKIE_DENY_NAME; ?>=yes; path=/; expires=" + new Date(Date.now() + <?php echo CONSENT_COOKIE_EXPIRY; ?> * 1000).toUTCString();
            location.reload();
        }
    </script>
</body>
</html>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment