Skip to content

Commit 9af66d3

Browse files
committed
Some refactoring for new UV index api.
1 parent 91ae594 commit 9af66d3

File tree

8 files changed

+161
-249
lines changed

8 files changed

+161
-249
lines changed

Cmfcmf/OpenWeatherMap.php

Lines changed: 77 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
use Cmfcmf\OpenWeatherMap\AbstractCache;
2121
use Cmfcmf\OpenWeatherMap\CurrentWeather;
22-
use Cmfcmf\OpenWeatherMap\CurrentUvi;
22+
use Cmfcmf\OpenWeatherMap\UVIndex;
2323
use Cmfcmf\OpenWeatherMap\CurrentWeatherGroup;
2424
use Cmfcmf\OpenWeatherMap\Exception as OWMException;
2525
use Cmfcmf\OpenWeatherMap\Fetcher\CurlFetcher;
@@ -69,14 +69,9 @@ class OpenWeatherMap
6969
private $weatherHistoryUrl = 'http://history.openweathermap.org/data/2.5/history/city?';
7070

7171
/**
72-
* @var string The basic api url to fetch current uv data from.
72+
* @var string The basic api url to fetch uv index data from.
7373
*/
74-
private $uviUrl = 'http://api.openweathermap.org/v3/uvi/%s,%s/current.json?';
75-
76-
/**
77-
* @var string The basic api url to fetch current uv data from.
78-
*/
79-
private $uviHistoryUrl = 'http://api.openweathermap.org/v3/uvi/%s,%s/%s.json?';
74+
private $uviUrl = 'http://api.openweathermap.org/v3/uvi';
8075

