Skip to content

Commit 17d3153

Browse files
committed
feat: added geocoding resource and lots of cleanup
1 parent 7e65155 commit 17d3153

24 files changed

+127
-686
lines changed

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
],
1414
"require": {
1515
"php": ">=8.1",
16-
"programmatordev/php-api-sdk": "^0.1.0",
16+
"programmatordev/php-api-sdk": "^0.2.0",
1717
"programmatordev/yet-another-php-validator": "^1.1"
1818
},
1919
"require-dev": {

src/Entity/Geocoding/ZipCodeLocation.php

-47
This file was deleted.

src/Entity/Location.php

+10-44
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
class Location
66
{
7-
private ?int $id;
8-
97
private ?string $name;
108

119
private ?string $state;
@@ -14,36 +12,18 @@ class Location
1412

1513
private ?array $localNames;
1614

17-
private ?int $population;
15+
private ?string $zipCode;
1816

1917
private Coordinate $coordinate;
2018

21-
private ?Timezone $timezone;
22-
23-
private ?\DateTimeImmutable $sunriseAt;
24-
25-
private ?\DateTimeImmutable $sunsetAt;
26-
2719
public function __construct(array $data)
2820
{
29-
$this->coordinate = new Coordinate([
30-
'lat' => $data['lat'],
31-
'lon' => $data['lon']
32-
]);
33-
$this->id = !empty($data['id']) ? $data['id'] : null;
34-
$this->name = !empty($data['name']) ? $data['name'] : null;
35-
$this->state = !empty($data['state']) ? $data['state'] : null;
36-
$this->countryCode = !empty($data['country']) ? $data['country'] : null;
37-
$this->localNames = !empty($data['local_names']) ? $data['local_names'] : null;
38-
$this->population = !empty($data['population']) ? $data['population'] : null;
39-
$this->sunriseAt = !empty($data['sunrise']) ? \DateTimeImmutable::createFromFormat('U', $data['sunrise'], new \DateTimeZone('UTC')) : null;
40-
$this->sunsetAt = !empty($data['sunset']) ? \DateTimeImmutable::createFromFormat('U', $data['sunset'], new \DateTimeZone('UTC')) : null;
41-
$this->timezone = isset($data['timezone_offset']) ? new Timezone(['timezone_offset' => $data['timezone_offset']]) : null;
42-
}
43-
44-
public function getId(): ?int
45-
{
46-
return $this->id;
21+
$this->name = $data['name'] ?? null;
22+
$this->state = $data['state'] ?? null;
23+
$this->countryCode = $data['country'] ?? null;
24+
$this->localNames = $data['local_names'] ?? null;
25+
$this->zipCode = $data['zip'] ?? null;
26+
$this->coordinate = new Coordinate(['lat' => $data['lat'], 'lon' => $data['lon']]);
4727
}
4828

4929
public function getName(): ?string
@@ -69,31 +49,17 @@ public function getLocalNames(): ?array
6949
public function getLocalName(string $countryCode): ?string
7050
{
7151
$countryCode = strtolower($countryCode);
52+
7253
return $this->localNames[$countryCode] ?? null;
7354
}
7455

75-
public function getPopulation(): ?int
56+
public function getZipCode(): ?string
7657
{
77-
return $this->population;
58+
return $this->zipCode;
7859
}
7960

8061
public function getCoordinate(): Coordinate
8162
{
8263
return $this->coordinate;
8364
}
84-
85-
public function getTimezone(): ?Timezone
86-
{
87-
return $this->timezone;
88-
}
89-
90-
public function getSunriseAt(): ?\DateTimeImmutable
91-
{
92-
return $this->sunriseAt;
93-
}
94-
95-
public function getSunsetAt(): ?\DateTimeImmutable
96-
{
97-
return $this->sunsetAt;
98-
}
9965
}

src/Language/Language.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
namespace ProgrammatorDev\OpenWeatherMap\Language;
44

5-
use ProgrammatorDev\OpenWeatherMap\Util\ClassConstantsTrait;
5+
use ProgrammatorDev\OpenWeatherMap\Util\ReflectionTrait;
66

77
class Language
88
{
9-
use ClassConstantsTrait;
9+
use ReflectionTrait;
1010

1111
public const AFRIKAANS = 'af';
1212
public const ALBANIAN = 'al';

src/OpenWeatherMap.php

+7-5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use ProgrammatorDev\OpenWeatherMap\Exception\UnauthorizedException;
1313
use ProgrammatorDev\OpenWeatherMap\Exception\UnexpectedErrorException;
1414
use ProgrammatorDev\OpenWeatherMap\Language\Language;
15+
use ProgrammatorDev\OpenWeatherMap\Resource\GeocodingResource;
1516
use ProgrammatorDev\OpenWeatherMap\UnitSystem\UnitSystem;
1617

1718
class OpenWeatherMap extends Api
@@ -27,6 +28,12 @@ public function __construct(
2728

2829
$this->options = $this->configureOptions($options);
2930
$this->configureApi();
31+
32+
}
33+
34+
public function geocoding(): GeocodingResource
35+
{
36+
return new GeocodingResource($this);
3037
}
3138

3239
// public function config(): Config
@@ -47,11 +54,6 @@ public function __construct(
4754
// public function airPollution(): AirPollutionEndpoint
4855
// {
4956
// return new AirPollutionEndpoint($this);
50-
// }
51-
//
52-
// public function geocoding(): GeocodingEndpoint
53-
// {
54-
// return new GeocodingEndpoint($this);
5557
// }
5658

5759
private function configureOptions(array $options): array

src/Endpoint/GeocodingEndpoint.php renamed to src/Resource/GeocodingResource.php

+25-28
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,36 @@
11
<?php
22

3-
namespace ProgrammatorDev\OpenWeatherMap\Endpoint;
3+
namespace ProgrammatorDev\OpenWeatherMap\Resource;
44

5-
use Http\Client\Exception;
6-
use ProgrammatorDev\OpenWeatherMap\Endpoint\Util\ValidationTrait;
7-
use ProgrammatorDev\OpenWeatherMap\Entity\Geocoding\ZipCodeLocation;
5+
use ProgrammatorDev\Api\Method;
86
use ProgrammatorDev\OpenWeatherMap\Entity\Location;
9-
use ProgrammatorDev\OpenWeatherMap\Exception\ApiErrorException;
10-
use ProgrammatorDev\OpenWeatherMap\Util\EntityListTrait;
11-
use ProgrammatorDev\YetAnotherPhpValidator\Exception\ValidationException;
7+
use ProgrammatorDev\OpenWeatherMap\OpenWeatherMap;
8+
use ProgrammatorDev\OpenWeatherMap\Resource\Util\ValidationTrait;
9+
use ProgrammatorDev\OpenWeatherMap\Util\EntityTrait;
10+
use ProgrammatorDev\Validator\Exception\ValidationException;
11+
use Psr\Http\Client\ClientExceptionInterface;
1212

13-
class GeocodingEndpoint extends AbstractEndpoint
13+
class GeocodingResource
1414
{
15+
use EntityTrait;
1516
use ValidationTrait;
16-
use EntityListTrait;
1717

1818
private const NUM_RESULTS = 5;
1919

20-
protected int $cacheTtl = 60 * 60 * 24 * 30; // 30 days
20+
public function __construct(private readonly OpenWeatherMap $api) {}
2121

2222
/**
2323
* @return Location[]
24-
* @throws Exception
25-
* @throws ApiErrorException
24+
* @throws ClientExceptionInterface
2625
* @throws ValidationException
2726
*/
2827
public function getByLocationName(string $locationName, int $numResults = self::NUM_RESULTS): array
2928
{
30-
$this->validateSearchQuery($locationName, 'locationName');
31-
$this->validateNumResults($numResults);
29+
$this->validateQuery($locationName, 'locationName');
30+
$this->validatePositive($numResults, 'numResults');
3231

33-
$data = $this->sendRequest(
34-
method: 'GET',
32+
$data = $this->api->request(
33+
method: Method::GET,
3534
path: '/geo/1.0/direct',
3635
query: [
3736
'q' => $locationName,
@@ -43,39 +42,37 @@ public function getByLocationName(string $locationName, int $numResults = self::
4342
}
4443

4544
/**
46-
* @throws Exception
47-
* @throws ApiErrorException
45+
* @throws ClientExceptionInterface
4846
* @throws ValidationException
4947
*/
50-
public function getByZipCode(string $zipCode, string $countryCode): ZipCodeLocation
48+
public function getByZipCode(string $zipCode, string $countryCode): Location
5149
{
52-
$this->validateSearchQuery($zipCode, 'zipCode');
53-
$this->validateCountryCode($countryCode);
50+
$this->validateQuery($zipCode, 'zipCode');
51+
$this->validateCountry($countryCode, 'countryCode');
5452

55-
$data = $this->sendRequest(
53+
$data = $this->api->request(
5654
method: 'GET',
5755
path: '/geo/1.0/zip',
5856
query: [
5957
'zip' => \sprintf('%s,%s', $zipCode, $countryCode)
6058
]
6159
);
6260

63-
return new ZipCodeLocation($data);
61+
return new Location($data);
6462
}
6563

6664
/**
6765
* @return Location[]
68-
* @throws Exception
69-
* @throws ApiErrorException
66+
* @throws ClientExceptionInterface
7067
* @throws ValidationException
7168
*/
7269
public function getByCoordinate(float $latitude, float $longitude, int $numResults = self::NUM_RESULTS): array
7370
{
7471
$this->validateCoordinate($latitude, $longitude);
75-
$this->validateNumResults($numResults);
72+
$this->validatePositive($numResults, 'numResults');
7673

77-
$data = $this->sendRequest(
78-
method: 'GET',
74+
$data = $this->api->request(
75+
method: Method::GET,
7976
path: '/geo/1.0/reverse',
8077
query: [
8178
'lat' => $latitude,

src/Resource/Util/ValidationTrait.php

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace ProgrammatorDev\OpenWeatherMap\Resource\Util;
4+
5+
use ProgrammatorDev\Validator\Exception\ValidationException;
6+
use ProgrammatorDev\Validator\Validator;
7+
8+
trait ValidationTrait
9+
{
10+
/**
11+
* @throws ValidationException
12+
*/
13+
private function validateQuery(string $query, string $name): void
14+
{
15+
Validator::notBlank()->assert($query, $name);
16+
}
17+
18+
/**
19+
* @throws ValidationException
20+
*/
21+
private function validatePositive(int $number, string $name): void
22+
{
23+
Validator::greaterThan(0)->assert($number, $name);
24+
}
25+
26+
/**
27+
* @throws ValidationException
28+
*/
29+
private function validateCoordinate(float $latitude, float $longitude): void
30+
{
31+
Validator::range(-90, 90)->assert($latitude, 'latitude');
32+
Validator::range(-180, 180)->assert($longitude, 'longitude');
33+
}
34+
35+
/**
36+
* @throws ValidationException
37+
*/
38+
private function validateCountry(string $countryCode, string $name): void
39+
{
40+
Validator::country()->assert($countryCode, $name);
41+
}
42+
}

src/Test/AbstractTest.php

+8-14
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,24 @@
44

55
use Http\Mock\Client;
66
use PHPUnit\Framework\TestCase;
7-
use ProgrammatorDev\OpenWeatherMap\Config;
8-
use ProgrammatorDev\OpenWeatherMap\HttpClient\HttpClientBuilder;
7+
use ProgrammatorDev\Api\Builder\ClientBuilder;
98
use ProgrammatorDev\OpenWeatherMap\OpenWeatherMap;
109

1110
class AbstractTest extends TestCase
1211
{
13-
protected const APPLICATION_KEY = 'testappkey';
12+
protected const API_KEY = 'testapikey';
1413

15-
protected Client $mockHttpClient;
14+
protected OpenWeatherMap $api;
15+
16+
protected Client $mockClient;
1617

1718
protected function setUp(): void
1819
{
1920
parent::setUp();
2021

21-
$this->mockHttpClient = new Client();
22-
}
22+
$this->mockClient = new Client();
2323

24-
protected function givenApi(): OpenWeatherMap
25-
{
26-
return new OpenWeatherMap(
27-
new Config([
28-
'applicationKey' => self::APPLICATION_KEY,
29-
'httpClientBuilder' => new HttpClientBuilder($this->mockHttpClient)
30-
])
31-
);
24+
$this->api = new OpenWeatherMap(self::API_KEY);
25+
$this->api->setClientBuilder(new ClientBuilder($this->mockClient));
3226
}
3327
}

src/UnitSystem/UnitSystem.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
namespace ProgrammatorDev\OpenWeatherMap\UnitSystem;
44

5-
use ProgrammatorDev\OpenWeatherMap\Util\ClassConstantsTrait;
5+
use ProgrammatorDev\OpenWeatherMap\Util\ReflectionTrait;
66

77
class UnitSystem
88
{
9-
use ClassConstantsTrait;
9+
use ReflectionTrait;
1010

1111
public const METRIC = 'metric';
1212
public const IMPERIAL = 'imperial';

0 commit comments

Comments
 (0)