101 lines
3.0 KiB
PHP
101 lines
3.0 KiB
PHP
<?php
|
|
require_once 'config.php';
|
|
require_once __DIR__ . '/error_config.php';
|
|
session_start();
|
|
set_json_headers();
|
|
require_auth();
|
|
|
|
$method = $_SERVER['REQUEST_METHOD'];
|
|
|
|
// =====================================================
|
|
// POST: 특정 폴더 안의 파일들 삭제
|
|
// 또는 특정 파일 URL들 삭제
|
|
// =====================================================
|
|
if ($method !== 'POST') {
|
|
json_response(['error' => 'POST만 허용됩니다'], 405);
|
|
}
|
|
|
|
$input = get_json_input();
|
|
|
|
// 안전 가드: uploads 디렉토리 밖으로 못 나가게
|
|
function is_safe_uploads_path($path) {
|
|
$real_uploads = realpath(UPLOADS_DIR);
|
|
$real_target = realpath($path);
|
|
if ($real_uploads === false) return false;
|
|
if ($real_target === false) return false;
|
|
return strpos($real_target, $real_uploads) === 0;
|
|
}
|
|
|
|
$deleted = [];
|
|
$failed = [];
|
|
|
|
// 1) URL 리스트로 개별 파일 삭제
|
|
if (isset($input['urls']) && is_array($input['urls'])) {
|
|
foreach ($input['urls'] as $url) {
|
|
$url = trim($url);
|
|
if ($url === '') continue;
|
|
|
|
// uploads/ 로 시작하는 상대 경로만 허용
|
|
if (!preg_match('#^uploads/#', $url)) {
|
|
$failed[] = ['url' => $url, 'reason' => 'invalid path'];
|
|
continue;
|
|
}
|
|
|
|
// 외부 URL은 건너뛰기 (http://, https:// 등)
|
|
if (preg_match('#^https?://#i', $url)) {
|
|
continue;
|
|
}
|
|
|
|
// 절대 경로 만들기
|
|
$relative = preg_replace('#^uploads/#', '', $url);
|
|
$full_path = UPLOADS_DIR . '/' . $relative;
|
|
|
|
if (!file_exists($full_path)) {
|
|
$failed[] = ['url' => $url, 'reason' => 'not found'];
|
|
continue;
|
|
}
|
|
|
|
if (!is_safe_uploads_path($full_path)) {
|
|
$failed[] = ['url' => $url, 'reason' => 'unsafe path'];
|
|
continue;
|
|
}
|
|
|
|
if (@unlink($full_path)) {
|
|
$deleted[] = $url;
|
|
} else {
|
|
$failed[] = ['url' => $url, 'reason' => 'unlink failed'];
|
|
}
|
|
}
|
|
}
|
|
|
|
// 2) 폴더 삭제 (프로젝트 폴더 통째로)
|
|
if (isset($input['folder'])) {
|
|
$folder = trim($input['folder']);
|
|
if ($folder !== '' && !preg_match('#[/\\\\]#', $folder)) {
|
|
$folder_path = UPLOADS_DIR . '/' . $folder;
|
|
if (is_dir($folder_path) && is_safe_uploads_path($folder_path)) {
|
|
// 폴더 안의 파일들 삭제
|
|
$files = glob($folder_path . '/*');
|
|
foreach ($files as $f) {
|
|
if (is_file($f)) {
|
|
if (@unlink($f)) {
|
|
$deleted[] = $folder . '/' . basename($f);
|
|
} else {
|
|
$failed[] = ['url' => $folder . '/' . basename($f), 'reason' => 'unlink failed'];
|
|
}
|
|
}
|
|
}
|
|
// 빈 폴더는 삭제
|
|
@rmdir($folder_path);
|
|
}
|
|
}
|
|
}
|
|
|
|
json_response([
|
|
'success' => true,
|
|
'deleted_count' => count($deleted),
|
|
'failed_count' => count($failed),
|
|
'deleted' => $deleted,
|
|
'failed' => $failed
|
|
]);
|