Widget Settings Importer/Exporter - Version 1.2

Version Description

  • Adding PHP version check to avoid errors upon activation.
  • Using locally uploaded file instead of url to retreive uploaded json
Download this release

Release Info

Developer kevinlangleyjr
Plugin Icon wp plugin Widget Settings Importer/Exporter
Version 1.2
Comparing to
See all releases

Code changes from version 1.1 to 1.2

Files changed (3) hide show
  1. class-widget-data.php +470 -0
  2. readme.txt +9 -3
  3. widget-data.php +10 -467
class-widget-data.php ADDED
@@ -0,0 +1,470 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Widget_Data {
4
+
5
+ /**
6
+ * initialize
7
+ */
8
+ public static function init() {
9
+ if( !is_admin() )
10
+ return;
11
+
12
+ add_action( 'admin_menu', array( __CLASS__, 'add_admin_menus' ) );
13
+ add_action( 'load-tools_page_widget-settings-export', array( __CLASS__, 'export_widget_settings' ) );
14
+ add_action( 'wp_ajax_import_widget_data', array( __CLASS__, 'ajax_import_widget_data' ) );
15
+ }
16
+
17
+ /**
18
+ * Register admin pages
19
+ */
20
+ public static function add_admin_menus() {
21
+ // export
22
+ $export_page = add_management_page( 'Widget Settings Export', 'Widget Settings Export', 'manage_options', 'widget-settings-export', array( __CLASS__, 'export_settings_page' ) );
23
+ //import
24
+ $import_page = add_management_page( 'Widget Settings Import', 'Widget Settings Import', 'manage_options', 'widget-settings-import', array( __CLASS__, 'import_settings_page' ) );
25
+
26
+ add_action( 'admin_enqueue_scripts', function($hook) use ($export_page, $import_page){
27
+ if( !in_array( $hook, array( $export_page, $import_page ) ) )
28
+ return;
29
+
30
+ wp_enqueue_style( 'widget_data', plugins_url( '/widget-data.css', __FILE__ ) );
31
+ wp_enqueue_script( 'widget_data', plugins_url( '/widget-data.js', __FILE__ ), array( 'jquery', 'wp-ajax-response' ) );
32
+ wp_localize_script( 'widget_data', 'widgets_url', get_admin_url( false, 'widgets.php' ) );
33
+ } );
34
+ }
35
+
36
+ /**
37
+ * HTML for export admin page
38
+ */
39
+ public static function export_settings_page() {
40
+ $sidebar_widgets = self::order_sidebar_widgets( wp_get_sidebars_widgets() );
41
+ ?>
42
+ <div class="widget-data export-widget-settings">
43
+ <div class="wrap">
44
+ <h2>Widget Setting Export</h2>
45
+ <div id="notifier" style="display: none;"></div>
46
+ <form action="" method="post" id="widget-export-settings">
47
+ <input type="hidden" id="action" name="action" value="export_widget_settings" />
48
+ <?php wp_nonce_field('export_widget_settings', '_wpnonce'); ?>
49
+ <p>
50
+ <a class="button select-all">Select All Active Widgets</a>
51
+ <a class="button unselect-all">Un-Select All Active Widgets</a>
52
+ </p>
53
+ <div class="title">
54
+ <h3>Sidebars</h3>
55
+ <div class="clear"></div>
56
+ </div>
57
+ <div class="sidebars">
58
+ <?php
59
+ foreach ( $sidebar_widgets as $sidebar_name => $widget_list ) :
60
+ if ( empty( $widget_list ) )
61
+ continue;
62
+
63
+ $sidebar_info = self::get_sidebar_info( $sidebar_name );
64
+ if( !empty($sidebar_info) ): ?>
65
+ <div class="sidebar">
66
+ <h4><?php echo $sidebar_info['name']; ?></h4>
67
+
68
+ <div class="widgets">
69
+ <?php
70
+ foreach ( $widget_list as $widget ) :
71
+
72
+ $widget_type = trim( substr( $widget, 0, strrpos( $widget, '-' ) ) );
73
+ $widget_type_index = trim( substr( $widget, strrpos( $widget, '-' ) + 1 ) );
74
+ $widget_options = get_option( 'widget_' . $widget_type );
75
+ $widget_title = isset( $widget_options[$widget_type_index]['title'] ) ? $widget_options[$widget_type_index]['title'] : $widget_type_index;
76
+ ?>
77
+ <div class="import-form-row">
78
+ <input class="<?php echo ($sidebar_name == 'wp_inactive_widgets') ? 'inactive' : 'active'; ?> widget-checkbox" type="checkbox" name="<?php echo esc_attr( $widget ); ?>" id="<?php echo esc_attr( 'meta_' . $widget ); ?>" />
79
+ <label for="<?php echo esc_attr( 'meta_' . $widget ); ?>">
80
+ <?php
81
+ echo ucfirst( $widget_type );
82
+ if( !empty( $widget_title ) )
83
+ echo ' - ' . $widget_title;
84
+ ?>
85
+ </label>
86
+ </div>
87
+ <?php endforeach; ?>
88
+ </div> <!-- end widgets -->
89
+ </div> <!-- end sidebar -->
90
+ <?php endif;
91
+ endforeach; ?>
92
+ </div> <!-- end sidebars -->
93
+ <input class="button-bottom button-primary" type="submit" value="Export Widget Settings"/>
94
+ </form>
95
+ </div> <!-- end wrap -->
96
+ </div> <!-- end export-widget-settings -->
97
+ <?php
98
+ }
99
+
100
+ /**
101
+ * HTML for import admin page
102
+ * @return type
103
+ */
104
+ public static function import_settings_page() {
105
+ ?>
106
+ <div class="widget-data import-widget-settings">
107
+ <div class="wrap">
108
+ <h2>Widget Setting Import</h2>
109
+ <?php if ( isset( $_FILES['widget-upload-file'] ) ) : ?>
110
+ <div id="notifier" style="display: none;"></div>
111
+ <div class="import-wrapper">
112
+ <p>
113
+ <a class="button select-all">Select All Active Widgets</a>
114
+ <a class="button unselect-all">Un-Select All Active Widgets</a>
115
+ </p>
116
+ <form action="" id="import-widget-data" method="post">
117
+ <?php wp_nonce_field('import_widget_data', '_wpnonce');
118
+
119
+ $json = self::get_widget_settings_json();
120
+
121
+ if( is_wp_error($json) )
122
+ wp_die( $json->get_error_message() );
123
+
124
+ if( !$json || !( $json_data = json_decode( $json[0], true ) ) )
125
+ return;
126
+
127
+ $json_file = $json[1];
128
+ ?>
129
+ <input type="hidden" name="import_file" value="<?php echo esc_attr( $json_file ); ?>"/>
130
+ <input type="hidden" name="action" value="import_widget_data"/>
131
+ <div class="title">
132
+ <p class="widget-selection-error">Please select a widget to continue.</p>
133
+ <h3>Sidebars</h3>
134
+ <div class="clear"></div>
135
+ </div>
136
+ <div class="sidebars">
137
+ <?php
138
+ if ( isset( $json_data[0] ) ) :
139
+ foreach ( self::order_sidebar_widgets( $json_data[0] ) as $sidebar_name => $widget_list ) :
140
+ if ( count( $widget_list ) == 0 ) {
141
+ continue;
142
+ }
143
+ $sidebar_info = self::get_sidebar_info( $sidebar_name );
144
+ if ( $sidebar_info ) : ?>
145
+ <div class="sidebar">
146
+ <h4><?php echo $sidebar_info['name']; ?></h4>
147
+
148
+ <div class="widgets">
149
+ <?php
150
+ foreach ( $widget_list as $widget ) :
151
+ $widget_options = false;
152
+
153
+ $widget_type = trim( substr( $widget, 0, strrpos( $widget, '-' ) ) );
154
+ $widget_type_index = trim( substr( $widget, strrpos( $widget, '-' ) + 1 ) );
155
+ foreach ( $json_data[1] as $name => $option ) {
156
+ if ( $name == $widget_type ) {
157
+ $widget_type_options = $option;
158
+ break;
159
+ }
160
+ }
161
+ if ( !isset($widget_type_options) || !$widget_type_options )
162
+ continue;
163
+
164
+ $widget_title = isset( $widget_type_options[$widget_type_index]['title'] ) ? $widget_type_options[$widget_type_index]['title'] : '';
165
+ $widget_options = $widget_type_options[$widget_type_index];
166
+ ?>
167
+ <div class="import-form-row">
168
+ <input class="<?php echo ($sidebar_name == 'wp_inactive_widgets') ? 'inactive' : 'active'; ?> widget-checkbox" type="checkbox" name="<?php echo esc_attr( printf('widgets[%s][%d]', $widget_type, $widget_type_index) ); ?>" id="<?php echo esc_attr( 'meta_' . $widget ); ?>" />
169
+ <label for="meta_<?php echo esc_attr( 'meta_' . $widget ); ?>">&nbsp;
170
+ <?php
171
+ echo ucfirst( $widget_type );
172
+ if( !empty( $widget_title ) )
173
+ echo ' - ' . $widget_title;
174
+ ?>
175
+ </label>
176
+ </div>
177
+ <?php endforeach; ?>
178
+ </div> <!-- end widgets -->
179
+ </div> <!-- end sidebar -->
180
+ <?php endif; ?>
181
+ <?php endforeach; ?>
182
+ <?php endif; ?>
183
+ </div> <!-- end sidebars -->
184
+ <input class="button-bottom button-primary" type="submit" name="import-widgets" id="import-widgets" value="Import Widget Settings" />
185
+ </form>
186
+ </div>
187
+ <?php else : ?>
188
+ <form action="" id="upload-widget-data" method="post" enctype="multipart/form-data">
189
+ <p>Select the file that contains widget settings</p>
190
+ <p>
191
+ <input type="text" disabled="disabled" class="file-name regular-text" />
192
+ <a id="upload-button" class="button upload-button">Select a file</a>
193
+ <input type="file" name="widget-upload-file" id="widget-upload-file" size="40" style="display:none;" />
194
+ </p>
195
+ <input type="submit" name="button-upload-submit" id="button-upload-submit" class="button" value="Show Widget Settings" />
196
+ </form>
197
+ <?php endif; ?>
198
+ </div> <!-- end wrap -->
199
+ </div> <!-- end import-widget-settings -->
200
+ <?php
201
+ }
202
+
203
+ /**
204
+ * Retrieve widgets from sidebars and create JSON object
205
+ * @param array $posted_array
206
+ * @return string
207
+ */
208
+ public static function parse_export_data( $posted_array ) {
209
+ $sidebars_array = get_option( 'sidebars_widgets' );
210
+ $sidebar_export = array( );
211
+ foreach ( $sidebars_array as $sidebar => $widgets ) {
212
+ if ( !empty( $widgets ) && is_array( $widgets ) ) {
213
+ foreach ( $widgets as $sidebar_widget ) {
214
+ if ( in_array( $sidebar_widget, array_keys( $posted_array ) ) ) {
215
+ $sidebar_export[$sidebar][] = $sidebar_widget;
216
+ }
217
+ }
218
+ }
219
+ }
220
+ $widgets = array( );
221
+ foreach ( $posted_array as $k => $v ) {
222
+ $widget = array( );
223
+ $widget['type'] = trim( substr( $k, 0, strrpos( $k, '-' ) ) );
224
+ $widget['type-index'] = trim( substr( $k, strrpos( $k, '-' ) + 1 ) );
225
+ $widget['export_flag'] = ($v == 'on') ? true : false;
226
+ $widgets[] = $widget;
227
+ }
228
+ $widgets_array = array( );
229
+ foreach ( $widgets as $widget ) {
230
+ $widget_val = get_option( 'widget_' . $widget['type'] );
231
+ $multiwidget_val = $widget_val['_multiwidget'];
232
+ $widgets_array[$widget['type']][$widget['type-index']] = $widget_val[$widget['type-index']];
233
+ if ( isset( $widgets_array[$widget['type']]['_multiwidget'] ) )
234
+ unset( $widgets_array[$widget['type']]['_multiwidget'] );
235
+
236
+ $widgets_array[$widget['type']]['_multiwidget'] = $multiwidget_val;
237
+ }
238
+ unset( $widgets_array['export'] );
239
+ $export_array = array( $sidebar_export, $widgets_array );
240
+ $json = json_encode( $export_array );
241
+ return $json;
242
+ }
243
+
244
+ /**
245
+ * Import widgets
246
+ * @param array $import_array
247
+ */
248
+ public static function parse_import_data( $import_array ) {
249
+ $sidebars_data = $import_array[0];
250
+ $widget_data = $import_array[1];
251
+ $current_sidebars = get_option( 'sidebars_widgets' );
252
+ $new_widgets = array( );
253
+
254
+ foreach ( $sidebars_data as $import_sidebar => $import_widgets ) :
255
+
256
+ foreach ( $import_widgets as $import_widget ) :
257
+ //if the sidebar exists
258
+ if ( isset( $current_sidebars[$import_sidebar] ) ) :
259
+ $title = trim( substr( $import_widget, 0, strrpos( $import_widget, '-' ) ) );
260
+ $index = trim( substr( $import_widget, strrpos( $import_widget, '-' ) + 1 ) );
261
+ $current_widget_data = get_option( 'widget_' . $title );
262
+ $new_widget_name = self::get_new_widget_name( $title, $index );
263
+ $new_index = trim( substr( $new_widget_name, strrpos( $new_widget_name, '-' ) + 1 ) );
264
+
265
+ if ( !empty( $new_widgets[ $title ] ) && is_array( $new_widgets[$title] ) ) {
266
+ while ( array_key_exists( $new_index, $new_widgets[$title] ) ) {
267
+ $new_index++;
268
+ }
269
+ }
270
+ $current_sidebars[$import_sidebar][] = $title . '-' . $new_index;
271
+ if ( array_key_exists( $title, $new_widgets ) ) {
272
+ $new_widgets[$title][$new_index] = $widget_data[$title][$index];
273
+ $multiwidget = $new_widgets[$title]['_multiwidget'];
274
+ unset( $new_widgets[$title]['_multiwidget'] );
275
+ $new_widgets[$title]['_multiwidget'] = $multiwidget;
276
+ } else {
277
+ $current_widget_data[$new_index] = $widget_data[$title][$index];
278
+ $current_multiwidget = $current_widget_data['_multiwidget'];
279
+ $new_multiwidget = isset($widget_data[$title]['_multiwidget']) ? $widget_data[$title]['_multiwidget'] : false;
280
+ $multiwidget = ($current_multiwidget != $new_multiwidget) ? $current_multiwidget : 1;
281
+ unset( $current_widget_data['_multiwidget'] );
282
+ $current_widget_data['_multiwidget'] = $multiwidget;
283
+ $new_widgets[$title] = $current_widget_data;
284
+ }
285
+
286
+ endif;
287
+ endforeach;
288
+ endforeach;
289
+
290
+ if ( isset( $new_widgets ) && isset( $current_sidebars ) ) {
291
+ update_option( 'sidebars_widgets', $current_sidebars );
292
+
293
+ foreach ( $new_widgets as $title => $content )
294
+ update_option( 'widget_' . $title, $content );
295
+
296
+ return true;
297
+ }
298
+
299
+ return false;
300
+ }
301
+
302
+ /**
303
+ * Output the JSON for download
304
+ */
305
+ public static function export_widget_settings() {
306
+ // @TODO check something better than just $_POST
307
+ if ( isset( $_POST['action'] ) && $_POST['action'] == 'export_widget_settings' ){
308
+ header( "Content-Description: File Transfer" );
309
+ header( "Content-Disposition: attachment; filename=widget_data.json" );
310
+ header( "Content-Type: application/octet-stream" );
311
+ echo self::parse_export_data( $_POST );
312
+ exit;
313
+ }
314
+ }
315
+
316
+ /**
317
+ * Parse JSON import file and load
318
+ */
319
+ public static function ajax_import_widget_data() {
320
+ $response = array(
321
+ 'what' => 'widget_import_export',
322
+ 'action' => 'import_submit'
323
+ );
324
+
325
+ $widgets = isset( $_POST['widgets'] ) ? $_POST['widgets'] : false;
326
+ $import_file = isset( $_POST['import_file'] ) ? $_POST['import_file'] : false;
327
+
328
+ if( empty($widgets) || empty($import_file) ){
329
+ $response['id'] = new WP_Error('import_widget_data', 'No widget data posted to import');
330
+ $response = new WP_Ajax_Response( $response );
331
+ $response->send();
332
+ }
333
+
334
+ $json_data = file_get_contents( $import_file );
335
+ $json_data = json_decode( $json_data, true );
336
+ $sidebar_data = $json_data[0];
337
+ $widget_data = $json_data[1];
338
+ foreach ( $sidebar_data as $title => $sidebar ) {
339
+ $count = count( $sidebar );
340
+ for ( $i = 0; $i < $count; $i++ ) {
341
+ $widget = array( );
342
+ $widget['type'] = trim( substr( $sidebar[$i], 0, strrpos( $sidebar[$i], '-' ) ) );
343
+ $widget['type-index'] = trim( substr( $sidebar[$i], strrpos( $sidebar[$i], '-' ) + 1 ) );
344
+ if ( !isset( $widgets[$widget['type']][$widget['type-index']] ) ) {
345
+ unset( $sidebar_data[$title][$i] );
346
+ }
347
+ }
348
+ $sidebar_data[$title] = array_values( $sidebar_data[$title] );
349
+ }
350
+
351
+ foreach ( $widgets as $widget_title => $widget_value ) {
352
+ foreach ( $widget_value as $widget_key => $widget_value ) {
353
+ $widgets[$widget_title][$widget_key] = $widget_data[$widget_title][$widget_key];
354
+ }
355
+ }
356
+
357
+ $sidebar_data = array( array_filter( $sidebar_data ), $widgets );
358
+ $response['id'] = ( self::parse_import_data( $sidebar_data ) ) ? true : new WP_Error( 'widget_import_submit', 'Unknown Error' );
359
+
360
+ $response = new WP_Ajax_Response( $response );
361
+ $response->send();
362
+ }
363
+
364
+ /**
365
+ * Read uploaded JSON file
366
+ * @return type
367
+ */
368
+ public static function get_widget_settings_json() {
369
+ $widget_settings = self::upload_widget_settings_file();
370
+
371
+ if( is_wp_error( $widget_settings ) || ! $widget_settings )
372
+ return false;
373
+
374
+ if( isset( $widget_settings['error'] ) )
375
+ return new WP_Error( 'widget_import_upload_error', $widget_settings['error'] );
376
+
377
+ $file_contents = file_get_contents( $widget_settings['file'] );
378
+ return array( $file_contents, $widget_settings['file'] );
379
+ }
380
+
381
+ /**
382
+ * Upload JSON file
383
+ * @return boolean
384
+ */
385
+ public static function upload_widget_settings_file() {
386
+ if ( isset( $_FILES['widget-upload-file'] ) ) {
387
+ add_filter( 'upload_mimes', array( __CLASS__, 'json_upload_mimes' ) );
388
+
389
+ $upload = wp_handle_upload( $_FILES['widget-upload-file'], array( 'test_form' => false ) );
390
+
391
+ remove_filter( 'upload_mimes', array( __CLASS__, 'json_upload_mimes' ) );
392
+ return $upload;
393
+ }
394
+
395
+ return false;
396
+ }
397
+
398
+ /**
399
+ *
400
+ * @param string $widget_name
401
+ * @param string $widget_index
402
+ * @return string
403
+ */
404
+ public static function get_new_widget_name( $widget_name, $widget_index ) {
405
+ $current_sidebars = get_option( 'sidebars_widgets' );
406
+ $all_widget_array = array( );
407
+ foreach ( $current_sidebars as $sidebar => $widgets ) {
408
+ if ( !empty( $widgets ) && is_array( $widgets ) && $sidebar != 'wp_inactive_widgets' ) {
409
+ foreach ( $widgets as $widget ) {
410
+ $all_widget_array[] = $widget;
411
+ }
412
+ }
413
+ }
414
+ while ( in_array( $widget_name . '-' . $widget_index, $all_widget_array ) ) {
415
+ $widget_index++;
416
+ }
417
+ $new_widget_name = $widget_name . '-' . $widget_index;
418
+ return $new_widget_name;
419
+ }
420
+
421
+ /**
422
+ *
423
+ * @global type $wp_registered_sidebars
424
+ * @param type $sidebar_id
425
+ * @return boolean
426
+ */
427
+ public static function get_sidebar_info( $sidebar_id ) {
428
+ global $wp_registered_sidebars;
429
+
430
+ //since wp_inactive_widget is only used in widgets.php
431
+ if ( $sidebar_id == 'wp_inactive_widgets' )
432
+ return array( 'name' => 'Inactive Widgets', 'id' => 'wp_inactive_widgets' );
433
+
434
+ foreach ( $wp_registered_sidebars as $sidebar ) {
435
+ if ( isset( $sidebar['id'] ) && $sidebar['id'] == $sidebar_id )
436
+ return $sidebar;
437
+ }
438
+
439
+ return false;
440
+ }
441
+
442
+ /**
443
+ *
444
+ * @param array $sidebar_widgets
445
+ * @return type
446
+ */
447
+ public static function order_sidebar_widgets( $sidebar_widgets ) {
448
+ $inactive_widgets = false;
449
+
450
+ //seperate inactive widget sidebar from other sidebars so it can be moved to the end of the array, if it exists
451
+ if ( isset( $sidebar_widgets['wp_inactive_widgets'] ) ) {
452
+ $inactive_widgets = $sidebar_widgets['wp_inactive_widgets'];
453
+ unset( $sidebar_widgets['wp_inactive_widgets'] );
454
+ $sidebar_widgets['wp_inactive_widgets'] = $inactive_widgets;
455
+ }
456
+
457
+ return $sidebar_widgets;
458
+ }
459
+
460
+ /**
461
+ * Add mime type for JSON
462
+ * @param array $existing_mimes
463
+ * @return string
464
+ */
465
+ public static function json_upload_mimes( $existing_mimes = array( ) ) {
466
+ $existing_mimes['json'] = 'application/json';
467
+ return $existing_mimes;
468
+ }
469
+
470
+ }
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: kevinlangleyjr, smccafferty, markparolisi, voceplatforms
3
  Tags: widget, import, export
