Rara One Click Demo Import - Version 1.0.0

Version Description

Download this release

Release Info

Developer raratheme
Plugin Icon 128x128 Rara One Click Demo Import
Version 1.0.0
Comparing to
See all releases

Version 1.0.0

assets/css/style.css ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Overriding WordPress native styles */
2
+
3
+ .rrdi h2 {
4
+ text-align: inherit;
5
+ }
6
+
7
+ .rrdi h2:first-child,
8
+ .rrdi h3:first-child {
9
+ margin-top: 0;
10
+ }
11
+
12
+ .rrdi hr {
13
+ margin: 2.62em 0;
14
+ }
15
+
16
+ .feature-section + hr {
17
+ margin-top: 0;
18
+ }
19
+
20
+ #wpbody select {
21
+ height: auto;
22
+ padding: .62em;
23
+ line-height: inherit;
24
+ }
25
+
26
+ .rrdi .notice {
27
+ display: block !important;
28
+ margin-top: 1.4em;
29
+ margin-bottom: 0;
30
+ }
31
+
32
+ /* Plugin elements */
33
+
34
+ .RRDI__demo-import-files {
35
+ width: 100%;
36
+ }
37
+
38
+ .RRDI__demo-import-preview-image-message {
39
+ font-style: italic;
40
+ }
41
+
42
+ /* Plugin title */
43
+
44
+ .RRDI__title:before {
45
+ width: auto;
46
+ height: auto;
47
+ font-size: inherit;
48
+ }
49
+
50
+ /* Plugin intro text */
51
+
52
+ .RRDI__intro-text ul {
53
+ padding: 0 4%;
54
+ list-style-type: square;
55
+ }
56
+
57
+ /* Plugin multi select import and Plugin file upload containers */
58
+
59
+ .RRDI__file-upload,
60
+ .RRDI__multi-select-import,
61
+ .RRDI__demo-import-notice:not(:empty) {
62
+ padding: 4%;
63
+ margin: 1.62em 0;
64
+ background-color: #ffffff;
65
+ border: 1px solid #e5e5e5;
66
+ }
67
+
68
+ .RRDI__file-upload {
69
+ margin: 0;
70
+ margin-bottom: -1px;
71
+ }
72
+
73
+ .RRDI__file-upload span {
74
+ font-size: .81em;
75
+ font-weight: normal;
76
+ opacity: .66;
77
+ }
78
+
79
+ .RRDI__demo-import-notice:not(:empty) {
80
+ border: 0;
81
+ border-left: 4px solid #00a0d2;
82
+ -webkit-box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
83
+ box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
84
+ }
85
+
86
+ [dir="rtl"] .RRDI__demo-import-notice:not(:empty) {
87
+ border: 0;
88
+ border-right: 4px solid #00a0d2;
89
+ }
90
+
91
+ /* Plugin button */
92
+
93
+ .RRDI__button-container {
94
+ margin-top: 1.62em;
95
+ }
96
+
97
+ /* AJAX loader */
98
+
99
+ .RRDI__ajax-loader {
100
+ font-size: 1.5em;
101
+ display: none;
102
+ }
103
+
104
+ .RRDI__ajax-loader .spinner {
105
+ display: inline-block;
106
+ float: none;
107
+ visibility: visible;
108
+ margin-bottom: 6px;
109
+ }
assets/js/script.js ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery( function ( $ ) {
2
+
3
+ $( '.js-rrdi-import-data' ).on( 'click', function () {
4
+ // Reset response div content.
5
+ $( '.js-rrdi-ajax-response' ).empty();
6
+
7
+ // Prepare data for the AJAX call
8
+ var data = new FormData();
9
+ data.append( 'action', 'rrdi_import_demo_data' );
10
+ data.append( 'security', rrdi.ajax_nonce );
11
+ data.append( 'selected', $( '#RRDI__demo-import-files' ).val() );
12
+ if ( $('#RRDI__content-file-upload').length ) {
13
+ data.append( 'content_file', $('#RRDI__content-file-upload')[0].files[0] );
14
+ }
15
+ if ( $('#RRDI__widget-file-upload').length ) {
16
+ data.append( 'widget_file', $('#RRDI__widget-file-upload')[0].files[0] );
17
+ }
18
+ if ( $('#RRDI__customizer-file-upload').length ) {
19
+ data.append( 'customizer_file', $('#RRDI__customizer-file-upload')[0].files[0] );
20
+ }
21
+
22
+ // AJAX call to import everything (content, widgets, before/after setup)
23
+ ajaxCall( data );
24
+
25
+ });
26
+
27
+ function ajaxCall( data ) {
28
+ $.ajax({
29
+ method: 'POST',
30
+ url: rrdi.ajax_url,
31
+ data: data,
32
+ contentType: false,
33
+ processData: false,
34
+ beforeSend: function() {
35
+ $( '.js-rrdi-ajax-loader' ).show();
36
+ }
37
+ })
38
+ .done( function( response ) {
39
+
40
+ if ( 'undefined' !== typeof response.status && 'newAJAX' === response.status ) {
41
+ ajaxCall( data );
42
+ }
43
+ else if ( 'undefined' !== typeof response.message ) {
44
+ $( '.js-rrdi-ajax-response' ).append( '<p>' + response.message + '</p>' );
45
+ $( '.js-rrdi-ajax-loader' ).hide();
46
+ }
47
+ else {
48
+ $( '.js-rrdi-ajax-response' ).append( '<div class="notice notice-error is-dismissible"><p>' + response + '</p></div>' );
49
+ $( '.js-rrdi-ajax-loader' ).hide();
50
+ }
51
+ })
52
+ .fail( function( error ) {
53
+ $( '.js-rrdi-ajax-response' ).append( '<div class="notice notice-error is-dismissible"><p>Error: ' + error.statusText + ' (' + error.status + ')' + '</p></div>' );
54
+ $( '.js-rrdi-ajax-loader' ).hide();
55
+ });
56
+ }
57
+
58
+ // Switch preview images on select change event, but only if the img element .js-rrdi-preview-image exists.
59
+ // Also switch the import notice (if it exists).
60
+ $( '#RRDI__demo-import-files' ).on( 'change', function(){
61
+ if ( $( '.js-rrdi-preview-image' ).length ) {
62
+
63
+ // Attempt to change the image, else display message for missing image.
64
+ var currentFilePreviewImage = rrdi.import_files[ this.value ]['import_preview_image_url'] || '';
65
+ $( '.js-rrdi-preview-image' ).prop( 'src', currentFilePreviewImage );
66
+ $( '.js-rrdi-preview-image-message' ).html( '' );
67
+
68
+ if ( '' === currentFilePreviewImage ) {
69
+ $( '.js-rrdi-preview-image-message' ).html( rrdi.texts.missing_preview_image );
70
+ }
71
+ }
72
+
73
+ // Update import notice.
74
+ var currentImportNotice = rrdi.import_files[ this.value ]['import_notice'] || '';
75
+ $( '.js-rrdi-demo-import-notice' ).html( currentImportNotice );
76
+ });
77
+
78
+ });
includes/class-rrdi-customizer-option.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * A class that extends WP_Customize_Setting so we can access
4
+ * the protected updated method when importing options.
5
+ *
6
+ * Used in the Customizer importer.
7
+ *
8
+ * @since 1.1.1
9
+ * @package rara-demo-import
10
+ */
11
+
12
+ final class RRDI_Customizer_Option extends WP_Customize_Setting {
13
+
14
+ /**
15
+ * Import an option value for this setting.
16
+ *
17
+ * @since 1.1.1
18
+ * @param mixed $value The option value.
19
+ * @return void
20
+ */
21
+ public function import( $value ) {
22
+ $this->update( $value );
23
+ }
24
+ }
includes/class-rrdi-helpers.php ADDED
@@ -0,0 +1,610 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Static functions used in the rrdi plugin.
4
+ *
5
+ * @package rara-demo-import
6
+ */
7
+
8
+ /**
9
+ * Class with static helper functions.
10
+ */
11
+ class RRDI_Helpers {
12
+
13
+ /**
14
+ * Filter through the array of import files and get rid of those who do not comply.
15
+ *
16
+ * @param array $import_files list of arrays with import file details.
17
+ * @return array list of filtered arrays.
18
+ */
19
+ public static function validate_import_file_info( $import_files ) {
20
+ $filtered_import_file_info = array();
21
+
22
+ foreach ( $import_files as $import_file ) {
23
+ if ( self::is_import_file_info_format_correct( $import_file ) ) {
24
+ $filtered_import_file_info[] = $import_file;
25
+ }
26
+ }
27
+
28
+ return $filtered_import_file_info;
29
+ }
30
+
31
+
32
+ /**
33
+ * Helper function: a simple check for valid import file format.
34
+ *
35
+ * @param array $import_file_info array with import file details.
36
+ * @return boolean
37
+ */
38
+ private static function is_import_file_info_format_correct( $import_file_info ) {
39
+ if ( ( empty( $import_file_info['import_file_url'] ) && empty( $import_file_info['local_import_file'] ) ) || empty( $import_file_info['import_file_name'] ) ) {
40
+ return false;
41
+ }
42
+
43
+ return true;
44
+ }
45
+
46
+
47
+ /**
48
+ * Download import files. Content .xml and widgets .wie|.json files.
49
+ *
50
+ * @param array $import_file_info array with import file details.
51
+ * @param string $start_date string of date and time.
52
+ * @return array|WP_Error array of paths to the downloaded files or WP_Error object with error message.
53
+ */
54
+ public static function download_import_files( $import_file_info, $start_date = '' ) {
55
+
56
+ $downloaded_files = array();
57
+ $upload_dir = wp_upload_dir();
58
+ $upload_path = apply_filters( 'rrdi/upload_file_path', trailingslashit( $upload_dir['path'] ) );
59
+
60
+ // ----- Set content file path -----
61
+ // Check if 'import_file_url' is not defined. That would mean a local file.
62
+ if ( empty( $import_file_info['import_file_url'] ) ) {
63
+ if ( file_exists( $import_file_info['local_import_file'] ) ) {
64
+ $downloaded_files['content'] = $import_file_info['local_import_file'];
65
+ }
66
+ else {
67
+ return new WP_Error(
68
+ 'url_or_local_file_not_defined',
69
+ sprintf(
70
+ __( '"import_file_url" or "local_import_file" for %s%s%s are not defined!', 'rara-demo-import' ),
71
+ '<strong>',
72
+ $$import_file_info['import_file_name'],
73
+ '</strong>'
74
+ )
75
+ );
76
+ }
77
+ }
78
+ else {
79
+
80
+ // Retrieve demo data content from the URL.
81
+ $demo_import_content = self::get_content_from_url( $import_file_info['import_file_url'], $import_file_info['import_file_name'] );
82
+
83
+ // Return from this function if there was an error.
84
+ if ( is_wp_error( $demo_import_content ) ) {
85
+ return $demo_import_content;
86
+ }
87
+
88
+ // Setup filename path to save the data content.
89
+ $demo_import_file_path = $upload_path . apply_filters( 'rrdi/downloaded_content_file_prefix', 'demo-content-import-file_' ) . $start_date . apply_filters( 'rrdi/downloaded_content_file_suffix_and_file_extension', '.xml' );
90
+
91
+ // Write data content to the file and return the file path on successful write.
92
+ $downloaded_files['content'] = self::write_to_file( $demo_import_content, $demo_import_file_path );
93
+
94
+ // Return from this function if there was an error.
95
+ if ( is_wp_error( $downloaded_files['content'] ) ) {
96
+ return $downloaded_files['content'];
97
+ }
98
+ }
99
+
100
+ // ----- Set widget file path -----
101
+ // Get widgets file as well. If defined!
102
+ if ( ! empty( $import_file_info['import_widget_file_url'] ) ) {
103
+
104
+ // Retrieve widget content from the URL.
105
+ $demo_import_widgets_content = self::get_content_from_url( $import_file_info['import_widget_file_url'], $import_file_info['import_file_name'] );
106
+
107
+ // Return from this function if there was an error.
108
+ if ( is_wp_error( $demo_import_widgets_content ) ) {
109
+ return $demo_import_widgets_content;
110
+ }
111
+
112
+ // Setup filename path to save the widget content.
113
+ $import_widgets_file_path = $upload_path . apply_filters( 'rrdi/downloaded_widgets_file_prefix', 'demo-widgets-import-file_' ) . $start_date . apply_filters( 'rrdi/downloaded_widgets_file_suffix_and_file_extension', '.json' );
114
+
115
+ // Write widget content to the file and return the file path on successful write.
116
+ $downloaded_files['widgets'] = self::write_to_file( $demo_import_widgets_content, $import_widgets_file_path );
117
+
118
+ // Return from this function if there was an error.
119
+ if ( is_wp_error( $downloaded_files['widgets'] ) ) {
120
+ return $downloaded_files['widgets'];
121
+ }
122
+ }
123
+ else if ( ! empty( $import_file_info['local_import_widget_file'] ) ) {
124
+ if ( file_exists( $import_file_info['local_import_widget_file'] ) ) {
125
+ $downloaded_files['widgets'] = $import_file_info['local_import_widget_file'];
126
+ }
127
+ }
128
+
129
+ // ----- Set customizer file path -----
130
+ // Get customizer import file as well. If defined!
131
+ if ( ! empty( $import_file_info['import_customizer_file_url'] ) ) {
132
+
133
+ // Retrieve customizer content from the URL.
134
+ $demo_import_customizer_content = self::get_content_from_url( $import_file_info['import_customizer_file_url'], $import_file_info['import_file_name'] );
135
+
136
+ // Return from this function if there was an error.
137
+ if ( is_wp_error( $demo_import_customizer_content ) ) {
138
+ return $demo_import_customizer_content;
139
+ }
140
+
141
+ // Setup filename path to save the customizer content.
142
+ $import_customizer_file_path = $upload_path . apply_filters( 'rrdi/downloaded_customizer_file_prefix', 'demo-customizer-import-file_' ) . $start_date . apply_filters( 'rrdi/downloaded_customizer_file_suffix_and_file_extension', '.dat' );
143
+
144
+ // Write customizer content to the file and return the file path on successful write.
145
+ $downloaded_files['customizer'] = self::write_to_file( $demo_import_customizer_content, $import_customizer_file_path );
146
+
147
+ // Return from this function if there was an error.
148
+ if ( is_wp_error( $downloaded_files['customizer'] ) ) {
149
+ return $downloaded_files['customizer'];
150
+ }
151
+ }
152
+ else if ( ! empty( $import_file_info['local_import_customizer_file'] ) ) {
153
+ if ( file_exists( $import_file_info['local_import_customizer_file'] ) ) {
154
+ $downloaded_files['customizer'] = $import_file_info['local_import_customizer_file'];
155
+ }
156
+ }
157
+
158
+ return $downloaded_files;
159
+ }
160
+
161
+
162
+ /**
163
+ * Helper function: get content from an url.
164
+ *
165
+ * @param string $url URL to the content file.
166
+ * @param string $file_name optional, name of the file (used in the error reports).
167
+ * @return string|WP_Error, content from the URL or WP_Error object with error message
168
+ */
169
+ private static function get_content_from_url( $url, $file_name = 'Import file' ) {
170
+
171
+ // Test if the URL to the file is defined.
172
+ if ( empty( $url ) ) {
173
+ return new WP_Error(
174
+ 'url_not_defined',
175
+ sprintf(
176
+ __( 'URL for %s%s%s file is not defined!', 'rara-demo-import' ),
177
+ '<strong>',
178
+ $file_name,
179
+ '</strong>'
180
+ )
181
+ );
182
+ }
183
+
184
+ // Get file content from the server.
185
+ $response = wp_remote_get(
186
+ $url,
187
+ array( 'timeout' => apply_filters( 'rrdi/timeout_for_downloading_import_file', 20 ) )
188
+ );
189
+
190
+ if ( is_wp_error( $response ) || 200 !== $response['response']['code'] ) {
191
+
192
+ // Collect the right format of error data (array or WP_Error).
193
+ $response_error = self::get_error_from_response( $response );
194
+
195
+ return new WP_Error(
196
+ 'file_fetching_error',
197
+ sprintf(
198
+ __( 'An error occurred while fetching %s%s%s file from the server!%sReason: %s - %s.', 'rara-demo-import' ),
199
+ '<strong>',
200
+ $file_name,
201
+ '</strong>',
202
+ '<br>',
203
+ $response_error['error_code'],
204
+ $response_error['error_message']
205
+ ) . '<br>' .
206
+ apply_filters( 'rrdi/message_after_file_fetching_error', '' )
207
+ );
208
+ }
209
+
210
+ // Return content retrieved from the URL.
211
+ return wp_remote_retrieve_body( $response );
212
+ }
213
+
214
+
215
+ /**
216
+ * Write content to a file.
217
+ *
218
+ * @param string $content content to be saved to the file.
219
+ * @param string $file_path file path where the content should be saved.
220
+ * @return string|WP_Error path to the saved file or WP_Error object with error message.
221
+ */
222
+ public static function write_to_file( $content, $file_path ) {
223
+
224
+ // Verify WP file-system credentials.
225
+ $verified_credentials = self::check_wp_filesystem_credentials();
226
+
227
+ if ( is_wp_error( $verified_credentials ) ) {
228
+ return $verified_credentials;
229
+ }
230
+
231
+ // By this point, the $wp_filesystem global should be working, so let's use it to create a file.
232
+ global $wp_filesystem;
233
+
234
+ if ( ! $wp_filesystem->put_contents( $file_path, $content ) ) {
235
+ return new WP_Error(
236
+ 'failed_writing_file_to_server',
237
+ sprintf(
238
+ __( 'An error occurred while writing file to your server! Tried to write a file to: %s%s.', 'rara-demo-import' ),
239
+ '<br>',
240
+ $file_path
241
+ )
242
+ );
243
+ }
244
+
245
+ // Return the file path on successful file write.
246
+ return $file_path;
247
+ }
248
+
249
+
250
+ /**
251
+ * Append content to the file.
252
+ *
253
+ * @param string $content content to be saved to the file.
254
+ * @param string $file_path file path where the content should be saved.
255
+ * @param string $separator_text separates the existing content of the file with the new content.
256
+ * @return boolean|WP_Error, path to the saved file or WP_Error object with error message.
257
+ */
258
+ public static function append_to_file( $content, $file_path, $separator_text = '' ) {
259
+
260
+ // Verify WP file-system credentials.
261
+ $verified_credentials = self::check_wp_filesystem_credentials();
262
+
263
+ if ( is_wp_error( $verified_credentials ) ) {
264
+ return $verified_credentials;
265
+ }
266
+
267
+ // By this point, the $wp_filesystem global should be working, so let's use it to create a file.
268
+ global $wp_filesystem;
269
+
270
+ $existing_data = '';
271
+ if ( file_exists( $file_path ) ) {
272
+ $existing_data = $wp_filesystem->get_contents( $file_path );
273
+ }
274
+
275
+ // Style separator.
276
+ $separator = PHP_EOL . '---' . $separator_text . '---' . PHP_EOL;
277
+
278
+ if ( ! $wp_filesystem->put_contents( $file_path, $existing_data . $separator . $content . PHP_EOL ) ) {
279
+ return new WP_Error(
280
+ 'failed_writing_file_to_server',
281
+ sprintf(
282
+ __( 'An error occurred while writing file to your server! Tried to write a file to: %s%s.', 'rara-demo-import' ),
283
+ '<br>',
284
+ $file_path
285
+ )
286
+ );
287
+ }
288
+
289
+ return true;
290
+ }
291
+
292
+
293
+ /**
294
+ * Get data from a file
295
+ *
296
+ * @param string $file_path file path where the content should be saved.
297
+ * @return string $data, content of the file or WP_Error object with error message.
298
+ */
299
+ public static function data_from_file( $file_path ) {
300
+
301
+ // Verify WP file-system credentials.
302
+ $verified_credentials = self::check_wp_filesystem_credentials();
303
+
304
+ if ( is_wp_error( $verified_credentials ) ) {
305
+ return $verified_credentials;
306
+ }
307
+
308
+ // By this point, the $wp_filesystem global should be working, so let's use it to read a file.
309
+ global $wp_filesystem;
310
+
311
+ $data = $wp_filesystem->get_contents( $file_path );
312
+
313
+ if ( ! $data ) {
314
+ return new WP_Error(
315
+ 'failed_reading_file_from_server',
316
+ sprintf(
317
+ __( 'An error occurred while reading a file from your server! Tried reading file from path: %s%s.', 'rara-demo-import' ),
318
+ '<br>',
319
+ $file_path
320
+ )
321
+ );
322
+ }
323
+
324
+ // Return the file data.
325
+ return $data;
326
+ }
327
+
328
+
329
+ /**
330
+ * Helper function: check for WP file-system credentials needed for reading and writing to a file.
331
+ *
332
+ * @return boolean|WP_Error
333
+ */
334
+ private static function check_wp_filesystem_credentials() {
335
+
336
+ // Check if the file-system method is 'direct', if not display an error.
337
+ if ( ! ( 'direct' === get_filesystem_method() ) ) {
338
+ return new WP_Error(
339
+ 'no_direct_file_access',
340
+ sprintf(
341
+ __( 'This WordPress page does not have %sdirect%s write file access. This plugin needs it in order to save the demo import xml file to the upload directory of your site. You can change this setting with these instructions: %s.', 'rara-demo-import' ),
342
+ '<strong>',
343
+ '</strong>',
344
+ '<a href="http://gregorcapuder.com/wordpress-how-to-set-direct-filesystem-method/" target="_blank">How to set <strong>direct</strong> filesystem method</a>'
345
+ )
346
+ );
347
+ }
348
+
349
+ // Get plugin page settings.
350
+ $plugin_page_setup = apply_filters( 'rrdi/plugin_page_setup', array(
351
+ 'parent_slug' => 'themes.php',
352
+ 'page_title' => esc_html__( 'Rara One Click Demo Import' , 'rara-demo-import' ),
353
+ 'menu_title' => esc_html__( 'Import Demo Data' , 'rara-demo-import' ),
354
+ 'capability' => 'import',
355
+ 'menu_slug' => 'rara-demo-import',
356
+ )
357
+ );
358
+
359
+ // Get user credentials for WP file-system API.
360
+ $demo_import_page_url = wp_nonce_url( $plugin_page_setup['parent_slug'] . '?page=' . $plugin_page_setup['menu_slug'], $plugin_page_setup['menu_slug'] );
361
+
362
+ if ( false === ( $creds = request_filesystem_credentials( $demo_import_page_url, '', false, false, null ) ) ) {
363
+ return new WP_error(
364
+ 'filesystem_credentials_could_not_be_retrieved',
365
+ __( 'An error occurred while retrieving reading/writing permissions to your server (could not retrieve WP filesystem credentials)!', 'rara-demo-import' )
366
+ );
367
+ }
368
+
369
+ // Now we have credentials, try to get the wp_filesystem running.
370
+ if ( ! WP_Filesystem( $creds ) ) {
371
+ return new WP_Error(
372
+ 'wrong_login_credentials',
373
+ __( 'Your WordPress login credentials don\'t allow to use WP_Filesystem!', 'rara-demo-import' )
374
+ );
375
+ }
376
+
377
+ return true;
378
+ }
379
+
380
+
381
+ /**
382
+ * Helper function: get the right format of response errors
383
+ *
384
+ * @param array|WP_Error $response array or WP_Error.
385
+ * @return array, with error code and error message.
386
+ */
387
+ private static function get_error_from_response( $response ) {
388
+ $response_error = array();
389
+
390
+ if ( is_array( $response ) ) {
391
+ $response_error['error_code'] = $response['response']['code'];
392
+ $response_error['error_message'] = $response['response']['message'];
393
+ }
394
+ else {
395
+ $response_error['error_code'] = $response->get_error_code();
396
+ $response_error['error_message'] = $response->get_error_message();
397
+ }
398
+
399
+ return $response_error;
400
+ }
401
+
402
+
403
+ /**
404
+ * Get log file path
405
+ *
406
+ * @param string $start_date date|time|timestamp to use in the log filename.
407
+ * @return string, path to the log file
408
+ */
409
+ public static function get_log_path( $start_date = '' ) {
410
+
411
+ $upload_dir = wp_upload_dir();
412
+ $upload_path = apply_filters( 'rrdi/upload_file_path', trailingslashit( $upload_dir['path'] ) );
413
+
414
+ $log_path = $upload_path . apply_filters( 'rrdi/log_file_prefix', 'log_file_' ) . $start_date . apply_filters( 'rrdi/log_file_suffix_and_file_extension', '.txt' );
415
+
416
+ self::register_file_as_media_attachment( $log_path );
417
+
418
+ return $log_path;
419
+ }
420
+
421
+
422
+ /**
423
+ * Register file as attachment to the Media page.
424
+ *
425
+ * @param string $log_path log file path.
426
+ * @return void
427
+ */
428
+ public static function register_file_as_media_attachment( $log_path ) {
429
+
430
+ // Check the type of file.
431
+ $log_mimes = array( 'txt' => 'text/plain' );
432
+ $filetype = wp_check_filetype( basename( $log_path ), apply_filters( 'rrdi/file_mimes', $log_mimes ) );
433
+
434
+ // Prepare an array of post data for the attachment.
435
+ $attachment = array(
436
+ 'guid' => self::get_log_url( $log_path ),
437
+ 'post_mime_type' => $filetype['type'],
438
+ 'post_title' => apply_filters( 'rrdi/attachment_prefix', esc_html__( 'Rara One Click Demo Import - ', 'rara-demo-import' ) ) . preg_replace( '/\.[^.]+$/', '', basename( $log_path ) ),
439
+ 'post_content' => '',
440
+ 'post_status' => 'inherit',
441
+ );
442
+
443
+ // Insert the file as attachment in Media page.
444
+ $attach_id = wp_insert_attachment( $attachment, $log_path );
445
+ }
446
+
447
+
448
+ /**
449
+ * Get log file url
450
+ *
451
+ * @param string $log_path log path to use for the log filename.
452
+ * @return string, url to the log file.
453
+ */
454
+ public static function get_log_url( $log_path ) {
455
+
456
+ $upload_dir = wp_upload_dir();
457
+ $upload_url = apply_filters( 'rrdi/upload_file_url', trailingslashit( $upload_dir['url'] ) );
458
+
459
+ return $upload_url . basename( $log_path );
460
+ }
461
+
462
+
463
+ /**
464
+ * Check if the AJAX call is valid.
465
+ */
466
+ public static function verify_ajax_call() {
467
+
468
+ check_ajax_referer( 'rrdi-ajax-verification', 'security' );
469
+
470
+ // Check if user has the WP capability to import data.
471
+ if ( ! current_user_can( 'import' ) ) {
472
+ wp_die(
473
+ sprintf(
474
+ __( '%sYour user role isn\'t high enough. You don\'t have permission to import demo data.%s', 'rara-demo-import' ),
475
+ '<div class="notice notice-error"><p>',
476
+ '</p></div>'
477
+ )
478
+ );
479
+ }
480
+ }
481
+
482
+
483
+ /**
484
+ * Process uploaded files and return the paths to these files.
485
+ *
486
+ * @param array $uploaded_files $_FILES array form an AJAX request.
487
+ * @param string $log_file_path path to the log file.
488
+ * @return array of paths to the content import and widget import files.
489
+ */
490
+ public static function process_uploaded_files( $uploaded_files, $log_file_path ) {
491
+
492
+ // Variable holding the paths to the uploaded files.
493
+ $selected_import_files = array();
494
+
495
+ // Upload settings to disable form and type testing for AJAX uploads.
496
+ $upload_overrides = array(
497
+ 'test_form' => false,
498
+ 'test_type' => false,
499
+ );
500
+
501
+ // Handle demo content and widgets file upload.
502
+ $content_file_info = wp_handle_upload( $_FILES['content_file'], $upload_overrides );
503
+ $widget_file_info = wp_handle_upload( $_FILES['widget_file'], $upload_overrides );
504
+ $customizer_file_info = wp_handle_upload( $_FILES['customizer_file'], $upload_overrides );
505
+
506
+ if ( empty( $content_file_info['file'] ) || isset( $content_file_info['error'] ) ) {
507
+
508
+ // Write error to log file and send an AJAX response with the error.
509
+ self::log_error_and_send_ajax_response(
510
+ __( 'Please upload XML file for content import. If you want to import widgets or customizer settings only, please use Widget Importer & Exporter or the Customizer Export/Import plugin.', 'rara-demo-import' ),
511
+ $log_file_path,
512
+ esc_html__( 'Upload files', 'rara-demo-import' )
513
+ );
514
+ }
515
+
516
+ // Set uploaded content file.
517
+ $selected_import_files['content'] = $content_file_info['file'];
518
+
519
+ // Process widget import file.
520
+ if ( $widget_file_info && ! isset( $widget_file_info['error'] ) ) {
521
+
522
+ // Set uploaded widget file.
523
+ $selected_import_files['widgets'] = $widget_file_info['file'];
524
+ }
525
+ else {
526
+
527
+ // Add this error to log file.
528
+ $log_added = self::append_to_file(
529
+ sprintf(
530
+ __( 'Widget file was not uploaded. Error: %s', 'rara-demo-import' ),
531
+ $widget_file_info['error']
532
+ ),
533
+ $log_file_path,
534
+ esc_html__( 'Upload files' , 'rara-demo-import' )
535
+ );
536
+ }
537
+
538
+ // Process Customizer import file.
539
+ if ( $customizer_file_info && ! isset( $customizer_file_info['error'] ) ) {
540
+
541
+ // Set uploaded widget file.
542
+ $selected_import_files['customizer'] = $customizer_file_info['file'];
543
+ }
544
+ else {
545
+
546
+ // Add this error to log file.
547
+ $log_added = self::append_to_file(
548
+ sprintf(
549
+ __( 'Customizer file was not uploaded. Error: %s', 'rara-demo-import' ),
550
+ $customizer_file_info['error']
551
+ ),
552
+ $log_file_path,
553
+ esc_html__( 'Upload files' , 'rara-demo-import' )
554
+ );
555
+ }
556
+
557
+ // Add this message to log file.
558
+ $log_added = self::append_to_file(
559
+ __( 'The import files were successfully uploaded!', 'rara-demo-import' ) . self::import_file_info( $selected_import_files ),
560
+ $log_file_path,
561
+ esc_html__( 'Upload files' , 'rara-demo-import' )
562
+ );
563
+
564
+ // Return array with paths of uploaded files.
565
+ return $selected_import_files;
566
+ }
567
+
568
+
569
+ /**
570
+ * Get import file information and max execution time.
571
+ *
572
+ * @param array $selected_import_files array of selected import files.
573
+ */
574
+ public static function import_file_info( $selected_import_files ) {
575
+ return PHP_EOL .
576
+ sprintf(
577
+ __( 'Initial max execution time = %s', 'rara-demo-import' ),
578
+ ini_get( 'max_execution_time' )
579
+ ) . PHP_EOL .
580
+ sprintf(
581
+ __( 'Files info:%1$sSite URL = %2$s%1$sData file = %3$s%1$sWidget file = %4$s%1$sCustomizer file = %5$s', 'rara-demo-import' ),
582
+ PHP_EOL,
583
+ get_site_url(),
584
+ $selected_import_files['content'],
585
+ empty( $selected_import_files['widgets'] ) ? esc_html__( 'not defined!', 'rara-demo-import' ) : $selected_import_files['widgets'],
586
+ empty( $selected_import_files['customizer'] ) ? esc_html__( 'not defined!', 'rara-demo-import' ) : $selected_import_files['customizer']
587
+ );
588
+ }
589
+
590
+
591
+ /**
592
+ * Write the error to the log file and send the AJAX response.
593
+ *
594
+ * @param string $error_text text to display in the log file and in the AJAX response.
595
+ * @param string $log_file_path path to the log file.
596
+ * @param string $separator title separating the old and new content.
597
+ */
598
+ public static function log_error_and_send_ajax_response( $error_text, $log_file_path, $separator = '' ) {
599
+
600
+ // Add this error to log file.
601
+ $log_added = self::append_to_file(
602
+ $error_text,
603
+ $log_file_path,
604
+ $separator
605
+ );
606
+
607
+ // Send JSON Error response to the AJAX call.
608
+ wp_send_json( $error_text );
609
+ }
610
+ }
includes/class-rrdi-importer.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class for declaring the importer used in the Rara One Click Demo Import plugin
4
+ *
5
+ * @package rara-demo-import
6
+ */
7
+
8
+ class RRDI_Importer {
9
+
10
+ private $importer;
11
+
12
+ public function __construct( $importer_options = array(), $logger = null ) {
13
+
14
+ // Include files that are needed for WordPress Importer v2.
15
+ $this->include_required_files();
16
+
17
+ // Set the WordPress Importer v2 as the importer used in this plugin.
18
+ // More: https://github.com/humanmade/WordPress-Importer.
19
+ $this->importer = new RRDI_WXR_Importer( $importer_options );
20
+
21
+ // Set logger to the importer.
22
+ if ( ! empty( $logger ) ) {
23
+ $this->set_logger( $logger );
24
+ }
25
+ }
26
+
27
+ /**
28
+ * Include required files.
29
+ */
30
+ private function include_required_files() {
31
+ defined( 'WP_LOAD_IMPORTERS' ) || define( 'WP_LOAD_IMPORTERS', true );
32
+ require ABSPATH . '/wp-admin/includes/class-wp-importer.php';
33
+ require RRDI_PATH . 'includes/class-rrdi-wxr-importer.php';
34
+ }
35
+
36
+ /**
37
+ * Imports content from a WordPress export file.
38
+ *
39
+ * @param string $data_file path to xml file, file with WordPress export data.
40
+ */
41
+ public function import( $data_file ) {
42
+ $this->importer->import( $data_file );
43
+ }
44
+
45
+ /**
46
+ * Set the logger used in the import
47
+ *
48
+ * @param object $logger logger instance.
49
+ */
50
+ public function set_logger( $logger ) {
51
+ $this->importer->set_logger( $logger );
52
+ }
53
+
54
+ /**
55
+ * Get all protected variables from the HM_WXR_Importer needed for continuing the import.
56
+ */
57
+ public function get_importer_data() {
58
+ return $this->importer->get_importer_data();
59
+ }
60
+
61
+ /**
62
+ * Sets all protected variables from the HM_WXR_Importer needed for continuing the import.
63
+ *
64
+ * @param array $data with set variables.
65
+ */
66
+ public function set_importer_data( $data ) {
67
+ $this->importer->set_importer_data( $data );
68
+ }
69
+ }
includes/class-rrdi-include-files.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Include files.
4
+ *
5
+ * @package rara-demo-import
6
+ */
7
+
8
+ /**
9
+ * Rara One Click Demo Import class, so we don't have to worry about namespaces.
10
+ */
11
+ class RRDI_Theme_Demo_Include_Files {
12
+
13
+ function __construct()
14
+ {
15
+ // Include files.
16
+ require RRDI_PATH . 'includes/class-rrdi-helpers.php';
17
+ require RRDI_PATH . 'includes/class-rrdi-importer.php';
18
+ require RRDI_PATH . 'includes/vendor/class-rrdi-widget-importer.php';
19
+ require RRDI_PATH . 'includes/vendor/class-rrdi-customizer-importer.php';
20
+ require RRDI_PATH . 'includes/class-rrdi-logger.php';
21
+ }
22
+ }
23
+ new RRDI_Theme_Demo_Include_Files;
includes/class-rrdi-init.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Display admin error message if PHP version is older than 5.3.2.
4
+ * Otherwise execute the main plugin class.
5
+ */
6
+ class RDDI_init
7
+ {
8
+ function __construct()
9
+ {
10
+ $this->rddi_init_version_check();
11
+ }
12
+
13
+ function rddi_init_version_check()
14
+ {
15
+ if ( version_compare( phpversion(), '5.3.2', '<' ) ) {
16
+
17
+ /**
18
+ * Display an admin error notice when PHP is older the version 5.3.2.
19
+ * Hook it to the 'admin_notices' action.
20
+ */
21
+ function rrdi_old_php_admin_error_notice() {
22
+ $message = sprintf( esc_html__( 'The %2$sRara One Click Demo Import%3$s plugin requires %2$sPHP 5.3.2+%3$s to run properly. Please contact your hosting company and ask them to update the PHP version of your site to at least PHP 5.3.2.%4$s Your current version of PHP: %2$s%1$s%3$s', 'rara-demo-import' ), phpversion(), '<strong>', '</strong>', '<br>' );
23
+
24
+ printf( '<div class="notice notice-error"><p>%1$s</p></div>', wp_kses_post( $message ) );
25
+ }
26
+ add_action( 'admin_notices', 'rrdi_old_php_admin_error_notice' );
27
+ }
28
+ else {
29
+
30
+ // Require main plugin file.
31
+ require RRDI_PATH . 'includes/class-rrdi-main.php';
32
+
33
+ // Instantiate the main plugin class *Singleton*.
34
+ $Theme_Demo_Import = RRDI_Theme_Demo_Import::getInstance();
35
+ }
36
+ }
37
+ }
38
+ new RDDI_init;
includes/class-rrdi-logger.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Logger class used in the Rara One Click Demo Import plugin
4
+ *
5
+ * @package rara-demo-import
6
+ */
7
+
8
+ // Include files.
9
+ require RRDI_PATH . 'includes/extras/class-logger.php';
10
+ require RRDI_PATH . 'includes/extras/class-logger-cli.php';
11
+
12
+ class RRDI_Logger extends HM_WP_Importer_Logger_CLI {
13
+
14
+ /**
15
+ * Variable for front-end error display.
16
+ */
17
+ public $error_output = '';
18
+
19
+ /**
20
+ * Overwritten log function from HM_WP_Importer_Logger_CLI.
21
+ *
22
+ * Logs with an arbitrary level.
23
+ *
24
+ * @param mixed $level level of reporting.
25
+ * @param string $message log message.
26
+ * @param array $context context to the log message.
27
+ */
28
+ public function log( $level, $message, array $context = array() ) {
29
+
30
+ // Save error messages for front-end display.
31
+ $this->error_output( $level, $message, $context = array() );
32
+
33
+ if ( $this->level_to_numeric( $level ) < $this->level_to_numeric( $this->min_level ) ) {
34
+ return;
35
+ }
36
+
37
+ printf(
38
+ '[%s] %s' . PHP_EOL,
39
+ strtoupper( $level ),
40
+ $message
41
+ );
42
+ }
43
+
44
+
45
+ /**
46
+ * Save messages for error output.
47
+ * Only the messages greater then Error.
48
+ *
49
+ * @param mixed $level level of reporting.
50
+ * @param string $message log message.
51
+ * @param array $context context to the log message.
52
+ */
53
+ public function error_output( $level, $message, array $context = array() ) {
54
+ if ( $this->level_to_numeric( $level ) < $this->level_to_numeric( 'error' ) ) {
55
+ return;
56
+ }
57
+
58
+ $this->error_output .= sprintf(
59
+ '[%s] %s<br>',
60
+ strtoupper( $level ),
61
+ $message
62
+ );
63
+ }
64
+ }
includes/class-rrdi-main.php ADDED
@@ -0,0 +1,683 @@