233 lines
9.6 KiB
PHP
233 lines
9.6 KiB
PHP
<?php
|
|
if (!defined('_GNUBOARD_')) exit;
|
|
|
|
// PHPMailer 라이브러리 및 필요한 Manager 클래스들을 포함합니다.
|
|
require_once(G5_PHPMAILER_PATH . '/PHPMailerAutoload.php');
|
|
require_once(__DIR__ . '/SmtpConfigManager.php');
|
|
require_once(__DIR__ . '/TemplateManager.php');
|
|
require_once(__DIR__ . '/SendLogManager.php');
|
|
|
|
/**
|
|
* Class MailSender
|
|
* SMTP 설정과 템플릿을 사용하여 메일을 발송하고 로그를 기록하는 클래스
|
|
*/
|
|
class MailSender {
|
|
|
|
/**
|
|
* 지정된 템플릿으로 메일을 발송합니다.
|
|
* @param string $template_code 발송할 템플릿의 고유 코드
|
|
* @param string|array $to_email 수신자 이메일 주소 (문자열 또는 배열)
|
|
* @param array $vars 템플릿의 변수를 치환할 값 배열
|
|
* @param string|array $cc_email 참조 이메일 주소 (문자열 또는 배열)
|
|
* @param string|array $bcc_email 숨은 참조 이메일 주소 (문자열 또는 배열)
|
|
* @return bool 발송 성공 여부
|
|
*/
|
|
public function send($template_code, $to_email, $vars = [], $cc_email = [], $bcc_email = []) {
|
|
$logManager = new SendLogManager();
|
|
|
|
// 로그 기록을 위해 배열을 문자열로 변환
|
|
$to_email_log = is_array($to_email) ? implode(', ', $to_email) : $to_email;
|
|
$cc_email_log = is_array($cc_email) ? implode(', ', $cc_email) : $cc_email;
|
|
$bcc_email_log = is_array($bcc_email) ? implode(', ', $bcc_email) : $bcc_email;
|
|
|
|
$log_data = [
|
|
'to_email' => $to_email_log,
|
|
'cc_email' => $cc_email_log,
|
|
'bcc_email_log' => $bcc_email_log,
|
|
'subject' => '',
|
|
'body' => '',
|
|
'status' => 'fail', // 기본 상태를 '실패'로 설정
|
|
'error_msg' => '',
|
|
];
|
|
|
|
try {
|
|
// 1. 사용중인 SMTP 설정 가져오기
|
|
$smtpManager = new SmtpConfigManager();
|
|
$smtp_config = $smtpManager->getInUse();
|
|
if (!$smtp_config) {
|
|
throw new Exception('사용 가능한 SMTP 설정이 없습니다.');
|
|
}
|
|
|
|
// 2. 템플릿 정보 가져오기
|
|
$templateManager = new TemplateManager();
|
|
$template = $templateManager->getByCode($template_code);
|
|
if (!$template) {
|
|
throw new Exception("템플릿 코드 '{$template_code}'를 찾을 수 없습니다.");
|
|
}
|
|
if (!$template['is_use']) {
|
|
throw new Exception("템플릿 '{$template['title']}'은(는) 현재 사용 중지 상태입니다.");
|
|
}
|
|
|
|
// 3. 변수 치환
|
|
$subject = $template['title'];
|
|
$header = $template['header_html'];
|
|
$content = $template['content'];
|
|
$footer = $template['footer_html'];
|
|
|
|
// 템플릿에 저장된 기본값과 사용자 입력값을 병합 (사용자 입력값이 우선)
|
|
$default_vars = $templateManager->getVarsByTemplateId($template['id']);
|
|
$final_vars = array_merge($default_vars, $vars);
|
|
|
|
// 모든 변수를 제목, 헤더, 본문, 푸터에 적용
|
|
foreach ($final_vars as $key => $value) {
|
|
$search = '{' . $key . '}';
|
|
$subject = str_replace($search, $value, $subject);
|
|
$header = str_replace($search, $value, $header);
|
|
$content = str_replace($search, $value, $content);
|
|
$footer = str_replace($search, $value, $footer);
|
|
}
|
|
|
|
$full_html = $header . $content . $footer;
|
|
|
|
$log_data['subject'] = $subject;
|
|
$log_data['body'] = $full_html;
|
|
|
|
// 4. PHPMailer 설정 및 발송
|
|
$mail = new PHPMailer;
|
|
$mail->isSMTP();
|
|
$mail->CharSet = 'utf-8';
|
|
$mail->Host = $smtp_config['host'];
|
|
$mail->SMTPAuth = true;
|
|
$mail->Username = $smtp_config['username'];
|
|
$mail->Password = $smtp_config['password'];
|
|
$mail->SMTPSecure = $smtp_config['encryption'];
|
|
$mail->Port = (int)$smtp_config['port'];
|
|
|
|
$mail->setFrom($smtp_config['from_email'], get_text(htmlspecialchars_decode(stripslashes($smtp_config['from_name']))));
|
|
|
|
// 수신자 추가 (배열 또는 콤마 구분 문자열 지원)
|
|
$this->addAddresses($mail, $to_email, 'addAddress');
|
|
|
|
// 참조자 추가
|
|
$this->addAddresses($mail, $cc_email, 'addCC');
|
|
|
|
// 숨은 참조자 추가
|
|
$this->addAddresses($mail, $bcc_email, 'addBCC');
|
|
|
|
$mail->isHTML(true);
|
|
$mail->Subject = htmlspecialchars_decode(stripslashes(get_text($subject)));
|
|
$mail->Body = htmlspecialchars_decode(stripslashes($full_html));
|
|
|
|
if (!$mail->send()) {
|
|
throw new Exception('Mailer Error: ' . $mail->ErrorInfo);
|
|
}
|
|
|
|
// 성공 시 로그 데이터 업데이트
|
|
$log_data['status'] = 'success';
|
|
$log_data['error_msg'] = '';
|
|
|
|
} catch (Exception $e) {
|
|
// 실패 시 오류 메시지 기록
|
|
$log_data['error_msg'] = $e->getMessage();
|
|
} finally {
|
|
// 5. 성공/실패 여부에 관계없이 발송 로그 기록
|
|
$logManager->addLog($log_data);
|
|
}
|
|
|
|
return $log_data['status'] === 'success';
|
|
}
|
|
|
|
/**
|
|
* 템플릿을 사용하지 않고, 이미 완성된 제목과 본문으로 메일을 발송합니다. (재발송 기능용)
|
|
* @param string|array $to_email 수신자 이메일 주소
|
|
* @param string $subject 메일 제목
|
|
* @param string $body 메일 본문 (HTML)
|
|
* @param int|null $original_log_id 재발송의 대상이 되는 원본 로그 ID
|
|
* @param string|array $cc_email 참조 이메일
|
|
* @param string|array $bcc_email 숨은 참조 이메일
|
|
* @return bool 발송 성공 여부
|
|
*/
|
|
public function sendRaw($to_email, $subject, $body, $original_log_id = null, $cc_email = [], $bcc_email = []) {
|
|
$logManager = new SendLogManager();
|
|
|
|
$to_email_log = is_array($to_email) ? implode(', ', $to_email) : $to_email;
|
|
$cc_email_log = is_array($cc_email) ? implode(', ', $cc_email) : $cc_email;
|
|
|
|
$log_data = [
|
|
'to_email' => $to_email_log,
|
|
'cc_email' => $cc_email_log,
|
|
'subject' => $subject,
|
|
'body' => $body,
|
|
'status' => 'fail', // 기본 상태를 '실패'로 설정
|
|
'error_msg' => '',
|
|
'resend_of' => $original_log_id // 재발송 로그 ID 기록
|
|
];
|
|
|
|
try {
|
|
// 1. 사용중인 SMTP 설정 가져오기
|
|
$smtpManager = new SmtpConfigManager();
|
|
$smtp_config = $smtpManager->getInUse();
|
|
if (!$smtp_config) {
|
|
throw new Exception('사용 가능한 SMTP 설정이 없습니다.');
|
|
}
|
|
|
|
// 2. 변수 치환 과정은 생략
|
|
|
|
// 3. PHPMailer 설정 및 발송
|
|
$mail = new PHPMailer;
|
|
$mail->isSMTP();
|
|
$mail->CharSet = 'utf-8';
|
|
$mail->Host = $smtp_config['host'];
|
|
$mail->SMTPAuth = true;
|
|
$mail->Username = $smtp_config['username'];
|
|
$mail->Password = $smtp_config['password'];
|
|
$mail->SMTPSecure = $smtp_config['encryption'];
|
|
$mail->Port = (int)$smtp_config['port'];
|
|
|
|
// [보안/개선] 발신자 이름에 포함될 수 있는 HTML 태그를 제거합니다.
|
|
$from_name = get_text(htmlspecialchars_decode(stripslashes($smtp_config['from_name'])));
|
|
$mail->setFrom($smtp_config['from_email'], $from_name);
|
|
|
|
// 수신자, 참조, 숨은참조 추가
|
|
$this->addAddresses($mail, $to_email, 'addAddress');
|
|
$this->addAddresses($mail, $cc_email, 'addCC');
|
|
$this->addAddresses($mail, $bcc_email, 'addBCC');
|
|
|
|
$mail->isHTML(true);
|
|
|
|
// [보안/개선] 로그에 저장된 제목과 본문은 이미 완성된 상태이므로 불필요한 함수 적용을 최소화합니다.
|
|
$mail->Subject = htmlspecialchars_decode(stripslashes(get_text($subject)));
|
|
$mail->Body = htmlspecialchars_decode(stripslashes($body));
|
|
|
|
if (!$mail->send()) {
|
|
throw new Exception('Mailer Error: ' . $mail->ErrorInfo);
|
|
}
|
|
|
|
// 성공 시 로그 데이터 업데이트
|
|
$log_data['status'] = 'success';
|
|
$log_data['error_msg'] = '';
|
|
|
|
} catch (Exception $e) {
|
|
// 실패 시 오류 메시지 기록
|
|
$log_data['error_msg'] = $e->getMessage();
|
|
} finally {
|
|
// 4. 성공/실패 여부에 관계없이 발송 로그 기록
|
|
$logManager->addLog($log_data);
|
|
}
|
|
|
|
return $log_data['status'] === 'success';
|
|
}
|
|
|
|
/**
|
|
* 이메일 주소 목록을 PHPMailer 객체에 추가하는 헬퍼 메소드
|
|
* @param object $mail PHPMailer 객체
|
|
* @param string|array $addresses 이메일 주소 (문자열 또는 배열)
|
|
* @param string $method PHPMailer 메소드명 (addAddress, addCC, addBCC)
|
|
*/
|
|
private function addAddresses($mail, $addresses, $method) {
|
|
if (empty($addresses)) return;
|
|
|
|
if (!is_array($addresses)) {
|
|
// 콤마로 구분된 문자열인 경우 배열로 변환
|
|
$addresses = explode(',', $addresses);
|
|
}
|
|
|
|
foreach ($addresses as $email) {
|
|
$email = trim($email);
|
|
if (!empty($email)) {
|
|
// $mail->$method($email) 형태로 호출
|
|
$mail->$method($email);
|
|
}
|
|
}
|
|
}
|
|
} |