Files
edu/ajax/toggle_content_wishlist.php

239 lines
7.1 KiB
PHP

<?php
//=========================
// [마이페이지][북마크 토글]
// - 저장한 콘텐츠 체크 / 체크해제 처리
// - 체크해제 시 실제 delete 하지 않고 is_active 값을 0으로 update
// - 체크 시 is_active 값을 1로 update 또는 신규 insert
//=========================
require_once __DIR__ . '/../bbs/db_conn.php';
header('Content-Type: application/json; charset=utf-8');
// ---------------------------------------------------------
// 세션 시작
// TODO: 실제 로그인 세션 연동 후 교체
// ---------------------------------------------------------
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
$memberId = $_SESSION['member_id'] ?? '';
$sysCompCode = $_SESSION['sys_comp_code'] ?? '';
// 테스트용 임시값
// $memberId = 'U001';
// $sysCompCode = 'COMP01';
/**
* JSON 응답 출력 후 종료
*/
function response_json(array $data): void
{
echo json_encode($data, JSON_UNESCAPED_UNICODE);
exit;
}
try {
$pdo = db_conn();
$pdo->exec("SET NAMES 'utf8mb4'");
// ---------------------------------------------------------
// 1. 요청 JSON 읽기
// - 프런트에서 fetch + JSON body로 전달
// ---------------------------------------------------------
$raw = file_get_contents('php://input');
$req = json_decode($raw, true);
$contentId = trim((string)($req['content_id'] ?? ''));
$isChecked = trim((string)($req['is_checked'] ?? ''));
// ---------------------------------------------------------
// 2. 기본 유효성 검사
// ---------------------------------------------------------
if ($memberId === '' || $sysCompCode === '') {
response_json([
'success' => false,
'message' => '로그인 정보가 없습니다.'
]);
}
if ($contentId === '') {
response_json([
'success' => false,
'message' => 'content_id가 없습니다.'
]);
}
// ---------------------------------------------------------
// 3. 체크값 정규화
// - 현재 운영 중 프런트는 Y/N을 보낼 수 있고,
// 향후 1/0으로 바뀔 가능성도 있으므로 둘 다 허용
// - 최종적으로 DB 저장용 is_active 값은 '1' / '0' 으로 맞춘다.
// ---------------------------------------------------------
if ($isChecked === 'Y' || $isChecked === '1') {
$activeValue = '1';
} elseif ($isChecked === 'N' || $isChecked === '0') {
$activeValue = '0';
} else {
response_json([
'success' => false,
'message' => '유효하지 않은 요청입니다.'
]);
}
// ---------------------------------------------------------
// 4. 기존 북마크 이력 존재 여부 확인
// - member_id + sys_comp_code + content_id 조합 기준
// ---------------------------------------------------------
$stmtCheck = $pdo->prepare("
SELECT COUNT(*) AS cnt
FROM edu_content_wishlist
WHERE member_id = :member_id
AND sys_comp_code = :sys_comp_code
AND content_id = :content_id
");
$stmtCheck->execute([
':member_id' => $memberId,
':sys_comp_code' => $sysCompCode,
':content_id' => $contentId,
]);
$exists = (int)$stmtCheck->fetchColumn();
// ---------------------------------------------------------
// 5. INSERT / UPDATE 처리
//
// [기존 row 있음]
// - is_active만 update
// - updated_at 갱신
// - 체크(활성화) 시 favorited_at도 NOW()로 갱신
//
// [기존 row 없음]
// - 신규 insert
// - created_at / updated_at 저장
// - 체크 상태가 1이면 favorited_at도 NOW() 저장
//
// ※ 실제 delete 하지 않고 soft delete 방식 유지
// ---------------------------------------------------------
if ($exists > 0) {
if ($activeValue === '1') {
// 체크 ON
$stmtUpdate = $pdo->prepare("
UPDATE edu_content_wishlist
SET is_active = :is_active,
favorited_at = NOW(),
updated_at = NOW()
WHERE member_id = :member_id
AND sys_comp_code = :sys_comp_code
AND content_id = :content_id
");
} else {
// 체크 OFF
$stmtUpdate = $pdo->prepare("
UPDATE edu_content_wishlist
SET is_active = :is_active,
updated_at = NOW()
WHERE member_id = :member_id
AND sys_comp_code = :sys_comp_code
AND content_id = :content_id
");
}
$stmtUpdate->execute([
':is_active' => $activeValue,
':member_id' => $memberId,
':sys_comp_code' => $sysCompCode,
':content_id' => $contentId,
]);
} else {
if ($activeValue === '1') {
// 신규 체크 ON insert
$stmtInsert = $pdo->prepare("
INSERT INTO edu_content_wishlist (
member_id,
sys_comp_code,
content_id,
is_active,
favorited_at,
created_at,
updated_at
) VALUES (
:member_id,
:sys_comp_code,
:content_id,
:is_active,
NOW(),
NOW(),
NOW()
)
");
} else {
// 신규 체크 OFF 요청이 들어온 경우도 예외 없이 기록은 남김
// (운영상 불필요하다면 이 분기는 막아도 됨)
$stmtInsert = $pdo->prepare("
INSERT INTO edu_content_wishlist (
member_id,
sys_comp_code,
content_id,
is_active,
created_at,
updated_at
) VALUES (
:member_id,
:sys_comp_code,
:content_id,
:is_active,
NOW(),
NOW()
)
");
}
$stmtInsert->execute([
':member_id' => $memberId,
':sys_comp_code' => $sysCompCode,
':content_id' => $contentId,
':is_active' => $activeValue,
]);
}
// ---------------------------------------------------------
// 6. saved 탭 카운트만 재계산
// - 북마크 토글은 saved 상태만 변경하므로
// watching / completed 카운트는 여기서 건드리지 않는다.
// ---------------------------------------------------------
$stmtSavedCount = $pdo->prepare("
SELECT COUNT(*)
FROM edu_content_wishlist cw
WHERE cw.member_id = :saved_member_id
AND cw.sys_comp_code = :saved_sys_comp_code
AND cw.is_active = '1'
");
$stmtSavedCount->execute([
':saved_member_id' => $memberId,
':saved_sys_comp_code' => $sysCompCode,
]);
$savedCount = (int)$stmtSavedCount->fetchColumn();
// ---------------------------------------------------------
// 7. 성공 응답 반환
// ---------------------------------------------------------
response_json([
'success' => true,
'content_id' => $contentId,
'is_checked' => $activeValue,
'counts' => [
'saved' => $savedCount,
]
]);
} catch (Throwable $e) {
response_json([
'success' => false,
'message' => '북마크 처리 중 오류가 발생했습니다.',
'error' => $e->getMessage(),
]);
}