api/app/Console/Commands/SendEngagementReminderNotif...

78 lines
2.1 KiB
PHP

<?php
namespace App\Console\Commands;
use App\Models\User;
use App\Notifications\EngagementReminderNotification;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Builder;
class SendEngagementReminderNotifications extends Command
{
protected $signature = 'notifications:send-engagement-reminders
{--limit= : Maximum number of users to notify}
{--dry-run : Count eligible users without sending notifications}';
protected $description = 'Send occasional hard-coded engagement reminders to mobile users.';
public function handle(): int
{
$limit = $this->limitOption();
if ($limit === false) {
$this->error('The --limit option must be an integer greater than zero.');
return self::FAILURE;
}
$query = $this->eligibleUsersQuery();
if ($this->option('dry-run')) {
$this->info("{$query->count()} eligible user(s) found.");
return self::SUCCESS;
}
$sent = 0;
foreach ($query->lazyById(100) as $user) {
if ($limit !== null && $sent >= $limit) {
break;
}
$user->notify(
new EngagementReminderNotification(EngagementReminderNotification::randomMessageKey()),
);
$sent++;
}
$this->info("{$sent} engagement reminder notification(s) sent.");
return self::SUCCESS;
}
private function eligibleUsersQuery(): Builder
{
return User::query()
->select(['id', 'locale', 'suspended_at'])
->whereNull('suspended_at')
->whereHas('deviceTokens')
->whereDoesntHave('mealPosts', fn (Builder $query): Builder => $query
->where('created_at', '>=', now()->subDay()));
}
private function limitOption(): int|false|null
{
$limit = $this->option('limit');
if ($limit === null || $limit === '') {
return null;
}
return filter_var($limit, FILTER_VALIDATE_INT, [
'options' => ['min_range' => 1],
]);
}
}