PluginProbe
wp-forecast / 9.6
wp-forecast v9.6
10.0 trunk 1.4 1.6 1.7 1.8 1.9 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3..5 3..8 3.0 3.1 3.2 3.3 3.4 3.6 All 86 releases
← All changes | wp-forecast.php +447 -383 3..89.6 View file →
@@ -1,472 +1,536 @@
1 1 <?php
2 +/**
3 + * Plugin Name: wp-forecast
4 + * Plugin URI: http://www.tuxlog.de
5 + * Description: wp-forecast is a highly customizable plugin for WordPress, showing weather-data from Open-Meteo or OpenWeathermMap.
6 + * Version: 9.6
7 + * Author: Hans Matzen
8 + * Author URI: http://www.tuxlog.de
9 + * License: GPLv2
10 + * License URI: https://www.gnu.org/licenses/gpl-2.0.html
11 + * Domain Path: lang
12 + * Text Domain: wp-forecast
13 + *
14 + * @package wp-forecast
15 + */
16 +
17 +/**
18 + * Copyright 2006-2025 Hans Matzen
19 + *
20 + * This program is free software; you can redistribute it and/or modify
21 + * it under the terms of the GNU General Public License as published by
22 + * the Free Software Foundation; either version 2 of the License, or
23 + * (at your option) any later version.
24 + *
25 + * This program is distributed in the hope that it will be useful,
26 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 + * GNU General Public License for more details.
29 + *
30 + * You should have received a copy of the GNU General Public License
31 + * along with this program; if not, write to the Free Software
32 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 + */
34 +
35 +//
36 +// maximal number of widgets to use.
37 +//
38 +$wpf_maxwidgets = 8;
39 +
2 40 /*
3 -Plugin Name: wp-forecast
4 -Plugin URI: http://www.tuxlog.de
5 -Description: wp-forecast is a highly customizable plugin for wordpress, showing weather-data from accuweather.com.
6 -Version: 3.8
7 -Author: Hans Matzen
8 -Author URI: http://www.tuxlog.de
9 -*/
41 + ---------- no parameters to change after this point --------------------
42 + */
43 +// define path to wp-forecast plugin.
44 +define( 'WPF_PATH', plugin_dir_path( __FILE__ ) );
10 45
11 -/*
12 - Copyright 2006-2012 Hans Matzen
46 +// OpenWeathermap functions.
47 +require_once 'func-openweathermap.php';
48 +require_once 'func-openweathermap-v2.php';
49 +// Open-Meteo functions.
50 +require_once 'func-openmeteo.php';
13 51
14 - This program is free software; you can redistribute it and/or modify
15 - it under the terms of the GNU General Public License as published by
16 - the Free Software Foundation; either version 2 of the License, or
17 - (at your option) any later version.
52 +// OpenUV data functions.
53 +require_once 'func-openuv.php';
54 +// ipstack functions.
55 +require_once 'func-ipstack.php';
18 56
19 - This program is distributed in the hope that it will be useful,
20 - but WITHOUT ANY WARRANTY; without even the implied warranty of
21 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 - GNU General Public License for more details.
57 +// generic functions.
58 +require_once 'funclib.php';
59 +// include setup functions.
60 +require_once 'wpf-setup.php';
61 +// include admin options page.
62 +require_once 'wp-forecast-admin.php';
63 +// display functions.
64 +require_once 'wp-forecast-show.php';
65 +// shortcodes.
66 +require_once 'shortcodes.php';
67 +// support for WordPress autoupdate.
68 +require_once 'wpf-autoupdate.php';
69 +// virtual page class.
70 +require_once 'class-wpf-virtualpage.php';
23 71
24 - You should have received a copy of the GNU General Public License
25 - along with this program; if not, write to the Free Software
26 - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 -*/
28 72
73 +global $blog_id;
29 74
30 -//
31 -// only use this in case of severe problems accessing the admin dialog
32 -//
33 -// preselected transport method for fetching the weather data
34 -// valid values are
35 -// curl - uses libcurl
36 -// fsockopen - uses fsockopen
37 -// streams - uses fopen with streams
38 -// exthttp - uses pecl http extension
39 -// this will override every setting from the admin dialog
40 -// you have to assure that the chosen transport is supported by the
41 -// wordpress class WP_Http;
42 -//
43 -static $wp_forecast_pre_transport="";
75 +/**
76 + * Set cache with weather data for current parameters
77 + * a wrapper function called via the init hook.
78 + */
79 +function wp_forecast_init() {
80 + $count = (int) wpf_get_option( 'wp-forecast-count' );
44 81
45 -//
46 -// maximal number of widgets to use
47 -//
48 -$wpf_maxwidgets=20;
82 + $weather = array();
49 83
50 -//
51 -// set to 0 for no debugging information
52 -// set to 1 for call stack
53 -// set to 2 for call stack including xml parser
54 -//
55 -static $wpf_debug=0;
84 + for ( $i = 0;$i < $count;$i++ ) {
85 + $wpfcid = get_widget_id( $i );
56 86
87 + $wpf_vars = get_wpf_opts( $wpfcid );
57 88
58 -/* ---------- no parameters to change after this point -------------------- */
89 + // use visitors location for weather and UV.
90 + if ( isset( $wpf_vars['visitorlocation'] ) && $wpf_vars['visitorlocation'] ) {
91 + // get users ip address.
92 + $vip = ipstack_get_visitor_ip();
59 93
60 -// accuweather data functions
61 -require_once("func_accu.php");
62 -// weatherbug data functions
63 -require_once("func_bug.php");
64 -// google data functions
65 -require_once("func_google.php");
94 + // get location information about ip address.
95 + $vloc = ipstack_get_data( wpf_get_option( 'wp-forecast-ipstackapikey' ), $vip );
66 96
67 -// generic functions
68 -require_once("funclib.php");
69 -// include setup functions
70 -require_once("wpf_setup.php");
71 -// include admin options page
72 -require_once("wp-forecast-admin.php");
73 -// display functions
74 -require_once("wp-forecast-show.php");
75 -// shortcodes
76 -require_once("shortcodes.php");
77 -// support for wordpress autoupdate
78 -require_once("wpf_autoupdate.php");
79 -// super admin dialog
80 -require_once("wpf_sa_admin.php");
97 + // find matching locations from open-meteo.
98 + // search locations for openmeteo.
99 + $openmeteo_loc = get_loclist( $wpf_vars['OPENMETEO_LOC_URI'], ( ! isset( $vloc['city'] ) ? '' : $vloc['city'] ) );
81 100
101 + // guess the locations which might be correct matching the country.
102 + $locations = array();
82 103
83 -global $blog_id;
104 + // prefilter list of found locations to reduce runtime.
105 + foreach ( $openmeteo_loc as $al ) {
106 + if ( strpos( $al['country'], $vloc['country_name'] ) !== false ) {
107 + $locations[] = $al;
108 + }
109 + }
84 110
85 -//
86 -// set cache with weather data for current parameters
87 -// a wrapper function called via the init hook
88 -//
111 + if ( count( $locations ) == 1 ) {
112 + // if there is only one location in the array take this one.
113 + $wpf_vars['location'] = $locations[0]['name'];
114 + $wpf_vars['locname'] = $locations[0]['name'];
115 + $wpf_vars['loclatitude'] = $locations[0]['latitude'];
116 + $wpf_vars['loclongitude'] = $locations[0]['longitude'];
117 + } else {
118 + // get the weather data of all the weather locations in the array and find the best match on lat and lon.
119 + $ldist = 99000.0;
120 + $lat1 = ( ! isset( $vloc['latitude'] ) ? '' : $vloc['latitude'] );
121 + $lon1 = ( ! isset( $vloc['longitude'] ) ? '' : $vloc['longitude'] );
122 + $tloc = '';
123 + $tname = '';
124 + foreach ( $locations as $ll ) {
125 + $lat2 = $ll['latitude'];
126 + $lon2 = $ll['longitude'];
127 + $cdist = distanceCalculation( $lat1, $lon1, $lat2, $lon2 );
89 128
90 -function wp_forecast_init()
91 -{
92 - pdebug(1,"Start of function wp_forecast_init ()");
129 + if ( $cdist < $ldist ) {
130 + $ldist = $cdist;
131 + $tloc = $ll['name'];
132 + $tname = $ll['name'];
133 + $tlat = $ll['latitude'];
134 + $tlon = $ll['longitude'];
135 + }
136 + }
93 137
94 - // first of all check if we have to set a hard given
95 - // transport method
96 - if (isset($wp_forecast_pre_transport) &&
97 - wpf_get_option("wp-forecast-pre-transport") != $wp_forecast_pre_transport )
98 - {
99 - pdebug(1,"Setting hard coded transport method to $wp_forecast_pre_transport");
100 - wpf_update_option("wp-forecast-pre-transport",$wp_forecast_pre_transport);
101 - }
138 + if ( '' != $tloc ) {
139 + $wpf_vars['locname'] = $tname;
140 + $wpf_vars['location'] = $tloc;
141 + $wpf_vars['loclatitude'] = $tlan;
142 + $wpf_vars['loclongitude'] = $tlon;
143 + } else {
144 + // nothing found set default values.
145 + $wpf_vars['location'] = 'Berlin Alexanderplatz';
146 + $wpf_vars['locname'] = 'Berlin Alexanderplatz';
147 + $wpf_vars['loclatitude'] = '52.521918';
148 + $wpf_vars['loclongitude'] = '13.413215';
149 + }
150 + }
102 151
103 - $count=(int) wpf_get_option('wp-forecast-count');
104 -
105 - $weather=array();
106 -
107 - for ($i=0;$i<$count;$i++)
108 - {
109 - $wpfcid=get_widget_id($i);
110 -
111 - $wpf_vars=get_wpf_opts($wpfcid);
152 + // make sure weather data is updated.
153 + $wpf_vars['expire'] = 0;
112 154
113 - if ($wpf_vars['expire'] < time())
114 - {
115 - switch ($wpf_vars['service'])
116 - {
117 - case "accu":
118 - $w = accu_get_weather($wpf_vars['ACCU_BASE_URI'],
119 - $wpf_vars['location'],
120 - $wpf_vars['metric']);
121 - // next line is beta for non utf8 charactes in weatherdata
122 - $weather=accu_xml_parser(utf8_encode($w));
123 - //$weather=accu_xml_parser($w);
124 - break;
125 -
126 - case "bug":
127 - $w1 = bug_get_weather($wpf_vars['BUG_BASE_URI'],$wpf_vars['apikey1'],
128 - $wpf_vars['location'],$wpf_vars['metric']);
129 - $weather1=bug_xml_parser($w1);
130 - $w2 = bug_get_weather($wpf_vars['BUG_FORC_URI'],$wpf_vars['apikey1'],
131 - $wpf_vars['location'],$wpf_vars['metric']);
132 - $weather2=bug_xml_parser($w2);
133 - $weather = array_merge($weather2,$weather1);
134 - break;
155 + // update wpf_vars in case we changed lat and lon.
156 + wpf_update_option( 'wp-forecast-opts' . $wpfcid, serialize( $wpf_vars ) );
157 + }
135 158
136 - case "com":
137 - // to be done
138 - break;
139 -
140 - case "google":
141 - $w = google_get_weather($wpf_vars['GOOGLE_BASE_URI'],
142 - $wpf_vars['location'],
143 - substr($wpf_vars['wpf_language'],0,2));
144 - $weather=google_xml_parser(utf8_encode($w));
145 - break;
146 - }
159 + // check if we have to fetch the weather data or if we can use the cache.
160 + if ( $wpf_vars['expire'] < time() ) {
161 + switch ( $wpf_vars['service'] ) {
162 + case 'openweathermap':
163 + $w = openweathermap_get_weather_v2( $wpf_vars['OPENWEATHERMAP_BASE_URI'], $wpf_vars['apikey1'], $wpf_vars['loclatitude'], $wpf_vars['loclongitude'], $wpf_vars['metric'] );
164 + $weather = openweathermap_get_data_v2( $w, $wpf_vars );
165 + break;
147 166
148 - pdebug(1,"Fetched xml was:\n".$w);
167 + case 'openweathermap3':
168 + $w = openweathermap_get_weather( $wpf_vars['OPENWEATHERMAP_BASE_URI_V3'], $wpf_vars['apikey1'], $wpf_vars['loclatitude'], $wpf_vars['loclongitude'], $wpf_vars['metric'] );
169 + $weather = openweathermap_get_data( $w, $wpf_vars );
170 + break;
171 + case 'openmeteo':
172 + $w = openmeteo_get_weather( $wpf_vars['OPENMETEO_BASE_URI'], $wpf_vars['loclatitude'], $wpf_vars['loclongitude'], $wpf_vars['metric'] );
173 + $weather = openmeteo_get_data( $w, $wpf_vars );
174 + break;
175 + }
149 176
150 - // store weather to database and set expire time
151 - // if the current data wasnt available use old data
152 - if ( count($weather)>0)
153 - {
154 - wpf_update_option("wp-forecast-cache".$wpfcid, serialize($weather));
155 - if ( empty($weather['failure']) or $weather['failure'] == "" )
156 - wpf_update_option("wp-forecast-expire".$wpfcid, time()+$wpf_vars['refresh']);
157 - else
158 - wpf_update_option("wp-forecast-expire".$wpfcid, 0);
159 - }
177 + // get OpenUV data if wanted.
178 + if ( isset( $wpf_vars['ouv_apikey'] ) && trim( $wpf_vars['ouv_apikey'] ) != '' ) {
179 + $ouv = openuv_get_data( $wpf_vars['ouv_apikey'], $weather['lat'], $weather['lon'] );
180 + if ( is_wp_error( $ouv ) ) {
181 + $weather['openuv'] = '';
182 + $weather['failure'] = $ouv->get_error_message();
183 + } else {
184 + $weather['openuv'] = $ouv;
185 + }
186 + }
187 +
188 + // store weather to database and set expire time.
189 + // if the current data wasnt available use old data.
190 + if ( count( $weather ) > 0 ) {
191 + wpf_update_option( 'wp-forecast-cache' . $wpfcid, serialize( $weather ) );
192 + if ( empty( $weather['failure'] ) || '' == $weather['failure'] ) {
193 + wpf_update_option( 'wp-forecast-expire' . $wpfcid, time() + $wpf_vars['refresh'] );
194 + } else {
195 + wpf_update_option( 'wp-forecast-expire' . $wpfcid, 0 );
196 + }
197 + }
198 + }
160 199 }
161 - }
162 -
163 - // javascript hinzufügen fuer ajax widget
164 - wp_enqueue_script('wpf_update',
165 - '/' . PLUGINDIR . '/wp-forecast/wpf_update.js',
166 - array('jquery'), "9999");
167 200
168 - pdebug(1,"End of function wp_forecast_init ()");
201 + // javascript hinzufügen fuer ajax widget.
202 + if ( ! is_admin() && get_option( 'wpf_sem_ajaxload' ) > 0 ) {
203 + wp_enqueue_script( 'wpf_update', plugins_url( 'wpf_update.js', __FILE__ ), array( 'jquery' ), '9999' );
204 + }
205 + // javascript hinzufügen für suche im admin dialog.
206 + if ( is_admin() ) {
207 + wp_enqueue_script( 'wp-color-picker' );
208 + wp_enqueue_script( 'wp-forecast-search', plugins_url( 'wp-forecast-admin.js', __FILE__ ), array( 'jquery' ), '9999' );
209 + }
210 +
211 + // add css attribute display to the list of safe css styles for pulldown widget.
212 + add_filter(
213 + 'safe_style_css',
214 + function( $styles ) {
215 + $styles[] = 'display';
216 + return $styles;
217 + }
218 + );
169 219 }
170 220
171 221
172 -//
173 -// this function is called from your template
174 -// to insert your weather data at the place you want it to be
175 -// support to select language on a per call basis from Robert Lang
176 -//
177 -function wp_forecast_widget($args=array(),$wpfcid="A", $language_override=null)
178 -{
222 +/**
223 + * This function is called from your template
224 + * to insert your weather data at the place you want it to be
225 + * support to select language on a per call basis from Robert Lang.
226 + *
227 + * @param array $args Default parameters.
228 + * @param string $wpfcid The Widget ID.
229 + * @param string $language_override ISO Code of the language.
230 + */
231 +function wp_forecast_widget( $args = array(), $wpfcid = 'A', $language_override = null ) {
232 + if ( '?' == $wpfcid ) {
233 + $wpf_vars = get_wpf_opts( 'A' );
234 + } else {
235 + $wpf_vars = get_wpf_opts( $wpfcid );
236 + }
179 237
180 - pdebug(1,"Start of function wp_forecast_widget (".$wpfcid.")");
181 -
182 - if ($wpfcid == "?")
183 - $wpf_vars=get_wpf_opts("A");
184 - else
185 - $wpf_vars=get_wpf_opts($wpfcid);
238 + if ( ! empty( $language_override ) ) {
239 + $wpf_vars['wpf_language'] = $language_override;
240 + }
186 241
187 - if (!empty($language_override)) {
188 - $wpf_vars['wpf_language']=$language_override;
189 - }
242 + if ( '?' == $wpfcid ) {
243 + $weather = maybe_unserialize( wpf_get_option( 'wp-forecast-cacheA' ) );
244 + } else {
245 + $weather = maybe_unserialize( wpf_get_option( 'wp-forecast-cache' . $wpfcid ) );
246 + }
190 247
191 - if ($wpfcid == "?")
192 - $weather=maybe_unserialize(wpf_get_option("wp-forecast-cacheA"));
193 - else
194 - $weather=maybe_unserialize(wpf_get_option("wp-forecast-cache".$wpfcid));
248 + show( $wpfcid, $args, $wpf_vars );
249 +}
195 250
196 - show($wpfcid,$args,$wpf_vars);
251 +/**
252 + * This is the wrapper function for displaying from sidebar.php
253 + * and not as a widget. since the parameters are different we need this.
254 + *
255 + * @param string $wpfcid The Widget ID.
256 + * @param string $language_override ISO Code of the language.
257 + */
258 +function wp_forecast( $wpfcid = 'A', $language_override = null ) {
259 + wp_forecast_widget( array(), $wpfcid, $language_override );
260 +}
197 261
198 - pdebug(1,"End of function wp_forecast_widget ()");
199 -}
262 +/**
263 + * A function to show a range of widgets at once.
264 + *
265 + * @param int $from Lowest widget number to display.
266 + * @param int $to Highest widget number to display.
267 + * @param int $numpercol Number of widgets per column.
268 + * @param string $language_override ISO Code of the language.
269 + */
270 +function wp_forecast_range( $from = 0, $to = 0, $numpercol = 1, $language_override = null ) {
271 + global $wpf_maxwidgets;
272 + $wcount = 1;
200 273
201 -//
202 -// this is the wrapper function for displaying from sidebar.php
203 -// and not as a widget. since the parameters are different we need this
204 -//
205 -function wp_forecast($wpfcid="A", $language_override=null)
206 -{
207 - pdebug(1,"Start of function wp_forecast ()");
208 -
209 - wp_forecast_widget( array(), $wpfcid, $language_override);
274 + // check min and max limit.
275 + if ( $from < 0 ) {
276 + $from = 0;
277 + }
210 278
211 - pdebug(1,"End of function wp_forecast ()");
212 -}
279 + if ( $to > $wpf_maxwidgets ) {
280 + $to = $wpf_maxwidgets;
281 + }
213 282
214 -//
215 -// a function to show a range of widgets at once
216 -//
217 -function wp_forecast_range($from=0, $to=0, $numpercol=1, $language_override=null)
218 -{
219 - global $wpf_maxwidgets;
220 - $wcount=1;
283 + // output table header.
284 + echo '<table><tr>';
221 285
222 - // check min and max limit
223 - if ($from < 0)
224 - $from = 0;
225 -
226 - if ($to > $wpf_maxwidgets)
227 - $to = $wpf_maxwidgets;
228 -
229 - // output table header
230 - echo "<table><tr>";
286 + // out put widgets in a table.
287 + for ( $i = $from;$i <= $to;$i++ ) {
231 288
232 - // out put widgets in a table
233 - for ($i=$from;$i<=$to;$i++) {
289 + if ( 1 == $wcount % $numpercol ) {
290 + echo '<tr>';
291 + }
234 292
235 - if ( $wcount % $numpercol == 1)
236 - echo "<tr>";
293 + echo '<td>';
294 + wp_forecast( get_widget_id( $i ), $language_override );
295 + echo '</td>';
237 296
238 - echo "<td>";
239 - wp_forecast( get_widget_id($i), $language_override);
240 - echo "</td>";
297 + if ( ( 0 == $wcount % $numpercol ) && ( $i < $to ) ) {
298 + echo '</tr>';
299 + }
241 300
242 - if ( ($wcount % $numpercol == 0) and ($i< $to))
243 - echo "</tr>";
301 + ++$wcount;
302 + }
244 303
245 - $wcount += 1;
246 - }
247 -
248 - // output table footer
249 - echo "</tr></table>";
304 + // output table footer.
305 + echo '</tr></table>';
250 306 }
251 307
252 -//
253 -// a function to show a set of widgets at once
254 -//
255 -function wp_forecast_set($wset, $numpercol=1, $language_override=null)
256 -{
257 - global $wpf_maxwidgets;
258 - $wcount=1;
259 - $wset_max= count($wset)-1;
308 +/**
309 + * A function to show a set of widgets at once.
310 + *
311 + * @param array $wset Array with numbers of widgets to display.
312 + * @param int $numpercol Number of widgets per column.
313 + * @param string $language_override ISO Code of the language.
314 + */
315 +function wp_forecast_set( $wset, $numpercol = 1, $language_override = null ) {
316 + global $wpf_maxwidgets;
317 + $wcount = 1;
318 + $wset_max = count( $wset ) - 1;
260 319
261 - // output table header
262 - echo "<table><tr>";
320 + // output table header.
321 + echo '<table><tr>';
263 322
264 - // out put widgets in a table
265 - for ($i=0;$i<=$wset_max;$i++) {
323 + // out put widgets in a table.
324 + for ( $i = 0;$i <= $wset_max;$i++ ) {
266 325
267 - if ( $wcount % $numpercol == 1)
268 - echo "<tr>";
326 + if ( 1 == $wcount % $numpercol ) {
327 + echo '<tr>';
328 + }
269 329
270 - echo "<td>";
271 - wp_forecast( $wset[$i], $language_override);
272 - echo "</td>";
330 + echo '<td>';
331 + wp_forecast( $wset[ $i ], $language_override );
332 + echo '</td>';
273 333
274 - if ( ($wcount % $numpercol == 0) and ($i< $wset_max))
275 - echo "</tr>";
334 + if ( ( 0 == $wcount % $numpercol ) && ( $i < $wset_max ) ) {
335 + echo '</tr>';
336 + }
276 337
277 - $wcount += 1;
278 - }
279 -
280 - // output table footer
281 - echo "</tr></table>";
338 + ++$wcount;
339 + }
340 +
341 + // output table footer.
342 + echo '</tr></table>';
282 343 }
283 344
284 -//
285 -// returns the widget data as an array
286 -//
287 -function wp_forecast_data($wpfcid="A", $language_override=null)
288 -{
289 - pdebug(1,"Start of function wp_forecast_data ()");
290 -
291 - $wpf_vars=get_wpf_opts($wpfcid);
345 +/**
346 + * Returns the widget data as an array.
347 + *
348 + * @param string $wpfcid The Widget ID.
349 + * @param string $language_override ISO Code of the language.
350 + */
351 +function wp_forecast_data( $wpfcid = 'A', $language_override = null ) {
352 + $wpf_vars = get_wpf_opts( $wpfcid );
292 353
293 - if (!empty($language_override)) {
294 - $wpf_vars['wpf_language']=$language_override;
295 - }
354 + if ( ! empty( $language_override ) ) {
355 + $wpf_vars['wpf_language'] = $language_override;
356 + }
296 357
297 - extract($wpf_vars);
298 - $w=maybe_unserialize(wpf_get_option("wp-forecast-cache".$wpfcid));
358 + $w = maybe_unserialize( wpf_get_option( 'wp-forecast-cache' . $wpfcid ) );
299 359
300 - $weather_arr=array();
360 + $weather_arr = array();
301 361
302 - // read service dependent weather data
303 - switch ($wpf_vars['service']) {
304 - case "accu":
305 - $weather_arr= accu_forecast_data($wpfcid,$language_override);
306 - break;
307 - case "bug":
308 - $weather_arr= bug_forecast_data($wpfcid,$language_override);
309 - break;
310 - case "com":
311 - // to be done
312 - break;
313 - case "google":
314 - $weather_arr= google_forecast_data($wpfcid,$language_override);
315 - break;
316 - }
362 + // read service dependent weather data.
363 + switch ( $wpf_vars['service'] ) {
364 + case 'openweathermap':
365 + $weather_arr = openweathermap_forecast_data_v2( $wpfcid, $language_override );
366 + break;
367 + case 'openweathermap3':
368 + $weather_arr = openweathermap_forecast_data( $wpfcid, $language_override );
369 + break;
370 + case 'openmeteo':
371 + $weather_arr = openmeteo_forecast_data( $wpfcid, $language_override );
372 + break;
373 + }
317 374
318 - return $weather_arr;
319 -
320 - pdebug(1,"End of function wp_forecast_data ()");
321 -
375 + // add openuv data to weather_arr.
376 + if ( is_array( $w ) && array_key_exists( 'openuv', $w ) ) {
377 + $weather_arr['openuv'] = $w['openuv'];
378 + } else {
379 + $weather_arr['openuv'] = array();
380 + }
381 +
382 + return $weather_arr;
322 383 }
323 384
324 385
325 -//
326 -// set the choosen number of widgets, set at the widget page
327 -//
328 -function wpf_widget_setup() {
329 - global $wpf_maxwidgets;
386 +/**
387 + * Register the wp-forecast widget
388 + */
389 +function reg_wpf_widget() {
390 + return register_widget( 'wpf_widget' );
391 +}
392 +/**
393 + * Register the UV Widget
394 + */
395 +function reg_wpf_uv_widget() {
396 + return register_widget( 'WpfUvWidget' );
397 +}
330 398
331 - pdebug(1,"Start of function wpf_widget_setup ()");
332 -
333 - $count = $newcount = wpf_get_option('wp-forecast-count');
334 - if ( isset($_POST['wpf-count-submit']) ) {
335 - $number = (int) $_POST['wp-forecast-count'];
336 - if ( $number > $wpf_maxwidgets ) $number = $wpf_maxwidgets;
337 - if ( $number < 1 ) $number = 1;
338 - $newcount = $number;
339 - }
340 - if ( $count != $newcount ) {
341 - $count = $newcount;
342 - wpf_update_option('wp-forecast-count', $count);
343 - // add missing option to database
344 - wp_forecast_activate();
345 - // init the new number of widgets
346 - widget_wp_forecast_init($count);
347 - }
399 +/**
400 + * Init the wp-forecast widgets.
401 + */
402 +function widget_wp_forecast_init() {
403 + global $wp_version,$wpf_maxwidgets, $wpf_lang_dict;
348 404
349 - pdebug(1,"End of function wpf_widget_setup ()");
350 -}
405 + // include widget class.
406 + require_once 'class-wpf-widget.php';
407 + require_once 'class-wpfuvwidget.php';
351 408
352 -//
353 -// form snippet to set the number of wanted widgets from
354 -// the widget page
355 -//
356 -function wpf_widget_page() {
357 - global $wpf_maxwidgets;
358 -
359 - pdebug(1,"Start of function wpf_widget_page ()");
360 -
361 - $count = $newcount = wpf_get_option('wp-forecast-count');
362 -
363 - // get locale
364 - $locale = get_locale();
365 - if ( empty($locale) )
366 - $locale = 'en_US';
367 - // load translation
368 - if(function_exists('load_textdomain')) {
369 - load_textdomain("wp-forecast_".$locale,ABSPATH . "wp-content/plugins/wp-forecast/lang/".$locale.".mo");
370 - }
409 + $count = (int) wpf_get_option( 'wp-forecast-count' );
371 410
411 + // check for widget support.
412 + if ( ! function_exists( 'register_sidebar_widget' ) ) {
413 + return;
414 + }
372 415
373 - $out = "<div class='wrap'><form method='POST' action='#'>";
374 - $out .= "<h2>WP-Forecast Widgets</h2>";
375 - $out .= "<p style='line-height: 30px;'>".__('How many wp-forecast widgets would you like?',"wp-forecast_".$locale)." ";
376 - $out .= "<select id='wp-forecast-count' name='wp-forecast-count'>";
416 + // add fetch weather data to init the cache before any headers are sent.
417 + add_action( 'init', 'wp_forecast_init' );
418 + add_action( 'admin_init', 'wp_forecast_admin_init' );
377 419
378 - for ( $i = 1; $i <= $wpf_maxwidgets; ++$i ) {
379 - $out .= "<option value='$i' ";
380 - if ($count==$i)
381 - $out .= "selected='selected' ";
382 - $out .= ">$i</option>";
383 - }
384 - $out .= "</select> <span class='submit'><input type='submit' name='wpf-count-submit' id='wpf-count-submit' value=".esc_attr(__('Save'))." /></span></p></form></div>";
385 - echo $out;
420 + // add css.
421 + add_action( 'wp_enqueue_scripts', 'wp_forecast_css' );
386 422
387 - pdebug(1,"End of function wpf_widget_page ()");
388 -}
423 + for ( $i = 0;$i <= $wpf_maxwidgets;$i++ ) {
424 + $wpfcid = get_widget_id( $i );
389 425
390 -function widget_wp_forecast_init()
391 -{
426 + // register our widget and add a control.
427 + // translators: %s is for the Widget ID.
428 + $name = sprintf( __( 'wp-forecast %s' ), $wpfcid );
429 + $id = "wp-forecast-$wpfcid";
392 430
393 - global $wp_version,$wpf_maxwidgets;
431 + // translators: %s is for the widget ID.
432 + $uvname = sprintf( __( 'wp-forecast-uv %s' ), $wpfcid );
433 + $uvid = "wp-forecast-uv-$wpfcid";
394 434
395 - pdebug(1,"Start of function widget_wp_forecast_init ()");
396 -
397 - $count=(int) wpf_get_option('wp-forecast-count');
435 + // add widget.
436 + add_action( 'widgets_init', 'reg_wpf_widget' );
437 + add_action( 'widgets_init', 'reg_wpf_uv_widget' );
398 438
399 - // check for widget support
400 - if ( !function_exists('register_sidebar_widget') )
401 - return;
439 + wp_unregister_sidebar_widget( $i >= $count ? 'wp_forecast_widget' . $wpfcid : '' );
402 440
403 - // add fetch weather data to init the cache before any headers are sent
404 - add_action('init','wp_forecast_init');
405 - add_action('admin_init','wp_forecast_admin_init');
406 -
407 - // add css in header
408 - add_action('wp_head', 'wp_forecast_css');
409 -
410 - // javascript hinzufügen
411 - //wp_enqueue_script('wpf_update',
412 -// '/' . PLUGINDIR . '/wp-forecast/wpf_update.js',
413 -// array('jquery'), "9999");
441 + wp_register_widget_control(
442 + $id,
443 + $name,
444 + $i < $count ? 'wpf_admin_hint' : '',
445 + array(
446 + 'width' => 300,
447 + 'height' => 150,
448 + )
449 + );
414 450
415 - for ($i=0;$i<=$wpf_maxwidgets;$i++) {
416 - $wpfcid = get_widget_id( $i );
451 + wp_unregister_widget_control( $i >= $count ? 'wpf_admin_hint' . $wpfcid : '' );
452 + }
453 +}
417 454
418 - // register our widget and add a control
419 - $name = sprintf(__('wp-forecast %s'), $wpfcid);
420 - $id = "wp-forecast-$wpfcid";
421 -
422 -
423 - // include widget class (new widget api)
424 - require_once("class-wpf_widget.php");
425 - // register class
426 - add_action('widgets_init', create_function('', 'return register_widget("wpf_widget");'));
427 -
428 - wp_unregister_sidebar_widget($i >= $count ? 'wp_forecast_widget'.$wpfcid:'');
429 -
430 - wp_register_widget_control($id, $name, $i < $count ? 'wpf_admin_hint' : '',
431 - array('width' => 300, 'height' => 150));
432 -
433 - wp_unregister_widget_control($i >= $count ? 'wpf_admin_hint'.$wpfcid : '');
434 - }
455 +/**
456 + * Filters the REQUEST_URI for virtual page slug
457 + * to show weather in an iframe.
458 + */
459 +function wpf_filter_url() {
460 + $url = ( isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '' );
461 + $url = trim( parse_url( $url, PHP_URL_PATH ), '/' );
435 462
436 - // add actions for setup the count of wanted wpf widgets
437 - add_action('sidebar_admin_setup', 'wpf_widget_setup');
438 - add_action('sidebar_admin_page', 'wpf_widget_page');
463 + // determine if it is a wpf virtual page call.
464 + if ( strpos( $url, 'wp-forecast-direct' ) !== false ) {
465 + $wpfcid = ( isset( $_GET['wpfcid'] ) ? sanitize_text_field( wp_unslash( $_GET['wpfcid'] ) ) : 'A' );
466 + $language_override = ( isset( $_GET['language_override'] ) ? sanitize_text_field( wp_unslash( $_GET['language_override'] ) ) : '' );
467 + $header = ( isset( $_GET['header'] ) ? sanitize_text_field( wp_unslash( $_GET['header'] ) ) : '' );
468 + $selector = ( isset( $_GET['selector'] ) ? sanitize_text_field( wp_unslash( $_GET['selector'] ) ) : '' );
439 469
440 - // add filters for transport method check
441 - add_filter('use_fsockopen_transport','wpf_check_fsockopen');
442 - add_filter('use_fopen_transport','wpf_check_fopen');
443 - add_filter('use_streams_transport','wpf_check_streams');
444 - add_filter('use_http_extension_transport','wpf_check_exthttp');
445 - add_filter('use_curl_transport','wpf_check_curl');
470 + if ( '1' == $selector ) {
471 + $selector = '?';
472 + }
473 + $args = array();
474 + $wpf_vars = get_wpf_opts( $wpfcid );
446 475
447 - pdebug(1,"End of function widget_wp_forecast_init ()");
476 + if ( ! empty( $language_override ) ) {
477 + $wpf_vars['wpf_language'] = $language_override;
478 + }
448 479
449 -}
480 + $weather = maybe_unserialize( wpf_get_option( 'wp-forecast-cache' . $wpfcid ) );
450 481
482 + // only show weather html without page or header.
483 + if ( ! $header || 0 == $header ) {
484 + show( $selector . $wpfcid, $args, $wpf_vars );
485 + exit;
486 + }
451 487
488 + if ( 1 == $header ) {
489 + echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' . "\n";
490 + echo '<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="' . esc_attr( str_replace( '_', '-', $wpf_vars['wpf_language'] ) ) . '">' . "\n";
491 + echo "<head><title>wp-forecast iframe</title>\n";
492 + echo '<meta http-equiv="content-type" content="text/html; charset=utf-8" />' . "\n";
493 + echo '<style>' . wp_kses( wp_forecast_get_nowp_css(), wpf_allowed_tags() ) . '</style>' . "\n";
494 + echo "</head>\n<body>\n";
452 495
453 -// MAIN
496 + show( $selector . $wpfcid, $args, $wpf_vars );
454 497
455 -pdebug(1,"Start of MAIN");
498 + echo "</body></html>\n";
499 + exit;
500 + }
456 501
457 -// activating deactivating the plugin
458 -register_activation_hook(__FILE__,'wp_forecast_activate');
459 -register_deactivation_hook(__FILE__,'wp_forecast_deactivate');
502 + if ( 2 == $header ) {
503 + // create weather html.
504 + // add css.
505 + add_action( 'wp_enqueue_scripts', 'wp_forecast_css_nowp' );
506 + ob_start();
507 + show( $selector . $wpfcid, $args, $wpf_vars );
508 + $out = ob_get_contents();
509 + ob_end_clean();
460 510
461 -// add option page
462 -add_action('admin_menu', 'wp_forecast_admin');
511 + // create virtual page and display it.
512 + $args = array(
513 + 'slug' => 'wp-forecast-direct',
514 + 'title' => 'wp-forecast weather',
515 + 'content' => $out,
516 + );
517 + $pg4 = new Wpf_VirtualPage( $args );
518 + }
519 + }
520 +}
463 521
464 -// add super admin options page (check for super admin is done inside)
465 -add_action('admin_menu', 'wpmu_forecast_admin');
466 522
523 +// MAIN.
524 +
525 +// activating deactivating the plugin.
526 +register_activation_hook( __FILE__, 'wp_forecast_activate' );
527 +register_deactivation_hook( __FILE__, 'wp_forecast_deactivate' );
528 +
529 +// add option page.
530 +add_action( 'admin_menu', 'wp_forecast_admin' );
531 +
467 532 // Run our code later in case this loads prior to any required plugins.
468 -add_action('plugins_loaded', 'widget_wp_forecast_init');
533 +add_action( 'plugins_loaded', 'widget_wp_forecast_init' );
469 534
470 -
471 -pdebug(1,"End of MAIN");
472 -?>
535 +// add virtual page filter.
536 +add_action( 'init', 'wpf_filter_url' );