Widget Importer & Exporter - Version 1.5

Version Description

Download this release

Release Info

Developer stevengliebe
Plugin Icon 128x128 Widget Importer & Exporter
Version 1.5
Comparing to
See all releases

Code changes from version 1.4.5 to 1.5

css/style.css CHANGED
@@ -1,71 +1,112 @@
1
-
2
  /* Cell padding */
3
 
4
  #wie-import-results td {
5
- padding: 2px 30px 2px 0;
6
  }
7
 
8
  /* Sidebar name */
9
 
10
  .wie-import-results-sidebar-name {
11
- font-weight: bold;
12
  }
13
 
14
  /* Widget instance title */
15
 
16
  .wie-import-results-widget-title {
17
- font-style: italic;
18
  }
19
 
20
  /* Message (sidebar and widget) */
21
 
22
  .wie-import-results-sidebar .wie-import-results-message {
23
- font-weight: bold;
24
  }
25
 
26
  .wie-import-results-message-success {
27
- color: #1c8a1f;
28
  }
29
 
30
  .wie-import-results-message-warning {
31
- color: #eb860f;
32
  }
33
 
34
  .wie-import-results-message-error {
35
- color: #cc2626;
36
  }
37
 
38
  /* Empty row after each sidebar/widget set */
39
 
40
  .wie-import-results-space {
41
- height: 8px;
42
  }
43
 
44
- /* Box in footer */
45
 
46
  .wie-box {
47
- padding: 25px;
48
- border: 1px solid #e5e5e5;
49
- background-color: #fff;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  }
51
 
52
- p {
53
- margin-bottom: 18px;
54
- }
55
 
56
- p:last-child {
57
- margin-bottom: 0;
58
- }
 
59
 
60
- .wie-box h4 {
61
- margin-top: 0;
62
- }
63
 
64
- #wie-support-project {
65
- max-width: 560px;
66
- margin: 30px 0;
67
  }
68
 
69
- #wie-support-project .button {
70
- margin-right: 5px;
71
- }
 
 
 
 
 
 
 
 
 
 
1
  /* Cell padding */
2
 
3
  #wie-import-results td {
4
+ padding: 2px 30px 2px 0;
5
  }
6
 
7
  /* Sidebar name */
8
 
9
  .wie-import-results-sidebar-name {
10
+ font-weight: bold;
11
  }
12
 
13
  /* Widget instance title */
14
 
15
  .wie-import-results-widget-title {
16
+ font-style: italic;
17
  }
18
 
19
  /* Message (sidebar and widget) */
20
 
21
  .wie-import-results-sidebar .wie-import-results-message {
22
+ font-weight: bold;
23
  }
24
 
25
  .wie-import-results-message-success {
26
+ color: #1c8a1f;
27
  }
28
 
29
  .wie-import-results-message-warning {
30
+ color: #eb860f;
31
  }
32
 
33
  .wie-import-results-message-error {
34
+ color: #cc2626;
35
  }
36
 
37
  /* Empty row after each sidebar/widget set */
38
 
39
  .wie-import-results-space {
40
+ height: 8px;
41
  }
42
 
43
+ /* Project support box */
44
 
45
  .wie-box {
46
+ position: relative;
47
+ padding: 20px 24px;
48
+ border: 1px solid #e5e5e5;
49
+ background-color: #fff;
50
+ }
51
+
52
+ #wie-project {
53
+ max-width: 520px;
54
+ margin: 20px 0 30px 0;
55
+ }
56
+
57
+ #wie-project-logo {
58
+ position: relative;
59
+ top: -1px;
60
+ right: -1px;
61
+ margin-left: 20px;
62
+ margin-bottom: 15px;
63
+ float: right;
64
+ }
65
+
66
+ #wie-project p {
67
+ margin-top: 0;
68
+ margin-bottom: 18px;
69
+ }
70
+
71
+ #wie-project ul {
72
+ margin-bottom: 0;
73
+ }
74
+
75
+ #wie-host-line a {
76
+ font-weight: bold;
77
+ }
78
+
79
+ /* Help */
80
+
81
+ #wie-help {
82
+ font-style: italic;
83
  }
84
 
85
+ /* Notices */
 
 
86
 
87
+ #wie-notice-message {
88
+ display: inline-block;
89
+ width: calc( 100% - 125px );
90
+ }
91
 
92
+ #wie-notice-message a {
93
+ white-space: nowrap;
94
+ }
95
 
96
+ #wie-notice-remind {
97
+ display: inline-block;
98
+ float: right;
99
  }
100
 
101
+ @media only screen and (max-width: 400px) {
102
+
103
+ #wie-notice-message {
104
+ width: auto;
105
+ padding-right: 4px;
106
+ }
107
+
108
+ #wie-notice-remind {
109
+ float: none;
110
+ }
111
+
112
+ }
img/wp-ultimate-logo.png ADDED
Binary file
img/wp-ultimate-logo@2x.png ADDED
Binary file
includes/admin.php CHANGED
@@ -6,36 +6,64 @@
6
  *
7
  * @package Widget_Importer_Exporter
8
  * @subpackage Functions
9
- * @copyright Copyright (c) 2017, churchthemes.com
10
- * @link https://churchthemes.com/plugins/widget-importer-exporter
11
- * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
12
  * @since 1.4
13
  */
14
 
15
- // No direct access
16
- if ( ! defined( 'ABSPATH' ) ) exit;
 
 
17
 
18
  /**
19
- * Add plugin action link
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  *
21
  * Insert an "Import/Export" link into the plugin's action links (Plugin page's list)
22
  *
23
  * @since 1.4
24
- * @param array $links Existing action links
25
  * @return array Modified action links
26
  */
