1: <?php
2: namespace TIC\MailBundle\Command;
3:
4: use TIC\CoreBundle\Base\TICCommand as BaseCommand;
5:
6: use Symfony\Component\Console\Input\InputOption;
7: use Symfony\Component\Console\Input\InputArgument;
8: use Symfony\Component\Console\Input\InputInterface;
9: use Symfony\Component\Console\Output\OutputInterface;
10:
11: use TIC\MailBundle\Service\MailerService;
12:
13: /**
14: * Commande de génération et d'envoi de notification par email.
15: */
16: class SendNotificationCommand extends BaseCommand
17: {
18: use \TIC\DormBundle\Traits\ManagerTrait;
19:
20: protected $mailer;
21:
22: /**
23: * DI avec auto-wiring (inutile de définir le "call" sur le service grace à l'attribut @required).
24: * @see https://symfony.com/doc/current/service_container/injection_types.html#setter-injection
25: * @see https://symfony.com/doc/current/service_container/autowiring.html#autowiring-other-methods-e-g-setters-and-public-typed-properties
26: *
27: * @required
28: */
29: public function setMailer(MailerService $mailer): void
30: {
31: $this->mailer = $mailer;
32: }
33:
34: /**
35: * {@inheritdoc}
36: */
37: protected function configure(): void
38: {
39: parent::configure();
40: $this
41: ->setDescription("Commande de génération et d'envoi de notification par email.")
42: ->addArgument('ref', InputArgument::OPTIONAL, "Référence du modèle de notification à utiliser")
43: ->addOption('to', null, InputOption::VALUE_REQUIRED, "Adresse email du destinataire")
44: ->addOption('data', null, InputOption::VALUE_REQUIRED, "Chaine JSON des données à passer aux templates")
45: ->addOption('locale', null, InputOption::VALUE_REQUIRED, "Langue à utiliser pour générer les messages")
46: ->setHelp("Lancer la commande sans préciser le modèle (ref) affichera la liste des modèles disponibles")
47: ;
48: }
49:
50: /**
51: * {@inheritdoc}
52: */
53: protected function execute(InputInterface $input, OutputInterface $output): int
54: {
55: $ref = $input->getArgument('ref');
56: if ($ref === null) return $this->listrefs();
57:
58: $to = $input->getOption('to');
59: if ($to === null) $to = 'root@localhost';
60:
61: $data = $input->getOption('data');
62: if ($data) {
63: if (\strpos($data, '"') === false) $data = \strtr($data, "'", '"');
64: $data = \json_decode($data, true);
65: }
66: if ($data === null) $data = array();
67:
68: $locale = $input->getOption('locale');
69:
70: return $this->sendmail($ref, $to, $data, $locale);
71: }
72:
73: /**
74: * Retourne la liste des modèles de notification disponibles.
75: */
76: protected function listrefs(): int
77: {
78: $rows = array();
79: foreach ($this->getRepo('Template')->findAll() as $template) {
80: $rows[] = array($template->getRef(), $template->getTarget(), \substr($template->getLabel(), 0, 60));
81: }
82: $this->io->title("Liste des modèles de notifications disponibles");
83: $this->io->table(array("Ref", "Target", "Label"), $rows);
84: return self::SUCCESS;
85: }
86:
87: /**
88: * Génère et envoi par email un message de notification.
89: *
90: * @param string $ref Référence du modèle de notification (cf mailer_templates dans parameters.yml)
91: * @param string|array $to Adresses mail des destinataires (chaine avec virgule en séparateur acceptée)
92: * @param array $data Liste clé/valeur pour les substitutions des templates
93: * @param string $locale Spécifie la locale à utiliser pour les templates
94: * @param string|array $pjs Pièces-jointes (chemin ou structure {'name':, 'type':, 'data':}, seul ou en liste)
95: */
96: protected function sendmail(string $ref, mixed $to, array $data = [], string $locale = null, mixed $pjs = []): int
97: {
98: $this->io->section(sprintf("Notification [%s] pour <%s>", $ref, $to));
99:
100: // Préparation, composition puis envoi d'un message PLAIN et/ou HTML (méthode "combo")
101: # $data['locale'] = $locale;
102: # $nb = $this->mailer->notify($ref, $to, $data, $pjs);
103:
104: // Préparation d'un message à envoyer (instance Symfony Email & environnement Twig)
105: $message = $this->mailer->prepare($ref, $to, $pjs, $locale);
106: if ($message === null) $this->exitError("Failed to prepare Email message:\n" . $this->mailer->getLastError());
107:
108: // Composition du contenu textuel d'un message (rendu des vues Twig)
109: $rc = $this->mailer->compose($message, $data, $ref);
110: if (! $rc) $this->exitError("Failed to compose Email message:\n" . $this->mailer->getLastError());
111:
112: // Affichage et debug du message généré
113: if ($this->out->isDebug()) dump($message);
114: elseif ($this->out->isVerbose()) {
115: $charset = $message->getTextCharset();
116: if ($charset) $this->io->block($message->getTextBody(), null, null, ' | ', false);
117: $charset = $message->getHtmlCharset();
118: if ($charset) $this->io->block($message->getHtmlBody(), null, null, ' | ', false);
119: }
120:
121: // Envoi un message préparé (sans logs)
122: if (! $this->test) {
123: $rc = $this->mailer->send($message, $ref);
124: if (empty($rc)) $this->exitError("No message sent!");
125: if ($rc < 0) $this->exitError("Failed to send Email message:\n" . $this->mailer->getLastError(), \abs($rc));
126: $this->io->success("Done: $rc message(s) successfully sent.");
127: }
128: return self::SUCCESS;
129: }
130:
131: }
132: