Completed
Push — master ( a1727f...e2607c )
by Philippe
03:34
created

src/Message.php (10 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Message.php
4
 *
5
 * PHP version 5.6+
6
 *
7
 * @author Philippe Gaultier <[email protected]>
8
 * @copyright 2010-2016 Philippe Gaultier
9
 * @license http://www.sweelix.net/license license
10
 * @version XXX
11
 * @link http://www.sweelix.net
12
 * @package sweelix\postmark
13
 */
14
15
namespace sweelix\postmark;
16
17
18
use yii\base\InvalidConfigException;
19
use yii\base\InvalidParamException;
20
use yii\base\NotSupportedException;
21
use yii\helpers\ArrayHelper;
22
use yii\mail\BaseMessage;
23
use Yii;
24
use yii\mail\MailerInterface;
25
26
/**
27
 * This component allow user to send an email
28
 *
29
 * @author Philippe Gaultier <[email protected]>
30
 * @copyright 2010-2016 Philippe Gaultier
31
 * @license http://www.sweelix.net/license license
32
 * @version XXX
33
 * @link http://www.sweelix.net
34
 * @package sweelix\postmark
35
 * @since XXX
36
 */
37
class Message extends BaseMessage
38
{
39
    /**
40
     * @var string from
41
     */
42
    protected $from;
43
44
    /**
45
     * @var array
46
     */
47
    protected $to = [];
48
49
    /**
50
     * @var string reply to
51
     */
52
    protected $replyTo;
53
54
    /**
55
     * @var array
56
     */
57
    protected $cc = [];
58
59
    /**
60
     * @var array
61
     */
62
    protected $bcc = [];
63
64
    /**
65
     * @var string
66
     */
67
    protected $subject;
68
69
    /**
70
     * @var string
71
     */
72
    protected $textBody;
73
74
    /**
75
     * @var string
76
     */
77
    protected $htmlBody;
78
79
    /**
80
     * @var array
81
     */
82
    protected $attachments = [];
83
84
    /**
85
     * @var string
86
     */
87
    protected $tag;
88
89
    /**
90
     * @var bool
91
     */
92
    protected $trackOpens = true;
93
94
    /**
95
     * @var array
96
     */
97
    protected $headers = [];
98
99
    /**
100
     * @var string
101
     */
102
    protected $templateId;
103
104
    /**
105
     * @var array
106
     */
107
    protected $templateModel;
108
109
    /**
110
     * @var bool
111
     */
112
    protected $inlineCss = true;
113
114
    /**
115
     * @inheritdoc
116
     */
117 1
    public function getCharset()
118
    {
119 1
        throw new NotSupportedException();
120
    }
121
122
    /**
123
     * @inheritdoc
124
     */
125 1
    public function setCharset($charset)
126
    {
127 1
        throw new NotSupportedException();
128
    }
129
130
    /**
131
     * @inheritdoc
132
     */
133 1
    public function getFrom()
134
    {
135 1
        return $this->extractEmails($this->from);
136
    }
137
138
    /**
139
     * @inheritdoc
140
     */
141 3
    public function setFrom($from)
142
    {
143 3
        $this->from = $from;
0 ignored issues
show
Documentation Bug introduced by
It seems like $from can also be of type array. However, the property $from is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
144 3
        return $this;
145
    }
146
147
    /**
148
     * @inheritdoc
149
     */
150 3
    public function getTo()
151
    {
152 3
        return $this->extractEmails($this->to);
153
    }
154
155
    /**
156
     * @inheritdoc
157
     */
158 3
    public function setTo($to)
159
    {
160 3
        $this->to = $to;
0 ignored issues
show
Documentation Bug introduced by
It seems like $to can also be of type string. However, the property $to is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
161 3
        return $this;
162
    }
163
164
    /**
165
     * @inheritdoc
166
     */
167 1
    public function getReplyTo()
168
    {
169 1
        return $this->extractEmails($this->replyTo);
170
    }
171
172
    /**
173
     * @inheritdoc
174
     */
175 1
    public function setReplyTo($replyTo)
176
    {
177 1
        $this->replyTo = $replyTo;
0 ignored issues
show
Documentation Bug introduced by
It seems like $replyTo can also be of type array. However, the property $replyTo is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
178 1
        return $this;
179
    }
180
181
    /**
182
     * @inheritdoc
183
     */
184 1
    public function getCc()
185
    {
186 1
        return $this->extractEmails($this->cc);
187
    }
188
189
    /**
190
     * @inheritdoc
191
     */
192 1
    public function setCc($cc)
193
    {
194 1
        $this->cc = $cc;
0 ignored issues
show
Documentation Bug introduced by
It seems like $cc can also be of type string. However, the property $cc is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
195 1
        return $this;
196
    }
197
198
    /**
199
     * @inheritdoc
200
     */
201 1
    public function getBcc()
202
    {
203 1
        return $this->extractEmails($this->bcc);
204
    }
205
206
    /**
207
     * @inheritdoc
208
     */
209 1
    public function setBcc($bcc)
210
    {
211 1
        $this->bcc = $bcc;
0 ignored issues
show
Documentation Bug introduced by
It seems like $bcc can also be of type string. However, the property $bcc is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
212 1
        return $this;
213
    }
214
215
    /**
216
     * @inheritdoc
217
     */
218 3
    public function getSubject()
219
    {
220 3
        return $this->subject;
221
    }
222
223
    /**
224
     * @inheritdoc
225
     */
226 2
    public function setSubject($subject)
227
    {
228 2
        $this->subject = $subject;
229 2
        return $this;
230
    }
231
232
    /**
233
     * @return string|null text body of the message
234
     * @since XXX
235
     */
236 1
    public function getTextBody()
237
    {
238 1
        return $this->textBody;
239
    }
240
241
    /**
242
     * @inheritdoc
243
     */
244 2
    public function setTextBody($text)
245
    {
246 2
        $this->textBody = $text;
247 2
        return $this;
248
    }
249
250
    /**
251
     * @return string|null html body of the message
252
     * @since XXX
253
     */
254 1
    public function getHtmlBody()
255
    {
256 1
        return $this->htmlBody;
257
    }
258
259
    /**
260
     * @inheritdoc
261
     */
262 1
    public function setHtmlBody($html)
263
    {
264 1
        $this->htmlBody = $html;
265 1
        return $this;
266
    }
267
268
    /**
269
     * @return string tag associated to the email
270
     * @since XXX
271
     */
272 1
    public function getTag()
273
    {
274 1
        return $this->tag;
275
    }
276
277
    /**
278
     * @param string $tag tag which should be associated to the email
279
     * @return $this
280
     * @since XXX
281
     */
282 1
    public function setTag($tag)
283
    {
284 1
        $this->tag = $tag;
285 1
        return $this;
286
    }
287
288
    /**
289
     * @param bool $trackOpens define if mail should be tracked
290
     * @return $this
291
     * @since XXX
292
     */
293 1
    public function setTrackOpens($trackOpens)
294
    {
295 1
        $this->trackOpens = $trackOpens;
296 1
        return $this;
297
    }
298
299
    /**
300
     * @return bool tracking status
301
     * @since XXX
302
     */
303 1
    public function getTrackOpens()
304
    {
305 1
        return $this->trackOpens;
306
    }
307
308
    /**
309
     * @param integer $templateId template Id used. in this case, Subject / HtmlBody / TextBody are discarded
310
     * @return $this
311
     * @since XXX
312
     */
313 2
    public function setTemplateId($templateId)
314
    {
315 2
        $this->templateId = $templateId;
0 ignored issues
show
Documentation Bug introduced by
The property $templateId was declared of type string, but $templateId is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
316 2
        return $this;
317
    }
318
319
    /**
320
     * @return integer|null current templateId
321
     * @since XXX
322
     */
323 1
    public function getTemplateId()
324
    {
325 1
        return $this->templateId;
326
    }
327
328
    /**
329
     * @param array $templateModel model associated with the template
330
     * @return $this
331
     * @since XXX
332
     */
333 2
    public function setTemplateModel($templateModel)
334
    {
335 2
        $this->templateModel = $templateModel;
336 2
        return $this;
337
    }
338
339
    /**
340
     * @return array current template model
341
     * @since XXX
342
     */
343 1
    public function getTemplateModel()
344
    {
345 1
        return $this->templateModel;
346
    }
347
348
    /**
349
     * @param bool $inlineCss define if css should be inlined
350
     * @return $this
351
     * @since XXX
352
     */
353 1
    public function setInlineCss($inlineCss)
354
    {
355 1
        $this->inlineCss = $inlineCss;
356 1
        return $this;
357
    }
358
359
    /**
360
     * @return bool define if css should be inlined
361
     * @since XXX
362
     */
363 1
    public function getInlineCss()
364
    {
365 1
        return $this->inlineCss;
366
    }
367
368
    /**
369
     * @param array $header add custom header to the mail
370
     * @since XXX
371
     */
372 1
    public function addHeader($header)
373
    {
374 1
        $this->headers[] = $header;
375 1
    }
376
377
    /**
378
     * @return array|null headers which should be added to the mail
379
     * @since XXX
380
     */
381 1
    public function getHeaders()
382
    {
383 1
        return empty($this->headers) ? null : $this->headers;
384
    }
385
386
    /**
387
     * @return array|null list of attachments
388
     * @since XXX
389
     */
390 1
    public function getAttachments()
391
    {
392 1
        return empty($this->attachments) ? null : $this->attachments;
393
    }
394
395
    /**
396
     * @inheritdoc
397
     */
398 1
    public function attach($fileName, array $options = [])
399
    {
400 1
        $attachment['Content'] = base64_encode(file_get_contents($fileName));
0 ignored issues
show
Coding Style Comprehensibility introduced by
$attachment was never initialized. Although not strictly required by PHP, it is generally a good practice to add $attachment = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
401 1
        if (!empty($options['fileName'])) {
402 1
            $attachment['Name'] = $options['fileName'];
403 1
        } else {
404 1
            $attachment['Name'] = pathinfo($fileName, PATHINFO_BASENAME);
405
        }
406 1
        if (!empty($options['contentType'])) {
407 1
            $attachment['ContentType'] = $options['contentType'];
408 1
        } else {
409 1
            $attachment['ContentType'] = 'application/octet-stream';
410
        }
411 1
        $this->attachments[] = $attachment;
412 1
        return $this;
413
    }
414
415
    /**
416
     * @inheritdoc
417
     */
418 2
    public function attachContent($content, array $options = [])
419
    {
420 2
        $attachment['Content'] = base64_encode($content);
0 ignored issues
show
Coding Style Comprehensibility introduced by
$attachment was never initialized. Although not strictly required by PHP, it is generally a good practice to add $attachment = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
421 2
        if (!empty($options['fileName'])) {
422 1
            $attachment['Name'] = $options['fileName'];
423 1
        } else {
424 1
            throw new InvalidParamException('Filename is missing');
425
        }
426 1
        if (!empty($options['contentType'])) {
427 1
            $attachment['ContentType'] = $options['contentType'];
428 1
        } else {
429 1
            $attachment['ContentType'] = 'application/octet-stream';
430
        }
431 1
        $this->attachments[] = $attachment;
432 1
        return $this;
433
    }
434
435
    /**
436
     * @inheritdoc
437
     */
438 1
    public function embed($fileName, array $options = [])
439
    {
440 1
        $embed['Content'] = base64_encode(file_get_contents($fileName));
0 ignored issues
show
Coding Style Comprehensibility introduced by
$embed was never initialized. Although not strictly required by PHP, it is generally a good practice to add $embed = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
441 1
        if (!empty($options['fileName'])) {
442 1
            $embed['Name'] = $options['fileName'];
443 1
        } else {
444 1
            $embed['Name'] = pathinfo($fileName, PATHINFO_BASENAME);
445
        }
446 1
        if (!empty($options['contentType'])) {
447 1
            $embed['ContentType'] = $options['contentType'];
448 1
        } else {
449 1
            $embed['ContentType'] = 'application/octet-stream';
450
        }
451 1
        $embed['ContentID'] = 'cid:' . uniqid();
452 1
        $this->attachments[] = $embed;
453 1
        return $embed['ContentID'];
454
    }
455
456
    /**
457
     * @inheritdoc
458
     */
459 2
    public function embedContent($content, array $options = [])
460
    {
461 2
        $embed['Content'] = base64_encode($content);
0 ignored issues
show
Coding Style Comprehensibility introduced by
$embed was never initialized. Although not strictly required by PHP, it is generally a good practice to add $embed = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
462 2
        if (!empty($options['fileName'])) {
463 1
            $embed['Name'] = $options['fileName'];
464 1
        } else {
465 1
            throw new InvalidParamException('Filename is missing');
466
        }
467 1
        if (!empty($options['contentType'])) {
468 1
            $embed['ContentType'] = $options['contentType'];
469 1
        } else {
470 1
            $embed['ContentType'] = 'application/octet-stream';
471
        }
472 1
        $embed['ContentID'] = 'cid:' . uniqid();
473 1
        $this->attachments[] = $embed;
474 1
        return $embed['ContentID'];
475
    }
476
477
    /**
478
     * @inheritdoc
479
     * @todo make real serialization to make message compliant with PostmarkAPI
480
     */
481
    public function toString()
482
    {
483
        return serialize($this);
484
    }
485
486
487
    /**
488
     * @param array|string $emailsData email can be defined as string. In this case no transformation is done
489
     *                                 or as an array ['[email protected]', '[email protected]' => 'Email 2']
490
     * @return string|null
491
     * @since XXX
492
     */
493 3
    private function extractEmails($emailsData)
494
    {
495 3
        $emails = null;
496 3
        if (empty($emailsData) === false) {
497 3
            if (is_array($emailsData) === true) {
498 1
                foreach ($emailsData as $key => $email) {
499 1
                    if (is_int($key) === true) {
500 1
                        $emails[] = $email;
501 1
                    } else {
502 1
                        if (preg_match('/[.,:]/', $email) > 0) {
503 1
                            $email = '"'. $email .'"';
504 1
                        }
505 1
                        $emails[] = $email . ' ' . '<' . $key . '>';
506
                    }
507 1
                }
508 1
                $emails = implode(', ', $emails);
509 3
            } elseif (is_string($emailsData) === true) {
510 3
                $emails = $emailsData;
511 3
            }
512 3
        }
513 3
        return $emails;
514
    }
515
516
517
}