Skip to content

Commit 99929ad

Browse files
authored
Merge branch 'master' into v3
2 parents d2b0fb3 + fdac750 commit 99929ad

File tree

6 files changed

+210
-146
lines changed

6 files changed

+210
-146
lines changed

.travis.yml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ language: php
55

66
matrix:
77
include:
8-
- php: hhvm
98
- php: nightly
9+
- php: 7.3
1010
- php: 7.2
1111
- php: 7.1
1212
- php: 7.0
@@ -19,11 +19,15 @@ matrix:
1919
allow_failures:
2020
- php: nightly
2121

22-
install:
23-
- if [[ ! $TRAVIS_PHP_VERSION = hhvm* ]]; then phpenv config-rm xdebug.ini || echo "xdebug not available"; fi
24-
- 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
22+
before_install:
23+
- phpenv config-rm xdebug.ini || echo "xdebug not available"
24+
- INI_FILE=~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
2525
- echo date.timezone = Europe/Berlin >> $INI_FILE
2626
- echo memory_limit = -1 >> $INI_FILE
27+
28+
install:
29+
# Use composer update instead of composer install to install a working set of
30+
# dependencies on all PHP versions.
2731
- composer update
2832

2933
script:

Cmfcmf/OpenWeatherMap.php

Lines changed: 100 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class OpenWeatherMap
7171
/**
7272
* @var string The basic api url to fetch uv index data from.
7373
*/
74-
private $uvIndexUrl = 'https://api.openweathermap.org/v3/uvi';
74+
private $uvIndexUrl = 'https://api.openweathermap.org/data/2.5/uvi';
7575

7676
/**
7777
* @var AbstractCache|bool $cache The cache to use.
@@ -312,47 +312,73 @@ public function getWeatherHistory($query, \DateTime $start, $endOrCount = 1, $ty
312312
/**
313313
* Returns the current uv index at the location you specified.
314314
*
315-
* @param float $lat The location's latitude.
316-
* @param float $lon The location's longitude.
315+
* @param float $lat The location's latitude.
316+
* @param float $lon The location's longitude.
317317
*
318318
* @throws OpenWeatherMap\Exception If OpenWeatherMap returns an error.
319319
* @throws \InvalidArgumentException If an argument error occurs.
320320
*
321-
* @return UVIndex The uvi object.
321+
* @return UVIndex
322322
*
323323
* @api
324324
*/
325325
public function getCurrentUVIndex($lat, $lon)
326326
{
327-
$answer = $this->getRawCurrentUVIndexData($lat, $lon);
327+
$answer = $this->getRawUVIndexData('current', $lat, $lon);
328328
$json = $this->parseJson($answer);
329329

330330
return new UVIndex($json);
331331
}
332332

333333
/**
334-
* Returns the uv index at date, time and location you specified.
334+
* Returns a forecast of the uv index at the specified location.
335+
* The optional $cnt parameter determines the number of days to forecase.
336+
* The maximum supported number of days is 8.
335337
*
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'.
338+
* @param float $lat The location's latitude.
339+
* @param float $lon The location's longitude.
340+
* @param int $cnt Number of returned days (default to 8).
342341
*
343342
* @throws OpenWeatherMap\Exception If OpenWeatherMap returns an error.
344343
* @throws \InvalidArgumentException If an argument error occurs.
345344
*
346-
* @return UVIndex The uvi object.
345+
* @return UVIndex[]
347346
*
348347
* @api
349348
*/
350-
public function getUVIndex($lat, $lon, $dateTime, $timePrecision = 'day')
349+
public function getForecastUVIndex($lat, $lon, $cnt = 8)
351350
{
352-
$answer = $this->getRawUVIndexData($lat, $lon, $dateTime, $timePrecision);
353-
$json = $this->parseJson($answer);
351+
$answer = $this->getRawUVIndexData('forecast', $lat, $lon, $cnt);
352+
$data = $this->parseJson($answer);
354353

355-
return new UVIndex($json);
354+
return array_map(function ($entry) {
355+
return new UVIndex($entry);
356+
}, $data);
357+
}
358+
359+
/**
360+
* Returns the historic uv index at the specified location.
361+
*
362+
* @param float $lat The location's latitude.
363+
* @param float $lon The location's longitude.
364+
* @param \DateTime $start Starting point of time period.
365+
* @param \DateTime $end Final point of time period.
366+
*
367+
* @throws OpenWeatherMap\Exception If OpenWeatherMap returns an error.
368+
* @throws \InvalidArgumentException If an argument error occurs.
369+
*
370+
* @return UVIndex[]
371+
*
372+
* @api
373+
*/
374+
public function getHistoricUVIndex($lat, $lon, $start, $end)
375+
{
376+
$answer = $this->getRawUVIndexData('historic', $lat, $lon, null, $start, $end);
377+
$data = $this->parseJson($answer);
378+
379+
return array_map(function ($entry) {
380+
return new UVIndex($entry);
381+
}, $data);
356382
}
357383

