Skip to content

Commit

Permalink
Merge pull request #1902 from MTES-MCT/hotfix/1886-pdf-replace-file-a…
Browse files Browse the repository at this point in the history
…ttached-email-by-download-file

[QA] Export PDF - Remplacer la pièce jointe par un lien de téléchargement dans le mail
  • Loading branch information
emilschn authored Nov 13, 2023
2 parents 473e739 + 0cc976c commit 4fe741a
Show file tree
Hide file tree
Showing 18 changed files with 135 additions and 61 deletions.
2 changes: 1 addition & 1 deletion src/Command/SlugifyDocumentSignalementCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ public function execute(InputInterface $input, OutputInterface $output): int

$command = 'make upload action=image zip='.$this->territory->getZip();
if (\count($file) > 1) {
$this->uploadHandlerService->uploadFromFilename($filename, self::BASE_DIRECTORY_CSV);
$this->uploadHandlerService->moveFromBucketTempFolder($filename, self::BASE_DIRECTORY_CSV);
$io->success(sprintf('%s files has been slugify', $countFileSlugged));
$io->success(
sprintf(
Expand Down
14 changes: 9 additions & 5 deletions src/Controller/Back/SignalementFileController.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,17 @@ public function generatePdfSignalement(
/** @var User $user */
$user = $this->getUser();

$message = (new PdfExportMessage())
->setSignalementId($signalement->getId())
->setUserEmail($user->getEmail());
if ($signalement->getPhotos()->count() < 21) {
$message = (new PdfExportMessage())
->setSignalementId($signalement->getId())
->setUserEmail($user->getEmail());

$messageBus->dispatch($message);
$messageBus->dispatch($message);

$this->addFlash('success', 'L\'export pdf vous sera envoyé par email !');
$this->addFlash('success', 'L\'export pdf vous sera envoyé par email !');
} else {
$this->addFlash('error', 'La fonctionnalité est temporairement désactivée sur ce signalement en raison d\'un trop grand nombre de photos.');
}

return $this->redirect($this->generateUrl('back_signalement_view', ['uuid' => $signalement->getUuid()]));
}
Expand Down
2 changes: 1 addition & 1 deletion src/Controller/FrontSignalementController.php
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ public function envoi(
foreach ($dataFiles as $key => $files) {
foreach ($files as $titre => $file) {
$file = $fileFactory->createInstanceFrom(
filename: $uploadHandlerService->uploadFromFilename($file),
filename: $uploadHandlerService->moveFromBucketTempFolder($file),
title: $titre,
type: 'documents' === $key ? File::FILE_TYPE_DOCUMENT : File::FILE_TYPE_PHOTO
);
Expand Down
8 changes: 4 additions & 4 deletions src/Controller/Security/SecurityController.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,16 @@ public function check()
throw new LogicException('This code should never be reached');
}

#[Route('/_up/{filename}', name: 'show_uploaded_file')]
#[Route('/_up/{filename}/{uuid?}', name: 'show_uploaded_file')]
public function showUploadedFile(
string $filename,
LoggerInterface $logger,
Signalement|null $signalement = null): BinaryFileResponse|RedirectResponse
{
Signalement|null $signalement = null
): BinaryFileResponse|RedirectResponse {
$request = Request::createFromGlobals();
$this->denyAccessUnlessGranted(
'FILE_VIEW',
$this->isCsrfTokenValid('suivi_signalement_ext_file_view', $request->get('t'))
null === $this->getUser() ? $this->isCsrfTokenValid('suivi_signalement_ext_file_view', $request->get('t')) : $signalement
);

$tmpFilepath = $this->getParameter('uploads_tmp_dir').$filename;
Expand Down
15 changes: 11 additions & 4 deletions src/Messenger/MessageHandler/PdfExportMessageHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
use App\Service\Mailer\NotificationMail;
use App\Service\Mailer\NotificationMailerRegistry;
use App\Service\Mailer\NotificationMailerType;
use App\Service\Signalement\Export\SignalementExportPdf;
use App\Service\Signalement\Export\SignalementExportPdfGenerator;
use App\Service\UploadHandlerService;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
use Twig\Environment;
Expand All @@ -17,10 +18,11 @@ class PdfExportMessageHandler
{
public function __construct(
private readonly NotificationMailerRegistry $notificationMailerRegistry,
private readonly SignalementExportPdf $signalementExportPdf,
private readonly SignalementExportPdfGenerator $signalementExportPdfGenerator,
private readonly Environment $twig,
private readonly SignalementRepository $signalementRepository,
private readonly ParameterBagInterface $parameterBag,
private readonly UploadHandlerService $uploadHandlerService,
) {
}

Expand All @@ -40,17 +42,22 @@ public function __invoke(PdfExportMessage $pdfExportMessage): void
'situations' => $criticitesFormatted,
]);

$pdfContent = $this->signalementExportPdf->generate(
$tmpFilename = $this->signalementExportPdfGenerator->generateToTempFolder(
$signalement,
$htmlContent,
$this->parameterBag->get('export_options')
);

$filename = $this->uploadHandlerService->uploadFromFilename($tmpFilename);

$this->notificationMailerRegistry->send(
new NotificationMail(
type: NotificationMailerType::TYPE_PDF_EXPORT,
to: $pdfExportMessage->getUserEmail(),
signalement: $signalement,
attachment: ['content' => $pdfContent, 'filename' => $signalement->getReference().'.pdf'],
params: [
'filename' => $filename,
]
)
);
}
Expand Down
24 changes: 21 additions & 3 deletions src/Security/Voter/FileVoter.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ protected function voteOnAttribute(string $attribute, $subject, TokenInterface $
/** @var User $user */
$user = $token->getUser();
if ($user instanceof UserInterface) {
if ($user->isSuperAdmin() || $subject instanceof Signalement && $subject->getTerritory() === $user->getTerritory()) {
if ($user->isSuperAdmin() || (
$user->isTerritoryAdmin() &&
$subject instanceof Signalement &&
$subject->getTerritory() === $user->getTerritory()
)
) {
return true;
}
}
Expand All @@ -51,8 +56,21 @@ private function canCreate(Signalement $signalement, User $user): bool
})->count() > 0;
}

private function canView(bool $authorization, User|null $user): bool
private function canView(bool|Signalement $subject, ?User $user = null): bool
{
return $authorization || $user instanceof UserInterface;
return $subject instanceof Signalement ? $this->checkSignalementPermission($subject, $user) : $subject;
}

private function checkSignalementPermission(Signalement $signalement, ?User $user = null): bool
{
if (null === $user) {
return false;
}

return $signalement->getAffectations()->filter(
function (Affectation $affectation) use ($user) {
return $affectation->getPartner()->getId() === $user->getPartner()->getId();
}
)->count() > 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@

class SignalementPdfExportMailer extends AbstractNotificationMailer
{
public const FILE_404 = 'blank.pdf';
protected ?NotificationMailerType $mailerType = NotificationMailerType::TYPE_PDF_EXPORT;
protected ?string $mailerSubject = 'Voici l\'export pdf du signalement !';
protected ?string $mailerButtonText = 'Accéder au signalement';
protected ?string $mailerButtonText = 'Afficher le PDF';
protected ?string $mailerTemplate = 'signalement_pdf_export';

public function __construct(
Expand All @@ -29,12 +30,16 @@ public function __construct(
public function getMailerParamsFromNotification(NotificationMail $notificationMail): array
{
$signalement = $notificationMail->getSignalement();
$attachment = $notificationMail->getAttachment();

return [
'signalement' => $signalement,
'attachContent' => $attachment,
'link' => $this->generateLinkSignalementView($signalement->getUuid()),
'link' => $this->generateLink(
'show_uploaded_file', [
'folder' => '_up',
'filename' => $notificationMail->getParams()['filename'] ?? self::FILE_404,
'uuid' => $signalement->getUuid(),
]
),
];
}
}
17 changes: 0 additions & 17 deletions src/Service/Signalement/Export/SignalementExportPdf.php

This file was deleted.

33 changes: 33 additions & 0 deletions src/Service/Signalement/Export/SignalementExportPdfGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace App\Service\Signalement\Export;

use App\Entity\Signalement;
use Knp\Snappy\Pdf;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;

class SignalementExportPdfGenerator
{
public function __construct(private readonly Pdf $pdf, private readonly ParameterBagInterface $parameterBag)
{
}

public function generate(string $content, ?array $options = null): string
{
return $this->pdf->getOutputFromHtml($content, $options ?? []);
}

public function generateToTempFolder(
Signalement $signalement,
string $content,
?array $options = null
): string {
$pdfContent = $this->generate($content, $options);

$filename = 'export-pdf-signalement-'.$signalement->getUuid().'.pdf';
$tmpFilepath = $this->parameterBag->get('uploads_tmp_dir').$filename;
file_put_contents($tmpFilepath, $pdfContent);

return $filename;
}
}
2 changes: 1 addition & 1 deletion src/Service/Signalement/SignalementFileProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public function process(array $files, string $inputName): array
);
$title = $this->filenameGenerator->getTitle();
} else {
$filename = $this->uploadHandlerService->uploadFromFilename($file);
$filename = $this->uploadHandlerService->moveFromBucketTempFolder($file);
$title = $key;
$withTokenGenerated = true;
}
Expand Down
23 changes: 22 additions & 1 deletion src/Service/UploadHandlerService.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public function toTempFolder(UploadedFile $file): self|array
return $this;
}

public function uploadFromFilename(string $filename, ?string $directory = null): ?string
public function moveFromBucketTempFolder(string $filename, ?string $directory = null): ?string
{
$filename = null === $directory ? $filename : $directory.$filename;
$this->logger->info($filename);
Expand All @@ -96,6 +96,27 @@ public function uploadFromFilename(string $filename, ?string $directory = null):
return null;
}

public function uploadFromFilename(string $filename): ?string
{
$this->logger->info($filename);
$localTmpFolder = $this->parameterBag->get('uploads_tmp_dir');
$tmpFilepath = $localTmpFolder.$filename;

try {
$pathInfo = pathinfo($tmpFilepath);
$newFilename = $pathInfo['filename'].'.'.$pathInfo['extension'];

$fileResource = fopen($tmpFilepath, 'r');
$this->fileStorage->writeStream($newFilename, $fileResource);

return $newFilename;
} catch (FilesystemException $exception) {
$this->logger->error($exception->getMessage());
}

return null;
}

/**
* @throws MaxUploadSizeExceededException
*/
Expand Down
13 changes: 10 additions & 3 deletions templates/back/signalement/view/header.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,16 @@
{% endif %}

{% if canExportSignalement %}
<a href="#" data-user="Exporter le PDF" data-mail="La fonctionnalité est temporairement désactivée."
class="fr-btn fr-btn--sm fr-btn--icon-left fr-fi-file-pdf-fill ignore-blank-style disabled-link part-infos-hover"
title="Exporter le PDF" >Exporter le PDF</a>
{% if signalement.getPhotos()|length < 21 %}
<a href="{{ path('back_signalement_gen_pdf',{uuid:signalement.uuid}) }}"
class="fr-btn fr-btn--sm fr-btn--icon-left fr-fi-file-pdf-fill ignore-blank-style"
title="Exporter le PDF">Exporter le PDF
</a>
{% else %}
<a href="#" data-user="Exporter le PDF" data-mail="La fonctionnalité est temporairement désactivée sur ce signalement en raison d'un trop grand nombre de photos."
class="fr-btn fr-btn--sm fr-btn--icon-left fr-fi-file-pdf-fill ignore-blank-style disabled-link part-infos-hover"
title="Exporter le PDF" >Exporter le PDF</a>
{% endif %}
{% endif %}
</div>
</div>
Expand Down
6 changes: 3 additions & 3 deletions templates/back/signalement/view/photos-documents.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@
<div class="fr-px-5w fr-py-8w fr-rounded fr-border fr-text--center part-infos-hover"
data-user="{{ photo.user.nomComplet ?? 'N/R' }}" data-mail="{{ photo.createdAt is defined ? photo.createdAt|date('d.m.Y') : 'N/R' }}
"
style="background: url('{{ asset('_up/'~photo.filename) }}')no-repeat center center/cover">
<a href="{{ asset('_up/'~photo.filename) }}"
style="background: url('{{ asset('_up/'~photo.filename~'/'~signalement.uuid) }}')no-repeat center center/cover">
<a href="{{ asset('_up/'~photo.filename~'/'~signalement.uuid) }}"
class="fr-btn fr-btn--sm fr-icon-eye-line img-box" title="Voir la photo"
target="_blank" rel="noopener"></a>
{% if is_granted('ROLE_ADMIN_PARTNER') or (isAffected and isAccepted) %}
Expand Down Expand Up @@ -82,7 +82,7 @@
</div>
</div>
<div class="fr-col-3 fr-text--right">
<a href="{{ asset('_up/'~doc.filename) }}"
<a href="{{ asset('_up/'~doc.filename~'/'~signalement.uuid) }}"
class="fr-btn fr-btn--sm fr-icon-eye-fill img-box" title="Afficher le document"
target="_blank" rel="noopener"></a>
{% if (is_granted('ROLE_ADMIN_PARTNER') or (isAffected and isAccepted))
Expand Down
4 changes: 2 additions & 2 deletions tests/Functional/Controller/SecurityControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public function testShowUploadedFileSucceed(): void
$userRepository = static::getContainer()->get(UserRepository::class);
$user = $userRepository->findOneBy(['email' => '[email protected]']);
$client->loginUser($user);
$client->request('GET', '/_up/check.png');
$client->request('GET', '/_up/check.png/00000000-0000-0000-2022-000000000001');
/** @var BinaryFileResponse $response */
$response = $client->getResponse();
$this->assertTrue($response->isSuccessful());
Expand All @@ -30,7 +30,7 @@ public function testShowUploadedFileFailed(): void
$user = $userRepository->findOneBy(['email' => '[email protected]']);
$client->loginUser($user);

$client->request('GET', '/_up/file_not_exist.txt');
$client->request('GET', '/_up/file_not_exist.txt/00000000-0000-0000-2022-000000000001');
/** @var BinaryFileResponse $response */
$response = $client->getResponse();
$this->assertEquals('image-404.png', $response->getFile()->getFilename());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
use Symfony\Bridge\Twig\Mime\NotificationEmail;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Mime\Part\DataPart;

class PdfExportMessageHandlerTest extends WebTestCase
{
Expand Down Expand Up @@ -39,13 +38,8 @@ public function testHandleGeneratePdfMessage()
$this->assertEmailCount(1);
/** @var NotificationEmail $email */
$email = $this->getMailerMessage();
$this->assertEmailAttachmentCount($email, 1);
$this->assertEmailHtmlBodyContains($email, 'Un export pdf est disponible pour le signalement');
$this->assertEmailHtmlBodyContains($email, '#2023-1');
$this->assertEmailAddressContains($email, 'To', '[email protected]');
/** @var DataPart $attachment */
$attachment = $email->getAttachments()[0];
$this->assertEquals('2023-1.pdf', $attachment->getFilename());
$this->assertEquals('%PDF-1.4', substr($attachment->getBody(), 0, 8));
}
}
2 changes: 1 addition & 1 deletion tests/Functional/Service/UploadHandlerServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public function testUploadFromFilename(): void
$this->filenameGenerator,
);

$filename = $uploadHandlerService->uploadFromFilename('sample.txt');
$filename = $uploadHandlerService->moveFromBucketTempFolder('sample.txt');
$this->assertEquals('sample.txt', $filename);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
namespace App\Tests\Unit\Service\Signalement\Export;

use App\Repository\SignalementRepository;
use App\Service\Signalement\Export\SignalementExportPdf;
use App\Service\Signalement\Export\SignalementExportPdfGenerator;
use Knp\Snappy\Pdf;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Twig\Environment;

class SignalementExportPdfTest extends KernelTestCase
Expand All @@ -14,7 +15,8 @@ public function testGeneratePdf()
{
self::bootKernel();
$pdf = static::getContainer()->get(Pdf::class);
$signalementExportPdf = new SignalementExportPdf($pdf);
$parameterBag = static::getContainer()->get(ParameterBagInterface::class);
$signalementExportPdfGenerator = new SignalementExportPdfGenerator($pdf, $parameterBag);

$twig = static::getContainer()->get(Environment::class);
$signalementRepository = static::getContainer()->get(SignalementRepository::class);
Expand All @@ -26,7 +28,7 @@ public function testGeneratePdf()
'situations' => [],
]);
$options = static::getContainer()->getParameter('export_options');
$pdfContent = $signalementExportPdf->generate($html, $options);
$pdfContent = $signalementExportPdfGenerator->generate($html, $options);
$this->assertNotEmpty($pdfContent);
$this->assertStringStartsWith('%PDF-', $pdfContent);
}
Expand Down
Loading

0 comments on commit 4fe741a

Please sign in to comment.