<?php
namespace App\Controller\Api;
use App\Service\LetterFilesService;
use Doctrine\ORM\EntityManagerInterface;
use Evo\Infrastructure\MappingORM\Letter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\HeaderUtils;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\Routing\Annotation\Route;
class DownloadLettersOrganizationController extends AbstractController
{
private EntityManagerInterface $entityManager;
private LetterFilesService $letterFilesService;
public function __construct(EntityManagerInterface $entityManager, LetterFilesService $letterFilesService)
{
$this->entityManager = $entityManager;
$this->letterFilesService = $letterFilesService;
}
/**
* @Route("/organizations/{id}/download/letters", name="app_organization_letters_download", methods={"GET"})
*/
public function getAllLettersForOrganizationId(Request $request, string $id): Response
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$queryLetterIds = $request->query->get('letterIds', []);
$idsArray = isset($queryLetterIds[0]) ? explode(',', $queryLetterIds[0]) : [];
/** @var \Iterator<Letter> $letters */
$letterRepo = $this->entityManager->getRepository(Letter::class);
$letters = $letterRepo->getLettersForDownloadForOrganizationId($id, $idsArray);
// Vérifier si la liste de lettres est vide
if (!iterator_count($letterRepo->getLettersForDownloadForOrganizationId($id, $idsArray))) {
return new Response('File not found', Response::HTTP_NOT_FOUND);
}
// Stream the zip directly to the output
$response = new StreamedResponse(function () use ($letters, $id) {
$zip = new \ZipArchive();
$zipFilename = tempnam(sys_get_temp_dir(), 'zip');
if (true === $zip->open($zipFilename, \ZipArchive::CREATE | \ZipArchive::OVERWRITE)) {
foreach ($letters as $letter) {
if ($letter['contentPathAWS'] && $this->letterFilesService->isFileExist($letter['contentPathAWS'])) {
$splitPath = explode('/', $letter['contentPathAWS']);
$slug = end($splitPath);
// Ajouter le fichier directement au zip en mémoire
$zip->addFromString('courriers_'.$id.'/'.$slug, $this->letterFilesService->read($letter['contentPathAWS']));
}
}
$zip->close();
}
// Lire et streamer le contenu du zip directement
readfile($zipFilename);
unlink($zipFilename); // Supprimer le fichier temporaire
});
$response->headers->set('Content-Type', 'application/zip');
$response->headers->set('Content-Disposition', HeaderUtils::makeDisposition(
HeaderUtils::DISPOSITION_ATTACHMENT,
$id.'_letters.zip'
));
return $response;
}
}