Skip to content

Commit 45fab12

Browse files
authoredJun 9, 2019
Version 3 Update (#134)
* Remove deprecated constructor and methods * Replace '°C' by °C * Use °F instead of just F * Switch to PSR-6 cache implementation * Use PSR-17 and PSR-18 for HTTP calls * Apply fixes from StyleCI (#135) * Allow php-http/guzzle6-adapter@1 * Drop support for PHP 5 and throw error on status codes other than 200 psr/http-client requires PHP 7 * Hmpf * Add forgotten conversion from "F" to "°F" * Consistently capitalize PHP and API * Apply fixes from StyleCI * Apply fixes from StyleCI * Remove weather history support I am removing support for querying weather history, because there is no way to receive a free API key to test it. * Fix typo
1 parent fdac750 commit 45fab12

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1641
-1618
lines changed
 

‎.travis.yml

+5-6
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,14 @@ matrix:
1010
- php: 7.2
1111
- php: 7.1
1212
- php: 7.0
13-
- php: 5.6
14-
- php: 5.5
15-
- php: 5.4
16-
- php: 5.3
17-
dist: precise
1813
fast_finish: true
1914
allow_failures:
2015
- php: nightly
2116

17+
cache:
18+
directories:
19+
- "$HOME/.composer/cache"
20+
2221
before_install:
2322
- phpenv config-rm xdebug.ini || echo "xdebug not available"
2423
- INI_FILE=~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
@@ -28,7 +27,7 @@ before_install:
2827
install:
2928
# Use composer update instead of composer install to install a working set of
3029
# dependencies on all PHP versions.
31-
- composer update
30+
- composer update --prefer-dist --prefer-stable
3231

3332
script:
3433
- vendor/bin/phpunit --coverage-text --coverage-clover=coverage.xml

‎Cmfcmf/OpenWeatherMap.php

+55-144
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,31 @@
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

1819
namespace Cmfcmf;
1920

20-
use Cmfcmf\OpenWeatherMap\AbstractCache;
2121
use Cmfcmf\OpenWeatherMap\CurrentWeather;
2222
use Cmfcmf\OpenWeatherMap\UVIndex;
2323
use Cmfcmf\OpenWeatherMap\CurrentWeatherGroup;
2424
use Cmfcmf\OpenWeatherMap\Exception as OWMException;
25-
use Cmfcmf\OpenWeatherMap\Fetcher\CurlFetcher;
26-
use Cmfcmf\OpenWeatherMap\Fetcher\FetcherInterface;
27-
use Cmfcmf\OpenWeatherMap\Fetcher\FileGetContentsFetcher;
2825
use 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

Comments
 (0)
Please sign in to comment.