Passed
Push — master ( 5b7bcd...49a209 )
by Andreas
17:05
created

org_openpsa_mail_message::get_message()   A

Complexity

Conditions 5
Paths 8

Size

Total Lines 40
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
cc 5
eloc 27
nc 8
nop 0
dl 0
loc 40
ccs 0
cts 16
cp 0
crap 30
rs 9.1768
c 0
b 0
f 0
1
<?php
2
/**
3
 * @package org.openpsa.mail
4
 * @author CONTENT CONTROL http://www.contentcontrol-berlin.de/
5
 * @copyright CONTENT CONTROL http://www.contentcontrol-berlin.de/
6
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License
7
 */
8
9
/**
10
 * Wrapper class for emails
11
 *
12
 * @package org.openpsa.mail
13
 */
14
class org_openpsa_mail_message
15
{
16
    private $_to;
17
18
    private $_encoding;
19
20
    private $_headers;
21
22
    private $_body;
23
    private $_html_body;
24
25
    /**
26
     * @var Swift_Message
27
     */
28
    private $_message;
29
30 6
    public function __construct($to, array $headers, string $encoding)
31
    {
32 6
        $this->_to = $this->_encode_address_field($to);
33 6
        $this->_headers = $headers;
34 6
        $this->_encoding = $encoding;
35
36 6
        $this->_message = new Swift_Message('');
37 6
    }
38
39 6
    public function get_recipients()
40
    {
41 6
        return $this->_to;
42
    }
43
44
    public function get_message() : Swift_Message
45
    {
46
        // set headers
47
        $headers_setter_map = [
48
            "content-type" => "setContentType",
49
            "content-description" => "setDescription",
50
            "from" => "setFrom",
51
            "to" => "setTo",
52
            "cc" => "setCc",
53
            "bcc" => "setBcc",
54
            "reply-to" => "setReplyTo",
55
            "subject" => "setSubject",
56
            "date" => "setDate",
57
            "return-path" => "setReturnPath"
58
        ];
59
60
        // map headers we got to swift setter methods
61
        $msg_headers = $this->_message->getHeaders();
62
        $headers = $this->get_headers();
63
        foreach ($headers as $name => $value) {
64
            if (array_key_exists(strtolower($name), $headers_setter_map)) {
65
                $setter = $headers_setter_map[strtolower($name)];
66
                $this->_message->$setter($value);
67
            } elseif ($msg_headers->has($name)) {
68
                // header already exists => just set a new value
69
                $msg_headers->get($name)->setValue($value);
0 ignored issues
show
Bug introduced by
The method setValue() does not exist on Swift_Mime_Header. It seems like you code against a sub-type of Swift_Mime_Header such as Swift_Mime_Headers_OpenDKIMHeader or Swift_Mime_Headers_UnstructuredHeader. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

69
                $msg_headers->get($name)->/** @scrutinizer ignore-call */ setValue($value);
Loading history...
70
            } else {
71
                $msg_headers->addTextHeader($name, $value);
72
            }
73
        }
74
75
        // somehow we need to set the body after the headers...
76
        if (!empty($this->_html_body)) {
77
            $this->_message->setBody($this->_html_body, 'text/html');
78
            $this->_message->addPart($this->_body, 'text/plain');
79
        } else {
80
            $this->_message->setBody($this->_body, 'text/plain');
81
        }
82
83
        return $this->_message;
84
    }
85
86
    public function set_header_field(string $name, $value)
87
    {
88
        $this->_headers[$name] = $value;
89
    }
90
91 6
    public function get_headers() : array
92
    {
93 6
        if (empty($this->_headers['Content-Type'])) {
94 6
            $this->_headers['Content-Type'] = "text/plain; charset={$this->_encoding}";
95
        }
96
97 6
        reset($this->_headers);
98 6
        foreach ($this->_headers as $header => $value) {
99 6
            if (is_string($value)) {
100 6
                $this->_headers[$header] = trim($value);
101
            }
102 6
            if (in_array(strtolower($header), ['from', 'reply-to', 'to'])) {
103 6
                $this->_headers[$header] = $this->_encode_address_field($value);
104
            }
105
        }
106
107 6
        return $this->_headers;
108
    }
109
110 6
    public function get_body()
111
    {
112 6
        return $this->_body;
113
    }
114
115 4
    public function set_body($body)
116
    {
117 4
        $this->_body = $body;
118 4
        $this->_html_body = null;
119 4
    }
120
121 2
    public function set_html_body(string $body, string $altBody, array $attachments, bool $do_image_embedding)
122
    {
123 2
        $this->_body = $altBody;
124 2
        $this->_html_body = $body;
125
126
        // adjust html body
127 2
        if ($do_image_embedding) {
128 1
            $this->_embed_images();
129
        }
130
131
        // process attachments
132 2
        $this->_process_attachments($attachments);
133 2
    }
134
135 1
    private function _embed_images()
136
    {
137
        // anything with SRC = "" something in it (images etc)
138 1
        $regExp_src = "/(src|background)=([\"'�])(((https?|ftp):\/\/)?(.*?))\\2/i";
139 1
        preg_match_all($regExp_src, $this->_html_body, $matches_src);
140 1
        debug_print_r("matches_src:", $matches_src);
141
142
        $matches = [
143 1
            "whole" => $matches_src[0],
144 1
            "uri" => $matches_src[3],
145 1
            "proto" => $matches_src[4],
146 1
            "location" => $matches_src[6]
147
        ];
148
149 1
        foreach ($matches["whole"] as $key => $match) {
150
            $location = $matches["location"][$key];
151
            // uri is fully qualified
152
            if ($matches['proto'][$key]) {
153
                $uri = $matches["uri"][$key];
154
            }
155
            // uri is relative
156
            elseif (preg_match('/^\//', $location)) {
157
                $uri = midcom::get()->get_host_name() . $location;
158
            } else {
159
                debug_add('No usable uri found, skipping embed', MIDCOM_LOG_WARN);
160
                continue;
161
            }
162
163
            // replace src by swiftmailer embedded image
164
            $repl = $this->_message->embed(Swift_Image::fromPath($uri));
165
            $new_html = str_replace($location, $repl, $match);
166
            $this->_html_body = str_replace($match, $new_html, $this->_html_body);
167
        }
168 1
    }
169
170 2
    private function _process_attachments(array $attachments)
171
    {
172 2
        foreach ($attachments as $att) {
173
            if (empty($att['mimetype'])) {
174
                $att['mimetype'] = "application/octet-stream";
175
            }
176
177
            $swift_att = false;
178
            // we got a file path
179
            if (!empty($att['file'])) {
180
                $swift_att = Swift_Attachment::fromPath($att['file'], $att['mimetype']);
181
            }
182
            // we got the contents (bytes)
183
            elseif (!empty($att['content'])) {
184
                $swift_att = new Swift_Attachment($att['content'], $att['name'], $att['mimetype']);
185
            }
186
187
            if ($swift_att) {
188
                $this->_message->attach($swift_att);
189
            }
190
        }
191 2
    }
192
193
    /**
194
     * Helper function that provides backwards compatibility
195
     * to addresses specified in a "Name <[email protected]>" format
196
     *
197
     * @param string $value The value to encode
198
     * @return mixed the encoded value
199
     */
200 6
    private function _encode_address_field($value)
201
    {
202 6
        if (is_array($value)) {
0 ignored issues
show
introduced by
The condition is_array($value) is always false.
Loading history...
203
            array_walk($value, [$this, '_encode_address_field']);
204
            return $value;
205
        }
206 6
        if ($pos = strpos($value, '<')) {
207 1
            $name = substr($value, 0, $pos);
208 1
            $name = preg_replace('/^\s*"/', '', $name);
209 1
            $name = preg_replace('/"\s*$/', '', $name);
210 1
            $address = substr($value, $pos + 1);
211 1
            $address = substr($address, 0, strlen($address) - 1);
212 1
            $value = [$address => $name];
213
        }
214 6
        return $value;
215
    }
216
}
217