, Ruben Garcia * @since 1.4.1 */ // Exit if accessed directly if( !defined( 'ABSPATH' ) ) exit; /** * Register Bulk Awards Tool meta boxes * * @since 1.4.1 * * @param array $meta_boxes * * @return array */ function gamipress_bulk_awards_tool_meta_boxes( $meta_boxes ) { // Grab our points types as an array $points_types_options = array( '' => __( 'Choose a points type', 'gamipress' ) ); foreach( gamipress_get_points_types() as $slug => $data ) { $points_types_options[$slug] = $data['plural_name']; } // Grab our requirement types as an array $requirement_types_options = array( '' => __( 'Choose a requirement type', 'gamipress' ) ); foreach( gamipress_get_requirement_types() as $slug => $data ) { $requirement_types_options[$slug] = $data['singular_name']; } $meta_boxes['bulk-awards'] = array( 'title' => gamipress_dashicon( 'yes' ) . __( 'Bulk Awards', 'gamipress' ), 'fields' => apply_filters( 'gamipress_bulk_awards_tool_fields', array( // Points 'bulk_award_points' => array( 'name' => __( 'Points to Award', 'gamipress' ), 'tooltip' => __( 'Points amount to award (the amount will be added to the current user balance).', 'gamipress' ), 'label_cb' => 'cmb_tooltip_label_cb', 'type' => 'text_small', 'default' => '0', ), 'bulk_award_points_type' => array( 'name' => __( 'Points Type', 'gamipress' ), 'tooltip' => __( 'Points type of points amount to award.', 'gamipress' ), 'label_cb' => 'cmb_tooltip_label_cb', 'type' => 'select', 'options' => $points_types_options ), 'bulk_award_points_register_movement' => array( 'name' => __( 'Register on user earnings', 'gamipress' ), 'tooltip' => __( 'Check this option to register this balance movement on user earnings.', 'gamipress' ), 'label_cb' => 'cmb_tooltip_label_cb', 'type' => 'checkbox', 'classes' => 'gamipress-switch' ), 'bulk_award_points_earnings_text' => array( 'name' => __( 'Earning entry text', 'gamipress' ), 'tooltip' => __( 'Enter the line text to be displayed on user earnings.', 'gamipress' ), 'label_cb' => 'cmb_tooltip_label_cb', 'type' => 'text', 'show_if' => array( 'bulk_award_points_register_movement' => 'checked' ), 'classes_cb' => 'cmb_conditional_fields_classes_cb', 'default' => __( 'Manual balance adjustment', 'gamipress' ), ), 'bulk_award_points_all_users' => array( 'name' => __( 'Award to all users', 'gamipress' ), 'tooltip' => __( 'Check this option to award the points amount to all users.', 'gamipress' ), 'label_cb' => 'cmb_tooltip_label_cb', 'type' => 'checkbox', 'classes' => 'gamipress-switch' ), 'bulk_award_points_users' => array( 'name' => __( 'Users to award', 'gamipress' ), 'tooltip' => __( 'Choose users to award this points amount.', 'gamipress' ), 'label_cb' => 'cmb_tooltip_label_cb', 'type' => 'advanced_select', 'multiple' => true, 'custom_classes' => 'gamipress-user-selector', 'attributes' => array( 'data-placeholder' => __( 'Choose users(s)', 'gamipress' ), 'data-close-on-select' => 'false', ), 'options_cb' => 'gamipress_options_cb_users', 'hide_if' => array( 'bulk_award_points_all_users' => 'checked' ), 'classes_cb' => 'cmb_conditional_fields_classes_cb', ), 'bulk_award_points_roles' => array( 'name' => __( 'Roles to award', 'gamipress' ), 'tooltip' => __( 'Choose roles to award this points amount.', 'gamipress' ), 'label_cb' => 'cmb_tooltip_label_cb', 'type' => 'advanced_select', 'multiple' => true, 'custom_classes' => 'gamipress-selector', 'attributes' => array( 'data-placeholder' => __( 'Choose role(s)', 'gamipress' ), 'data-close-on-select' => 'false', ), 'options_cb' => 'gamipress_options_cb_roles', 'hide_if' => array( 'bulk_award_points_all_users' => 'checked' ), 'classes_cb' => 'cmb_conditional_fields_classes_cb', ), 'bulk_award_points_button' => array( 'label' => __( 'Award Points', 'gamipress' ), 'type' => 'button', 'button' => 'primary' ), // Achievements 'bulk_award_achievements' => array( 'name' => __( 'Achievements to Award', 'gamipress' ), 'tooltip' => __( 'Choose the achievements to award.', 'gamipress' ), 'label_cb' => 'cmb_tooltip_label_cb', 'type' => 'advanced_select', 'multiple' => true, 'classes' => 'gamipress-post-selector', 'attributes' => array( 'data-post-type' => implode( ',', gamipress_get_achievement_types_slugs() ), 'data-placeholder' => __( 'Choose achievement(s)', 'gamipress' ), 'data-close-on-select' => 'false', ), 'options_cb' => 'gamipress_options_cb_posts', ), 'bulk_award_achievements_all_users' => array( 'name' => __( 'Award to all users', 'gamipress' ), 'tooltip' => __( 'Check this option to award the achievements to all users.', 'gamipress' ), 'label_cb' => 'cmb_tooltip_label_cb', 'type' => 'checkbox', 'classes' => 'gamipress-switch' ), 'bulk_award_achievements_users' => array( 'name' => __( 'Users to award', 'gamipress' ), 'tooltip' => __( 'Choose users to award this achievements.', 'gamipress' ), 'label_cb' => 'cmb_tooltip_label_cb', 'type' => 'advanced_select', 'multiple' => true, 'custom_classes' => 'gamipress-user-selector', 'attributes' => array( 'data-placeholder' => __( 'Choose users(s)', 'gamipress' ), 'data-close-on-select' => 'false', ), 'options_cb' => 'gamipress_options_cb_users', 'hide_if' => array( 'bulk_award_achievements_all_users' => 'checked' ), 'classes_cb' => 'cmb_conditional_fields_classes_cb', ), 'bulk_award_achievements_roles' => array( 'name' => __( 'Roles to award', 'gamipress' ), 'tooltip' => __( 'Choose roles to award this achievements.', 'gamipress' ), 'label_cb' => 'cmb_tooltip_label_cb', 'type' => 'advanced_select', 'multiple' => true, 'custom_classes' => 'gamipress-selector', 'attributes' => array( 'data-placeholder' => __( 'Choose role(s)', 'gamipress' ), 'data-close-on-select' => 'false', ), 'options_cb' => 'gamipress_options_cb_roles', 'hide_if' => array( 'bulk_award_achievements_all_users' => 'checked' ), 'classes_cb' => 'cmb_conditional_fields_classes_cb', ), 'bulk_award_achievements_button' => array( 'label' => __( 'Award Achievements', 'gamipress' ), 'type' => 'button', 'button' => 'primary' ), // Ranks 'bulk_award_rank' => array( 'name' => __( 'Rank to Award', 'gamipress' ), 'tooltip' => __( 'Choose the rank to award.', 'gamipress' ), 'label_cb' => 'cmb_tooltip_label_cb', 'desc' => __( 'Important! Users on higher rank will be downgrade to this rank.', 'gamipress' ), 'type' => 'advanced_select', 'classes' => 'gamipress-post-selector', 'attributes' => array( 'data-post-type' => implode( ',', gamipress_get_rank_types_slugs() ), 'data-placeholder' => __( 'Choose rank', 'gamipress' ), ), 'options_cb' => 'gamipress_options_cb_posts', ), 'bulk_award_rank_all_users' => array( 'name' => __( 'Award to all users', 'gamipress' ), 'tooltip' => __( 'Check this option to award the rank to all users.', 'gamipress' ), 'label_cb' => 'cmb_tooltip_label_cb', 'type' => 'checkbox', 'classes' => 'gamipress-switch' ), 'bulk_award_rank_users' => array( 'name' => __( 'Users to award', 'gamipress' ), 'tooltip' => __( 'Choose users to award this rank.', 'gamipress' ), 'label_cb' => 'cmb_tooltip_label_cb', 'type' => 'advanced_select', 'multiple' => true, 'custom_classes' => 'gamipress-user-selector', 'attributes' => array( 'data-placeholder' => __( 'Choose users(s)', 'gamipress' ), 'data-close-on-select' => 'false', ), 'options_cb' => 'gamipress_options_cb_users', 'hide_if' => array( 'bulk_award_rank_all_users' => 'checked' ), 'classes_cb' => 'cmb_conditional_fields_classes_cb', ), 'bulk_award_rank_roles' => array( 'name' => __( 'Roles to award', 'gamipress' ), 'tooltip' => __( 'Choose roles to award this rank.', 'gamipress' ), 'label_cb' => 'cmb_tooltip_label_cb', 'type' => 'advanced_select', 'multiple' => true, 'custom_classes' => 'gamipress-selector', 'attributes' => array( 'data-placeholder' => __( 'Choose role(s)', 'gamipress' ), 'data-close-on-select' => 'false', ), 'options_cb' => 'gamipress_options_cb_roles', 'hide_if' => array( 'bulk_award_rank_all_users' => 'checked' ), 'classes_cb' => 'cmb_conditional_fields_classes_cb', ), 'bulk_award_rank_button' => array( 'label' => __( 'Award Rank', 'gamipress' ), 'type' => 'button', 'button' => 'primary' ), // Requirements 'bulk_award_requirements_type' => array( 'name' => __( 'Requirement Type', 'gamipress' ), 'tooltip' => __( 'Choose the requirement type to award.', 'gamipress' ), 'label_cb' => 'cmb_tooltip_label_cb', 'type' => 'select', 'options' => $requirement_types_options, ), 'bulk_award_requirements' => array( 'name' => __( 'Requirements to Award', 'gamipress' ), 'tooltip' => __( 'Choose the requirements to award.', 'gamipress' ), 'label_cb' => 'cmb_tooltip_label_cb', 'type' => 'advanced_select', 'multiple' => true, 'custom_classes' => 'gamipress-post-selector', 'attributes' => array( 'data-action' => 'gamipress_get_requirements', 'data-post-type' => implode( ',', gamipress_get_requirement_types_slugs() ), 'data-placeholder' => __( 'Choose requirement(s)', 'gamipress' ), 'data-close-on-select' => 'false', ), 'options_cb' => 'gamipress_options_cb_posts', 'hide_if' => array( 'bulk_award_requirements_type' => '' ), 'classes_cb' => 'cmb_conditional_fields_classes_cb', ), 'bulk_award_requirements_all_users' => array( 'name' => __( 'Award to all users', 'gamipress' ), 'tooltip' => __( 'Check this option to award the requirements to all users.', 'gamipress' ), 'label_cb' => 'cmb_tooltip_label_cb', 'type' => 'checkbox', 'classes' => 'gamipress-switch' ), 'bulk_award_requirements_users' => array( 'name' => __( 'Users to award', 'gamipress' ), 'tooltip' => __( 'Choose users to award this requirements.', 'gamipress' ), 'label_cb' => 'cmb_tooltip_label_cb', 'type' => 'advanced_select', 'multiple' => true, 'custom_classes' => 'gamipress-user-selector', 'attributes' => array( 'data-placeholder' => __( 'Choose users(s)', 'gamipress' ), 'data-close-on-select' => 'false', ), 'options_cb' => 'gamipress_options_cb_users', 'hide_if' => array( 'bulk_award_requirements_all_users' => 'checked' ), 'classes_cb' => 'cmb_conditional_fields_classes_cb', ), 'bulk_award_requirements_roles' => array( 'name' => __( 'Roles to award', 'gamipress' ), 'tooltip' => __( 'Choose roles to award this requirements.', 'gamipress' ), 'label_cb' => 'cmb_tooltip_label_cb', 'type' => 'advanced_select', 'multiple' => true, 'custom_classes' => 'gamipress-selector', 'attributes' => array( 'data-placeholder' => __( 'Choose role(s)', 'gamipress' ), 'data-close-on-select' => 'false', ), 'options_cb' => 'gamipress_options_cb_roles', 'hide_if' => array( 'bulk_award_requirements_all_users' => 'checked' ), 'classes_cb' => 'cmb_conditional_fields_classes_cb', ), 'bulk_award_requirements_button' => array( 'label' => __( 'Award Requirements', 'gamipress' ), 'type' => 'button', 'button' => 'primary' ), ) ), 'vertical_tabs' => true, 'tabs' => apply_filters( 'gamipress_bulk_awards_tool_tabs', array( 'bulk_award_points' => array( 'icon' => 'dashicons-star-filled', 'title' => __( 'Points', 'gamipress' ), 'fields' => array( 'bulk_award_points', 'bulk_award_points_type', 'bulk_award_points_register_movement', 'bulk_award_points_earnings_text', 'bulk_award_points_all_users', 'bulk_award_points_users', 'bulk_award_points_roles', 'bulk_award_points_button', ), ), 'bulk_award_achievements' => array( 'icon' => 'dashicons-awards', 'title' => __( 'Achievements', 'gamipress' ), 'fields' => array( 'bulk_award_achievements', 'bulk_award_achievements_all_users', 'bulk_award_achievements_users', 'bulk_award_achievements_roles', 'bulk_award_achievements_button', ), ), 'bulk_award_rank' => array( 'icon' => 'dashicons-rank', 'title' => __( 'Ranks', 'gamipress' ), 'fields' => array( 'bulk_award_rank', 'bulk_award_rank_all_users', 'bulk_award_rank_users', 'bulk_award_rank_roles', 'bulk_award_rank_button', ), ), 'bulk_award_requirement' => array( 'icon' => 'dashicons-editor-ol', 'title' => __( 'Requirements', 'gamipress' ), 'fields' => array( 'bulk_award_requirements_type', 'bulk_award_requirements', 'bulk_award_requirements_all_users', 'bulk_award_requirements_users', 'bulk_award_requirements_roles', 'bulk_award_requirements_button', ), ) ) ) ); return $meta_boxes; } add_filter( 'gamipress_tools_general_meta_boxes', 'gamipress_bulk_awards_tool_meta_boxes' ); /** * AJAX handler for the recount activity tool * * @since 1.4.1 */ function gamipress_ajax_bulk_awards_tool() { // 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' ) ); } // Check parameters received if( ! isset( $_POST['bulk_award'] ) || empty( $_POST['bulk_award'] ) ) { wp_send_json_error( __( 'You are not allowed to perform this action.', 'gamipress' ) ); } $bulk_award = sanitize_text_field( $_POST['bulk_award'] ); $loop = ( ! isset( $_POST['loop'] ) ? 0 : absint( $_POST['loop'] ) ); $limit = 100; $offset = $limit * $loop; $run_again = false; ignore_user_abort( true ); if ( ! gamipress_is_function_disabled( 'set_time_limit' ) ) set_time_limit( 0 ); // Initialize vars $points_types = gamipress_get_points_types(); $rank_types = gamipress_get_rank_types(); $to_all_users = false; $specific_users = array(); $specific_roles = array(); $join = array(); $where = array(); if( $bulk_award === 'points' ) { // Check points parameters $points_to_award = absint( $_POST['bulk_award_points'] ); if( $points_to_award === 0 ) { wp_send_json_error( __( 'Choose a valid points amount to award.', 'gamipress' ) ); } $points_type_to_award = sanitize_text_field( $_POST['bulk_award_points_type'] ); if( $points_type_to_award === '' || ! isset( $points_types[$points_type_to_award] ) ) { wp_send_json_error( __( 'Choose a valid points type.', 'gamipress' ) ); } $to_all_users = isset( $_POST['bulk_award_points_all_users'] ); if( ! $to_all_users ) { $specific_users = isset( $_POST['bulk_award_points_users'] ) ? $_POST['bulk_award_points_users'] : array(); $specific_roles = isset( $_POST['bulk_award_points_roles'] ) ? $_POST['bulk_award_points_roles'] : array(); } } else if( $bulk_award === 'achievements' ) { // Check achievements parameters $achievements = isset( $_POST['bulk_award_achievements'] ) ? $_POST['bulk_award_achievements'] : array(); if( empty( $achievements ) ) { wp_send_json_error( __( 'Choose at least one achievement to be awarded.', 'gamipress' ) ); } $to_all_users = isset( $_POST['bulk_award_achievements_all_users'] ); if( ! $to_all_users ) { $specific_users = isset( $_POST['bulk_award_achievements_users'] ) ? $_POST['bulk_award_achievements_users'] : array(); $specific_roles = isset( $_POST['bulk_award_achievements_roles'] ) ? $_POST['bulk_award_achievements_roles'] : array(); } } else if( $bulk_award === 'rank' ) { // Check rank parameters $rank_id = absint( $_POST['bulk_award_rank'] ); $rank = get_post( $rank_id ); if( ! $rank || ! isset( $rank_types[$rank->post_type] ) ) { wp_send_json_error( __( 'Choose a valid rank to be awarded.', 'gamipress' ) ); } $to_all_users = isset( $_POST['bulk_award_rank_all_users'] ); if( ! $to_all_users ) { $specific_users = isset( $_POST['bulk_award_rank_users'] ) ? $_POST['bulk_award_rank_users'] : array(); $specific_roles = isset( $_POST['bulk_award_rank_roles'] ) ? $_POST['bulk_award_rank_roles'] : array(); } } else if( $bulk_award === 'requirements' ) { // Check requirements parameters $requirements = isset( $_POST['bulk_award_requirements'] ) ? $_POST['bulk_award_requirements'] : array(); if( empty( $requirements ) ) { wp_send_json_error( __( 'Choose at least one requirement to be awarded.', 'gamipress' ) ); } $to_all_users = isset( $_POST['bulk_award_requirements_all_users'] ); if( ! $to_all_users ) { $specific_users = isset( $_POST['bulk_award_requirements_users'] ) ? $_POST['bulk_award_requirements_users'] : array(); $specific_roles = isset( $_POST['bulk_award_requirements_roles'] ) ? $_POST['bulk_award_requirements_roles'] : array(); } } // Ensure all specific users are correct foreach( $specific_users as $i => $specific_user ) { if( absint( $specific_user ) === 0 ) unset( $specific_users[$i] ); } // Ensure all specific roles are correct $editable_roles = get_editable_roles(); foreach( $specific_roles as $i => $specific_role ) { if( ! isset( $editable_roles[$specific_role] ) ) unset( $specific_roles[$i] ); } // Check users parameters if( ! $to_all_users && empty( $specific_users ) && empty( $specific_roles ) ) wp_send_json_error( __( 'Choose at least one user to award.', 'gamipress' ) ); if( $to_all_users ) { // Get stored users $users = gamipress_get_users( array( 'offset' => $offset, 'limit' => $limit, ) ); // Return a success message if finished, else run again if( empty( $users ) && $loop !== 0 ) { wp_send_json_success( __( 'Bulk award process has been done successfully.', 'gamipress' ) ); } else { $run_again = true; } } else { // Get specific stored users // Setup specific users where if( ! empty( $specific_users ) && count( $specific_users ) > 0 ) { // Sanitize user IDs foreach ( $specific_users as $i => $user_id ) { $specific_users[$i] = absint( $user_id ); } $where[] = "u.ID IN( " . implode( ', ', $specific_users ) . " )"; } // Setup specific users join if( ! empty( $specific_roles ) && count( $specific_roles ) > 0 ) { // Setup join to the users meta table $join[] = "LEFT JOIN {$wpdb->usermeta} AS umcap ON ( umcap.user_id = u.ID AND umcap.meta_key = '" . $wpdb->get_blog_prefix() . "capabilities' )"; foreach( $specific_roles as $role ) { $role = esc_sql( $role ); $where[] = "umcap.meta_value LIKE '%\\\"{$role}\\\"%'"; } } // Setup each query part $where = ( ! empty( $where ) ? "WHERE (" . implode( ') OR (', $where ) . ")" : '' ); $join = ( ! empty( $join ) ? implode( ' ', $join ) : '' ); $sql = "SELECT u.ID FROM {$wpdb->users} AS u {$join} {$where} ORDER BY u.ID ASC LIMIT {$offset}, {$limit}"; $users = $wpdb->get_results( $sql ); // Return a success message if finished, else run again if( empty( $users ) && $loop !== 0 ) { wp_send_json_success( __( 'Bulk award process has been done successfully.', 'gamipress' ) ); } else { $run_again = true; } } if( empty( $users ) ) wp_send_json_error( __( 'Could not find users to award.', 'gamipress' ) ); // Let's to bulk award foreach( $users as $user ) { if( $bulk_award === 'points' ) { // When an admin awards points to user is required to set the total points balance $user_points = gamipress_get_user_points( $user->ID, $points_type_to_award ); // Award points gamipress_award_points_to_user( $user->ID, $user_points + $points_to_award, $points_type_to_award, array( 'admin_id' => get_current_user_id() ) ); $register_movement = isset( $_POST['bulk_award_points_register_movement'] ) ? true : false; $earnings_text = isset( $_POST['bulk_award_points_earnings_text'] ) ? stripslashes( sanitize_text_field( $_POST['bulk_award_points_earnings_text'] ) ) : ''; if( $register_movement ) { // Insert the custom user earning for the manual balance adjustment gamipress_insert_user_earning( $user->ID, array( 'title' => $earnings_text, 'user_id' => $user->ID, 'post_id' => gamipress_get_points_type_id( $points_type_to_award ), 'post_type' => 'points-type', 'points' => $points_to_award, 'points_type' => $points_type_to_award, 'date' => date( 'Y-m-d H:i:s', current_time( 'timestamp' ) ), ) ); } } else if( $bulk_award === 'achievements' ) { // Award achievements foreach( $achievements as $achievement ) { gamipress_award_achievement_to_user( absint( $achievement ), $user->ID, get_current_user_id() ); } } else if( $bulk_award === 'rank' ) { // Award rank gamipress_update_user_rank( $user->ID, $rank_id, get_current_user_id() ); } else if( $bulk_award === 'requirements' ) { // Award requirements foreach( $requirements as $requirement ) { gamipress_award_achievement_to_user( absint( $requirement ), $user->ID, get_current_user_id() ); } } } if( $run_again ) { $awarded_users = $limit * ( $loop + 1 ); if( $to_all_users ) { // Get the users count $users_count = gamipress_get_users_count(); } else { $users_count = absint( $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->users} AS u {$join} {$where} ORDER BY u.ID ASC" ) ); } $remaining_users = $users_count - $awarded_users; // Return a run again message (just when awarding to all users) wp_send_json_success( array( 'run_again' => $run_again, 'message' => sprintf( __( '%d remaining users', 'gamipress' ), ( $remaining_users > 0 ? $remaining_users : 0 ) ), ) ); } else { // Return a success message wp_send_json_success( __( 'Bulk award process has been done successfully.', 'gamipress' ) ); } } add_action( 'wp_ajax_gamipress_bulk_awards_tool', 'gamipress_ajax_bulk_awards_tool' );