Skip to content

Commit

Permalink
Merge pull request #99 from cmfcmf/uv-index
Browse files Browse the repository at this point in the history
Add UV Index API support
  • Loading branch information
cmfcmf authored Feb 8, 2017
2 parents 088065f + 50e1ab3 commit 04a0b0e
Show file tree
Hide file tree
Showing 17 changed files with 428 additions and 38 deletions.
4 changes: 1 addition & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@ matrix:
allow_failures:
- php: nightly

before_install:
- if [[ ! $TRAVIS_PHP_VERSION = hhvm* ]]; then phpenv config-rm xdebug.ini || echo "xdebug not available"; fi

install:
- if [[ ! $TRAVIS_PHP_VERSION = hhvm* ]]; then phpenv config-rm xdebug.ini || echo "xdebug not available"; fi
- 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
- echo date.timezone = Europe/Berlin >> $INI_FILE
- echo memory_limit = -1 >> $INI_FILE
Expand Down
154 changes: 153 additions & 1 deletion Cmfcmf/OpenWeatherMap.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

use Cmfcmf\OpenWeatherMap\AbstractCache;
use Cmfcmf\OpenWeatherMap\CurrentWeather;
use Cmfcmf\OpenWeatherMap\UVIndex;
use Cmfcmf\OpenWeatherMap\CurrentWeatherGroup;
use Cmfcmf\OpenWeatherMap\Exception as OWMException;
use Cmfcmf\OpenWeatherMap\Fetcher\CurlFetcher;
Expand Down Expand Up @@ -67,6 +68,11 @@ class OpenWeatherMap
*/
private $weatherHistoryUrl = 'http://history.openweathermap.org/data/2.5/history/city?';

/**
* @var string The basic api url to fetch uv index data from.
*/
private $uvIndexUrl = 'http://api.openweathermap.org/v3/uvi';

/**
* @var AbstractCache|bool $cache The cache to use.
*/
Expand Down Expand Up @@ -303,6 +309,52 @@ public function getWeatherHistory($query, \DateTime $start, $endOrCount = 1, $ty
return new WeatherHistory($xml, $query);
}

/**
* Returns the current uv index at the location you specified.
*
* @param float $lat The location's latitude.
* @param float $lon The location's longitude.
*
* @throws OpenWeatherMap\Exception If OpenWeatherMap returns an error.
* @throws \InvalidArgumentException If an argument error occurs.
*
* @return UVIndex The uvi object.
*
* @api
*/
public function getCurrentUVIndex($lat, $lon)
{
$answer = $this->getRawCurrentUVIndexData($lat, $lon);
$json = $this->parseJson($answer);

return new UVIndex($json);
}

/**
* Returns the uv index at date, time and location you specified.
*
* @param float $lat The location's latitude.
* @param float $lon The location's longitude.
* @param \DateTimeInterface $dateTime The date and time to request data for.
* @param string $timePrecision This decides about the timespan OWM will look for the uv index. The tighter
* the timespan, the less likely it is to get a result. Can be 'year', 'month',
* 'day', 'hour', 'minute' or 'second', defaults to 'day'.
*
* @throws OpenWeatherMap\Exception If OpenWeatherMap returns an error.
* @throws \InvalidArgumentException If an argument error occurs.
*
* @return UVIndex The uvi object.
*
* @api
*/
public function getUVIndex($lat, $lon, $dateTime, $timePrecision = 'day')
{
$answer = $this->getRawUVIndexData($lat, $lon, $dateTime, $timePrecision);
$json = $this->parseJson($answer);

return new UVIndex($json);
}

/**
* Directly returns the xml/json/html string returned by OpenWeatherMap for the current weather.
*
Expand Down Expand Up @@ -396,7 +448,7 @@ public function getRawDailyForecastData($query, $units = 'imperial', $lang = 'en
}

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

/**
* Directly returns the json string returned by OpenWeatherMap for the current UV index data.
*
* @param float $lat The location's latitude.
* @param float $lon The location's longitude.
*
* @return bool|string Returns the fetched data.
*
* @api
*/
public function getRawCurrentUVIndexData($lat, $lon)
{
if (!$this->apiKey) {
throw new \RuntimeException('Before using this method, you must set the api key using ->setApiKey()');
}
if (!is_float($lat) || !is_float($lon)) {
throw new \InvalidArgumentException('$lat and $lon must be floating point numbers');
}
$url = $this->buildUVIndexUrl($lat, $lon);

return $this->cacheOrFetchResult($url);
}

