PluginProbe
GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI / 8.0.5
GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI v8.0.5
8.0.5 8.0.4 8.0.3 8.0.1 8.0.2 8.0.0 7.9.9.7 7.9.9.6 7.9.9.5 7.9.9.4 7.9.9.3 7.9.9.2 7.9.9.1 7.9.9 7.9.8 7.9.7 7.9.6 7.9.5 7.9.4 7.9.3 7.9.2 7.9.1 7.9.0 7.8.9 7.8.8 All 47 releases
← All changes | includes/admin/tools/import-export-setup.php +494 -0 7.8.9 → 8.0.5 View file →
@@ -1,0 +1,494 @@
1 +<?php
2 +/**
3 + * Import/Export Setup Tool
4 + *
5 + * @package GamiPress\Admin\Tools\Import_Export_Setup
6 + * @author GamiPress <[email protected]>, Ruben Garcia <[email protected]>
7 + * @since 1.7.0
8 + */
9 +// Exit if accessed directly
10 +if( !defined( 'ABSPATH' ) ) exit;
11 +
12 +/**
13 + * Register Import/Export Setup Tool meta boxes
14 + *
15 + * @since 1.7.0
16 + *
17 + * @param array $meta_boxes
18 + *
19 + * @return array
20 + */
21 +function gamipress_import_export_setup_tool_meta_boxes( $meta_boxes ) {
22 +
23 + // Setup vars
24 + $points_types = gamipress_get_points_types();
25 + $achievement_types = gamipress_get_achievement_types();
26 + $rank_types = gamipress_get_rank_types();
27 +
28 + $options = array();
29 +
30 + // Points types options
31 + if( count( $points_types ) ) $options['all-points-types'] = __( 'All Points Types', 'gamipress' );
32 +
33 + foreach( $points_types as $slug => $data ) {
34 + $options[$slug . '-points-type'] = '<strong>' . $data['plural_name'] . '</strong>';
35 + $options[$slug . '-points-awards'] = __( 'Points Awards', 'gamipress' );
36 + $options[$slug . '-points-deducts'] = __( 'Points Deductions', 'gamipress' );
37 + }
38 +
39 + // Achievement types options
40 + if( count( $achievement_types ) ) $options['all-achievement-types'] = __( 'All Achievement Types', 'gamipress' );
41 +
42 + foreach( $achievement_types as $slug => $data ) {
43 + $options[$slug . '-achievement-type'] = '<strong>' . $data['singular_name'] . '</strong>';
44 + $options[$slug . '-achievements'] = __( 'Achievements', 'gamipress' );
45 + $options[$slug . '-steps'] = __( 'Steps', 'gamipress' );
46 + }
47 +
48 + // Rank types options
49 + if( count( $rank_types ) ) $options['all-rank-types'] = __( 'All Rank Types', 'gamipress' );
50 +
51 + foreach( $rank_types as $slug => $data ) {
52 + $options[$slug . '-rank-type'] = '<strong>' . $data['singular_name'] . '</strong>';
53 + $options[$slug . '-ranks'] = __( 'Ranks', 'gamipress' );
54 + $options[$slug . '-rank-requirements'] = __( 'Requirements', 'gamipress' );
55 + }
56 +
57 + $meta_boxes['import-export-setup'] = array(
58 + 'title' => gamipress_dashicon( 'admin-generic' ) . __( 'Setup', 'gamipress' ),
59 + 'fields' => apply_filters( 'gamipress_import_export_setup_tool_fields', array(
60 + 'export_setup_options' => array(
61 + 'label' => __( 'Export Setup', 'gamipress' ),
62 + 'desc' => __( 'Choose the stored setup you want to export.', 'gamipress' ),
63 + 'type' => 'multicheck',
64 + 'classes' => 'gamipress-switch gamipress-all-types-multicheck',
65 + 'options' => $options,
66 + ),
67 + 'export_setup' => array(
68 + 'label' => __( 'Export Setup', 'gamipress' ),
69 + 'desc' => __( 'Export elements setup on this site as a file to easily import those elements to another site.', 'gamipress' ),
70 + 'type' => 'button',
71 + 'button' => 'primary',
72 + 'icon' => 'dashicons-download',
73 + 'action' => 'export_setup'
74 + ),
75 + 'import_setup_file' => array(
76 + 'type' => 'text',
77 + 'attributes' => array( 'type' => 'file' )
78 + ),
79 + 'import_setup' => array(
80 + 'label' => __( 'Import Setup', 'gamipress' ),
81 + 'type' => 'button',
82 + 'button' => 'primary',
83 + 'icon' => 'dashicons-upload',
84 + ),
85 + ) ),
86 + 'vertical_tabs' => true,
87 + 'tabs' => apply_filters( 'gamipress_import_export_setup_tool_tabs', array(
88 + 'export_points' => array(
89 + 'icon' => 'dashicons-download',
90 + 'title' => __( 'Export', 'gamipress' ),
91 + 'fields' => array(
92 + 'export_setup_options',
93 + 'export_setup',
94 + ),
95 + ),
96 + 'import_points' => array(
97 + 'icon' => 'dashicons-upload',
98 + 'title' => __( 'Import', 'gamipress' ),
99 + 'fields' => array(
100 + 'import_setup_file',
101 + 'import_setup',
102 + ),
103 + ),
104 + ) )
105 + );
106 +
107 + return $meta_boxes;
108 +
109 +}
110 +add_filter( 'gamipress_tools_import_export_meta_boxes', 'gamipress_import_export_setup_tool_meta_boxes' );
111 +
112 +/**
113 + * Export Setup action
114 + *
115 + * @since 1.7.0
116 + */
117 +function gamipress_ajax_export_setup_tool() {
118 +
119 + // Security check, forces to die if not security passed
120 + check_ajax_referer( 'gamipress_admin', 'nonce' );
121 +
122 + global $wpdb;
123 +
124 + $postmeta = GamiPress()->db->postmeta;
125 +
126 + $items = $_POST['items'];
127 +
128 + // Check parameters received
129 + if( ! isset( $items ) || empty( $items ) ) {
130 + wp_send_json_error( __( 'No items selected.', 'gamipress' ) );
131 + }
132 +
133 + // Check parameters received
134 + if( ! is_array( $items ) ) {
135 + wp_send_json_error( __( 'No items selected.', 'gamipress' ) );
136 + }
137 +
138 + // Check user capabilities
139 + if( ! current_user_can( gamipress_get_manager_capability() ) ) {
140 + wp_send_json_error( __( 'You are not allowed to perform this action.', 'gamipress' ) );
141 + }
142 +
143 + ignore_user_abort( true );
144 +
145 + if ( ! gamipress_is_function_disabled( 'set_time_limit' ) ) {
146 + set_time_limit( 0 );
147 + }
148 +
149 + // Setup vars
150 + $setup = array();
151 + $posts_to_export = array();
152 + $points_types = gamipress_get_points_types();
153 + $achievement_types = gamipress_get_achievement_types();
154 + $rank_types = gamipress_get_rank_types();
155 + $points_types_slugs = gamipress_get_points_types_slugs();
156 + $achievement_types_slugs = gamipress_get_achievement_types_slugs();
157 + $rank_types_slugs = gamipress_get_rank_types_slugs();
158 + $types = array_merge( $points_types, $achievement_types, $rank_types );
159 + $types_slugs = array_merge( $points_types_slugs, $achievement_types_slugs, $rank_types_slugs );
160 + $suffixes = array(
161 + '-points-type',
162 + '-points-awards',
163 + '-points-deducts',
164 + '-achievement-type',
165 + '-achievements',
166 + '-steps',
167 + '-rank-type',
168 + '-ranks',
169 + '-rank-requirements',
170 + );
171 +
172 + // Common arg to query requirements
173 + $query_args = array(
174 + 'post_status' => 'any',
175 + 'orderby' => 'menu_order',
176 + 'order' => 'ASC',
177 + 'posts_per_page' => -1,
178 + 'suppress_filters' => false,
179 + );
180 +
181 + foreach( $items as $item_to_export ) {
182 +
183 + foreach( $suffixes as $suffix ) {
184 +
185 + // If option does not ends with one of suffixes then is not correct
186 + if( ! gamipress_ends_with( $item_to_export, $suffix ) ) {
187 + continue;
188 + }
189 +
190 + // Remove the suffix to get the type
191 + $type = str_replace( $suffix, '', $item_to_export );
192 +
193 + // Check if is a registered type option
194 + if( ! in_array( $type, $types_slugs ) ) {
195 + continue;
196 + }
197 +
198 + switch( $suffix ) {
199 + case '-points-type':
200 + case '-achievement-type':
201 + case '-rank-type':
202 + // Append type to the posts to export array
203 + $posts_to_export[] = gamipress_get_post( $types[$type]['ID'] );
204 + break;
205 + case '-points-awards':
206 + case '-points-deducts':
207 +
208 + // Remove first "-"
209 + $post_type = substr( $suffix, 1 );
210 + // Remove last "s"
211 + $post_type = rtrim( $post_type, 's' );
212 +
213 + $posts = get_posts( array_merge( $query_args, array(
214 + 'post_type' => $post_type,
215 + 'post_parent' => $types[$type]['ID'],
216 + ) ) );
217 +
218 + // Bail if not posts found
219 + if( empty( $posts ) ) break;
220 +
221 + // Merge posts to posts to export
222 + $posts_to_export = array_merge( $posts_to_export, $posts );
223 +
224 + break;
225 + case '-steps':
226 + case '-rank-requirements':
227 +
228 + // Remove first "-"
229 + $post_type = substr( $suffix, 1 );
230 + // Remove last "s"
231 + $post_type = rtrim( $post_type, 's' );
232 +
233 + $parents = get_posts( array_merge( $query_args, array(
234 + 'post_type' => $type,
235 + ) ) );
236 +
237 + $parents = wp_list_pluck( $parents, 'ID' );
238 +
239 + // Bail if not parents found
240 + if( empty( $parents ) ) break;
241 +
242 + $posts = get_posts( array_merge( $query_args, array(
243 + 'post_type' => $post_type,
244 + 'post_parent__in' => $parents,
245 + ) ) );
246 +
247 + // Bail if not posts found
248 + if( empty( $posts ) ) break;
249 +
250 + // Merge posts to posts to export
251 + $posts_to_export = array_merge( $posts_to_export, $posts );
252 +
253 + break;
254 + case '-achievements':
255 + case '-ranks':
256 +
257 + $posts = get_posts( array_merge( $query_args, array(
258 + 'post_type' => $type,
259 + ) ) );
260 +
261 + // Bail if not posts found
262 + if( empty( $posts ) ) break;
263 +
264 + // Merge posts to posts to export
265 + $posts_to_export = array_merge( $posts_to_export, $posts );
266 +
267 + break;
268 + }
269 +
270 + }
271 +
272 + }
273 +
274 + foreach( $posts_to_export as $post ) {
275 +
276 + if( $post instanceof WP_Post ) {
277 + $post = $post->to_array();
278 + }
279 +
280 + if( is_array( $post ) && isset( $post['ID'] ) && absint( $post['ID'] ) !== 0 ) {
281 +
282 + $post_id = $post['ID'];
283 + $post['meta'] = array();
284 +
285 + // Get all post metas
286 + $post_metas = $wpdb->get_results( "SELECT meta_key, meta_value FROM {$postmeta} WHERE post_id={$post_id}" );
287 +
288 + foreach( $post_metas as $meta ) {
289 +
290 + $meta_key = $meta->meta_key;
291 + $meta_value = $meta->meta_value;
292 +
293 + // Turn thumbnail ID into a thumbnail URL for the import process
294 + if( $meta_key === '_thumbnail_id' && absint( $meta_value ) !== 0 ) {
295 + $meta_value = wp_get_attachment_image_url( $meta_value, 'full' );
296 + }
297 +
298 + /**
299 + * Filter meta value to allow custom processing
300 + *
301 + * @since 1.7.0
302 + *
303 + * @param mixed $meta_value
304 + * @param string $meta_key
305 + * @param array $post
306 + *
307 + * @return mixed
308 + */
309 + $post['meta'][$meta_key] = apply_filters( 'gamipress_export_setup_tool_post_meta_value', $meta_value, $meta_key, $post );
310 + }
311 +
312 + /**
313 + * Filter to append custom data to post to export
314 + *
315 + * @since 1.7.0
316 + *
317 + * @param array $post
318 + *
319 + * @return array
320 + */
321 + $post = apply_filters( 'gamipress_export_setup_tool_post', $post );
322 +
323 +
324 + $setup[] = $post;
325 + }
326 + }
327 +
328 + wp_send_json_success( array(
329 + 'setup_raw' => $setup,
330 + 'setup' => json_encode( $setup ),
331 + 'message' => __( 'Setup export process has been done successfully.', 'gamipress' ),
332 + ) );
333 +
334 +}
335 +add_action( 'wp_ajax_gamipress_export_setup_tool', 'gamipress_ajax_export_setup_tool' );
336 +
337 +/**
338 + * AJAX handler for the import setup tool
339 + *
340 + * @since 1.7.0
341 + */
342 +function gamipress_ajax_import_setup_tool() {
343 +
344 + // Security check, forces to die if not security passed
345 + check_ajax_referer( 'gamipress_admin', 'nonce' );
346 +
347 + // Check parameters received
348 + if( ! isset( $_FILES['file'] ) ) {
349 + wp_send_json_error( __( 'No setup to import.', 'gamipress' ) );
350 + }
351 +
352 + $import_file = $_FILES['file']['tmp_name'];
353 +
354 + if( empty( $import_file ) ) {
355 + wp_send_json_error( __( 'Can not retrieve the file to import, check server file permissions.', 'gamipress' ) );
356 + }
357 +
358 + // Check user capabilities
359 + if( ! current_user_can( gamipress_get_manager_capability() ) ) {
360 + wp_send_json_error( __( 'You are not allowed to perform this action.', 'gamipress' ) );
361 + }
362 +
363 + // Retrieve the setup from the file and convert the json object to an array
364 + $setup = json_decode( file_get_contents( $import_file ), true ) ;
365 +
366 + if( ! is_array( $setup ) || empty( $setup ) ) {
367 + wp_send_json_error( __( 'Empty setup, so nothing to import.', 'gamipress' ) );
368 + }
369 +
370 + ignore_user_abort( true );
371 +
372 + if ( ! gamipress_is_function_disabled( 'set_time_limit' ) ) {
373 + set_time_limit( 0 );
374 + }
375 +
376 + // Setup vars
377 + $user_id = get_current_user_id();
378 + $processed = array();
379 +
380 + // Make a first loop to insert all posts given
381 + foreach( $setup as $original_post ) {
382 +
383 + // Since post will be modified, make a copy
384 + $post = $original_post;
385 +
386 + /**
387 + * Filter post that will being imported
388 + *
389 + * @since 1.7.0
390 + *
391 + * @param array $post
392 + *
393 + * @return array
394 + */
395 + $post = apply_filters( 'gamipress_import_setup_tool_post', $post );
396 +
397 + // Remote post ID
398 + $post_id = $post['ID'];
399 +
400 + $defaults = array(
401 + 'ID' => 0,
402 + 'post_author' => $user_id,
403 + 'post_content' => '',
404 + 'post_content_filtered' => '',
405 + 'post_title' => '',
406 + 'post_excerpt' => '',
407 + 'post_status' => 'draft',
408 + 'post_type' => 'post',
409 + 'comment_status' => '',
410 + 'ping_status' => '',
411 + 'post_password' => '',
412 + 'to_ping' => '',
413 + 'pinged' => '',
414 + 'post_parent' => 0,
415 + 'menu_order' => 0,
416 + 'guid' => '',
417 + 'import_id' => 0,
418 + 'context' => '',
419 + );
420 +
421 + $post_data = wp_parse_args( $post, $defaults );
422 +
423 + unset( $post_data['ID'] );
424 +
425 + // Local post ID
426 + $local_post_id = wp_insert_post( $post_data );
427 +
428 + // Update post ID for following filters
429 + $post['ID'] = $local_post_id;
430 +
431 + // Add post inserted to processed posts array
432 + $processed[$post_id] = $local_post_id;
433 +
434 + // Process post metas
435 + if( isset( $post['meta'] ) && is_array( $post['meta'] ) ) {
436 +
437 + foreach( $post['meta'] as $meta_key => $meta_value ) {
438 +
439 + // Check if thumbnail ID is a external URL and import the external file to this install
440 + if( $meta_key === '_thumbnail_id' && ! empty( $meta_value ) && ! is_numeric( $meta_value ) ) {
441 +
442 + $meta_value = gamipress_import_attachment( $meta_value );
443 +
444 + }
445 +
446 + /**
447 + * Filter meta value to allow custom processing
448 + *
449 + * @since 1.7.0
450 + *
451 + * @param mixed $meta_value
452 + * @param string $meta_key
453 + * @param array $post
454 + *
455 + * @return mixed
456 + */
457 + $meta_value = apply_filters( 'gamipress_import_setup_tool_post_meta_value', $meta_value, $meta_key, $post );
458 +
459 + // Skip meta if there is any error
460 + if( is_wp_error( $meta_value ) ) continue;
461 +
462 + $meta_value = maybe_unserialize( $meta_value );
463 +
464 + update_post_meta( $post['ID'], $meta_key, $meta_value, true );
465 + }
466 +
467 + }
468 +
469 + }
470 +
471 + // Second loop to update external post parents to local posts
472 + foreach( $setup as $post ) {
473 +
474 + // Bail if this post hasn't been processed
475 + if( ! isset( $processed[$post['ID']] ) ) continue;
476 +
477 + // Check if post parent have been processed too
478 + if( isset( $post['post_parent'] ) && absint( $post['post_parent'] ) !== 0 && isset( $processed[$post['post_parent']] ) ) {
479 + // Update post parent
480 + wp_update_post( array(
481 + 'ID' => $processed[$post['ID']],
482 + 'post_parent' => $processed[$post['post_parent']],
483 + ) );
484 + }
485 + }
486 +
487 + // Flush the GamiPress cache
488 + gamipress_flush_cache();
489 +
490 + // Return a success message
491 + wp_send_json_success( __( 'Setup has been imported successfully.', 'gamipress' ) );
492 +
493 +}
494 +add_action( 'wp_ajax_gamipress_import_setup_tool', 'gamipress_ajax_import_setup_tool' );