Page publique /upload.php (mobile-first, sans auth) : le client scanne un QR code au comptoir, choisit le poste de destination, et envoie ses documents. Les fichiers sont déposés dans le share SMB du compte, enregistrés en BDD (mêmes tables que les mails) et déclenchent le webhook si configuré. Page admin /admin/qrcode.php pour générer/imprimer les QR codes par poste. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017SChGCatJdbmZKCyYvTJMf
105 lines
3.2 KiB
PHP
105 lines
3.2 KiB
PHP
<?php
|
|
require_once __DIR__ . '/../includes/db.php';
|
|
|
|
header('Content-Type: application/json');
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
http_response_code(405);
|
|
echo json_encode(['error' => 'Méthode non autorisée']);
|
|
exit;
|
|
}
|
|
|
|
$accountId = (int)($_POST['account_id'] ?? 0);
|
|
if (!$accountId) {
|
|
http_response_code(400);
|
|
echo json_encode(['error' => 'Compte non spécifié']);
|
|
exit;
|
|
}
|
|
|
|
$st = db()->prepare('SELECT id, username, smb_path, webhook_url FROM accounts WHERE id = ? AND active = 1');
|
|
$st->execute([$accountId]);
|
|
$account = $st->fetch();
|
|
if (!$account) {
|
|
http_response_code(404);
|
|
echo json_encode(['error' => 'Compte introuvable ou inactif']);
|
|
exit;
|
|
}
|
|
|
|
if (empty($_FILES['files']) || !is_array($_FILES['files']['name'])) {
|
|
http_response_code(400);
|
|
echo json_encode(['error' => 'Aucun fichier envoyé']);
|
|
exit;
|
|
}
|
|
|
|
$destDir = $account['smb_path'];
|
|
if (!is_dir($destDir)) mkdir($destDir, 0750, true);
|
|
|
|
$st = db()->prepare('INSERT INTO source_file (account_id, title, sender, file_name) VALUES (?, ?, ?, ?)');
|
|
$st->execute([$account['id'], 'Dépôt comptoir', 'Téléversement mobile', 'upload_' . time()]);
|
|
$sourceId = (int)db()->lastInsertId();
|
|
|
|
$uploaded = 0;
|
|
$errors = [];
|
|
$fileCount = count($_FILES['files']['name']);
|
|
|
|
for ($i = 0; $i < $fileCount; $i++) {
|
|
if ($_FILES['files']['error'][$i] !== UPLOAD_ERR_OK) {
|
|
$errors[] = $_FILES['files']['name'][$i] . ' : erreur upload';
|
|
continue;
|
|
}
|
|
|
|
$origName = $_FILES['files']['name'][$i];
|
|
$tmpPath = $_FILES['files']['tmp_name'][$i];
|
|
|
|
$safeName = preg_replace('/[^a-zA-Z0-9._\- ]/', '_', $origName);
|
|
$destPath = $destDir . '/' . $safeName;
|
|
|
|
if (file_exists($destPath)) {
|
|
$ext = pathinfo($safeName, PATHINFO_EXTENSION);
|
|
$base = pathinfo($safeName, PATHINFO_FILENAME);
|
|
$destPath = $destDir . '/' . $base . '_' . time() . ($ext ? '.' . $ext : '');
|
|
$safeName = basename($destPath);
|
|
}
|
|
|
|
if (move_uploaded_file($tmpPath, $destPath)) {
|
|
chmod($destPath, 0644);
|
|
db()->prepare('INSERT INTO files (source_file_id, file_name, path) VALUES (?, ?, ?)')
|
|
->execute([$sourceId, $safeName, $destPath]);
|
|
$uploaded++;
|
|
} else {
|
|
$errors[] = $origName . ' : échec écriture';
|
|
}
|
|
}
|
|
|
|
if ($uploaded === 0) {
|
|
db()->prepare('DELETE FROM source_file WHERE id = ?')->execute([$sourceId]);
|
|
http_response_code(500);
|
|
echo json_encode(['error' => 'Aucun fichier enregistré', 'details' => $errors]);
|
|
exit;
|
|
}
|
|
|
|
if (!empty($account['webhook_url'])) {
|
|
$ctx = stream_context_create(['http' => [
|
|
'method' => 'POST',
|
|
'header' => "Content-Type: application/json\r\n",
|
|
'content' => json_encode([
|
|
'account' => $account['username'],
|
|
'subject' => 'Dépôt comptoir',
|
|
'from' => 'Téléversement mobile',
|
|
'source_id' => $sourceId,
|
|
'files' => $uploaded,
|
|
'received_at' => date('c'),
|
|
]),
|
|
'timeout' => 5,
|
|
'ignore_errors' => true,
|
|
]]);
|
|
@file_get_contents($account['webhook_url'], false, $ctx);
|
|
}
|
|
|
|
echo json_encode([
|
|
'success' => true,
|
|
'uploaded' => $uploaded,
|
|
'account' => $account['username'],
|
|
'errors' => $errors,
|
|
]);
|