Skip to content

Commit 04a0b0e

Browse files
authored
Merge pull request #99 from cmfcmf/uv-index
Add UV Index API support
2 parents 088065f + 50e1ab3 commit 04a0b0e

17 files changed

+428
-38
lines changed

.travis.yml

+1-3
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,8 @@ matrix:
1717
allow_failures:
1818
- php: nightly
1919

20-
before_install:
21-
- if [[ ! $TRAVIS_PHP_VERSION = hhvm* ]]; then phpenv config-rm xdebug.ini || echo "xdebug not available"; fi
22-
2320
install:
21+
- if [[ ! $TRAVIS_PHP_VERSION = hhvm* ]]; then phpenv config-rm xdebug.ini || echo "xdebug not available"; fi
2422
- if [[ ! $TRAVIS_PHP_VERSION = hhvm* ]]; then INI_FILE=~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini; else INI_FILE=/etc/hhvm/php.ini; fi
2523
- echo date.timezone = Europe/Berlin >> $INI_FILE
2624
- echo memory_limit = -1 >> $INI_FILE

Cmfcmf/OpenWeatherMap.php

+153-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
use Cmfcmf\OpenWeatherMap\AbstractCache;
2121
use Cmfcmf\OpenWeatherMap\CurrentWeather;
22+
use Cmfcmf\OpenWeatherMap\UVIndex;
2223
use Cmfcmf\OpenWeatherMap\CurrentWeatherGroup;
2324
use Cmfcmf\OpenWeatherMap\Exception as OWMException;
2425
use Cmfcmf\OpenWeatherMap\Fetcher\CurlFetcher;
@@ -67,6 +68,11 @@ class OpenWeatherMap
6768
*/
6869
private $weatherHistoryUrl = 'http://history.openweathermap.org/data/2.5/history/city?';
6970

71+
/**
72+
* @var string The basic api url to fetch uv index data from.
73+
*/
74+
private $uvIndexUrl = 'http://api.openweathermap.org/v3/uvi';
75+
7076
/**
7177
* @var AbstractCache|bool $cache The cache to use.
7278
*/
@@ -303,6 +309,52 @@ public function getWeatherHistory($query, \DateTime $start, $endOrCount = 1, $ty
303309
return new WeatherHistory($xml, $query);
304310
}
305311

312+
/**
313+
* Returns the current 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+
*
318+
* @throws OpenWeatherMap\Exception If OpenWeatherMap returns an error.
319+
* @throws \InvalidArgumentException If an argument error occurs.
320+
*
321+
* @return UVIndex The uvi object.
322+
*
323+
* @api
324+
*/
325+
public function getCurrentUVIndex($lat, $lon)
326+
{
327+
$answer = $this->getRawCurrentUVIndexData($lat, $lon);
328+
$json = $this->parseJson($answer);
329+
330+
return new UVIndex($json);
331+
}
332+
333+
/**
334+
* Returns the uv index at date, time and location you specified.
335+
*
336+
* @param float $lat The location's latitude.
337+
* @param float $lon The location's longitude.
338+
* @param \DateTimeInterface $dateTime The date and time to request data for.
339+
* @param string $timePrecision This decides about the timespan OWM will look for the uv index. The tighter
340+
* the timespan, the less likely it is to get a result. Can be 'year', 'month',
341+
* 'day', 'hour', 'minute' or 'second', defaults to 'day'.
342+
*
343+
* @throws OpenWeatherMap\Exception If OpenWeatherMap returns an error.
344+
* @throws \InvalidArgumentException If an argument error occurs.
345+
*
346+
* @return UVIndex The uvi object.
347+
*
348+
* @api
349+
*/
350+
public function getUVIndex($lat, $lon, $dateTime, $timePrecision = 'day')
351+
{
352+
$answer = $this->getRawUVIndexData($lat, $lon, $dateTime, $timePrecision);
353+
$json = $this->parseJson($answer);
354+
355+
return new UVIndex($json);
356+
}
357+
306358
/**
307359
* Directly returns the xml/json/html string returned by OpenWeatherMap for the current weather.
308360
*
@@ -396,7 +448,7 @@ public function getRawDailyForecastData($query, $units = 'imperial', $lang = 'en
396448
}
397449

398450
/**
399-
* Directly returns the xml/json/html string returned by OpenWeatherMap for the weather history.
451+
* Directly returns the json string returned by OpenWeatherMap for the weather history.
400452
*
401453
* @param array|int|string $query The place to get weather information for. For possible values see ::getWeather.
402454
* @param \DateTime $start The \DateTime object of the date to get the first weather information from.
@@ -436,6 +488,59 @@ public function getRawWeatherHistory($query, \DateTime $start, $endOrCount = 1,
436488
return $this->cacheOrFetchResult($url);
437489
}
438490

491+
/**
492+
* Directly returns the json string returned by OpenWeatherMap for the current UV index data.
493+
*
494+
* @param float $lat The location's latitude.
495+
* @param float $lon The location's longitude.
496+
*
497+
* @return bool|string Returns the fetched data.
498+
*
499+
* @api
500+
*/
501+
public function getRawCurrentUVIndexData($lat, $lon)
502+
{
503+
if (!$this->apiKey) {
504+
throw new \RuntimeException('Before using this method, you must set the api key using ->setApiKey()');
505+
}
506+
if (!is_float($lat) || !is_float($lon)) {
507+
throw new \InvalidArgumentException('$lat and $lon must be floating point numbers');
508+
}
509+
$url = $this->buildUVIndexUrl($lat, $lon);
510+
511+
return $this->cacheOrFetchResult($url);
512+
}
513+
514+
/**
515+
* Directly returns the json string returned by OpenWeatherMap for the UV index data.
516+
*
517+
* @param float $lat The location's latitude.
518+
* @param float $lon The location's longitude.
519+
* @param \DateTimeInterface $dateTime The date and time to request data for.
520+
* @param string $timePrecision This decides about the timespan OWM will look for the uv index. The tighter
521+
* the timespan, the less likely it is to get a result. Can be 'year', 'month',
522+
* 'day', 'hour', 'minute' or 'second', defaults to 'day'.
523+
*
524+
* @return bool|string Returns the fetched data.
525+
*
526+
* @api
527+
*/
528+
public function getRawUVIndexData($lat, $lon, $dateTime, $timePrecision = 'day')
529+
{
530+
if (!$this->apiKey) {
531+
throw new \RuntimeException('Before using this method, you must set the api key using ->setApiKey()');
532+
}
533+
if (!is_float($lat) || !is_float($lon)) {
534+
throw new \InvalidArgumentException('$lat and $lon must be floating point numbers');
535+
}
536+
if (interface_exists('DateTimeInterface') && !$dateTime instanceof \DateTimeInterface || !$dateTime instanceof \DateTime) {
537+
throw new \InvalidArgumentException('$dateTime must be an instance of \DateTime or \DateTimeInterface');
538+
}
539+
$url = $this->buildUVIndexUrl($lat, $lon, $dateTime, $timePrecision);
540+
541+
return $this->cacheOrFetchResult($url);
542+
}
543+
439544
/**
440545
* Returns whether or not the last result was fetched from the cache.
441546
*
@@ -503,6 +608,50 @@ private function buildUrl($query, $units, $lang, $appid, $mode, $url)
503608
return $url;
504609
}
505610

611+
/**
612+
* @param float $lat
613+
* @param float $lon
614+
* @param \DateTime|\DateTimeImmutable $dateTime
615+
* @param string $timePrecision
616+
*
617+
* @return string
618+
*/
619+
private function buildUVIndexUrl($lat, $lon, $dateTime = null, $timePrecision = null)
620+
{
621+
if ($dateTime !== null) {
622+
$format = '\Z';
623+
switch ($timePrecision) {
624+
/** @noinspection PhpMissingBreakStatementInspection */
625+
case 'second':
626+
$format = ':s' . $format;
627+
/** @noinspection PhpMissingBreakStatementInspection */
628+
case 'minute':
629+
$format = ':i' . $format;
630+
/** @noinspection PhpMissingBreakStatementInspection */
631+
case 'hour':
632+
$format = '\TH' . $format;
633+
/** @noinspection PhpMissingBreakStatementInspection */
634+
case 'day':
635+
$format = '-d' . $format;
636+
/** @noinspection PhpMissingBreakStatementInspection */
637+
case 'month':
638+
$format = '-m' . $format;
639+
case 'year':
640+
$format = 'Y' . $format;
641+
break;
642+
default:
643+
throw new \InvalidArgumentException('$timePrecision is invalid.');
644+
}
645+
// OWM only accepts UTC timezones.
646+
$dateTime->setTimezone(new \DateTimeZone('UTC'));
647+
$dateTime = $dateTime->format($format);
648+
} else {
649+
$dateTime = 'current';
650+
}
651+
652+
return sprintf($this->uvIndexUrl . '/%s,%s/%s.json?appid=%s', $lat, $lon, $dateTime, $this->apiKey);
653+
}
654+
506655
/**
507656
* Builds the query string for the url.
508657
*
@@ -565,6 +714,9 @@ private function parseJson($answer)
565714
if (json_last_error() !== JSON_ERROR_NONE) {
566715
throw new OWMException('OpenWeatherMap returned an invalid json object. JSON error was: ' . $this->json_last_error_msg());
567716
}
717+
if (isset($json->message)) {
718+
throw new OWMException('An error occurred: '. $json->message);
719+
}
568720

569721
return $json;
570722
}

Cmfcmf/OpenWeatherMap/CurrentWeather.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public function __construct($data, $units)
103103
$utctz = new \DateTimeZone('UTC');
104104

105105
if ($data instanceof \SimpleXMLElement) {
106-
$this->city = new City($data->city['id'], $data->city['name'], $data->city->coord['lon'], $data->city->coord['lat'], $data->city->country);
106+
$this->city = new City($data->city['id'], $data->city['name'], $data->city->coord['lat'], $data->city->coord['lon'], $data->city->country);
107107
$this->temperature = new Temperature(new Unit($data->temperature['value'], $data->temperature['unit']), new Unit($data->temperature['min'], $data->temperature['unit']), new Unit($data->temperature['max'], $data->temperature['unit']));
108108
$this->humidity = new Unit($data->humidity['value'], $data->humidity['unit']);
109109
$this->pressure = new Unit($data->pressure['value'], $data->pressure['unit']);
@@ -114,7 +114,7 @@ public function __construct($data, $units)
114114
$this->weather = new Weather($data->weather['number'], $data->weather['value'], $data->weather['icon']);
115115
$this->lastUpdate = new \DateTime($data->lastupdate['value'], $utctz);
116116
} else {
117-
$this->city = new City($data->id, $data->name, $data->coord->lon, $data->coord->lat, $data->sys->country);
117+
$this->city = new City($data->id, $data->name, $data->coord->lat, $data->coord->lon, $data->sys->country);
118118
$this->temperature = new Temperature(new Unit($data->main->temp, $units), new Unit($data->main->temp_min, $units), new Unit($data->main->temp_max, $units));
119119
$this->humidity = new Unit($data->main->humidity, '%');
120120
$this->pressure = new Unit($data->main->pressure, 'hPa');

Cmfcmf/OpenWeatherMap/CurrentWeatherGroup.php

-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717

1818
namespace Cmfcmf\OpenWeatherMap;
1919

20-
use Cmfcmf\OpenWeatherMap;
21-
2220
/**
2321
* Class CurrentWeatherGroup used to hold the current weather data for a group of cities.
2422
*/

