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\\.$#"
|
||||
paths:
|
||||
- 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;
|
||||
|
||||
class GetNHLMatchRequest
|
||||
class FetchNHLMatchRequest
|
||||
{
|
||||
public function __construct(
|
||||
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
|
||||
{
|
||||
private string $srId;
|
||||
private Provider $provider;
|
||||
private string $providerGameId;
|
||||
private Season $season;
|
||||
private \DateTimeImmutable $scheduled;
|
||||
private \DateTimeImmutable $startTimeScheduled;
|
||||
private ?\DateTimeImmutable $endTimeScheduled;
|
||||
private Team $home;
|
||||
private Team $away;
|
||||
private string $venue_arena;
|
||||
private string $venue;
|
||||
|
||||
public function create(
|
||||
string $srId,
|
||||
Provider $provider,
|
||||
string $providerGameId,
|
||||
Season $season,
|
||||
\DateTimeImmutable $scheduled,
|
||||
\DateTimeImmutable $startTimeScheduled,
|
||||
?\DateTimeImmutable $endTimeScheduled,
|
||||
Team $home,
|
||||
Team $away,
|
||||
string $venue_arena,
|
||||
string $venue,
|
||||
): void {
|
||||
$this->srId = $srId;
|
||||
$this->provider = $provider;
|
||||
$this->providerGameId = $providerGameId;
|
||||
$this->season = $season;
|
||||
$this->scheduled = $scheduled;
|
||||
$this->startTimeScheduled = $startTimeScheduled;
|
||||
$this->endTimeScheduled = $endTimeScheduled;
|
||||
$this->home = $home;
|
||||
$this->away = $away;
|
||||
$this->venue_arena = $venue_arena;
|
||||
$this->venue = $venue;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,17 @@ namespace App\Domain\Entity;
|
|||
|
||||
class League extends AEntity
|
||||
{
|
||||
private Provider $provider;
|
||||
private string $providerLeagueId;
|
||||
private string $name;
|
||||
|
||||
public function create(
|
||||
Provider $provider,
|
||||
string $providerLeagueId,
|
||||
string $name,
|
||||
): void {
|
||||
$this->provider = $provider;
|
||||
$this->providerLeagueId = $providerLeagueId;
|
||||
$this->name = $name;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,5 +11,4 @@ class Provider extends AEntity
|
|||
): void {
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -6,17 +6,23 @@ namespace App\Domain\Entity;
|
|||
|
||||
class Season extends AEntity
|
||||
{
|
||||
private Provider $provider;
|
||||
private string $providerSeasonId;
|
||||
private League $league;
|
||||
private string $type; // should be an enum
|
||||
private int $year;
|
||||
private string $kind; // should be an enum
|
||||
|
||||
public function create(
|
||||
Provider $provider,
|
||||
string $providerSeasonId,
|
||||
League $league,
|
||||
string $type,
|
||||
string $kind,
|
||||
int $year,
|
||||
): void {
|
||||
$this->provider = $provider;
|
||||
$this->providerSeasonId = $providerSeasonId;
|
||||
$this->league = $league;
|
||||
$this->type = $type;
|
||||
$this->kind = $kind;
|
||||
$this->year = $year;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,17 +6,23 @@ namespace App\Domain\Entity;
|
|||
|
||||
class Team extends AEntity
|
||||
{
|
||||
private Provider $provider;
|
||||
private string $providerTeamId;
|
||||
private string $name;
|
||||
private string $alias;
|
||||
private string $sr_id;
|
||||
private bool $active;
|
||||
|
||||
public function create(
|
||||
Provider $provider,
|
||||
string $providerTeamId,
|
||||
string $name,
|
||||
string $alias,
|
||||
string $sr_id,
|
||||
bool $active,
|
||||
): void {
|
||||
$this->provider = $provider;
|
||||
$this->providerTeamId = $providerTeamId;
|
||||
$this->name = $name;
|
||||
$this->alias = $alias;
|
||||
$this->sr_id = $sr_id;
|
||||
$this->active = $active;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
namespace App\Infrastructure\Console;
|
||||
|
||||
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\Command\Command;
|
||||
|
||||
|
|
@ -17,7 +17,7 @@ class GetNHLScheduleCommand
|
|||
|
||||
public function __invoke(): int
|
||||
{
|
||||
$this->commandBus->ask(new GetNHLMatchRequest(2025, 'REG'));
|
||||
$this->commandBus->ask(new FetchNHLMatchRequest(2025, 'REG'));
|
||||
|
||||
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