207 lines
5.9 KiB
PHP
207 lines
5.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
// src/Utils/Mailer/MailerService.php
|
|
|
|
namespace RprtCli\Utils\Mailer;
|
|
|
|
use Exception;
|
|
use RprtCli\Utils\Configuration\ConfigurationInterface;
|
|
use RprtCli\Utils\PdfExport\PdfExportInterface;
|
|
use Symfony\Component\Mailer\Mailer;
|
|
use Symfony\Component\Mailer\Transport;
|
|
use Symfony\Component\Mime\Email;
|
|
|
|
use function date;
|
|
use function explode;
|
|
use function fgets;
|
|
use function file_exists;
|
|
use function rawurlencode;
|
|
use function readline;
|
|
use function strtotime;
|
|
use function system;
|
|
use function trim;
|
|
use function var_dump;
|
|
|
|
use const STDIN;
|
|
|
|
/**
|
|
* Send emails with invoices as attachments.
|
|
*
|
|
* https://symfony.com/doc/current/mailer.html
|
|
*/
|
|
class MailerService implements MailerInterface
|
|
{
|
|
protected $config;
|
|
|
|
protected $pdf;
|
|
|
|
// Data properties.
|
|
protected $to;
|
|
protected $subject;
|
|
protected $text;
|
|
protected $attachment;
|
|
protected $templatePath;
|
|
|
|
protected $email;
|
|
|
|
public function __construct(ConfigurationInterface $config, PdfExportInterface $pdf)
|
|
{
|
|
$this->config = $config;
|
|
$this->pdf = $pdf;
|
|
}
|
|
|
|
public function setRecipients(array $to): void
|
|
{
|
|
$this->to = $to;
|
|
}
|
|
|
|
public function setSubject(string $subject): void
|
|
{
|
|
$this->subject = $subject;
|
|
}
|
|
|
|
public function setAttachment(string $path): void
|
|
{
|
|
// @TODO - add some error handling.
|
|
$this->attachment = $path;
|
|
}
|
|
|
|
public function getProperty(string $property)
|
|
{
|
|
// Only for simple value properies - string and numbers.
|
|
// from, to, subject.
|
|
if (! isset($this->{$property})) {
|
|
$value = $this->config->get('email.' . $property, false);
|
|
if (! $value) {
|
|
$value = readline("Property {$property} is not configured. Enter value: ");
|
|
}
|
|
$this->{$property} = $value;
|
|
}
|
|
return $this->{$property};
|
|
}
|
|
|
|
protected function getRecipients()
|
|
{
|
|
if (! isset($this->to)) {
|
|
$value = $this->config->get('email.to', false);
|
|
if (! $value) {
|
|
$value = explode(',', readline('Provide recipients\' emails separated by a comma: '));
|
|
}
|
|
$this->to = $value;
|
|
}
|
|
return $this->to;
|
|
}
|
|
|
|
private function readPassword($prompt = "Enter Password:")
|
|
{
|
|
echo $prompt;
|
|
system('stty -echo');
|
|
$password = trim(fgets(STDIN));
|
|
system('stty echo');
|
|
return $password;
|
|
}
|
|
|
|
protected function getPasswordProperty()
|
|
{
|
|
if (! isset($this->password)) {
|
|
$value = $this->config->get('email.password', false);
|
|
if (! $value) {
|
|
$value = $this->readPassword();
|
|
}
|
|
$this->password = $value;
|
|
}
|
|
return $this->password;
|
|
}
|
|
|
|
public function sendMail(string $from, array $to, string $subject, string $text, array $attachment = []): void
|
|
{
|
|
$email = new Email();
|
|
$email->from($from);
|
|
$email->to(...$to);
|
|
// @TODO use twig for templates. Create new template service.
|
|
// https://github.com/symfony/mailer
|
|
$email->subject($subject);
|
|
$email->text($text);
|
|
if (! empty($attachment)) {
|
|
if (! isset($attachment['path'])) {
|
|
var_dump('Attachment path missing!');
|
|
} else {
|
|
$email->attachFromPath($attachment['path'], $attachment['name'] ?? null, $attachment['type'] ?? null);
|
|
}
|
|
}
|
|
// Not sure whether it would be nicer to use class property instead of variable.
|
|
$transport = $this->getTransport();
|
|
$mailer = $this->getMailer($transport);
|
|
$mailer->send($email);
|
|
}
|
|
|
|
public function getTransport()
|
|
{
|
|
// @TODO remove username and password from config.
|
|
$username = rawurlencode($this->getProperty('username'));
|
|
$password = rawurlencode($this->getPasswordProperty());
|
|
// If your credentials contain special characters, you must URL-encode them.
|
|
// $mailer_dsn = "gmail+smtp://{$username}:{$password}@default";
|
|
$mailer_dsn = "gmail://{$username}:{$password}@localhost?encryption=tls&auth_mode=oauth";
|
|
return Transport::fromDsn($mailer_dsn);
|
|
}
|
|
|
|
public function getMailer($transport)
|
|
{
|
|
return new Mailer($transport);
|
|
}
|
|
|
|
public function sendDefaultMail(string $output): void
|
|
{
|
|
$tokens = $this->pdf->gatherTokensForTemplate(
|
|
$this->getEmailTemplatePath(),
|
|
false,
|
|
$this->getDefaultTokens(),
|
|
'email.tokens'
|
|
);
|
|
$text = $this->pdf->replaceTokensInTemplate($this->getEmailTemplatePath(), $tokens);
|
|
$this->sendMail(
|
|
$this->getProperty('from'),
|
|
$this->getProperty('to'),
|
|
$this->getProperty('subject'),
|
|
$text,
|
|
['path' => $output, 'Invoice', 'application/pdf']
|
|
);
|
|
}
|
|
|
|
public function getDefaultTokens(): array
|
|
{
|
|
$tokens = [];
|
|
$date = strtotime('-1 month');
|
|
$tokens['month'] = date('F', $date);
|
|
$tokens['year'] = date('Y', $date);
|
|
return $tokens;
|
|
}
|
|
|
|
protected function getEmailTemplatePath(): ?string
|
|
{
|
|
if (! isset($this->templatePath)) {
|
|
$template_path = $this->config->get('email.template_path', false);
|
|
if (! $template_path) {
|
|
$template_path = readline('Enter template file path: ');
|
|
}
|
|
if (! file_exists($template_path)) {
|
|
throw new Exception('Template file not found!');
|
|
}
|
|
$this->templatePath = $template_path;
|
|
}
|
|
return $this->templatePath;
|
|
}
|
|
|
|
public function setEmailTemplatePath(string $path): void
|
|
{
|
|
if (file_exists($path)) {
|
|
$this->templatePath = $path;
|
|
return;
|
|
}
|
|
throw new Exception('Email template file not found!');
|
|
}
|
|
}
|