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

org_openpsa_mail::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 2
dl 0
loc 11
ccs 7
cts 7
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 7
    public function __construct(string $backend = 'try_default', array $backend_params = [])
117
    {
118 7
        $this->_component = 'org.openpsa.mail';
119 7
        $this->encoding = $this->_i18n->get_current_charset();
120
121 7
        $backend_params['swift_plugins'] = $this->_config->get_array('swift_plugins');
122
123 7
        $this->_backend = org_openpsa_mail_backend::get($backend, $backend_params);
124
125 7
        $this->headers['X-Originating-IP'] = '[' . $_SERVER['REMOTE_ADDR'] . ']';
126 7
        $this->headers['X-Mailer'] = "PHP/" . PHP_VERSION . ' /OpenPSA/' . midcom::VERSION . '/' . get_class($this->_backend);
127 7
    }
128
129
    /**
130
     * Make it possible to get header values via $mail->to and the like
131
     */
132 7
    public function __get($name)
133
    {
134 7
        $name = ucfirst($name);
135 7
        if (array_key_exists($name, $this->headers)) {
136 6
            return $this->headers[$name];
137
        }
138
139 7
        return $this->base__get($name);
140
    }
141
142
    /**
143
     * Make it possible to set header values via $mail->to and the like
144
     */
145 6
    public function __set($name, $value)
146
    {
147 6
        $name = ucfirst($name);
148 6
        if (array_key_exists($name, $this->headers)) {
149 6
            $this->headers[$name] = $value;
150
        }
151 6
    }
152
153
    /**
154
     * Tries to convert HTML to plaintext
155
     */
156 2
    private function html2text(string $html) : string
157
    {
158
        // strip all tags except br
159 2
        $text = strip_tags($html, '<br>');
160
161
        // Decode entities
162 2
        $text = html_entity_decode($text, ENT_QUOTES);
163
164
        $converters = [
165 2
            '/\x0a\x0d|\x0d\x0a|\x0d/' => "\n", // Convert various newlines to unix ones
166
            "/<br\s*\\/?>/i" => "\n", // convert <br/> tags to newlines
167
            "/[ \t\f]+$/m" => '', // Trim whitespace from end of lines
168
            "/^[ \t\f]+/m" => '', // Trim whitespace from beginning of lines
169
            "/[ \t\f]+/" => ' ', // Convert multiple concurrent spaces to one
170
            "/\n{3,}/" => "\n\n", // Strip extra linebreaks
171
        ];
172 2
        $text = preg_replace(array_keys($converters), array_values($converters), $text);
173
174
        // Wrap to RFC width
175 2
        $text = wordwrap($text, 72, "\n");
176
177 2
        return trim($text);
178
    }
179
180
    /**
181
     * Prepares message for sending
182
     *
183
     * Calls MIME etc encodings as necessary.
184
     */
185 6
    private function _prepare_message() : org_openpsa_mail_message
186
    {
187 6
        if (!empty($this->parameters)) {
188 2
            $template_helper = new org_openpsa_mail_template($this->parameters);
189 2
            $this->headers['Subject'] = $template_helper->parse($this->headers['Subject']);
190 2
            $this->body = $template_helper->parse($this->body);
191 2
            $this->html_body = $template_helper->parse($this->html_body);
192
        }
193
        //Translate newlines
194 6
        $this->body = preg_replace("/\n\r|\r\n|\r/", "\n", $this->body);
195 6
        $this->html_body = preg_replace("/\n\r|\r\n|\r/", "\n", $this->html_body);
196
197
        //Try to translate HTML-only body to plaintext as well
198 6
        if (empty($this->body) && !empty($this->html_body) && !$this->allow_only_html) {
199 2
            $this->body = $this->html2text($this->html_body);
200
        }
201
202 6
        $message = new org_openpsa_mail_message($this->to, $this->headers, $this->encoding);
203
204
        //Check whether it's necessary to initialize MIME
205 6
        if (!empty($this->html_body) || !empty($this->attachments)) {
206 2
            $message->set_html_body($this->html_body, $this->body, $this->attachments, $this->_do_image_embedding);
207
        } else {
208 4
            $message->set_body($this->body);
209
        }
210
211 6
        return $message;
212
    }
213
214
    /**
215
     * Sends the email
216
     */
217 6
    public function send()
218
    {
219
        // prepare mail for sending
220 6
        $message = $this->_prepare_message();
221
222 6
        $ret = $this->_backend->send($message);
223 6
        if (!$ret) {
224
            debug_add('Mail sending failed: ' . $this->_backend->get_error_message(), MIDCOM_LOG_ERROR);
225
        }
226 6
        return $ret;
227
    }
228
229 1
    public function embed_images()
230
    {
231 1
        $this->_do_image_embedding = true;
232 1
    }
233
234
    /**
235
     * Get error message from mail class
236
     */
237
    public function get_error_message() : string
238
    {
239
        return $this->_backend->get_error_message();
240
    }
241
}
242