選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

155 行
4.2KB

  1. <?php
  2. namespace App\Logic;
  3. use App\Codes\EnvironmentName;
  4. use App\Events\Email\ConfirmEvent;
  5. use App\Exceptions\AppCommonException;
  6. use App\Email\BaseEmailer;
  7. use App\Models\Email;
  8. use App\Models\EmailAttachment;
  9. use Exception;
  10. use Illuminate\Database\Eloquent\Collection;
  11. use Illuminate\Support\Carbon;
  12. use Illuminate\Support\Str;
  13. use Validator;
  14. class EmailManager
  15. {
  16. private Email $model;
  17. private bool $canSend = false;
  18. /**
  19. * @var Collection<int, EmailAttachment>|null
  20. */
  21. private ?Collection $attachments = null;
  22. public function __construct(int|BaseEmailer $param)
  23. {
  24. if (is_numeric($param)) {
  25. $this->model = Email::lockForUpdate()->findOrfail($param);
  26. $this->canSend = $this->model->send_datetime === null;
  27. if (!$this->checkAuth()) throw new AppCommonException("メール権限エラー");
  28. } else if ($param instanceof BaseEmailer) {
  29. $this->model = $param->makeModel();
  30. }
  31. }
  32. public function checkAuth()
  33. {
  34. return true;
  35. }
  36. public function getEmailId()
  37. {
  38. $this->model->setId();
  39. return $this->model->id;
  40. }
  41. public function getTimestamp(): Carbon|null
  42. {
  43. return $this->model->updated_at;
  44. }
  45. public function create()
  46. {
  47. $this->model->save();
  48. return [];
  49. }
  50. public function setSubject(string $subject)
  51. {
  52. if ($this->canSend()) {
  53. $this->model->subject = $subject;
  54. } else {
  55. throw new AppCommonException("送信済みメール編集エラー");
  56. }
  57. return $this;
  58. }
  59. public function setContent(string $content)
  60. {
  61. if ($this->canSend()) {
  62. $this->model->content = $content;
  63. } else {
  64. throw new AppCommonException("送信済みメール編集エラー");
  65. }
  66. return $this;
  67. }
  68. public function attach(string $filepath, string $filename, string $mimeType)
  69. {
  70. if ($this->attachments === null) {
  71. $this->attachments = new Collection();
  72. }
  73. $attachment = new EmailAttachment();
  74. $attachment->filepath = $filepath;
  75. $attachment->send_filename = $filename;
  76. $attachment->mime = $mimeType;
  77. $this->attachments->push($attachment);
  78. return $this;
  79. }
  80. public function update()
  81. {
  82. $this->model->save();
  83. return [];
  84. }
  85. public function confirm()
  86. {
  87. // ローカル開発環境用の制御
  88. // 送信先の判定と、送信先の書き換え
  89. if (app()->environment([EnvironmentName::LOCAL->value])) {
  90. $email = $this->model->email;
  91. $emailRewrite = config('mail.developmentEmail');
  92. if ($emailRewrite) {
  93. // 送信先書き換え
  94. $this->model->email = $emailRewrite;
  95. } else {
  96. // 送信NG
  97. info(sprintf("ローカル環境Email送信対象外アドレスのため、メール送信スキップ [%s]", $email));
  98. return;
  99. }
  100. }
  101. // ステージング環境では特定のドメインに対してのみ送信可能
  102. // 送信先の書き換えは行わない
  103. if (app()->environment([EnvironmentName::STAGING->value])) {
  104. $email = $this->model->email;
  105. if (!Str::endsWith($email, ['@satellite-tech.co.jp', '@sute.jp', '@kyoto-public.or.jp'])) {
  106. // 送信NG
  107. info(sprintf("ローカル環境Email送信対象外アドレスのため、メール送信スキップ [%s]", $email));
  108. return;
  109. }
  110. }
  111. $validator = Validator::make(['email' => $this->model->email], [
  112. 'email' => ['required', 'email:strict,dns']
  113. ]);
  114. if ($validator->fails()) {
  115. throw new Exception(sprintf("%s [%s]", $validator->errors()->first(), $this->model->email));
  116. }
  117. if ($this->canSend() !== null) {
  118. $this->model->setId();
  119. ConfirmEvent::dispatch($this->model, $this->attachments);
  120. } else {
  121. throw new AppCommonException("送信済みエラー");
  122. }
  123. }
  124. public function canSend()
  125. {
  126. return $this->canSend;
  127. }
  128. }