<commit_before><?php
/**
 * User-related Functions
 *
 * @package BadgeOS
 * @subpackage Admin
 * @author Credly, LLC
 * @license http://www.gnu.org/licenses/agpl.txt GNU AGPL v3.0
 * @link https://credly.com
 */

/**
 * Get a user's badgeos achievements
 *
 * @since  1.0.0
 * @param  array $args An array of all our relevant arguments
 * @return array       An array of all the achievement objects that matched our parameters, or empty if none
 */
function badgeos_get_user_achievements( $args = array() ) {

	// Setup our default args
	$defaults = array(
		'user_id'          => 0,     // The given user's ID
		'site_id'          => 1,     // The given site's ID
		'achievement_id'   => false, // A specific achievement's post ID
		'achievement_type' => false, // A specific achievement type
		'since'            => 0,     // A specific timestamp to use in place of $limit_in_days
	);
	$args = wp_parse_args( $args, $defaults );

	// Use current user's ID if none specified
	if ( ! $args['user_id'] )
		$args['user_id'] = wp_get_current_user()->ID;

	// Grab the user's current achievements
	$achievements = ( $earned_items = get_user_meta( absint( $args['user_id'] ), '_badgeos_achievements', true ) ) ? $earned_items : array( $args['site_id'] => array() );

	// If we want all sites (or no specific site), return the full array
	if ( empty( $args['site_id']) || 'all' == $args['site_id'] )
		return $achievements;

	// Otherwise, we only want the specific site's achievements
	$achievements = $achievements[$args['site_id']];

	if ( is_array( $achievements) && ! empty( $achievements ) ) {
		foreach ( $achievements as $key => $achievement ) {

			// Drop any achievements earned before our since timestamp
			if ( absint($args['since']) > $achievement->date_earned )
				unset($achievements[$key]);

			// Drop any achievements that don't match our achievement ID
			if ( ! empty( $args['achievement_id'] ) && absint( $args['achievement_id'] ) != $achievement->ID )
				unset($achievements[$key]);

			// Drop any achievements that don't match our achievement type
			if ( ! empty( $args['achievement_type'] ) && $args['achievement_type'] != $achievement->post_type )
				unset($achievements[$key]);

		}
	}

	// Return our $achievements array_values (so our array keys start back at 0), or an empty array
	return array_values( $achievements );

}

/**
 * Updates the user's earned achievements
 *
 * We can either replace the achievement's array, or append new achievements to it.
 *
 * @since  1.0.0
 * @param  array        $earned_achievements An array containing all our relevant arguments
 * @return integer|bool                      The updated umeta ID on success, false on failure
 */
function badgeos_update_user_achievements( $args = array() ) {

	// Setup our default args
	$defaults = array(
		'user_id'          => 0,     // The given user's ID
		'site_id'          => 1,     // The given site's ID
		'all_achievements' => false, // An array of ALL achievements earned by the user
		'new_achievements' => false, // An array of NEW achievements earned by the user
	);
	$args = wp_parse_args( $args, $defaults );

	// Use current user's ID if none specified
	if ( ! $args['user_id'] )
		$args['user_id'] = wp_get_current_user()->ID;

	// Grab our user's achievements
	$achievements = badgeos_get_user_achievements( array( 'user_id' => absint( $args['user_id'] ), 'site_id' => 'all' ) );

	// If we don't already have an array stored for this site, create a fresh one
	if ( !isset( $achievements[$args['site_id']] ) )
		$achievements[$args['site_id']] = array();

	// Determine if we should be replacing or appending to our achievements array
	if ( is_array( $args['all_achievements'] ) )
		$achievements[$args['site_id']] = $args['all_achievements'];
	elseif ( is_array( $args['new_achievements'] ) && ! empty( $args['new_achievements'] ) )
		$achievements[$args['site_id']] = array_merge( $achievements[$args['site_id']], $args['new_achievements'] );

	// Finally, update our user meta
	return update_user_meta( absint( $args['user_id'] ), '_badgeos_achievements', $achievements);

}

/**
 * Return a user's points
 *
 * @since  1.0
 * @param  string   $user_id      The given user's ID
 * @return integer  $user_points  The user's current points
 */
function badgeos_get_users_points( $user_id = 0 ) {

	// Use current user's ID if none specified
	if ( ! $user_id )
		$user_id = wp_get_current_user()->ID;

	// Return our user's points as an integer (sanely falls back to 0 if empty)
	return absint( get_user_meta( $user_id, '_badgeos_points', true ) );
}

/**
 * Posts a log entry when a user earns points
 *
 * @since  1.0
 * @param  integer $user_id    The given user's ID
 * @param  integer $new_points The new points the user is being awarded
 * @param  integer $admin_id   If being awarded by an admin, the admin's user ID
 * @return int                 The user's updated point total
 */
