Files
Rosary/api/upload_photo.php
T
pguzman 663fde3909 Initial commit — Rosary Presenter App
Full source for loveandrosary.com: slide-based Rosary/novena/Divine Mercy
Chaplet presentation tool with multi-user roles, SVG bead ring, audio uploads,
donate strip, and public session profiles.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 18:44:08 -07:00

79 lines
2.3 KiB
PHP

<?php
/**
* api/upload_photo.php
* POST: handle photo upload.
* Returns JSON: {"path": "uploads/filename.jpg"} on success, {"error": "..."} on failure.
*/
require_once __DIR__ . '/../config/db.php';
require_once __DIR__ . '/../includes/auth.php';
header('Content-Type: application/json');
require_auth();
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo json_encode(['error' => 'Method not allowed']);
exit;
}
if (!isset($_FILES['photo']) || $_FILES['photo']['error'] !== UPLOAD_ERR_OK) {
$upload_errors = [
UPLOAD_ERR_INI_SIZE => 'File exceeds server upload limit',
UPLOAD_ERR_FORM_SIZE => 'File exceeds form size limit',
UPLOAD_ERR_PARTIAL => 'File was only partially uploaded',
UPLOAD_ERR_NO_FILE => 'No file was uploaded',
UPLOAD_ERR_NO_TMP_DIR => 'Missing temporary folder',
UPLOAD_ERR_CANT_WRITE => 'Failed to write file to disk',
UPLOAD_ERR_EXTENSION => 'A PHP extension stopped the upload',
];
$err_code = $_FILES['photo']['error'] ?? UPLOAD_ERR_NO_FILE;
$err_msg = $upload_errors[$err_code] ?? 'Unknown upload error';
http_response_code(400);
echo json_encode(['error' => $err_msg]);
exit;
}
$file = $_FILES['photo'];
$max_size = 5 * 1024 * 1024; // 5 MB
// Validate file size
if ($file['size'] > $max_size) {
http_response_code(400);
echo json_encode(['error' => 'File is too large (max 5 MB)']);
exit;
}
// Validate MIME type using finfo (not just extension)
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime = $finfo->file($file['tmp_name']);
$allowed = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
if (!in_array($mime, $allowed, true)) {
http_response_code(400);
echo json_encode(['error' => 'Invalid file type. Allowed: JPEG, PNG, GIF, WebP']);
exit;
}
$ext_map = [
'image/jpeg' => 'jpg',
'image/png' => 'png',
'image/gif' => 'gif',
'image/webp' => 'webp',
];
$ext = $ext_map[$mime];
$filename = bin2hex(random_bytes(16)) . '.' . $ext;
$dest = UPLOADS_DIR . $filename;
if (!is_dir(UPLOADS_DIR)) {
mkdir(UPLOADS_DIR, 0755, true);
}
if (!move_uploaded_file($file['tmp_name'], $dest)) {
http_response_code(500);
echo json_encode(['error' => 'Failed to save file']);
exit;
}
echo json_encode(['path' => UPLOADS_URL . $filename]);