본문으로 건너뛰기

LMS 메시지 발송 시 제목 입력 기능

PHP 8 · GODO26
변경 파일 수: 49개
변경 파일 목록
총 49개
Admin (30)
auto_send_config_recipient_section.phpcrm/auto_send_config/auto_send_config.phpcrm/crm_recipe_send.phpcrm/layer_preview_auto_send.phpcrm/layer_template_contents_sms.phpcrm/message_template_register.phpcrm/template_contents_sms.phpcrm/message_template_register/layer_member_sms_history_result.phpcrm/mobile_message_history/layer_sms_contents.phpcrm/mobile_message_history/layer_sms_history_result.phpcrm/mobile_message_history/layer_kakao_alimtalk_content_setting.phpcrm/mobile_send/layer_kakao_friendtalk_content_setting.phpcrm/mobile_send/layer_mobile_send_save_sms_template.phpcrm/mobile_send/layer_mobile_send_sms_template.phpcrm/mobile_send/layer_mobile_send_sms_template_result.phpcrm/mobile_send/layer_myapp_push_content_setting.phpcrm/mobile_send/layer_send_method_setting.phpcrm/mobile_send/layer_sms_content_setting.phpcrm/mobile_send/mobile_send.phpcrm/layer_preview_mobile_send_alternative.phpcrm/preview_mobile_send/layer_preview_mobile_send_sms.phpcrm/preview_mobile_send/sms_auto.phpmember/sms_log.phpmember/sms_send.phpmember/cart_remind_regist.phppromotion/comeback_coupon_regist.phppromotion/layer_cart_remind_message.phppromotion/layer_comeback_coupon_sms.phpshare/layer_standby_sms.phpshare/member_crm_sms.phpshare/
변경 파일 코드
추가삭제
Admin/crm/auto_send_config/auto_send_config_recipient_section.php+16-1
변경 전auto_send_config_recipient_section.php
 
<div class="ncua-card__body-block-section-wrap">
<section class="ncua-card__body-block-section">
<div class="ncua-card__body-title--xs">내용 입력</div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
<div id="sms-message-input-container-<?= $recipient ?>"
data-initial-value="<?= htmlspecialchars($autoSendConfig['SMS']['templateContents'] ?? '', ENT_QUOTES) ?>">
</div>
 
변경 후auto_send_config_recipient_section.php
 
<div class="ncua-card__body-block-section-wrap">
<section class="ncua-card__body-block-section">
<div class="ncua-card__body-title--xs tooltip-align" data-tooltip-seq="009">내용 입력</div>
<?php /* 제목은 본문이 LMS(90bytes 초과)일 때만 활성 — 토글·카운트는 JS(initMessageModules)가 담당 */ ?>
<div class="message-title-field">
<div class="ncua-input ncua-input--xs is-disabled">
<div class="ncua-input__content">
<div class="ncua-input__field ncua-input__field--xs">
<input name="recipients[<?= $recipient ?>][SMS][templateTitle]" type="text"
value="<?= htmlspecialchars($autoSendConfig['SMS']['templateTitle'] ?? '', ENT_QUOTES) ?>"
placeholder="제목을 입력해 주세요." data-sms-title-input disabled />
</div>
</div>
</div>
<span class="message-title-count">
<span data-sms-title-current>0</span>/40
</span>
</div>
<div id="sms-message-input-container-<?= $recipient ?>"
data-initial-value="<?= htmlspecialchars($autoSendConfig['SMS']['templateContents'] ?? '', ENT_QUOTES) ?>">
</div>
 
Admin/crm/auto_send_config.php+45-1
변경 전auto_send_config.php
if (tabInfo.channel === 'SMS') {
const input = messageInputInstances[recipient]?.SMS;
const smsContent = input ? normalizeNewlines(input.getValue()) : '';
this.setPreview(section, { content: smsContent || '메시지 내용을 입력하세요.' });
 
 
} else if (tabInfo.channel === 'KAKAO_ALRIM_TALK') {
const tabContent = section.querySelector('[data-tab="KAKAO_ALRIM_TALK"]');
if (!tabContent) return;
// SMS/LMS 포인트 힌트 업데이트
const byteLength = smsInput.calculateLength(normalized);
smsInput.setHint(byteLength > 90 ? 'LMS 건당 3포인트 차감' : 'SMS 건당 1포인트 차감');
 
 
// 빈 내용일 때 안내문구 숨김
if (normalized === '') {
const caution = document.querySelector(`#sms-chip-selector-container-${recipient} [data-caution-template]`);
});
messageInputInstances[recipient].SMS = smsInput;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
// 초기 힌트 상태 설정
const hintEl = smsContainer.querySelector('[data-message-hint]');
if (hintEl) hintEl.classList.add('destructive');
 
변경 후auto_send_config.php
if (tabInfo.channel === 'SMS') {
const input = messageInputInstances[recipient]?.SMS;
const smsContent = input ? normalizeNewlines(input.getValue()) : '';
const smsTitleInput = section.querySelector('input[data-sms-title-input]');
const smsTitle = smsTitleInput && !smsTitleInput.disabled ? smsTitleInput.value.replace(/\{[^}]*\}/g, '') : '';
this.setPreview(section, { title: smsTitle, content: smsContent || '메시지 내용을 입력하세요.' });
} else if (tabInfo.channel === 'KAKAO_ALRIM_TALK') {
const tabContent = section.querySelector('[data-tab="KAKAO_ALRIM_TALK"]');
if (!tabContent) return;
// SMS/LMS 포인트 힌트 업데이트
const byteLength = smsInput.calculateLength(normalized);
smsInput.setHint(byteLength > 90 ? 'LMS 건당 3포인트 차감' : 'SMS 건당 1포인트 차감');
// 본문 기준 SMS/LMS 판단 — LMS 일 때만 제목 입력 활성화
setSmsTitleEnabled(byteLength > 90);
// 빈 내용일 때 안내문구 숨김
if (normalized === '') {
const caution = document.querySelector(`#sms-chip-selector-container-${recipient} [data-caution-template]`);
});
messageInputInstances[recipient].SMS = smsInput;
 
// ===== SMS/LMS 제목 — 본문이 LMS(90bytes 초과)일 때만 활성 (모바일 발송과 동일 규칙) =====
const SMS_TITLE_MAX_BYTES = 40;
const sectionEl = smsContainer.closest('[data-target-type]');
const smsTitleInput = sectionEl.querySelector('input[data-sms-title-input]');
const smsTitleCounter = sectionEl.querySelector('[data-sms-title-current]');
 
// 미리보기 — LMS 상태에서 값이 있을 때만 노출, 제목은 변수 미지원이라 치환자는 공란으로 표기
const updateSmsTitlePreview = () => {
if (!smsTitleInput) return;
const value = !smsTitleInput.disabled ? smsTitleInput.value.replace(/\{[^}]*\}/g, '') : '';
PreviewFacade.setPreview(sectionEl, { title: value });
};
 
// 제목 입력 — 이모지 제거, 40bytes 초과분 자동 삭제 (byte 기준은 본문 MessageInput 과 동일)
const handleSmsTitleInput = () => {
if (!smsTitleInput) return;
let value = smsInput.removeEmoji(smsTitleInput.value).value;
value = smsInput.truncateBytes(value, SMS_TITLE_MAX_BYTES);
if (smsTitleInput.value !== value) {
smsTitleInput.value = value;
}
if (smsTitleCounter) smsTitleCounter.textContent = smsInput.getByteLength(value);
updateSmsTitlePreview();
};
 
// SMS 로 돌아오면 값은 유지한 채 비활성
const setSmsTitleEnabled = (enabled) => {
if (!smsTitleInput) return;
smsTitleInput.disabled = !enabled;
smsTitleInput.closest('.ncua-input').classList.toggle('is-disabled', !enabled);
updateSmsTitlePreview();
};
 
if (smsTitleInput) {
smsTitleInput.addEventListener('input', handleSmsTitleInput);
// 초기 상태: 저장된 본문 byte 기준 활성 여부 + 저장된 제목 카운트 반영
setSmsTitleEnabled(smsInput.calculateLength(smsInitialValue) > 90);
handleSmsTitleInput();
}
 
// 초기 힌트 상태 설정
const hintEl = smsContainer.querySelector('[data-message-hint]');
if (hintEl) hintEl.classList.add('destructive');
 
Admin/crm/crm_recipe_send.php+8
변경 전crm_recipe_send.php
el.querySelector('.ncua-input__destructive-icon-wrap')?.remove();
});
 
 
 
 
 
 
const fail = (message, subMessage) => {
NCDSAlert({ message, subMessage, iconType: 'error' });
$button.prop('disabled', false);
allKeys.includes(MobileMessageReplaceCode.normalizeReplaceKey(key)) ? `{${key}}` : match);
window.alternativeMessageInput.insertText(alternativeContents);
window.alternativePreview?.setContent(alternativeContents);
 
 
 
}
 
sendClickLog('send');
 
변경 후crm_recipe_send.php
el.querySelector('.ncua-input__destructive-icon-wrap')?.remove();
});
 
// 제목 40byte 초과(C4-2)는 미해소 에러라 재표기
if (typeof refreshOverSmsTitleState === 'function') {
refreshOverSmsTitleState();
}
 
const fail = (message, subMessage) => {
NCDSAlert({ message, subMessage, iconType: 'error' });
$button.prop('disabled', false);
allKeys.includes(MobileMessageReplaceCode.normalizeReplaceKey(key)) ? `{${key}}` : match);
window.alternativeMessageInput.insertText(alternativeContents);
window.alternativePreview?.setContent(alternativeContents);
if (typeof copyMainTitleToAlternativeSmsTitle === 'function') {
copyMainTitleToAlternativeSmsTitle();
}
}
 
sendClickLog('send');
 
Admin/crm/layer_preview_auto_send.php+6-1
변경 전layer_preview_auto_send.php
<?php if ($channelKey === 'SMS'): ?>
<!-- SMS 미리보기 -->
<section data-component="sms-message-preview" class="mobile-preview mobile-preview--sms">
<div class="ncua-prev"><?= nl2br(htmlspecialchars($templateContents)) ?></div>
 
 
 
 
 
</section>
<?php elseif ($channelKey === 'KAKAO_ALRIM_TALK'):
 
변경 후layer_preview_auto_send.php
<?php if ($channelKey === 'SMS'): ?>
<!-- SMS 미리보기 -->
<section data-component="sms-message-preview" class="mobile-preview mobile-preview--sms">
<div class="ncua-prev">
<?php if (($channelData['templateTitle'] ?? '') !== ''): ?>
<div class="sms-title-side-preview"><?= htmlspecialchars($channelData['templateTitle']) ?></div>
<?php endif; ?>
<?= nl2br(htmlspecialchars($templateContents)) ?>
</div>
</section>
<?php elseif ($channelKey === 'KAKAO_ALRIM_TALK'):
 
Admin/crm/layer_template_contents_sms.php+6-1
변경 전layer_template_contents_sms.php
<!-- SMS/LMS -->
<section class="mobile-preview mobile-preview--sms layer-preview-contents--sms">
<div class="ncua-prev"><?= nl2br(htmlspecialchars($smsData?->getContents() ?? '')) ?></div>
 
 
 
 
 
</section>
 
변경 후layer_template_contents_sms.php
<!-- SMS/LMS -->
<section class="mobile-preview mobile-preview--sms layer-preview-contents--sms">
<div class="ncua-prev">
<?php if (($smsData?->getMessageTitle() ?? '') !== ''): ?>
<div class="sms-title-side-preview"><?= htmlspecialchars($smsData->getMessageTitle()) ?></div>
<?php endif; ?>
<?= nl2br(htmlspecialchars($smsData?->getContents() ?? '')) ?>
</div>
</section>
 
Admin/crm/message_template_register.php+56-2
변경 전message_template_register.php
element.querySelectorAll('input, textarea, select').forEach(field => {
// 체크박스로 제어되는 textarea는 제외
if (field.id === 'channelAddTextarea' || field.id === 'extraInfoTextarea') return;
 
 
// 수정/복제 모드에서 발송수단, 제공사는 disabled 유지
if (field.name === 'sendMethod' || field.name === 'provider') return;
field.disabled = !isVisible;
});
};
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
/**
* SMS 바이트 수에 따라 SMS/LMS 포인트 차감 힌트 텍스트 변경
*/
} else {
smsMessageInput.setHint('');
}
 
 
};
 
/**
}
});
 
// 수정/복제 모드: initialValue 기준으로 SMS/LMS 힌트 초기화
updateSmsMessageHint(initialData.smsContent || '');
 
 
 
 
 
const smsVariableSelector = GodoUIModule.render({
type: 'ChipSelector',
target: '#sms-variable-selector-container',
document.querySelectorAll('#sms-message-input-container .ncua-input, #kakao-message-input-container .ncua-input, #myapp-message-input-container .ncua-input')
.forEach(el => el.setAttribute('data-show-hint-text', 'true'));
 
let templatePreview = null;
window.addEventListener('crmPreviewLoaded', function() {
const currentSendMethod = document.querySelector('input[name="sendMethod"]:checked')?.value || 'sms';
const sendTypeMap = { 'sms': 'SMS', 'kakao': 'ALIMTALK', 'myapp': 'MYAPP' };
}
templatePreview.setContent(displayValue);
}
 
 
 
};
 
// 변수 변환 체크박스 이벤트 리스너 (CrmPreview 체크박스 사용)
formData.append('templateCategory', document.querySelector('input[name="templateCategory"]:checked')?.value || '');
formData.append('templateTitle', document.querySelector('input[name="templateTitle"]')?.value || '');
formData.append('templateMessageContent', escapeLineBreaks(document.querySelector('textarea[name="smsMessageInput"]')?.value || ''));
 
 
 
submitForm();
} else if (sendMethod === 'kakao') {
 
변경 후message_template_register.php
element.querySelectorAll('input, textarea, select').forEach(field => {
// 체크박스로 제어되는 textarea는 제외
if (field.id === 'channelAddTextarea' || field.id === 'extraInfoTextarea') return;
// SMS 제목은 본문 LMS 여부로 활성 상태를 관리하므로 제외
if (field.name === 'templateMessageTitle') return;
// 수정/복제 모드에서 발송수단, 제공사는 disabled 유지
if (field.name === 'sendMethod' || field.name === 'provider') return;
field.disabled = !isVisible;
});
};
 
// crmPreviewLoaded 이후 생성 — 선언보다 먼저 실행되는 초기화 코드(제목 미리보기 등)에서 참조하므로 여기서 선언
let templatePreview = null;
 
/**
* SMS/LMS 메시지 제목 — 본문이 LMS(90bytes 초과)일 때만 활성 (모바일 발송과 동일 정책)
*/
const SMS_TITLE_MAX_BYTES = 40;
const getSmsTitleInput = () => document.querySelector('input[name="templateMessageTitle"]');
 
const isSmsTitleEnabled = () => {
const input = getSmsTitleInput();
return !!input && !input.disabled;
};
 
// 미리보기 — LMS 상태에서 값이 있을 때만 노출, 제목은 변수 미지원이라 치환자는 공란으로 표기
const updateSmsTitlePreview = () => {
if (!templatePreview) return;
const value = isSmsTitleEnabled() ? getSmsTitleInput().value.replace(/\{[^}]*\}/g, '') : '';
templatePreview.setTitle(value);
};
 
// SMS 로 돌아오면 값은 유지한 채 비활성
const setSmsTitleEnabled = (enabled) => {
const input = getSmsTitleInput();
if (!input) return;
input.disabled = !enabled;
input.closest('.ncua-input').classList.toggle('is-disabled', !enabled);
updateSmsTitlePreview();
};
 
// 제목 입력 — 이모지 제거, 40bytes 초과분 자동 삭제 (byte 기준은 본문 MessageInput 과 동일)
const handleSmsTitleInput = () => {
const input = getSmsTitleInput();
let value = smsMessageInput.removeEmoji(input.value).value;
value = smsMessageInput.truncateBytes(value, SMS_TITLE_MAX_BYTES);
if (input.value !== value) {
input.value = value;
}
document.querySelector('[data-sms-title-current]').textContent = smsMessageInput.getByteLength(value);
updateSmsTitlePreview();
};
 
/**
* SMS 바이트 수에 따라 SMS/LMS 포인트 차감 힌트 텍스트 변경
*/
} else {
smsMessageInput.setHint('');
}
// 본문 기준 SMS/LMS 판단 — LMS 일 때만 제목 입력 활성화
setSmsTitleEnabled(currentBytes > 90);
};
 
/**
}
});
 
// 수정/복제 모드: initialValue 기준으로 SMS/LMS 힌트 초기화 (제목 활성 상태 포함)
updateSmsMessageHint(initialData.smsContent || '');
 
// 제목 입력 이벤트 + 초기 카운터 반영 (수정/복제 모드: 저장된 제목)
getSmsTitleInput().addEventListener('input', handleSmsTitleInput);
handleSmsTitleInput();
 
const smsVariableSelector = GodoUIModule.render({
type: 'ChipSelector',
target: '#sms-variable-selector-container',
document.querySelectorAll('#sms-message-input-container .ncua-input, #kakao-message-input-container .ncua-input, #myapp-message-input-container .ncua-input')
.forEach(el => el.setAttribute('data-show-hint-text', 'true'));
 
 
window.addEventListener('crmPreviewLoaded', function() {
const currentSendMethod = document.querySelector('input[name="sendMethod"]:checked')?.value || 'sms';
const sendTypeMap = { 'sms': 'SMS', 'kakao': 'ALIMTALK', 'myapp': 'MYAPP' };
}
templatePreview.setContent(displayValue);
}
if (sendMethod === 'sms') {
updateSmsTitlePreview();
}
};
 
// 변수 변환 체크박스 이벤트 리스너 (CrmPreview 체크박스 사용)
formData.append('templateCategory', document.querySelector('input[name="templateCategory"]:checked')?.value || '');
formData.append('templateTitle', document.querySelector('input[name="templateTitle"]')?.value || '');
formData.append('templateMessageContent', escapeLineBreaks(document.querySelector('textarea[name="smsMessageInput"]')?.value || ''));
// 제목은 SMS/LMS 여부와 무관하게 입력값이 있으면 함께 저장 (모바일 발송 템플릿 저장과 동일)
formData.append('templateMessageTitle', getSmsTitleInput()?.value || '');
 
submitForm();
} else if (sendMethod === 'kakao') {
 
Admin/crm/message_template_register/template_contents_sms.php+15-1
변경 전template_contents_sms.php
<!-- 본문 입력: SMS 바이트형 -->
<div class="message-content sms-byte-mode" data-component="message-content">
<div class="ncua-card__body-title-wrap ncua-required">
<p class="ncua-card__body-title--xs">본문 입력</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
</div>
<div id="sms-message-input-container" class="message-input-container"></div>
</div>
<div class="ncua-accordion__content has-dot">
<ul>
<li>URL 삽입 시 [단축 URL] 앱을 이용하시면 짧고 간단하게 URL을 사용하실 수 있습니다. <a href="https://apps.godo.co.kr/apps/1519" target="_blank" class="ncua-link-underline">바로가기</a></li>
 
</ul>
</div>
</details>
 
변경 후template_contents_sms.php
<!-- 본문 입력: SMS 바이트형 -->
<div class="message-content sms-byte-mode" data-component="message-content">
<div class="ncua-card__body-title-wrap ncua-required">
<p class="ncua-card__body-title--xs tooltip-align" data-tooltip-seq="008">본문 입력</p>
</div>
<?php /* 제목은 본문이 LMS(90bytes 초과)일 때만 활성 — 토글은 JS(setSmsTitleEnabled)가 담당 */ ?>
<div class="message-title-field">
<div class="ncua-input ncua-input--xs is-disabled">
<div class="ncua-input__content">
<div class="ncua-input__field ncua-input__field--xs">
<input name="templateMessageTitle" type="text" value="<?= htmlspecialchars($response->getSms()?->getMessageTitle() ?? '') ?>" placeholder="제목을 입력해 주세요." disabled />
</div>
</div>
</div>
<span class="message-title-count">
<span data-sms-title-current>0</span>/40
</span>
</div>
<div id="sms-message-input-container" class="message-input-container"></div>
</div>
<div class="ncua-accordion__content has-dot">
<ul>
<li>URL 삽입 시 [단축 URL] 앱을 이용하시면 짧고 간단하게 URL을 사용하실 수 있습니다. <a href="https://apps.godo.co.kr/apps/1519" target="_blank" class="ncua-link-underline">바로가기</a></li>
<li>제목은 LMS 발송 시에만 적용되는 선택 입력 항목으로, 미입력 시에는 ‘제목 없음’으로 발송되며 SMS 발송 시에는 포함되지 않습니다.</li>
</ul>
</div>
</details>
 
Admin/crm/mobile_message_history/layer_member_sms_history_result.php+1-1
변경 전layer_member_sms_history_result.php
</div>
</td>
<td>
<div class="ncua-align-items-start"><button class="ncua-left-align mobile-history-list-message-content-btn js-show-message-contents" data-send-key="<?= $smsHistory->getSendKey() ?>" type="button"><?= $smsHistory->getContent() ?></button></div>
</td>
<td>
<div class="ncua-flex-column"><?= $smsHistory->getSenderName() ?> <span><?= $smsHistory->getFrom() ?></span></div>
 
변경 후layer_member_sms_history_result.php
</div>
</td>
<td>
<div class="ncua-align-items-start"><button class="ncua-left-align mobile-history-list-message-content-btn js-show-message-contents" data-send-key="<?= $smsHistory->getSendKey() ?>" type="button"><?php if (($smsHistory->getTitle() ?? '') !== ''): ?><span style="display: block;"><?= gd_htmlspecialchars($smsHistory->getTitle()) ?></span><?php endif; ?><?= $smsHistory->getContent() ?></button></div>
</td>
<td>
<div class="ncua-flex-column"><?= $smsHistory->getSenderName() ?> <span><?= $smsHistory->getFrom() ?></span></div>
 
