Passed
Push — master ( 47c5a8...15e316 )
by Andreas
24:56
created

org_openpsa_mail::embed_images()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @package org.openpsa.mail
4
 * @author The Midgard Project, http://www.midgard-project.org
5
 * @copyright The Midgard Project, http://www.midgard-project.org
6
 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
7
 */
8
9
/**
10
 * Class for handling email sending
11
 *
12
 * <b>Sending Mails</b>
13
 *
14
 * Currently, the engine will send the emails through an autodetected transport, which
15
 * can be either SMTP, Sendmail or PHP's mail() function (in that order).
16
 *
17
 * <b>Example usage code</b>
18
 *
19
 * <code>
20
 * $mail = new org_openpsa_mail();
21
 *
22
 * $mail->from = '[email protected]';
23
 * $mail->subject = $this->_config->get('mail_from');
24
 * $mail->body = $this->_config->get('mail_body');
25
 * $mail->to = $this->_person->email;
26
 *
27
 * if (!$mail->send())
28
 * {
29
 *     debug_add("Email could not be sent: " . $mail->get_error_string(), MIDCOM_LOG_WARN);
30
 * }
31
 * </code>
32
 *
33
 * @property mixed $bcc BCC address(es)
34
 * @property mixed $cc CC address(es)
35
 * @property mixed $from From address(es)
36
 * @property string $subject Subject line
37
 * @property mixed $to To address(es)
38
 * @package org.openpsa.mail
39
 */
