Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 19 additions & 12 deletions includes/experimental-tools/class-experimental-tools.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ class Experimental_Tools {
*/
const REST_ROUTE = '/experimental-tools';

/**
* Usage data retention window in days. Used for pruning and as the
* upper bound for usage lookback queries.
*
* @var int
*/
const USAGE_RETENTION_DAYS = 90;

/**
* Initialize hooks.
*/
Expand Down Expand Up @@ -405,8 +413,8 @@ public static function track_usage( $slug, $user_id ) {
}
$all_settings[ $slug ]['users'][ $user_id ]['daily'][ $today ]++;

// Prune buckets older than 90 days to keep the option compact.
$cutoff = gmdate( 'Y-m-d', time() - 90 * DAY_IN_SECONDS );
// Prune buckets older than the retention window to keep the option compact.
$cutoff = gmdate( 'Y-m-d', time() - self::USAGE_RETENTION_DAYS * DAY_IN_SECONDS );
foreach ( $all_settings[ $slug ]['users'][ $user_id ]['daily'] as $date => $count ) {
if ( $date < $cutoff ) {
unset( $all_settings[ $slug ]['users'][ $user_id ]['daily'][ $date ] );
Expand Down Expand Up @@ -449,16 +457,15 @@ public static function get_usage_count( $slug, $days = 30 ) {
* @return int
*/
public static function get_user_usage_count( $slug, $user_id, $days = 30 ) {
$settings = self::get_tool_settings( $slug );
$user_key = (string) $user_id;
$total = 0;
$cutoff = gmdate( 'Y-m-d', time() - $days * DAY_IN_SECONDS );

if ( ! empty( $settings['users'][ $user_key ]['daily'] ) ) {
foreach ( $settings['users'][ $user_key ]['daily'] as $date => $count ) {
if ( $date >= $cutoff ) {
$total += (int) $count;
}
$settings = self::get_tool_settings( $slug );
$user_key = (string) $user_id;
$user_data = $settings['users'][ $user_key ] ?? [];
$total = 0;
$cutoff = gmdate( 'Y-m-d', time() - $days * DAY_IN_SECONDS );

foreach ( $user_data['daily'] ?? [] as $date => $count ) {
if ( $date >= $cutoff ) {
$total += (int) $count;
}
}
return $total;
Expand Down
29 changes: 29 additions & 0 deletions tests/unit-tests/experimental-tools.php
Original file line number Diff line number Diff line change
Expand Up @@ -206,4 +206,33 @@ function ( $action_slug, $fields ) use ( &$captured_slug, &$captured_fields ) {
$this->assertEquals( $slug, $captured_slug );
$this->assertEquals( 'hook-test', $captured_fields['api_key'] );
}

/**
* Per-user usage count returns correct values for individual users.
*/
public function test_per_user_usage_count() {
$slug = $this->register_test_tool();
$user_a = self::factory()->user->create();
$user_b = self::factory()->user->create();

Experimental_Tools::track_usage( $slug, $user_a );
Experimental_Tools::track_usage( $slug, $user_a );
Experimental_Tools::track_usage( $slug, $user_b );

$this->assertEquals( 2, Experimental_Tools::get_user_usage_count( $slug, $user_a ) );
$this->assertEquals( 1, Experimental_Tools::get_user_usage_count( $slug, $user_b ) );
// Total across all users.
$this->assertEquals( 3, Experimental_Tools::get_usage_count( $slug ) );
Comment thread
adekbadek marked this conversation as resolved.

// Seed an older daily bucket and verify it's excluded with a narrow window.
$all_settings = get_option( Experimental_Tools::OPTION_NAME, [] );
$old_date = gmdate( 'Y-m-d', time() - 10 * DAY_IN_SECONDS );
$all_settings[ $slug ]['users'][ (string) $user_a ]['daily'][ $old_date ] = 7;
update_option( Experimental_Tools::OPTION_NAME, $all_settings );

// 5-day window excludes the 10-day-old bucket.
$this->assertEquals( 2, Experimental_Tools::get_user_usage_count( $slug, $user_a, 5 ) );
// Full retention window includes it.
$this->assertEquals( 9, Experimental_Tools::get_user_usage_count( $slug, $user_a, Experimental_Tools::USAGE_RETENTION_DAYS ) );
}
}
Loading