Created
December 4, 2024 01:33
-
-
Save fuelingtheweb/1de86958eda4950be62d443c6f92d39f to your computer and use it in GitHub Desktop.
app/Console/Commands/CreateWeek.php - Interacts with a college football API for weekly picks app
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Console\Commands; | |
use App\Models\Game; | |
use App\Models\Season; | |
use App\Models\Stat; | |
use App\Models\Team; | |
use App\Models\Week; | |
use Illuminate\Console\Command; | |
use Illuminate\Support\Carbon; | |
use Illuminate\Support\Facades\Http; | |
class CreateWeek extends Command | |
{ | |
protected $signature = 'pickem:create-week'; | |
protected $description = 'Create week'; | |
private $weeks; | |
private $week; | |
private $teams; | |
public function handle(): void | |
{ | |
$this->week = $this->upcomingWeek(); | |
if (! $this->week) { | |
$this->error('No upcoming weeks found.'); | |
return; | |
} | |
if ($this->previousWeekIsUnfinished()) { | |
$this->error("The previous week hasn't ended yet."); | |
return; | |
} | |
$this->createSeasonIfMissing(); | |
$this->createGames($this->createWeek()); | |
} | |
private function createSeasonIfMissing() | |
{ | |
$season = Season::current(); | |
if ($this->isCurrentSeason($season)) { | |
return; | |
} | |
$previousStats = $season?->stats ?? collect(); | |
$season = Season::create([ | |
'year' => $this->week['season'], | |
'type' => $this->week['seasonType'] == 'regular' ? 'reg' : 'pst', | |
]); | |
$previousStats->each( | |
fn ($stat) => Stat::create([ | |
'user_id' => $stat->user_id, | |
'league_id' => $stat->league_id, | |
'season_id' => $season->id, | |
]), | |
); | |
} | |
private function isCurrentSeason($season) | |
{ | |
if ($season?->year != $this->week['season']) { | |
return false; | |
} | |
return match ($this->week['seasonType']) { | |
'regular' => $season->type === 'reg', | |
'postseason' => $season->type === 'pst', | |
default => false, | |
}; | |
} | |
private function createWeek() | |
{ | |
return Week::create([ | |
'name' => $this->week['seasonType'] == 'regular' | |
? "Week {$this->week['week']}" | |
: 'Bowls', | |
'season_id' => Season::where(['year' => $this->week['season'], 'type' => $this->typeFromApi()])->value('id'), | |
]); | |
} | |
private function typeFromApi() | |
{ | |
return match ($this->week['seasonType']) { | |
'regular' => 'reg', | |
'postseason' => 'pst', | |
default => 'reg', | |
}; | |
} | |
private function createGames(Week $week) | |
{ | |
$this->teams = Team::pluck('id', 'espn_id'); | |
$this->games()->each(fn ($game) => $this->createGame($week, $game)); | |
} | |
private function createGame(Week $week, $game) | |
{ | |
if ($game['home_division'] != 'fbs' || $game['away_division'] != 'fbs') { | |
return; | |
} | |
Game::create([ | |
'espn_id' => $game['id'], | |
'week_id' => $week->id, | |
'home_team_id' => $this->teams->get($game['home_id']), | |
'away_team_id' => $this->teams->get($game['away_id']), | |
'name' => $game['notes'], | |
'kickoff' => $game['start_time_tbd'] | |
? null | |
: Carbon::parse($game['start_date'], 'UTC')->tz(config('app.timezone')), | |
'is_neutral' => $game['neutral_site'], | |
'type' => str($game['notes'])->contains('CFP Semifinal') | |
? Game::TYPE_SEMIFINAL | |
: Game::TYPE_DEFAULT, | |
]); | |
} | |
private function upcomingWeek() | |
{ | |
if (Season::latest()->value('year') < now()->year) { | |
return $this->weeks()->first(); | |
} | |
return $this->weeks()->firstWhere(function ($week) { | |
return Carbon::parse($week['firstGameStart'])->isFuture(); | |
}); | |
} | |
private function previousWeekIsUnfinished() | |
{ | |
$currentWeek = Week::current(); | |
$previousWeek = $currentWeek | |
? $this->weeks() | |
->where('week', str($currentWeek->name)->remove('Week ')->toString()) | |
->where('season', $currentWeek->season->year) | |
->first() | |
: null; | |
return $previousWeek && Carbon::parse($previousWeek['lastGameStart'])->isFuture(); | |
} | |
private function weeks() | |
{ | |
if ($this->weeks) { | |
return $this->weeks; | |
} | |
$response = Http::withToken(config('services.cfbd.token')) | |
->get('https://api.collegefootballdata.com/calendar', [ | |
'year' => now()->year, | |
]); | |
return $this->weeks = collect($response->json()); | |
} | |
private function games() | |
{ | |
$response = Http::withToken(config('services.cfbd.token')) | |
->get('https://api.collegefootballdata.com/games', [ | |
'year' => $this->week['season'], | |
'week' => $this->week['week'], | |
'seasonType' => $this->week['seasonType'], | |
'division' => 'fbs', | |
]); | |
return collect($response->json()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment