Files
sam-kd/sales_manager_scenario/delete_consultation.php
hskwon aca1767eb9 초기 커밋: 5130 레거시 시스템
- URL 하드코딩 → .env APP_URL 기반 동적 URL로 변경
- DB 연결 하드코딩 → .env 기반으로 변경
- MySQL strict mode DATE 오류 수정
2025-12-10 20:14:31 +09:00

173 lines
5.9 KiB
PHP

<?php
// 출력 버퍼링 시작
ob_start();
error_reporting(0);
require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
// GCS 삭제 함수 (GCP_storage_dev.md 참고)
function deleteFromGCS($bucket_name, $object_name, $service_account_path = null) {
if (!$service_account_path) {
$service_account_path = $_SERVER['DOCUMENT_ROOT'] . '/apikey/google_service_account.json';
}
if (!file_exists($service_account_path)) {
error_log('GCS 삭제 실패: 서비스 계정 파일 없음');
return false;
}
$serviceAccount = json_decode(file_get_contents($service_account_path), true);
if (!$serviceAccount) {
error_log('GCS 삭제 실패: 서비스 계정 JSON 파싱 오류');
return false;
}
// OAuth 2.0 토큰 생성
$now = time();
$jwtHeader = base64_encode(json_encode(['alg' => 'RS256', 'typ' => 'JWT']));
$jwtClaim = base64_encode(json_encode([
'iss' => $serviceAccount['client_email'],
'scope' => 'https://www.googleapis.com/auth/devstorage.full_control',
'aud' => 'https://oauth2.googleapis.com/token',
'exp' => $now + 3600,
'iat' => $now
]));
$privateKey = openssl_pkey_get_private($serviceAccount['private_key']);
if (!$privateKey) {
error_log('GCS 삭제 실패: 개인 키 읽기 오류');
return false;
}
openssl_sign($jwtHeader . '.' . $jwtClaim, $signature, $privateKey, OPENSSL_ALGO_SHA256);
openssl_free_key($privateKey);
$jwt = $jwtHeader . '.' . $jwtClaim . '.' . base64_encode($signature);
// OAuth 토큰 요청
$tokenCh = curl_init('https://oauth2.googleapis.com/token');
curl_setopt($tokenCh, CURLOPT_POST, true);
curl_setopt($tokenCh, CURLOPT_POSTFIELDS, http_build_query([
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'assertion' => $jwt
]));
curl_setopt($tokenCh, CURLOPT_RETURNTRANSFER, true);
curl_setopt($tokenCh, CURLOPT_HTTPHEADER, ['Content-Type: application/x-www-form-urlencoded']);
$tokenResponse = curl_exec($tokenCh);
$tokenCode = curl_getinfo($tokenCh, CURLINFO_HTTP_CODE);
curl_close($tokenCh);
if ($tokenCode !== 200) {
error_log('GCS 삭제 실패: OAuth 토큰 요청 실패 (HTTP ' . $tokenCode . ')');
return false;
}
$tokenData = json_decode($tokenResponse, true);
if (!isset($tokenData['access_token'])) {
error_log('GCS 삭제 실패: OAuth 토큰 없음');
return false;
}
$accessToken = $tokenData['access_token'];
// GCS에서 파일 삭제
$delete_url = 'https://storage.googleapis.com/storage/v1/b/' .
urlencode($bucket_name) . '/o/' .
urlencode($object_name);
$ch = curl_init($delete_url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $accessToken
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// 204 No Content 또는 404 Not Found는 성공으로 간주
if ($code === 204 || $code === 404) {
return true;
} else {
error_log('GCS 삭제 실패 (HTTP ' . $code . '): ' . $response);
return false;
}
}
// 출력 버퍼 비우기
ob_clean();
header('Content-Type: application/json; charset=utf-8');
// 권한 체크
if (!isset($user_id) || $level > 5) {
echo json_encode(['success' => false, 'message' => '접근 권한이 없습니다.']);
exit;
}
// 업무협의 ID 확인
$consultation_id = isset($_POST['id']) ? intval($_POST['id']) : 0;
$manager_id = $user_id;
if ($consultation_id <= 0) {
echo json_encode(['success' => false, 'message' => '잘못된 요청입니다.']);
exit;
}
try {
$pdo = db_connect();
// 녹음 파일 정보 조회
$sql = "SELECT audio_file_path FROM manager_consultations WHERE id = ? AND manager_id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$consultation_id, $manager_id]);
$consultation = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$consultation) {
echo json_encode(['success' => false, 'message' => '녹음 파일을 찾을 수 없습니다.']);
exit;
}
// 1. 서버 파일 삭제
if (!empty($consultation['audio_file_path'])) {
// GCS URI가 아닌 경우 로컬 파일 삭제
if (strpos($consultation['audio_file_path'], 'gs://') !== 0) {
$file_path = $_SERVER['DOCUMENT_ROOT'] . $consultation['audio_file_path'];
$file_path = str_replace('\\', '/', $file_path);
$file_path = preg_replace('#/+#', '/', $file_path);
if (file_exists($file_path)) {
@unlink($file_path);
}
} else {
// 2. GCS 파일 삭제 (GCS URI인 경우)
$gcs_uri = $consultation['audio_file_path'];
if (preg_match('#gs://([^/]+)/(.+)#', $gcs_uri, $matches)) {
$bucket_name = $matches[1];
$object_name = $matches[2];
$gcs_deleted = deleteFromGCS($bucket_name, $object_name);
if (!$gcs_deleted) {
error_log('GCS 파일 삭제 실패: ' . $gcs_uri);
}
}
}
}
// 3. DB에서 삭제
$delete_sql = "DELETE FROM manager_consultations WHERE id = ? AND manager_id = ?";
$delete_stmt = $pdo->prepare($delete_sql);
$delete_stmt->execute([$consultation_id, $manager_id]);
echo json_encode(['success' => true, 'message' => '녹음 파일이 삭제되었습니다.']);
} catch (Exception $e) {
error_log('녹음 파일 삭제 오류: ' . $e->getMessage());
echo json_encode(['success' => false, 'message' => '삭제 중 오류가 발생했습니다: ' . $e->getMessage()]);
}
?>