Admin/crm/mobile_message_history/layer_sms_contents.php+6-1
변경 전layer_sms_contents.php
 
<div class="mobile-preview-wrap">
<section class="mobile-preview mobile-preview--sms">
<div class="ncua-prev"><?= nl2br(gd_htmlspecialchars_stripslashes($content)) ?></div>
 
 
 
 
 
</section>
</div>
 
변경 후layer_sms_contents.php
 
<div class="mobile-preview-wrap">
<section class="mobile-preview mobile-preview--sms">
<div class="ncua-prev">
<?php if (($title ?? '') !== ''): ?>
<div class="sms-title-side-preview"><?= gd_htmlspecialchars_stripslashes($title) ?></div>
<?php endif; ?>
<?= nl2br(gd_htmlspecialchars_stripslashes($content)) ?>
</div>
</section>
</div>
 
Admin/crm/mobile_message_history/layer_sms_history_result.php+1-1
변경 전layer_sms_history_result.php
</div>
</td>
<td>
<div class="ncua-align-items-start"><button class="ncua-left-align mobile-history-list-message-content-btn js-show-message-contents" data-send-key="<?= $smsHistory->getSendKey() ?>" type="button"><?= $smsHistory->getContent() ?></button></div>
</td>
<td>
<div class="ncua-flex-column"><?= $smsHistory->getSenderName() ?> <span><?= $smsHistory->getFrom() ?></span></div>
 
변경 후layer_sms_history_result.php
</div>
</td>
<td>
<div class="ncua-align-items-start"><button class="ncua-left-align mobile-history-list-message-content-btn js-show-message-contents" data-send-key="<?= $smsHistory->getSendKey() ?>" type="button"><?php if (($smsHistory->getTitle() ?? '') !== ''): ?><span style="display: block;"><?= gd_htmlspecialchars($smsHistory->getTitle()) ?></span><?php endif; ?><?= $smsHistory->getContent() ?></button></div>
</td>
<td>
<div class="ncua-flex-column"><?= $smsHistory->getSenderName() ?> <span><?= $smsHistory->getFrom() ?></span></div>
 
Admin/crm/mobile_send/layer_kakao_alimtalk_content_setting.php+75-2
변경 전layer_kakao_alimtalk_content_setting.php
return !!input && !input.disabled;
}
 
// 발송 요청용 제목 — LMS 활성 상태에서 값이 있을 때만. 미입력 시 null('제목없음' 처리는 발송 시스템 담당)
function getAlternativeSmsTitleForSend() {
return resolveTitleForSend(getAlternativeSmsTitleInput(), isAlternativeSmsTitleEnabled());
}
 
<div class="message-content send-method-component" data-target="ALTERNATIVE">
<div class="ncua-card__body-title-wrap">
<p class="ncua-card__body-title--xs">내용 입력</p>
<button type="button" class="ncua-btn ncua-btn--xs ncua-btn--text-gray has-underline refresh-btn load-main-contents">
메시지 최신 상태 반영
</button>
</div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
<div id="messageContentAlternativeContainer"></div>
</div>
<div id="replaceCodeAlternativeContainer" class="send-method-component" data-target="ALTERNATIVE"></div>
<ul>
<li>SMS 작성 시 90byte를 초과하면 LMS로 자동 전환되어 발송됩니다.</li>
<li>변수에 실제 데이터가 적용된 최종 메시지가 90byte를 초과하는 경우에도 LMS로 전환될 수 있습니다.</li>
 
</ul>
</div>
</details>
alternativeMessageInput.setValue('');
alternativeMessageInput.insertText(convertedMessage);
alternativePreview.setContent(resolveReplaceCode(convertedMessage, false));
 
NCDSToast({message: '메시지가 최신 내용으로 업데이트 됐습니다.', color: 'success'});
});
 
} else {
window.alternativeMessageInput.setHint(window.alternativeMessageInput.calculateLength(input) > 90 ? 'LMS 건당 3포인트 차감' : 'SMS 건당 1포인트 차감');
}
 
 
}
});
 
setDefaultPreview(['ALIMTALK_TEXT', 'ALTERNATIVE_TEXT']);
}
</script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
변경 후layer_kakao_alimtalk_content_setting.php
return !!input && !input.disabled;
}
 
// 발송 요청용 제목 — LMS(제목 활성)일 때만 전송, 미입력·치환자만 입력 시 '[제목없음]' 으로 발송
function getAlternativeSmsTitleForSend() {
return resolveTitleForSend(getAlternativeSmsTitleInput(), isAlternativeSmsTitleEnabled());
}
 
<div class="message-content send-method-component" data-target="ALTERNATIVE">
<div class="ncua-card__body-title-wrap">
<p class="ncua-card__body-title--xs tooltip-align" data-tooltip-seq="010">내용 입력</p>
<button type="button" class="ncua-btn ncua-btn--xs ncua-btn--text-gray has-underline refresh-btn load-main-contents">
메시지 최신 상태 반영
</button>
</div>
<div class="message-title-field">
<div class="ncua-input ncua-input--xs ncua-input--full-width-with-count is-disabled">
<div class="ncua-input__content-wrap">
<div class="ncua-input__content">
<div class="ncua-input__field ncua-input__field--xs">
<input name="alternativeSmsTitle" type="text" value="" placeholder="제목을 입력해 주세요." disabled />
</div>
</div>
<div class="ncua-input__field-text-count">
<output class="ncua-input__field-text-count-current" data-alternative-sms-title-current>0</output><span>/40</span>
</div>
</div>
</div>
</div>
<div id="messageContentAlternativeContainer"></div>
</div>
<div id="replaceCodeAlternativeContainer" class="send-method-component" data-target="ALTERNATIVE"></div>
<ul>
<li>SMS 작성 시 90byte를 초과하면 LMS로 자동 전환되어 발송됩니다.</li>
<li>변수에 실제 데이터가 적용된 최종 메시지가 90byte를 초과하는 경우에도 LMS로 전환될 수 있습니다.</li>
<li>본문 내용이 LMS인 경우에만 제목 입력이 가능하며, 제목 영역에는 직접 (광고) 문구를 입력하지 않도록 하고 광고 삽입이 필요한 경우 광고성 문구 추가 기능을 사용해야 합니다.</li>
</ul>
</div>
</details>
alternativeMessageInput.setValue('');
alternativeMessageInput.insertText(convertedMessage);
alternativePreview.setContent(resolveReplaceCode(convertedMessage, false));
copyMainTitleToAlternativeSmsTitle();
NCDSToast({message: '메시지가 최신 내용으로 업데이트 됐습니다.', color: 'success'});
});
 
} else {
window.alternativeMessageInput.setHint(window.alternativeMessageInput.calculateLength(input) > 90 ? 'LMS 건당 3포인트 차감' : 'SMS 건당 1포인트 차감');
}
// 대체 본문 기준 SMS/LMS 판단 — LMS 일 때만 제목 입력 활성화
setAlternativeSmsTitleEnabled(window.alternativeMessageInput.calculateLength(input) > 90);
}
});
 
setDefaultPreview(['ALIMTALK_TEXT', 'ALTERNATIVE_TEXT']);
}
</script>
 
<script type="text/javascript">
// ===== SMS/LMS 대체 메시지 제목 (규칙·디자인은 SMS/친구톡 대체와 동일) =====
function getAlternativeSmsTitleInput() {
return document.querySelector('input[name="alternativeSmsTitle"]');
}
 
// 제목 입력 — 이모지 제거 후 40bytes 규칙 적용 (applySmsTitleByteRule)
function handleAlternativeSmsTitleInput() {
const input = getAlternativeSmsTitleInput();
const value = applySmsTitleByteRule(input, window.alternativeMessageInput);
document.querySelector('[data-alternative-sms-title-current]').textContent = window.alternativeMessageInput.getByteLength(value);
updateAlternativeSmsTitlePreview();
}
 
// 대체 본문이 LMS(90bytes 초과)일 때만 제목 활성 — SMS 로 돌아오면 값은 유지한 채 비활성
function setAlternativeSmsTitleEnabled(enabled) {
const input = getAlternativeSmsTitleInput();
if (!input) return;
// 대체 미지원(캐러셀·와이드아이템 등)이면 본문 길이와 무관하게 비활성 — payload 에도 실리지 않는다
if (typeof enableAlternative === 'function' && !enableAlternative(getActivatedSendMethod())) {
enabled = false;
}
input.disabled = !enabled;
input.closest('.ncua-input').classList.toggle('is-disabled', !enabled);
updateAlternativeSmsTitlePreview();
}
 
function isAlternativeSmsTitleEnabled() {
const input = getAlternativeSmsTitleInput();
return !!input && !input.disabled;
}
 
// 발송 요청용 제목 — LMS 활성 상태에서 값이 있을 때만. 미입력 시 null('제목없음' 처리는 발송 시스템 담당)
function getAlternativeSmsTitleForSend() {
return resolveTitleForSend(getAlternativeSmsTitleInput(), isAlternativeSmsTitleEnabled());
}
 
// 미리보기 — LMS 상태에서 값이 있을 때만 노출, 치환자는 공란으로 표기
function updateAlternativeSmsTitlePreview() {
window.alternativePreview.setTitle(isAlternativeSmsTitleEnabled() ? stripTitleReplaceCodes(getAlternativeSmsTitleInput().value) : '');
}
 
// 메인 제목 → 대체 제목 매핑 — 알림톡은 강조표기형(templateTitle)만 매핑 대상
function copyMainTitleToAlternativeSmsTitle() {
const input = getAlternativeSmsTitleInput();
if (!input || getActivatedSendMethod() !== 'ALIMTALK') return;
input.value = getSelectedKakaoAlimtalkTemplate()?.templateTitle ?? '';
// 본문 카피 직후엔 입력 이벤트가 없어 활성 상태가 갱신되지 않는다 — 여기서 다시 잡아야 payload 에 실린다
setAlternativeSmsTitleEnabled(window.alternativeMessageInput.calculateLength(window.alternativeMessageInput.getValue() ?? '') > 90);
handleAlternativeSmsTitleInput();
}
 
getAlternativeSmsTitleInput().addEventListener('input', handleAlternativeSmsTitleInput);
</script>
 
Admin/crm/mobile_send/layer_kakao_friendtalk_content_setting.php+73-2
변경 전layer_kakao_friendtalk_content_setting.php
return !!input && !input.disabled;
}
 
// 발송 요청용 제목 — LMS 활성 상태에서 값이 있을 때만. 미입력 시 null('제목없음' 처리는 발송 시스템 담당)
function getAlternativeSmsTitleForSend() {
return resolveTitleForSend(getAlternativeSmsTitleInput(), isAlternativeSmsTitleEnabled());
}
 
<div class="message-content send-method-component" data-target="ALTERNATIVE">
<div class="ncua-card__body-title-wrap">
<p class="ncua-card__body-title--xs">내용 입력</p>
<button type="button" class="ncua-btn ncua-btn--xs ncua-btn--text-gray has-underline refresh-btn load-main-contents">
메시지 최신 상태 반영
</button>
</div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
<div id="messageContentAlternativeContainer"></div>
</div>
<div id="replaceCodeAlternativeContainer" class="js-replace-code send-method-component" data-target="ALTERNATIVE"></div>
<ul>
<li>SMS 작성 시 90byte를 초과하면 LMS로 자동 전환되어 발송됩니다.</li>
<li>변수에 실제 데이터가 적용된 최종 메시지가 90byte를 초과하는 경우에도 LMS로 전환될 수 있습니다.</li>
 
</ul>
</div>
</details>
updateCampaignTypeComponent(radio.value);
updateDefaultPreview(radio.value);
applyFriendtalkRecipeDefaults(radio.value);
 
 
 
 
});
});
 
}
});
 
 
 
kakaoFriendtalkTabSection.querySelector('input[name="friendtalkCampaignHeader"]').addEventListener('input', function(e) {
window.preview.setTitle(resolveReplaceCode(e.target.value));
if (e.target.value === '') {
 
const initialTextContent = <?= json_encode($initialTextContent ?? '', JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP) ?>;
const initialAlternativeMessage = <?= json_encode($initialAlternativeMessage ?? '', JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP) ?>;
 
 
if (isRecipeContext) {
const wideItemPointHint = kakaoFriendtalkTabSection.querySelector('.js-wide-item-point-hint');
} else {
window.alternativeMessageInput.setHint(window.alternativeMessageInput.calculateLength(input) > 90 ? 'LMS 건당 3포인트 차감' : 'SMS 건당 1포인트 차감');
}
 
 
}
});
 
MobileMessageReplaceCode.updateExpireCodeGuide('#replaceCodeAlternativeContainer', initialAlternativeMessage);
}
 
 
 
 
 
 
 
 
applyFriendtalkRecipeDefaults(getCampaignMessageType());
}
 
updateItemListPreview();
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
// 친구톡 아이템 이미지 업로드 초기화
function initItemImageFileInput(containerId, itemKey, isFirst = false) {
const container = document.getElementById(containerId);
 
변경 후layer_kakao_friendtalk_content_setting.php
return !!input && !input.disabled;
}
 
// 발송 요청용 제목 — LMS(제목 활성)일 때만 전송, 미입력·치환자만 입력 시 '[제목없음]' 으로 발송
function getAlternativeSmsTitleForSend() {
return resolveTitleForSend(getAlternativeSmsTitleInput(), isAlternativeSmsTitleEnabled());
}
 
<div class="message-content send-method-component" data-target="ALTERNATIVE">
<div class="ncua-card__body-title-wrap">
<p class="ncua-card__body-title--xs tooltip-align" data-tooltip-seq="010">내용 입력</p>
<button type="button" class="ncua-btn ncua-btn--xs ncua-btn--text-gray has-underline refresh-btn load-main-contents">
메시지 최신 상태 반영
</button>
</div>
<div class="message-title-field">
<div class="ncua-input ncua-input--xs ncua-input--full-width-with-count is-disabled">
<div class="ncua-input__content-wrap">
<div class="ncua-input__content">
<div class="ncua-input__field ncua-input__field--xs">
<input name="alternativeSmsTitle" type="text" value="" placeholder="제목을 입력해 주세요." disabled />
</div>
</div>
<div class="ncua-input__field-text-count">
<output class="ncua-input__field-text-count-current" data-alternative-sms-title-current>0</output><span>/40</span>
</div>
</div>
</div>
</div>
<div id="messageContentAlternativeContainer"></div>
</div>
<div id="replaceCodeAlternativeContainer" class="js-replace-code send-method-component" data-target="ALTERNATIVE"></div>
<ul>
<li>SMS 작성 시 90byte를 초과하면 LMS로 자동 전환되어 발송됩니다.</li>
<li>변수에 실제 데이터가 적용된 최종 메시지가 90byte를 초과하는 경우에도 LMS로 전환될 수 있습니다.</li>
<li>본문 내용이 LMS인 경우에만 제목 입력이 가능하며, 제목 영역에는 직접 (광고) 문구를 입력하지 않도록 하고 광고 삽입이 필요한 경우 광고성 문구 추가 기능을 사용해야 합니다.</li>
</ul>
</div>
</details>
updateCampaignTypeComponent(radio.value);
updateDefaultPreview(radio.value);
applyFriendtalkRecipeDefaults(radio.value);
// 유형에 따라 대체 지원 여부가 바뀌므로 제목 활성 상태를 다시 평가 (초기 change 는 대체 입력 생성 전이라 건너뜀)
if (window.alternativeMessageInput) {
setAlternativeSmsTitleEnabled(window.alternativeMessageInput.calculateLength(window.alternativeMessageInput.getValue() ?? '') > 90);
}
});
});
 
}
});
 
getAlternativeSmsTitleInput().addEventListener('input', handleAlternativeSmsTitleInput);
 
kakaoFriendtalkTabSection.querySelector('input[name="friendtalkCampaignHeader"]').addEventListener('input', function(e) {
window.preview.setTitle(resolveReplaceCode(e.target.value));
if (e.target.value === '') {
 
const initialTextContent = <?= json_encode($initialTextContent ?? '', JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP) ?>;
const initialAlternativeMessage = <?= json_encode($initialAlternativeMessage ?? '', JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP) ?>;
const initialAlternativeTitle = <?= json_encode($initialAlternativeTitle ?? '', JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP) ?>;
 
if (isRecipeContext) {
const wideItemPointHint = kakaoFriendtalkTabSection.querySelector('.js-wide-item-point-hint');
} else {
window.alternativeMessageInput.setHint(window.alternativeMessageInput.calculateLength(input) > 90 ? 'LMS 건당 3포인트 차감' : 'SMS 건당 1포인트 차감');
}
// 대체 본문 기준 SMS/LMS 판단 — LMS 일 때만 제목 입력 활성화
setAlternativeSmsTitleEnabled(window.alternativeMessageInput.calculateLength(input) > 90);
}
});
 
MobileMessageReplaceCode.updateExpireCodeGuide('#replaceCodeAlternativeContainer', initialAlternativeMessage);
}
 
// 레시피 기본 대체 제목 prefill — 대체 본문이 LMS면 활성 노출, SMS면 값만 유지한 채 비활성 (메인 SMS 레이어와 동일)
if (initialAlternativeTitle !== '') {
getAlternativeSmsTitleInput().value = initialAlternativeTitle;
setAlternativeSmsTitleEnabled(window.alternativeMessageInput.calculateLength(initialAlternativeMessage) > 90);
handleAlternativeSmsTitleInput();
}
 
applyFriendtalkRecipeDefaults(getCampaignMessageType());
}
 
updateItemListPreview();
}
 
// ===== SMS/LMS 대체 메시지 제목 (규칙은 SMS 레이어의 제목과 동일) =====
function getAlternativeSmsTitleInput() {
return kakaoFriendtalkTabSection.querySelector('input[name="alternativeSmsTitle"]');
}
 
// 제목 입력 — 이모지 제거 후 40bytes 규칙 적용 (applySmsTitleByteRule)
function handleAlternativeSmsTitleInput() {
const input = getAlternativeSmsTitleInput();
const value = applySmsTitleByteRule(input, window.alternativeMessageInput);
kakaoFriendtalkTabSection.querySelector('[data-alternative-sms-title-current]').textContent = window.alternativeMessageInput.getByteLength(value);
updateAlternativeSmsTitlePreview();
}
 
// 대체 본문이 LMS(90bytes 초과)일 때만 제목 활성 — SMS 로 돌아오면 값은 유지한 채 비활성
function setAlternativeSmsTitleEnabled(enabled) {
const input = getAlternativeSmsTitleInput();
// 대체 미지원(캐러셀·와이드아이템 등)이면 본문 길이와 무관하게 비활성 — payload 에도 실리지 않는다
if (typeof enableAlternative === 'function' && !enableAlternative(getActivatedSendMethod())) {
enabled = false;
}
input.disabled = !enabled;
input.closest('.ncua-input').classList.toggle('is-disabled', !enabled);
updateAlternativeSmsTitlePreview();
}
 
function isAlternativeSmsTitleEnabled() {
const input = getAlternativeSmsTitleInput();
return !!input && !input.disabled;
}
 
// 발송 요청용 제목 — LMS 활성 상태에서 값이 있을 때만. 미입력 시 null('제목없음' 처리는 발송 시스템 담당)
function getAlternativeSmsTitleForSend() {
return resolveTitleForSend(getAlternativeSmsTitleInput(), isAlternativeSmsTitleEnabled());
}
 
// 미리보기 — LMS 상태에서 값이 있을 때만 노출, 치환자는 공란으로 표기
function updateAlternativeSmsTitlePreview() {
window.alternativePreview.setTitle(isAlternativeSmsTitleEnabled() ? stripTitleReplaceCodes(getAlternativeSmsTitleInput().value) : '');
}
 
// 친구톡 아이템 이미지 업로드 초기화
function initItemImageFileInput(containerId, itemKey, isFirst = false) {
const container = document.getElementById(containerId);
 
Admin/crm/mobile_send/layer_mobile_send_save_sms_template.php+3-1
변경 전layer_mobile_send_save_sms_template.php
 
<div class="modal-dialog__content layer-save-as-template">
<input type="hidden" id="templateContents" value="<?= htmlspecialchars($contents, ENT_QUOTES) ?>" />
 
<div class="ncua-table ncua-table--vertical">
<table>
<tbody>
mode: 'save',
category: category.value,
subject: subject.value.trim(),
contents: contents.value
 
}, function(response) {
if (response.success) {
NCDSToast({ message: '저장되었습니다.', color: 'success' });
 
변경 후layer_mobile_send_save_sms_template.php
 
<div class="modal-dialog__content layer-save-as-template">
<input type="hidden" id="templateContents" value="<?= htmlspecialchars($contents, ENT_QUOTES) ?>" />
<input type="hidden" id="templateMessageTitle" value="<?= htmlspecialchars($messageTitle ?? '', ENT_QUOTES) ?>" />
<div class="ncua-table ncua-table--vertical">
<table>
<tbody>
mode: 'save',
category: category.value,
subject: subject.value.trim(),
contents: contents.value,
messageTitle: document.querySelector('#templateMessageTitle').value
}, function(response) {
if (response.success) {
NCDSToast({ message: '저장되었습니다.', color: 'success' });
 
Admin/crm/mobile_send/layer_mobile_send_sms_template.php+3-3
변경 전layer_mobile_send_sms_template.php
}
}
 
function applyTemplateSmsContents(contents) {
const convertedContents = contents
.replace(/\\r\\n/g, '\n')
.replace(/\\n/g, '\n');
 
setTemplate(convertedContents);
}
 
document.getElementById('btnSearch').addEventListener('click', function() {
return;
}
 
applyTemplateSmsContents(selected.dataset.contents);
layer_close();
});
 
 
변경 후layer_mobile_send_sms_template.php
}
}
 
function applyTemplateSmsContents(contents, messageTitle = '') {
const convertedContents = contents
.replace(/\\r\\n/g, '\n')
.replace(/\\n/g, '\n');
 
setTemplate(convertedContents, messageTitle);
}
 
