Mail::setaddParams()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
/**
4
 * This file is part of the alphaz Framework.
5
 *
6
 * @author Muhammad Umer Farooq (Malik) <[email protected]>
7
 *
8
 * @link https://github.com/alphazframework/framework
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 *  file that was distributed with this source code.
12
 * @since 1.9.0
13
 *
14
 * @license MIT
15
 */
16
17
namespace alphaz\Mail;
18
19
class Mail
20
{
21
    /**
22
     * Additional parameters for sending the mail.
23
     *
24
     * @since 1.9.0
25
     *
26
     * @var string
27
     */
28
    private $addparams = '';
29
30
    /**
31
     * Collection of all attachments.
32
     *
33
     * @since 1.9.0
34
     *
35
     * @var array
36
     */
37
    private $attachments = [];
38
    /**
39
     * Collection of all BCC (Blind Copy Carbon) mail-addresses.
40
     *
41
     * @since 1.9.0
42
     *
43
     * @var array
44
     */
45
    private $bcc = [];
46
    /**
47
     * Collection of all CC (Copy Carbon) mail-addresses.
48
     *
49
     * @since 1.9.0
50
     *
51
     * @var array
52
     */
53
    private $cc = [];
54
    /**
55
     * The formatted content (HTML) of the mail.
56
     *
57
     * @since 1.9.0
58
     *
59
     * @var string|HTML
0 ignored issues
show
Bug introduced by
The type alphaz\Mail\HTML was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
60
     */
61
    private $contentHTML = '';
62
    /**
63
     * The plain content (non HTML) content of the mail.
64
     *
65
     * @since 1.9.0
66
     *
67
     * @var string
68
     */
69
    private $contentPlain = '';
70
    /**
71
     * Collection of all receivers.
72
     *
73
     * @since 1.9.0
74
     *
75
     * @var array
76
     */
77
    private $receivers = [];
78
    /**
79
     * The mail-address on which should be answered.
80
     *
81
     * @since 1.9.0
82
     *
83
     * @var string
84
     */
85
    private $replyTo = '';
86
    /**
87
     * The sender of the mail.
88
     *
89
     * @since 1.9.0
90
     *
91
     * @var string
92
     */
93
    private $sender = '';
94
    /**
95
     * The subject of the mail.
96
     *
97
     * @since 1.9.0
98
     *
99
     * @var string
100
     */
101
    private $subject = '';
102
    /**
103
     * Configuration for smtp.
104
     *
105
     * @since 1.9.0
106
     *
107
     * @var string
108
     */
109
    private $smtp = [];
110
111
    /**
112
     * For add attachment.
113
     *
114
     * @param resource $file
115
     *
116
     * @since 1.9.0
117
     *
118
     * @return void
119
     */
120
    public function addAttachment($file)
121
    {
122
        $this->attachments = $file;
0 ignored issues
show
Documentation Bug introduced by
It seems like $file of type resource is incompatible with the declared type array of property $attachments.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
123
    }
124
125
    /**
126
     * For add a new BCC.
127
     *
128
     * @param string $bcc
129
     *
130
     * @since 1.9.0
131
     *
132
     * @return bool
133
     */
134
    public function addBcc($bcc)
135
    {
136
        if ($this->isValidEmail($bcc) === true) {
137
            if (is_array($bcc, $this->bcc) === false) {
0 ignored issues
show
introduced by
The condition is_array($bcc, $this->bcc) === false is always true.
Loading history...
Unused Code introduced by
The call to is_array() has too many arguments starting with $this->bcc. ( Ignorable by Annotation )

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

137
            if (/** @scrutinizer ignore-call */ is_array($bcc, $this->bcc) === false) {

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
138
                $this->bcc[] = $bcc;
139
            }
140
        }
141
142
        return false;
143
    }
144
145
    /**
146
     * For adding a new cc.
147
     *
148
     * @param string $cc
149
     *
150
     * @since 1.9.0
151
     *
152
     * @return bool
153
     */
154
    public function addCc($cc)
155
    {
156
        if ($this->isValidEmail($cc) === true) {
157
            if (is_array($cc, $this->cc) === false) {
0 ignored issues
show
Unused Code introduced by
The call to is_array() has too many arguments starting with $this->cc. ( Ignorable by Annotation )

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

157
            if (/** @scrutinizer ignore-call */ is_array($cc, $this->cc) === false) {

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
introduced by
The condition is_array($cc, $this->cc) === false is always true.
Loading history...
158
                $this->cc[] = $cc;
159
            }
160
        }
161
162
        return false;
163
    }
164
165
    /**
166
     * For adding a receiver.
167
     *
168
     * @param string $email
169
     *
170
     * @since 1.9.0
171
     *
172
     * @return bool
173
     */
174
    public function addReceiver($email)
175
    {
176
        if ($this->isValidEmail($email) === true) {
177
            if (@is_array($email, $this->receivers) === false) {
0 ignored issues
show
Unused Code introduced by
The call to is_array() has too many arguments starting with $this->receivers. ( Ignorable by Annotation )

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

177
            if (@/** @scrutinizer ignore-call */ is_array($email, $this->receivers) === false) {

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
178
                $this->receivers[] = $email;
179
            }
180
        }
181
182
        return false;
183
    }
184
185
    /**
186
     * For preparing an attachment to send with mail.
187
     *
188
     * @since 1.9.0
189
     *
190
     * @return mix-data
0 ignored issues
show
Documentation Bug introduced by
The doc comment mix-data at position 0 could not be parsed: Unknown type name 'mix-data' at position 0 in mix-data.
Loading history...
191
     */
192
    public function prepareAttachment($attachment)
193
    {
194
        if ($this->isFile($attachment) !== true) {
0 ignored issues
show
Unused Code introduced by
The call to alphaz\Mail\Mail::isFile() has too many arguments starting with $attachment. ( Ignorable by Annotation )

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

194
        if ($this->/** @scrutinizer ignore-call */ isFile($attachment) !== true) {

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
195
            return false;
196
        }
197
        //http://php.net/manual/en/class.finfo.php
198
        $fileInfo = new \finfo(FILEINFO_MIME_TYPE);
199
        $fileType = $fileInfo->file($attachment);
200
        $file = fopen($attachment, 'r');
201
        $fileContent = fread($file, filesize($attachment));
202
        $fileContent = chunk_split(base64_encode($fileContent));
203
        fclose($file);
204
        $msgContent = 'Content-Type: '.$fileType.'; name='.basename($attachment)."\r\n";
205
        $msgContent .= 'Content-Transfer-Encoding: base64'."\r\n";
206
        $msgContent .= 'Content-ID: <'.basename($attachment).'>'."\r\n";
207
        $msgContent .= "\r\n".$fileContent."\r\n\r\n";
208
209
        return $msgContent;
210
    }
211
212
    /**
213
     * For send the mail.
214
     *
215
     * @since 1.9.0
216
     *
217
     * @return bool.
0 ignored issues
show
Documentation Bug introduced by
The doc comment bool. at position 0 could not be parsed: Unknown type name 'bool.' at position 0 in bool..
Loading history...
218
     */
219
    public function send()
220
    {
221
        //Check if a sender is available.
222
        if (empty(trim($this->sender))) {
223
            return false;
224
        }
225
        if ((is_array($this->receivers) === false) || (count($this->receivers) < 1)) {
226
            return false;
227
        }
228
        $receivers = implode(',', $this->receivers);
229
        if (!empty(trim($this->replyTo))) {
230
            $headers[] = 'Reply-To: '.$this->replyTo;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$headers was never initialized. Although not strictly required by PHP, it is generally a good practice to add $headers = array(); before regardless.
Loading history...
231
        } else {
232
            $headers[] = 'Reply-To: '.$this->sender;
233
        }
234
        if ((is_array($this->bcc) === true) && (count($this->bcc) > 0)) {
235
            $headers[] = 'Bcc: '.implode(',', $this->bcc);
236
        }
237
        if ((is_array($this->cc) === true) && (count($this->cc) > 0)) {
238
            $headers[] = 'Cc: '.implode(',', $this->cc);
239
        }
240
        //Generate boundaries for mail content areas.
241
        $boundaryMessage = md5(rand().'message');
242
        $boundaryContent = md5(rand().'content');
243
        //Set the header informations of the mail.
244
        $headers = [];
245
        $headers[] = 'MIME-Version: 1.0';
246
        $headers[] = 'X-Mailer: PHP/'.phpversion();
247
        $headers[] = 'Date: '.date('r', $_SERVER['REQUEST_TIME']);
248
        $headers[] = 'X-Originating-IP: '.$_SERVER['SERVER_ADDR'];
249
        $headers[] = 'Content-Type: multipart/related;boundary='.$boundaryMessage;
250
        $headers[] = 'Content-Transfer-Encoding: 8bit';
251
        $headers[] = 'From: '.$this->sender;
252
        $headers[] = 'Return-Path: '.$this->sender;
253
        //Start to generate the content of the mail.
254
        $msgContent = "\r\n".'--'.$boundaryMessage."\r\n";
255
        $msgContent .= 'Content-Type: multipart/alternative; boundary='.$boundaryContent."\r\n";
256
        if (!empty(trim($this->contentPlain))) {
257
            $msgContent .= "\r\n".'--'.$boundaryContent."\r\n";
258
            $msgContent .= 'Content-Type: text/plain; charset=ISO-8859-1'."\r\n";
259
            $msgContent .= "\r\n".$this->contentPlain."\r\n";
260
        }
261
        if (!empty(trim($this->contentHTML))) {
262
            $msgContent .= "\r\n".'--'.$boundaryContent."\r\n";
263
            $msgContent .= 'Content-Type: text/html; charset=ISO-8859-1'."\r\n";
264
            $msgContent .= "\r\n".$this->contentHTML."\r\n";
265
        }
266
        //Close the message area of the mail.
267
        $msgContent .= "\r\n".'--'.$boundaryContent.'--'."\r\n";
268
        foreach ($this->attachments as $attachment) {
269
            $attachmentContent = $this->prepareAttachment($attachment);
270
            if ($attachmentContent !== false) {
271
                $msgContent .= "\r\n".'--'.$boundaryMessage."\r\n";
272
                $msgContent .= $attachmentContent;
273
            }
274
        }
275
        //Close the area of the whole mail content.
276
        $msgContent .= "\r\n".'--'.$boundaryMessage.'--'."\r\n";
277
        if (!isset($this->smtp['status']) || $this->smtp['status'] === false) {
278
            $return = mail($receivers, $this->subject, $msgContent, implode("\r\n", $headers), $this->addparams);
279
        } else {
280
            $return = $this->sendSMTP($receivers, $this->sender, $msgContent);
281
        }
282
283
        return $return;
284
    }
285
286
    /**
287
     * Check is email is valid.
288
     *
289
     * @param string $email
290
     *
291
     * @since 1.9.0
292
     *
293
     * @return bool
294
     */
295
    public function isValidEmail($email)
296
    {
297
        if (filter_var($email, FILTER_VALIDATE_EMAIL) !== false) {
298
            return true;
299
        }
300
        if (filter_var($email, FILTER_SANITIZE_EMAIL) !== false) {
301
            return true;
302
        } else {
303
            return false;
304
        }
305
    }
306
307
    /**
308
     * Set SMPT status.
309
     *
310
     * @param $status
311
     *
312
     * @since 1.9.0
313
     *
314
     * @return bool
315
     */
316
    public function isSMTP(bool $status = false)
317
    {
318
        if ($status === true) {
319
            $this->smtp['status'] = $status;
320
        } else {
321
            $this->smtp['status'] = $status;
322
        }
323
    }
324
325
    /**
326
     * Send mail over SMTP.
327
     *
328
     * @param $to sender email
0 ignored issues
show
Bug introduced by
The type alphaz\Mail\sender was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
329
     *             $from from email
330
     *             $message message to be send
331
     *
332
     * @since 1.9.0
333
     *
334
     * @return bool
335
     */
336
    public function sendSMTP($to, $from, $message)
337
    {
338
        $host = __config()->email->smtp_host;
0 ignored issues
show
Bug introduced by
The call to __config() has too few arguments starting with key. ( Ignorable by Annotation )

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

338
        $host = /** @scrutinizer ignore-call */ __config()->email->smtp_host;

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
339
        $user = __config()->email->smtp_user;
340
        $pass = __config()->email->smtp_pass;
341
        $port = __config()->email->smtp_port;
342
        if ($h = fsockopen($host, $port)) {
343
            $data = [
344
                0,
345
                "EHLO $host",
346
                'AUTH LOGIN',
347
                base64_encode($user),
348
                base64_encode($pass),
349
                "MAIL FROM: <$from>",
350
                "RCPT TO: <$to>",
351
                'DATA',
352
                $message,
353
            ];
354
            foreach ($data as $c) {
355
                $c && fwrite($h, "$c\r\n");
356
                while (substr(fgets($h, 256), 3, 1) != ' ') {
357
                }
358
            }
359
            fwrite($h, "QUIT\r\n");
360
361
            return fclose($h);
362
        }
363
    }
364
365
    /**
366
     * For set additional parameter for the mail function (4th parameter).
367
     *
368
     * @param string $parameter
369
     *
370
     * @since 1.9.0
371
     *
372
     * @return void
373
     */
374
    public function setaddParams($params)
375
    {
376
        $this->addparams = $params;
377
    }
378
379
    /**
380
     * For the formatted content (HTML) of the mail.
381
     *
382
     * @param string $content
383
     *
384
     * @since 1.9.0
385
     *
386
     * @return void
387
     */
388
    public function setContentHTML($content)
389
    {
390
        $content = wordwrap($content, 60, "\n");
391
        $this->contentHTML = $content;
392
    }
393
394
    /**
395
     * For set the plain content of the mail.
396
     *
397
     * @param string $content
398
     *
399
     * @since 1.9.0
400
     *
401
     * @return void
402
     */
403
    public function setContentPlain($content)
404
    {
405
        $content = wordwrap($content, 60, "\n");
406
        $this->contentPlain = $content;
407
    }
408
409
    /**
410
     * For set reply_to in mail.
411
     *
412
     * @param string $subject The subject of the mail.
413
     *
414
     * @since 1.9.0
415
     *
416
     * @return bool
417
     */
418
    public function setReplyTo($email)
419
    {
420
        if ($this->isValidEmail($email) === true) {
421
            $this->reply_to = $email;
0 ignored issues
show
Bug Best Practice introduced by
The property reply_to does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
422
        } else {
423
            return false;
424
        }
425
    }
426
427
    /**
428
     * For set sender in mail.
429
     *
430
     * @param string $subject The subject of the mail.
431
     *
432
     * @since 1.9.0
433
     *
434
     * @return bool
435
     */
436
    public function setSender($email)
437
    {
438
        if ($this->isValidEmail($email) === true) {
439
            $this->sender = $email;
440
        } else {
441
            return false;
442
        }
443
    }
444
445
    /**
446
     * For set subject in mail.
447
     *
448
     * @param string $subject The subject of the mail.
449
     *
450
     * @since 1.9.0
451
     *
452
     * @return bool
453
     */
454
    public function setSubject($subject)
455
    {
456
        $this->subject = $subject;
457
    }
458
459
    /**
460
     * Check file exists or not.
461
     *
462
     * @param resource $file
463
     *
464
     * @since 1.9.0
465
     *
466
     * @return bool
467
     */
468
    public function isFile()
469
    {
470
        return file_exists($this->file);
0 ignored issues
show
Bug Best Practice introduced by
The property file does not exist on alphaz\Mail\Mail. Did you maybe forget to declare it?
Loading history...
471
    }
472
473
    /**
474
     * Clear all the information.
475
     *
476
     * @since 1.9.0
477
     *
478
     * @return void
479
     */
480
    public function clear()
481
    {
482
        unset($this->cc);
483
        unset($this->bcc);
484
        unset($this->receivers);
485
        unset($this->attachments);
486
        unset($this->contentHTML);
487
        unset($this->contentPlain);
488
    }
489
}
490