Completed
Push — master ( 8e75ab...e22200 )
by Gary
02:28
created

WP_REST_React_Controller::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 3
nc 1
nop 0
1
<?php
2
3
/**
4
 * Class WP_REST_React_Controller
5
 */
6
class WP_REST_React_Controller {
7
	/**
8
	 * Constructor.
9
	 */
10
	public function __construct() {
11
		$this->namespace = 'wp/v2';
0 ignored issues
show
Bug introduced by
The property namespace does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
12
		$this->rest_base = 'react';
0 ignored issues
show
Bug introduced by
The property rest_base does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
13
	}
14
15
	/**
16
	 * Register the routes for the objects of the controller.
17
	 */
18
	public function register_routes() {
19
		register_rest_route( $this->namespace, $this->rest_base, array(
20
			array(
21
				'methods'             => WP_Rest_Server::READABLE,
22
				'callback'            => array( $this, 'get_items' ),
23
				'permission_callback' => array( $this, 'get_items_permission_callback' ),
24
				'args'                => $this->get_collection_params(),
25
			),
26
			array(
27
				'methods'             => WP_Rest_Server::CREATABLE,
28
				'callback'            => array( $this, 'create_item' ),
29
				'permission_callback' => array( $this, 'create_item_permission_callback' ),
30
				'args'                => $this->get_creation_params(),
31
			),
32
			'schema' => array( $this, 'get_public_item_schema' ),
33
		) );
34
	}
35
36
	/**
37
	 * Check if a given request has access to read reactions.
38
	 *
39
	 * @param  WP_REST_Request $request Full details about the request.
40
	 * @return WP_Error|boolean
41
	 */
42
	public function get_items_permissions_check( $request ) {
43
		if ( ! empty( $request['post'] ) ) {
44
			foreach ( (array) $request['post'] as $post_id ) {
45
				$post = get_post( $post_id );
46
				if ( ! empty( $post_id ) && $post && ! $this->check_read_post_permission( $post ) ) {
0 ignored issues
show
Bug introduced by
The method check_read_post_permission() does not seem to exist on object<WP_REST_React_Controller>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
47
					return new WP_Error( 'rest_cannot_read_post', __( 'Sorry, you cannot read the post for this reaction.' ), array( 'status' => rest_authorization_required_code() ) );
48
				} else if ( 0 === $post_id && ! current_user_can( 'moderate_comments' ) ) {
49
					return new WP_Error( 'rest_cannot_read', __( 'Sorry, you cannot read reactions without a post.' ), array( 'status' => rest_authorization_required_code() ) );
50
				}
51
			}
52
		}
53
54
		return true;
55
	}
56
57
	/**
58
	 * Get a list of reactions.
59
	 *
60
	 * @param  WP_REST_Request $request Full details about the request.
61
	 * @return WP_Error|WP_REST_Response
62
	 */
63
	public function get_items( $request ) {
64
		$prepared_args = array(
65
			'post__in' => $request['post'],
66
			'type'     => 'reaction',
67
		);
68
69
		/**
70
		 * Filter arguments, before passing to WP_Comment_Query, when querying reactions via the REST API.
71
		 *
72
		 * @see https://developer.wordpress.org/reference/classes/wp_comment_query/
73
		 *
74
		 * @param array           $prepared_args Array of arguments for WP_Comment_Query.
75
		 * @param WP_REST_Request $request       The current request.
76
		 */
77
		$prepared_args = apply_filters( 'rest_reaction_query', $prepared_args, $request );
78
79
		$query = new WP_Comment_Query;
80
		$query_result = $query->query( $prepared_args );
81
82
		$reactions_count = array();
83
		foreach( $query_result as $reaction ) {
84
			if ( empty( $reactions_count[ $reaction->comment_content ] ) ) {
85
				$reactions_count[ $reaction->comment_content ] = array(
86
					'count'   => 0,
87
					'post_id' => $reaction->comment_post_ID,
88
				);
89
			}
90
91
			$reactions_count[ $reaction->comment_content ]++;
92
		}
93
94
		$reactions = array();
95
		foreach( $reactions_count as $emoji => $data ) {
96
			$reaction = array(
97
				'emoji'   => $emoji,
98
				'count'   => $data['count'],
99
				'post_id' => $data['post_id'],
100
			);
101
102
			$data = $this->prepare_item_for_response( $reaction, $request );
103
			$reactions[] = $this->prepare_response_for_collection( $data );
0 ignored issues
show
Bug introduced by
The method prepare_response_for_collection() does not seem to exist on object<WP_REST_React_Controller>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
104
		}
105
106
		$total_reactions = (int) $query->found_comments;
107
		$reaction_groups = count( $reactions );
108
109
		$response = rest_ensure_response( $reactions );
110
		$response->header( 'X-WP-Total', $total_reactions );
111
		$response->header( 'X-WP-TotalGroups', $reaction_groups );
112
113
		return $response;
114
	}
115
116
	/**
117
	 * Check if a given request has access to create a reaction
118
	 *
119
	 * @param  WP_REST_Request $request Full details about the request.
120
	 * @return WP_Error|boolean
121
	 */
122
	public function create_item_permissions_check( $request ) {
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
123
		return true;
124
	}
125
126
	/**
127
	 * Create a reaction.
128
	 *
129
	 * @param  WP_REST_Request $request Full details about the request.
130
	 * @return WP_Error|WP_REST_Response
131
	 */
132
	public function create_item( $request ) {
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
133
	}
134
135
	/**
136
	 * Prepare a reaction group output for response.
137
	 *
138
	 * @param  array            $reaction Reaction data.
139
	 * @param  WP_REST_Request  $request  Request object.
140
	 * @return WP_REST_Response $response
141
	 */
142
	public function prepare_item_for_response( $reaction, $request ) {
143
		$data = array(
144
			'emoji'   => $reaction['emoji'],
145
			'count'   => (int) $reaction['count'],
146
			'post_id' => (int) $reaction['post_id'],
147
		);
148
149
		// Wrap the data in a response object
150
		$response = rest_ensure_response( $data );
151
152
		$response->add_links( $this->prepare_links( $reaction ) );
153
154
		/**
155
		 * Filter a reaction group returned from the API.
156
		 *
157
		 * Allows modification of the reaction right before it is returned.
158
		 *
159
		 * @param WP_REST_Response  $response   The response object.
160
		 * @param array             $reaction   The original reaction data.
161
		 * @param WP_REST_Request   $request    Request used to generate the response.
162
		 */
163
		return apply_filters( 'rest_prepare_comment', $response, $reaction, $request );
164
	}
165
166
	/**
167
	 * Prepare links for the request.
168
	 *
169
	 * @param array $comment Reaction.
0 ignored issues
show
Bug introduced by
There is no parameter named $comment. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
170
	 * @return array Links for the given reaction.
171
	 */
172
	protected function prepare_links( $reaction ) {
173
		$links = array(
174
			'self' => array(
175
				'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $comment->emoji ) ),
0 ignored issues
show
Bug introduced by
The variable $comment does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
176
			),
177
			'collection' => array(
178
				'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ),
179
			),
180
		);
181
182
		if ( 0 !== (int) $reaction['post_id'] ) {
183
			$post = get_post( $reaction['post_id'] );
184
			if ( ! empty( $post->ID ) ) {
185
				$obj = get_post_type_object( $post->post_type );
186
				$base = ! empty( $obj->rest_base ) ? $obj->rest_base : $obj->name;
187
				$links['up'] = array(
188
					'href'       => rest_url( '/wp/v2/' . $base . '/' . $reaction['post_id'] ),
189
					'embeddable' => true,
190
					'post_type'  => $post->post_type,
191
				);
192
			}
193
		}
194
195
		return $links;
196
	}
197
198
	/**
199
	 * Get the query params for collections
200
	 *
201
	 * @return array
202
	 */
203
	public function get_collection_params() {
204
		$query_params = array();
205
206
		$query_params['post']   = array(
207
			'default'           => array(),
208
			'description'       => __( 'Limit result set to resources assigned to specific post ids.' ),
209
			'type'              => 'array',
210
			'sanitize_callback' => 'wp_parse_id_list',
211
			'validate_callback' => 'rest_validate_request_arg',
212
		);
213
214
		return $query_params;
215
	}
216
	/**
217
	 * Get the query params for collections
218
	 *
219
	 * @return array
220
	 */
221
	public function get_creation_params() {
222
		$query_params = array();
223
224
		$query_params['post']   = array(
225
			'default'           => array(),
226
			'description'       => __( 'The post ID to add a reaction to.' ),
227
			'type'              => 'integer',
228
			'sanitize_callback' => 'absint',
229
			'validate_callback' => 'rest_validate_request_arg',
230
		);
231
232
		$query_params['emoji']  = array(
233
			'default'           => array(),
234
			'description'       => __( 'The reaction emoji.' ),
235
			'type'              => 'string',
236
			'validate_callback' => 'rest_validate_request_arg',
237
		);
238
239
		return $query_params;
240
	}
241
}