Files
ladill-transfer/app/Http/Controllers/Api/TransferController.php
T
isaaccladandCursor c396c97ce2
Deploy Ladill Transfer / deploy (push) Successful in 36s
Fix transfer share links and redesign recipient download email.
Use transfer.ladill.com share URLs in notifications and APIs, add the email
logo, and show file details with a prominent download button.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-08 15:56:06 +00:00

82 lines
2.9 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Services\Identity\MailboxUserResolver;
use App\Services\Transfer\TransferService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use RuntimeException;
class TransferController extends Controller
{
public function __construct(
private TransferService $transfers,
private MailboxUserResolver $users,
) {}
/** Service-to-service upload (e.g. Ladill Mail for attachments above 25 MB). */
public function store(Request $request): JsonResponse
{
if ($request->attributes->get('service_caller') !== 'webmail') {
return response()->json(['message' => 'Forbidden.'], 403);
}
$maxBytes = (int) config('transfer.max_file_bytes', 0);
$maxFiles = (int) config('transfer.max_files_per_transfer', 20);
$fileRules = ['required', 'file'];
if ($maxBytes > 0) {
$fileRules[] = 'max:'.(int) ceil($maxBytes / 1024);
}
$data = $request->validate([
'mailbox' => ['required', 'email', 'max:255'],
'title' => ['nullable', 'string', 'max:120'],
'message' => ['nullable', 'string', 'max:2000'],
'retention_days' => ['nullable', 'integer', 'min:1', 'max:365'],
'files' => ['required', 'array', 'min:1', 'max:'.$maxFiles],
'files.*' => $fileRules,
]);
try {
$user = $this->users->resolve((string) $data['mailbox']);
} catch (RuntimeException $e) {
return response()->json(['message' => $e->getMessage()], 422);
}
$title = trim((string) ($data['title'] ?? ''));
if ($title === '') {
$title = 'Email attachment';
}
$retentionDays = (int) ($data['retention_days'] ?? config('transfer.mail_retention_days', config('transfer.default_retention_days', 30)));
try {
$transfer = $this->transfers->create($user, [
'title' => $title,
'message' => $data['message'] ?? null,
'retention_days' => $retentionDays,
], $request->file('files', []));
} catch (RuntimeException $e) {
return response()->json(['message' => $e->getMessage()], 422);
}
$transfer->load(['files', 'qrCode']);
return response()->json([
'data' => [
'id' => $transfer->id,
'title' => $transfer->title,
'public_url' => $transfer->qrCode?->shareUrl(),
'paid_until' => $transfer->paid_until?->toIso8601String(),
'expires_at' => $transfer->paid_until?->toIso8601String(),
'files' => $transfer->files->map(fn ($file) => [
'name' => $file->original_name,
'size_bytes' => $file->size_bytes,
])->values(),
],
], 201);
}
}