wordpress-activitypub/includes/model/class-comment.php

306 lines
8.2 KiB
PHP
Raw Normal View History

2021-02-18 07:12:32 +01:00
<?php
namespace Activitypub\Model;
/**
* ActivityPub Comment Class
*
* @author Django Doucet
*/
class Comment {
private $comment;
2022-11-15 17:13:20 +01:00
private $id;
private $comment_author_url;
private $post_author;
private $in_reply_to;
private $content_warning;
private $permalink;
private $context;
private $to_recipients;
private $tags;
private $update;
2022-04-15 03:04:43 +02:00
private $deleted;
2022-11-15 17:13:20 +01:00
private $replies;
2021-02-18 07:12:32 +01:00
/**
* Initialize the class
*/
public function __construct( $comment = null ) {
2022-12-23 12:12:12 +01:00
$this->comment = $comment;
$this->id = $this->generate_comment_id();
2021-02-18 07:12:32 +01:00
$this->comment_author_url = \get_author_posts_url( $this->comment->user_id );
2022-09-28 19:18:30 +02:00
$this->in_reply_to = $this->generate_parent_url();
$this->content_warning = $this->generate_content_warning();
$this->permalink = $this->generate_permalink();
$this->context = $this->generate_context();
$this->to_recipients = $this->generate_mention_recipients();
$this->tags = $this->generate_tags();
$this->update = $this->generate_update();
$this->deleted = $this->generate_trash();
$this->replies = $this->generate_replies();
2021-02-18 07:12:32 +01:00
}
public function __call( $method, $params ) {
$var = \strtolower( \substr( $method, 4 ) );
if ( \strncasecmp( $method, 'get', 3 ) === 0 ) {
return $this->$var;
}
if ( \strncasecmp( $method, 'set', 3 ) === 0 ) {
$this->$var = $params[0];
}
}
public function to_array() {
$comment = $this->comment;
$array = array(
2022-11-15 17:13:20 +01:00
'id' => $this->id,
2021-02-18 07:12:32 +01:00
'type' => 'Note',
2022-09-28 19:18:30 +02:00
'published' => \gmdate( 'Y-m-d\TH:i:s\Z', \strtotime( $comment->comment_date_gmt ) ),
2021-02-18 07:12:32 +01:00
'attributedTo' => $this->comment_author_url,
2022-09-28 19:18:30 +02:00
'summary' => $this->content_warning,
'inReplyTo' => $this->in_reply_to,
2023-03-10 22:54:50 +01:00
'content' => $this->get_content(),
2021-02-18 07:12:32 +01:00
'contentMap' => array(
2023-03-10 22:54:50 +01:00
\strstr( \get_locale(), '_', true ) => $this->get_content(),
2021-02-18 07:12:32 +01:00
),
2022-04-15 03:04:43 +02:00
'context' => $this->context,
2022-12-23 12:12:12 +01:00
// 'source' => \get_comment_link( $comment ), //non-conforming, see https://www.w3.org/TR/activitypub/#source-property
2022-04-15 09:17:00 +02:00
'url' => \get_comment_link( $comment ), //link for mastodon
2023-01-30 05:44:52 +01:00
'to' => array( 'https://www.w3.org/ns/activitystreams#Public' ),
'cc' => array( 'https://www.w3.org/ns/activitystreams#Public' ),
2021-02-18 07:12:32 +01:00
'tag' => $this->tags,
);
2022-04-15 03:04:43 +02:00
if ( $this->replies ) {
$array['replies'] = $this->replies;
}
if ( $this->update ) {
$array['updated'] = $this->update;
}
if ( $this->deleted ) {
$array['deleted'] = $this->deleted;
}
2021-02-18 07:12:32 +01:00
return \apply_filters( 'activitypub_comment', $array );
}
public function to_json() {
return \wp_json_encode( $this->to_array(), JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_QUOT );
}
public function generate_comment_author_link() {
return \get_author_posts_url( $this->comment->comment_author );
}
2022-04-15 03:04:43 +02:00
public function generate_comment_id() {
return \Activitypub\set_ap_comment_id( $this->comment->comment_ID );
2022-04-15 03:04:43 +02:00
}
2021-02-18 07:12:32 +01:00
public function generate_permalink() {
2023-03-10 22:54:50 +01:00
return \get_comment_link( $this->comment );
2021-02-18 07:12:32 +01:00
}
/**
* What is status being replied to
2021-02-18 07:12:32 +01:00
* Comment ID or Post ID
*/
public function generate_parent_url() {
$comment = $this->comment;
$parent_comment = \get_comment( $comment->comment_parent );
2022-04-15 09:17:00 +02:00
if ( $comment->comment_parent ) {
2022-04-15 03:04:43 +02:00
//is parent remote?
2022-09-28 19:18:30 +02:00
$in_reply_to = \get_comment_meta( $comment->comment_parent, 'source_url', true );
if ( ! $in_reply_to ) {
$in_reply_to = add_query_arg(
2022-04-15 09:17:00 +02:00
array(
2022-04-15 03:04:43 +02:00
'p' => $comment->comment_post_ID,
'replytocom' => $comment->comment_parent,
2022-04-15 09:17:00 +02:00
),
2022-04-15 03:04:43 +02:00
trailingslashit( site_url() )
);
}
} else { //parent is_post
// Backwards compatibility
2023-01-30 04:23:51 +01:00
$pretty_permalink = \get_post_meta( $comment->comment_post_ID, 'activitypub_canonical_url', true );
if ( $pretty_permalink ) {
2022-09-28 19:18:30 +02:00
$in_reply_to = $pretty_permalink;
} else {
2022-09-28 19:18:30 +02:00
$in_reply_to = add_query_arg(
array(
'p' => $comment->comment_post_ID,
),
trailingslashit( site_url() )
);
}
}
2022-09-28 19:18:30 +02:00
return $in_reply_to;
}
public function generate_context() {
$comment = $this->comment;
// support pretty_permalinks
2023-01-30 04:23:51 +01:00
$pretty_permalink = \get_post_meta( $comment->comment_post_ID, 'activitypub_canonical_url', true );
if ( $pretty_permalink ) {
$context = $pretty_permalink;
2021-02-18 07:12:32 +01:00
} else {
$context = add_query_arg(
2022-04-15 09:17:00 +02:00
array(
2022-04-15 03:04:43 +02:00
'p' => $comment->comment_post_ID,
2022-04-15 09:17:00 +02:00
),
2022-04-15 03:04:43 +02:00
trailingslashit( site_url() )
);
2021-02-18 07:12:32 +01:00
}
return $context;
2022-04-15 03:04:43 +02:00
}
2021-02-18 07:12:32 +01:00
/**
2022-04-15 09:17:00 +02:00
* Generate courtesy Content Warning
* If parent status used CW let's just copy it
2021-02-18 07:12:32 +01:00
* TODO: Move to preprocess_comment / row_actions
* Add option for wrapping CW in Details/Summary markup
2022-04-15 09:17:00 +02:00
* Figure out some CW syntax: [shortcode-style], {brackets-style}?
2021-02-18 07:12:32 +01:00
* So it can be inserted into reply textbox, and removed or modified at will
*/
public function generate_content_warning() {
$comment = $this->comment;
2022-09-28 19:18:30 +02:00
$content_warning = null;
2022-04-15 09:17:00 +02:00
// Temporarily generate Summary from parent
2021-02-18 07:12:32 +01:00
$parent_comment = \get_comment( $comment->comment_parent );
if ( $parent_comment ) {
//get (received) comment
$ap_object = \unserialize( \get_comment_meta( $comment->comment_parent, 'ap_object', true ) );
if ( isset( $ap_object['object']['summary'] ) ) {
2022-09-28 19:18:30 +02:00
$content_warning = $ap_object['object']['summary'];
2021-02-18 07:12:32 +01:00
}
}
// TODO Replace auto generate with Summary shortcode
2022-04-15 03:04:43 +02:00
/*summary = \get_comment_meta( $this->comment->comment_ID, 'summary', true ) ;
2021-02-18 07:12:32 +01:00
if ( !empty( $summary ) ) {
2022-09-28 19:18:30 +02:00
$content_warning = \Activitypub\add_summary( $summary );
2021-02-18 07:12:32 +01:00
} */
2022-09-28 19:18:30 +02:00
return $content_warning;
2021-02-18 07:12:32 +01:00
}
/**
* Who is being replied to
*/
2023-03-10 22:54:50 +01:00
public function get_content() {
$comment = $this->comment;
if ( isset( $this->content ) ) {
return $this->content;
2022-04-15 09:17:00 +02:00
}
2023-03-10 22:54:50 +01:00
$comment_content = $comment->comment_content;
$filtered_content = \apply_filters( 'the_content', $comment_content, $comment );
$decoded_content = \html_entity_decode( $filtered_content, \ENT_QUOTES, 'UTF-8' );
$content = \trim( \preg_replace( '/[\n\r\t]/', '', $decoded_content ) );
$this->content = $content;
return $content;
2021-02-18 07:12:32 +01:00
}
/**
* Mention user being replied to
*/
public function generate_tags() {
2023-01-30 05:44:52 +01:00
if ( $this->tags ) {
return $this->tags;
}
$tags = array();
$mentions = apply_filters( 'activitypub_extract_mentions', array(), $this->comment->comment_content, $this );
if ( $mentions ) {
foreach ( $mentions as $mention => $url ) {
$tag = array(
2021-02-18 07:12:32 +01:00
'type' => 'Mention',
2023-01-30 05:44:52 +01:00
'href' => $url,
'name' => $mention,
2021-02-18 07:12:32 +01:00
);
2023-01-30 05:44:52 +01:00
$tags[] = $tag;
2021-02-18 07:12:32 +01:00
}
}
2023-01-30 05:44:52 +01:00
$this->tags = $tags;
return $tags;
2021-02-18 07:12:32 +01:00
}
/**
2022-04-15 03:04:43 +02:00
* Generate updated datetime
*/
public function generate_update() {
$comment = $this->comment;
$updated = null;
if ( \get_comment_meta( $comment->comment_ID, 'ap_last_modified', true ) ) {
$updated = \wp_date( 'Y-m-d\TH:i:s\Z', \get_comment_meta( $comment->comment_ID, 'ap_last_modified', true ) );
}
return $updated;
}
/**
* Generate deleted datetime
*/
public function generate_trash() {
$comment = $this->comment;
$deleted = null;
2022-09-28 19:18:30 +02:00
if ( 'trash' === $comment->status ) {
$deleted = \gmdate( 'Y-m-d\TH:i:s\Z', \strtotime( $comment->comment_date_gmt ) );
2022-04-15 03:04:43 +02:00
}
return $deleted;
}
/**
* Generate replies collections
2021-02-18 07:12:32 +01:00
*/
2022-04-15 03:04:43 +02:00
public function generate_replies() {
$comment = $this->comment;
2022-09-28 19:18:30 +02:00
$replies = array();
2022-04-15 03:04:43 +02:00
$args = array(
2022-04-15 09:17:00 +02:00
'post_id' => $comment->comment_post_ID,
'parent' => $comment->comment_ID,
'status' => 'approve',
'hierarchical' => false,
2022-04-15 03:04:43 +02:00
);
$comments_list = \get_comments( $args );
if ( $comments_list ) {
2022-04-15 09:17:00 +02:00
$items = array();
foreach ( $comments_list as $comment ) {
// remote replies
$source_url = \get_comment_meta( $comment->comment_ID, 'source_url', true );
2022-09-28 19:18:30 +02:00
if ( ! empty( $source_url ) ) {
$items[] = $source_url;
} else {
// local replies
$comment_url = \add_query_arg( //
array(
'p' => $comment->comment_post_ID,
'replytocom' => $comment->comment_ID,
),
trailingslashit( site_url() )
);
$items[] = $comment_url;
}
2022-04-15 03:04:43 +02:00
}
2022-09-28 19:18:30 +02:00
2022-04-15 09:17:00 +02:00
$replies = (object) array(
'type' => 'Collection',
'id' => \add_query_arg( array( 'replies' => '' ), $this->id ),
'first' => (object) array(
'type' => 'CollectionPage',
'partOf' => \add_query_arg( array( 'replies' => '' ), $this->id ),
'items' => $items,
),
);
2022-04-15 03:04:43 +02:00
}
return $replies;
2021-02-18 07:12:32 +01:00
}
2022-04-15 09:17:00 +02:00
}