diff --git a/docs/03-supported-apis.md b/docs/03-supported-apis.md index afd06a1..ba99395 100644 --- a/docs/03-supported-apis.md +++ b/docs/03-supported-apis.md @@ -177,8 +177,6 @@ foreach ($airPollutionHistory->getList() as $airPollution) { #### `getByLocationName` -Get locations by location name. Returns an array of [`Location`](05-entities.md#location) entities: - ```php /** * @return Location[] @@ -186,14 +184,16 @@ Get locations by location name. Returns an array of [`Location`](05-entities.md# getByLocationName(string $locationName, int $numResults = 5): array ``` +Get locations by location name. + +Returns an array of [`Location`](05-entities.md#location) entities. + ```php -$api->geocoding()->getByLocationName('lisbon'); +$locations = $api->geocoding()->getByLocationName('lisbon'); ``` #### `getByCoordinate` -Get locations by coordinate. Returns an array of [`Location`](05-entities.md#location) entities: - ```php /** * @return Location[] @@ -201,20 +201,26 @@ Get locations by coordinate. Returns an array of [`Location`](05-entities.md#loc getByCoordinate(float $latitude, float $longitude, int $numResults = 5): array ``` +Get locations by coordinate. + +Returns an array of [`Location`](05-entities.md#location) entities. + ```php -$api->geocoding()->getByCoordinate(50, 50); +$locations = $api->geocoding()->getByCoordinate(50, 50); ``` #### `getByZipCode` -Get location by zip code. Returns a [`Location`](05-entities.md#location) entity: - ```php -getByZipCode(string $zipCode, string $countryCode): Location +getByZipCode(string $zipCode, string $countryCode): ZipLocation ``` +Get location by zip code. + +Returns a [`ZipLocation`](05-entities.md#ziplocation) entity. + ```php -$api->geocoding()->getByZipCode('1000-001', 'pt'); +$location = $api->geocoding()->getByZipCode('1000-001', 'pt'); ``` ## Common Methods @@ -260,25 +266,25 @@ $openWeatherMap->weather() #### `withCacheTtl` ```php -withCacheTtl(int $seconds): self +withCacheTtl(?int $ttl): self ``` Makes a request and saves into cache for the provided duration in seconds. -If `0` seconds is provided, the request will not be cached. +Semantics of values: +- `0`, the response will not be cached (if the servers specifies no `max-age`). +- `null`, the response will be cached for as long as it can (forever). -> **Note** -> Setting cache to `0` seconds will **not** invalidate any existing cache. +> [!NOTE] +> Setting cache to `null` or `0` seconds will **not** invalidate any existing cache. -Check the [Cache TTL](02-configuration.md#cache-ttl) section for more information regarding default values. +[//]: # (Check the [Cache TTL](02-configuration.md#cache-ttl) section for more information regarding default values.) -Available for all APIs if `cache` is enabled in the [configuration](02-configuration.md#cache). +[//]: # (Available for all APIs if `cache` is enabled in the [configuration](02-configuration.md#cache).) ```php -use ProgrammatorDev\OpenWeatherMap\Language\Language - -// Cache will be saved for 1 hour for this request alone -$openWeatherMap->weather() +// cache will be saved for 1 hour for this request alone +$api->weather() ->withCacheTtl(3600) ->getCurrent(50, 50); ``` \ No newline at end of file diff --git a/docs/05-entities.md b/docs/05-entities.md index 739e8ab..606a3ab 100644 --- a/docs/05-entities.md +++ b/docs/05-entities.md @@ -16,6 +16,8 @@ - [AirPollutionLocation](#airpollutionlocation) - [AirPollutionLocationList](#airpollutionlocationlist) - [AirQuality](#airquality) +- [Geocoding](#geocoding) + - [ZipLocation](#ziplocation) - [Common](#common) - [AtmosphericPressure](#atmosphericpressure) - [Coordinate](#coordinate) @@ -197,6 +199,15 @@ - `getIndex()`: `int` - `getQualitativeName()`: `string` +## Geocoding + +### ZipLocation + +- `getZipCode()`: `string` +- `getName()`: `string` +- `getCountryCode()`: `string` +- `getCoordinate()`: [`Coordinate`](#coordinate) + ## Common ### AtmosphericPressure @@ -217,13 +228,16 @@ ### Location +- `getCoordinate()`: [`Coordinate`](#coordinate) +- `getId()`: `?int` - `getName()`: `?string` - `getState()`: `?string` - `getCountryCode()`: `?string` - `getLocalNames()`: `?array` - `getLocalName(string $countryCode)`: `?string` -- `getZipCode()`: `?string` -- `getCoordinate()`: [`Coordinate`](#coordinate) +- `getTimezone()`: [`?Timezone`](#timezone) +- `getSunriseAt()`: `?\DateTimeImmutable` +- `getSunsetAt()`: `?\DateTimeImmutable` ### MoonPhase @@ -252,8 +266,8 @@ ### Timezone -- `getIdentifier()`: `?string` - `getOffset()`: `int` +- `getIdentifier()`: `?string` ### WeatherCondition diff --git a/src/Entity/Geocoding/ZipLocation.php b/src/Entity/Geocoding/ZipLocation.php new file mode 100644 index 0000000..5bbe563 --- /dev/null +++ b/src/Entity/Geocoding/ZipLocation.php @@ -0,0 +1,48 @@ +zipCode = $data['zip']; + $this->name = $data['name']; + $this->countryCode = $data['country']; + + $this->coordinate = new Coordinate([ + 'lat' => $data['lat'], + 'lon' => $data['lon'] + ]); + } + + public function getZipCode(): string + { + return $this->zipCode; + } + + public function getName(): string + { + return $this->name; + } + + public function getCountryCode(): string + { + return $this->countryCode; + } + + public function getCoordinate(): Coordinate + { + return $this->coordinate; + } +} \ No newline at end of file diff --git a/src/Entity/Location.php b/src/Entity/Location.php index 795474b..3c5d154 100644 --- a/src/Entity/Location.php +++ b/src/Entity/Location.php @@ -4,6 +4,10 @@ class Location { + private Coordinate $coordinate; + + private ?int $id; + private ?string $name; private ?string $state; @@ -12,18 +16,46 @@ class Location private ?array $localNames; - private ?string $zipCode; + private ?Timezone $timezone; - private Coordinate $coordinate; + private ?\DateTimeImmutable $sunriseAt; + + private ?\DateTimeImmutable $sunsetAt; public function __construct(array $data) { + $this->coordinate = new Coordinate([ + 'lat' => $data['lat'], + 'lon' => $data['lon'] + ]); + + $this->id = $data['id'] ?? null; $this->name = $data['name'] ?? null; $this->state = $data['state'] ?? null; $this->countryCode = $data['country'] ?? null; $this->localNames = $data['local_names'] ?? null; - $this->zipCode = $data['zip'] ?? null; - $this->coordinate = new Coordinate(['lat' => $data['lat'], 'lon' => $data['lon']]); + + $this->timezone = isset($data['timezone_offset']) + ? new Timezone(['timezone_offset' => $data['timezone_offset']]) + : null; + + $this->sunriseAt = isset($data['sunrise']) + ? \DateTimeImmutable::createFromFormat('U', $data['sunrise']) + : null; + + $this->sunsetAt = isset($data['sunset']) + ? \DateTimeImmutable::createFromFormat('U', $data['sunset']) + : null; + } + + public function getCoordinate(): Coordinate + { + return $this->coordinate; + } + + public function getId(): ?int + { + return $this->id; } public function getName(): ?string @@ -53,13 +85,18 @@ public function getLocalName(string $countryCode): ?string return $this->localNames[$countryCode] ?? null; } - public function getZipCode(): ?string + public function getTimezone(): ?Timezone { - return $this->zipCode; + return $this->timezone; } - public function getCoordinate(): Coordinate + public function getSunriseAt(): ?\DateTimeImmutable { - return $this->coordinate; + return $this->sunriseAt; + } + + public function getSunsetAt(): ?\DateTimeImmutable + { + return $this->sunsetAt; } } \ No newline at end of file diff --git a/src/Entity/Timezone.php b/src/Entity/Timezone.php index c49391b..95c0485 100644 --- a/src/Entity/Timezone.php +++ b/src/Entity/Timezone.php @@ -4,23 +4,23 @@ class Timezone { - private ?string $identifier; - private int $offset; + private ?string $identifier; + public function __construct(array $data) { - $this->identifier = $data['timezone'] ?? null; $this->offset = $data['timezone_offset']; + $this->identifier = $data['timezone'] ?? null; } - public function getIdentifier(): ?string + public function getOffset(): int { - return $this->identifier; + return $this->offset; } - public function getOffset(): int + public function getIdentifier(): ?string { - return $this->offset; + return $this->identifier; } } \ No newline at end of file diff --git a/src/Resource/GeocodingResource.php b/src/Resource/GeocodingResource.php index d9d9894..22d9a0d 100644 --- a/src/Resource/GeocodingResource.php +++ b/src/Resource/GeocodingResource.php @@ -3,6 +3,7 @@ namespace ProgrammatorDev\OpenWeatherMap\Resource; use ProgrammatorDev\Api\Method; +use ProgrammatorDev\OpenWeatherMap\Entity\Geocoding\ZipLocation; use ProgrammatorDev\OpenWeatherMap\Entity\Location; use ProgrammatorDev\OpenWeatherMap\Resource\Util\ValidationTrait; use ProgrammatorDev\OpenWeatherMap\Util\EntityTrait; @@ -42,7 +43,7 @@ public function getByLocationName(string $locationName, int $numResults = self:: * @throws ClientExceptionInterface * @throws ValidationException */ - public function getByZipCode(string $zipCode, string $countryCode): Location + public function getByZipCode(string $zipCode, string $countryCode): ZipLocation { $this->validateQuery($zipCode, 'zipCode'); $this->validateCountry($countryCode, 'countryCode'); @@ -55,7 +56,7 @@ public function getByZipCode(string $zipCode, string $countryCode): Location ] ); - return new Location($data); + return new ZipLocation($data); } /** diff --git a/tests/Integration/GeocodingResourceTest.php b/tests/Integration/GeocodingResourceTest.php index d706e70..fde076d 100644 --- a/tests/Integration/GeocodingResourceTest.php +++ b/tests/Integration/GeocodingResourceTest.php @@ -2,6 +2,7 @@ namespace ProgrammatorDev\OpenWeatherMap\Test\Integration; +use ProgrammatorDev\OpenWeatherMap\Entity\Geocoding\ZipLocation; use ProgrammatorDev\OpenWeatherMap\Entity\Location; use ProgrammatorDev\OpenWeatherMap\Test\AbstractTest; use ProgrammatorDev\OpenWeatherMap\Test\MockResponse; @@ -34,7 +35,7 @@ public static function provideCollectionResponseData(): \Generator public static function provideItemResponseData(): \Generator { yield 'get by zip code' => [ - Location::class, + ZipLocation::class, MockResponse::GEOCODING_ZIP, 'geocoding', 'getByZipCode', diff --git a/tests/Unit/LocationTest.php b/tests/Unit/LocationTest.php index 77ba688..226e963 100644 --- a/tests/Unit/LocationTest.php +++ b/tests/Unit/LocationTest.php @@ -4,6 +4,7 @@ use ProgrammatorDev\OpenWeatherMap\Entity\Coordinate; use ProgrammatorDev\OpenWeatherMap\Entity\Location; +use ProgrammatorDev\OpenWeatherMap\Entity\Timezone; use ProgrammatorDev\OpenWeatherMap\Test\AbstractTest; class LocationTest extends AbstractTest @@ -11,24 +12,29 @@ class LocationTest extends AbstractTest public function testMethods() { $entity = new Location([ - 'name' => 'Name', - 'state' => 'State', - 'country' => 'CO', + 'lat' => 50, + 'lon' => 50, + 'id' => 123, + 'name' => 'name', + 'state' => 'state', + 'country' => 'co', 'local_names' => [ - 'en' => 'Local Name' + 'en' => 'local name' ], - 'zip' => 'ZIP123', - 'lat' => 50, - 'lon' => 50 + 'timezone_offset' => 0, + 'sunrise' => 1661834187, + 'sunset' => 1661882248 ]); - $this->assertSame('Name', $entity->getName()); - $this->assertSame('State', $entity->getState()); - $this->assertSame('CO', $entity->getCountryCode()); - $this->assertSame(['en' => 'Local Name'], $entity->getLocalNames()); - $this->assertSame('Local Name', $entity->getLocalName('en')); - $this->assertSame(null, $entity->getLocalName('pt')); - $this->assertSame('ZIP123', $entity->getZipCode()); $this->assertInstanceOf(Coordinate::class, $entity->getCoordinate()); + $this->assertSame('name', $entity->getName()); + $this->assertSame('state', $entity->getState()); + $this->assertSame('co', $entity->getCountryCode()); + $this->assertSame(['en' => 'local name'], $entity->getLocalNames()); + $this->assertSame('local name', $entity->getLocalName('en')); + $this->assertSame(null, $entity->getLocalName('pt')); + $this->assertInstanceOf(Timezone::class, $entity->getTimezone()); + $this->assertInstanceOf(\DateTimeImmutable::class, $entity->getSunriseAt()); + $this->assertInstanceOf(\DateTimeImmutable::class, $entity->getSunsetAt()); } } \ No newline at end of file diff --git a/tests/Unit/TimezoneTest.php b/tests/Unit/TimezoneTest.php new file mode 100644 index 0000000..84bc444 --- /dev/null +++ b/tests/Unit/TimezoneTest.php @@ -0,0 +1,20 @@ + 'UTC', + 'timezone_offset' => 0 + ]); + + $this->assertSame('UTC', $entity->getIdentifier()); + $this->assertSame(0, $entity->getOffset()); + } +} \ No newline at end of file diff --git a/tests/Unit/ZipLocationTest.php b/tests/Unit/ZipLocationTest.php new file mode 100644 index 0000000..494ba37 --- /dev/null +++ b/tests/Unit/ZipLocationTest.php @@ -0,0 +1,26 @@ + '1234-567', + 'name' => 'name', + 'country' => 'co', + 'lat' => 50, + 'lon' => 50 + ]); + + $this->assertSame('1234-567', $entity->getZipCode()); + $this->assertSame('name', $entity->getName()); + $this->assertSame('co', $entity->getCountryCode()); + $this->assertInstanceOf(Coordinate::class, $entity->getCoordinate()); + } +} \ No newline at end of file