/**
* Directly returns the json string returned by OpenWeatherMap for the UV index data.
*
* @param float $lat The location's latitude.
* @param float $lon The location's longitude.
* @param \DateTimeInterface $dateTime The date and time to request data for.
* @param string $timePrecision This decides about the timespan OWM will look for the uv index. The tighter
* the timespan, the less likely it is to get a result. Can be 'year', 'month',
* 'day', 'hour', 'minute' or 'second', defaults to 'day'.
*
* @return bool|string Returns the fetched data.
*
* @api
*/
public function getRawUVIndexData($lat, $lon, $dateTime, $timePrecision = 'day')
{
if (!$this->apiKey) {
throw new \RuntimeException('Before using this method, you must set the api key using ->setApiKey()');
}
if (!is_float($lat) || !is_float($lon)) {
throw new \InvalidArgumentException('$lat and $lon must be floating point numbers');
}
if (interface_exists('DateTimeInterface') && !$dateTime instanceof \DateTimeInterface || !$dateTime instanceof \DateTime) {
throw new \InvalidArgumentException('$dateTime must be an instance of \DateTime or \DateTimeInterface');
}
$url = $this->buildUVIndexUrl($lat, $lon, $dateTime, $timePrecision);

return $this->cacheOrFetchResult($url);
}

/**
* Returns whether or not the last result was fetched from the cache.
*
Expand Down Expand Up @@ -503,6 +608,50 @@ private function buildUrl($query, $units, $lang, $appid, $mode, $url)
return $url;
}

/**
* @param float $lat
* @param float $lon
* @param \DateTime|\DateTimeImmutable $dateTime
* @param string $timePrecision
*
* @return string
*/
private function buildUVIndexUrl($lat, $lon, $dateTime = null, $timePrecision = null)
{
if ($dateTime !== null) {
$format = '\Z';
switch ($timePrecision) {
/** @noinspection PhpMissingBreakStatementInspection */
case 'second':
$format = ':s' . $format;
/** @noinspection PhpMissingBreakStatementInspection */
case 'minute':
$format = ':i' . $format;
/** @noinspection PhpMissingBreakStatementInspection */
case 'hour':
$format = '\TH' . $format;
/** @noinspection PhpMissingBreakStatementInspection */
case 'day':
$format = '-d' . $format;
/** @noinspection PhpMissingBreakStatementInspection */
case 'month':
$format = '-m' . $format;
case 'year':
$format = 'Y' . $format;
break;
default:
throw new \InvalidArgumentException('$timePrecision is invalid.');
}
// OWM only accepts UTC timezones.
$dateTime->setTimezone(new \DateTimeZone('UTC'));
$dateTime = $dateTime->format($format);
} else {
$dateTime = 'current';
}

return sprintf($this->uvIndexUrl . '/%s,%s/%s.json?appid=%s', $lat, $lon, $dateTime, $this->apiKey);
}

/**
* Builds the query string for the url.
*
Expand Down Expand Up @@ -565,6 +714,9 @@ private function parseJson($answer)
if (json_last_error() !== JSON_ERROR_NONE) {
throw new OWMException('OpenWeatherMap returned an invalid json object. JSON error was: ' . $this->json_last_error_msg());
}
if (isset($json->message)) {
throw new OWMException('An error occurred: '. $json->message);
}

return $json;
}
Expand Down
4 changes: 2 additions & 2 deletions Cmfcmf/OpenWeatherMap/CurrentWeather.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public function __construct($data, $units)
$utctz = new \DateTimeZone('UTC');

if ($data instanceof \SimpleXMLElement) {
$this->city = new City($data->city['id'], $data->city['name'], $data->city->coord['lon'], $data->city->coord['lat'], $data->city->country);
$this->city = new City($data->city['id'], $data->city['name'], $data->city->coord['lat'], $data->city->coord['lon'], $data->city->country);
$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']));
$this->humidity = new Unit($data->humidity['value'], $data->humidity['unit']);
$this->pressure = new Unit($data->pressure['value'], $data->pressure['unit']);
Expand All @@ -114,7 +114,7 @@ public function __construct($data, $units)
$this->weather = new Weather($data->weather['number'], $data->weather['value'], $data->weather['icon']);
$this->lastUpdate = new \DateTime($data->lastupdate['value'], $utctz);
} else {
$this->city = new City($data->id, $data->name, $data->coord->lon, $data->coord->lat, $data->sys->country);
$this->city = new City($data->id, $data->name, $data->coord->lat, $data->coord->lon, $data->sys->country);
$this->temperature = new Temperature(new Unit($data->main->temp, $units), new Unit($data->main->temp_min, $units), new Unit($data->main->temp_max, $units));
$this->humidity = new Unit($data->main->humidity, '%');
$this->pressure = new Unit($data->main->pressure, 'hPa');
Expand Down
2 changes: 0 additions & 2 deletions Cmfcmf/OpenWeatherMap/CurrentWeatherGroup.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@

namespace Cmfcmf\OpenWeatherMap;

use Cmfcmf\OpenWeatherMap;

/**
* Class CurrentWeatherGroup used to hold the current weather data for a group of cities.
*/
Expand Down
55 changes: 55 additions & 0 deletions Cmfcmf/OpenWeatherMap/UVIndex.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php
/**
* OpenWeatherMap-PHP-API — A php api to parse weather data from http://www.OpenWeatherMap.org .
*
* @license MIT
*
* Please see the LICENSE file distributed with this source code for further
* information regarding copyright and licensing.
*
* Please visit the following links to read about the usage policies and the license of
* OpenWeatherMap before using this class:
*
* @see http://www.OpenWeatherMap.org
* @see http://www.OpenWeatherMap.org/terms
* @see http://openweathermap.org/appid
*/

