PluginProbe
ActivityPub / 9.2.1
ActivityPub v9.2.1
9.3.1 9.3.0 9.2.2 9.2.1 9.2.0 9.1.0 9.0.2 9.0.1 9.0.0 8.3.0 8.2.1 8.2.0 8.1.1 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.2.0 1.3.0 2.0.0 2.0.1 2.1.0 2.1.1 All 160 releases
activitypub / includes / rest / admin / class-statistics-controller.php

class-statistics-controller.php in ActivityPub 9.2.1, at includes/rest/admin/class-statistics-controller.php

141 lines 3.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Statistics_Controller file.
4 *
5 * @package Activitypub
6 */
7
8 namespace Activitypub\Rest\Admin;
9
10 use Activitypub\Collection\Actors;
11 use Activitypub\OAuth\Server as OAuth_Server;
12 use Activitypub\Statistics;
13
14 use function Activitypub\user_can_act_as_blog;
15
16 /**
17 * ActivityPub Statistics_Controller class.
18 *
19 * Provides REST endpoints for ActivityPub statistics.
20 */
21 class Statistics_Controller extends \WP_REST_Controller {
22
23 /**
24 * The namespace of this controller's route.
25 *
26 * @var string
27 */
28 protected $namespace = ACTIVITYPUB_REST_NAMESPACE;
29
30 /**
31 * The base of this controller's route.
32 *
33 * @var string
34 */
35 protected $rest_base = 'admin/stats';
36
37 /**
38 * Register routes.
39 */
40 public function register_routes() {
41 \register_rest_route(
42 $this->namespace,
43 '/' . $this->rest_base . '/(?P<user_id>[\d]+)',
44 array(
45 array(
46 'methods' => \WP_REST_Server::READABLE,
47 'callback' => array( $this, 'get_item' ),
48 'permission_callback' => array( $this, 'get_item_permissions_check' ),
49 'args' => array(
50 'user_id' => array(
51 'description' => 'The user ID to get stats for.',
52 'type' => 'integer',
53 'required' => true,
54 ),
55 ),
56 ),
57 )
58 );
59 }
60
61 /**
62 * Checks if a given request has access to get stats.
63 *
64 * @param \WP_REST_Request $request The request object.
65 *
66 * @return true|\WP_Error True if the request has access, WP_Error otherwise.
67 */
68 public function get_item_permissions_check( $request ) {
69 // This is an admin endpoint; scoped OAuth C2S tokens must not drive it.
70 $denied = OAuth_Server::deny_if_oauth();
71 if ( null !== $denied ) {
72 return $denied;
73 }
74
75 $user_id = (int) $request->get_param( 'user_id' );
76
77 // Check if user can access stats for this actor.
78 if ( Actors::BLOG_USER_ID === $user_id ) {
79 if ( ! user_can_act_as_blog() ) {
80 return new \WP_Error(
81 'rest_forbidden',
82 \__( 'You do not have permission to view blog stats.', 'activitypub' ),
83 array( 'status' => 403 )
84 );
85 }
86 } elseif ( \get_current_user_id() !== $user_id ) {
87 return new \WP_Error(
88 'rest_forbidden',
89 \__( 'You do not have permission to view this user\'s stats.', 'activitypub' ),
90 array( 'status' => 403 )
91 );
92 }
93
94 return true;
95 }
96
97 /**
98 * Retrieves statistics for a user.
99 *
100 * @param \WP_REST_Request $request The request object.
101 *
102 * @return \WP_REST_Response|\WP_Error Response object or WP_Error object.
103 */
104 public function get_item( $request ) {
105 $user_id = (int) $request->get_param( 'user_id' );
106 $transient_key = 'activitypub_stats_' . $user_id;
107
108 $response = \get_transient( $transient_key );
109
110 if ( false === $response ) {
111 $stats = Statistics::get_current_stats( $user_id, 'month' );
112 $comparison = Statistics::get_period_comparison( $user_id, $stats );
113 $monthly_data = Statistics::get_rolling_monthly_breakdown( $user_id );
114 $comment_types = Statistics::get_comment_types_for_stats();
115
116 $stats_response = array(
117 'posts_count' => $stats['posts_count'],
118 'followers_total' => $stats['followers_total'],
119 'top_posts' => $stats['top_posts'],
120 'top_multiplicator' => $stats['top_multiplicator'],
121 );
122
123 // Include per-type engagement counts from current period stats.
124 foreach ( \array_keys( $comment_types ) as $type ) {
125 $stats_response[ $type . '_count' ] = $stats[ $type . '_count' ] ?? 0;
126 }
127
128 $response = array(
129 'stats' => $stats_response,
130 'comparison' => $comparison,
131 'monthly' => \array_values( $monthly_data ),
132 'comment_types' => $comment_types,
133 );
134
135 \set_transient( $transient_key, $response, 15 * MINUTE_IN_SECONDS );
136 }
137
138 return \rest_ensure_response( $response );
139 }
140 }
141