| Total Complexity | 123 |
| Total Lines | 1224 |
| Duplicated Lines | 0 % |
| Changes | 5 | ||
| Bugs | 0 | Features | 0 |
Complex classes like Email often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Email, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 31 | class Email extends BaseClass{ |
||
| 32 | /** |
||
| 33 | * @var int $wrap |
||
| 34 | */ |
||
| 35 | protected $wrap = 78; |
||
| 36 | |||
| 37 | /** |
||
| 38 | * @var string |
||
| 39 | */ |
||
| 40 | protected $from; |
||
| 41 | |||
| 42 | /** |
||
| 43 | * @var array $to |
||
| 44 | */ |
||
| 45 | protected $to = array(); |
||
| 46 | |||
| 47 | /** |
||
| 48 | * @var array $cc |
||
| 49 | */ |
||
| 50 | protected $cc = array(); |
||
| 51 | |||
| 52 | /** |
||
| 53 | * @var array $bcc |
||
| 54 | */ |
||
| 55 | protected $bcc = array(); |
||
| 56 | |||
| 57 | /** |
||
| 58 | * @var string |
||
| 59 | */ |
||
| 60 | protected $replyTo; |
||
| 61 | |||
| 62 | /** |
||
| 63 | * @var string $subject |
||
| 64 | */ |
||
| 65 | protected $subject; |
||
| 66 | |||
| 67 | /** |
||
| 68 | * @var string $message |
||
| 69 | */ |
||
| 70 | protected $message; |
||
| 71 | |||
| 72 | /** |
||
| 73 | * @var array $headers |
||
| 74 | */ |
||
| 75 | protected $headers = array(); |
||
| 76 | |||
| 77 | /** |
||
| 78 | * @var string $parameters |
||
| 79 | */ |
||
| 80 | protected $params; |
||
| 81 | |||
| 82 | /** |
||
| 83 | * @var array $attachments |
||
| 84 | */ |
||
| 85 | protected $attachments = array(); |
||
| 86 | |||
| 87 | /** |
||
| 88 | * @var string $uid |
||
| 89 | */ |
||
| 90 | protected $uid; |
||
| 91 | |||
| 92 | /** |
||
| 93 | * Send mail protocol, current supported values are: |
||
| 94 | * "mail", "smtp" |
||
| 95 | * @var string |
||
| 96 | */ |
||
| 97 | protected $protocol = 'mail'; |
||
| 98 | |||
| 99 | /** |
||
| 100 | * Send mail transport, current supported values are: |
||
| 101 | * "tls", "plain" |
||
| 102 | * @var string |
||
| 103 | */ |
||
| 104 | protected $transport = 'plain'; |
||
| 105 | |||
| 106 | /** |
||
| 107 | * SMTP connection socket |
||
| 108 | * @var resource |
||
| 109 | */ |
||
| 110 | protected $smtpSocket; |
||
| 111 | |||
| 112 | /** |
||
| 113 | * SMTP server hostname |
||
| 114 | * @var string |
||
| 115 | */ |
||
| 116 | protected $smtpHostname = 'localhost'; |
||
| 117 | |||
| 118 | /** |
||
| 119 | * SMTP server port |
||
| 120 | * @var integer |
||
| 121 | */ |
||
| 122 | protected $smtpPort = 25; |
||
| 123 | |||
| 124 | /** |
||
| 125 | * SMTP authentication username |
||
| 126 | * @var string |
||
| 127 | */ |
||
| 128 | protected $smtpUsername; |
||
| 129 | |||
| 130 | /** |
||
| 131 | * SMTP authentication password |
||
| 132 | * @var string |
||
| 133 | */ |
||
| 134 | protected $smtpPassword; |
||
| 135 | |||
| 136 | /** |
||
| 137 | * SMTP server connection timeout (second) |
||
| 138 | * @var integer |
||
| 139 | */ |
||
| 140 | protected $smtpConnectionTimeout = 30; |
||
| 141 | |||
| 142 | /** |
||
| 143 | * SMTP server response timeout (second) |
||
| 144 | * @var integer |
||
| 145 | */ |
||
| 146 | protected $smtpResponseTimeout = 10; |
||
| 147 | |||
| 148 | /** |
||
| 149 | * The last SMTP response string |
||
| 150 | * @var string |
||
| 151 | */ |
||
| 152 | protected $smtpResponse; |
||
| 153 | |||
| 154 | /** |
||
| 155 | * The last sending mail error |
||
| 156 | * @var string|null |
||
| 157 | */ |
||
| 158 | protected $error = null; |
||
| 159 | |||
| 160 | /** |
||
| 161 | * The log for sending mail |
||
| 162 | * @var array |
||
| 163 | */ |
||
| 164 | protected $logs = array(); |
||
| 165 | |||
| 166 | |||
| 167 | /** |
||
| 168 | * __construct |
||
| 169 | * |
||
| 170 | * Resets the class properties. |
||
| 171 | */ |
||
| 172 | public function __construct() { |
||
| 173 | parent::__construct(); |
||
| 174 | $this->reset(); |
||
| 175 | } |
||
| 176 | |||
| 177 | /** |
||
| 178 | * reset |
||
| 179 | * |
||
| 180 | * Resets all properties to initial state. |
||
| 181 | * |
||
| 182 | * @return object |
||
| 183 | */ |
||
| 184 | public function reset() { |
||
| 185 | $this->from = null; |
||
| 186 | $this->to = array(); |
||
| 187 | $this->cc = array(); |
||
| 188 | $this->bcc = array(); |
||
| 189 | $this->replyTo = null; |
||
| 190 | $this->headers = array(); |
||
| 191 | $this->subject = null; |
||
| 192 | $this->message = null; |
||
| 193 | $this->wrap = 78; |
||
| 194 | $this->params = null; |
||
| 195 | $this->attachments = array(); |
||
| 196 | $this->logs = array(); |
||
| 197 | $this->error = null; |
||
| 198 | $this->uid = $this->getUniqueId(); |
||
| 199 | $this->smtpResponse = null; |
||
| 200 | return $this; |
||
| 201 | } |
||
| 202 | |||
| 203 | /** |
||
| 204 | * setFrom |
||
| 205 | * |
||
| 206 | * @param string $email The email to send as from. |
||
| 207 | * @param string $name The name to send as from. |
||
| 208 | * |
||
| 209 | * @return object |
||
| 210 | */ |
||
| 211 | public function setFrom($email, $name = null) { |
||
| 212 | $this->addMailHeader('From', (string) $email, (string) $name); |
||
| 213 | $this->from = $this->formatHeader($email, $name); |
||
| 214 | return $this; |
||
| 215 | } |
||
| 216 | |||
| 217 | /** |
||
| 218 | * setTo |
||
| 219 | * |
||
| 220 | * @param string $email The email address to send to. |
||
| 221 | * @param string $name The name of the person to send to. |
||
| 222 | * |
||
| 223 | * @return object |
||
| 224 | */ |
||
| 225 | public function setTo($email, $name = null) { |
||
| 226 | $this->to[] = $this->formatHeader((string) $email, (string) $name); |
||
| 227 | return $this; |
||
| 228 | } |
||
| 229 | |||
| 230 | /** |
||
| 231 | * Set destination using array |
||
| 232 | * @params array $emails the list of recipient. This is an |
||
| 233 | * associative array name => email |
||
| 234 | * @example array('John Doe' => '[email protected]') |
||
| 235 | * |
||
| 236 | * @return object the current instance |
||
| 237 | */ |
||
| 238 | public function setTos(array $emails) { |
||
| 239 | foreach ($emails as $name => $email) { |
||
| 240 | if (is_numeric($name)) { |
||
| 241 | $this->setTo($email); |
||
| 242 | } else { |
||
| 243 | $this->setTo($email, $name); |
||
| 244 | } |
||
| 245 | } |
||
| 246 | return $this; |
||
| 247 | } |
||
| 248 | |||
| 249 | /** |
||
| 250 | * getTo |
||
| 251 | * |
||
| 252 | * Return an array of formatted To addresses. |
||
| 253 | * |
||
| 254 | * @return array |
||
| 255 | */ |
||
| 256 | public function getTo() { |
||
| 257 | return $this->to; |
||
| 258 | } |
||
| 259 | |||
| 260 | /** |
||
| 261 | * setCc |
||
| 262 | * |
||
| 263 | * @param array $pairs An array of name => email pairs. |
||
| 264 | * @example array('John Doe' => '[email protected]') |
||
| 265 | * @return object |
||
| 266 | */ |
||
| 267 | public function setCc(array $pairs) { |
||
| 268 | $this->cc = $pairs; |
||
| 269 | return $this->addMailHeaders('Cc', $pairs); |
||
| 270 | } |
||
| 271 | |||
| 272 | /** |
||
| 273 | * Return the list of Cc |
||
| 274 | * |
||
| 275 | * @return array |
||
| 276 | */ |
||
| 277 | public function getCc() { |
||
| 278 | return $this->cc; |
||
| 279 | } |
||
| 280 | |||
| 281 | /** |
||
| 282 | * setBcc |
||
| 283 | * |
||
| 284 | * @param array $pairs An array of name => email pairs. |
||
| 285 | * @example array('John Doe' => '[email protected]') |
||
| 286 | * |
||
| 287 | * @return object |
||
| 288 | */ |
||
| 289 | public function setBcc(array $pairs) { |
||
| 290 | $this->bcc = $pairs; |
||
| 291 | return $this->addMailHeaders('Bcc', $pairs); |
||
| 292 | } |
||
| 293 | |||
| 294 | /** |
||
| 295 | * Return the list of Bcc |
||
| 296 | * |
||
| 297 | * @return array |
||
| 298 | */ |
||
| 299 | public function getBcc() { |
||
| 300 | return $this->bcc; |
||
| 301 | } |
||
| 302 | |||
| 303 | /** |
||
| 304 | * setReplyTo |
||
| 305 | * |
||
| 306 | * @param string $email |
||
| 307 | * @param string $name |
||
| 308 | * |
||
| 309 | * @return object |
||
| 310 | */ |
||
| 311 | public function setReplyTo($email, $name = null) { |
||
| 312 | $this->replyTo = $this->formatHeader($email, $name); |
||
| 313 | return $this->addMailHeader('Reply-To', $email, $name); |
||
| 314 | } |
||
| 315 | |||
| 316 | /** |
||
| 317 | * setHtml |
||
| 318 | * |
||
| 319 | * @return object |
||
| 320 | */ |
||
| 321 | public function setHtml() { |
||
| 322 | $this->addGenericHeader('Content-Type', 'text/html; charset="utf-8"'); |
||
| 323 | return $this; |
||
| 324 | } |
||
| 325 | |||
| 326 | /** |
||
| 327 | * setSubject |
||
| 328 | * |
||
| 329 | * @param string $subject The email subject |
||
| 330 | * |
||
| 331 | * @return object |
||
| 332 | */ |
||
| 333 | public function setSubject($subject) { |
||
| 334 | $this->subject = $this->encodeUtf8( |
||
| 335 | $this->filterOther((string) $subject)); |
||
| 336 | return $this; |
||
| 337 | } |
||
| 338 | |||
| 339 | /** |
||
| 340 | * getSubject function. |
||
| 341 | * |
||
| 342 | * @return string |
||
| 343 | */ |
||
| 344 | public function getSubject() { |
||
| 345 | return $this->subject; |
||
| 346 | } |
||
| 347 | |||
| 348 | /** |
||
| 349 | * setMessage |
||
| 350 | * |
||
| 351 | * @param string $message The message to send. |
||
| 352 | * |
||
| 353 | * @return object |
||
| 354 | */ |
||
| 355 | public function setMessage($message) { |
||
| 356 | $this->message = str_replace("\n.", "\n..", (string) $message); |
||
| 357 | return $this; |
||
| 358 | } |
||
| 359 | |||
| 360 | /** |
||
| 361 | * getMessage |
||
| 362 | * |
||
| 363 | * @return string |
||
| 364 | */ |
||
| 365 | public function getMessage() { |
||
| 366 | return $this->message; |
||
| 367 | } |
||
| 368 | |||
| 369 | /** |
||
| 370 | * addAttachment |
||
| 371 | * |
||
| 372 | * @param string $path The file path to the attachment. |
||
| 373 | * @param string $filename The filename of the attachment when emailed. |
||
| 374 | * @param string $data |
||
| 375 | * |
||
| 376 | * @return object |
||
| 377 | */ |
||
| 378 | public function addAttachment($path, $filename = null, $data = null) { |
||
| 379 | if (!file_exists($path)) { |
||
| 380 | show_error('The file [' . $path . '] does not exists.'); |
||
| 381 | return $this; |
||
| 382 | } |
||
| 383 | if (empty($filename)) { |
||
| 384 | $filename = basename($path); |
||
| 385 | } |
||
| 386 | $filename = $this->encodeUtf8($this->filterOther((string) $filename)); |
||
| 387 | if (empty($data)) { |
||
| 388 | $data = $this->getAttachmentData($path); |
||
| 389 | } |
||
| 390 | $this->attachments[] = array( |
||
| 391 | 'path' => $path, |
||
| 392 | 'file' => $filename, |
||
| 393 | 'data' => chunk_split(base64_encode($data)) |
||
| 394 | ); |
||
| 395 | return $this; |
||
| 396 | } |
||
| 397 | |||
| 398 | /** |
||
| 399 | * addMailHeader |
||
| 400 | * |
||
| 401 | * @param string $header The header to add. |
||
| 402 | * @param string $email The email to add. |
||
| 403 | * @param string $name The name to add. |
||
| 404 | * |
||
| 405 | * @return object |
||
| 406 | */ |
||
| 407 | public function addMailHeader($header, $email, $name = null) { |
||
| 408 | $address = $this->formatHeader((string) $email, (string) $name); |
||
| 409 | $this->headers[$header] = $address; |
||
| 410 | return $this; |
||
| 411 | } |
||
| 412 | |||
| 413 | /** |
||
| 414 | * addMailHeaders |
||
| 415 | * |
||
| 416 | * @param string $header The header to add. |
||
| 417 | * @param array $pairs An array of name => email pairs. |
||
| 418 | * |
||
| 419 | * @return object |
||
| 420 | */ |
||
| 421 | public function addMailHeaders($header, array $pairs) { |
||
| 422 | if (count($pairs) === 0) { |
||
| 423 | show_error('You must pass at least one name => email pair.'); |
||
| 424 | return $this; |
||
| 425 | } |
||
| 426 | $addresses = array(); |
||
| 427 | foreach ($pairs as $name => $email) { |
||
| 428 | if (is_numeric($name)) { |
||
| 429 | $name = null; |
||
| 430 | } |
||
| 431 | $addresses[] = $this->formatHeader($email, $name); |
||
| 432 | } |
||
| 433 | $this->addGenericHeader($header, implode(',', $addresses)); |
||
| 434 | return $this; |
||
| 435 | } |
||
| 436 | |||
| 437 | /** |
||
| 438 | * addGenericHeader |
||
| 439 | * |
||
| 440 | * @param string $name The generic header to add. |
||
| 441 | * @param mixed $value The value of the header. |
||
| 442 | * |
||
| 443 | * @return object |
||
| 444 | */ |
||
| 445 | public function addGenericHeader($name, $value) { |
||
| 446 | $this->headers[$name] = $value; |
||
| 447 | return $this; |
||
| 448 | } |
||
| 449 | |||
| 450 | /** |
||
| 451 | * getHeaders |
||
| 452 | * |
||
| 453 | * Return the headers registered so far as an array. |
||
| 454 | * |
||
| 455 | * @return array |
||
| 456 | */ |
||
| 457 | public function getHeaders() { |
||
| 458 | return $this->headers; |
||
| 459 | } |
||
| 460 | |||
| 461 | /** |
||
| 462 | * setAdditionalParameters |
||
| 463 | * |
||
| 464 | * Such as "[email protected] |
||
| 465 | * |
||
| 466 | * @param string $additionalParameters The addition mail parameter. |
||
| 467 | * |
||
| 468 | * @return object |
||
| 469 | */ |
||
| 470 | public function setParameters($additionalParameters) { |
||
| 471 | $this->params = (string) $additionalParameters; |
||
| 472 | return $this; |
||
| 473 | } |
||
| 474 | |||
| 475 | /** |
||
| 476 | * getAdditionalParameters |
||
| 477 | * |
||
| 478 | * @return string |
||
| 479 | */ |
||
| 480 | public function getParameters() { |
||
| 481 | return $this->params; |
||
| 482 | } |
||
| 483 | |||
| 484 | /** |
||
| 485 | * setWrap |
||
| 486 | * |
||
| 487 | * @param int $wrap The number of characters at which the message will wrap. |
||
| 488 | * |
||
| 489 | * @return object |
||
| 490 | */ |
||
| 491 | public function setWrap($wrap = 78) { |
||
| 492 | $wrap = (int) $wrap; |
||
| 493 | if ($wrap < 1) { |
||
| 494 | $wrap = 78; |
||
| 495 | } |
||
| 496 | $this->wrap = $wrap; |
||
| 497 | return $this; |
||
| 498 | } |
||
| 499 | |||
| 500 | /** |
||
| 501 | * getWrap |
||
| 502 | * |
||
| 503 | * @return int |
||
| 504 | */ |
||
| 505 | public function getWrap() { |
||
| 506 | return $this->wrap; |
||
| 507 | } |
||
| 508 | |||
| 509 | /** |
||
| 510 | * hasAttachments |
||
| 511 | * |
||
| 512 | * Checks if the email has any registered attachments. |
||
| 513 | * |
||
| 514 | * @return bool |
||
| 515 | */ |
||
| 516 | public function hasAttachments() { |
||
| 517 | return !empty($this->attachments); |
||
| 518 | } |
||
| 519 | |||
| 520 | /** |
||
| 521 | * getWrapMessage |
||
| 522 | * |
||
| 523 | * @return string |
||
| 524 | */ |
||
| 525 | public function getWrapMessage() { |
||
| 526 | return wordwrap($this->message, $this->wrap); |
||
| 527 | } |
||
| 528 | |||
| 529 | /** |
||
| 530 | * Return the send mail protocol |
||
| 531 | * @return string |
||
| 532 | */ |
||
| 533 | public function getProtocol() { |
||
| 534 | return $this->protocol; |
||
| 535 | } |
||
| 536 | |||
| 537 | /** |
||
| 538 | * Set the send mail protocol to "mail" |
||
| 539 | * |
||
| 540 | * @return object the current instance |
||
| 541 | */ |
||
| 542 | public function setProtocolMail() { |
||
| 543 | $this->protocol = 'mail'; |
||
| 544 | return $this; |
||
| 545 | } |
||
| 546 | |||
| 547 | /** |
||
| 548 | * Set the send mail protocol to "smtp" |
||
| 549 | * |
||
| 550 | * @return object the current instance |
||
| 551 | */ |
||
| 552 | public function setProtocolSmtp() { |
||
| 553 | $this->protocol = 'smtp'; |
||
| 554 | return $this; |
||
| 555 | } |
||
| 556 | |||
| 557 | /** |
||
| 558 | * Return the mail transport |
||
| 559 | * @return string |
||
| 560 | */ |
||
| 561 | public function getTransport() { |
||
| 562 | return $this->transport; |
||
| 563 | } |
||
| 564 | |||
| 565 | /** |
||
| 566 | * Set the send mail transport to "tls" |
||
| 567 | * |
||
| 568 | * @return object the current instance |
||
| 569 | */ |
||
| 570 | public function setTransportTls() { |
||
| 571 | $this->transport = 'tls'; |
||
| 572 | return $this; |
||
| 573 | } |
||
| 574 | |||
| 575 | /** |
||
| 576 | * Set the send mail transport to "plain" |
||
| 577 | * |
||
| 578 | * @return object the current instance |
||
| 579 | */ |
||
| 580 | public function setTransportPlain() { |
||
| 583 | } |
||
| 584 | |||
| 585 | /** |
||
| 586 | * Return the smtp server hostname |
||
| 587 | * @return string |
||
| 588 | */ |
||
| 589 | public function getSmtpHostname() { |
||
| 590 | return $this->smtpHostname; |
||
| 591 | } |
||
| 592 | |||
| 593 | /** |
||
| 594 | * Set the smtp server hostname |
||
| 595 | * @param string $smtpHostname |
||
| 596 | * |
||
| 597 | * @return object the current instance |
||
| 598 | */ |
||
| 599 | public function setSmtpHostname($smtpHostname) { |
||
| 602 | } |
||
| 603 | |||
| 604 | /** |
||
| 605 | * Return the smtp server port |
||
| 606 | * @return integer |
||
| 607 | */ |
||
| 608 | public function getSmtpPort() { |
||
| 609 | return $this->smtpPort; |
||
| 610 | } |
||
| 611 | |||
| 612 | /** |
||
| 613 | * Set the smtp server port |
||
| 614 | * @param integer $smtpPort |
||
| 615 | * |
||
| 616 | * @return object the current instance |
||
| 617 | */ |
||
| 618 | public function setSmtpPort($smtpPort) { |
||
| 619 | $this->smtpPort = $smtpPort; |
||
| 620 | return $this; |
||
| 621 | } |
||
| 622 | |||
| 623 | /** |
||
| 624 | * Return the smtp username |
||
| 625 | * @return string |
||
| 626 | */ |
||
| 627 | public function getSmtpUsername() { |
||
| 628 | return $this->smtpUsername; |
||
| 629 | } |
||
| 630 | |||
| 631 | /** |
||
| 632 | * Set the smtp username |
||
| 633 | * @param string $smtpUsername |
||
| 634 | * |
||
| 635 | * @return object the current instance |
||
| 636 | */ |
||
| 637 | public function setSmtpUsername($smtpUsername) { |
||
| 638 | $this->smtpUsername = $smtpUsername; |
||
| 639 | return $this; |
||
| 640 | } |
||
| 641 | |||
| 642 | /** |
||
| 643 | * Return the smtp password |
||
| 644 | * @return string |
||
| 645 | */ |
||
| 646 | public function getSmtpPassword() { |
||
| 647 | return $this->smtpPassword; |
||
| 648 | } |
||
| 649 | |||
| 650 | /** |
||
| 651 | * Set the smtp password |
||
| 652 | * @param string $smtpPassword |
||
| 653 | * |
||
| 654 | * @return object the current instance |
||
| 655 | */ |
||
| 656 | public function setSmtpPassword($smtpPassword) { |
||
| 657 | $this->smtpPassword = $smtpPassword; |
||
| 658 | return $this; |
||
| 659 | } |
||
| 660 | |||
| 661 | /** |
||
| 662 | * Return the smtp server connection timeout |
||
| 663 | * @return integer |
||
| 664 | */ |
||
| 665 | public function getSmtpConnectionTimeout() { |
||
| 666 | return $this->smtpConnectionTimeout; |
||
| 667 | } |
||
| 668 | |||
| 669 | /** |
||
| 670 | * Set the smtp server connection timeout |
||
| 671 | * @param integer $timeout |
||
| 672 | * |
||
| 673 | * @return object the current instance |
||
| 674 | */ |
||
| 675 | public function setSmtpConnectionTimeout($timeout) { |
||
| 676 | $this->smtpConnectionTimeout = $timeout; |
||
| 677 | return $this; |
||
| 678 | } |
||
| 679 | |||
| 680 | /** |
||
| 681 | * Return the smtp server response timeout |
||
| 682 | * @return integer |
||
| 683 | */ |
||
| 684 | public function getSmtpResponseTimeout() { |
||
| 685 | return $this->smtpResponseTimeout; |
||
| 686 | } |
||
| 687 | |||
| 688 | /** |
||
| 689 | * Set the smtp server response timeout |
||
| 690 | * @param integer $timeout |
||
| 691 | * |
||
| 692 | * @return object the current instance |
||
| 693 | */ |
||
| 694 | public function setSmtpResponseTimeout($timeout) { |
||
| 695 | $this->smtpResponseTimeout = $timeout; |
||
| 696 | return $this; |
||
| 697 | } |
||
| 698 | |||
| 699 | /** |
||
| 700 | * send the email |
||
| 701 | * |
||
| 702 | * @return boolean |
||
| 703 | */ |
||
| 704 | public function send() { |
||
| 705 | if (empty($this->to)) { |
||
| 706 | show_error('Unable to send mail, no destination address has been set.'); |
||
| 707 | return false; |
||
| 708 | } |
||
| 709 | if (empty($this->from)) { |
||
| 710 | show_error('Unable to send mail, no sender address has been set.'); |
||
| 711 | return false; |
||
| 712 | } |
||
| 713 | if ($this->protocol == 'mail') { |
||
| 714 | return $this->sendMail(); |
||
| 715 | } else if ($this->protocol == 'smtp') { |
||
| 716 | return $this->sendSmtp(); |
||
| 717 | } |
||
| 718 | return false; |
||
| 719 | } |
||
| 720 | |||
| 721 | |||
| 722 | /** |
||
| 723 | * Return the last error when sending mail |
||
| 724 | * @return string|null |
||
| 725 | */ |
||
| 726 | public function getError() { |
||
| 727 | return $this->error; |
||
| 728 | } |
||
| 729 | |||
| 730 | /** |
||
| 731 | * Return the sending mail logs content |
||
| 732 | * @return array |
||
| 733 | */ |
||
| 734 | public function getLogs() { |
||
| 735 | return $this->logs; |
||
| 736 | } |
||
| 737 | |||
| 738 | /** |
||
| 739 | * Debug |
||
| 740 | * @codeCoverageIgnore |
||
| 741 | * |
||
| 742 | * @return string |
||
| 743 | */ |
||
| 744 | public function debug() { |
||
| 745 | return '<pre>' . print_r($this->logs, true) . '</pre>'; |
||
| 746 | } |
||
| 747 | |||
| 748 | /** |
||
| 749 | * Get attachment data |
||
| 750 | * |
||
| 751 | * @param string $path The path to the attachment file. |
||
| 752 | * |
||
| 753 | * @return string|boolean |
||
| 754 | */ |
||
| 755 | protected function getAttachmentData($path) { |
||
| 756 | $filesize = filesize($path); |
||
| 757 | $handle = fopen($path, "r"); |
||
| 758 | $attachment = null; |
||
| 759 | if (is_resource($handle)) { |
||
| 760 | $attachment = fread($handle, $filesize); |
||
| 761 | fclose($handle); |
||
| 762 | } |
||
| 763 | return $attachment; |
||
| 764 | } |
||
| 765 | |||
| 766 | /** |
||
| 767 | * assembleAttachment |
||
| 768 | * |
||
| 769 | * @return object |
||
| 770 | */ |
||
| 771 | protected function setAttachmentHeaders() { |
||
| 772 | $this->headers['MIME-Version'] = '1.0'; |
||
| 773 | $this->headers['Content-Type'] = "multipart/mixed; boundary=\"{$this->uid}\""; |
||
| 774 | return $this; |
||
| 775 | } |
||
| 776 | |||
| 777 | /** |
||
| 778 | * assembleAttachmentBody |
||
| 779 | * |
||
| 780 | * @return string |
||
| 781 | */ |
||
| 782 | protected function assembleAttachmentBody() { |
||
| 783 | $body = array(); |
||
| 784 | $body[] = "This is a multi-part message in MIME format."; |
||
| 785 | $body[] = "--{$this->uid}"; |
||
| 786 | $body[] = "Content-Type: text/html; charset=\"utf-8\""; |
||
| 787 | $body[] = "Content-Transfer-Encoding: base64"; |
||
| 788 | $body[] = PHP_EOL; |
||
| 789 | $body[] = chunk_split(base64_encode($this->message)); |
||
| 790 | $body[] = PHP_EOL; |
||
| 791 | $body[] = "--{$this->uid}"; |
||
| 792 | |||
| 793 | foreach ($this->attachments as $attachment) { |
||
| 794 | $body[] = $this->getAttachmentMimeTemplate($attachment); |
||
| 795 | } |
||
| 796 | return implode(PHP_EOL, $body) . '--'; |
||
| 797 | } |
||
| 798 | |||
| 799 | /** |
||
| 800 | * getAttachmentMimeTemplate |
||
| 801 | * |
||
| 802 | * @param array $attachment An array containing 'file' and 'data' keys. |
||
| 803 | * |
||
| 804 | * @return string |
||
| 805 | */ |
||
| 806 | protected function getAttachmentMimeTemplate($attachment) { |
||
| 807 | $file = $attachment['file']; |
||
| 808 | $data = $attachment['data']; |
||
| 809 | |||
| 810 | $head = array(); |
||
| 811 | $head[] = "Content-Type: application/octet-stream; name=\"{$file}\""; |
||
| 812 | $head[] = "Content-Transfer-Encoding: base64"; |
||
| 813 | $head[] = "Content-Disposition: attachment; filename=\"{$file}\""; |
||
| 814 | $head[] = ""; |
||
| 815 | $head[] = $data; |
||
| 816 | $head[] = ""; |
||
| 817 | $head[] = "--{$this->uid}"; |
||
| 818 | |||
| 819 | return implode(PHP_EOL, $head); |
||
| 820 | } |
||
| 821 | |||
| 822 | /** |
||
| 823 | * formatHeader |
||
| 824 | * |
||
| 825 | * Formats a display address for emails according to RFC2822 e.g. |
||
| 826 | * Name <[email protected]> |
||
| 827 | * |
||
| 828 | * @param string $email The email address. |
||
| 829 | * @param string $name The display name. |
||
| 830 | * |
||
| 831 | * @return string |
||
| 832 | */ |
||
| 833 | protected function formatHeader($email, $name = null) { |
||
| 840 | } |
||
| 841 | |||
| 842 | /** |
||
| 843 | * encodeUtf8 |
||
| 844 | * |
||
| 845 | * @param string $value The value to encode. |
||
| 846 | * |
||
| 847 | * @return string |
||
| 848 | */ |
||
| 849 | protected function encodeUtf8($value) { |
||
| 850 | $value = trim($value); |
||
| 851 | if (preg_match('/(\s)/', $value)) { |
||
| 852 | return $this->encodeUtf8Words($value); |
||
| 853 | } |
||
| 854 | return $this->encodeUtf8Word($value); |
||
| 855 | } |
||
| 856 | |||
| 857 | /** |
||
| 858 | * encodeUtf8Word |
||
| 859 | * |
||
| 860 | * @param string $value The word to encode. |
||
| 861 | * |
||
| 862 | * @return string |
||
| 863 | */ |
||
| 864 | protected function encodeUtf8Word($value) { |
||
| 865 | return sprintf('=?UTF-8?B?%s?=', base64_encode($value)); |
||
| 866 | } |
||
| 867 | |||
| 868 | /** |
||
| 869 | * encodeUtf8Words |
||
| 870 | * |
||
| 871 | * @param string $value The words to encode. |
||
| 872 | * |
||
| 873 | * @return string |
||
| 874 | */ |
||
| 875 | protected function encodeUtf8Words($value) { |
||
| 876 | $words = explode(' ', $value); |
||
| 877 | $encoded = array(); |
||
| 878 | foreach ($words as $word) { |
||
| 879 | $encoded[] = $this->encodeUtf8Word($word); |
||
| 880 | } |
||
| 881 | return join($this->encodeUtf8Word(' '), $encoded); |
||
| 882 | } |
||
| 883 | |||
| 884 | /** |
||
| 885 | * filterEmail |
||
| 886 | * |
||
| 887 | * Removes any carriage return, line feed, tab, double quote, comma |
||
| 888 | * and angle bracket characters before sanitizing the email address. |
||
| 889 | * |
||
| 890 | * @param string $email The email to filter. |
||
| 891 | * |
||
| 892 | * @return string |
||
| 893 | */ |
||
| 894 | protected function filterEmail($email) { |
||
| 895 | $rule = array( |
||
| 896 | "\r" => '', |
||
| 897 | "\n" => '', |
||
| 898 | "\t" => '', |
||
| 899 | '"' => '', |
||
| 900 | ',' => '', |
||
| 901 | '<' => '', |
||
| 902 | '>' => '' |
||
| 903 | ); |
||
| 904 | $email = strtr($email, $rule); |
||
| 905 | $email = filter_var($email, FILTER_SANITIZE_EMAIL); |
||
| 906 | return $email; |
||
| 907 | } |
||
| 908 | |||
| 909 | /** |
||
| 910 | * filterName |
||
| 911 | * |
||
| 912 | * Removes any carriage return, line feed or tab characters. Replaces |
||
| 913 | * double quotes with single quotes and angle brackets with square |
||
| 914 | * brackets, before sanitizing the string and stripping out html tags. |
||
| 915 | * |
||
| 916 | * @param string $name The name to filter. |
||
| 917 | * |
||
| 918 | * @return string |
||
| 919 | */ |
||
| 920 | protected function filterName($name) { |
||
| 921 | $rule = array( |
||
| 922 | "\r" => '', |
||
| 923 | "\n" => '', |
||
| 924 | "\t" => '', |
||
| 925 | '"' => "'", |
||
| 926 | '<' => '[', |
||
| 927 | '>' => ']', |
||
| 928 | ); |
||
| 929 | $filtered = filter_var( |
||
| 930 | $name, |
||
| 931 | FILTER_SANITIZE_STRING, |
||
| 932 | FILTER_FLAG_NO_ENCODE_QUOTES |
||
| 933 | ); |
||
| 934 | return trim(strtr($filtered, $rule)); |
||
| 935 | } |
||
| 936 | |||
| 937 | /** |
||
| 938 | * filterOther |
||
| 939 | * |
||
| 940 | * Removes ASCII control characters including any carriage return, line |
||
| 941 | * feed or tab characters. |
||
| 942 | * |
||
| 943 | * @param string $data The data to filter. |
||
| 944 | * |
||
| 945 | * @return string |
||
| 946 | */ |
||
| 947 | protected function filterOther($data) { |
||
| 948 | return filter_var($data, FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW); |
||
| 949 | } |
||
| 950 | |||
| 951 | /** |
||
| 952 | * Get destinataire for send |
||
| 953 | * |
||
| 954 | * @return string |
||
| 955 | */ |
||
| 956 | protected function getToForSend() { |
||
| 958 | } |
||
| 959 | |||
| 960 | /** |
||
| 961 | * getHeadersForSend |
||
| 962 | * |
||
| 963 | * @return string |
||
| 964 | */ |
||
| 965 | protected function getHeadersForSend() { |
||
| 966 | $headers = null; |
||
| 967 | foreach ($this->headers as $key => $value) { |
||
| 968 | $headers .= $key . ': ' . $value . PHP_EOL; |
||
| 969 | } |
||
| 970 | return $headers; |
||
| 971 | } |
||
| 972 | |||
| 973 | /** |
||
| 974 | * Get the attachment message for send or the simple message |
||
| 975 | * @return string |
||
| 976 | */ |
||
| 977 | protected function getMessageWithAttachmentForSend() { |
||
| 978 | $message = $this->getWrapMessage(); |
||
| 979 | if ($this->hasAttachments()) { |
||
| 980 | $this->setAttachmentHeaders(); |
||
| 981 | $message = $this->assembleAttachmentBody(); |
||
| 982 | } |
||
| 983 | return $message; |
||
| 984 | } |
||
| 985 | |||
| 986 | /** |
||
| 987 | * getUniqueId |
||
| 988 | * |
||
| 989 | * @return string |
||
| 990 | */ |
||
| 991 | protected function getUniqueId() { |
||
| 992 | return md5(uniqid(time())); |
||
| 993 | } |
||
| 994 | |||
| 995 | /** |
||
| 996 | * Send smtp command to server |
||
| 997 | * @param string $command the smtp command |
||
| 998 | * |
||
| 999 | * @return object |
||
| 1000 | */ |
||
| 1001 | protected function sendCommand($command) { |
||
| 1002 | fputs($this->smtpSocket, $command . PHP_EOL); |
||
| 1003 | $this->smtpResponse = $this->getSmtpServerResponse(); |
||
| 1004 | return $this; |
||
| 1005 | } |
||
| 1006 | |||
| 1007 | /** |
||
| 1008 | * Send EHLO or HELO command to smtp server |
||
| 1009 | * @return boolean true if server response is OK otherwise will return false |
||
| 1010 | */ |
||
| 1011 | protected function sendHelloCommand() { |
||
| 1012 | $responseCode = $this->sendCommand('EHLO ' . $this->getSmtpClientHostname()) |
||
| 1013 | ->getSmtpResponseCode(); |
||
| 1014 | if ($responseCode !== 250) { |
||
| 1015 | //May be try with "HELO" |
||
| 1016 | $responseCode = $this->sendCommand('HELO ' . $this->getSmtpClientHostname()) |
||
| 1017 | ->getSmtpResponseCode(); |
||
| 1018 | if ($responseCode !== 250) { |
||
| 1019 | $this->error = $this->smtpResponse; |
||
| 1020 | return false; |
||
| 1021 | } |
||
| 1022 | } |
||
| 1023 | return true; |
||
| 1024 | } |
||
| 1025 | |||
| 1026 | /** |
||
| 1027 | * Get the smtp server response |
||
| 1028 | * @return mixed |
||
| 1029 | */ |
||
| 1030 | protected function getSmtpServerResponse() { |
||
| 1031 | $response = ''; |
||
| 1032 | stream_set_timeout($this->smtpSocket, $this->smtpResponseTimeout); |
||
| 1033 | while (($line = fgets($this->smtpSocket)) !== false) { |
||
| 1034 | $response .= trim($line) . "\n"; |
||
| 1035 | if (substr($line, 3, 1) == ' ') { |
||
| 1036 | break; |
||
| 1037 | } |
||
| 1038 | } |
||
| 1039 | $response = trim($response); |
||
| 1040 | return $response; |
||
| 1041 | } |
||
| 1042 | |||
| 1043 | /** |
||
| 1044 | * Return the last response code |
||
| 1045 | * |
||
| 1046 | * @param string|null $response the response string if is null |
||
| 1047 | * will use the last smtp response |
||
| 1048 | * |
||
| 1049 | * @return integer the 3 digit of response code |
||
| 1050 | */ |
||
| 1051 | protected function getSmtpResponseCode($response = null) { |
||
| 1052 | if ($response === null) { |
||
| 1053 | $response = $this->smtpResponse; |
||
| 1054 | } |
||
| 1055 | return (int) substr($response, 0, 3); |
||
| 1056 | } |
||
| 1057 | |||
| 1058 | /** |
||
| 1059 | * Establish connection to smtp server |
||
| 1060 | * @return boolean |
||
| 1061 | */ |
||
| 1062 | protected function smtpConnection() { |
||
| 1098 | } |
||
| 1099 | |||
| 1100 | /** |
||
| 1101 | * Check if server support TLS connection |
||
| 1102 | * @return object |
||
| 1103 | */ |
||
| 1104 | protected function checkForSmtpConnectionTls() { |
||
| 1105 | if ($this->transport == 'tls') { |
||
| 1106 | $tlsCode = $this->sendCommand('STARTTLS')->getSmtpResponseCode(); |
||
| 1107 | $this->logs['STARTTLS'] = $this->smtpResponse; |
||
| 1108 | if ($tlsCode === 220) { |
||
| 1109 | /** |
||
| 1110 | * STREAM_CRYPTO_METHOD_TLS_CLIENT is quite the mess ... |
||
| 1111 | * |
||
| 1112 | * - On PHP <5.6 it doesn't even mean TLS, but SSL 2.0, and there's no option to use actual TLS |
||
| 1113 | * - On PHP 5.6.0-5.6.6, >=7.2 it means negotiation with any of TLS 1.0, 1.1, 1.2 |
||
| 1114 | * - On PHP 5.6.7-7.1.* it means only TLS 1.0 |
||
| 1115 | * |
||
| 1116 | * We want the negotiation, so we'll force it below ... |
||
| 1117 | */ |
||
| 1118 | $method = STREAM_CRYPTO_METHOD_TLS_CLIENT; |
||
| 1119 | if(version_compare(PHP_VERSION, '5.6', '>=')) { |
||
| 1120 | $method = STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; |
||
| 1121 | } |
||
| 1122 | stream_socket_enable_crypto($this->smtpSocket, true, $method); |
||
| 1123 | $hello = $this->sendHelloCommand(); |
||
| 1124 | $this->logs['HELLO_TLS'] = $this->smtpResponse; |
||
| 1125 | if (!$hello) { |
||
| 1126 | return false; |
||
| 1127 | } |
||
| 1128 | } |
||
| 1129 | } |
||
| 1130 | return true; |
||
| 1131 | } |
||
| 1132 | |||
| 1133 | /** |
||
| 1134 | * Client authentication |
||
| 1135 | * @return boolean |
||
| 1136 | */ |
||
| 1137 | protected function smtpAuthentication() { |
||
| 1138 | $authCode = $this->sendCommand('AUTH LOGIN')->getSmtpResponseCode(); |
||
| 1139 | $this->logs['AUTH_LOGIN'] = $this->smtpResponse; |
||
| 1140 | if ($authCode === 334) { |
||
| 1141 | $this->sendCommand(base64_encode($this->smtpUsername))->getSmtpResponseCode(); |
||
| 1142 | $code = $this->sendCommand(base64_encode($this->smtpPassword))->getSmtpResponseCode(); |
||
| 1143 | $this->logs['CLIENT_AUTH'] = $this->smtpResponse; |
||
| 1144 | if ($code !== 235) { |
||
| 1145 | $this->error = $this->smtpResponse; |
||
| 1146 | return false; |
||
| 1147 | } |
||
| 1148 | } |
||
| 1149 | return true; |
||
| 1150 | } |
||
| 1151 | |||
| 1152 | /** |
||
| 1153 | * Send mail using "mail" protocol |
||
| 1154 | * @return boolean |
||
| 1155 | */ |
||
| 1156 | protected function sendMail() { |
||
| 1157 | $to = $this->getToForSend(); |
||
| 1158 | $message = $this->getMessageWithAttachmentForSend(); |
||
| 1159 | $headers = $this->getHeadersForSend(); |
||
| 1160 | $this->logger->info('Sending new mail using mail protocol, the information are listed below: ' |
||
| 1161 | . 'destination: ' . $to . ', headers: ' . $headers . ', message: ' . $message); |
||
| 1162 | $result = mail($to, $this->subject, $message, $headers, $this->params); |
||
| 1163 | if (!$result) { |
||
| 1164 | $this->error = 'Error when sending mail using mail protocol'; |
||
| 1165 | } |
||
| 1166 | return $result; |
||
| 1167 | } |
||
| 1168 | |||
| 1169 | /** |
||
| 1170 | * Send mail using "smtp" protocol |
||
| 1171 | * @return boolean |
||
| 1172 | */ |
||
| 1173 | protected function sendSmtp() { |
||
| 1224 | } |
||
| 1225 | |||
| 1226 | /** |
||
| 1227 | * Return the client hostname for SMTP |
||
| 1228 | * |
||
| 1229 | * There are only two legal types of hostname - either a fully |
||
| 1230 | * qualified domain name (eg: "mail.example.com") or an IP literal |
||
| 1231 | * (eg: "[1.2.3.4]"). |
||
| 1232 | * |
||
| 1233 | * @link https://tools.ietf.org/html/rfc5321#section-2.3.5 |
||
| 1234 | * @link http://cbl.abuseat.org/namingproblems.html |
||
| 1235 | * @return string |
||
| 1236 | */ |
||
| 1237 | protected function getSmtpClientHostname() { |
||
| 1238 | $globals = &class_loader('GlobalVar', 'classes'); |
||
| 1239 | if ($globals->server('SERVER_NAME')) { |
||
| 1240 | return $globals->server('SERVER_NAME'); |
||
| 1241 | } |
||
| 1242 | if ($globals->server('SERVER_ADDR')) { |
||
| 1243 | return $globals->server('SERVER_ADDR'); |
||
| 1244 | } |
||
| 1245 | return '[127.0.0.1]'; |
||
| 1246 | } |
||
| 1247 | |||
| 1248 | /** |
||
| 1249 | * Class desctructor |
||
| 1250 | * @codeCoverageIgnore |
||
| 1251 | */ |
||
| 1252 | public function __destruct() { |
||
| 1253 | if (is_resource($this->smtpSocket)) { |
||
| 1254 | fclose($this->smtpSocket); |
||
| 1255 | } |
||
| 1256 | } |
||
| 1257 | } |
||
| 1258 |
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
$accountIdthat can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theidproperty of an instance of theAccountclass. 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.