8176
/**
8277
* @var AbstractCache|bool $cache The cache to use.
@@ -314,6 +309,34 @@ public function getWeatherHistory($query, \DateTime $start, $endOrCount = 1, $ty
314309
return new WeatherHistory($xml, $query);
315310
}
316311

312+
/**
313+
* Returns the uv index at the location you specified.
314+
*
315+
* @param float $lat The location's latitude.
316+
* @param float $lon The location's longitude.
317+
* @param \DateTimeInterface $dateTime The date and time to request data for.
318+
* @param string $timePrecision This decides about the timespan OWM will look for the uv index. The tighter
319+
* the timespan, the less likely it is to get a result. Can be 'year', 'month',
320+
* 'day', 'hour', 'minute' or 'second', defaults to 'day'.
321+
*
322+
* @throws OpenWeatherMap\Exception If OpenWeatherMap returns an error.
323+
* @throws \InvalidArgumentException If an argument error occurs.
324+
*
325+
* @return UVIndex The uvi object.
326+
*
327+
* There are three ways to specify the place to get weather information for:
328+
* - Use the coordinates: $query must be an associative array containing the 'lat' and 'lon' values.
329+
*
330+
* @api
331+
*/
332+
public function getUVIndex($lat, $lon, $dateTime, $timePrecision = 'day')
333+
{
334+
$answer = $this->getRawUVIndexData($lat, $lon, $dateTime, $timePrecision);
335+
$json = $this->parseJson($answer);
336+
337+
return new UVIndex($json);
338+
}
339+
317340
/**
318341
* Directly returns the xml/json/html string returned by OpenWeatherMap for the current weather.
319342
*
@@ -407,7 +430,7 @@ public function getRawDailyForecastData($query, $units = 'imperial', $lang = 'en
407430
}
408431

409432
/**
410-
* Directly returns the xml/json/html string returned by OpenWeatherMap for the weather history.
433+
* Directly returns the json string returned by OpenWeatherMap for the weather history.
411434
*
412435
* @param array|int|string $query The place to get weather information for. For possible values see ::getWeather.
413436
* @param \DateTime $start The \DateTime object of the date to get the first weather information from.
@@ -450,104 +473,57 @@ public function getRawWeatherHistory($query, \DateTime $start, $endOrCount = 1,
450473
/**
451474
* Directly returns the json string returned by OpenWeatherMap for the UVI data.
452475
*
453-
* @param array $query The place to get information as follows: [latitude, longitude, date time]. For possible values see ::getWeather.
454-
* @param string $appid Your app id, default ''. See http://openweathermap.org/appid for more details.
476+
* @param float $lat The location's latitude.
477+
* @param float $lon The location's longitude.
478+
* @param \DateTimeInterface $dateTime The date and time to request data for.
479+
* @param string $timePrecision This decides about the timespan OWM will look for the uv index. The tighter
480+
* the timespan, the less likely it is to get a result. Can be 'year', 'month',
481+
* 'day', 'hour', 'minute' or 'second', defaults to 'day'.
455482
*
456-
* @throws \InvalidArgumentException
457-
*
458-
* @return string Returns false on failure and the fetched data in the format you specified on success.
459-
*
460-
* Warning If an error occurred, OpenWeatherMap ALWAYS returns data in json format.
483+
* @return bool|string Returns the fetched data.
461484
*
462485
* @api
463486
*/
464-
public function getRawUviData($query, $appid = '')
487+
public function getRawUVIndexData($lat, $lon, $dateTime, $timePrecision = 'day')
465488
{
466-
if (!is_array($query)) {
467-
throw new \InvalidArgumentException('$query must get information is as follows: [latitude, longitude]');
468-
} elseif (count($query) != 2) {
469-
throw new \InvalidArgumentException('$query must get information is as follows: [latitude, longitude]');
470-
} else {
471-
$url = $this->buildUviUrl($query, $appid);
489+
if (!$this->apiKey) {
490+
throw new \RuntimeException('Before using this method, you must set the api key using ->setApiKey()');
472491
}
473-
474-
return $this->cacheOrFetchResult($url);
475-
}
476-
477-
/**
478-
* Directly returns the json string returned by OpenWeatherMap for the UVI history data.
479-
*
480-
* @param array|int|string $query The place to get weather information for. For possible values see ::getWeather.
481-
* @param string $appid Your app id, default ''. See http://openweathermap.org/appid for more details.
482-
*
483-
* @throws \InvalidArgumentException
484-
*
485-
* @return string Returns false on failure and the fetched data in the format you specified on success.
486-
*
487-
* Warning If an error occurred, OpenWeatherMap ALWAYS returns data in json format.
488-
*
489-
* @api
490-
*/
491-
public function getRawUviHistory($query, $appid = '')
492-
{
493-
if (!is_array($query)) {
494-
throw new \InvalidArgumentException('$query must get information is as follows: [latitude, longitude, ISO 8601 date format]');
495-
} elseif (count($query) != 3) {
496-
throw new \InvalidArgumentException('$query must get information is as follows: [latitude, longitude, ISO 8601 date format]');
497-
} else {
498-
$url = $this->buildUviUrl($query, $appid);
492+
if (!is_float($lat) || !is_float($lon)) {
493+
throw new \InvalidArgumentException('$lat and $lon must be floating point numbers');
499494
}
495+
if (interface_exists('DateTimeInterface') && !$dateTime instanceof \DateTimeInterface || !$dateTime instanceof \DateTime) {
496+
throw new \InvalidArgumentException('$dateTime must be an instance of \DateTime or \DateTimeInterface');
497+
}
498+
$format = '\Z';
499+
switch ($timePrecision) {
500+
/** @noinspection PhpMissingBreakStatementInspection */
501+
case 'second':
502+
$format = ':s' . $format;
503+
/** @noinspection PhpMissingBreakStatementInspection */
504+
case 'minute':
505+
$format = ':i' . $format;
506+
/** @noinspection PhpMissingBreakStatementInspection */
507+
case 'hour':
508+
$format = '\TH' . $format;
509+
/** @noinspection PhpMissingBreakStatementInspection */
510+
case 'day':
511+
$format = '-d' . $format;
512+
/** @noinspection PhpMissingBreakStatementInspection */
513+
case 'month':
514+
$format = '-m' . $format;
515+
case 'year':
516+
$format = 'Y' . $format;
517+
break;
518+
default:
519+
throw new \InvalidArgumentException('$timePrecision is invalid.');
520+
}
521+
// OWM only accepts UTC timezones.
522+
$dateTime->setTimezone(new \DateTimeZone('UTC'));
500523

501-
return $this->cacheOrFetchResult($url);
502-
}
503-
504-
/**
505-
* Returns the current uvi at the location you specified.
506-
*
507-
* @param array|int|string $query The place to get weather information for. For possible values see below.
508-
* @param string $appid Your app id, default ''. See http://openweathermap.org/appid for more details.
509-
*
510-
* @throws OpenWeatherMap\Exception If OpenWeatherMap returns an error.
511-
* @throws \InvalidArgumentException If an argument error occurs.
512-
*
513-
* @return CurrentUvi The uvi object.
514-
*
515-
* There are three ways to specify the place to get weather information for:
516-
* - Use the coordinates: $query must be an associative array containing the 'lat' and 'lon' values.
517-
*
518-
* @api
519-
*/
520-
public function getUvi($query, $appid = '')
521-
{
522-
$answer = $this->getRawUviData($query, $appid);
523-
$json = $this->parseJson($answer);
524-
525-
return new CurrentUvi($json);
526-
}
524+
$url = sprintf($this->uviUrl . '/%s,%s/%s.json?appid=%s', $lat, $lon, $dateTime->format($format), $this->apiKey);
527525

528-
/**
529-
* Returns the history uvi at the location you specified.
530-
*
531-
* @param array|int|string $query The place to get weather information for. For possible values see below.
532-
* @param string $appid Your app id, default ''. See http://openweathermap.org/appid for more details.
533-
* @param string $dateTime Your date time, default ''. See http://openweathermap.org/api/uvi for more details about date format.
534-
*
535-
* @throws OpenWeatherMap\Exception If OpenWeatherMap returns an error.
536-
* @throws \InvalidArgumentException If an argument error occurs.
537-
*
538-
* @return CurrentUvi The uvi object.
539-
*
540-
* There are three ways to specify the place to get weather information for:
541-
* - Use the coordinates: $query must be an associative array containing the 'lat' and 'lon' values.
542-
*
543-
* @api
544-
*/
545-
public function getUviHistory($query, $appid = '')
546-
{
547-
$answer = $this->getRawUviHistory($query, $appid);
548-
$json = $this->parseJson($answer);
549-
550-
return new CurrentUvi($json);
526+
return $this->cacheOrFetchResult($url);
551527
}
552528

553529
/**
@@ -617,34 +593,6 @@ private function buildUrl($query, $units, $lang, $appid, $mode, $url)
617593
return $url;
618594
}
619595

620-
/**
621-
* Build the url to fetch UVI data from.
622-
*
623-
* @param $query
624-
* @param $units
625-
* @param $lang
626-
* @param $appid
627-
* @param $mode
628-
* @param string $url The url to prepend.
629-
*
630-
* @return bool|string The fetched url, false on failure.
631-
*/
632-
private function buildUviUrl($query, $appid)
633-
{
634-
$queryLength = count($query);
635-
switch ($queryLength) {
636-
case 2:
637-
$queryUrl = sprintf($this->uviUrl, $query[0], $query[1]);
638-
break;
639-
case 3:
640-
$queryUrl = sprintf($this->uviHistoryUrl, $query[0], $query[1], $query[2]);
641-
break;
642-
}
643-
$queryUrl .= 'APPID=';
644-
645-
return $queryUrl .= empty($appid) ? $this->apiKey : $appid;
646-
}
647-
648596
/**
649597
* Builds the query string for the url.
650598
*
@@ -707,6 +655,9 @@ private function parseJson($answer)
707655
if (json_last_error() !== JSON_ERROR_NONE) {
708656
throw new OWMException('OpenWeatherMap returned an invalid json object. JSON error was: ' . $this->json_last_error_msg());
709657
}
658+
if (isset($json->message)) {
659+
throw new OWMException('An error occurred: '. $json->message);
660+
}
710661

711662
return $json;
712663
}

Cmfcmf/OpenWeatherMap/CurrentUvi.php renamed to Cmfcmf/OpenWeatherMap/UVIndex.php

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,35 +17,39 @@
1717

1818
namespace Cmfcmf\OpenWeatherMap;
1919

20-
use Cmfcmf\OpenWeatherMap\Util\Uvi;
20+
use Cmfcmf\OpenWeatherMap\Util\Location;
2121

2222
/**
23-
* Weather class used to hold the current weather data.
23+
* UVIndex class used to hold the uv index for a given date, time and location.
2424
*/
25-
class CurrentUvi
25+
class UVIndex
2626
{
2727
/**
28-
* The city object.
29-
*
30-
* @var Util\Uvi
28+
* @var \DateTime
29+
*/
30+
public $time;
31+
32+
/**
33+
* @var Location
34+
*/
35+
public $location;
36+
37+
/**
38+
* @var float
3139
*/
32-
public $uvi;
40+
public $uvIndex;
3341

3442
/**
35-
* Create a new uvi object.
43+
* Create a new current uv index object.
3644
*
37-
* @param mixed $data
45+
* @param object $data
3846
*
3947
* @internal
4048
*/
4149
public function __construct($data)
4250
{
43-
// generate the object from response JSON.
44-
// ($time, $latitude, $longitude, $data)
45-
if (empty($data->message) && empty($data->code)) {
46-
$this->uvi = new Uvi($data->time, $data->location->latitude, $data->location->longitude, $data->data);
47-
} else {
48-
$this->uvi = null;
49-
}
51+
$this->time = new \DateTime($data->time);
52+
$this->location = new Location($data->location->longitude, $data->location->latitude);
53+
$this->uvIndex = (float)$data->data;
5054
}
5155
}

Cmfcmf/OpenWeatherMap/Util/City.php

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
/**
2121
* The city class representing a city object.
2222
*/
23-
class City
23+
class City extends Location
2424
{
2525
/**
2626
* @var int The city id.
@@ -32,16 +32,6 @@ class City
3232
*/
3333
public $name;
3434

35-
/**
36-
* @var float The longitude of the city.
37-
*/
38-
public $lon;
39-
40-
/**
41-
* @var float The latitude of the city.
42-
*/
43-
public $lat;
44-
4535
/**
4636
* @var string The abbreviation of the country the city is located in.
4737
*/
@@ -68,9 +58,9 @@ public function __construct($id, $name = null, $lon = null, $lat = null, $countr
6858
{
6959
$this->id = (int)$id;
7060
$this->name = isset($name) ? (string)$name : null;
71-
$this->lon = isset($lon) ? (float)$lon : null;
72-
$this->lat = isset($lat) ? (float)$lat : null;
7361
$this->country = isset($country) ? (string)$country : null;
7462
$this->population = isset($population) ? (int)$population : null;
63+
64+
parent::__construct($lon, $lat);
7565
}
7666
}

0 commit comments

Comments
 (0)