40
class org_openpsa_mail
41
{
42
    use midcom_baseclasses_components_base {__get as base__get;}
0 ignored issues
show
introduced by
The trait midcom_baseclasses_components_base requires some properties which are not provided by org_openpsa_mail: $i18n, $head
Loading history...
43
44
    /**
45
     * Text body
46
     *
47
     * @var string
48
     */
49
    public $body = '';
50
51
    /**
52
     * key is header name, value is header data
53
     *
54
     * @var array
55
     */
56
    public $headers = [
57
        'Subject' => null,
58
        'From' => null,
59
        'To' => null,
60
        'Cc' => null,
61
        'Bcc' => null,
62
    ];
63
64
    /**
65
     * HTML body (of MIME/multipart message)
66
     *
67
     * @var string
68
     */
69
    public $html_body = '';
70
71
    /**
72
     * The parameters to use for the Mail template.
73
     *
74
     * @var array
75
     */
76
    public $parameters = [];
77
78
    /**
79
     * Primary keys are int, secondary keys for decoded array are:
80
     *
81
     * 'name'     (filename)
82
     * 'content'  (file contents)
83
     * 'mimetype' Array for encoding may instead of 'content' have 'file'
84
     *            which is path to the file to be attached
85
     *
86
     * @var array
87
     */
88
    public $attachments = [];
89
90
    /**
91
     * Character encoding in which the texts etc are
92
     *
93
     * @var string
94
     */
95
    public $encoding;
96
97
    /**
98
     * Allow to send only HTML body
99
     *
100
     * @var boolean
101
     */
102
    public $allow_only_html = false;
103
104
    /**
105
     * shall embed_images be called by message class?
106
     *
107
     * @var boolean
108
     */
109
    private $_do_image_embedding = false;
110
111
    /**
112
     * @var org_openpsa_mail_backend
113
     */
114
    private $_backend;
115
116 9
    public function __construct(string $backend = 'try_default', array $backend_params = [])
117
    {
118 9
        $this->_component = 'org.openpsa.mail';
119 9
        $this->encoding = $this->_i18n->get_current_charset();
120
121 9
        $this->_backend = org_openpsa_mail_backend::get($backend, $backend_params);
122
123 9
        $this->headers['X-Originating-IP'] = '[' . $_SERVER['REMOTE_ADDR'] . ']';
124 9
        $this->headers['X-Mailer'] = "PHP/" . PHP_VERSION . ' /OpenPSA/' . midcom::VERSION . '/' . get_class($this->_backend);
125
    }
126
127
    /**
128
     * Make it possible to get header values via $mail->to and the like
129
     */
130 9
    public function __get($name)
131
    {
132 9
        $name = ucfirst($name);
133 9
        if (array_key_exists($name, $this->headers)) {
134 8
            return $this->headers[$name];
135
        }
136
137 9
        return $this->base__get($name);
138
    }
139
140
    /**
141
     * Make it possible to set header values via $mail->to and the like
142
     */
143 9
    public function __set($name, $value)
144
    {
145 9
        $name = ucfirst($name);
146 9
        if (array_key_exists($name, $this->headers)) {
147 9
            $this->headers[$name] = $value;
148
        }
149
    }
150
151
    /**
152
     * Tries to convert HTML to plaintext
153
     */
154 2
    private function html2text(string $html) : string
155
    {
156
        // strip all tags except br
157 2
        $text = strip_tags($html, '<br>');
158
159
        // Decode entities
160 2
        $text = html_entity_decode($text, ENT_QUOTES);
161
162 2
        $converters = [
163
            '/\x0a\x0d|\x0d\x0a|\x0d/' => "\n", // Convert various newlines to unix ones
164
            "/<br\s*\\/?>/i" => "\n", // convert <br/> tags to newlines
165
            "/[ \t\f]+$/m" => '', // Trim whitespace from end of lines
166
            "/^[ \t\f]+/m" => '', // Trim whitespace from beginning of lines
167
            "/[ \t\f]+/" => ' ', // Convert multiple concurrent spaces to one
168
            "/\n{3,}/" => "\n\n", // Strip extra linebreaks
169
        ];
170 2
        $text = preg_replace(array_keys($converters), array_values($converters), $text);
171
172
        // Wrap to RFC width
173 2
        $text = wordwrap($text, 72, "\n");
174
175 2
        return trim($text);
176
    }
177
178
    /**
179
     * Prepares message for sending
180
     *
181
     * Calls MIME etc encodings as necessary.
182
     */
183 8
    private function _prepare_message() : org_openpsa_mail_message
184
    {
185 8
        if (!empty($this->parameters)) {
186 4
            $template_helper = new org_openpsa_mail_template($this->parameters);
187 4
            $this->headers['Subject'] = $template_helper->parse($this->headers['Subject']);
188 4
            $this->body = $template_helper->parse($this->body);
189 4
            $this->html_body = $template_helper->parse($this->html_body);
190
        }
191
        //Translate newlines
192 8
        $this->body = preg_replace("/\n\r|\r\n|\r/", "\n", $this->body);
193 8
        $this->html_body = preg_replace("/\n\r|\r\n|\r/", "\n", $this->html_body);
194
195
        //Try to translate HTML-only body to plaintext as well
196 8
        if (empty($this->body) && !empty($this->html_body) && !$this->allow_only_html) {
197 2
            $this->body = $this->html2text($this->html_body);
198
        }
199
200 8
        $message = new org_openpsa_mail_message($this->to, array_filter($this->headers), $this->encoding);
201
202
        //Check whether it's necessary to initialize MIME
203 8
        if (!empty($this->html_body) || !empty($this->attachments)) {
204 2
            $message->set_html_body($this->html_body, $this->body, $this->attachments, $this->_do_image_embedding);
205
        } else {
206 6
            $message->set_body($this->body);
207
        }
208
209 8
        return $message;
210
    }
211
212
    /**
213
     * Sends the email
214
     */
215 8
    public function send()
216
    {
217
        // prepare mail for sending
218 8
        $message = $this->_prepare_message();
219
220 8
        $ret = $this->_backend->send($message);
221 8
        if (!$ret) {
222
            debug_add('Mail sending failed: ' . $this->_backend->get_error_message(), MIDCOM_LOG_ERROR);
223
        }
224 8
        return $ret;
225
    }
226
227 1
    public function embed_images()
228
    {
229 1
        $this->_do_image_embedding = true;
230
    }
231
232
    /**
233
     * Get error message from mail class
234
     */
235
    public function get_error_message() : string
236
    {
237
        return $this->_backend->get_error_message();
238
    }
239
}
240