function badgeos_update_users_points( $user_id = 0, $new_points = 0, $admin_id = 0 ) {

	// Use current user's ID if none specified
	if ( ! $user_id )
		$user_id = wp_get_current_user()->ID;

	// Setup our user objects
	$user  = get_userdata( $user_id );
	$admin = get_userdata( $admin_id );

	// Grab the user's current points
	$current_points = badgeos_get_users_points( $user_id );

	// If we're getting an admin ID, $new_points is actually the final total, so subtract the current points
	if ( $admin_id ) $new_points = $new_points - $current_points;

	// Update our user's total
	$updated_points_total = absint( $current_points + $new_points );
	update_user_meta( $user_id, '_badgeos_points', $updated_points_total );

	// Alter our log message if this was an admin action
	if ( $admin_id )
		$log_message = sprintf( __( '%1$s awarded %2$s %3$s points for a new total of %4$s points', 'badgeos' ), $admin->user_login, $user->user_login, number_format( $new_points ), number_format( $updated_points_total ) );
	else
		$log_message = sprintf( __( '%1$s earned %2$s points for a new total of %3$s points', 'badgeos' ), $user->user_login, number_format( $new_points ), number_format( $updated_points_total ) );

	// Create a log entry
	badgeos_post_log_entry( null, $user_id, 'points', $log_message );

	// Maybe award some points-based badges
	foreach ( badgeos_get_points_based_achievements() as $achievement )
		badgeos_maybe_award_achievement_to_user( $achievement->ID );

	return $updated_points_total;
}

/**
 * Award new points to a user based on logged activites and earned badges
 *
 * @since  1.0
 * @param  integer $user_id        The given user's ID
 * @param  integer $achievement_id The given achievement's post ID
 * @return integer                 The user's updated points total
 */
function badgeos_award_user_points( $user_id, $achievement_id ) {

	// Grab our points from the provided post
	$points = absint( get_post_meta( $achievement_id, '_badgeos_points', true ) );

	if ( ! empty( $points ) )
		return badgeos_update_users_points( $user_id, $points );
}<commit_msg>Update points functionality so point log entries have relevant meta<commit_after><?php
/**
 * User-related Functions
 *
 * @package BadgeOS
 * @subpackage Admin
 * @author Credly, LLC
 * @license http://www.gnu.org/licenses/agpl.txt GNU AGPL v3.0
 * @link https://credly.com
 */

/**
 * Get a user's badgeos achievements
 *
 * @since  1.0.0
 * @param  array $args An array of all our relevant arguments
 * @return array       An array of all the achievement objects that matched our parameters, or empty if none
 */
function badgeos_get_user_achievements( $args = array() ) {

	// Setup our default args
	$defaults = array(
		'user_id'          => 0,     // The given user's ID
		'site_id'          => 1,     // The given site's ID
		'achievement_id'   => false, // A specific achievement's post ID
		'achievement_type' => false, // A specific achievement type
		'since'            => 0,     // A specific timestamp to use in place of $limit_in_days
	);
	$args = wp_parse_args( $args, $defaults );

	// Use current user's ID if none specified
	if ( ! $args['user_id'] )
		$args['user_id'] = wp_get_current_user()->ID;

	// Grab the user's current achievements
	$achievements = ( $earned_items = get_user_meta( absint( $args['user_id'] ), '_badgeos_achievements', true ) ) ? $earned_items : array( $args['site_id'] => array() );

	// If we want all sites (or no specific site), return the full array
	if ( empty( $args['site_id']) || 'all' == $args['site_id'] )
		return $achievements;

	// Otherwise, we only want the specific site's achievements
	$achievements = $achievements[$args['site_id']];

	if ( is_array( $achievements) && ! empty( $achievements ) ) {
		foreach ( $achievements as $key => $achievement ) {

			// Drop any achievements earned before our since timestamp
			if ( absint($args['since']) > $achievement->date_earned )
				unset($achievements[$key]);

			// Drop any achievements that don't match our achievement ID
			if ( ! empty( $args['achievement_id'] ) && absint( $args['achievement_id'] ) != $achievement->ID )
				unset($achievements[$key]);

			// Drop any achievements that don't match our achievement type
			if ( ! empty( $args['achievement_type'] ) && $args['achievement_type'] != $achievement->post_type )
				unset($achievements[$key]);

		}
	}

	// Return our $achievements array_values (so our array keys start back at 0), or an empty array
	return array_values( $achievements );

}

/**
 * Updates the user's earned achievements
 *
 * We can either replace the achievement's array, or append new achievements to it.
 *
 * @since  1.0.0
 * @param  array        $earned_achievements An array containing all our relevant arguments
 * @return integer|bool                      The updated umeta ID on success, false on failure
 */
