PluginProbe
Event Post / 6.1.1
Event Post v6.1.1
6.1.1 6.1.0 6.0.1 6.0.0 5.12.0 trunk 3.9 4.0 4.2 4.3 4.4 4.5 5.0 5.1 5.10.0 5.10.1 5.10.2 5.10.3 5.10.4 5.11.0 5.11.1 5.2 5.5 5.6 5.6.1 All 46 releases
event-post / inc / openweathermap.php

openweathermap.php in Event Post 6.1.1, at inc/openweathermap.php

530 lines 17.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Weather support
4 *
5 * @package event-post
6 * @version 6.1.1
7 * @since 4.3.0
8 */
9
10 namespace EventPost;
11
12 if ( ! defined( 'ABSPATH' ) ) exit;
13
14 $EventPostWeather = new Weather();
15
16 /**
17 * Provides weather support thanks to OpenWeatherMap
18 * http://openweathermap.org
19 *
20 * License: Creative Commons (cc-by-sa)
21 * http://creativecommons.org/licenses/by-sa/2.0/.
22 *
23 *
24 * Get an API key
25 * http://openweathermap.org/appid#get
26 */
27 class Weather {
28
29 var $META_WEATHER;
30
31 var $api_key;
32 var $units;
33 var $unit_names;
34 var $theme;
35
36 function __construct() {
37 // Hook into the plugin
38
39 add_action('eventpost_getsettings_action', array(&$this, 'get_settings'), 1, 2);
40 add_action('eventpost_settings_form', array(&$this, 'settings_form'));
41 add_action('evenpost_init', array(&$this, 'init'));
42 }
43
44 /**
45 * PHP4 constructor
46 */
47 function Weather() {
48 $this->__construct();
49 }
50
51 /**
52 * Only for localization
53 *
54 * Available values:
55 *
56 * - clear sky
57 * - few clouds
58 * - scattered clouds
59 * - broken clouds
60 * - shower rain
61 * - rain
62 * - thunderstorm
63 * - snow
64 * - mist
65 */
66 function localize(){
67 __('clear sky', 'event-post');
68 __('few clouds', 'event-post');
69 __('scattered clouds', 'event-post');
70 __('broken clouds', 'event-post');
71 __('shower rain', 'event-post');
72 __('rain', 'event-post');
73 __('thunderstorm', 'event-post');
74 __('snow', 'event-post');
75 __('mist', 'event-post');
76
77 }
78
79 /**
80 * Get settings
81 *
82 * @param array reference &$ep_settings
83 * @param boolean reference &$reg_settings
84 */
85 function get_settings(&$ep_settings, &$reg_settings) {
86 if (!isset($ep_settings['weather_enabled'])) {
87 $ep_settings['weather_enabled'] = false;
88 $reg_settings = true;
89 }
90 if (!isset($ep_settings['weather_api_key'])) {
91 $ep_settings['weather_api_key'] = '';
92 $reg_settings = true;
93 }
94 if (!isset($ep_settings['weather_units'])) {
95 $ep_settings['weather_units'] = 'standard';
96 $reg_settings = true;
97 }
98 }
99
100 /**
101 * Settings form
102 *
103 * @param type $ep_settings
104 */
105 function settings_form($ep_settings) {
106 ?>
107 <h2><?php esc_html_e('Weather', 'event-post'); ?></h2>
108 <?php // Translators: %s is a link to openweathermap.org ?>
109 <p class="description"><?php printf(esc_html(__('Provided thanks to %s', 'event-post')), '<a href="http://openweathermap.org" target="_blank">openweathermap.org</a>'); ?></p>
110 <table class="form-table" id="eventpost-settings-table-weather">
111 <tbody>
112 <tr>
113 <th>
114 <?php esc_html_e('Enable weather', 'event-post') ?>
115 </th>
116 <td>
117 <label for="weather_enabled">
118 <input type="checkbox" name="ep_settings[weather_enabled]" id="weather_enabled" <?php if ($ep_settings['weather_enabled'] == '1') {
119 echo esc_attr('checked');
120 } ?> value="1">
121 <?php esc_html_e('Enable weather feature', 'event-post') ?>
122 </label>
123 </td>
124 </tr>
125 <tr>
126 <th>
127 <label for="weather_api_key">
128 <?php esc_html_e('API key', 'event-post') ?>
129 </label>
130 </th>
131 <td>
132 <input type="text" name="ep_settings[weather_api_key]" id="weather_api_key" value="<?php echo esc_attr($ep_settings['weather_api_key']); ?>" size="40">
133 <?php // Translators: %s is a link to openweathermap.org/appid#get ?>
134 <p class="description"><?php printf(esc_html(__('Get a free API key at: %s', 'event-post')), '<a href="http://openweathermap.org/appid#get" target="_blank">openweathermap.org/appid#get</a>'); ?></p>
135 </td>
136 </tr>
137 <tr>
138 <th>
139 <label for="weather_units">
140 <?php esc_html_e('Units', 'event-post') ?>
141 </label>
142 </th>
143 <td>
144 <select name="ep_settings[weather_units]" id="weather_units">
145 <option value="standard" <?php selected($ep_settings['weather_units'], 'standard', true);?>>
146 <?php esc_html_e('Standard (Fahrenheit)', 'event-post') ?>
147 </option>
148 <option value="metric" <?php selected($ep_settings['weather_units'], 'metric', true);?>>
149 <?php esc_html_e('Metric (Celsius)', 'event-post') ?>
150 </option>
151 <option value="imperial" <?php selected($ep_settings['weather_units'], 'imperial', true);?>>
152 <?php esc_html_e('Imperial (Kelvin)', 'event-post') ?>
153 </option>
154 </select>
155 </td>
156 </tr>
157 </tbody>
158 </table><!-- #eventpost-settings-table-weather -->
159 <?php
160 }
161
162 /**
163 * Initialization of weather support
164 *
165 * @param object $EP
166 *
167 * @return void
168 */
169 function init($EP) {
170 // Ensure OpenWeatherMap is required and available.
171 if (!$EP->settings['weather_enabled'] || !$EP->settings['weather_api_key']) {
172 return;
173 }
174
175 $this->META_WEATHER = 'event_weather';
176 $this->api_key = $EP->settings['weather_api_key'];
177 $this->units = $EP->settings['weather_units'];
178 $this->theme = 'default';
179 $this->unit_names = array('standard'=>'F', 'metric'=>'C', 'imperial'=>'K');
180
181 // Alter objects
182 add_filter('eventpost_params', array(&$this, 'params'));
183 add_filter('eventpost_retreive', array(&$this, 'retreive'));
184
185 // Alter schema
186 add_filter('eventpost_item_scheme_entities', array(&$this, 'scheme_entities'));
187 add_filter('eventpost_item_scheme_values', array(&$this, 'scheme_values'), 1, 2);
188 add_filter('eventpost_default_list_shema', array(&$this, 'default_shema'));
189 add_filter('eventpost_get_single', array(&$this, 'get_single'), 1, 2);
190
191
192 add_action('eventpost_custom_box_date', array(&$this, 'get_weather'));
193
194
195 }
196
197 /**
198 * Alters parameters
199 *
200 * @param array $params
201 *
202 * @return array
203 */
204 function params($params = array()) {
205 $params['weather'] = true;
206 return $params;
207 }
208
209 /**
210 * Alters an event object
211 *
212 * @param WP_Post $event
213 *
214 * @return WP_Post
215 */
216 function retreive($event) {
217 $event->weather = get_post_meta($event->ID, $this->META_WEATHER, true);
218 return $event;
219 }
220
221 /**
222 * Alters schema entities
223 *
224 * @param array $attr
225 *
226 * @return array
227 */
228 function scheme_entities($attr = array()) {
229 array_push($attr, '%event_weather%');
230 return $attr;
231 }
232
233 /**
234 * Alters schema values
235 *
236 * @param array $values
237 *
238 * @return array
239 */
240 function scheme_values($values = array(), $post = null) {
241 array_push($values, $this->get_weather($post));
242 return $values;
243 }
244
245 /**
246 * Alters default schema
247 *
248 * @param array $schema
249 *
250 * @return array
251 */
252 function default_shema($schema) {
253 $schema['item'] = str_replace('</%child%>', "%event_weather%\n</%child%>", $schema['item']);
254 return $schema;
255 }
256
257 function get_single($event_datas, $post = null) {
258 return $event_datas . $this->get_weather($post);
259 }
260
261 //From here, methods intends to get datas
262
263 function get_weather_icons($weather){
264 $string = '';
265 foreach((array) $weather as $item){
266 $text = ucfirst(__(strtolower($item->description), 'event-post')); // phpcs:ignore WordPress.WP.I18n
267 $string.='<span class="eventpost-weather-'.str_replace('-', '', strtolower($item->description)).' eventpost-weather-'.$item->icon.'">'
268 // Translators: %s is the weather description
269 . '<img src="'. plugins_url('../img/weather/'.$this->theme.'/'.$item->icon.'.png', __FILE__).'" alt="'.sprintf('%s icon', $text).'">'
270 . '<em class="eventpost-weather-text">'.$text.'</em>'
271 . '</span>';
272 }
273 return $string;
274 }
275 /**
276 * Get weather item
277 *
278 * @param object $item
279 *
280 * @return string
281 */
282 function get_weather_item($item){
283 $string = '';
284 $string.= '<div class="eventpost-weather-item">'
285 .'<span class="eventpost-weather-date">'.date_i18n(get_option('date_format').' '.get_option('time_format'), $item->dt).'</span> '
286 .'<span class="eventpost-weather-temp">'.round($item->main->temp).' &deg'.$this->unit_names[$this->units].'</span> '
287 .'<span class="eventpost-weather-list">'.$this->get_weather_icons($item->weather).'</span>'
288 .'</div>';
289 return $string;
290 }
291
292 /**
293 * Get weather
294 *
295 * @param type $post
296 *
297 * @return string
298 */
299 function get_weather($post = null, $echo=false) {
300 global $EventPost;
301 $event = $EventPost->retreive($post);
302 if(false === $weather = $this->get_weather_datas($event)){
303 return '';
304 }
305 if(false == $weather['data']){
306 return '';
307 }
308
309 $string='';
310
311 switch ($weather['type']){
312 case 'current':
313 $string.=$this->get_weather_item($weather['data']);
314 break;
315 case 'history':
316 if(!isset($weather['data']->list) || !is_array($weather['data']->list)){
317 break;
318 }
319 foreach($weather['data']->list as $day){
320 if($day->dt >= $event->time_start && $day->dt <= $event->time_end){
321 $string.=$this->get_weather_item($day);
322 }
323 }
324 break;
325 case 'forecast':
326 if(!is_array($weather['data']->list)){
327 break;
328 }
329 foreach($weather['data']->list as $day){
330 if($day->dt >= $event->time_start && $day->dt <= $event->time_end){
331 $string.=$this->get_weather_item($day);
332 }
333 }
334 break;
335 }
336 if($echo){
337 echo wp_kses($string, EventPost()->kses_tags);
338 }
339 return $string;
340 }
341
342 /**
343 * Get weather datas
344 *
345 * @param type $event
346 *
347 * @return type
348 */
349 function get_weather_datas($event){
350 if (!$event->lat || !$event->long || !is_numeric($event->time_start) || !is_numeric($event->time_end)) {
351 return false;
352 }
353
354 $now = current_time('timestamp');
355 $local_weather = $event->weather;
356
357
358
359 // Datas are allready stored, we probably won't get better ones.
360 if(is_array($local_weather) && $local_weather['data'] && ($local_weather['type']=='current' || $local_weather['type']=='history')){
361 return $local_weather;
362 }
363
364 // Finally, we have to fetch datas...
365 $weather = array('type'=>false, 'data'=>false);
366
367 // For Current and history results, we definitly store datas
368 if ( $event->time_start<= $now && $event->time_end>=$now) {
369 $weather = array('type'=>'current', 'data'=>$this->get_current($event), 'fetched'=>time());
370 update_post_meta($event->ID, $this->META_WEATHER, $weather);
371 }
372 elseif ( $event->time_end<$now) {// History
373 $weather = array('type'=>'history', 'data'=>$this->get_history($event), 'fetched'=>time());
374 update_post_meta($event->ID, $this->META_WEATHER, $weather);
375 }
376 else {
377 // Forecast datas are only stored in cache for 24 hours
378 $transient_name = 'eventpost_weather_' . $event->ID;
379 $weather = get_transient($transient_name);
380 if (false === $weather || empty($weather)) {
381 $weather = array('type'=>'forecast', 'data'=>$this->get_forecast($event), 'fetched'=>time());
382 set_transient($transient_name, $weather, 1 * DAY_IN_SECONDS);
383 }
384 }
385 return $weather;
386 }
387
388
389 /**
390 * Generates the URL to call the API
391 *
392 * @param type $method
393 * @param type $params
394 *
395 * @return type
396 */
397 function get_url($method = 'weather', $params = array()) {
398 $params['APPID']= $this->api_key;
399 $params['units']= $this->units;
400 return 'http://api.openweathermap.org/data/2.5/' . $method . '?' . http_build_query($params);
401 }
402
403 /**
404 * Current weather
405 * http://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&APPID=XXXX
406 *
407 * Return:
408 *
409 * {"coord":{"lon":139,"lat":35},
410 * "sys":{"country":"JP","sunrise":1369769524,"sunset":1369821049},
411 * "weather":[{"id":804,"main":"clouds","description":"overcast clouds","icon":"04n"}],
412 * "main":{"temp":289.5,"humidity":89,"pressure":1013,"temp_min":287.04,"temp_max":292.04},
413 * "wind":{"speed":7.31,"deg":187.002},
414 * "rain":{"3h":0},
415 * "clouds":{"all":92},
416 * "dt":1369824698,
417 * "id":1851632,
418 * "name":"Shuzenji",
419 * "cod":200}
420 *
421 * @param type $event
422 *
423 * @return object
424 */
425 function get_current($event){
426 if (!$event->lat || !$event->long) {
427 return;
428 }
429 return json_decode(wp_remote_retrieve_body(
430 wp_remote_get(
431 $this-> get_url('weather', array(
432 'lat' => $event->lat,
433 'lon' => $event->long,
434 ))
435 )
436 ));
437 }
438
439 /**
440 * Forecast
441 * api.openweathermap.org/data/2.5/forecast?lat={lat}&lon={lon}&APPID=XXXX
442 *
443 * Return:
444 *
445 * {"city":{"id":1851632,"name":"Shuzenji",
446 * "coord":{"lon":138.933334,"lat":34.966671},
447 * "country":"JP",
448 * "cod":"200",
449 * "message":0.0045,
450 * "cnt":38,
451 * "list":[{
452 * "dt":1406106000,
453 * "main":{
454 * "temp":298.77,
455 * "temp_min":298.77,
456 * "temp_max":298.774,
457 * "pressure":1005.93,
458 * "sea_level":1018.18,
459 * "grnd_level":1005.93,
460 * "humidity":87
461 * "temp_kf":0.26},
462 * "weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04d"}],
463 * "clouds":{"all":88},
464 * "wind":{"speed":5.71,"deg":229.501},
465 * "sys":{"pod":"d"},
466 * "dt_txt":"2014-07-23 09:00:00"}
467 * ]}
468 *
469 * @param type $event
470 *
471 * @return type
472 */
473 function get_forecast($event){
474 if (!$event->lat || !$event->long) {
475 return;
476 }
477 return json_decode(wp_remote_retrieve_body(
478 wp_remote_get(
479 $this-> get_url('forecast', array(
480 'lat' => $event->lat,
481 'lon' => $event->long,
482 ))
483 )
484 ));
485 }
486
487 /**
488 * ### history
489 * http://api.openweathermap.org/data/2.5/history/city?lat={lat}&lon={lon}&type=hour&start={start}&end={end}&APPID=XXXX
490 *
491 * Parameters:
492 * lat, lon coordinates of the location of your interest
493 * type type of the call, keep this parameter in the API call as 'hour'
494 * start start date (unix time, UTC time zone), e.g. start=1369728000
495 * end end date (unix time, UTC time zone), e.g. end=1369789200
496 * cnt amount of returned data (one per hour, can be used instead of 'end') *
497 * return:
498 * {"message":"","cod":"200","type":"tick","station_id":39419,"cnt":30,
499 * "list":[
500 * {"dt":1345291920,
501 * "main":{"temp":291.55,"humidity":95,"pressure":1009.3},
502 * "wind":{"speed":0,"gust":0.3},
503 * "rain":{"1h":0.6,"today":2.7},
504 * "calc":{"dewpoint":17.6} }
505 * ]}
506 *
507 * @param type $event
508 *
509 * @return type
510 */
511 function get_history($event) {
512 if (!$event->start || !$event->end || !$event->lat || !$event->long) {
513 return;
514 }
515 $history = json_decode(wp_remote_retrieve_body(
516 wp_remote_get(
517 $this-> get_url('history/city', array(
518 'lat' => $event->lat,
519 'lon' => $event->long,
520 'start' => $event->time_start,
521 'end' => $event->time_end,
522 'type' => 'hour',
523 ))
524 )
525 ));
526 return $history ? $history : (object) array('result'=>false);
527 }
528
529 }
530