feat: FetchNHLMatch + FakeSportRadarEngine
This commit is contained in:
parent
59991f006c
commit
edd4a185da
|
|
@ -0,0 +1,5 @@
|
||||||
|
imports:
|
||||||
|
- { resource: services.yaml }
|
||||||
|
|
||||||
|
services:
|
||||||
|
App\Application\SportRadar\SportRadarEngine: '@App\Infrastructure\SportRadar\FakeSportRadarEngine'
|
||||||
|
|
@ -7,3 +7,6 @@ parameters:
|
||||||
message: "#^Property .+::.+ is never read, only written\\.$#"
|
message: "#^Property .+::.+ is never read, only written\\.$#"
|
||||||
paths:
|
paths:
|
||||||
- src/Domain/Entity/*.php
|
- src/Domain/Entity/*.php
|
||||||
|
-
|
||||||
|
message: "#^Variable \\$metadata might not be defined\\.$#"
|
||||||
|
path: src/Infrastructure/Persistence/Mapping/*.php
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Application\UseCase;
|
||||||
|
|
||||||
|
use App\Application\SportRadar\SportRadarEngine;
|
||||||
|
use App\Domain\Entity\Game;
|
||||||
|
use App\Domain\Entity\Provider;
|
||||||
|
use App\Domain\Entity\Season;
|
||||||
|
use App\Domain\Entity\Team;
|
||||||
|
use App\Domain\Enum\ENHLSeasonType;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
|
||||||
|
class FetchNHLMatch
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private readonly SportRadarEngine $sportRadarEngine,
|
||||||
|
private readonly EntityManagerInterface $entityManager,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __invoke(FetchNHLMatchRequest $request): void
|
||||||
|
{
|
||||||
|
$provider = $this->entityManager->getRepository(Provider::class)->findOneBy(['id' => '885fe581-c4c3-45e7-a06c-29ece7d47fad']); // id should not be here
|
||||||
|
$matchs = $this->sportRadarEngine->getNHLSchedule($request->year, ENHLSeasonType::from($request->type));
|
||||||
|
|
||||||
|
$season = $this->entityManager->getRepository(Season::class)->findOneBy(['providerSeasonId' => $matchs['season']['providerId']]);
|
||||||
|
/** @var array<string, Team> $teams */
|
||||||
|
$teams = [];
|
||||||
|
|
||||||
|
foreach ($matchs['games'] as $match) {
|
||||||
|
$game = new Game();
|
||||||
|
$game->create(
|
||||||
|
$provider,
|
||||||
|
$match['providerId'],
|
||||||
|
$season,
|
||||||
|
$match['scheduled'],
|
||||||
|
null,
|
||||||
|
$teams[$match['homeTeamProviderId']] ?? $teams[$match['homeTeamProviderId']] = $this->findTeamOrThrow($provider, $match['homeTeamProviderId']),
|
||||||
|
$teams[$match['awayTeamProviderId']] ?? $teams[$match['awayTeamProviderId']] = $this->findTeamOrThrow($provider, $match['awayTeamProviderId']),
|
||||||
|
$match['venueArena'],
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->entityManager->persist($game);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->entityManager->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function findTeamOrThrow(Provider $provider, string $teamId): Team // should be in a trait?
|
||||||
|
{
|
||||||
|
return $this->entityManager->getRepository(Team::class)->findOneBy(['provider' => $provider, 'providerTeamId' => $teamId]) ?? throw new \Exception("Team $teamId not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,7 +4,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Application\UseCase;
|
namespace App\Application\UseCase;
|
||||||
|
|
||||||
class GetNHLMatchRequest
|
class FetchNHLMatchRequest
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
public readonly int $year,
|
public readonly int $year,
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace App\Application\UseCase;
|
|
||||||
|
|
||||||
use App\Application\ReadModel\Provider;
|
|
||||||
use App\Application\SportRadar\SportRadarEngine;
|
|
||||||
use App\Domain\Enum\ENHLSeasonType;
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
|
|
||||||
class GetNHLMatch
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly SportRadarEngine $sportRadarEngine,
|
|
||||||
private readonly EntityManagerInterface $entityManager,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __invoke(GetNHLMatchRequest $request): void
|
|
||||||
{
|
|
||||||
dd($this->entityManager->getRepository(Provider::class)->findAll());
|
|
||||||
dd($this->sportRadarEngine->getNHLSchedule($request->year, ENHLSeasonType::from($request->type))['games'][0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -6,26 +6,32 @@ namespace App\Domain\Entity;
|
||||||
|
|
||||||
class Game extends AEntity
|
class Game extends AEntity
|
||||||
{
|
{
|
||||||
private string $srId;
|
private Provider $provider;
|
||||||
|
private string $providerGameId;
|
||||||
private Season $season;
|
private Season $season;
|
||||||
private \DateTimeImmutable $scheduled;
|
private \DateTimeImmutable $startTimeScheduled;
|
||||||
|
private ?\DateTimeImmutable $endTimeScheduled;
|
||||||
private Team $home;
|
private Team $home;
|
||||||
private Team $away;
|
private Team $away;
|
||||||
private string $venue_arena;
|
private string $venue;
|
||||||
|
|
||||||
public function create(
|
public function create(
|
||||||
string $srId,
|
Provider $provider,
|
||||||
|
string $providerGameId,
|
||||||
Season $season,
|
Season $season,
|
||||||
\DateTimeImmutable $scheduled,
|
\DateTimeImmutable $startTimeScheduled,
|
||||||
|
?\DateTimeImmutable $endTimeScheduled,
|
||||||
Team $home,
|
Team $home,
|
||||||
Team $away,
|
Team $away,
|
||||||
string $venue_arena,
|
string $venue,
|
||||||
): void {
|
): void {
|
||||||
$this->srId = $srId;
|
$this->provider = $provider;
|
||||||
|
$this->providerGameId = $providerGameId;
|
||||||
$this->season = $season;
|
$this->season = $season;
|
||||||
$this->scheduled = $scheduled;
|
$this->startTimeScheduled = $startTimeScheduled;
|
||||||
|
$this->endTimeScheduled = $endTimeScheduled;
|
||||||
$this->home = $home;
|
$this->home = $home;
|
||||||
$this->away = $away;
|
$this->away = $away;
|
||||||
$this->venue_arena = $venue_arena;
|
$this->venue = $venue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,17 @@ namespace App\Domain\Entity;
|
||||||
|
|
||||||
class League extends AEntity
|
class League extends AEntity
|
||||||
{
|
{
|
||||||
|
private Provider $provider;
|
||||||
|
private string $providerLeagueId;
|
||||||
private string $name;
|
private string $name;
|
||||||
|
|
||||||
public function create(
|
public function create(
|
||||||
|
Provider $provider,
|
||||||
|
string $providerLeagueId,
|
||||||
string $name,
|
string $name,
|
||||||
): void {
|
): void {
|
||||||
|
$this->provider = $provider;
|
||||||
|
$this->providerLeagueId = $providerLeagueId;
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,5 +11,4 @@ class Provider extends AEntity
|
||||||
): void {
|
): void {
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -6,17 +6,23 @@ namespace App\Domain\Entity;
|
||||||
|
|
||||||
class Season extends AEntity
|
class Season extends AEntity
|
||||||
{
|
{
|
||||||
|
private Provider $provider;
|
||||||
|
private string $providerSeasonId;
|
||||||
private League $league;
|
private League $league;
|
||||||
private string $type; // should be an enum
|
|
||||||
private int $year;
|
private int $year;
|
||||||
|
private string $kind; // should be an enum
|
||||||
|
|
||||||
public function create(
|
public function create(
|
||||||
|
Provider $provider,
|
||||||
|
string $providerSeasonId,
|
||||||
League $league,
|
League $league,
|
||||||
string $type,
|
string $kind,
|
||||||
int $year,
|
int $year,
|
||||||
): void {
|
): void {
|
||||||
|
$this->provider = $provider;
|
||||||
|
$this->providerSeasonId = $providerSeasonId;
|
||||||
$this->league = $league;
|
$this->league = $league;
|
||||||
$this->type = $type;
|
$this->kind = $kind;
|
||||||
$this->year = $year;
|
$this->year = $year;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,17 +6,23 @@ namespace App\Domain\Entity;
|
||||||
|
|
||||||
class Team extends AEntity
|
class Team extends AEntity
|
||||||
{
|
{
|
||||||
|
private Provider $provider;
|
||||||
|
private string $providerTeamId;
|
||||||
private string $name;
|
private string $name;
|
||||||
private string $alias;
|
private string $alias;
|
||||||
private string $sr_id;
|
private bool $active;
|
||||||
|
|
||||||
public function create(
|
public function create(
|
||||||
|
Provider $provider,
|
||||||
|
string $providerTeamId,
|
||||||
string $name,
|
string $name,
|
||||||
string $alias,
|
string $alias,
|
||||||
string $sr_id,
|
bool $active,
|
||||||
): void {
|
): void {
|
||||||
|
$this->provider = $provider;
|
||||||
|
$this->providerTeamId = $providerTeamId;
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
$this->alias = $alias;
|
$this->alias = $alias;
|
||||||
$this->sr_id = $sr_id;
|
$this->active = $active;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
namespace App\Infrastructure\Console;
|
namespace App\Infrastructure\Console;
|
||||||
|
|
||||||
use App\Application\CommandBus\UseCaseCommandBus;
|
use App\Application\CommandBus\UseCaseCommandBus;
|
||||||
use App\Application\UseCase\GetNHLMatchRequest;
|
use App\Application\UseCase\FetchNHLMatchRequest;
|
||||||
use Symfony\Component\Console\Attribute\AsCommand;
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
|
||||||
|
|
@ -17,7 +17,7 @@ class GetNHLScheduleCommand
|
||||||
|
|
||||||
public function __invoke(): int
|
public function __invoke(): int
|
||||||
{
|
{
|
||||||
$this->commandBus->ask(new GetNHLMatchRequest(2025, 'REG'));
|
$this->commandBus->ask(new FetchNHLMatchRequest(2025, 'REG'));
|
||||||
|
|
||||||
return Command::SUCCESS;
|
return Command::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
$builder = new Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder($metadata);
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->setReadOnly()
|
||||||
|
->setTable('game')
|
||||||
|
;
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->createField('id', 'uuid')
|
||||||
|
->nullable(false)
|
||||||
|
->makePrimaryKey()
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->createField('providerGameId', 'uuid')
|
||||||
|
->columnName('provider_game_id')
|
||||||
|
->nullable(false)
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->createField('startTimeScheduled', 'datetimetz_immutable')
|
||||||
|
->columnName('start_time_scheduled')
|
||||||
|
->nullable(false)
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->createField('endTimeScheduled', 'datetimetz_immutable')
|
||||||
|
->columnName('end_time_scheduled')
|
||||||
|
->nullable(true)
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->createField('venue', 'string')
|
||||||
|
->nullable(false)
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->createManyToOne('provider', App\Domain\Entity\Provider::class)
|
||||||
|
->addJoinColumn('provider_id', 'id', false, false, 'CASCADE')
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->createManyToOne('season', App\Domain\Entity\Season::class)
|
||||||
|
->addJoinColumn('season_id', 'id', false, false, 'CASCADE')
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->createManyToOne('home', App\Domain\Entity\Team::class)
|
||||||
|
->addJoinColumn('home_team_id', 'id', false, false, 'CASCADE')
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->createManyToOne('away', App\Domain\Entity\Team::class)
|
||||||
|
->addJoinColumn('away_team_id', 'id', false, false, 'CASCADE')
|
||||||
|
->build();
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
$builder = new Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder($metadata);
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->setReadOnly()
|
||||||
|
->setTable('league')
|
||||||
|
;
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->createField('id', 'uuid')
|
||||||
|
->nullable(false)
|
||||||
|
->makePrimaryKey()
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->createField('providerLeagueId', 'uuid')
|
||||||
|
->columnName('provider_league_id')
|
||||||
|
->nullable(false)
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->createManyToOne('provider', 'App\\Domain\\Entity\\Provider')
|
||||||
|
->addJoinColumn('provider_id', 'id', false, false, 'CASCADE')
|
||||||
|
->build();
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
$builder = new Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder($metadata);
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->setReadOnly()
|
||||||
|
->setTable('season')
|
||||||
|
;
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->createField('id', 'uuid')
|
||||||
|
->nullable(false)
|
||||||
|
->makePrimaryKey()
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->createField('providerSeasonId', 'uuid')
|
||||||
|
->columnName('provider_season_id')
|
||||||
|
->nullable(false)
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->createField('year', 'integer')
|
||||||
|
->nullable(false)
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->createField('kind', 'string') // should be enum
|
||||||
|
->nullable(false)
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->createManyToOne('provider', App\Domain\Entity\Provider::class)
|
||||||
|
->addJoinColumn('provider_id', 'id', false, false, 'CASCADE')
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->createManyToOne('league', App\Domain\Entity\League::class)
|
||||||
|
->addJoinColumn('league_id', 'id', false, false, 'CASCADE')
|
||||||
|
->build();
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
$builder = new Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder($metadata);
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->setReadOnly()
|
||||||
|
->setTable('team')
|
||||||
|
;
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->createField('id', 'uuid')
|
||||||
|
->nullable(false)
|
||||||
|
->makePrimaryKey()
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->createField('providerTeamId', 'uuid')
|
||||||
|
->columnName('provider_team_id')
|
||||||
|
->nullable(false)
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->createField('name', 'string')
|
||||||
|
->nullable(false)
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->createField('alias', 'string')
|
||||||
|
->nullable(false)
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->createField('active', 'boolean')
|
||||||
|
->nullable(false)
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->createManyToOne('provider', App\Domain\Entity\Provider::class)
|
||||||
|
->addJoinColumn('provider_id', 'id', false, false, 'CASCADE')
|
||||||
|
->build();
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Infrastructure\SportRadar;
|
||||||
|
|
||||||
|
use App\Application\SportRadar\SportRadarEngine;
|
||||||
|
use App\Domain\Enum\ENHLSeasonType;
|
||||||
|
|
||||||
|
class FakeSportRadarEngine implements SportRadarEngine
|
||||||
|
{
|
||||||
|
public function getNHLSchedule(int $year, ENHLSeasonType $seasonType): array
|
||||||
|
{
|
||||||
|
if (2025 !== $year || ENHLSeasonType::REGULAR_SEASON !== $seasonType) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$fake_sport_radar_nhl_schedule = json_decode(file_get_contents(__DIR__ . '/Fixtures/sport_radar_nhl_schedule_2025_REG_19_12_2025.json'), true);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'league' => [
|
||||||
|
'providerId' => $fake_sport_radar_nhl_schedule['league']['id'],
|
||||||
|
'name' => $fake_sport_radar_nhl_schedule['league']['name'],
|
||||||
|
'alias' => $fake_sport_radar_nhl_schedule['league']['alias'],
|
||||||
|
],
|
||||||
|
'season' => [
|
||||||
|
'providerId' => $fake_sport_radar_nhl_schedule['season']['id'],
|
||||||
|
'year' => $fake_sport_radar_nhl_schedule['season']['year'],
|
||||||
|
'type' => ENHLSeasonType::from($fake_sport_radar_nhl_schedule['season']['type']),
|
||||||
|
],
|
||||||
|
'games' => array_map(fn ($game) => [
|
||||||
|
'providerId' => $game['id'],
|
||||||
|
'scheduled' => new \DateTimeImmutable($game['scheduled']),
|
||||||
|
'homeTeamProviderId' => $game['home']['id'],
|
||||||
|
'awayTeamProviderId' => $game['away']['id'],
|
||||||
|
'venueArena' => $game['venue']['name'],
|
||||||
|
], $fake_sport_radar_nhl_schedule['games']),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue