@@ -25,11 +25,6 @@ class Statistics {
2525 * Initialize the class, registering WordPress hooks.
2626 */
2727 public static function init () {
28- // Register rewrite rules directly since we're already on init.
29- self ::add_rewrite_rules ();
30-
31- \add_action ( 'template_redirect ' , array ( self ::class, 'render_wrapped_card ' ) );
32- \add_filter ( 'query_vars ' , array ( self ::class, 'add_query_vars ' ) );
3328 \add_filter ( 'activitypub_stats_comment_types ' , array ( self ::class, 'add_federated_comments_type ' ) );
3429 }
3530
@@ -50,152 +45,6 @@ public static function add_federated_comments_type( $types ) {
5045 return $ types ;
5146 }
5247
53- /**
54- * Add rewrite rules for nice wrapped URLs.
55- */
56- public static function add_rewrite_rules () {
57- // /fediverse-wrapped or /fediverse-wrapped/2024.
58- \add_rewrite_rule (
59- '^fediverse-wrapped/?$ ' ,
60- 'index.php?activitypub_wrapped=1 ' ,
61- 'top '
62- );
63-
64- \add_rewrite_rule (
65- '^fediverse-wrapped/(\d{4})/?$ ' ,
66- 'index.php?activitypub_wrapped=1&activitypub_wrapped_year=$matches[1] ' ,
67- 'top '
68- );
69-
70- // /@username/wrapped or /@username/wrapped/2024.
71- \add_rewrite_rule (
72- '^@([\w\-\.]+)/wrapped/?$ ' ,
73- 'index.php?activitypub_wrapped=1&actor=$matches[1] ' ,
74- 'top '
75- );
76-
77- \add_rewrite_rule (
78- '^@([\w\-\.]+)/wrapped/(\d{4})/?$ ' ,
79- 'index.php?activitypub_wrapped=1&actor=$matches[1]&activitypub_wrapped_year=$matches[2] ' ,
80- 'top '
81- );
82- }
83-
84- /**
85- * Add custom query vars.
86- *
87- * @param array $vars The existing query vars.
88- *
89- * @return array The modified query vars.
90- */
91- public static function add_query_vars ( $ vars ) {
92- $ vars [] = 'activitypub_wrapped ' ;
93- $ vars [] = 'activitypub_wrapped_year ' ;
94- return $ vars ;
95- }
96-
97- /**
98- * Render the wrapped card if requested.
99- */
100- public static function render_wrapped_card () {
101- if ( ! \get_query_var ( 'activitypub_wrapped ' ) ) {
102- return ;
103- }
104-
105- // Get user ID from actor query var or fallback to GET param.
106- $ actor = \get_query_var ( 'actor ' );
107- if ( $ actor ) {
108- $ actor_object = Actors::get_by_username ( $ actor );
109- $ user_id = $ actor_object && ! \is_wp_error ( $ actor_object ) ? $ actor_object ->get__id () : Actors::BLOG_USER_ID ;
110- } else {
111- // phpcs:ignore WordPress.Security.NonceVerification.Recommended
112- $ user_id = isset ( $ _GET ['user_id ' ] ) ? \intval ( $ _GET ['user_id ' ] ) : Actors::BLOG_USER_ID ;
113- }
114-
115- // Get year from query var or GET param.
116- $ year = \get_query_var ( 'activitypub_wrapped_year ' );
117- if ( ! $ year ) {
118- // phpcs:ignore WordPress.Security.NonceVerification.Recommended
119- $ year = isset ( $ _GET ['year ' ] ) ? \intval ( $ _GET ['year ' ] ) : (int ) \gmdate ( 'Y ' );
120- }
121- $ year = (int ) $ year ;
122-
123- // Get annual summary if available.
124- $ stats = self ::get_annual_summary ( $ user_id , $ year );
125-
126- if ( ! $ stats ) {
127- // No stored stats - get real-time data for the requested year.
128- $ start = \gmdate ( 'Y-01-01 00:00:00 ' , \strtotime ( $ year . '-01-01 ' ) );
129- $ end = \gmdate ( 'Y-12-31 23:59:59 ' , \strtotime ( $ year . '-12-31 ' ) );
130-
131- $ stats = array (
132- 'posts_count ' => self ::count_federated_posts_in_range ( $ user_id , $ start , $ end ),
133- 'followers_total ' => self ::get_follower_count ( $ user_id ),
134- 'top_posts ' => self ::get_top_posts ( $ user_id , $ start , $ end , 5 ),
135- 'top_multiplicator ' => self ::get_top_multiplicator ( $ user_id , $ start , $ end ),
136- );
137-
138- // Add counts for each comment type dynamically.
139- foreach ( \array_keys ( self ::get_comment_types_for_stats () ) as $ type ) {
140- $ stats [ $ type . '_count ' ] = self ::count_engagement_in_range ( $ user_id , $ start , $ end , $ type );
141- }
142-
143- // Add annual-specific fields.
144- $ stats ['most_active_month ' ] = null ;
145- $ stats ['followers_net_change ' ] = 0 ;
146- }
147-
148- $ args = \array_merge (
149- $ stats ,
150- array (
151- 'year ' => $ year ,
152- 'user_id ' => $ user_id ,
153- 'site_name ' => \get_bloginfo ( 'name ' ),
154- 'followers_total ' => self ::get_follower_count ( $ user_id ),
155- )
156- );
157-
158- // Load the template.
159- \load_template ( ACTIVITYPUB_PLUGIN_DIR . 'templates/statistics/wrapped-card.php ' , true , array ( 'args ' => $ args ) );
160- exit ;
161- }
162-
163- /**
164- * Get the wrapped card URL for a user.
165- *
166- * @param int $user_id The user ID.
167- * @param int $year Optional. The year. Defaults to current year.
168- *
169- * @return string The wrapped card URL.
170- */
171- public static function get_wrapped_url ( $ user_id , $ year = null ) {
172- if ( ! $ year ) {
173- $ year = (int ) \gmdate ( 'Y ' );
174- }
175-
176- // For blog actor, use /fediverse-wrapped/YEAR.
177- if ( Actors::BLOG_USER_ID === $ user_id ) {
178- return \home_url ( sprintf ( '/fediverse-wrapped/%d/ ' , $ year ) );
179- }
180-
181- // For user actors, use /@username/wrapped/YEAR.
182- $ actor = Actors::get_by_id ( $ user_id );
183- if ( $ actor && ! \is_wp_error ( $ actor ) ) {
184- $ username = $ actor ->get_preferred_username ();
185- return \home_url ( sprintf ( '/@%s/wrapped/%d/ ' , $ username , $ year ) );
186- }
187-
188- // Fallback to query string URL.
189- return \add_query_arg (
190- array (
191- 'activitypub_wrapped ' => '1 ' ,
192- 'user_id ' => $ user_id ,
193- 'year ' => $ year ,
194- ),
195- \home_url ()
196- );
197- }
198-
19948 /**
20049 * Option prefix for statistics storage.
20150 *
0 commit comments