document.getElementById('btnSearch').addEventListener('click', function() {
return;
}
 
applyTemplateSmsContents(selected.dataset.contents, selected.dataset.messageTitle ?? '');
layer_close();
});
 
 
Admin/crm/mobile_send/layer_mobile_send_sms_template_result.php+7-2
변경 전layer_mobile_send_sms_template_result.php
<div class="ncua-align-center">
<label class="ncua-radio-field ncua-radio-field--xs">
<span class="ncua-radio-input ncua-radio-input--xs ncua-radio-field__input">
<input type="radio" name="template" value="<?= $template['sno'] ?>" data-contents="<?= htmlspecialchars($template['contents'], ENT_QUOTES) ?>"/>
</span>
</label>
</div>
</td>
<td><div><?= nl2br(htmlspecialchars(str_replace(['\r\n', '\n'], "\n", $template['subject'] ?? ''))) ?></div></td>
<td><div><?= nl2br(htmlspecialchars(str_replace(['\r\n', '\n'], "\n", $template['contents'] ?? ''))) ?></div></td>
 
 
 
 
 
</tr>
<?php endforeach; ?>
<?php endif; ?>
 
변경 후layer_mobile_send_sms_template_result.php
<div class="ncua-align-center">
<label class="ncua-radio-field ncua-radio-field--xs">
<span class="ncua-radio-input ncua-radio-input--xs ncua-radio-field__input">
<input type="radio" name="template" value="<?= $template['sno'] ?>" data-contents="<?= htmlspecialchars($template['contents'], ENT_QUOTES) ?>" data-message-title="<?= htmlspecialchars($template['messageTitle'] ?? '', ENT_QUOTES) ?>"/>
</span>
</label>
</div>
</td>
<td><div><?= nl2br(htmlspecialchars(str_replace(['\r\n', '\n'], "\n", $template['subject'] ?? ''))) ?></div></td>
<td>
<?php /* td > div 가 flex 컨테이너라 제목·내용을 하나의 블록으로 감싸야 분리되지 않음 */ ?>
<div>
<div><?php if (($template['messageTitle'] ?? '') !== ''): ?><strong style="display: block;"><?= htmlspecialchars($template['messageTitle']) ?></strong><?php endif; ?><?= nl2br(htmlspecialchars(str_replace(['\r\n', '\n'], "\n", $template['contents'] ?? ''))) ?></div>
</div>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
 
Admin/crm/mobile_send/layer_myapp_push_content_setting.php+86-2
변경 전layer_myapp_push_content_setting.php
return !!input && !input.disabled;
}
 
// 발송 요청용 제목 — LMS 활성 상태에서 값이 있을 때만. 미입력 시 null('제목없음' 처리는 발송 시스템 담당)
function getAlternativeSmsTitleForSend() {
return resolveTitleForSend(getAlternativeSmsTitleInput(), isAlternativeSmsTitleEnabled());
}
 
<div class="message-content send-method-component" data-target="ALTERNATIVE">
<div class="ncua-card__body-title-wrap">
<p class="ncua-card__body-title--xs">내용 입력</p>
<button type="button" class="ncua-btn ncua-btn--xs ncua-btn--text-gray has-underline refresh-btn load-main-contents">
메시지 최신 상태 반영
</button>
</div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
<div id="messageContentAlternativeContainer"></div>
</div>
<div id="replaceCodeAlternativeContainer" class="send-method-component" data-target="ALTERNATIVE"></div>
<ul>
<li>SMS 작성 시 90byte를 초과하면 LMS로 자동 전환되어 발송됩니다.</li>
<li>변수에 실제 데이터가 적용된 최종 메시지가 90byte를 초과하는 경우에도 LMS로 전환될 수 있습니다.</li>
 
</ul>
</div>
</details>
alternativeMessageInput.setValue('');
alternativeMessageInput.insertText(convertedMessage);
alternativePreview.setContent(resolveReplaceCode(convertedMessage, false));
 
 
 
NCDSToast({message: '메시지가 최신 내용으로 업데이트 됐습니다.', color: 'success'});
});
 
} else {
window.alternativeMessageInput.setHint(window.alternativeMessageInput.calculateLength(input) > 90 ? 'LMS 건당 3포인트 차감' : 'SMS 건당 1포인트 차감');
}
 
 
}
});
 
window.alternativePreview.setContent(resolveReplaceCode(initialAlternativeMessage, false));
MobileMessageReplaceCode.updateExpireCodeGuide('#replaceCodeAlternativeContainer', initialAlternativeMessage);
}
 
syncMyappTitlePreview(initialMyappTitle);
syncMyappMessagePreview(initialMyappMessage);
}
});
});
</script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
변경 후layer_myapp_push_content_setting.php
return !!input && !input.disabled;
}
 
// 발송 요청용 제목 — LMS(제목 활성)일 때만 전송, 미입력·치환자만 입력 시 '[제목없음]' 으로 발송
function getAlternativeSmsTitleForSend() {
return resolveTitleForSend(getAlternativeSmsTitleInput(), isAlternativeSmsTitleEnabled());
}
 
<div class="message-content send-method-component" data-target="ALTERNATIVE">
<div class="ncua-card__body-title-wrap">
<p class="ncua-card__body-title--xs tooltip-align" data-tooltip-seq="010">내용 입력</p>
<button type="button" class="ncua-btn ncua-btn--xs ncua-btn--text-gray has-underline refresh-btn load-main-contents">
메시지 최신 상태 반영
</button>
</div>
<div class="message-title-field">
<div class="ncua-input ncua-input--xs ncua-input--full-width-with-count is-disabled">
<div class="ncua-input__content-wrap">
<div class="ncua-input__content">
<div class="ncua-input__field ncua-input__field--xs">
<input name="alternativeSmsTitle" type="text" value="" placeholder="제목을 입력해 주세요." disabled />
</div>
</div>
<div class="ncua-input__field-text-count">
<output class="ncua-input__field-text-count-current" data-alternative-sms-title-current>0</output><span>/40</span>
</div>
</div>
</div>
</div>
<div id="messageContentAlternativeContainer"></div>
</div>
<div id="replaceCodeAlternativeContainer" class="send-method-component" data-target="ALTERNATIVE"></div>
<ul>
<li>SMS 작성 시 90byte를 초과하면 LMS로 자동 전환되어 발송됩니다.</li>
<li>변수에 실제 데이터가 적용된 최종 메시지가 90byte를 초과하는 경우에도 LMS로 전환될 수 있습니다.</li>
<li>본문 내용이 LMS인 경우에만 제목 입력이 가능하며, 제목 영역에는 직접 (광고) 문구를 입력하지 않도록 하고 광고 삽입이 필요한 경우 광고성 문구 추가 기능을 사용해야 합니다.</li>
</ul>
</div>
</details>
alternativeMessageInput.setValue('');
alternativeMessageInput.insertText(convertedMessage);
alternativePreview.setContent(resolveReplaceCode(convertedMessage, false));
 
copyMainTitleToAlternativeSmsTitle();
 
NCDSToast({message: '메시지가 최신 내용으로 업데이트 됐습니다.', color: 'success'});
});
 
} else {
window.alternativeMessageInput.setHint(window.alternativeMessageInput.calculateLength(input) > 90 ? 'LMS 건당 3포인트 차감' : 'SMS 건당 1포인트 차감');
}
// 대체 본문 기준 SMS/LMS 판단 — LMS 일 때만 제목 입력 활성화
setAlternativeSmsTitleEnabled(window.alternativeMessageInput.calculateLength(input) > 90);
}
});
 
window.alternativePreview.setContent(resolveReplaceCode(initialAlternativeMessage, false));
MobileMessageReplaceCode.updateExpireCodeGuide('#replaceCodeAlternativeContainer', initialAlternativeMessage);
}
 
syncMyappTitlePreview(initialMyappTitle);
syncMyappMessagePreview(initialMyappMessage);
}
});
});
</script>
 
<script type="text/javascript">
// ===== SMS/LMS 대체 메시지 제목 (규칙·디자인은 SMS/친구톡 대체와 동일) =====
function getAlternativeSmsTitleInput() {
return document.querySelector('input[name="alternativeSmsTitle"]');
}
 
// 제목 입력 — 이모지 제거 후 40bytes 규칙 적용 (applySmsTitleByteRule)
function handleAlternativeSmsTitleInput() {
const input = getAlternativeSmsTitleInput();
const value = applySmsTitleByteRule(input, window.alternativeMessageInput);
document.querySelector('[data-alternative-sms-title-current]').textContent = window.alternativeMessageInput.getByteLength(value);
updateAlternativeSmsTitlePreview();
}
 
// 대체 본문이 LMS(90bytes 초과)일 때만 제목 활성 — SMS 로 돌아오면 값은 유지한 채 비활성
function setAlternativeSmsTitleEnabled(enabled) {
const input = getAlternativeSmsTitleInput();
if (!input) return;
// 대체 미지원(캐러셀·와이드아이템 등)이면 본문 길이와 무관하게 비활성 — payload 에도 실리지 않는다
if (typeof enableAlternative === 'function' && !enableAlternative(getActivatedSendMethod())) {
enabled = false;
}
input.disabled = !enabled;
input.closest('.ncua-input').classList.toggle('is-disabled', !enabled);
updateAlternativeSmsTitlePreview();
}
 
function isAlternativeSmsTitleEnabled() {
const input = getAlternativeSmsTitleInput();
return !!input && !input.disabled;
}
 
// 발송 요청용 제목 — LMS 활성 상태에서 값이 있을 때만. 미입력 시 null('제목없음' 처리는 발송 시스템 담당)
function getAlternativeSmsTitleForSend() {
return resolveTitleForSend(getAlternativeSmsTitleInput(), isAlternativeSmsTitleEnabled());
}
 
// 미리보기 — LMS 상태에서 값이 있을 때만 노출, 치환자는 공란으로 표기
function updateAlternativeSmsTitlePreview() {
window.alternativePreview.setTitle(isAlternativeSmsTitleEnabled() ? stripTitleReplaceCodes(getAlternativeSmsTitleInput().value) : '');
}
 
function copyMainTitleToAlternativeSmsTitle() {
const input = getAlternativeSmsTitleInput();
if (!input || getActivatedSendMethod() !== 'MYAPP') return;
input.value = document.querySelector('input[name="myappTitle"]')?.value ?? '';
handleAlternativeSmsTitleInput();
}
 
getAlternativeSmsTitleInput().addEventListener('input', handleAlternativeSmsTitleInput);
 
// 레시피 기본 대체 제목 prefill — 대체 본문이 LMS면 활성 노출, SMS면 값만 유지한 채 비활성.
// 제목 접근자가 이 블록에 선언돼 있어(앞 블록의 초기화 시점엔 미정의) 여기서 수행한다.
(function () {
const initialAlternativeTitle = <?= json_encode($initialAlternativeTitle ?? '', JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP) ?>;
if (initialAlternativeTitle === '') return;
 
getAlternativeSmsTitleInput().value = initialAlternativeTitle;
setAlternativeSmsTitleEnabled(window.alternativeMessageInput.calculateLength(window.alternativeMessageInput.getValue() ?? '') > 90);
handleAlternativeSmsTitleInput();
})();
</script>
 
Admin/crm/mobile_send/layer_send_method_setting.php+130-2
변경 전layer_send_method_setting.php
previewContainer.setContent(resolveReplaceCode(content));
dispatchMessageContentInput(messageContainer);
 
