Completed
Push — master ( 8bbcb3...7ba149 )
by Frederik
03:51
created

FormattedMessageFactory::createMessage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
declare(strict_types=1);
3
4
namespace Genkgo\Mail;
5
6
use Genkgo\Mail\Header\ContentType;
7
use Genkgo\Mail\Mime\MultiPart;
8
use Genkgo\Mail\Mime\Boundary;
9
use Genkgo\Mail\Mime\EmbeddedImage;
10
use Genkgo\Mail\Mime\HtmlPart;
11
use Genkgo\Mail\Mime\PartInterface;
12
use Genkgo\Mail\Mime\PlainTextPart;
13
14
/**
15
 * Class FormattedMessageFactory
16
 * @package Genkgo\Mail
17
 */
18
final class FormattedMessageFactory
19
{
20
    /**
21
     * @var array
22
     */
23
    private $attachments = [];
24
    /**
25
     * @var array
26
     */
27
    private $embedImages = [];
28
    /**
29
     * @var string
30
     */
31
    private $html;
32
    /**
33
     * @var AlternativeText
34
     */
35
    private $text;
36
37
    /**
38
     * @param string $html
39
     * @return FormattedMessageFactory
40
     */
41 3
    public function withHtml(string $html): FormattedMessageFactory
42
    {
43 3
        $clone = clone $this;
44 3
        $clone->html = $html;
45 3
        $clone->text = AlternativeText::fromHtml($html);
46 3
        return $clone;
47
    }
48
49
    /**
50
     * @param string $html
51
     * @return FormattedMessageFactory
52
     */
53 2
    public function withHtmlAndNoGeneratedAlternativeText(string $html): FormattedMessageFactory
54
    {
55 2
        $clone = clone $this;
56 2
        $clone->html = $html;
57 2
        return $clone;
58
    }
59
60
    /**
61
     * @param AlternativeText $text
62
     * @return FormattedMessageFactory
63
     */
64 2
    public function withAlternativeText(AlternativeText $text): FormattedMessageFactory
65
    {
66 2
        $clone = clone $this;
67 2
        $clone->text = $text;
68 2
        return $clone;
69
    }
70
71
    /**
72
     * @param PartInterface $part
73
     * @return FormattedMessageFactory
74
     */
75 5
    public function withAttachment(PartInterface $part): FormattedMessageFactory
76
    {
77
        try {
78 5
            $disposition = (string) $part->getHeader('Content-Disposition')->getValue();
79 4
            if (substr($disposition, 0, strpos($disposition, ';')) !== 'attachment') {
80 1
                throw new \InvalidArgumentException(
81 4
                    'An attachment must have Content-Disposition header with value `attachment`'
82
                );
83
            }
84 2
        } catch (\UnexpectedValueException $e) {
85 1
            throw new \InvalidArgumentException(
86 1
                'An attachment must have an Content-Disposition header'
87
            );
88
        }
89
90 3
        $clone = clone $this;
91 3
        $clone->attachments[] = $part;
92 3
        return $clone;
93
    }
94
95
    /**
96
     * @param EmbeddedImage $embeddedImage
97
     * @return FormattedMessageFactory
98
     */
99 3
    public function withEmbeddedImage(EmbeddedImage $embeddedImage): FormattedMessageFactory
100
    {
101 3
        $clone = clone $this;
102 3
        $clone->embedImages[] = $embeddedImage;
103 3
        return $clone;
104
    }
105
106
    /**
107
     * @return MessageInterface
108
     */
109 5
    public function createMessage(): MessageInterface
110
    {
111 5
        return (new MimeMessageFactory())->createMessage($this->createMessageRoot());
112
    }
113
114
    /**
115
     * @return PartInterface
116
     */
117 5
    private function createMessageRoot(): PartInterface
118
    {
119 5
        if (!empty($this->attachments)) {
120 2
            return (new MultiPart(
121 2
                Boundary::newRandom(),
122 2
                new ContentType('multipart/mixed')
123
            ))
124 2
                ->withPart($this->createMessageHumanReadable())
125 2
                ->withParts($this->attachments)
126
            ;
127
        }
128
129 3
        return $this->createMessageHumanReadable();
130
    }
131
132
    /**
133
     * @return PartInterface
134
     */
135 5
    private function createMessageHumanReadable(): PartInterface
136
    {
137 5
        if (!empty($this->embedImages)) {
138 2
            return (new MultiPart(
139 2
                Boundary::newRandom(),
140 2
                new ContentType('multipart/related')
141
            ))
142 2
                ->withPart($this->createMessageText())
143 2
                ->withParts($this->embedImages);
144
        }
145
146 3
        return $this->createMessageText();
147
    }
148
149
    /**
150
     * @return PartInterface
151
     */
152 5
    private function createMessageText(): PartInterface
153
    {
154 5
        if ($this->text === null && $this->html === null) {
155 1
            return new PlainTextPart('');
156
        }
157
158 4
        if ($this->text === null) {
159 1
            return new HtmlPart($this->html);
160
        }
161
162 3
        if ($this->html === null) {
163 1
            return new PlainTextPart((string)$this->text);
164
        }
165
166 2
        return (new MultiPart(
167 2
            Boundary::newRandom(),
168 2
            new ContentType('multipart/alternative')
169
        ))
170 2
            ->withPart(new PlainTextPart((string)$this->text))
171 2
            ->withPart(new HtmlPart($this->html));
172
    }
173
}