function badgeos_update_user_achievements( $args = array() ) {

	// Setup our default args
	$defaults = array(
		'user_id'          => 0,     // The given user's ID
		'site_id'          => 1,     // The given site's ID
		'all_achievements' => false, // An array of ALL achievements earned by the user
		'new_achievements' => false, // An array of NEW achievements earned by the user
	);
	$args = wp_parse_args( $args, $defaults );

	// Use current user's ID if none specified
	if ( ! $args['user_id'] )
		$args['user_id'] = wp_get_current_user()->ID;

	// Grab our user's achievements
	$achievements = badgeos_get_user_achievements( array( 'user_id' => absint( $args['user_id'] ), 'site_id' => 'all' ) );

	// If we don't already have an array stored for this site, create a fresh one
	if ( !isset( $achievements[$args['site_id']] ) )
		$achievements[$args['site_id']] = array();

	// Determine if we should be replacing or appending to our achievements array
	if ( is_array( $args['all_achievements'] ) )
		$achievements[$args['site_id']] = $args['all_achievements'];
	elseif ( is_array( $args['new_achievements'] ) && ! empty( $args['new_achievements'] ) )
		$achievements[$args['site_id']] = array_merge( $achievements[$args['site_id']], $args['new_achievements'] );

	// Finally, update our user meta
	return update_user_meta( absint( $args['user_id'] ), '_badgeos_achievements', $achievements);

}

/**
 * Return a user's points
 *
 * @since  1.0
 * @param  string   $user_id      The given user's ID
 * @return integer  $user_points  The user's current points
 */
function badgeos_get_users_points( $user_id = 0 ) {

	// Use current user's ID if none specified
	if ( ! $user_id )
		$user_id = wp_get_current_user()->ID;

	// Return our user's points as an integer (sanely falls back to 0 if empty)
	return absint( get_user_meta( $user_id, '_badgeos_points', true ) );
}

/**
 * Posts a log entry when a user earns points
 *
 * @since  1.0
 * @param  integer $user_id        The given user's ID
 * @param  integer $new_points     The new points the user is being awarded
 * @param  integer $admin_id       If being awarded by an admin, the admin's user ID
 * @param  integer $achievement_id The achievement that generated the points, if applicable
 * @return integer                 The user's updated point total
 */
function badgeos_update_users_points( $user_id = 0, $new_points = 0, $admin_id = 0, $achievement_id = null ) {

	// Use current user's ID if none specified
	if ( ! $user_id )
		$user_id = wp_get_current_user()->ID;

	// Setup our user objects
	$user  = get_userdata( $user_id );
	$admin = get_userdata( $admin_id );

	// Grab the user's current points
	$current_points = badgeos_get_users_points( $user_id );

	// If we're getting an admin ID, $new_points is actually the final total, so subtract the current points
	if ( $admin_id ) $new_points = $new_points - $current_points;

	// Update our user's total
	$updated_points_total = absint( $current_points + $new_points );
	update_user_meta( $user_id, '_badgeos_points', $updated_points_total );

	// Alter our log message if this was an admin action
	if ( $admin_id )
		$log_message = sprintf( __( '%1$s awarded %2$s %3$s points for a new total of %4$s points', 'badgeos' ), $admin->user_login, $user->user_login, number_format( $new_points ), number_format( $updated_points_total ) );
	else
		$log_message = sprintf( __( '%1$s earned %2$s points for a new total of %3$s points', 'badgeos' ), $user->user_login, number_format( $new_points ), number_format( $updated_points_total ) );

	// Create a log entry
	$log_entry_id = badgeos_post_log_entry( $achievement_id, $user_id, 'points', $log_message );

	// Add relevant meta to our log entry
	update_post_meta( $log_entry_id, '_badgeos_awarded_points', $new_points );
	update_post_meta( $log_entry_id, '_badgeos_total_user_points', $updated_points_total );
	if ( $admin_id )
		update_post_meta( $log_entry_id, '_badgeos_admin_awarded', $admin_id );

	// Maybe award some points-based badges
	foreach ( badgeos_get_points_based_achievements() as $achievement )
		badgeos_maybe_award_achievement_to_user( $achievement->ID );

	return $updated_points_total;
}

/**
 * Award new points to a user based on logged activites and earned badges
 *
 * @since  1.0
 * @param  integer $user_id        The given user's ID
 * @param  integer $achievement_id The given achievement's post ID
 * @return integer                 The user's updated points total
 */
function badgeos_award_user_points( $user_id, $achievement_id ) {

	// Grab our points from the provided post
	$points = absint( get_post_meta( $achievement_id, '_badgeos_points', true ) );

	if ( ! empty( $points ) )
		return badgeos_update_users_points( $user_id, $points, false, $achievement_id );
}
{'fraction_non_alphanumeric': 0.12671892189218922, 'fraction_numerical': 0.0044004400440044, 'mean_word_length': 3.8661759785881564, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 53, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7415224', 'n_tokens_mistral': 4962, 'n_tokens_neox': 4705, 'n_words': 1466}