first commit 2

This commit is contained in:
hmw1001
2026-06-11 18:47:38 +09:00
parent c768729ce6
commit 6f534e33a6
11095 changed files with 1595758 additions and 0 deletions
+233
View File
@@ -0,0 +1,233 @@
<?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);
}
}
}
}
@@ -0,0 +1,61 @@
<?php
if (!defined('_GNUBOARD_')) exit;
class SendLogManager {
protected $table = 'g5_mail_send_log';
public function getTotalCount() {
$row = sql_fetch("SELECT COUNT(*) as cnt FROM {$this->table}");
return $row['cnt'] ?? 0;
}
/**
* [추가] 페이징된 로그 목록을 가져옵니다.
* @param int $from_record 시작 레코드
* @param int $page_rows 페이지당 레코드 수
* @return array
*/
public function getPagedList($from_record, $page_rows) {
$from_record = (int)$from_record;
$page_rows = (int)$page_rows;
$sql = "SELECT * FROM {$this->table} ORDER BY id DESC LIMIT {$from_record}, {$page_rows}";
$result = sql_query($sql);
$list = [];
while($row = sql_fetch_array($result)) {
$list[] = $row;
}
return $list;
}
public function getById($id) {
$id = (int)$id;
return sql_fetch("SELECT * FROM {$this->table} WHERE id = '{$id}'");
}
// C:/project/other/saungjin/adm/mail_manage/classes/SendLogManager.php 파일
public function addLog($data) {
global $member;
// 넘어온 데이터를 안전하게 처리
$to_email = sql_real_escape_string($data['to_email']);
$cc_email = isset($data['cc_email']) ? sql_real_escape_string($data['cc_email']) : '';
$bcc_email = isset($data['bcc_email']) ? sql_real_escape_string($data['bcc_email']) : '';
$subject = sql_real_escape_string($data['subject']);
$body = sql_real_escape_string($data['body']);
$status = in_array($data['status'], ['success', 'fail']) ? $data['status'] : 'fail';
$error_msg = isset($data['error_msg']) ? sql_real_escape_string($data['error_msg']) : '';
$send_time = G5_TIME_YMDHIS;
$resend_of = isset($data['resend_of']) ? (int)$data['resend_of'] : 'NULL';
$created_by = $member['mb_id'] ?? 'guest'; // 로그인한 사용자 또는 guest
// [수정] install.php의 테이블 구조와 일치하도록 쿼리 수정
$sql = "INSERT INTO {$this->table}
(to_email, cc_email,bcc_email, subject, body, status, send_time, created_by, created_at, error_msg, resend_of)
VALUES
('{$to_email}', '{$cc_email}', '{$bcc_email}' ,'{$subject}', '{$body}', '{$status}', '{$send_time}', '{$created_by}', '{$send_time}', '{$error_msg}', {$resend_of})";
sql_query($sql);
}
}
@@ -0,0 +1,230 @@
<?php
if (!defined('_GNUBOARD_')) exit;
class SmtpConfigManager
{
private $table = 'g5_mail_smtp_config';
// [추가] 로그 테이블명 변수
private $log_table = 'g5_mail_smtp_change_log';
public function getAll()
{
$sql = "SELECT * FROM {$this->table} WHERE is_deleted = 0 ORDER BY id DESC";
$result = sql_query($sql);
$list = [];
while ($row = sql_fetch_array($result)) {
$list[] = $row;
}
return $list;
}
public function get($id)
{
$id = (int)$id;
return sql_fetch("SELECT * FROM {$this->table} WHERE id = '{$id}' AND is_deleted = 0");
}
public function getInUse()
{
// [추가] 사용중(is_use=1)인 첫번째 설정을 가져오는 메소드
return sql_fetch("SELECT * FROM {$this->table} WHERE is_use = 1 AND is_deleted = 0 LIMIT 1");
}
public function create($data)
{
global $member;
$now = G5_TIME_YMDHIS;
$set_sql = [];
$set_sql[] = " name = '" . sql_real_escape_string(trim($data['name'])) . "' ";
$set_sql[] = " host = '" . sql_real_escape_string(trim($data['host'])) . "' ";
$set_sql[] = " username = '" . sql_real_escape_string(trim($data['username'])) . "' ";
$set_sql[] = " password = '" . sql_real_escape_string(trim($data['password'])) . "' ";
$set_sql[] = " port = '" . (int)$data['port'] . "' ";
$set_sql[] = " encryption = '" . (in_array($data['encryption'], ['none', 'ssl', 'tls']) ? $data['encryption'] : 'ssl') . "' ";
$set_sql[] = " from_email = '" . sql_real_escape_string(trim($data['from_email'])) . "' ";
$set_sql[] = " from_name = '" . sql_real_escape_string(trim($data['from_name'])) . "' ";
$set_sql[] = " is_use = '" . (isset($data['is_use']) ? 1 : 0) . "' ";
$set_sql[] = " is_deleted = '0' ";
$set_sql[] = " created_by = '{$member['mb_id']}' ";
$set_sql[] = " updated_by = '{$member['mb_id']}' ";
$set_sql[] = " created_at = '{$now}' ";
$set_sql[] = " updated_at = '{$now}' ";
$sql = "INSERT INTO {$this->table} SET " . implode(', ', $set_sql);
sql_query($sql);
// [추가] 로그 기록
$id = sql_insert_id();
$details = "새로운 SMTP 설정 추가: " . sql_real_escape_string(trim($data['name']));
$this->insertLog($id, 'insert', $member['mb_id'], $details);
}
public function update($id, $data)
{
global $member;
$id = (int)$id;
$now = G5_TIME_YMDHIS;
$set_sql = [];
$set_sql[] = " name = '" . sql_real_escape_string(trim($data['name'])) . "' ";
$set_sql[] = " host = '" . sql_real_escape_string(trim($data['host'])) . "' ";
$set_sql[] = " username = '" . sql_real_escape_string(trim($data['username'])) . "' ";
$set_sql[] = " port = '" . (int)$data['port'] . "' ";
$set_sql[] = " encryption = '" . (in_array($data['encryption'], ['none', 'ssl', 'tls']) ? $data['encryption'] : 'ssl') . "' ";
$set_sql[] = " from_email = '" . sql_real_escape_string(trim($data['from_email'])) . "' ";
$set_sql[] = " from_name = '" . sql_real_escape_string(trim($data['from_name'])) . "' ";
$set_sql[] = " is_use = '" . (isset($data['is_use']) ? 1 : 0) . "' ";
$set_sql[] = " updated_by = '{$member['mb_id']}' ";
$set_sql[] = " updated_at = '{$now}' ";
if (!empty($data['password'])) {
$set_sql[] = " password = '" . sql_real_escape_string(trim($data['password'])) . "' ";
}
$sql = "UPDATE {$this->table} SET " . implode(', ', $set_sql) . " WHERE id = {$id}";
sql_query($sql);
// [추가] 로그 기록
$details = "SMTP 설정 수정 (ID: {$id})";
$this->insertLog($id, 'update', $member['mb_id'], $details);
}
public function delete($id)
{
global $member;
$id = (int)$id;
$now = G5_TIME_YMDHIS;
$mb_id = sql_real_escape_string($member['mb_id']);
$sql = "UPDATE {$this->table} SET
is_deleted = 1,
updated_by = '{$mb_id}',
updated_at = '{$now}'
WHERE id = {$id}";
sql_query($sql);
// [추가] 로그 기록
$details = "SMTP 설정 삭제 (ID: {$id})";
$this->insertLog($id, 'delete', $member['mb_id'], $details);
}
/**
* [추가] 변경 이력을 기록하는 private 메소드
*/
private function insertLog($smtp_config_id, $action, $changed_by, $details)
{
$smtp_config_id = (int)$smtp_config_id;
$action = sql_real_escape_string($action);
$changed_by = sql_real_escape_string($changed_by);
$details = sql_real_escape_string($details);
$change_date = G5_TIME_YMDHIS;
$sql = "INSERT INTO {$this->log_table}
(smtp_config_id, `action`, changed_by, change_date, change_details)
VALUES
('{$smtp_config_id}', '{$action}', '{$changed_by}', '{$change_date}', '{$details}')";
sql_query($sql);
}
}
/*if (!defined('_GNUBOARD_')) exit;
class SmtpConfigManager
{
private $table = 'g5_mail_smtp_config';
public function getAll()
{
$sql = "SELECT * FROM {$this->table} WHERE is_deleted = 0 ORDER BY id DESC";
$result = sql_query($sql);
$list = [];
while ($row = sql_fetch_array($result)) {
$list[] = $row;
}
return $list;
}
public function get($id)
{
$id = (int)$id;
return sql_fetch("SELECT * FROM {$this->table} WHERE id = '{$id}' AND is_deleted = 0");
}
public function getInUse()
{
// [추가] 사용중(is_use=1)인 첫번째 설정을 가져오는 메소드
return sql_fetch("SELECT * FROM {$this->table} WHERE is_use = 1 AND is_deleted = 0 LIMIT 1");
}
public function create($data)
{
global $member;
$now = G5_TIME_YMDHIS;
// [수정] sql_array_insert 함수 대신 직접 SQL 구문을 생성합니다.
// 이 방식은 SQL 인젝션에 더 안전하고 호환성 문제가 없습니다.
$set_sql = [];
$set_sql[] = " name = '".sql_real_escape_string(trim($data['name']))."' ";
$set_sql[] = " host = '".sql_real_escape_string(trim($data['host']))."' ";
$set_sql[] = " username = '".sql_real_escape_string(trim($data['username']))."' ";
$set_sql[] = " password = '".sql_real_escape_string(trim($data['password']))."' ";
$set_sql[] = " port = '".(int)$data['port']."' ";
$set_sql[] = " encryption = '".(in_array($data['encryption'], ['none','ssl','tls']) ? $data['encryption'] : 'ssl')."' ";
$set_sql[] = " from_email = '".sql_real_escape_string(trim($data['from_email']))."' ";
$set_sql[] = " from_name = '".sql_real_escape_string(trim($data['from_name']))."' ";
$set_sql[] = " is_use = '".(isset($data['is_use']) ? 1 : 0)."' ";
$set_sql[] = " is_deleted = '0' ";
$set_sql[] = " created_by = '{$member['mb_id']}' ";
$set_sql[] = " updated_by = '{$member['mb_id']}' ";
$set_sql[] = " created_at = '{$now}' ";
$set_sql[] = " updated_at = '{$now}' ";
$sql = "INSERT INTO {$this->table} SET " . implode(', ', $set_sql);
sql_query($sql);
}
public function update($id, $data)
{
global $member;
$id = (int)$id;
$now = G5_TIME_YMDHIS;
// [수정] sql_array_insert 함수 대신 직접 SQL 구문을 생성합니다.
$set_sql = [];
$set_sql[] = " name = '".sql_real_escape_string(trim($data['name']))."' ";
$set_sql[] = " host = '".sql_real_escape_string(trim($data['host']))."' ";
$set_sql[] = " username = '".sql_real_escape_string(trim($data['username']))."' ";
$set_sql[] = " port = '".(int)$data['port']."' ";
$set_sql[] = " encryption = '".(in_array($data['encryption'], ['none','ssl','tls']) ? $data['encryption'] : 'ssl')."' ";
$set_sql[] = " from_email = '".sql_real_escape_string(trim($data['from_email']))."' ";
$set_sql[] = " from_name = '".sql_real_escape_string(trim($data['from_name']))."' ";
$set_sql[] = " is_use = '".(isset($data['is_use']) ? 1 : 0)."' ";
$set_sql[] = " updated_by = '{$member['mb_id']}' ";
$set_sql[] = " updated_at = '{$now}' ";
// 비밀번호가 입력된 경우에만 업데이트
if (!empty($data['password'])) {
$set_sql[] = " password = '".sql_real_escape_string(trim($data['password']))."' ";
}
$sql = "UPDATE {$this->table} SET " . implode(', ', $set_sql) . " WHERE id = {$id}";
sql_query($sql);
}
public function delete($id)
{
global $member;
$id = (int)$id;
$now = G5_TIME_YMDHIS;
// [개선] sql_real_escape_string 을 사용하여 보안 강화
$mb_id = sql_real_escape_string($member['mb_id']);
$sql = "UPDATE {$this->table} SET
is_deleted = 1,
updated_by = '{$mb_id}',
updated_at = '{$now}'
WHERE id = {$id}";
sql_query($sql);
}
}*/
+159
View File
@@ -0,0 +1,159 @@
<?php
if (!defined('_GNUBOARD_')) exit;
class TemplateManager
{
protected $table = 'g5_mail_template';
private $log_table = 'g5_mail_template_change_log';
// [추가] 템플릿 변수 테이블명
private $vars_table = 'g5_mail_template_vars';
public function getAll()
{
// [수정] is_use -> is_deleted 로 조건 변경
$result = sql_query("SELECT * FROM {$this->table} WHERE is_deleted = 0 ORDER BY id DESC");
$list = [];
while ($row = sql_fetch_array($result)) {
$list[] = $row;
}
return $list;
}
public function getById($id)
{
$id = (int)$id;
return sql_fetch("SELECT * FROM {$this->table} WHERE id = '{$id}' AND is_deleted = 0 AND is_use = 1");
}
public function getByCode($code)
{
$code = sql_real_escape_string($code);
return sql_fetch("SELECT * FROM {$this->table} WHERE code = '{$code}' AND is_deleted = 0");
}
/**
* [추가] 특정 템플릿에 속한 모든 변수들을 가져옵니다.
* @param int $template_id
* @return array
*/
public function getVarsByTemplateId($template_id)
{
$template_id = (int)$template_id;
$sql = "SELECT var_name, default_value FROM {$this->vars_table} WHERE template_id = '{$template_id}'";
$result = sql_query($sql);
$vars = [];
while ($row = sql_fetch_array($result)) {
$vars[$row['var_name']] = $row['default_value'];
}
return $vars;
}
public function save($data)
{
global $member;
$id = isset($data['id']) ? (int)$data['id'] : 0;
$code = sql_real_escape_string($data['code']);
$title = sql_real_escape_string($data['title']);
$content = $data['content']; // [주의] SQL Escape는 syncTemplateVars에서 처리
// [추가] 헤더와 푸터 데이터를 받습니다.
$header_html = $data['header_html'] ?? '';
$footer_html = $data['footer_html'] ?? '';
$is_use = isset($data['is_use']) ? 1 : 0;
$now = G5_TIME_YMDHIS;
$mb_id = sql_real_escape_string($member['mb_id']);
if ($id > 0) {
// [수정] 업데이트 쿼리 수정
$sql = "UPDATE {$this->table} SET
code = '{$code}',
title = '{$title}',
content = '" . sql_real_escape_string($content) . "',
header_html = '" . sql_real_escape_string($header_html) . "',
footer_html = '" . sql_real_escape_string($footer_html) . "',
is_use = '{$is_use}',
updated_by = '{$mb_id}',
updated_at = '{$now}'
WHERE id = '{$id}'";
sql_query($sql);
// [추가] 업데이트 로그 기록
$details = "템플릿 수정 (ID: {$id}, 코드: {$code})";
$this->insertTemplateLog($id, 'update', $mb_id, $details);
} else {
// [수정] 생성 쿼리 수정
$sql = "INSERT INTO {$this->table}
(code, title, content, header_html, footer_html, is_use, is_deleted, created_by, updated_by, created_at, updated_at)
VALUES
('{$code}', '{$title}', '" . sql_real_escape_string($content) . "', '" . sql_real_escape_string($header_html) . "', '" . sql_real_escape_string($footer_html) . "', '{$is_use}', 0, '{$mb_id}', '{$mb_id}', '{$now}', '{$now}')";
sql_query($sql);
$id = sql_insert_id(); // 새로 생성된 ID를 가져옴
// [추가] 생성 로그 기록
$details = "새 템플릿 생성: " . $title;
$this->insertTemplateLog($id, 'insert', $mb_id, $details);
}
// [핵심 추가] 템플릿 변수 동기화
$this->syncTemplateVars($id, $content, $data['variables'] ?? []);
}
public function delete($id)
{
global $member;
$id = (int)$id;
$mb_id = sql_real_escape_string($member['mb_id']);
$now = G5_TIME_YMDHIS;
// [참고] is_deleted 필드는 사용하지 않으므로 실제 삭제 처리합니다.
// g5_mail_template_vars 테이블은 FOREIGN KEY (ON DELETE CASCADE) 설정으로 자동 삭제됩니다.
sql_query("DELETE FROM {$this->table} WHERE id = '{$id}'");
// [수정] 삭제 로그 기록
$details = "템플릿 삭제 (ID: {$id})";
$this->insertTemplateLog($id, 'delete', $mb_id, $details);
}
private function insertTemplateLog($template_id, $action, $changed_by, $details)
{
$template_id = (int)$template_id;
$action = sql_real_escape_string($action);
$changed_by = sql_real_escape_string($changed_by);
$details = sql_real_escape_string($details);
$change_date = G5_TIME_YMDHIS;
$sql = "INSERT INTO {$this->log_table}
(template_id, `action`, changed_by, change_date, change_details)
VALUES
('{$template_id}', '{$action}', '{$changed_by}', '{$change_date}', '{$details}')";
sql_query($sql);
}
/**
* [핵심 추가] 템플릿 내용의 변수와 DB를 동기화하는 메소드
*/
private function syncTemplateVars($template_id, $content, $submitted_vars)
{
// 1. 템플릿 내용에서 현재 사용중인 모든 변수 추출 (예: {name}, {order_id})
preg_match_all('/{(\w+)}/u', $content, $matches);
$vars_in_content = array_unique($matches[1]);
// 2. 이 템플릿과 관련된 기존 변수들을 모두 삭제 (가장 간단하고 확실한 동기화 방법)
sql_query("DELETE FROM {$this->vars_table} WHERE template_id = '{$template_id}'");
// 3. 내용에 존재하는 변수들만 다시 INSERT
if (!empty($vars_in_content)) {
$now = G5_TIME_YMDHIS;
foreach ($vars_in_content as $var_name) {
// 폼에서 전송된 기본값이 있으면 사용하고, 없으면 빈 문자열로 설정
$default_value = $submitted_vars[$var_name] ?? '';
$sql = "INSERT INTO {$this->vars_table}
(template_id, var_name, default_value, created_at, updated_at)
VALUES
('{$template_id}', '" . sql_real_escape_string($var_name) . "', '" . sql_real_escape_string($default_value) . "', '{$now}', '{$now}')";
sql_query($sql);
}
}
}
}