-
Notifications
You must be signed in to change notification settings - Fork 80
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into add/content-warning-metabox
- Loading branch information
Showing
12 changed files
with
446 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
<?php | ||
namespace Activitypub\Collection; | ||
|
||
use WP_Post; | ||
use WP_Comment; | ||
use WP_Error; | ||
|
||
use Activitypub\Comment; | ||
|
||
use function Activitypub\is_local_comment; | ||
use function Activitypub\get_rest_url_by_path; | ||
|
||
/** | ||
* Class containing code for getting replies Collections and CollectionPages of posts and comments. | ||
*/ | ||
class Replies { | ||
/** | ||
* Build base arguments for fetching the comments of either a WordPress post or comment. | ||
* | ||
* @param WP_Post|WP_Comment $wp_object | ||
*/ | ||
private static function build_args( $wp_object ) { | ||
$args = array( | ||
'status' => 'approve', | ||
'orderby' => 'comment_date_gmt', | ||
'order' => 'ASC', | ||
); | ||
|
||
if ( $wp_object instanceof WP_Post ) { | ||
$args['parent'] = 0; // TODO: maybe this is unnecessary. | ||
$args['post_id'] = $wp_object->ID; | ||
} elseif ( $wp_object instanceof WP_Comment ) { | ||
$args['parent'] = $wp_object->comment_ID; | ||
} else { | ||
return new WP_Error(); | ||
} | ||
|
||
return $args; | ||
} | ||
|
||
/** | ||
* Adds pagination args comments query. | ||
* | ||
* @param array $args Query args built by self::build_args. | ||
* @param int $page The current pagination page. | ||
* @param int $comments_per_page The number of comments per page. | ||
*/ | ||
private static function add_pagination_args( $args, $page, $comments_per_page ) { | ||
$args['number'] = $comments_per_page; | ||
|
||
$offset = intval( $page ) * $comments_per_page; | ||
$args['offset'] = $offset; | ||
|
||
return $args; | ||
} | ||
|
||
|
||
/** | ||
* Get the replies collections ID. | ||
* | ||
* @param WP_Post|WP_Comment $wp_object | ||
* | ||
* @return string The rest URL of the replies collection. | ||
*/ | ||
private static function get_id( $wp_object ) { | ||
if ( $wp_object instanceof WP_Post ) { | ||
return get_rest_url_by_path( sprintf( 'posts/%d/replies', $wp_object->ID ) ); | ||
} elseif ( $wp_object instanceof WP_Comment ) { | ||
return get_rest_url_by_path( sprintf( 'comments/%d/replies', $wp_object->comment_ID ) ); | ||
} else { | ||
return new WP_Error(); | ||
} | ||
} | ||
|
||
/** | ||
* Get the replies collection. | ||
* | ||
* @param WP_Post|WP_Comment $wp_object | ||
* @param int $page | ||
* | ||
* @return array An associative array containing the replies collection without JSON-LD context. | ||
*/ | ||
public static function get_collection( $wp_object ) { | ||
$id = self::get_id( $wp_object ); | ||
|
||
if ( ! $id ) { | ||
return null; | ||
} | ||
|
||
$replies = array( | ||
'id' => $id, | ||
'type' => 'Collection', | ||
); | ||
|
||
$replies['first'] = self::get_collection_page( $wp_object, 0, $replies['id'] ); | ||
|
||
return $replies; | ||
} | ||
|
||
/** | ||
* Get the ActivityPub ID's from a list of comments. | ||
* | ||
* It takes only federated/non-local comments into account, others also do not have an | ||
* ActivityPub ID available. | ||
* | ||
* @param WP_Comment[] $comments The comments to retrieve the ActivityPub ids from. | ||
* | ||
* @return string[] A list of the ActivityPub ID's. | ||
*/ | ||
private static function get_reply_ids( $comments ) { | ||
$comment_ids = array(); | ||
// Only add external comments from the fediverse. | ||
// Maybe use the Comment class more and the function is_local_comment etc. | ||
foreach ( $comments as $comment ) { | ||
if ( is_local_comment( $comment ) ) { | ||
continue; | ||
} | ||
|
||
$public_comment_id = Comment::get_source_id( $comment->comment_ID ); | ||
if ( $public_comment_id ) { | ||
$comment_ids[] = $public_comment_id; | ||
} | ||
} | ||
return $comment_ids; | ||
} | ||
|
||
/** | ||
* Returns a replies collection page as an associative array. | ||
* | ||
* @link https://www.w3.org/TR/activitystreams-vocabulary/#dfn-collectionpage | ||
* | ||
* @param WP_Post|WP_Comment $wp_object The post of comment the replies are for. | ||
* @param int $page The current pagination page. | ||
* @param string $part_of The collection id/url the returned CollectionPage belongs to. | ||
* | ||
* @return array A CollectionPage as an associative array. | ||
*/ | ||
public static function get_collection_page( $wp_object, $page, $part_of = null ) { | ||
// Build initial arguments for fetching approved comments. | ||
$args = self::build_args( $wp_object ); | ||
|
||
// Retrieve the partOf if not already given. | ||
$part_of = $part_of ?? self::get_id( $wp_object ); | ||
|
||
// If the collection page does not exist. | ||
if ( is_wp_error( $args ) || is_wp_error( $part_of ) ) { | ||
return null; | ||
} | ||
|
||
// Get to total replies count. | ||
$total_replies = \get_comments( array_merge( $args, array( 'count' => true ) ) ); | ||
|
||
// Modify query args to retrieve paginated results. | ||
$comments_per_page = \get_option( 'comments_per_page' ); | ||
|
||
// Fetch internal and external comments for current page. | ||
$comments = get_comments( self::add_pagination_args( $args, $page, $comments_per_page ) ); | ||
|
||
// Get the ActivityPub ID's of the comments, without out local-only comments. | ||
$comment_ids = self::get_reply_ids( $comments ); | ||
|
||
// Build the associative CollectionPage array. | ||
$collection_page = array( | ||
'id' => \add_query_arg( 'page', $page, $part_of ), | ||
'type' => 'CollectionPage', | ||
'partOf' => $part_of, | ||
'items' => $comment_ids, | ||
); | ||
|
||
if ( $total_replies / $comments_per_page > $page + 1 ) { | ||
$collection_page['next'] = \add_query_arg( 'page', $page + 1, $part_of ); | ||
} | ||
|
||
return $collection_page; | ||
} | ||
} |
Oops, something went wrong.