first commit 2
This commit is contained in:
@@ -0,0 +1,297 @@
|
||||
<?php
|
||||
if (!defined('_GNUBOARD_')) exit;
|
||||
|
||||
/**
|
||||
* rb.board.core.journal :: write.skin.php
|
||||
* '저널' 타입 전용 글쓰기 폼
|
||||
*/
|
||||
|
||||
// 스킨 CSS 로드
|
||||
$_skin_url = G5_THEME_URL . '/skin/board/rb.board.core.journal';
|
||||
add_stylesheet('<link rel="stylesheet" href="' . $_skin_url . '/style.css?ver=' . G5_SERVER_TIME . '">', 0);
|
||||
|
||||
$field_map = array(
|
||||
'summary' => 'wr_1',
|
||||
'featured' => 'wr_10',
|
||||
'main_display' => 'wr_8', // 💡 [추가] 메인 화면 노출 필드 매핑
|
||||
);
|
||||
$ebook_link_field = 'wr_link1';
|
||||
$cfg_write = isset($board_config['write']) ? $board_config['write'] : array();
|
||||
|
||||
// 💡 [추가] 지정 최신글 개수 확인
|
||||
$featured_count = 0;
|
||||
if ($is_admin) {
|
||||
$sql = " select count(*) as cnt from {$write_table} where {$field_map['featured']} = 'Y' ";
|
||||
// 수정 모드이고, 현재 글이 이미 지정 최신글이라면 개수에서 제외하지 않음 (이미 포함되어 있으므로)
|
||||
// 하지만 로직상 '현재 체크되어 있지 않은데 체크하려는 경우'를 막아야 하므로,
|
||||
// DB에 저장된 총 개수를 가져오고, JS에서 판단하는 것이 좋음.
|
||||
$row = sql_fetch($sql);
|
||||
$featured_count = $row['cnt'];
|
||||
}
|
||||
?>
|
||||
|
||||
<style>
|
||||
/* 에디터 토글 버튼 스타일 */
|
||||
.editor-toggle-buttons {
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
}
|
||||
.btn-editor-toggle {
|
||||
/*padding: 6px 12px;*/
|
||||
font-size: 13px;
|
||||
border: 1px solid #ddd;
|
||||
background-color: #f8f9fa;
|
||||
color: #555;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.btn-editor-toggle:hover {
|
||||
background-color: #e9ecef;
|
||||
}
|
||||
.btn-editor-toggle.active {
|
||||
background-color: #4a90e2;
|
||||
color: #fff;
|
||||
border-color: #4a90e2;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="board-write-container">
|
||||
<form name="fwrite" id="fwrite" action="<?php echo $action_url ?>" onsubmit="return fwrite_submit(this);" method="post" enctype="multipart/form-data" autocomplete="off" novalidate>
|
||||
<input type="hidden" name="uid" value="<?php echo get_uniqid(); ?>">
|
||||
<input type="hidden" name="w" value="<?php echo $w ?>"><input type="hidden" name="bo_table" value="<?php echo $bo_table ?>"><input type="hidden" name="wr_id" value="<?php echo $wr_id ?>"><input type="hidden" name="sca" value="<?php echo $sca ?>"><input type="hidden" name="sfl" value="<?php echo $sfl ?>"><input type="hidden" name="stx" value="<?php echo $stx ?>"><input type="hidden" name="spt" value="<?php echo $spt ?>"><input type="hidden" name="sst" value="<?php echo $sst ?>"><input type="hidden" name="sod" value="<?php echo $sod ?>"><input type="hidden" name="page" value="<?php echo $page ?>">
|
||||
|
||||
<!-- 💡 [핵심] HTML 에디터 사용 여부를 서버에 알리기 위한 필드 -->
|
||||
<input type="hidden" name="html" value="<?php echo $html ?>">
|
||||
|
||||
<div class="write-form-group">
|
||||
<label for="wr_subject" class="form-label">제목<span class="required">*</span></label>
|
||||
<input type="text" name="wr_subject" value="<?php echo $subject ?>" id="wr_subject" required class="form-control" placeholder="제목을 입력하세요">
|
||||
</div>
|
||||
|
||||
<?php if ($is_category): ?>
|
||||
<div class="write-form-group">
|
||||
<label for="ca_name" class="form-label">카테고리<span class="required">*</span></label>
|
||||
<select name="ca_name" id="ca_name" required class="form-control"><option value="">선택하세요</option><?php echo $category_option ?></select>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($cfg_write['use_summary'])): ?>
|
||||
<div class="write-form-group">
|
||||
<label for="<?php echo $field_map['summary']; ?>" class="form-label"><?php echo $cfg_write['summary_label'] ?: '요약'; ?></label>
|
||||
<textarea name="<?php echo $field_map['summary']; ?>" id="<?php echo $field_map['summary']; ?>" class="form-control" rows="3" placeholder="<?php echo $cfg_write['summary_placeholder']; ?>"><?php echo $write[$field_map['summary']]; ?></textarea>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="write-form-group">
|
||||
<label for="wr_content" class="form-label">내용</label>
|
||||
<div class="editor-toggle-buttons">
|
||||
<button type="button" class="btn btn-sm btn-editor-toggle <?php echo $is_dhtml_editor ? 'active' : ''; ?>" data-editor-type="dhtml">HTML 에디터</button>
|
||||
<button type="button" class="btn btn-sm btn-editor-toggle <?php echo $is_dhtml_editor ? '' : 'active'; ?>" data-editor-type="text">텍스트 에디터</button>
|
||||
</div>
|
||||
|
||||
<!-- HTML 에디터 영역 -->
|
||||
<div id="dhtml-editor-area" style="display: <?php echo $is_dhtml_editor ? 'block' : 'none'; ?>;">
|
||||
<?php if ($is_dhtml_editor) { echo $editor_html; } ?>
|
||||
</div>
|
||||
|
||||
<!-- 텍스트 에디터 영역 -->
|
||||
<div id="text-editor-area" style="display: <?php echo $is_dhtml_editor ? 'none' : 'block'; ?>;">
|
||||
<!-- 💡 [수정] 텍스트 에디터의 ID와 name을 명확히 구분 -->
|
||||
<!-- 초기 로드 시 HTML 에디터가 활성화되어 있으면 name 속성을 제거해야 충돌 방지 -->
|
||||
<textarea id="wr_content_text" class="form-control" rows="10" <?php echo $is_dhtml_editor ? '' : 'name="wr_content"'; ?>><?php echo $content ?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="form-divider">
|
||||
|
||||
<?php for ($i=1; $is_file && $i<=$board['bo_upload_count']; $i++):
|
||||
$file_label = isset($cfg_write['file_labels'][$i]) ? $cfg_write['file_labels'][$i] : '첨부파일 #'.$i;
|
||||
$file_text = isset($cfg_write['file_texts'][$i]) ? $cfg_write['file_texts'][$i] : '';
|
||||
?>
|
||||
<div class="write-form-group file-upload-group">
|
||||
<label for="bf_file_<?php echo $i ?>" class="form-label"><?php echo $file_label; ?><?php if($i==1) echo '<span class="required">*</span>'; ?></label>
|
||||
<div class="file-input-wrapper">
|
||||
<input type="file" name="bf_file[]" id="bf_file_<?php echo $i ?>" title="파일첨부 <?php echo $i ?> : 용량 <?php echo $upload_max_filesize ?> 이하만 업로드 가능" class="form-control" <?php if ($w=='' && $i==1) echo 'required'; ?>>
|
||||
<?php if ($w == 'u' && $file[$i-1]['file']): ?>
|
||||
<span class="file-delete-wrap"><input type="checkbox" id="bf_file_del_<?php echo $i-1 ?>" name="bf_file_del[<?php echo $i-1; ?>]" value="1"><label for="bf_file_del_<?php echo $i-1 ?>"><?php echo $file[$i-1]['source'].'('.$file[$i-1]['size'].')'; ?> 파일 삭제</label></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if($file_text): ?><p class="form-text"><?php echo $file_text; ?></p><?php endif; ?>
|
||||
</div>
|
||||
<?php endfor; ?>
|
||||
|
||||
<hr class="form-divider">
|
||||
|
||||
<?php if ($is_admin): ?>
|
||||
<div class="admin-options-group">
|
||||
<h3 class="form-section-title">관리자 전용 설정</h3>
|
||||
<div class="admin-option-item">
|
||||
<label class="form-check-label" for="is_featured">
|
||||
<input type="checkbox" name="<?php echo $field_map['featured']; ?>" value="Y" id="is_featured" class="admin-option-checkbox" <?php echo ($write[$field_map['featured']] == 'Y') ? 'checked' : ''; ?>>
|
||||
<span class="option-text">이 글을 '지정 최신글'로 설정합니다. (최대 6개, 현재 <?php echo $featured_count; ?>개)</span>
|
||||
</label>
|
||||
<div id="ebook-link-group" style="display: <?php echo ($write[$field_map['featured']] == 'Y') ? 'block' : 'none'; ?>; margin-top: 15px;">
|
||||
<label for="<?php echo $ebook_link_field; ?>" class="form-label" style="margin-top:0;">E-book 링크</label>
|
||||
<input type="url" name="<?php echo $ebook_link_field; ?>" value="<?php echo $write[$ebook_link_field]; ?>" id="<?php echo $ebook_link_field; ?>" class="form-control" placeholder="https://example.com/ebook/123">
|
||||
<p class="form-text">'지정 최신글'로 설정했을 경우, 클릭 시 이동할 이북 주소를 입력하세요.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="write-form-footer">
|
||||
<a href="<?php echo get_pretty_url($bo_table); ?>" class="btn btn-secondary">취소</a>
|
||||
<button type="submit" id="btn_submit" accesskey="s" class="btn btn-primary">작성완료</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const isFeaturedCheckbox = document.getElementById('is_featured');
|
||||
const ebookLinkGroup = document.getElementById('ebook-link-group');
|
||||
|
||||
// 💡 [추가] 지정 최신글 개수 제한 로직
|
||||
const featuredCount = <?php echo $featured_count; ?>;
|
||||
const isAlreadyFeatured = <?php echo ($write[$field_map['featured']] == 'Y') ? 'true' : 'false'; ?>;
|
||||
const maxFeatured = 12;
|
||||
|
||||
if (isFeaturedCheckbox) {
|
||||
isFeaturedCheckbox.addEventListener('change', function() {
|
||||
// 체크하려고 할 때 개수 확인
|
||||
if (this.checked) {
|
||||
// 이미 지정된 글이 아니면서, 현재 개수가 꽉 찼다면
|
||||
if (!isAlreadyFeatured && featuredCount >= maxFeatured) {
|
||||
alert('지정 최신글은 최대 ' + maxFeatured + '개까지만 설정할 수 있습니다.\n기존 글의 설정을 해제한 후 다시 시도해주세요.');
|
||||
this.checked = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ebookLinkGroup) {
|
||||
ebookLinkGroup.style.display = this.checked ? 'block' : 'none';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const dhtmlEditorArea = document.getElementById('dhtml-editor-area');
|
||||
const textEditorArea = document.getElementById('text-editor-area');
|
||||
const editorToggleButtons = document.querySelectorAll('.btn-editor-toggle');
|
||||
const wrContentTextarea = document.getElementById('wr_content_text');
|
||||
const wrContentDhtmlTextarea = document.getElementById('wr_content'); // 그누보드 에디터가 생성하는 textarea
|
||||
const htmlInput = document.querySelector('input[name="html"]'); // html 모드 저장용
|
||||
|
||||
function setEditorMode(isDhtml) {
|
||||
if (isDhtml) {
|
||||
// HTML 에디터 모드
|
||||
dhtmlEditorArea.style.display = 'block';
|
||||
textEditorArea.style.display = 'none';
|
||||
|
||||
// 텍스트 에디터의 내용을 HTML 에디터로 복사 (가능한 경우)
|
||||
if (typeof CKEDITOR !== 'undefined' && CKEDITOR.instances.wr_content) {
|
||||
CKEDITOR.instances.wr_content.setData(wrContentTextarea.value);
|
||||
}
|
||||
|
||||
// name 속성 조정: HTML 에디터가 wr_content를 사용하도록
|
||||
if (wrContentDhtmlTextarea) {
|
||||
wrContentDhtmlTextarea.setAttribute('name', 'wr_content');
|
||||
}
|
||||
wrContentTextarea.removeAttribute('name');
|
||||
|
||||
// html 필드 값 설정 (html1 또는 html2)
|
||||
if (htmlInput) htmlInput.value = 'html1';
|
||||
|
||||
} else {
|
||||
// 텍스트 에디터 모드
|
||||
dhtmlEditorArea.style.display = 'none';
|
||||
textEditorArea.style.display = 'block';
|
||||
|
||||
// HTML 에디터의 내용을 텍스트 에디터로 복사
|
||||
if (typeof CKEDITOR !== 'undefined' && CKEDITOR.instances.wr_content) {
|
||||
wrContentTextarea.value = CKEDITOR.instances.wr_content.getData();
|
||||
} else if (wrContentDhtmlTextarea) {
|
||||
wrContentTextarea.value = wrContentDhtmlTextarea.value;
|
||||
}
|
||||
|
||||
// name 속성 조정: 텍스트 에디터가 wr_content를 사용하도록
|
||||
wrContentTextarea.setAttribute('name', 'wr_content');
|
||||
if (wrContentDhtmlTextarea) {
|
||||
wrContentDhtmlTextarea.removeAttribute('name');
|
||||
}
|
||||
|
||||
// html 필드 값 초기화 (텍스트 모드)
|
||||
if (htmlInput) htmlInput.value = '';
|
||||
}
|
||||
|
||||
// 버튼 스타일 업데이트
|
||||
editorToggleButtons.forEach(btn => {
|
||||
if ((btn.dataset.editorType === 'dhtml' && isDhtml) || (btn.dataset.editorType === 'text' && !isDhtml)) {
|
||||
btn.classList.add('active');
|
||||
} else {
|
||||
btn.classList.remove('active');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 초기 모드 설정
|
||||
setEditorMode(<?php echo $is_dhtml_editor ? 'true' : 'false'; ?>);
|
||||
|
||||
editorToggleButtons.forEach(button => {
|
||||
button.addEventListener('click', function() {
|
||||
const type = this.dataset.editorType;
|
||||
setEditorMode(type === 'dhtml');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function fwrite_submit(f) {
|
||||
// 그누보드 에디터 내용 동기화 (필수)
|
||||
<?php echo $editor_js; ?>
|
||||
|
||||
let content = '';
|
||||
const dhtmlEditorArea = document.getElementById('dhtml-editor-area');
|
||||
|
||||
// 현재 활성화된 에디터 확인
|
||||
if (dhtmlEditorArea && dhtmlEditorArea.style.display === 'block') {
|
||||
// HTML 에디터 모드
|
||||
if (typeof CKEDITOR !== 'undefined' && CKEDITOR.instances.wr_content) {
|
||||
content = CKEDITOR.instances.wr_content.getData();
|
||||
} else if (document.getElementById('wr_content')) {
|
||||
content = document.getElementById('wr_content').value;
|
||||
}
|
||||
} else {
|
||||
// 텍스트 에디터 모드
|
||||
content = document.getElementById('wr_content_text').value;
|
||||
}
|
||||
|
||||
// 내용 유효성 검사 (태그 제거 후 확인)
|
||||
let contentCheck = content.replace(/<[^>]*>/g, '').replace(/ /g, '').trim();
|
||||
|
||||
// 파일 첨부 여부 확인
|
||||
let hasFile = false;
|
||||
const fileInputs = document.querySelectorAll('input[name="bf_file[]"]');
|
||||
for (let i = 0; i < fileInputs.length; i++) {
|
||||
if (fileInputs[i].value) {
|
||||
hasFile = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 수정 모드일 때 기존 파일이 있는지 확인 (삭제 체크박스가 있으면 파일이 있는 것임)
|
||||
const fileDeletes = document.querySelectorAll('input[name^="bf_file_del"]');
|
||||
if (fileDeletes.length > 0) {
|
||||
hasFile = true;
|
||||
}
|
||||
|
||||
if (contentCheck === '' && !hasFile) {
|
||||
alert('내용을 입력하거나 파일을 첨부해주세요.');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user