1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
13:
14: 15: 16: 17: 18: 19: 20:
21: class Horde_Service_Weather_Google extends Horde_Service_Weather_Base
22: {
23: const API_URL = 'http://www.google.com/ig/api';
24:
25: 26: 27: 28: 29:
30: protected $_language = 'en';
31:
32: 33: 34: 35: 36: 37: 38: 39:
40: public $internalUnits;
41:
42: public $title = 'Google Weather';
43:
44: public $link = 'http://google.com';
45:
46: 47: 48: 49: 50: 51:
52: public $iconMap = array(
53: 'chance_of_rain' => '11.png',
54: 'chance_of_snow' => '14.png',
55: 'chance_of_storm' => '3.png',
56: 'chance_of_tstorm' => '3.png',
57: 'clear' => '32.png',
58: 'cloudy' => '26.png',
59: 'flurries' => '14.png',
60: 'fog' => '20.png',
61: 'haze' => '21.png',
62: 'mostly_cloudy' => '28.png',
63: 'mostly_sunny' => '34.png',
64: 'partly_cloudy' => '30.png',
65: 'partlysunny' => '30.png',
66: 'sleet' => '10.png',
67: 'rain' => '12.png',
68: 'snow' => '16.png',
69: 'sunny' => '32.png',
70: 'thunderstorm' => '3.png',
71: 'storm' => '12.png',
72: 'mist' => '29.png',
73: 'icy' => '7.png',
74: 'dust' => '19.png',
75: 'smoke' => '22.png'
76: );
77:
78: 79: 80: 81: 82: 83: 84: 85: 86:
87: public function __construct(array $params = array())
88: {
89: if (!empty($params['language'])) {
90: $this->_language = $params['language'];
91: }
92:
93: parent::__construct($params);
94: }
95:
96: 97: 98: 99: 100:
101: public function getCurrentConditions($location)
102: {
103: $this->_getCommonElements($location);
104: return $this->_current;
105: }
106:
107: 108: 109: 110: 111:
112: public function getForecast($location,
113: $length = Horde_Service_Weather::FORECAST_3DAY,
114: $type = Horde_Service_Weather::FORECAST_TYPE_STANDARD)
115: {
116: $this->_getCommonElements($location);
117: return $this->_forecast;
118: }
119:
120: 121: 122: 123: 124: 125: 126: 127: 128:
129: public function searchLocations($location,
130: $type = Horde_Service_Weather::SEARCHTYPE_STANDARD)
131: {
132:
133:
134: if ($type == Horde_Service_Weather::SEARCHTYPE_IP) {
135: throw new Horde_Service_Weather_Exception('Location by IP is not supported by this driver.');
136: }
137:
138: $this->_getCommonElements($location);
139: return $this->_station;
140: }
141:
142: 143: 144: 145: 146:
147: public function getSupportedForecastLengths()
148: {
149: return array(3 => Horde_Service_Weather::FORECAST_3DAY);
150: }
151:
152: 153:
154: protected function _getCommonElements($location)
155: {
156: if (!empty($this->_current) && $location == $this->_lastLocation) {
157: return;
158: }
159:
160: $this->_lastLocation = $location;
161: $url = new Horde_Url(self::API_URL);
162: $url = $url->add(array(
163: 'weather' => $location,
164: 'hl' => $this->_language
165: ))->setRaw(true);
166: $results = $this->_makeRequest($url);
167: if ($results->weather->problem_cause) {
168: throw new Horde_Service_Weather_Exception(
169: Horde_Service_Weather_Translation::t("There was a problem with the weather request. Maybe an invalid location?"));
170: }
171: $this->internalUnits = $results->weather->forecast_information->unit_system['data'] == 'US' ?
172: Horde_Service_Weather::UNITS_STANDARD :
173: Horde_Service_Weather::UNITS_METRIC;
174:
175: $this->_station = $this->_parseStation($results->weather->forecast_information);
176:
177:
178: if (!empty($this->_station->lat)) {
179: $date = new Horde_Date(time());
180: $this->_station->sunset = new Horde_Date(date_sunset($date->timestamp(), SUNFUNCS_RET_TIMESTAMP, $this->_station->lat, $this->_station->lon));
181: $this->_station->sunrise = new Horde_Date(date_sunrise($date->timestamp(), SUNFUNCS_RET_TIMESTAMP, $this->_station->lat, $this->_station->lon));
182: }
183: $this->_forecast = $this->_parseForecast($results->weather);
184: $this->_current = $this->_parseCurrent($results->weather->current_conditions);
185: $this->_current->time = new Horde_Date((string)$results->weather->forecast_information->current_date_time['data']);
186: }
187:
188: 189: 190: 191: 192: 193: 194:
195: protected function _parseStation($station)
196: {
197: $properties = array(
198:
199: 'name' => urldecode((string)$station->city['data']),
200: 'city' => urldecode((string)$station->city['data']),
201: 'state' => urldecode((string)$station->city['data']),
202: 'country' => '',
203: 'country_name' => '',
204: 'tz' => '',
205: 'lat' => $station->latitude_e6['data'],
206: 'lon' => $station->longitude_e6['data'],
207: 'zip' => '',
208: 'code' => (string)$station->postal_code['data'],
209: 'time' => (string)$station->current_date_time['data']
210: );
211:
212: return new Horde_Service_Weather_Station($properties);
213: }
214:
215: 216: 217: 218: 219: 220: 221:
222: protected function _parseForecast($forecast)
223: {
224: $forecast = new Horde_Service_Weather_Forecast_Google($forecast, $this);
225: return $forecast;
226: }
227:
228: 229: 230: 231: 232: 233: 234:
235: protected function _parseCurrent($current)
236: {
237:
238: $current = new Horde_Service_Weather_Current_Google($current, $this);
239: $current->units = $this->units;
240:
241: return $current;
242: }
243:
244: 245: 246: 247: 248:
249: protected function _makeRequest($url)
250: {
251: $cachekey = md5('hordeweather' . $url);
252: if ((!empty($this->_cache) &&
253: !($results = $this->_cache->get($cachekey, $this->_cache_lifetime))) ||
254: empty($this->_cache)) {
255: $response = $this->_http->get($url);
256: if (!$response->code == '200') {
257: throw new Horde_Service_Weather_Exception($response->code);
258: }
259: $ct = $response->getHeader('content-type');
260: $results = $response->getBody();
261: $matches = array();
262: if (preg_match("@charset=([^;\"'/>]+)@i", $ct, $matches)) {
263: $results = Horde_String::convertCharset($results, $matches[1], 'utf-8');
264: }
265: if (!empty($this->_cache)) {
266: $this->_cache->set($cachekey, $results);
267: }
268: }
269: try {
270: return new SimplexmlElement($results);
271: } catch (Exception $e) {
272: throw new Horde_Service_Weather_Exception($e);
273: }
274: }
275:
276: }