namespace Cmfcmf\OpenWeatherMap;

use Cmfcmf\OpenWeatherMap\Util\Location;

/**
* UVIndex class used to hold the uv index for a given date, time and location.
*/
class UVIndex
{
/**
* @var \DateTime
*/
public $time;

/**
* @var Location
*/
public $location;

/**
* @var float
*/
public $uvIndex;

/**
* Create a new current uv index object.
*
* @param object $data
*
* @internal
*/
public function __construct($data)
{
$this->time = new \DateTime($data->time);
$this->location = new Location($data->location->latitude, $data->location->longitude);
$this->uvIndex = (float)$data->data;
}
}
20 changes: 5 additions & 15 deletions Cmfcmf/OpenWeatherMap/Util/City.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
/**
* The city class representing a city object.
*/
class City
class City extends Location
{
/**
* @var int The city id.
Expand All @@ -32,16 +32,6 @@ class City
*/
public $name;

/**
* @var float The longitude of the city.
*/
public $lon;

/**
* @var float The latitude of the city.
*/
public $lat;

/**
* @var string The abbreviation of the country the city is located in.
*/
Expand All @@ -57,20 +47,20 @@ class City
*
* @param int $id The city id.
* @param string $name The name of the city.
* @param float $lon The longitude of the city.
* @param float $lat The latitude of the city.
* @param float $lon The longitude of the city.
* @param string $country The abbreviation of the country the city is located in
* @param int $population The city's population.
*
* @internal
*/
public function __construct($id, $name = null, $lon = null, $lat = null, $country = null, $population = null)
public function __construct($id, $name = null, $lat = null, $lon = null, $country = null, $population = null)
{
$this->id = (int)$id;
$this->name = isset($name) ? (string)$name : null;
$this->lon = isset($lon) ? (float)$lon : null;
$this->lat = isset($lat) ? (float)$lat : null;
$this->country = isset($country) ? (string)$country : null;
$this->population = isset($population) ? (int)$population : null;

parent::__construct($lat, $lon);
}
}
48 changes: 48 additions & 0 deletions Cmfcmf/OpenWeatherMap/Util/Location.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php
/**
* OpenWeatherMap-PHP-API — A php api to parse weather data from http://www.OpenWeatherMap.org .
*
* @license MIT
*
* Please see the LICENSE file distributed with this source code for further
* information regarding copyright and licensing.
*
* Please visit the following links to read about the usage policies and the license of
* OpenWeatherMap before using this class:
*
* @see http://www.OpenWeatherMap.org
* @see http://www.OpenWeatherMap.org/terms
* @see http://openweathermap.org/appid
*/

namespace Cmfcmf\OpenWeatherMap\Util;

/**
* The city class representing a city object.
*/
class Location
{
/**
* @var float The latitude of the city.
*/
public $lat;

/**
* @var float The longitude of the city.
*/
public $lon;

/**
* Create a new location object.
*
* @param float $lat The latitude of the city.
* @param float $lon The longitude of the city.
*
* @internal
*/
public function __construct($lat = null, $lon = null)
{
$this->lat = isset($lat) ? (float)$lat : null;
$this->lon = isset($lon) ? (float)$lon : null;
}
}
Loading

0 comments on commit 04a0b0e

Please sign in to comment.