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-achievements.php +416 -0 7.9.2 → 8.0.5 View file →
@@ -1,0 +1,416 @@
1 +<?php
2 +/**
3 + * Import/Export Achievements Tool
4 + *
5 + * @package GamiPress\Admin\Tools\Import_Export_Achievements
6 + * @author GamiPress <[email protected]>, Ruben Garcia <[email protected]>
7 + * @since 1.6.4
8 + */
9 +// Exit if accessed directly
10 +if( !defined( 'ABSPATH' ) ) exit;
11 +
12 +/**
13 + * Register Import/Export Achievements Tool meta boxes
14 + *
15 + * @since 1.6.4
16 + *
17 + * @param array $meta_boxes
18 + *
19 + * @return array
20 + */
21 +function gamipress_import_export_achievements_tool_meta_boxes( $meta_boxes ) {
22 +
23 + $meta_boxes['import-export-achievements'] = array(
24 + 'title' => gamipress_dashicon( 'awards' ) . __( 'User Achievements', 'gamipress' ),
25 + 'fields' => apply_filters( 'gamipress_import_export_achievements_tool_fields', array(
26 +
27 + // Export
28 +
29 + 'export_achievements_achievement_types' => array(
30 + 'name' => __( 'Achievement Types To Export', 'gamipress' ),
31 + 'tooltip' => __( 'Choose the achievement types to export.', 'gamipress' ),
32 + 'label_cb' => 'cmb_tooltip_label_cb',
33 + 'type' => 'multicheck',
34 + 'classes' => 'gamipress-switch',
35 + 'options_cb' => 'gamipress_options_cb_achievement_types',
36 + 'option_all' => false,
37 + ),
38 + 'export_achievements_user_field' => array(
39 + 'name' => __( 'User Field', 'gamipress' ),
40 + 'tooltip' => __( 'Choose the field to display on user column.', 'gamipress' ),
41 + 'label_cb' => 'cmb_tooltip_label_cb',
42 + 'type' => 'select',
43 + 'options' => array(
44 + 'id' => __( 'ID', 'gamipress' ),
45 + 'username' => __( 'Username', 'gamipress' ),
46 + 'email' => __( 'Email', 'gamipress' ),
47 + ),
48 + 'default' => 'email'
49 + ),
50 + 'export_achievements_achievement_field' => array(
51 + 'name' => __( 'Achievement Field', 'gamipress' ),
52 + 'tooltip' => __( 'Choose the field to display on achievements column.', 'gamipress' ),
53 + 'label_cb' => 'cmb_tooltip_label_cb',
54 + 'type' => 'select',
55 + 'options' => array(
56 + 'id' => __( 'ID', 'gamipress' ),
57 + 'title' => __( 'Title', 'gamipress' ),
58 + 'slug' => __( 'Slug', 'gamipress' ),
59 + ),
60 + 'default' => 'slug'
61 + ),
62 + 'export_achievements' => array(
63 + 'label' => __( 'Export User Achievements', 'gamipress' ),
64 + 'type' => 'button',
65 + 'icon' => 'dashicons-download',
66 + 'button' => 'primary',
67 + 'action' => 'export_achievements'
68 +
69 + ),
70 +
71 + // Import
72 +
73 + 'import_achievements_file' => array(
74 + 'name' => __( 'CSV File', 'gamipress' ),
75 + 'type' => 'text',
76 + 'attributes' => array(
77 + 'type' => 'file',
78 + 'accept' => '.csv'
79 + )
80 + ),
81 + 'import_actions' => array(
82 + 'type' => 'multi_buttons',
83 + 'buttons' => array(
84 + 'import_achievements' => array(
85 + 'label' => __( 'Import User Achievements', 'gamipress' ),
86 + 'type' => 'button',
87 + 'button' => 'primary',
88 + 'icon' => 'dashicons-upload',
89 + 'action' => 'import_achievements'
90 + ),
91 + 'download_achievements_csv_template' => array(
92 + 'label' => __( 'Download CSV Template', 'gamipress' ),
93 + 'type' => 'button',
94 + 'icon' => 'dashicons-media-spreadsheet',
95 + )
96 + ),
97 + ),
98 +
99 + ) ),
100 + 'vertical_tabs' => true,
101 + 'tabs' => apply_filters( 'gamipress_import_export_achievements_tool_tabs', array(
102 + 'export_achievements' => array(
103 + 'icon' => 'dashicons-download',
104 + 'title' => __( 'Export', 'gamipress' ),
105 + 'fields' => array(
106 + 'export_achievements_achievement_types',
107 + 'export_achievements_user_field',
108 + 'export_achievements_achievement_field',
109 + 'export_achievements',
110 + ),
111 + ),
112 + 'import_achievements' => array(
113 + 'icon' => 'dashicons-upload',
114 + 'title' => __( 'Import', 'gamipress' ),
115 + 'fields' => array(
116 + 'import_achievements_file',
117 + 'import_actions',
118 + ),
119 + ),
120 + ) )
121 + );
122 +
123 + return $meta_boxes;
124 +
125 +}
126 +add_filter( 'gamipress_tools_import_export_meta_boxes', 'gamipress_import_export_achievements_tool_meta_boxes' );
127 +
128 +/**
129 + * AJAX handler for the export achievements tool
130 + *
131 + * @since 1.6.4
132 + */
133 +function gamipress_import_export_achievements_tool_ajax_export() {
134 + // Security check, forces to die if not security passed
135 + check_ajax_referer( 'gamipress_admin', 'nonce' );
136 +
137 + global $wpdb;
138 +
139 + // Check user capabilities
140 + if( ! current_user_can( gamipress_get_manager_capability() ) ) {
141 + wp_send_json_error( __( 'You are not allowed to perform this action.', 'gamipress' ) );
142 + }
143 +
144 + // Setup vars
145 + $achievement_types = gamipress_get_achievement_types();
146 + $desired_achievement_types = ( isset( $_REQUEST['achievement_types'] ) ? $_REQUEST['achievement_types'] : array() );
147 + $user_field = ( isset( $_REQUEST['user_field'] ) ? sanitize_text_field( $_REQUEST['user_field'] ) : 'email' );
148 + $achievement_field = ( isset( $_REQUEST['achievement_field'] ) ? sanitize_text_field( $_REQUEST['achievement_field'] ) : 'slug' );
149 + $loop = ( isset( $_REQUEST['loop'] ) ? absint( $_REQUEST['loop'] ) : 0 );
150 + $limit = 200;
151 + $offset = $limit * $loop;
152 + $items_to_export = array();
153 +
154 + if( $loop === 0 ) {
155 + // Set the CSV headers
156 + $items_to_export[] = array(
157 + 'user' => __( 'User', 'gamipress' ),
158 + 'achievements' => __( 'Achievements', 'gamipress' ),
159 + 'achievement_type' => __( 'Achievements Type (slug)', 'gamipress' ),
160 + );
161 + }
162 +
163 + // Check the achievement types received
164 + if( empty( $desired_achievement_types ) ) {
165 + wp_send_json_error( __( 'You need to choose at least 1 achievement type to export.', 'gamipress' ) );
166 + }
167 +
168 + ignore_user_abort( true );
169 +
170 + if ( ! gamipress_is_function_disabled( 'set_time_limit' ) ) {
171 + set_time_limit( 0 );
172 + }
173 +
174 + // Get stored users
175 + $users = gamipress_get_users( array(
176 + 'offset' => $offset,
177 + 'limit' => $limit,
178 + ) );
179 +
180 + if( empty( $users ) ) {
181 + // Return a success message
182 + wp_send_json_success( __( 'User\'s achievements export process has been done successfully.', 'gamipress' ) );
183 + }
184 +
185 + // Let's to get the data from our users
186 + foreach( $users as $user ) {
187 +
188 + $user_column = '';
189 +
190 + switch( $user_field ) {
191 + case 'id':
192 + $user_column = $user->ID;
193 + break;
194 + case 'username':
195 + $user_column = $user->user_login;
196 + break;
197 + case 'email':
198 + $user_column = $user->user_email;
199 + break;
200 + }
201 +
202 + foreach( $desired_achievement_types as $achievement_type ) {
203 +
204 + // Skip not registered achievement types
205 + if( ! isset( $achievement_types[$achievement_type] ) )
206 + continue;
207 +
208 + $user_achievements = gamipress_get_user_achievements( array(
209 + 'user_id' => $user->ID,
210 + 'achievement_type' => $achievement_type,
211 + ) );
212 +
213 + if( $user_achievements ) {
214 +
215 + $achievements = array();
216 +
217 + // Loop all user achievements to build an array of desired achievement field to be imploded by comma
218 + foreach( $user_achievements as $user_achievement ) {
219 +
220 + switch( $achievement_field ) {
221 + case 'id':
222 + $achievements[] = $user_achievement->ID;
223 + break;
224 + case 'title':
225 + $achievement = gamipress_get_post( $user_achievement->ID );
226 + $achievements[] = $achievement->post_title;
227 + break;
228 + case 'slug':
229 + $achievement = gamipress_get_post( $user_achievement->ID );
230 + $achievements[] = $achievement->post_name;
231 + break;
232 + }
233 +
234 + }
235 +
236 + // Export a row per achievement type
237 + $items_to_export[] = array(
238 + 'user' => $user_column,
239 + 'achievements' => implode( ',', $achievements ),
240 + 'achievement_type' => $achievement_type,
241 + );
242 + }
243 +
244 + }
245 +
246 + }
247 +
248 + $exported_users = $limit * ( $loop + 1 );
249 +
250 + // Get the users count
251 + $users_count = gamipress_get_users_count();
252 +
253 + $total = $users_count - $exported_users;
254 +
255 + if( $total > 0 ) {
256 + // Return a run again message
257 + wp_send_json_success( array(
258 + 'run_again' => true,
259 + 'items' => $items_to_export,
260 + 'message' => sprintf( __( '%d remaining users', 'gamipress' ), ( $users_count - $exported_users ) ),
261 + ) );
262 + } else {
263 + // Return a run again message
264 + wp_send_json_success( array(
265 + 'run_again' => false,
266 + 'items' => $items_to_export,
267 + 'message' => __( 'User\'s achievements export process has been done successfully.', 'gamipress' ),
268 + ) );
269 + }
270 +
271 +}
272 +add_action( 'wp_ajax_gamipress_import_export_achievements_tool_export', 'gamipress_import_export_achievements_tool_ajax_export' );
273 +
274 +
275 +/**
276 + * AJAX handler for the import achievements tool
277 + *
278 + * @since 1.6.4
279 + */
280 +function gamipress_import_export_achievements_tool_ajax_import() {
281 + // Security check, forces to die if not security passed
282 + check_ajax_referer( 'gamipress_admin', 'nonce' );
283 +
284 + global $wpdb;
285 +
286 + // Check user capabilities
287 + if( ! current_user_can( gamipress_get_manager_capability() ) ) {
288 + wp_send_json_error( __( 'You are not allowed to perform this action.', 'gamipress' ) );
289 + }
290 +
291 + // Check parameters received
292 + if( ! isset( $_FILES['file'] ) ) {
293 + wp_send_json_error( __( 'No file to import.', 'gamipress' ) );
294 + }
295 +
296 + $import_file = $_FILES['file']['tmp_name'];
297 +
298 + if( empty( $import_file ) ) {
299 + wp_send_json_error( __( 'Can\'t retrieve the file to import, check server file permissions.', 'gamipress' ) );
300 + }
301 +
302 + ignore_user_abort( true );
303 +
304 + if ( ! gamipress_is_function_disabled( 'set_time_limit' ) ) {
305 + set_time_limit( 0 );
306 + }
307 +
308 + // Retrieve the content from the file
309 + $file_contents = file_get_contents( $import_file );
310 +
311 + if( empty( $file_contents ) ) {
312 + wp_send_json_error( __( 'Empty file, so nothing to import.', 'gamipress' ) );
313 + }
314 +
315 + // Setup vars
316 + $posts = GamiPress()->db->posts;
317 + $achievement_types = gamipress_get_achievement_types_slugs();
318 + $post_type_where = "AND post_type IN('" . implode( "', '", $achievement_types ) . "')";
319 +
320 + // Explode by line breaks
321 + $lines = explode( "\n", $file_contents );
322 +
323 + foreach( $lines as $number => $line ) {
324 +
325 + $columns = str_getcsv( $line );
326 +
327 + if( count( $columns ) >= 2 ) {
328 +
329 + $user = false;
330 + $achievements = array();
331 +
332 + // User
333 + if( isset( $columns[0] ) && ! empty( $columns[0] ) ) {
334 +
335 + $user_field = 'login';
336 +
337 + if( filter_var( $columns[0], FILTER_VALIDATE_EMAIL ) ) {
338 + $user_field = 'email';
339 + } else if( is_numeric( $columns[0] ) ) {
340 + $user_field = 'id';
341 + }
342 +
343 + $user = get_user_by( $user_field, $columns[0] );
344 +
345 + }
346 +
347 + // Achievements
348 + if( isset( $columns[1] ) && ! empty( $columns[1] ) ) {
349 +
350 + $achievements = explode( ',', $columns[1] );
351 +
352 + }
353 +
354 + // Check if everything is done
355 + if( $user && count( $achievements ) > 0 ) {
356 +
357 + // Loop all achievements that will be awarded
358 + foreach( $achievements as $achievement ) {
359 +
360 + $revoke = false;
361 +
362 + // If achievement has a negative sign, then user is looking to revoke
363 + if ( substr( $achievement, 0, 1 ) === '-') {
364 + $revoke = true;
365 + $achievement = substr( $achievement, 1); // Remove the negative sign
366 + }
367 +
368 + if( is_numeric( $achievement ) ) {
369 +
370 + // Search by ID
371 + $achievement_post = gamipress_get_post( $achievement );
372 +
373 + } else {
374 +
375 + // Search by title
376 + $achievement_post = $wpdb->get_row( $wpdb->prepare(
377 + "SELECT * FROM {$posts} WHERE post_title = %s {$post_type_where}",
378 + $achievement
379 + ) );
380 +
381 + if( ! $achievement_post ) {
382 + // Search by slug
383 + $achievement_post = $wpdb->get_row( $wpdb->prepare(
384 + "SELECT * FROM {$posts} WHERE post_name = %s {$post_type_where}",
385 + $achievement
386 + ) );
387 +
388 + }
389 +
390 + }
391 +
392 + // Check if post object is an achievement
393 + if( $achievement_post && gamipress_is_achievement( $achievement_post ) ) {
394 +
395 + if( $revoke ) {
396 + // Revoke the achievement to the user
397 + gamipress_revoke_achievement_to_user( $achievement_post->ID, $user->ID );
398 + } else {
399 + // Award the achievement to the user
400 + gamipress_award_achievement_to_user( $achievement_post->ID, $user->ID, get_current_user_id() );
401 + }
402 +
403 +
404 + }
405 + }
406 +
407 + }
408 +
409 + }
410 +
411 + }
412 +
413 + // Return a success message
414 + wp_send_json_success( __( 'Achievements has been awarded successfully to all users.', 'gamipress' ) );
415 +}
416 +add_action( 'wp_ajax_gamipress_import_export_achievements_tool_import', 'gamipress_import_export_achievements_tool_ajax_import' );