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 <wiebe@automattic.com>
This commit is contained in:
Matthias Pfefferle 2023-11-07 10:27:20 +01:00 committed by GitHub
parent 57b39a5c08
commit 26d0d357c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 96 additions and 26 deletions

View file

@ -5,6 +5,7 @@ use WP_Error;
use Activitypub\Http; use Activitypub\Http;
use Activitypub\Activity\Activity; use Activitypub\Activity\Activity;
use Activitypub\Collection\Followers; use Activitypub\Collection\Followers;
use Activitypub\Collection\Users;
/** /**
* Returns the ActivityPub default JSON-context * Returns the ActivityPub default JSON-context
@ -474,3 +475,75 @@ function is_json( $data ) {
function is_blog_public() { function is_blog_public() {
return (bool) apply_filters( 'activitypub_is_blog_public', \get_option( 'blog_public', 1 ) ); return (bool) apply_filters( 'activitypub_is_blog_public', \get_option( 'blog_public', 1 ) );
} }
/**
* Get active users based on a given duration
*
* @param int $duration The duration to check in month(s)
*
* @return int The number of active users
*/
function get_active_users( $duration = 1 ) {
$duration = intval( $duration );
$transient_key = sprintf( 'monthly_active_users_%d', $duration );
$count = get_transient( $transient_key );
if ( false === $count ) {
global $wpdb;
$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 )";
$query = $wpdb->prepare( $query, $duration );
$count = $wpdb->get_var( $query ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
set_transient( $transient_key, $count, DAY_IN_SECONDS );
}
// if 0 authors where active
if ( 0 === $count ) {
return 0;
}
// if single user mode
if ( is_single_user() ) {
return 1;
}
// if blog user is disabled
if ( is_user_disabled( Users::BLOG_USER_ID ) ) {
return $count;
}
// also count blog user
return $count + 1;
}
/**
* Get the total number of users
*
* @return int The total number of users
*/
function get_total_users() {
// if single user mode
if ( is_single_user() ) {
return 1;
}
$users = \get_users(
array(
'capability__in' => array( 'publish_posts' ),
)
);
if ( is_array( $users ) ) {
$users = count( $users );
} else {
$users = 1;
}
// if blog user is disabled
if ( is_user_disabled( Users::BLOG_USER_ID ) ) {
return $users;
}
return $users + 1;
}

View file

@ -3,6 +3,8 @@ namespace Activitypub\Rest;
use WP_REST_Response; use WP_REST_Response;
use function Activitypub\get_total_users;
use function Activitypub\get_active_users;
use function Activitypub\get_rest_url_by_path; use function Activitypub\get_rest_url_by_path;
/** /**
@ -82,24 +84,14 @@ class Nodeinfo {
'version' => \get_bloginfo( 'version' ), 'version' => \get_bloginfo( 'version' ),
); );
$users = \get_users(
array(
'capability__in' => array( 'publish_posts' ),
)
);
if ( is_countable( $users ) ) {
$users = count( $users );
} else {
$users = 1;
}
$posts = \wp_count_posts(); $posts = \wp_count_posts();
$comments = \wp_count_comments(); $comments = \wp_count_comments();
$nodeinfo['usage'] = array( $nodeinfo['usage'] = array(
'users' => array( 'users' => array(
'total' => $users, 'total' => get_total_users(),
'activeMonth' => get_active_users( '1 month ago' ),
'activeHalfyear' => get_active_users( '6 month ago' ),
), ),
'localPosts' => (int) $posts->publish, 'localPosts' => (int) $posts->publish,
'localComments' => (int) $comments->approved, 'localComments' => (int) $comments->approved,
@ -139,24 +131,14 @@ class Nodeinfo {
'version' => \get_bloginfo( 'version' ), 'version' => \get_bloginfo( 'version' ),
); );
$users = \get_users(
array(
'capability__in' => array( 'publish_posts' ),
)
);
if ( is_countable( $users ) ) {
$users = count( $users );
} else {
$users = 1;
}
$posts = \wp_count_posts(); $posts = \wp_count_posts();
$comments = \wp_count_comments(); $comments = \wp_count_comments();
$nodeinfo['usage'] = array( $nodeinfo['usage'] = array(
'users' => array( 'users' => array(
'total' => (int) $users, 'total' => get_total_users(),
'activeMonth' => get_active_users( 1 ),
'activeHalfyear' => get_active_users( 6 ),
), ),
'localPosts' => (int) $posts->publish, 'localPosts' => (int) $posts->publish,
'localComments' => (int) $comments->approved, 'localComments' => (int) $comments->approved,

View file

@ -1,6 +1,9 @@
<?php <?php
namespace Activitypub\Integration; namespace Activitypub\Integration;
use function Activitypub\get_total_users;
use function Activitypub\get_active_users;
/** /**
* Compatibility with the NodeInfo plugin * Compatibility with the NodeInfo plugin
* *
@ -31,6 +34,12 @@ class Nodeinfo {
$nodeinfo['protocols']['outbound'][] = 'activitypub'; $nodeinfo['protocols']['outbound'][] = 'activitypub';
} }
$nodeinfo['usage']['users'] = array(
'total' => get_total_users(),
'activeMonth' => get_active_users( '1 month ago' ),
'activeHalfyear' => get_active_users( '6 month ago' ),
);
return $nodeinfo; return $nodeinfo;
} }
@ -44,6 +53,12 @@ class Nodeinfo {
public static function add_nodeinfo2_discovery( $nodeinfo ) { public static function add_nodeinfo2_discovery( $nodeinfo ) {
$nodeinfo['protocols'][] = 'activitypub'; $nodeinfo['protocols'][] = 'activitypub';
$nodeinfo['usage']['users'] = array(
'total' => get_total_users(),
'activeMonth' => get_active_users( '1 month ago' ),
'activeHalfyear' => get_active_users( '6 month ago' ),
);
return $nodeinfo; return $nodeinfo;
} }
} }