Cmfcmf/OpenWeatherMap/UVIndex.php

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
/**
3+
* OpenWeatherMap-PHP-API — A php api to parse weather data from http://www.OpenWeatherMap.org .
4+
*
5+
* @license MIT
6+
*
7+
* Please see the LICENSE file distributed with this source code for further
8+
* information regarding copyright and licensing.
9+
*
10+
* Please visit the following links to read about the usage policies and the license of
11+
* OpenWeatherMap before using this class:
12+
*
13+
* @see http://www.OpenWeatherMap.org
14+
* @see http://www.OpenWeatherMap.org/terms
15+
* @see http://openweathermap.org/appid
16+
*/
17+
18+
namespace Cmfcmf\OpenWeatherMap;
19+
20+
use Cmfcmf\OpenWeatherMap\Util\Location;
21+
22+
/**
23+
* UVIndex class used to hold the uv index for a given date, time and location.
24+
*/
25+
class UVIndex
26+
{
27+
/**
28+
* @var \DateTime
29+
*/
30+
public $time;
31+
32+
/**
33+
* @var Location
34+
*/
35+
public $location;
36+
37+
/**
38+
* @var float
39+
*/
40+
public $uvIndex;
41+
42+
/**
43+
* Create a new current uv index object.
44+
*
45+
* @param object $data
46+
*
47+
* @internal
48+
*/
49+
public function __construct($data)
50+
{
51+
$this->time = new \DateTime($data->time);
52+
$this->location = new Location($data->location->latitude, $data->location->longitude);
53+
$this->uvIndex = (float)$data->data;
54+
}
55+
}

