416 lines
16 KiB
PHP
416 lines
16 KiB
PHP
<?php
|
|
$sub_menu = "800500";
|
|
include_once('./_common.php');
|
|
|
|
auth_check($auth[$sub_menu], 'r');
|
|
|
|
$g5['title'] = '이메일 템플릿 관리';
|
|
|
|
// 액션 처리
|
|
$action = isset($_REQUEST['action']) ? clean_xss_tags($_REQUEST['action']) : '';
|
|
$id = (int) ($_REQUEST['id'] ?? 0);
|
|
|
|
// POST 요청 처리 (생성, 수정, 삭제)
|
|
if ($action && $_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
auth_check($auth[$sub_menu], 'w');
|
|
|
|
try {
|
|
if ($action === 'save') {
|
|
$template_key = clean_xss_tags($_POST['template_key'] ?? '');
|
|
$template_name = clean_xss_tags($_POST['template_name'] ?? '');
|
|
$subject = clean_xss_tags($_POST['subject'] ?? '');
|
|
$content = $_POST['content'] ?? ''; // HTML 내용이므로 clean_xss_tags 사용하지 않음
|
|
$variables = clean_xss_tags($_POST['variables'] ?? '');
|
|
|
|
if (!$template_key || !$template_name || !$subject || !$content) {
|
|
throw new Exception('필수 항목을 모두 입력해주세요.');
|
|
}
|
|
|
|
// 템플릿 키 중복 확인 (수정 시 제외)
|
|
if ($id === 0) {
|
|
$existing = sql_fetch("SELECT id FROM order_mail_templates WHERE template_key = '{$template_key}'");
|
|
if ($existing) {
|
|
throw new Exception('이미 존재하는 템플릿 키입니다.');
|
|
}
|
|
}
|
|
|
|
$data = [
|
|
'template_key' => $template_key,
|
|
'template_name' => $template_name,
|
|
'subject' => $subject,
|
|
'content' => $content,
|
|
'variables' => $variables,
|
|
'updated_at' => date('Y-m-d H:i:s')
|
|
];
|
|
|
|
if ($id > 0) {
|
|
// 수정
|
|
$set_clauses = [];
|
|
foreach ($data as $key => $value) {
|
|
$set_clauses[] = "`{$key}` = '" . sql_real_escape_string($value) . "'";
|
|
}
|
|
$sql = "UPDATE order_mail_templates SET " . implode(', ', $set_clauses) . " WHERE id = '{$id}'";
|
|
sql_query($sql);
|
|
$message = '이메일 템플릿이 수정되었습니다.';
|
|
} else {
|
|
// 생성
|
|
$data['created_at'] = date('Y-m-d H:i:s');
|
|
$fields = array_keys($data);
|
|
$values = array_values($data);
|
|
$fields_str = '`' . implode('`, `', $fields) . '`';
|
|
$values_str = "'" . implode("', '", array_map('sql_real_escape_string', $values)) . "'";
|
|
$sql = "INSERT INTO order_mail_templates ({$fields_str}) VALUES ({$values_str})";
|
|
sql_query($sql);
|
|
$message = '이메일 템플릿이 생성되었습니다.';
|
|
}
|
|
|
|
alert($message, './mail_templates.php');
|
|
}
|
|
|
|
if ($action === 'delete') {
|
|
if ($id > 0) {
|
|
sql_query("DELETE FROM order_mail_templates WHERE id = '{$id}'");
|
|
alert('이메일 템플릿이 삭제되었습니다.', './mail_templates.php');
|
|
}
|
|
}
|
|
|
|
} catch (Exception $e) {
|
|
alert('오류: ' . $e->getMessage());
|
|
}
|
|
|
|
goto_url('./mail_templates.php');
|
|
exit;
|
|
}
|
|
|
|
// GET 요청 처리 (목록, 편집 폼)
|
|
$mode = isset($_GET['mode']) ? clean_xss_tags($_GET['mode']) : 'list';
|
|
$template = null;
|
|
|
|
if ($mode === 'edit' && $id > 0) {
|
|
$template = sql_fetch("SELECT * FROM order_mail_templates WHERE id = '{$id}'");
|
|
if (!$template) {
|
|
alert('존재하지 않는 템플릿입니다.', './mail_templates.php');
|
|
}
|
|
}
|
|
|
|
// 템플릿 목록 조회
|
|
$templates = [];
|
|
$sql = "SELECT * FROM order_mail_templates ORDER BY template_key ASC";
|
|
$result = sql_query($sql);
|
|
while ($row = sql_fetch_array($result)) {
|
|
$templates[] = $row;
|
|
}
|
|
|
|
include_once(G5_ADMIN_PATH . '/admin.head.php');
|
|
?>
|
|
|
|
<div class="local_desc01 local_desc">
|
|
<p>
|
|
이메일 알림에 사용되는 템플릿을 관리합니다.<br>
|
|
변수를 사용하여 동적인 내용을 삽입할 수 있습니다. 예: {customer_name}, {estimate_id}
|
|
</p>
|
|
</div>
|
|
|
|
<?php if ($mode === 'list'): ?>
|
|
<!-- 템플릿 목록 -->
|
|
<div class="local_ov01 local_ov">
|
|
<span class="btn_ov01">
|
|
<span class="ov_txt">전체 템플릿 </span>
|
|
<span class="ov_num"><?php echo count($templates); ?>개</span>
|
|
</span>
|
|
<a href="?mode=edit" class="btn btn_02">새 템플릿 추가</a>
|
|
</div>
|
|
|
|
<div class="tbl_head01 tbl_wrap">
|
|
<table>
|
|
<caption><?php echo $g5['title']; ?> 목록</caption>
|
|
<thead>
|
|
<tr>
|
|
<th scope="col">템플릿 키</th>
|
|
<th scope="col">템플릿명</th>
|
|
<th scope="col">제목</th>
|
|
<th scope="col">변수</th>
|
|
<th scope="col">수정일</th>
|
|
<th scope="col">관리</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if (empty($templates)): ?>
|
|
<tr>
|
|
<td colspan="6" class="empty_table">등록된 템플릿이 없습니다.</td>
|
|
</tr>
|
|
<?php else: ?>
|
|
<?php foreach ($templates as $tpl): ?>
|
|
<tr>
|
|
<td class="td_left">
|
|
<code><?php echo get_text($tpl['template_key']); ?></code>
|
|
</td>
|
|
<td class="td_left">
|
|
<strong><?php echo get_text($tpl['template_name']); ?></strong>
|
|
</td>
|
|
<td class="td_left">
|
|
<?php echo get_text($tpl['subject']); ?>
|
|
</td>
|
|
<td class="td_left">
|
|
<?php
|
|
$variables = json_decode($tpl['variables'], true);
|
|
if (is_array($variables)) {
|
|
echo '<small>' . implode(', ', array_map(function ($var) {
|
|
return '{' . $var . '}'; }, $variables)) . '</small>';
|
|
}
|
|
?>
|
|
</td>
|
|
<td class="td_datetime">
|
|
<?php echo $tpl['updated_at'] ? date('Y-m-d H:i', strtotime($tpl['updated_at'])) : '-'; ?>
|
|
</td>
|
|
<td class="td_mng td_mng_s">
|
|
<a href="?mode=edit&id=<?php echo $tpl['id']; ?>" class="btn btn_03">수정</a>
|
|
<a href="javascript:void(0);" onclick="previewTemplate(<?php echo $tpl['id']; ?>)"
|
|
class="btn btn_04">미리보기</a>
|
|
<a href="javascript:void(0);" onclick="deleteTemplate(<?php echo $tpl['id']; ?>)"
|
|
class="btn btn_02">삭제</a>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<?php else: ?>
|
|
<!-- 템플릿 편집 폼 -->
|
|
<div class="local_desc02 local_desc">
|
|
<p>
|
|
<a href="./mail_templates.php" class="btn btn_01">목록으로 돌아가기</a>
|
|
</p>
|
|
</div>
|
|
|
|
<form name="ftemplate" method="post" onsubmit="return validateForm()">
|
|
<input type="hidden" name="action" value="save">
|
|
<input type="hidden" name="id" value="<?php echo $template['id'] ?? 0; ?>">
|
|
|
|
<div class="tbl_frm01 tbl_wrap">
|
|
<table>
|
|
<caption><?php echo $template ? '템플릿 수정' : '새 템플릿 추가'; ?></caption>
|
|
<colgroup>
|
|
<col class="grid_4">
|
|
<col>
|
|
</colgroup>
|
|
<tbody>
|
|
<tr>
|
|
<th scope="row"><label for="template_key">템플릿 키<strong class="sound_only">필수</strong></label></th>
|
|
<td>
|
|
<input type="text" name="template_key" id="template_key"
|
|
value="<?php echo get_text($template['template_key'] ?? ''); ?>" class="frm_input"
|
|
maxlength="100" required <?php echo $template ? 'readonly' : ''; ?>>
|
|
<span class="frm_info">영문, 숫자, 언더스코어만 사용 가능 (예: customer_request_complete)</span>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th scope="row"><label for="template_name">템플릿명<strong class="sound_only">필수</strong></label></th>
|
|
<td>
|
|
<input type="text" name="template_name" id="template_name"
|
|
value="<?php echo get_text($template['template_name'] ?? ''); ?>" class="frm_input"
|
|
maxlength="255" required>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th scope="row"><label for="subject">이메일 제목<strong class="sound_only">필수</strong></label></th>
|
|
<td>
|
|
<input type="text" name="subject" id="subject"
|
|
value="<?php echo get_text($template['subject'] ?? ''); ?>" class="frm_input"
|
|
maxlength="255" required>
|
|
<span class="frm_info">변수 사용 가능: {customer_name}, {estimate_id} 등</span>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th scope="row"><label for="content">이메일 내용<strong class="sound_only">필수</strong></label></th>
|
|
<td>
|
|
<textarea name="content" id="content" rows="15" class="frm_input"
|
|
required><?php echo get_text($template['content'] ?? ''); ?></textarea>
|
|
<span class="frm_info">HTML 태그 사용 가능. 변수는 {변수명} 형태로 입력</span>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th scope="row"><label for="variables">사용 가능한 변수</label></th>
|
|
<td>
|
|
<input type="text" name="variables" id="variables"
|
|
value="<?php echo get_text($template['variables'] ?? ''); ?>" class="frm_input"
|
|
placeholder='["customer_name", "estimate_id", "total_amount"]'>
|
|
<span class="frm_info">JSON 배열 형태로 입력 (예: ["customer_name", "estimate_id"])</span>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="btn_confirm01 btn_confirm">
|
|
<input type="submit" value="<?php echo $template ? '수정' : '등록'; ?>" class="btn_submit">
|
|
<a href="./mail_templates.php" class="btn_cancel">취소</a>
|
|
</div>
|
|
</form>
|
|
|
|
<?php endif; ?>
|
|
|
|
<!-- 미리보기 모달 -->
|
|
<div id="previewModal" class="modal" style="display: none;">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h3>템플릿 미리보기</h3>
|
|
<span class="close" onclick="closePreview()">×</span>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div id="previewContent"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
.modal {
|
|
position: fixed;
|
|
z-index: 1000;
|
|
left: 0;
|
|
top: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background-color: rgba(0, 0, 0, 0.5);
|
|
}
|
|
|
|
.modal-content {
|
|
background-color: #fefefe;
|
|
margin: 5% auto;
|
|
padding: 0;
|
|
border: 1px solid #888;
|
|
width: 80%;
|
|
max-width: 800px;
|
|
border-radius: 5px;
|
|
}
|
|
|
|
.modal-header {
|
|
padding: 15px 20px;
|
|
background-color: #f8f9fa;
|
|
border-bottom: 1px solid #dee2e6;
|
|
border-radius: 5px 5px 0 0;
|
|
}
|
|
|
|
.modal-header h3 {
|
|
margin: 0;
|
|
display: inline-block;
|
|
}
|
|
|
|
.close {
|
|
color: #aaa;
|
|
float: right;
|
|
font-size: 28px;
|
|
font-weight: bold;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.close:hover {
|
|
color: black;
|
|
}
|
|
|
|
.modal-body {
|
|
padding: 20px;
|
|
max-height: 500px;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
code {
|
|
background-color: #f8f9fa;
|
|
padding: 2px 4px;
|
|
border-radius: 3px;
|
|
font-family: monospace;
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
// 폼 유효성 검사
|
|
function validateForm() {
|
|
const templateKey = document.getElementById('template_key').value.trim();
|
|
const templateName = document.getElementById('template_name').value.trim();
|
|
const subject = document.getElementById('subject').value.trim();
|
|
const content = document.getElementById('content').value.trim();
|
|
|
|
if (!templateKey || !templateName || !subject || !content) {
|
|
alert('필수 항목을 모두 입력해주세요.');
|
|
return false;
|
|
}
|
|
|
|
// 템플릿 키 형식 검사
|
|
if (!/^[a-zA-Z0-9_]+$/.test(templateKey)) {
|
|
alert('템플릿 키는 영문, 숫자, 언더스코어만 사용할 수 있습니다.');
|
|
return false;
|
|
}
|
|
|
|
// 변수 JSON 형식 검사
|
|
const variables = document.getElementById('variables').value.trim();
|
|
if (variables) {
|
|
try {
|
|
JSON.parse(variables);
|
|
} catch (e) {
|
|
alert('변수는 올바른 JSON 배열 형태로 입력해주세요.');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// 템플릿 삭제
|
|
function deleteTemplate(id) {
|
|
if (!confirm('정말로 이 템플릿을 삭제하시겠습니까?')) {
|
|
return;
|
|
}
|
|
|
|
const form = document.createElement('form');
|
|
form.method = 'POST';
|
|
form.innerHTML = `
|
|
<input type="hidden" name="action" value="delete">
|
|
<input type="hidden" name="id" value="${id}">
|
|
`;
|
|
document.body.appendChild(form);
|
|
form.submit();
|
|
}
|
|
|
|
// 템플릿 미리보기
|
|
function previewTemplate(id) {
|
|
fetch('mail_templates_ajax.php?action=preview&id=' + id)
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
document.getElementById('previewContent').innerHTML = `
|
|
<h4>제목: ${data.data.subject}</h4>
|
|
<div style="border: 1px solid #ddd; padding: 15px; background: white;">
|
|
${data.data.content}
|
|
</div>
|
|
<p><small>사용 가능한 변수: ${data.data.variables || '없음'}</small></p>
|
|
`;
|
|
document.getElementById('previewModal').style.display = 'block';
|
|
} else {
|
|
alert('미리보기를 불러올 수 없습니다: ' + data.message);
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
alert('미리보기 중 오류가 발생했습니다.');
|
|
});
|
|
}
|
|
|
|
// 미리보기 닫기
|
|
function closePreview() {
|
|
document.getElementById('previewModal').style.display = 'none';
|
|
}
|
|
|
|
// 모달 외부 클릭 시 닫기
|
|
window.onclick = function (event) {
|
|
const modal = document.getElementById('previewModal');
|
|
if (event.target === modal) {
|
|
closePreview();
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<?php
|
|
include_once(G5_ADMIN_PATH . '/admin.tail.php');
|
|
?>
|