, Ruben Garcia * @since 2.0.3 */ // Exit if accessed directly if( !defined( 'ABSPATH' ) ) exit; /** * Register Import/Export Achievements Tool meta boxes * * @since 2.0.3 * * @param array $meta_boxes * * @return array */ function gamipress_import_export_earnings_tool_meta_boxes( $meta_boxes ) { // Setup vars $points_types = gamipress_get_points_types(); $achievement_types = gamipress_get_achievement_types(); $rank_types = gamipress_get_rank_types(); $options = array(); // Points types options if( count( $points_types ) ) $options['all-points-types'] = __( 'All Points Types', 'gamipress' ); foreach( $points_types as $slug => $data ) { $options[$slug . '-points-type'] = '' . $data['plural_name'] . ''; $options[$slug . '-points-awards'] = __( 'Points Awards', 'gamipress' ); $options[$slug . '-points-deducts'] = __( 'Points Deductions', 'gamipress' ); } // Achievement types options if( count( $achievement_types ) ) $options['all-achievement-types'] = __( 'All Achievement Types', 'gamipress' ); foreach( $achievement_types as $slug => $data ) { $options[$slug . '-achievement-type'] = '' . $data['singular_name'] . ''; $options[$slug . '-achievements'] = __( 'Achievements', 'gamipress' ); $options[$slug . '-steps'] = __( 'Steps', 'gamipress' ); } // Rank types options if( count( $rank_types ) ) $options['all-rank-types'] = __( 'All Rank Types', 'gamipress' ); foreach( $rank_types as $slug => $data ) { $options[$slug . '-rank-type'] = '' . $data['singular_name'] . ''; $options[$slug . '-ranks'] = __( 'Ranks', 'gamipress' ); $options[$slug . '-rank-requirements'] = __( 'Requirements', 'gamipress' ); } $meta_boxes['import-export-earnings'] = array( 'title' => gamipress_dashicon( 'awards' ) . __( 'Export User Earnings', 'gamipress' ), 'fields' => apply_filters( 'gamipress_import_export_earnings_tool_fields', array( 'export_earnings_types' => array( 'name' => __( 'Earnings Types To Export', 'gamipress' ), 'tooltip' => __( 'Choose the earnings types to export.', 'gamipress' ), 'label_cb' => 'cmb_tooltip_label_cb', 'type' => 'multicheck', 'classes' => 'gamipress-switch gamipress-all-types-multicheck', 'options' => $options, ), 'export_earnings_user_field' => array( 'name' => __( 'User Field', 'gamipress' ), 'tooltip' => __( 'Choose the field to display on user column.', 'gamipress' ), 'label_cb' => 'cmb_tooltip_label_cb', 'type' => 'select', 'options' => array( 'id' => __( 'ID', 'gamipress' ), 'username' => __( 'Username', 'gamipress' ), 'email' => __( 'Email', 'gamipress' ), ), 'default' => 'email' ), 'export_earnings_post_field' => array( 'name' => __( 'Element Field', 'gamipress' ), 'tooltip' => __( 'Choose the field to display for the element (achievement, step, rank, etc) assigned to the earning.', 'gamipress' ), 'label_cb' => 'cmb_tooltip_label_cb', 'type' => 'select', 'options' => array( 'id' => __( 'ID', 'gamipress' ), 'title' => __( 'Title', 'gamipress' ), 'slug' => __( 'Slug', 'gamipress' ), ), 'default' => 'slug' ), 'export_earnings_from' => array( 'name' => __( 'From (Optional)', 'gamipress' ), 'tooltip' => __( 'Choose the date from you want to export. User earnings registered after this date will be exported.', 'gamipress' ) . '
' . __( 'Leave blank to no filter by this date.', 'gamipress' ), 'label_cb' => 'cmb_tooltip_label_cb', 'type' => 'text_date_timestamp', ), 'export_earnings_to' => array( 'name' => __( 'To (Optional)', 'gamipress' ), 'tooltip' => __( 'Choose the date until you want to export. User earnings registered before this date will be exported.', 'gamipress' ) . '
' . __( 'Leave blank to no filter by this date.', 'gamipress' ), 'label_cb' => 'cmb_tooltip_label_cb', 'type' => 'text_date_timestamp', ), 'export_earnings' => array( 'label' => __( 'Export User Earnings', 'gamipress' ), 'type' => 'button', 'icon' => 'dashicons-download', 'button' => 'primary', 'action' => 'export_earnings' ), ) ), ); return $meta_boxes; } add_filter( 'gamipress_tools_import_export_meta_boxes', 'gamipress_import_export_earnings_tool_meta_boxes' ); /** * AJAX handler for the export earnings tool * * @since 2.0.3 */ function gamipress_import_export_earnings_tool_ajax_export() { // Security check, forces to die if not security passed check_ajax_referer( 'gamipress_admin', 'nonce' ); global $wpdb; // Check user capabilities if( ! current_user_can( gamipress_get_manager_capability() ) ) { wp_send_json_error( __( 'You are not allowed to perform this action.', 'gamipress' ) ); } // Setup types $points_types = gamipress_get_points_types(); $achievement_types = gamipress_get_achievement_types(); $rank_types = gamipress_get_rank_types(); $points_types_slugs = gamipress_get_points_types_slugs(); $achievement_types_slugs = gamipress_get_achievement_types_slugs(); $rank_types_slugs = gamipress_get_rank_types_slugs(); $all_types = array_merge( $points_types, $achievement_types, $rank_types ); $all_types_slugs = array_merge( $points_types_slugs, $achievement_types_slugs, $rank_types_slugs ); $suffixes = array( '-points-type', '-points-awards', '-points-deducts', '-achievement-type', '-achievements', '-steps', '-rank-type', '-ranks', '-rank-requirements', ); // Setup vars $types = ( isset( $_REQUEST['types'] ) ? $_REQUEST['types'] : array() ); $user_field = ( isset( $_REQUEST['user_field'] ) ? sanitize_text_field( $_REQUEST['user_field'] ) : 'email' ); $post_field = ( isset( $_REQUEST['post_field'] ) ? sanitize_text_field( $_REQUEST['post_field'] ) : 'slug' ); $from = ( isset( $_REQUEST['from'] ) ? sanitize_text_field( $_REQUEST['from'] ) : '' ); $to = ( isset( $_REQUEST['to'] ) ? sanitize_text_field( $_REQUEST['to'] ) : '' ); // Setup from if( $from !== '' && strtotime( $from ) === false ) { $from = ''; } // Setup to if( $to !== '' && strtotime( $to ) === false ) { $to = ''; } if( $to !== '' ) { $to = date( 'Y-m-d 23:59:59', strtotime( $to ) ); } $post_types = array(); $points_types = array( '' ); // Add an empty points type for elements without a points type foreach( $types as $type ) { foreach( $suffixes as $suffix ) { // If option does not ends with one of suffixes then is not correct if( ! gamipress_ends_with( $type, $suffix ) ) { continue; } // Remove the suffix to get the type $type = str_replace( $suffix, '', $type ); // Skip if not is a registered type option if( ! in_array( $type, $all_types_slugs ) ) { continue; } switch( $suffix ) { case '-points-type': case '-achievement-type': case '-rank-type': case '-achievements': case '-ranks': // Add the post type $post_types[] = $type; if( $suffix === '-points-type' ) { $post_types[] = 'points-type'; // To include manual awards/deductions $points_types[] = $type; } break; case '-points-awards': case '-points-deducts': case '-steps': case '-rank-requirements': // Remove first "-" $post_type = substr( $suffix, 1 ); // Remove last "s" $post_type = rtrim( $post_type, 's' ); // Add the post type $post_types[] = $post_type; break; } } } // Check the achievement types received if( empty( $post_types ) ) { wp_send_json_error( __( 'You need to choose at least 1 type to export.', 'gamipress' ) ); } ignore_user_abort( true ); if ( ! gamipress_is_function_disabled( 'set_time_limit' ) ) { set_time_limit( 0 ); } $loop = ( isset( $_REQUEST['loop'] ) ? absint( $_REQUEST['loop'] ) : 0 ); $limit = 200; $offset = $limit * $loop; $items_to_export = array(); if( $loop === 0 ) { // Set the CSV headers $items_to_export[] = array( 'title' => __( 'Description', 'gamipress' ), 'user' => __( 'User', 'gamipress' ), 'post' => __( 'Element', 'gamipress' ), 'post_type' => __( 'Element Type', 'gamipress' ), 'points' => __( 'Points', 'gamipress' ), 'points_type' => __( 'Points Type', 'gamipress' ), 'date' => __( 'Date', 'gamipress' ), ); } $query = array( 'post_type' => $post_types, 'points_type' => $points_types, 'after' => $from, 'before' => $to, ); $where = gamipress_get_earnings_where( $query ); // Merge all wheres $where = implode( ' AND ', $where ); $user_earnings = GamiPress()->db->user_earnings; if( ! gamipress_is_network_wide_active() ) { // Get users earnings from the current site $earnings = $wpdb->get_results( "SELECT * FROM {$user_earnings} AS ue LEFT JOIN {$wpdb->usermeta} AS umcap ON ( umcap.user_id = ue.user_id ) WHERE {$where} AND umcap.meta_key = '" . $wpdb->get_blog_prefix() . "capabilities' ORDER BY ue.date DESC LIMIT {$offset}, {$limit}" ); } else { // Get all stored user earnings $earnings = $wpdb->get_results( "SELECT * FROM {$user_earnings} AS ue WHERE {$where} ORDER BY ue.date DESC LIMIT {$offset}, {$limit}" ); } if( empty( $earnings ) ) { // Return a success message wp_send_json_success( __( 'User\'s earnings export process has been done successfully.', 'gamipress' ) ); } // Let's to setup the items to export foreach( $earnings as $earning ) { $user_column = ''; $user = get_userdata( $earning->user_id ); switch( $user_field ) { case 'id': $user_column = ( $user ? $user->ID : '' ); break; case 'username': $user_column = ( $user ? $user->user_login : '' ); break; case 'email': $user_column = ( $user ? $user->user_email : '' ); break; } $post_column = ''; $post = gamipress_get_post( $earning->post_id ); switch( $post_field ) { case 'id': $post_column = ( $post ? $post->ID : '' ); break; case 'title': $post_column = ( $post ? $post->post_title : '' ); break; case 'slug': $post_column = ( $post ? $post->post_name : '' ); break; } // Export a row per achievement type $items_to_export[] = array( 'title' => $earning->title, 'user' => $user_column, 'post' => $post_column, 'post_type' => $earning->post_type, 'points' => $earning->points, 'points_type' => $earning->points_type, 'date' => $earning->date ); } $exported_earnings = $limit * ( $loop + 1 ); if( ! gamipress_is_network_wide_active() ) { // Count users earnings from the current site $earnings_count = absint( $wpdb->get_var( "SELECT COUNT(*) FROM {$user_earnings} AS ue LEFT JOIN {$wpdb->usermeta} AS umcap ON ( umcap.user_id = ue.user_id ) WHERE {$where} AND umcap.meta_key = '" . $wpdb->get_blog_prefix() . "capabilities' ORDER BY ue.date DESC" ) ); } else { // Count all stored user earnings $earnings_count = absint( $wpdb->get_var( "SELECT COUNT(*) FROM {$user_earnings} AS ue WHERE {$where} ORDER BY ue.date DESC" ) ); } $total = $earnings_count - $exported_earnings; if( $total > 0 ) { // Return a run again message wp_send_json_success( array( 'run_again' => true, 'items' => $items_to_export, 'message' => sprintf( __( '%d remaining earnings', 'gamipress' ), ( $earnings_count - $exported_earnings ) ), ) ); } else { // Return a run again message wp_send_json_success( array( 'run_again' => false, 'items' => $items_to_export, 'message' => __( 'User\'s earnings export process has been done successfully.', 'gamipress' ), ) ); } } add_action( 'wp_ajax_gamipress_import_export_earnings_tool_export', 'gamipress_import_export_earnings_tool_ajax_export' );