Widget Settings Importer/Exporter - Version 1.1

Version Description

  • Refactoring for performance / integrating changes made by Automattic
  • Better styles for wp-admin
Download this release

Release Info

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

Code changes from version 1.0 to 1.1

Files changed (4) hide show
  1. readme.txt +7 -3
  2. widget-data.css +11 -71
  3. widget-data.js +58 -88
  4. widget-data.php +150 -182
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.3
6
- Stable tag: 1.0
7
 
8
  Allows you to export and import widgets settings.
9
 
@@ -25,6 +25,10 @@ Gives the user the ability to export the current widget settings and states as a
25
 
26
  == Changelog ==
27
 
 
 
 
 
28
  = 1.0 =
29
  * Refactoring for performace.
30
  * Documentation
@@ -40,4 +44,4 @@ Gives the user the ability to export the current widget settings and states as a
40
  * Fixing blank redirect with WP installed within sub directory
41
 
42
  = 0.1 =
43
- * First Version
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
 
25
 
26
  == Changelog ==
27
 
28
+ = 1.1 =
29
+ * Refactoring for performance / integrating changes made by Automattic
30
+ * Better styles for wp-admin
31
+
32
  = 1.0 =
33
  * Refactoring for performace.
34
  * Documentation
44
  * Fixing blank redirect with WP installed within sub directory
45
 
46
  = 0.1 =
