Mailer.php 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. <?php
  2. declare(strict_types=1);
  3. use PHPMailer\PHPMailer\PHPMailer;
  4. use PHPMailer\PHPMailer\Exception;
  5. /**
  6. * Allow to send emails.
  7. *
  8. * The Minz_Mailer class must be inherited by classes under app/Mailers.
  9. * They work similarly to the ActionControllers in the way they have a view to
  10. * which you can pass params (eg. $this->view->foo = 'bar').
  11. *
  12. * The view file is not determined automatically, so you have to select one
  13. * with, for instance:
  14. *
  15. * ```
  16. * $this->view->_path('user_mailer/email_need_validation.txt.php')
  17. * ```
  18. *
  19. * Minz_Mailer uses the PHPMailer library under the hood. The latter requires
  20. * PHP >= 5.5 to work. If you instantiate a Minz_Mailer with PHP < 5.5, a
  21. * warning will be logged.
  22. *
  23. * The email is sent by calling the `mail` method.
  24. */
  25. class Minz_Mailer {
  26. /**
  27. * The view attached to the mailer.
  28. * You should set its file with `$this->view->_path($path)`
  29. *
  30. * @var Minz_View
  31. */
  32. protected $view;
  33. private string $mailer;
  34. /** @var array{'hostname':string,'host':string,'auth':bool,'username':string,'password':string,'secure':string,'port':int,'from':string} */
  35. private array $smtp_config;
  36. private int $debug_level;
  37. /**
  38. * @phpstan-param class-string|'' $viewType
  39. * @param string $viewType Name of the class (inheriting from Minz_View) to use for the view model
  40. * @throws Minz_ConfigurationException
  41. */
  42. public function __construct(string $viewType = '') {
  43. $view = null;
  44. if ($viewType !== '' && class_exists($viewType)) {
  45. $view = new $viewType();
  46. if (!($view instanceof Minz_View)) {
  47. $view = null;
  48. }
  49. }
  50. $this->view = $view ?? new Minz_View();
  51. $this->view->_layout(null);
  52. $this->view->attributeParams();
  53. $conf = Minz_Configuration::get('system');
  54. $this->mailer = $conf->mailer;
  55. $this->smtp_config = $conf->smtp;
  56. // According to https://github.com/PHPMailer/PHPMailer/wiki/SMTP-Debugging#debug-levels
  57. // we should not use debug level above 2 unless if we have big trouble
  58. // to connect.
  59. if ($conf->environment === 'development') {
  60. $this->debug_level = 2;
  61. } else {
  62. $this->debug_level = 0;
  63. }
  64. }
  65. /**
  66. * Send an email.
  67. *
  68. * @param string $to The recipient of the email
  69. * @param string $subject The subject of the email
  70. * @return bool true on success, false if a SMTP error happens
  71. */
  72. public function mail(string $to, string $subject): bool {
  73. ob_start();
  74. $this->view->render();
  75. $body = ob_get_contents() ?: '';
  76. ob_end_clean();
  77. PHPMailer::$validator = 'html5';
  78. $mail = new PHPMailer(true);
  79. try {
  80. // Server settings
  81. $mail->SMTPDebug = $this->debug_level;
  82. $mail->Debugoutput = 'error_log';
  83. if ($this->mailer === 'smtp') {
  84. $mail->isSMTP();
  85. $mail->Hostname = $this->smtp_config['hostname'];
  86. $mail->Host = $this->smtp_config['host'];
  87. $mail->SMTPAuth = $this->smtp_config['auth'];
  88. $mail->Username = $this->smtp_config['username'];
  89. $mail->Password = $this->smtp_config['password'];
  90. $mail->SMTPSecure = $this->smtp_config['secure'];
  91. $mail->Port = $this->smtp_config['port'];
  92. } else {
  93. $mail->isMail();
  94. }
  95. // Recipients
  96. $mail->setFrom($this->smtp_config['from']);
  97. $mail->addAddress($to);
  98. // Content
  99. $mail->isHTML(false);
  100. $mail->CharSet = 'utf-8';
  101. $mail->Subject = $subject;
  102. $mail->Body = $body;
  103. $mail->send();
  104. return true;
  105. } catch (Exception $e) {
  106. Minz_Log::error('Minz_Mailer cannot send a message: ' . $mail->ErrorInfo);
  107. return false;
  108. }
  109. }
  110. }