-
Notifications
You must be signed in to change notification settings - Fork 11
/
MailSender.php
118 lines (97 loc) · 3.83 KB
/
MailSender.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<?php declare(strict_types=1);
namespace Frosh\MailArchive\Services;
use Shopware\Core\Content\Mail\Service\AbstractMailSender;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
use Shopware\Core\Framework\Uuid\Uuid;
use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Mailer\Envelope;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;
#[AsDecorator(decorates: \Shopware\Core\Content\Mail\Service\MailSender::class)]
class MailSender extends AbstractMailSender
{
public function __construct(
private readonly AbstractMailSender $mailSender,
private readonly RequestStack $requestStack,
private readonly EntityRepository $froshMailArchiveRepository,
private readonly EntityRepository $customerRepository,
private readonly EmlFileManager $emlFileManager
) {
}
public function send(Email $email, ?Envelope $envelope = null): void
{
// let first send the mail itself, to see if it was really sent or entered error state
$this->mailSender->send($email, $envelope);
$this->saveMail($email);
}
public function getDecorated(): AbstractMailSender
{
return $this->mailSender;
}
private function saveMail(Email $message): void
{
$id = Uuid::randomHex();
$emlPath = $this->emlFileManager->writeFile($id, $message->toString());
$attachments = [];
foreach ($message->getAttachments() as $attachment) {
$attachments[] = [
'fileName' => $attachment->getFilename(),
'contentType' => $attachment->getContentType(),
'fileSize' => \strlen($attachment->bodyToString()),
];
}
$this->froshMailArchiveRepository->create([
[
'id' => $id,
'sender' => [$message->getFrom()[0]->getAddress() => $message->getFrom()[0]->getName()],
'receiver' => $this->convertAddress($message->getTo()),
'subject' => $message->getSubject(),
'plainText' => nl2br((string) $message->getTextBody()),
'htmlText' => $message->getHtmlBody(),
'emlPath' => $emlPath,
'salesChannelId' => $this->getCurrentSalesChannelId(),
'customerId' => $this->getCustomerIdByMail($message->getTo()),
'attachments' => $attachments,
],
], Context::createDefaultContext());
}
private function getCurrentSalesChannelId(): ?string
{
if ($this->requestStack->getMainRequest() === null) {
return null;
}
$salesChannelId = $this->requestStack->getMainRequest()->attributes->get('sw-sales-channel-id');
if (!\is_string($salesChannelId)) {
return null;
}
return $salesChannelId;
}
/**
* @param Address[] $to
*/
private function getCustomerIdByMail(array $to): ?string
{
$criteria = new Criteria();
$addresses = \array_map(function (Address $mail) {
return $mail->getAddress();
}, $to);
$criteria->addFilter(new EqualsAnyFilter('email', $addresses));
return $this->customerRepository->searchIds($criteria, Context::createDefaultContext())->firstId();
}
/**
* @param Address[] $addresses
* @return array<string, string>
*/
private function convertAddress(array $addresses): array
{
$list = [];
foreach ($addresses as $address) {
$list[$address->getAddress()] = $address->getName();
}
return $list;
}
}