47
+ * First Version
widget-data.css CHANGED
@@ -1,71 +1,11 @@
1
- .widget-data .title {
2
- border-style: solid;
3
- border-width: 1px;
4
- font-size: 13px;
5
- border-color: #DFDFDF;
6
- color: #464646;
7
- text-shadow: 0 1px 0 #FFFFFF;
8
- background-color: #F1F1F1;
9
- background-image: -moz-linear-gradient(center top , #F9F9F9, #ECECEC);
10
- }
11
-
12
-
13
- .widget-data .title h3 {
14
- font-family: Georgia,"Times New Roman","Bitstream Charter",Times,serif;
15
- font-size: 15px;
16
- font-weight: normal;
17
- margin: 0;
18
- overflow: hidden;
19
- padding: 8px 10px;
20
- white-space: nowrap;
21
- width: 100px;
22
- }
23
-
24
- .widget-data .sidebars {
25
- border-color: #DFDFDF;
26
- border-style: solid;
27
- border-width: 1px;
28
- }
29
-
30
- #notifier{
31
- display:block;
32
- margin: 5px 0 15px;
33
- padding: 0.6em;
34
- -webkit-border-radius: 3px;
35
- border-radius: 3px;
36
- border-width: 1px;
37
- border-style: solid;
38
- }
39
-
40
- #notifier p {
41
- margin: .5em 0;
42
- padding: 2px;
43
- }
44
-
45
- #notifier.success {
46
- background-color: lightYellow;
47
- border-color: #E6DB55;
48
- }
49
-
50
- #notifier.error {
51
- background-color: #FFEBE8;
52
- border-color: #C00;
53
- }
54
-
55
- #upload-button { display:none; margin:4px 0 0 10px; }
56
-
57
- #output-text {background:#fff; display:block; width:400px; height:20px; border:solid 1px #eee; padding:5px;}
58
-
59
- #button-upload {margin-top:20px;}
60
-
61
- .widget-data .left {float: left; margin-bottom:10px;}
62
- .widget-data .right {float: right}
63
- .widget-data .sidebars .sidebar label {font-size: 12px;}
64
- .widget-data .sidebars .sidebar h4 {margin: 0; padding: 8px 20px; background:#eee;}
65
- .widget-data .button-bottom {margin-top: 10px;}
66
- .widget-data .export-selection-error {float: right;}
67
- .widget-data .title p {margin: 0; float: right; padding-top: 10px; font-size: 11px; color: red; padding: 10px 10px 0 0; display: none;}
68
-
69
- div.sidebar div.widgets .import-form-row { padding-left:30px; }
70
- div.sidebar div.widgets .import-form-row:nth-child(odd) { background-color:#fff; }
71
- div.sidebar div.widgets .import-form-row:nth-child(even){ background-color:#F9F9F9; }
1
+ .widget-data .title { border: solid 1px #DFDFDF; background-color: #F1F1F1; }
2
+ .widget-data .title h3 { margin: 0; padding: 8px 10px; }
3
+ .widget-data .title .widget-selection-error { display:none; margin: 0; float: right; color: #FF0000; padding: 10px 10px 0 0; }
4
+ .widget-data .sidebars { border: solid 1px #DFDFDF; }
5
+ .widget-data .sidebars .sidebar h4 { margin: 0; padding: 8px 20px; background:#eee; }
6
+ .widget-data .sidebars .sidebar .widgets input[type="checkbox"] { margin-right:3px; }
7
+ .widget-data .sidebars .sidebar .widgets .import-form-row { padding-left:30px; background-color:#FFF; }
8
+ .widget-data .sidebars .sidebar .widgets .import-form-row:nth-child(even){ background-color:#F9F9F9; }
9
+ .widget-data form#upload-widget-data span.file-name { min-width:300px; display:inline-block; height:20px; top:7px; border: solid 1px #bbb; position: relative; }
10
+ .widget-data form#upload-widget-data #upload-button { margin:4px 0 0 10px; }
11
+ .widget-data .button-bottom { margin-top: 10px; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
widget-data.js CHANGED
@@ -1,81 +1,70 @@
1
- /*global window, document,jQuery,widgets_url,ajaxurl*/
2
- (function(){
3
  "use strict";
4
-
5
- var $ = jQuery;
6
 
7
  /**
8
  * Display the notification div, populate a message, and set a CSS class
9
  * @param String message Message to display
10
  * @param String className CSS class of error or success
11
  */
12
- function show_notification(message, className){
13
- var $notifier = $('#notifier');
14
- className = className || 'success';
15
- $notifier.html('<p>'+message+'</p>');
16
- $notifier.addClass(className).fadeIn('slow');
 
17
  jQuery('body,html').animate({
18
  scrollTop: 0
19
  }, 800);
20
- }
 
 
 
 
 
 
 
 
 
21
 
22
- /**
23
- * Push the user to the Widget management page in wp-admin
24
- */
25
- function redirect_to_widgets() {
26
- window.location.replace(widgets_url);
27
- }
28
-
29
- jQuery(function($){
30
-
31
- var wrapper = $('<div/>').css({
32
- height:0,
33
- width:0,
34
- 'overflow':'hidden'
35
- }),
36
- $fileInput = $('#upload-file').wrap(wrapper),
37
- $widgetCheckbox = $('.widget-checkbox'),
38
- $widgetSelectionError = $('.widget-selection-error');
39
-
40
  /**
41
- * Check all widget checkbox fields on click
 
42
  * @param Object e Event object
43
  */
44
- $('#SelectAllActive').click(function(e){
45
  e.preventDefault();
46
- $widgetCheckbox.not(":checked").each(function(){
47
- $(this).attr( 'checked', true );
48
- });
 
 
 
 
 
 
 
 
49
  });
50
 
51
- /**
52
- * Uncheck all widget checkbox fields on click
53
- * @param Object e Event object
54
- */
55
- $('#UnSelectAllActive').click(function(e){
56
- e.preventDefault();
57
- $widgetCheckbox.filter(":checked").each(function(){
58
- $(this).attr( 'checked', false );
59
- });
60
- });
61
-
62
  /**
63
  * Handle the export form submission
64
  * @param Object e Event object
65
  */
66
  $('form#widget-export-settings').submit(function(e) {
67
  // return and show notification if no widgets are selected
68
- if ($widgetCheckbox.filter(':checked').length === 0) {
69
  e.preventDefault();
70
- $widgetSelectionError.fadeIn('slow').delay(2000).fadeOut('slow');
71
  return;
72
  }
73
  var message = 'All of the requested widgets have been exported.';
74
  $('form#widget-export-settings').fadeOut('slow');
75
- window.setTimeout(redirect_to_widgets, 4000);
76
- show_notification(message, 'success');
 
 
77
  });
78
-
79
  /***
80
  * Handle imports
81
  * @param Object e Event object
@@ -83,52 +72,33 @@
83
  $('form#import-widget-data').submit(function(e){
84
  e.preventDefault();
85
 
86
- if ($widgetCheckbox.filter(':checked').length === 0) {
87
- $widgetSelectionError.fadeIn('slow').delay(2000).fadeOut('slow');
88
  return false;
89
  }
90
  var message, newClass;
91
- $.ajax({
92
- type:'POST',
93
- url: ajaxurl,
94
- data: $("#import-widget-data").serialize()
95
- })
96
- .done(function(data){
97
- //@TODO check response code or something better than a response string
98
- if(data === "SUCCESS") {
99
- message = 'All widgets with registered sidebars have been imported successfully.';
100
- newClass = 'success';
101
- $('.import-wrapper').fadeOut('slow');
102
- window.setTimeout(redirect_to_widgets, 4000);
103
- } else {
104
- message = 'There was a problem importing your widgets. Please try again.';
105
- newClass = 'error';
106
- }
107
- show_notification(message, newClass);
108
- });
109
 
110
- });
111
-
112
- /**
113
- *
114
- */
115
- $fileInput.change(function(){
116
- var $this = $(this), $outputText = $('#output-text'),
117
- sub = $this.val().lastIndexOf('\\') + 1,
118
- newString = $this.val().substring(sub);
119
- $outputText.text(newString);
120
- $outputText.fadeIn('slow');
121
  });
122
 
123
  /**
124
  *
125
  */
126
- $('#upload-button').click(function(e){
127
- e.preventDefault();
128
- $fileInput.click();
129
- }).show();
130
- });
131
-
132
-
133
- }(window, document,jQuery,widgets_url,ajaxurl));
134
 
 
 
 
 
1
+ !function ($) {
 
2
  "use strict";
 
 
3
 
4
  /**
5
  * Display the notification div, populate a message, and set a CSS class
6
  * @param String message Message to display
7
  * @param String className CSS class of error or success
8
  */
9
+ var show_notification = function(message, className){
10
+ var notification = $('div#notifier').empty().removeClass('error updated');
11
+ notification.html('<p>' + message + '</p>');
12
+ notification.addClass(className);
13
+
14
+ notification.fadeIn('slow');
15
  jQuery('body,html').animate({
16
  scrollTop: 0
17
  }, 800);
18
+ },
19
+ wrapper = $('<div/>').css({
20
+ height:0,
21
+ width:0,
22
+ 'overflow':'hidden'
23
+ });
24
+ $(function () {
25
+ var fileInput = $('#widget-upload-file').wrap(wrapper),
26
+ widgetCheckboxes = $('.widget-data .widget-checkbox'),
27
+ widgetSelectionError = $('.widget-data p.widget-selection-error');
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  /**
30
+ * Handle click events for widget-data to select all checkboxes on click, to uncheck all
31
+ * checkboxes on click, and to activate the file upload when the file upload button is clicked.
32
  * @param Object e Event object
33
  */
34
+ $('.widget-data').on('click', '.select-all, .unselect-all, .upload-button', function(e){
35
  e.preventDefault();
36
+ if( $(this).hasClass('select-all') ){
37
+ widgetCheckboxes.not(":checked").each(function(){
38
+ $(this).attr( 'checked', true );
39
+ });
40
+ } else if( $(this).hasClass('unselect-all') ){
41
+ widgetCheckboxes.filter(":checked").each(function(){
42
+ $(this).attr( 'checked', false );
43
+ });
44
+ } else if( $(this).hasClass('upload-button') ){
45
+ fileInput.click();
46
+ }
47
  });
48
 
 
 
 
 
 
 
 
 
 
 
 
49
  /**
50
  * Handle the export form submission
51
  * @param Object e Event object
52
  */
53
  $('form#widget-export-settings').submit(function(e) {
54
  // return and show notification if no widgets are selected
55
+ if (widgetCheckboxes.filter(':checked').length === 0) {
56
  e.preventDefault();
57
+ show_notification('Please select a widget to continue.', 'error');
58
  return;
59
  }
60
  var message = 'All of the requested widgets have been exported.';
61
  $('form#widget-export-settings').fadeOut('slow');
62
+ window.setTimeout(function () {
63
+ window.location.replace(widgets_url);
64
+ }, 4000);
65
+ show_notification(message, 'updated');
66
  });
67
+
68
  /***
69
  * Handle imports
70
  * @param Object e Event object
72
  $('form#import-widget-data').submit(function(e){
73
  e.preventDefault();
74
 
75
+ if (widgetCheckboxes.filter(':checked').length === 0) {
76
+ widgetSelectionError.fadeIn('slow').delay(2000).fadeOut('slow');
77
  return false;
78
  }
79
  var message, newClass;
80
+ $.post( ajaxurl, $("#import-widget-data").serialize(), function(r){
81
+ var res = wpAjax.parseAjaxResponse(r, 'notifier');
82
+ if( ! res )
83
+ return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
 
85
+ $('.import-wrapper').fadeOut('slow');
86
+ show_notification('All widgets with registered sidebars have been imported successfully.', 'updated');
87
+ // window.setTimeout(function () {
88
+ // window.location.replace(widgets_url);
89
+ // }, 4000);
90
+ });
 
 
 
 
 
91
  });
92
 
93
  /**
94
  *
95
  */
96
+ fileInput.change(function(){
97
+ var outputText = $('#upload-widget-data .file-name'),
98
+ sub = $(this).val().lastIndexOf('\\') + 1,
99
+ filename = $(this).val().substring(sub);
 
 
 
 
100
 
101
+ outputText.val(filename);
102
+ });
103
+ });
104
+ }(window.jQuery);
widget-data.php CHANGED
@@ -2,10 +2,11 @@
2
  /*
3
  Plugin Name: Widget Data - Setting Import/Export Plugin
4
  Description: Adds functionality to export and import widget data
5
- Authors: Kevin Langley, Sean McCafferty, Mark Parolisi
6
- Version: 1.0
 
7
  * ******************************************************************
8
- Copyright 2011-2011 Kevin Langley & Sean McCafferty (email : klangley@voceconnect.com & smccafferty@voceconnect.com)
9
 
10
  This program is free software: you can redistribute it and/or modify
11
  it under the terms of the GNU General Public License as published by
@@ -24,61 +25,55 @@
24
 
25
  class Widget_Data {
26
 
27
- var $import_filename;
28
-
29
  /**
30
- * @constructor
31
  */
32
- function __construct() {
33
- add_action( 'admin_menu', array( $this, 'add_admin_menus' ) );
34
- add_action( 'admin_enqueue_scripts', array( $this, 'add_admin_scripts' ) );
35
- add_action( 'load-tools_page_widget-settings-export', array( $this, 'export_widget_settings' ) );
36
- add_action( 'wp_ajax_widget_import_submit', array( $this, 'widget_import_submit' ) );
37
- add_filter( 'upload_mimes', array( $this, 'json_upload_mimes' ) );
38
- }
39
 
40
- /**
41
- * Load JS and CSS
42
- * @param type $hook
43
- */
44
- function add_admin_scripts( $hook ) {
45
- if ( 'tools_page_widget-settings-import' != $hook || 'tools_page_widget-settings-export' != $hook ) {
46
- wp_register_style( 'widget_data_css', plugins_url( '/widget-data.css', __FILE__ ) );
47
- wp_enqueue_style( 'widget_data_css' );
48
- wp_register_script( 'widget_data', plugins_url( '/widget-data.js', __FILE__ ) );
49
- wp_enqueue_script( 'widget_data' );
50
- wp_localize_script( 'widget_data', 'widgets_url', get_admin_url( false, 'widgets.php' ) );
51
- }
52
  }
53
 
54
  /**
55
  * Register admin pages
56
  */
57
- function add_admin_menus() {
58
  // export
59
- $this->submenu_export = add_submenu_page( 'tools.php', 'Widget Settings Export', 'Widget Settings Export', 'administrator', 'widget-settings-export', array( &$this, 'export_settings_page' ) );
60
  //import
61
- $this->submenu_import = add_submenu_page( 'tools.php', 'Widget Settings Import', 'Widget Settings Import', 'administrator', 'widget-settings-import', array( &$this, 'import_settings_page' ) );
 
 
 
 
 
 
 
 
 
62
  }
63
 
64
  /**
65
  * HTML for export admin page
66
  */
67
- function export_settings_page() {
68
- $sidebar_widgets = $this->order_sidebar_widgets( wp_get_sidebars_widgets() );
69
  ?>
70
  <div class="widget-data export-widget-settings">
71
  <div class="wrap">
72
  <h2>Widget Setting Export</h2>
73
  <div id="notifier" style="display: none;"></div>
74
  <form action="" method="post" id="widget-export-settings">
75
- <div class="left">
76
- <button class="button-bottom button button-highlighted" type="button" name="SelectAllActive" id="SelectAllActive">Select All Active Widgets</button>
77
- <button class="button-bottom button button-highlighted" type="button" name="UnSelectAllActive" id="UnSelectAllActive">Un-Select All Active Widgets</button>
78
- </div>
79
- <div style="clear:both;"></div>
 
80
  <div class="title">
81
- <p class="widget-selection-error">Please select a widget to continue.</p>
82
  <h3>Sidebars</h3>
83
  <div class="clear"></div>
84
  </div>
@@ -88,7 +83,7 @@ class Widget_Data {
88
  if ( count( $widget_list ) == 0 )
89
  continue;
90
 
91
- $sidebar_info = $this->get_sidebar_info( $sidebar_name );
92
  ?>
93
 
94
  <div class="sidebar">
@@ -100,21 +95,16 @@ class Widget_Data {
100
 
101
  $widget_type = trim( substr( $widget, 0, strrpos( $widget, '-' ) ) );
102
  $widget_type_index = trim( substr( $widget, strrpos( $widget, '-' ) + 1 ) );
103
- $option_name = 'widget_' . $widget_type;
104
- $widget_options = get_option( $option_name );
105
- $widget_title = isset( $widget_options[$widget_type_index]['title'] ) ? $widget_options[$widget_type_index]['title'] : '';
106
  ?>
107
  <div class="import-form-row">
108
- <input class="<?php echo ($sidebar_name == 'wp_inactive_widgets') ? 'inactive' : 'active'; ?> widget-checkbox" type="checkbox" name="<?php echo $widget; ?>" id="meta_<?php echo $widget; ?>" />
109
- <label for="meta_<?php echo $widget; ?>">&nbsp;
110
- <?php
111
- echo ucfirst( $widget_type );
112
-
113
- if ( !empty( $widget_title ) ) :
114
- echo (' - ' . $widget_title);
115
- else :
116
- echo (' - ' . $widget_type_index);
117
- endif;
118
  ?>
119
  </label>
120
  </div>
@@ -123,9 +113,7 @@ class Widget_Data {
123
  </div> <!-- end sidebar -->
124
  <?php endforeach; ?>
125
  </div> <!-- end sidebars -->
126
- <div class="right">
127
- <button class="button-bottom button-primary" type="submit" name="export-widgets" id="export-widgets">Export Widget Settings</button>
128
- </div>
129
  </form>
130
  </div> <!-- end wrap -->
131
  </div> <!-- end export-widget-settings -->
@@ -136,30 +124,33 @@ class Widget_Data {
136
  * HTML for import admin page
137
  * @return type
138
  */
139
- function import_settings_page() {
140
  ?>
141
  <div class="widget-data import-widget-settings">
142
  <div class="wrap">
143
  <h2>Widget Setting Import</h2>
144
-
145
- <?php if ( isset( $_FILES['upload-file'] ) ) : ?>
146
  <div id="notifier" style="display: none;"></div>
147
  <div class="import-wrapper">
148
- <div class="left">
149
- <button class="button-bottom button button-highlighted" type="button" name="SelectAllActive" id="SelectAllActive">Select All Active Widgets</button>
150
- <button class="button-bottom button button-highlighted" type="button" name="UnSelectAllActive" id="UnSelectAllActive">Un-Select All Active Widgets</button>
151
- </div>
152
- <div style="clear:both;"></div>
153
  <form action="" id="import-widget-data" method="post">
154
- <?php
155
- $json = $this->get_widget_settings_json();
156
- $json_data = json_decode( $json[0], true );
157
- $json_file = $json[1];
158
-
159
- if ( !$json_data ) {
160
- return;
161
- }
 
 
 
162
  ?>
 
 
163
  <div class="title">
164
  <p class="widget-selection-error">Please select a widget to continue.</p>
165
  <h3>Sidebars</h3>
@@ -168,14 +159,12 @@ class Widget_Data {
168
  <div class="sidebars">
169
  <?php
170
  if ( isset( $json_data[0] ) ) :
171
- foreach ( $this->order_sidebar_widgets( $json_data[0] ) as $sidebar_name => $widget_list ) :
172
  if ( count( $widget_list ) == 0 ) {
173
  continue;
174
  }
175
- $sidebar_info = $this->get_sidebar_info( $sidebar_name );
176
- ?>
177
-
178
- <?php if ( $sidebar_info ) : ?>
179
  <div class="sidebar">
180
  <h4><?php echo $sidebar_info['name']; ?></h4>
181
 
@@ -186,24 +175,25 @@ class Widget_Data {
186
 
187
  $widget_type = trim( substr( $widget, 0, strrpos( $widget, '-' ) ) );
188
  $widget_type_index = trim( substr( $widget, strrpos( $widget, '-' ) + 1 ) );
189
- $option_name = 'widget_' . $widget_type;
190
- $widget_type_options = $this->get_option_from_array( $widget_type, $json_data[1] );
191
- if ( $widget_type_options ) :
192
- $widget_title = isset( $widget_type_options[$widget_type_index]['title'] ) ? $widget_type_options[$widget_type_index]['title'] : '';
193
- $widget_options = $widget_type_options[$widget_type_index];
194
- endif;
 
 
 
 
 
195
  ?>
196
  <div class="import-form-row">
197
- <input class="<?php echo ($sidebar_name == 'wp_inactive_widgets') ? 'inactive' : 'active'; ?> widget-checkbox" type="checkbox" name="widgets[<?php echo $widget_type; ?>][<?php echo $widget_type_index; ?>]" id="meta_<?php echo $widget; ?>" />
198
- <label for="meta_<?php echo $widget; ?>">&nbsp;
199
- <?php
200
- echo ucfirst( $widget_type );
201
-
202
- if ( !empty( $widget_title ) ) :
203
- echo (' - ' . $widget_title);
204
- else :
205
- echo (' - ' . $widget_type_index);
206
- endif;
207
  ?>
208
  </label>
209
  </div>
@@ -213,26 +203,19 @@ class Widget_Data {
213
  <?php endif; ?>
214
  <?php endforeach; ?>
215
  <?php endif; ?>
216
- <input type="hidden" name="import_file" value="<?php echo $json_file; ?>"/>
217
- <input type="hidden" name="action" value="widget_import_submit"/>
218
  </div> <!-- end sidebars -->
219
- <div class="right">
220
- <button class="button-bottom button-primary" type="submit" name="import-widgets" id="import-widgets">Import Widget Settings</button>
221
- </div>
222
  </form>
223
  </div>
224
  <?php else : ?>
225
  <form action="" id="upload-widget-data" method="post" enctype="multipart/form-data">
226
  <p>Select the file that contains widget settings</p>
227
- <div id="output-text" style="float:left;"></div>
228
- <label>
229
- <input type="file" name="upload-file" id="upload-file" size="40" />
230
- <button id="upload-button" class="button-secondary">Select a file</button>
231
- </label>
232
- <div style="clear:both;"></div>
233
- <div class="block">
234
- <button type="submit" name="button-upload" id="button-upload" class="button">Show Widget Settings</button>
235
- </div>
236
  </form>
237
  <?php endif; ?>
238
  </div> <!-- end wrap -->
@@ -245,7 +228,7 @@ class Widget_Data {
245
  * @param array $posted_array
246
  * @return string
247
  */
248
- function parse_export_data( $posted_array ) {
249
  $sidebars_array = get_option( 'sidebars_widgets' );
250
  $sidebar_export = array( );
251
  foreach ( $sidebars_array as $sidebar => $widgets ) {
@@ -270,13 +253,14 @@ class Widget_Data {
270
  $widget_val = get_option( 'widget_' . $widget['type'] );
271
  $multiwidget_val = $widget_val['_multiwidget'];
272
  $widgets_array[$widget['type']][$widget['type-index']] = $widget_val[$widget['type-index']];
273
- if ( isset( $widgets_array[$widget['type']]['_multiwidget'] ) ) {
274
  unset( $widgets_array[$widget['type']]['_multiwidget'] );
275
- }
276
  $widgets_array[$widget['type']]['_multiwidget'] = $multiwidget_val;
277
  }
278
  unset( $widgets_array['export'] );
279
  $export_array = array( $sidebar_export, $widgets_array );
 
280
  $json = json_encode( $export_array );
281
  return $json;
282
  }
@@ -285,7 +269,7 @@ class Widget_Data {
285
  * Import widgets
286
  * @param array $import_array
287
  */
288
- function parse_import_data( $import_array ) {
289
  $sidebars_data = $import_array[0];
290
  $widget_data = $import_array[1];
291
  $current_sidebars = get_option( 'sidebars_widgets' );
@@ -299,10 +283,10 @@ class Widget_Data {
299
  $title = trim( substr( $import_widget, 0, strrpos( $import_widget, '-' ) ) );
300
  $index = trim( substr( $import_widget, strrpos( $import_widget, '-' ) + 1 ) );
301
  $current_widget_data = get_option( 'widget_' . $title );
302
- $new_widget_name = $this->get_new_widget_name( $title, $index );
303
  $new_index = trim( substr( $new_widget_name, strrpos( $new_widget_name, '-' ) + 1 ) );
304
 
305
- if ( is_array( $new_widgets[$title] ) ) {
306
  while ( array_key_exists( $new_index, $new_widgets[$title] ) ) {
307
  $new_index++;
308
  }
@@ -329,26 +313,26 @@ class Widget_Data {
329
 
330
  if ( isset( $new_widgets ) && isset( $current_sidebars ) ) {
331
  update_option( 'sidebars_widgets', $current_sidebars );
332
- foreach ( $new_widgets as $title => $content ) {
 
333
  update_option( 'widget_' . $title, $content );
334
- }
335
 
336
  return true;
337
- } else {
338
- return false;
339
  }
 
 
340
  }
341
 
342
  /**
343
  * Output the JSON for download
344
  */
345
- function export_widget_settings() {
346
  // @TODO check something better than just $_POST
347
- if ( $_POST ) {
348
  header( "Content-Description: File Transfer" );
349
  header( "Content-Disposition: attachment; filename=widget_data.json" );
350
  header( "Content-Type: application/octet-stream" );
351
- echo $json = $this->parse_export_data( $_POST );
352
  exit;
353
  }
354
  }
@@ -356,13 +340,26 @@ class Widget_Data {
356
  /**
357
  * Parse JSON import file and load
358
  */
359
- function widget_import_submit() {
360
- $widgets = $_POST['widgets'];
361
- $json_data = file_get_contents( $_POST['import_file'] );
 
 
 
 
 
 
 
 
 
 
 
 
 
362
  $json_data = json_decode( $json_data, true );
363
  $sidebar_data = $json_data[0];
364
  $widget_data = $json_data[1];
365
- foreach ( $sidebar_data as $title => &$sidebar ) {
366
  $count = count( $sidebar );
367
  for ( $i = 0; $i < $count; $i++ ) {
368
  $widget = array( );
@@ -376,43 +373,46 @@ class Widget_Data {
376
  }
377
 
378
  foreach ( $widgets as $widget_title => $widget_value ) {
379
- foreach ( $widget_value as $k => $v ) {
380
- $widgets[$widget_title][$k] = $widget_data[$widget_title][$k];
381
  }
382
  }
383
 
384
- $sidebar_data = array_filter( $sidebar_data );
385
- $new_array = array( $sidebar_data, $widgets );
386
- ini_set( 'display_errors', 0 );
387
- error_reporting( 0 );
388
- if ( $this->parse_import_data( $new_array ) ) {
389
- echo "SUCCESS";
390
- } else {
391
- echo "ERROR";
392
- }
393
 
394
- exit;
 
395
  }
396
 
397
  /**
398
  * Read uploaded JSON file
399
  * @return type
400
  */
401
- function get_widget_settings_json() {
402
- $widget_settings = $this->upload_widget_settings_file();
403
- $file_contents = file_get_contents( $widget_settings['file'] );
404
- return array( $file_contents, $widget_settings['file'] );
 
 
 
 
 
 
 
405
  }
406
 
407
  /**
408
  * Upload JSON file
409
  * @return boolean
410
  */
411
- function upload_widget_settings_file() {
412
- if ( isset( $_FILES['upload-file'] ) ) {
413
- $overrides = array( 'test_form' => false );
414
- $upload = wp_handle_upload( $_FILES['upload-file'], $overrides );
 
415
 
 
416
  return $upload;
417
  }
418
 
@@ -425,13 +425,13 @@ class Widget_Data {
425
  * @param string $widget_index
426
  * @return string
427
  */
428
- 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 $w ) {
434
- $all_widget_array[] = $w;
435
  }
436
  }
437
  }
@@ -442,65 +442,33 @@ class Widget_Data {
442
  return $new_widget_name;
443
  }
444
 
445
- /**
446
- *
447
- * @param string $option_name
448
- * @param array $array_options
449
- * @return boolean
450
- */
451
- function get_option_from_array( $option_name, $array_options ) {
452
- foreach ( $array_options as $name => $option ) {
453
- if ( $name == $option_name ) {
454
- return $option;
455
- }
456
- }
457
- return false;
458
- }
459
-
460
  /**
461
  *
462
  * @global type $wp_registered_sidebars
463
  * @param type $sidebar_id
464
  * @return boolean
465
  */
466
- function get_sidebar_info( $sidebar_id ) {
467
  global $wp_registered_sidebars;
468
 
469
  //since wp_inactive_widget is only used in widgets.php
470
- if ( $sidebar_id == 'wp_inactive_widgets' ) {
471
  return array( 'name' => 'Inactive Widgets', 'id' => 'wp_inactive_widgets' );
472
- }
473
 
474
  foreach ( $wp_registered_sidebars as $sidebar ) {
475
- if ( isset( $sidebar['id'] ) && $sidebar['id'] == $sidebar_id ) {
476
  return $sidebar;
477
- }
478
  }
479
 
480
  return false;
481
  }
482
 
483
- /**
484
- *
485
- * @global type $wp_registered_widgets
486
- * @param type $widget
487
- * @return boolean
488
- */
489
- function get_widget_info( $widget ) {
490
- global $wp_registered_widgets;
491
- if ( isset( $wp_registered_widgets[$widget] ) ) {
492
- return true;
493
- } else {
494
- return false;
495
- }
496
- }
497
-
498
  /**
499
  *
500
  * @param array $sidebar_widgets
501
  * @return type
502
  */
503
- function order_sidebar_widgets( $sidebar_widgets ) {
504
  $inactive_widgets = false;
505
 
506
  //seperate inactive widget sidebar from other sidebars so it can be moved to the end of the array, if it exists
@@ -518,11 +486,11 @@ class Widget_Data {
518
  * @param array $existing_mimes
519
  * @return string
520
  */
521
- function json_upload_mimes( $existing_mimes = array( ) ) {
522
  $existing_mimes['json'] = 'application/json';
523
  return $existing_mimes;
524
  }
525
 
526
  }
527
 
528
- add_action( 'init', create_function( '', 'new Widget_Data();' ) );
2
  /*
3
  Plugin Name: Widget Data - Setting Import/Export Plugin
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
 
11
  This program is free software: you can redistribute it and/or modify
12
  it under the terms of the GNU General Public License as published by
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>
83
  if ( count( $widget_list ) == 0 )
84
  continue;
85
 
86
+ $sidebar_info = self::get_sidebar_info( $sidebar_name );
87
  ?>
88
 
89
  <div class="sidebar">
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>
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 -->
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>
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
 
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>
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 -->
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 ) {
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
  }
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' );
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
  }
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
  }
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( );
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
 
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
  }
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
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' ) );