PluginProbe
ActivityPub / trunk
ActivityPub vtrunk
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 / class-comments-controller.php

class-comments-controller.php in ActivityPub trunk, at includes/rest/class-comments-controller.php

169 lines 4.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Comments_Controller file.
4 *
5 * @package Activitypub
6 */
7
8 namespace Activitypub\Rest;
9
10 use Activitypub\Comment;
11 use Activitypub\Webfinger;
12
13 use function Activitypub\is_post_publicly_queryable;
14
15 /**
16 * Comments_Controller class.
17 *
18 * @author Matthias Pfefferle
19 *
20 * @see https://www.w3.org/TR/activitypub/#followers
21 */
22 class Comments_Controller extends \WP_REST_Controller {
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 = 'comments/(?P<comment_id>[\d]+)';
36
37 /**
38 * Register routes.
39 */
40 public function register_routes() {
41 \register_rest_route(
42 $this->namespace,
43 '/' . $this->rest_base . '/remote-reply',
44 array(
45 'args' => array(
46 'comment_id' => array(
47 'description' => 'The ID of the comment.',
48 'type' => 'integer',
49 'minimum' => 1,
50 'required' => true,
51 'validate_callback' => array( $this, 'validate_comment' ),
52 ),
53 ),
54 array(
55 'methods' => \WP_REST_Server::READABLE,
56 'callback' => array( $this, 'get_item' ),
57 'permission_callback' => '__return_true',
58 'args' => array(
59 'resource' => array(
60 'description' => 'The resource to reply to.',
61 'type' => 'string',
62 'required' => true,
63 ),
64 ),
65 ),
66 'schema' => array( $this, 'get_item_schema' ),
67 )
68 );
69 }
70
71 /**
72 * Validates if a comment can be replied to remotely.
73 *
74 * @param mixed $param The parameter to validate.
75 *
76 * @return true|\WP_Error True if the comment can be replied to, WP_Error otherwise.
77 */
78 public function validate_comment( $param ) {
79 $comment = \get_comment( $param );
80
81 if ( ! $comment ) {
82 return new \WP_Error( 'activitypub_comment_not_found', \__( 'Comment not found', 'activitypub' ), array( 'status' => 404 ) );
83 }
84
85 /*
86 * A comment inherits the visibility of its parent post. Check this
87 * BEFORE the local-only guard below, so that any comment on a non-
88 * publicly-queryable parent returns the same "not found" shape — we
89 * never want an outsider to distinguish "comment exists but is local"
90 * from "comment missing" when the parent post is private.
91 */
92 if ( ! is_post_publicly_queryable( $comment->comment_post_ID ) ) {
93 return new \WP_Error( 'activitypub_comment_not_found', \__( 'Comment not found', 'activitypub' ), array( 'status' => 404 ) );
94 }
95
96 if ( Comment::is_local( $comment ) ) {
97 return new \WP_Error( 'activitypub_local_only_comment', \__( 'Comment is local only', 'activitypub' ), array( 'status' => 403 ) );
98 }
99
100 return true;
101 }
102
103 /**
104 * Retrieves the remote reply URL for a comment.
105 *
106 * @param \WP_REST_Request $request The request object.
107 *
108 * @return \WP_REST_Response|\WP_Error Response object or WP_Error object.
109 */
110 public function get_item( $request ) {
111 $resource = $request->get_param( 'resource' );
112 $comment_id = $request->get_param( 'comment_id' );
113
114 $template = Webfinger::get_remote_follow_endpoint( $resource );
115
116 if ( \is_wp_error( $template ) ) {
117 return $template;
118 }
119
120 $resource = Comment::get_source_id( $comment_id );
121
122 if ( ! $resource ) {
123 $resource = Comment::generate_id( \get_comment( $comment_id ) );
124 }
125
126 $url = \str_replace( '{uri}', $resource, $template );
127
128 return \rest_ensure_response(
129 array(
130 'url' => $url,
131 'template' => $template,
132 )
133 );
134 }
135
136 /**
137 * Retrieves the schema for the remote reply endpoint.
138 *
139 * @return array Schema data.
140 */
141 public function get_item_schema() {
142 if ( $this->schema ) {
143 return $this->add_additional_fields_schema( $this->schema );
144 }
145
146 $this->schema = array(
147 '$schema' => 'http://json-schema.org/draft-04/schema#',
148 'title' => 'remote-reply',
149 'type' => 'object',
150 'properties' => array(
151 'url' => array(
152 'description' => 'The URL to the remote reply page.',
153 'type' => 'string',
154 'format' => 'uri',
155 'required' => true,
156 ),
157 'template' => array(
158 'description' => 'The template URL for remote replies.',
159 'type' => 'string',
160 'format' => 'uri',
161 'required' => true,
162 ),
163 ),
164 );
165
166 return $this->add_additional_fields_schema( $this->schema );
167 }
168 }
169