// 본문 갱신으로 SMS/LMS 판정이 끝난 뒤, LMS(제목 활성)면 제목에도 (광고) 삽입 — 제목 40bytes 에 카운트됨
const titleInput = resolveAdTitleInput(messageContainer);
if (titleInput && !titleInput.disabled && !titleInput.value.startsWith('(광고)')) {
titleInput.value = '(광고)' + titleInput.value;
titleInput.dataset.titleAdInsert = '1'; // 시스템 삽입 표시 — 절삭 대신 에러 처리 (C4-2)
titleInput.dispatchEvent(new Event('input'));
return /^https?:\/\//.test(string);
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
function addAdText(messageContainer, previewContainer) {
 
const content = '(광고)\n' + messageContainer.getValue() + '\n' + smsRejectText;
messageContainer.setValue(content);
previewContainer.setContent(resolveReplaceCode(content));
 
 
 
 
 
 
 
 
 
 
 
 
 
}
 
function removeAdText(messageContainer, previewContainer) {
 
 
 
 
 
 
let content = messageContainer.getValue();
content = content.replace(/^\(광고\)\n?/, '');
const escapedRejectText = smsRejectText.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
messageContainer.setValue(content);
previewContainer.setContent(resolveReplaceCode(content));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
}
 
/**
 
변경 후layer_send_method_setting.php
previewContainer.setContent(resolveReplaceCode(content));
dispatchMessageContentInput(messageContainer);
 
// 제목에도 (광고) 삽입 — 제목 영역이 비활성(SMS)이어도 삽입한다(레거시 동작과 동일). 제목 40bytes 에 카운트됨
const titleInput = resolveAdTitleInput(messageContainer);
if (titleInput && !titleInput.value.startsWith('(광고)')) {
titleInput.value = '(광고)' + titleInput.value;
titleInput.dataset.titleAdInsert = '1'; // 시스템 삽입 표시 — 절삭 대신 에러 처리 (C4-2)
titleInput.dispatchEvent(new Event('input'));
return /^https?:\/\//.test(string);
}
 
// LMS 제목 최대 byte — 직접 입력 초과는 절삭(C1-1), (광고) 삽입 초과는 에러 유지(C4-2)
const SMS_TITLE_MAX_BYTES = 40;
 
// 제목 인풋과 같은 탭의 '광고성 문구 추가' 체크박스
function getAdCheckboxForTitle(titleInput) {
for (let node = titleInput.parentElement; node; node = node.parentElement) {
const checkbox = node.querySelector('input[name="use080Reject"]');
if (checkbox) return checkbox;
}
return null;
}
 
// 초과 에러 표기 — destructive 로 테두리·byte 카운터가 함께 빨간색이 된다
function setSmsTitleOverState(titleInput, isOver) {
titleInput.classList.toggle('js-title-over', isOver);
 
if (isOver) {
NCDSValidator.highlight(titleInput);
} else {
NCDSValidator.unhighlight(titleInput);
}
}
 
// 제목 byte 규칙 적용(이모지 제거 포함) 후 최종 값 반환
function applySmsTitleByteRule(titleInput, messageInputModule) {
let value = messageInputModule.removeEmoji(titleInput.value).value;
const isOver = messageInputModule.getByteLength(value) > SMS_TITLE_MAX_BYTES;
// addAdText 가 (광고) 삽입 시에만 세우는 1회성 플래그 (사용자 타이핑과 구분)
const adInserted = titleInput.dataset.titleAdInsert === '1';
const base = titleInput.dataset.titleOverBase;
let caret = null;
 
delete titleInput.dataset.titleAdInsert;
 
if (isOver && (adInserted || base !== undefined)) {
// C4-2 — 절삭하지 않는다. 초과 상태에서는 늘리는 입력만 되돌리고 삭제는 허용
if (!adInserted && base !== undefined && messageInputModule.getByteLength(value) > messageInputModule.getByteLength(base)) {
// 되돌린 만큼 커서를 입력 직전 위치로 복원
caret = Math.max(0, (titleInput.selectionStart ?? value.length) - (value.length - base.length));
value = base;
}
titleInput.dataset.titleOverBase = value;
setSmsTitleOverState(titleInput, true);
} else {
// C1-1 — 직접 입력 초과는 (광고) 체크 여부와 무관하게 자동 절삭
value = messageInputModule.truncateBytes(value, SMS_TITLE_MAX_BYTES);
delete titleInput.dataset.titleOverBase;
setSmsTitleOverState(titleInput, false);
}
 
if (titleInput.value !== value) {
titleInput.value = value;
if (caret !== null) {
titleInput.setSelectionRange(caret, caret);
}
}
return value;
}
 
// 발송 버튼의 .destructive 일괄 초기화(mobile_send.php) 후 미해소 에러 재표기
function refreshOverSmsTitleState() {
document.querySelectorAll('input[name="smsTitle"], input[name="alternativeSmsTitle"]')
.forEach(input => {
if (input.classList.contains('js-title-over')) {
setSmsTitleOverState(input, true);
}
});
}
 
// 초과 제목이 숨은 탭에 있으면 그 탭으로 전환해 에러 표시를 보이게 한다
function revealSmsTitleInput(input) {
const target = input.closest('.send-method-component')?.dataset.target;
const tabButton = target
? document.querySelector(`.ncua-tab-button[data-send-tab-type="${target}"]`)
: null;
 
if (tabButton && !tabButton.classList.contains('is-active')) {
tabButton.click();
}
 
NCDSValidator.highlight(input);
input.focus();
input.scrollIntoView({ block: 'center' });
}
 
// 발송 차단 검사용 — payload 에 실리는 기준(disabled)과 동일하게 판정한다.
// 가시성으로 거르면 탭을 옮겨 숨겨진 제목이 검사를 건너뛴 채 전송된다.
function findOverSmsTitleInput() {
const titleInputs = document.querySelectorAll('input[name="smsTitle"], input[name="alternativeSmsTitle"]');
return Array.from(titleInputs)
.find(input => !input.disabled && input.classList.contains('js-title-over')) ?? null;
}
 
function addAdText(messageContainer, previewContainer) {
// 본문은 SMS/LMS 공통으로 (광고) 삽입
const content = '(광고)\n' + messageContainer.getValue() + '\n' + smsRejectText;
messageContainer.setValue(content);
previewContainer.setContent(resolveReplaceCode(content));
dispatchMessageContentInput(messageContainer);
 
// 본문 갱신으로 SMS/LMS 판정이 끝난 뒤, LMS(제목 활성)면 제목에도 (광고) 삽입 — 제목 40bytes 에 카운트됨
const titleInput = resolveAdTitleInput(messageContainer);
if (titleInput && !titleInput.disabled && !titleInput.value.startsWith('(광고)')) {
titleInput.value = '(광고)' + titleInput.value;
titleInput.dataset.titleAdInsert = '1'; // 시스템 삽입 표시 — 절삭 대신 에러 처리 (C4-2)
titleInput.dispatchEvent(new Event('input'));
// 초과했다면 해당 영역으로 포커싱
if (titleInput.classList.contains('js-title-over')) {
titleInput.focus();
}
}
}
 
function removeAdText(messageContainer, previewContainer) {
const titleInput = resolveAdTitleInput(messageContainer);
if (titleInput && titleInput.value.startsWith('(광고)')) {
titleInput.value = titleInput.value.replace(/^\(광고\)/, '');
titleInput.dispatchEvent(new Event('input'));
}
 
let content = messageContainer.getValue();
content = content.replace(/^\(광고\)\n?/, '');
const escapedRejectText = smsRejectText.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
messageContainer.setValue(content);
previewContainer.setContent(resolveReplaceCode(content));
dispatchMessageContentInput(messageContainer);
}
 
// 광고 문구가 들어갈 제목 인풋 — 대체 메시지 컨테이너면 대체 제목, 아니면 메인 제목
function resolveAdTitleInput(messageContainer) {
return messageContainer === window.alternativeMessageInput
? document.querySelector('input[name="alternativeSmsTitle"]')
: document.querySelector('input[name="smsTitle"]');
}
 
// setValue 는 MessageInput 의 onInput 콜백을 부르지 않으므로, 본문 변경 후
// SMS/LMS 판단(제목 활성 토글·힌트 갱신)이 다시 돌도록 input 이벤트를 수동 발행
function dispatchMessageContentInput(messageContainer) {
const name = messageContainer === window.alternativeMessageInput ? 'messageAlternativeContent' : 'messageContent';
document.querySelector(`textarea[name="${name}"]`)?.dispatchEvent(new Event('input'));
}
 
/**
 
Admin/crm/mobile_send/layer_sms_content_setting.php+98-6
변경 전layer_sms_content_setting.php
return !!input && !input.disabled;
}
 
// 발송 요청용 제목 — LMS 활성 상태에서 값이 있을 때만. 미입력 시 null('제목없음' 처리는 발송 시스템 담당)
function getSmsTitleForSend() {
return resolveTitleForSend(getSmsTitleInput(), isSmsTitleEnabled());
}
<div class="tab-content-wrap">
<div class="message-content">
<div class="ncua-card__body-title-wrap">
<p class="ncua-card__body-title--xs">내용 입력</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
</div>
<div id="messageContentContainer"></div>
</div>
<ul>
<li>SMS 작성 시 90byte를 초과하면 LMS로 자동 전환되어 발송됩니다.</li>
<li>변수에 실제 데이터가 적용된 최종 메시지가 90byte를 초과하는 경우에도 LMS로 전환될 수 있습니다.</li>
 
</ul>
</div>
</details>
 
$(document).ready(function () {
initializeSmsContentSettingSectionEvents();
initializeSmsContentSettingSectionElement();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
});
 
function initializeSmsContentSettingSectionEvents() {
});
return;
}
const smsData = [{ name: "contents", value: message }];
 
 
 
 
$.post('./mobile_send/layer_mobile_send_save_sms_template.php', smsData, function (data) {
ncds_layer_popup({message: data, title: '템플릿으로 저장<div class="modal-title-description">작성한 내용을 저장할 카테고리와 제목을 선택하여 주시기 바랍니다.</div>', size: 'wide-sm'});
});
removeAdText(window.messageInput, window.preview);
}
});
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
}
 
// 칩 버튼 생성 함수
 
syncSmsPreviewAndHint(initialMessage);
 
 
 
 
 
 
 
 
const recipientType = document.querySelector('input[name="recipientType"]:checked')?.value;
if (['EXCEL_UPLOAD', 'DIRECT'].includes(recipientType)) {
smsSettingSection.querySelector('.js-replace-code').classList.add('display-none');
} else {
window.messageInput.setHint(window.messageInput.calculateLength(input) > 90 ? 'LMS 건당 3포인트 차감' : 'SMS 건당 1포인트 차감');
}
 
 
}
 
function setTemplate(message) {
smsSettingSection.querySelector('input[name="use080Reject"]').checked = false;
 
// 메시지 적용
window.messageInput.setValue('');
window.messageInput.insertText(message);
 
 
 
 
 
 
// 템플릿 불러오기 안내문구
smsSettingSection.querySelector('#useTemplateCaution').hidden = false;
}
shortLinkInput.value = '';
smsSettingSection.querySelector('[data-role="chip-container"]').innerHTML = '';
window.messageInput.setValue('');
 
 
 
 
 
window.preview.reset();
 
const isImpossibleAddShortLink = document.querySelectorAll(`.chip-button[data-send-tab-type="${getActivatedSendTabType()}"]`).length > 4;
 
변경 후layer_sms_content_setting.php
return !!input && !input.disabled;
}
 
// 발송 요청용 제목 — LMS(제목 활성)일 때만 전송, 미입력·치환자만 입력 시 '[제목없음]' 으로 발송
function getSmsTitleForSend() {
return resolveTitleForSend(getSmsTitleInput(), isSmsTitleEnabled());
}
<div class="tab-content-wrap">
<div class="message-content">
<div class="ncua-card__body-title-wrap">
<p class="ncua-card__body-title--xs tooltip-align" data-tooltip-seq="010">내용 입력</p>
</div>
<div class="message-title-field">
<div class="ncua-input ncua-input--xs ncua-input--full-width-with-count is-disabled">
<div class="ncua-input__content-wrap">
<div class="ncua-input__content">
<div class="ncua-input__field ncua-input__field--xs">
<input name="smsTitle" type="text" value="" placeholder="제목을 입력해 주세요." disabled />
</div>
</div>
<div class="ncua-input__field-text-count">
<output class="ncua-input__field-text-count-current" data-sms-title-current>0</output><span>/40</span>
</div>
</div>
</div>
</div>
<div id="messageContentContainer"></div>
</div>
<ul>
<li>SMS 작성 시 90byte를 초과하면 LMS로 자동 전환되어 발송됩니다.</li>
<li>변수에 실제 데이터가 적용된 최종 메시지가 90byte를 초과하는 경우에도 LMS로 전환될 수 있습니다.</li>
<li>본문 내용이 LMS인 경우에만 제목 입력이 가능하며, 제목 영역에는 직접 (광고) 문구를 입력하지 않도록 하고 광고 삽입이 필요한 경우 광고성 문구 추가 기능을 사용해야 합니다.</li>
</ul>
</div>
</details>
 
$(document).ready(function () {
initializeSmsContentSettingSectionEvents();
 
// CrmPreview(crm-preview.js)는 loader 가 비동기 로드하므로, 준비 전에 element 를 초기화하면
// MessagePreview 렌더가 null 을 반환해 window.preview 가 null 이 되고, 이후 제목 기본값 prefill·
// LMS 제목 활성화까지 중단된다(레시피 iframe 로드 레이스). → CrmPreview 준비 후 element 초기화.
let isElementInitialized = false;
const runElementInit = function () {
if (isElementInitialized) {
return;
}
isElementInitialized = true;
initializeSmsContentSettingSectionElement();
};
// crmPreviewLoaded 가 ready 이전에 이미 발생했을 수 있으므로(캐시 히트 등) 리스너를 먼저 등록하고,
// 준비 완료 상태면 즉시 실행한다(중복 실행은 isElementInitialized 가드로 방지).
window.addEventListener('crmPreviewLoaded', runElementInit);
if (typeof CrmPreview !== 'undefined' && typeof GodoUIModule !== 'undefined') {
runElementInit();
}
});
 
function initializeSmsContentSettingSectionEvents() {
});
return;
}
// 제목은 SMS/LMS 여부와 무관하게 입력값이 있으면 함께 저장
const smsData = [
{ name: "contents", value: message },
{ name: "messageTitle", value: getSmsTitleInput().value }
];
$.post('./mobile_send/layer_mobile_send_save_sms_template.php', smsData, function (data) {
ncds_layer_popup({message: data, title: '템플릿으로 저장<div class="modal-title-description">작성한 내용을 저장할 카테고리와 제목을 선택하여 주시기 바랍니다.</div>', size: 'wide-sm'});
});
removeAdText(window.messageInput, window.preview);
}
});
 
getSmsTitleInput().addEventListener('input', handleSmsTitleInput);
}
 
function getSmsTitleInput() {
return smsSettingSection.querySelector('input[name="smsTitle"]');
}
 
// 제목 입력 — 이모지 제거 후 40bytes 규칙 적용 (applySmsTitleByteRule)
function handleSmsTitleInput() {
const input = getSmsTitleInput();
const value = applySmsTitleByteRule(input, window.messageInput);
smsSettingSection.querySelector('[data-sms-title-current]').textContent = window.messageInput.getByteLength(value);
updateSmsTitlePreview();
}
 
// 본문이 LMS(90bytes 초과)일 때만 제목 활성 — SMS 로 돌아오면 값은 유지한 채 비활성
function setSmsTitleEnabled(enabled) {
const input = getSmsTitleInput();
input.disabled = !enabled;
input.closest('.ncua-input').classList.toggle('is-disabled', !enabled);
updateSmsTitlePreview();
}
 
function isSmsTitleEnabled() {
const input = getSmsTitleInput();
return !!input && !input.disabled;
}
 
// 발송 요청용 제목 — LMS 활성 상태에서 값이 있을 때만. 미입력 시 null('제목없음' 처리는 발송 시스템 담당)
function getSmsTitleForSend() {
return resolveTitleForSend(getSmsTitleInput(), isSmsTitleEnabled());
}
 
// 미리보기 — LMS 상태에서 값이 있을 때만 노출, 치환자는 공란으로 표기
function updateSmsTitlePreview() {
window.preview.setTitle(isSmsTitleEnabled() ? stripTitleReplaceCodes(getSmsTitleInput().value) : '');
}
 
// 칩 버튼 생성 함수
 
syncSmsPreviewAndHint(initialMessage);
 
// 레시피 기본 제목 prefill — 본문이 LMS면 활성 노출, SMS면 값만 유지한 채 비활성 (setTemplate 패턴)
const initialTitle = <?= json_encode($initialTitle ?? '', JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP) ?>;
if (initialTitle !== '') {
getSmsTitleInput().value = initialTitle;
handleSmsTitleInput();
}
 
const recipientType = document.querySelector('input[name="recipientType"]:checked')?.value;
if (['EXCEL_UPLOAD', 'DIRECT'].includes(recipientType)) {
smsSettingSection.querySelector('.js-replace-code').classList.add('display-none');
} else {
window.messageInput.setHint(window.messageInput.calculateLength(input) > 90 ? 'LMS 건당 3포인트 차감' : 'SMS 건당 1포인트 차감');
}
// 본문 기준 SMS/LMS 판단 — LMS 일 때만 제목 입력 활성화 (#15092)
setSmsTitleEnabled(window.messageInput.calculateLength(input) > 90);
}
 
function setTemplate(message, messageTitle = '') {
smsSettingSection.querySelector('input[name="use080Reject"]').checked = false;
 
// 메시지 적용 (insertText 가 onInput 을 호출해 SMS/LMS 판단·제목 활성 토글이 함께 갱신됨)
window.messageInput.setValue('');
window.messageInput.insertText(message);
 
// 저장된 메시지 제목 복원 — SMS 상태면 값만 유지한 채 비활성으로 노출됨
const titleInput = getSmsTitleInput();
titleInput.value = messageTitle ?? '';
handleSmsTitleInput();
 
// 템플릿 불러오기 안내문구
smsSettingSection.querySelector('#useTemplateCaution').hidden = false;
}
shortLinkInput.value = '';
smsSettingSection.querySelector('[data-role="chip-container"]').innerHTML = '';
window.messageInput.setValue('');
const titleInput = getSmsTitleInput();
titleInput.value = '';
setSmsTitleOverState(titleInput, false); // 40byte 초과 에러 표기까지 함께 해제
setSmsTitleEnabled(false);
smsSettingSection.querySelector('[data-sms-title-current]').textContent = '0';
window.preview.reset();
 
const isImpossibleAddShortLink = document.querySelectorAll(`.chip-button[data-send-tab-type="${getActivatedSendTabType()}"]`).length > 4;
 
Admin/crm/mobile_send.php+8
변경 전mobile_send.php
el.querySelector('.ncua-input__destructive-icon-wrap')?.remove();
});
 
 
 
 
 
 
// 발신번호 검증
if (!messageConfig.hasCallNumber) {
NCDSAlert({message: '발신번호가 없어 발송할 수 없습니다.', subMessage: '설정에서 발신번호 등록 후 발송 시도를 해주세요.', iconType: 'error'});
});
window.alternativeMessageInput.insertText(alternativeContents);
window.alternativePreview.setContent(alternativeContents);
 
 
 
}
}
 
 
변경 후mobile_send.php
el.querySelector('.ncua-input__destructive-icon-wrap')?.remove();
});
 
// 제목 40byte 초과(C4-2)는 미해소 에러라 재표기
if (typeof refreshOverSmsTitleState === 'function') {
refreshOverSmsTitleState();
}
 
// 발신번호 검증
if (!messageConfig.hasCallNumber) {
NCDSAlert({message: '발신번호가 없어 발송할 수 없습니다.', subMessage: '설정에서 발신번호 등록 후 발송 시도를 해주세요.', iconType: 'error'});
});
window.alternativeMessageInput.insertText(alternativeContents);
window.alternativePreview.setContent(alternativeContents);
if (typeof copyMainTitleToAlternativeSmsTitle === 'function') {
copyMainTitleToAlternativeSmsTitle();
}
}
}
 
 
Admin/crm/preview_mobile_send/layer_preview_mobile_send_alternative.php+13-1
변경 전layer_preview_mobile_send_alternative.php
<section class="mobile-preview mobile-preview--sms">
<div class="ncua-prev alternative-contents-preview" style="white-space: pre-wrap;"><?= $alternativeContents ?></div>
 
 
 
 
 
 
</section>
<script>
const alternativeSmsPreview = document.querySelector('.alternative-contents-preview');
$(document).ready(() => {
alternativeSmsPreview.textContent = resolveReplaceCodeForPreview(alternativeSmsPreview.textContent);
 
 
 
 
 
 
})
</script>
 
변경 후layer_preview_mobile_send_alternative.php
<section class="mobile-preview mobile-preview--sms">
<?php /* pre-wrap 은 본문에만 — 말풍선에 걸면 템플릿 마크업의 공백·줄바꿈까지 렌더링됨 */ ?>
<div class="ncua-prev">
<?php if (($alternativeTitle ?? '') !== ''): ?>
<div class="sms-title-side-preview alternative-title-preview"><?= gd_htmlspecialchars($alternativeTitle) ?></div>
<?php endif; ?>
<div class="alternative-contents-preview" style="white-space: pre-wrap;"><?= $alternativeContents ?></div>
</div>
</section>
<script>
const alternativeSmsPreview = document.querySelector('.alternative-contents-preview');
$(document).ready(() => {
alternativeSmsPreview.textContent = resolveReplaceCodeForPreview(alternativeSmsPreview.textContent);
 
// 제목은 변수 치환 미지원 — 변수는 공란으로 표기
const alternativeTitlePreview = document.querySelector('.alternative-title-preview');
if (alternativeTitlePreview) {
alternativeTitlePreview.textContent = alternativeTitlePreview.textContent.replace(/[#$]?\{[^}]*\}/g, '');
}
})
</script>
 
Admin/crm/preview_mobile_send/layer_preview_mobile_send_sms.php+13-1
변경 전layer_preview_mobile_send_sms.php
<section class="mobile-preview mobile-preview--sms">
<div class="ncua-prev sms-contents-preview" style="white-space: pre-wrap;"><?= $mainContents ?></div>
 
 
 
 
 
 
</section>
<script>
const smsPreview = document.querySelector('.sms-contents-preview');
$(document).ready(() => {
smsPreview.textContent = resolveReplaceCodeForPreview(smsPreview.textContent);
 
 
 
 
 
 
})
</script>
 
변경 후layer_preview_mobile_send_sms.php
<section class="mobile-preview mobile-preview--sms">
<?php /* pre-wrap 은 본문에만 — 말풍선에 걸면 템플릿 마크업의 공백·줄바꿈까지 렌더링됨 */ ?>
<div class="ncua-prev">
<?php if (($mainTitle ?? '') !== ''): ?>
<div class="sms-title-side-preview sms-title-preview"><?= gd_htmlspecialchars($mainTitle) ?></div>
<?php endif; ?>
<div class="sms-contents-preview" style="white-space: pre-wrap;"><?= $mainContents ?></div>
</div>
</section>
<script>
const smsPreview = document.querySelector('.sms-contents-preview');
$(document).ready(() => {
smsPreview.textContent = resolveReplaceCodeForPreview(smsPreview.textContent);
 
// 제목은 변수 치환 미지원 — 변수는 공란으로 표기
const smsTitlePreview = document.querySelector('.sms-title-preview');
if (smsTitlePreview) {
smsTitlePreview.textContent = smsTitlePreview.textContent.replace(/[#$]?\{[^}]*\}/g, '');
}
})
</script>
 
Admin/member/sms_auto.php+43-4
변경 전sms_auto.php
</label>
<input type="hidden" name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][recipientMode]" value="<?php echo $typeData['recipientMode']; ?>"/>
<input type="hidden" name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][recipientSno]" value="<?php echo $typeData['recipientSno']; ?>"/>
<textarea name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][recipientContents]" rows="4" class="form-control"><?php echo $typeData['recipientContents']; ?></textarea>
 
 
 
</td>
<?php } ?>
<td class="form-inline">
</label>
<input type="hidden" name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][memberMode]" value="<?php echo $typeData['memberMode']; ?>"/>
<input type="hidden" name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][memberSno]" value="<?php echo $typeData['memberSno']; ?>"/>
<textarea name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][memberContents]" rows="4" class="form-control"><?php echo $typeData['memberContents']; ?></textarea>
 
 
 
<?php } else { ?>
<div class="text-center text-blue">운영자 전용</div>
<?php } ?>
</label>
<input type="hidden" name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][adminMode]" value="<?php echo $typeData['adminMode']; ?>"/>
<input type="hidden" name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][adminSno]" value="<?php echo $typeData['adminSno']; ?>"/>
 
 
 
<textarea name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][adminContents]" rows="4"
class="form-control <?php if ($sKey == 'admin') { ?> width100p <?php } ?>"><?php echo $typeData['adminContents']; ?></textarea>
<?php } else { ?>
<div class="text-center text-orange-red">회원 전용</div>
<?php } ?>
</label>
<input type="hidden" name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][providerMode]" value="<?php echo $typeData['providerMode']; ?>"/>
<input type="hidden" name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][providerSno]" value="<?php echo $typeData['providerSno']; ?>"/>
<textarea name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][providerContents]" rows="4" class="form-control"><?php echo $typeData['providerContents']; ?></textarea>
 
 
 
<?php } else { ?>
<?php if ($sKey == 'admin') { ?>
<div class="text-center text-orange-red">본사 전용</div>
<input type="hidden" name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][providerSno]" value="<?php echo $typeData['providerSno']; ?>"/>
<input type="hidden" name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][providerMode]" value="<?php echo $typeData['providerMode']; ?>"/>
<input type="hidden" name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][providerContents]" value="<?php echo $typeData['providerContents']; ?>"/>
 