4
  Requires at least: 2.8
5
- Tested up to: 3.5
6
- Stable tag: 1.1
7
 
8
  Allows you to export and import widgets settings.
9
 
@@ -11,7 +11,9 @@ Allows you to export and import widgets settings.
11
 
12
  Gives the user the ability to export the current widget settings and states as a json file. You can then import those settings on a different server or installation of WordPress so you have the same widgets within the same sidebars as the export. The import will not overwrite any data currently within the sidebars, but instead will increment the widgets and add a new instance of the widget instead.
13
 
14
- **Please note that the plugin currently does not import anything if that particular sidebar is unavailable during the import.
 
 
15
 
16
  == Installation ==
17
 
@@ -25,6 +27,10 @@ Gives the user the ability to export the current widget settings and states as a
25
 
26
  == Changelog ==
27
 
 
 
 
 
28
  = 1.1 =
29
  * Refactoring for performance / integrating changes made by Automattic
30
  * Better styles for wp-admin
2
  Contributors: kevinlangleyjr, smccafferty, markparolisi, voceplatforms
3
  Tags: widget, import, export
4
  Requires at least: 2.8
5
+ Tested up to: 3.5.2
6
+ Stable tag: 1.2
7
 
8
  Allows you to export and import widgets settings.
9
 
11
 
