Skip to content

Commit 26d0d35

Browse files
pfefferlemattwiebe
andauthored
Add monthly active users (#530)
* Add monthly active users for better stats on FediDB * use more optimized query thanks @mattwiebe * use transients, improve logic --------- Co-authored-by: Matt Wiebe <[email protected]>
1 parent 57b39a5 commit 26d0d35

File tree

3 files changed

+96
-26
lines changed

3 files changed

+96
-26
lines changed

includes/functions.php

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Activitypub\Http;
66
use Activitypub\Activity\Activity;
77
use Activitypub\Collection\Followers;
8+
use Activitypub\Collection\Users;
89

910
/**
1011
* Returns the ActivityPub default JSON-context
@@ -474,3 +475,75 @@ function is_json( $data ) {
474475
function is_blog_public() {
475476
return (bool) apply_filters( 'activitypub_is_blog_public', \get_option( 'blog_public', 1 ) );
476477
}
478+
479+
/**
480+
* Get active users based on a given duration
481+
*
482+
* @param int $duration The duration to check in month(s)
483+
*
484+
* @return int The number of active users
485+
*/
486+
function get_active_users( $duration = 1 ) {
487+
488+
$duration = intval( $duration );
489+
$transient_key = sprintf( 'monthly_active_users_%d', $duration );
490+
$count = get_transient( $transient_key );
491+
492+
if ( false === $count ) {
493+
global $wpdb;
494+
$query = "SELECT COUNT( DISTINCT post_author ) FROM {$wpdb->posts} WHERE post_type = 'post' AND post_status = 'publish' AND post_date <= DATE_SUB( NOW(), INTERVAL %d MONTH )";
495+
$query = $wpdb->prepare( $query, $duration );
496+
$count = $wpdb->get_var( $query ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
497+
498+
set_transient( $transient_key, $count, DAY_IN_SECONDS );
499+
}
500+
501+
// if 0 authors where active
502+
if ( 0 === $count ) {
503+
return 0;
504+
}
505+
506+
// if single user mode
507+
if ( is_single_user() ) {
508+
return 1;
509+
}
510+
511+
// if blog user is disabled
512+
if ( is_user_disabled( Users::BLOG_USER_ID ) ) {
513+
return $count;
514+
}
515+
516+
// also count blog user
517+
return $count + 1;
518+
}
519+
520+
/**
521+
* Get the total number of users
522+
*
523+
* @return int The total number of users
524+
*/
525+
function get_total_users() {
526+
// if single user mode
527+
if ( is_single_user() ) {
528+
return 1;
529+
}
530+
531+
$users = \get_users(
532+
array(
533+
'capability__in' => array( 'publish_posts' ),
534+
)
535+
);
536+
537+
if ( is_array( $users ) ) {
538+
$users = count( $users );
539+
} else {
540+
$users = 1;
541+
}
542+
543+
// if blog user is disabled
544+
if ( is_user_disabled( Users::BLOG_USER_ID ) ) {
545+
return $users;
546+
}
547+
548+
return $users + 1;
549+
}

includes/rest/class-nodeinfo.php

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
use WP_REST_Response;
55

6+
use function Activitypub\get_total_users;
7+
use function Activitypub\get_active_users;
68
use function Activitypub\get_rest_url_by_path;
79

810
/**
@@ -82,24 +84,14 @@ public static function nodeinfo( $request ) {
8284
'version' => \get_bloginfo( 'version' ),
8385
);
8486

85-
$users = \get_users(
86-
array(
87-
'capability__in' => array( 'publish_posts' ),
88-
)
89-
);
90-
91-
if ( is_countable( $users ) ) {
92-
$users = count( $users );
93-
} else {
94-
$users = 1;
95-
}
96-
9787
$posts = \wp_count_posts();
9888
$comments = \wp_count_comments();
9989

10090
$nodeinfo['usage'] = array(
10191
'users' => array(
102-
'total' => $users,
92+
'total' => get_total_users(),
93+
'activeMonth' => get_active_users( '1 month ago' ),
94+
'activeHalfyear' => get_active_users( '6 month ago' ),
10395
),
10496
'localPosts' => (int) $posts->publish,
10597
'localComments' => (int) $comments->approved,
@@ -139,24 +131,14 @@ public static function nodeinfo2( $request ) {
139131
'version' => \get_bloginfo( 'version' ),
140132
);
141133

142-
$users = \get_users(
143-
array(
144-
'capability__in' => array( 'publish_posts' ),
145-
)
146-
);
147-
148-
if ( is_countable( $users ) ) {
149-
$users = count( $users );
150-
} else {
151-
$users = 1;
152-
}
153-
154134
$posts = \wp_count_posts();
155135
$comments = \wp_count_comments();
156136

157137
$nodeinfo['usage'] = array(
158138
'users' => array(
159-
'total' => (int) $users,
139+
'total' => get_total_users(),
140+
'activeMonth' => get_active_users( 1 ),
141+
'activeHalfyear' => get_active_users( 6 ),
160142
),
161143
'localPosts' => (int) $posts->publish,
162144
'localComments' => (int) $comments->approved,

integration/class-nodeinfo.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
<?php
22
namespace Activitypub\Integration;
33

4+
use function Activitypub\get_total_users;
5+
use function Activitypub\get_active_users;
6+
47
/**
58
* Compatibility with the NodeInfo plugin
69
*
@@ -31,6 +34,12 @@ public static function add_nodeinfo_discovery( $nodeinfo, $version ) {
3134
$nodeinfo['protocols']['outbound'][] = 'activitypub';
3235
}
3336

37+
$nodeinfo['usage']['users'] = array(
38+
'total' => get_total_users(),
39+
'activeMonth' => get_active_users( '1 month ago' ),
40+
'activeHalfyear' => get_active_users( '6 month ago' ),
41+
);
42+
3443
return $nodeinfo;
3544
}
3645

@@ -44,6 +53,12 @@ public static function add_nodeinfo_discovery( $nodeinfo, $version ) {
4453
public static function add_nodeinfo2_discovery( $nodeinfo ) {
4554
$nodeinfo['protocols'][] = 'activitypub';
4655

56+
$nodeinfo['usage']['users'] = array(
57+
'total' => get_total_users(),
58+
'activeMonth' => get_active_users( '1 month ago' ),
59+
'activeHalfyear' => get_active_users( '6 month ago' ),
60+
);
61+
4762
return $nodeinfo;
4863
}
4964
}

0 commit comments

Comments
 (0)