← Back
Editing: ReportSender.php
<?php namespace App\Report; use App\Entity\User; use App\Repository\UserRepository; use App\Service\PdfService; use App\Service\SolutionService; use App\Service\Utils; use App\Session\Filter\SessionFiltersContainer; use Psr\Log\LoggerInterface; use Symfony\Bridge\Twig\Mime\TemplatedEmail; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Mailer\Exception\TransportExceptionInterface; use Symfony\Component\Mailer\MailerInterface; use Symfony\Component\Mime\Address; use Twig\Environment; use Twig\Error\LoaderError; use Twig\Error\RuntimeError; use Twig\Error\SyntaxError; final class ReportSender { public function __construct( private readonly SolutionService $solutionService, private readonly MailerInterface $mailer, private readonly ReportFactory $reportFactory, private readonly Environment $templating, private readonly PdfService $pdfService, private readonly UserRepository $userRepository, private readonly SessionFiltersContainer $sessionFiltersContainer, private readonly Utils $utils, private readonly LoggerInterface $logger, private readonly string $publicDir, private readonly string $fromMail ) { } /** * @throws TransportExceptionInterface */ public function sendReportEmail(User $user, array $data, ?\DateTimeInterface $startDate = null): void { $formatter = new \IntlDateFormatter('fr_FR', \IntlDateFormatter::TRADITIONAL, \IntlDateFormatter::TRADITIONAL); $formatter->setPattern('MMMM y'); if (null === $startDate) { $startDate = new \DateTime('first day of previous month'); } $date = ucfirst($formatter->format($startDate)); $email = (new TemplatedEmail()) ->from($this->fromMail) ->to(new Address($user->getEmail())) ->subject('Rapport d\'activité du mois '.$date) // path of the Twig template to render ->htmlTemplate('emails/report-monthly.html.twig'); // attach files and solutions $solutions = []; foreach ($data as $solution => $info) { $pdfFilepath = $this->publicDir.'/uploads/'.$solution.'.pdf'; $email->attachFromPath($pdfFilepath); $solutions[] = $this->solutionService->getSolutionBySlug($solution); } // pass variables (name => value) to the template $email->context( [ 'user' => $user, 'solutions' => $solutions, 'date' => $date, ] ); $this->mailer?->send($email); } public function sendReportForUser(User $user, ?\DateTimeInterface $startDate = null): void { if ($user->hasRole('ROLE_ORGANIZATION') && null === $user->getOrganization()) { $this->logger->warning(sprintf('Skipping report for user %s: organization role without organization attached', $user->getEmail())); return; } $this->sessionFiltersContainer->initForUser($user); $list = 'manager-report'; if ($user->hasRole('ROLE_ORGANIZATION')) { $list = 'organization-report'; } if ($user->hasRole('ROLE_SUPERVISOR')) { $list = 'supervisor-report'; } if ($user->hasRole('ROLE_AGENT')) { $list = 'agent-report'; } $data = $this->reportFactory->getReportInfo($list, $user, $startDate); if (false === $this->isSendable($data)) { return; } $pdfFilepath = []; foreach ($data as $solution => $info) { $pdfFilepath[] = $this->generateReportPdf($user, $solution, $info, $startDate); } $this->sendReportEmail($user, $data, $startDate); $filesystem = new Filesystem(); foreach ($pdfFilepath as $filePath) { if (!empty($filePath) && $filesystem->exists($pdfFilepath)) { $filesystem->remove($pdfFilepath); } } } /** * @throws LoaderError * @throws RuntimeError * @throws SyntaxError * @throws TransportExceptionInterface */ public function sendReportForUsers(string $role): void { $users = $this->userRepository->findByRole($role); foreach ($users as $user) { try { $this->sendReportForUser($user); } catch (\Throwable $e) { $this->logger->error(sprintf('Failed to send report for user %s: %s', $user->getEmail(), $e->getMessage())); } } } /** * @throws SyntaxError * @throws RuntimeError * @throws LoaderError */ public function generateReportPdf( User $user, string $solution, array $info, ?\DateTimeInterface $startDate = null ): string { if (null === $startDate) { $startDate = new \DateTime('first day of previous month'); } $formatter = new \IntlDateFormatter('fr_FR', \IntlDateFormatter::TRADITIONAL, \IntlDateFormatter::TRADITIONAL); $formatter->setPattern('MMMM y'); $logo = $this->utils->imageToBase64($this->publicDir.'/img/arithmetic-logo.png'); $arrowTrendDown = $this->utils->imageToBase64($this->publicDir.'/img/arrow-trend-down-solid.png'); $arrowTrendUp = $this->utils->imageToBase64($this->publicDir.'/img/arrow-trend-up-solid.png'); $logoData = $this->utils->imageToBase64($this->publicDir.'/img/'.$solution.'-logo.png'); $compagnyLogoPath = $user->getAgency()?->getLogo() ?? $user->getOrganization()?->getLogo(); $html = $this->templating->render('emails/pdf/report.html.twig', [ 'user' => $user, 'info' => $info, 'prevDate' => ucfirst($formatter->format((clone $startDate)->sub(new \DateInterval('P1M')))), 'date' => ucfirst($formatter->format($startDate)), 'solution' => $solution, 'logo' => $logo, 'compagnyLogo' => $compagnyLogoPath ? $this->utils->imageToBase64( "$this->publicDir/uploads/logos/$compagnyLogoPath" ) : null, 'logoData' => $logoData, 'arrowTrendDown' => $arrowTrendDown, 'arrowTrendUp' => $arrowTrendUp, ]); $pdfFilepath = $this->publicDir.'/uploads/'.$solution.'.pdf'; $this->pdfService->generatePdf($html, $pdfFilepath); return ''; } private function isSendable(array $reportInfos): bool { $totalControls = array_reduce( $reportInfos, function (int $carry, array $item) { $carry += $item['totalControls']; return $carry; }, 0 ); return $totalControls > 0; } }
Save File
Cancel