12
  Gives the user the ability to export the current widget settings and states as a json file. You can then import those settings on a different server or installation of WordPress so you have the same widgets within the same sidebars as the export. The import will not overwrite any data currently within the sidebars, but instead will increment the widgets and add a new instance of the widget instead.
13
 
14
+ ** Please note that the plugin currently does not import anything if that particular sidebar is unavailable during the import.
15
+
16
+ *** This plugin requires at least PHP 5.3.0
17
 
18
  == Installation ==
19
 
27
 
28
  == Changelog ==
29
 
30
+ = 1.2 =
31
+ * Adding PHP version check to avoid errors upon activation.
32
+ * Using locally uploaded file instead of url to retreive uploaded json
33
+
34
  = 1.1 =
35
  * Refactoring for performance / integrating changes made by Automattic
36
  * Better styles for wp-admin
widget-data.php CHANGED
@@ -4,7 +4,7 @@
4
  Description: Adds functionality to export and import widget data
5
  Author: Voce Communications - Kevin Langley, Sean McCafferty, Mark Parolisi
6
  Author URI: http://vocecommunications.com
7
- Version: 1.1
8
  * ******************************************************************
9
  Copyright 2011-2011 Voce Communications
10
 
@@ -23,474 +23,17 @@
23
  * ******************************************************************
