Skip to content

Commit e13fb5e

Browse files
Changes to WordCamp and Meetup REST API endpoints (#926)
* List meetups on their REST API base and hide all meetups without public post status * Prevent getting non-public WordCamp data from REST API
1 parent 4fcecb6 commit e13fb5e

File tree

3 files changed

+161
-18
lines changed

3 files changed

+161
-18
lines changed
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php
2+
3+
/**
4+
* Class to access Meetup CPT posts via the v2 REST API.
5+
*
6+
* @see WP_REST_Posts_Controller
7+
*/
8+
class WordCamp_REST_Meetups_Controller extends WP_REST_Posts_Controller {
9+
/**
10+
* Retrieves the Meetup post's schema, conforming to JSON Schema.
11+
*
12+
* Meetup-specific modifications to the standard post schema.
13+
*
14+
* @access public
15+
*
16+
* @return array Item schema data.
17+
*/
18+
public function get_item_schema() {
19+
$schema = parent::get_item_schema();
20+
21+
// Since there is more than one public post status, show it in REST response.
22+
if ( false === array_search( 'view', $schema['properties']['status']['context'] ) ) {
23+
$schema['properties']['status']['context'][] = 'view';
24+
}
25+
26+
return $this->add_additional_fields_schema( $schema );
27+
}
28+
29+
/**
30+
* Sanitizes and validates the list of post statuses, including whether the
31+
* user can query private statuses.
32+
*
33+
* Based on the method in WP_REST_Posts_Controller, but takes into account that
34+
* there are multiple public statuses for the Meetup CPT.
35+
*
36+
* @access public
37+
*
38+
* @param string|array $statuses One or more post statuses.
39+
* @param WP_REST_Request $request Full details about the request.
40+
* @param string $parameter Additional parameter to pass to validation.
41+
* @return array|WP_Error A list of valid statuses, otherwise WP_Error object.
42+
*/
43+
public function sanitize_post_statuses( $statuses, $request, $parameter ) {
44+
$statuses = wp_parse_slug_list( $statuses );
45+
46+
$public_statuses = Meetup_Loader::get_public_post_statuses();
47+
48+
foreach ( $statuses as $status ) {
49+
if ( in_array( $status, $public_statuses ) ) {
50+
continue;
51+
}
52+
53+
$post_type_obj = get_post_type_object( $this->post_type );
54+
55+
if ( current_user_can( $post_type_obj->cap->edit_posts ) ) {
56+
$result = rest_validate_request_arg( $status, $request, $parameter );
57+
if ( is_wp_error( $result ) ) {
58+
return $result;
59+
}
60+
} else {
61+
return new WP_Error( 'rest_forbidden_status', __( 'Status is forbidden.' ), array( 'status' => rest_authorization_required_code() ) );
62+
}
63+
}
64+
65+
return $statuses;
66+
}
67+
68+
/**
69+
* Checks if user can read the Meetup post.
70+
*
71+
* First make our custom check against public Meetup statuses and
72+
* after that fallback to default WP_REST_Posts_Controller for assurance.
73+
*
74+
* @access public
75+
*
76+
* @param object $post Post object.
77+
* @return bool Whether the post can be read.
78+
*/
79+
public function check_read_permission( $post ) {
80+
$public_statuses = Meetup_Loader::get_public_post_statuses();
81+
82+
// If post status is not listed as public, it cannot be read.
83+
if ( ! in_array( $post->post_status, $public_statuses ) ) {
84+
return false;
85+
}
86+
87+
// Fallback to default read permission check.
88+
return WP_REST_Posts_Controller::check_read_permission( $post );
89+
}
90+
}

public_html/wp-content/plugins/wcpt/wcpt-meetup/meetup-loader.php

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public function __construct() {
2525
parent::__construct();
2626
add_action( 'init', array( $this, 'register_meetup_taxonomy' ) );
2727
add_action( 'set_object_terms', array( $this, 'log_meetup_tags' ), 10, 6 );
28+
add_filter( 'rest_wp_meetup_collection_params', array( $this, 'set_rest_post_status_default' ) );
2829
}
2930

3031
/**
@@ -53,16 +54,19 @@ public function log_meetup_tags( $event_id, $terms, $tt_ids, $taxonomy, $append,
5354
'object_ids' => $event_id,
5455
'term_taxonomy_id' => $tt_added_ids,
5556
'fields' => 'names',
56-
)
57-
);
57+
) );
5858

5959
$added_terms = $added_terms_query->get_terms();
6060

61-
add_post_meta( $event_id, '_tags_log', array(
62-
'timestamp' => time(),
63-
'user_id' => get_current_user_id(),
64-
'message' => 'Tags added: ' . join( ', ', $added_terms ),
65-
) );
61+
add_post_meta(
62+
$event_id,
63+
'_tags_log',
64+
array(
65+
'timestamp' => time(),
66+
'user_id' => get_current_user_id(),
67+
'message' => 'Tags added: ' . join( ', ', $added_terms ),
68+
)
69+
);
6670
}
6771

6872
if ( count( $tt_removed_ids ) > 0 ) {
@@ -71,14 +75,17 @@ public function log_meetup_tags( $event_id, $terms, $tt_ids, $taxonomy, $append,
7175
'term_taxonomy_id' => $tt_removed_ids,
7276
'fields' => 'names',
7377
'hide_empty' => false,
74-
)
75-
) )->get_terms();
76-
77-
add_post_meta( $event_id, '_tags_log', array(
78-
'timestamp' => time(),
79-
'user_id' => get_current_user_id(),
80-
'message' => 'Tags removed: ' . join( ', ', $removed_terms ),
81-
) );
78+
) ) )->get_terms();
79+
80+
add_post_meta(
81+
$event_id,
82+
'_tags_log',
83+
array(
84+
'timestamp' => time(),
85+
'user_id' => get_current_user_id(),
86+
'message' => 'Tags removed: ' . join( ', ', $removed_terms ),
87+
)
88+
);
8289
}
8390

8491
}
@@ -111,13 +118,14 @@ public function register_meetup_taxonomy() {
111118
* Include files specific for meetup event
112119
*/
113120
public function includes() {
121+
require_once WCPT_DIR . 'wcpt-meetup/class-wp-rest-meetups-controller.php';
114122
}
115123

116124
/**
117125
* Register meetup custom post type
118126
*/
119127
public function register_post_types() {
120-
// Meetup post type labels
128+
// Meetup post type labels.
121129
$wcpt_labels = array(
122130
'name' => __( 'Meetups', 'wordcamporg' ),
123131
'singular_name' => __( 'Meetup', 'wordcamporg' ),
@@ -147,9 +155,10 @@ public function register_post_types() {
147155
'author',
148156
);
149157

150-
// Register WordCamp post type
158+
// Register meetup post type.
151159
register_post_type(
152-
Meetup_Application::POST_TYPE, array(
160+
Meetup_Application::POST_TYPE,
161+
array(
153162
'labels' => $wcpt_labels,
154163
'rewrite' => $wcpt_rewrite,
155164
'supports' => $wcpt_supports,
@@ -177,6 +186,7 @@ public function register_post_types() {
177186
'menu_icon' => 'dashicons-wordpress',
178187
'show_in_rest' => true,
179188
'rest_base' => 'meetups',
189+
'rest_controller_class' => 'WordCamp_REST_Meetups_Controller',
180190
)
181191
);
182192
}
@@ -199,6 +209,23 @@ public static function get_public_post_statuses() {
199209
return Meetup_Application::get_public_post_statuses();
200210
}
201211

212+
/**
213+
* Change the default status used for the Meetup CPT in the v2 REST API.
214+
*
215+
* @hooked filter rest_wp_meetup_collection_params
216+
*
217+
* @param array $query_params
218+
*
219+
* @return array
220+
*/
221+
public function set_rest_post_status_default( $query_params ) {
222+
if ( isset( $query_params['status'] ) ) {
223+
$query_params['status']['default'] = self::get_public_post_statuses();
224+
}
225+
226+
return $query_params;
227+
}
228+
202229
}
203230

204231
endif;

public_html/wp-content/plugins/wcpt/wcpt-wordcamp/class-wp-rest-wordcamps-controller.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,30 @@ public function sanitize_post_statuses( $statuses, $request, $parameter ) {
8181

8282
return $statuses;
8383
}
84+
85+
/**
86+
* Checks if user can read the WordCamp post.
87+
*
88+
* First make our custom check against public WordCamp statuses and
89+
* after that fallback to default WP_REST_Posts_Controller for assurance.
90+
*
91+
* @access public
92+
*
93+
* @param object $post Post object.
94+
* @return bool Whether the post can be read.
95+
*/
96+
public function check_read_permission( $post ) {
97+
$public_statuses = WordCamp_Loader::get_public_post_statuses();
98+
99+
// Camps that are scheduled and then cancelled should still be available (though not included by default).
100+
$public_statuses[] = 'wcpt-cancelled';
101+
102+
// If post status is not listed as public, it cannot be read.
103+
if ( ! in_array( $post->post_status, $public_statuses ) ) {
104+
return false;
105+
}
106+
107+
// Fallback to default read permission check.
108+
return WP_REST_Posts_Controller::check_read_permission( $post );
109+
}
84110
}

0 commit comments

Comments
 (0)