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-earnings.php +375 -0 7.9.1 → 8.0.5 View file →
@@ -1,0 +1,375 @@
1 +<?php
2 +/**
3 + * Import/Export Earnings Tool
4 + *
5 + * @package GamiPress\Admin\Tools\Import_Export_Earnings
6 + * @author GamiPress <[email protected]>, Ruben Garcia <[email protected]>
7 + * @since 2.0.3
8 + */
9 +// Exit if accessed directly
10 +if( !defined( 'ABSPATH' ) ) exit;
11 +
12 +/**
13 + * Register Import/Export Achievements Tool meta boxes
14 + *
15 + * @since 2.0.3
16 + *
17 + * @param array $meta_boxes
18 + *
19 + * @return array
20 + */
21 +function gamipress_import_export_earnings_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-earnings'] = array(
58 + 'title' => gamipress_dashicon( 'awards' ) . __( 'Export User Earnings', 'gamipress' ),
59 + 'fields' => apply_filters( 'gamipress_import_export_earnings_tool_fields', array(
60 + 'export_earnings_types' => array(
61 + 'name' => __( 'Earnings Types To Export', 'gamipress' ),
62 + 'tooltip' => __( 'Choose the earnings types to export.', 'gamipress' ),
63 + 'label_cb' => 'cmb_tooltip_label_cb',
64 + 'type' => 'multicheck',
65 + 'classes' => 'gamipress-switch gamipress-all-types-multicheck',
66 + 'options' => $options,
67 + ),
68 + 'export_earnings_user_field' => array(
69 + 'name' => __( 'User Field', 'gamipress' ),
70 + 'tooltip' => __( 'Choose the field to display on user column.', 'gamipress' ),
71 + 'label_cb' => 'cmb_tooltip_label_cb',
72 + 'type' => 'select',
73 + 'options' => array(
74 + 'id' => __( 'ID', 'gamipress' ),
75 + 'username' => __( 'Username', 'gamipress' ),
76 + 'email' => __( 'Email', 'gamipress' ),
77 + ),
78 + 'default' => 'email'
79 + ),
80 + 'export_earnings_post_field' => array(
81 + 'name' => __( 'Element Field', 'gamipress' ),
82 + 'tooltip' => __( 'Choose the field to display for the element (achievement, step, rank, etc) assigned to the earning.', 'gamipress' ),
83 + 'label_cb' => 'cmb_tooltip_label_cb',
84 + 'type' => 'select',
85 + 'options' => array(
86 + 'id' => __( 'ID', 'gamipress' ),
87 + 'title' => __( 'Title', 'gamipress' ),
88 + 'slug' => __( 'Slug', 'gamipress' ),
89 + ),
90 + 'default' => 'slug'
91 + ),
92 + 'export_earnings_from' => array(
93 + 'name' => __( 'From (Optional)', 'gamipress' ),
94 + 'tooltip' => __( 'Choose the date from you want to export. User earnings registered <strong>after</strong> this date will be exported.', 'gamipress' )
95 + . '<br>' . __( 'Leave blank to no filter by this date.', 'gamipress' ),
96 + 'label_cb' => 'cmb_tooltip_label_cb',
97 + 'type' => 'text_date_timestamp',
98 + ),
99 + 'export_earnings_to' => array(
100 + 'name' => __( 'To (Optional)', 'gamipress' ),
101 + 'tooltip' => __( 'Choose the date until you want to export. User earnings registered <strong>before</strong> this date will be exported.', 'gamipress' )
102 + . '<br>' . __( 'Leave blank to no filter by this date.', 'gamipress' ),
103 + 'label_cb' => 'cmb_tooltip_label_cb',
104 + 'type' => 'text_date_timestamp',
105 + ),
106 + 'export_earnings' => array(
107 + 'label' => __( 'Export User Earnings', 'gamipress' ),
108 + 'type' => 'button',
109 + 'icon' => 'dashicons-download',
110 + 'button' => 'primary',
111 + 'action' => 'export_earnings'
112 + ),
113 + ) ),
114 + );
115 +
116 + return $meta_boxes;
117 +
118 +}
119 +add_filter( 'gamipress_tools_import_export_meta_boxes', 'gamipress_import_export_earnings_tool_meta_boxes' );
120 +
121 +/**
122 + * AJAX handler for the export earnings tool
123 + *
124 + * @since 2.0.3
125 + */
126 +function gamipress_import_export_earnings_tool_ajax_export() {
127 + // Security check, forces to die if not security passed
128 + check_ajax_referer( 'gamipress_admin', 'nonce' );
129 +
130 + global $wpdb;
131 +
132 + // Check user capabilities
133 + if( ! current_user_can( gamipress_get_manager_capability() ) ) {
134 + wp_send_json_error( __( 'You are not allowed to perform this action.', 'gamipress' ) );
135 + }
136 +
137 + // Setup types
138 + $points_types = gamipress_get_points_types();
139 + $achievement_types = gamipress_get_achievement_types();
140 + $rank_types = gamipress_get_rank_types();
141 + $points_types_slugs = gamipress_get_points_types_slugs();
142 + $achievement_types_slugs = gamipress_get_achievement_types_slugs();
143 + $rank_types_slugs = gamipress_get_rank_types_slugs();
144 + $all_types = array_merge( $points_types, $achievement_types, $rank_types );
145 + $all_types_slugs = array_merge( $points_types_slugs, $achievement_types_slugs, $rank_types_slugs );
146 + $suffixes = array(
147 + '-points-type',
148 + '-points-awards',
149 + '-points-deducts',
150 + '-achievement-type',
151 + '-achievements',
152 + '-steps',
153 + '-rank-type',
154 + '-ranks',
155 + '-rank-requirements',
156 + );
157 +
158 + // Setup vars
159 + $types = ( isset( $_REQUEST['types'] ) ? $_REQUEST['types'] : array() );
160 + $user_field = ( isset( $_REQUEST['user_field'] ) ? sanitize_text_field( $_REQUEST['user_field'] ) : 'email' );
161 + $post_field = ( isset( $_REQUEST['post_field'] ) ? sanitize_text_field( $_REQUEST['post_field'] ) : 'slug' );
162 + $from = ( isset( $_REQUEST['from'] ) ? sanitize_text_field( $_REQUEST['from'] ) : '' );
163 + $to = ( isset( $_REQUEST['to'] ) ? sanitize_text_field( $_REQUEST['to'] ) : '' );
164 +
165 + // Setup from
166 + if( $from !== '' && strtotime( $from ) === false ) {
167 + $from = '';
168 + }
169 +
170 + // Setup to
171 + if( $to !== '' && strtotime( $to ) === false ) {
172 + $to = '';
173 + }
174 +
175 + if( $to !== '' ) {
176 + $to = date( 'Y-m-d 23:59:59', strtotime( $to ) );
177 + }
178 +
179 + $post_types = array();
180 + $points_types = array( '' ); // Add an empty points type for elements without a points type
181 +
182 + foreach( $types as $type ) {
183 +
184 + foreach( $suffixes as $suffix ) {
185 +
186 + // If option does not ends with one of suffixes then is not correct
187 + if( ! gamipress_ends_with( $type, $suffix ) ) {
188 + continue;
189 + }
190 +
191 + // Remove the suffix to get the type
192 + $type = str_replace( $suffix, '', $type );
193 +
194 + // Skip if not is a registered type option
195 + if( ! in_array( $type, $all_types_slugs ) ) {
196 + continue;
197 + }
198 +
199 + switch( $suffix ) {
200 + case '-points-type':
201 + case '-achievement-type':
202 + case '-rank-type':
203 + case '-achievements':
204 + case '-ranks':
205 + // Add the post type
206 + $post_types[] = $type;
207 +
208 + if( $suffix === '-points-type' ) {
209 + $post_types[] = 'points-type'; // To include manual awards/deductions
210 + $points_types[] = $type;
211 + }
212 + break;
213 + case '-points-awards':
214 + case '-points-deducts':
215 + case '-steps':
216 + case '-rank-requirements':
217 + // Remove first "-"
218 + $post_type = substr( $suffix, 1 );
219 + // Remove last "s"
220 + $post_type = rtrim( $post_type, 's' );
221 +
222 + // Add the post type
223 + $post_types[] = $post_type;
224 + break;
225 + }
226 +
227 + }
228 +
229 + }
230 +
231 + // Check the achievement types received
232 + if( empty( $post_types ) ) {
233 + wp_send_json_error( __( 'You need to choose at least 1 type to export.', 'gamipress' ) );
234 + }
235 +
236 + ignore_user_abort( true );
237 +
238 + if ( ! gamipress_is_function_disabled( 'set_time_limit' ) ) {
239 + set_time_limit( 0 );
240 + }
241 +
242 + $loop = ( isset( $_REQUEST['loop'] ) ? absint( $_REQUEST['loop'] ) : 0 );
243 + $limit = 200;
244 + $offset = $limit * $loop;
245 + $items_to_export = array();
246 +
247 + if( $loop === 0 ) {
248 + // Set the CSV headers
249 + $items_to_export[] = array(
250 + 'title' => __( 'Description', 'gamipress' ),
251 + 'user' => __( 'User', 'gamipress' ),
252 + 'post' => __( 'Element', 'gamipress' ),
253 + 'post_type' => __( 'Element Type', 'gamipress' ),
254 + 'points' => __( 'Points', 'gamipress' ),
255 + 'points_type' => __( 'Points Type', 'gamipress' ),
256 + 'date' => __( 'Date', 'gamipress' ),
257 + );
258 + }
259 +
260 + $query = array(
261 + 'post_type' => $post_types,
262 + 'points_type' => $points_types,
263 + 'after' => $from,
264 + 'before' => $to,
265 + );
266 +
267 + $where = gamipress_get_earnings_where( $query );
268 +
269 + // Merge all wheres
270 + $where = implode( ' AND ', $where );
271 +
272 + $user_earnings = GamiPress()->db->user_earnings;
273 +
274 + if( ! gamipress_is_network_wide_active() ) {
275 + // Get users earnings from the current site
276 + $earnings = $wpdb->get_results(
277 + "SELECT *
278 + FROM {$user_earnings} AS ue
279 + LEFT JOIN {$wpdb->usermeta} AS umcap ON ( umcap.user_id = ue.user_id )
280 + WHERE {$where} AND umcap.meta_key = '" . $wpdb->get_blog_prefix() . "capabilities'
281 + ORDER BY ue.date DESC
282 + LIMIT {$offset}, {$limit}"
283 + );
284 + } else {
285 + // Get all stored user earnings
286 + $earnings = $wpdb->get_results( "SELECT * FROM {$user_earnings} AS ue WHERE {$where} ORDER BY ue.date DESC LIMIT {$offset}, {$limit}" );
287 + }
288 +
289 + if( empty( $earnings ) ) {
290 + // Return a success message
291 + wp_send_json_success( __( 'User\'s earnings export process has been done successfully.', 'gamipress' ) );
292 + }
293 +
294 + // Let's to setup the items to export
295 + foreach( $earnings as $earning ) {
296 +
297 + $user_column = '';
298 + $user = get_userdata( $earning->user_id );
299 +
300 + switch( $user_field ) {
301 + case 'id':
302 + $user_column = ( $user ? $user->ID : '' );
303 + break;
304 + case 'username':
305 + $user_column = ( $user ? $user->user_login : '' );
306 + break;
307 + case 'email':
308 + $user_column = ( $user ? $user->user_email : '' );
309 + break;
310 + }
311 +
312 + $post_column = '';
313 + $post = gamipress_get_post( $earning->post_id );
314 +
315 + switch( $post_field ) {
316 + case 'id':
317 + $post_column = ( $post ? $post->ID : '' );
318 + break;
319 + case 'title':
320 + $post_column = ( $post ? $post->post_title : '' );
321 + break;
322 + case 'slug':
323 + $post_column = ( $post ? $post->post_name : '' );
324 + break;
325 + }
326 +
327 + // Export a row per achievement type
328 + $items_to_export[] = array(
329 + 'title' => $earning->title,
330 + 'user' => $user_column,
331 + 'post' => $post_column,
332 + 'post_type' => $earning->post_type,
333 + 'points' => $earning->points,
334 + 'points_type' => $earning->points_type,
335 + 'date' => $earning->date
336 + );
337 +
338 + }
339 +
340 + $exported_earnings = $limit * ( $loop + 1 );
341 +
342 + if( ! gamipress_is_network_wide_active() ) {
343 + // Count users earnings from the current site
344 + $earnings_count = absint( $wpdb->get_var(
345 + "SELECT COUNT(*)
346 + FROM {$user_earnings} AS ue
347 + LEFT JOIN {$wpdb->usermeta} AS umcap ON ( umcap.user_id = ue.user_id )
348 + WHERE {$where} AND umcap.meta_key = '" . $wpdb->get_blog_prefix() . "capabilities'
349 + ORDER BY ue.date DESC"
350 + ) );
351 + } else {
352 + // Count all stored user earnings
353 + $earnings_count = absint( $wpdb->get_var( "SELECT COUNT(*) FROM {$user_earnings} AS ue WHERE {$where} ORDER BY ue.date DESC" ) );
354 + }
355 +
356 + $total = $earnings_count - $exported_earnings;
357 +
358 + if( $total > 0 ) {
359 + // Return a run again message
360 + wp_send_json_success( array(
361 + 'run_again' => true,
362 + 'items' => $items_to_export,
363 + 'message' => sprintf( __( '%d remaining earnings', 'gamipress' ), ( $earnings_count - $exported_earnings ) ),
364 + ) );
365 + } else {
366 + // Return a run again message
367 + wp_send_json_success( array(
368 + 'run_again' => false,
369 + 'items' => $items_to_export,
370 + 'message' => __( 'User\'s earnings export process has been done successfully.', 'gamipress' ),
371 + ) );
372 + }
373 +
374 +}
375 +add_action( 'wp_ajax_gamipress_import_export_earnings_tool_export', 'gamipress_import_export_earnings_tool_ajax_export' );