358384
/**
@@ -489,55 +515,45 @@ public function getRawWeatherHistory($query, \DateTime $start, $endOrCount = 1,
489515
}
490516

491517
/**
492-
* Directly returns the json string returned by OpenWeatherMap for the current UV index data.
518+
* Directly returns the json string returned by OpenWeatherMap for the UV index data.
493519
*
494-
* @param float $lat The location's latitude.
495-
* @param float $lon The location's longitude.
520+
* @param string $mode The type of requested data (['historic', 'forecast', 'current']).
521+
* @param float $lat The location's latitude.
522+
* @param float $lon The location's longitude.
523+
* @param int $cnt Number of returned days (only allowed for 'forecast' data).
524+
* @param \DateTime $start Starting point of time period (only allowed and required for 'historic' data).
525+
* @param \DateTime $end Final point of time period (only allowed and required for 'historic' data).
496526
*
497527
* @return bool|string Returns the fetched data.
498528
*
499529
* @api
500530
*/
501-
public function getRawCurrentUVIndexData($lat, $lon)
531+
public function getRawUVIndexData($mode, $lat, $lon, $cnt = null, $start = null, $end = null)
502532
{
503-
if (!$this->apiKey) {
504-
throw new \RuntimeException('Before using this method, you must set the api key using ->setApiKey()');
533+
if (!in_array($mode, array('current', 'forecast', 'historic'), true)) {
534+
throw new \InvalidArgumentException("$mode must be one of 'historic', 'forecast', 'current'.");
505535
}
506536
if (!is_float($lat) || !is_float($lon)) {
507537
throw new \InvalidArgumentException('$lat and $lon must be floating point numbers');
508538
}
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()');
539+
if (isset($cnt) && (!is_int($cnt) || $cnt > 8 || $cnt < 1)) {
540+
throw new \InvalidArgumentException('$cnt must be an int between 1 and 8');
532541
}
533-
if (!is_float($lat) || !is_float($lon)) {
534-
throw new \InvalidArgumentException('$lat and $lon must be floating point numbers');
542+
if (isset($start) && !$start instanceof \DateTime) {
543+
throw new \InvalidArgumentException('$start must be an instance of \DateTime');
544+
}
545+
if (isset($end) && !$end instanceof \DateTime) {
546+
throw new \InvalidArgumentException('$end must be an instance of \DateTime');
535547
}
536-
if (interface_exists('DateTimeInterface') && !$dateTime instanceof \DateTimeInterface || !$dateTime instanceof \DateTime) {
537-
throw new \InvalidArgumentException('$dateTime must be an instance of \DateTime or \DateTimeInterface');
548+
if ($mode === 'current' && (isset($start) || isset($end) || isset($cnt))) {
549+
throw new \InvalidArgumentException('Neither $start, $end, nor $cnt must be set for current data.');
550+
} elseif ($mode === 'forecast' && (isset($start) || isset($end) || !isset($cnt))) {
551+
throw new \InvalidArgumentException('$cnt needs to be set and both $start and $end must not be set for forecast data.');
552+
} elseif ($mode === 'historic' && (!isset($start) || !isset($end) || isset($cnt))) {
553+
throw new \InvalidArgumentException('Both $start and $end need to be set and $cnt must not be set for historic data.');
538554
}
539-
$url = $this->buildUVIndexUrl($lat, $lon, $dateTime, $timePrecision);
540555

556+
$url = $this->buildUVIndexUrl($mode, $lat, $lon, $cnt, $start, $end);
541557
return $this->cacheOrFetchResult($url);
542558
}
543559

@@ -564,10 +580,12 @@ private function cacheOrFetchResult($url)
564580
/** @var AbstractCache $cache */
565581
$cache = $this->cache;
566582
$cache->setSeconds($this->seconds);
583+
567584
if ($cache->isCached($url)) {
568585
$this->wasCached = true;
569586
return $cache->getCached($url);
570587
}
588+
571589
$result = $this->fetcher->fetch($url);
572590
$cache->setCached($url, $result);
573591
} else {
@@ -601,47 +619,41 @@ private function buildUrl($query, $units, $lang, $appid, $mode, $url)
601619
}
602620

603621
/**
604-
* @param float $lat
605-
* @param float $lon
606-
* @param \DateTime|\DateTimeImmutable $dateTime
607-
* @param string $timePrecision
622+
* @param string $mode The type of requested data.
623+
* @param float $lat The location's latitude.
624+
* @param float $lon The location's longitude.
625+
* @param int $cnt Number of returned days.
626+
* @param \DateTime $start Starting point of time period.
627+
* @param \DateTime $end Final point of time period.
608628
*
609629
* @return string
610630
*/
611-
private function buildUVIndexUrl($lat, $lon, $dateTime = null, $timePrecision = null)
631+
private function buildUVIndexUrl($mode, $lat, $lon, $cnt = null, \DateTime $start = null, \DateTime $end = null)
612632
{
613-
if ($dateTime !== null) {
614-
$format = '\Z';
615-
switch ($timePrecision) {
616-
/** @noinspection PhpMissingBreakStatementInspection */
617-
case 'second':
618-
$format = ':s' . $format;
619-
/** @noinspection PhpMissingBreakStatementInspection */
620-
case 'minute':
621-
$format = ':i' . $format;
622-
/** @noinspection PhpMissingBreakStatementInspection */
623-
case 'hour':
624-
$format = '\TH' . $format;
625-
/** @noinspection PhpMissingBreakStatementInspection */
626-
case 'day':
627-
$format = '-d' . $format;
628-
/** @noinspection PhpMissingBreakStatementInspection */
629-
case 'month':
630-
$format = '-m' . $format;
631-
case 'year':
632-
$format = 'Y' . $format;
633-
break;
634-
default:
635-
throw new \InvalidArgumentException('$timePrecision is invalid.');
636-
}
637-
// OWM only accepts UTC timezones.
638-
$dateTime->setTimezone(new \DateTimeZone('UTC'));
639-
$dateTime = $dateTime->format($format);
640-
} else {
641-
$dateTime = 'current';
633+
$params = array(
634+
'appid' => $this->apiKey,
635+
'lat' => $lat,
636+
'lon' => $lon,
637+
);
638+
639+
switch ($mode) {
640+
case 'historic':
641+
$requestMode = '/history';
642+
$params['start'] = $start->format('U');
643+
$params['end'] = $end->format('U');
644+
break;
645+
case 'forecast':
646+
$requestMode = '/forecast';
647+
$params['cnt'] = $cnt;
648+
break;
649+
case 'current':
650+
$requestMode = '';
651+
break;
652+
default:
653+
throw new \InvalidArgumentException("Invalid mode $mode for uv index url");
642654
}
643655

644-
return sprintf($this->uvIndexUrl . '/%s,%s/%s.json?appid=%s', $lat, $lon, $dateTime, $this->apiKey);
656+
return sprintf($this->uvIndexUrl . '%s?%s', $requestMode, http_build_query($params));
645657
}
646658

647659
/**
@@ -707,7 +719,8 @@ private function parseJson($answer)
707719
{
708720
$json = json_decode($answer);
709721
if (json_last_error() !== JSON_ERROR_NONE) {
710-
throw new OWMException('OpenWeatherMap returned an invalid json object. JSON error was: ' . $this->json_last_error_msg());
722+
throw new OWMException('OpenWeatherMap returned an invalid json object. JSON error was: "' .
723+
$this->json_last_error_msg() . '". The retrieved json was: ' . $answer);
711724
}
712725
if (isset($json->message)) {
713726
throw new OWMException('An error occurred: '. $json->message);

Cmfcmf/OpenWeatherMap/UVIndex.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ class UVIndex
4949
public function __construct($data)
5050
{
5151
$utctz = new \DateTimeZone('UTC');
52-
$this->time = new \DateTime($data->time, $utctz);
53-
$this->location = new Location($data->location->latitude, $data->location->longitude);
54-
$this->uvIndex = (float)$data->data;
52+
$this->time = new \DateTime($data->date_iso, $utctz);
53+
$this->location = new Location($data->lat, $data->lon);
54+
$this->uvIndex = (float)$data->value;
5555
}
5656
}

Examples/UVIndex.php

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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+
use Cmfcmf\OpenWeatherMap;
18+
use Cmfcmf\OpenWeatherMap\Exception as OWMException;
19+
20+
require_once __DIR__ . '/bootstrap.php';
21+
22+
$cli = false;
23+
$lf = '<br>';
24+
if (php_sapi_name() === 'cli') {
25+
$lf = "\n";
26+
$cli = true;
27+
}
28+
29+
// Language of data (try your own language here!):
30+
$lang = 'de';
31+
32+
// Units (can be 'metric' or 'imperial' [default]):
33+
$units = 'metric';
34+
35+
// Get OpenWeatherMap object. Don't use caching (take a look into Example_Cache.php to see how it works).
36+
$owm = new OpenWeatherMap();
37+
$owm->setApiKey($myApiKey);
38+
39+
// Example 1: Get current uv index in Berlin.
40+
$uvIndex = $owm->getCurrentUVIndex(52.520008, 13.404954);
41+
echo "EXAMPLE 1$lf";
42+
43+
echo "Current uv index: $uvIndex->uvIndex";
44+
echo $lf;
45+
46+
// Example 2: Get uv index forecast in Berlin.
47+
$forecast = $owm->getForecastUVIndex(52.520008, 13.404954);
48+
echo "EXAMPLE 2$lf";
49+
50+
foreach ($forecast as $day) {
51+
echo "{$day->time->format('r')} will have an uv index of: $day->uvIndex";
52+
echo $lf;
53+
}
54+
55+
56+
// Example 3: Get historic uv index in Berlin.
57+
$history = $owm->getHistoricUVIndex(52.520008, 13.404954, new DateTime('-4month'), new DateTime('-3month'));
58+
echo "EXAMPLE 3$lf";
59+
60+
foreach ($history as $day) {
61+
echo "{$day->time->format('r')} had an uv index of: $day->uvIndex";
62+
echo $lf;
63+
}

0 commit comments

Comments
 (0)