<?php } ?>
</tr>
<?php
<script type="text/javascript">
<!--
$(document).ready(function () {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
$('.btn-change-password').click(function () {
$.get('../share/layer_sms_password.php?mode=change', function () {
BootstrapDialog.closeAll();
 
변경 후sms_auto.php
</label>
<input type="hidden" name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][recipientMode]" value="<?php echo $typeData['recipientMode']; ?>"/>
<input type="hidden" name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][recipientSno]" value="<?php echo $typeData['recipientSno']; ?>"/>
<div class="js-sms-auto-subject-wrap mgb5">
<input type="text" name="<?= $sKey ?>[<?= $typeData['code'] ?>][recipientMessageTitle]" class="form-control js-sms-auto-subject" placeholder="제목 입력" value="<?= gd_isset($typeData['recipientMessageTitle']) ?>"/>
</div>
<textarea name="<?= $sKey ?>[<?= $typeData['code'] ?>][recipientContents]" rows="4" class="form-control js-sms-auto-contents"><?= $typeData['recipientContents'] ?></textarea>
</td>
<?php } ?>
<td class="form-inline">
</label>
<input type="hidden" name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][memberMode]" value="<?php echo $typeData['memberMode']; ?>"/>
<input type="hidden" name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][memberSno]" value="<?php echo $typeData['memberSno']; ?>"/>
<div class="js-sms-auto-subject-wrap mgb5">
<input type="text" name="<?= $sKey ?>[<?= $typeData['code'] ?>][memberMessageTitle]" class="form-control js-sms-auto-subject" placeholder="제목 입력" value="<?= gd_isset($typeData['memberMessageTitle']) ?>"/>
</div>
<textarea name="<?= $sKey ?>[<?= $typeData['code'] ?>][memberContents]" rows="4" class="form-control js-sms-auto-contents"><?= $typeData['memberContents'] ?></textarea>
<?php } else { ?>
<div class="text-center text-blue">운영자 전용</div>
<?php } ?>
</label>
<input type="hidden" name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][adminMode]" value="<?php echo $typeData['adminMode']; ?>"/>
<input type="hidden" name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][adminSno]" value="<?php echo $typeData['adminSno']; ?>"/>
<div class="js-sms-auto-subject-wrap mgb5">
<input type="text" name="<?= $sKey ?>[<?= $typeData['code'] ?>][adminMessageTitle]" class="form-control js-sms-auto-subject" placeholder="제목 입력" value="<?= gd_isset($typeData['adminMessageTitle']) ?>"/>
</div>
<textarea name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][adminContents]" rows="4"
class="form-control js-sms-auto-contents <?php if ($sKey == 'admin') { ?> width100p <?php } ?>"><?= $typeData['adminContents'] ?></textarea>
<?php } else { ?>
<div class="text-center text-orange-red">회원 전용</div>
<?php } ?>
</label>
<input type="hidden" name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][providerMode]" value="<?php echo $typeData['providerMode']; ?>"/>
<input type="hidden" name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][providerSno]" value="<?php echo $typeData['providerSno']; ?>"/>
<div class="js-sms-auto-subject-wrap mgb5">
<input type="text" name="<?= $sKey ?>[<?= $typeData['code'] ?>][providerMessageTitle]" class="form-control js-sms-auto-subject" placeholder="제목 입력" value="<?= gd_isset($typeData['providerMessageTitle']) ?>"/>
</div>
<textarea name="<?= $sKey ?>[<?= $typeData['code'] ?>][providerContents]" rows="4" class="form-control js-sms-auto-contents"><?= $typeData['providerContents'] ?></textarea>
<?php } else { ?>
<?php if ($sKey == 'admin') { ?>
<div class="text-center text-orange-red">본사 전용</div>
<input type="hidden" name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][providerSno]" value="<?php echo $typeData['providerSno']; ?>"/>
<input type="hidden" name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][providerMode]" value="<?php echo $typeData['providerMode']; ?>"/>
<input type="hidden" name="<?php echo $sKey; ?>[<?php echo $typeData['code']; ?>][providerContents]" value="<?php echo $typeData['providerContents']; ?>"/>
<input type="hidden" name="<?= $sKey ?>[<?= $typeData['code'] ?>][providerMessageTitle]" value="<?= gd_isset($typeData['providerMessageTitle']) ?>"/>
<?php } ?>
</tr>
<?php
<script type="text/javascript">
<!--
$(document).ready(function () {
// 제목 바이트 계산 (한글 등 멀티바이트 2byte, ASCII 1byte, 개행 제외)
function smsAutoStringToByte(str) {
var length = 0;
for (var i = 0; i < str.length; i++) {
if (escape(str.charAt(i)).length >= 4) length += 2;
else if (escape(str.charAt(i)) != "%0D") length++;
}
return length;
}
// 이모티콘 제거 (서로게이트 페어 + 변형선택자, 기획: 제목·본문 입력 불가)
function smsAutoStripEmoji(str) {
if (!str) return str;
return str.replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, '').replace(/[\uFE00-\uFE0F\u200D\u20E3]/g, '');
}
// 자동발송 제목 영역은 항상 활성 노출(C3). 본문은 이모티콘만 자동 제거.
$('.js-sms-auto-contents').on('keyup change', function () {
var $ta = $(this);
var stripped = smsAutoStripEmoji($ta.val());
if (stripped !== $ta.val()) { $ta.val(stripped); }
});
$('.js-sms-auto-subject').on('keyup keydown', function () {
var input = $(this);
var text = smsAutoStripEmoji(input.val());
while (smsAutoStringToByte(text) > <?= $lmsSubjectLimit; ?>) { text = text.substring(0, text.length - 1); }
input.val(text);
});
$('.btn-change-password').click(function () {
$.get('../share/layer_sms_password.php?mode=change', function () {
BootstrapDialog.closeAll();
 
Admin/member/sms_log.php+4
변경 전sms_log.php
$listHtml[] = '<td class="text-center number">' . ($data['receiverCnt'] * $lmsPoint) . '</td>';
}
$listHtml[] = '<td style="word-break:break-all;word-wrap:break-word;overflow:hidden;" class="multirows">';
 
 
 
 
$listHtml[] = '<div class="div-contents">' . $data['contents'] . '</div>';
if ($data['sendStatus'] === 'r' && $data['smsType'] === 'user') {
$listHtml[] = '<div><button type="button" class="btn btn-xs btn-gray btn-modify">수정하기</button></div>';
 
변경 후sms_log.php
$listHtml[] = '<td class="text-center number">' . ($data['receiverCnt'] * $lmsPoint) . '</td>';
}
$listHtml[] = '<td style="word-break:break-all;word-wrap:break-word;overflow:hidden;" class="multirows">';
if ($data['sendFl'] === 'lms') {
$subjectText = ($data['subject'] !== null && $data['subject'] !== '') ? $data['subject'] : '[' . __('제목없음') . ']';
$listHtml[] = '<div class="div-subject text-darkblue"><strong>' . gd_htmlspecialchars($subjectText) . '</strong></div>';
}
$listHtml[] = '<div class="div-contents">' . $data['contents'] . '</div>';
if ($data['sendStatus'] === 'r' && $data['smsType'] === 'user') {
$listHtml[] = '<div><button type="button" class="btn btn-xs btn-gray btn-modify">수정하기</button></div>';
 
Admin/member/sms_send.php+75-2
변경 전sms_send.php
return length;
}
 
 
 
 
 
 
 
 
 
 
 
 
 
/**
* SMS 내용 길이 체크
*/
function setContentsLength(contentsNm, countId) {
var textarea = $('textarea[name=' + contentsNm + ']');
var contentsText = textarea.val();
 
 
 
 
var textLength = stringToByte(contentsText);
if (textLength > <?php echo $smsStringLimit;?>) {
if (textLength > <?php echo $lmsStringLimit;?>) {
$('.sms-type').hide();
$('.lms-type').show();
$('input[name=sendFl]').val('lms');
 
 
} else {
$('#' + countId).css("color", "");
$('.sms-type').show();
$('.lms-type').hide();
$('input[name=sendFl]').val('sms');
 
}
$('#' + countId).val(textLength);
}
setContentsLength('smsContents', 'smsStringCount');
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
function setReceiverCount() {
var checkedType = $('[name=receiverType]:checked').val();
var receiverCount = 0, agreeCount = 0, rejectCount = 0;
dialog: false,
debug: true,
submitHandler: function (form) {
console.log('submitHan', form);
 
 
 
 
 
var divisionInt = 1;
if ($('input[name=sendFl]').val() === 'lms') {
divisionInt = <?php echo $lmsPoint;?>;
<div class="notice-danger pull-left mgl15 display-none">회원 외 치환코드는 정상 적용되지 않으니 저장된 메시지 수정 시에만 이용바랍니다.</div>
</div>
</div>
 
 
 
 
 
 
 
 
<div class="row pdt5">
<div class="col-xs-3 pdr0">
<label class="width100p">
<div class="col-xs-12">
<div class="notice-info">URL 삽입 시 [단축 URL] 앱을 이용하시면 짧고 간단하게 URL을 사용하실 수 있습니다. <a href="https://apps.godo.co.kr/apps/1519" class="btn-link" target="_blank">바로가기</a></div>
<div class="notice-info">치환코드 사용 시 LMS로 발송될 수 있으며 일부 문자가 포인트 부족으로 발송되지 않을 수 있습니다.<br/>- 포인트 충전 후 <a href="../member/sms_log.php" class="btn-link" target="_blank">SMS 발송 내역 보기</a>에서 재발송하실 수 있습니다.</div>
 
<div class="notice-danger sms-large-caution">발송내용에 이모지 또는 사용 불가능한 특수문자, 맞춤법이 바르지 않은 문자가 포함되어있으면 일부 내용은 삭제되고 발송되오니 주의하시기 바랍니다.<br/>대량 SMS(LMS) 발송 시 이모지를 사용하지 않는 것과 맞춤법에 어긋나는 문자가 입력 되지는 않았는지 확인하시는 것을 권장 드리며,<br/> 발송 내용에 사용가능한 특수문자는 매뉴얼을 참고하시기 바랍니다.</div>
</div>
</div>
<%= checkbox %> <%= subject %>
<button type="button" class="btn btn-sm btn-white pull-right js-btn-save" data-text="저장">수정</button>
<button type="button" class="btn btn-sm btn-white pull-right js-btn-insert mgr5">삽입</button>
 
<label class="width100p pdt5">
<textarea rows="13" class="form-control width100p" name="contents"><%= contents %></textarea>
</label>
 
변경 후sms_send.php
return length;
}
 
/**
* 이모티콘 제거 (제목/본문 이모티콘 입력 불가 - 자동 삭제)
*/
function stripEmoji(str) {
if (!str) {
return str;
}
return str
.replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, '')
.replace(/[\uFE00-\uFE0F\u200D\u20E3]/g, '');
}
 
/**
* SMS 내용 길이 체크
*/
function setContentsLength(contentsNm, countId) {
var textarea = $('textarea[name=' + contentsNm + ']');
var stripped = stripEmoji(textarea.val());
if (stripped !== textarea.val()) {
textarea.val(stripped);
}
var contentsText = stripped;
var textLength = stringToByte(contentsText);
if (textLength > <?php echo $smsStringLimit;?>) {
if (textLength > <?php echo $lmsStringLimit;?>) {
$('.sms-type').hide();
$('.lms-type').show();
$('input[name=sendFl]').val('lms');
$('#smsSubject').prop('disabled', false); // LMS: 제목 영역 활성
setSubjectLength();
} else {
$('#' + countId).css("color", "");
$('.sms-type').show();
$('.lms-type').hide();
$('input[name=sendFl]').val('sms');
$('#smsSubject').prop('disabled', true); // SMS: 제목 영역 비활성(값 유지, 미발송)
}
$('#' + countId).val(textLength);
}
setContentsLength('smsContents', 'smsStringCount');
}
 
/**
* LMS 제목 Byte 체크 (공백 포함 최대 <?= $lmsSubjectLimit; ?>Byte, 초과분 자동 삭제)
*/
function setSubjectLength() {
var input = $('#smsSubject');
if (input.length === 0) {
return;
}
var limit = <?= $lmsSubjectLimit; ?>;
var text = stripEmoji(input.val());
var adChecked = $('input[name=sms080Reject]').is(':checked');
var byte = stringToByte(text);
if (adChecked && byte > limit) {
// C4-2: (광고) 자동 삽입으로 40Byte 초과 -> 절삭하지 않고 에러 표기
input.val(text);
setSubjectOver(true);
} else {
// C1-1: 직접 입력 40Byte 초과분 자동삭제
while (stringToByte(text) > limit) {
text = text.substring(0, text.length - 1);
}
input.val(text);
byte = stringToByte(text);
setSubjectOver(false);
}
$('#smsSubjectCount').val(byte);
}
 
function setSubjectOver(isOver) {
var input = $('#smsSubject');
if (isOver) {
input.addClass('js-subject-over').css('border-color', '#e74c3c');
$('#smsSubjectCount').css('color', '#e74c3c');
} else {
input.removeClass('js-subject-over').css('border-color', '');
$('#smsSubjectCount').css('color', '');
}
}
 
function setReceiverCount() {
var checkedType = $('[name=receiverType]:checked').val();
var receiverCount = 0, agreeCount = 0, rejectCount = 0;
dialog: false,
debug: true,
submitHandler: function (form) {
// C4-2: 제목 40Byte 초과(광고 삽입 등) 시 발송 차단
if ($('input[name=sendFl]').val() === 'lms' && $('#smsSubject').length && stringToByte(stripEmoji($('#smsSubject').val())) > <?= $lmsSubjectLimit; ?>) {
BootstrapDialog.show({title: '경고', message: '제목은 최대 <?= $lmsSubjectLimit; ?>bytes까지 입력 가능합니다.', closable: true});
$('#smsSubject').focus();
return false;
}
var divisionInt = 1;
if ($('input[name=sendFl]').val() === 'lms') {
divisionInt = <?php echo $lmsPoint;?>;
<div class="notice-danger pull-left mgl15 display-none">회원 외 치환코드는 정상 적용되지 않으니 저장된 메시지 수정 시에만 이용바랍니다.</div>
</div>
</div>
<div class="row pdt5 js-subject-row">
<div class="col-xs-3 pdr0">
<input type="text" name="smsSubject" id="smsSubject" class="form-control width100p" placeholder="제목을 입력해주세요." value="<?= gd_isset($smsSubject); ?>" onkeyup="setSubjectLength();" onkeydown="setSubjectLength();" disabled="disabled"/>
<div class="mgt5">
<input type="text" id="smsSubjectCount" value="0" readonly="readonly" class="form-control width-3xs"> / <?= $lmsSubjectLimit; ?> Bytes
</div>
</div>
</div>
<div class="row pdt5">
<div class="col-xs-3 pdr0">
<label class="width100p">
<div class="col-xs-12">
<div class="notice-info">URL 삽입 시 [단축 URL] 앱을 이용하시면 짧고 간단하게 URL을 사용하실 수 있습니다. <a href="https://apps.godo.co.kr/apps/1519" class="btn-link" target="_blank">바로가기</a></div>
<div class="notice-info">치환코드 사용 시 LMS로 발송될 수 있으며 일부 문자가 포인트 부족으로 발송되지 않을 수 있습니다.<br/>- 포인트 충전 후 <a href="../member/sms_log.php" class="btn-link" target="_blank">SMS 발송 내역 보기</a>에서 재발송하실 수 있습니다.</div>
<div class="notice-info">본문 내용이 LMS인 경우에만 제목 입력이 가능하며, 제목 영역에는 직접 (광고) 문구를 입력하지 않도록 하고 광고 삽입이 필요한 경우 광고성 문구 추가 기능을 사용해야 합니다.</div>
<div class="notice-danger sms-large-caution">발송내용에 이모지 또는 사용 불가능한 특수문자, 맞춤법이 바르지 않은 문자가 포함되어있으면 일부 내용은 삭제되고 발송되오니 주의하시기 바랍니다.<br/>대량 SMS(LMS) 발송 시 이모지를 사용하지 않는 것과 맞춤법에 어긋나는 문자가 입력 되지는 않았는지 확인하시는 것을 권장 드리며,<br/> 발송 내용에 사용가능한 특수문자는 매뉴얼을 참고하시기 바랍니다.</div>
</div>
</div>
<%= checkbox %> <%= subject %>
<button type="button" class="btn btn-sm btn-white pull-right js-btn-save" data-text="저장">수정</button>
<button type="button" class="btn btn-sm btn-white pull-right js-btn-insert mgr5">삽입</button>
<input type="text" name="messageTitle" class="form-control width100p mgt5 js-sms-contents-subject" placeholder="제목을 입력해주세요." value="<%= messageTitle %>" disabled="disabled"/>
<label class="width100p pdt5">
<textarea rows="13" class="form-control width100p" name="contents"><%= contents %></textarea>
</label>
 
Admin/promotion/cart_remind_regist.php+69-14
변경 전cart_remind_regist.php
}
if (e.target.checked) {
$body.val('(광고)\n' + $body.val() + '\n무료거부 ' + $('input[name="sms080Reject"]').data('reject-number'));
 
 
 
}
changeCartRemindContentsLength();
 
// 본문 반영으로 SMS/LMS 판정이 끝난 뒤에 제목 처리 — 제목 영역이 비활성(SMS)이면 (광고) 미표기
if (e.target.checked && $subject.length && !$subject.prop('disabled')) {
$subject.val('(광고)' + $subject.val());
}
changeCartRemindSubjectLength();
});
 
}
if (e.target.checked) {
$body.val('(광고)\n' + $body.val() + '\n무료거부 ' + $('input[name="sms080Reject"]').data('reject-number'));
if ($subject.length) {
$subject.val('(광고)' + $subject.val());
}
}
changeCartRemindContentsLength();
 
 
 
 
 
changeCartRemindSubjectLength();
});
 
<span class="cart-remind-sms notice-info">SMS : 발송 건당 1포인트 차감</span>
</div>
</div>
 
 
 
 
<div class="form-inline mgt10">
<textarea name="cartRemindSendMessage" rows="8" class="smsContents form-control width-xl js-sms080-update"><?= $cartRemindData['cartRemindSendMessage']; ?></textarea>
<div class="mgt5">
<a href="https://www.nhn-commerce.com/customer/board-view.gd?type=notice&idx=1237" target="_blank" class="btn-link">자세히보기></a>
</p>
<p class="notice-info">장바구니 링크 치환코드는 LMS인 경우에만 정상적으로 발송됩니다</p>
 
</div>
</td>
</tr>
 
// 글자수 체크
$('textarea[name=cartRemindSendMessage]').keyup(changeCartRemindContentsLength);
 
displayCartRemindCouponLink();
changeCartRemindType();
changeCartRemindSendType();
changeCartRemindManualDirectPeriod();
changeCartRemindContentsLength();
 
 
// 광고성 문구 추가
$('input[name="sms080Reject"]').click(function (e) {
$('.js-sms080-update').val($('.js-sms080-update').val().replace(/(\n무료거부\s[0-9\-]*)/g, ''));
if(e.target.checked){
$('.js-sms080-update').val($('.js-sms080-update').val() + '\n무료거부 ' + $('input[name="sms080Reject"]').data('reject-number'));
};
 
 
 
 
 
 
 
 
 
 
});
 
});
* SMS 내용 길이 체크
*/
function changeCartRemindContentsLength() {
var contentsText = $('textarea[name=cartRemindSendMessage]').val();
 
 
 
 
 
var textLength = stringToByte(contentsText);
 
if ($('input:hidden[name="cartRemindSendType"]').val() == 'sms' && textLength > <?= $smsStringLimit; ?>) {
}
$('#cartRemindSendMessageCount').val(textLength);
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
// 발송유형 따른 폼 변경
function changeCartRemindType() {
if ($('input:radio[name="cartRemindType"]:checked').val() == 'manual') {
$('.cart-remind-sms').hide();
$('.cart-remind-sms select').attr('disabled', 'disabled');
$('.cart-remind-sms input').attr('disabled', 'disabled');
 
 
// sms발송
} else if ($('input:hidden[name="cartRemindSendType"]').val() == 'sms') {
$('.cart-remind-lms').hide();
$('.cart-remind-sms').show();
$('.cart-remind-sms select').removeAttr('disabled');
$('.cart-remind-sms input').removeAttr('disabled');
 
 
}
}
// 발급방식에 따른 폼 변경
}
return length;
}
 
 
 
 
 
 
 
 
 
 
 
 
</script>
 
변경 후cart_remind_regist.php
}
if (e.target.checked) {
$body.val('(광고)\n' + $body.val() + '\n무료거부 ' + $('input[name="sms080Reject"]').data('reject-number'));
if ($subject.length) {
$subject.val('(광고)' + $subject.val());
}
}
changeCartRemindContentsLength();
 
 
 
 
 
changeCartRemindSubjectLength();
});
 
}
if (e.target.checked) {
$body.val('(광고)\n' + $body.val() + '\n무료거부 ' + $('input[name="sms080Reject"]').data('reject-number'));
 
 
 
}
changeCartRemindContentsLength();
 
// 본문 반영으로 SMS/LMS 판정이 끝난 뒤에 제목 처리 — 제목 영역이 비활성(SMS)이면 (광고) 미표기
if (e.target.checked && $subject.length && !$subject.prop('disabled')) {
$subject.val('(광고)' + $subject.val());
}
changeCartRemindSubjectLength();
});
 
<span class="cart-remind-sms notice-info">SMS : 발송 건당 1포인트 차감</span>
</div>
</div>
<div class="form-inline mgt10 js-cart-subject-row">
<input type="text" name="cartRemindSendSubject" id="cartRemindSendSubject" class="form-control width-xl" placeholder="제목을 입력해주세요." value="<?= gd_isset($cartRemindData['cartRemindSendSubject']); ?>" disabled="disabled"/>
<input type="text" id="cartRemindSubjectCount" value="0" readonly="readonly" class="form-control width-3xs"> / <?= $lmsSubjectLimit; ?> Bytes
</div>
<div class="form-inline mgt10">
<textarea name="cartRemindSendMessage" rows="8" class="smsContents form-control width-xl js-sms080-update"><?= $cartRemindData['cartRemindSendMessage']; ?></textarea>
<div class="mgt5">
<a href="https://www.nhn-commerce.com/customer/board-view.gd?type=notice&idx=1237" target="_blank" class="btn-link">자세히보기></a>
</p>
<p class="notice-info">장바구니 링크 치환코드는 LMS인 경우에만 정상적으로 발송됩니다</p>
<p class="notice-info">본문 내용이 LMS인 경우에만 제목 입력이 가능하며, 제목 영역에는 직접 (광고) 문구를 입력하지 않도록 하고 광고 삽입이 필요한 경우 광고성 문구 추가 기능을 사용해야 합니다.</p>
</div>
</td>
</tr>
 
// 글자수 체크
$('textarea[name=cartRemindSendMessage]').keyup(changeCartRemindContentsLength);
$('#cartRemindSendSubject').on('keyup keydown', changeCartRemindSubjectLength);
displayCartRemindCouponLink();
changeCartRemindType();
changeCartRemindSendType();
changeCartRemindManualDirectPeriod();
changeCartRemindContentsLength();
changeCartRemindSubjectLength();
 
// 광고성 문구 추가 (본문: (광고) 접두 + 무료거부 접미 / LMS 제목: (광고) 접두)
$('input[name="sms080Reject"]').click(function (e) {
var $body = $('.js-sms080-update');
$body.val($body.val().replace(/(\(광고\)\n)|(\n무료거부\s[0-9\-]*)/g, ''));
var $subject = $('#cartRemindSendSubject');
if ($subject.length) {
$subject.val($subject.val().replace(/^\(광고\)/, ''));
}
if (e.target.checked) {
$body.val('(광고)\n' + $body.val() + '\n무료거부 ' + $('input[name="sms080Reject"]').data('reject-number'));
if ($subject.length) {
$subject.val('(광고)' + $subject.val());
}
}
changeCartRemindContentsLength();
changeCartRemindSubjectLength();
});
 
});
* SMS 내용 길이 체크
*/
function changeCartRemindContentsLength() {
var $cartTa = $('textarea[name=cartRemindSendMessage]');
var strippedBody = stripEmoji($cartTa.val());
if (strippedBody !== $cartTa.val()) {
$cartTa.val(strippedBody);
}
var contentsText = strippedBody;
var textLength = stringToByte(contentsText);
 
if ($('input:hidden[name="cartRemindSendType"]').val() == 'sms' && textLength > <?= $smsStringLimit; ?>) {
}
$('#cartRemindSendMessageCount').val(textLength);
}
 
/**
* LMS 제목 Byte 체크 (공백 포함 최대 <?= $lmsSubjectLimit; ?>Byte, 초과분 자동 삭제)
*/
function changeCartRemindSubjectLength() {
var input = $('#cartRemindSendSubject');
if (input.length === 0) {
return;
}
var limit = <?= $lmsSubjectLimit; ?>;
var text = stripEmoji(input.val());
while (stringToByte(text) > limit) {
text = text.substring(0, text.length - 1);
}
input.val(text);
$('#cartRemindSubjectCount').val(stringToByte(text));
}
// 발송유형 따른 폼 변경
function changeCartRemindType() {
if ($('input:radio[name="cartRemindType"]:checked').val() == 'manual') {
$('.cart-remind-sms').hide();
$('.cart-remind-sms select').attr('disabled', 'disabled');
$('.cart-remind-sms input').attr('disabled', 'disabled');
 
$('#cartRemindSendSubject').prop('disabled', false); // LMS: 제목 영역 활성
// sms발송
} else if ($('input:hidden[name="cartRemindSendType"]').val() == 'sms') {
$('.cart-remind-lms').hide();
$('.cart-remind-sms').show();
$('.cart-remind-sms select').removeAttr('disabled');
$('.cart-remind-sms input').removeAttr('disabled');
 
$('#cartRemindSendSubject').prop('disabled', true); // SMS: 제목 영역 비활성(값 유지, 미저장/미발송)
}
}
// 발급방식에 따른 폼 변경
}
return length;
}
 
/**
* 이모티콘 제거 (제목/본문 이모티콘 입력 불가 - 자동 삭제)
*/
function stripEmoji(str) {
if (!str) {
return str;
}
return str
.replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, '')
.replace(/[\uFE00-\uFE0F\u200D\u20E3]/g, '');
}
</script>
 
Admin/promotion/comeback_coupon_regist.php+68-11
변경 전comeback_coupon_regist.php
}
if (e.target.checked) {
$send_contents.val('(광고)\n' + $send_contents.val() + '\n무료거부 ' + $(selector).data('reject-number'));
 
 
 
 
}
refresh_send_contents();
 
// 본문 반영으로 SMS/LMS 판정이 끝난 뒤에 제목 처리 — 제목 영역이 비활성(SMS)이면 (광고) 미표기
if (e.target.checked && $smsSubject.length && !$smsSubject.prop('disabled')) {
$smsSubject.val('(광고)' + $smsSubject.val());
setSubjectLength();
}
});
}
</script>
}
if (e.target.checked) {
$send_contents.val('(광고)\n' + $send_contents.val() + '\n무료거부 ' + $(selector).data('reject-number'));
if ($smsSubject.length) {
$smsSubject.val('(광고)' + $smsSubject.val());
setSubjectLength();
}
}
refresh_send_contents();
 
 
 
 
 
 
});
}
</script>
<button type="button" class="btn btn-white btn-sm pull-right js-toggle-replace-code" data-target=".replace_code_area" data-text="치환코드 닫기">치환코드 보기</button>
</div>
</div>
 
 
 
 
 
 
 
 
<div class="row pdt5">
<div class="col-xs-3 pdr0">
<label class="width100p">
링크는 단축 URL로 자동 변환하였습니다.<br/>
[단축 URL] 앱을 이용하여 단축 URL을 생성하면, 조회수 및 통계 자료를 확인하실 수 있습니다. <a href="https://apps.godo.co.kr/apps/1519" class="btn-link" target="_blank">바로가기</a>
</div>
 
