--- /dev/null
+<?php
+
+namespace App\Console\Commands;
+
+use App\Models\DiscordGuild;
+use App\Models\Episode;
+use Illuminate\Console\Command;
+
+class DiscordEpisodeSubscriptionsCommand extends Command
+{
+ /**
+ * The name and signature of the console command.
+ *
+ * @var string
+ */
+ protected $signature = 'discord:episode-subscriptions';
+
+ /**
+ * The console command description.
+ *
+ * @var string
+ */
+ protected $description = 'Update episode subscriptions and create or update guild events accordingly';
+
+ /**
+ * Execute the console command.
+ *
+ * @return int
+ */
+ public function handle() {
+ $guilds = DiscordGuild::all();
+ foreach ($guilds as $guild) {
+ try {
+ $this->handleGuild($guild);
+ } catch (\Exception $e) {
+ $this->error('error handling guild '.$guild->name.': '.$e->getMessage());
+ }
+ }
+ return 0;
+ }
+
+ private function handleGuild(DiscordGuild $guild) {
+ $from = now()->sub(1, 'hour');
+ $eventIDs = $guild->event_subscriptions->pluck('event_id')->toArray();
+ $userIDs = $guild->user_subscriptions->pluck('user_id')->toArray();
+ if (empty($eventIDs) && empty($userIDs)) return;
+
+ $query = Episode::with(['channels', 'event', 'players'])
+ ->where('episodes.start', '>', $from)
+ ->orderBy('episodes.start', 'ASC')
+ ->limit(20);
+ $query->where(function ($subquery) use ($eventIDs, $userIDs) {
+ if (!empty($eventIDs)) {
+ $subquery->whereIn('episodes.event_id', $eventIDs);
+ }
+ if (!empty($userIDs)) {
+ $subquery->orWhereHas('players', function ($builder) use ($userIDs) {
+ $builder->whereIn('episode_players.user_id', $userIDs);
+ });
+ }
+ });
+ $episodes = $query->get();
+ foreach ($episodes as $episode) {
+ $this->handleEpisode($episode);
+ }
+ }
+
+ private function handleEpisode(Episode $episode) {
+ $this->line($episode->start.' '.$episode->event->title.' ' .$episode->title);
+ foreach ($episode->players as $player) {
+ $this->line(' - '.$player->name_override);
+ }
+ }
+
+}
--- /dev/null
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+ /**
+ * Run the migrations.
+ */
+ public function up(): void
+ {
+ Schema::create('discord_guild_event_subscriptions', function (Blueprint $table) {
+ $table->id();
+ $table->foreignId('discord_guild_id')->constrained();
+ $table->foreignId('event_id')->constrained();
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('discord_guild_event_subscriptions');
+ }
+};
--- /dev/null
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+ /**
+ * Run the migrations.
+ */
+ public function up(): void
+ {
+ Schema::create('discord_guild_user_subscriptions', function (Blueprint $table) {
+ $table->id();
+ $table->foreignId('discord_guild_id')->constrained();
+ $table->foreignId('user_id')->constrained();
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('discord_guild_user_subscriptions');
+ }
+};