Cmfcmf/OpenWeatherMap/Util/City.php

+5-15
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
*/
@@ -57,20 +47,20 @@ class City
5747
*
5848
* @param int $id The city id.
5949
* @param string $name The name of the city.
60-
* @param float $lon The longitude of the city.
6150
* @param float $lat The latitude of the city.
51+
* @param float $lon The longitude of the city.
6252
* @param string $country The abbreviation of the country the city is located in
6353
* @param int $population The city's population.
6454
*
6555
* @internal
6656
*/
67-
public function __construct($id, $name = null, $lon = null, $lat = null, $country = null, $population = null)
57+
public function __construct($id, $name = null, $lat = null, $lon = null, $country = null, $population = null)
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($lat, $lon);
7565
}
7666
}
+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
/**
3+
* OpenWeatherMap-PHP-API — A php api to parse weather data from http://www.OpenWeatherMap.org .
4+
*
5+
* @license MIT
6+
*
7+
* Please see the LICENSE file distributed with this source code for further
8+
* information regarding copyright and licensing.
9+
*
10+
* Please visit the following links to read about the usage policies and the license of
11+
* OpenWeatherMap before using this class:
12+
*
13+
* @see http://www.OpenWeatherMap.org
14+
* @see http://www.OpenWeatherMap.org/terms
15+
* @see http://openweathermap.org/appid
16+
*/
17+
18+
namespace Cmfcmf\OpenWeatherMap\Util;
19+
20+
/**
21+
* The city class representing a city object.
22+
*/
23+
class Location
24+
{
25+
/**
26+
* @var float The latitude of the city.
27+
*/
28+
public $lat;
29+
30+
/**
31+
* @var float The longitude of the city.
32+
*/
33+
public $lon;
34+
35+
/**
36+
* Create a new location object.
37+
*
38+
* @param float $lat The latitude of the city.
39+
* @param float $lon The longitude of the city.
40+
*
41+
* @internal
42+
*/
43+
public function __construct($lat = null, $lon = null)
44+
{
45+
$this->lat = isset($lat) ? (float)$lat : null;
46+
$this->lon = isset($lon) ? (float)$lon : null;
47+
}
48+
}

0 commit comments

Comments
 (0)