</div>
</div>
</td>
return length;
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
/**
* SMS 내용 길이 체크
*/
function setContentsLength(contentsNm, countId) {
var textarea = $('textarea[name=' + contentsNm + ']');
var contentsText = textarea.val();
 
 
 
 
var textLength = stringToByte(contentsText);
if (textLength > <?php echo $smsStringLimit;?>) {
if (textLength > <?php echo $lmsStringLimit;?>) {
$('.sms-type').hide();
$('.lms-type').show();
$('input[name=sendFl]').val('lms');
 
 
 
 
} else {
$('#' + countId).css("color", "");
$('.sms-type').show();
$('.lms-type').hide();
$('input[name=sendFl]').val('sms');
 
}
$('#' + countId).val(textLength);
}
 
// 글자수 체크
$('textarea[name=smsContents]').keyup(setSendLength).change(setSendLength);
 
 
$("#frmCoupon").validate({
submitHandler: function (form) {
changeTargetType();
checkSms();
setSendLength();
 
set_click_replace_code_insert('.replace-code-area .js-btn-insert');
set_change_focus_contents('textarea[name="smsContents"]');
set_click_sms080_contents(':checkbox[name="sms080Reject"]');
function set_click_sms080_contents (selector) {
$(selector).click(function (e) {
$send_contents.val($send_contents.val().replace(/(\(광고\)\n)|(\n무료거부\s[0-9\-]*)/g, ''));
 
 
 
 
if (e.target.checked) {
$send_contents.val('(광고)\n' + $send_contents.val() + '\n무료거부 ' + $(selector).data('reject-number'));
 
 
 
 
}
refresh_send_contents();
});
 
변경 후comeback_coupon_regist.php
}
if (e.target.checked) {
$send_contents.val('(광고)\n' + $send_contents.val() + '\n무료거부 ' + $(selector).data('reject-number'));
if ($smsSubject.length) {
$smsSubject.val('(광고)' + $smsSubject.val());
setSubjectLength();
}
}
refresh_send_contents();
 
 
 
 
 
 
});
}
</script>
}
if (e.target.checked) {
$send_contents.val('(광고)\n' + $send_contents.val() + '\n무료거부 ' + $(selector).data('reject-number'));
 
 
 
 
}
refresh_send_contents();
 
// 본문 반영으로 SMS/LMS 판정이 끝난 뒤에 제목 처리 — 제목 영역이 비활성(SMS)이면 (광고) 미표기
if (e.target.checked && $smsSubject.length && !$smsSubject.prop('disabled')) {
$smsSubject.val('(광고)' + $smsSubject.val());
setSubjectLength();
}
});
}
</script>
<button type="button" class="btn btn-white btn-sm pull-right js-toggle-replace-code" data-target=".replace_code_area" data-text="치환코드 닫기">치환코드 보기</button>
</div>
</div>
<div class="row pdt5 js-subject-row">
<div class="col-xs-3 pdr0">
<input type="text" name="smsSubject" id="smsSubject" class="form-control width100p" placeholder="제목을 입력해주세요." value="<?= gd_isset($couponData['smsSubject']) ?>" disabled="disabled"/>
<div class="mgt5">
<input type="text" id="smsSubjectCount" value="0" readonly="readonly" class="form-control width-3xs"> / <?= $lmsSubjectLimit; ?> Bytes
</div>
</div>
</div>
<div class="row pdt5">
<div class="col-xs-3 pdr0">
<label class="width100p">
링크는 단축 URL로 자동 변환하였습니다.<br/>
[단축 URL] 앱을 이용하여 단축 URL을 생성하면, 조회수 및 통계 자료를 확인하실 수 있습니다. <a href="https://apps.godo.co.kr/apps/1519" class="btn-link" target="_blank">바로가기</a>
</div>
<div class="notice-info">본문 내용이 LMS인 경우에만 제목 입력이 가능하며, 제목 영역에는 직접 (광고) 문구를 입력하지 않도록 하고 광고 삽입이 필요한 경우 광고성 문구 추가 기능을 사용해야 합니다.</div>
</div>
</div>
</td>
return length;
}
 
/**
* 이모티콘 제거 (제목/본문 이모티콘 입력 불가 - 자동 삭제)
*/
function stripEmoji(str) {
if (!str) {
return str;
}
return str
.replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, '')
.replace(/[\uFE00-\uFE0F\u200D\u20E3]/g, '');
}
 
/**
* LMS 제목 Byte 체크 (공백 포함 최대 <?= $lmsSubjectLimit; ?>Byte, 초과분 자동 삭제)
*/
function setSubjectLength() {
var input = $('#smsSubject');
if (input.length === 0) {
return;
}
var limit = <?= $lmsSubjectLimit; ?>;
var text = stripEmoji(input.val());
while (stringToByte(text) > limit) {
text = text.substring(0, text.length - 1);
}
input.val(text);
$('#smsSubjectCount').val(stringToByte(text));
}
 
/**
* SMS 내용 길이 체크
*/
function setContentsLength(contentsNm, countId) {
var textarea = $('textarea[name=' + contentsNm + ']');
var stripped = stripEmoji(textarea.val());
if (stripped !== textarea.val()) {
textarea.val(stripped);
}
var contentsText = stripped;
var textLength = stringToByte(contentsText);
if (textLength > <?php echo $smsStringLimit;?>) {
if (textLength > <?php echo $lmsStringLimit;?>) {
$('.sms-type').hide();
$('.lms-type').show();
$('input[name=sendFl]').val('lms');
<?php if ($checkMode == 'canModify') { ?>
$('#smsSubject').prop('disabled', false); // LMS: 제목 영역 활성
<?php } ?>
setSubjectLength();
} else {
$('#' + countId).css("color", "");
$('.sms-type').show();
$('.lms-type').hide();
$('input[name=sendFl]').val('sms');
$('#smsSubject').prop('disabled', true); // SMS: 제목 영역 비활성(값 유지)
}
$('#' + countId).val(textLength);
}
 
// 글자수 체크
$('textarea[name=smsContents]').keyup(setSendLength).change(setSendLength);
$('#smsSubject').on('keyup keydown', setSubjectLength);
 
$("#frmCoupon").validate({
submitHandler: function (form) {
changeTargetType();
checkSms();
setSendLength();
setSubjectLength();
set_click_replace_code_insert('.replace-code-area .js-btn-insert');
set_change_focus_contents('textarea[name="smsContents"]');
set_click_sms080_contents(':checkbox[name="sms080Reject"]');
function set_click_sms080_contents (selector) {
$(selector).click(function (e) {
$send_contents.val($send_contents.val().replace(/(\(광고\)\n)|(\n무료거부\s[0-9\-]*)/g, ''));
var $smsSubject = $('#smsSubject');
if ($smsSubject.length) {
$smsSubject.val($smsSubject.val().replace(/^\(광고\)/, ''));
}
if (e.target.checked) {
$send_contents.val('(광고)\n' + $send_contents.val() + '\n무료거부 ' + $(selector).data('reject-number'));
if ($smsSubject.length) {
$smsSubject.val('(광고)' + $smsSubject.val());
setSubjectLength();
}
}
refresh_send_contents();
});
 
Admin/promotion/layer_cart_remind_message.php+46-1
변경 전layer_cart_remind_message.php
<span class="cart-remind-sms notice-info">SMS : 발송 건당 1포인트 차감</span>
</div>
</div>
 
 
 
 
<div class="form-inline mgt10">
<textarea name="cartRemindSendMessage" rows="8" class="smsContents form-control width-xl"><?= $cartRemindData['cartRemindSendMessage']; ?></textarea>
<div class="mgt5">
<a href="https://www.nhn-commerce.com/customer/board-view.gd?type=notice&idx=1237" target="_blank" class="btn-link">자세히보기></a>
</p>
<p class="notice-info">장바구니 링크 치환코드는 LMS인 경우에만 정상적으로 발송됩니다</p>
 
</div>
</td>
</tr>
 
// 글자수 체크
$('textarea[name=cartRemindSendMessage]').keyup(changeCartRemindContentsLength);
 
changeCartRemindSendType();
changeCartRemindContentsLength();
 
});
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
/**
* SMS 내용 길이 체크
*/
function changeCartRemindContentsLength() {
var contentsText = $('textarea[name=cartRemindSendMessage]').val();
 
 
 
 
 
var textLength = stringToByte(contentsText);
 
if ($('input:hidden[name="cartRemindSendType"]').val() == 'sms' && textLength > <?= $smsStringLimit; ?>) {
$('.cart-remind-sms').hide();
$('.cart-remind-sms select').attr('disabled', 'disabled');
$('.cart-remind-sms input').attr('disabled', 'disabled');
 
 
// sms발송
} else if ($('input:hidden[name="cartRemindSendType"]').val() == 'sms') {
$('.cart-remind-lms').hide();
$('.cart-remind-sms').show();
$('.cart-remind-sms select').removeAttr('disabled');
$('.cart-remind-sms input').removeAttr('disabled');
 
 
}
}
/**
}
return length;
}
 
 
 
 
 
 
 
 
 
 
 
 
</script>
 
 
변경 후layer_cart_remind_message.php
<span class="cart-remind-sms notice-info">SMS : 발송 건당 1포인트 차감</span>
</div>
</div>
<div class="form-inline mgt10 js-cart-subject-row">
<input type="text" name="cartRemindSendSubject" id="cartRemindSendSubject" class="form-control width-xl" placeholder="제목을 입력해주세요." value="<?= gd_isset($cartRemindData['cartRemindSendSubject']); ?>" disabled="disabled"/>
<input type="text" id="cartRemindSubjectCount" value="0" readonly="readonly" class="form-control width-3xs"> / <?= $lmsSubjectLimit; ?> Bytes
</div>
<div class="form-inline mgt10">
<textarea name="cartRemindSendMessage" rows="8" class="smsContents form-control width-xl"><?= $cartRemindData['cartRemindSendMessage']; ?></textarea>
<div class="mgt5">
<a href="https://www.nhn-commerce.com/customer/board-view.gd?type=notice&idx=1237" target="_blank" class="btn-link">자세히보기></a>
</p>
<p class="notice-info">장바구니 링크 치환코드는 LMS인 경우에만 정상적으로 발송됩니다</p>
<p class="notice-info">본문 내용이 LMS인 경우에만 제목 입력이 가능하며, 제목 영역에는 직접 (광고) 문구를 입력하지 않도록 하고 광고 삽입이 필요한 경우 광고성 문구 추가 기능을 사용해야 합니다.</p>
</div>
</td>
</tr>
 
// 글자수 체크
$('textarea[name=cartRemindSendMessage]').keyup(changeCartRemindContentsLength);
$('#cartRemindSendSubject').on('keyup keydown', changeCartRemindSubjectLength);
changeCartRemindSendType();
changeCartRemindContentsLength();
changeCartRemindSubjectLength();
});
 
/**
* LMS 제목 Byte 체크 (공백 포함 최대 <?= $lmsSubjectLimit; ?>Byte, 초과분 자동 삭제)
*/
function changeCartRemindSubjectLength() {
var input = $('#cartRemindSendSubject');
if (input.length === 0) {
return;
}
var limit = <?= $lmsSubjectLimit; ?>;
var text = stripEmoji(input.val());
while (stringToByte(text) > limit) {
text = text.substring(0, text.length - 1);
}
input.val(text);
$('#cartRemindSubjectCount').val(stringToByte(text));
}
/**
* SMS 내용 길이 체크
*/
function changeCartRemindContentsLength() {
var $cartTa = $('textarea[name=cartRemindSendMessage]');
var strippedBody = stripEmoji($cartTa.val());
if (strippedBody !== $cartTa.val()) {
$cartTa.val(strippedBody);
}
var contentsText = strippedBody;
var textLength = stringToByte(contentsText);
 
if ($('input:hidden[name="cartRemindSendType"]').val() == 'sms' && textLength > <?= $smsStringLimit; ?>) {
$('.cart-remind-sms').hide();
$('.cart-remind-sms select').attr('disabled', 'disabled');
$('.cart-remind-sms input').attr('disabled', 'disabled');
 
$('#cartRemindSendSubject').prop('disabled', false); // LMS: 제목 영역 활성
// sms발송
} else if ($('input:hidden[name="cartRemindSendType"]').val() == 'sms') {
$('.cart-remind-lms').hide();
$('.cart-remind-sms').show();
$('.cart-remind-sms select').removeAttr('disabled');
$('.cart-remind-sms input').removeAttr('disabled');
 
$('#cartRemindSendSubject').prop('disabled', true); // SMS: 제목 영역 비활성(값 유지, 미저장/미발송)
}
}
/**
}
return length;
}
 
/**
* 이모티콘 제거 (제목/본문 이모티콘 입력 불가 - 자동 삭제)
*/
function stripEmoji(str) {
if (!str) {
return str;
}
return str
.replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, '')
.replace(/[\uFE00-\uFE0F\u200D\u20E3]/g, '');
}
</script>
 
 
Admin/share/layer_comeback_coupon_sms.php+6
변경 전layer_comeback_coupon_sms.php
<col style="width:80%" />
</colgroup>
<tbody>
 
 
 
 
 
 
<tr>
<th>발송 내용</th>
<td>
 
변경 후layer_comeback_coupon_sms.php
<col style="width:80%" />
</colgroup>
<tbody>
<tr>
<th>제목</th>
<td>
<input type="text" class="form-control width100p" readonly="readonly" value="<?= gd_isset($data['smsSubject']) !== '' ? gd_isset($data['smsSubject']) : '[제목없음]' ?>"/>
</td>
</tr>
<tr>
<th>발송 내용</th>
<td>
 
Admin/share/layer_standby_sms.php+48-6
변경 전layer_standby_sms.php
*/
?>
<form action="" method="post">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
<div class="row">
<div class="col-xs-12">
<div class="pull-left">
<span class="sms-type text-darkblue">SMS : 발송 건당 1포인트 차감</span>
<span class="lms-type text-orange-red display-none">LMS : 발송 건당 <?php echo $lmsPoint; ?>포인트 차감</span>
</div>
<div class="pull-right">
<input type="text" id="smsStringCount" value="0" readonly="readonly" class="form-control width-3xs"> /
<span class="sms-type"><?php echo $smsStringLimit; ?></span><span class="lms-type display-none"><?php echo number_format($lmsStringLimit); ?></span> Bytes
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<textarea name="contents" id="contents" rows="8" class="form-control"><?= $data['contents']; ?></textarea>
</div>
</div>
<div class="row">
<div class="center modal-footer">
<button type="submit" id="modify" class="btn btn-red">수정</button>
$(document).ready(function () {
var $textarea = $('textarea[name=contents]');
$textarea.on('keyup change', setSendLength).trigger('change');
 
 
});
function setSendLength() {
setContentsLength('contents', 'smsStringCount');
$('.sms-type').hide();
$('.lms-type').show();
$('input[name=sendFl]').val('lms');
 
 
} else {
$('#' + countId).css("color", "");
$('.sms-type').show();
$('.lms-type').hide();
$('input[name=sendFl]').val('sms');
 
}
$('#' + countId).val(textLength);
}
}
return length;
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
</script>
 
변경 후layer_standby_sms.php
*/
?>
<form action="" method="post">
<div class="row">
<div class="col-xs-12">
<div class="pull-right form-inline">
<input type="text" id="subjectStringCount" value="0" readonly="readonly" class="form-control width-3xs"> / <?= $lmsSubjectLimit; ?> Bytes
</div>
<div style="overflow:hidden; padding-right:10px;">
<input type="text" name="subject" id="subject" class="form-control" placeholder="제목을 입력해주세요." value="<?= gd_isset($data['subject']); ?>" disabled="disabled"/>
</div>
</div>
</div>
<div class="row mgt10">
<div class="col-xs-12">
<textarea name="contents" id="contents" rows="8" class="form-control"><?= $data['contents']; ?></textarea>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="pull-left">
<span class="sms-type text-darkblue">SMS : 발송 건당 1포인트 차감</span>
<span class="lms-type text-orange-red display-none">LMS : 발송 건당 <?php echo $lmsPoint; ?>포인트 차감</span>
</div>
 
<div class="pull-right">
<input type="text" id="smsStringCount" value="0" readonly="readonly" class="form-control width-3xs"> /
<span class="sms-type"><?php echo $smsStringLimit; ?></span><span class="lms-type display-none"><?php echo number_format($lmsStringLimit); ?></span> Bytes
</div>
</div>
</div>
 
 
 
 
 
<div class="row">
<div class="center modal-footer">
<button type="submit" id="modify" class="btn btn-red">수정</button>
$(document).ready(function () {
var $textarea = $('textarea[name=contents]');
$textarea.on('keyup change', setSendLength).trigger('change');
$('#subject').on('keyup keydown', setSubjectLength);
setSubjectLength();
});
function setSendLength() {
setContentsLength('contents', 'smsStringCount');
$('.sms-type').hide();
$('.lms-type').show();
$('input[name=sendFl]').val('lms');
$('#subject').prop('disabled', false); // LMS: 제목 영역 활성
setSubjectLength();
} else {
$('#' + countId).css("color", "");
$('.sms-type').show();
$('.lms-type').hide();
$('input[name=sendFl]').val('sms');
$('#subject').prop('disabled', true); // SMS: 제목 영역 비활성(값 유지, 미발송)
}
$('#' + countId).val(textLength);
}
}
return length;
}
/**
* 이모티콘 제거 (제목/본문 이모티콘 입력 불가 - 자동 삭제)
*/
function stripEmoji(str) {
if (!str) {
return str;
}
return str
.replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, '')
.replace(/[\uFE00-\uFE0F\u200D\u20E3]/g, '');
}
/**
* LMS 제목 Byte 체크 (공백 포함 최대 <?= $lmsSubjectLimit; ?>Byte, 초과분 자동 삭제)
*/
function setSubjectLength() {
var input = $('#subject');
if (input.length === 0) {
return;
}
var limit = <?= $lmsSubjectLimit; ?>;
var text = stripEmoji(input.val());
while (stringToByte(text) > limit) {
text = text.substring(0, text.length - 1);
}
input.val(text);
$('#subjectStringCount').val(stringToByte(text));
}
</script>
 
