365 lines
12 KiB
PHP
365 lines
12 KiB
PHP
<?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);
|
|
} |