<?php
if (!defined('_GNUBOARD_')) exit;
add_stylesheet('<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">', 0);
include_once(G5_LIB_PATH.'/thumbnail.lib.php');
// 스타일시트 연결
add_stylesheet('<link rel="stylesheet" href="'.$board_skin_url.'/style.view.css">', 0);
$view_content = get_view_thumbnail($view['content']);
// 1. wr_subject = 테이블명 기준으로 DB 테이블 정보 조회
$table_name = isset($view['wr_subject']) ? trim($view['wr_subject']) : '';
$table_columns = array();
$table_status = array();
if ($table_name) {
// 컬럼 정보 조회
$col_sql = " SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_KEY, COLUMN_DEFAULT, EXTRA, COLUMN_COMMENT
FROM information_schema.COLUMNS
WHERE TABLE_NAME = '".sql_real_escape_string($table_name)."'
ORDER BY ORDINAL_POSITION ";
$col_result = sql_query($col_sql);
while ($col_row = sql_fetch_array($col_result)) {
$table_columns[] = $col_row;
}
// 테이블 상태 정보 조회
$status_sql = " SELECT TABLE_NAME, ENGINE, TABLE_ROWS, AVG_ROW_LENGTH, DATA_LENGTH, INDEX_LENGTH,
TABLE_COMMENT, CREATE_TIME, UPDATE_TIME
FROM information_schema.TABLES
WHERE TABLE_NAME = '".sql_real_escape_string($table_name)."' ";
$table_status = sql_fetch($status_sql);
}
// 2. 데몬 파일 소스코드 조회 (하위 디렉토리 재귀 검색 포함)
$daemon_name = isset($view['x2_daemon']) ? $view['x2_daemon'] : '';
$daemon_code = '';
if ($daemon_name) {
$daemon_root = '/home/www/DATA/UPBIT/daemon';
$target_path = '';
// 루트에 바로 있는지 먼저 확인 (속도 최적화)
if (file_exists($daemon_root . '/' . $daemon_name)) {
$target_path = $daemon_root . '/' . $daemon_name;
} else {
// 없으면 하위 디렉토리 전체 스캔
if (is_dir($daemon_root) && is_readable($daemon_root)) {
try {
$di = new RecursiveDirectoryIterator($daemon_root, RecursiveDirectoryIterator::SKIP_DOTS);
$it = new RecursiveIteratorIterator($di);
foreach ($it as $file) {
if ($file->isFile() && $file->getFilename() == $daemon_name) {
$target_path = $file->getPathname();
break;
}
}
} catch (Exception $e) { }
}
}
// 파일 읽기
if ($target_path && file_exists($target_path) && is_readable($target_path)) {
$daemon_code = file_get_contents($target_path);
}
}
// 3. 이벤트(Event) 상세 정보 조회 (외부 DB 대응 버전)
$event_name = isset($view['x2_events']) ? trim($view['x2_events']) : '';
$event_info = array();
if ($event_name && isset($db_upbit) && $db_upbit) {
$evt_sql = " SELECT * FROM information_schema.EVENTS
WHERE EVENT_NAME = '".sql_real_escape_string($event_name)."'
LIMIT 1 ";
try {
// 테이블 정보 가져올 때랑 똑같은 방식으로 외부 DB에 쿼리 전송
if ($db_upbit instanceof mysqli) {
$res = mysqli_query($db_upbit, $evt_sql);
$event_info = mysqli_fetch_assoc($res);
} else {
// PDO 환경일 경우
$stmt = $db_upbit->query($evt_sql);
$event_info = $stmt->fetch(PDO::FETCH_ASSOC);
}
} catch (Exception $e) {
// 에러 나면 조용히 넘어가기
}
}
?>
<style>
.View-Header .status-badge { color: <?php echo $state_color; ?>; border: 1px solid <?php echo $state_color; ?>; }
</style>
<article id="VIEW">
<canvas id="starCanvas"></canvas>
<div class="View-Wrapper">
<header class="View-Header">
<h2><i class="fa-solid fa-terminal"></i> SYSTEM_CORE_VIEWER</h2>
<div class="status-badge">
<i class="fa-solid fa-circle" style="font-size: 8px; margin-right: 6px; vertical-align: middle;"></i>
<?php echo $view['x2_ca2']; ?>
</div>
</header>
<section class="Hero-Target-Section">
<div class="Hero-Icon">
<i class="fa-solid fa-microchip"></i>
</div>
<div class="Hero-Content">
<span class="label">Target Object / Identifier</span>
<div class="subject-text"><?php echo get_text($view['wr_subject']); ?></div>
<div class="kor-text"><?php echo get_text($view['wr_subject_kor']); ?></div>
<?php if(isset($view['wr_1']) && trim($view['wr_1'])) { ?>
<div class="Hero-Memo">
<i class="fa-solid fa-note-sticky"></i>
<span><?php echo nl2br(get_text($view['wr_1'])); ?></span>
</div>
<?php } ?>
</div>
</section>
<section class="Dashboard-Grid">
<div class="info-item">
<span class="label"><i class="fa-solid fa-building-columns"></i> Exchange</span>
<div class="value"><?php echo $view['ca_name'] ? $view['ca_name'] : 'N/A'; ?></div>
</div>
<div class="info-item">
<span class="label"><i class="fa-solid fa-layer-group"></i> Type</span>
<div class="value"><?php echo $view['x2_ca2']; ?> <span style="color:#334155; margin:0 5px;"></div>
</div>
<div class="info-item">
<span class="label"><i class="fa-solid fa-layer-group"></i> Form</span>
<div class="value"></span> <?php echo $view['x2_ca3']; ?></div>
</div>
<div class="info-item">
<span class="label"><i class="fa-solid fa-shield-halved"></i> DB TABLE</span>
<div class="value accent"><?php echo $view['wr_subject']; ?></div>
</div>
<div class="info-item">
<span class="label"><i class="fa-solid fa-table"></i> TABLE DAEMON</span>
<div class="value accent"><?php echo $view['x2_daemon']; ?></div>
</div>
<div class="info-item">
<span class="label"><i class="fa-solid fa-gears"></i> DB EVENT</span>
<div class="value accent"><?php echo $view['x2_events']; ?></div>
</div>
</section>
<div class="dynamic-result-area">
<div class="res-item"><span>[STATUS]</span> <b style="color:<?php echo $state_color; ?>"><?php echo $is_run ? 'ACTIVE' : 'INACTIVE'; ?></b></div>
<div class="res-item"><span>[ID]</span> <b>#<?php echo $view['wr_id']; ?></b></div>
<div class="res-item"><span>[TABLE]</span> <b><?php echo $table_name; ?></b></div>
<div class="res-item"><span>[ENGINE]</span> <b><?php echo isset($table_status['ENGINE']) ? $table_status['ENGINE'] : '-'; ?></b></div>
<div class="res-item"><span>[ROWS]</span> <b><?php echo isset($table_status['TABLE_ROWS']) ? number_format($table_status['TABLE_ROWS']) : '-'; ?></b></div>
</div>
<section class="View-Body">
<?php if ($view_content) { ?>
<div class="section-title">Detailed Description</div>
<div class="main-content">
<?php echo $view_content; ?>
</div>
<?php } ?>
<?php if (isset($view['x2_content']) && trim($view['x2_content'])) { ?>
<div class="section-title">Additional Information</div>
<div class="info-card additional">
<div class="main-content" style="margin-bottom:0;">
<?php echo nl2br(stripslashes($view['x2_content'])); ?>
</div>
</div>
<?php } ?>
<?php if (isset($view['x2_content_2']) && trim($view['x2_content_2'])) { ?>
<div class="section-title" style="color:#ff2d55;">Special Notes & Warnings</div>
<div class="info-card special">
<div class="main-content" style="margin-bottom:0; color:#fca5a5;">
<?php echo nl2br(stripslashes($view['x2_content_2'])); ?>
</div>
</div>
<?php } ?>
<?php if ($table_name) { ?>
<div class="db_table_title"><i class="fa-solid fa-database"></i> DB TABLE</div>
<div class="section-title tbl-status-title">Table Status</div>
<div class="tbl-status-wrap">
<table class="tbl-status">
<tbody>
<?php
$status_fields = array(
'TABLE_NAME' => 'Table Name',
'ENGINE' => 'Engine',
'TABLE_ROWS' => 'Rows',
'DATA_LENGTH' => 'Data Length',
'INDEX_LENGTH' => 'Index Length',
'TABLE_COMMENT'=> 'Comment',
'CREATE_TIME' => 'Created',
'UPDATE_TIME' => 'Updated',
);
foreach ($status_fields as $key => $label) {
$val = isset($table_status[$key]) ? $table_status[$key] : '-';
if (in_array($key, array('DATA_LENGTH','INDEX_LENGTH'))) {
$val = $val !== '-' ? number_format($val) . ' bytes' : '-';
} elseif ($key === 'TABLE_ROWS') {
$val = $val !== '-' ? number_format($val) : '-';
}
echo '<tr><td class="tbl-status-label">'.htmlspecialchars($label).'</td><td class="tbl-status-val">'.htmlspecialchars($val).'</td></tr>';
}
?>
</tbody>
</table>
</div>
<div class="tbl-col-wrap">
<table class="tbl-col">
<thead>
<tr class="tbl-col-head">
<th>#</th>
<th>Column Name</th>
<th>Type</th>
<th>Null</th>
<th>Key</th>
<th>Default</th>
<th>Extra</th>
<th>Comment</th>
</tr>
</thead>
<tbody>
<?php
foreach ($table_columns as $i => $col) {
$row_class = ($i % 2 === 0) ? 'tbl-col-row even' : 'tbl-col-row odd';
$null_class = ($col['IS_NULLABLE'] === 'YES') ? 'col-null-yes' : 'col-null-no';
$key_class = ($col['COLUMN_KEY'] === 'PRI') ? 'col-key-pri' : (($col['COLUMN_KEY'] === 'MUL') ? 'col-key-mul' : 'col-key-none');
$key_val = $col['COLUMN_KEY'] ? $col['COLUMN_KEY'] : '-';
$default_val = ($col['COLUMN_DEFAULT'] !== null) ? htmlspecialchars($col['COLUMN_DEFAULT']) : '<span class="col-null-val">NULL</span>';
echo '<tr class="'.$row_class.'">';
echo '<td class="col-num">'.($i+1).'</td>';
echo '<td class="col-name">'.htmlspecialchars($col['COLUMN_NAME']).'</td>';
echo '<td class="col-type">'.htmlspecialchars($col['COLUMN_TYPE']).'</td>';
echo '<td class="'.$null_class.'">'.$col['IS_NULLABLE'].'</td>';
echo '<td class="'.$key_class.'">'.$key_val.'</td>';
echo '<td class="col-default">'.$default_val.'</td>';
echo '<td class="col-extra">'.htmlspecialchars($col['EXTRA']).'</td>';
echo '<td class="col-comment">'.htmlspecialchars($col['COLUMN_COMMENT']).'</td>';
echo '</tr>';
}
?>
</tbody>
</table>
</div>
<?php } ?>
<div class="db_arrow_title"><i class="fa-solid fa-up-down"></i></div>
<?php if ($daemon_name) { ?>
<div class="db_table_title"><i class="fa-solid fa-robot"></i> DAEMON</div><div class="section-title tbl-col-title">Table Column Definition</div>
<div class="section-title" style="color:#00d4ff;">Daemon Source Code (<?php echo $daemon_name; ?>)</div>
<pre class="code-block"><?php echo htmlspecialchars($daemon_code); ?></pre>
<?php } ?>
<?php if ($event_name && $event_info) { ?>
<div class="db_event_title"><i class="fa-regular fa-clock"></i> DB EVENT</div>
<div class="section-title" style="color:#f59e0b;">Event Scheduler Status (<?php echo $event_name; ?>)</div>
<div class="tbl-status-wrap" style="margin-bottom:20px; border-color: rgba(245, 158, 11, 0.2);">
<table class="tbl-status">
<tbody>
<tr>
<td class="tbl-status-label">Status / Interval</td>
<td class="tbl-status-val">
<?php
$is_enabled = ($event_info['STATUS'] === 'ENABLED');
$s_color = $is_enabled ? '#00d4ff' : '#ff2d55';
echo '<b style="color:'.$s_color.'">'.$event_info['STATUS'].'</b>';
echo ' <span style="color:#475569; margin:0 10px;">|</span> Every ';
echo $event_info['INTERVAL_VALUE'] . ' ' . $event_info['INTERVAL_FIELD'];
?>
</td>
</tr>
<tr>
<td class="tbl-status-label">Last Executed</td>
<td class="tbl-status-val"><?php echo $event_info['LAST_EXECUTED'] ?: 'NEVER'; ?></td>
</tr>
</tbody>
</table>
</div>
<div class="section-title" style="color:#f59e0b;">Event SQL Definition</div>
<pre class="code-block" style="border-color: rgba(245, 158, 11, 0.2);"><?php echo htmlspecialchars($event_info['EVENT_DEFINITION']); ?></pre>
<?php } ?>
<?php if ($view['x2_memo']) { ?>
<ul class="memo_box">
<li class="memo_title">
<i class="fa-solid fa-code"></i> MEMO
<label>
<?php if ($view['x2_memo_clean']) { ?><i class="fa-solid fa-trash"></i> 삭제된 메모<?php } ?>
</label>
</li>
<li class="memo_memo" <?php if ($view['x2_memo_clean']) { ?>style="text-decoration: line-through; opacity: 0.5;"<?php } ?>>
<?php echo nl2br(stripslashes($view['x2_memo'])); ?>
</li>
</ul>
<?php } ?>
</section>
<?php if ($view['file']['count'] > 0 || ($view['link'][1] || $view['link'][2])) { ?>
<section style="padding: 25px 40px; background: rgba(15, 23, 42, 0.4); border-top: 1px solid #1e293b;">
<div style="display:flex; flex-wrap:wrap; gap:12px;">
<?php
for ($i=1; $i<=count($view['link']); $i++) {
if ($view['link'][$i]) {
echo '<a href="'.$view['link_href'][$i].'" target="_blank" class="btn-ui" style="font-size:0.75rem;"><i class="fa-solid fa-link"></i> '.cut_str($view['link'][$i], 40).'</a>';
}
}
if ($view['file']['count']) {
for ($i=0; $i<count($view['file']); $i++) {
if (isset($view['file'][$i]['source']) && !isset($view['file'][$i]['view'])) {
echo '<a href="'.$view['file'][$i]['href'].'" class="btn-ui" style="font-size:0.75rem;"><i class="fa-solid fa-download"></i> '.$view['file'][$i]['source'].'</a>';
}
}
}
?>
</div>
</section>
<?php } ?>
<?php if ($view['x2_tag']) { ?>
<div class="Tag-Container">
<i class="fa-solid fa-tags" style="color:#475569; margin-right:10px; align-self:center;"></i>
<?php
$tags = explode(',', $view['x2_tag']);
foreach($tags as $tag_val) {
$tag_val = trim($tag_val);
if($tag_val) {
echo '<a href="'.G5_BBS_URL.'/board.php?bo_table='.$bo_table.'&stx='.urlencode($tag_val).'&sfl=wr_subject||wr_content" class="x2-tag-item">#'.$tag_val.'</a>';
}
}
?>
</div>
<?php } ?>
<footer class="View-Footer">
<a href="<?php echo $list_href; ?>" class="btn-ui"><i class="fa-solid fa-list"></i> LIST</a>
<?php if ($update_href) { ?>
<a href="<?php echo $update_href; ?>" class="btn-ui btn-edit"><i class="fa-solid fa-pen-to-square"></i> EDIT CONFIG</a>
<?php } ?>
<?php if ($delete_href) { ?>
<a href="<?php echo $delete_href; ?>" onclick="return confirm('정말 삭제하시겠습니까?');" class="btn-ui" style="color:#ff2d55; border-color:#ff2d5522;"><i class="fa-solid fa-trash-can"></i> DELETE</a>
<?php } ?>
</footer>
</div>
<nav class="Post-Nav">
<?php if ($prev_href) { ?>
<a href="<?php echo $prev_href; ?>" class="nav-item">
<span class="nav-label"><i class="fa-solid fa-arrow-left"></i> Previous Post</span>
<span class="nav-title"><?php echo $prev_wr_subject; ?></span>
</a>
<?php } else { ?>
<div class="nav-item" style="opacity:0.3; cursor:default;">
<span class="nav-label">Previous Post</span>
<span class="nav-title">No more posts</span>
</div>
<?php } ?>
<?php if ($next_href) { ?>
<a href="<?php echo $next_href; ?>" class="nav-item" style="text-align:right;">
<span class="nav-label">Next Post <i class="fa-solid fa-arrow-right"></i></span>
<span class="nav-title"><?php echo $next_wr_subject; ?></span>
</a>
<?php } else { ?>
<div class="nav-item" style="opacity:0.3; cursor:default; text-align:right;">
<span class="nav-label">Next Post</span>
<span class="nav-title">No more posts</span>
</div>
<?php } ?>
</nav>
</article>