27
  function wie_add_plugin_action_link( $links ) {
28
 
29
- // If has permission
30
- if ( ! current_user_can( 'edit_theme_options' ) ) { // can manage Appearance > Widgets
31
- return false;
32
  }
33
 
34
  // Have links array?
35
  if ( is_array( $links ) ) {
36
 
37
- // Append "Settings" link
38
- $links[] = '<a href="' . esc_url( admin_url( 'tools.php?page=widget-importer-exporter' ) ) . '">' . esc_html( __( 'Import/Export', 'widget-importer-exporter' ) ) . '</a>';
 
 
 
 
39
 
40
  }
41
 
@@ -55,40 +83,41 @@ add_filter( 'plugin_action_links_' . plugin_basename( WIE_FILE ), 'wie_add_plugi
55
  */
56
  function wie_add_widgets_screen_link() {
57
 
58
- // Build link with same style as 'Manage with Live Preview'
59
  $link_html = sprintf(
60
  wp_kses(
61
  ' <a href="%1$s" class="page-title-action">%2$s</a>',
62
  array(
63
- 'a' => array( // link tag only
64
- 'href' => array(),
65
- 'class' => array()
66
- )
 
67
  )
68
  ),
69
  esc_url( admin_url( 'tools.php?page=widget-importer-exporter' ) ),
70
- esc_html( __( 'Import/Export', 'widget-importer-exporter' ) )
71
  );
72
 
73
- // Output JavaScript to insert link after 'Manage with Live Preview'
74
  ?>
75
 
76
  <script type="text/javascript">
77
 
78
- jQuery( document ).ready( function( $ ) {
79
 
80
- // Encode string for security
81
- var link_html = <?php echo wp_json_encode( $link_html ); ?>;
82
 
83
- // Insert after last button by title
84
- $( '.page-title-action' ).last().after( link_html );
85
 
86
- } );
87
 
88
  </script>
89
-
90
  <?php
91
 
92
  }
93
 
94
- add_action( 'admin_print_footer_scripts-widgets.php', 'wie_add_widgets_screen_link' ); // WP 4.6+
 
6
  *
7
  * @package Widget_Importer_Exporter
8
  * @subpackage Functions
9
+ * @copyright Copyright (c) 2017, WP Ultimate
10
+ * @link https://wpultimate.com/widget-importer-exporter
11
+ * @license GPLv2 or later
12
  * @since 1.4
13
  */
14
 
15
+ // No direct access.
16
+ if ( ! defined( 'ABSPATH' ) ) {
17
+ exit;
18
+ }
19
 
20
  /**
21
+ * Enqueue admin styles.
22
+ *
23
+ * @since 1.5
24
+ */
25
+ function wie_enqueue_styles() {
26
+
27
+ // Get current screen.
28
+ $screen = get_current_screen();
29
+
30
+ // Only on WIE and Dashboard screens.
31
+ if ( ! in_array( $screen->base, array( 'dashboard', 'tools_page_widget-importer-exporter' ), true ) ) {
32
+ return;
33
+ }
34
+
35
+ // Enqueue styles
36
+ wp_enqueue_style( 'wie-main', WIE_URL . '/' . WIE_CSS_DIR . '/style.css', false, WIE_VERSION ); // Bust cache on update.
37
+
38
+ }
39
+
40
+ add_action( 'admin_enqueue_scripts', 'wie_enqueue_styles' ); // admin-end only.
41
+
42
+ /**
43
+ * Add plugin action link.
44
  *
45
  * Insert an "Import/Export" link into the plugin's action links (Plugin page's list)
46
  *
47
  * @since 1.4
48
+ * @param array $links Existing action links.
49
  * @return array Modified action links
50
  */
51
  function wie_add_plugin_action_link( $links ) {
52
 
53
+ // If has permission.
54
+ if ( ! current_user_can( 'edit_theme_options' ) ) {
55
+ return array();
56
  }
57
 
58
  // Have links array?
59
  if ( is_array( $links ) ) {
60
 
61
+ // Append "Settings" link.
62
+ $links[] = sprintf(
63
+ '<a href="%1$s">%2$s</a>',
64
+ esc_url( admin_url( 'tools.php?page=widget-importer-exporter' ) ),
65
+ esc_html__( 'Import/Export', 'widget-importer-exporter' )
66
+ );
67
 
68
  }
69
 
83
  */
84
  function wie_add_widgets_screen_link() {
85
 
86
+ // Build link with same style as 'Manage with Live Preview'.
87
  $link_html = sprintf(
88
  wp_kses(
89
  ' <a href="%1$s" class="page-title-action">%2$s</a>',
90
  array(
91
+ // Link tag only.
92
+ 'a' => array(
93
+ 'href' => array(),
94
+ 'class' => array(),
95
+ ),
96
  )
97
  ),
98
  esc_url( admin_url( 'tools.php?page=widget-importer-exporter' ) ),
99
+ esc_html__( 'Import/Export', 'widget-importer-exporter' )
100
  );
101
 
102
+ // Output JavaScript to insert link after 'Manage with Live Preview'.
103
  ?>
104
 
105
  <script type="text/javascript">
106
 
107
+ jQuery( document ).ready( function ( $ ) {
108
 
109
+ // Encode string for security
110
+ var link_html = <?php echo wp_json_encode( $link_html ); ?>;
111
 
112
+ // Insert after last button by title
113
+ $( '.page-title-action' ).last().after( link_html );
114
 
115
+ } );
116
 
117
  </script>
 
118
  <?php
119
 
120
  }
121
 
122
+ // WP 4.6+.
123
+ add_action( 'admin_print_footer_scripts-widgets.php', 'wie_add_widgets_screen_link' );
includes/export.php CHANGED
@@ -4,14 +4,16 @@
4
  *
5
  * @package Widget_Importer_Exporter
6
  * @subpackage Functions
7
- * @copyright Copyright (c) 2013, churchthemes.com
8
- * @link https://churchthemes.com/plugins/widget-importer-exporter
9
- * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
10
  * @since 0.1
11
  */
12
 
13
- // No direct access
14
- if ( ! defined( 'ABSPATH' ) ) exit;
 
 
15
 
16
  /**
17
  * Generate export data
@@ -21,26 +23,28 @@ if ( ! defined( 'ABSPATH' ) ) exit;
21
  */
22
  function wie_generate_export_data() {
23
 
24
- // Get all available widgets site supports
25
  $available_widgets = wie_available_widgets();
26
 
27
- // Get all widget instances for each widget
28
  $widget_instances = array();
 
 
29
  foreach ( $available_widgets as $widget_data ) {
30
 
31
- // Get all instances for this ID base
32
  $instances = get_option( 'widget_' . $widget_data['id_base'] );
33
 
34
- // Have instances
35
  if ( ! empty( $instances ) ) {
36
 
37
- // Loop instances
38
  foreach ( $instances as $instance_id => $instance_data ) {
39
 
40
- // Key is ID (not _multiwidget)
41
  if ( is_numeric( $instance_id ) ) {
42
  $unique_instance_id = $widget_data['id_base'] . '-' . $instance_id;
43
- $widget_instances[$unique_instance_id] = $instance_data;
44
  }
45
 
46
  }
@@ -49,29 +53,29 @@ function wie_generate_export_data() {
49
 
50
  }
51
 
52
- // Gather sidebars with their widget instances
53
- $sidebars_widgets = get_option( 'sidebars_widgets' ); // get sidebars and their unique widgets IDs
54
  $sidebars_widget_instances = array();
55
  foreach ( $sidebars_widgets as $sidebar_id => $widget_ids ) {
56
 
57
- // Skip inactive widgets
58
- if ( 'wp_inactive_widgets' == $sidebar_id ) {
59
  continue;
60
  }
61
 
62
- // Skip if no data or not an array (array_version)
63
  if ( ! is_array( $widget_ids ) || empty( $widget_ids ) ) {
64
  continue;
65
  }
66
 
67
- // Loop widget IDs for this sidebar
68
  foreach ( $widget_ids as $widget_id ) {
69
 
70
  // Is there an instance for this widget ID?
71
- if ( isset( $widget_instances[$widget_id] ) ) {
72
 
73
- // Add to array
74
- $sidebars_widget_instances[$sidebar_id][$widget_id] = $widget_instances[$widget_id];
75
 
76
  }
77
 
@@ -79,13 +83,13 @@ function wie_generate_export_data() {
79
 
80
  }
81
 
82
- // Filter pre-encoded data
83
  $data = apply_filters( 'wie_unencoded_export_data', $sidebars_widget_instances );
84
 
85
- // Encode the data for file contents
86
- $encoded_data = json_encode( $data );
87
 
88
- // Return contents
89
  return apply_filters( 'wie_generate_export_data', $encoded_data );
90
 
91
  }
@@ -101,24 +105,27 @@ function wie_generate_export_data() {
101
  */
102
  function wie_send_export_file() {
103
 
104
- // Export requested
105
  if ( ! empty( $_GET['export'] ) ) {
106
 
 
 
 
107
  // Build filename
108
  // Single Site: yoursite.com-widgets.wie
109
- // Multisite: site.multisite.com-widgets.wie or multisite.com-site-widgets.wie
110
  $site_url = site_url( '', 'http' );
111
- $site_url = trim( $site_url, '/\\' ); // remove trailing slash
112
- $filename = str_replace( 'http://', '', $site_url ); // remove http://
113
- $filename = str_replace( array( '/', '\\' ), '-', $filename ); // replace slashes with -
114
- $filename .= '-widgets.wie'; // append
115
  $filename = apply_filters( 'wie_export_filename', $filename );
116
 
117
- // Generate export file contents
118
  $file_contents = wie_generate_export_data();
119
  $filesize = strlen( $file_contents );
120
 
121
- // Headers to prompt "Save As"
122
  header( 'Content-Type: application/octet-stream' );
123
  header( 'Content-Disposition: attachment; filename=' . $filename );
124
  header( 'Expires: 0' );
@@ -126,14 +133,16 @@ function wie_send_export_file() {
126
  header( 'Pragma: public' );
127
  header( 'Content-Length: ' . $filesize );
128
 
129
- // Clear buffering just in case
 
130
  @ob_end_clean();
131
  flush();
132
 
133
- // Output file contents
 
134
  echo $file_contents;
135
 
136
- // Stop execution
137
  exit;
138
 
139
  }
4
  *
5
  * @package Widget_Importer_Exporter
6
  * @subpackage Functions
7
+ * @copyright Copyright (c) 2013 - 2017, WP Ultimate
8
+ * @link https://wpultimate.com/widget-importer-exporter
9
+ * @license GPLv2 or later
10
  * @since 0.1
11
  */
12
 
13
+ // No direct access.
14
+ if ( ! defined( 'ABSPATH' ) ) {
15
+ exit;
16
+ }
17
 
18
  /**
19
  * Generate export data
23
  */
24
  function wie_generate_export_data() {
25
 
26
+ // Get all available widgets site supports.
27
  $available_widgets = wie_available_widgets();
28
 
29
+ // Get all widget instances for each widget.
30
  $widget_instances = array();
31
+
32
+ // Loop widgets.
33
  foreach ( $available_widgets as $widget_data ) {
34
 
35
+ // Get all instances for this ID base.
36
  $instances = get_option( 'widget_' . $widget_data['id_base'] );
37
 
38
+ // Have instances.
39
  if ( ! empty( $instances ) ) {
40
 
41
+ // Loop instances.
42
  foreach ( $instances as $instance_id => $instance_data ) {
43
 
44
+ // Key is ID (not _multiwidget).
45
  if ( is_numeric( $instance_id ) ) {
46
  $unique_instance_id = $widget_data['id_base'] . '-' . $instance_id;
47
+ $widget_instances[ $unique_instance_id ] = $instance_data;
48
  }
49
 
50
  }
53
 
54
  }
55
 
56
+ // Gather sidebars with their widget instances.
57
+ $sidebars_widgets = get_option( 'sidebars_widgets' );
58
  $sidebars_widget_instances = array();
59
  foreach ( $sidebars_widgets as $sidebar_id => $widget_ids ) {
60
 
61
+ // Skip inactive widgets.
62
+ if ( 'wp_inactive_widgets' === $sidebar_id ) {
63
  continue;
64
  }
65
 
66
+ // Skip if no data or not an array (array_version).
67
  if ( ! is_array( $widget_ids ) || empty( $widget_ids ) ) {
68
  continue;
69
  }
70
 
71
+ // Loop widget IDs for this sidebar.
72
  foreach ( $widget_ids as $widget_id ) {
73
 
74
  // Is there an instance for this widget ID?
75
+ if ( isset( $widget_instances[ $widget_id ] ) ) {
76
 
77
+ // Add to array.
78
+ $sidebars_widget_instances[ $sidebar_id ][ $widget_id ] = $widget_instances[ $widget_id ];
79
 
80
  }
81
 
83
 
84
  }
85
 
86
+ // Filter pre-encoded data.
87
  $data = apply_filters( 'wie_unencoded_export_data', $sidebars_widget_instances );
88
 
89
+ // Encode the data for file contents.
90
+ $encoded_data = wp_json_encode( $data );
91
 
92
+ // Return contents.
93
  return apply_filters( 'wie_generate_export_data', $encoded_data );
94
 
95
  }
105
  */
106
  function wie_send_export_file() {
107
 
108
+ // Export requested.
109
  if ( ! empty( $_GET['export'] ) ) {
110
 
111
+ // Check referer before doing anything else.
112
+ check_admin_referer( 'wie_export', 'wie_export_nonce' );
113
+
114
  // Build filename
115
  // Single Site: yoursite.com-widgets.wie
116
+ // Multisite: site.multisite.com-widgets.wie or multisite.com-site-widgets.wie.
117
  $site_url = site_url( '', 'http' );
118
+ $site_url = trim( $site_url, '/\\' ); // Remove trailing slash.
119
+ $filename = str_replace( 'http://', '', $site_url ); // Remove http://.
120
+ $filename = str_replace( array( '/', '\\' ), '-', $filename ); // Replace slashes with - .
121
+ $filename .= '-widgets.wie'; // Append.
122
  $filename = apply_filters( 'wie_export_filename', $filename );
123
 
124
+ // Generate export file contents.
125
  $file_contents = wie_generate_export_data();
126
  $filesize = strlen( $file_contents );
127
 
128
+ // Headers to prompt "Save As".
129
  header( 'Content-Type: application/octet-stream' );
130
  header( 'Content-Disposition: attachment; filename=' . $filename );
131
  header( 'Expires: 0' );
133
  header( 'Pragma: public' );
134
  header( 'Content-Length: ' . $filesize );
135
 
136
+ // Clear buffering just in case.
137
+ // @codingStandardsIgnoreLine
138
  @ob_end_clean();
139
  flush();
140
 
141
+ // Output file contents.
142
+ // @todo export or verify the output data. Or simply ignore the line.
143
  echo $file_contents;
144
 
145
+ // Stop execution.
146
  exit;
147
 
148
  }
includes/import.php CHANGED
@@ -4,14 +4,16 @@
4
  *
5
  * @package Widget_Importer_Exporter
6
  * @subpackage Functions
7
- * @copyright Copyright (c) 2013 - 2017, churchthemes.com
8
- * @link https://churchthemes.com/plugins/widget-importer-exporter
9
- * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
10
  * @since 0.3
11
  */
12
 
13
- // No direct access
14
- if ( ! defined( 'ABSPATH' ) ) exit;
 
 
15
 
16
  /**
17
  * Upload import file
@@ -20,45 +22,54 @@ if ( ! defined( 'ABSPATH' ) ) exit;
20
  */
21
  function wie_upload_import_file() {
22
 
23
- // Check nonce for security since form was posted
24
- if ( ! empty( $_POST ) && ! empty( $_FILES['wie_import_file'] ) && check_admin_referer( 'wie_import', 'wie_import_nonce' ) ) { // check_admin_referer prints fail page and dies
 
25
 
26
- // Workaround for upload bug in WordPress 4.7.1
27
  // This will only be applied for WordPress 4.7.1. Other versions are not affected.
28
  add_filter( 'wp_check_filetype_and_ext', 'wie_disable_real_mime_check', 10, 4 );
29
 
30
- // Uploaded file
31
  $uploaded_file = $_FILES['wie_import_file'];
32
 
33
- // Check file type
34
- // This will also fire if no file uploaded
35
  $wp_filetype = wp_check_filetype_and_ext( $uploaded_file['tmp_name'], $uploaded_file['name'], false );
36
- if ( 'wie' != $wp_filetype['ext'] && ! wp_match_mime_types( 'wie', $wp_filetype['type'] ) ) {
 
37
  wp_die(
38
  wp_kses(
39
  __( 'You must upload a <b>.wie</b> file generated by this plugin.', 'widget-importer-exporter' ),
40
  array(
41
- 'b' => array()
42
  )
43
  ),
44
  '',
45
- array( 'back_link' => true )
 
 
46
  );
 
47
  }
48
 
49
  // Check and move file to uploads dir, get file data
50
- // Will show die with WP errors if necessary (file too large, quota exceeded, etc.)
51
- $overrides = array( 'test_form' => false );
52
- $file_data = wp_handle_upload( $uploaded_file, $overrides );
 
 
53
  if ( isset( $file_data['error'] ) ) {
54
  wp_die(
55
- $file_data['error'],
56
  '',
57
- array( 'back_link' => true )
 
 
58
  );
59
  }
60
 
61
- // Process import file
62
  wie_process_import_file( $file_data['file'] );
63
 
64
  }
@@ -73,7 +84,7 @@ add_action( 'load-tools_page_widget-importer-exporter', 'wie_upload_import_file'
73
  * This parses a file and triggers importation of its widgets.
74
  *
75
  * @since 0.3
76
- * @param string $file Path to .wie file uploaded
77
  * @global string $wie_import_results
78
  */
79
  function wie_process_import_file( $file ) {
@@ -82,22 +93,26 @@ function wie_process_import_file( $file ) {
82
 
83
  // File exists?
84
  if ( ! file_exists( $file ) ) {
 
85
  wp_die(
86
  esc_html__( 'Import file could not be found. Please try again.', 'widget-importer-exporter' ),
87
  '',
88
- array( 'back_link' => true )
 
 
89
  );
 
90
  }
91
 
92
- // Get file contents and decode
93
- $data = file_get_contents( $file );
94
  $data = json_decode( $data );
95
 
96
- // Delete import file
97
  unlink( $file );
98
 
99
  // Import the widget data
100
- // Make results available for display on import/export page
101
  $wie_import_results = wie_import_data( $data );
102
 
103
  }
@@ -107,7 +122,7 @@ function wie_process_import_file( $file ) {
107
  *
108
  * @since 0.4
109
  * @global array $wp_registered_sidebars
110
- * @param object $data JSON widget data from .wie file
111
  * @return array Results array
112
  */
113
  function wie_import_data( $data ) {
@@ -115,110 +130,116 @@ function wie_import_data( $data ) {
115
  global $wp_registered_sidebars;
116
 
117
  // Have valid data?
118
- // If no data or could not decode
119
  if ( empty( $data ) || ! is_object( $data ) ) {
 
120
  wp_die(
121
  esc_html__( 'Import data could not be read. Please try a different file.', 'widget-importer-exporter' ),
122
  '',
123
- array( 'back_link' => true )
 
 
124
  );
 
125
  }
126
 
127
- // Hook before import
128
  do_action( 'wie_before_import' );
129
  $data = apply_filters( 'wie_import_data', $data );
130
 
131
- // Get all available widgets site supports
132
  $available_widgets = wie_available_widgets();
133
 
134
- // Get all existing widget instances
135
  $widget_instances = array();
136
  foreach ( $available_widgets as $widget_data ) {
137
- $widget_instances[$widget_data['id_base']] = get_option( 'widget_' . $widget_data['id_base'] );
138
  }
139
 
140
- // Begin results
141
  $results = array();
142
 
143
- // Loop import data's sidebars
144
  foreach ( $data as $sidebar_id => $widgets ) {
145
 
146
- // Skip inactive widgets
147
- // (should not be in export file)
148
- if ( 'wp_inactive_widgets' == $sidebar_id ) {
149
  continue;
150
  }
151
 
152
- // Check if sidebar is available on this site
153
- // Otherwise add widgets to inactive, and say so
154
- if ( isset( $wp_registered_sidebars[$sidebar_id] ) ) {
155
- $sidebar_available = true;
156
- $use_sidebar_id = $sidebar_id;
157
  $sidebar_message_type = 'success';
158
- $sidebar_message = '';
159
  } else {
160
- $sidebar_available = false;
161
- $use_sidebar_id = 'wp_inactive_widgets'; // add to inactive if sidebar does not exist in theme
162
  $sidebar_message_type = 'error';
163
- $sidebar_message = esc_html__( 'Widget area does not exist in theme (using Inactive)', 'widget-importer-exporter' );
164
  }
165
 
166
  // Result for sidebar
167
- $results[$sidebar_id]['name'] = ! empty( $wp_registered_sidebars[$sidebar_id]['name'] ) ? $wp_registered_sidebars[$sidebar_id]['name'] : $sidebar_id; // sidebar name if theme supports it; otherwise ID
168
- $results[$sidebar_id]['message_type'] = $sidebar_message_type;
169
- $results[$sidebar_id]['message'] = $sidebar_message;
170
- $results[$sidebar_id]['widgets'] = array();
 
171
 
172
- // Loop widgets
173
  foreach ( $widgets as $widget_instance_id => $widget ) {
174
 
175
  $fail = false;
176
 
177
- // Get id_base (remove -# from end) and instance ID number
178
- $id_base = preg_replace( '/-[0-9]+$/', '', $widget_instance_id );
179
  $instance_id_number = str_replace( $id_base . '-', '', $widget_instance_id );
180
 
181
  // Does site support this widget?
182
- if ( ! $fail && ! isset( $available_widgets[$id_base] ) ) {
183
- $fail = true;
184
  $widget_message_type = 'error';
185
- $widget_message = esc_html__( 'Site does not support widget', 'widget-importer-exporter' ); // explain why widget not imported
186
  }
187
 
188
  // Filter to modify settings object before conversion to array and import
189
  // Leave this filter here for backwards compatibility with manipulating objects (before conversion to array below)
190
- // Ideally the newer wie_widget_settings_array below will be used instead of this
191
- $widget = apply_filters( 'wie_widget_settings', $widget ); // object
192
 
193
  // Convert multidimensional objects to multidimensional arrays
194
  // Some plugins like Jetpack Widget Visibility store settings as multidimensional arrays
195
  // Without this, they are imported as objects and cause fatal error on Widgets page
196
  // If this creates problems for plugins that do actually intend settings in objects then may need to consider other approach: https://wordpress.org/support/topic/problem-with-array-of-arrays
197
- // It is probably much more likely that arrays are used than objects, however
198
  $widget = json_decode( wp_json_encode( $widget ), true );
199
 
200
  // Filter to modify settings array
201
  // This is preferred over the older wie_widget_settings filter above
202
- // Do before identical check because changes may make it identical to end result (such as URL replacements)
203
  $widget = apply_filters( 'wie_widget_settings_array', $widget );
204
 
205
  // Does widget with identical settings already exist in same sidebar?
206
- if ( ! $fail && isset( $widget_instances[$id_base] ) ) {
207
 
208
- // Get existing widgets in this sidebar
209
  $sidebars_widgets = get_option( 'sidebars_widgets' );
210
- $sidebar_widgets = isset( $sidebars_widgets[$use_sidebar_id] ) ? $sidebars_widgets[$use_sidebar_id] : array(); // check Inactive if that's where will go
211
 
212
- // Loop widgets with ID base
213
- $single_widget_instances = ! empty( $widget_instances[$id_base] ) ? $widget_instances[$id_base] : array();
214
  foreach ( $single_widget_instances as $check_id => $check_widget ) {
215
 
216
  // Is widget in same sidebar and has identical settings?
217
- if ( in_array( "$id_base-$check_id", $sidebar_widgets ) && (array) $widget == $check_widget ) {
218
 
219
  $fail = true;
220
  $widget_message_type = 'warning';
221
- $widget_message = esc_html__( 'Widget already exists', 'widget-importer-exporter' ); // explain why widget not imported
 
 
222
 
223
  break;
224
 
@@ -228,50 +249,59 @@ function wie_import_data( $data ) {
228
 
229
  }
230
 
231
- // No failure
232
  if ( ! $fail ) {
233
 
234
  // Add widget instance
235
- $single_widget_instances = get_option( 'widget_' . $id_base ); // all instances for that widget ID base, get fresh every time
236
- $single_widget_instances = ! empty( $single_widget_instances ) ? $single_widget_instances : array( '_multiwidget' => 1 ); // start fresh if have to
237
- $single_widget_instances[] = $widget; // add it
238
-
239
- // Get the key it was given
240
- end( $single_widget_instances );
241
- $new_instance_id_number = key( $single_widget_instances );
242
-
243
- // If key is 0, make it 1
244
- // When 0, an issue can occur where adding a widget causes data from other widget to load, and the widget doesn't stick (reload wipes it)
245
- if ( '0' === strval( $new_instance_id_number ) ) {
246
- $new_instance_id_number = 1;
247
- $single_widget_instances[$new_instance_id_number] = $single_widget_instances[0];
248
- unset( $single_widget_instances[0] );
249
- }
 
 
 
250
 
251
- // Move _multiwidget to end of array for uniformity
252
- if ( isset( $single_widget_instances['_multiwidget'] ) ) {
253
- $multiwidget = $single_widget_instances['_multiwidget'];
254
- unset( $single_widget_instances['_multiwidget'] );
255
- $single_widget_instances['_multiwidget'] = $multiwidget;
256
- }
257
 
258
- // Update option with new widget
259
- update_option( 'widget_' . $id_base, $single_widget_instances );
260
 
261
- // Assign widget instance to sidebar
262
- $sidebars_widgets = get_option( 'sidebars_widgets' ); // which sidebars have which widgets, get fresh every time
 
263
 
264
  // Avoid rarely fatal error when the option is an empty string
265
- // https://github.com/churchthemes/widget-importer-exporter/pull/11
266
  if ( ! $sidebars_widgets ) {
267
  $sidebars_widgets = array();
268
  }
269
 
270
- $new_instance_id = $id_base . '-' . $new_instance_id_number; // use ID number from new widget instance
271
- $sidebars_widgets[$use_sidebar_id][] = $new_instance_id; // add new instance to sidebar
272
- update_option( 'sidebars_widgets', $sidebars_widgets ); // save the amended data
 
 
 
 
 
273
 
274
- // After widget import action
275
  $after_widget_import = array(
276
  'sidebar' => $use_sidebar_id,
277
  'sidebar_old' => $sidebar_id,
@@ -280,35 +310,35 @@ function wie_import_data( $data ) {
280
  'widget_id' => $new_instance_id,
281
  'widget_id_old' => $widget_instance_id,
282
  'widget_id_num' => $new_instance_id_number,
283
- 'widget_id_num_old' => $instance_id_number
284
  );
285
  do_action( 'wie_after_widget_import', $after_widget_import );
286
 
287
- // Success message
288
  if ( $sidebar_available ) {
289
  $widget_message_type = 'success';
290
- $widget_message = esc_html__( 'Imported', 'widget-importer-exporter' );
291
  } else {
292
  $widget_message_type = 'warning';
293
- $widget_message = esc_html__( 'Imported to Inactive', 'widget-importer-exporter' );
294
  }
295
 
296
  }
297
 
298
  // Result for widget instance
299
- $results[$sidebar_id]['widgets'][$widget_instance_id]['name'] = isset( $available_widgets[$id_base]['name'] ) ? $available_widgets[$id_base]['name'] : $id_base; // widget name or ID if name not available (not supported by site)
300
- $results[$sidebar_id]['widgets'][$widget_instance_id]['title'] = ! empty( $widget['title'] ) ? $widget['title'] : esc_html__( 'No Title', 'widget-importer-exporter' ); // show "No Title" if widget instance is untitled
301
- $results[$sidebar_id]['widgets'][$widget_instance_id]['message_type'] = $widget_message_type;
302
- $results[$sidebar_id]['widgets'][$widget_instance_id]['message'] = $widget_message;
303
 
304
  }
305
 
306
  }
307
 
308
- // Hook after import
309
  do_action( 'wie_after_import' );
310
 
311
- // Return results
312
  return apply_filters( 'wie_import_results', $results );
313
 
314
  }
4
  *
5
  * @package Widget_Importer_Exporter
6
  * @subpackage Functions
7
+ * @copyright Copyright (c) 2013 - 2017, WP Ultimate
8
+ * @link https://wpultimate.com/widget-importer-exporter
9
+ * @license GPLv2 or later
10
  * @since 0.3
11
  */
12
 
13
+ // No direct access.
14
+ if ( ! defined( 'ABSPATH' ) ) {
15
+ exit;
16
+ }
17
 
18
  /**
19
  * Upload import file
22
  */
23
  function wie_upload_import_file() {
24
 
25
+ // Check nonce for security since form was posted.
26
+ // check_admin_referer prints fail page and dies.
27
+ if ( ! empty( $_POST ) && ! empty( $_FILES['wie_import_file'] ) && check_admin_referer( 'wie_import', 'wie_import_nonce' ) ) {
28
 
29
+ // Workaround for upload bug in WordPress 4.7.1.
30
  // This will only be applied for WordPress 4.7.1. Other versions are not affected.
31
  add_filter( 'wp_check_filetype_and_ext', 'wie_disable_real_mime_check', 10, 4 );
32
 
33
+ // Uploaded file.
34
  $uploaded_file = $_FILES['wie_import_file'];
35
 
36
+ // Check file type.
37
+ // This will also fire if no file uploaded.
38
  $wp_filetype = wp_check_filetype_and_ext( $uploaded_file['tmp_name'], $uploaded_file['name'], false );
39
+ if ( 'wie' !== $wp_filetype['ext'] && ! wp_match_mime_types( 'wie', $wp_filetype['type'] ) ) {
40
+
41
  wp_die(
42
  wp_kses(
43
  __( 'You must upload a <b>.wie</b> file generated by this plugin.', 'widget-importer-exporter' ),
44
  array(
45
+ 'b' => array(),
46
  )
47
  ),
48
  '',
49
+ array(
50
+ 'back_link' => true,
51
+ )
52
  );
53
+
54
  }
55
 
56
  // Check and move file to uploads dir, get file data
57
+ // Will show die with WP errors if necessary (file too large, quota exceeded, etc.).
58
+ $file_data = wp_handle_upload( $uploaded_file, array(
59
+ 'test_form' => false,
60
+ ) );
61
+
62
  if ( isset( $file_data['error'] ) ) {
63
  wp_die(
64
+ esc_html( $file_data['error'] ),
65
  '',
66
+ array(
67
+ 'back_link' => true,
68
+ )
69
  );
70
  }
71
 
72
+ // Process import file.
73
  wie_process_import_file( $file_data['file'] );
74
 
75
  }
84
  * This parses a file and triggers importation of its widgets.
85
  *
86
  * @since 0.3
87
+ * @param string $file Path to .wie file uploaded.
88
  * @global string $wie_import_results
89
  */
90
  function wie_process_import_file( $file ) {
93
 
94
  // File exists?
95
  if ( ! file_exists( $file ) ) {
96
+
97
  wp_die(
98
  esc_html__( 'Import file could not be found. Please try again.', 'widget-importer-exporter' ),
99
  '',
100
+ array(
101
+ 'back_link' => true,
102
+ )
103
  );
104
+
105
  }
106
 
107
+ // Get file contents and decode.
108
+ $data = implode( '', file( $file ) );
109
  $data = json_decode( $data );
110
 
111
+ // Delete import file.
112
  unlink( $file );
113
 
114
  // Import the widget data
115
+ // Make results available for display on import/export page.
116
  $wie_import_results = wie_import_data( $data );
117
 
118
  }
122
  *
123
  * @since 0.4
124
  * @global array $wp_registered_sidebars
125
+ * @param object $data JSON widget data from .wie file.
126
  * @return array Results array
127
  */
128
  function wie_import_data( $data ) {
130
  global $wp_registered_sidebars;
131
 
132
  // Have valid data?
133
+ // If no data or could not decode.
134
  if ( empty( $data ) || ! is_object( $data ) ) {
135
+
136
  wp_die(
137
  esc_html__( 'Import data could not be read. Please try a different file.', 'widget-importer-exporter' ),
138
  '',
139
+ array(
140
+ 'back_link' => true,
141
+ )
142
  );
143
+
144
  }
145
 
146
+ // Hook before import.
147
  do_action( 'wie_before_import' );
148
  $data = apply_filters( 'wie_import_data', $data );
149
 
150
+ // Get all available widgets site supports.
151
  $available_widgets = wie_available_widgets();
152
 
153
+ // Get all existing widget instances.
154
  $widget_instances = array();
155
  foreach ( $available_widgets as $widget_data ) {
156
+ $widget_instances[ $widget_data['id_base'] ] = get_option( 'widget_' . $widget_data['id_base'] );
157
  }
158
 
159
+ // Begin results.
160
  $results = array();
161
 
162
+ // Loop import data's sidebars.
163
  foreach ( $data as $sidebar_id => $widgets ) {
164
 
165
+ // Skip inactive widgets (should not be in export file).
166
+ if ( 'wp_inactive_widgets' === $sidebar_id ) {
 
167
  continue;
168
  }
169
 
170
+ // Check if sidebar is available on this site.
171
+ // Otherwise add widgets to inactive, and say so.
172
+ if ( isset( $wp_registered_sidebars[ $sidebar_id ] ) ) {
173
+ $sidebar_available = true;
174
+ $use_sidebar_id = $sidebar_id;
175
  $sidebar_message_type = 'success';
176
+ $sidebar_message = '';
177
  } else {
178
+ $sidebar_available = false;
179
+ $use_sidebar_id = 'wp_inactive_widgets'; // Add to inactive if sidebar does not exist in theme.
180
  $sidebar_message_type = 'error';
181
+ $sidebar_message = esc_html__( 'Widget area does not exist in theme (using Inactive)', 'widget-importer-exporter' );
182
  }
183
 
184
  // Result for sidebar
185
+ // Sidebar name if theme supports it; otherwise ID.
186
+ $results[ $sidebar_id ]['name'] = ! empty( $wp_registered_sidebars[ $sidebar_id ]['name'] ) ? $wp_registered_sidebars[ $sidebar_id ]['name'] : $sidebar_id;
187
+ $results[ $sidebar_id ]['message_type'] = $sidebar_message_type;
188
+ $results[ $sidebar_id ]['message'] = $sidebar_message;
189
+ $results[ $sidebar_id ]['widgets'] = array();
190
 
191
+ // Loop widgets.
192
  foreach ( $widgets as $widget_instance_id => $widget ) {
193
 
194
  $fail = false;
195
 
196
+ // Get id_base (remove -# from end) and instance ID number.
197
+ $id_base = preg_replace( '/-[0-9]+$/', '', $widget_instance_id );
198
  $instance_id_number = str_replace( $id_base . '-', '', $widget_instance_id );
199
 
200
  // Does site support this widget?
201
+ if ( ! $fail && ! isset( $available_widgets[ $id_base ] ) ) {
202
+ $fail = true;
203
  $widget_message_type = 'error';
204
+ $widget_message = esc_html__( 'Site does not support widget', 'widget-importer-exporter' ); // Explain why widget not imported.
205
  }
206
 
207
  // Filter to modify settings object before conversion to array and import
208
  // Leave this filter here for backwards compatibility with manipulating objects (before conversion to array below)
209
+ // Ideally the newer wie_widget_settings_array below will be used instead of this.
210
+ $widget = apply_filters( 'wie_widget_settings', $widget );
211
 
212
  // Convert multidimensional objects to multidimensional arrays
213
  // Some plugins like Jetpack Widget Visibility store settings as multidimensional arrays
214
  // Without this, they are imported as objects and cause fatal error on Widgets page
215
  // If this creates problems for plugins that do actually intend settings in objects then may need to consider other approach: https://wordpress.org/support/topic/problem-with-array-of-arrays
216
+ // It is probably much more likely that arrays are used than objects, however.
217
  $widget = json_decode( wp_json_encode( $widget ), true );
218
 
219
  // Filter to modify settings array
220
  // This is preferred over the older wie_widget_settings filter above
221
+ // Do before identical check because changes may make it identical to end result (such as URL replacements).
222
  $widget = apply_filters( 'wie_widget_settings_array', $widget );
223
 
224
  // Does widget with identical settings already exist in same sidebar?
225
+ if ( ! $fail && isset( $widget_instances[ $id_base ] ) ) {
226
 
227
+ // Get existing widgets in this sidebar.
228
  $sidebars_widgets = get_option( 'sidebars_widgets' );
229
+ $sidebar_widgets = isset( $sidebars_widgets[ $use_sidebar_id ] ) ? $sidebars_widgets[ $use_sidebar_id ] : array(); // Check Inactive if that's where will go.
230
 
231
+ // Loop widgets with ID base.
232
+ $single_widget_instances = ! empty( $widget_instances[ $id_base ] ) ? $widget_instances[ $id_base ] : array();
233
  foreach ( $single_widget_instances as $check_id => $check_widget ) {
234
 
235
  // Is widget in same sidebar and has identical settings?
236
+ if ( in_array( "$id_base-$check_id", $sidebar_widgets, true ) && (array) $widget === $check_widget ) {
237
 
238
  $fail = true;
239
  $widget_message_type = 'warning';
240
+
241
+ // Explain why widget not imported.
242
+ $widget_message = esc_html__( 'Widget already exists', 'widget-importer-exporter' );
243
 
244
  break;
245
 
249
 
250
  }
251
 
252
+ // No failure.
253
  if ( ! $fail ) {
254
 
255
  // Add widget instance
256
+ $single_widget_instances = get_option( 'widget_' . $id_base ); // All instances for that widget ID base, get fresh every time.
257
+ $single_widget_instances = ! empty( $single_widget_instances ) ? $single_widget_instances : array(
258
+ '_multiwidget' => 1, // Start fresh if have to.
259
+ );
260
+ $single_widget_instances[] = $widget; // Add it.
261
+
262
+ // Get the key it was given.
263
+ end( $single_widget_instances );
264
+ $new_instance_id_number = key( $single_widget_instances );
265
+
266
+ // If key is 0, make it 1
267
+ // When 0, an issue can occur where adding a widget causes data from other widget to load,
268
+ // and the widget doesn't stick (reload wipes it).
269
+ if ( '0' === strval( $new_instance_id_number ) ) {
270
+ $new_instance_id_number = 1;
271
+ $single_widget_instances[ $new_instance_id_number ] = $single_widget_instances[0];
272
+ unset( $single_widget_instances[0] );
273
+ }
274
 
275
+ // Move _multiwidget to end of array for uniformity.
276
+ if ( isset( $single_widget_instances['_multiwidget'] ) ) {
277
+ $multiwidget = $single_widget_instances['_multiwidget'];
278
+ unset( $single_widget_instances['_multiwidget'] );
279
+ $single_widget_instances['_multiwidget'] = $multiwidget;
280
+ }
281
 
282
+ // Update option with new widget.
283
+ update_option( 'widget_' . $id_base, $single_widget_instances );
284
 
285
+ // Assign widget instance to sidebar.
286
+ // Which sidebars have which widgets, get fresh every time.
287
+ $sidebars_widgets = get_option( 'sidebars_widgets' );
288
 
289
  // Avoid rarely fatal error when the option is an empty string
290
+ // https://github.com/stevengliebe/widget-importer-exporter/pull/11.
291
  if ( ! $sidebars_widgets ) {
292
  $sidebars_widgets = array();
293
  }
294
 
295
+ // Use ID number from new widget instance.
296
+ $new_instance_id = $id_base . '-' . $new_instance_id_number;
297
+
298
+ // Add new instance to sidebar.
299
+ $sidebars_widgets[ $use_sidebar_id ][] = $new_instance_id;
300
+
301
+ // Save the amended data.
302
+ update_option( 'sidebars_widgets', $sidebars_widgets );
303
 
304
+ // After widget import action.
305
  $after_widget_import = array(
306
  'sidebar' => $use_sidebar_id,
307
  'sidebar_old' => $sidebar_id,
310
  'widget_id' => $new_instance_id,
311
  'widget_id_old' => $widget_instance_id,
312
  'widget_id_num' => $new_instance_id_number,
313
+ 'widget_id_num_old' => $instance_id_number,
314
  );
315
  do_action( 'wie_after_widget_import', $after_widget_import );
316
 
317
+ // Success message.
318
  if ( $sidebar_available ) {
319
  $widget_message_type = 'success';
320
+ $widget_message = esc_html__( 'Imported', 'widget-importer-exporter' );
321
  } else {
322
  $widget_message_type = 'warning';
323
+ $widget_message = esc_html__( 'Imported to Inactive', 'widget-importer-exporter' );
324
  }
325
 
326
  }
327
 
328
  // Result for widget instance
329
+ $results[ $sidebar_id ]['widgets'][ $widget_instance_id ]['name'] = isset( $available_widgets[ $id_base ]['name'] ) ? $available_widgets[ $id_base ]['name'] : $id_base; // Widget name or ID if name not available (not supported by site).
330
+ $results[ $sidebar_id ]['widgets'][ $widget_instance_id ]['title'] = ! empty( $widget['title'] ) ? $widget['title'] : esc_html__( 'No Title', 'widget-importer-exporter' ); // Show "No Title" if widget instance is untitled.
331
+ $results[ $sidebar_id ]['widgets'][ $widget_instance_id ]['message_type'] = $widget_message_type;
332
+ $results[ $sidebar_id ]['widgets'][ $widget_instance_id ]['message'] = $widget_message;
333
 
334
  }
335
 
336
  }
337
 
338
+ // Hook after import.
339
  do_action( 'wie_after_import' );
340
 
341
+ // Return results.
342
  return apply_filters( 'wie_import_results', $results );
343
 
344
  }
includes/mime-types.php CHANGED
@@ -4,14 +4,16 @@
4
  *
5
  * @package Widget_Importer_Exporter
6
  * @subpackage Functions
7
- * @copyright Copyright (c) 2013 - 2017, churchthemes.com
8
- * @link https://churchthemes.com/plugins/widget-importer-exporter
9
- * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
10
  * @since 0.1
11
  */
12
 
13
- // No direct access
14
- if ( ! defined( 'ABSPATH' ) ) exit;
 
 
15
 
16
  /**
17
  * Add mime type for upload
@@ -19,7 +21,7 @@ if ( ! defined( 'ABSPATH' ) ) exit;
19
  * Make sure the WordPress install will accept .wie uploads.
20
  *
21
  * @since 0.1
22
- * @param array $mime_types Currently uploadable mime types
23
  * @return array Mime types with additions
24
  */
25
  function wie_add_mime_types( $mime_types ) {
@@ -38,26 +40,27 @@ add_filter( 'upload_mimes', 'wie_add_mime_types' );
38
  * This is a workaround for a WordPress 4.7.1 bug affecting uploads. Other versions not affected.
39
  * This workaround will only take effect on installs of 4.7.1 and only during import.
40
  *
41
- * This is called in includes/import.php by wie_upload_import_file() so that it only happens during upload via this plugin.
42
- * add_filter( 'wp_check_filetype_and_ext', 'wie_disable_real_mime_check', 10, 4 );
43
  *
44
- * Based on the Disable Real MIME Check plugin by Sergey Biryukov: https://wordpress.org/plugins/disable-real-mime-check/
45
- * More information: https://wordpress.org/support/topic/solution-for-wp-4-7-1-bug-causing-you-must-upload-a-wie-file-generated-by/
 
46
  */
47
  function wie_disable_real_mime_check( $data, $file, $filename, $mimes ) {
48
 
49
  $wp_version = get_bloginfo( 'version' );
50
 
51
- // WordPress 4.7.1 - 4.7.3 are affected only
52
- // 4.7.2 and 4.7.3 were rushed out as security updates without the upload bug being fixed
53
- if ( ! in_array( $wp_version, array( '4.7.1', '4.7.2', '4.7.3' ) ) ) {
54
  return $data;
55
  }
56
 
57
  $wp_filetype = wp_check_filetype( $filename, $mimes );
58
 
59
- $ext = $wp_filetype['ext'];
60
- $type = $wp_filetype['type'];
61
  $proper_filename = $data['proper_filename'];
62
 
63
  return compact( 'ext', 'type', 'proper_filename' );
4
  *
5
  * @package Widget_Importer_Exporter
6
  * @subpackage Functions
7
+ * @copyright Copyright (c) 2013 - 2017, WP Ultimate
8
+ * @link https://wpultimate.com/widget-importer-exporter
9
+ * @license GPLv2 or later
10
  * @since 0.1
11
  */
12
 
13
+ // No direct access.
14
+ if ( ! defined( 'ABSPATH' ) ) {
15
+ exit;
16
+ }
17
 
18
  /**
19
  * Add mime type for upload
21
  * Make sure the WordPress install will accept .wie uploads.
22
  *
23
  * @since 0.1
24
+ * @param array $mime_types Currently uploadable mime types.
25
  * @return array Mime types with additions
26
  */
27
  function wie_add_mime_types( $mime_types ) {
40
  * This is a workaround for a WordPress 4.7.1 bug affecting uploads. Other versions not affected.
41
  * This workaround will only take effect on installs of 4.7.1 and only during import.
42
  *
43
+ * This is called in includes/import.php by wie_upload_import_file() so that it only happens during upload via this
44
+ * plugin. add_filter( 'wp_check_filetype_and_ext', 'wie_disable_real_mime_check', 10, 4 );
45
  *
46
+ * Based on the Disable Real MIME Check plugin by Sergey Biryukov:
47
+ * https://wordpress.org/plugins/disable-real-mime-check/ More information:
48
+ * https://wordpress.org/support/topic/solution-for-wp-4-7-1-bug-causing-you-must-upload-a-wie-file-generated-by/
49
  */
50
  function wie_disable_real_mime_check( $data, $file, $filename, $mimes ) {
51
 
52
  $wp_version = get_bloginfo( 'version' );
53
 
54
+ // WordPress 4.7.1 - 4.7.3 are affected only.
55
+ // 4.7.2 and 4.7.3 were rushed out as security updates without the upload bug being fixed.
56
+ if ( ! in_array( $wp_version, array( '4.7.1', '4.7.2', '4.7.3' ), true ) ) {
57
  return $data;
58
  }
59
 
60
  $wp_filetype = wp_check_filetype( $filename, $mimes );
61
 
62
+ $ext = $wp_filetype['ext'];
63
+ $type = $wp_filetype['type'];
64
  $proper_filename = $data['proper_filename'];
65
 
66
  return compact( 'ext', 'type', 'proper_filename' );
includes/notices.php ADDED
@@ -0,0 +1,378 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Notice Functions
4
+ *
5
+ * Admin notice functions.
6
+ *
7
+ * @package Widget_Importer_Exporter
8
+ * @subpackage Functions
9
+ * @copyright Copyright (c) 2017, WP Ultimate
10
+ * @link https://wpultimate.com/widget-importer-exporter
11
+ * @license GPLv2 or later
12
+ * @since 1.5
13
+ */
14
+
15
+ // No direct access.
16
+ if ( ! defined( 'ABSPATH' ) ) {
17
+ exit;
18
+ }
19
+
20
+ /**
21
+ * Activate security notices.
22
+ *
23
+ * To Do: Make this into a class that other plugins can use similarly.
24
+ *
25
+ * @since 1.5
26
+ */
27
+ function wie_security_notices() {
28
+
29
+ $notices = array();
30
+
31
+ // Outdated PHP notice.
32
+ $notices[] = 'wie_php_notice';
33
+
34
+ // HTTP notice.
35
+ $notices[] = 'wie_http_notice';
36
+
37
+ // Filter notices.
38
+ $notices = apply_filters( 'wie_security_notices', $notices );
39
+
40
+ // Loop notices to activate.
41
+ foreach ( $notices as $notice ) {
42
+ add_action( 'admin_notices', $notice );
43
+ }
44
+
45
+ }
46
+
47
+ add_action( 'admin_init', 'wie_security_notices' );
48
+
49
+ /**
50
+ * Show security notice?
51
+ *
52
+ * Return true or false for a notice type if certain conditions are met.
53
+ *
54
+ * @since 1.5
55
+ * @param string $type php or http.
56
+ * @return bool True if notice should be shown.
57
+ */
58
+ function wie_show_security_notice( $type ) {
59
+
60
+ // Show unless there is reason not to.
61
+ $show = true;
62
+
63
+ // Prepare for "Remind Later" link.
64
+ $current_time = current_time( 'timestamp' );
65
+ $reminder_days = 7; // show notice X days after "Remind Later" is clicked.
66
+
67
+ // Get current screen.
68
+ $screen = get_current_screen();
69
+
70
+ // Only on WIE and Dashboard screens.
71
+ if ( ! in_array( $screen->base, array( 'dashboard', 'tools_page_widget-importer-exporter' ), true ) ) {
72
+ $show = false;
73
+ }
74
+
75
+ // Only if user is Administrator.
76
+ if ( ! current_user_can( 'administrator' ) ) {
77
+ $show = false;
78
+ }
79
+
80
+ // Type of notice.
81
+ $option_prefix = '';
82
+ if ( 'php' === $type ) {
83
+
84
+ // PHP version.
85
+ $php_version_used = phpversion();
86
+ $php_version_required = '5.6'; // notice shows if lower than this version.
87
+
88
+ // Only if PHP version is outdated.
89
+ if ( version_compare( $php_version_used, $php_version_required, '>=' ) ) {
90
+ $show = false;
91
+ }
92
+
93
+ // Set option prefix.
94
+ $option_prefix = 'wie_php_notice';
95
+
96
+ } elseif ( 'http' === $type ) {
97
+
98
+ // Only if HTTPS is not used.
99
+ // is_ssl() no reliable with load balancers so instead check if Settings > General is using an https URL.
100
+ if ( preg_match( '/^https:.*/', get_bloginfo( 'url' ) ) ) {
101
+ $show = false;
102
+ }
103
+
104
+ // Set option prefix.
105
+ $option_prefix = 'wie_http_notice';
106
+
107
+ } else { // invalid type.
108
+ $show = false;
109
+ }
110
+
111
+ // Only if not already dismissed.
112
+ if ( $option_prefix && get_option( $option_prefix . '_dismissed' ) ) {
113
+ $show = false;
114
+ }
115
+
116
+ // Only if X days has not passed since time "Remind Later" was clicked
117
+ $reminder_time = get_option( $option_prefix . '_reminder' ); // timestamp for moment "Remind Later" was set.
118
+ if ( $reminder_time ) { // Only check if a reminder was set.
119
+
120
+ $reminder_seconds = $reminder_days * DAY_IN_SECONDS; // Seconds to wait until notice shows again.
121
+ $reminder_time_end = $reminder_time + $reminder_seconds; // Timestamp that must be in past for notice to show again.
122
+
123
+ if ( $reminder_time && $current_time < $reminder_time_end ) {
124
+ $show = false;
125
+ }
126
+
127
+ }
128
+
129
+ return $show;
130
+
131
+ }
132
+
133
+ /**
134
+ * PHP outdated notice
135
+ *
136
+ * @since 1.5
137
+ */
138
+ function wie_php_notice() {
139
+
140
+ // Only on certain conditions.
141
+ if ( ! wie_show_security_notice( 'php' ) ) {
142
+ return;
143
+ }
144
+
145
+ // Output notice.
146
+ ?>
147
+
148
+ <div id="wie-security-notice" class="notice notice-warning is-dismissible" data-type="php">
149
+
150
+ <p>
151
+
152
+ <span id="wie-notice-message">
153
+
154
+ <?php
155
+ printf(
156
+ wp_kses(
157
+ /* translators: %1$s is PHP version used, %2$s is URL to guide with instructions for fixing */
158
+ __( '<b>PHP Security Warning:</b> Your version of PHP is %1$s which is outdated and insecure. <b><a href="%2$s" target="_blank">Fix This Now</a></b>', 'widget-importer-exporter' ),
159
+ array(
160
+ 'b' => array(),
161
+ 'a' => array(
162
+ 'href' => array(),
163
+ 'target' => array(),
164
+ 'id' => array(),
165
+ ),
166
+ )
167
+ ),
168
+ esc_html( phpversion() ),
169
+ 'https://wpultimate.com/update-php-wordpress'
170
+ );
171
+ ?>
172
+
173
+ </span>
174
+
175
+ <span id="wie-notice-remind">
176
+ <a href="#" id="wie-notice-remind-link">
177
+ <?php esc_html_e( 'Remind Later', 'widget-importer-exporter' ); ?>
178
+ </a>
179
+ </span>
180
+
181
+ </p>
182
+
183
+ </div>
184
+
185
+ <?php
186
+
187
+ }
188
+
189
+ /**
190
+ * HTTP notice
191
+ *
192
+ * @since 1.5
193
+ */
194
+ function wie_http_notice() {
195
+
196
+ // Only if showing a notice.
197
+ if ( ! wie_show_security_notice( 'http' ) ) {
198
+ return;
199
+ }
200
+
201
+ // Output notice.
202
+ ?>
203
+
204
+ <div id="wie-security-notice" class="notice notice-warning is-dismissible" data-type="http">
205
+
206
+ <p>
207
+
208
+ <span id="wie-notice-message">
209
+
210
+ <?php
211
+ printf(
212
+ wp_kses(
213
+ /* translators: %1$s is URL to guide with instructions for fixing */
214
+ __( '<b>HTTP Security Warning:</b> Your website is not using HTTPS/SSL. This is a security risk. <b><a href="%1$s" target="_blank">Fix This Now</a></b>', 'widget-importer-exporter' ),
215
+ array(
216
+ 'b' => array(),
217
+ 'a' => array(
218
+ 'href' => array(),
219
+ 'target' => array(),
220
+ 'id' => array(),
221
+ ),
222
+ )
223
+ ),
224
+ 'https://wpultimate.com/ssl-https-wordpress'
225
+ );
226
+ ?>
227
+
228
+ </span>
229
+
230
+ <span id="wie-notice-remind">
231
+ <a href="#" id="wie-notice-remind-link">
232
+ <?php esc_html_e( 'Remind Later', 'widget-importer-exporter' ); ?>
233
+ </a>
234
+ </span>
235
+
236
+ </p>
237
+
238
+ </div>
239
+
240
+ <?php
241
+
242
+ }
243
+
244
+ /**
245
+ * JavaScript for remembering notice was dismissed
246
+ *
247
+ * Since normally the dismiss button only closes notice for current page view.
248
+ * this uses AJAX to set an option so that the notice can be hidden indefinitely.
249
+ *
250
+ * @since 1.5
251
+ */
252
+ function wie_dismiss_notice_js() {
253
+
254
+ // Only when a notice is being shown.
255
+ if ( ! wie_show_security_notice( 'php' ) && ! wie_show_security_notice( 'http' ) ) {
256
+ return;
257
+ }
258
+
259
+ // Nonce.
260
+ $ajax_nonce = wp_create_nonce( 'wie_dismiss_notice' );
261
+
262
+ // JavaScript for detecting click on dismiss icon.
263
+ ?>
264
+
265
+ <script type="text/javascript">
266
+
267
+ jQuery( document ).ready( function( $ ) {
268
+
269
+ // Dismiss icon
270
+ $( document ).on( 'click', '#wie-security-notice .notice-dismiss', function() {
271
+
272
+ // Notice container
273
+ var $container = $( this ).parents( '#wie-security-notice' );
274
+
275
+ // Get data-type attribute
276
+ var type = $container.data( 'type' );
277
+
278
+ // Send request.
279
+ if ( 'php' === type || 'http' === type ) {
280
+
281
+ $.ajax( {
282
+ url: ajaxurl,
283
+ data: {
284
+ action: 'wie_dismiss_notice',
285
+ security: '<?php echo esc_js( $ajax_nonce ); ?>',
286
+ type: type,
287
+ },
288
+ } );
289
+
290
+ }
291
+
292
+ } );
293
+
294
+ // Remind later link
295
+ $( document ).on( 'click', '#wie-notice-remind-link', function() {
296
+
297
+ // Stop click to URL.
298
+ event.preventDefault();
299
+
300
+ // Notice container
301
+ var $container = $( this ).parents( '#wie-security-notice' );
302
+
303
+ // Get data-type attribute
304
+ var type = $container.data( 'type' );
305
+
306
+ // Send request.
307
+ if ( 'php' == type || 'http' == type ) {
308
+
309
+ $.ajax( {
310
+ url: ajaxurl,
311
+ data: {
312
+ action: 'wie_dismiss_notice',
313
+ security: '<?php echo esc_js( $ajax_nonce ); ?>',
314
+ type: type,
315
+ reminder: true,
316
+ },
317
+ } );
318
+
319
+ }
320
+
321
+ // Fade out notice.
322
+ $container.fadeOut( 'fast' );
323
+
324
+ } );
325
+
326
+ } );
327
+
328
+ </script>
329
+
330
+ <?php
331
+
332
+ }
333
+
334
+ // JavaScript for remembering notice was dismissed.
335
+ add_action( 'admin_print_footer_scripts', 'wie_dismiss_notice_js' );
336
+
337
+ /**
338
+ * Set option to prevent notice from showing again.
339
+ *
340
+ * This is called by AJAX in wie_dismiss_notice_js()
341
+ *
342
+ * @since 1.5
343
+ */
344
+ function wie_dismiss_notice() {
345
+
346
+ // Only if is AJAX request.
347
+ if ( ! ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
348
+ return;
349
+ }
350
+
351
+ // Check nonce.
352
+ check_ajax_referer( 'wie_dismiss_notice', 'security' );
353
+
354
+ // Only if user is Administrator.
355
+ if ( ! current_user_can( 'administrator' ) ) {
356
+ return;
357
+ }
358
+
359
+ // Get type.
360
+ if ( ! empty( $_GET['type'] ) && in_array( $_GET['type'], array( 'php', 'http' ), true ) ) {
361
+ $type = wp_unslash( $_GET['type'] );
362
+ } else {
363
+ return;
364
+ }
365
+
366
+ // Option prefix.
367
+ $option_prefix = 'wie_' . $type . '_notice';
368
+
369
+ // Update option so notice is not shown again.
370
+ if ( ! empty( $_GET['reminder'] ) ) {
371
+ update_option( $option_prefix . '_reminder', current_time( 'timestamp' ) );
372
+ } else {
373
+ update_option( $option_prefix . '_dismissed', '1' );
374
+ }
375
+
376
+ }
377
+
378
+ add_action( 'wp_ajax_wie_dismiss_notice', 'wie_dismiss_notice' );
includes/page.php CHANGED
@@ -4,48 +4,36 @@
4
  *
5
  * @package Widget_Importer_Exporter
6
  * @subpackage Functions
7
- * @copyright Copyright (c) 2013 - 2017, churchthemes.com
8
- * @link https://churchthemes.com/plugins/widget-importer-exporter
9
- * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
10
  * @since 0.1
11
  */
12
 
13
- // No direct access
14
- if ( ! defined( 'ABSPATH' ) ) exit;
 
 
15
 
16
  /**
17
  * Add import/export page under Tools
18
  *
19
- * Also enqueue Stylesheet for this page only.
20
- *
21
  * @since 0.1
22
  */
23
  function wie_add_import_export_page() {
24
 
25
- // Add page
26
  $page_hook = add_management_page(
27
- esc_html__( 'Widget Importer & Exporter', 'widget-importer-exporter' ), // page title
28
- esc_html__( 'Widget Importer & Exporter', 'widget-importer-exporter' ), // menu title
29
- 'edit_theme_options', // capability (can manage Appearance > Widgets)
30
- 'widget-importer-exporter', // menu slug
31
- 'wie_import_export_page_content' // callback for displaying page content
32
  );
33
 
34
- // Enqueue stylesheet
35
- add_action( 'admin_print_styles-' . $page_hook, 'wie_enqueue_styles' );
36
-
37
  }
38
 
39
- add_action( 'admin_menu', 'wie_add_import_export_page' ); // register post type
40
-
41
- /**
42
- * Enqueue stylesheets for import/export page
43
- *
44
- * @since 0.1
45
- */
46
- function wie_enqueue_styles() {
47
- wp_enqueue_style( 'wie-main', WIE_URL . '/' . WIE_CSS_DIR . '/style.css', false, WIE_VERSION ); // bust cache on update
48
- }
49
 
50
  /**
51
  * Import/export page content
@@ -55,54 +43,54 @@ function wie_enqueue_styles() {
55
  function wie_import_export_page_content() {
56
 
57
  ?>
58
-
59
  <div class="wrap">
60
 
61
- <?php screen_icon(); ?>
62
-
63
  <h2><?php esc_html_e( 'Widget Importer & Exporter', 'widget-importer-exporter' ); ?></h2>
64
 
65
  <?php
66
- // Show import results if have them
 
 
 
67
  if ( wie_have_import_results() ) {
68
 
69
  wie_show_import_results();
70
 
71
- wie_footer();
72
-
73
- return; // don't show content below
74
 
75
  }
 
76
  ?>
77
 
78
  <h3 class="title"><?php echo esc_html_x( 'Import Widgets', 'heading', 'widget-importer-exporter' ); ?></h3>
79
 
80
  <p>
 
81
  <?php
 
82
  echo wp_kses(
83
  __( 'Please select a <b>.wie</b> file generated by this plugin.', 'widget-importer-exporter' ),
84
  array(
85
- 'b' => array()
86
  )
87
  );
 
88
  ?>
 
89
  </p>
90
 
91
  <form method="post" enctype="multipart/form-data">
92
-
93
  <?php wp_nonce_field( 'wie_import', 'wie_import_nonce' ); ?>
94
-
95
- <input type="file" name="wie_import_file" id="wie-import-file" />
96
-
97
  <?php submit_button( esc_html_x( 'Import Widgets', 'button', 'widget-importer-exporter' ) ); ?>
98
-
99
  </form>
100
 
101
  <?php if ( ! empty( $wie_import_results ) ) : ?>
102
  <p id="wie-import-results">
103
- <?php echo $wie_import_results; ?>
104
  </p>
105
- <br />
106
  <?php endif; ?>
107
 
108
  <h3 class="title"><?php echo esc_html_x( 'Export Widgets', 'heading', 'widget-importer-exporter' ); ?></h3>
@@ -112,22 +100,24 @@ function wie_import_export_page_content() {
112
  echo wp_kses(
113
  __( 'Click below to generate a <b>.wie</b> file for all active widgets.', 'widget-importer-exporter' ),
114
  array(
115
- 'b' => array()
116
  )
117
  );
118
  ?>
119
  </p>
120
 
121
  <p class="submit">
122
- <a href="<?php echo esc_url( admin_url( basename( $_SERVER['PHP_SELF'] ) . '?page=' . $_GET['page'] . '&export=1' ) ); ?>" id="wie-export-button" class="button button-primary"><?php echo esc_html_x( 'Export Widgets', 'button', 'widget-importer-exporter' ); ?></a>
 
 
 
 
123
  </p>
124
 
125
  </div>
126
 
127
  <?php
128
 
129
- wie_footer();
130
-
131
  }
132
 
133
  /**
@@ -169,11 +159,12 @@ function wie_show_import_results() {
169
  <?php
170
  printf(
171
  wp_kses(
172
- __( 'You can manage your <a href="%s">Widgets</a> or <a href="%s">Go Back</a>.', 'widget-importer-exporter' ),
 
173
  array(
174
  'a' => array(
175
- 'href' => array()
176
- )
177
  )
178
  ),
179
  esc_url( admin_url( 'widgets.php' ) ),
@@ -185,36 +176,51 @@ function wie_show_import_results() {
185
  <table id="wie-import-results">
186
 
187
  <?php
188
- // Loop sidebars
189
  $results = $wie_import_results;
190
  foreach ( $results as $sidebar ) :
191
  ?>
192
 
193
  <tr class="wie-import-results-sidebar">
194
  <td colspan="2" class="wie-import-results-sidebar-name">
195
- <?php echo $sidebar['name']; // sidebar name if theme supports it; otherwise ID ?>
 
 
 
196
  </td>
197
- <td class="wie-import-results-sidebar-message wie-import-results-message wie-import-results-message-<?php echo $sidebar['message_type']; ?>">
198
- <?php echo $sidebar['message']; // sidebar may not exist in theme ?>
 
 
 
199
  </td>
200
  </tr>
201
 
202
  <?php
203
- // Loop widgets
204
  foreach ( $sidebar['widgets'] as $widget ) :
205
  ?>
206
 
207
- <tr class="wie-import-results-widget">
208
- <td class="wie-import-results-widget-name">
209
- <?php echo $widget['name']; // widget name or ID if name not available (not supported by site) ?>
210
- </td>
211
- <td class="wie-import-results-widget-title">
212
- <?php echo $widget['title']; // shows "No Title" if widget instance is untitled ?>
213
- </td>
214
- <td class="wie-import-results-widget-message wie-import-results-message wie-import-results-message-<?php echo $widget['message_type']; ?>">
215
- <?php echo $widget['message']; // sidebar may not exist in theme ?>
216
- </td>
217
- </tr>
 
 
 
 
 
 
 
 
 
218
 
219
  <?php endforeach; ?>
220
 
@@ -225,91 +231,102 @@ function wie_show_import_results() {
225
  <?php endforeach; ?>
226
 
227
  </table>
228
-
229
  <?php
230
-
231
  }
232
 
233
  /**
234
- * Show footer
235
  *
236
- * Outputs information on supporting the project and getting support
237
  */
238
- function wie_footer() {
239
-
240
- ?>
241
-
242
- <p id="wie-help">
243
 
244
- <?php
245
- printf(
246
- wp_kses(
247
- /* translators: %1$s is URL to support forum */
248
- __( '<b>Need Help?</b> Post your question in the plugin\'s <a href="%1$s" target="_blank">Support Forum</a>.', 'widget-importer-exporter' ),
249
- array(
250
- 'b' => array(),
251
- 'a' => array(
252
- 'href' => array(),
253
- 'target' => array(),
254
- ),
255
- )
256
- ),
257
- 'https://wordpress.org/support/plugin/widget-importer-exporter/'
258
- );
259
- ?>
260
 
261
- </p>
262
 
263
- <div id="wie-support-project" class="wie-box">
264
 
265
- <h4>Support This Project</h4>
 
 
266
 
267
  <p>
268
 
269
  <?php
270
- printf(
271
- wp_kses(
272
- __( 'Please be one of the special few to support this plugin with a gift or review. There are costs to cover with more than 1,000,000 free downloads and free support. <b>Thank you!</b>', 'widget-importer-exporter' ),
273
- array(
274
- 'b' => array(),
275
- )
276
- ),
277
- 'https://churchthemes.com/project-support/',
278
- 'https://wordpress.org/support/plugin/widget-importer-exporter/reviews/?filter=5'
279
  );
280
  ?>
281
 
282
  </p>
283
 
284
- <p>
285
- <a href="https://churchthemes.com/project-support/" class="button" target="_blank"><?php esc_html_e( 'Give $5 or More', 'widget-importer-exporter' ); ?></a>
286
- <a href="https://wordpress.org/support/plugin/widget-importer-exporter/reviews/?filter=5" class="button" target="_blank"><?php esc_html_e( 'Add Your Review', 'widget-importer-exporter' ); ?></a>
287
- </p>
288
-
289
- <p>
290
 
291
- <i>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
292
 
 
293
  <?php
294
  printf(
295
  wp_kses(
296
- __( 'Visit <a href="%1$s" target="_blank">churchthemes.com</a> and follow us on <a href="%2$s" target="_blank">Twitter</a> and <a href="%3$s" target="_blank">Facebook</a>', 'widget-importer-exporter' ),
 
297
  array(
 
298
  'a' => array(
299
- 'href' => array(),
300
  'target' => array(),
301
  ),
302
  )
303
  ),
304
- 'https://churchthemes.com',
305
- 'https://twitter.com/churchthemes',
306
- 'https://www.facebook.com/churchthemescom'
307
  );
308
  ?>
 
309
 
310
- </i>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
311
 
312
- </p>
313
 
314
  </div>
315
 
4
  *
5
  * @package Widget_Importer_Exporter
6
  * @subpackage Functions
7
+ * @copyright Copyright (c) 2013 - 2017, WP Ultimate
8
+ * @link https://wpultimate.com/widget-importer-exporter
9
+ * @license GPLv2 or later
10
  * @since 0.1
11
  */
12
 
13
+ // No direct access.
14
+ if ( ! defined( 'ABSPATH' ) ) {
15
+ exit;
16
+ }
17
 
18
  /**
19
  * Add import/export page under Tools
20
  *
 
 
21
  * @since 0.1
22
  */
23
  function wie_add_import_export_page() {
24
 
25
+ // Add page.
26
  $page_hook = add_management_page(
27
+ esc_html__( 'Widget Importer & Exporter', 'widget-importer-exporter' ), // Page title.
28
+ esc_html__( 'Widget Importer & Exporter', 'widget-importer-exporter' ), // Menu title.
29
+ 'edit_theme_options', // Capability (can manage Appearance > Widgets).
30
+ 'widget-importer-exporter', // Menu Slug.
31
+ 'wie_import_export_page_content' // Callback for displaying page content.
32
  );
33
 
 
 
 
34
  }
35
 
36
+ add_action( 'admin_menu', 'wie_add_import_export_page' );
 
 
 
 
 
 
 
 
 
37
 
38
  /**
39
  * Import/export page content
43
  function wie_import_export_page_content() {
44
 
45
  ?>
 
46
  <div class="wrap">
47
 
 
 
48
  <h2><?php esc_html_e( 'Widget Importer & Exporter', 'widget-importer-exporter' ); ?></h2>
49
 
50
  <?php
51
+
52
+ wie_header();
53
+
54
+ // Show import results if have them.
55
  if ( wie_have_import_results() ) {
56
 
57
  wie_show_import_results();
58
 
59
+ // Don't show content below.
60
+ return;
 
61
 
62
  }
63
+
64
  ?>
65
 
66
  <h3 class="title"><?php echo esc_html_x( 'Import Widgets', 'heading', 'widget-importer-exporter' ); ?></h3>
67
 
68
  <p>
69
+
70
  <?php
71
+
72
  echo wp_kses(
73
  __( 'Please select a <b>.wie</b> file generated by this plugin.', 'widget-importer-exporter' ),
74
  array(
75
+ 'b' => array(),
76
  )
77
  );
78
+
79
  ?>
80
+
81
  </p>
82
 
83
  <form method="post" enctype="multipart/form-data">
 
84
  <?php wp_nonce_field( 'wie_import', 'wie_import_nonce' ); ?>
85
+ <input type="file" name="wie_import_file" id="wie-import-file"/>
 
 
86
  <?php submit_button( esc_html_x( 'Import Widgets', 'button', 'widget-importer-exporter' ) ); ?>
 
87
  </form>
88
 
89
  <?php if ( ! empty( $wie_import_results ) ) : ?>
90
  <p id="wie-import-results">
91
+ <?php echo wp_kses_post( $wie_import_results ); ?>
92
  </p>
93
+ <br/>
94
  <?php endif; ?>
95
 
96
  <h3 class="title"><?php echo esc_html_x( 'Export Widgets', 'heading', 'widget-importer-exporter' ); ?></h3>
100
  echo wp_kses(
101
  __( 'Click below to generate a <b>.wie</b> file for all active widgets.', 'widget-importer-exporter' ),
102
  array(
103
+ 'b' => array(),
104
  )
105
  );
106
  ?>
107
  </p>
108
 
109
  <p class="submit">
110
+
111
+ <a href="<?php echo esc_url( admin_url( basename( $_SERVER['PHP_SELF'] ) . '?page=' . $_GET['page'] . '&export=1&wie_export_nonce=' . wp_create_nonce( 'wie_export' ) ) ); ?>" id="wie-export-button" class="button button-primary">
112
+ <?php echo esc_html_x( 'Export Widgets', 'button', 'widget-importer-exporter' ); ?>
113
+ </a>
114
+
115
  </p>
116
 
117
  </div>
118
 
119
  <?php
120
 
 
 
121
  }
122
 
123
  /**
159
  <?php
160
  printf(
161
  wp_kses(
162
+ /* translators: %1$s is URL for widgets screen, %2$s is URL to go back */
163
+ __( 'You can manage your <a href="%1$s">Widgets</a> or <a href="%2$s">Go Back</a>.', 'widget-importer-exporter' ),
164
  array(
165
  'a' => array(
166
+ 'href' => array(),
167
+ ),
168
  )
169
  ),
170
  esc_url( admin_url( 'widgets.php' ) ),
176
  <table id="wie-import-results">
177
 
178
  <?php
179
+ // Loop sidebars.
180
  $results = $wie_import_results;
181
  foreach ( $results as $sidebar ) :
182
  ?>
183
 
184
  <tr class="wie-import-results-sidebar">
185
  <td colspan="2" class="wie-import-results-sidebar-name">
186
+ <?php
187
+ // Sidebar name if theme supports it; otherwise ID.
188
+ echo esc_html( $sidebar['name'] );
189
+ ?>
190
  </td>
191
+ <td class="wie-import-results-sidebar-message wie-import-results-message wie-import-results-message-<?php echo esc_attr( $sidebar['message_type'] ); ?>">
192
+ <?php
193
+ // Sidebar may not exist in theme.
194
+ echo esc_html( $sidebar['message'] );
195
+ ?>
196
  </td>
197
  </tr>
198
 
199
  <?php
200
+ // Loop widgets.
201
  foreach ( $sidebar['widgets'] as $widget ) :
202
  ?>
203
 
204
+ <tr class="wie-import-results-widget">
205
+ <td class="wie-import-results-widget-name">
206
+ <?php
207
+ // Widget name or ID if name not available (not supported by site).
208
+ echo esc_html( $widget['name'] );
209
+ ?>
210
+ </td>
211
+ <td class="wie-import-results-widget-title">
212
+ <?php
213
+ // Shows "No Title" if widget instance is untitled.
214
+ echo esc_html( $widget['title'] );
215
+ ?>
216
+ </td>
217
+ <td class="wie-import-results-widget-message wie-import-results-message wie-import-results-message-<?php echo esc_attr( $widget['message_type'] ); ?>">
218
+ <?php
219
+ // Sidebar may not exist in theme.
220
+ echo esc_html( $widget['message'] );
221
+ ?>
222
+ </td>
223
+ </tr>
224
 
225
  <?php endforeach; ?>
226
 
231
  <?php endforeach; ?>
232
 
233
  </table>
 
234
  <?php
 
235
  }
236
 
237
  /**
238
+ * Show header
239
  *
240
+ * Outputs information on supporting the project
241
  */
242
+ function wie_header() {
 
 
 
 
243
 
244
+ // Logo URLs.
245
+ $img_dir_url = WIE_URL . '/' . WIE_IMG_DIR;
246
+ $logo_url = $img_dir_url . '/wp-ultimate-logo.png';
247
+ $logo_hidpi_url = $img_dir_url . '/wp-ultimate-logo@2x.png';
 
 
 
 
 
 
 
 
 
 
 
 
248
 
249
+ ?>
250
 
251
+ <div id="wie-project" class="wie-box">
252
 
253
+ <a href="https://wpultimate.com" target="_blank">
254
+ <img src="<?php echo esc_url( $logo_url ); ?>" srcset="<?php echo esc_url( $logo_url ); ?> 1x, <?php echo esc_url( $logo_hidpi_url ); ?> 2x" id="wie-project-logo" width="40" height="40" alt="<?php esc_attr_e( 'WP Ultimate Logo', 'widget-importer-exporter' ); ?>">
255
+ </a>
256
 
257
  <p>
258
 
259
  <?php
260
+ echo wp_kses(
261
+ __( '<b>Keep it Free</b> - There are costs to cover with 1,000,000+ downloads and free support. Keep this plugin going by trying our WordPress hosting.', 'widget-importer-exporter' ),
262
+ array(
263
+ 'b' => array(),
264
+ )
 
 
 
 
265
  );
266
  ?>
267
 
268
  </p>
269
 
270
+ <ul>
 
 
 
 
 
271
 
272
+ <li id="wie-host-line">
273
+ <?php
274
+ printf(
275
+ wp_kses(
276
+ /* translators: %1$s is URL to WP Ultimate */
277
+ __( '<a href="%1$s" target="_blank">Host with WP Ultimate</a> - Free trial. We\'ll move your site for free to make it easy.', 'widget-importer-exporter' ),
278
+ array(
279
+ 'b' => array(),
280
+ 'a' => array(
281
+ 'href' => array(),
282
+ 'target' => array(),
283
+ ),
284
+ )
285
+ ),
286
+ 'https://wpultimate.com/'
287
+ );
288
+ ?>
289
+ </li>
290
 
291
+ <li>
292
  <?php
293
  printf(
294
  wp_kses(
295
+ /* translators: %1$s is URL to add a review on WordPress.org */
296
+ __( '<a href="%1$s" target="_blank">Add Your Review</a> - Share your experience with other users.', 'widget-importer-exporter' ),
297
  array(
298
+ 'b' => array(),
299
  'a' => array(
300
+ 'href' => array(),
301
  'target' => array(),
302
  ),
303
  )
304
  ),
305
+ 'https://wordpress.org/support/plugin/widget-importer-exporter/reviews/?filter=5'
 
 
306
  );
307
  ?>
308
+ </li>
309
 
310
+ <li>
311
+ <?php
312
+ printf(
313
+ wp_kses(
314
+ /* translators: %1$s is URL to support forum on WordPress.org */
315
+ __( '<a href="%1$s" target="_blank">Get Support</a> - Need help? Post a question on the support forum.', 'widget-importer-exporter' ),
316
+ array(
317