• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

rich-id / email-template-bundle / #13

pending completion
#13

push

mdevlamynck
Add generics to tie generator with model, need to fix the null case, should not need to store the model in the service

2 of 2 new or added lines in 1 file covered. (100.0%)

105 of 117 relevant lines covered (89.74%)

4.38 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.16
/src/Domain/Email/AbstractEmail.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace RichId\EmailTemplateBundle\Domain\Email;
6

7
use RichId\EmailTemplateBundle\Domain\Attachment\Attachment;
8
use RichId\EmailTemplateBundle\Domain\Constant;
9
use RichId\EmailTemplateBundle\Domain\Email\Trait\EmailDataTrait;
10
use RichId\EmailTemplateBundle\Domain\Exception\InvalidEmailServiceException;
11
use RichId\EmailTemplateBundle\Domain\Fetcher\EmailTemplateFetcher;
12
use RichId\EmailTemplateBundle\Domain\Model\EmailModelInterface;
13
use RichId\EmailTemplateBundle\Domain\Port\TemplatingInterface;
14
use RichId\EmailTemplateBundle\Domain\Port\TranslatorInterface;
15
use Symfony\Component\Mime\Email;
16
use Symfony\Contracts\Service\Attribute\Required;
17

18
/** @template T of EmailModelInterface */
19
abstract class AbstractEmail
20
{
21
    public const TEMPLATES = [Constant::DEFAULT_TEMPLATE];
22
    protected const BODY_TYPE = self::BODY_TYPE_TRANSLATION;
23

24
    protected const BODY_TYPE_TRANSLATION = 'translation';
25
    protected const BODY_TYPE_TWIG = 'twig';
26

27
    protected const TRANSLATION_DOMAIN = 'emails';
28
    protected const TEMPLATING_FOLDER = 'emails';
29

30
    #[Required]
31
    public TemplatingInterface $templating;
32

33
    #[Required]
34
    public TranslatorInterface $translator;
35

36
    #[Required]
37
    public EmailTemplateFetcher $emailTemplateFetcher;
38

39
    /** @var ?T */
40
    protected ?EmailModelInterface $data = null;
41

42
    /** @param ?T $data */
43
    public function setData(?EmailModelInterface $data): self
44
    {
45
        $this->data = $data;
12✔
46

47
        return $this;
12✔
48
    }
49

50
    abstract public function getEmailSlug(): string;
51

52
    /** @return string[] */
53
    abstract protected function getTo(): array;
54

55
    protected function assertValidParameters(): void
56
    {
57
    }
58

59
    public function getName(): string
60
    {
61
        return $this->translator->trans(
×
62
            \sprintf('%s.name', $this->getEmailSlug()),
×
63
            [],
×
64
            static::TRANSLATION_DOMAIN
65
        );
66
    }
67

68
    /** @return string[] */
69
    protected function getCc(): array
70
    {
71
        return [];
1✔
72
    }
73

74
    /** @return string[] */
75
    protected function getBcc(): array
76
    {
77
        return [];
1✔
78
    }
79

80
    /** @return string[] */
81
    protected function getFrom(): array
82
    {
83
        return [];
1✔
84
    }
85

86
    /** @return Attachment[] */
87
    protected function getAttachments(): array
88
    {
89
        return [];
2✔
90
    }
91

92
    protected function skippedIf(): bool
93
    {
94
        return false;
8✔
95
    }
96

97
    protected function getSubject(): string
98
    {
99
        return $this->translator->trans(
6✔
100
            \sprintf('%s.%s.%s', $this->getEmailSlug(), $this->getTemplateSlug(), 'subject'),
6✔
101
            $this->customSubjectParameters(),
6✔
102
            static::TRANSLATION_DOMAIN
103
        );
104
    }
105

106
    /** @return array<string, mixed> */
107
    protected function customSubjectParameters(): array
108
    {
109
        return [];
6✔
110
    }
111

112
    protected function getBody(): string
113
    {
114
        if (static::BODY_TYPE === static::BODY_TYPE_TRANSLATION) {
6✔
115
            return $this->getTranslationBody();
4✔
116
        }
117

118
        if (static::BODY_TYPE === static::BODY_TYPE_TWIG) {
2✔
119
            return $this->getTwigBody();
1✔
120
        }
121

122
        throw new \InvalidArgumentException(\sprintf('Invalid argument for BODY_TYPE: %s given.', static::BODY_TYPE));
1✔
123
    }
124

125
    protected function getTranslationBody(): string
126
    {
127
        return $this->translator->trans(
4✔
128
            \sprintf('%s.%s.%s', $this->getEmailSlug(), $this->getTemplateSlug(), 'body'),
4✔
129
            $this->customBodyParameters(),
4✔
130
            static::TRANSLATION_DOMAIN
131
        );
132
    }
133

134
    protected function getTwigBody(): string
135
    {
136
        return $this->templating->render(
1✔
137
            \sprintf('%s/%s/%s.html.twig', static::TEMPLATING_FOLDER, $this->getEmailSlug(), $this->getTemplateSlug()),
1✔
138
            $this->customBodyParameters()
1✔
139
        );
140
    }
141

142
    /** @return array<string, mixed> */
143
    protected function customBodyParameters(): array
144
    {
145
        return [];
1✔
146
    }
147

148
    final protected function getEmail(): ?Email
149
    {
150
        $template = $this->getTemplateSlug();
12✔
151

152
        if (!$this->supportTemplate($template)) {
12✔
153
            throw new InvalidEmailServiceException($this::class, $template);
×
154
        }
155

156
        $this->assertValidParameters();
12✔
157

158
        if ($this->skippedIf()) {
9✔
159
            return null;
1✔
160
        }
161

162
        $to = $this->getTo();
8✔
163

164
        if (empty($to)) {
8✔
165
            return null;
2✔
166
        }
167

168
        $email = new Email();
6✔
169
        $email->subject($this->getSubject())
6✔
170
            ->html($this->getBody())
6✔
171
            ->to(...\array_unique($to));
5✔
172

173
        if (!empty($this->getCc())) {
5✔
174
            $email->cc(...\array_unique($this->getCc()));
4✔
175
        }
176

177
        if (!empty($this->getBcc())) {
5✔
178
            $email->bcc(...\array_unique($this->getBcc()));
4✔
179
        }
180

181
        if (!empty($this->getFrom())) {
5✔
182
            $email->from(...\array_unique($this->getFrom()));
4✔
183
        }
184

185
        foreach ($this->getAttachments() as $attachment) {
5✔
186
            if ($attachment instanceof Attachment) {
3✔
187
                $email->attach($attachment->getData(), $attachment->getFilename(), $attachment->getContentType());
3✔
188
            }
189
        }
190

191
        return $email;
5✔
192
    }
193

194
    final public function supportTemplate(string $template): bool
195
    {
196
        return \in_array($template, static::TEMPLATES);
12✔
197
    }
198

199
    final protected function getTemplateSlug(): string
200
    {
201
        return ($this->emailTemplateFetcher)($this->getEmailSlug());
12✔
202
    }
203
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc