1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13: 14: 15: 16: 17: 18:
19: class Horde_Block_Weather extends Horde_Core_Block
20: {
21: 22:
23: public $updateable = true;
24:
25: protected $_refreshParams;
26:
27: 28:
29: public function __construct($app, $params = array())
30: {
31:
32: parent::__construct($app, $params);
33: $this->_name = _("weather");
34: }
35:
36: 37: 38: 39: 40: 41: 42: 43:
44: public function refreshContent($vars = null)
45: {
46: $this->_refreshParams = $vars;
47: return $this->_content();
48: }
49:
50: 51:
52: protected function _title()
53: {
54: return _("Weather");
55: }
56:
57: 58:
59: protected function _params()
60: {
61: $weather = $GLOBALS['injector']
62: ->getInstance('Horde_Weather');
63: $lengths = $weather->getSupportedForecastLengths();
64: return array(
65: 'location' => array(
66: 'type' => 'text',
67: 'name' => _("Location"),
68: 'default' => 'Boston,MA'
69: ),
70: 'units' => array(
71: 'type' => 'enum',
72: 'name' => _("Units"),
73: 'default' => 'standard',
74: 'values' => array(
75: Horde_Service_Weather::UNITS_STANDARD => _("English"),
76: Horde_Service_Weather::UNITS_METRIC => _("Metric")
77: )
78: ),
79: 'days' => array(
80: 'type' => 'enum',
81: 'name' => _("Forecast Days (note that the returned forecast returns both day and night; a large number here could result in a wide block)"),
82: 'default' => 3,
83: 'values' => $lengths
84: ),
85: 'detailedForecast' => array(
86: 'type' => 'checkbox',
87: 'name' => _("Display detailed forecast"),
88: 'default' => 0
89: )
90: );
91: }
92:
93: 94:
95: protected function _content()
96: {
97: global $conf, $prefs;
98:
99: $weather = $GLOBALS['injector']
100: ->getInstance('Horde_Weather');
101:
102:
103: $weather->units = $this->_params['units'];
104:
105: if (!empty($this->_refreshParams) && !empty($this->_refreshParams->location)) {
106: $location = $this->_refreshParams->location;
107: $html = '';
108: $instance = '';
109: } else {
110: $instance = hash('md5', mt_rand());
111: $GLOBALS['injector']
112: ->getInstance('Horde_Core_Factory_Imple')
113: ->create(
114: 'WeatherLocationAutoCompleter',
115: array(
116: 'triggerId' => 'location' . $instance,
117: 'instance' => $instance
118: )
119: );
120:
121: $html = '<input id="location' . $instance . '" name="location' . $instance . '"><input type="button" id="button' . $instance . '" class="button" value="'
122: . _("Change Location") . '" /><span style="display:none;" id="location' . $instance . '_loading_img">'
123: . Horde::img('loading.gif') . '</span>';
124: $location = $this->_params['location'];
125: }
126:
127:
128: try {
129: $location = $weather->searchLocations($location);
130: } catch (Horde_Service_Weather_Exception $e) {
131: return $e->getMessage();
132: }
133:
134: $html .= '<div id="weathercontent' . $instance . '">';
135:
136: if (is_array($location)) {
137:
138: $html = sprintf(_("Several locations possible with the parameter: %s"), $this->_params['location'])
139: . '<br />';
140: foreach ($location as $real_location) {
141: $html .= '<li>' . $real_location->city . ', ' . $real_location->state . '(' . $real_location->code . ")</li>\n";
142: }
143: $html .= '</ul>';
144: return $html;
145: }
146: try {
147: $forecast = $weather->getForecast($location->code, $this->_params['days']);
148: $station = $weather->getStation();
149: $current = $weather->getCurrentConditions($location->code);
150: } catch (Horde_Service_Weather_Exception $e) {
151: return $e->getMessage();
152: }
153:
154:
155: $units = $weather->getUnits($weather->units);
156:
157:
158: $html .= '<div class="control">'
159: . '<strong>' . $station->name . '</strong>';
160: if ($current->time->timestamp()) {
161: $html .= ' ' . sprintf(_("Local time: %s %s"), $current->time->strftime($GLOBALS['prefs']->getValue('date_format')), $current->time->strftime($GLOBALS['prefs']->getValue('time_format')));
162: }
163: $html .= '</div>';
164:
165:
166: if ($station->sunrise) {
167: $html .= '<strong>' . _("Sunrise") . ': </strong>'
168: . Horde::img('block/sunrise/sunrise.png', _("Sunrise"))
169: . sprintf("%s %s", $station->sunrise->strftime($GLOBALS['prefs']->getValue('date_format')), $station->sunrise->strftime($GLOBALS['prefs']->getValue('time_format')));
170: $html .= ' <strong>' . _("Sunset") . ': </strong>'
171: . Horde::img('block/sunrise/sunset.png', _("Sunset"))
172: . sprintf("%s %s", $station->sunset->strftime($GLOBALS['prefs']->getValue('date_format')), $station->sunset->strftime($GLOBALS['prefs']->getValue('time_format')));
173: $html .= '<br />';
174: }
175:
176:
177: $html .= '<strong>' . _("Temperature") . ': </strong>' .
178: $current->temp . '°' . Horde_String::upper($units['temp']);
179:
180:
181: if (is_numeric($current->dewpoint)) {
182: $html .= ' <strong>' . _("Dew point") . ': </strong>' .
183: round($current->dewpoint) . '°' . Horde_String::upper($units['temp']);
184: }
185:
186:
187:
188:
189:
190:
191:
192: if ($current->pressure) {
193: $html .= '<br /><strong>' . _("Pressure") . ': </strong>';
194: $trend = $current->pressure_trend;
195: if (empty($trend)) {
196: $html .= sprintf('%d %s',
197: round($current->pressure), $units['pres']);
198: } else {
199: $html .= sprintf(_("%d %s and %s"),
200: round($current->pressure), $units['pres'],
201: _($trend));
202: }
203: }
204: if ($current->wind_direction) {
205:
206: $html .= '<br /><strong>' . _("Wind") . ': </strong>';
207:
208: $html .= sprintf(
209: _("From the %s (%s °) at %s %s"),
210: $current->wind_direction,
211: $current->wind_degrees,
212: $current->wind_speed,
213: $units['wind']);
214: if ($current->wind_gust > 0) {
215: $html .= ', ' . _("gusting") . ' ' . $current->wind_gust . ' ' . $units['wind'];
216: }
217: }
218:
219:
220: if ($current->humidity) {
221: $html .= '<br /><strong>' . _("Humidity") . ': </strong>' . $current->humidity;
222: }
223:
224: if ($current->visibility) {
225:
226: $html .= ' <strong>' . _("Visibility") . ': </strong>'
227: . round($current->visibility) . ' ' . $units['vis'];
228: }
229:
230:
231: $condition = $current->condition;
232: $html .= '<br /><strong>' . _("Current condition") . ': </strong>'
233: . Horde::img(Horde_Themes::img('weather/32x32/' . $current->icon))
234: . ' ' . $condition;
235:
236:
237: if ($this->_params['days'] > 0) {
238: $html .= '<div class="control"><strong>' .
239: sprintf(_("%d-day forecast"), $this->_params['days']) .
240: '</strong></div>';
241:
242: $futureDays = 0;
243: $html .= '<table class="horde-block-weather">';
244:
245:
246: $html .= '<tr>';
247: $html .= '<th>' . _("Day") . '</th><th>' .
248: sprintf(_("Temperature%s(%sHi%s/%sLo%s)"),
249: '<br />',
250: '<span style="color:red">', '</span>',
251: '<span style="color:blue">', '</span>') .
252: '</th><th>' . _("Condition") . '</th>';
253:
254: if (isset($this->_params['detailedForecast'])) {
255: if (in_array(Horde_Service_Weather::FORECAST_FIELD_PRECIPITATION, $forecast->fields)) {
256: $html .= '<th>' . sprintf(_("Precipitation%schance"), '<br />') . '</th>';
257: }
258:
259: if (in_array(Horde_Service_Weather::FORECAST_FIELD_HUMIDITY, $forecast->fields)) {
260: $html .= '<th>' . _("Humidity") . '</th>';
261: }
262:
263: if (in_array(Horde_Service_Weather::FORECAST_FIELD_WIND, $forecast->fields)) {
264: $html .= '<th>' . _("Wind") . '</th>';
265: }
266: }
267:
268: $html .= '</tr>';
269: $which = -1;
270: foreach ($forecast as $day) {
271: $which++;
272: if ($which > $this->_params['days']) {
273: break;
274: }
275: $html .= '<tr class="item0">';
276:
277: $html .= '<td><strong>';
278:
279: if ($which == 0) {
280: $html .= _("Today");
281: } elseif ($which == 1) {
282: $html .= _("Tomorrow");
283: } else {
284: $html .= strftime('%A', mktime(0, 0, 0, date('m'), date('d') + $futureDays, date('Y')));
285: }
286: $html .= '</strong><br />' .
287: strftime('%b %d', mktime(0, 0, 0, date('m'), date('d') + $futureDays, date('Y'))) .
288: '</td>';
289:
290:
291: $condition = $day->conditions;
292:
293:
294: $html .= '<td>'
295: . '<span style="color:red">' . $day->high . '°'
296: . Horde_String::upper($units['temp']) . '</span>/'
297: . '<span style="color:blue">' . $day->low . '°'
298: . Horde_String::upper($units['temp']) . '</span></td>';
299:
300:
301: $html .= '<td>'
302: . Horde::img(Horde_Themes::img('weather/32x32/' . $day->icon))
303: . '<br />' . $condition . '</td>';
304:
305: if (isset($this->_params['detailedForecast'])) {
306: if (in_array(Horde_Service_Weather::FORECAST_FIELD_PRECIPITATION, $forecast->fields)) {
307: $html .= '<td>'
308: . ($day->precipitation_percent >= 0 ? $day->precipitation_percent . '%' : _("N/A")) . '</td>';
309: }
310: if (in_array(Horde_Service_Weather::FORECAST_FIELD_HUMIDITY, $forecast->fields)) {
311: $html .= '<td>'
312: . ($day->humidity ? $day->humidity . '%': _("N/A")) . '</td>';
313: }
314: if (in_array(Horde_Service_Weather::FORECAST_FIELD_WIND, $forecast->fields)) {
315:
316: if ($day->wind_direction) {
317: $html .= '<td>' . ' '
318: . sprintf(_("From the %s at %s %s"),
319: $day->wind_direction,
320: $day->wind_speed,
321: $units['wind']);
322: if ($day->wind_gust && $day->wind_gust > $day->wind_speed) {
323: $html .= ', ' . _("gusting") . ' '
324: . $day->wind_gust . ' ' . $units['wind'];
325: }
326: $html .= '</td>';
327: } else {
328: $html .= '<td>' . _("N/A") . '</td>';
329: }
330: }
331: }
332: $html .= '</tr>';
333: $futureDays++;
334: }
335: $html .= '</table>';
336: }
337:
338: if ($weather->logo) {
339: $html .= '<div class="rightAlign">'
340: . _("Weather data provided by") . ' '
341: . Horde::link(
342: Horde::externalUrl($weather->link),
343: $weather->title, '', '_blank', '', $weather->title)
344: . Horde::img(new Horde_Themes_Image($weather->logo))
345: . '</a></div>';
346: } else {
347: $html .= '<div class="rightAlign">'
348: . _("Weather data provided by") . ' '
349: . Horde::link(
350: Horde::externalUrl($weather->link),
351: $weather->title, '', '_blank', '', $weather->title)
352: . '<em>' . $weather->title . '</em>'
353: . '</a></div>';
354: }
355:
356: return $html . '</div>';
357: }
358:
359: }
360: