403Webshell
Server IP : 188.114.96.3  /  Your IP : 216.73.216.143
Web Server : Apache
System : Linux sv058.home.net.pl 6.8.2 husak_dirty_pages_fix #1 SMP PREEMPT_DYNAMIC Tue Apr 2 22:06:51 CEST 2024 x86_64
User :  ( 3194769)
PHP Version : 8.5.12
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : OFF
Directory :  /polana/includes/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /polana/includes/polana_v172_newsletter.php
<?php
declare(strict_types=1);
/** POLANA V17.2: newsletter with double opt-in. Loaded by patched newsletter.php and newsletter_subscribe(). */

function pv172_domain(): string { return 'https://mojapolanasmakow.pl'; }
function pv172_support_mail(): string { return '[email protected]'; }

function pv172_upgrade_schema(): void {
    newsletter_install_table();
    $db = newsletter_db();
    $columns = [];
    foreach ($db->query('SHOW COLUMNS FROM newsletter_subscribers')->fetchAll(PDO::FETCH_ASSOC) as $column) {
        $columns[(string)$column['Field']] = true;
    }
    $missing = [];
    if (!isset($columns['verify_token'])) $missing[] = 'ADD COLUMN verify_token CHAR(64) NULL';
    if (!isset($columns['verified_at'])) $missing[] = 'ADD COLUMN verified_at DATETIME NULL';
    if (!isset($columns['verification_sent_at'])) $missing[] = 'ADD COLUMN verification_sent_at DATETIME NULL';
    if ($missing) $db->exec('ALTER TABLE newsletter_subscribers ' . implode(', ', $missing));
}

function pv172_valid_email(string $email): string {
    $email = mb_strtolower(trim($email), 'UTF-8');
    return (strlen($email) <= 190 && filter_var($email, FILTER_VALIDATE_EMAIL)) ? $email : '';
}
function pv172_mail_html(string $heading, string $body): string {
    return '<!doctype html><html lang="pl"><head><meta charset="utf-8"></head>' .
        '<body style="margin:0;padding:25px;background:#f4f1ea;font-family:Arial,sans-serif;color:#20382b">' .
        '<table role="presentation" width="100%" cellpadding="0" cellspacing="0"><tr><td align="center">' .
        '<table role="presentation" style="max-width:580px;background:#fff;border-radius:15px" width="100%">' .
        '<tr><td style="padding:32px"><h2 style="color:#1a5c42">' . htmlspecialchars($heading, ENT_QUOTES, 'UTF-8') .
        '</h2><div style="line-height:1.7">' . $body . '</div><p style="font-size:12px;color:#737373;margin-top:30px">' .
        'Moja Polana Smaków · Kraków</p></td></tr></table></td></tr></table></body></html>';
}
function pv172_subscribe(string $email, string $name = '', string $source = 'footer'): array {
    $email = pv172_valid_email($email);
    if ($email === '') return ['ok'=>false, 'message'=>'Podaj poprawny adres e-mail.'];
    $generic = 'Jeśli ten adres wymaga potwierdzenia, wyślemy wiadomość z linkiem. Sprawdź też folder SPAM.';
    // Never add an unverified subscriber to the active marketing audience.
    if (setting('smtp_enabled', '0') !== '1' || !smtp_password_is_set() || smtp_password() === '') {
        return ['ok'=>false, 'message'=>'Zapis chwilowo niedostępny. Spróbuj ponownie później.'];
    }
    pv172_upgrade_schema();
    $db = newsletter_db();
    $stmt = $db->prepare('SELECT id, status, verify_token, verification_sent_at FROM newsletter_subscribers WHERE email=? LIMIT 1');
    $stmt->execute([$email]);
    $existing = $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
    if ($existing && (string)$existing['status'] === 'active') {
        return ['ok'=>true, 'message'=>$generic];
    }
    // Avoid mail bombing; a pending confirmation can be resent after five minutes.
    if ($existing && !empty($existing['verification_sent_at']) && (time() - strtotime((string)$existing['verification_sent_at']) < 300)) {
        return ['ok'=>true, 'message'=>$generic];
    }
    $token = bin2hex(random_bytes(32));
    $name = mb_substr(trim($name), 0, 150, 'UTF-8');
    $source = mb_substr(preg_replace('/[^a-z0-9_-]/i', '', $source) ?: 'footer', 0, 50);
    $ipHash = newsletter_ip_hash();
    $agent = mb_substr((string)($_SERVER['HTTP_USER_AGENT'] ?? ''), 0, 255, 'UTF-8');
    if ($existing) {
        $up = $db->prepare('UPDATE newsletter_subscribers SET status="pending", name=?, source=?, consent_at=NOW(), consent_ip_hash=?, user_agent=?, verify_token=?, verification_sent_at=NULL WHERE id=?');
        $up->execute([$name ?: null, $source, $ipHash, $agent ?: null, $token, $existing['id']]);
    } else {
        $up = $db->prepare('INSERT INTO newsletter_subscribers (email,name,source,status,consent_at,consent_ip_hash,user_agent,unsubscribe_token,verify_token) VALUES (?,?,?,"pending",NOW(),?,?,?,?)');
        $up->execute([$email, $name ?: null, $source, $ipHash, $agent ?: null, bin2hex(random_bytes(32)), $token]);
    }
    $url = pv172_domain() . '/newsletter.php?confirm=' . rawurlencode($token);
    $safeUrl = htmlspecialchars($url, ENT_QUOTES, 'UTF-8');
    $html = pv172_mail_html('Potwierdź zapis do newslettera',
        '<p>Otrzymaliśmy prośbę o zapis na newsletter Mojej Polany Smaków.</p>' .
        '<p><a href="'.$safeUrl.'" style="display:inline-block;background:#1a6347;color:#fff;text-decoration:none;padding:14px 20px;border-radius:10px">Potwierdź adres e-mail</a></p>' .
        '<p>Nie zapisywałeś(-aś) się? Zignoruj tę wiadomość — bez potwierdzenia nie będziemy wysyłać newslettera.</p>');
    $text = "Potwierdź zapis do newslettera Mojej Polany Smaków:\n" . $url . "\n\nJeśli to nie Ty, zignoruj wiadomość.";
    try {
        smtp_send_mail($email, 'Potwierdź zapis — Moja Polana Smaków', $html, $text, pv172_support_mail());
        $db->prepare('UPDATE newsletter_subscribers SET verification_sent_at=NOW() WHERE email=? AND verify_token=?')->execute([$email,$token]);
    } catch (Throwable $e) {
        // Keep as pending; do not claim success if SMTP rejected the send.
        error_log('[POLANA NEWSLETTER v172 mail] ' . $e->getMessage());
        return ['ok'=>false,'message'=>'Nie udało się wysłać potwierdzenia. Spróbuj ponownie później.'];
    }
    return ['ok'=>true,'message'=>$generic];
}