Admin/share/member_crm_sms.php+8
변경 전member_crm_sms.php
$listHtml[] = '<td class="text-center">' . $sSendFl . '</td>';
$listHtml[] = '<td style="word-break:break-all;word-wrap:break-word;overflow:hidden;" class="multirows">';
if ($data['sendFl'] != 'kakao') {
 
 
 
 
 
 
 
 
$listHtml[] = '<div>' . $data['contents'] . '</div>';
} else {
$listHtml[] = '<div>' . nl2br($data['templateContent']) . '</div>';
 
변경 후member_crm_sms.php
$listHtml[] = '<td class="text-center">' . $sSendFl . '</td>';
$listHtml[] = '<td style="word-break:break-all;word-wrap:break-word;overflow:hidden;" class="multirows">';
if ($data['sendFl'] != 'kakao') {
// LMS 제목 — 있으면 그대로, 없으면 '[제목없음]' 표시(표시 시점 변환). 제목은 LMS 한정.
if ($data['sendFl'] == 'lms') {
$smsSubject = trim($data['subject'] ?? '');
if ($smsSubject === '') {
$smsSubject = '[제목없음]';
}
$listHtml[] = '<div><strong>' . gd_htmlspecialchars($smsSubject) . '</strong></div>';
}
$listHtml[] = '<div>' . $data['contents'] . '</div>';
} else {
$listHtml[] = '<div>' . nl2br($data['templateContent']) . '</div>';
 
Component/CartRemind/CartRemind.php+15
변경 전CartRemind.php
$getCartRemindSend['autoSendTime'] = $cartRemindData['cartRemindAutoSendTime'];
$getCartRemindSend['smsType'] = $cartRemindData['cartRemindSendType'];
$getCartRemindSend['message'] = $cartRemindData['cartRemindSendMessage'];
 
$getCartRemindSend['cartUrl'] = $cartRemindData['cartRemindSendUrl'];
if ($cartRemindData['cartRemindCoupon'] > 0) {
$getCartRemindSend['coupon'] = $cartRemindData['cartRemindCoupon'];
$validator->add('cartRemindCoupon', null, null); // 발송쿠폰
$validator->add('cartRemindSendType', null, true); // 발송타입 (sms,lms)
$validator->add('cartRemindSendMessage', null, true); // 발송메세지
 
 
if ($validator->act($arrData, true) === false) {
throw new \Exception(gd_implode("<br/>", $validator->errors));
// 선택에 따른 값의 초기화를 위한 빈값 제거 - 주석처리 함 - 상태에 따른 빈값 저장(초기화)이 필요한 경우가 존재함.
// $arrData = ArrayUtils::removeEmpty($arrData);
 
 
 
 
 
 
switch (substr($arrData['mode'], 0, 6)) {
case 'insert' : {
// 저장
$validator->add('cartRemindNo', 'number', true); // 장바구니 알림 고유번호
$validator->add('cartRemindSendType', null, true); // 발송타입 (sms,lms)
$validator->add('cartRemindSendMessage', null, true); // 발송메세지
 
 
if ($validator->act($arrData, true) === false) {
throw new \Exception(gd_implode("<br/>", $validator->errors));
// 선택에 따른 값의 초기화를 위한 빈값 제거 - 주석처리 함 - 상태에 따른 빈값 저장(초기화)이 필요한 경우가 존재함.
// $arrData = ArrayUtils::removeEmpty($arrData);
 
 
 
 
 
 
// 수정
$arrBind = $this->db->get_binding(DBTableField::tableCartRemind(), $arrData, 'update', gd_array_keys($arrData), ['cartRemindNo']);
$this->db->bind_param_push($arrBind['bind'], 'i', $arrData['cartRemindNo']);
}
// sms, lms
$smsSendData['sendFl'] = $cartRemindSendData['smsType'];
 
 
 
// ??
$smsSendData['agreeCnt'] = '';
 
변경 후CartRemind.php
$getCartRemindSend['autoSendTime'] = $cartRemindData['cartRemindAutoSendTime'];
$getCartRemindSend['smsType'] = $cartRemindData['cartRemindSendType'];
$getCartRemindSend['message'] = $cartRemindData['cartRemindSendMessage'];
$getCartRemindSend['subject'] = $cartRemindData['cartRemindSendSubject'] ?? '';
$getCartRemindSend['cartUrl'] = $cartRemindData['cartRemindSendUrl'];
if ($cartRemindData['cartRemindCoupon'] > 0) {
$getCartRemindSend['coupon'] = $cartRemindData['cartRemindCoupon'];
$validator->add('cartRemindCoupon', null, null); // 발송쿠폰
$validator->add('cartRemindSendType', null, true); // 발송타입 (sms,lms)
$validator->add('cartRemindSendMessage', null, true); // 발송메세지
$validator->add('cartRemindSendSubject', null, null); // LMS 제목 (선택, lms 시)
 
if ($validator->act($arrData, true) === false) {
throw new \Exception(gd_implode("<br/>", $validator->errors));
// 선택에 따른 값의 초기화를 위한 빈값 제거 - 주석처리 함 - 상태에 따른 빈값 저장(초기화)이 필요한 경우가 존재함.
// $arrData = ArrayUtils::removeEmpty($arrData);
 
// LMS 제목은 LMS 상태에서만 저장(C5). 본문이 SMS면 제목 영역은 저장하지 않음(빈값).
if (gd_isset($arrData['cartRemindSendType']) === 'sms') {
$arrData['cartRemindSendSubject'] = '';
}
 
switch (substr($arrData['mode'], 0, 6)) {
case 'insert' : {
// 저장
$validator->add('cartRemindNo', 'number', true); // 장바구니 알림 고유번호
$validator->add('cartRemindSendType', null, true); // 발송타입 (sms,lms)
$validator->add('cartRemindSendMessage', null, true); // 발송메세지
$validator->add('cartRemindSendSubject', null, null); // LMS 제목 (선택, lms 시)
 
if ($validator->act($arrData, true) === false) {
throw new \Exception(gd_implode("<br/>", $validator->errors));
// 선택에 따른 값의 초기화를 위한 빈값 제거 - 주석처리 함 - 상태에 따른 빈값 저장(초기화)이 필요한 경우가 존재함.
// $arrData = ArrayUtils::removeEmpty($arrData);
 
// LMS 제목은 LMS 상태에서만 저장(C5). 본문이 SMS면 제목 영역은 저장하지 않음(빈값).
if (gd_isset($arrData['cartRemindSendType']) === 'sms') {
$arrData['cartRemindSendSubject'] = '';
}
 
// 수정
$arrBind = $this->db->get_binding(DBTableField::tableCartRemind(), $arrData, 'update', gd_array_keys($arrData), ['cartRemindNo']);
$this->db->bind_param_push($arrBind['bind'], 'i', $arrData['cartRemindNo']);
}
// sms, lms
$smsSendData['sendFl'] = $cartRemindSendData['smsType'];
// LMS 제목 (LMS 발송 시에만 SmsAdmin 에서 사용)
$smsSendData['smsSubject'] = $cartRemindSendData['subject'] ?? '';
 
// ??
$smsSendData['agreeCnt'] = '';
 
Component/Coupon/CouponAdmin.php+3
변경 전CouponAdmin.php
지금 바로 확인하세요!";
}
$validator->add('smsContents', 'required', true); // SMS 발송 내용
 
 
// 전송일 null처리
$arrData['sendDt'] = null;
$smsSendData['smsPoint'] = Sms::getPoint();
// 전송 내용
$smsSendData['smsContents'] = str_replace('rc_memNm', 'memNm', $getData['smsContents']);
 
 
// 치환 코드 그룹
$smsSendData['replaceCodeGroup'] = 'promotion';
// 전송요청 수
 
변경 후CouponAdmin.php
지금 바로 확인하세요!";
}
$validator->add('smsContents', 'required', true); // SMS 발송 내용
$validator->add('smsSubject', null, null); // LMS 제목 (검증 없음, garbageDelete 방지용 등록)
 
// 전송일 null처리
$arrData['sendDt'] = null;
$smsSendData['smsPoint'] = Sms::getPoint();
// 전송 내용
$smsSendData['smsContents'] = str_replace('rc_memNm', 'memNm', $getData['smsContents']);
// LMS 제목 (LMS 발송 시에만 SmsAdmin 에서 사용)
$smsSendData['smsSubject'] = isset($getData['smsSubject']) ? $getData['smsSubject'] : '';
// 치환 코드 그룹
$smsSendData['replaceCodeGroup'] = 'promotion';
// 전송요청 수
 
Component/Database/DBTableField.php+3
변경 전DBTableField.php
['val' => 'cartRemindAutoSendTime', 'typ' => 'i', 'def' => '10'], // 장바구니 알림 자동발송 시 발송 시간
['val' => 'cartRemindSendType', 'typ' => 's', 'def' => 'lms'], // 장바구니 알림 전송 형식 - sms, lms
['val' => 'cartRemindSendMessage', 'typ' => 's', 'def' => '(광고)[{rc_mallNm}] {rc_memNm}님의 장바구니에 상품이 담겨 있습니다. 아래 장바구니 바로가기를 통해 바로 확인하실 수 있습니다. ▶ 장바구니 바로가기: {rc_cartRemindLink}'], // 장바구니 알림 전송 내용
 
['val' => 'cartRemindSendUrl', 'typ' => 's', 'def' => ''], // 장바구니 알림 바로가기 링크
['val' => 'cartRemindInsertAdminId', 'typ' => 's', 'def' => null], // 장바구니 알림 등록자 아이디
['val' => 'managerNo', 'typ' => 'i', 'def' => 0], // 장바구니 알림 등록자 키
['val' => 'smsAutoType', 'typ' => 's', 'def' => null], // SMS 자동발송 수신 종류 (member, admin, provider)
['val' => 'subject', 'typ' => 's', 'def' => null], // SMS 템플릿 제목
['val' => 'contents', 'typ' => 's', 'def' => null], // SMS 템플릿 내용
 
['val' => 'description', 'typ' => 's', 'def' => null], // 설명
['val' => 'isUserBasic', 'typ' => 's', 'def' => 'n'], // 전송타입(user)기본제공여부
['val' => 'modDt', 'typ' => 's', 'def' => null], // 수정일
['val' => 'smsFl', 'typ' => 's', 'def' => 'n'], // sms동시 발송여부 - y:발송 / n:미발송
['val' => 'smsSpamFl', 'typ' => 's', 'def' => 'n'], // 광고성 문구 추가 - y:추가 / n:미추가
['val' => 'smsContents', 'typ' => 's', 'def' => ''], // SMS 발송 내용
 
['val' => 'managerNo', 'typ' => 'i', 'def' => ''], // 등록 관리자 고유번호
['val' => 'deleteFl', 'typ' => 's', 'def' => 'n'], // 삭제 flag - y:삭제 / n:미삭제
['val' => 'sendDt', 'typ' => 's', 'def' => null], // 전송일
 
변경 후DBTableField.php
['val' => 'cartRemindAutoSendTime', 'typ' => 'i', 'def' => '10'], // 장바구니 알림 자동발송 시 발송 시간
['val' => 'cartRemindSendType', 'typ' => 's', 'def' => 'lms'], // 장바구니 알림 전송 형식 - sms, lms
['val' => 'cartRemindSendMessage', 'typ' => 's', 'def' => '(광고)[{rc_mallNm}] {rc_memNm}님의 장바구니에 상품이 담겨 있습니다. 아래 장바구니 바로가기를 통해 바로 확인하실 수 있습니다. ▶ 장바구니 바로가기: {rc_cartRemindLink}'], // 장바구니 알림 전송 내용
['val' => 'cartRemindSendSubject', 'typ' => 's', 'def' => ''], // 장바구니 알림 LMS 제목
['val' => 'cartRemindSendUrl', 'typ' => 's', 'def' => ''], // 장바구니 알림 바로가기 링크
['val' => 'cartRemindInsertAdminId', 'typ' => 's', 'def' => null], // 장바구니 알림 등록자 아이디
['val' => 'managerNo', 'typ' => 'i', 'def' => 0], // 장바구니 알림 등록자 키
['val' => 'smsAutoType', 'typ' => 's', 'def' => null], // SMS 자동발송 수신 종류 (member, admin, provider)
['val' => 'subject', 'typ' => 's', 'def' => null], // SMS 템플릿 제목
['val' => 'contents', 'typ' => 's', 'def' => null], // SMS 템플릿 내용
['val' => 'messageTitle', 'typ' => 's', 'def' => null], // LMS 메시지 제목
['val' => 'description', 'typ' => 's', 'def' => null], // 설명
['val' => 'isUserBasic', 'typ' => 's', 'def' => 'n'], // 전송타입(user)기본제공여부
['val' => 'modDt', 'typ' => 's', 'def' => null], // 수정일
['val' => 'smsFl', 'typ' => 's', 'def' => 'n'], // sms동시 발송여부 - y:발송 / n:미발송
['val' => 'smsSpamFl', 'typ' => 's', 'def' => 'n'], // 광고성 문구 추가 - y:추가 / n:미추가
['val' => 'smsContents', 'typ' => 's', 'def' => ''], // SMS 발송 내용
['val' => 'smsSubject', 'typ' => 's', 'def' => ''], // LMS 제목
['val' => 'managerNo', 'typ' => 'i', 'def' => ''], // 등록 관리자 고유번호
['val' => 'deleteFl', 'typ' => 's', 'def' => 'n'], // 삭제 flag - y:삭제 / n:미삭제
['val' => 'sendDt', 'typ' => 's', 'def' => null], // 전송일
 
Component/Sms/SmsAdmin.php+13
변경 전SmsAdmin.php
$dbData[$autoData[$autoType . 'Mode']][$smsType][$autoCode][$autoType]['sno'] = $autoData[$autoType . 'Sno'];
$dbData[$autoData[$autoType . 'Mode']][$smsType][$autoCode][$autoType]['subject'] = $autoData['subject'];
$dbData[$autoData[$autoType . 'Mode']][$smsType][$autoCode][$autoType]['contents'] = $autoData[$autoType . 'Contents'];
 
// $dbData[$autoData[$autoType . 'Mode']][$smsType][$autoCode][$autoType]['smsType'] = $smsType;
unset($request[$smsType][$autoCode][$autoType . 'Mode']);
unset($request[$smsType][$autoCode][$autoType . 'Sno']);
unset($request[$smsType][$autoCode]['subject']);
unset($request[$smsType][$autoCode][$autoType . 'Contents']);
 
}
}
}
$getData = gd_htmlspecialchars_stripslashes($this->db->query_fetch($strSQL, null, false));
foreach ($getData as $data) {
$setData[$data['smsType']][$data['smsAutoCode']][$data['smsAutoType']]['contents'] = $data['contents'];
 
$setData[$data['smsType']][$data['smsAutoCode']][$data['smsAutoType']]['sno'] = $data['sno'];
}
unset($getData);
foreach ($arrType as $sendType) {
if (isset($setData[$keyType][$val['code']][$sendType]['contents']) === true) {
$smsAutoType[$keyType][$key][$sendType . 'Contents'] = $setData[$keyType][$val['code']][$sendType]['contents'];
 
 
 
$smsAutoType[$keyType][$key][$sendType . 'Mode'] = 'update';
$smsAutoType[$keyType][$key][$sendType . 'Sno'] = $setData[$keyType][$val['code']][$sendType]['sno'];
} else {
$smsAutoType[$keyType][$key][$sendType . 'Contents'] = $val[$sendType . 'Contents'];
 
 
$smsAutoType[$keyType][$key][$sendType . 'Mode'] = 'insert';
$smsAutoType[$keyType][$key][$sendType . 'Sno'] = '';
}
}
if ($receiverData['sendFl'] === 'lms') {
$message = new \Component\Sms\LmsMessage($receiverData['smsContents'], $receiverData['replaceCodeGroup']);
 
 
 
 
 
} else {
$message = new \Component\Sms\SmsMessage($receiverData['smsContents'], $receiverData['replaceCodeGroup']);
}
 
변경 후SmsAdmin.php
$dbData[$autoData[$autoType . 'Mode']][$smsType][$autoCode][$autoType]['sno'] = $autoData[$autoType . 'Sno'];
$dbData[$autoData[$autoType . 'Mode']][$smsType][$autoCode][$autoType]['subject'] = $autoData['subject'];
$dbData[$autoData[$autoType . 'Mode']][$smsType][$autoCode][$autoType]['contents'] = $autoData[$autoType . 'Contents'];
$dbData[$autoData[$autoType . 'Mode']][$smsType][$autoCode][$autoType]['messageTitle'] = gd_isset($autoData[$autoType . 'MessageTitle'], '');
// $dbData[$autoData[$autoType . 'Mode']][$smsType][$autoCode][$autoType]['smsType'] = $smsType;
unset($request[$smsType][$autoCode][$autoType . 'Mode']);
unset($request[$smsType][$autoCode][$autoType . 'Sno']);
unset($request[$smsType][$autoCode]['subject']);
unset($request[$smsType][$autoCode][$autoType . 'Contents']);
unset($request[$smsType][$autoCode][$autoType . 'MessageTitle']);
}
}
}
$getData = gd_htmlspecialchars_stripslashes($this->db->query_fetch($strSQL, null, false));
foreach ($getData as $data) {
$setData[$data['smsType']][$data['smsAutoCode']][$data['smsAutoType']]['contents'] = $data['contents'];
$setData[$data['smsType']][$data['smsAutoCode']][$data['smsAutoType']]['messageTitle'] = $data['messageTitle'];
$setData[$data['smsType']][$data['smsAutoCode']][$data['smsAutoType']]['sno'] = $data['sno'];
}
unset($getData);
foreach ($arrType as $sendType) {
if (isset($setData[$keyType][$val['code']][$sendType]['contents']) === true) {
$smsAutoType[$keyType][$key][$sendType . 'Contents'] = $setData[$keyType][$val['code']][$sendType]['contents'];
$messageTitle = gd_isset($setData[$keyType][$val['code']][$sendType]['messageTitle'], '');
$smsAutoType[$keyType][$key][$sendType . 'MessageTitle'] = $messageTitle;
$smsAutoType[$keyType][$key][$sendType . 'Title'] = $messageTitle; // CRM 뷰 호환(messageTitle 일원화)
$smsAutoType[$keyType][$key][$sendType . 'Mode'] = 'update';
$smsAutoType[$keyType][$key][$sendType . 'Sno'] = $setData[$keyType][$val['code']][$sendType]['sno'];
} else {
$smsAutoType[$keyType][$key][$sendType . 'Contents'] = $val[$sendType . 'Contents'];
$smsAutoType[$keyType][$key][$sendType . 'MessageTitle'] = '';
$smsAutoType[$keyType][$key][$sendType . 'Title'] = ''; // CRM 뷰 호환
$smsAutoType[$keyType][$key][$sendType . 'Mode'] = 'insert';
$smsAutoType[$keyType][$key][$sendType . 'Sno'] = '';
}
}
if ($receiverData['sendFl'] === 'lms') {
$message = new \Component\Sms\LmsMessage($receiverData['smsContents'], $receiverData['replaceCodeGroup']);
// LMS 제목 (미입력 시 빈 값)
// 튜닝 상점 대비: 구버전 SmsSender(setSubject 미보유)에서 발송 중단 방지
if (method_exists($transport, 'setSubject')) {
$transport->setSubject($receiverData['smsSubject'] ?? '');
}
} else {
$message = new \Component\Sms\SmsMessage($receiverData['smsContents'], $receiverData['replaceCodeGroup']);
}
 
Component/Sms/SmsAuto.php+6-1
변경 전SmsAuto.php
{
$logger = $this->logger;
$binds = [];
$this->db->strField = 'smsType, smsAutoType, contents, subject';
$this->db->strJoin = DB_SMS_CONTENTS;
$this->db->strWhere = 'smsType= ? AND smsAutoCode = ? AND smsAutoType IN (\'' . gd_implode('\', \'', $wheres) . '\') AND contents != \'\' AND contents IS NOT NULL';
$this->db->bind_param_push($binds, 's', $this->smsType);
}
$transport->setSmsPoint(Sms::getPoint());
$transport->setMessage($message);
 
 
 
 
 
$transport->setSmsType($item['smsType']);
$transport->setReceiver($receiverData);
$transport->setSendDate($this->smsAutoSendDate);
 
변경 후SmsAuto.php
{
$logger = $this->logger;
$binds = [];
$this->db->strField = 'smsType, smsAutoType, contents, subject, messageTitle';
$this->db->strJoin = DB_SMS_CONTENTS;
$this->db->strWhere = 'smsType= ? AND smsAutoCode = ? AND smsAutoType IN (\'' . gd_implode('\', \'', $wheres) . '\') AND contents != \'\' AND contents IS NOT NULL';
$this->db->bind_param_push($binds, 's', $this->smsType);
}
$transport->setSmsPoint(Sms::getPoint());
$transport->setMessage($message);
// LMS 제목 (설정된 자동발송 문구 제목 - LMS 발송 시에만 SmsSender 에서 사용, 미입력 시 [제목없음])
// 튜닝 상점 대비: 구버전 SmsSender(setSubject 미보유)에서 발송 중단 방지
if (method_exists($transport, 'setSubject')) {
$transport->setSubject($item['messageTitle'] ?? '');
}
$transport->setSmsType($item['smsType']);
$transport->setReceiver($receiverData);
$transport->setSendDate($this->smsAutoSendDate);
 
Component/Sms/SmsSender.php+32-1
변경 전SmsSender.php
protected $isThrowPasswordException = false;
/** @var string|null SMS 발송 트리거 타입 (예: FALLBACK) */
protected $sendTriggerType;
 
 
/** @var string SMS 대량발송 파일 경로 */
private $_smsLargeFilePath;
/** @var object SMS 대량발송 TXT 파일 생성 로거 */
];
//@formatter:on
if ($this->_isLms()) {
$this->sendSms['subject'] = '';
}
if ($this->sendTriggerType !== null) {
$this->sendSms['sendTriggerType'] = $this->sendTriggerType;
];
if ($this->_isLms()) {
$this->smsLog['sendFl'] = 'lms';
 
}
}
$this->sendTriggerType = $sendTriggerType;
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
/**
* @param bool $isThrowPasswordException
*/
 
변경 후SmsSender.php
protected $isThrowPasswordException = false;
/** @var string|null SMS 발송 트리거 타입 (예: FALLBACK) */
protected $sendTriggerType;
/** @var string|null LMS 제목 */
protected $subject;
/** @var string SMS 대량발송 파일 경로 */
private $_smsLargeFilePath;
/** @var object SMS 대량발송 TXT 파일 생성 로거 */
];
//@formatter:on
if ($this->_isLms()) {
$this->sendSms['subject'] = $this->resolveSubject();
}
if ($this->sendTriggerType !== null) {
$this->sendSms['sendTriggerType'] = $this->sendTriggerType;
];
if ($this->_isLms()) {
$this->smsLog['sendFl'] = 'lms';
$this->smsLog['subject'] = trim(preg_replace('/#?\{[^}]*\}/u', '', (string) $this->subject)); // 저장은 치환자 제거한 원문(빈값 유지), [제목없음] 변환은 발송/표시 시점만
}
}
$this->sendTriggerType = $sendTriggerType;
}
/**
* LMS 제목 설정 (LMS 발송 시에만 사용)
*
* @param string|null $subject
*/
public function setSubject(?string $subject): void
{
$this->subject = $subject;
}
/**
* 실발송용 LMS 제목 계산
* - 제목 치환자({..}/#{..})는 미지원이므로 공란 처리
* - LMS 인데 제목이 없으면(또는 치환자만 있어 공란) '[제목없음]' 으로 발송
*
* @return string
*/
protected function resolveSubject(): string
{
// 치환자 제거 (제목 영역은 치환자 미지원 → 실발송 시 공란 처리)
$subject = trim(preg_replace('/#?\{[^}]*\}/u', '', (string) $this->subject));
if ($subject === '') {
return '[제목없음]';
}
return $subject;
}
/**
* @param bool $isThrowPasswordException
*/
 
Controller/Admin/Crm/LayerPreviewMobileSendController.php+14
변경 전LayerPreviewMobileSendController.php
switch ($sendMethod) {
case 'SMS':
$smsData = $payload['smsLmsRequest'] ?? [];
 
$this->setData('mainContents', $smsData['content'] ?? '');
$this->setData('showAdWarningText', 'n');
$previewContents = 'crm/preview_mobile_send/layer_preview_mobile_send_sms.php';
 
$this->setData('friendtalk', $friendTalkData);
$this->setData('alternativeContents', $friendTalkData['alternativeInfo']['content'] ?? '');
 
 
 
 
 
 
$this->setData('showAdWarningText', $showAdWarningText);
$previewContents = 'crm/preview_mobile_send/layer_preview_mobile_send_kakao_friendtalk.php';
break;
$this->setData('template', $previewMeta);
$this->setData('hasAddChannelButton', $hasAddChannelButton);
$this->setData('alternativeContents', $alimTalkData['alternativeInfo']['content'] ?? '');
 
$this->setData('showAdWarningText', 'n');
$previewContents = 'crm/preview_mobile_send/layer_preview_mobile_send_kakao_alimtalk.php';
break;
$this->setData('myappPayload', $myappPushData);
$this->setData('showAdWarningText', $showAdWarningText);
$this->setData('alternativeContents', $payload['myappRequest']['alternativeInfo']['content'] ?? '');
 
 
 
 
 
 
$previewContents = 'crm/preview_mobile_send/layer_preview_mobile_send_myapp_push.php';
break;
}
 
