Skip to content

Commit 654211b

Browse files
committed
Merge branch 'M2Mobi-group_weather'
2 parents c3530d7 + 6c444d7 commit 654211b

File tree

3 files changed

+198
-15
lines changed

3 files changed

+198
-15
lines changed

Cmfcmf/OpenWeatherMap.php

+68
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
use Cmfcmf\OpenWeatherMap\AbstractCache;
2121
use Cmfcmf\OpenWeatherMap\CurrentWeather;
22+
use Cmfcmf\OpenWeatherMap\CurrentWeatherGroup;
2223
use Cmfcmf\OpenWeatherMap\Exception as OWMException;
2324
use Cmfcmf\OpenWeatherMap\Fetcher\CurlFetcher;
2425
use Cmfcmf\OpenWeatherMap\Fetcher\FetcherInterface;
@@ -46,6 +47,11 @@ class OpenWeatherMap
4647
*/
4748
private $weatherUrl = 'http://api.openweathermap.org/data/2.5/weather?';
4849

50+
/**
51+
* @var string The basic api url to fetch weather group data from.
52+
*/
53+
private $weatherGroupUrl = 'http://api.openweathermap.org/data/2.5/group?';
54+
4955
/**
5056
* @var string The basic api url to fetch weekly forecast data from.
5157
*/
@@ -182,6 +188,29 @@ public function getWeather($query, $units = 'imperial', $lang = 'en', $appid = '
182188
return new CurrentWeather($xml, $units);
183189
}
184190

191+
/**
192+
* Returns the current weather for a group of city ids.
193+
*
194+
* @param array $ids The city ids to get weather information for
195+
* @param string $units Can be either 'metric' or 'imperial' (default). This affects almost all units returned.
196+
* @param string $lang The language to use for descriptions, default is 'en'. For possible values see http://openweathermap.org/current#multi.
197+
* @param string $appid Your app id, default ''. See http://openweathermap.org/appid for more details.
198+
*
199+
* @throws OpenWeatherMap\Exception If OpenWeatherMap returns an error.
200+
* @throws \InvalidArgumentException If an argument error occurs.
201+
*
202+
* @return Array Array of CurrentWeather objects.
203+
*
204+
* @api
205+
*/
206+
public function getWeatherGroup($ids, $units = 'imperial', $lang = 'en', $appid = '')
207+
{
208+
$answer = $this->getRawWeatherGroupData($ids, $units, $lang, $appid);
209+
$json = $this->parseJson($answer);
210+
211+
return new CurrentWeatherGroup($json, $units);
212+
}
213+
185214
/**
186215
* Returns the forecast for the place you specified. DANGER: Might return
187216
* fewer results than requested due to a bug in the OpenWeatherMap API!
@@ -296,6 +325,26 @@ public function getRawWeatherData($query, $units = 'imperial', $lang = 'en', $ap
296325
return $this->cacheOrFetchResult($url);
297326
}
298327

328+
/**
329+
* Directly returns the JSON string returned by OpenWeatherMap for the group of current weather.
330+
* Only a JSON response format is supported for this webservice.
331+
*
332+
* @param array $ids The city ids to get weather information for
333+
* @param string $units Can be either 'metric' or 'imperial' (default). This affects almost all units returned.
334+
* @param string $lang The language to use for descriptions, default is 'en'. For possible values see http://openweathermap.org/current#multi.
335+
* @param string $appid Your app id, default ''. See http://openweathermap.org/appid for more details.
336+
*
337+
* @return string Returns false on failure and the fetched data in the format you specified on success.
338+
*
339+
* @api
340+
*/
341+
public function getRawWeatherGroupData($ids, $units = 'imperial', $lang = 'en', $appid = '')
342+
{
343+
$url = $this->buildUrl($ids, $units, $lang, $appid, 'json', $this->weatherGroupUrl);
344+
345+
return $this->cacheOrFetchResult($url);
346+
}
347+
299348
/**
300349
* Directly returns the xml/json/html string returned by OpenWeatherMap for the hourly forecast.
301350
*
@@ -468,6 +517,8 @@ private function buildQueryUrlParameter($query)
468517
switch ($query) {
469518
case is_array($query) && isset($query['lat']) && isset($query['lon']) && is_numeric($query['lat']) && is_numeric($query['lon']):
470519
return "lat={$query['lat']}&lon={$query['lon']}";
520+
case is_array($query) && is_numeric($query[0]):
521+
return 'id='.implode(',', $query);
471522
case is_numeric($query):
472523
return "id=$query";
473524
case is_string($query):
@@ -501,4 +552,21 @@ private function parseXML($answer)
501552
}
502553
}
503554
}
555+
556+
/**
557+
* @param string $answer The content returned by OpenWeatherMap.
558+
*
559+
* @return \stdClass
560+
* @throws OWMException If the content isn't valid JSON.
561+
*/
562+
private function parseJson($answer)
563+
{
564+
$json = json_decode($answer);
565+
if (json_last_error() !== JSON_ERROR_NONE) {
566+
throw new OWMException('OpenWeatherMap returned an invalid json object: ' . json_last_error_msg());
567+
}
568+
569+
return $json;
570+
}
571+
504572
}

Cmfcmf/OpenWeatherMap/CurrentWeather.php

+35-15
Original file line numberDiff line numberDiff line change
@@ -87,31 +87,51 @@ class CurrentWeather
8787
/**
8888
* Create a new weather object.
8989
*
90-
* @param \SimpleXMLElement $xml
91-
* @param string $units
90+
* @param mixed $data
91+
* @param string $units
9292
*
9393
* @internal
9494
*/
95-
public function __construct(\SimpleXMLElement $xml, $units)
95+
public function __construct($data, $units)
9696
{
97-
$this->city = new City($xml->city['id'], $xml->city['name'], $xml->city->coord['lon'], $xml->city->coord['lat'], $xml->city->country);
98-
$this->temperature = new Temperature(new Unit($xml->temperature['value'], $xml->temperature['unit']), new Unit($xml->temperature['min'], $xml->temperature['unit']), new Unit($xml->temperature['max'], $xml->temperature['unit']));
99-
$this->humidity = new Unit($xml->humidity['value'], $xml->humidity['unit']);
100-
$this->pressure = new Unit($xml->pressure['value'], $xml->pressure['unit']);
101-
102-
// This is kind of a hack, because the units are missing in the xml document.
97+
// This is kind of a hack, because the units are missing in the document.
10398
if ($units == 'metric') {
10499
$windSpeedUnit = 'm/s';
105100
} else {
106101
$windSpeedUnit = 'mph';
107102
}
108-
$this->wind = new Wind(new Unit($xml->wind->speed['value'], $windSpeedUnit, $xml->wind->speed['name']), new Unit($xml->wind->direction['value'], $xml->wind->direction['code'], $xml->wind->direction['name']));
109103

110-
$this->clouds = new Unit($xml->clouds['value'], null, $xml->clouds['name']);
111-
$this->precipitation = new Unit($xml->precipitation['value'], $xml->precipitation['unit'], $xml->precipitation['mode']);
112104
$utctz = new \DateTimeZone('UTC');
113-
$this->sun = new Sun(new \DateTime($xml->city->sun['rise'], $utctz), new \DateTime($xml->city->sun['set'], $utctz));
114-
$this->weather = new WeatherObj($xml->weather['number'], $xml->weather['value'], $xml->weather['icon']);
115-
$this->lastUpdate = new \DateTime($xml->lastupdate['value'], $utctz);
105+
106+
if ($data instanceof \SimpleXMLElement) {
107+
$this->city = new City($data->city['id'], $data->city['name'], $data->city->coord['lon'], $data->city->coord['lat'], $data->city->country);
108+
$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']));
109+
$this->humidity = new Unit($data->humidity['value'], $data->humidity['unit']);
110+
$this->pressure = new Unit($data->pressure['value'], $data->pressure['unit']);
111+
$this->wind = new Wind(new Unit($data->wind->speed['value'], $windSpeedUnit, $data->wind->speed['name']), new Unit($data->wind->direction['value'], $data->wind->direction['code'], $data->wind->direction['name']));
112+
$this->clouds = new Unit($data->clouds['value'], null, $data->clouds['name']);
113+
$this->precipitation = new Unit($data->precipitation['value'], $data->precipitation['unit'], $data->precipitation['mode']);
114+
$this->sun = new Sun(new \DateTime($data->city->sun['rise'], $utctz), new \DateTime($data->city->sun['set'], $utctz));
115+
$this->weather = new WeatherObj($data->weather['number'], $data->weather['value'], $data->weather['icon']);
116+
$this->lastUpdate = new \DateTime($data->lastupdate['value'], $utctz);
117+
} else {
118+
$this->city = new City($data->id, $data->name, $data->coord->lon, $data->coord->lat, $data->sys->country);
119+
$this->temperature = new Temperature(new Unit($data->main->temp, $units), new Unit($data->main->temp_min, $units), new Unit($data->main->temp_max, $units));
120+
$this->humidity = new Unit($data->main->humidity, '%');
121+
$this->pressure = new Unit($data->main->pressure, 'hPa');
122+
$this->wind = new Wind(new Unit($data->wind->speed, $windSpeedUnit), new Unit($data->wind->deg));
123+
$this->clouds = new Unit($data->clouds->all, '%');
124+
125+
// the rain field is not always present in the JSON response
126+
// and sometimes it contains the field '1h', sometimes the field '3h'
127+
$rain = isset($data->rain) ? (array) $data->rain : [];
128+
$rainUnit = !empty($rain) ? key($rain) : '';
129+
$rainValue = !empty($rain) ? current($rain) : 0.0;
130+
$this->precipitation = new Unit($rainValue, $rainUnit);
131+
132+
$this->sun = new Sun(\DateTime::createFromFormat('U', $data->sys->sunrise, $utctz), \DateTime::createFromFormat('U', $data->sys->sunset, $utctz));
133+
$this->weather = new WeatherObj($data->weather[0]->id, $data->weather[0]->description, $data->weather[0]->icon);
134+
$this->lastUpdate = \DateTime::createFromFormat('U', $data->dt, $utctz);
135+
}
116136
}
117137
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
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+
18+
namespace Cmfcmf\OpenWeatherMap;
19+
20+
use Cmfcmf\OpenWeatherMap;
21+
22+
/**
23+
* Class CurrentWeatherGroup used to hold the current weather data for a group of cities.
24+
*/
25+
class CurrentWeatherGroup implements \Iterator
26+
{
27+
/**
28+
* An array of {@link CurrentWeather} objects.
29+
*
30+
* @var CurrentWeather[]
31+
*
32+
* @see CurrentWeather The CurrentWeather class.
33+
*/
34+
private $currentWeathers;
35+
36+
/**
37+
* @internal
38+
*/
39+
private $position = 0;
40+
41+
/**
42+
* Create a new current weathers group object.
43+
*
44+
* @param \stdClass $json The current weathers group json.
45+
* @param string $units The units used.
46+
*
47+
* @internal
48+
*/
49+
public function __construct(\stdClass $json, $units)
50+
{
51+
foreach ($json->list as $currentWeather) {
52+
$this->currentWeathers[] = new CurrentWeather($currentWeather, $units);
53+
}
54+
}
55+
56+
/**
57+
* @internal
58+
*/
59+
public function rewind()
60+
{
61+
$this->position = 0;
62+
}
63+
64+
/**
65+
* @internal
66+
*/
67+
public function current()
68+
{
69+
return $this->currentWeathers[$this->position];
70+
}
71+
72+
/**
73+
* @internal
74+
*/
75+
public function key()
76+
{
77+
return $this->current()->city->id;
78+
}
79+
80+
/**
81+
* @internal
82+
*/
83+
public function next()
84+
{
85+
++$this->position;
86+
}
87+
88+
/**
89+
* @internal
90+
*/
91+
public function valid()
92+
{
93+
return isset($this->currentWeathers[$this->position]);
94+
}
95+
}

0 commit comments

Comments
 (0)