feat: architecture
Signed-off-by: Superkooka <aymeric.gueracague@gmail.com>
This commit is contained in:
parent
2b7144614f
commit
aa12eb92a4
|
|
@ -25,3 +25,5 @@ APP_SHARE_DIR=var/share
|
||||||
# See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
|
# See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
|
||||||
DEFAULT_URI=http://localhost
|
DEFAULT_URI=http://localhost
|
||||||
###< symfony/routing ###
|
###< symfony/routing ###
|
||||||
|
|
||||||
|
SPORT_RADAR_APIKEY=
|
||||||
4
Makefile
4
Makefile
|
|
@ -15,6 +15,10 @@ build:
|
||||||
install:
|
install:
|
||||||
docker-compose -f docker-compose.yaml run --rm nhl-schedule composer install
|
docker-compose -f docker-compose.yaml run --rm nhl-schedule composer install
|
||||||
|
|
||||||
|
.PHONY: run
|
||||||
|
run:
|
||||||
|
docker-compose -f docker-compose.yaml run --rm nhl-schedule php bin/console app:get-nhl-schedule
|
||||||
|
|
||||||
.PHONY: static-check
|
.PHONY: static-check
|
||||||
static-check:
|
static-check:
|
||||||
docker-compose -f docker-compose.yaml run --rm nhl-schedule php -d memory_limit=4G vendor/bin/phpstan analyse -c phpstan.neon
|
docker-compose -f docker-compose.yaml run --rm nhl-schedule php -d memory_limit=4G vendor/bin/phpstan analyse -c phpstan.neon
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
"symfony/dotenv": "8.0.*",
|
"symfony/dotenv": "8.0.*",
|
||||||
"symfony/flex": "^2",
|
"symfony/flex": "^2",
|
||||||
"symfony/framework-bundle": "8.0.*",
|
"symfony/framework-bundle": "8.0.*",
|
||||||
|
"symfony/http-client": "8.0.*",
|
||||||
"symfony/runtime": "8.0.*",
|
"symfony/runtime": "8.0.*",
|
||||||
"symfony/yaml": "8.0.*"
|
"symfony/yaml": "8.0.*"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "1319f86cd294d1bc92527e45febb8246",
|
"content-hash": "43beda2ab15c41986add9f99a79923ae",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "psr/cache",
|
"name": "psr/cache",
|
||||||
|
|
@ -1367,6 +1367,180 @@
|
||||||
],
|
],
|
||||||
"time": "2025-12-06T16:55:34+00:00"
|
"time": "2025-12-06T16:55:34+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/http-client",
|
||||||
|
"version": "v8.0.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/http-client.git",
|
||||||
|
"reference": "727fda60d0aebfdfcc4c8bc4661f0cb8f44153c0"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/http-client/zipball/727fda60d0aebfdfcc4c8bc4661f0cb8f44153c0",
|
||||||
|
"reference": "727fda60d0aebfdfcc4c8bc4661f0cb8f44153c0",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=8.4",
|
||||||
|
"psr/log": "^1|^2|^3",
|
||||||
|
"symfony/http-client-contracts": "~3.4.4|^3.5.2",
|
||||||
|
"symfony/service-contracts": "^2.5|^3"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"amphp/amp": "<3",
|
||||||
|
"php-http/discovery": "<1.15"
|
||||||
|
},
|
||||||
|
"provide": {
|
||||||
|
"php-http/async-client-implementation": "*",
|
||||||
|
"php-http/client-implementation": "*",
|
||||||
|
"psr/http-client-implementation": "1.0",
|
||||||
|
"symfony/http-client-implementation": "3.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"amphp/http-client": "^5.3.2",
|
||||||
|
"amphp/http-tunnel": "^2.0",
|
||||||
|
"guzzlehttp/promises": "^1.4|^2.0",
|
||||||
|
"nyholm/psr7": "^1.0",
|
||||||
|
"php-http/httplug": "^1.0|^2.0",
|
||||||
|
"psr/http-client": "^1.0",
|
||||||
|
"symfony/cache": "^7.4|^8.0",
|
||||||
|
"symfony/dependency-injection": "^7.4|^8.0",
|
||||||
|
"symfony/http-kernel": "^7.4|^8.0",
|
||||||
|
"symfony/messenger": "^7.4|^8.0",
|
||||||
|
"symfony/process": "^7.4|^8.0",
|
||||||
|
"symfony/rate-limiter": "^7.4|^8.0",
|
||||||
|
"symfony/stopwatch": "^7.4|^8.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Component\\HttpClient\\": ""
|
||||||
|
},
|
||||||
|
"exclude-from-classmap": [
|
||||||
|
"/Tests/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Nicolas Grekas",
|
||||||
|
"email": "p@tchwork.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"http"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/http-client/tree/v8.0.1"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/nicolas-grekas",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2025-12-05T14:08:45+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/http-client-contracts",
|
||||||
|
"version": "v3.6.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/http-client-contracts.git",
|
||||||
|
"reference": "75d7043853a42837e68111812f4d964b01e5101c"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/75d7043853a42837e68111812f4d964b01e5101c",
|
||||||
|
"reference": "75d7043853a42837e68111812f4d964b01e5101c",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=8.1"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"thanks": {
|
||||||
|
"url": "https://github.com/symfony/contracts",
|
||||||
|
"name": "symfony/contracts"
|
||||||
|
},
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-main": "3.6-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Contracts\\HttpClient\\": ""
|
||||||
|
},
|
||||||
|
"exclude-from-classmap": [
|
||||||
|
"/Test/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Nicolas Grekas",
|
||||||
|
"email": "p@tchwork.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Generic abstractions related to HTTP clients",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"abstractions",
|
||||||
|
"contracts",
|
||||||
|
"decoupling",
|
||||||
|
"interfaces",
|
||||||
|
"interoperability",
|
||||||
|
"standards"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/http-client-contracts/tree/v3.6.0"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2025-04-29T11:18:49+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/http-foundation",
|
"name": "symfony/http-foundation",
|
||||||
"version": "v8.0.1",
|
"version": "v8.0.1",
|
||||||
|
|
|
||||||
|
|
@ -463,7 +463,7 @@ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||||
* },
|
* },
|
||||||
* disallow_search_engine_index?: bool, // Enabled by default when debug is enabled. // Default: true
|
* disallow_search_engine_index?: bool, // Enabled by default when debug is enabled. // Default: true
|
||||||
* http_client?: bool|array{ // HTTP Client configuration
|
* http_client?: bool|array{ // HTTP Client configuration
|
||||||
* enabled?: bool, // Default: false
|
* enabled?: bool, // Default: true
|
||||||
* max_host_connections?: int, // The maximum number of connections to a single host.
|
* max_host_connections?: int, // The maximum number of connections to a single host.
|
||||||
* default_options?: array{
|
* default_options?: array{
|
||||||
* headers?: array<string, mixed>,
|
* headers?: array<string, mixed>,
|
||||||
|
|
|
||||||
|
|
@ -7,17 +7,23 @@
|
||||||
# Put parameters here that don't need to change on each machine where the app is deployed
|
# Put parameters here that don't need to change on each machine where the app is deployed
|
||||||
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
|
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
|
||||||
parameters:
|
parameters:
|
||||||
|
app.sport_radar_apikey: '%env(SPORT_RADAR_APIKEY)%'
|
||||||
services:
|
services:
|
||||||
# default configuration for services in *this* file
|
|
||||||
_defaults:
|
_defaults:
|
||||||
autowire: true # Automatically injects dependencies in your services.
|
autowire: true # Automatically injects dependencies in your services.
|
||||||
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
|
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
|
||||||
|
|
||||||
# makes classes in src/ available to be used as services
|
|
||||||
# this creates a service per class whose id is the fully-qualified class name
|
|
||||||
App\:
|
App\:
|
||||||
resource: '../src/'
|
resource: '../src/'
|
||||||
|
|
||||||
# add more service definitions when explicit configuration is needed
|
App\Application\CommandBus\UseCaseCommandBus:
|
||||||
# please note that last definitions always *replace* previous ones
|
arguments:
|
||||||
|
$handlers: !tagged_iterator 'app.usecase'
|
||||||
|
|
||||||
|
App\Application\UseCase\:
|
||||||
|
resource: '../src/Application/UseCase/'
|
||||||
|
tags: ['app.usecase']
|
||||||
|
exclude:
|
||||||
|
- '../src/Application/UseCase/*Request.php'
|
||||||
|
|
||||||
|
App\Application\SportRadar\SportRadarEngine: '@App\Infrastructure\SportRadar\HTTPSportRadarEngine'
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -2,3 +2,8 @@ parameters:
|
||||||
level: 8
|
level: 8
|
||||||
paths:
|
paths:
|
||||||
- src
|
- src
|
||||||
|
ignoreErrors:
|
||||||
|
-
|
||||||
|
message: "#^Property .+::.+ is never read, only written\\.$#"
|
||||||
|
paths:
|
||||||
|
- src/Domain/Entity/*.php
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Application\CommandBus;
|
||||||
|
|
||||||
|
class UseCaseCommandBus
|
||||||
|
{
|
||||||
|
/** @var array<class-string, callable> */
|
||||||
|
private array $handlers = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param iterable<object> $handlers
|
||||||
|
*/
|
||||||
|
public function __construct(iterable $handlers)
|
||||||
|
{
|
||||||
|
foreach ($handlers as $handler) {
|
||||||
|
$this->handlers[$this->resolveQueryClass($handler)] = $handler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ask(object $query): mixed
|
||||||
|
{
|
||||||
|
$queryClass = $query::class;
|
||||||
|
|
||||||
|
if (!isset($this->handlers[$queryClass])) {
|
||||||
|
throw new \RuntimeException(sprintf('No query handler found for %s', $queryClass));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ($this->handlers[$queryClass])($query);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function resolveQueryClass(object $handler): string
|
||||||
|
{
|
||||||
|
$reflection = new \ReflectionMethod($handler, '__invoke');
|
||||||
|
$param = $reflection->getParameters()[0];
|
||||||
|
|
||||||
|
$type = $param->getType();
|
||||||
|
|
||||||
|
if (!$type instanceof \ReflectionNamedType) {
|
||||||
|
throw new \RuntimeException('Handler parameter must have a single named type');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $type->getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Application\SportRadar;
|
||||||
|
|
||||||
|
interface SportRadarEngine
|
||||||
|
{
|
||||||
|
public function getNHLSchedule(): void;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Application\UseCase;
|
||||||
|
|
||||||
|
class GetNHLMatch
|
||||||
|
{
|
||||||
|
public function __invoke(GetNHLMatchRequest $request): void
|
||||||
|
{
|
||||||
|
dd($request->type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Application\UseCase;
|
||||||
|
|
||||||
|
class GetNHLMatchRequest
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public readonly string $type,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Domain\Entity;
|
||||||
|
|
||||||
|
abstract class AEntity
|
||||||
|
{
|
||||||
|
protected string $id;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->id = $this->generateUUIDv4();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Grégoire Pineau <lyrixx@lyrixx.info>
|
||||||
|
*
|
||||||
|
* https://github.com/symfony/polyfill-uuid/blob/a41886c1c81dc075a09c71fe6db5b9d68c79de23/Uuid.php#L378-L438
|
||||||
|
*/
|
||||||
|
private function generateUUIDv4(): string
|
||||||
|
{
|
||||||
|
$timeOffsetInt = 0x01B21DD213814000;
|
||||||
|
|
||||||
|
$time = microtime(false);
|
||||||
|
$time = substr($time, 11) . substr($time, 2, 7);
|
||||||
|
|
||||||
|
$time = str_pad(dechex((int) $time + $timeOffsetInt), 16, '0', \STR_PAD_LEFT);
|
||||||
|
|
||||||
|
// https://tools.ietf.org/html/rfc4122#section-4.1.5
|
||||||
|
// We are using a random data for the sake of simplicity: since we are
|
||||||
|
// not able to get a super precise timeOfDay as a unique sequence
|
||||||
|
$clockSeq = random_int(0, 0x3FFF);
|
||||||
|
|
||||||
|
static $node;
|
||||||
|
if (null === $node) {
|
||||||
|
if (\function_exists('apcu_fetch')) {
|
||||||
|
$node = apcu_fetch('__symfony_uuid_node');
|
||||||
|
if (false === $node) {
|
||||||
|
$node = sprintf(
|
||||||
|
'%06x%06x',
|
||||||
|
random_int(0, 0xFFFFFF) | 0x010000,
|
||||||
|
random_int(0, 0xFFFFFF)
|
||||||
|
);
|
||||||
|
apcu_store('__symfony_uuid_node', $node);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$node = sprintf(
|
||||||
|
'%06x%06x',
|
||||||
|
random_int(0, 0xFFFFFF) | 0x010000,
|
||||||
|
random_int(0, 0xFFFFFF)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprintf(
|
||||||
|
'%08s-%04s-1%03s-%04x-%012s',
|
||||||
|
// 32 bits for "time_low"
|
||||||
|
substr($time, -8),
|
||||||
|
|
||||||
|
// 16 bits for "time_mid"
|
||||||
|
substr($time, -12, 4),
|
||||||
|
|
||||||
|
// 16 bits for "time_hi_and_version",
|
||||||
|
// four most significant bits holds version number 1
|
||||||
|
substr($time, -15, 3),
|
||||||
|
|
||||||
|
// 16 bits:
|
||||||
|
// * 8 bits for "clk_seq_hi_res",
|
||||||
|
// * 8 bits for "clk_seq_low",
|
||||||
|
// two most significant bits holds zero and one for variant DCE1.1
|
||||||
|
$clockSeq | 0x8000,
|
||||||
|
|
||||||
|
// 48 bits for "node"
|
||||||
|
$node
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Domain\Entity;
|
||||||
|
|
||||||
|
class Game extends AEntity
|
||||||
|
{
|
||||||
|
private string $srId;
|
||||||
|
private Season $season;
|
||||||
|
private \DateTimeImmutable $scheduled;
|
||||||
|
private Team $home;
|
||||||
|
private Team $away;
|
||||||
|
private string $venue_arena;
|
||||||
|
|
||||||
|
public function create(
|
||||||
|
string $srId,
|
||||||
|
Season $season,
|
||||||
|
\DateTimeImmutable $scheduled,
|
||||||
|
Team $home,
|
||||||
|
Team $away,
|
||||||
|
string $venue_arena,
|
||||||
|
): void {
|
||||||
|
$this->srId = $srId;
|
||||||
|
$this->season = $season;
|
||||||
|
$this->scheduled = $scheduled;
|
||||||
|
$this->home = $home;
|
||||||
|
$this->away = $away;
|
||||||
|
$this->venue_arena = $venue_arena;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Domain\Entity;
|
||||||
|
|
||||||
|
class League extends AEntity
|
||||||
|
{
|
||||||
|
private string $name;
|
||||||
|
|
||||||
|
public function create(
|
||||||
|
string $name,
|
||||||
|
): void {
|
||||||
|
$this->name = $name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Domain\Entity;
|
||||||
|
|
||||||
|
class Season extends AEntity
|
||||||
|
{
|
||||||
|
private League $league;
|
||||||
|
private string $type; // should be an enum
|
||||||
|
private int $year;
|
||||||
|
|
||||||
|
public function create(
|
||||||
|
League $league,
|
||||||
|
string $type,
|
||||||
|
int $year,
|
||||||
|
): void {
|
||||||
|
$this->league = $league;
|
||||||
|
$this->type = $type;
|
||||||
|
$this->year = $year;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Domain\Entity;
|
||||||
|
|
||||||
|
class Team extends AEntity
|
||||||
|
{
|
||||||
|
private string $name;
|
||||||
|
private string $alias;
|
||||||
|
private string $sr_id;
|
||||||
|
|
||||||
|
public function create(
|
||||||
|
string $name,
|
||||||
|
string $alias,
|
||||||
|
string $sr_id,
|
||||||
|
): void {
|
||||||
|
$this->name = $name;
|
||||||
|
$this->alias = $alias;
|
||||||
|
$this->sr_id = $sr_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Infrastructure\Console;
|
||||||
|
|
||||||
|
use App\Application\CommandBus\UseCaseCommandBus;
|
||||||
|
use App\Application\UseCase\GetNHLMatchRequest;
|
||||||
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
|
||||||
|
#[AsCommand(name: 'app:get-nhl-schedule')]
|
||||||
|
class GetNHLScheduleCommand
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private readonly UseCaseCommandBus $commandBus,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __invoke(): int
|
||||||
|
{
|
||||||
|
$this->commandBus->ask(new GetNHLMatchRequest('REG'));
|
||||||
|
|
||||||
|
return Command::SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Infrastructure\SportRadar;
|
||||||
|
|
||||||
|
use App\Application\SportRadar\SportRadarEngine;
|
||||||
|
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||||
|
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||||
|
|
||||||
|
class HTTPSportRadarEngine implements SportRadarEngine
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private HttpClientInterface $client,
|
||||||
|
#[Autowire('%app.sport_radar_apikey%')]
|
||||||
|
string $apiKey,
|
||||||
|
) {
|
||||||
|
$this->client = $client->withOptions(
|
||||||
|
[
|
||||||
|
'headers' => [
|
||||||
|
'x-api-key' => $apiKey,
|
||||||
|
'accept' => 'application/json',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getNHLSchedule(): void
|
||||||
|
{
|
||||||
|
$response = $this->client->request('GET', 'https://api.sportradar.com/nhl/trial/v7/en/games/2025/REG/schedule.json');
|
||||||
|
|
||||||
|
// return ['a'];
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue