src/Service/TemplatesService.php line 202

  1. <?php
  2. declare(strict_types=1);
  3. /*
  4.  * This file is part of the guesthouse administration package.
  5.  *
  6.  * (c) Alexander Elchlepp <info@fewohbee.de>
  7.  *
  8.  * For the full copyright and license information, please view the LICENSE
  9.  * file that was distributed with this source code.
  10.  */
  11. namespace App\Service;
  12. use App\Entity\Correspondence;
  13. use App\Entity\Entreprise;
  14. use App\Entity\FileCorrespondence;
  15. use App\Entity\Invoice;
  16. use App\Entity\Location;
  17. use App\Entity\MailAttachment;
  18. use App\Entity\Payment;
  19. use App\Entity\Reservation;
  20. use App\Entity\Template;
  21. use App\Entity\TemplateType;
  22. use App\Entity\User;
  23. use App\Interfaces\ITemplateRenderer;
  24. use Doctrine\ORM\EntityManagerInterface;
  25. use Symfony\Component\HttpFoundation\Request;
  26. use Symfony\Component\HttpFoundation\RequestStack;
  27. use Symfony\Contracts\Translation\TranslatorInterface;
  28. use Twig\Environment;
  29. class TemplatesService
  30. {
  31.     private $em null;
  32.     private $app null;
  33.     private $requestStack;
  34.     private $mpdfs;
  35.     private $twig;
  36.     private $webHost;
  37.     private $translator;
  38.     public function __construct(string $webHostEnvironment $twigEntityManagerInterface $emRequestStack $requestStackMpdfService $mpdfsTranslatorInterface $translator)
  39.     {
  40.         $this->em $em;
  41.         $this->requestStack $requestStack;
  42.         $this->mpdfs $mpdfs;
  43.         $this->twig $twig;
  44.         $this->webHost $webHost;
  45.         $this->translator $translator;
  46.     }
  47.     /**
  48.      * Extract form data and return Template object.
  49.      *
  50.      * @param string $id
  51.      *
  52.      * @return Template
  53.      */
  54.     public function getEntityFromForm(Request $request$id 'new')
  55.     {
  56.         $template = new Template();
  57.         if ('new' !== $id) {
  58.             $template $this->em->getRepository(Template::class)->find($id);
  59.         }
  60.         $templateId $request->request->get('type-'.$id);
  61.         $type $this->em->getRepository(TemplateType::class)->find($templateId);
  62.         if (!($type instanceof TemplateType)) {
  63.             // throw ""
  64.         }
  65.         $template->setTemplateType($type);
  66.         $template->setName(trim($request->request->get('name-'.$id)));
  67.         $template->setText($request->request->get('text-'.$id));
  68.         $template->setParams($request->request->get('params-'.$id));
  69.         if ($request->request->has('default-'.$id)) {
  70.             $template->setIsDefault(true);
  71.         } else {
  72.             $template->setIsDefault(false);
  73.         }
  74.         if ('new' === $id) {
  75.             $userId $request->request->get('user-'.$id);
  76.             $user $this->em->getRepository(User::class)->find($userId);
  77.             $template->setCreatedBy($user);
  78.             $marchand $this->em->getRepository(Entreprise::class)->find($user->getEntreprise());
  79.             $template->setMarchand($marchand);
  80.         }
  81.         return $template;
  82.     }
  83.     /**
  84.      * Delete entity.
  85.      *
  86.      * @param int $id
  87.      *
  88.      * @return bool
  89.      */
  90.     public function deleteEntity($id)
  91.     {
  92.         $template $this->em->getRepository(Template::class)->find($id);
  93.         $this->em->remove($template);
  94.         $this->em->flush();
  95.         return true;
  96.     }
  97.     public function renderTemplateForReservations($templateId$reservations)
  98.     {
  99.         /* @var $template \App\Entity\Template */
  100.         $template $this->em->getRepository(Template::class)->find($templateId);
  101.         $templateStr $this->twig->createTemplate($template->getText());
  102.         return $templateStr->render([
  103.             'reservations' => $reservations,
  104.         ]);
  105.     }
  106.     public function renderTemplate(int $templateIdmixed $paramITemplateRenderer $serviceObj$type): string
  107.     {
  108.         /* @var $template Template */
  109.         $template $this->em->getRepository(Template::class)->find($templateId);
  110.         $params = [];
  111.         if($type == 2){
  112.             $service 'InvoiceTemplateService';
  113.         }else{
  114.             $service $template->getTemplateType()->getService();
  115.         }
  116.         if (!empty($service)) {
  117.             // each service must implement the ITemplateRenderer interface
  118.             $params $serviceObj->getRenderParams($template$param);
  119.         }
  120.         $str $this->replaceTwigSyntax($template->getText());
  121.         $templateStr $this->twig->createTemplate($str);
  122.         return $templateStr->render($params);
  123.     }
  124.     public function getReferencedReservationsInSession()
  125.     {
  126.         $reservations = [];
  127.         if ($this->requestStack->getSession()->has('selectedReservationIds')) {
  128.             $selectedReservationIds $this->requestStack->getSession()->get('selectedReservationIds');
  129.             foreach ($selectedReservationIds as $id) {
  130.                 $reservations[] = $this->em->getReference(Location::class, $id);
  131.             }
  132.         }
  133.         return $reservations;
  134.     }
  135.     public function addFileAsAttachment($cId$reservations)
  136.     {
  137.         $fileIds = [];
  138.         foreach ($reservations as $reservation) {
  139.             // save file ids in context of reservation id
  140.             $fileIds[$reservation->getId()] = $cId;
  141.         }
  142.         $attachments $this->requestStack->getSession()->get('templateAttachmentIds');
  143.         $attachments[] = $fileIds;
  144.         $this->requestStack->getSession()->set('templateAttachmentIds'$attachments);
  145.         return true;
  146.     }
  147.     /**
  148.      * Returns a MailAttachment entity which can be passed to Mailer.
  149.      *
  150.      * @param type $attachmentId
  151.      */
  152.     public function getMailAttachment($attachmentId): ?MailAttachment
  153.     {
  154.         /* @var $attachment \App\Entity\Correspondence */
  155.         $attachment $this->em->getRepository(Correspondence::class)->find($attachmentId);
  156.         if ($attachment instanceof FileCorrespondence) {
  157.             $data $this->getPDFOutput($attachment->getText(), $attachment->getName(), $attachment->getTemplate(), true);
  158.             return new MailAttachment($data$attachment->getName().'.pdf''application/pdf');
  159.         }
  160.         return null;
  161.     }
  162.     public function getPDFOutput($input$name$template$noResponseOutput false)
  163.     {
  164.         /*
  165.          * I: send the file inline to the browser. The plug-in is used if available. The name given by filename is used when one selects the "Save as" option on the link generating the PDF.
  166.          * D: send to the browser and force a file download with the name given by filename.
  167.          * F: save to a local file with the name given by filename (may include a path).
  168.          * S: return the document as a string. filename is ignored.
  169.          */
  170.         $dest = ($noResponseOutput 'S' 'D');
  171.         $mpdf $this->mpdfs->getMpdf();
  172.         $params json_decode($template->getParams());
  173.         $mpdf->addPage(
  174.             $params->orientation,
  175.             '',
  176.             '',
  177.             '',
  178.             '',
  179.             $params->marginLeft,
  180.             $params->marginRight,
  181.             $params->marginTop,
  182.             $params->marginBottom,
  183.             $params->marginHeader,
  184.             $params->marginFooter
  185.         );
  186.         $inputMapped $this->mapImageSrc($input);
  187.         /*
  188.          * mode
  189.          * 0 - Use this (default) if the text you pass is a complete HTML page including head and body and style definitions.
  190.          * 1 - Use this when you want to set a CSS stylesheet
  191.          * 2 - Write HTML code without the <head> information. Does not need to be contained in <body>
  192.          */
  193.         $mpdf->WriteHTML($inputMapped0);
  194.         return $mpdf->Output($name.'.pdf'$dest);
  195.     }
  196.     /**
  197.      * This maps the src of images to the real web host.
  198.      * This is sometimes needed e.g. when using it with docker.
  199.      * The docker web host is "web" when the application is requested via "localhost" in the browser,
  200.      * mpdf uses the host from the request, which is localhost. But there is no web server listening on localhost in the php container.
  201.      * That's why we need to change the src to the real host "web".
  202.      *
  203.      * @param string $input
  204.      *
  205.      * @return string
  206.      */
  207.     private function mapImageSrc($input)
  208.     {
  209.         $host rtrim($this->webHost'/').'/';
  210.         return preg_replace('/src="\/(.*)"/i''src="'.$host.'$1"'$input);
  211.     }
  212.     /**
  213.      * Returns the default Template or null.
  214.      *
  215.      * @param Template[] $templates
  216.      */
  217.     public function getDefaultTemplate(array $templates): ?Template
  218.     {
  219.         // find default template
  220.         foreach ($templates as $template) {
  221.             if ($template->getIsDefault()) {
  222.                 return $template;
  223.             }
  224.         }
  225.         return null;
  226.     }
  227.     private function replaceTwigSyntax(string $string): string
  228.     {
  229.         $t1 str_replace('[[''{{'$string);
  230.         $t2 str_replace(']]''}}'$t1);
  231.         $t3 str_replace('[%''{%'$t2);
  232.         $t4 str_replace('%]''%}'$t3);
  233.         $t5 str_replace('[#''{#'$t4);
  234.         $t6 str_replace('#]''#}'$t5);
  235.         $t7 preg_replace("/<div class=\"footer\">(.*)<\/div>/s"'<htmlpagefooter name="footer">$1</htmlpagefooter><sethtmlpagefooter name="footer" value="on"></sethtmlpagefooter>'$t6);
  236.         return $t7;
  237.     }
  238.     public function getRenderParams(Template $templatemixed $param)
  239.     {
  240.         $payments = [];
  241.         $payment $this->em->getRepository(Payment::class)->find($param);
  242.         $payments[] = $payment;
  243.         $invoice $payment->getInvoice();
  244.         $grandTotal $payment->getAmount();
  245.         $vatSums = [];
  246.         $brutto 0;
  247.         $netto 0;
  248.         $appartmantTotal 0;
  249.         $miscTotal 0;
  250.         $params = [
  251.             'invoice' => $invoice,
  252.             'payments' => $payments,
  253.             'grandTotal' => $grandTotal,
  254.             'vats' => $vatSums,
  255.             'brutto' => $brutto,
  256.             'netto' => $netto,
  257.             'bruttoFormated' => number_format($brutto2',''.'),
  258.             'nettoFormated' => number_format($brutto $netto2',''.'),
  259.             'appartmentTotal' => number_format($appartmantTotal2',''.'),
  260.             'miscTotal' => number_format($miscTotal2',''.'),
  261.         ];
  262.         return $params;
  263.     }
  264. }