giftcon_dev/app/Repositories/Admin/Mail/AdminMailRepository.php

162 lines
5.5 KiB
PHP

<?php
namespace App\Repositories\Admin\Mail;
use Illuminate\Support\Facades\DB;
final class AdminMailRepository
{
public function createBatch(array $row): int
{
DB::table('admin_mail_batches')->insert($row);
return (int)DB::getPdo()->lastInsertId();
}
public function updateBatch(int $batchId, array $row): int
{
return DB::table('admin_mail_batches')->where('id', $batchId)->update($row);
}
public function findBatch(int $batchId): ?object
{
$b = DB::table('admin_mail_batches')->where('id',$batchId)->first();
return $b ?: null;
}
public function listBatches(array $filters, int $perPage)
{
$q = DB::table('admin_mail_batches');
if (!empty($filters['status'])) $q->where('status', $filters['status']);
if (!empty($filters['send_mode'])) $q->where('send_mode', $filters['send_mode']);
if (!empty($filters['date_from'])) $q->whereDate('created_at','>=',$filters['date_from']);
if (!empty($filters['date_to'])) $q->whereDate('created_at','<=',$filters['date_to']);
if (!empty($filters['q'])) {
$kw = '%'.$filters['q'].'%';
$q->where(function($w) use ($kw){
$w->where('subject_raw','like',$kw)
->orWhere('body_raw','like',$kw)
->orWhere('from_email','like',$kw)
->orWhere('admin_name','like',$kw)
->orWhere('last_error','like',$kw);
});
}
return $q->orderByDesc('id')->paginate($perPage)->withQueryString();
}
public function bulkInsertItems(int $batchId, array $rows): void
{
// rows: [ [batch_id, seq, to_email, ...], ... ]
DB::table('admin_mail_batch_items')->insert($rows);
}
public function listItems(int $batchId, array $filters, int $perPage)
{
$q = DB::table('admin_mail_batch_items')->where('batch_id',$batchId);
if (!empty($filters['status'])) $q->where('status',$filters['status']);
if (!empty($filters['to'])) $q->where('to_email','like','%'.$filters['to'].'%');
if (!empty($filters['q'])) {
$kw = '%'.$filters['q'].'%';
$q->where(function($w) use ($kw){
$w->where('subject_final','like',$kw)->orWhere('body_final','like',$kw)->orWhere('last_error','like',$kw);
});
}
return $q->orderBy('seq')->paginate($perPage)->withQueryString();
}
public function markBatchSending(int $batchId): void
{
DB::table('admin_mail_batches')->where('id',$batchId)->update([
'status' => 'sending',
'started_at' => now()->format('Y-m-d H:i:s'),
]);
}
public function pickDueScheduledBatches(int $limit=20): array
{
$rows = DB::table('admin_mail_batches')
->where('status','scheduled')
->whereNotNull('scheduled_at')
->where('scheduled_at','<=', now()->format('Y-m-d H:i:s'))
->orderBy('scheduled_at')
->limit($limit)
->get();
return $rows ? $rows->all() : [];
}
public function setBatchQueued(int $batchId): void
{
DB::table('admin_mail_batches')->where('id',$batchId)->update(['status'=>'queued']);
}
public function countItemsByStatus(int $batchId): array
{
$rows = DB::table('admin_mail_batch_items')
->select('status', DB::raw('COUNT(*) as c'))
->where('batch_id',$batchId)
->groupBy('status')->get();
$map = ['sent'=>0,'failed'=>0,'canceled'=>0,'skipped'=>0,'queued'=>0];
foreach ($rows as $r) $map[$r->status] = (int)$r->c;
return $map;
}
public function updateBatchCounts(int $batchId, array $counts, ?string $status=null, ?string $lastError=null): void
{
$row = [
'sent_count' => (int)($counts['sent'] ?? 0),
'failed_count' => (int)($counts['failed'] ?? 0),
'canceled_count' => (int)(($counts['canceled'] ?? 0) + ($counts['skipped'] ?? 0)),
];
if ($status) $row['status'] = $status;
if ($lastError !== null) $row['last_error'] = $lastError;
if (in_array($status, ['sent','partial','failed','canceled'], true)) {
$row['finished_at'] = now()->format('Y-m-d H:i:s');
}
DB::table('admin_mail_batches')->where('id',$batchId)->update($row);
}
public function cancelBatch(int $batchId): void
{
DB::table('admin_mail_batches')->where('id',$batchId)->update([
'status'=>'canceled',
'finished_at'=>now()->format('Y-m-d H:i:s'),
]);
DB::table('admin_mail_batch_items')
->where('batch_id',$batchId)
->whereIn('status',['queued'])
->update(['status'=>'canceled','last_error'=>'batch_canceled']);
}
public function resetFailedToQueued(int $batchId): int
{
return DB::table('admin_mail_batch_items')
->where('batch_id',$batchId)
->where('status','failed')
->update(['status'=>'queued','last_error'=>'','attempts'=>0]);
}
public function nextQueuedItems(int $batchId, int $limit=200): array
{
$rows = DB::table('admin_mail_batch_items')
->where('batch_id',$batchId)
->where('status','queued')
->orderBy('seq')
->limit($limit)
->get();
return $rows ? $rows->all() : [];
}
public function updateItem(int $id, array $row): void
{
DB::table('admin_mail_batch_items')->where('id',$id)->update($row);
}
}