first commit 2

This commit is contained in:
hmw1001
2026-06-11 18:47:38 +09:00
parent c768729ce6
commit 6f534e33a6
11095 changed files with 1595758 additions and 0 deletions
@@ -0,0 +1,35 @@
<?php
if (!defined('_GNUBOARD_')) exit;
/**
* rb.custom :: general_ad_section/config.php
* 일반 광고 모듈 설정 파일
*/
$general_ad_config = array(
// 이 모듈이 가져올 배너의 위치(bn_position) 코드
'position' => 'general_main',
// --- 💡 [최종 수정] 레이아웃 및 출력 모드 설정 ---
// 1. 출력 모드 설정 ('fixed', 'slide', 'both')
'display_mode' => 'fixed', // 기본값으로 슬라이드형만 출력
// 2. 고정형 그리드 설정
'fixed_grid_columns' => 2, // 한 줄에 표시할 배너 개수
// 3. 배너 유닛 크기 및 간격 설정
'banner_width' => 180, // 슬라이드 배너 한 개의 가로 크기 (px)
'banner_height' => 80, // 배너 한 개의 세로 크기 (px)
'banner_gap' => 10, // 배너 사이의 간격 (px)
// 4. 슬라이드 옵션
'slide_options' => array(
'fx' => 'carousel', // 캐러셀 효과
'timeout' => 4000, // 각 슬라이드 표시 시간 (0이면 자동롤링 안함)
'slides' => '> .banner-unit-wrapper', // 슬라이드 될 자식 요소
'log' => false,
'allow-wrap' => true, // 무한 반복
),
);
?>
@@ -0,0 +1,92 @@
/* General Ad Section Style - Final Layout Fix */
.general-ad-section {
padding: 20px;
background: #f1f3f5;
border-radius: 12px;
}
/* 1. 고정형 그리드 */
.general-ad-fixed-grid {
display: flex;
flex-wrap: wrap;
gap: var(--banner-gap, 10px);
margin-bottom: var(--banner-gap, 10px);
}
.general-ad-fixed-grid .banner-unit-wrapper {
flex: 1 0 calc((100% - (var(--banner-gap, 10px) * (var(--fixed-columns) - 1))) / var(--fixed-columns));
height: var(--banner-height, 80px);
position: relative;
overflow: hidden;
min-width: 150px;
}
/* 2. 슬라이드형 래퍼 */
.general-ad-row {
position: relative;
margin-bottom: 20px;
padding: 0 50px;
}
.general-ad-slider {
width: 100%;
height: var(--banner-height, 80px);
overflow: hidden;
}
.general-ad-slider .banner-unit-wrapper {
height: 100%;
}
.banner-unit-wrapper img {
width: 100%;
height: 100%;
display: block;
object-fit: contain;
}
.slider-controls .swiper-button-prev,
.slider-controls .swiper-button-next {
color: #555 !important;
width: 30px;
height: 30px;
background-color: #fff;
border: 1px solid #ddd;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
z-index: 10;
top: 50%;
transform: translateY(-50%);
margin-top: 0;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.slider-controls .swiper-button-prev:after,
.slider-controls .swiper-button-next:after {
font-size: 14px !important;
font-weight: bold;
}
.slider-controls .swiper-button-prev { left: 0; }
.slider-controls .swiper-button-next { right: 0; }
.empty-banner {
text-align: center;
padding: 20px;
color: #999;
}
@media (max-width: 1024px) {
.general-ad-fixed-grid .banner-unit-wrapper {
flex-basis: calc((100% - var(--banner-gap, 10px)) / 2);
}
.general-ad-row {
padding: 0 30px;
}
.general-ad-slider {
height: 60px;
}
}
@@ -0,0 +1,51 @@
(function($) {
"use strict";
if (typeof window.initGeneralAdSection === 'function') {
// return;
}
window.initGeneralAdSection = function(moduleId) {
const $module = $('#' + moduleId);
if (!$module.length) return;
$module.find('.general-ad-row').each(function() {
const $row = $(this);
const $swiperContainer = $row.find('.swiper-container');
const slidesPerView = parseInt($swiperContainer.data('slides-per-view'), 10) || 6;
const spaceBetween = parseInt($swiperContainer.data('space-between'), 10) || 10;
const totalSlides = $swiperContainer.find('.swiper-slide').length;
const loop = totalSlides > 1;
new Swiper($swiperContainer[0], {
slidesPerView: 2,
spaceBetween: spaceBetween,
loop: loop,
autoplay: {
delay: 3000,
disableOnInteraction: false,
},
navigation: {
nextEl: $row.find('.swiper-button-next')[0],
prevEl: $row.find('.swiper-button-prev')[0],
},
breakpoints: {
640: { slidesPerView: 3 },
768: { slidesPerView: 4 },
1024: {
slidesPerView: (totalSlides < slidesPerView) ? totalSlides : slidesPerView
}
}
});
});
};
$(function() {
$('.general-ad-section').each(function() {
window.initGeneralAdSection($(this).attr('id'));
});
});
})(jQuery);
@@ -0,0 +1,166 @@
<?php
if (!defined('_GNUBOARD_')) exit;
/**
* rb.custom :: general_ad_section/module.php
* 일반 광고 모듈 (설정에 따라 고정형/슬라이드형 선택)
*/
if (!isset($md_id) || !$md_id) return;
$md_id_safe = sql_real_escape_string($md_id);
$module_config = sql_fetch(" SELECT * FROM `rb_module` WHERE md_id = '{$md_id_safe}' ");
if (!$module_config) $module_config = sql_fetch(" SELECT * FROM `rb_module_shop` WHERE md_id = '{$md_id_safe}' ");
if (!$module_config) return;
$config_path = __DIR__ . '/config.php';
if (file_exists($config_path)) include_once($config_path);
else return;
// 데이터 가져오기
$position = $general_ad_config['position'];
$sql = " SELECT * FROM `rb_banner` WHERE bn_position = '{$position}' AND bn_begin_time <= NOW() AND bn_end_time >= NOW() ORDER BY bn_order ASC, bn_id DESC ";
$result = sql_query($sql);
$all_banners = [];
while ($row = sql_fetch_array($result)) {
$row['bn_img'] = '<img src="' . G5_DATA_URL . '/banners/' . $row['bn_id'] . '" alt="' . get_text($row['bn_alt']) . '">';
$all_banners[] = $row;
}
// 💡 [핵심 수정] 설정값(display_mode)에 따라 배너 분류
$display_mode = $general_ad_config['display_mode']; // 'fixed' or 'slide'
$fixed_banners = [];
$slide_groups = [];
if ($display_mode === 'fixed') {
// 고정형: 모든 배너를 고정 영역으로
$fixed_banners = $all_banners;
} else {
// 슬라이드형: 모든 배너를 하나의 슬라이드 그룹으로 (다중 행 처리는 아래에서 함)
// 키는 임의로 'default'로 지정
if (!empty($all_banners)) {
$slide_groups['default'] = $all_banners;
}
}
$md_banner_skin = isset($module_config['md_banner_skin']) && $module_config['md_banner_skin'] !=''? $module_config['md_banner_skin'] : 'rb.mod/banner/skin/split_layout';
$item_skin_file = G5_PATH . '/rb/' . $md_banner_skin . '/skin.php';
$css_vars = [
'--fixed-columns: ' . (int)$general_ad_config['fixed_grid_columns'],
'--banner-width: ' . (int)$general_ad_config['banner_width'] . 'px',
'--banner-height: ' . (int)$general_ad_config['banner_height'] . 'px',
'--banner-gap: ' . (int)$general_ad_config['banner_gap'] . 'px',
];
$visual_id = 'gas_' . uniqid();
?>
<div class="general-ad-section" id="<?php echo $visual_id; ?>" style="<?php echo implode('; ', $css_vars); ?>;">
<!-- 1. 고정형 배너 영역 -->
<?php if (!empty($fixed_banners)): ?>
<div class="general-ad-fixed-grid">
<?php
foreach ($fixed_banners as $banner) {
if (file_exists($item_skin_file)) {
echo '<div class="banner-unit-wrapper">';
include($item_skin_file);
echo '</div>';
}
}
?>
</div>
<?php endif; ?>
<!-- 2. 슬라이드형 배너 영역 (다중 행 지원) -->
<?php if (!empty($slide_groups)): ?>
<?php foreach ($slide_groups as $group_name => $banners):
$columns = (int)$general_ad_config['fixed_grid_columns'];
$chunk_size = $columns * 2;
$banner_rows = array_chunk($banners, $chunk_size);
?>
<?php foreach ($banner_rows as $row_index => $banners_in_row):
$current_count = count($banners_in_row);
$slides_per_view = ($current_count < $columns) ? $current_count : $columns;
?>
<div class="general-ad-row">
<div class="swiper-container general-ad-slider"
data-slides-per-view="<?php echo $slides_per_view; ?>"
data-space-between="<?php echo (int)$general_ad_config['banner_gap']; ?>">
<div class="swiper-wrapper">
<?php foreach ($banners_in_row as $banner): ?>
<div class="swiper-slide banner-unit-wrapper">
<?php
if (file_exists($item_skin_file)) {
include($item_skin_file);
}
?>
</div>
<?php endforeach; ?>
</div>
</div>
<div class="slider-controls">
<div class="swiper-button-prev btn-prev"><i class="fa fa-chevron-left"></i></div>
<div class="swiper-button-next btn-next"><i class="fa fa-chevron-right"></i></div>
</div>
</div>
<?php endforeach; ?>
<?php endforeach; ?>
<?php endif; ?>
<?php if (empty($fixed_banners) && empty($slide_groups)): ?>
<div class="empty-banner">등록된 배너가 없습니다.</div>
<?php endif; ?>
</div>
<link rel="stylesheet" href="<?php echo G5_THEME_URL; ?>/rb.custom/general_ad_section/module.css?ver=<?php echo G5_CSS_VER; ?>">
<!-- 통합 동적 로더 (Swiper) -->
<script>
(function() {
var currentModuleId = '<?php echo $visual_id; ?>';
var initFunctionName = 'initGeneralAdSection';
var themeUrl = '<?php echo G5_THEME_URL; ?>';
var jsVer = '<?php echo G5_JS_VER; ?>';
function loadScript(src, id, callback) {
if (document.getElementById(id)) {
if (callback) callback();
return;
}
var script = document.createElement('script');
script.id = id;
script.src = src;
script.async = false;
if (callback) {
script.onload = callback;
}
document.head.appendChild(script);
}
function finalAction() {
if (typeof window[initFunctionName] === 'function') {
window[initFunctionName](currentModuleId);
}
}
function loadModuleScript() {
loadScript(themeUrl + '/rb.custom/general_ad_section/module.js?ver=' + jsVer, 'general-ad-section-js', finalAction);
}
if (typeof Swiper === 'undefined') {
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'https://unpkg.com/swiper/swiper-bundle.min.css';
document.head.appendChild(link);
loadScript('https://unpkg.com/swiper/swiper-bundle.min.js', 'swiper-bundle-js', loadModuleScript);
} else {
loadModuleScript();
}
})();
</script>