function pv172_confirm(string $token): bool {
    if (!preg_match('/^[a-f0-9]{64}$/D', $token)) return false;
    pv172_upgrade_schema();
    $db = newsletter_db();
    $db->beginTransaction();
    try {
        $q = $db->prepare('SELECT id, email, unsubscribe_token FROM newsletter_subscribers WHERE verify_token=? AND status="pending" LIMIT 1 FOR UPDATE');
        $q->execute([$token]);
        $row = $q->fetch(PDO::FETCH_ASSOC);
        if (!$row) { $db->rollBack(); return false; }
        $up = $db->prepare('UPDATE newsletter_subscribers SET status="active", verified_at=NOW(), withdrawn_at=NULL, verify_token=NULL WHERE id=? AND verify_token=?');
        $up->execute([$row['id'], $token]);
        $db->commit();
    } catch (Throwable $e) {
        if ($db->inTransaction()) $db->rollBack();
        throw $e;
    }
    // Confirmation succeeds even if the optional welcome email fails.
    if (setting('smtp_enabled', '0') === '1') {
        try {
            $url = pv172_domain() . '/newsletter.php?unsubscribe=' . rawurlencode((string)$row['unsubscribe_token']);
            $body = "Dziękujemy za potwierdzenie zapisu.\n\nWypisz się w dowolnym momencie: " . $url;
            $html = pv172_mail_html('Witamy na Polanie!', '<p>Twój adres został potwierdzony. Będziemy pisać o menu, nowościach i wydarzeniach.</p><p><a href="'.htmlspecialchars($url, ENT_QUOTES, 'UTF-8').'">Wypisz się z newslettera</a></p>');
            smtp_send_mail((string)$row['email'], 'Witamy w newsletterze — Moja Polana Smaków', $html, $body, pv172_support_mail());
        } catch (Throwable $e) { error_log('[POLANA NEWSLETTER v172 welcome] ' . $e->getMessage()); }
    }
    return true;
}

Youez - 2016 - github.com/yon3zu
LinuXploit