@@ -71,7 +71,7 @@ class OpenWeatherMap
71
71
/**
72
72
* @var string The basic api url to fetch uv index data from.
73
73
*/
74
- private $ uvIndexUrl = 'https://api.openweathermap.org/v3 /uvi ' ;
74
+ private $ uvIndexUrl = 'https://api.openweathermap.org/data/2.5 /uvi ' ;
75
75
76
76
/**
77
77
* @var AbstractCache|bool $cache The cache to use.
@@ -312,47 +312,73 @@ public function getWeatherHistory($query, \DateTime $start, $endOrCount = 1, $ty
312
312
/**
313
313
* Returns the current uv index at the location you specified.
314
314
*
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.
317
317
*
318
318
* @throws OpenWeatherMap\Exception If OpenWeatherMap returns an error.
319
319
* @throws \InvalidArgumentException If an argument error occurs.
320
320
*
321
- * @return UVIndex The uvi object.
321
+ * @return UVIndex
322
322
*
323
323
* @api
324
324
*/
325
325
public function getCurrentUVIndex ($ lat , $ lon )
326
326
{
327
- $ answer = $ this ->getRawCurrentUVIndexData ( $ lat , $ lon );
327
+ $ answer = $ this ->getRawUVIndexData ( ' current ' , $ lat , $ lon );
328
328
$ json = $ this ->parseJson ($ answer );
329
329
330
330
return new UVIndex ($ json );
331
331
}
332
332
333
333
/**
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.
335
337
*
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).
342
341
*
343
342
* @throws OpenWeatherMap\Exception If OpenWeatherMap returns an error.
344
343
* @throws \InvalidArgumentException If an argument error occurs.
345
344
*
346
- * @return UVIndex The uvi object.
345
+ * @return UVIndex[]
347
346
*
348
347
* @api
349
348
*/
350
- public function getUVIndex ($ lat , $ lon , $ dateTime , $ timePrecision = ' day ' )
349
+ public function getForecastUVIndex ($ lat , $ lon , $ cnt = 8 )
351
350
{
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 );
354
353
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 );
356
382
}
357
383
358
384
/**
@@ -489,55 +515,45 @@ public function getRawWeatherHistory($query, \DateTime $start, $endOrCount = 1,
489
515
}
490
516
491
517
/**
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.
493
519
*
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).
496
526
*
497
527
* @return bool|string Returns the fetched data.
498
528
*
499
529
* @api
500
530
*/
501
- public function getRawCurrentUVIndexData ( $ lat , $ lon )
531
+ public function getRawUVIndexData ( $ mode , $ lat , $ lon, $ cnt = null , $ start = null , $ end = null )
502
532
{
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'. " );
505
535
}
506
536
if (!is_float ($ lat ) || !is_float ($ lon )) {
507
537
throw new \InvalidArgumentException ('$lat and $lon must be floating point numbers ' );
508
538
}
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 ' );
532
541
}
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 ' );
535
547
}
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. ' );
538
554
}
539
- $ url = $ this ->buildUVIndexUrl ($ lat , $ lon , $ dateTime , $ timePrecision );
540
555
556
+ $ url = $ this ->buildUVIndexUrl ($ mode , $ lat , $ lon , $ cnt , $ start , $ end );
541
557
return $ this ->cacheOrFetchResult ($ url );
542
558
}
543
559
@@ -564,10 +580,12 @@ private function cacheOrFetchResult($url)
564
580
/** @var AbstractCache $cache */
565
581
$ cache = $ this ->cache ;
566
582
$ cache ->setSeconds ($ this ->seconds );
583
+
567
584
if ($ cache ->isCached ($ url )) {
568
585
$ this ->wasCached = true ;
569
586
return $ cache ->getCached ($ url );
570
587
}
588
+
571
589
$ result = $ this ->fetcher ->fetch ($ url );
572
590
$ cache ->setCached ($ url , $ result );
573
591
} else {
@@ -601,47 +619,41 @@ private function buildUrl($query, $units, $lang, $appid, $mode, $url)
601
619
}
602
620
603
621
/**
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.
608
628
*
609
629
* @return string
610
630
*/
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 )
612
632
{
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 " );
642
654
}
643
655
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 ) );
645
657
}
646
658
647
659
/**
@@ -707,7 +719,8 @@ private function parseJson($answer)
707
719
{
708
720
$ json = json_decode ($ answer );
709
721
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 );
711
724
}
712
725
if (isset ($ json ->message )) {
713
726
throw new OWMException ('An error occurred: ' . $ json ->message );
0 commit comments