<?php
namespace Acme\SudcmsBundle\Service;
use Acme\SudcmsBundle\Entity\FormAdresses;
use Acme\SudcmsBundle\Entity\FormSite;
use Acme\SudcmsBundle\Entity\Site;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Address;
use Twig\Environment;
class MailerService extends CommonLogsService {
private $mailer;
public $subject = "";
public $fromEmail = "";
public $fromName = "";
private $defaultRecipient = [
"prenom" => "Agence",
"nom" => "Otidea",
"email" => "mathieu@otidea.com",
"type" => "to"
];
private $renderer;
private $entityManager;
private $containerBag;
private $parameterBag;
public bool $errorLogsFolder = false;
public string $siteDirectory = '';
private string $logsFolder = '/public/logs/mail/normal';
public function __construct(
private Filesystem $filesystem,
private RequestStack $requestStack,
MailerInterface $mailer,
Environment $renderer,
EntityManagerInterface $entityManager,
ParameterBagInterface $parameterBag,
ContainerBagInterface $containerBag
) {
parent::__construct($filesystem, $parameterBag, $this, $entityManager);
$this->mailer = $mailer;
$this->renderer = $renderer;
$this->entityManager = $entityManager;
$this->containerBag = $containerBag;
$this->parameterBag = $parameterBag;
$pathFoler = explode('/', $this->requestStack->getCurrentRequest()->server->get('SCRIPT_NAME'));
$pathInfo = explode('/', $this->requestStack->getCurrentRequest()->getPathInfo());
$session = new Session();
if ($pathInfo[0] == 'admin' || $pathInfo[1] == 'admin') {
$this->site = $entityManager->getRepository(Site::class)->findOneBy(['id' => $session->get('admin_site_uid')]);
} else {
$this->site = $entityManager->getRepository(Site::class)->findOneBy(['projectDirectory' => $pathFoler[1]]);
}
}
/**
* Envoi d'un email avec une enveloppe (skin) par défaut
* @param array $recipients ce tableau contient les différentes adresses mails ( $recipients[[to],[cc],[cci]] )
* @param array $attachments pièces jointes à ajouter au mail
* @param string|null $formName Nom du formulaire lié pour récupération des destinataires
*/
public function sendMail(array $recipients = array(), $htmlContent = NULL, array $attachments = array(),
string $formName = NULL,
$typeTo = true): bool {
if ($this->subject == null || trim($this->subject) == "" || $htmlContent == null || trim($htmlContent) == "") {
throw new \Exception('MailerService: Les paramètres ne sont pas correctement définis.');
}
$site = $this->entityManager->getRepository(Site::class)->find(CURRENT_SITE_ID);
$email = (new TemplatedEmail());
$email->subject($this->subject);
$email->from(new Address($site->getSiteSenderMail(), $site->getSiteSenderNameMail()));
// récupération de l'adresse en copie de tous les mails.
if ($site->getSiteCopyMail() !== null && trim($site->getSiteCopyMail()) != "") {
$recipients[] = [
'type' => 'cci',
'email' => $site->getSiteCopyMail(),
'prenom' => 'Copie mail du site',
'nom' => $site->getSiteName(),
];
}
//Si liaison avec un formulaire, on rajoute les destinataires
if ($formName != NULL) {
$recipientsForm = $this->getFormRecipients($formName);
if (is_array($recipientsForm) && sizeof($recipientsForm) > 0) {
$recipients = array_merge($recipients, $recipientsForm);
}
}
// nombre de destinataires direct
$numberRecipientTo = $numberRecipientCc = $numberRecipientBcc = 0;
// définition des destinataires et le type d'envoi
foreach ($recipients as $recip) {
$firstname = isset($recip['prenom']) ? $recip['prenom'] : "";
$lastname = isset($recip['nom']) ? $recip['nom'] : "";
if (isset($recip['email']) && filter_var($recip['email'], FILTER_VALIDATE_EMAIL) && isset($recip['type'])) {
$fullName = trim($firstname . " " . $lastname);
if ($recip['type'] == "to") {
if ($numberRecipientTo == 0)
$email->to(new Address($recip['email'], $fullName));
else
$email->addTo(new Address($recip['email'], $fullName));
$numberRecipientTo++;
}
//Tableau contenant les adresses mails en cc
if ($recip['type'] == "cc") {
if ($numberRecipientCc == 0)
$email->cc(new Address($recip['email'], $fullName));
else
$email->addCc(new Address($recip['email'], $fullName));
$numberRecipientCc++;
}
//Tableau contenant les adresses mails en cci (copie conforme invisible)(cci ->Bcc)
if ($recip['type'] == "cci") {
if ($numberRecipientBcc == 0)
$email->bcc(new Address($recip['email'], $fullName));
else
$email->addBcc(new Address($recip['email'], $fullName));
$numberRecipientBcc++;
}
}
}
// si aucun mail to n'est définit, on envoi le mail sur notre boite pour
// nous informer du probleme
if ($numberRecipientTo === 0 && $typeTo) {
$fullName = $this->defaultRecipient['prenom'] . " " . $this->defaultRecipient['nom'];
$email->to(new Address($this->defaultRecipient['email'], $fullName));
$this->subject = "Erreur destinataire mail sur " . $site->getSiteName() . " : " . $this->subject;
}
// $originFile = $this->parameterBag->get('upload_mail_media') . '/' . $site->getSiteHeaderMail();
if ($site->getSiteHeaderMail() != null || $site->getSiteHeaderMail() != '') {
// bandeau haut sur le mail
$imageData = $this->parameterBag->get("upload_mail_media_" . $site->getId()) . '/' . $site->getSiteHeaderMail();
$email->embedFromPath($imageData, 'header', 'image/jpg');
}
// création du template mail
$email->htmlTemplate('layouts/layouts_emails/skin_default.html.twig')
->context([
'content' => $htmlContent,
]);
// piece jointe
if (isset($attachments) && is_array($attachments) && sizeof($attachments) > 0) {
foreach ($attachments as $attachment)
$email->attachFromPath($attachment);
}
// envoi du mail
try {
$this->mailer->send($email);
$this->writeLog(json_encode(
[
'status' => 'Envoyé',
'destinataires' => $recipients,
'sujet' => $this->subject,
'formulaire' => $formName,
'contenu' => $htmlContent,
'piece jointe' => $attachments
]
), 'Envoi de mail');
return true;
} catch (TransportExceptionInterface $e) {
$this->errorLogsFolder = true;
$this->writeLog(json_encode(
[
'status' => $e->getMessage(),
'destinataires' => $recipients,
'sujet' => $this->subject,
'formulaire' => $formName,
'contenu' => $htmlContent,
'piece jointe' => $attachments
]
), 'Envoi de mail');
return false;
}
}
/**
* Retourne la liste des mails liés au formulaire
* @param string $formName nom du formulaire pour récupérer les destinataires
* @return array tableau contenant les destinataires
*/
private function getFormRecipients(string $formName = ""): array {
$allRecipients = [];
if ($formName !== "") {
$form = $this->entityManager->getRepository(FormSite::class)->findOneBy(['name' => $formName]);
$addresses = $this->entityManager->getRepository(FormAdresses::class)->findBy(['formSite' => $form->getId(),
'enabled' => 1]);
if (is_array($addresses) && sizeof($addresses) > 0) {
foreach ($addresses as $address) {
$allRecipients[] = [
"nom" => $address->getNom(),
"prenom" => $address->getPrenom(),
"email" => $address->getEmail(),
"type" => $address->getType()
];
}
}
}
return $allRecipients;
}
// Surcharge de la fonction writeLog pour ajouter le type de log avec son dossier
public function getPathLogFile(): string {
$this->siteDirectory = $this->site->getProjectDirectory();
if ($this->errorLogsFolder) {
$this->logsFolder = '/public/logs/mail/error';
}
// Vérification de l'existence du dossier de logs pour les API
if (!$this->filesystem->exists($this->parameterBag->get('kernel.project_dir') . '/../' . $this->siteDirectory . $this->logsFolder)) {
$this->filesystem->mkdir($this->parameterBag->get('kernel.project_dir') . '/../' . $this->siteDirectory . $this->logsFolder,
0755);
}
return $this->parameterBag->get('kernel.project_dir') . '/../' . $this->siteDirectory . $this->logsFolder . '/';
}
}