Files
egbim_homepage/egbim/bbs/descope_qa_comment.php
T
2026-07-23 16:15:57 +09:00

196 lines
6.2 KiB
PHP

<?php
// /egbim/bbs/descope_qa_comment.php
date_default_timezone_set('Asia/Seoul');
header('Content-Type: application/json; charset=utf-8');
ini_set('display_errors', 1);
error_reporting(E_ALL);
function out($arr, $code=200){
http_response_code($code);
echo json_encode($arr, JSON_UNESCAPED_UNICODE);
exit;
}
/* ✅ 세션 복원 */
require_once __DIR__ . '/../skin/member/basic/descope_session.php';
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
/* ✅ 로그인 정보 */
$loginId = $_SESSION['user']['loginIds'][0] ?? '';
$userName = $_SESSION['user']['name'] ?? ($_SESSION['user']['userName'] ?? '');
/* ✅ 관리자 가드 */
@include_once $_SERVER['DOCUMENT_ROOT'].'/egbim/bbs/admin_guard.php';
$isAdmin = function_exists('is_qna_admin') ? is_qna_admin($loginId) : false;
if ($isAdmin && function_exists('get_admin_display_name')) {
$userName = get_admin_display_name($loginId, $userName);
}
/* ✅ 입력 데이터 */
$data = $_POST;
$postId = isset($data['postId']) ? (int)$data['postId'] : 0;
$comment = isset($data['comment']) ? trim($data['comment']) : '';
if ($postId < 1 || ($comment === '' && empty($_FILES['images']['name'][0]))) {
out(['status'=>'fail','message'=>'댓글 또는 이미지가 필요합니다.'], 400);
}
if (mb_strlen($comment,'UTF-8') > 2000) {
out(['status'=>'fail','message'=>'댓글은 2,000자 이내로 입력하세요.'], 400);
}
/* ✅ DB 연결 */
try{
$pdo = new PDO(
"mysql:host=db;dbname=egbim;charset=utf8mb4",
'egbim','baron3840!!',
[
PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE=>PDO::FETCH_ASSOC,
]
);
$pdo->exec("SET time_zone = '+09:00'");
}catch(Exception $e){
out(['status'=>'fail','message'=>'DB 연결 실패: '.$e->getMessage()],500);
}
/* ✅ 글 존재 확인 */
$st = $pdo->prepare("SELECT post_id, login_id AS author_id, is_secret FROM qa_posts WHERE post_id=?");
$st->execute([$postId]);
$post = $st->fetch();
if (!$post) out(['status'=>'fail','message'=>'존재하지 않는 글입니다.'],404);
if (!$isAdmin && (int)$post['is_secret'] === 1 && $post['author_id'] !== $loginId) {
out(['status'=>'fail','message'=>'비밀글에는 작성자 본인과 관리자만 댓글을 작성할 수 있습니다.'],403);
}
/* ✅ 로그인 이름 폴백 */
if ($loginId === '') $loginId = 'guest';
if ($userName === '') $userName = $loginId;
/* ✅ 댓글 INSERT */
try {
$ins = $pdo->prepare("
INSERT INTO qa_comments (post_id, commenter, user_name, content, created_at)
VALUES (:pid, :login_id, :user_name, :content, NOW())
");
$ins->execute([
':pid' => $postId,
':login_id' => $loginId,
':user_name' => $userName,
':content' => $comment,
]);
$cid = (int)$pdo->lastInsertId();
} catch (Exception $e) {
out(['status'=>'fail','message'=>'댓글 저장 실패: '.$e->getMessage()],500);
}
/* ================================
댓글 이미지 업로드 + 썸네일 생성
================================ */
$uploadedPaths = [];
$thumbPaths = [];
$uploadDir = $_SERVER['DOCUMENT_ROOT'].'/egbim/uploads/comment/';
$thumbDir = $uploadDir.'thumb/';
$uploadUrl = '/uploads/comment/';
$thumbUrl = '/uploads/comment/thumb/';
if (!is_dir($uploadDir)) mkdir($uploadDir, 0777, true);
if (!is_dir($thumbDir)) mkdir($thumbDir, 0777, true);
// 🔧 썸네일 생성 함수
function create_thumbnail($src, $dest, $target_width = 180) {
$info = getimagesize($src);
if (!$info) return false;
switch ($info[2]) {
case IMAGETYPE_JPEG: $img = imagecreatefromjpeg($src); break;
case IMAGETYPE_PNG: $img = imagecreatefrompng($src); break;
case IMAGETYPE_GIF: $img = imagecreatefromgif($src); break;
case IMAGETYPE_WEBP: $img = imagecreatefromwebp($src); break;
default: return false;
}
$width = $info[0];
$height = $info[1];
$target_height = intval($height * ($target_width / $width));
$thumb = imagecreatetruecolor($target_width, $target_height);
imagecopyresampled($thumb, $img, 0, 0, 0, 0,
$target_width, $target_height,
$width, $height
);
imagejpeg($thumb, $dest, 90);
return true;
}
$imageList = [];
// 🔧 이미지 저장
if (!empty($_FILES['images']['name'][0])) {
foreach ($_FILES['images']['tmp_name'] as $i => $tmpName) {
if (!is_uploaded_file($tmpName)) continue;
$ext = strtolower(pathinfo($_FILES['images']['name'][$i], PATHINFO_EXTENSION));
if (!in_array($ext, ['jpg','jpeg','png','gif','webp'])) continue;
$newName = time().'_'.bin2hex(random_bytes(3)).'.'.$ext;
$dest = $uploadDir.$newName;
$thumbName = 'thumb_'.$newName;
$thumbDest = $thumbDir.$thumbName;
// 원본 저장
if (move_uploaded_file($tmpName, $dest)) {
chmod($dest, 0644);
// 🔥 썸네일 생성
create_thumbnail($dest, $thumbDest, 180);
$uploadedPaths[] = $uploadUrl.$newName;
$thumbPaths[] = $thumbUrl.$thumbName;
}
}
/* 🔧 DB 저장 */
$imgStmt = $pdo->prepare("
INSERT INTO qa_comment_images (comment_id, file_name, file_path, thumb_path)
VALUES (:cid, :name, :path, :thumb)
");
foreach ($uploadedPaths as $i => $url) {
$imgStmt->execute([
':cid' => $cid,
':name' => $_FILES['images']['name'][$i],
':path' => $url,
':thumb'=> $thumbPaths[$i]
]);
/* 응답용 데이터 */
$imageList[] = [
'full' => $url,
'thumb' => $thumbPaths[$i],
'name' => $_FILES['images']['name'][$i]
];
}
}
/* ✅ 성공 응답 */
out([
'status' => 'ok',
'comment_id' => $cid,
'login_id' => $loginId,
'user_name' => $userName,
'comment_text' => $comment,
'created_at' => (new DateTime('now', new DateTimeZone('Asia/Seoul')))->format('Y-m-d H:i:s'),
// 'images' => $uploadedPaths,
'images' => $imageList
]);