Skip to content

Commit

Permalink
feat: experimental auditing features (#79)
Browse files Browse the repository at this point in the history
* feat(nodes): display sync users count in Nodes table

* refactor: move user table handling

* feat(users-table): add original user link

* feat(membership-plans): display active memberships count

* feat(memberships): single table; experimental discrepancies column

* feat(memberships): active members link; restrict to specific user

* feat: view the discrepant members

* feat(subscriptions): sortable columns
  • Loading branch information
adekbadek authored Apr 10, 2024
1 parent 0c4fbe4 commit 0c31fd6
Show file tree
Hide file tree
Showing 17 changed files with 541 additions and 137 deletions.
14 changes: 14 additions & 0 deletions includes/class-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -191,4 +191,18 @@ public static function admin_init() {
*/
public static function enqueue_scripts() {
}

/**
* Has experimental auditing features?
*
* @return bool True if experimental auditing features are enabled.
*/
public static function use_experimental_auditing_features() {
$user_slug = defined( 'NEWSPACK_NETWORK_EXPERIMENTAL_AUDITING_USER' ) ? NEWSPACK_NETWORK_EXPERIMENTAL_AUDITING_USER : false;
if ( ! $user_slug ) {
return false;
}
$user = get_user_by( 'login', $user_slug );
return $user && get_current_user_id() === $user->ID;
}
}
2 changes: 2 additions & 0 deletions includes/class-initializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class Initializer {
*/
public static function init() {
Admin::init();
Users::init();

if ( Site_Role::is_hub() ) {
Hub\Admin::init();
Expand All @@ -37,6 +38,7 @@ public static function init() {
if ( Site_Role::is_node() ) {
if ( Node\Settings::get_hub_url() ) {
Node\Webhook::init();
Node\Info_Endpoints::init();
Node\Pulling::init();
Rest_Authenticaton::init_node_filters();
}
Expand Down
109 changes: 109 additions & 0 deletions includes/class-users.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?php
/**
* Newspack Users Admin page
*
* @package Newspack
*/

namespace Newspack_Network;

/**
* Class to handle the Users admin page
*/
class Users {

/**
* Runs the initialization.
*/
public static function init() {
add_filter( 'manage_users_columns', [ __CLASS__, 'manage_users_columns' ] );
add_filter( 'manage_users_custom_column', [ __CLASS__, 'manage_users_custom_column' ], 10, 3 );
add_filter( 'users_list_table_query_args', [ __CLASS__, 'users_list_table_query_args' ] );
}

/**
* Add a custom column to the Users table
*
* @param array $columns The current columns.
* @return array
*/
public static function manage_users_columns( $columns ) {
if ( Site_Role::is_hub() ) {
$columns['newspack_network_activity'] = __( 'Newspack Network Activity', 'newspack-network' );
}
if ( \Newspack_Network\Admin::use_experimental_auditing_features() ) {
$columns['newspack_network_user'] = __( 'Network Original User', 'newspack-network' );
}
return $columns;
}

/**
* Add content to the custom column
*
* @param string $value The current column value.
* @param string $column_name The current column name.
* @param int $user_id The current user ID.
* @return string
*/
public static function manage_users_custom_column( $value, $column_name, $user_id ) {
if ( 'newspack_network_user' === $column_name ) {
$remote_site = get_user_meta( $user_id, \Newspack_Network\Utils\Users::USER_META_REMOTE_SITE, true );
$remote_id = (int) get_user_meta( $user_id, \Newspack_Network\Utils\Users::USER_META_REMOTE_ID, true );
if ( $remote_site ) {
return sprintf(
'<a href="%swp-admin/user-edit.php?user_id=%d">%s</a>',
trailingslashit( esc_url( $remote_site ) ),
$remote_id,
sprintf( '%s (#%d)', $remote_site, $remote_id )
);
}
}
if ( 'newspack_network_activity' === $column_name && Site_Role::is_hub() ) {
$user = get_user_by( 'id', $user_id );
if ( ! $user ) {
return $value;
}

$last_activity = \Newspack_Network\Hub\Stores\Event_Log::get( [ 'email' => $user->user_email ], 1 );

if ( empty( $last_activity ) ) {
return '-';
}

$last_activity = $last_activity[0];

$summary = $last_activity->get_summary();
$event_log_url = add_query_arg(
[
'page' => \Newspack_Network\Hub\Admin\Event_Log::PAGE_SLUG,
'email' => $user->user_email,
],
admin_url( 'admin.php' )
);
return sprintf(
'%s: <code>%s</code><br><a href="%s">%s</a>',
__( 'Last Activity', 'newspack-network' ),
$summary,
$event_log_url,
__( 'View all', 'newspack-network' )
);

}
return $value;
}

/**
* Handle the filtering of users by multiple roles.
* Unfortunatelly, `get_views` and `get_views_links` are not filterable, so "All" will
* be displayed as the active filter.
*
* @param array $args The current query args.
*/
public static function users_list_table_query_args( $args ) {
if ( isset( $_REQUEST['role__in'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
$args['role__in'] = explode( ',', sanitize_text_field( $_REQUEST['role__in'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
unset( $args['role'] );
}
return $args;
}
}
10 changes: 9 additions & 1 deletion includes/cli/backfillers/class-reader-registered.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

namespace Newspack_Network\Backfillers;

use WP_CLI;

/**
* Backfiller class.
*/
Expand All @@ -29,10 +31,14 @@ protected function get_processed_item_output( $event ) {
* @return \Newspack_Network\Incoming_Events\Abstract_Incoming_Event[] $events An array of events.
*/
public function get_events() {
$roles_to_sync = \Newspack_Network\Utils\Users::get_synced_user_roles();
if ( empty( $roles_to_sync ) ) {
WP_CLI::error( 'Incompatible Newspack plugin version or no roles to sync.' );
}
// Get all users registered between this-> and $end.
$users = get_users(
[
'role__in' => \Newspack\Reader_Activation::get_reader_roles(),
'role__in' => $roles_to_sync,
'date_query' => [
'after' => $this->start,
'before' => $this->end,
Expand All @@ -49,6 +55,8 @@ public function get_events() {
]
);

WP_CLI::line( sprintf( 'Found %s user(s) eligible for sync.', count( $users ) ) );

$this->maybe_initialize_progress_bar( 'Processing users', count( $users ) );

$events = [];
Expand Down
3 changes: 0 additions & 3 deletions includes/cli/class-data-backfill.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,6 @@ public static function data_backfill( $args, $assoc_args ) { // phpcs:ignore Gen
}
WP_CLI::line( '' );

if ( ! method_exists( '\Newspack\Reader_Activation', 'get_reader_roles' ) ) {
WP_CLI::error( 'Incompatible Newspack plugin version.' );
}
if ( $live ) {
WP_CLI::line( '⚡️ Heads up! Running live, data will be updated.' );
} else {
Expand Down
67 changes: 36 additions & 31 deletions includes/hub/admin/class-membership-plans-table.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,6 @@
* The Membership_Plans Table
*/
class Membership_Plans_Table extends \WP_List_Table {
/**
* Whether to show local or network plans.
*
* @var bool
*/
private $is_local = false;

/**
* Constructs the controller.
*
* @param bool $is_local Whether to show local or network plans.
*/
public function __construct( $is_local = false ) {
$this->is_local = $is_local;
parent::__construct();
}

/**
* Get the table columns
*
Expand All @@ -42,12 +25,12 @@ public function get_columns() {
'id' => __( 'ID', 'newspack-network' ),
'name' => __( 'Name', 'newspack-network' ),
];
if ( $this->is_local ) {
$columns['node_url'] = __( '-', 'newspack-network' );
} else {
$columns['node_url'] = __( 'Node URL', 'newspack-network' );
}
$columns['site_url'] = __( 'Site URL', 'newspack-network' );
$columns['network_pass_id'] = __( 'Network ID', 'newspack-network' );
if ( \Newspack_Network\Admin::use_experimental_auditing_features() ) {
$columns['active_members_count'] = __( 'Active Members', 'newspack-network' );
$columns['network_pass_discrepancies'] = __( 'Discrepancies', 'newspack-network' );
}
$columns['links'] = __( 'Links', 'newspack-network' );
return $columns;
}
Expand All @@ -57,11 +40,7 @@ public function get_columns() {
*/
public function prepare_items() {
$this->_column_headers = [ $this->get_columns(), [], [], 'id' ];
if ( $this->is_local ) {
$this->items = Membership_Plans::get_local_membership_plans();
} else {
$this->items = Membership_Plans::get_membershp_plans_from_nodes();
}
$this->items = Membership_Plans::get_membershp_plans_from_network();
}

/**
Expand All @@ -72,16 +51,42 @@ public function prepare_items() {
* @return string
*/
public function column_default( $item, $column_name ) {
$memberships_list_url = sprintf( '%s/wp-admin/edit.php?s&post_status=wcm-active&post_type=wc_user_membership&post_parent=%d', $item['site_url'], $item['id'] );

if ( $column_name === 'network_pass_id' && $item[ $column_name ] ) {
return sprintf( '<code>%s</code>', $item[ $column_name ] );
}
if ( $column_name === 'links' ) {
$edit_url = get_edit_post_link( $item['id'] );
if ( isset( $item['node_url'] ) ) {
$edit_url = sprintf( '%s/wp-admin/post.php?post=%d&action=edit', $item['node_url'], $item['id'] );
if ( $column_name === 'network_pass_discrepancies' && isset( $item['network_pass_discrepancies'] ) && $item['network_pass_id'] ) {
$discrepancies = $item['network_pass_discrepancies'];
$count = count( $discrepancies );
if ( $count === 0 ) {
return esc_html__( 'None', 'newspack-network' );
}

$memberships_list_url_with_emails_url = add_query_arg(
\Newspack_Network\Woocommerce_Memberships\Admin::MEMBERSHIPS_TABLE_EMAILS_QUERY_PARAM,
implode( ',', $discrepancies ),
$memberships_list_url
);
$message = sprintf(
/* translators: %d is the number of members */
_n(
'%d member doesn\'t match the shared member pool',
'%d members don\'t match the shared member pool',
$count,
'newspack-plugin'
),
$count
);
return sprintf( '<a href="%s">%s</a>', esc_url( $memberships_list_url_with_emails_url ), esc_html( $message ) );
}
if ( $column_name === 'links' ) {
$edit_url = sprintf( '%s/wp-admin/post.php?post=%d&action=edit', $item['site_url'], $item['id'] );
return sprintf( '<a href="%s">%s</a>', esc_url( $edit_url ), esc_html__( 'Edit', 'newspack-network' ) );
}
if ( $column_name === 'active_members_count' && $item[ $column_name ] ) {
return sprintf( '<a href="%s">%s</a>', esc_url( $memberships_list_url ), $item[ $column_name ] );
}
return isset( $item[ $column_name ] ) ? $item[ $column_name ] : '';
}
}
Loading

0 comments on commit 0c31fd6

Please sign in to comment.