This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
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-2017 Philippe Gaultier |
||
9 | * @license http://www.sweelix.net/license license |
||
10 | * @version XXX |
||
11 | * @link http://www.sweelix.net |
||
12 | * @package sweelix\sendgrid |
||
13 | */ |
||
14 | |||
15 | namespace sweelix\sendgrid; |
||
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-2017 Philippe Gaultier |
||
31 | * @license http://www.sweelix.net/license license |
||
32 | * @version XXX |
||
33 | * @link http://www.sweelix.net |
||
34 | * @package sweelix\sendgrid |
||
35 | * @since XXX |
||
36 | */ |
||
37 | class Message extends BaseMessage |
||
38 | { |
||
39 | /** |
||
40 | * @var string|array from |
||
41 | */ |
||
42 | protected $from; |
||
43 | |||
44 | /** |
||
45 | * @var array |
||
46 | */ |
||
47 | protected $to = []; |
||
48 | |||
49 | /** |
||
50 | * @var string|array 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 temporary attachment directory |
||
86 | */ |
||
87 | protected $attachmentsTmdDir; |
||
88 | |||
89 | /** |
||
90 | * @var array |
||
91 | */ |
||
92 | protected $uniqueArguments = []; |
||
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 array substitution pairs used to mark expandable vars in template mode https://github.com/sendgrid/sendgrid-php#setsubstitutions |
||
111 | */ |
||
112 | public $substitutionsPairs = ['{', '}']; |
||
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 | $fromMail = null; |
|
136 | 1 | reset($this->from); |
|
137 | 1 | list($email, $name) = each($this->from); |
|
138 | 1 | if (is_numeric($email) === true) { |
|
139 | 1 | $fromMail = $name; |
|
140 | 1 | } else { |
|
141 | 1 | $fromMail = $email; |
|
142 | } |
||
143 | 1 | return $fromMail; |
|
144 | } |
||
145 | |||
146 | /** |
||
147 | * @return string|null extract and return the name associated with from |
||
148 | * @since XXX |
||
149 | */ |
||
150 | 1 | public function getFromName() |
|
151 | { |
||
152 | 1 | reset($this->from); |
|
153 | 1 | list($email, $name) = each($this->from); |
|
154 | 1 | if (is_numeric($email) === false) { |
|
155 | 1 | return $name; |
|
156 | } else { |
||
157 | return null; |
||
158 | } |
||
159 | } |
||
160 | |||
161 | /** |
||
162 | * @inheritdoc |
||
163 | */ |
||
164 | 3 | public function setFrom($from) |
|
165 | { |
||
166 | 3 | if (is_string($from) === true) { |
|
167 | 3 | $from = [$from]; |
|
168 | 3 | } |
|
169 | 3 | $this->from = $from; |
|
170 | 3 | return $this; |
|
171 | } |
||
172 | |||
173 | /** |
||
174 | * @inheritdoc |
||
175 | */ |
||
176 | 3 | public function getTo() |
|
177 | { |
||
178 | 3 | return self::normalizeEmails($this->to); |
|
179 | } |
||
180 | |||
181 | /** |
||
182 | * @inheritdoc |
||
183 | */ |
||
184 | 3 | public function setTo($to) |
|
185 | { |
||
186 | 3 | $this->to = $to; |
|
0 ignored issues
–
show
|
|||
187 | 3 | return $this; |
|
188 | } |
||
189 | |||
190 | /** |
||
191 | * @inheritdoc |
||
192 | */ |
||
193 | 1 | public function getReplyTo() |
|
194 | { |
||
195 | 1 | $replyTo = null; |
|
196 | 1 | if (is_array($this->replyTo) === true) { |
|
197 | 1 | reset($this->replyTo); |
|
198 | 1 | list($email, $name) = each($this->replyTo); |
|
199 | 1 | if (is_numeric($email) === true) { |
|
200 | 1 | $replyTo = $name; |
|
201 | 1 | } else { |
|
202 | 1 | $replyTo = $email; |
|
203 | } |
||
204 | 1 | } |
|
205 | 1 | return $replyTo; |
|
206 | } |
||
207 | |||
208 | /** |
||
209 | * @inheritdoc |
||
210 | */ |
||
211 | 1 | public function setReplyTo($replyTo) |
|
212 | { |
||
213 | 1 | if (is_string($replyTo) === true) { |
|
214 | 1 | $replyTo = [$replyTo]; |
|
215 | 1 | } |
|
216 | 1 | $this->replyTo = $replyTo; |
|
217 | 1 | return $this; |
|
218 | } |
||
219 | |||
220 | /** |
||
221 | * @inheritdoc |
||
222 | */ |
||
223 | 1 | public function getCc() |
|
224 | { |
||
225 | 1 | return $this->cc; |
|
226 | } |
||
227 | |||
228 | /** |
||
229 | * @inheritdoc |
||
230 | */ |
||
231 | 1 | public function setCc($cc) |
|
232 | { |
||
233 | 1 | $this->cc = self::normalizeEmails($cc); |
|
0 ignored issues
–
show
It seems like
self::normalizeEmails($cc) of type null is incompatible with the declared type array of property $cc .
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.. ![]() Are you sure the assignment to
$this->cc is correct as self::normalizeEmails($cc) (which targets sweelix\sendgrid\Message::normalizeEmails() ) seems to always return null.
This check looks for function or method calls that always return null and whose return value is assigned to a variable. class A
{
function getObject()
{
return null;
}
}
$a = new A();
$object = $a->getObject();
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||
234 | 1 | return $this; |
|
235 | } |
||
236 | |||
237 | /** |
||
238 | * @inheritdoc |
||
239 | */ |
||
240 | 1 | public function getBcc() |
|
241 | { |
||
242 | 1 | return $this->bcc; |
|
243 | } |
||
244 | |||
245 | /** |
||
246 | * @inheritdoc |
||
247 | */ |
||
248 | 1 | public function setBcc($bcc) |
|
249 | { |
||
250 | 1 | $this->bcc = self::normalizeEmails($bcc); |
|
0 ignored issues
–
show
It seems like
self::normalizeEmails($bcc) of type null is incompatible with the declared type array of property $bcc .
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.. ![]() Are you sure the assignment to
$this->bcc is correct as self::normalizeEmails($bcc) (which targets sweelix\sendgrid\Message::normalizeEmails() ) seems to always return null.
This check looks for function or method calls that always return null and whose return value is assigned to a variable. class A
{
function getObject()
{
return null;
}
}
$a = new A();
$object = $a->getObject();
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||
251 | 1 | return $this; |
|
252 | } |
||
253 | |||
254 | /** |
||
255 | * @inheritdoc |
||
256 | */ |
||
257 | 3 | public function getSubject() |
|
258 | { |
||
259 | 3 | return $this->subject; |
|
260 | } |
||
261 | |||
262 | /** |
||
263 | * @inheritdoc |
||
264 | */ |
||
265 | 2 | public function setSubject($subject) |
|
266 | { |
||
267 | 2 | $this->subject = $subject; |
|
268 | 2 | return $this; |
|
269 | } |
||
270 | |||
271 | /** |
||
272 | * @return string|null text body of the message |
||
273 | * @since XXX |
||
274 | */ |
||
275 | 1 | public function getTextBody() |
|
276 | { |
||
277 | 1 | return $this->textBody; |
|
278 | } |
||
279 | |||
280 | /** |
||
281 | * @inheritdoc |
||
282 | */ |
||
283 | 2 | public function setTextBody($text) |
|
284 | { |
||
285 | 2 | $this->textBody = $text; |
|
286 | 2 | return $this; |
|
287 | } |
||
288 | |||
289 | /** |
||
290 | * @return string|null html body of the message |
||
291 | * @since XXX |
||
292 | */ |
||
293 | 1 | public function getHtmlBody() |
|
294 | { |
||
295 | 1 | return $this->htmlBody; |
|
296 | } |
||
297 | |||
298 | /** |
||
299 | * @inheritdoc |
||
300 | */ |
||
301 | 1 | public function setHtmlBody($html) |
|
302 | { |
||
303 | 1 | $this->htmlBody = $html; |
|
304 | 1 | return $this; |
|
305 | } |
||
306 | |||
307 | /** |
||
308 | * @return array list of unique arguments attached to the email |
||
309 | * @since XXX |
||
310 | */ |
||
311 | public function getUniqueArguments() |
||
312 | { |
||
313 | return $this->uniqueArguments; |
||
314 | } |
||
315 | |||
316 | /** |
||
317 | * @param string $key key of the unique argument |
||
318 | * @param string $value value of the unique argument which will be added to the mail |
||
319 | * @return $this |
||
320 | * @since XXX |
||
321 | */ |
||
322 | public function addUniqueArgument($key, $value) |
||
323 | { |
||
324 | $this->uniqueArguments[$key] = $value; |
||
325 | return $this; |
||
326 | } |
||
327 | |||
328 | /** |
||
329 | * @param string $templateId template Id used. in this case, Subject / HtmlBody / TextBody are discarded |
||
330 | * @return $this |
||
331 | * @since XXX |
||
332 | */ |
||
333 | 2 | public function setTemplateId($templateId) |
|
334 | { |
||
335 | 2 | $this->templateId = $templateId; |
|
336 | 2 | return $this; |
|
337 | } |
||
338 | |||
339 | /** |
||
340 | * @return string|null current templateId |
||
341 | * @since XXX |
||
342 | */ |
||
343 | 1 | public function getTemplateId() |
|
344 | { |
||
345 | 1 | return $this->templateId; |
|
346 | } |
||
347 | |||
348 | /** |
||
349 | * @param array $templateModel model associated with the template |
||
350 | * @return $this |
||
351 | * @since XXX |
||
352 | */ |
||
353 | 2 | public function setTemplateModel($templateModel) |
|
354 | { |
||
355 | 2 | $this->templateModel = $templateModel; |
|
356 | 2 | return $this; |
|
357 | } |
||
358 | |||
359 | /** |
||
360 | * @return array current template model |
||
361 | * @since XXX |
||
362 | */ |
||
363 | 1 | public function getTemplateModel() |
|
364 | { |
||
365 | 1 | $templateModel = []; |
|
366 | 1 | list($left, $right) = $this->substitutionsPairs; |
|
367 | 1 | foreach ($this->templateModel as $key => $value) { |
|
368 | 1 | if (is_array($value) === false) { |
|
369 | 1 | $value = [$value]; |
|
370 | 1 | } |
|
371 | 1 | $templateModel[$left.$key.$right] = $value; |
|
372 | 1 | } |
|
373 | 1 | return $templateModel; |
|
374 | } |
||
375 | |||
376 | /** |
||
377 | * @param array $header add custom header to the mail |
||
378 | * @since XXX |
||
379 | */ |
||
380 | 1 | public function addHeader($header) |
|
381 | { |
||
382 | 1 | $this->headers[] = $header; |
|
383 | 1 | } |
|
384 | |||
385 | /** |
||
386 | * @return array|null headers which should be added to the mail |
||
387 | * @since XXX |
||
388 | */ |
||
389 | 1 | public function getHeaders() |
|
390 | { |
||
391 | 1 | return empty($this->headers) ? [] : $this->headers; |
|
392 | } |
||
393 | |||
394 | /** |
||
395 | * @return array|null list of attachments |
||
396 | * @since XXX |
||
397 | */ |
||
398 | 1 | public function getAttachments() |
|
399 | { |
||
400 | 1 | return empty($this->attachments) ? [] : $this->attachments; |
|
401 | } |
||
402 | |||
403 | /** |
||
404 | * @inheritdoc |
||
405 | */ |
||
406 | 1 | public function attach($fileName, array $options = []) |
|
407 | { |
||
408 | $attachment = [ |
||
409 | 'File' => $fileName |
||
410 | 1 | ]; |
|
411 | 1 | if (!empty($options['fileName'])) { |
|
412 | 1 | $attachment['Name'] = $options['fileName']; |
|
413 | 1 | } else { |
|
414 | 1 | $attachment['Name'] = pathinfo($fileName, PATHINFO_BASENAME); |
|
415 | } |
||
416 | 1 | $this->attachments[] = $attachment; |
|
417 | 1 | return $this; |
|
418 | } |
||
419 | |||
420 | /** |
||
421 | * @return string temporary directory to store contents |
||
422 | * @since XXX |
||
423 | * @throws InvalidConfigException |
||
424 | */ |
||
425 | 1 | protected function getTempDir() |
|
426 | { |
||
427 | 1 | if ($this->attachmentsTmdDir === null) { |
|
428 | 1 | $uid = uniqid(); |
|
429 | 1 | $this->attachmentsTmdDir = Yii::getAlias('@app/runtime/'.$uid.'/'); |
|
0 ignored issues
–
show
It seems like
\Yii::getAlias('@app/runtime/' . $uid . '/') can also be of type boolean . However, the property $attachmentsTmdDir 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 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;
}
![]() |
|||
430 | 1 | $status = true; |
|
431 | 1 | if (file_exists($this->attachmentsTmdDir) === false) { |
|
432 | 1 | $status = mkdir($this->attachmentsTmdDir, 0755, true); |
|
433 | 1 | } |
|
434 | 1 | if ($status === false) { |
|
435 | throw new InvalidConfigException('Directory \''.$this->attachmentsTmdDir.'\' cannot be created'); |
||
436 | } |
||
437 | 1 | } |
|
438 | 1 | return $this->attachmentsTmdDir; |
|
439 | } |
||
440 | |||
441 | /** |
||
442 | * @inheritdoc |
||
443 | */ |
||
444 | 2 | public function attachContent($content, array $options = []) |
|
445 | { |
||
446 | 2 | if (!isset($options['fileName']) || empty($options['fileName'])) { |
|
447 | 1 | throw new InvalidParamException('Filename is missing'); |
|
448 | } |
||
449 | 1 | $filePath = $this->getTempDir().'/'.$options['fileName']; |
|
450 | 1 | if (file_put_contents($filePath, $content) === false) { |
|
451 | throw new InvalidConfigException('Cannot write file \''.$filePath.'\''); |
||
452 | } |
||
453 | 1 | $this->attach($filePath, $options); |
|
454 | 1 | return $this; |
|
455 | } |
||
456 | |||
457 | /** |
||
458 | * @inheritdoc |
||
459 | */ |
||
460 | 1 | public function embed($fileName, array $options = []) |
|
461 | { |
||
462 | $embed = [ |
||
463 | 'File' => $fileName |
||
464 | 1 | ]; |
|
465 | 1 | if (!empty($options['fileName'])) { |
|
466 | 1 | $embed['Name'] = $options['fileName']; |
|
467 | 1 | } else { |
|
468 | 1 | $embed['Name'] = pathinfo($fileName, PATHINFO_BASENAME); |
|
469 | } |
||
470 | 1 | $embed['ContentID'] = 'cid:' . uniqid(); |
|
471 | 1 | $this->attachments[] = $embed; |
|
472 | 1 | return $embed['ContentID']; |
|
473 | } |
||
474 | |||
475 | /** |
||
476 | * @inheritdoc |
||
477 | */ |
||
478 | 1 | public function embedContent($content, array $options = []) |
|
479 | { |
||
480 | 1 | if (isset($options['fileName']) === false || empty($options['fileName'])) { |
|
481 | 1 | throw new InvalidParamException('fileName is missing'); |
|
482 | } |
||
483 | $filePath = $this->getTempDir().'/'.$options['fileName']; |
||
484 | if (file_put_contents($filePath, $content) === false) { |
||
485 | throw new InvalidConfigException('Cannot write file \''.$filePath.'\''); |
||
486 | } |
||
487 | $cid = $this->embed($filePath, $options); |
||
488 | return $cid; |
||
489 | } |
||
490 | |||
491 | /** |
||
492 | * @inheritdoc |
||
493 | * @todo make real serialization to make message compliant with PostmarkAPI |
||
494 | */ |
||
495 | public function toString() |
||
496 | { |
||
497 | return serialize($this); |
||
498 | } |
||
499 | |||
500 | |||
501 | /** |
||
502 | * @param array|string $emailsData email can be defined as string. In this case no transformation is done |
||
503 | * or as an array ['[email protected]', '[email protected]' => 'Email 2'] |
||
504 | * @return string|null |
||
505 | * @since XXX |
||
506 | */ |
||
507 | public static function stringifyEmails($emailsData) |
||
508 | { |
||
509 | $emails = null; |
||
510 | if (empty($emailsData) === false) { |
||
511 | if (is_array($emailsData) === true) { |
||
512 | foreach ($emailsData as $key => $email) { |
||
513 | if (is_int($key) === true) { |
||
514 | $emails[] = $email; |
||
515 | } else { |
||
516 | if (preg_match('/[.,:]/', $email) > 0) { |
||
517 | $email = '"'. $email .'"'; |
||
518 | } |
||
519 | $emails[] = $email . ' ' . '<' . $key . '>'; |
||
520 | } |
||
521 | } |
||
522 | $emails = implode(', ', $emails); |
||
523 | } elseif (is_string($emailsData) === true) { |
||
524 | $emails = $emailsData; |
||
525 | } |
||
526 | } |
||
527 | return $emails; |
||
528 | } |
||
529 | |||
530 | 3 | public static function normalizeEmails($emailsData) |
|
531 | { |
||
532 | 3 | $emails = null; |
|
533 | 3 | if (empty($emailsData) === false) { |
|
534 | 3 | if (is_array($emailsData) === true) { |
|
535 | 1 | foreach ($emailsData as $key => $email) { |
|
536 | 1 | if (is_int($key) === true) { |
|
537 | 1 | $emails[$email] = null; |
|
538 | 1 | } else { |
|
539 | 1 | $emails[$key] = $email; |
|
540 | } |
||
541 | 1 | } |
|
542 | 3 | } elseif (is_string($emailsData) === true) { |
|
543 | 3 | $emails[$emailsData] = null; |
|
544 | 3 | } |
|
545 | 3 | } |
|
546 | 3 | return $emails; |
|
547 | } |
||
548 | |||
549 | 2 | public function send(MailerInterface $mailer = null) |
|
550 | { |
||
551 | 2 | $result = parent::send($mailer); |
|
552 | if ($this->attachmentsTmdDir !== null) { |
||
553 | //TODO: clean up tmpdir after ourselves |
||
554 | } |
||
555 | return $result; |
||
556 | } |
||
557 | |||
558 | |||
559 | } |
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 theid
property of an instance of theAccount
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.