24
  */
25
 
26
- class Widget_Data {
27
 
28
- /**
29
- * initialize
30
- */
31
- public static function init() {
32
- if( !is_admin() )
33
- return;
34
 
35
- add_action( 'admin_menu', array( __CLASS__, 'add_admin_menus' ) );
36
- add_action( 'load-tools_page_widget-settings-export', array( __CLASS__, 'export_widget_settings' ) );
37
- add_action( 'wp_ajax_import_widget_data', array( __CLASS__, 'ajax_import_widget_data' ) );
38
  }
39
-
40
- /**
41
- * Register admin pages
42
- */
43
- public static function add_admin_menus() {
44
- // export
45
- $export_page = add_management_page( 'Widget Settings Export', 'Widget Settings Export', 'manage_options', 'widget-settings-export', array( __CLASS__, 'export_settings_page' ) );
46
- //import
47
- $import_page = add_management_page( 'Widget Settings Import', 'Widget Settings Import', 'manage_options', 'widget-settings-import', array( __CLASS__, 'import_settings_page' ) );
48
-
49
- add_action( 'admin_enqueue_scripts', function($hook) use ($export_page, $import_page){
50
- if( !in_array( $hook, array( $export_page, $import_page ) ) )
51
- return;
52
-
53
- wp_enqueue_style( 'widget_data', plugins_url( '/widget-data.css', __FILE__ ) );
54
- wp_enqueue_script( 'widget_data', plugins_url( '/widget-data.js', __FILE__ ), array( 'jquery', 'wp-ajax-response' ) );
55
- wp_localize_script( 'widget_data', 'widgets_url', get_admin_url( false, 'widgets.php' ) );
56
- } );
57
- }
58
-
59
- /**
60
- * HTML for export admin page
61
- */
62
- public static function export_settings_page() {
63
- $sidebar_widgets = self::order_sidebar_widgets( wp_get_sidebars_widgets() );
64
- ?>
65
- <div class="widget-data export-widget-settings">
66
- <div class="wrap">
67
- <h2>Widget Setting Export</h2>
68
- <div id="notifier" style="display: none;"></div>
69
- <form action="" method="post" id="widget-export-settings">
70
- <input type="hidden" id="action" name="action" value="export_widget_settings" />
71
- <?php wp_nonce_field('export_widget_settings', '_wpnonce'); ?>
72
- <p>
73
- <a class="button select-all">Select All Active Widgets</a>
74
- <a class="button unselect-all">Un-Select All Active Widgets</a>
75
- </p>
76
- <div class="title">
77
- <h3>Sidebars</h3>
78
- <div class="clear"></div>
79
- </div>
80
- <div class="sidebars">
81
- <?php
82
- foreach ( $sidebar_widgets as $sidebar_name => $widget_list ) :
83
- if ( count( $widget_list ) == 0 )
84
- continue;
85
-
86
- $sidebar_info = self::get_sidebar_info( $sidebar_name );
87
- ?>
88
-
89
- <div class="sidebar">
90
- <h4><?php echo $sidebar_info['name']; ?></h4>
91
-
92
- <div class="widgets">
93
- <?php
94
- foreach ( $widget_list as $widget ) :
95
-
96
- $widget_type = trim( substr( $widget, 0, strrpos( $widget, '-' ) ) );
97
- $widget_type_index = trim( substr( $widget, strrpos( $widget, '-' ) + 1 ) );
98
- $widget_options = get_option( 'widget_' . $widget_type );
99
- $widget_title = isset( $widget_options[$widget_type_index]['title'] ) ? $widget_options[$widget_type_index]['title'] : $widget_type_index;
100
- ?>
101
- <div class="import-form-row">
102
- <input class="<?php echo ($sidebar_name == 'wp_inactive_widgets') ? 'inactive' : 'active'; ?> widget-checkbox" type="checkbox" name="<?php echo esc_attr( $widget ); ?>" id="<?php echo esc_attr( 'meta_' . $widget ); ?>" />
103
- <label for="<?php echo esc_attr( 'meta_' . $widget ); ?>">
104
- <?php
105
- echo ucfirst( $widget_type );
106
- if( !empty( $widget_title ) )
107
- echo ' - ' . $widget_title;
108
- ?>
109
- </label>
110
- </div>
111
- <?php endforeach; ?>
112
- </div> <!-- end widgets -->
113
- </div> <!-- end sidebar -->
114
- <?php endforeach; ?>
115
- </div> <!-- end sidebars -->
116
- <input class="button-bottom button-primary" type="submit" value="Export Widget Settings"/>
117
- </form>
118
- </div> <!-- end wrap -->
119
- </div> <!-- end export-widget-settings -->
120
- <?php
121
- }
122
-
123
- /**
124
- * HTML for import admin page
125
- * @return type
126
- */
127
- public static function import_settings_page() {
128
- ?>
129
- <div class="widget-data import-widget-settings">
130
- <div class="wrap">
131
- <h2>Widget Setting Import</h2>
132
- <?php if ( isset( $_FILES['widget-upload-file'] ) ) : ?>
133
- <div id="notifier" style="display: none;"></div>
134
- <div class="import-wrapper">
135
- <p>
136
- <a class="button select-all">Select All Active Widgets</a>
137
- <a class="button unselect-all">Un-Select All Active Widgets</a>
138
- </p>
139
- <form action="" id="import-widget-data" method="post">
140
- <?php wp_nonce_field('import_widget_data', '_wpnonce');
141
-
142
- $json = self::get_widget_settings_json();
143
-
144
- if( is_wp_error($json) )
145
- wp_die( $json->get_error_message() );
146
-
147
- if( !( $json_data = json_decode( $json[0], true ) ) )
148
- return;
149
-
150
- $json_file = $json[1];
151
- ?>
152
- <input type="hidden" name="import_file" value="<?php echo esc_attr( $json_file ); ?>"/>
153
- <input type="hidden" name="action" value="import_widget_data"/>
154
- <div class="title">
155
- <p class="widget-selection-error">Please select a widget to continue.</p>
156
- <h3>Sidebars</h3>
157
- <div class="clear"></div>
158
- </div>
159
- <div class="sidebars">
160
- <?php
161
- if ( isset( $json_data[0] ) ) :
162
- foreach ( self::order_sidebar_widgets( $json_data[0] ) as $sidebar_name => $widget_list ) :
163
- if ( count( $widget_list ) == 0 ) {
164
- continue;
165
- }
166
- $sidebar_info = self::get_sidebar_info( $sidebar_name );
167
- if ( $sidebar_info ) : ?>
168
- <div class="sidebar">
169
- <h4><?php echo $sidebar_info['name']; ?></h4>
170
-
171
- <div class="widgets">
172
- <?php
173
- foreach ( $widget_list as $widget ) :
174
- $widget_options = false;
175
-
176
- $widget_type = trim( substr( $widget, 0, strrpos( $widget, '-' ) ) );
177
- $widget_type_index = trim( substr( $widget, strrpos( $widget, '-' ) + 1 ) );
178
- foreach ( $json_data[1] as $name => $option ) {
179
- if ( $name == $widget_type ) {
180
- $widget_type_options = $option;
181
- break;
182
- }
183
- }
184
- if ( !isset($widget_type_options) || !$widget_type_options )
185
- continue;
186
-
187
- $widget_title = isset( $widget_type_options[$widget_type_index]['title'] ) ? $widget_type_options[$widget_type_index]['title'] : '';
188
- $widget_options = $widget_type_options[$widget_type_index];
189
- ?>
190
- <div class="import-form-row">
191
- <input class="<?php echo ($sidebar_name == 'wp_inactive_widgets') ? 'inactive' : 'active'; ?> widget-checkbox" type="checkbox" name="<?php echo esc_attr( printf('widgets[%s][%d]', $widget_type, $widget_type_index) ); ?>" id="<?php echo esc_attr( 'meta_' . $widget ); ?>" />
192
- <label for="meta_<?php echo esc_attr( 'meta_' . $widget ); ?>">&nbsp;
193
- <?php
194
- echo ucfirst( $widget_type );
195
- if( !empty( $widget_title ) )
196
- echo ' - ' . $widget_title;
197
- ?>
198
- </label>
199
- </div>
200
- <?php endforeach; ?>
201
- </div> <!-- end widgets -->
202
- </div> <!-- end sidebar -->
203
- <?php endif; ?>
204
- <?php endforeach; ?>
205
- <?php endif; ?>
206
- </div> <!-- end sidebars -->
207
- <input class="button-bottom button-primary" type="submit" name="import-widgets" id="import-widgets" value="Import Widget Settings" />
208
- </form>
209
- </div>
210
- <?php else : ?>
211
- <form action="" id="upload-widget-data" method="post" enctype="multipart/form-data">
212
- <p>Select the file that contains widget settings</p>
213
- <p>
214
- <input type="text" disabled="disabled" class="file-name regular-text" />
215
- <a id="upload-button" class="button upload-button">Select a file</a>
216
- <input type="file" name="widget-upload-file" id="widget-upload-file" size="40" style="display:none;" />
217
- </p>
218
- <input type="submit" name="button-upload-submit" id="button-upload-submit" class="button" value="Show Widget Settings" />
219
- </form>
220
- <?php endif; ?>
221
- </div> <!-- end wrap -->
222
- </div> <!-- end import-widget-settings -->
223
- <?php
224
- }
225
-
226
- /**
227
- * Retrieve widgets from sidebars and create JSON object
228
- * @param array $posted_array
229
- * @return string
230
- */
231
- public static function parse_export_data( $posted_array ) {
232
- $sidebars_array = get_option( 'sidebars_widgets' );
233
- $sidebar_export = array( );
234
- foreach ( $sidebars_array as $sidebar => $widgets ) {
235
- if ( !empty( $widgets ) && is_array( $widgets ) ) {
236
- foreach ( $widgets as $sidebar_widget ) {
237
- if ( in_array( $sidebar_widget, array_keys( $posted_array ) ) ) {
238
- $sidebar_export[$sidebar][] = $sidebar_widget;
239
- }
240
- }
241
- }
242
- }
243
- $widgets = array( );
244
- foreach ( $posted_array as $k => $v ) {
245
- $widget = array( );
246
- $widget['type'] = trim( substr( $k, 0, strrpos( $k, '-' ) ) );
247
- $widget['type-index'] = trim( substr( $k, strrpos( $k, '-' ) + 1 ) );
248
- $widget['export_flag'] = ($v == 'on') ? true : false;
249
- $widgets[] = $widget;
250
- }
251
- $widgets_array = array( );
252
- foreach ( $widgets as $widget ) {
253
- $widget_val = get_option( 'widget_' . $widget['type'] );
254
- $multiwidget_val = $widget_val['_multiwidget'];
255
- $widgets_array[$widget['type']][$widget['type-index']] = $widget_val[$widget['type-index']];
256
- if ( isset( $widgets_array[$widget['type']]['_multiwidget'] ) )
257
- unset( $widgets_array[$widget['type']]['_multiwidget'] );
258
-
259
- $widgets_array[$widget['type']]['_multiwidget'] = $multiwidget_val;
260
- }
261
- unset( $widgets_array['export'] );
262
- $export_array = array( $sidebar_export, $widgets_array );
263
- error_log(var_export($export_array, true));
264
- $json = json_encode( $export_array );
265
- return $json;
266
- }
267
-
268
- /**
269
- * Import widgets
270
- * @param array $import_array
271
- */
272
- public static function parse_import_data( $import_array ) {
273
- $sidebars_data = $import_array[0];
274
- $widget_data = $import_array[1];
275
- $current_sidebars = get_option( 'sidebars_widgets' );
276
- $new_widgets = array( );
277
-
278
- foreach ( $sidebars_data as $import_sidebar => $import_widgets ) :
279
-
280
- foreach ( $import_widgets as $import_widget ) :
281
- //if the sidebar exists
282
- if ( isset( $current_sidebars[$import_sidebar] ) ) :
283
- $title = trim( substr( $import_widget, 0, strrpos( $import_widget, '-' ) ) );
284
- $index = trim( substr( $import_widget, strrpos( $import_widget, '-' ) + 1 ) );
285
- $current_widget_data = get_option( 'widget_' . $title );
286
- $new_widget_name = self::get_new_widget_name( $title, $index );
287
- $new_index = trim( substr( $new_widget_name, strrpos( $new_widget_name, '-' ) + 1 ) );
288
-
289
- if ( !empty( $new_widgets[ $title ] ) && is_array( $new_widgets[$title] ) ) {
290
- while ( array_key_exists( $new_index, $new_widgets[$title] ) ) {
291
- $new_index++;
292
- }
293
- }
294
- $current_sidebars[$import_sidebar][] = $title . '-' . $new_index;
295
- if ( array_key_exists( $title, $new_widgets ) ) {
296
- $new_widgets[$title][$new_index] = $widget_data[$title][$index];
297
- $multiwidget = $new_widgets[$title]['_multiwidget'];
298
- unset( $new_widgets[$title]['_multiwidget'] );
299
- $new_widgets[$title]['_multiwidget'] = $multiwidget;
300
- } else {
301
- $current_widget_data[$new_index] = $widget_data[$title][$index];
302
- $current_multiwidget = $current_widget_data['_multiwidget'];
303
- $new_multiwidget = $widget_data[$title]['_multiwidget'];
304
- $multiwidget = ($current_multiwidget != $new_multiwidget) ? $current_multiwidget : 1;
305
- unset( $current_widget_data['_multiwidget'] );
306
- $current_widget_data['_multiwidget'] = $multiwidget;
307
- $new_widgets[$title] = $current_widget_data;
308
- }
309
-
310
- endif;
311
- endforeach;
312
- endforeach;
313
-
314
- if ( isset( $new_widgets ) && isset( $current_sidebars ) ) {
315
- update_option( 'sidebars_widgets', $current_sidebars );
316
-
317
- foreach ( $new_widgets as $title => $content )
318
- update_option( 'widget_' . $title, $content );
319
-
320
- return true;
321
- }
322
-
323
- return false;
324
- }
325
-
326
- /**
327
- * Output the JSON for download
328
- */
329
- public static function export_widget_settings() {
330
- // @TODO check something better than just $_POST
331
- if ( isset( $_POST['action'] ) && $_POST['action'] == 'export_widget_settings' ){
332
- header( "Content-Description: File Transfer" );
333
- header( "Content-Disposition: attachment; filename=widget_data.json" );
334
- header( "Content-Type: application/octet-stream" );
335
- echo self::parse_export_data( $_POST );
336
- exit;
337
- }
338
- }
339
-
340
- /**
341
- * Parse JSON import file and load
342
- */
343
- public static function ajax_import_widget_data() {
344
- $response = array(
345
- 'what' => 'widget_import_export',
346
- 'action' => 'import_submit'
347
- );
348
-
349
- $widgets = isset( $_POST['widgets'] ) ? $_POST['widgets'] : false;
350
- $import_file = isset( $_POST['import_file'] ) ? $_POST['import_file'] : false;
351
-
352
- if( empty($widgets) || empty($import_file) ){
353
- $response['id'] = new WP_Error('import_widget_data', 'No widget data posted to import');
354
- $response = new WP_Ajax_Response( $response );
355
- $response->send();
356
- }
357
-
358
- $json_data = file_get_contents( $import_file );
359
- $json_data = json_decode( $json_data, true );
360
- $sidebar_data = $json_data[0];
361
- $widget_data = $json_data[1];
362
- foreach ( $sidebar_data as $title => $sidebar ) {
363
- $count = count( $sidebar );
364
- for ( $i = 0; $i < $count; $i++ ) {
365
- $widget = array( );
366
- $widget['type'] = trim( substr( $sidebar[$i], 0, strrpos( $sidebar[$i], '-' ) ) );
367
- $widget['type-index'] = trim( substr( $sidebar[$i], strrpos( $sidebar[$i], '-' ) + 1 ) );
368
- if ( !isset( $widgets[$widget['type']][$widget['type-index']] ) ) {
369
- unset( $sidebar_data[$title][$i] );
370
- }
371
- }
372
- $sidebar_data[$title] = array_values( $sidebar_data[$title] );
373
- }
374
-
375
- foreach ( $widgets as $widget_title => $widget_value ) {
376
- foreach ( $widget_value as $widget_key => $widget_value ) {
377
- $widgets[$widget_title][$widget_key] = $widget_data[$widget_title][$widget_key];
378
- }
379
- }
380
-
381
- $sidebar_data = array( array_filter( $sidebar_data ), $widgets );
382
- $response['id'] = ( self::parse_import_data( $sidebar_data ) ) ? true : new WP_Error( 'widget_import_submit', 'Unknown Error' );
383
-
384
- $response = new WP_Ajax_Response( $response );
385
- $response->send();
386
- }
387
-
388
- /**
389
- * Read uploaded JSON file
390
- * @return type
391
- */
392
- public static function get_widget_settings_json() {
393
- $widget_settings = self::upload_widget_settings_file();
394
-
395
- if( is_wp_error( $widget_settings ) || ! $widget_settings )
396
- return false;
397
-
398
- if( isset( $widget_settings['error'] ) )
399
- return new WP_Error( 'widget_import_upload_error', $widget_settings['error'] );
400
-
401
- $file_contents = file_get_contents( $widget_settings['url'] );
402
- return array( $file_contents, $widget_settings['url'] );
403
- }
404
-
405
- /**
406
- * Upload JSON file
407
- * @return boolean
408
- */
409
- public static function upload_widget_settings_file() {
410
- if ( isset( $_FILES['widget-upload-file'] ) ) {
411
- add_filter( 'upload_mimes', array( __CLASS__, 'json_upload_mimes' ) );
412
-
413
- $upload = wp_handle_upload( $_FILES['widget-upload-file'], array( 'test_form' => false ) );
414
-
415
- remove_filter( 'upload_mimes', array( __CLASS__, 'json_upload_mimes' ) );
416
- return $upload;
417
- }
418
-
419
- return false;
420
- }
421
-
422
- /**
423
- *
424
- * @param string $widget_name
425
- * @param string $widget_index
426
- * @return string
427
- */
428
- public static function get_new_widget_name( $widget_name, $widget_index ) {
429
- $current_sidebars = get_option( 'sidebars_widgets' );
430
- $all_widget_array = array( );
431
- foreach ( $current_sidebars as $sidebar => $widgets ) {
432
- if ( !empty( $widgets ) && is_array( $widgets ) && $sidebar != 'wp_inactive_widgets' ) {
433
- foreach ( $widgets as $widget ) {
434
- $all_widget_array[] = $widget;
435
- }
436
- }
437
- }
438
- while ( in_array( $widget_name . '-' . $widget_index, $all_widget_array ) ) {
439
- $widget_index++;
440
- }
441
- $new_widget_name = $widget_name . '-' . $widget_index;
442
- return $new_widget_name;
443
- }
444
-
445
- /**
446
- *
447
- * @global type $wp_registered_sidebars
448
- * @param type $sidebar_id
449
- * @return boolean
450
- */
451
- public static function get_sidebar_info( $sidebar_id ) {
452
- global $wp_registered_sidebars;
453
-
454
- //since wp_inactive_widget is only used in widgets.php
455
- if ( $sidebar_id == 'wp_inactive_widgets' )
456
- return array( 'name' => 'Inactive Widgets', 'id' => 'wp_inactive_widgets' );
457
-
458
- foreach ( $wp_registered_sidebars as $sidebar ) {
459
- if ( isset( $sidebar['id'] ) && $sidebar['id'] == $sidebar_id )
460
- return $sidebar;
461
- }
462
-
463
- return false;
464
- }
465
-
466
- /**
467
- *
468
- * @param array $sidebar_widgets
469
- * @return type
470
- */
471
- public static function order_sidebar_widgets( $sidebar_widgets ) {
472
- $inactive_widgets = false;
473
-
474
- //seperate inactive widget sidebar from other sidebars so it can be moved to the end of the array, if it exists
475
- if ( isset( $sidebar_widgets['wp_inactive_widgets'] ) ) {
476
- $inactive_widgets = $sidebar_widgets['wp_inactive_widgets'];
477
- unset( $sidebar_widgets['wp_inactive_widgets'] );
478
- $sidebar_widgets['wp_inactive_widgets'] = $inactive_widgets;
479
- }
480
-
481
- return $sidebar_widgets;
482
- }
483
-
484
- /**
485
- * Add mime type for JSON
486
- * @param array $existing_mimes
487
- * @return string
488
- */
489
- public static function json_upload_mimes( $existing_mimes = array( ) ) {
490
- $existing_mimes['json'] = 'application/json';
491
- return $existing_mimes;
492
- }
493
-
494
  }
495
 
496
- add_action( 'init', array( 'Widget_Data', 'init' ) );
 
 
 
4
  Description: Adds functionality to export and import widget data
5
  Author: Voce Communications - Kevin Langley, Sean McCafferty, Mark Parolisi
6
  Author URI: http://vocecommunications.com
7
+ Version: 1.2
8
  * ******************************************************************
9
  Copyright 2011-2011 Voce Communications
10
 
23
  * ******************************************************************
24
  */
25
 
26
+ define( "WIDGET_DATA_MIN_PHP_VER", '5.3.0' );
27
 
28
+ register_activation_hook( __FILE__, 'widget_data_activation' );
 
 
 
 
 
29
 
30
+ function widget_data_activation() {
31
+ if ( version_compare( phpversion(), WIDGET_DATA_MIN_PHP_VER, '<' ) ) {
32
+ die( sprintf( "The minimum PHP version required for this plugin is %s", WIDGET_DATA_MIN_PHP_VER ) );
33
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  }
35
 
36
+ if ( version_compare( phpversion(), WIDGET_DATA_MIN_PHP_VER, '>=' ) ) {
37
+ require( __DIR__ . '/class-widget-data.php' );
38
+ add_action( 'init', array( 'Widget_Data', 'init' ) );
39
+ }