src/Controller/EmailController.php line 133

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Person;
  4. use App\Form\EmailType;
  5. use App\Entity\Attachment;
  6. use App\Entity\Newsletter;
  7. use App\Service\PdfService;
  8. use App\Entity\Dto\EmailDto;
  9. use App\Service\MailerService;
  10. use App\Entity\EmailHistoryEntry;
  11. use App\Repository\PersonRepository;
  12. use App\Service\EmailHistoryService;
  13. use App\Repository\InvoiceRepository;
  14. use App\Repository\NewsletterRepository;
  15. use Doctrine\Persistence\ManagerRegistry;
  16. use App\Repository\ClientConfigRepository;
  17. use Symfony\Component\HttpFoundation\Request;
  18. use Symfony\Component\HttpFoundation\Response;
  19. use App\Repository\EmailHistoryEntryRepository;
  20. use Symfony\Component\Routing\Annotation\Route;
  21. use App\Repository\CustomerHistoryEntryRepository;
  22. use Symfony\Component\HttpFoundation\File\UploadedFile;
  23. use Menke\UserBundle\Controller\AbstractClientableController;
  24. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  25. use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
  26. use Symfony\Component\HttpFoundation\File\Exception\FileException;
  27. /**
  28.  * @Route("/email")
  29.  * @IsGranted("ROLE_MANAGER")
  30.  * @IsGranted("ROLE_ADMIN")
  31.  */
  32. class EmailController extends AbstractClientableController
  33. {
  34.     const LISTING_LIMIT 20;
  35.     private $em;
  36.     public function __construct(ManagerRegistry $em)
  37.     {
  38.         $this->em $em->getManager();
  39.     }
  40.     /**
  41.      * @Route("/", name="email_index", methods="GET")
  42.      */
  43.     public function index(EmailHistoryEntryRepository $emailHistoryRepo): Response
  44.     {
  45.         $emailEntries $emailHistoryRepo->getHistoryByClientPaged($this->getCurrentClient(), self::LISTING_LIMIT'DESC''date'1);
  46.         return $this->render('email/index.html.twig', [
  47.             'emailEntries' => $emailEntries,
  48.             'total' => $emailEntries->count(),
  49.             'pages' => ceil($emailEntries->count() / self::LISTING_LIMIT),
  50.             'page' => 1,
  51.         ]);
  52.     }
  53.     /**
  54.      * @Route("/{page}/{orderby}/{order}", name="email_index_listing", methods="GET", requirements={"page"="\d+","order"="asc|desc"})
  55.      */
  56.     public function indexListing(EmailHistoryEntryRepository $emailHistoryRepo$page$orderby$order): Response
  57.     {
  58.         $emailEntries $emailHistoryRepo->getHistoryByClientPaged($this->getCurrentClient(), self::LISTING_LIMIT$order$orderby$page);
  59.         return $this->render('email/_index_listing.html.twig', [
  60.             'emailEntries' => $emailEntries,
  61.             'total' => $emailEntries->count(),
  62.             'pages' => ceil($emailEntries->count() / self::LISTING_LIMIT),
  63.             'page' => $page,
  64.         ]);
  65.     }
  66.     /**
  67.      * @Route("/{id}", name="email_show", methods="GET", requirements={"id"="\d+"})
  68.      */
  69.     public function show(Request $requestEmailHistoryEntry $emailEntry): Response
  70.     {
  71.         $this->denyAccessUnlessGranted('ROLE_MANAGER'$emailEntry);
  72.         return $this->render('email/show.html.twig', [
  73.             'emailEntry' => $emailEntry,
  74.         ]);
  75.     }
  76.     // /**
  77.     //  * @Route("/{id}/attachment", name="email_attachment", methods="GET", requirements={"id"="\d+"})
  78.     //  */
  79.     // public function attachment(Request $request, EmailHistoryEntry $emailEntry): Response
  80.     // {
  81.     //     $this->denyAccessUnlessGranted('ROLE_MANAGER', $emailEntry);
  82.     //     if ($emailEntry->getAttachment() && $emailEntry->getAttachmentName()) {
  83.     //         $file = $this->getParameter('attachment_directory') . '/' . $emailEntry->getAttachment();
  84.     //         $mimeType = mime_content_type($file);
  85.     //         $headers = [
  86.     //             'Content-Type' => $mimeType,
  87.     //             'Content-Disposition' => 'attachment; filename="' . $emailEntry->getAttachmentName() . '"'
  88.     //         ];
  89.     //         return new Response(file_get_contents($file), 200, $headers);
  90.     //     }
  91.     //     return new Response('Die Datei konnte nicht gefunden werden.', 404);
  92.     // }
  93.     /**
  94.      * @Route("/{id}/attachment", name="email_attachment", methods="GET", requirements={"id"="\d+"})
  95.      */
  96.     public function attachment(Request $requestAttachment $attachment): Response
  97.     {
  98.         if ($attachment->getEmailHistoryEntry()) {
  99.             $this->denyAccessUnlessGranted('ROLE_MANAGER'$attachment->getEmailHistoryEntry());
  100.     
  101.             if ($attachment->getName() && $attachment->getPath()) {
  102.                 $file $attachment->getPath();
  103.                 $mimeType mime_content_type($file);
  104.                 $headers = [
  105.                     'Content-Type' => $mimeType,
  106.                     'Content-Disposition' => 'attachment; filename="' $attachment->getName() . '"'
  107.                 ];
  108.                 return new Response(file_get_contents($file), 200$headers);
  109.             }
  110.         }
  111.         return new Response('Die Datei konnte nicht gefunden werden.'404);
  112.     }
  113.     /**
  114.      * @Route("/sender/{personId}/{emailAddress}", name="email_sender", methods="GET|POST", requirements={"personId"="\d+"}, defaults={"personId"=0, "email"=""})
  115.      */
  116.     public function sender(Request $request$personId 0$emailAddress ''MailerService $mailerEmailHistoryService $emailHistoryServicePersonRepository $personRepo)
  117.     {
  118.         $user $this->getCurrentUser();
  119.         $email = new EmailDto();
  120.         if ($emailAddress) {
  121.             $email->recipient $emailAddress;
  122.         } elseif ($personId) {
  123.             $person $personRepo->findOneBy(['id' => $personId]);
  124.             if ($person && $person->getContactEmail()) {
  125.                 $email->recipientId $personId;
  126.                 $email->recipient $person->getContactEmail();
  127.             }
  128.         }
  129.         $form $this->createForm(EmailType::class, $email, [
  130.             'action' => $this->generateUrl('email_sender'),
  131.         ]);
  132.         $form->handleRequest($request);
  133.         if ($form->isSubmitted() && $form->isValid()) {
  134.             $isTest false;
  135.             if ($email->testRecipient != '') {
  136.                 $isTest true;
  137.                 $recipients = [$email->testRecipient];
  138.             } else {
  139.                 $recipients = [$email->recipient];
  140.             }
  141.            
  142.             $attachments = [];
  143.             $this->handleAttachmentUpload($form$attachments);
  144.             $success $mailer->sendCustomMessage(
  145.                 $user->getClient(),
  146.                 $email->sender,
  147.                 $email->subject,
  148.                 $email->content,
  149.                 $recipients,
  150.                 $attachments
  151.             );
  152.             if ($success) {
  153.                 $this->addFlash('notice''E-Mail wurde versandt.');
  154.                 if (!$isTest) {
  155.                     $people = [];
  156.                     if ($email->recipientId) {
  157.                         $people $personRepo->findBy(['id' => $email->recipientId]);
  158.                     }
  159.                     $emailHistoryService->saveProtocolEntriesFromEmailDto($email$attachments$people$this->getCurrentUser()->getEmail(), $this->getCurrentClient());
  160.                 }
  161.             } else {
  162.                 $this->addFlash('error''Beim E-Mail-Versand ist ein Fehler aufgetreten.');
  163.             }
  164.             return $this->redirectToRoute('customer_index');
  165.         }
  166.         return $this->render('email/sender.html.twig', [
  167.             'email' => $email,
  168.             'form' => $form->createView(),
  169.         ]);
  170.     }
  171.     /**
  172.      * @Route("/sender/multiple", name="email_sender_multiple", methods="GET|POST")
  173.      */
  174.     public function senderMultiple(
  175.         Request $request,
  176.         MailerService $mailer,
  177.         PersonRepository $personRepo,
  178.         EmailHistoryService $emailHistoryService,
  179.         ClientConfigRepository $clientConfigRepo
  180.     ) {
  181.         $user $this->getCurrentUser();
  182.         $config $clientConfigRepo->getSingleByClient($this->getCurrentClient());
  183.         $email = new EmailDto();
  184.         $items $request->request->get('item');
  185.         if ($items) {
  186.             $people $personRepo->getPeopleByClientAndIds($this->getCurrentClient(), array_keys($items));
  187.             $email->recipients $people;
  188.         }
  189.         $speakers $request->request->get('speaker');
  190.         if (empty($email->recipients) && $speakers) {
  191.             $people $personRepo->getPeopleByClientAndSpeakerIds($this->getCurrentClient(), array_keys($speakers));
  192.             $email->recipients $people;
  193.         }
  194.         $form $this->createForm(EmailType::class, $email, [
  195.             'action' => $this->generateUrl('email_sender_multiple'),
  196.             'form_mode' => EmailType::FORM_MODE_MULTIPLE,
  197.             'client' => $this->getCurrentClient(),
  198.         ]);
  199.         $form->handleRequest($request);
  200.         if ($form->isSubmitted() && $form->isValid()) {
  201.             $isTest false;
  202.             if ($email->testRecipient != '') {
  203.                 $isTest true;
  204.                 $recipients = ['email' => $email->testRecipient];
  205.                 $subject '[TEST] '.$email->subject;
  206.             } else {
  207.                 $recipients $this->parseRecipients($email$config);
  208.                 $subject $email->subject;
  209.             }
  210.             $attachments = [];
  211.             $this->handleAttachmentUpload($form$attachments);
  212.             $success $mailer->sendIndividualMessage(
  213.                 $user->getClient(),
  214.                 $email->sender,
  215.                 $subject,
  216.                 $email->content,
  217.                 $recipients,
  218.                 $attachments
  219.             );
  220.             if ($success) {
  221.                 $this->addFlash('notice''E-Mail wurde versandt.');
  222.                 if (!$isTest) {
  223.                     $emailHistoryService->saveProtocolEntriesFromEmailDto($email$attachments$email->recipients$this->getCurrentUser()->getEmail(), $this->getCurrentClient());
  224.                     return $this->redirectToRoute('customer_index');
  225.                 }
  226.                 $this->addFlash('notice''E-Mail wurde versandt.');
  227.             } else {
  228.                 $this->addFlash('error''Beim E-Mail-Versand ist ein Fehler aufgetreten.');
  229.             }
  230.            return $this->redirectToRoute('customer_index');
  231.            
  232.         }
  233.         return $this->render('email/sender-multiple.html.twig', [
  234.             'email' => $email,
  235.             'form' => $form->createView(),
  236.         ]);
  237.     }
  238.     /**
  239.      * @Route("/sender/all/{type}", name="email_sender_all", methods="GET|POST")
  240.      */
  241.     public function senderAll(
  242.         Request $request,
  243.         MailerService $mailer,
  244.         PersonRepository $personRepo,
  245.         EmailHistoryService $emailHistoryService,
  246.         ClientConfigRepository $clientConfigRepo,
  247.         NewsletterRepository $newsletterRepository,
  248.         $type
  249.     ) {
  250.         $user $this->getCurrentUser();
  251.         $config $clientConfigRepo->getSingleByClient($this->getCurrentClient());
  252.         $email = new EmailDto();
  253.         $recipientEntities = [];
  254.         switch ($type) {
  255.             case 'customer':
  256.                 $recipientEntities $personRepo->getPersonByClient($this->getCurrentClient(), true);
  257.                 break;
  258.             case 'speaker':
  259.                 $recipientEntities $personRepo->getPersonByClient($this->getCurrentClient(), falsetrue);
  260.                 break;
  261.             case 'family':
  262.                 $recipientEntities $personRepo->getFamilyByClient($this->getCurrentClient());
  263.                 break;
  264.             case 'newsletter':
  265.                 $recipientEntities['persons'] = $personRepo->getNewsletterRecipientsByClient($this->getCurrentClient());
  266.                 $recipientEntities['newsletter_persons'] = $newsletterRepository->getActiveMembers();
  267.                 break;
  268.         }
  269.         $email->recipients count($recipientEntities) . ' Empfänger';
  270.         if ($type === 'newsletter') {
  271.             $customers 0;
  272.             $speakers 0;
  273.             $newsletterPersons 0;
  274.             foreach ($recipientEntities['persons'] as $recipient) {
  275.                 if ($recipient->isSpeaker()) {
  276.                     $speakers++;
  277.                 } else if ($recipient->isCustomer()) {
  278.                     $customers++;
  279.                 }
  280.             }
  281.             $newsletterPersons count($recipientEntities['newsletter_persons']);
  282.             $email->recipients .= " (davon {$customers} Kunde(n) und {$speakers} Referent(en)) "
  283.                 "sowie {$newsletterPersons} Newsletter Abonnenten";
  284.             $recipientEntities array_merge($recipientEntities['persons'], $recipientEntities['newsletter_persons']);
  285.         }
  286.         $form $this->createForm(EmailType::class, $email, [
  287.             'action' => $this->generateUrl('email_sender_all', ['type' => $type]),
  288.             'form_mode' => EmailType::FORM_MODE_ALL,
  289.             'client' => $this->getCurrentClient(),
  290.         ]);
  291.         $form->handleRequest($request);
  292.         if ($form->isSubmitted() && $form->isValid()) {
  293.             $email->recipients $recipientEntities;
  294.             $isTest false;
  295.             if ($email->action == 'test') {
  296.                 $isTest true;
  297.                 $recipients = [['email' => $email->testRecipient]];
  298.             } else {
  299.                 $recipients $this->parseRecipients($email$config);
  300.             }
  301.             $attachments = [];
  302.             $this->handleAttachmentUpload($form$attachments);
  303.             $success $mailer->sendIndividualMessage(
  304.                 $user->getClient(),
  305.                 $email->sender,
  306.                 $email->subject,
  307.                 $email->content,
  308.                 $recipients,
  309.                 $attachments
  310.             );
  311.             if ($success) {
  312.                 $this->addFlash('notice''E-Mail wurde versandt.');
  313.                 if (!$isTest) {
  314.                     $emailHistoryService->saveProtocolEntriesFromEmailDto($email$attachments$email->recipients$this->getCurrentUser()->getEmail(), $this->getCurrentClient());
  315.                     return $this->redirectToRoute('customer_index');
  316.                 }
  317.             } else {
  318.                 $this->addFlash('error''Beim E-Mail-Versand ist ein Fehler aufgetreten.');
  319.                 return $this->redirectToRoute('customer_index');
  320.             }
  321.         }
  322.         return $this->render('email/sender-multiple.html.twig', [
  323.             'email' => $email,
  324.             'form' => $form->createView(),
  325.         ]);
  326.     }
  327.     protected function parseRecipients(EmailDto $email$config)
  328.     {
  329.         $recipients = [];
  330.         foreach ($email->recipients as $recipient) {
  331.             if ($recipient instanceof Person) {
  332.                 $recipientItem = [];
  333.                 if ($recipient->getContactEmail()) {
  334.                     $recipientItem['email'] = $recipient->getContactEmail();
  335.                 } elseif ($recipient->getUser() && $recipient->getUser()->getEmail()) {
  336.                     $recipientItem['email'] = $recipient->getUser()->getEmail();
  337.                 } elseif ($recipient->getFamilyMemberOf()) {
  338.                     if ($recipient->getFamilyMemberOf()->getContactEmail()) {
  339.                         $recipientItem['email'] = $recipient->getFamilyMemberOf()->getContactEmail();
  340.                     } elseif ($recipient->getFamilyMemberOf()->getUser() && $recipient->getFamilyMemberOf()->getUser()->getEmail()) {
  341.                         $recipientItem['email'] = $recipient->getFamilyMemberOf()->getUser()->getEmail();
  342.                     }
  343.                 }
  344.             } elseif ($recipient instanceof Newsletter) {
  345.                 $recipientItem['email'] = $recipient->getEmail();
  346.             }
  347.             if (count($recipientItem) > 0) {
  348.                 if ($email->isNewsletter && $recipient->isReceiveNewsletter()) {
  349.                     $hash md5($recipient->getId() . '_' $recipient->getCreated()->format('Y-m-d H:i:s'));
  350.                     $link $this->generateUrl('newsletter_unsubscribe', ['hash' => $hash], UrlGeneratorInterface::ABSOLUTE_URL);
  351.                     $recipientItem['addendum'] = str_ireplace(
  352.                         '[link]',
  353.                         '<a href="' $link '" target="_blank">Link</a>',
  354.                         $config->getNewsletterClause()
  355.                     );
  356.                     $recipients[] = $recipientItem;
  357.                 } elseif (!$email->isNewsletter) {
  358.                     $recipients[] = $recipientItem;
  359.                 }
  360.             }
  361.         }
  362.         return $recipients;
  363.     }
  364.     /**
  365.      * @Route("/send-again/{id}", name="email_send_again", methods="GET|POST")
  366.      */
  367.     public function sendHistoryEntryAgain(
  368.         Request $request,
  369.         EmailHistoryEntry $emailEntry,
  370.         MailerService $mailer,
  371.         CustomerHistoryEntryRepository $repo,
  372.         EmailHistoryService $emailHistoryService,
  373.         InvoiceRepository $invoiceRepository,
  374.         PdfService $pdfService
  375.     ) {
  376.         $this->denyAccessUnlessGranted('ROLE_MANAGER'$emailEntry);
  377.         try {
  378.             if ($request->query->has('invoiceId')) {
  379.                 $customerHistoryEntry $repo->findOneBy(['emailHistoryEntry' => $emailEntry]);
  380.                 $recipients explode(','$emailEntry->getRecipients());
  381.                 if ($customerHistoryEntry && count($recipients) > 0) {
  382.                     $invoice $invoiceRepository->find($request->get('invoiceId'));
  383.                     $pdf $pdfService->getInvoicePdf($this->getCurrentClient(), $invoice);
  384.                     $sentMessage $mailer->sendInvoiceEmail(
  385.                         $invoice,
  386.                         'Rechnung-' $invoice->getNumber() . '.pdf',
  387.                         $pdf->Output('S''Rechnung-' $invoice->getNumber() . '.pdf')
  388.                     );
  389.                     $outputfile $this->generateUniqueFileName() . '.pdf';
  390.                     $outputpath $this->getParameter('attachment_directory') . '/' $outputfile;
  391.                     $pdf->Output('F'$outputpath);
  392.                     $emailHistoryService->saveProtocolEntryFromInvoiceMessage(
  393.                         $invoice,
  394.                         $sentMessage['sender'],
  395.                         $sentMessage['subject'],
  396.                         $sentMessage['message'],
  397.                         $outputfile,
  398.                         'Rechnung-' $invoice->getNumber() . '.pdf'
  399.                     );
  400.                     $this->addFlash('notice''E-Mail wurde versandt.');
  401.                 } else {
  402.                     $this->addFlash('error''Diese E-Mail kann nicht versandt werden, weil der Empfänger ungültig ist.');
  403.                 }
  404.                 return $this->redirectToRoute('customer_index');
  405.             }
  406.             $customerHistoryEntry $repo->findOneBy(['emailHistoryEntry' => $emailEntry]);
  407.             $recipients explode(','$emailEntry->getRecipients());
  408.             if ($customerHistoryEntry && count($recipients) > 0) {
  409.                 $recipient $recipients[0];
  410.                 $mailer->sendPlainMessage(
  411.                     $this->getCurrentClient(),
  412.                     null,
  413.                     $emailEntry->getSubject(),
  414.                     $emailEntry->getContent(),
  415.                     $recipient,
  416.                     $emailEntry->getAttachments()
  417.                 );
  418.                 $emailHistoryService->saveProtocolEntriesFromPerson(
  419.                     $this->getCurrentClient(),
  420.                     $customerHistoryEntry->getCustomer(),
  421.                     $customerHistoryEntry->getType(),
  422.                     $emailEntry->getSubject(),
  423.                     $emailEntry->getContent(),
  424.                     $customerHistoryEntry->getEntry(),
  425.                     null,
  426.                     $emailEntry->getAttachments()
  427.                 );
  428.                 $this->addFlash('notice''E-Mail wurde versandt.');
  429.             } else {
  430.                 $this->addFlash('error''Diese E-Mail kann nicht versandt werden, weil der Empfänger ungültig ist.');
  431.             }
  432.         } catch (\Exception $e) {
  433.             $this->addFlash('error''Beim E-Mail-Versand ist ein Fehler aufgetreten.');
  434.         }
  435.         return $this->redirectToRoute('customer_index');
  436.     }
  437.     protected function handleAttachmentUpload(&$form, &$attachments)
  438.     {
  439.         if ($attachmentsList $form->get('attachments')->getData()) {
  440.             foreach ($attachmentsList as $attachment) {
  441.                 /** @var UploadedFile */
  442.                 $attachmentName $attachment->getClientOriginalName();
  443.                 $fileName $this->generateUniqueFileName() . '.' $attachment->guessExtension();
  444.     
  445.                 try {
  446.                     $attachment->move(
  447.                         $this->getParameter('attachment_directory'),
  448.                         $fileName
  449.                     );
  450.                     $attachmentPath $this->getParameter('attachment_directory') . '/' $fileName;
  451.                     
  452.                     $attachmentModel = new Attachment();
  453.                     $attachmentModel->setName($attachmentName);
  454.                     $attachmentModel->setPath($attachmentPath);
  455.                     $attachmentModel->setCreatedAt(new \DateTimeImmutable());
  456.                     $this->em->persist($attachmentModel);
  457.                     $this->em->flush();
  458.                     $attachments[] = $attachmentModel;
  459.                 } catch (FileException $e) {
  460.                     // ... handle exception if something happens during file upload
  461.                 }
  462.             }
  463.         }
  464.     }
  465.     private function generateUniqueFileName()
  466.     {
  467.         return md5(uniqid());
  468.     }
  469. }