11<?php
2- /**
3- * OpenWeatherMap-PHP-API — A php api to parse weather data from http://www.OpenWeatherMap.org .
2+
3+ /*
4+ * OpenWeatherMap-PHP-API — A PHP API to parse weather data from https://OpenWeatherMap.org.
45 *
56 * @license MIT
67 *
78 * Please see the LICENSE file distributed with this source code for further
89 * information regarding copyright and licensing.
910 *
1011 * Please visit the following links to read about the usage policies and the license of
11- * OpenWeatherMap before using this class :
12+ * OpenWeatherMap data before using this library :
1213 *
13- * @see http ://www. OpenWeatherMap.org
14- * @see http ://www. OpenWeatherMap.org/terms
15- * @see http ://openweathermap .org/appid
14+ * @see https ://OpenWeatherMap.org/price
15+ * @see https ://OpenWeatherMap.org/terms
16+ * @see https ://OpenWeatherMap .org/appid
1617 */
1718
1819namespace Cmfcmf ;
1920
20- use Cmfcmf \OpenWeatherMap \AbstractCache ;
2121use Cmfcmf \OpenWeatherMap \CurrentWeather ;
2222use Cmfcmf \OpenWeatherMap \UVIndex ;
2323use Cmfcmf \OpenWeatherMap \CurrentWeatherGroup ;
2424use Cmfcmf \OpenWeatherMap \Exception as OWMException ;
25- use Cmfcmf \OpenWeatherMap \Fetcher \CurlFetcher ;
26- use Cmfcmf \OpenWeatherMap \Fetcher \FetcherInterface ;
27- use Cmfcmf \OpenWeatherMap \Fetcher \FileGetContentsFetcher ;
2825use Cmfcmf \OpenWeatherMap \WeatherForecast ;
29- use Cmfcmf \OpenWeatherMap \WeatherHistory ;
26+ use Psr \Cache \CacheItemPoolInterface ;
27+ use Psr \Http \Client \ClientInterface ;
28+ use Psr \Http \Message \RequestFactoryInterface ;
3029
3130/**
3231 * Main class for the OpenWeatherMap-PHP-API. Only use this class.
@@ -63,35 +62,35 @@ class OpenWeatherMap
6362 */
6463 private $ weatherDailyForecastUrl = 'https://api.openweathermap.org/data/2.5/forecast/daily? ' ;
6564
66- /**
67- * @var string The basic api url to fetch history weather data from.
68- */
69- private $ weatherHistoryUrl = 'https://history.openweathermap.org/data/2.5/history/city? ' ;
70-
7165 /**
7266 * @var string The basic api url to fetch uv index data from.
7367 */
7468 private $ uvIndexUrl = 'https://api.openweathermap.org/data/2.5/uvi ' ;
7569
7670 /**
77- * @var AbstractCache|bool $cache The cache to use.
71+ * @var CacheItemPoolInterface|null $cache The cache to use.
7872 */
79- private $ cache = false ;
73+ private $ cache = null ;
8074
8175 /**
8276 * @var int
8377 */
84- private $ seconds ;
78+ private $ ttl ;
8579
8680 /**
8781 * @var bool
8882 */
8983 private $ wasCached = false ;
9084
9185 /**
92- * @var FetcherInterface The url fetcher.
86+ * @var ClientInterface
87+ */
88+ private $ httpClient ;
89+
90+ /**
91+ * @var RequestFactoryInterface
9392 */
94- private $ fetcher ;
93+ private $ httpRequestFactory ;
9594
9695 /**
9796 * @var string
@@ -101,45 +100,31 @@ class OpenWeatherMap
101100 /**
102101 * Constructs the OpenWeatherMap object.
103102 *
104- * @param string $apiKey The OpenWeatherMap API key. Required and only optional for BC.
105- * @param null|FetcherInterface $fetcher The interface to fetch the data from OpenWeatherMap. Defaults to
106- * CurlFetcher() if cURL is available. Otherwise defaults to
107- * FileGetContentsFetcher() using 'file_get_contents()'.
108- * @param bool|string $cache If set to false, caching is disabled. Otherwise this must be a class
109- * extending AbstractCache. Defaults to false.
110- * @param int $seconds How long weather data shall be cached. Default 10 minutes.
111- *
112- * @throws \Exception If $cache is neither false nor a valid callable extending Cmfcmf\OpenWeatherMap\Util\Cache.
103+ * @param string $apiKey The OpenWeatherMap API key. Required.
104+ * @param ClientInterface $httpClient A PSR-18 compatible HTTP client implementation.
105+ * @param RequestFactoryInterface $httpRequestFactory A PSR-17 compatbile HTTP request factory implementation.
106+ * @param null|CacheItemPoolInterface $cache If set to null, caching is disabled. Otherwise this must be
107+ * a PSR-6 compatible cache instance.
108+ * @param int $ttl How long weather data shall be cached. Defaults to 10 minutes.
109+ * Only used if $cache is not null.
113110 *
114111 * @api
115112 */
116- public function __construct ($ apiKey = '' , $ fetcher = null , $ cache = false , $ seconds = 600 )
113+ public function __construct ($ apiKey , $ httpClient , $ httpRequestFactory , $ cache = null , $ ttl = 600 )
117114 {
118115 if (!is_string ($ apiKey ) || empty ($ apiKey )) {
119- // BC
120- $ seconds = $ cache !== false ? $ cache : 600 ;
121- $ cache = $ fetcher !== null ? $ fetcher : false ;
122- $ fetcher = $ apiKey !== '' ? $ apiKey : null ;
123- } else {
124- $ this ->apiKey = $ apiKey ;
116+ throw new \InvalidArgumentException ("You must provide an API key. " );
125117 }
126118
127- if ($ cache !== false && !($ cache instanceof AbstractCache)) {
128- throw new \InvalidArgumentException ('The cache class must implement the FetcherInterface! ' );
129- }
130- if (!is_numeric ($ seconds )) {
131- throw new \InvalidArgumentException ('$seconds must be numeric. ' );
132- }
133- if (!isset ($ fetcher )) {
134- $ fetcher = (function_exists ('curl_version ' )) ? new CurlFetcher () : new FileGetContentsFetcher ();
135- }
136- if ($ seconds == 0 ) {
137- $ cache = false ;
119+ if (!is_numeric ($ ttl )) {
120+ throw new \InvalidArgumentException ('$ttl must be numeric. ' );
138121 }
139122
123+ $ this ->apiKey = $ apiKey ;
124+ $ this ->httpClient = $ httpClient ;
125+ $ this ->httpRequestFactory = $ httpRequestFactory ;
140126 $ this ->cache = $ cache ;
141- $ this ->seconds = $ seconds ;
142- $ this ->fetcher = $ fetcher ;
127+ $ this ->ttl = $ ttl ;
143128 }
144129
145130 /**
@@ -279,39 +264,6 @@ public function getDailyWeatherForecast($query, $units = 'imperial', $lang = 'en
279264 return new WeatherForecast ($ xml , $ units , $ days );
280265 }
281266
282- /**
283- * Returns the weather history for the place you specified.
284- *
285- * @param array|int|string $query The place to get weather information for. For possible values see ::getWeather.
286- * @param \DateTime $start
287- * @param int $endOrCount
288- * @param string $type Can either be 'tick', 'hour' or 'day'.
289- * @param string $units Can be either 'metric' or 'imperial' (default). This affects almost all units returned.
290- * @param string $lang The language to use for descriptions, default is 'en'. For possible values see http://openweathermap.org/current#multi.
291- * @param string $appid Your app id, default ''. See http://openweathermap.org/appid for more details.
292- *
293- * @throws OpenWeatherMap\Exception If OpenWeatherMap returns an error.
294- * @throws \InvalidArgumentException If an argument error occurs.
295- *
296- * @return WeatherHistory
297- *
298- * @api
299- */
300- public function getWeatherHistory ($ query , \DateTime $ start , $ endOrCount = 1 , $ type = 'hour ' , $ units = 'imperial ' , $ lang = 'en ' , $ appid = '' )
301- {
302- if (!in_array ($ type , array ('tick ' , 'hour ' , 'day ' ))) {
303- throw new \InvalidArgumentException ('$type must be either "tick", "hour" or "day" ' );
304- }
305-
306- $ xml = json_decode ($ this ->getRawWeatherHistory ($ query , $ start , $ endOrCount , $ type , $ units , $ lang , $ appid ), true );
307-
308- if ($ xml ['cod ' ] != 200 ) {
309- throw new OWMException ($ xml ['message ' ], $ xml ['cod ' ]);
310- }
311-
312- return new WeatherHistory ($ xml , $ query );
313- }
314-
315267 /**
316268 * Returns the current uv index at the location you specified.
317269 *
@@ -476,47 +428,6 @@ public function getRawDailyForecastData($query, $units = 'imperial', $lang = 'en
476428 return $ this ->cacheOrFetchResult ($ url );
477429 }
478430
479- /**
480- * Directly returns the json string returned by OpenWeatherMap for the weather history.
481- *
482- * @param array|int|string $query The place to get weather information for. For possible values see ::getWeather.
483- * @param \DateTime $start The \DateTime object of the date to get the first weather information from.
484- * @param \DateTime|int $endOrCount Can be either a \DateTime object representing the end of the period to
485- * receive weather history data for or an integer counting the number of
486- * reports requested.
487- * @param string $type The period of the weather history requested. Can be either be either "tick",
488- * "hour" or "day".
489- * @param string $units Can be either 'metric' or 'imperial' (default). This affects almost all units returned.
490- * @param string $lang The language to use for descriptions, default is 'en'. For possible values see http://openweathermap.org/current#multi.
491- * @param string $appid Your app id, default ''. See http://openweathermap.org/appid for more details.
492- *
493- * @throws \InvalidArgumentException
494- *
495- * @return string Returns false on failure and the fetched data in the format you specified on success.
496- *
497- * Warning If an error occurred, OpenWeatherMap ALWAYS returns data in json format.
498- *
499- * @api
500- */
501- public function getRawWeatherHistory ($ query , \DateTime $ start , $ endOrCount = 1 , $ type = 'hour ' , $ units = 'imperial ' , $ lang = 'en ' , $ appid = '' )
502- {
503- if (!in_array ($ type , array ('tick ' , 'hour ' , 'day ' ))) {
504- throw new \InvalidArgumentException ('$type must be either "tick", "hour" or "day" ' );
505- }
506-
507- $ url = $ this ->buildUrl ($ query , $ units , $ lang , $ appid , 'json ' , $ this ->weatherHistoryUrl );
508- $ url .= "&type= $ type&start= {$ start ->format ('U ' )}" ;
509- if ($ endOrCount instanceof \DateTime) {
510- $ url .= "&end= {$ endOrCount ->format ('U ' )}" ;
511- } elseif (is_numeric ($ endOrCount ) && $ endOrCount > 0 ) {
512- $ url .= "&cnt= $ endOrCount " ;
513- } else {
514- throw new \InvalidArgumentException ('$endOrCount must be either a \DateTime or a positive integer. ' );
515- }
516-
517- return $ this ->cacheOrFetchResult ($ url );
518- }
519-
520431 /**
521432 * Directly returns the json string returned by OpenWeatherMap for the UV index data.
522433 *
@@ -570,14 +481,6 @@ public function wasCached()
570481 return $ this ->wasCached ;
571482 }
572483
573- /**
574- * @deprecated Use {@link self::getRawWeatherData()} instead.
575- */
576- public function getRawData ($ query , $ units = 'imperial ' , $ lang = 'en ' , $ appid = '' , $ mode = 'xml ' )
577- {
578- return $ this ->getRawWeatherData ($ query , $ units , $ lang , $ appid , $ mode );
579- }
580-
581484 /**
582485 * Fetches the result or delivers a cached version of the result.
583486 *
@@ -587,20 +490,28 @@ public function getRawData($query, $units = 'imperial', $lang = 'en', $appid = '
587490 */
588491 private function cacheOrFetchResult ($ url )
589492 {
590- if ($ this ->cache !== false ) {
591- /** @var AbstractCache $cache */
592- $ cache = $ this ->cache ;
593- $ cache ->setSeconds ($ this ->seconds );
594-
595- if ($ cache ->isCached ($ url )) {
493+ if ($ this ->cache !== null ) {
494+ $ key = str_replace (
495+ ["{ " , "} " , "( " , ") " , "/ " , "\\" , "@ " , ": " ],
496+ ["_ " , "_ " , "_ " , "_ " , "_ " , "_ " , "_ " , "_ " ],
497+ $ url );
498+ $ item = $ this ->cache ->getItem ($ key );
499+ if ($ item ->isHit ()) {
596500 $ this ->wasCached = true ;
597- return $ cache -> getCached ( $ url );
501+ return $ item -> get ( );
598502 }
503+ }
599504
600- $ result = $ this ->fetcher ->fetch ($ url );
601- $ cache ->setCached ($ url , $ result );
602- } else {
603- $ result = $ this ->fetcher ->fetch ($ url );
505+ $ response = $ this ->httpClient ->sendRequest ($ this ->httpRequestFactory ->createRequest ("GET " , $ url ));
506+ $ result = $ response ->getBody ()->getContents ();
507+ if ($ response ->getStatusCode () !== 200 ) {
508+ throw new OWMException ('OpenWeatherMap returned a response with status code ' . $ response ->getStatusCode () . ' and the following content ' . $ result );
509+ }
510+
511+ if ($ this ->cache !== null ) {
512+ $ item ->set ($ result );
513+ $ item ->expiresAfter ($ this ->ttl );
514+ $ this ->cache ->save ($ item );
604515 }
605516 $ this ->wasCached = false ;
606517
@@ -723,7 +634,7 @@ private function parseXML($answer)
723634 /**
724635 * @param string $answer The content returned by OpenWeatherMap.
725636 *
726- * @return \stdClass
637+ * @return \stdClass|array
727638 * @throws OWMException If the content isn't valid JSON.
728639 */
729640 private function parseJson ($ answer )
0 commit comments