1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38:
39: class weather {
40:
41: 42: 43: 44:
45: private $themes = array(
46: 'blue' => 'theme-blue',
47: 'darkblue' => 'theme-darkblue',
48: 'green' => 'theme-green',
49: 'black' => 'theme-black',
50: 'darkred' => 'theme-darkred'
51: );
52:
53: 54: 55: 56:
57: private $theme = "theme-darkblue";
58:
59: 60: 61: 62:
63: private $weather_api = "http://api.openweathermap.org/data/2.5/weather?units=metric&";
64: private $forecast_api = "http://api.openweathermap.org/data/2.5/forecast/daily/?cnt=4&units=metric&mode=json&";
65:
66: 67: 68: 69:
70: private $city = "";
71: private $city_id = "";
72: private $city_lat = "";
73: private $city_lon = "";
74:
75: 76: 77: 78:
79: private $temp_metric = "c";
80:
81: 82: 83: 84:
85: private $output = "";
86:
87: 88: 89: 90:
91: private $cache_folder = "./cache/";
92:
93: 94: 95: 96:
97: private $cache = false;
98:
99: 100: 101: 102:
103: private $cache_time = 600;
104:
105: 106: 107: 108:
109: private $width = 270;
110: private $height = 248;
111:
112: 113: 114: 115:
116: private $weather_info = array();
117:
118: 119: 120: 121: 122:
123: private $languages = array(
124: 'en' => array(
125: 'cannot_access' => "Can't Access Weather API",
126: 'invalid_city_info' => "Please select valid city information",
127: 'show_next_days' => "Show weather next three days",
128: 'back_to_weather' => "Back to current weather details",
129: 'weather' => 'Weather',
130: 'weather_desc' => "Weather description",
131: 'wind' => 'Wind',
132: 'wind_degree' => 'Wind degree',
133: 'humidity' => 'Humidity',
134: 'pressure' => 'Pressure',
135: 'hi' => 'HI',
136: 'lo' => 'LO'
137: ),
138: 'it' => array(
139: 'cannot_access' => "Impossibile accedere Meteo",
140: 'invalid_city_info' => "Si prega di selezionare le informazioni citt� valida",
141: 'show_next_days' => "Mostra previsioni prossimi tre giorni",
142: 'back_to_weather' => "Torna a correnti dettagli meteo",
143: 'weather' => 'Meteo',
144: 'weather_desc' => "descrizione Meteo",
145: 'wind' => 'vento',
146: 'wind_degree' => 'grado Vento',
147: 'humidity' => 'umidit�',
148: 'pressure' => 'pressione',
149: 'hi' => 'alto',
150: 'lo' => 'basso'
151: ),
152: 'fr' => array(
153: 'cannot_access' => "Impossible d'acc�der � l'API M�t�o",
154: 'invalid_city_info' => "S'il vous pla�t s�lectionner l'information de la ville valide",
155: 'show_next_days' => "Montrez temps trois prochains jours",
156: 'back_to_weather' => "Retour aux d�tails m�t�orologiques actuelles",
157: 'weather' => 'm�t�o',
158: 'weather_desc' => "Description m�t�o",
159: 'wind' => 'vent',
160: 'wind_degree' => 'Degr� de Vent',
161: 'humidity' => 'humidit�',
162: 'pressure' => 'pression',
163: 'hi' => 'haut',
164: 'lo' => 'faible'
165: )
166: );
167:
168: private $api_lang = array('en', 'it', 'ru', 'fr', 'ua', 'de', 'pt', 'ro', 'pl', 'fi', 'nl', 'sp', 'bg', 'se', 'zh_tw', 'zh_cn', 'tr');
169:
170: 171: 172: 173:
174: private $lang = 'en';
175: private $lang_api = 'en';
176:
177: 178: 179: 180: 181: 182: 183: 184: 185: 186:
187: public function __construct($config = null) {
188: if (is_array($config)) {
189: foreach ($config as $key => $value) {
190:
191: if ($key == "theme" && isset($this->themes[$value])) {
192: $this->theme = $this->themes[$value];
193: }
194:
195:
196: if ($key == 'city') {
197: $this->city = $value;
198: $this->file_name = $this->city;
199: }
200: if ($key == 'city_id') {
201: $this->city_id = $value;
202: $this->file_name = $this->city_id;
203: }
204: if ($key == 'city_lat') {
205: $this->city_lat = $value;
206: $this->file_name = $this->city_lat;
207: }
208: if ($key == 'city_lon') {
209: $this->city_lon = $value;
210: $this->file_name .= '_'.$this->city_lon;
211: }
212:
213:
214: if ($key == 'temp_metrics' && ($value == "c" || $value == 'f')) {
215: $this->temp_metric = $value;
216: }
217:
218: if ($key == "lang" && (isset($this->languages[$value]) || in_array($value, $this->api_lang))) {
219: if (isset($this->languages[$value])) {
220: $this->lang = $value;
221: }
222:
223: if (in_array($value, $this->api_lang)) {
224: $this->lang_api = $value;
225: }
226: }
227:
228: if ($key == "output" && ($value == "row")) {
229: $this->output = "row";
230: }
231: }
232: } else {
233: $this->city = $config;
234: }
235: }
236:
237:
238:
239: 240: 241: 242: 243: 244: 245:
246: public function set_city($name = null, $id = null, $lat = null, $lon = null) {
247: if ($name) {
248: $this->city = $name;
249: $this->city_id = null;
250: $this->city_lat = null;
251: $this->city_lon = null;
252: $this->file_name = $this->city;
253: }
254:
255: if ($id) {
256: $this->city_id = $id;
257: $this->city = null;
258: $this->city_lat = null;
259: $this->city_lon = null;
260: $this->file_name = $this->city_id;
261: }
262:
263: if ($lat && $lon) {
264: $this->city_lat = $lat;
265: $this->city_lon = $lon;
266: $this->city_id = null;
267: $this->city = null;
268: $this->file_name = $this->city_lat."_".$this->city_lon;
269: }
270:
271:
272: }
273:
274: 275: 276: 277: 278:
279: public function set_theme($theme) {
280: if (isset($this->themes[$theme])) {
281: $this->theme = $this->themes[$theme];
282: }
283: }
284:
285: 286: 287: 288:
289: public function set_temp_metrics($metrics = 'c') {
290: if ($metrics == 'c' || $metrics == 'f')
291: $this->temp_metric = $metrics;
292: }
293:
294: 295: 296: 297:
298: public function set_lang($lang) {
299: if (isset($this->languages[$lang])) {
300: $this->lang = $lang;
301: }
302:
303: if (in_array($lang, $this->api_lang)) {
304: $this->lang_api = $lang;
305: }
306: }
307:
308: 309: 310: 311: 312:
313: public function set_dimention($width, $height) {
314: if ($width > 270)
315: $this->width = $width;
316: if ($height > 248)
317: $this->height = $height;
318: }
319:
320: 321: 322: 323:
324: public function set_output($out = "") {
325: if ($out == "row") {
326: $this->output = "row";
327: }
328: }
329:
330: 331: 332: 333: 334: 335: 336: 337:
338: public function set_cache($cache_time, $cache_folder = false) {
339: if ($cache_time > 0) {
340: $this->cache = TRUE;
341: $this->cache_time = $cache_time;
342: if ($cache_folder)
343: $this->cache_folder = $cache_folder;
344: }
345: }
346:
347: 348: 349:
350: public function disable_cache() {
351: $this->cache = FALSE;
352: }
353:
354: 355: 356: 357: 358: 359: 360:
361: public function get_weather() {
362: if (!$this->city && !$this->city_id && (!$this->city_lat && !$this->city_lon))
363: return $this->languages[$this->lang]['invalid_city_info'];
364:
365: $search_q = "";
366: if ($this->city) {
367: $search_q = "q=" . $this->city;
368: } elseif ($this->city_id) {
369: $search_q = "id=" . $this->city_id;
370: } else {
371: $search_q = "lat=" . $this->city_lat . "&lon=" . $this->city_lon;
372: }
373:
374: $read_cache = $this->read_wether();
375:
376: if ($read_cache) {
377: $weather = true;
378: } else {
379: $weather = @file_get_contents($this->weather_api . $search_q . '&lang=' . $this->lang_api);
380: }
381:
382: if ($weather) {
383: if (!$read_cache) {
384: $weather_forecast = @file_get_contents($this->forecast_api . $search_q . '&lang=' . $this->lang_api);
385: $weather = json_decode($weather);
386: $weather_forecast = json_decode($weather_forecast);
387:
388:
389: if (isset($weather->message))
390: return ($weather->message);
391:
392: $this->extract_weather($weather, $weather_forecast);
393: }
394:
395: if ($this->output == "row") {
396: return $this->weather_info;
397: }
398:
399: return $this->markup();
400: } else {
401: return $this->languages[$this->lang]['cannot_access'];
402: }
403: }
404:
405:
406: 407: 408: 409: 410:
411: private function ($weather, $weather_forecast) {
412:
413: $this->weather_info['place'] = $weather->name . (($weather->name) ? ',' : '' ) . $weather->sys->country;
414: $this->weather_info['icon'] = $weather->weather[0]->icon;
415: $this->weather_info['weather_main'] = $weather->weather[0]->main;
416: $this->weather_info['weather_description'] = $weather->weather[0]->description;
417: $this->weather_info['temp_c'] = round($weather->main->temp, 1);
418: $this->weather_info['temp_c_accurate'] = ($weather->main->temp);
419: $this->weather_info['temp_f'] = round((9 / 5) * $weather->main->temp, 1) + 32;
420: $this->weather_info['temp_f_accurate'] = ((9 / 5) * $weather->main->temp) + 32;
421: $this->weather_info['temp'] = (($this->temp_metric == 'c') ? $this->weather_info['temp_c'] : $this->weather_info['temp_f']);
422: $this->weather_info['symbol'] = (($this->temp_metric == 'c') ? 'C' : 'F');
423: $this->weather_info['humidity'] = $weather->main->humidity;
424: $this->weather_info['wind_speed'] = $weather->wind->speed;
425: $this->weather_info['rain'] = (isset($weather->rain)) ? (array)$weather->rain : false;
426:
427: $this->weather_info['wind_degree'] = $weather->wind->deg;
428: $this->weather_info['pressure'] = $weather->main->pressure;
429: $this->weather_info['lat'] = $weather->coord->lat;
430: $this->weather_info['lon'] = $weather->coord->lon;
431:
432:
433: $forecaster = array();
434: for ($i = 1; $i <= 3; $i++) {
435: $forecaster[$i]['day'] = date('D', $weather_forecast->list[$i]->dt);
436: $forecaster[$i]['month'] = date('M d', $weather_forecast->list[$i]->dt);
437: $forecaster[$i]['min_temp_c'] = round($weather_forecast->list[$i]->temp->min, 1);
438: $forecaster[$i]['min_temp_f'] = round((9 / 5) * $weather_forecast->list[$i]->temp->min, 1) + 32;
439: $forecaster[$i]['max_temp_c'] = round($weather_forecast->list[$i]->temp->max, 1);
440: $forecaster[$i]['max_temp_f'] = round((9 / 5) * $weather_forecast->list[$i]->temp->max, 1) + 32;
441: $forecaster[$i]['temp_max'] = (($this->temp_metric == 'c') ? $forecaster[$i]['max_temp_c'] : $forecaster[$i]['max_temp_f']);
442: $forecaster[$i]['temp_min'] = (($this->temp_metric == 'c') ? $forecaster[$i]['min_temp_c'] : $forecaster[$i]['min_temp_f']);
443: $forecaster[$i]['symbol'] = (($this->temp_metric == 'c') ? 'C' : 'F');
444: $forecaster[$i]['weather_main'] = $weather_forecast->list[$i]->weather[0]->main;
445: $forecaster[$i]['icon'] = $weather_forecast->list[$i]->weather[0]->icon;
446: }
447:
448: $this->weather_info['forecast'] = $forecaster;
449:
450:
451: if ($this->cache) {
452: $this->save_weather($this->weather_info);
453: }
454: }
455:
456: 457: 458: 459:
460: private function save_weather($weather) {
461: $weather_json = json_encode($weather);
462: $file = $this->cache_folder . $this->file_name . '.txt';
463: $handle = @fopen($file, 'w');
464: if ($handle) {
465: fwrite($handle, $weather_json);
466: fclose($handle);
467: }
468: }
469:
470: 471: 472: 473:
474: private function read_wether() {
475: $file = $this->cache_folder . $this->file_name . '.txt';
476: if (file_exists($file)) {
477: if (((time() - $this->cache_time) > filemtime($file)) || !$this->cache)
478: return false;
479: $handle = @fopen($file, 'r');
480: if ($handle) {
481: $json_weather = fread($handle, filesize($file));
482: $this->weather_info = json_decode($json_weather, true);
483:
484: if ($this->temp_metric == "c") {
485: $this->weather_info['temp'] = $this->weather_info['temp_c'];
486: $this->weather_info['symbol'] = 'C';
487:
488: for ($i = 1; $i <= 3; $i++) {
489: $this->weather_info['forecast'][$i]['temp_min'] = $this->weather_info['forecast'][$i]['min_temp_c'];
490: $this->weather_info['forecast'][$i]['temp_max'] = $this->weather_info['forecast'][$i]['max_temp_c'];
491: $this->weather_info['forecast'][$i]['symbol'] = 'C';
492: }
493: } else {
494: $this->weather_info['temp'] = $this->weather_info['temp_f'];
495: $this->weather_info['symbol'] = 'F';
496: for ($i = 1; $i <= 3; $i++) {
497: $this->weather_info['forecast'][$i]['temp_min'] = $this->weather_info['forecast'][$i]['min_temp_f'];
498: $this->weather_info['forecast'][$i]['temp_max'] = $this->weather_info['forecast'][$i]['max_temp_f'];
499: $this->weather_info['forecast'][$i]['symbol'] = 'F';
500: }
501: }
502:
503: fclose($handle);
504: return true;
505: }
506: }
507:
508: return false;
509: }
510:
511: 512: 513: 514:
515: private function markup() {
516: $next_weather = $this->languages[$this->lang]['show_next_days'];
517: $back_weather = $this->languages[$this->lang]['back_to_weather'];
518: $markup = '<div class="widget" style="width:' . $this->width . 'px;height:' . $this->height . 'px">
519: <div class="upper">
520: <div class="degree-box">
521: <div class="temp">
522: <h2 class="title"><span class="update">' . $this->weather_info['temp'] . '<sup>o</sup>' . $this->weather_info['symbol'] . '</span></h2></div>
523: <div class="place update ' . $this->theme . '-place">' . $this->weather_info['place'] . '</div></div>
524: <div id="change-weather" onclick="change_weather($(this))" show-ul="weather-forecast" class="change-weather next-icon" title="' . $next_weather . '"></div>
525: </div>
526: <div class="clear"></div>
527: <div class="lower ' . $this->theme . '-lower">
528:
529: <ul id="weather-info" class="infos-w">
530: <li class="info-w weather"><h2 class="title"><span class="weather-bg" title="' . $this->languages[$this->lang]['weather'] . '"></span></h2>
531: <span class="update">' . $this->weather_info['weather_main'] . '</span>
532: <h2 class="title"><span><img title="' . $this->languages[$this->lang]['weather_desc'] . '" src="http://openweathermap.org/img/w/' . $this->weather_info['icon'] . '.png" /></span></h2>
533: <span class="update">' . $this->weather_info['weather_description'] . '</span></li>
534: <li class="info-w wind"><h2 class="title"><span class="wind-bg" title="' . $this->languages[$this->lang]['wind'] . '"></span></h2>
535: <span class="update">' . $this->weather_info['wind_speed'] . 'm/s</span>
536: <h2><span class="wind-degree" title="' . $this->languages[$this->lang]['wind_degree'] . '"></span></h2><p class="update">' . $this->weather_info['wind_degree'] . '<sup>o</sup></p></li>
537: <li class="info-w"><h2 class="title"><span class="humidity" title="' . $this->languages[$this->lang]['humidity'] . '"></span></h2>
538: <p class="update">' . $this->weather_info['humidity'] . '%</p>
539: <h2><span class="pressure" title="' . $this->languages[$this->lang]['pressure'] . '"></span> </h2><p class="update">' . $this->weather_info['pressure'] . ' hPa</p></li></ul>';
540:
541:
542: $inner_li = "";
543: foreach ($this->weather_info['forecast'] as $weather) {
544: $inner_li .= '<li class="info-w"><h2 class="title">' . $weather['day'] . '</h2><h3>' . $weather['month'] . '</h3>
545: <span class="main update">
546: <img title="' . $weather['weather_main'] . '" src="http://openweathermap.org/img/w/' . $weather['icon'] . '" /></span>
547: <br/><span class="des update">' . $this->languages[$this->lang]['hi'] . ': ' . $weather['temp_max'] . '<sup>o</sup>' . $weather['symbol'] . '<br/>
548: ' . $this->languages[$this->lang]['lo'] . ': ' . $weather['temp_min'] . '<sup>o</sup>' . $weather['symbol'] . '</span></li>';
549: }
550:
551: $markup .= '<ul style="display:none" id="weather-forecast" class="infos-w">' . $inner_li . '</ul></div></div>';
552:
553:
554: $markup .= '<script type="text/javascript">
555: function change_weather (sender){
556: var elm = sender.attr("show-ul");
557: var next_elm = "";
558:
559: if(elm == "weather-forecast"){
560: next_elm = "weather-info";
561: sender.removeClass("next-icon");
562: sender.addClass("back-icon");
563: sender.prop("title","' . $back_weather . '");
564: }
565: else {
566: next_elm = "weather-forecast";
567: sender.removeClass("back-icon");
568: sender.addClass("next-icon");
569: sender.prop("title","' . $next_weather . '");
570: }
571:
572: //Set element next item
573: sender.attr("show-ul",next_elm);
574: sender.parent().parent().find("#"+next_elm).slideUp("slow");
575: sender.parent().parent().find("#"+elm).slideDown("slow");
576: }
577: </script>';
578: return $markup;
579: }
580:
581: }