변경 후LayerPreviewMobileSendController.php
switch ($sendMethod) {
case 'SMS':
$smsData = $payload['smsLmsRequest'] ?? [];
$this->setData('mainTitle', $smsData['title'] ?? '');
$this->setData('mainContents', $smsData['content'] ?? '');
$this->setData('showAdWarningText', 'n');
$previewContents = 'crm/preview_mobile_send/layer_preview_mobile_send_sms.php';
 
$this->setData('friendtalk', $friendTalkData);
$this->setData('alternativeContents', $friendTalkData['alternativeInfo']['content'] ?? '');
// 대체 제목 미입력 시 메인 메시지 타이틀(친구톡 헤더)이 있으면 카피하여 표기 (미리보기 전용)
$alternativeTitle = $friendTalkData['alternativeInfo']['title'] ?? '';
if ($alternativeTitle === '' || $alternativeTitle === null) {
$alternativeTitle = $friendTalkData['header'] ?? '';
}
$this->setData('alternativeTitle', $alternativeTitle);
$this->setData('showAdWarningText', $showAdWarningText);
$previewContents = 'crm/preview_mobile_send/layer_preview_mobile_send_kakao_friendtalk.php';
break;
$this->setData('template', $previewMeta);
$this->setData('hasAddChannelButton', $hasAddChannelButton);
$this->setData('alternativeContents', $alimTalkData['alternativeInfo']['content'] ?? '');
$this->setData('alternativeTitle', $alimTalkData['alternativeInfo']['title'] ?? '');
$this->setData('showAdWarningText', 'n');
$previewContents = 'crm/preview_mobile_send/layer_preview_mobile_send_kakao_alimtalk.php';
break;
$this->setData('myappPayload', $myappPushData);
$this->setData('showAdWarningText', $showAdWarningText);
$this->setData('alternativeContents', $payload['myappRequest']['alternativeInfo']['content'] ?? '');
// 대체 제목 미입력 시 메인 메시지 타이틀(푸시 제목)이 있으면 카피하여 표기 (미리보기 전용)
$alternativeTitle = $payload['myappRequest']['alternativeInfo']['title'] ?? '';
if ($alternativeTitle === '' || $alternativeTitle === null) {
$alternativeTitle = $myappPushData['pushSubject'] ?? '';
}
$this->setData('alternativeTitle', $alternativeTitle);
$previewContents = 'crm/preview_mobile_send/layer_preview_mobile_send_myapp_push.php';
break;
}
 
Controller/Admin/Crm/MobileSend/LayerKakaoFriendtalkContentSettingController.php+2
변경 전LayerKakaoFriendtalkContentSettingController.php
$friendtalkRequest = $defaultCampaignRequest['kakaoFriendtalkRequest'] ?? [];
$initialTextContent = $friendtalkRequest['text']['content'] ?? '';
$initialAlternativeMessage = $defaultCampaignRequest['smsLmsRequest']['content'] ?? '';
 
 
$this->setData('is080RejectAvailable', $is080RejectAvailable);
$this->setData('campaignMessageTypes', CampaignMessageType::cases());
$this->setData('friendtalkRequest', $friendtalkRequest);
$this->setData('initialTextContent', $initialTextContent);
$this->setData('initialAlternativeMessage', $initialAlternativeMessage);
 
$this->getView()->setDefine('layout', 'layout_layer.php');
}
}
 
변경 후LayerKakaoFriendtalkContentSettingController.php
$friendtalkRequest = $defaultCampaignRequest['kakaoFriendtalkRequest'] ?? [];
$initialTextContent = $friendtalkRequest['text']['content'] ?? '';
$initialAlternativeMessage = $defaultCampaignRequest['smsLmsRequest']['content'] ?? '';
$initialAlternativeTitle = $defaultCampaignRequest['smsLmsRequest']['title'] ?? '';
 
$this->setData('is080RejectAvailable', $is080RejectAvailable);
$this->setData('campaignMessageTypes', CampaignMessageType::cases());
$this->setData('friendtalkRequest', $friendtalkRequest);
$this->setData('initialTextContent', $initialTextContent);
$this->setData('initialAlternativeMessage', $initialAlternativeMessage);
$this->setData('initialAlternativeTitle', $initialAlternativeTitle);
$this->getView()->setDefine('layout', 'layout_layer.php');
}
}
 
Controller/Admin/Crm/MobileSend/LayerMobileSendSaveSmsTemplateController.php+2
변경 전LayerMobileSendSaveSmsTemplateController.php
{
$request = Request::post()->toArray();
$contents = $request['contents'] ?? '';
 
 
$categories = SmsTemplateCategory::getFindOptions();
 
$this->setData('categories', $categories);
$this->setData('contents', $contents);
 
 
$this->getView()->setDefine('layout', 'layout_layer.php');
}
 
변경 후LayerMobileSendSaveSmsTemplateController.php
{
$request = Request::post()->toArray();
$contents = $request['contents'] ?? '';
$messageTitle = $request['messageTitle'] ?? '';
 
$categories = SmsTemplateCategory::getFindOptions();
 
$this->setData('categories', $categories);
$this->setData('contents', $contents);
$this->setData('messageTitle', $messageTitle);
 
$this->getView()->setDefine('layout', 'layout_layer.php');
}
 
Controller/Admin/Crm/MobileSend/LayerMyappPushContentSettingController.php+2
변경 전LayerMyappPushContentSettingController.php
$initialTitle = $myappRequest['title'] ?? '';
$initialMessage = $myappRequest['content'] ?? '';
$initialAlternativeMessage = $recipeContext['defaultCampaignRequest']['smsLmsRequest']['content'] ?? '';
 
 
$this->setData('is080RejectAvailable', $is080RejectAvailable);
$this->setData('myappPushSendConditions', MyappPushSendCondition::cases());
$this->setData('initialTitle', $initialTitle);
$this->setData('initialMessage', $initialMessage);
$this->setData('initialAlternativeMessage', $initialAlternativeMessage);
 
$this->getView()->setDefine('layout', 'layout_layer.php');
}
}
 
변경 후LayerMyappPushContentSettingController.php
$initialTitle = $myappRequest['title'] ?? '';
$initialMessage = $myappRequest['content'] ?? '';
$initialAlternativeMessage = $recipeContext['defaultCampaignRequest']['smsLmsRequest']['content'] ?? '';
$initialAlternativeTitle = $recipeContext['defaultCampaignRequest']['smsLmsRequest']['title'] ?? '';
 
$this->setData('is080RejectAvailable', $is080RejectAvailable);
$this->setData('myappPushSendConditions', MyappPushSendCondition::cases());
$this->setData('initialTitle', $initialTitle);
$this->setData('initialMessage', $initialMessage);
$this->setData('initialAlternativeMessage', $initialAlternativeMessage);
$this->setData('initialAlternativeTitle', $initialAlternativeTitle);
$this->getView()->setDefine('layout', 'layout_layer.php');
}
}
 
Controller/Admin/Crm/MobileSend/LayerSmsContentSettingController.php+2
변경 전LayerSmsContentSettingController.php
$recipeContext = $this->resolveRecipeContext();
$isRecipeContext = $this->hasRecipeContext();
$initialMessage = $recipeContext['defaultCampaignRequest']['smsLmsRequest']['content'] ?? '';
 
 
$this->setData('is080RejectAvailable', $is080RejectAvailable);
$this->setData('isRecipeContext', $isRecipeContext);
$this->setData('initialMessage', $initialMessage);
 
$this->getView()->setDefine('layout', 'layout_layer.php');
}
}
 
변경 후LayerSmsContentSettingController.php
$recipeContext = $this->resolveRecipeContext();
$isRecipeContext = $this->hasRecipeContext();
$initialMessage = $recipeContext['defaultCampaignRequest']['smsLmsRequest']['content'] ?? '';
$initialTitle = $recipeContext['defaultCampaignRequest']['smsLmsRequest']['title'] ?? '';
 
$this->setData('is080RejectAvailable', $is080RejectAvailable);
$this->setData('isRecipeContext', $isRecipeContext);
$this->setData('initialMessage', $initialMessage);
$this->setData('initialTitle', $initialTitle);
$this->getView()->setDefine('layout', 'layout_layer.php');
}
}
 
Controller/Admin/Crm/Sms/SmsTemplatePsController.php+1
변경 전SmsTemplatePsController.php
'templateCategory' => $category->value,
'templateTitle' => $subject,
'templateMessageContent' => $contents,
 
]);
 
$sno = $service->setSmsContents($templateDto);
 
변경 후SmsTemplatePsController.php
'templateCategory' => $category->value,
'templateTitle' => $subject,
'templateMessageContent' => $contents,
'templateMessageTitle' => trim($request['messageTitle'] ?? ''),
]);
 
$sno = $service->setSmsContents($templateDto);
 
Controller/Admin/Member/SmsAutoController.php+1
변경 전SmsAutoController.php
// SMS 포인트 Sync
Sms::saveSmsPoint();
$memberJoin = ComponentUtils::getPolicy('member.join');
 
$this->setData('smsAutoList', Sms::SMS_AUTO_RECEIVE_LIST);
$this->setData('smsAutoOrderPeriod', Sms::SMS_AUTO_ORDER_PERIOD);
$this->setData('smsAutoOrderAfterPeriod', Sms::SMS_ORDER_AFTER_PERIOD);
 
변경 후SmsAutoController.php
// SMS 포인트 Sync
Sms::saveSmsPoint();
$memberJoin = ComponentUtils::getPolicy('member.join');
$this->setData('lmsSubjectLimit', defined(Sms::class . '::LMS_SUBJECT_LIMIT') ? Sms::LMS_SUBJECT_LIMIT : 40);
$this->setData('smsAutoList', Sms::SMS_AUTO_RECEIVE_LIST);
$this->setData('smsAutoOrderPeriod', Sms::SMS_AUTO_ORDER_PERIOD);
$this->setData('smsAutoOrderAfterPeriod', Sms::SMS_ORDER_AFTER_PERIOD);
 
Controller/Admin/Member/SmsLogPsController.php+25-14
변경 전SmsLogPsController.php
try {
$requestParams = $request->post()->all();
$godoSms = new GodoSmsServerApi();
$smsLog = $componentSmsLog->getSmsLog('*', $requestParams['smsLogSno']);
 
 
 
 
 
 
 
 
 
 
 
 
if ($smsLog['replaceCodeType'] == 'none') {
// SMS 결과 수신 처리
if ($godoSms->smsReserveChange($requestParams['sno'], 'modify', $requestParams['contents']) !== true) {
throw new LayerException(__('수정이 실패되었습니다.'));
} else {
$componentSmsLog->editContents($requestParams);
$this->json(__('수정되었습니다.'));
}
} else {
// SMS 결과 수신 처리
if ($godoSms->smsSendListReserveChange($requestParams['sno'], 'modify', $requestParams['contents']) !== true) {
throw new LayerException(__('수정이 실패되었습니다.'));
} else {
$componentSmsLog->editContents($requestParams);
$this->json(__('수정되었습니다.'));
}
 
 
 
 
 
}
 
} catch (LayerException $e) {
$this->json($e->getMessage());
}
 
변경 후SmsLogPsController.php
try {
$requestParams = $request->post()->all();
$godoSms = new GodoSmsServerApi();
// 발송내역 고유번호 (수정 레이어는 sno 로 전달)
$smsLogSno = gd_isset($requestParams['smsLogSno'], gd_isset($requestParams['sno']));
$smsLog = $componentSmsLog->getSmsLog('*', $smsLogSno);
if (empty($smsLog)) {
throw new LayerException(__('발송내역을 찾을 수 없습니다.'));
}
// 예약변경 API 는 DB 의 contents/subject 를 읽어 외부(고도 SMS 서버)로 전송하므로
// 외부 예약 메시지에 수정 내용이 반영되도록 DB 를 먼저 갱신한다.
$requestParams['sno'] = $smsLogSno;
$componentSmsLog->editContents($requestParams);
if ($smsLog['replaceCodeType'] == 'none') {
$result = $godoSms->smsReserveChange($smsLogSno, 'modify');
 
 
 
 
 
 
} else {
// 치환코드 발송건은 수신자별로 재구성되므로 해당 발송내역의 발송리스트 sno 목록을 전달한다.
$smsSendList = $componentSmsLog->getSmsSendList(['smsLogSno' => $smsLogSno]);
$sendListSno = [];
foreach ((array) gd_isset($smsSendList['data'], []) as $sendListRow) {
$sendListSno[] = $sendListRow['sno'];
 
}
$result = $godoSms->smsSendListReserveChange($smsLogSno, 'modify', $sendListSno);
}
if ($result !== true) {
throw new LayerException(__('수정이 실패되었습니다.'));
}
$this->json(__('수정되었습니다.'));
} catch (LayerException $e) {
$this->json($e->getMessage());
}
 
Controller/Admin/Member/SmsSendController.php+4
변경 전SmsSendController.php
'board' => '게시판',
];
$smsContents = '';
 
$receiveTotal = $rejectCount = 0;
$receiverData = $reSenderData = [];
$popupMode = false;
$componentSmsLog = \App::load('Component\\Sms\\SmsLog');
$smsLog = $componentSmsLog->getSmsLog('*', $request->post()->get('smsLogSno')); // 재전송 문자내역 조회
$smsContents = StringUtils::htmlSpecialCharsStripSlashes($smsLog['contents']); // 재전송 메시지 설정
 
$smsSendList = $componentSmsLog->getSmsSendList($request->post()->all())['data']; // 재전송 문자내역 발송내역 조회
$hasGuest = $componentSmsLog->hasGuestBySendList($smsSendList); // 발송내역 중 비회원 발송내역 확인
$isReSendAll = $request->post()->get('mode', '') == 'resend_all_member';
$this->setData('sms080Policy', ComponentUtils::getPolicy('sms.sms080'));
$this->setData('smsStringLimit', Sms::SMS_STRING_LIMIT);
$this->setData('lmsStringLimit', Sms::LMS_STRING_LIMIT);
 
$this->setData('smsForbidTime', Sms::SMS_FORBID_TIME);
$this->setData('lmsPoint', Sms::LMS_POINT);
$this->setData('smsCallNum', $smsCallNum);
$this->setData('receiverMode', $receiverMode);
$this->setData('popupMode', $popupMode);
$this->setData('smsContents', $smsContents);
 
$this->setData('reSenderData', $reSenderData);
$this->setData('receiveTotal', $receiveTotal);
$this->setData('rejectCount', $rejectCount);
 
변경 후SmsSendController.php
'board' => '게시판',
];
$smsContents = '';
$smsSubject = '';
$receiveTotal = $rejectCount = 0;
$receiverData = $reSenderData = [];
$popupMode = false;
$componentSmsLog = \App::load('Component\\Sms\\SmsLog');
$smsLog = $componentSmsLog->getSmsLog('*', $request->post()->get('smsLogSno')); // 재전송 문자내역 조회
$smsContents = StringUtils::htmlSpecialCharsStripSlashes($smsLog['contents']); // 재전송 메시지 설정
$smsSubject = StringUtils::htmlSpecialCharsStripSlashes($smsLog['subject'] ?? ''); // 재전송 LMS 제목 복원
$smsSendList = $componentSmsLog->getSmsSendList($request->post()->all())['data']; // 재전송 문자내역 발송내역 조회
$hasGuest = $componentSmsLog->hasGuestBySendList($smsSendList); // 발송내역 중 비회원 발송내역 확인
$isReSendAll = $request->post()->get('mode', '') == 'resend_all_member';
$this->setData('sms080Policy', ComponentUtils::getPolicy('sms.sms080'));
$this->setData('smsStringLimit', Sms::SMS_STRING_LIMIT);
$this->setData('lmsStringLimit', Sms::LMS_STRING_LIMIT);
$this->setData('lmsSubjectLimit', defined(Sms::class . '::LMS_SUBJECT_LIMIT') ? Sms::LMS_SUBJECT_LIMIT : 40);
$this->setData('smsForbidTime', Sms::SMS_FORBID_TIME);
$this->setData('lmsPoint', Sms::LMS_POINT);
$this->setData('smsCallNum', $smsCallNum);
$this->setData('receiverMode', $receiverMode);
$this->setData('popupMode', $popupMode);
$this->setData('smsContents', $smsContents);
$this->setData('smsSubject', $smsSubject);
$this->setData('reSenderData', $reSenderData);
$this->setData('receiveTotal', $receiveTotal);
$this->setData('rejectCount', $rejectCount);
 
Controller/Admin/Promotion/CartRemindRegistController.php+1
변경 전CartRemindRegistController.php
$this->setData('selected', $selected);
$this->setData('smsStringLimit', Sms::SMS_STRING_LIMIT);
$this->setData('lmsStringLimit', Sms::LMS_STRING_LIMIT);
 
$this->setData('lmsPoint', Sms::LMS_POINT);
$this->setData('sms080Policy', ComponentUtils::getPolicy('sms.sms080'));
$this->setData('commerceSmsRefusalIntroUrl', ConfigUrlUtils::getNhnCommerceEchostUrl('sms-refusal-intro'));
 
변경 후CartRemindRegistController.php
$this->setData('selected', $selected);
$this->setData('smsStringLimit', Sms::SMS_STRING_LIMIT);
$this->setData('lmsStringLimit', Sms::LMS_STRING_LIMIT);
$this->setData('lmsSubjectLimit', defined(Sms::class . '::LMS_SUBJECT_LIMIT') ? Sms::LMS_SUBJECT_LIMIT : 40);
$this->setData('lmsPoint', Sms::LMS_POINT);
$this->setData('sms080Policy', ComponentUtils::getPolicy('sms.sms080'));
$this->setData('commerceSmsRefusalIntroUrl', ConfigUrlUtils::getNhnCommerceEchostUrl('sms-refusal-intro'));
 
Controller/Admin/Promotion/ComebackCouponRegistController.php+1
변경 전ComebackCouponRegistController.php
]);
$this->setData('smsStringLimit', Sms::SMS_STRING_LIMIT);
$this->setData('lmsStringLimit', Sms::LMS_STRING_LIMIT);
 
$this->setData('smsForbidTime', Sms::SMS_FORBID_TIME);
$this->setData('lmsPoint', Sms::LMS_POINT);
$this->setData('checkMode', gd_isset($checkMode));
 
변경 후ComebackCouponRegistController.php
]);
$this->setData('smsStringLimit', Sms::SMS_STRING_LIMIT);
$this->setData('lmsStringLimit', Sms::LMS_STRING_LIMIT);
$this->setData('lmsSubjectLimit', defined(Sms::class . '::LMS_SUBJECT_LIMIT') ? Sms::LMS_SUBJECT_LIMIT : 40);
$this->setData('smsForbidTime', Sms::SMS_FORBID_TIME);
$this->setData('lmsPoint', Sms::LMS_POINT);
$this->setData('checkMode', gd_isset($checkMode));
 
Controller/Admin/Promotion/LayerCartRemindMessageController.php+2-1
변경 전LayerCartRemindMessageController.php
{
$cartRemindNo = Request::get()->get('cartRemindNo');
$cartRemind = new CartRemind();
$cartRemindData = $cartRemind->getCartRemindInfo($cartRemindNo,'cartRemindNo, cartRemindSendType, cartRemindSendMessage');
 
$this->setData('cartRemindData', $cartRemindData);
$this->setData('smsStringLimit', Sms::SMS_STRING_LIMIT);
$this->setData('lmsStringLimit', Sms::LMS_STRING_LIMIT);
 
$this->setData('lmsPoint', Sms::LMS_POINT);
$this->getView()->setDefine('layout', 'layout_layer.php');
}
 
변경 후LayerCartRemindMessageController.php
{
$cartRemindNo = Request::get()->get('cartRemindNo');
$cartRemind = new CartRemind();
$cartRemindData = $cartRemind->getCartRemindInfo($cartRemindNo,'cartRemindNo, cartRemindSendType, cartRemindSendMessage, cartRemindSendSubject');
 
$this->setData('cartRemindData', $cartRemindData);
$this->setData('smsStringLimit', Sms::SMS_STRING_LIMIT);
$this->setData('lmsStringLimit', Sms::LMS_STRING_LIMIT);
$this->setData('lmsSubjectLimit', defined(Sms::class . '::LMS_SUBJECT_LIMIT') ? Sms::LMS_SUBJECT_LIMIT : 40);
$this->setData('lmsPoint', Sms::LMS_POINT);
$this->getView()->setDefine('layout', 'layout_layer.php');
}
 
Controller/Admin/Share/LayerStandbySmsController.php+2-1
변경 전LayerStandbySmsController.php
{
/** @var \Bundle\Component\Sms\SmsLog $smsLog */
$smsLog = App::load('\\Component\\Sms\\SmsLog');
$data = $smsLog->getSmsLog('sno, sendFl, contents, contentsMask', Request::get()->get('sno'));
$this->getView()->setDefine('layout', 'layout_layer.php');
$this->setData('data', gd_htmlspecialchars_stripslashes($data));
$this->setData('smsStringLimit', Sms::SMS_STRING_LIMIT);
$this->setData('lmsStringLimit', Sms::LMS_STRING_LIMIT);
 
$this->setData('smsForbidTime', Sms::SMS_FORBID_TIME);
$this->setData('lmsPoint', Sms::LMS_POINT);
}
 
변경 후LayerStandbySmsController.php
{
/** @var \Bundle\Component\Sms\SmsLog $smsLog */
$smsLog = App::load('\\Component\\Sms\\SmsLog');
$data = $smsLog->getSmsLog('sno, sendFl, subject, contents, contentsMask', Request::get()->get('sno'));
$this->getView()->setDefine('layout', 'layout_layer.php');
$this->setData('data', gd_htmlspecialchars_stripslashes($data));
$this->setData('smsStringLimit', Sms::SMS_STRING_LIMIT);
$this->setData('lmsStringLimit', Sms::LMS_STRING_LIMIT);
$this->setData('lmsSubjectLimit', defined(Sms::class . '::LMS_SUBJECT_LIMIT') ? Sms::LMS_SUBJECT_LIMIT : 40);
$this->setData('smsForbidTime', Sms::SMS_FORBID_TIME);
$this->setData('lmsPoint', Sms::LMS_POINT);
}