142 lines
3.7 KiB
PHP
142 lines
3.7 KiB
PHP
|
<?php
|
||
|
|
||
|
namespace App\Console\Commands;
|
||
|
|
||
|
use App\EmailLog;
|
||
|
use App\Facade\UserConfig;
|
||
|
use App\Http\Middleware\GlobalConfiguration;
|
||
|
use Illuminate\Console\Command;
|
||
|
use Illuminate\Mail\Mailer;
|
||
|
use Illuminate\Mail\Message;
|
||
|
use Illuminate\Support\Facades\Mail;
|
||
|
|
||
|
class SendEmailsCommand extends Command
|
||
|
{
|
||
|
const MAX_EMAILS_PER_BATCH = 100;
|
||
|
|
||
|
const MAX_NUMBER_ATTEMPTS = 5;
|
||
|
|
||
|
const SECONDS_TO_SLEEP = 30;
|
||
|
|
||
|
/**
|
||
|
* The name and signature of the console command.
|
||
|
*
|
||
|
* @var string
|
||
|
*/
|
||
|
protected $signature = 'bt-queue:send-emails {--poll}';
|
||
|
|
||
|
/**
|
||
|
* The console command description.
|
||
|
*
|
||
|
* @var string
|
||
|
*/
|
||
|
protected $description = 'Sends e-mails queued in the database.';
|
||
|
|
||
|
/**
|
||
|
* Create a new command instance.
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
public function __construct()
|
||
|
{
|
||
|
parent::__construct();
|
||
|
|
||
|
GlobalConfiguration::updateMailConfig();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Execute the console command.
|
||
|
*
|
||
|
* @return mixed
|
||
|
*/
|
||
|
public function handle()
|
||
|
{
|
||
|
if (!UserConfig::get('queue_emails'))
|
||
|
{
|
||
|
$this->output->error('E-mail queueing is not enabled. E-mails are being sent immediately.');
|
||
|
}
|
||
|
|
||
|
$this->output->writeln('E-mail queue runner started');
|
||
|
|
||
|
while (true)
|
||
|
{
|
||
|
$emailsToSend = EmailLog::where([
|
||
|
['sent_at', null],
|
||
|
['number_attempts', '<', self::MAX_NUMBER_ATTEMPTS]
|
||
|
])->limit(self::MAX_EMAILS_PER_BATCH)->get();
|
||
|
|
||
|
$this->output->writeln(sprintf(
|
||
|
'%d e-mail%s to send',
|
||
|
$emailsToSend->count(),
|
||
|
$emailsToSend->count() == 1 ? '' : 's'
|
||
|
));
|
||
|
|
||
|
/** @var EmailLog $emailToSend */
|
||
|
foreach ($emailsToSend as $emailToSend)
|
||
|
{
|
||
|
$this->sendEmail($emailToSend);
|
||
|
}
|
||
|
|
||
|
if (!$this->option('poll'))
|
||
|
{
|
||
|
exit();
|
||
|
}
|
||
|
|
||
|
sleep(self::SECONDS_TO_SLEEP);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private function sendEmail(EmailLog $emailLog)
|
||
|
{
|
||
|
$this->output->writeln(sprintf('Sending message with subject \'%s\'', $emailLog->subject));
|
||
|
|
||
|
try
|
||
|
{
|
||
|
app('mailer')->send(
|
||
|
[],
|
||
|
[],
|
||
|
function (Message $message) use ($emailLog)
|
||
|
{
|
||
|
$message->setFrom($emailLog->sender_address, $emailLog->sender_name);
|
||
|
$message->setSubject($emailLog->subject);
|
||
|
|
||
|
$this->addAddresses($emailLog->to_addresses, $message, 'To');
|
||
|
$this->addAddresses($emailLog->cc_addresses, $message, 'Cc');
|
||
|
$this->addAddresses($emailLog->bcc_addresses, $message, 'Bcc');
|
||
|
|
||
|
$message->addPart($emailLog->body_plain, 'text/plain');
|
||
|
$message->setBody($emailLog->body_html, 'text/html');
|
||
|
}
|
||
|
);
|
||
|
|
||
|
$emailLog->sent_at = new \DateTime();
|
||
|
|
||
|
$this->output->writeln('Send completed');
|
||
|
}
|
||
|
catch (\Exception $ex)
|
||
|
{
|
||
|
$this->output->error(sprintf('Send failed: %s', $ex->getMessage()));
|
||
|
}
|
||
|
finally
|
||
|
{
|
||
|
$emailLog->number_attempts++;
|
||
|
$emailLog->save();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private function addAddresses($dbFieldData, Message $message, $property)
|
||
|
{
|
||
|
$decoded = json_decode($dbFieldData);
|
||
|
|
||
|
if (is_array($decoded))
|
||
|
{
|
||
|
foreach ($decoded as $addressInfo)
|
||
|
{
|
||
|
$this->output->writeln(sprintf('Adding %s address: \'"%s" <%s>\'', $property, $addressInfo->name, $addressInfo->address));
|
||
|
|
||
|
$message->{"set{$property}"}($addressInfo->address, $addressInfo->name);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|