WordPress REST API (Version 2) - Version 2.0-beta8

Version Description

Download this release

Release Info

Developer danielbachhuber
Plugin Icon 128x128 WordPress REST API (Version 2)
Version 2.0-beta8
Comparing to
See all releases

Code changes from version 2.0-beta7 to 2.0-beta8

CHANGELOG.md CHANGED
@@ -1,5 +1,41 @@
1
  # Changelog
2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  ## 2.0 Beta 7.0
4
 
5
  - Sync infrastructure from WordPress core as of r35691.
1
  # Changelog
2
 
3
+ ## 2.0 Beta 8.0
4
+
5
+ - Prevent fatals when uploading attachment by including admin utilities.
6
+
7
+ (props @danielbachhuber, [#1756](https://github.com/WP-API/WP-API/pull/1756))
8
+
9
+ - Return 201 status code when creating a term.
10
+
11
+ (props @danielbachhuber, [#1753](https://github.com/WP-API/WP-API/pull/1753))
12
+
13
+ - Don't permit requesting terms cross routes.
14
+
15
+ Clients should only be able to request categories from the category route, and tags from the tag route.
16
+
17
+ (props @danielbachhuber, [#1764](https://github.com/WP-API/WP-API/pull/1764))
18
+
19
+ - Set `fields=>id` when using `WP_User_Query` to fix large memory usage
20
+
21
+ (props @joehoyle, [#1770](https://github.com/WP-API/WP-API/pull/1770))
22
+
23
+ - Fix Post `_link` to attached attachments.
24
+
25
+ (props @danielbachhuber, [#1777](https://github.com/WP-API/WP-API/pull/1777))
26
+
27
+ - Add support for getting a post with a custom public status.
28
+
29
+ (props @danielbachhuber, [#1765](https://github.com/WP-API/WP-API/pull/1765))
30
+
31
+ - Ensure post content doesn't get double-slashed on update.
32
+
33
+ (props @joehoyle, [#1772](https://github.com/WP-API/WP-API/pull/1772))
34
+
35
+ - Change 'int' to 'integer' for `WP_REST_Controller::validate_schema_property()`
36
+
37
+ (props @wpsmith, [#1759](https://github.com/WP-API/WP-API/pull/1759))
38
+
39
  ## 2.0 Beta 7.0
40
 
41
  - Sync infrastructure from WordPress core as of r35691.
lib/endpoints/class-wp-rest-attachments-controller.php CHANGED
@@ -330,6 +330,9 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
330
  // Get the content-type
331
  $type = array_shift( $headers['content_type'] );
332
 
 
 
 
333
  // Save the file
334
  $tmpfname = wp_tempnam( $filename );
335
 
@@ -364,6 +367,22 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
364
  return $sideloaded;
365
  }
366
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
367
  /**
368
  * Handle an upload via multipart/form-data ($_FILES)
369
  *
330
  // Get the content-type
331
  $type = array_shift( $headers['content_type'] );
332
 
333
+ /** Include admin functions to get access to wp_tempnam() and wp_handle_sideload() */
334
+ require_once ABSPATH . 'wp-admin/includes/admin.php';
335
+
336
  // Save the file
337
  $tmpfname = wp_tempnam( $filename );
338
 
367
  return $sideloaded;
368
  }
369
 
370
+ /**
371
+ * Get the query params for collections of attachments.
372
+ *
373
+ * @return array
374
+ */
375
+ public function get_collection_params() {
376
+ $params = parent::get_collection_params();
377
+ $params['parent'] = array(
378
+ 'description' => 'Limit results to attachments from a specified parent.',
379
+ 'type' => 'integer',
380
+ 'default' => null,
381
+ 'sanitize_callback' => 'absint',
382
+ );
383
+ return $params;
384
+ }
385
+
386
  /**
387
  * Handle an upload via multipart/form-data ($_FILES)
388
  *
lib/endpoints/class-wp-rest-meta-controller.php CHANGED
@@ -103,7 +103,7 @@ abstract class WP_REST_Meta_Controller extends WP_REST_Controller {
103
  'properties' => array(
104
  'id' => array(
105
  'description' => 'Unique identifier for the object.',
106
- 'type' => 'int',
107
  'context' => array( 'edit' ),
108
  'readonly' => true,
109
  ),
103
  'properties' => array(
104
  'id' => array(
105
  'description' => 'Unique identifier for the object.',
106
+ 'type' => 'integer',
107
  'context' => array( 'edit' ),
108
  'readonly' => true,
109
  ),
lib/endpoints/class-wp-rest-posts-controller.php CHANGED
@@ -15,20 +15,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
15
 
16
  $base = $this->get_post_type_base( $this->post_type );
17
 
18
- $posts_args = array(
19
- 'context' => array(
20
- 'default' => 'view',
21
- ),
22
- 'page' => array(
23
- 'default' => 1,
24
- 'sanitize_callback' => 'absint',
25
- ),
26
- 'per_page' => array(
27
- 'default' => 10,
28
- 'sanitize_callback' => 'absint',
29
- ),
30
- 'filter' => array(),
31
- );
32
 
33
  register_rest_route( 'wp/v2', '/' . $base, array(
34
  array(
@@ -88,6 +75,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
88
  $args = array();
89
  $args['paged'] = $request['page'];
90
  $args['posts_per_page'] = $request['per_page'];
 
91
 
92
  if ( is_array( $request['filter'] ) ) {
93
  $args = array_merge( $args, $request['filter'] );
@@ -263,8 +251,8 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
263
  if ( is_wp_error( $post ) ) {
264
  return $post;
265
  }
266
-
267
- $post_id = wp_update_post( $post, true );
268
  if ( is_wp_error( $post_id ) ) {
269
  if ( in_array( $post_id->get_error_code(), array( 'db_update_error' ) ) ) {
270
  $post_id->add_data( array( 'status' => 500 ) );
@@ -947,6 +935,11 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
947
  return true;
948
  }
949
 
 
 
 
 
 
950
  // Can we read the parent if we're inheriting?
951
  if ( 'inherit' === $post->post_status && $post->post_parent > 0 ) {
952
  $parent = get_post( $post->post_parent );
@@ -1212,22 +1205,22 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
1212
  // If we have a featured image, add that.
1213
  if ( $featured_image = get_post_thumbnail_id( $post->ID ) ) {
1214
  $image_url = rest_url( 'wp/v2/media/' . $featured_image );
1215
- $links['http://api.w.org/featuredmedia'] = array(
1216
  'href' => $image_url,
1217
  'embeddable' => true,
1218
  );
1219
  }
1220
  if ( ! in_array( $post->post_type, array( 'attachment', 'nav_menu_item', 'revision' ) ) ) {
1221
  $attachments_url = rest_url( 'wp/v2/media' );
1222
- $attachments_url = add_query_arg( 'post_parent', $post->ID, $attachments_url );
1223
- $links['http://api.w.org/attachment'] = array(
1224
  'href' => $attachments_url,
1225
  );
1226
  }
1227
 
1228
  $taxonomies = get_object_taxonomies( $post->post_type );
1229
  if ( ! empty( $taxonomies ) ) {
1230
- $links['http://api.w.org/term'] = array();
1231
 
1232
  foreach ( $taxonomies as $tax ) {
1233
  $taxonomy_obj = get_taxonomy( $tax );
@@ -1239,7 +1232,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
1239
  $tax_base = ! empty( $taxonomy_obj->rest_base ) ? $taxonomy_obj->rest_base : $tax;
1240
  $terms_url = rest_url( trailingslashit( $base ) . $post->ID . '/terms/' . $tax_base );
1241
 
1242
- $links['http://api.w.org/term'][] = array(
1243
  'href' => $terms_url,
1244
  'taxonomy' => $tax,
1245
  'embeddable' => true,
@@ -1248,7 +1241,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
1248
  }
1249
 
1250
  if ( post_type_supports( $post->post_type, 'custom-fields' ) ) {
1251
- $links['http://api.w.org/meta'] = array(
1252
  'href' => rest_url( trailingslashit( $base ) . $post->ID . '/meta' ),
1253
  'embeddable' => true,
1254
  );
@@ -1544,4 +1537,15 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
1544
  return $this->add_additional_fields_schema( $schema );
1545
  }
1546
 
 
 
 
 
 
 
 
 
 
 
 
1547
  }
15
 
16
  $base = $this->get_post_type_base( $this->post_type );
17
 
18
+ $posts_args = $this->get_collection_params();
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
  register_rest_route( 'wp/v2', '/' . $base, array(
21
  array(
75
  $args = array();
76
  $args['paged'] = $request['page'];
77
  $args['posts_per_page'] = $request['per_page'];
78
+ $args['post_parent'] = $request['parent'];
79
 
80
  if ( is_array( $request['filter'] ) ) {
81
  $args = array_merge( $args, $request['filter'] );
251
  if ( is_wp_error( $post ) ) {
252
  return $post;
253
  }
254
+ // convert the post object to an array, otherwise wp_update_post will expect non-escaped input
255
+ $post_id = wp_update_post( (array) $post, true );
256
  if ( is_wp_error( $post_id ) ) {
257
  if ( in_array( $post_id->get_error_code(), array( 'db_update_error' ) ) ) {
258
  $post_id->add_data( array( 'status' => 500 ) );
935
  return true;
936
  }
937
 
938
+ $post_status_obj = get_post_status_object( $post->post_status );
939
+ if ( $post_status_obj && $post_status_obj->public ) {
940
+ return true;
941
+ }
942
+
943
  // Can we read the parent if we're inheriting?
944
  if ( 'inherit' === $post->post_status && $post->post_parent > 0 ) {
945
  $parent = get_post( $post->post_parent );
1205
  // If we have a featured image, add that.
1206
  if ( $featured_image = get_post_thumbnail_id( $post->ID ) ) {
1207
  $image_url = rest_url( 'wp/v2/media/' . $featured_image );
1208
+ $links['https://api.w.org/featuredmedia'] = array(
1209
  'href' => $image_url,
1210
  'embeddable' => true,
1211
  );
1212
  }
1213
  if ( ! in_array( $post->post_type, array( 'attachment', 'nav_menu_item', 'revision' ) ) ) {
1214
  $attachments_url = rest_url( 'wp/v2/media' );
1215
+ $attachments_url = add_query_arg( 'parent', $post->ID, $attachments_url );
1216
+ $links['https://api.w.org/attachment'] = array(
1217
  'href' => $attachments_url,
1218
  );
1219
  }
1220
 
1221
  $taxonomies = get_object_taxonomies( $post->post_type );
1222
  if ( ! empty( $taxonomies ) ) {
1223
+ $links['https://api.w.org/term'] = array();
1224
 
1225
  foreach ( $taxonomies as $tax ) {
1226
  $taxonomy_obj = get_taxonomy( $tax );
1232
  $tax_base = ! empty( $taxonomy_obj->rest_base ) ? $taxonomy_obj->rest_base : $tax;
1233
  $terms_url = rest_url( trailingslashit( $base ) . $post->ID . '/terms/' . $tax_base );
1234
 
1235
+ $links['https://api.w.org/term'][] = array(
1236
  'href' => $terms_url,
1237
  'taxonomy' => $tax,
1238
  'embeddable' => true,
1241
  }
1242
 
1243
  if ( post_type_supports( $post->post_type, 'custom-fields' ) ) {
1244
+ $links['https://api.w.org/meta'] = array(
1245
  'href' => rest_url( trailingslashit( $base ) . $post->ID . '/meta' ),
1246
  'embeddable' => true,
1247
  );
1537
  return $this->add_additional_fields_schema( $schema );
1538
  }
1539
 
1540
+ /**
1541
+ * Get the query params for collections of attachments.
1542
+ *
1543
+ * @return array
1544
+ */
1545
+ public function get_collection_params() {
1546
+ $params = parent::get_collection_params();
1547
+ $params['filter'] = array();
1548
+ return $params;
1549
+ }
1550
+
1551
  }
lib/endpoints/class-wp-rest-terms-controller.php CHANGED
@@ -138,7 +138,7 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
138
  public function get_item( $request ) {
139
 
140
  $term = get_term_by( 'term_taxonomy_id', (int) $request['id'], $this->taxonomy );
141
- if ( ! $term ) {
142
  return new WP_Error( 'rest_term_invalid', __( "Term doesn't exist." ), array( 'status' => 404 ) );
143
  }
144
  if ( is_wp_error( $term ) ) {
@@ -202,7 +202,10 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
202
  'id' => $term['term_taxonomy_id'],
203
  ) );
204
 
205
- return rest_ensure_response( $response );
 
 
 
206
  }
207
 
208
  /**
138
  public function get_item( $request ) {
139
 
140
  $term = get_term_by( 'term_taxonomy_id', (int) $request['id'], $this->taxonomy );
141
+ if ( ! $term || $term->taxonomy !== $this->taxonomy ) {
142
  return new WP_Error( 'rest_term_invalid', __( "Term doesn't exist." ), array( 'status' => 404 ) );
143
  }
144
  if ( is_wp_error( $term ) ) {
202
  'id' => $term['term_taxonomy_id'],
203
  ) );
204
 
205
+ $response = rest_ensure_response( $response );
206
+ $response->set_status( 201 );
207
+ $response->header( 'Location', rest_url( '/wp/v2/terms/' . $this->get_taxonomy_base( $this->taxonomy ) . '/' . $term['term_taxonomy_id'] ) );
208
+ return $response;
209
  }
210
 
211
  /**
lib/endpoints/class-wp-rest-users-controller.php CHANGED
@@ -125,6 +125,8 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
125
  $response = rest_ensure_response( $users );
126
  unset( $prepared_args['number'] );
127
  unset( $prepared_args['offset'] );
 
 
128
  $count_query = new WP_User_Query( $prepared_args );
129
  $total_users = $count_query->get_total();
130
  $response->header( 'X-WP-Total', (int) $total_users );
125
  $response = rest_ensure_response( $users );
126
  unset( $prepared_args['number'] );
127
  unset( $prepared_args['offset'] );
128
+ $prepared_args['fields'] = 'ID';
129
+
130
  $count_query = new WP_User_Query( $prepared_args );
131
  $total_users = $count_query->get_total();
132
  $response->header( 'X-WP-Total', (int) $total_users );
plugin.php CHANGED
@@ -4,7 +4,7 @@
4
  * Description: JSON-based REST API for WordPress, developed as part of GSoC 2013.
5
  * Author: WP REST API Team
6
  * Author URI: http://wp-api.org
7
- * Version: 2.0-beta7
8
  * Plugin URI: https://github.com/WP-API/WP-API
9
  * License: GPL2+
10
  */
4
  * Description: JSON-based REST API for WordPress, developed as part of GSoC 2013.
5
  * Author: WP REST API Team
6
  * Author URI: http://wp-api.org
7
+ * Version: 2.0-beta8
8
  * Plugin URI: https://github.com/WP-API/WP-API
9
  * License: GPL2+
10
  */
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: rmccue, rachelbaker, danielbachhuber, joehoyle
3
  Tags: json, rest, api, rest-api
4
  Requires at least: 4.3
5
  Tested up to: 4.4
6
- Stable tag: 2.0-beta7
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -36,6 +36,42 @@ For full-flavoured API support, you'll need to be using pretty permalinks to use
36
 
37
  == Changelog ==
38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  = 2.0 Beta 7.0 =
40
 
41
  * Sync infrastructure from WordPress core as of r35691.
3
  Tags: json, rest, api, rest-api
4
  Requires at least: 4.3
5
  Tested up to: 4.4
6
+ Stable tag: 2.0-beta8
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
36
 
37
  == Changelog ==
38
 
39
+ = 2.0 Beta 8.0 =
40
+
41
+ * Prevent fatals when uploading attachment by including admin utilities.
42
+
43
+ (props @danielbachhuber, [#1756](https://github.com/WP-API/WP-API/pull/1756))
44
+
45
+ * Return 201 status code when creating a term.
46
+
47
+ (props @danielbachhuber, [#1753](https://github.com/WP-API/WP-API/pull/1753))
48
+
49
+ * Don't permit requesting terms cross routes.
50
+
51
+ Clients should only be able to request categories from the category route, and tags from the tag route.
52
+
53
+ (props @danielbachhuber, [#1764](https://github.com/WP-API/WP-API/pull/1764))
54
+
55
+ * Set `fields=>id` when using `WP_User_Query` to fix large memory usage
56
+
57
+ (props @joehoyle, [#1770](https://github.com/WP-API/WP-API/pull/1770))
58
+
59
+ * Fix Post `_link` to attached attachments.
60
+
61
+ (props @danielbachhuber, [#1777](https://github.com/WP-API/WP-API/pull/1777))
62
+
63
+ * Add support for getting a post with a custom public status.
64
+
65
+ (props @danielbachhuber, [#1765](https://github.com/WP-API/WP-API/pull/1765))
66
+
67
+ * Ensure post content doesn't get double-slashed on update.
68
+
69
+ (props @joehoyle, [#1772](https://github.com/WP-API/WP-API/pull/1772))
70
+
71
+ * Change 'int' to 'integer' for `WP_REST_Controller::validate_schema_property()`
72
+
73
+ (props @wpsmith, [#1759](https://github.com/WP-API/WP-API/pull/1759))
74
+
75
  = 2.0 Beta 7.0 =
76
 
77
  * Sync infrastructure from WordPress core as of r35691.