From 120dee172b28bdab83eb10772bff56a63088299f Mon Sep 17 00:00:00 2001 From: Oh Martin Date: Thu, 4 Sep 2025 14:47:18 +0200 Subject: [PATCH 1/2] PKG --- app/dependencies.php | 2 +- app/repositories.php | 2 +- app/routes.php | 2 +- composer.json | 63 ++++--------------- .../Actions/Weather/GetWeatherAction.php | 4 +- .../User/InMemoryUserRepository.php | 2 +- .../Provider/SlimWeatherProvider.php | 46 ++++++++++++++ src/Service/OpenWeatherClient.php | 2 +- .../User/InMemoryUserRepositoryTest.php | 2 +- 9 files changed, 67 insertions(+), 58 deletions(-) create mode 100644 src/Infrastructure/Provider/SlimWeatherProvider.php diff --git a/app/dependencies.php b/app/dependencies.php index 77e6ae6..8f7f74c 100644 --- a/app/dependencies.php +++ b/app/dependencies.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Application\Settings\SettingsInterface; -use App\Service\OpenWeatherClient; +use Ohrionmartin\Weather\Service\OpenWeatherClient; use GuzzleHttp\Client; use DI\ContainerBuilder; use Monolog\Handler\StreamHandler; diff --git a/app/repositories.php b/app/repositories.php index 15f20f3..2648661 100644 --- a/app/repositories.php +++ b/app/repositories.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Domain\User\UserRepository; -use App\Infrastructure\Persistence\User\InMemoryUserRepository; +use Ohrionmartin\Weather\Infrastructure\Persistence\User\InMemoryUserRepository; use DI\ContainerBuilder; return function (ContainerBuilder $containerBuilder) { diff --git a/app/routes.php b/app/routes.php index 0c73de7..dbc49da 100644 --- a/app/routes.php +++ b/app/routes.php @@ -4,7 +4,7 @@ declare(strict_types=1); use App\Application\Actions\User\ListUsersAction; use App\Application\Actions\User\ViewUserAction; -use App\Application\Actions\Weather\GetWeatherAction; +use Ohrionmartin\Weather\Application\Actions\Weather\GetWeatherAction; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; use Slim\App; diff --git a/composer.json b/composer.json index cfb6737..4a2a371 100644 --- a/composer.json +++ b/composer.json @@ -1,63 +1,26 @@ { - "name": "slim/slim-skeleton", - "description": "A Slim Framework skeleton application for rapid development", - "keywords": [ - "microframework", - "rest", - "router", - "psr7" - ], - "homepage": "http://github.com/slimphp/Slim-Skeleton", + "name": "ohrionmartin/weather", + "description": "Reusable Slim components for fetching weather via OpenWeather One Call API 3.0", + "type": "library", "license": "MIT", + "autoload": { + "psr-4": { + "Ohrionmartin\\Weather\\": "src/" + } + }, "authors": [ { - "name": "Josh Lockhart", - "email": "info@joshlockhart.com", - "homepage": "http://www.joshlockhart.com/" - }, - { - "name": "Pierre Berube", - "email": "pierre@lgse.com", - "homepage": "http://www.lgse.com/" + "name": "Oh Martin", + "email": "oh@nampharm.com.na" } ], + "minimum-stability": "stable", "require": { - "php": "^7.4 || ^8.0", - "ext-json": "*", - "guzzlehttp/guzzle": "^7", - "monolog/monolog": "^2.8", - "php-di/php-di": "^6.4", - "slim/psr7": "^1.5", - "slim/slim": "^4.10", - "vlucas/phpdotenv": "^5.6" - }, - "require-dev": { - "jangregor/phpstan-prophecy": "^1.0.0", - "phpspec/prophecy-phpunit": "^2.0", - "phpstan/extension-installer": "^1.2.0", - "phpstan/phpstan": "^1.8", - "phpunit/phpunit": "^9.5.26", - "squizlabs/php_codesniffer": "^3.7" + "ext-json": "*" }, "config": { "allow-plugins": { - "phpstan/extension-installer": true - }, - "process-timeout": 0, - "sort-packages": true - }, - "autoload": { - "psr-4": { - "App\\": "src/" + "phpstan/extension-installer": false } - }, - "autoload-dev": { - "psr-4": { - "Tests\\": "tests/" - } - }, - "scripts": { - "start": "php -S localhost:8080 -t public", - "test": "phpunit" } } diff --git a/src/Application/Actions/Weather/GetWeatherAction.php b/src/Application/Actions/Weather/GetWeatherAction.php index da56023..f3c7d85 100644 --- a/src/Application/Actions/Weather/GetWeatherAction.php +++ b/src/Application/Actions/Weather/GetWeatherAction.php @@ -2,9 +2,9 @@ declare(strict_types=1); -namespace App\Application\Actions\Weather; +namespace Ohrionmartin\Weather\Application\Actions\Weather; -use App\Service\OpenWeatherClient; +use Ohrionmartin\Weather\Service\OpenWeatherClient; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; diff --git a/src/Infrastructure/Persistence/User/InMemoryUserRepository.php b/src/Infrastructure/Persistence/User/InMemoryUserRepository.php index b85a74f..5e847b7 100644 --- a/src/Infrastructure/Persistence/User/InMemoryUserRepository.php +++ b/src/Infrastructure/Persistence/User/InMemoryUserRepository.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace App\Infrastructure\Persistence\User; +namespace Ohrionmartin\Weather\Infrastructure\Persistence\User; use App\Domain\User\User; use App\Domain\User\UserNotFoundException; diff --git a/src/Infrastructure/Provider/SlimWeatherProvider.php b/src/Infrastructure/Provider/SlimWeatherProvider.php new file mode 100644 index 0000000..db6b4a3 --- /dev/null +++ b/src/Infrastructure/Provider/SlimWeatherProvider.php @@ -0,0 +1,46 @@ +addDefinitions([ + Client::class => function () { + return new Client([ + 'headers' => [ + 'Accept' => 'application/json', + 'User-Agent' => 'Slim-Weather/1.0', + ], + ]); + }, + + OpenWeatherClient::class => function (ContainerInterface $c) { + $apiKey = $_ENV['OPENWEATHER_API_KEY'] ?? $_SERVER['OPENWEATHER_API_KEY'] ?? ''; + $baseUrl = 'https://api.openweathermap.org/data/3.0'; + + if ($apiKey === '') { + throw new \RuntimeException('OPENWEATHER_API_KEY is not configured'); + } + + return new OpenWeatherClient($c->get(Client::class), $apiKey, $baseUrl); + }, + ]); + } + + public static function routes(App $app): void + { + // Expose a ready-to-use endpoint for consumers (optional) + $app->get('/weather', GetWeatherAction::class); + } +} diff --git a/src/Service/OpenWeatherClient.php b/src/Service/OpenWeatherClient.php index da03a18..c5c53b3 100644 --- a/src/Service/OpenWeatherClient.php +++ b/src/Service/OpenWeatherClient.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace App\Service; +namespace Ohrionmartin\Weather\Service; use GuzzleHttp\ClientInterface; use GuzzleHttp\Exception\GuzzleException; diff --git a/tests/Infrastructure/Persistence/User/InMemoryUserRepositoryTest.php b/tests/Infrastructure/Persistence/User/InMemoryUserRepositoryTest.php index 6b51b0c..fdeb575 100644 --- a/tests/Infrastructure/Persistence/User/InMemoryUserRepositoryTest.php +++ b/tests/Infrastructure/Persistence/User/InMemoryUserRepositoryTest.php @@ -6,7 +6,7 @@ namespace Tests\Infrastructure\Persistence\User; use App\Domain\User\User; use App\Domain\User\UserNotFoundException; -use App\Infrastructure\Persistence\User\InMemoryUserRepository; +use Ohrionmartin\Weather\Infrastructure\Persistence\User\InMemoryUserRepository; use Tests\TestCase; class InMemoryUserRepositoryTest extends TestCase From 24007122d8c63a2d19f25e15e099971b44175cd3 Mon Sep 17 00:00:00 2001 From: Oh Martin Date: Fri, 5 Sep 2025 09:49:19 +0200 Subject: [PATCH 2/2] require guzzlehttp --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 4a2a371..1091ef4 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,8 @@ ], "minimum-stability": "stable", "require": { - "ext-json": "*" + "ext-json": "*", + "guzzlehttp/guzzle": "^7.8" }, "config": { "allow-plugins": {