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
+365
View File
@@ -0,0 +1,365 @@
<?php
if (!defined('_GNUBOARD_')) exit;
// 💡 [핵심 수정] 라이브러리가 어디서든 독립적으로 실행될 수 있도록 필요한 상수를 정의합니다.
// AJAX 등 다른 경로로 라이브러리만 직접 호출될 때, 상수가 정의되지 않는 문제를 해결합니다.
// if(!defined(...))로 감싸서 _common.php 등에서 이미 정의된 경우 충돌을 방지합니다.
if (!defined('SURVEY_STATUS_DRAFT')) define('SURVEY_STATUS_DRAFT', 'draft');
if (!defined('SURVEY_STATUS_ACTIVE')) define('SURVEY_STATUS_ACTIVE', 'active');
if (!defined('SURVEY_STATUS_CLOSED')) define('SURVEY_STATUS_CLOSED', 'closed');
if (!defined('SURVEY_STATUS_DELETED')) define('SURVEY_STATUS_DELETED', 'deleted');
if (!defined('RESPONSE_STATUS_STARTED')) define('RESPONSE_STATUS_STARTED', 'started');
if (!defined('RESPONSE_STATUS_COMPLETED')) define('RESPONSE_STATUS_COMPLETED', 'completed');
if (!defined('RESPONSE_STATUS_ABANDONED')) define('RESPONSE_STATUS_ABANDONED', 'abandoned');
/**
* 설문 관리 라이브러리 함수들
*/
/**
* 설문지 정보 가져오기
*/
function get_survey($sv_id) {
global $g5;
$sql = "SELECT * FROM survey_master WHERE sv_id = '$sv_id'";
return sql_fetch($sql);
}
/**
* 설문 질문 목록 가져오기
*/
function get_survey_questions($sv_id) {
global $g5;
$sql = "SELECT * FROM survey_questions WHERE sv_id = '$sv_id' ORDER BY sq_order ASC";
$result = sql_query($sql);
$questions = array();
while ($row = sql_fetch_array($result)) {
if ($row['sq_options']) {
$row['sq_options'] = json_decode($row['sq_options'], true);
}
if ($row['sq_validation']) {
$row['sq_validation'] = json_decode($row['sq_validation'], true);
}
$questions[] = $row;
}
return $questions;
}
/**
* 설문 응답 수 가져오기
*/
function get_survey_response_count($sv_id, $status = 'completed') {
global $g5;
$where = "sv_id = '$sv_id'";
if ($status) {
$where .= " AND sr_status = '$status'";
}
$sql = "SELECT COUNT(*) as cnt FROM survey_responses WHERE $where";
$row = sql_fetch($sql);
return $row['cnt'];
}
/**
* 설문 상태 업데이트
*/
function update_survey_status($sv_id, $status) {
global $g5;
$sql = "UPDATE survey_master SET sv_status = '$status', sv_updated_at = NOW() WHERE sv_id = '$sv_id'";
return sql_query($sql);
}
/**
* 설문 응답 시작
*/
function start_survey_response($sv_id, $mb_id = null, $ip = '', $user_agent = '', $session_id = '') {
global $g5;
$sql = "INSERT INTO survey_responses
(sv_id, sr_mb_id, sr_ip, sr_user_agent, sr_session_id, sr_started_at, sr_status)
VALUES
('$sv_id', ".($mb_id ? "'$mb_id'" : 'NULL').", '$ip', '$user_agent', '$session_id', NOW(), '".RESPONSE_STATUS_STARTED."')";
sql_query($sql);
return sql_insert_id();
}
/**
* 설문 응답 완료
*/
function complete_survey_response($sr_id) {
global $g5;
$sql = "UPDATE survey_responses
SET sr_status = '".RESPONSE_STATUS_COMPLETED."', sr_completed_at = NOW()
WHERE sr_id = '$sr_id'";
return sql_query($sql);
}
/**
* 설문 답변 저장
*/
function save_survey_answer($sr_id, $sq_id, $value, $text = '') {
global $g5;
// 기존 답변 삭제
$sql = "DELETE FROM survey_answers WHERE sr_id = '$sr_id' AND sq_id = '$sq_id'";
sql_query($sql);
// 새 답변 저장
if (is_array($value)) {
foreach ($value as $v) {
$sql = "INSERT INTO survey_answers (sr_id, sq_id, sa_value, sa_text, sa_created_at)
VALUES ('$sr_id', '$sq_id', '$v', '$text', NOW())";
sql_query($sql);
}
} else {
$sql = "INSERT INTO survey_answers (sr_id, sq_id, sa_value, sa_text, sa_created_at)
VALUES ('$sr_id', '$sq_id', '$value', '$text', NOW())";
sql_query($sql);
}
return true;
}
/**
* 설문 통계 업데이트
*/
function update_survey_statistics($sv_id) {
global $g5;
// 기존 통계 삭제
$sql = "DELETE FROM survey_statistics WHERE sv_id = '$sv_id'";
sql_query($sql);
// 질문별 통계 생성
$questions = get_survey_questions($sv_id);
$total_responses = get_survey_response_count($sv_id, 'completed');
foreach ($questions as $question) {
$sq_id = $question['sq_id'];
if (in_array($question['sq_type'], ['radio', 'checkbox', 'select'])) {
// 선택형 질문 통계
$sql = "SELECT sa_value, COUNT(*) as cnt
FROM survey_answers sa
JOIN survey_responses sr ON sa.sr_id = sr.sr_id
WHERE sr.sv_id = '$sv_id' AND sa.sq_id = '$sq_id' AND sr.sr_status = 'completed'
GROUP BY sa_value";
$result = sql_query($sql);
while ($row = sql_fetch_array($result)) {
$percentage = $total_responses > 0 ? round(($row['cnt'] / $total_responses) * 100, 2) : 0;
$insert_sql = "INSERT INTO survey_statistics
(sv_id, sq_id, ss_option_value, ss_count, ss_percentage)
VALUES
('$sv_id', '$sq_id', '{$row['sa_value']}', '{$row['cnt']}', '$percentage')";
sql_query($insert_sql);
}
} elseif ($question['sq_type'] == 'rating') {
// 평점 질문 통계
$sql = "SELECT sa_value, COUNT(*) as cnt
FROM survey_answers sa
JOIN survey_responses sr ON sa.sr_id = sr.sr_id
WHERE sr.sv_id = '$sv_id' AND sa.sq_id = '$sq_id' AND sr.sr_status = 'completed'
GROUP BY sa_value
ORDER BY CAST(sa_value AS UNSIGNED)";
$result = sql_query($sql);
while ($row = sql_fetch_array($result)) {
$percentage = $total_responses > 0 ? round(($row['cnt'] / $total_responses) * 100, 2) : 0;
$insert_sql = "INSERT INTO survey_statistics
(sv_id, sq_id, ss_option_value, ss_count, ss_percentage)
VALUES
('$sv_id', '$sq_id', '{$row['sa_value']}', '{$row['cnt']}', '$percentage')";
sql_query($insert_sql);
}
}
}
return true;
}
/**
* 설문 템플릿 목록 가져오기
*/
function get_survey_templates($category = '') {
global $g5;
$where = "st_is_public = 1";
if ($category) {
$where .= " AND st_category = '$category'";
}
$sql = "SELECT * FROM survey_templates WHERE $where ORDER BY st_created_at DESC";
$result = sql_query($sql);
$templates = array();
while ($row = sql_fetch_array($result)) {
$templates[] = $row;
}
return $templates;
}
/**
* 설문 템플릿으로 설문 생성
*/
function create_survey_from_template($template_id, $title, $created_by) {
global $g5;
$template = sql_fetch("SELECT * FROM survey_templates WHERE st_id = '$template_id'");
if (!$template) {
return false;
}
$template_data = json_decode($template['st_data'], true);
// 설문지 생성
$sql = "INSERT INTO survey_master
(sv_title, sv_description, sv_start_date, sv_end_date, sv_status, sv_created_by)
VALUES
('$title', '{$template_data['description']}', NOW(), DATE_ADD(NOW(), INTERVAL 30 DAY), '".SURVEY_STATUS_DRAFT."', '$created_by')";
sql_query($sql);
$sv_id = sql_insert_id();
// 질문들 생성
foreach ($template_data['questions'] as $index => $question) {
$sq_order = $index + 1;
$sq_type = $question['type'];
$sq_title = addslashes($question['title']);
$sq_required = isset($question['required']) && $question['required'] ? 1 : 0;
$sq_options = isset($question['options']) ? addslashes(json_encode($question['options'])) : '';
$sq_validation = isset($question['validation']) ? addslashes(json_encode($question['validation'])) : '';
$sql = "INSERT INTO survey_questions
(sv_id, sq_order, sq_type, sq_title, sq_required, sq_options, sq_validation)
VALUES
('$sv_id', '$sq_order', '$sq_type', '$sq_title', '$sq_required', '$sq_options', '$sq_validation')";
sql_query($sql);
}
return $sv_id;
}
/**
* 설문 데이터 엑셀 내보내기용 배열 생성
*/
function get_survey_export_data($sv_id) {
global $g5;
$survey = get_survey($sv_id);
$questions = get_survey_questions($sv_id);
// 헤더 생성
$headers = ['응답ID', '응답자', 'IP주소', '시작시간', '완료시간'];
foreach ($questions as $question) {
$headers[] = strip_tags($question['sq_title']);
}
// 데이터 생성
$data = array();
$data[] = $headers;
$sql = "SELECT * FROM survey_responses
WHERE sv_id = '$sv_id' AND sr_status = 'completed'
ORDER BY sr_completed_at DESC";
$result = sql_query($sql);
while ($response = sql_fetch_array($result)) {
$row = array();
$row[] = $response['sr_id'];
$row[] = $response['sr_mb_id'] ?: '익명';
$row[] = $response['sr_ip'];
$row[] = $response['sr_started_at'];
$row[] = $response['sr_completed_at'];
// 각 질문별 답변
foreach ($questions as $question) {
$answer_sql = "SELECT sa_value, sa_text FROM survey_answers
WHERE sr_id = '{$response['sr_id']}' AND sq_id = '{$question['sq_id']}'";
$answer_result = sql_query($answer_sql);
$answers = array();
while ($answer = sql_fetch_array($answer_result)) {
if ($answer['sa_text']) {
$answers[] = $answer['sa_value'] . ' (' . $answer['sa_text'] . ')';
} else {
$answers[] = $answer['sa_value'];
}
}
$row[] = implode(', ', $answers);
}
$data[] = $row;
}
return $data;
}
/**
* 설문 유효성 검사
*/
function validate_survey_access($sv_id, $mb_id = null, $ip = '') {
global $g5;
$survey = get_survey($sv_id);
if (!$survey) {
return array('success' => false, 'message' => '존재하지 않는 설문입니다.');
}
// 상태 확인
if ($survey['sv_status'] != SURVEY_STATUS_ACTIVE) {
return array('success' => false, 'message' => '현재 참여할 수 없는 설문입니다.');
}
// 기간 확인
$now = date('Y-m-d H:i:s');
if ($now < $survey['sv_start_date']) {
return array('success' => false, 'message' => '아직 시작되지 않은 설문입니다.');
}
if ($now > $survey['sv_end_date']) {
return array('success' => false, 'message' => '종료된 설문입니다.');
}
// 중복 참여 확인
if (!$survey['sv_allow_multiple']) {
$where = "sv_id = '$sv_id' AND sr_status = 'completed'";
if ($mb_id) {
$where .= " AND sr_mb_id = '$mb_id'";
} else {
$where .= " AND sr_ip = '$ip'";
}
$existing = sql_fetch("SELECT COUNT(*) as cnt FROM survey_responses WHERE $where");
if ($existing['cnt'] > 0) {
return array('success' => false, 'message' => '이미 참여하신 설문입니다.');
}
}
// 최대 응답 수 확인
if ($survey['sv_max_responses']) {
$total_responses = get_survey_response_count($sv_id, 'completed');
if ($total_responses >= $survey['sv_max_responses']) {
return array('success' => false, 'message' => '설문 참여 인원이 마감되었습니다.');
}
}
return array('success' => true, 'survey' => $survey);
}