Restructure: move all files from Public HTML/ to root for Hostinger deployment
This commit is contained in:
Executable
+168
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
/**
|
||||
* MSPE Media API
|
||||
*/
|
||||
|
||||
require_once 'config.php';
|
||||
|
||||
$method = $_SERVER['REQUEST_METHOD'];
|
||||
$id = $_GET['id'] ?? null;
|
||||
|
||||
// Require auth for all media operations
|
||||
requireAuth();
|
||||
|
||||
// CSRF protection for write operations
|
||||
if ($method !== 'GET') {
|
||||
requireSameOriginRequest();
|
||||
}
|
||||
|
||||
switch ($method) {
|
||||
case 'GET':
|
||||
getMedia();
|
||||
break;
|
||||
|
||||
case 'POST':
|
||||
if (isset($_GET['action']) && $_GET['action'] === 'delete') {
|
||||
deleteMediaBatch();
|
||||
} else {
|
||||
uploadMedia();
|
||||
}
|
||||
break;
|
||||
|
||||
case 'DELETE':
|
||||
if (!$id) {
|
||||
jsonResponse(['success' => false, 'message' => 'ID required'], 400);
|
||||
}
|
||||
deleteMedia($id);
|
||||
break;
|
||||
|
||||
default:
|
||||
jsonResponse(['success' => false, 'message' => 'Method not allowed'], 405);
|
||||
}
|
||||
|
||||
function getMedia() {
|
||||
global $db;
|
||||
// For a file-based system without a dedicated media DB table,
|
||||
// we can scan the uploads directory.
|
||||
// However, keeping a record in JSON is better for metadata.
|
||||
// Let's assume we have a 'media' table.
|
||||
|
||||
$media = $db->getAll('media');
|
||||
|
||||
// Sync with filesystem?
|
||||
// For simplicity, let's just return DB records.
|
||||
// If empty, one could scan dir, but we'll rely on upload recording.
|
||||
|
||||
$folder = $_GET['folder'] ?? null;
|
||||
$type = $_GET['type'] ?? null;
|
||||
$search = $_GET['search'] ?? null;
|
||||
|
||||
if ($folder) {
|
||||
$media = array_filter($media, function($m) use ($folder) {
|
||||
return ($m['folder'] ?? '') === $folder;
|
||||
});
|
||||
}
|
||||
|
||||
if ($type) {
|
||||
$media = array_filter($media, function($m) use ($type) {
|
||||
return strpos($m['type'], $type) !== false;
|
||||
});
|
||||
}
|
||||
|
||||
if ($search) {
|
||||
$media = array_filter($media, function($m) use ($search) {
|
||||
return stripos($m['name'], $search) !== false;
|
||||
});
|
||||
}
|
||||
|
||||
// Sort recent first
|
||||
usort($media, function($a, $b) {
|
||||
return strtotime($b['created_at']) - strtotime($a['created_at']);
|
||||
});
|
||||
|
||||
jsonResponse(['success' => true, 'data' => array_values($media)]);
|
||||
}
|
||||
|
||||
function uploadMedia() {
|
||||
global $db;
|
||||
|
||||
if (empty($_FILES)) {
|
||||
jsonResponse(['success' => false, 'message' => 'No files uploaded'], 400);
|
||||
}
|
||||
|
||||
$folder = $_POST['folder'] ?? '';
|
||||
$uploaded = [];
|
||||
|
||||
foreach ($_FILES as $key => $file) {
|
||||
// Handle array uploads (multiple files)
|
||||
if (is_array($file['name'])) {
|
||||
foreach ($file['name'] as $idx => $name) {
|
||||
$singleFile = [
|
||||
'name' => $name,
|
||||
'type' => $file['type'][$idx],
|
||||
'tmp_name' => $file['tmp_name'][$idx],
|
||||
'error' => $file['error'][$idx],
|
||||
'size' => $file['size'][$idx]
|
||||
];
|
||||
$result = processUpload($singleFile, $folder);
|
||||
if ($result) $uploaded[] = $result;
|
||||
}
|
||||
} else {
|
||||
$result = processUpload($file, $folder);
|
||||
if ($result) $uploaded[] = $result;
|
||||
}
|
||||
}
|
||||
|
||||
jsonResponse(['success' => true, 'data' => $uploaded]);
|
||||
}
|
||||
|
||||
function processUpload($file, $folder) {
|
||||
global $db;
|
||||
$res = handleFileUpload($file, $folder);
|
||||
|
||||
if ($res['success']) {
|
||||
$mediaItem = [
|
||||
'name' => $file['name'],
|
||||
'path' => $res['path'], // Relative path
|
||||
'full_url' => SITE_URL . '/' . $res['path'],
|
||||
'type' => $file['type'],
|
||||
'size' => $file['size'],
|
||||
'folder' => $folder,
|
||||
'created_at' => date('Y-m-d H:i:s')
|
||||
];
|
||||
return $db->insert('media', $mediaItem);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function deleteMedia($id) {
|
||||
deleteMediaInternal($id);
|
||||
jsonResponse(['success' => true, 'message' => 'File deleted']);
|
||||
}
|
||||
|
||||
function deleteMediaInternal($id) {
|
||||
global $db;
|
||||
$item = $db->get('media', $id);
|
||||
|
||||
if ($item) {
|
||||
// Delete physical file
|
||||
$filepath = __DIR__ . '/../' . $item['path'];
|
||||
if (file_exists($filepath)) {
|
||||
unlink($filepath);
|
||||
}
|
||||
$db->delete('media', $id);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function deleteMediaBatch() {
|
||||
$ids = getRequestBody()['ids'] ?? [];
|
||||
$deleted = 0;
|
||||
foreach ($ids as $id) {
|
||||
if (deleteMediaInternal($id)) {
|
||||
$deleted++;
|
||||
}
|
||||
}
|
||||
jsonResponse(['success' => true, 'message' => "{$deleted} file(s) deleted"]);
|
||||
}
|
||||
Reference in New Issue
Block a user