Initial xentral_oss_20.3.c9ffacf
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\SystemMailer;
|
||||
|
||||
use Xentral\Core\DependencyInjection\ServiceContainer;
|
||||
use Xentral\Modules\SystemMailer\Service\EmailAccountGateway;
|
||||
use Xentral\Modules\SystemMailer\Service\MailBodyCleaner;
|
||||
use Xentral\Modules\SystemMailer\Service\MailerTransportFactory;
|
||||
use Xentral\Modules\SystemMailer\Service\MailLogService;
|
||||
|
||||
final class Bootstrap
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function registerServices(): array
|
||||
{
|
||||
return [
|
||||
'SystemMailer' => 'onInitMailer',
|
||||
'MailLogService' => 'onInitMailLogService',
|
||||
'MailerTransportFactory' => 'onInitMailerTransportFactory',
|
||||
'EmailAccountGateway' => 'onInitEmailAccountGateway',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServiceContainer $container
|
||||
*
|
||||
* @return SystemMailer
|
||||
*/
|
||||
public static function onInitMailer(ServiceContainer $container): SystemMailer
|
||||
{
|
||||
return new SystemMailer(
|
||||
$container->get('MailerTransportFactory'),
|
||||
$container->get('EmailAccountGateway'),
|
||||
$container->get('MailLogService'),
|
||||
new MailBodyCleaner()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServiceContainer $container
|
||||
*
|
||||
* @return MailLogService
|
||||
*/
|
||||
public static function onInitMailLogService(ServiceContainer $container): MailLogService
|
||||
{
|
||||
return new MailLogService($container->get('Database'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServiceContainer $container
|
||||
*
|
||||
* @return EmailAccountGateway
|
||||
*/
|
||||
public static function onInitEmailAccountGateway(ServiceContainer $container): EmailAccountGateway
|
||||
{
|
||||
return new EmailAccountGateway($container->get('Database'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServiceContainer $container
|
||||
*
|
||||
* @return MailerTransportFactory
|
||||
*/
|
||||
public static function onInitMailerTransportFactory(ServiceContainer $container): MailerTransportFactory
|
||||
{
|
||||
return new MailerTransportFactory($container);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,688 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\SystemMailer\Data;
|
||||
|
||||
use DateTime;
|
||||
use DateTimeInterface;
|
||||
|
||||
final class EmailBackupAccount implements MailAccountInterface
|
||||
{
|
||||
/** @var string AUTH_STANDARD */
|
||||
public const AUTH_STANDARD = '';
|
||||
|
||||
/** @var string AUTH_SMTP */
|
||||
public const AUTH_SMTP = 'smtp';
|
||||
|
||||
/** @var string AUTH_GMAIL */
|
||||
public const AUTH_GMAIL = 'oauth_google';
|
||||
|
||||
/** @var int $id */
|
||||
private $id;
|
||||
|
||||
/** @var string $displayName */
|
||||
private $displayName;
|
||||
|
||||
/** @var string $description */
|
||||
private $description;
|
||||
|
||||
/** @var string $username */
|
||||
private $username;
|
||||
|
||||
/** @var string $password */
|
||||
private $password;
|
||||
|
||||
/** @var string $server */
|
||||
private $server;
|
||||
|
||||
/** @var string $emailAddress */
|
||||
private $emailAddress;
|
||||
|
||||
/** @var bool $imapIsSentFolderActive */
|
||||
private $imapIsSentFolderActive;
|
||||
|
||||
/** @var string $imapSentFolder */
|
||||
private $imapSentFolder;
|
||||
|
||||
/** @var int $imapPort */
|
||||
private $imapPort;
|
||||
|
||||
/** @var int $imapType */
|
||||
private $imapType;
|
||||
|
||||
/** @var int $letterTemplateId */
|
||||
private $letterTemplateId;
|
||||
|
||||
/** @var bool $isAutoresponseActive */
|
||||
private $isAutoresponseActive;
|
||||
|
||||
/** @var string$autoresponseSubject */
|
||||
private $autoresponseSubject;
|
||||
|
||||
/** @var string $autoresponseText */
|
||||
private $autoresponseText;
|
||||
|
||||
/** @var bool $autoResponseLimitEnabled */
|
||||
private $autoResponseLimitEnabled;
|
||||
|
||||
/** @var int $projectId */
|
||||
private $projectId;
|
||||
|
||||
/** @var bool $isBackupEnabled */
|
||||
private $isBackupEnabled;
|
||||
|
||||
/** @var int $backupDeleteAfter */
|
||||
private $backupDeleteAfter;
|
||||
|
||||
/** @var int $companyId */
|
||||
private $companyId;
|
||||
|
||||
/** @var int $addressId */
|
||||
private $addressId;
|
||||
|
||||
/** @var bool $isTicketSystemActive */
|
||||
private $isTicketSystemActive;
|
||||
|
||||
/** @var bool $isDeleted */
|
||||
private $isDeleted;
|
||||
|
||||
/** @var bool $isTicketDeleteEnabled */
|
||||
private $isTicketDeleteEnabled;
|
||||
|
||||
/** @var bool $isTicketMarkAsFinishedEnabled */
|
||||
private $isTicketMarkAsFinishedEnabled;
|
||||
|
||||
/** @var string $ticketQueueId */
|
||||
private $ticketQueueId;
|
||||
|
||||
/** @var int $ticketProjectId */
|
||||
private $ticketProjectId;
|
||||
|
||||
/** @var bool$isTicketInboundEmailAddressEnabled */
|
||||
private $isTicketInboundEmailAddressEnabled;
|
||||
|
||||
/** @var string $ticketStartDay */
|
||||
private $ticketStartDay;
|
||||
|
||||
/** @var bool $isSmtpActive */
|
||||
private $isSmtpActive;
|
||||
|
||||
/** @var string $smtpServer */
|
||||
private $smtpServer;
|
||||
|
||||
/** @var string $smtpSecurity */
|
||||
private $smtpSecurity;
|
||||
|
||||
/** @var int $smtpPort */
|
||||
private $smtpPort;
|
||||
|
||||
/** @var string $smtpSenderEmail */
|
||||
private $smtpSenderEmail;
|
||||
|
||||
/** @var string $smtpSenderName */
|
||||
private $smtpSenderName;
|
||||
|
||||
/** @var bool $isSignatureActive */
|
||||
private $isSignatureActive;
|
||||
|
||||
/** @var string $signatureText */
|
||||
private $signatureText;
|
||||
|
||||
/** @var int $signatureMutex */
|
||||
private $signatureMutex;
|
||||
|
||||
/** @var string $smtpAuthType */
|
||||
private $smtpAuthType;
|
||||
|
||||
/** @var string $smtpAuthParam */
|
||||
private $smtpAuthParam;
|
||||
|
||||
/** @var bool $smtpDebugEnabled */
|
||||
private $smtpDebugEnabled;
|
||||
|
||||
/** @var string $clientAlias */
|
||||
private $clientAlias;
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return EmailBackupAccount
|
||||
*/
|
||||
public static function fromDbState(array $data):EmailBackupAccount
|
||||
{
|
||||
$instance = new self();
|
||||
$instance->id = (int)($data['id'] ?? 0);
|
||||
$instance->displayName = $data['angezeigtername'] ?? '';
|
||||
$instance->emailAddress = $data['email'] ?? '';
|
||||
$instance->description = $data['internebeschreibung'] ?? '';
|
||||
$instance->username = $data['benutzername'] ?? '';
|
||||
$instance->password = $data['passwort'] ?? '';
|
||||
$instance->server = $data['server'] ?? '';
|
||||
$instance->imapIsSentFolderActive = 1 === (int)($data['imap_sentfolder_aktiv'] ?? 0);
|
||||
$instance->imapSentFolder = $data['imap_sentfolder'] ?? '';
|
||||
$instance->imapPort = (int)($data['imap_port'] ?? 0);
|
||||
$instance->imapType = (int)($data['imap_type'] ?? 0);
|
||||
$instance->letterTemplateId = (int)($data['geschaeftsbriefvorlage'] ?? 0);
|
||||
$instance->isAutoresponseActive = 1 === (int)($data['autoresponder'] ?? 0);
|
||||
$instance->autoresponseSubject = $data['autoresponderbetreff'] ?? '';
|
||||
$instance->autoresponseText = $data['autorespondertext'] ?? '';
|
||||
$instance->autoResponseLimitEnabled = 1 === (int)($data['autosresponder_blacklist'] ?? null);
|
||||
if (array_key_exists('autoresponder_blacklist', $data)) {
|
||||
$instance->autoResponseLimitEnabled = 1 === (int)($data['autoresponder_blacklist'] ?? 0);
|
||||
}
|
||||
$instance->projectId = (int)($data['projekt'] ?? 0);
|
||||
$instance->isBackupEnabled = 1 === (int)($data['emailbackup'] ?? 0);
|
||||
$instance->backupDeleteAfter = (int)($data['loeschtage'] ?? 0);
|
||||
$instance->addressId = (int)($data['adresse'] ?? 0);
|
||||
$instance->companyId = (int)($data['firma'] ?? 0);
|
||||
$instance->isDeleted = 1 === (int)($data['geloescht'] ?? 0);
|
||||
$instance->isTicketSystemActive = 1 === (int)($data['ticket'] ?? 0);
|
||||
$instance->isTicketDeleteEnabled = 1 === (int)($data['ticketloeschen'] ?? 0);
|
||||
$instance->isTicketMarkAsFinishedEnabled = 1 === (int)($data['ticketabgeschlossen'] ?? 0);
|
||||
$instance->ticketQueueId = $data['ticketqueue'] ?? '';
|
||||
$instance->ticketProjectId = (int)($data['ticketprojekt'] ?? 0);
|
||||
$instance->isTicketInboundEmailAddressEnabled = 1 === (int)($data['ticketemaileingehend'] ?? 0);
|
||||
$instance->ticketStartDay = $data['abdatum'] ?? '';
|
||||
$instance->isSmtpActive = 1 === (int)($data['smtp_extra'] ?? 0);
|
||||
$instance->smtpServer = $data['smtp'] ?? '';
|
||||
switch ((int)($data['smtp_ssl'] ?? 0)) {
|
||||
case 0:
|
||||
$instance->smtpSecurity = '';
|
||||
break;
|
||||
|
||||
case 1:
|
||||
$instance->smtpSecurity = 'tls';
|
||||
break;
|
||||
|
||||
case 2:
|
||||
$instance->smtpSecurity = 'ssl';
|
||||
break;
|
||||
|
||||
default:
|
||||
$instance->smtpSecurity = '';
|
||||
}
|
||||
$instance->smtpPort = (int)($data['smtp_port'] ?? 0);
|
||||
$instance->smtpSenderEmail = $data['smtp_frommail'] ?? '';
|
||||
$instance->smtpSenderName = $data['smtp_fromname'] ?? '';
|
||||
$instance->smtpAuthType = mb_strtolower($data['smtp_authtype'] ?? '');
|
||||
$instance->smtpAuthParam = $data['smtp_authparam'] ?? '';
|
||||
$instance->smtpDebugEnabled = (int)($data['smtp_loglevel'] ?? 0) > 0;
|
||||
$instance->clientAlias = $data['client_alias'] ?? '';
|
||||
$instance->isSignatureActive = 1 === (int)($data['eigenesignatur'] ?? 0);
|
||||
$instance->signatureText = $data['signatur'] ?? '';
|
||||
$instance->signatureMutex = (int)($data['mutex'] ?? 0);
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return EmailBackupAccount
|
||||
*/
|
||||
public function withSmtpSenderName(string $name): EmailBackupAccount
|
||||
{
|
||||
$clone = clone($this);
|
||||
$clone->smtpSenderName = $name;
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return EmailBackupAccount
|
||||
*/
|
||||
public function withDisplayName(string $name): EmailBackupAccount
|
||||
{
|
||||
$clone = clone($this);
|
||||
$clone->displayName = $name;
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getType():string
|
||||
{
|
||||
if (!$this->isSmtpActive) {
|
||||
return 'imap';
|
||||
}
|
||||
|
||||
return $this->smtpAuthType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getServerAddress():string
|
||||
{
|
||||
if ($this->isSmtpActive === true) {
|
||||
return $this->smtpServer;
|
||||
}
|
||||
|
||||
return $this->server;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getClientAlias():string
|
||||
{
|
||||
return $this->clientAlias;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getSenderEmailAddress():string
|
||||
{
|
||||
if ($this->isSmtpActive === true && $this->smtpSenderEmail !== '') {
|
||||
return $this->smtpSenderEmail;
|
||||
}
|
||||
|
||||
return $this->emailAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getSenderName():string
|
||||
{
|
||||
if ($this->isSmtpActive === true && $this->smtpSenderEmail !== '') {
|
||||
return $this->smtpSenderEmail;
|
||||
}
|
||||
|
||||
return $this->displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getUserName():string
|
||||
{
|
||||
if ($this->smtpAuthType === MailAccountInterface::TYPE_GOOGLE) {
|
||||
return $this->smtpSenderEmail;
|
||||
}
|
||||
|
||||
return $this->username;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getId(): int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDisplayName(): string
|
||||
{
|
||||
return $this->displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPassword(): string
|
||||
{
|
||||
return $this->password;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getImapServer(): string
|
||||
{
|
||||
return $this->server;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getEmailAddress(): string
|
||||
{
|
||||
return $this->emailAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isCopyToOutgoingFolderEnabled(): bool
|
||||
{
|
||||
return $this->imapIsSentFolderActive && !empty($this->imapSentFolder);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getImapOutgoingFolder(): string
|
||||
{
|
||||
return $this->imapSentFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getImapPort(): int
|
||||
{
|
||||
return $this->imapPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getImapType(): int
|
||||
{
|
||||
return $this->imapType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getLetterTemplateId(): int
|
||||
{
|
||||
return $this->letterTemplateId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isAutoresponseEnabled(): bool
|
||||
{
|
||||
return $this->isAutoresponseActive;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAutoresponseSubject(): string
|
||||
{
|
||||
return $this->autoresponseSubject;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAutoresponseText(): string
|
||||
{
|
||||
return $this->autoresponseText;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isAutoresponseLimitEnabled(): bool
|
||||
{
|
||||
return $this->autoResponseLimitEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getProjectId(): int
|
||||
{
|
||||
return $this->projectId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isBackupEnabled(): bool
|
||||
{
|
||||
return $this->isBackupEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getBackupDeleteAfterDays(): int
|
||||
{
|
||||
return $this->backupDeleteAfter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getCompanyId(): int
|
||||
{
|
||||
return $this->companyId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getAddressId(): int
|
||||
{
|
||||
return $this->addressId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isTicketImportEnabled(): bool
|
||||
{
|
||||
return $this->isTicketSystemActive;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isMarkedAsDeleted(): bool
|
||||
{
|
||||
return $this->isDeleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isDeleteAfterImportEnabled(): bool
|
||||
{
|
||||
return $this->isTicketDeleteEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isTicketMarkAsFinishedEnabled(): bool
|
||||
{
|
||||
return $this->isTicketMarkAsFinishedEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTicketQueueId(): string
|
||||
{
|
||||
return $this->ticketQueueId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getTicketProjectId(): int
|
||||
{
|
||||
return $this->ticketProjectId ?? 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isTicketInboundEmailAddressEnabled(): bool
|
||||
{
|
||||
return $this->isTicketInboundEmailAddressEnabled ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DateTimeInterface|null
|
||||
*/
|
||||
public function getImportStartDate(): ?DateTimeInterface
|
||||
{
|
||||
if (empty($this->ticketStartDay) || $this->ticketStartDay === '0000-00-00') {
|
||||
return null;
|
||||
}
|
||||
$dateTime = DateTime::createFromFormat('Y-m-d', (string)$this->ticketStartDay);
|
||||
if ($dateTime === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $dateTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getImportStartDateAsString(): string
|
||||
{
|
||||
// ensure legacy code compatibility
|
||||
if (!is_string($this->ticketStartDay) || empty($this->ticketStartDay)) {
|
||||
return '0000-00-00';
|
||||
}
|
||||
|
||||
return $this->ticketStartDay;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isSmtpEnabled(): bool
|
||||
{
|
||||
return $this->isSmtpActive;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSmtpServer(): string
|
||||
{
|
||||
return $this->smtpServer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSmtpSecurity(): string
|
||||
{
|
||||
return $this->smtpSecurity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getSmtpPort(): int
|
||||
{
|
||||
return $this->smtpPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSmtpSenderEmail(): string
|
||||
{
|
||||
return $this->smtpSenderEmail;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSmtpSenderName(): string
|
||||
{
|
||||
return $this->smtpSenderName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isSignatureEnabled(): bool
|
||||
{
|
||||
return $this->isSignatureActive;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSignatureText(): string
|
||||
{
|
||||
return $this->signatureText;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSmtpAuthType(): string
|
||||
{
|
||||
return $this->smtpAuthType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isSmtpDebugEnabled(): bool
|
||||
{
|
||||
return $this->smtpDebugEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function __debugInfo(): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'displayName' => $this->displayName,
|
||||
'emailAddress' => $this->emailAddress,
|
||||
'descrption' => $this->description,
|
||||
'username' => $this->username,
|
||||
'password' => '**********',
|
||||
'server' => $this->server,
|
||||
'imapIsSentFolderActive' => $this->imapIsSentFolderActive,
|
||||
'imapSentFolder' => $this->imapSentFolder,
|
||||
'imapPort' => $this->imapPort,
|
||||
'imapType' => $this->imapType,
|
||||
'letterTemplateId' => $this->letterTemplateId,
|
||||
'isAutoresponseActive' => $this->isAutoresponseActive,
|
||||
'autoresponseSubject' => $this->autoresponseSubject,
|
||||
'autoresponseText' => $this->autoresponseText,
|
||||
'autoresponseLimitEnabled' => $this->autoResponseLimitEnabled,
|
||||
'projectId' => $this->projectId,
|
||||
'isBackupEnabled' => $this->isBackupEnabled,
|
||||
'backupDeleteAfter' => $this->backupDeleteAfter,
|
||||
'addressId' => $this->addressId,
|
||||
'companyId' => $this->companyId,
|
||||
'isDeleted' => $this->isDeleted,
|
||||
'isTicketImportEnabled' => $this->isTicketSystemActive,
|
||||
'isTicketDeleteEnabled' => $this->isTicketDeleteEnabled,
|
||||
'isTicketMarkAsFinishedEnabled' => $this->isTicketMarkAsFinishedEnabled,
|
||||
'ticketQueueId' => $this->ticketQueueId,
|
||||
'ticketProjectId' => $this->ticketProjectId,
|
||||
'isTicketInboundEmailAddressEnabled' => $this->isTicketInboundEmailAddressEnabled,
|
||||
'ticketStartDate' => $this->ticketStartDay,
|
||||
'isSmtpEnabled' => $this->isSmtpActive,
|
||||
'smtpServer' => $this->smtpServer,
|
||||
'smtpSecurity' => $this->smtpSecurity,
|
||||
'smtpPort' => $this->smtpPort,
|
||||
'smtpSenderEmail' => $this->smtpSenderEmail,
|
||||
'smtpSenderName' => $this->smtpSenderName,
|
||||
'smtpAuthType' => $this->smtpAuthType,
|
||||
'smtpAuthParam' => $this->smtpAuthParam,
|
||||
'smtpDebugEnabled' => $this->smtpDebugEnabled,
|
||||
'clientAlias' => $this->clientAlias,
|
||||
'isSignatureEnabled' => $this->isSignatureActive,
|
||||
'signatureText' => $this->signatureText,
|
||||
'signatureMutex' => $this->signatureMutex,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\SystemMailer\Data;
|
||||
|
||||
interface MailAccountInterface
|
||||
{
|
||||
/** @var string TYPE_SMTP */
|
||||
const TYPE_SMTP = 'smtp';
|
||||
|
||||
/** @var string TYPE_IMAP */
|
||||
const TYPE_IMAP = 'imap';
|
||||
|
||||
/** @var string TYPE_GOOGLE */
|
||||
const TYPE_GOOGLE = 'oauth_google';
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getType():string;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getServerAddress():string;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getClientAlias():string;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSenderEmailAddress():string;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSenderName():string;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getUserName():string;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Modules\SystemMailer\Exception;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
class EmailBackupAccountException extends RuntimeException implements SystemMailerExceptionInterface
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Modules\SystemMailer\Exception;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
class GmailOAuthException extends RuntimeException implements SystemMailerExceptionInterface
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Modules\SystemMailer\Exception;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
class InvalidArgumentException extends RuntimeException implements SystemMailerExceptionInterface
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Modules\SystemMailer\Exception;
|
||||
|
||||
use Xentral\Core\Exception\ModuleExceptionInterface;
|
||||
|
||||
interface SystemMailerExceptionInterface extends ModuleExceptionInterface
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\SystemMailer\Service;
|
||||
|
||||
use Exception;
|
||||
use Xentral\Components\Database\Database;
|
||||
use Xentral\Components\Database\SqlQuery\SelectQuery;
|
||||
use Xentral\Modules\SystemMailer\Data\EmailBackupAccount;
|
||||
use Xentral\Modules\SystemMailer\Exception\EmailBackupAccountException;
|
||||
|
||||
final class EmailAccountGateway
|
||||
{
|
||||
/** @var Database $db */
|
||||
private $db;
|
||||
|
||||
/**
|
||||
* @param Database $database
|
||||
*/
|
||||
public function __construct(Database $database)
|
||||
{
|
||||
$this->db = $database;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
*
|
||||
* @throws EmailBackupAccountException
|
||||
*
|
||||
* @return EmailBackupAccount
|
||||
*/
|
||||
public function getEmailAccountById(int $id): EmailBackupAccount
|
||||
{
|
||||
$query = $this->getBaseQuery()->where('id = :id');
|
||||
$sql = $query->getStatement();
|
||||
$row = $this->db->fetchRow($sql, ['id' => $id]);
|
||||
if (empty($row)) {
|
||||
throw new EmailBackupAccountException('Account not found.');
|
||||
}
|
||||
|
||||
return EmailBackupAccount::fromDbState($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $userId
|
||||
*
|
||||
* @throws EmailBackupAccountException
|
||||
*
|
||||
* @return EmailBackupAccount
|
||||
*/
|
||||
public function getAccountByUser(int $userId): EmailBackupAccount
|
||||
{
|
||||
$query = $this->getBaseQuery();
|
||||
try {
|
||||
$query->join('', 'user AS u', 'u.adresse = e.adresse AND u.adresse != 0');
|
||||
} catch (Exception $e) {
|
||||
throw new EmailBackupAccountException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
$query->where('u.activ = 1')
|
||||
->where('u.id = :user_id');
|
||||
$sql = $query->getStatement();
|
||||
$values = ['user_id' => $userId];
|
||||
$row = $this->db->fetchRow($sql, $values);
|
||||
if (empty($row)) {
|
||||
throw new EmailBackupAccountException(sprintf('No email account found for user "%s"', $userId));
|
||||
}
|
||||
|
||||
return EmailBackupAccount::fromDbState($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $addressId
|
||||
*
|
||||
* @throws EmailBackupAccountException
|
||||
*
|
||||
* @return EmailBackupAccount
|
||||
*/
|
||||
public function getAccountByAddress(int $addressId): EmailBackupAccount
|
||||
{
|
||||
$query = $this->getBaseQuery()->where('e.adresse = :address_id');
|
||||
$row = $this->db->fetchRow($query, ['address_id' => $addressId]);
|
||||
if (empty($row)) {
|
||||
throw new EmailBackupAccountException(sprintf('No email account found for address "%s"', $addressId));
|
||||
}
|
||||
|
||||
return EmailBackupAccount::fromDbState($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $email
|
||||
*
|
||||
* @throws EmailBackupAccountException
|
||||
*
|
||||
* @return EmailBackupAccount
|
||||
*/
|
||||
public function getAccountByEmail(string $email): EmailBackupAccount
|
||||
{
|
||||
$query = $this->getBaseQuery()->where('email LIKE :email')->orWhere('smtp_frommail LIKE :email');
|
||||
$sql = $query->getStatement();
|
||||
$row = $this->db->fetchRow($sql, ['email' => $email]);
|
||||
if (empty($row)) {
|
||||
throw new EmailBackupAccountException(sprintf('No email account found for %s', $email));
|
||||
}
|
||||
|
||||
return EmailBackupAccount::fromDbState($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 20.3
|
||||
* @deprecated use getAccountByEmail instead
|
||||
*
|
||||
* @param string $email
|
||||
*
|
||||
* @return EmailBackupAccount|null
|
||||
*/
|
||||
public function tryGetEmailAccountByEmail(string $email): ?EmailBackupAccount
|
||||
{
|
||||
$query = $this->getBaseQuery()->where('email LIKE :email')->orWhere('smtp_frommail LIKE :email');
|
||||
$sql = $query->getStatement();
|
||||
$row = $this->db->fetchRow($sql, ['email' => $email]);
|
||||
if (empty($row)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return EmailBackupAccount::fromDbState($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return EmailBackupAccount[]
|
||||
*/
|
||||
public function getAccountsWithTicketActive(): array
|
||||
{
|
||||
$query = $this->getBaseQuery();
|
||||
$query->where('e.ticket = 1');
|
||||
$query->where('e.geloescht != 1');
|
||||
$sql = $query->getStatement();
|
||||
$rows = $this->db->fetchAll($sql);
|
||||
$accounts = [];
|
||||
foreach ($rows as $row) {
|
||||
$accounts[] = EmailBackupAccount::fromDbState($row);
|
||||
}
|
||||
|
||||
return $accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SelectQuery
|
||||
*/
|
||||
private function getBaseQuery(): SelectQuery
|
||||
{
|
||||
$select = $this->db->select();
|
||||
$select->cols(
|
||||
[
|
||||
'e.id',
|
||||
'e.angezeigtername',
|
||||
'e.internebeschreibung',
|
||||
'e.benutzername',
|
||||
'e.passwort',
|
||||
'e.server',
|
||||
'e.smtp',
|
||||
'e.ticket',
|
||||
'e.imap_sentfolder_aktiv',
|
||||
'e.imap_sentfolder',
|
||||
'e.imap_port',
|
||||
'e.imap_type',
|
||||
'e.autoresponder',
|
||||
'e.geschaeftsbriefvorlage',
|
||||
'e.autoresponderbetreff',
|
||||
'e.autorespondertext',
|
||||
'e.projekt',
|
||||
'e.emailbackup',
|
||||
'e.adresse',
|
||||
'e.firma',
|
||||
'e.loeschtage',
|
||||
'e.geloescht',
|
||||
'e.ticketloeschen',
|
||||
'e.ticketabgeschlossen',
|
||||
'e.ticketqueue',
|
||||
'e.ticketprojekt',
|
||||
'e.ticketemaileingehend',
|
||||
'e.smtp_extra',
|
||||
'e.smtp_ssl',
|
||||
'e.smtp_port',
|
||||
'e.smtp_frommail',
|
||||
'e.smtp_fromname',
|
||||
'e.autosresponder_blacklist as autoresponder_blacklist',
|
||||
'e.eigenesignatur',
|
||||
'e.signatur',
|
||||
'e.mutex',
|
||||
'e.abdatum',
|
||||
'e.email',
|
||||
'e.smtp_authtype',
|
||||
'e.smtp_authparam',
|
||||
'e.smtp_loglevel',
|
||||
'e.client_alias',
|
||||
]
|
||||
);
|
||||
$select->from('emailbackup as e');
|
||||
|
||||
return $select;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\SystemMailer\Service;
|
||||
|
||||
use Xentral\Components\Mailer\Data\EmailMessage;
|
||||
|
||||
final class MailBodyCleaner
|
||||
{
|
||||
/**
|
||||
* @param EmailMessage $email
|
||||
*
|
||||
* @return EmailMessage
|
||||
*/
|
||||
public function cleanEmailBody(EmailMessage $email): EmailMessage
|
||||
{
|
||||
return $email;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Modules\SystemMailer\Service;
|
||||
|
||||
use Xentral\Components\Database\Database;
|
||||
use Xentral\Components\Mailer\Data\EmailMessage;
|
||||
use Xentral\Modules\SystemMailer\Data\MailAccountInterface;
|
||||
|
||||
final class MailLogService
|
||||
{
|
||||
/** @var int LOGTYPE_DEFAULT */
|
||||
const LOGTYPE_DEFAULT = 0;
|
||||
|
||||
/** @var int LOGTYPE_CC */
|
||||
const LOGTYPE_CC = 1;
|
||||
|
||||
/** @var int LOGTYPE_BCC */
|
||||
const LOGTYPE_BCC = 2;
|
||||
|
||||
/** @var Database $db */
|
||||
private $db;
|
||||
|
||||
/**
|
||||
* @param Database $database
|
||||
*/
|
||||
public function __construct(Database $database)
|
||||
{
|
||||
$this->db = $database;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EmailMessage $email
|
||||
* @param MailAccountInterface $account
|
||||
* @param string $status
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function logOutgoingMail(EmailMessage $email, MailAccountInterface $account, $status):void
|
||||
{
|
||||
$status .= sprintf(
|
||||
' (Host:%s User: %s)',
|
||||
$account->getServerAddress(),
|
||||
$account->getUsername()
|
||||
);
|
||||
$insert = $this->db->insert();
|
||||
$insert->into('mailausgang');
|
||||
foreach ($email->getRecipients() as $recipient) {
|
||||
$insert->addRow()
|
||||
->cols(
|
||||
[
|
||||
'subject' => $email->getSubject(),
|
||||
'body' => $email->getBody(),
|
||||
'from' => $account->getSenderEmailAddress(),
|
||||
'to' => (string)$recipient,
|
||||
'status' => $status,
|
||||
'art' => self::LOGTYPE_DEFAULT,
|
||||
]
|
||||
)
|
||||
->set('zeit', 'NOW()');
|
||||
}
|
||||
foreach ($email->getCcRecipients() as $recipient) {
|
||||
$insert->addRow()
|
||||
->cols(
|
||||
[
|
||||
'subject' => $email->getSubject(),
|
||||
'body' => $email->getBody(),
|
||||
'from' => $account->getSenderEmailAddress(),
|
||||
'to' => (string)$recipient,
|
||||
'status' => $status,
|
||||
'art' => self::LOGTYPE_CC,
|
||||
]
|
||||
)
|
||||
->set('zeit', 'NOW()');
|
||||
}
|
||||
foreach ($email->getBccRecipients() as $recipient) {
|
||||
$insert->addRow()
|
||||
->cols(
|
||||
[
|
||||
'subject' => $email->getSubject(),
|
||||
'body' => $email->getBody(),
|
||||
'from' => $account->getSenderEmailAddress(),
|
||||
'to' => (string)$recipient,
|
||||
'status' => $status,
|
||||
'art' => self::LOGTYPE_BCC,
|
||||
]
|
||||
)
|
||||
->set('zeit', 'NOW()');
|
||||
}
|
||||
|
||||
$sql = $insert->getStatement();
|
||||
$values = $insert->getBindValues();
|
||||
|
||||
$this->db->perform($sql, $values);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $days
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function deleteLogsOlderThan(int $days = 90):int
|
||||
{
|
||||
$sql = 'DELETE FROM `mailausgang` WHERE DATE_SUB(CURDATE(), INTERVAL :dayInterval DAY) >= zeit';
|
||||
|
||||
return $this->db->fetchAffected($sql, ['dayInterval' => $days]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\SystemMailer\Service;
|
||||
|
||||
use PHPMailer\PHPMailer\PHPMailer;
|
||||
use Xentral\Components\Logger\LoggerAwareTrait;
|
||||
use Xentral\Components\Mailer\Config\OAuthMailerConfig;
|
||||
use Xentral\Components\Mailer\Config\SmtpMailerConfig;
|
||||
use Xentral\Components\Mailer\Transport\MailerTransportInterface;
|
||||
use Xentral\Components\Mailer\Transport\PhpMailerOAuth;
|
||||
use Xentral\Components\Mailer\Transport\PhpMailerTransport;
|
||||
use Xentral\Core\DependencyInjection\ContainerInterface;
|
||||
use Xentral\Modules\GoogleApi\Exception\GoogleAccountNotFoundException;
|
||||
use Xentral\Modules\GoogleApi\Exception\GoogleCredentialsException;
|
||||
use Xentral\Modules\GoogleApi\Service\GoogleAccountGateway;
|
||||
use Xentral\Modules\GoogleApi\Service\GoogleAuthorizationService;
|
||||
use Xentral\Modules\GoogleApi\Service\GoogleCredentialsService;
|
||||
use Xentral\Modules\SystemMailer\Data\EmailBackupAccount;
|
||||
use Xentral\Modules\SystemMailer\Exception\GmailOAuthException;
|
||||
use Xentral\Modules\SystemMailer\Exception\InvalidArgumentException;
|
||||
use Xentral\Modules\SystemMailer\Transport\PhpMailerGoogleAuthentification;
|
||||
|
||||
class MailerTransportFactory
|
||||
{
|
||||
use LoggerAwareTrait;
|
||||
|
||||
/** @var ContainerInterface $container */
|
||||
private $container;
|
||||
|
||||
/**
|
||||
* @param ContainerInterface $container
|
||||
*/
|
||||
public function __construct(ContainerInterface $container) {
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EmailBackupAccount $account
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return MailerTransportInterface
|
||||
*/
|
||||
public function createMailerTransport(EmailBackupAccount $account):MailerTransportInterface
|
||||
{
|
||||
switch ($account->getSmtpAuthType()) {
|
||||
|
||||
case EmailBackupAccount::AUTH_SMTP:
|
||||
return $this->createSmtpTransport($account);
|
||||
break;
|
||||
|
||||
case EmailBackupAccount::AUTH_GMAIL:
|
||||
return $this->createGoogleOAuthTransport($account);
|
||||
|
||||
default:
|
||||
throw new InvalidArgumentException('Only SMTP accounts are supported.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EmailBackupAccount $account
|
||||
*
|
||||
* @return SmtpMailerConfig
|
||||
*/
|
||||
public function createSmtpMailerConfig(EmailBackupAccount $account):SmtpMailerConfig
|
||||
{
|
||||
if ($account->isSmtpEnabled() === false || $account->getSmtpAuthType() !== EmailBackupAccount::AUTH_SMTP) {
|
||||
throw new InvalidArgumentException('Only SMTP accounts are supported.');
|
||||
}
|
||||
|
||||
$email = $account->getSmtpSenderEmail();
|
||||
if ($email === '') {
|
||||
$email = $account->getEmailAddress();
|
||||
}
|
||||
$sender = $account->getSmtpSenderName();
|
||||
if ($sender === '') {
|
||||
$sender = $account->getDisplayName();
|
||||
}
|
||||
$debug = 0;
|
||||
if ($account->isSmtpDebugEnabled()) {
|
||||
$debug = 4;
|
||||
}
|
||||
|
||||
return new SmtpMailerConfig([
|
||||
'sender_email' => $email,
|
||||
'sender_name' => $sender,
|
||||
'host' => $account->getSmtpServer(),
|
||||
'hostname' => $account->getClientAlias(),
|
||||
'username' => $account->getUserName(),
|
||||
'password' => $account->getPassword(),
|
||||
'port' => $account->getSmtpPort(),
|
||||
'smtp_security' => $account->getSmtpSecurity(),
|
||||
'mailer' => 'smtp',
|
||||
'smtp_debug' => $debug
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EmailBackupAccount $account
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return OAuthMailerConfig
|
||||
*/
|
||||
public function createGmailMailerConfig(EmailBackupAccount $account):OAuthMailerConfig
|
||||
{
|
||||
if (
|
||||
$account->isSmtpEnabled() === false
|
||||
|| $account->getSmtpAuthType() !== EmailBackupAccount::AUTH_GMAIL
|
||||
) {
|
||||
throw new InvalidArgumentException('Only SMTP OAUTH accounts are supported.');
|
||||
}
|
||||
$email = $account->getSmtpSenderEmail();
|
||||
if ($email === '') {
|
||||
$email = $account->getEmailAddress();
|
||||
}
|
||||
$sender = $account->getSmtpSenderName();
|
||||
if ($sender === '') {
|
||||
$sender = $account->getDisplayName();
|
||||
}
|
||||
$debug = 0;
|
||||
if ($account->isSmtpDebugEnabled()) {
|
||||
$debug = 4;
|
||||
}
|
||||
$cfgValues = [
|
||||
'sender_email' => $email,
|
||||
'sender_name' => $sender,
|
||||
'host' => $account->getSmtpServer(),
|
||||
'hostname' => $account->getClientAlias(),
|
||||
'port' => $account->getSmtpPort(),
|
||||
'smtp_security' => $account->getSmtpSecurity(),
|
||||
'mailer' => 'smtp',
|
||||
'smtp_debug' => $debug
|
||||
];
|
||||
if ($cfgValues['host'] === '') {
|
||||
$cfgValues['host'] = 'smtp.gmail.com';
|
||||
}
|
||||
|
||||
return new OAuthMailerConfig($cfgValues);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EmailBackupAccount $account
|
||||
*
|
||||
* @return PhpMailerTransport
|
||||
*/
|
||||
public function createSmtpTransport(EmailBackupAccount $account):PhpMailerTransport
|
||||
{
|
||||
$config = $this->createSmtpMailerConfig($account);
|
||||
$mailer = new PHPMailer(true);
|
||||
|
||||
return new PhpMailerTransport($mailer, $config, $this->logger);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EmailBackupAccount $account
|
||||
*
|
||||
* @throws GoogleCredentialsException
|
||||
* @throws GmailOAuthException
|
||||
* @throws GoogleAccountNotFoundException
|
||||
*
|
||||
* @return PhpMailerTransport
|
||||
*/
|
||||
public function createGoogleOAuthTransport(EmailBackupAccount $account):PhpMailerTransport
|
||||
{
|
||||
$config = $this->createGmailMailerConfig($account);
|
||||
/** @var GoogleCredentialsService $credentialsService */
|
||||
$credentialsService = $this->container->get('GoogleCredentialsService');
|
||||
$credentialsService->getCredentials()->validate();
|
||||
/** @var GoogleAccountGateway $googleApiGateway */
|
||||
$googleApiGateway = $this->container->get('GoogleAccountGateway');
|
||||
$googleAccount = $googleApiGateway->getAccountByGmailAddress($account->getSenderEmailAddress());
|
||||
|
||||
/** @var GoogleAuthorizationService $googleAuth */
|
||||
$googleAuth = $this->container->get('GoogleAuthorizationService');
|
||||
$oauth = new PhpMailerGoogleAuthentification(
|
||||
$googleApiGateway,
|
||||
$googleAuth,
|
||||
$googleAccount
|
||||
);
|
||||
$mailer = new PhpMailerOAuth(true, $oauth);
|
||||
|
||||
return new PhpMailerTransport($mailer, $config, $this->logger);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\SystemMailer;
|
||||
|
||||
use Exception;
|
||||
use Xentral\Components\Logger\LoggerAwareTrait;
|
||||
use Xentral\Components\Mailer\Data\EmailMessage;
|
||||
use Xentral\Components\Mailer\Data\FileAttachment;
|
||||
use Xentral\Components\Mailer\Exception\MailerTransportException;
|
||||
use Xentral\Components\Mailer\Mailer;
|
||||
use Xentral\Modules\GoogleApi\Exception\AuthorizationExpiredException;
|
||||
use Xentral\Modules\SystemMailer\Data\EmailBackupAccount;
|
||||
use Xentral\Modules\SystemMailer\Service\EmailAccountGateway;
|
||||
use Xentral\Modules\SystemMailer\Service\MailBodyCleaner;
|
||||
use Xentral\Modules\SystemMailer\Service\MailerTransportFactory;
|
||||
use Xentral\Modules\SystemMailer\Service\MailLogService;
|
||||
|
||||
final class SystemMailer
|
||||
{
|
||||
use LoggerAwareTrait;
|
||||
|
||||
/** @var MailerTransportFactory $factory */
|
||||
private $factory;
|
||||
|
||||
/** @var MailLogService $emailLog */
|
||||
private $emailLog;
|
||||
|
||||
/** @var MailBodyCleaner $cleaner */
|
||||
private $cleaner;
|
||||
|
||||
/** @var EmailAccountGateway $accountGateway */
|
||||
private $accountGateway;
|
||||
|
||||
/**
|
||||
* @param MailerTransportFactory $factory
|
||||
* @param EmailAccountGateway $accountGateway
|
||||
* @param MailLogService $emailLog
|
||||
* @param MailBodyCleaner $cleaner
|
||||
*/
|
||||
public function __construct(
|
||||
MailerTransportFactory $factory,
|
||||
EmailAccountGateway $accountGateway,
|
||||
MailLogService $emailLog,
|
||||
MailBodyCleaner $cleaner
|
||||
) {
|
||||
$this->factory = $factory;
|
||||
$this->emailLog = $emailLog;
|
||||
$this->cleaner = $cleaner;
|
||||
$this->accountGateway = $accountGateway;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EmailMessage $email
|
||||
* @param EmailBackupAccount $account
|
||||
*
|
||||
* @return bool success
|
||||
*/
|
||||
public function send(EmailMessage $email, EmailBackupAccount $account): bool
|
||||
{
|
||||
$transport = $this->factory->createMailerTransport($account);
|
||||
$email = $this->cleaner->cleanEmailBody($email);
|
||||
$mailer = new Mailer($transport);
|
||||
try {
|
||||
$success = $mailer->send($email);
|
||||
$this->emailLog->logOutgoingMail($email, $account, $transport->getStatus());
|
||||
if ($transport->hasErrors()) {
|
||||
$this->logger->error('Error while sending email.', ['error' => $transport->getErrorMessages()]);
|
||||
}
|
||||
} catch (MailerTransportException $e) {
|
||||
$this->logger->error($e->getMessage(), ['dump' => $transport->getErrorMessages()]);
|
||||
|
||||
return false;
|
||||
} catch (AuthorizationExpiredException $e) {
|
||||
$this->logger->error(
|
||||
'Sending Email Failed: Google authorization expired',
|
||||
['exception' => $e]
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated only for backwards compatibility with erpApi::MailSendFinal
|
||||
*
|
||||
* @param string $senderEmail
|
||||
* @param string $senderName
|
||||
* @param array $recipients
|
||||
* @param string $subject
|
||||
* @param string $body
|
||||
* @param array $attachFiles
|
||||
* @param array $ccs
|
||||
* @param array $bccs
|
||||
*
|
||||
* @return bool success
|
||||
*/
|
||||
public function composeAndSendEmail(
|
||||
$senderEmail,
|
||||
$senderName,
|
||||
$recipients,
|
||||
$subject,
|
||||
$body,
|
||||
$attachFiles = [],
|
||||
$ccs = [],
|
||||
$bccs = []
|
||||
): bool {
|
||||
//cannot use Mailer component if no emailbackup account exists
|
||||
$account = null;
|
||||
try {
|
||||
$account = $this->accountGateway->getAccountByEmail($senderEmail);
|
||||
} catch (Exception $e) {
|
||||
$account = null;
|
||||
$this->logger->error($e->getMessage(), ['exception' => $e]);
|
||||
}
|
||||
|
||||
if ($account === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//use Mailer component only for 'smtp' or 'gmail' authtype
|
||||
if (
|
||||
$account->isSmtpEnabled() === false
|
||||
|| (
|
||||
$account->getSmtpAuthType() !== EmailBackupAccount::AUTH_SMTP
|
||||
&& $account->getSmtpAuthType() !== EmailBackupAccount::AUTH_GMAIL
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$email = new EmailMessage($subject, $body, $recipients, $ccs, $bccs);
|
||||
foreach ($attachFiles as $file) {
|
||||
if ($file !== null && file_exists($file)) {
|
||||
$email->addAttachment(new FileAttachment($file));
|
||||
}
|
||||
}
|
||||
|
||||
$account = $account
|
||||
->withSmtpSenderName($senderName)
|
||||
->withDisplayName($senderName);
|
||||
|
||||
//send email with new Mailer component
|
||||
return $this->send($email, $account);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated only for backwards compatibility with erpApi::MailSendFinal
|
||||
*
|
||||
* @param array $recipients
|
||||
* @param string $subject
|
||||
* @param string $body
|
||||
* @param array $attachFiles
|
||||
* @param array $ccs
|
||||
* @param array $bccs
|
||||
*
|
||||
* @return EmailMessage
|
||||
*/
|
||||
public function composeEmail(
|
||||
$recipients,
|
||||
$subject,
|
||||
$body,
|
||||
$attachFiles = [],
|
||||
$ccs = [],
|
||||
$bccs = []
|
||||
): EmailMessage {
|
||||
$email = new EmailMessage($subject, $body, $recipients, $ccs, $bccs);
|
||||
foreach ($attachFiles as $file) {
|
||||
if ($file !== null && file_exists($file)) {
|
||||
$email->addAttachment(new FileAttachment($file));
|
||||
}
|
||||
}
|
||||
|
||||
return $email;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\SystemMailer\Transport;
|
||||
|
||||
use Xentral\Components\Mailer\Exception\OAuthCredentialsException;
|
||||
use Xentral\Components\Mailer\Transport\PhpMailerOAuthAuthentificationInterface;
|
||||
use Xentral\Modules\GoogleApi\Data\GoogleAccountData;
|
||||
use Xentral\Modules\GoogleApi\Exception\AuthorizationExpiredException;
|
||||
use Xentral\Modules\GoogleApi\Exception\NoAccessTokenException;
|
||||
use Xentral\Modules\GoogleApi\Exception\NoRefreshTokenException;
|
||||
use Xentral\Modules\GoogleApi\Service\GoogleAccountGateway;
|
||||
use Xentral\Modules\GoogleApi\Service\GoogleAuthorizationService;
|
||||
|
||||
final class PhpMailerGoogleAuthentification implements PhpMailerOAuthAuthentificationInterface
|
||||
{
|
||||
/** @var GoogleAccountGateway */
|
||||
private $gateway;
|
||||
|
||||
/** @var GoogleAuthorizationService */
|
||||
private $authorizationService;
|
||||
|
||||
/** @var GoogleAccountData */
|
||||
private $googleAccount;
|
||||
|
||||
/**
|
||||
* @param GoogleAccountGateway $gateway
|
||||
* @param GoogleAuthorizationService $authorizationService
|
||||
* @param GoogleAccountData $googleAccount
|
||||
*/
|
||||
public function __construct(
|
||||
GoogleAccountGateway $gateway,
|
||||
GoogleAuthorizationService $authorizationService,
|
||||
GoogleAccountData $googleAccount
|
||||
)
|
||||
{
|
||||
$this->gateway = $gateway;
|
||||
$this->authorizationService = $authorizationService;
|
||||
$this->googleAccount = $googleAccount;
|
||||
}
|
||||
|
||||
/**
|
||||
* GetOauth64
|
||||
*
|
||||
* encode the user email related to this request along with the token in base64
|
||||
* this is used for authentication, in the phpmailer smtp class
|
||||
*
|
||||
* @throws OAuthCredentialsException
|
||||
* @throws NoAccessTokenException
|
||||
* @throws NoRefreshTokenException
|
||||
* @throws AuthorizationExpiredException
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOauth64():string
|
||||
{
|
||||
$gmailAddress = $this->gateway->getAccountProperties($this->googleAccount->getId())
|
||||
->get('gmail_address');
|
||||
if ($this->googleAccount === null || $gmailAddress === null) {
|
||||
throw new OAuthCredentialsException('SMTP Google OAuth - missing credentials');
|
||||
}
|
||||
$token = $this->gateway->getAccessToken($this->googleAccount->getId());
|
||||
if ($token->getTimeToLive() < 30) {
|
||||
$token = $this->authorizationService->refreshAccessToken($this->googleAccount);
|
||||
}
|
||||
$offlineToken = $token->getToken();
|
||||
|
||||
return base64_encode(
|
||||
sprintf(
|
||||
"user=%s\001auth=Bearer %s\001\001",
|
||||
$gmailAddress,
|
||||
$offlineToken
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user