PluginProbe
ActivityPub / 4.1.1
ActivityPub v4.1.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 / collection / class-replies.php

class-replies.php in ActivityPub 4.1.1, at includes/collection/class-replies.php

186 lines 5.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Replies collection file.
4 *
5 * @package Activitypub
6 */
7
8 namespace Activitypub\Collection;
9
10 use WP_Post;
11 use WP_Comment;
12 use WP_Error;
13
14 use Activitypub\Comment;
15
16 use function Activitypub\is_local_comment;
17 use function Activitypub\get_rest_url_by_path;
18
19 /**
20 * Class containing code for getting replies Collections and CollectionPages of posts and comments.
21 */
22 class Replies {
23 /**
24 * Build base arguments for fetching the comments of either a WordPress post or comment.
25 *
26 * @param WP_Post|WP_Comment $wp_object The post or comment to fetch replies for.
27 */
28 private static function build_args( $wp_object ) {
29 $args = array(
30 'status' => 'approve',
31 'orderby' => 'comment_date_gmt',
32 'order' => 'ASC',
33 );
34
35 if ( $wp_object instanceof WP_Post ) {
36 $args['parent'] = 0; // TODO: maybe this is unnecessary.
37 $args['post_id'] = $wp_object->ID;
38 } elseif ( $wp_object instanceof WP_Comment ) {
39 $args['parent'] = $wp_object->comment_ID;
40 } else {
41 return new WP_Error();
42 }
43
44 return $args;
45 }
46
47 /**
48 * Adds pagination args comments query.
49 *
50 * @param array $args Query args built by self::build_args.
51 * @param int $page The current pagination page.
52 * @param int $comments_per_page The number of comments per page.
53 */
54 private static function add_pagination_args( $args, $page, $comments_per_page ) {
55 $args['number'] = $comments_per_page;
56
57 $offset = intval( $page ) * $comments_per_page;
58 $args['offset'] = $offset;
59
60 return $args;
61 }
62
63
64 /**
65 * Get the replies collections ID.
66 *
67 * @param WP_Post|WP_Comment $wp_object The post or comment to fetch replies for.
68 *
69 * @return string|WP_Error The rest URL of the replies collection or WP_Error if the object is not a post or comment.
70 */
71 private static function get_id( $wp_object ) {
72 if ( $wp_object instanceof WP_Post ) {
73 return get_rest_url_by_path( sprintf( 'posts/%d/replies', $wp_object->ID ) );
74 } elseif ( $wp_object instanceof WP_Comment ) {
75 return get_rest_url_by_path( sprintf( 'comments/%d/replies', $wp_object->comment_ID ) );
76 } else {
77 return new WP_Error();
78 }
79 }
80
81 /**
82 * Get the replies collection.
83 *
84 * @param WP_Post|WP_Comment $wp_object The post or comment to fetch replies for.
85 *
86 * @return array An associative array containing the replies collection without JSON-LD context.
87 */
88 public static function get_collection( $wp_object ) {
89 $id = self::get_id( $wp_object );
90
91 if ( ! $id ) {
92 return null;
93 }
94
95 $replies = array(
96 'id' => $id,
97 'type' => 'Collection',
98 );
99
100 $replies['first'] = self::get_collection_page( $wp_object, 0, $replies['id'] );
101
102 return $replies;
103 }
104
105 /**
106 * Get the ActivityPub ID's from a list of comments.
107 *
108 * It takes only federated/non-local comments into account, others also do not have an
109 * ActivityPub ID available.
110 *
111 * @param WP_Comment[] $comments The comments to retrieve the ActivityPub ids from.
112 *
113 * @return string[] A list of the ActivityPub ID's.
114 */
115 private static function get_reply_ids( $comments ) {
116 $comment_ids = array();
117 // Only add external comments from the fediverse.
118 // Maybe use the Comment class more and the function is_local_comment etc.
119 foreach ( $comments as $comment ) {
120 if ( is_local_comment( $comment ) ) {
121 continue;
122 }
123
124 $public_comment_id = Comment::get_source_id( $comment->comment_ID );
125 if ( $public_comment_id ) {
126 $comment_ids[] = $public_comment_id;
127 }
128 }
129 return $comment_ids;
130 }
131
132 /**
133 * Returns a replies collection page as an associative array.
134 *
135 * @link https://www.w3.org/TR/activitystreams-vocabulary/#dfn-collectionpage
136 *
137 * @param WP_Post|WP_Comment $wp_object The post of comment the replies are for.
138 * @param int $page The current pagination page.
139 * @param string $part_of The collection id/url the returned CollectionPage belongs to.
140 *
141 * @return array A CollectionPage as an associative array.
142 */
143 public static function get_collection_page( $wp_object, $page, $part_of = null ) {
144 // Build initial arguments for fetching approved comments.
145 $args = self::build_args( $wp_object );
146
147 // Retrieve the partOf if not already given.
148 $part_of = $part_of ?? self::get_id( $wp_object );
149
150 // If the collection page does not exist.
151 if ( is_wp_error( $args ) || is_wp_error( $part_of ) ) {
152 return null;
153 }
154
155 // Get to total replies count.
156 $total_replies = \get_comments( array_merge( $args, array( 'count' => true ) ) );
157
158 // Modify query args to retrieve paginated results.
159 $comments_per_page = (int) \get_option( 'comments_per_page' );
160 // If set to zero, we get errors below. You need at least one comment per page, here.
161 if ( ! $comments_per_page ) {
162 $comments_per_page = 1;
163 }
164
165 // Fetch internal and external comments for current page.
166 $comments = get_comments( self::add_pagination_args( $args, $page, $comments_per_page ) );
167
168 // Get the ActivityPub ID's of the comments, without out local-only comments.
169 $comment_ids = self::get_reply_ids( $comments );
170
171 // Build the associative CollectionPage array.
172 $collection_page = array(
173 'id' => \add_query_arg( 'page', $page, $part_of ),
174 'type' => 'CollectionPage',
175 'partOf' => $part_of,
176 'items' => $comment_ids,
177 );
178
179 if ( $total_replies / $comments_per_page > $page + 1 ) {
180 $collection_page['next'] = \add_query_arg( 'page', $page + 1, $part_of );
181 }
182
183 return $collection_page;
184 }
185 }
186