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

Version Description

Download this release

Release Info

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

Code changes from version 2.0-beta12 to 2.0-beta13

CHANGELOG.md CHANGED
@@ -1,5 +1,99 @@
1
  # Changelog
2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  ## 2.0 Beta 12.0 (February 9, 2016)
4
 
5
  - BREAKING CHANGE: Removes meta endpoints from primary plugin.
1
  # Changelog
2
 
3
+ ## 2.0 Beta 13.0 (March 29, 2016)
4
+
5
+ - BREAKING CHANGE: Fix Content-Disposition header parsing.
6
+
7
+ Allows regular form submissions from HTML forms, as well as properly formatted HTTP requests from clients. Note: this breaks backwards compatibility, as previously, the header parsing was completely wrong.
8
+
9
+ (props @rmccue, [#2239](https://github.com/WP-API/WP-API/pull/2239))
10
+
11
+ - BREAKING CHANGE: Use compact links for embedded responses if they are available.
12
+
13
+ Introduces curies for sites running WordPress 4.5 or greater; no changes for those running WordPress 4.4.
14
+
15
+ (props @joehoyle, [#2412](https://github.com/WP-API/WP-API/pull/2412))
16
+
17
+ - JavaScript client updates:
18
+
19
+ * Support lodash, plus older and newer underscore: add an alias for `_.contains`
20
+ * Add args and options on the model/collection prototypes
21
+ * Rework category/tag mixins to support new API structure
22
+ * Add workaround for the null/empty values returned by the API when creating a new post - these values are not accepted for subsequent updates/saves, so explicitly excluding them. See https://github.com/WP-API/WP-API/pull/2393
23
+ * Better handling of the (special) `me` endpoint
24
+ * Schema parsing cleanup
25
+ * Introduce `wp.api.loadPromise` so developers can ensure api load complete before using
26
+
27
+ (props @adamsilverstein, [#2403](https://github.com/WP-API/WP-API/pull/2403))
28
+
29
+ - Only adds alternate link header for publicly viewable CPTs.
30
+
31
+ (props @bradyvercher, [#2387](https://github.com/WP-API/WP-API/pull/2387))
32
+
33
+ - Adds `roles` param for `GET /wp/v2/users`.
34
+
35
+ (props @BE-Webdesign, [#2372](https://github.com/WP-API/WP-API/pull/2372))
36
+
37
+ - Declares `password` in user schema, but never displays it.
38
+
39
+ (props @danielbachhuber, [#2386](https://github.com/WP-API/WP-API/pull/2386))
40
+
41
+ - Permits `edit` context for requests which can edit the user.
42
+
43
+ (props @danielbachhuber, [#2383](https://github.com/WP-API/WP-API/pull/2383))
44
+
45
+ - Adds `rest_pre_insert_{$taxonomy}` filter for terms.
46
+
47
+ (props @kjbenk, [#2377](https://github.com/WP-API/WP-API/pull/2377))
48
+
49
+ - Supports taxonomy collection args on posts endpoint.
50
+
51
+ (props @joehoyle, [#2287](https://github.com/WP-API/WP-API/pull/2287))
52
+
53
+ - Removes post meta link from post response.
54
+
55
+ (props @joehoyle, [#2288](https://github.com/WP-API/WP-API/pull/2288))
56
+
57
+ - Registers `description` attribute when registering args from schema.
58
+
59
+ (props @danielbachhuber, [#2362](https://github.com/WP-API/WP-API/pull/2362))
60
+
61
+ - Uses `$comment` from the database with `rest_insert_comment` action.
62
+
63
+ (props @danielbachhuber, [#2349](https://github.com/WP-API/WP-API/pull/2349))
64
+
65
+ - Removes unnecessary global variables from users controller.
66
+
67
+ (props @claudiosmweb, [#2335](https://github.com/WP-API/WP-API/pull/2335))
68
+
69
+ - Ensures `GET /wp/v2/categories` with out of bounds offset doesn't return results.
70
+
71
+ (props @danielbachhuber, [#2313](https://github.com/WP-API/WP-API/pull/2313))
72
+
73
+ - Adds top-level support for date queries on posts and comments.
74
+
75
+ (props @BE-Webdesign, [#2266](https://github.com/WP-API/WP-API/pull/2266), [#2291](https://github.com/WP-API/WP-API/pull/2291))
76
+
77
+ - Respects `show_avatars` setting for comments.
78
+
79
+ (props @BE-Webdesign, [#2271](https://github.com/WP-API/WP-API/pull/2271))
80
+
81
+ - Uses cached `get_the_terms()` for terms-for-post for better performance.
82
+
83
+ (props @rmccue, [#2257](https://github.com/WP-API/WP-API/pull/2257))
84
+
85
+ - Ensures comments search is an empty string.
86
+
87
+ (props @rmccue, [#2256](https://github.com/WP-API/WP-API/pull/2256))
88
+
89
+ - If no title is provided in create attachment request or file metadata, falls back to filename.
90
+
91
+ (props @danielbachhuber, [#2254](https://github.com/WP-API/WP-API/pull/2254))
92
+
93
+ - Removes unused `$img_url_basename` variable in attachments controller.
94
+
95
+ (props @danielbachhuber, [#2250](https://github.com/WP-API/WP-API/pull/2250))
96
+
97
  ## 2.0 Beta 12.0 (February 9, 2016)
98
 
99
  - BREAKING CHANGE: Removes meta endpoints from primary plugin.
CONTRIBUTING.md CHANGED
@@ -2,6 +2,41 @@
2
  Hi, and thanks for considering contributing! Before you do though, here's a few
3
  notes on how best to contribute. Don't worry, I'll keep it short!
4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  ## Best Practices
6
 
7
  ### Commit Messages
2
  Hi, and thanks for considering contributing! Before you do though, here's a few
3
  notes on how best to contribute. Don't worry, I'll keep it short!
4
 
5
+ ## Getting Started
6
+
7
+ ### Submitting a pull request
8
+
9
+ Contributions to WP-API always follow a feature branch pull request workflow.
10
+
11
+ First, create a new branch for your changes. As far as branch naming goes, a
12
+ good rule of thumb is to use the issue number followed by a short slug that
13
+ represents the feature (e.g. `2392-contributing-docs`).
14
+
15
+ Then, submit a pull request early to get a round of feedback on your proposed
16
+ changes. It's better to get quick feedback to ensure you're on the right track.
17
+
18
+ Next, make sure you have adequate test coverage around your changes. With a
19
+ project of this magnitude, it's better to have too much test coverage than not
20
+ enough.
21
+
22
+ Last, leave a #reviewmerge comment on your pull request for a final review by
23
+ the WP-API team.
24
+
25
+ ### Running tests
26
+
27
+ The WP-API project uses two continuous integration (CI) services, Travis and
28
+ Scrutinizer, to automatically run a series of tests against its codebase on
29
+ every push. If you're submitting a pull request, it's expected that all tests
30
+ will pass — and that you add more tests for your change.
31
+
32
+ You can install the necessary libraries in your local environment with:
33
+
34
+ npm install -g grunt-cli
35
+ npm install
36
+ composer install
37
+
38
+ Then, run PHPUnit tests with `phpunit`, or WPCS tests with `grunt phpcs`.
39
+
40
  ## Best Practices
41
 
42
  ### Commit Messages
README.md CHANGED
@@ -8,11 +8,11 @@ Access your WordPress site's data through an easy-to-use HTTP REST API.
8
 
9
  ## WARNING
10
 
11
- The **"develop"** branch is undergoing substantial changes and is **NOT COMPLETE OR STABLE**. [Read the in-progress documentation](http://v2.wp-api.org/) to introduce yourself to endpoints, internal patterns, and implementation details.
12
 
13
  The **"master"** branch represents a **BETA** of our next version release.
14
 
15
- The latest **stable** version is available from the [WordPress Plugin Directory](https://wordpress.org/plugins/json-rest-api/).
16
 
17
  ## About
18
 
@@ -57,6 +57,10 @@ Also, be sure to use the Subversion `trunk` branch of WordPress Core as there ar
57
  All tickets for the project are being tracked on [GitHub][]. You can also take a
58
  look at the [recent updates][] for the project.
59
 
 
 
 
 
60
  ## Security
61
 
62
  We take the security of the API extremely seriously. If you think you've found
@@ -79,5 +83,6 @@ WordPress on your own server. **Do not test on servers you do not own.**)
79
 
80
  [docs]: http://v2.wp-api.org/
81
  [GitHub]: https://github.com/WP-API/WP-API/issues
 
82
  [recent updates]: https://make.wordpress.org/core/tag/json-api/
83
  [hackerone]: https://hackerone.com/wp-api
8
 
9
  ## WARNING
10
 
11
+ The **"develop"** branch is undergoing substantial changes and is **NOT COMPLETE OR STABLE**. [Read the in-progress documentation](http://v2.wp-api.org/) to introduce yourself to endpoints, internal patterns, and implementation details.
12
 
13
  The **"master"** branch represents a **BETA** of our next version release.
14
 
15
+ The latest **stable** version is available from the [WordPress Plugin Directory](https://wordpress.org/plugins/rest-api/).
16
 
17
  ## About
18
 
57
  All tickets for the project are being tracked on [GitHub][]. You can also take a
58
  look at the [recent updates][] for the project.
59
 
60
+ ## Contributing
61
+
62
+ Want to get involved? Check out [Contributing.md][contributing] for details on submitting fixes and new features.
63
+
64
  ## Security
65
 
66
  We take the security of the API extremely seriously. If you think you've found
83
 
84
  [docs]: http://v2.wp-api.org/
85
  [GitHub]: https://github.com/WP-API/WP-API/issues
86
+ [contributing]: CONTRIBUTING.md
87
  [recent updates]: https://make.wordpress.org/core/tag/json-api/
88
  [hackerone]: https://hackerone.com/wp-api
core-integration.php CHANGED
@@ -13,3 +13,72 @@ function wp_api_comment_query_vars( $query ) {
13
  $query->query_var_defaults['parent__not_in'] = array();
14
  }
15
  add_action( 'pre_get_comments', 'wp_api_comment_query_vars' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  $query->query_var_defaults['parent__not_in'] = array();
14
  }
15
  add_action( 'pre_get_comments', 'wp_api_comment_query_vars' );
16
+
17
+ if ( ! function_exists( 'wp_parse_slug_list' ) ) {
18
+ /**
19
+ * Clean up an array, comma- or space-separated list of slugs.
20
+ *
21
+ * @since
22
+ *
23
+ * @param array|string $list List of slugs.
24
+ * @return array Sanitized array of slugs.
25
+ */
26
+ function wp_parse_slug_list( $list ) {
27
+ if ( ! is_array( $list ) ) {
28
+ $list = preg_split( '/[\s,]+/', $list );
29
+ }
30
+
31
+ foreach ( $list as $key => $value ) {
32
+ $list[ $key ] = sanitize_title( $value );
33
+ }
34
+
35
+ return array_unique( $list );
36
+ }
37
+ }
38
+
39
+ if ( ! function_exists( 'rest_get_server' ) ) {
40
+ /**
41
+ * Retrieves the current REST server instance.
42
+ *
43
+ * Instantiates a new instance if none exists already.
44
+ *
45
+ * @since 4.5.0
46
+ *
47
+ * @global WP_REST_Server $wp_rest_server REST server instance.
48
+ *
49
+ * @return WP_REST_Server REST server instance.
50
+ */
51
+ function rest_get_server() {
52
+ /* @var WP_REST_Server $wp_rest_server */
53
+ global $wp_rest_server;
54
+
55
+ if ( empty( $wp_rest_server ) ) {
56
+ /**
57
+ * Filter the REST Server Class.
58
+ *
59
+ * This filter allows you to adjust the server class used by the API, using a
60
+ * different class to handle requests.
61
+ *
62
+ * @since 4.4.0
63
+ *
64
+ * @param string $class_name The name of the server class. Default 'WP_REST_Server'.
65
+ */
66
+ $wp_rest_server_class = apply_filters( 'wp_rest_server_class', 'WP_REST_Server' );
67
+ $wp_rest_server = new $wp_rest_server_class;
68
+
69
+ /**
70
+ * Fires when preparing to serve an API request.
71
+ *
72
+ * Endpoint objects should be created and register their hooks on this action rather
73
+ * than another action to ensure they're only loaded when needed.
74
+ *
75
+ * @since 4.4.0
76
+ *
77
+ * @param WP_REST_Server $wp_rest_server Server object.
78
+ */
79
+ do_action( 'rest_api_init', $wp_rest_server );
80
+ }
81
+
82
+ return $wp_rest_server;
83
+ }
84
+ }
extras.php CHANGED
@@ -24,7 +24,7 @@ if ( ! function_exists( 'rest_register_scripts' ) ) {
24
  // Use minified scripts if SCRIPT_DEBUG is not on.
25
  $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
26
 
27
- wp_register_script( 'wp-api', plugins_url( 'wp-api' . $suffix . '.js', __FILE__ ), array( 'jquery', 'backbone', 'underscore' ), '1.1', true );
28
 
29
  $settings = array(
30
  'root' => esc_url_raw( get_rest_url() ),
24
  // Use minified scripts if SCRIPT_DEBUG is not on.
25
  $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
26
 
27
+ wp_register_script( 'wp-api', plugins_url( 'wp-api' . $suffix . '.js', __FILE__ ), array( 'jquery', 'backbone', 'underscore' ), '1.2', true );
28
 
29
  $settings = array(
30
  'root' => esc_url_raw( get_rest_url() ),
lib/endpoints/class-wp-rest-attachments-controller.php CHANGED
@@ -109,6 +109,11 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
109
  $attachment->file = $file;
110
  $attachment->post_mime_type = $type;
111
  $attachment->guid = $url;
 
 
 
 
 
112
  $id = wp_insert_post( $attachment, true );
113
  if ( is_wp_error( $id ) ) {
114
  if ( in_array( $id->get_error_code(), array( 'db_update_error' ) ) ) {
@@ -187,7 +192,7 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
187
  * Prepare a single attachment for create or update
188
  *
189
  * @param WP_REST_Request $request Request object
190
- * @return WP_Error|obj $prepared_attachment Post object
191
  */
192
  protected function prepare_item_for_database( $request ) {
193
  $prepared_attachment = parent::prepare_item_for_database( $request );
@@ -231,7 +236,6 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
231
  if ( empty( $data['media_details'] ) ) {
232
  $data['media_details'] = new stdClass;
233
  } elseif ( ! empty( $data['media_details']['sizes'] ) ) {
234
- $img_url_basename = wp_basename( $data['source_url'] );
235
 
236
  foreach ( $data['media_details']['sizes'] as $size => &$size_data ) {
237
 
@@ -371,22 +375,10 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
371
  return new WP_Error( 'rest_upload_no_content_disposition', __( 'No Content-Disposition supplied' ), array( 'status' => 400 ) );
372
  }
373
 
374
- // Get the filename
375
- $filename = null;
376
-
377
- foreach ( $headers['content_disposition'] as $part ) {
378
- $part = trim( $part );
379
-
380
- if ( strpos( $part, 'filename' ) !== 0 ) {
381
- continue;
382
- }
383
-
384
- $filenameparts = explode( '=', $part );
385
- $filename = trim( $filenameparts[1] );
386
- }
387
 
388
  if ( empty( $filename ) ) {
389
- return new WP_Error( 'rest_upload_invalid_disposition', __( 'Invalid Content-Disposition supplied. Content-Disposition needs to be formatted as "filename=image.png" or similar.' ), array( 'status' => 400 ) );
390
  }
391
 
392
  if ( ! empty( $headers['content_md5'] ) ) {
@@ -439,6 +431,71 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
439
  return $sideloaded;
440
  }
441
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
442
  /**
443
  * Get the query params for collections of attachments.
444
  *
109
  $attachment->file = $file;
110
  $attachment->post_mime_type = $type;
111
  $attachment->guid = $url;
112
+
113
+ if ( empty( $attachment->post_title ) ) {
114
+ $attachment->post_title = preg_replace( '/\.[^.]+$/', '', basename( $file ) );
115
+ }
116
+
117
  $id = wp_insert_post( $attachment, true );
118
  if ( is_wp_error( $id ) ) {
119
  if ( in_array( $id->get_error_code(), array( 'db_update_error' ) ) ) {
192
  * Prepare a single attachment for create or update
193
  *
194
  * @param WP_REST_Request $request Request object
195
+ * @return WP_Error|stdClass $prepared_attachment Post object
196
  */
197
  protected function prepare_item_for_database( $request ) {
198
  $prepared_attachment = parent::prepare_item_for_database( $request );
236
  if ( empty( $data['media_details'] ) ) {
237
  $data['media_details'] = new stdClass;
238
  } elseif ( ! empty( $data['media_details']['sizes'] ) ) {
 
239
 
240
  foreach ( $data['media_details']['sizes'] as $size => &$size_data ) {
241
 
375
  return new WP_Error( 'rest_upload_no_content_disposition', __( 'No Content-Disposition supplied' ), array( 'status' => 400 ) );
376
  }
377
 
378
+ $filename = $this->get_filename_from_disposition( $headers['content_disposition'] );
 
 
 
 
 
 
 
 
 
 
 
 
379
 
380
  if ( empty( $filename ) ) {
381
+ return new WP_Error( 'rest_upload_invalid_disposition', __( 'Invalid Content-Disposition supplied. Content-Disposition needs to be formatted as `attachment; filename="image.png"` or similar.' ), array( 'status' => 400 ) );
382
  }
383
 
384
  if ( ! empty( $headers['content_md5'] ) ) {
431
  return $sideloaded;
432
  }
433
 
434
+ /**
435
+ * Parse filename from a Content-Disposition header value.
436
+ *
437
+ * As per RFC6266:
438
+ *
439
+ * content-disposition = "Content-Disposition" ":"
440
+ * disposition-type *( ";" disposition-parm )
441
+ *
442
+ * disposition-type = "inline" | "attachment" | disp-ext-type
443
+ * ; case-insensitive
444
+ * disp-ext-type = token
445
+ *
446
+ * disposition-parm = filename-parm | disp-ext-parm
447
+ *
448
+ * filename-parm = "filename" "=" value
449
+ * | "filename*" "=" ext-value
450
+ *
451
+ * disp-ext-parm = token "=" value
452
+ * | ext-token "=" ext-value
453
+ * ext-token = <the characters in token, followed by "*">
454
+ *
455
+ * @see http://tools.ietf.org/html/rfc2388
456
+ * @see http://tools.ietf.org/html/rfc6266
457
+ *
458
+ * @param string[] $disposition_header List of Content-Disposition header values.
459
+ * @return string|null Filename if available, or null if not found.
460
+ */
461
+ public static function get_filename_from_disposition( $disposition_header ) {
462
+ // Get the filename
463
+ $filename = null;
464
+
465
+ foreach ( $disposition_header as $value ) {
466
+ $value = trim( $value );
467
+
468
+ if ( strpos( $value, ';' ) === false ) {
469
+ continue;
470
+ }
471
+
472
+ list( $type, $attr_parts ) = explode( ';', $value, 2 );
473
+ $attr_parts = explode( ';', $attr_parts );
474
+ $attributes = array();
475
+ foreach ( $attr_parts as $part ) {
476
+ if ( strpos( $part, '=' ) === false ) {
477
+ continue;
478
+ }
479
+
480
+ list( $key, $value ) = explode( '=', $part, 2 );
481
+ $attributes[ trim( $key ) ] = trim( $value );
482
+ }
483
+
484
+ if ( empty( $attributes['filename'] ) ) {
485
+ continue;
486
+ }
487
+
488
+ $filename = trim( $attributes['filename'] );
489
+
490
+ // Unquote quoted filename, but after trimming.
491
+ if ( substr( $filename, 0, 1 ) === '"' && substr( $filename, -1, 1 ) === '"' ) {
492
+ $filename = substr( $filename, 1, -1 );
493
+ }
494
+ }
495
+
496
+ return $filename;
497
+ }
498
+
499
  /**
500
  * Get the query params for collections of attachments.
501
  *
lib/endpoints/class-wp-rest-comments-controller.php CHANGED
@@ -70,7 +70,7 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
70
  public function get_items_permissions_check( $request ) {
71
 
72
  if ( ! empty( $request['post'] ) ) {
73
- foreach ( $request['post'] as $post_id ) {
74
  $post = get_post( $post_id );
75
  if ( ! empty( $post_id ) && $post && ! $this->check_read_post_permission( $post ) ) {
76
  return new WP_Error( 'rest_cannot_read_post', __( 'Sorry, you cannot read the post for this comment.' ), array( 'status' => rest_authorization_required_code() ) );
@@ -135,9 +135,23 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
135
  'author__not_in' => $request['author_exclude'],
136
  );
137
 
 
 
 
 
 
 
 
 
 
 
 
138
  if ( empty( $request['offset'] ) ) {
139
  $prepared_args['offset'] = $prepared_args['number'] * ( absint( $request['page'] ) - 1 );
140
  }
 
 
 
141
 
142
  /**
143
  * Filter arguments, before passing to WP_Comment_Query, when querying comments via the REST API.
@@ -369,11 +383,11 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
369
  /**
370
  * Fires after a comment is created or updated via the REST API.
371
  *
372
- * @param array $prepared_comment Inserted comment data.
373
- * @param WP_REST_Request $request The request sent to the API.
374
- * @param boolean $creating True when creating a comment, false when updating.
375
  */
376
- do_action( 'rest_insert_comment', $prepared_comment, $request, true );
377
 
378
  return $response;
379
  }
@@ -443,7 +457,7 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
443
  $response = $this->prepare_item_for_response( $comment, $request );
444
 
445
  /* This action is documented in lib/endpoints/class-wp-rest-comments-controller.php */
446
- do_action( 'rest_insert_comment', $prepared_args, $request, false );
447
 
448
  return rest_ensure_response( $response );
449
  }
@@ -542,7 +556,6 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
542
  'author_email' => $comment->comment_author_email,
543
  'author_url' => $comment->comment_author_url,
544
  'author_ip' => $comment->comment_author_IP,
545
- 'author_avatar_urls' => rest_get_avatar_urls( $comment->comment_author_email ),
546
  'author_user_agent' => $comment->comment_agent,
547
  'date' => mysql_to_rfc3339( $comment->comment_date ),
548
  'date_gmt' => mysql_to_rfc3339( $comment->comment_date_gmt ),
@@ -556,6 +569,12 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
556
  'type' => get_comment_type( $comment->comment_ID ),
557
  );
558
 
 
 
 
 
 
 
559
  $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
560
  $data = $this->add_additional_fields_to_object( $data, $request );
561
  $data = $this->filter_response_by_context( $data, $context );
@@ -751,18 +770,6 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
751
  * @return array
752
  */
753
  public function get_item_schema() {
754
- $avatar_properties = array();
755
-
756
- $avatar_sizes = rest_get_avatar_sizes();
757
- foreach ( $avatar_sizes as $size ) {
758
- $avatar_properties[ $size ] = array(
759
- 'description' => sprintf( __( 'Avatar URL with image size of %d pixels.' ), $size ),
760
- 'type' => 'string',
761
- 'format' => 'uri',
762
- 'context' => array( 'embed', 'view', 'edit' ),
763
- );
764
- }
765
-
766
  $schema = array(
767
  '$schema' => 'http://json-schema.org/draft-04/schema#',
768
  'title' => 'comment',
@@ -779,13 +786,6 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
779
  'type' => 'integer',
780
  'context' => array( 'view', 'edit', 'embed' ),
781
  ),
782
- 'author_avatar_urls' => array(
783
- 'description' => __( 'Avatar URLs for the object author.' ),
784
- 'type' => 'object',
785
- 'context' => array( 'view', 'edit', 'embed' ),
786
- 'readonly' => true,
787
- 'properties' => $avatar_properties,
788
- ),
789
  'author_email' => array(
790
  'description' => __( 'Email address for the object author.' ),
791
  'type' => 'string',
@@ -899,6 +899,29 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
899
  ),
900
  ),
901
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
902
  return $this->add_additional_fields_schema( $schema );
903
  }
904
 
@@ -912,6 +935,12 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
912
 
913
  $query_params['context']['default'] = 'view';
914
 
 
 
 
 
 
 
915
  $query_params['author'] = array(
916
  'description' => __( 'Limit result set to comments assigned to specific user ids. Requires authorization.' ),
917
  'sanitize_callback' => 'wp_parse_id_list',
@@ -932,6 +961,12 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
932
  'validate_callback' => 'rest_validate_request_arg',
933
  'type' => 'string',
934
  );
 
 
 
 
 
 
935
  $query_params['exclude'] = array(
936
  'description' => __( 'Ensure result set excludes specific ids.' ),
937
  'type' => 'array',
70
  public function get_items_permissions_check( $request ) {
71
 
72
  if ( ! empty( $request['post'] ) ) {
73
+ foreach ( (array) $request['post'] as $post_id ) {
74
  $post = get_post( $post_id );
75
  if ( ! empty( $post_id ) && $post && ! $this->check_read_post_permission( $post ) ) {
76
  return new WP_Error( 'rest_cannot_read_post', __( 'Sorry, you cannot read the post for this comment.' ), array( 'status' => rest_authorization_required_code() ) );
135
  'author__not_in' => $request['author_exclude'],
136
  );
137
 
138
+ $prepared_args['date_query'] = array();
139
+ // Set before into date query. Date query must be specified as an array of an array.
140
+ if ( isset( $request['before'] ) ) {
141
+ $prepared_args['date_query'][0]['before'] = $request['before'];
142
+ }
143
+
144
+ // Set after into date query. Date query must be specified as an array of an array.
145
+ if ( isset( $request['after'] ) ) {
146
+ $prepared_args['date_query'][0]['after'] = $request['after'];
147
+ }
148
+
149
  if ( empty( $request['offset'] ) ) {
150
  $prepared_args['offset'] = $prepared_args['number'] * ( absint( $request['page'] ) - 1 );
151
  }
152
+ if ( empty( $request['search'] ) ) {
153
+ $prepared_args['search'] = '';
154
+ }
155
 
156
  /**
157
  * Filter arguments, before passing to WP_Comment_Query, when querying comments via the REST API.
383
  /**
384
  * Fires after a comment is created or updated via the REST API.
385
  *
386
+ * @param array $comment Comment as it exists in the database.
387
+ * @param WP_REST_Request $request The request sent to the API.
388
+ * @param boolean $creating True when creating a comment, false when updating.
389
  */
390
+ do_action( 'rest_insert_comment', $comment, $request, true );
391
 
392
  return $response;
393
  }
457
  $response = $this->prepare_item_for_response( $comment, $request );
458
 
459
  /* This action is documented in lib/endpoints/class-wp-rest-comments-controller.php */
460
+ do_action( 'rest_insert_comment', $comment, $request, false );
461
 
462
  return rest_ensure_response( $response );
463
  }
556
  'author_email' => $comment->comment_author_email,
557
  'author_url' => $comment->comment_author_url,
558
  'author_ip' => $comment->comment_author_IP,
 
559
  'author_user_agent' => $comment->comment_agent,
560
  'date' => mysql_to_rfc3339( $comment->comment_date ),
561
  'date_gmt' => mysql_to_rfc3339( $comment->comment_date_gmt ),
569
  'type' => get_comment_type( $comment->comment_ID ),
570
  );
571
 
572
+ $schema = $this->get_item_schema();
573
+
574
+ if ( ! empty( $schema['properties']['author_avatar_urls'] ) ) {
575
+ $data['author_avatar_urls'] = rest_get_avatar_urls( $comment->comment_author_email );
576
+ }
577
+
578
  $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
579
  $data = $this->add_additional_fields_to_object( $data, $request );
580
  $data = $this->filter_response_by_context( $data, $context );
770
  * @return array
771
  */
772
  public function get_item_schema() {
 
 
 
 
 
 
 
 
 
 
 
 
773
  $schema = array(
774
  '$schema' => 'http://json-schema.org/draft-04/schema#',
775
  'title' => 'comment',
786
  'type' => 'integer',
787
  'context' => array( 'view', 'edit', 'embed' ),
788
  ),
 
 
 
 
 
 
 
789
  'author_email' => array(
790
  'description' => __( 'Email address for the object author.' ),
791
  'type' => 'string',
899
  ),
900
  ),
901
  );
902
+
903
+ if ( get_option( 'show_avatars' ) ) {
904
+ $avatar_properties = array();
905
+
906
+ $avatar_sizes = rest_get_avatar_sizes();
907
+ foreach ( $avatar_sizes as $size ) {
908
+ $avatar_properties[ $size ] = array(
909
+ 'description' => sprintf( __( 'Avatar URL with image size of %d pixels.' ), $size ),
910
+ 'type' => 'string',
911
+ 'format' => 'uri',
912
+ 'context' => array( 'embed', 'view', 'edit' ),
913
+ );
914
+ }
915
+
916
+ $schema['properties']['author_avatar_urls'] = array(
917
+ 'description' => __( 'Avatar URLs for the object author.' ),
918
+ 'type' => 'object',
919
+ 'context' => array( 'view', 'edit', 'embed' ),
920
+ 'readonly' => true,
921
+ 'properties' => $avatar_properties,
922
+ );
923
+ }
924
+
925
  return $this->add_additional_fields_schema( $schema );
926
  }
927
 
935
 
936
  $query_params['context']['default'] = 'view';
937
 
938
+ $query_params['after'] = array(
939
+ 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.' ),
940
+ 'type' => 'string',
941
+ 'format' => 'date-time',
942
+ 'validate_callback' => 'rest_validate_request_arg',
943
+ );
944
  $query_params['author'] = array(
945
  'description' => __( 'Limit result set to comments assigned to specific user ids. Requires authorization.' ),
946
  'sanitize_callback' => 'wp_parse_id_list',
961
  'validate_callback' => 'rest_validate_request_arg',
962
  'type' => 'string',
963
  );
964
+ $query_params['before'] = array(
965
+ 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.' ),
966
+ 'type' => 'string',
967
+ 'format' => 'date-time',
968
+ 'validate_callback' => 'rest_validate_request_arg',
969
+ );
970
  $query_params['exclude'] = array(
971
  'description' => __( 'Ensure result set excludes specific ids.' ),
972
  'type' => 'array',
lib/endpoints/class-wp-rest-controller.php CHANGED
@@ -157,7 +157,14 @@ abstract class WP_REST_Controller {
157
  }
158
 
159
  $data = (array) $response->get_data();
160
- $links = WP_REST_Server::get_response_links( $response );
 
 
 
 
 
 
 
161
  if ( ! empty( $links ) ) {
162
  $data['_links'] = $links;
163
  }
@@ -190,7 +197,9 @@ abstract class WP_REST_Controller {
190
  continue;
191
  }
192
  if ( ! in_array( $context, $details['context'] ) ) {
193
- unset( $data[ $key ][ $attribute ] );
 
 
194
  }
195
  }
196
  }
@@ -438,6 +447,10 @@ abstract class WP_REST_Controller {
438
  'sanitize_callback' => 'rest_sanitize_request_arg',
439
  );
440
 
 
 
 
 
441
  if ( WP_REST_Server::CREATABLE === $method && isset( $params['default'] ) ) {
442
  $endpoint_args[ $field_id ]['default'] = $params['default'];
443
  }
157
  }
158
 
159
  $data = (array) $response->get_data();
160
+ $server = rest_get_server();
161
+
162
+ if ( method_exists( $server, 'get_compact_response_links' ) ) {
163
+ $links = call_user_func( array( $server, 'get_compact_response_links' ), $response );
164
+ } else {
165
+ $links = call_user_func( array( $server, 'get_response_links' ), $response );
166
+ }
167
+
168
  if ( ! empty( $links ) ) {
169
  $data['_links'] = $links;
170
  }
197
  continue;
198
  }
199
  if ( ! in_array( $context, $details['context'] ) ) {
200
+ if ( isset( $data[ $key ][ $attribute ] ) ) {
201
+ unset( $data[ $key ][ $attribute ] );
202
+ }
203
  }
204
  }
205
  }
447
  'sanitize_callback' => 'rest_sanitize_request_arg',
448
  );
449
 
450
+ if ( isset( $params['description'] ) ) {
451
+ $endpoint_args[ $field_id ]['description'] = $params['description'];
452
+ }
453
+
454
  if ( WP_REST_Server::CREATABLE === $method && isset( $params['default'] ) ) {
455
  $endpoint_args[ $field_id ]['default'] = $params['default'];
456
  }
lib/endpoints/class-wp-rest-posts-controller.php CHANGED
@@ -102,6 +102,17 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
102
  $args['post_status'] = $request['status'];
103
  $args['s'] = $request['search'];
104
 
 
 
 
 
 
 
 
 
 
 
 
105
  if ( is_array( $request['filter'] ) ) {
106
  $args = array_merge( $args, $request['filter'] );
107
  unset( $args['filter'] );
@@ -124,6 +135,20 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
124
  $args = apply_filters( "rest_{$this->post_type}_query", $args, $request );
125
  $query_args = $this->prepare_items_query( $args, $request );
126
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
  $posts_query = new WP_Query();
128
  $query_result = $posts_query->query( $query_args );
129
 
@@ -217,7 +242,9 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
217
  $data = $this->prepare_item_for_response( $post, $request );
218
  $response = rest_ensure_response( $data );
219
 
220
- $response->link_header( 'alternate', get_permalink( $id ), array( 'type' => 'text/html' ) );
 
 
221
 
222
  return $response;
223
  }
@@ -599,6 +626,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
599
  'post_parent__in',
600
  'post_parent__not_in',
601
  'posts_per_page',
 
602
  );
603
  $valid_vars = array_merge( $valid_vars, $rest_valid );
604
 
@@ -683,7 +711,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
683
  * Prepare a single post for create or update.
684
  *
685
  * @param WP_REST_Request $request Request object.
686
- * @return WP_Error|object $prepared_post Post object.
687
  */
688
  protected function prepare_item_for_database( $request ) {
689
  $prepared_post = new stdClass;
@@ -817,12 +845,12 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
817
  $prepared_post->ping_status = $request['ping_status'];
818
  }
819
  /**
820
- * Filter the query_vars used in `get_items` for the constructed query.
821
  *
822
  * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being
823
  * prepared for insertion.
824
  *
825
- * @param object $prepared_post An object representing a single post prepared
826
  * for inserting or updating the database.
827
  * @param WP_REST_Request $request Request object.
828
  */
@@ -1263,13 +1291,6 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
1263
  }
1264
  }
1265
 
1266
- if ( post_type_supports( $post->post_type, 'custom-fields' ) ) {
1267
- $links['https://api.w.org/meta'] = array(
1268
- 'href' => rest_url( trailingslashit( $base ) . $post->ID . '/meta' ),
1269
- 'embeddable' => true,
1270
- );
1271
- }
1272
-
1273
  return $links;
1274
  }
1275
 
@@ -1581,6 +1602,12 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
1581
 
1582
  $params['context']['default'] = 'view';
1583
 
 
 
 
 
 
 
1584
  if ( post_type_supports( $this->post_type, 'author' ) ) {
1585
  $params['author'] = array(
1586
  'description' => __( 'Limit result set to posts assigned to specific authors.' ),
@@ -1597,6 +1624,12 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
1597
  'validate_callback' => 'rest_validate_request_arg',
1598
  );
1599
  }
 
 
 
 
 
 
1600
  $params['exclude'] = array(
1601
  'description' => __( 'Ensure result set excludes specific ids.' ),
1602
  'type' => 'array',
@@ -1650,13 +1683,13 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
1650
  $post_type_obj = get_post_type_object( $this->post_type );
1651
  if ( $post_type_obj->hierarchical || 'attachment' === $this->post_type ) {
1652
  $params['parent'] = array(
1653
- 'description' => _( 'Limit result set to those of particular parent ids.' ),
1654
  'type' => 'array',
1655
  'sanitize_callback' => 'wp_parse_id_list',
1656
  'default' => array(),
1657
  );
1658
  $params['parent_exclude'] = array(
1659
- 'description' => _( 'Limit result set to all items except those of a particular parent id.' ),
1660
  'type' => 'array',
1661
  'sanitize_callback' => 'wp_parse_id_list',
1662
  'default' => array(),
@@ -1678,6 +1711,18 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
1678
  $params['filter'] = array(
1679
  'description' => __( 'Use WP Query arguments to modify the response; private query vars require appropriate authorization.' ),
1680
  );
 
 
 
 
 
 
 
 
 
 
 
 
1681
  return $params;
1682
  }
1683
 
102
  $args['post_status'] = $request['status'];
103
  $args['s'] = $request['search'];
104
 
105
+ $args['date_query'] = array();
106
+ // Set before into date query. Date query must be specified as an array of an array.
107
+ if ( isset( $request['before'] ) ) {
108
+ $args['date_query'][0]['before'] = $request['before'];
109
+ }
110
+
111
+ // Set after into date query. Date query must be specified as an array of an array.
112
+ if ( isset( $request['after'] ) ) {
113
+ $args['date_query'][0]['after'] = $request['after'];
114
+ }
115
+
116
  if ( is_array( $request['filter'] ) ) {
117
  $args = array_merge( $args, $request['filter'] );
118
  unset( $args['filter'] );
135
  $args = apply_filters( "rest_{$this->post_type}_query", $args, $request );
136
  $query_args = $this->prepare_items_query( $args, $request );
137
 
138
+ $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) );
139
+ foreach ( $taxonomies as $taxonomy ) {
140
+ $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
141
+
142
+ if ( ! empty( $request[ $base ] ) ) {
143
+ $query_args['tax_query'][] = array(
144
+ 'taxonomy' => $taxonomy->name,
145
+ 'field' => 'term_id',
146
+ 'terms' => $request[ $base ],
147
+ 'include_children' => false,
148
+ );
149
+ }
150
+ }
151
+
152
  $posts_query = new WP_Query();
153
  $query_result = $posts_query->query( $query_args );
154
 
242
  $data = $this->prepare_item_for_response( $post, $request );
243
  $response = rest_ensure_response( $data );
244
 
245
+ if ( is_post_type_viewable( get_post_type_object( $post->post_type ) ) ) {
246
+ $response->link_header( 'alternate', get_permalink( $id ), array( 'type' => 'text/html' ) );
247
+ }
248
 
249
  return $response;
250
  }
626
  'post_parent__in',
627
  'post_parent__not_in',
628
  'posts_per_page',
629
+ 'date_query',
630
  );
631
  $valid_vars = array_merge( $valid_vars, $rest_valid );
632
 
711
  * Prepare a single post for create or update.
712
  *
713
  * @param WP_REST_Request $request Request object.
714
+ * @return WP_Error|stdClass $prepared_post Post object.
715
  */
716
  protected function prepare_item_for_database( $request ) {
717
  $prepared_post = new stdClass;
845
  $prepared_post->ping_status = $request['ping_status'];
846
  }
847
  /**
848
+ * Filter a post before it is inserted via the REST API.
849
  *
850
  * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being
851
  * prepared for insertion.
852
  *
853
+ * @param stdClass $prepared_post An object representing a single post prepared
854
  * for inserting or updating the database.
855
  * @param WP_REST_Request $request Request object.
856
  */
1291
  }
1292
  }
1293
 
 
 
 
 
 
 
 
1294
  return $links;
1295
  }
1296
 
1602
 
1603
  $params['context']['default'] = 'view';
1604
 
1605
+ $params['after'] = array(
1606
+ 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.' ),
1607
+ 'type' => 'string',
1608
+ 'format' => 'date-time',
1609
+ 'validate_callback' => 'rest_validate_request_arg',
1610
+ );
1611
  if ( post_type_supports( $this->post_type, 'author' ) ) {
1612
  $params['author'] = array(
1613
  'description' => __( 'Limit result set to posts assigned to specific authors.' ),
1624
  'validate_callback' => 'rest_validate_request_arg',
1625
  );
1626
  }
1627
+ $params['before'] = array(
1628
+ 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.' ),
1629
+ 'type' => 'string',
1630
+ 'format' => 'date-time',
1631
+ 'validate_callback' => 'rest_validate_request_arg',
1632
+ );
1633
  $params['exclude'] = array(
1634
  'description' => __( 'Ensure result set excludes specific ids.' ),
1635
  'type' => 'array',
1683
  $post_type_obj = get_post_type_object( $this->post_type );
1684
  if ( $post_type_obj->hierarchical || 'attachment' === $this->post_type ) {
1685
  $params['parent'] = array(
1686
+ 'description' => __( 'Limit result set to those of particular parent ids.' ),
1687
  'type' => 'array',
1688
  'sanitize_callback' => 'wp_parse_id_list',
1689
  'default' => array(),
1690
  );
1691
  $params['parent_exclude'] = array(
1692
+ 'description' => __( 'Limit result set to all items except those of a particular parent id.' ),
1693
  'type' => 'array',
1694
  'sanitize_callback' => 'wp_parse_id_list',
1695
  'default' => array(),
1711
  $params['filter'] = array(
1712
  'description' => __( 'Use WP Query arguments to modify the response; private query vars require appropriate authorization.' ),
1713
  );
1714
+
1715
+ $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) );
1716
+ foreach ( $taxonomies as $taxonomy ) {
1717
+ $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
1718
+
1719
+ $params[ $base ] = array(
1720
+ 'description' => sprintf( __( 'Limit result set to all items that have the specified term assigned in the %s taxonomy.' ), $base ),
1721
+ 'type' => 'array',
1722
+ 'sanitize_callback' => 'wp_parse_id_list',
1723
+ 'default' => array(),
1724
+ );
1725
+ }
1726
  return $params;
1727
  }
1728
 
lib/endpoints/class-wp-rest-revisions-controller.php CHANGED
@@ -138,6 +138,9 @@ class WP_REST_Revisions_Controller extends WP_REST_Controller {
138
  }
139
 
140
  $post = get_post( $request['id'] );
 
 
 
141
  $post_type = get_post_type_object( 'revision' );
142
  return current_user_can( $post_type->cap->delete_post, $post->ID );
143
  }
138
  }
139
 
140
  $post = get_post( $request['id'] );
141
+ if ( ! $post ) {
142
+ return new WP_Error( 'rest_post_invalid_id', __( 'Invalid revision id.' ), array( 'status' => 404 ) );
143
+ }
144
  $post_type = get_post_type_object( 'revision' );
145
  return current_user_can( $post_type->cap->delete_post, $post->ID );
146
  }
lib/endpoints/class-wp-rest-terms-controller.php CHANGED
@@ -136,14 +136,35 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
136
  */
137
  $prepared_args = apply_filters( "rest_{$this->taxonomy}_query", $prepared_args, $request );
138
 
139
- if ( ! empty( $prepared_args['post'] ) ) {
140
- $terms_args = array(
141
- 'order' => $prepared_args['order'],
142
- 'orderby' => $prepared_args['orderby'],
143
- );
144
- $query_result = wp_get_object_terms( $prepared_args['post'], $this->taxonomy, $terms_args );
 
 
 
 
 
145
  } else {
146
  $query_result = get_terms( $this->taxonomy, $prepared_args );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  }
148
  $response = array();
149
  foreach ( $query_result as $term ) {
@@ -156,15 +177,6 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
156
  // Store pagation values for headers then unset for count query.
157
  $per_page = (int) $prepared_args['number'];
158
  $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 );
159
- unset( $prepared_args['number'] );
160
- unset( $prepared_args['offset'] );
161
-
162
- $total_terms = wp_count_terms( $this->taxonomy, $prepared_args );
163
-
164
- // wp_count_terms can return a falsy value when the term has no children
165
- if ( ! $total_terms ) {
166
- $total_terms = 0;
167
- }
168
 
169
  $response->header( 'X-WP-Total', (int) $total_terms );
170
  $max_pages = ceil( $total_terms / $per_page );
@@ -188,6 +200,73 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
188
  return $response;
189
  }
190
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
  /**
192
  * Check if a given request has access to read a term.
193
  *
@@ -253,17 +332,6 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
253
  * @return WP_REST_Request|WP_Error
254
  */
255
  public function create_item( $request ) {
256
- $name = $request['name'];
257
-
258
- $args = array();
259
-
260
- if ( isset( $request['description'] ) ) {
261
- $args['description'] = $request['description'];
262
- }
263
- if ( isset( $request['slug'] ) ) {
264
- $args['slug'] = $request['slug'];
265
- }
266
-
267
  if ( isset( $request['parent'] ) ) {
268
  if ( ! is_taxonomy_hierarchical( $this->taxonomy ) ) {
269
  return new WP_Error( 'rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.' ), array( 'status' => 400 ) );
@@ -272,13 +340,13 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
272
  $parent = get_term( (int) $request['parent'], $this->taxonomy );
273
 
274
  if ( ! $parent ) {
275
- return new WP_Error( 'rest_term_invalid', __( "Parent resource doesn't exist." ), array( 'status' => 404 ) );
276
  }
277
-
278
- $args['parent'] = $parent->term_id;
279
  }
280
 
281
- $term = wp_insert_term( $name, $this->taxonomy, $args );
 
 
282
  if ( is_wp_error( $term ) ) {
283
 
284
  // If we're going to inform the client that the term exists, give them the identifier
@@ -344,18 +412,6 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
344
  * @return WP_REST_Request|WP_Error
345
  */
346
  public function update_item( $request ) {
347
-
348
- $prepared_args = array();
349
- if ( isset( $request['name'] ) ) {
350
- $prepared_args['name'] = $request['name'];
351
- }
352
- if ( isset( $request['description'] ) ) {
353
- $prepared_args['description'] = $request['description'];
354
- }
355
- if ( isset( $request['slug'] ) ) {
356
- $prepared_args['slug'] = $request['slug'];
357
- }
358
-
359
  if ( isset( $request['parent'] ) ) {
360
  if ( ! is_taxonomy_hierarchical( $this->taxonomy ) ) {
361
  return new WP_Error( 'rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.' ), array( 'status' => 400 ) );
@@ -366,15 +422,15 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
366
  if ( ! $parent ) {
367
  return new WP_Error( 'rest_term_invalid', __( "Parent resource doesn't exist." ), array( 'status' => 400 ) );
368
  }
369
-
370
- $prepared_args['parent'] = $parent->term_id;
371
  }
372
 
 
 
373
  $term = get_term( (int) $request['id'], $this->taxonomy );
374
 
375
  // Only update the term if we haz something to update.
376
- if ( ! empty( $prepared_args ) ) {
377
- $update = wp_update_term( $term->term_id, $term->taxonomy, $prepared_args );
378
  if ( is_wp_error( $update ) ) {
379
  return $update;
380
  }
@@ -448,6 +504,51 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
448
  return $response;
449
  }
450
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
451
  /**
452
  * Prepare a single term output for response
453
  *
@@ -538,7 +639,7 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
538
  );
539
  }
540
  if ( ! empty( $post_type_links ) ) {
541
- $links['http://api.w.org/v2/post_type'] = $post_type_links;
542
  }
543
 
544
  return $links;
136
  */
137
  $prepared_args = apply_filters( "rest_{$this->taxonomy}_query", $prepared_args, $request );
138
 
139
+ // Can we use the cached call?
140
+ $use_cache = ! empty( $prepared_args['post'] )
141
+ && empty( $prepared_args['include'] )
142
+ && empty( $prepared_args['exclude'] )
143
+ && empty( $prepared_args['hide_empty'] )
144
+ && empty( $prepared_args['search'] )
145
+ && empty( $prepared_args['slug'] );
146
+
147
+ if ( ! empty( $prepared_args['post'] ) ) {
148
+ $query_result = $this->get_terms_for_post( $prepared_args );
149
+ $total_terms = $this->total_terms;
150
  } else {
151
  $query_result = get_terms( $this->taxonomy, $prepared_args );
152
+
153
+ $count_args = $prepared_args;
154
+ unset( $count_args['number'] );
155
+ unset( $count_args['offset'] );
156
+ $total_terms = wp_count_terms( $this->taxonomy, $count_args );
157
+
158
+ // Ensure we don't return results when offset is out of bounds
159
+ // see https://core.trac.wordpress.org/ticket/35935
160
+ if ( $prepared_args['offset'] >= $total_terms ) {
161
+ $query_result = array();
162
+ }
163
+
164
+ // wp_count_terms can return a falsy value when the term has no children
165
+ if ( ! $total_terms ) {
166
+ $total_terms = 0;
167
+ }
168
  }
169
  $response = array();
170
  foreach ( $query_result as $term ) {
177
  // Store pagation values for headers then unset for count query.
178
  $per_page = (int) $prepared_args['number'];
179
  $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 );
 
 
 
 
 
 
 
 
 
180
 
181
  $response->header( 'X-WP-Total', (int) $total_terms );
182
  $max_pages = ceil( $total_terms / $per_page );
200
  return $response;
201
  }
202
 
203
+ /**
204
+ * Get the terms attached to a post.
205
+ *
206
+ * This is an alternative to `get_terms()` that uses `get_the_terms()`
207
+ * instead, which hits the object cache. There are a few things not
208
+ * supported, notably `include`, `exclude`. In `self::get_items()` these
209
+ * are instead treated as a full query.
210
+ *
211
+ * @param array $prepared_args Arguments for `get_terms()`
212
+ * @return array List of term objects. (Total count in `$this->total_terms`)
213
+ */
214
+ protected function get_terms_for_post( $prepared_args ) {
215
+ $query_result = get_the_terms( $prepared_args['post'], $this->taxonomy );
216
+ if ( empty( $query_result ) ) {
217
+ $this->total_terms = 0;
218
+ return array();
219
+ }
220
+
221
+ // get_items() verifies that we don't have `include` set, and default
222
+ // ordering is by `name`
223
+ if ( ! in_array( $prepared_args['orderby'], array( 'name', 'none', 'include' ) ) ) {
224
+ switch ( $prepared_args['orderby'] ) {
225
+ case 'id':
226
+ $this->sort_column = 'term_id';
227
+ break;
228
+
229
+ case 'slug':
230
+ case 'term_group':
231
+ case 'description':
232
+ case 'count':
233
+ $this->sort_column = $prepared_args['orderby'];
234
+ break;
235
+ }
236
+ usort( $query_result, array( $this, 'compare_terms' ) );
237
+ }
238
+ if ( strtolower( $prepared_args['order'] ) !== 'asc' ) {
239
+ $query_result = array_reverse( $query_result );
240
+ }
241
+
242
+ // Pagination
243
+ $this->total_terms = count( $query_result );
244
+ $query_result = array_slice( $query_result, $prepared_args['offset'], $prepared_args['number'] );
245
+
246
+ return $query_result;
247
+ }
248
+
249
+ /**
250
+ * Comparison function for sorting terms by a column.
251
+ *
252
+ * Uses `$this->sort_column` to determine field to sort by.
253
+ *
254
+ * @param stdClass $left Term object.
255
+ * @param stdClass $right Term object.
256
+ * @return int <0 if left is higher "priority" than right, 0 if equal, >0 if right is higher "priority" than left.
257
+ */
258
+ protected function compare_terms( $left, $right ) {
259
+ $col = $this->sort_column;
260
+ $left_val = $left->$col;
261
+ $right_val = $right->$col;
262
+
263
+ if ( is_int( $left_val ) && is_int( $right_val ) ) {
264
+ return $left_val - $right_val;
265
+ }
266
+
267
+ return strcmp( $left_val, $right_val );
268
+ }
269
+
270
  /**
271
  * Check if a given request has access to read a term.
272
  *
332
  * @return WP_REST_Request|WP_Error
333
  */
334
  public function create_item( $request ) {
 
 
 
 
 
 
 
 
 
 
 
335
  if ( isset( $request['parent'] ) ) {
336
  if ( ! is_taxonomy_hierarchical( $this->taxonomy ) ) {
337
  return new WP_Error( 'rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.' ), array( 'status' => 400 ) );
340
  $parent = get_term( (int) $request['parent'], $this->taxonomy );
341
 
342
  if ( ! $parent ) {
343
+ return new WP_Error( 'rest_term_invalid', __( "Parent resource doesn't exist." ), array( 'status' => 400 ) );
344
  }
 
 
345
  }
346
 
347
+ $prepared_term = $this->prepare_item_for_database( $request );
348
+
349
+ $term = wp_insert_term( $prepared_term->name, $this->taxonomy, $prepared_term );
350
  if ( is_wp_error( $term ) ) {
351
 
352
  // If we're going to inform the client that the term exists, give them the identifier
412
  * @return WP_REST_Request|WP_Error
413
  */
414
  public function update_item( $request ) {
 
 
 
 
 
 
 
 
 
 
 
 
415
  if ( isset( $request['parent'] ) ) {
416
  if ( ! is_taxonomy_hierarchical( $this->taxonomy ) ) {
417
  return new WP_Error( 'rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.' ), array( 'status' => 400 ) );
422
  if ( ! $parent ) {
423
  return new WP_Error( 'rest_term_invalid', __( "Parent resource doesn't exist." ), array( 'status' => 400 ) );
424
  }
 
 
425
  }
426
 
427
+ $prepared_term = $this->prepare_item_for_database( $request );
428
+
429
  $term = get_term( (int) $request['id'], $this->taxonomy );
430
 
431
  // Only update the term if we haz something to update.
432
+ if ( ! empty( $prepared_term ) ) {
433
+ $update = wp_update_term( $term->term_id, $term->taxonomy, (array) $prepared_term );
434
  if ( is_wp_error( $update ) ) {
435
  return $update;
436
  }
504
  return $response;
505
  }
506
 
507
+ /**
508
+ * Prepare a single term for create or update
509
+ *
510
+ * @param WP_REST_Request $request Request object.
511
+ * @return object $prepared_term Term object.
512
+ */
513
+ public function prepare_item_for_database( $request ) {
514
+ $prepared_term = new stdClass;
515
+
516
+ if ( isset( $request['name'] ) ) {
517
+ $prepared_term->name = $request['name'];
518
+ }
519
+
520
+ if ( isset( $request['slug'] ) ) {
521
+ $prepared_term->slug = $request['slug'];
522
+ }
523
+
524
+ if ( isset( $request['taxonomy'] ) ) {
525
+ $prepared_term->taxonomy = $request['taxonomy'];
526
+ }
527
+
528
+ if ( isset( $request['description'] ) ) {
529
+ $prepared_term->description = $request['description'];
530
+ }
531
+
532
+ if ( isset( $request['parent'] ) ) {
533
+ $parent_term_id = 0;
534
+ $parent_term = get_term( (int) $request['parent'], $this->taxonomy );
535
+
536
+ if ( $parent_term ) {
537
+ $parent_term_id = $parent_term->term_id;
538
+ }
539
+
540
+ $prepared_term->parent = $parent_term_id;
541
+ }
542
+
543
+ /**
544
+ * Filter term data before inserting term via the REST API.
545
+ *
546
+ * @param object $prepared_term Term object.
547
+ * @param WP_REST_Request $request Request object.
548
+ */
549
+ return apply_filters( "rest_pre_insert_{$this->taxonomy}", $prepared_term, $request );
550
+ }
551
+
552
  /**
553
  * Prepare a single term output for response
554
  *
639
  );
640
  }
641
  if ( ! empty( $post_type_links ) ) {
642
+ $links['https://api.w.org/post_type'] = $post_type_links;
643
  }
644
 
645
  return $links;
lib/endpoints/class-wp-rest-users-controller.php CHANGED
@@ -19,17 +19,14 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
19
  array(
20
  'methods' => WP_REST_Server::READABLE,
21
  'callback' => array( $this, 'get_items' ),
 
22
  'args' => $this->get_collection_params(),
23
  ),
24
  array(
25
  'methods' => WP_REST_Server::CREATABLE,
26
  'callback' => array( $this, 'create_item' ),
27
  'permission_callback' => array( $this, 'create_item_permissions_check' ),
28
- 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array(
29
- 'password' => array(
30
- 'required' => true,
31
- ),
32
- ) ),
33
  ),
34
  'schema' => array( $this, 'get_public_item_schema' ),
35
  ) );
@@ -46,9 +43,7 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
46
  'methods' => WP_REST_Server::EDITABLE,
47
  'callback' => array( $this, 'update_item' ),
48
  'permission_callback' => array( $this, 'update_item_permissions_check' ),
49
- 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), array(
50
- 'password' => array(),
51
- ) ),
52
  ),
53
  array(
54
  'methods' => WP_REST_Server::DELETABLE,
@@ -75,6 +70,21 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
75
  ));
76
  }
77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  /**
79
  * Get all users
80
  *
@@ -101,6 +111,7 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
101
  );
102
  $prepared_args['orderby'] = $orderby_possibles[ $request['orderby'] ];
103
  $prepared_args['search'] = $request['search'];
 
104
 
105
  if ( ! current_user_can( 'list_users' ) ) {
106
  $prepared_args['has_published_posts'] = true;
@@ -192,7 +203,7 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
192
  }
193
 
194
  if ( 'edit' === $request['context'] && ! current_user_can( 'list_users' ) ) {
195
- return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you cannot view this resource with view context.' ), array( 'status' => rest_authorization_required_code() ) );
196
  } else if ( ! count_user_posts( $id, $types ) && ! current_user_can( 'edit_user', $id ) && ! current_user_can( 'list_users' ) ) {
197
  return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you cannot view this resource.' ), array( 'status' => rest_authorization_required_code() ) );
198
  }
@@ -263,8 +274,6 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
263
  * @return WP_Error|WP_REST_Response
264
  */
265
  public function create_item( $request ) {
266
- global $wp_roles;
267
-
268
  if ( ! empty( $request['id'] ) ) {
269
  return new WP_Error( 'rest_user_exists', __( 'Cannot create existing resource.' ), array( 'status' => 400 ) );
270
  }
@@ -312,7 +321,7 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
312
  /**
313
  * Fires after a user is created or updated via the REST API.
314
  *
315
- * @param object $user Data used to create the user (not a WP_User object).
316
  * @param WP_REST_Request $request Request object.
317
  * @param boolean $creating True when creating user, false when updating user.
318
  */
@@ -650,8 +659,6 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
650
  * @return array
651
  */
652
  public function get_item_schema() {
653
- global $wp_roles;
654
-
655
  $schema = array(
656
  '$schema' => 'http://json-schema.org/draft-04/schema#',
657
  'title' => 'user',
@@ -751,6 +758,12 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
751
  'type' => 'array',
752
  'context' => array( 'edit' ),
753
  ),
 
 
 
 
 
 
754
  'capabilities' => array(
755
  'description' => __( 'All capabilities assigned to the resource.' ),
756
  'type' => 'object',
@@ -845,6 +858,11 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
845
  'type' => 'string',
846
  'validate_callback' => 'rest_validate_request_arg',
847
  );
 
 
 
 
 
848
  return $query_params;
849
  }
850
  }
19
  array(
20
  'methods' => WP_REST_Server::READABLE,
21
  'callback' => array( $this, 'get_items' ),
22
+ 'permission_callback' => array( $this, 'get_items_permissions_check' ),
23
  'args' => $this->get_collection_params(),
24
  ),
25
  array(
26
  'methods' => WP_REST_Server::CREATABLE,
27
  'callback' => array( $this, 'create_item' ),
28
  'permission_callback' => array( $this, 'create_item_permissions_check' ),
29
+ 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),
 
 
 
 
30
  ),
31
  'schema' => array( $this, 'get_public_item_schema' ),
32
  ) );
43
  'methods' => WP_REST_Server::EDITABLE,
44
  'callback' => array( $this, 'update_item' ),
45
  'permission_callback' => array( $this, 'update_item_permissions_check' ),
46
+ 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
 
 
47
  ),
48
  array(
49
  'methods' => WP_REST_Server::DELETABLE,
70
  ));
71
  }
72
 
73
+ /**
74
+ * Permissions check for getting all users.
75
+ *
76
+ * @param WP_REST_Request $request Full details about the request.
77
+ * @return WP_Error|boolean
78
+ */
79
+ public function get_items_permissions_check( $request ) {
80
+ // Check if roles is specified in GET request and if user can list users.
81
+ if ( ! empty( $request['roles'] ) && ! current_user_can( 'list_users' ) ) {
82
+ return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you cannot filter by role.' ), array( 'status' => rest_authorization_required_code() ) );
83
+ }
84
+
85
+ return true;
86
+ }
87
+
88
  /**
89
  * Get all users
90
  *
111
  );
112
  $prepared_args['orderby'] = $orderby_possibles[ $request['orderby'] ];
113
  $prepared_args['search'] = $request['search'];
114
+ $prepared_args['role__in'] = $request['roles'];
115
 
116
  if ( ! current_user_can( 'list_users' ) ) {
117
  $prepared_args['has_published_posts'] = true;
203
  }
204
 
205
  if ( 'edit' === $request['context'] && ! current_user_can( 'list_users' ) ) {
206
+ return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you cannot view this resource with edit context.' ), array( 'status' => rest_authorization_required_code() ) );
207
  } else if ( ! count_user_posts( $id, $types ) && ! current_user_can( 'edit_user', $id ) && ! current_user_can( 'list_users' ) ) {
208
  return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you cannot view this resource.' ), array( 'status' => rest_authorization_required_code() ) );
209
  }
274
  * @return WP_Error|WP_REST_Response
275
  */
276
  public function create_item( $request ) {
 
 
277
  if ( ! empty( $request['id'] ) ) {
278
  return new WP_Error( 'rest_user_exists', __( 'Cannot create existing resource.' ), array( 'status' => 400 ) );
279
  }
321
  /**
322
  * Fires after a user is created or updated via the REST API.
323
  *
324
+ * @param WP_User $user Data used to create the user.
325
  * @param WP_REST_Request $request Request object.
326
  * @param boolean $creating True when creating user, false when updating user.
327
  */
659
  * @return array
660
  */
661
  public function get_item_schema() {
 
 
662
  $schema = array(
663
  '$schema' => 'http://json-schema.org/draft-04/schema#',
664
  'title' => 'user',
758
  'type' => 'array',
759
  'context' => array( 'edit' ),
760
  ),
761
+ 'password' => array(
762
+ 'description' => __( 'Password for the resource (never included).' ),
763
+ 'type' => 'string',
764
+ 'context' => array(), // Password is never displayed
765
+ 'required' => true,
766
+ ),
767
  'capabilities' => array(
768
  'description' => __( 'All capabilities assigned to the resource.' ),
769
  'type' => 'object',
858
  'type' => 'string',
859
  'validate_callback' => 'rest_validate_request_arg',
860
  );
861
+ $query_params['roles'] = array(
862
+ 'description' => __( 'Limit result set to resources matching at least one specific role provided. Accepts csv list or single role.' ),
863
+ 'type' => 'array',
864
+ 'sanitize_callback' => 'wp_parse_slug_list',
865
+ );
866
  return $query_params;
867
  }
868
  }
plugin.php CHANGED
@@ -3,8 +3,8 @@
3
  * Plugin Name: WP REST API
4
  * Description: JSON-based REST API for WordPress, originally developed as part of GSoC 2013.
5
  * Author: WP REST API Team
6
- * Author URI: http://wp-api.org
7
- * Version: 2.0-beta12
8
  * Plugin URI: https://github.com/WP-API/WP-API
9
  * License: GPL2+
10
  */
@@ -96,7 +96,7 @@ add_action( 'rest_api_init', 'create_initial_rest_routes', 0 );
96
  *
97
  * @since 4.4.0
98
  *
99
- * @global array $wp_taxonomies Registered taxonomies.
100
  */
101
  function _add_extra_api_post_type_arguments() {
102
  global $wp_post_types;
3
  * Plugin Name: WP REST API
4
  * Description: JSON-based REST API for WordPress, originally developed as part of GSoC 2013.
5
  * Author: WP REST API Team
6
+ * Author URI: http://v2.wp-api.org
7
+ * Version: 2.0-beta13
8
  * Plugin URI: https://github.com/WP-API/WP-API
9
  * License: GPL2+
10
  */
96
  *
97
  * @since 4.4.0
98
  *
99
+ * @global array $wp_post_types Registered post types.
100
  */
101
  function _add_extra_api_post_type_arguments() {
102
  global $wp_post_types;
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: rmccue, rachelbaker, danielbachhuber, joehoyle
3
  Tags: json, rest, api, rest-api
4
  Requires at least: 4.4
5
- Tested up to: 4.5-alpha
6
- Stable tag: 2.0-beta12
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -38,6 +38,100 @@ Once you've installed and activated the plugin, [check out the documentation](ht
38
 
39
  == Changelog ==
40
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  = 2.0 Beta 12.0 (February 9, 2016) =
42
 
43
  * BREAKING CHANGE: Removes meta endpoints from primary plugin.
2
  Contributors: rmccue, rachelbaker, danielbachhuber, joehoyle
3
  Tags: json, rest, api, rest-api
4
  Requires at least: 4.4
5
+ Tested up to: 4.5
6
+ Stable tag: 2.0-beta13
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
38
 
39
  == Changelog ==
40
 
41
+ = 2.0 Beta 13.0 (March 29, 2016) =
42
+
43
+ * BREAKING CHANGE: Fix Content-Disposition header parsing.
44
+
45
+ Allows regular form submissions from HTML forms, as well as properly formatted HTTP requests from clients. Note: this breaks backwards compatibility, as previously, the header parsing was completely wrong.
46
+
47
+ (props @rmccue, [#2239](https://github.com/WP-API/WP-API/pull/2239))
48
+
49
+ * BREAKING CHANGE: Use compact links for embedded responses if they are available.
50
+
51
+ Introduces curies for sites running WordPress 4.5 or greater; no changes for those running WordPress 4.4.
52
+
53
+ (props @joehoyle, [#2412](https://github.com/WP-API/WP-API/pull/2412))
54
+
55
+ * JavaScript client updates:
56
+
57
+ * Support lodash, plus older and newer underscore: add an alias for `_.contains`
58
+ * Add args and options on the model/collection prototypes
59
+ * Rework category/tag mixins to support new API structure
60
+ * Add workaround for the null/empty values returned by the API when creating a new post * these values are not accepted for subsequent updates/saves, so explicitly excluding them. See https://github.com/WP-API/WP-API/pull/2393
61
+ * Better handling of the (special) `me` endpoint
62
+ * Schema parsing cleanup
63
+ * Introduce `wp.api.loadPromise` so developers can ensure api load complete before using
64
+
65
+ (props @adamsilverstein, [#2403](https://github.com/WP-API/WP-API/pull/2403))
66
+
67
+ * Only adds alternate link header for publicly viewable CPTs.
68
+
69
+ (props @bradyvercher, [#2387](https://github.com/WP-API/WP-API/pull/2387))
70
+
71
+ * Adds `roles` param for `GET /wp/v2/users`.
72
+
73
+ (props @BE-Webdesign, [#2372](https://github.com/WP-API/WP-API/pull/2372))
74
+
75
+ * Declares `password` in user schema, but never displays it.
76
+
77
+ (props @danielbachhuber, [#2386](https://github.com/WP-API/WP-API/pull/2386))
78
+
79
+ * Permits `edit` context for requests which can edit the user.
80
+
81
+ (props @danielbachhuber, [#2383](https://github.com/WP-API/WP-API/pull/2383))
82
+
83
+ * Adds `rest_pre_insert_{$taxonomy}` filter for terms.
84
+
85
+ (props @kjbenk, [#2377](https://github.com/WP-API/WP-API/pull/2377))
86
+
87
+ * Supports taxonomy collection args on posts endpoint.
88
+
89
+ (props @joehoyle, [#2287](https://github.com/WP-API/WP-API/pull/2287))
90
+
91
+ * Removes post meta link from post response.
92
+
93
+ (props @joehoyle, [#2288](https://github.com/WP-API/WP-API/pull/2288))
94
+
95
+ * Registers `description` attribute when registering args from schema.
96
+
97
+ (props @danielbachhuber, [#2362](https://github.com/WP-API/WP-API/pull/2362))
98
+
99
+ * Uses `$comment` from the database with `rest_insert_comment` action.
100
+
101
+ (props @danielbachhuber, [#2349](https://github.com/WP-API/WP-API/pull/2349))
102
+
103
+ * Removes unnecessary global variables from users controller.
104
+
105
+ (props @claudiosmweb, [#2335](https://github.com/WP-API/WP-API/pull/2335))
106
+
107
+ * Ensures `GET /wp/v2/categories` with out of bounds offset doesn't return results.
108
+
109
+ (props @danielbachhuber, [#2313](https://github.com/WP-API/WP-API/pull/2313))
110
+
111
+ * Adds top-level support for date queries on posts and comments.
112
+
113
+ (props @BE-Webdesign, [#2266](https://github.com/WP-API/WP-API/pull/2266), [#2291](https://github.com/WP-API/WP-API/pull/2291))
114
+
115
+ * Respects `show_avatars` setting for comments.
116
+
117
+ (props @BE-Webdesign, [#2271](https://github.com/WP-API/WP-API/pull/2271))
118
+
119
+ * Uses cached `get_the_terms()` for terms-for-post for better performance.
120
+
121
+ (props @rmccue, [#2257](https://github.com/WP-API/WP-API/pull/2257))
122
+
123
+ * Ensures comments search is an empty string.
124
+
125
+ (props @rmccue, [#2256](https://github.com/WP-API/WP-API/pull/2256))
126
+
127
+ * If no title is provided in create attachment request or file metadata, falls back to filename.
128
+
129
+ (props @danielbachhuber, [#2254](https://github.com/WP-API/WP-API/pull/2254))
130
+
131
+ * Removes unused `$img_url_basename` variable in attachments controller.
132
+
133
+ (props @danielbachhuber, [#2250](https://github.com/WP-API/WP-API/pull/2250))
134
+
135
  = 2.0 Beta 12.0 (February 9, 2016) =
136
 
137
  * BREAKING CHANGE: Removes meta endpoints from primary plugin.
wp-api.js CHANGED
@@ -12,6 +12,11 @@
12
  wp.api = wp.api || new WP_API();
13
  wp.api.versionString = wp.api.versionString || 'wp/v2/';
14
 
 
 
 
 
 
15
  })( window );
16
 
17
  (function( window, undefined ) {
@@ -152,49 +157,49 @@
152
  };
153
 
154
  /**
155
- * Add defaults to a model from a route's endpoints.
156
  *
157
  * @param {array} routeEndpoints Array of route endpoints.
158
  * @param {Object} modelInstance An instance of the model (or collection)
159
- * to add the defaults to.
160
  */
161
  wp.api.utils.decorateFromRoute = function( routeEndpoints, modelInstance ) {
162
 
163
  /**
164
- * Build the defaults based on route endpoint data.
165
  */
166
  _.each( routeEndpoints, function( routeEndpoint ) {
167
 
168
- // Add post and edit endpoints as model defaults.
169
- if ( _.contains( routeEndpoint.methods, 'POST' ) || _.contains( routeEndpoint.methods, 'PUT' ) ) {
170
 
171
- // Add any non empty args, merging them into the defaults object.
172
  if ( ! _.isEmpty( routeEndpoint.args ) ) {
173
 
174
- // Set as defauls if no defaults yet.
175
- if ( _.isEmpty( modelInstance.defaults ) ) {
176
- modelInstance.defaults = routeEndpoint.args;
177
  } else {
178
 
179
- // We already have defaults, merge these new args in.
180
- modelInstance.defaults = _.union( routeEndpoint.args, modelInstance.defaults );
181
  }
182
  }
183
  } else {
184
 
185
  // Add GET method as model options.
186
- if ( _.contains( routeEndpoint.methods, 'GET' ) ) {
187
 
188
  // Add any non empty args, merging them into the defaults object.
189
  if ( ! _.isEmpty( routeEndpoint.args ) ) {
190
 
191
  // Set as defauls if no defaults yet.
192
- if ( _.isEmpty( modelInstance.options ) ) {
193
- modelInstance.options = routeEndpoint.args;
194
  } else {
195
 
196
  // We already have options, merge these new args in.
197
- modelInstance.options = _.union( routeEndpoint.args, modelInstance.options );
198
  }
199
  }
200
 
@@ -333,12 +338,12 @@
333
  /**
334
  * Build a helper to retrieve a collection.
335
  *
336
- * @param {string} parentModel The parent model.
337
- * @param {string} collectionName The name to use when constructing the collection.
338
- * @param {string} embedSourcePoint Where to check the embedds object for _embed data.
339
- * @param {string} embedIndex An addiitonal optional index for the _embed data.
340
  *
341
- * @return {Deferred.promise} A promise which resolves to the constructed collection.
342
  */
343
  buildCollectionGetter = function( parentModel, collectionName, embedSourcePoint, embedIndex ) {
344
  /**
@@ -439,32 +444,112 @@
439
  * Add a helper funtion to handle post Tags.
440
  */
441
  TagsMixin = {
 
 
 
 
 
 
442
  getTags: function() {
443
- return buildCollectionGetter( this, 'PostTags', 'https://api.w.org/term', 1 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
444
  }
445
  },
 
446
  /**
447
  * Add a helper funtion to handle post Categories.
448
  */
449
  CategoriesMixin = {
450
 
451
  /**
452
- * Get a PostCategories model for an model's categories.
453
- *
454
- * Uses the embedded data if available, otherwises fetches the
455
- * data from the server.
456
  *
457
- * @return {Deferred.promise} promise Resolves to a wp.api.collections.PostCategories
458
- * collection containing the post categories.
459
  */
460
  getCategories: function() {
461
- return buildCollectionGetter( this, 'PostCategories', 'https://api.w.org/term', 0 );
 
 
 
 
 
 
 
 
462
  },
463
 
464
  /**
465
  * Set the categories for a post.
466
  *
467
- * Accepts an array of category slugs, or a PostCategories collection.
468
  *
469
  * @param {array|Backbone.Collection} categories The categories to set on the post.
470
  *
@@ -474,17 +559,22 @@
474
  self = this,
475
  newCategories = [];
476
 
 
 
 
 
477
  // If this is an array of slugs, build a collection.
478
  if ( _.isArray( categories ) ) {
479
 
480
  // Get all the categories.
481
  allCategories = new wp.api.collections.Categories();
482
  allCategories.fetch( {
 
483
  success: function( allcats ) {
484
 
485
  // Find the passed categories and set them up.
486
  _.each( categories, function( category ) {
487
- newCategory = new wp.api.models.PostCategories( allcats.findWhere( { slug: category } ) );
488
 
489
  // Tie the new category to the post.
490
  newCategory.set( 'parent_post', self.get( 'id' ) );
@@ -492,7 +582,7 @@
492
  // Add the new category to the collection.
493
  newCategories.push( newCategory );
494
  } );
495
- categories = new wp.api.collections.PostCategories( newCategories );
496
  self.setCategoriesWithCollection( categories );
497
  }
498
  } );
@@ -506,37 +596,16 @@
506
  /**
507
  * Set the categories for a post.
508
  *
509
- * Accepts PostCategories collection.
510
  *
511
  * @param {array|Backbone.Collection} categories The categories to set on the post.
512
  *
513
  */
514
  setCategoriesWithCollection: function( categories ) {
515
- var removedCategories, addedCategories, categoriesIds, existingCategoriesIds;
516
-
517
- // Get the existing categories.
518
- this.getCategories().done( function( existingCategories ) {
519
-
520
- // Pluck out the category ids.
521
- categoriesIds = categories.pluck( 'id' );
522
- existingCategoriesIds = existingCategories.pluck( 'id' );
523
-
524
- // Calculate which categories have been removed or added (leave the rest).
525
- addedCategories = _.difference( categoriesIds, existingCategoriesIds );
526
- removedCategories = _.difference( existingCategoriesIds, categoriesIds );
527
-
528
- // Add the added categories.
529
- _.each( addedCategories, function( addedCategory ) {
530
 
531
- // Save the new categories on the post with a 'POST' method, not Backbone's default 'PUT'.
532
- existingCategories.create( categories.get( addedCategory ), { type: 'POST' } );
533
- } );
534
-
535
- // Remove the removed categories.
536
- _.each( removedCategories, function( removedCategory ) {
537
- existingCategories.get( removedCategory ).destroy();
538
- } );
539
- } );
540
  }
541
  },
542
 
@@ -559,13 +628,13 @@
559
  };
560
 
561
  // Exit if we don't have valid model defaults.
562
- if ( _.isUndefined( model.defaults ) ) {
563
  return model;
564
  }
565
 
566
  // Go thru the parsable date fields, if our model contains any of them it gets the TimeStampedMixin.
567
  _.each( parseableDates, function( theDateKey ) {
568
- if ( ! _.isUndefined( model.defaults[ theDateKey ] ) ) {
569
  hasDate = true;
570
  }
571
  } );
@@ -576,17 +645,17 @@
576
  }
577
 
578
  // Add the AuthorMixin for models that contain an author.
579
- if ( ! _.isUndefined( model.defaults.author ) ) {
580
  model = model.extend( AuthorMixin );
581
  }
582
 
583
  // Add the FeaturedImageMixin for models that contain a featured_image.
584
- if ( ! _.isUndefined( model.defaults.featured_image ) ) {
585
  model = model.extend( FeaturedImageMixin );
586
  }
587
 
588
  // Add the CategoriesMixin for models that support categories collections.
589
- if ( ! _.isUndefined( loadingObjects.collections[ modelClassName + 'Categories' ] ) ) {
590
  model = model.extend( CategoriesMixin );
591
  }
592
 
@@ -596,7 +665,7 @@
596
  }
597
 
598
  // Add the TagsMixin for models that support tags collections.
599
- if ( ! _.isUndefined( loadingObjects.collections[ modelClassName + 'Tags' ] ) ) {
600
  model = model.extend( TagsMixin );
601
  }
602
 
@@ -614,10 +683,12 @@
614
 
615
  // Suppress warning about parse function's unused "options" argument:
616
  /* jshint unused:false */
617
- (function( wp, wpApiSettings, Backbone, window, undefined ) {
618
 
619
  'use strict';
620
 
 
 
621
  /**
622
  * Backbone base model for all models.
623
  */
@@ -637,6 +708,16 @@
637
 
638
  options = options || {};
639
 
 
 
 
 
 
 
 
 
 
 
640
  if ( ! _.isUndefined( wpApiSettings.nonce ) && ! _.isNull( wpApiSettings.nonce ) ) {
641
  beforeSend = options.beforeSend;
642
 
@@ -652,7 +733,7 @@
652
  };
653
  }
654
 
655
- // Add '?force=true' to delete method when required.
656
  if ( this.requireForceForDelete && 'delete' === method ) {
657
  model.url = model.url() + '?force=true';
658
  }
@@ -665,7 +746,7 @@
665
  save: function( attrs, options ) {
666
 
667
  // Do we have the put method, then execute the save.
668
- if ( _.contains( this.methods, 'PUT' ) || _.contains( this.methods, 'POST' ) ) {
669
 
670
  // Proxy the call to the original save function.
671
  return Backbone.Model.prototype.save.call( this, attrs, options );
@@ -682,7 +763,7 @@
682
  destroy: function( options ) {
683
 
684
  // Do we have the DELETE method, then execute the destroy.
685
- if ( _.contains( this.methods, 'DELETE' ) ) {
686
 
687
  // Proxy the call to the original save function.
688
  return Backbone.Model.prototype.destroy.call( this, options );
@@ -723,13 +804,14 @@
723
  }
724
  }
725
  );
726
- })( wp, wpApiSettings, Backbone, window );
727
 
728
- /* global wpApiSettings:false */
729
- (function( wp, wpApiSettings, Backbone, _, window, undefined ) {
730
 
731
  'use strict';
732
 
 
 
733
  /**
734
  * Contains basic collection functionality such as pagination.
735
  */
@@ -800,8 +882,10 @@
800
 
801
  success = options.success;
802
  options.success = function( data, textStatus, request ) {
803
- self.state.totalPages = parseInt( request.getResponseHeader( 'x-wp-totalpages' ), 10 );
804
- self.state.totalObjects = parseInt( request.getResponseHeader( 'x-wp-total' ), 10 );
 
 
805
 
806
  if ( null === self.state.currentPage ) {
807
  self.state.currentPage = 1;
@@ -862,17 +946,20 @@
862
  }
863
  );
864
 
865
- })( wp, wpApiSettings, Backbone, _, window );
866
 
867
- /* global wpApiSettings */
868
- (function( window, undefined ) {
869
 
870
  'use strict';
871
 
872
- var Endpoint, initializedDeferreds = {};
873
-
874
  window.wp = window.wp || {};
875
- wp.api = wp.api || {};
 
 
 
 
876
 
877
  Endpoint = Backbone.Model.extend({
878
  defaults: {
@@ -991,19 +1078,14 @@
991
  index !== schemaRoot &&
992
  index !== ( '/' + routeModel.get( 'versionString' ).slice( 0, -1 ) )
993
  ) {
994
- /**
995
- * Single item models end with a regex/variable.
996
- *
997
- * @todo make model/collection logic more robust.
998
- */
999
- if ( index.endsWith( '+)' ) ) {
1000
  modelRoutes.push( { index: index, route: route } );
1001
  } else {
1002
 
1003
  // Collections end in a name.
1004
- if ( ! index.endsWith( 'me' ) ) {
1005
- collectionRoutes.push( { index: index, route: route } );
1006
- }
1007
  }
1008
  }
1009
  } );
@@ -1018,7 +1100,13 @@
1018
  // Extract the name and any parent from the route.
1019
  var modelClassName,
1020
  routeName = wp.api.utils.extractRoutePart( modelRoute.index, 2 ),
1021
- parentName = wp.api.utils.extractRoutePart( modelRoute.index, 4 );
 
 
 
 
 
 
1022
 
1023
  // If the model has a parent in its route, add that to its class name.
1024
  if ( '' !== parentName && parentName !== routeName ) {
@@ -1059,7 +1147,7 @@
1059
  if (
1060
  'Posts' !== this.name &&
1061
  'Pages' !== this.name &&
1062
- _.contains( this.methods, 'DELETE' )
1063
  ) {
1064
  this.requireForceForDelete = true;
1065
  }
@@ -1074,7 +1162,10 @@
1074
 
1075
  // Function that returns a constructed url based on the id.
1076
  url: function() {
1077
- var url = routeModel.get( 'apiRoot' ) + routeModel.get( 'versionString' ) + routeName;
 
 
 
1078
  if ( ! _.isUndefined( this.get( 'id' ) ) ) {
1079
  url += '/' + this.get( 'id' );
1080
  }
@@ -1223,6 +1314,6 @@
1223
  */
1224
 
1225
  // The wp.api.init function returns a promise that will resolve with the endpoint once it is ready.
1226
- wp.api.init();
1227
 
1228
- })( window );
12
  wp.api = wp.api || new WP_API();
13
  wp.api.versionString = wp.api.versionString || 'wp/v2/';
14
 
15
+ // Alias _includes to _.contains, ensuring it is available.
16
+ if ( ! _.isFunction( _.includes ) && _.isFunction( _.contains ) ) {
17
+ _.includes = _.contains;
18
+ }
19
+
20
  })( window );
21
 
22
  (function( window, undefined ) {
157
  };
158
 
159
  /**
160
+ * Add args and options to a model prototype from a route's endpoints.
161
  *
162
  * @param {array} routeEndpoints Array of route endpoints.
163
  * @param {Object} modelInstance An instance of the model (or collection)
164
+ * to add the args to.
165
  */
166
  wp.api.utils.decorateFromRoute = function( routeEndpoints, modelInstance ) {
167
 
168
  /**
169
+ * Build the args based on route endpoint data.
170
  */
171
  _.each( routeEndpoints, function( routeEndpoint ) {
172
 
173
+ // Add post and edit endpoints as model args.
174
+ if ( _.includes( routeEndpoint.methods, 'POST' ) || _.includes( routeEndpoint.methods, 'PUT' ) ) {
175
 
176
+ // Add any non empty args, merging them into the args object.
177
  if ( ! _.isEmpty( routeEndpoint.args ) ) {
178
 
179
+ // Set as defauls if no args yet.
180
+ if ( _.isEmpty( modelInstance.prototype.args ) ) {
181
+ modelInstance.prototype.args = routeEndpoint.args;
182
  } else {
183
 
184
+ // We already have args, merge these new args in.
185
+ modelInstance.prototype.args = _.union( routeEndpoint.args, modelInstance.prototype.defaults );
186
  }
187
  }
188
  } else {
189
 
190
  // Add GET method as model options.
191
+ if ( _.includes( routeEndpoint.methods, 'GET' ) ) {
192
 
193
  // Add any non empty args, merging them into the defaults object.
194
  if ( ! _.isEmpty( routeEndpoint.args ) ) {
195
 
196
  // Set as defauls if no defaults yet.
197
+ if ( _.isEmpty( modelInstance.prototype.options ) ) {
198
+ modelInstance.prototype.options = routeEndpoint.args;
199
  } else {
200
 
201
  // We already have options, merge these new args in.
202
+ modelInstance.prototype.options = _.union( routeEndpoint.args, modelInstance.prototype.options );
203
  }
204
  }
205
 
338
  /**
339
  * Build a helper to retrieve a collection.
340
  *
341
+ * @param {string} parentModel The parent model.
342
+ * @param {string} collectionName The name to use when constructing the collection.
343
+ * @param {string} embedSourcePoint Where to check the embedds object for _embed data.
344
+ * @param {string} embedIndex An addiitonal optional index for the _embed data.
345
  *
346
+ * @return {Deferred.promise} A promise which resolves to the constructed collection.
347
  */
348
  buildCollectionGetter = function( parentModel, collectionName, embedSourcePoint, embedIndex ) {
349
  /**
444
  * Add a helper funtion to handle post Tags.
445
  */
446
  TagsMixin = {
447
+
448
+ /**
449
+ * Get the tags for a post.
450
+ *
451
+ * @return {Deferred.promise} promise Resolves to an array of tags.
452
+ */
453
  getTags: function() {
454
+ var tagIds = this.get( 'tags' ),
455
+ tags = new wp.api.collections.Tags();
456
+
457
+ // Resolve with an empty array if no tags.
458
+ if ( _.isEmpty( tagIds ) ) {
459
+ return jQuery.Deferred().resolve( [] );
460
+ }
461
+
462
+ return tags.fetch( { data: { include: tagIds } } );
463
+ },
464
+
465
+ /**
466
+ * Set the tags for a post.
467
+ *
468
+ * Accepts an array of tag slugs, or a Tags collection.
469
+ *
470
+ * @param {array|Backbone.Collection} tags The tags to set on the post.
471
+ *
472
+ */
473
+ setTags: function( tags ) {
474
+ var allTags, newTag,
475
+ self = this,
476
+ newTags = [];
477
+
478
+ if ( _.isString( tags ) ) {
479
+ return false;
480
+ }
481
+
482
+ // If this is an array of slugs, build a collection.
483
+ if ( _.isArray( tags ) ) {
484
+
485
+ // Get all the tags.
486
+ allTags = new wp.api.collections.Tags();
487
+ allTags.fetch( {
488
+ data: { per_page: 100 },
489
+ success: function( alltags ) {
490
+
491
+ // Find the passed tags and set them up.
492
+ _.each( tags, function( tag ) {
493
+ newTag = new wp.api.models.Tag( alltags.findWhere( { slug: tag } ) );
494
+
495
+ // Tie the new tag to the post.
496
+ newTag.set( 'parent_post', self.get( 'id' ) );
497
+
498
+ // Add the new tag to the collection.
499
+ newTags.push( newTag );
500
+ } );
501
+ tags = new wp.api.collections.Tags( newTags );
502
+ self.setTagsWithCollection( tags );
503
+ }
504
+ } );
505
+
506
+ } else {
507
+ this.setTagsWithCollection( tags );
508
+ }
509
+ },
510
+
511
+ /**
512
+ * Set the tags for a post.
513
+ *
514
+ * Accepts a Tags collection.
515
+ *
516
+ * @param {array|Backbone.Collection} tags The tags to set on the post.
517
+ *
518
+ */
519
+ setTagsWithCollection: function( tags ) {
520
+
521
+ // Pluck out the category ids.
522
+ this.set( 'tags', tags.pluck( 'id' ) );
523
+ return this.save();
524
  }
525
  },
526
+
527
  /**
528
  * Add a helper funtion to handle post Categories.
529
  */
530
  CategoriesMixin = {
531
 
532
  /**
533
+ * Get a the categories for a post.
 
 
 
534
  *
535
+ * @return {Deferred.promise} promise Resolves to an array of categories.
 
536
  */
537
  getCategories: function() {
538
+ var categoryIds = this.get( 'categories' ),
539
+ categories = new wp.api.collections.Categories();
540
+
541
+ // Resolve with an empty array if no categories.
542
+ if ( _.isEmpty( categoryIds ) ) {
543
+ return jQuery.Deferred().resolve( [] );
544
+ }
545
+
546
+ return categories.fetch( { data: { include: categoryIds } } );
547
  },
548
 
549
  /**
550
  * Set the categories for a post.
551
  *
552
+ * Accepts an array of category slugs, or a Categories collection.
553
  *
554
  * @param {array|Backbone.Collection} categories The categories to set on the post.
555
  *
559
  self = this,
560
  newCategories = [];
561
 
562
+ if ( _.isString( categories ) ) {
563
+ return false;
564
+ }
565
+
566
  // If this is an array of slugs, build a collection.
567
  if ( _.isArray( categories ) ) {
568
 
569
  // Get all the categories.
570
  allCategories = new wp.api.collections.Categories();
571
  allCategories.fetch( {
572
+ data: { per_page: 100 },
573
  success: function( allcats ) {
574
 
575
  // Find the passed categories and set them up.
576
  _.each( categories, function( category ) {
577
+ newCategory = new wp.api.models.Category( allcats.findWhere( { slug: category } ) );
578
 
579
  // Tie the new category to the post.
580
  newCategory.set( 'parent_post', self.get( 'id' ) );
582
  // Add the new category to the collection.
583
  newCategories.push( newCategory );
584
  } );
585
+ categories = new wp.api.collections.Categories( newCategories );
586
  self.setCategoriesWithCollection( categories );
587
  }
588
  } );
596
  /**
597
  * Set the categories for a post.
598
  *
599
+ * Accepts Categories collection.
600
  *
601
  * @param {array|Backbone.Collection} categories The categories to set on the post.
602
  *
603
  */
604
  setCategoriesWithCollection: function( categories ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
605
 
606
+ // Pluck out the category ids.
607
+ this.set( 'categories', categories.pluck( 'id' ) );
608
+ return this.save();
 
 
 
 
 
 
609
  }
610
  },
611
 
628
  };
629
 
630
  // Exit if we don't have valid model defaults.
631
+ if ( _.isUndefined( model.prototype.args ) ) {
632
  return model;
633
  }
634
 
635
  // Go thru the parsable date fields, if our model contains any of them it gets the TimeStampedMixin.
636
  _.each( parseableDates, function( theDateKey ) {
637
+ if ( ! _.isUndefined( model.prototype.args[ theDateKey ] ) ) {
638
  hasDate = true;
639
  }
640
  } );
645
  }
646
 
647
  // Add the AuthorMixin for models that contain an author.
648
+ if ( ! _.isUndefined( model.prototype.args.author ) ) {
649
  model = model.extend( AuthorMixin );
650
  }
651
 
652
  // Add the FeaturedImageMixin for models that contain a featured_image.
653
+ if ( ! _.isUndefined( model.prototype.args.featured_image ) ) {
654
  model = model.extend( FeaturedImageMixin );
655
  }
656
 
657
  // Add the CategoriesMixin for models that support categories collections.
658
+ if ( ! _.isUndefined( model.prototype.args.categories ) ) {
659
  model = model.extend( CategoriesMixin );
660
  }
661
 
665
  }
666
 
667
  // Add the TagsMixin for models that support tags collections.
668
+ if ( ! _.isUndefined( model.prototype.args.tags ) ) {
669
  model = model.extend( TagsMixin );
670
  }
671
 
683
 
684
  // Suppress warning about parse function's unused "options" argument:
685
  /* jshint unused:false */
686
+ (function() {
687
 
688
  'use strict';
689
 
690
+ var wpApiSettings = window.wpApiSettings || {};
691
+
692
  /**
693
  * Backbone base model for all models.
694
  */
708
 
709
  options = options || {};
710
 
711
+ // Remove date_gmt if null.
712
+ if ( _.isNull( model.get( 'date_gmt' ) ) ) {
713
+ model.unset( 'date_gmt' );
714
+ }
715
+
716
+ // Remove slug if empty.
717
+ if ( _.isEmpty( model.get( 'slug' ) ) ) {
718
+ model.unset( 'slug' );
719
+ }
720
+
721
  if ( ! _.isUndefined( wpApiSettings.nonce ) && ! _.isNull( wpApiSettings.nonce ) ) {
722
  beforeSend = options.beforeSend;
723
 
733
  };
734
  }
735
 
736
+ // Add '?force=true' to use delete method when required.
737
  if ( this.requireForceForDelete && 'delete' === method ) {
738
  model.url = model.url() + '?force=true';
739
  }
746
  save: function( attrs, options ) {
747
 
748
  // Do we have the put method, then execute the save.
749
+ if ( _.includes( this.methods, 'PUT' ) || _.includes( this.methods, 'POST' ) ) {
750
 
751
  // Proxy the call to the original save function.
752
  return Backbone.Model.prototype.save.call( this, attrs, options );
763
  destroy: function( options ) {
764
 
765
  // Do we have the DELETE method, then execute the destroy.
766
+ if ( _.includes( this.methods, 'DELETE' ) ) {
767
 
768
  // Proxy the call to the original save function.
769
  return Backbone.Model.prototype.destroy.call( this, options );
804
  }
805
  }
806
  );
807
+ })();
808
 
809
+ ( function() {
 
810
 
811
  'use strict';
812
 
813
+ var wpApiSettings = window.wpApiSettings || {};
814
+
815
  /**
816
  * Contains basic collection functionality such as pagination.
817
  */
882
 
883
  success = options.success;
884
  options.success = function( data, textStatus, request ) {
885
+ if ( ! _.isUndefined( request ) ) {
886
+ self.state.totalPages = parseInt( request.getResponseHeader( 'x-wp-totalpages' ), 10 );
887
+ self.state.totalObjects = parseInt( request.getResponseHeader( 'x-wp-total' ), 10 );
888
+ }
889
 
890
  if ( null === self.state.currentPage ) {
891
  self.state.currentPage = 1;
946
  }
947
  );
948
 
949
+ } )();
950
 
951
+ ( function() {
 
952
 
953
  'use strict';
954
 
955
+ var Endpoint, initializedDeferreds = {},
956
+ wpApiSettings = window.wpApiSettings || {};
957
  window.wp = window.wp || {};
958
+ wp.api = wp.api || {};
959
+
960
+ if ( _.isEmpty( wpApiSettings ) ) {
961
+ wpApiSettings.root = window.location.origin + '/wp-json/';
962
+ }
963
 
964
  Endpoint = Backbone.Model.extend({
965
  defaults: {
1078
  index !== schemaRoot &&
1079
  index !== ( '/' + routeModel.get( 'versionString' ).slice( 0, -1 ) )
1080
  ) {
1081
+
1082
+ // Single items end with a regex (or the special case 'me').
1083
+ if ( /.*[+)|me]$/.test( index ) ) {
 
 
 
1084
  modelRoutes.push( { index: index, route: route } );
1085
  } else {
1086
 
1087
  // Collections end in a name.
1088
+ collectionRoutes.push( { index: index, route: route } );
 
 
1089
  }
1090
  }
1091
  } );
1100
  // Extract the name and any parent from the route.
1101
  var modelClassName,
1102
  routeName = wp.api.utils.extractRoutePart( modelRoute.index, 2 ),
1103
+ parentName = wp.api.utils.extractRoutePart( modelRoute.index, 4 ),
1104
+ routeEnd = wp.api.utils.extractRoutePart( modelRoute.index, 1 );
1105
+
1106
+ // Handle the special case of the 'me' route.
1107
+ if ( 'me' === routeEnd ) {
1108
+ routeName = 'me';
1109
+ }
1110
 
1111
  // If the model has a parent in its route, add that to its class name.
1112
  if ( '' !== parentName && parentName !== routeName ) {
1147
  if (
1148
  'Posts' !== this.name &&
1149
  'Pages' !== this.name &&
1150
+ _.includes( this.methods, 'DELETE' )
1151
  ) {
1152
  this.requireForceForDelete = true;
1153
  }
1162
 
1163
  // Function that returns a constructed url based on the id.
1164
  url: function() {
1165
+ var url = routeModel.get( 'apiRoot' ) +
1166
+ routeModel.get( 'versionString' ) +
1167
+ ( ( 'me' === routeName ) ? 'users/me' : routeName );
1168
+
1169
  if ( ! _.isUndefined( this.get( 'id' ) ) ) {
1170
  url += '/' + this.get( 'id' );
1171
  }
1314
  */
1315
 
1316
  // The wp.api.init function returns a promise that will resolve with the endpoint once it is ready.
1317
+ wp.api.loadPromise = wp.api.init();
1318
 
1319
+ } )();
wp-api.min.js CHANGED
@@ -1,2 +1,2 @@
1
- !function(a,b){"use strict";function c(){this.models={},this.collections={},this.views={}}a.wp=a.wp||{},wp.api=wp.api||new c,wp.api.versionString=wp.api.versionString||"wp/v2/"}(window),function(a,b){"use strict";var c,d;a.wp=a.wp||{},wp.api=wp.api||{},wp.api.utils=wp.api.utils||{},Date.prototype.toISOString||(c=function(a){return d=String(a),1===d.length&&(d="0"+d),d},Date.prototype.toISOString=function(){return this.getUTCFullYear()+"-"+c(this.getUTCMonth()+1)+"-"+c(this.getUTCDate())+"T"+c(this.getUTCHours())+":"+c(this.getUTCMinutes())+":"+c(this.getUTCSeconds())+"."+String((this.getUTCMilliseconds()/1e3).toFixed(3)).slice(2,5)+"Z"}),wp.api.utils.parseISO8601=function(a){var c,d,e,f,g=0,h=[1,4,5,6,7,10,11];if(d=/^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/.exec(a)){for(e=0;f=h[e];++e)d[f]=+d[f]||0;d[2]=(+d[2]||1)-1,d[3]=+d[3]||1,"Z"!==d[8]&&b!==d[9]&&(g=60*d[10]+d[11],"+"===d[9]&&(g=0-g)),c=Date.UTC(d[1],d[2],d[3],d[4],d[5]+g,d[6],d[7])}else c=Date.parse?Date.parse(a):NaN;return c},wp.api.utils.getRootUrl=function(){return a.location.origin?a.location.origin+"/":a.location.protocol+"/"+a.location.host+"/"},wp.api.utils.capitalize=function(a){return _.isUndefined(a)?a:a.charAt(0).toUpperCase()+a.slice(1)},wp.api.utils.extractRoutePart=function(a,b){var c;return b=b||1,a=a.replace(wp.api.versionString,""),c=a.split("/").reverse(),_.isUndefined(c[--b])?"":c[b]},wp.api.utils.extractParentName=function(a){var b,c=a.lastIndexOf("_id>[\\d]+)/");return 0>c?"":(b=a.substr(0,c-1),b=b.split("/"),b.pop(),b=b.pop())},wp.api.utils.decorateFromRoute=function(a,b){_.each(a,function(a){_.contains(a.methods,"POST")||_.contains(a.methods,"PUT")?_.isEmpty(a.args)||(_.isEmpty(b.defaults)?b.defaults=a.args:b.defaults=_.union(a.args,b.defaults)):_.contains(a.methods,"GET")&&(_.isEmpty(a.args)||(_.isEmpty(b.options)?b.options=a.args:b.options=_.union(a.args,b.options)))})},wp.api.utils.addMixinsAndHelpers=function(a,b,c){var d=!1,e=["date","modified","date_gmt","modified_gmt"],f={toJSON:function(){var a=_.clone(this.attributes);return _.each(e,function(b){b in a&&(_.isNull(a[b])||(a[b]=a[b].toISOString()))}),a},parse:function(a){var b;return _.each(e,function(c){c in a&&(_.isNull(a[c])||(b=wp.api.utils.parseISO8601(a[c]),a[c]=new Date(b)))}),a}},g=function(a,b,c,d,e){var f,g,h,i;return i=jQuery.Deferred(),g=a.get("_embedded")||{},_.isNumber(b)?(g[d]&&(h=_.findWhere(g[d],{id:b})),h||(h={id:b}),f=new wp.api.models[c](h),f.get(e)?i.resolve(f):f.fetch({success:function(a){i.resolve(a)}}),i.promise()):(i.reject(),i)},h=function(a,b,c,d){var e,f,g,h="",j="",k=jQuery.Deferred();return e=a.get("id"),f=a.get("_embedded")||{},_.isNumber(e)&&0!==e?(_.isUndefined(c)||_.isUndefined(f[c])?h={parent:e}:j=_.isUndefined(d)?f[c]:f[c][d],g=new wp.api.collections[b](j,h),_.isUndefined(g.models[0])?g.fetch({success:function(a){i(a,e),k.resolve(a)}}):(i(g,e),k.resolve(g)),k.promise()):(k.reject(),k)},i=function(a,b){_.each(a.models,function(a){a.set("parent_post",b)})},j={getMeta:function(){return h(this,"PostMeta","https://api.w.org/meta")}},k={getRevisions:function(){return h(this,"PostRevisions")}},l={getTags:function(){return h(this,"PostTags","https://api.w.org/term",1)}},m={getCategories:function(){return h(this,"PostCategories","https://api.w.org/term",0)},setCategories:function(a){var b,c,d=this,e=[];_.isArray(a)?(b=new wp.api.collections.Categories,b.fetch({success:function(b){_.each(a,function(a){c=new wp.api.models.PostCategories(b.findWhere({slug:a})),c.set("parent_post",d.get("id")),e.push(c)}),a=new wp.api.collections.PostCategories(e),d.setCategoriesWithCollection(a)}})):this.setCategoriesWithCollection(a)},setCategoriesWithCollection:function(a){var b,c,d,e;this.getCategories().done(function(f){d=a.pluck("id"),e=f.pluck("id"),c=_.difference(d,e),b=_.difference(e,d),_.each(c,function(b){f.create(a.get(b),{type:"POST"})}),_.each(b,function(a){f.get(a).destroy()})})}},n={getAuthorUser:function(){return g(this,this.get("author"),"User","author","name")}},o={getFeaturedImage:function(){return g(this,this.get("featured_image"),"Media","https://api.w.org/featuredmedia","source_url")}};return _.isUndefined(a.defaults)?a:(_.each(e,function(b){_.isUndefined(a.defaults[b])||(d=!0)}),d&&(a=a.extend(f)),_.isUndefined(a.defaults.author)||(a=a.extend(n)),_.isUndefined(a.defaults.featured_image)||(a=a.extend(o)),_.isUndefined(c.collections[b+"Categories"])||(a=a.extend(m)),_.isUndefined(c.collections[b+"Meta"])||(a=a.extend(j)),_.isUndefined(c.collections[b+"Tags"])||(a=a.extend(l)),_.isUndefined(c.collections[b+"Revisions"])||(a=a.extend(k)),a)}}(window),function(a,b,c,d,e){"use strict";a.api.WPApiBaseModel=c.Model.extend({sync:function(a,d,e){var f;return e=e||{},_.isUndefined(b.nonce)||_.isNull(b.nonce)||(f=e.beforeSend,e.beforeSend=function(a){return a.setRequestHeader("X-WP-Nonce",b.nonce),f?f.apply(this,arguments):void 0}),this.requireForceForDelete&&"delete"===a&&(d.url=d.url()+"?force=true"),c.sync(a,d,e)},save:function(a,b){return _.contains(this.methods,"PUT")||_.contains(this.methods,"POST")?c.Model.prototype.save.call(this,a,b):!1},destroy:function(a){return _.contains(this.methods,"DELETE")?c.Model.prototype.destroy.call(this,a):!1}}),a.api.models.Schema=a.api.WPApiBaseModel.extend({defaults:{_links:{},namespace:null,routes:{}},initialize:function(c,d){var e=this;d=d||{},a.api.WPApiBaseModel.prototype.initialize.call(e,c,d),e.apiRoot=d.apiRoot||b.root,e.versionString=d.versionString||b.versionString},url:function(){return this.apiRoot+this.versionString}})}(wp,wpApiSettings,Backbone,window),function(a,b,c,d,e,f){"use strict";a.api.WPApiBaseCollection=c.Collection.extend({initialize:function(a,b){this.state={data:{},currentPage:null,totalPages:null,totalObjects:null},d.isUndefined(b)?this.parent="":this.parent=b.parent},sync:function(a,e,f){var g,h,i=this;return f=f||{},g=f.beforeSend,"undefined"!=typeof b.nonce&&(f.beforeSend=function(a){return a.setRequestHeader("X-WP-Nonce",b.nonce),g?g.apply(i,arguments):void 0}),"read"===a&&(f.data?(i.state.data=d.clone(f.data),delete i.state.data.page):i.state.data=f.data={},"undefined"==typeof f.data.page?(i.state.currentPage=null,i.state.totalPages=null,i.state.totalObjects=null):i.state.currentPage=f.data.page-1,h=f.success,f.success=function(a,b,c){return i.state.totalPages=parseInt(c.getResponseHeader("x-wp-totalpages"),10),i.state.totalObjects=parseInt(c.getResponseHeader("x-wp-total"),10),null===i.state.currentPage?i.state.currentPage=1:i.state.currentPage++,h?h.apply(this,arguments):void 0}),c.sync(a,e,f)},more:function(a){if(a=a||{},a.data=a.data||{},d.extend(a.data,this.state.data),"undefined"==typeof a.data.page){if(!this.hasMore())return!1;null===this.state.currentPage||this.state.currentPage<=1?a.data.page=2:a.data.page=this.state.currentPage+1}return this.fetch(a)},hasMore:function(){return null===this.state.totalPages||null===this.state.totalObjects||null===this.state.currentPage?null:this.state.currentPage<this.state.totalPages}})}(wp,wpApiSettings,Backbone,_,window),function(a,b){"use strict";var c,d={};a.wp=a.wp||{},wp.api=wp.api||{},c=Backbone.Model.extend({defaults:{apiRoot:wpApiSettings.root,versionString:wp.api.versionString,schema:null,models:{},collections:{}},initialize:function(){var a,b=this;Backbone.Model.prototype.initialize.apply(b,arguments),a=jQuery.Deferred(),b.schemaConstructed=a.promise(),b.schemaModel=new wp.api.models.Schema(null,{apiRoot:b.get("apiRoot"),versionString:b.get("versionString")}),b.schemaModel.once("change",function(){b.constructFromSchema(),a.resolve(b)}),b.get("schema")?b.schemaModel.set(b.schemaModel.parse(b.get("schema"))):!_.isUndefined(sessionStorage)&&sessionStorage.getItem("wp-api-schema-model"+b.get("apiRoot")+b.get("versionString"))?b.schemaModel.set(b.schemaModel.parse(JSON.parse(sessionStorage.getItem("wp-api-schema-model"+b.get("apiRoot")+b.get("versionString"))))):b.schemaModel.fetch({success:function(a){_.isUndefined(sessionStorage)||sessionStorage.setItem("wp-api-schema-model"+b.get("apiRoot")+b.get("versionString"),JSON.stringify(a))},error:function(){}})},constructFromSchema:function(){var a,b,c,d,e=this,f=wpApiSettings.mapping||{models:{Categories:"Category",Comments:"Comment",Pages:"Page",PagesMeta:"PageMeta",PagesRevisions:"PageRevision",Posts:"Post",PostsCategories:"PostCategory",PostsRevisions:"PostRevision",PostsTags:"PostTag",Schema:"Schema",Statuses:"Status",Tags:"Tag",Taxonomies:"Taxonomy",Types:"Type",Users:"User"},collections:{PagesMeta:"PageMeta",PagesRevisions:"PageRevisions",PostsCategories:"PostCategories",PostsMeta:"PostMeta",PostsRevisions:"PostRevisions",PostsTags:"PostTags"}};a=[],b=[],c=e.get("apiRoot").replace(wp.api.utils.getRootUrl(),""),d={},d.models=e.get("models"),d.collections=e.get("collections"),_.each(e.schemaModel.get("routes"),function(d,f){f!==e.get(" versionString")&&f!==c&&f!=="/"+e.get("versionString").slice(0,-1)&&(f.endsWith("+)")?a.push({index:f,route:d}):f.endsWith("me")||b.push({index:f,route:d}))}),_.each(a,function(a){var b,c=wp.api.utils.extractRoutePart(a.index,2),g=wp.api.utils.extractRoutePart(a.index,4);""!==g&&g!==c?(b=wp.api.utils.capitalize(g)+wp.api.utils.capitalize(c),b=f.models[b]||b,d.models[b]=wp.api.WPApiBaseModel.extend({url:function(){var a=e.get("apiRoot")+e.get("versionString")+g+"/"+(_.isUndefined(this.get("parent"))||0===this.get("parent")?this.get("parent_post"):this.get("parent"))+"/"+c;return _.isUndefined(this.get("id"))||(a+="/"+this.get("id")),a},route:a,name:b,methods:a.route.methods,initialize:function(){"Posts"!==this.name&&"Pages"!==this.name&&_.contains(this.methods,"DELETE")&&(this.requireForceForDelete=!0)}})):(b=wp.api.utils.capitalize(c),b=f.models[b]||b,d.models[b]=wp.api.WPApiBaseModel.extend({url:function(){var a=e.get("apiRoot")+e.get("versionString")+c;return _.isUndefined(this.get("id"))||(a+="/"+this.get("id")),a},route:a,name:b,methods:a.route.methods})),wp.api.utils.decorateFromRoute(a.route.endpoints,d.models[b])}),_.each(b,function(a){var b,c,g=a.index.slice(a.index.lastIndexOf("/")+1),h=wp.api.utils.extractRoutePart(a.index,3);""!==h&&h!==g?(b=wp.api.utils.capitalize(h)+wp.api.utils.capitalize(g),c=f.models[b]||b,b=f.collections[b]||b,d.collections[b]=wp.api.WPApiBaseCollection.extend({url:function(){return e.get("apiRoot")+e.get("versionString")+h+"/"+this.parent+"/"+g},model:d.models[c],name:b,route:a,methods:a.route.methods})):(b=wp.api.utils.capitalize(g),c=f.models[b]||b,b=f.collections[b]||b,d.collections[b]=wp.api.WPApiBaseCollection.extend({url:e.get("apiRoot")+e.get("versionString")+g,model:d.models[c],name:b,route:a,methods:a.route.methods})),wp.api.utils.decorateFromRoute(a.route.endpoints,d.collections[b])}),_.each(d.models,function(a,b){d.models[b]=wp.api.utils.addMixinsAndHelpers(a,b,d)})}}),wp.api.endpoints=new Backbone.Collection({model:c}),wp.api.init=function(a){var b,e,f,g={};return a=a||{},g.apiRoot=a.apiRoot||wpApiSettings.root,g.versionString=a.versionString||wpApiSettings.versionString,g.schema=a.schema||null,g.schema||g.apiRoot!==wpApiSettings.root||g.versionString!==wpApiSettings.versionString||(g.schema=wpApiSettings.schema),d[g.apiRoot+g.versionString]||(b=wp.api.endpoints.findWhere({apiRoot:g.apiRoot,versionString:g.versionString}),b||(b=new c(g),wp.api.endpoints.add(b)),e=jQuery.Deferred(),f=e.promise(),b.schemaConstructed.done(function(a){wp.api.models=_.extend(a.get("models"),wp.api.models),wp.api.collections=_.extend(a.get("collections"),wp.api.collections),e.resolveWith(wp.api,[a])}),d[g.apiRoot+g.versionString]=f),d[g.apiRoot+g.versionString]},wp.api.init()}(window);
2
  //# sourceMappingURL=wp-api.min.map
1
+ !function(a,b){"use strict";function c(){this.models={},this.collections={},this.views={}}a.wp=a.wp||{},wp.api=wp.api||new c,wp.api.versionString=wp.api.versionString||"wp/v2/",!_.isFunction(_.includes)&&_.isFunction(_.contains)&&(_.includes=_.contains)}(window),function(a,b){"use strict";var c,d;a.wp=a.wp||{},wp.api=wp.api||{},wp.api.utils=wp.api.utils||{},Date.prototype.toISOString||(c=function(a){return d=String(a),1===d.length&&(d="0"+d),d},Date.prototype.toISOString=function(){return this.getUTCFullYear()+"-"+c(this.getUTCMonth()+1)+"-"+c(this.getUTCDate())+"T"+c(this.getUTCHours())+":"+c(this.getUTCMinutes())+":"+c(this.getUTCSeconds())+"."+String((this.getUTCMilliseconds()/1e3).toFixed(3)).slice(2,5)+"Z"}),wp.api.utils.parseISO8601=function(a){var c,d,e,f,g=0,h=[1,4,5,6,7,10,11];if(d=/^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/.exec(a)){for(e=0;f=h[e];++e)d[f]=+d[f]||0;d[2]=(+d[2]||1)-1,d[3]=+d[3]||1,"Z"!==d[8]&&b!==d[9]&&(g=60*d[10]+d[11],"+"===d[9]&&(g=0-g)),c=Date.UTC(d[1],d[2],d[3],d[4],d[5]+g,d[6],d[7])}else c=Date.parse?Date.parse(a):NaN;return c},wp.api.utils.getRootUrl=function(){return a.location.origin?a.location.origin+"/":a.location.protocol+"/"+a.location.host+"/"},wp.api.utils.capitalize=function(a){return _.isUndefined(a)?a:a.charAt(0).toUpperCase()+a.slice(1)},wp.api.utils.extractRoutePart=function(a,b){var c;return b=b||1,a=a.replace(wp.api.versionString,""),c=a.split("/").reverse(),_.isUndefined(c[--b])?"":c[b]},wp.api.utils.extractParentName=function(a){var b,c=a.lastIndexOf("_id>[\\d]+)/");return 0>c?"":(b=a.substr(0,c-1),b=b.split("/"),b.pop(),b=b.pop())},wp.api.utils.decorateFromRoute=function(a,b){_.each(a,function(a){_.includes(a.methods,"POST")||_.includes(a.methods,"PUT")?_.isEmpty(a.args)||(_.isEmpty(b.prototype.args)?b.prototype.args=a.args:b.prototype.args=_.union(a.args,b.prototype.defaults)):_.includes(a.methods,"GET")&&(_.isEmpty(a.args)||(_.isEmpty(b.prototype.options)?b.prototype.options=a.args:b.prototype.options=_.union(a.args,b.prototype.options)))})},wp.api.utils.addMixinsAndHelpers=function(a,b,c){var d=!1,e=["date","modified","date_gmt","modified_gmt"],f={toJSON:function(){var a=_.clone(this.attributes);return _.each(e,function(b){b in a&&(_.isNull(a[b])||(a[b]=a[b].toISOString()))}),a},parse:function(a){var b;return _.each(e,function(c){c in a&&(_.isNull(a[c])||(b=wp.api.utils.parseISO8601(a[c]),a[c]=new Date(b)))}),a}},g=function(a,b,c,d,e){var f,g,h,i;return i=jQuery.Deferred(),g=a.get("_embedded")||{},_.isNumber(b)?(g[d]&&(h=_.findWhere(g[d],{id:b})),h||(h={id:b}),f=new wp.api.models[c](h),f.get(e)?i.resolve(f):f.fetch({success:function(a){i.resolve(a)}}),i.promise()):(i.reject(),i)},h=function(a,b,c,d){var e,f,g,h="",j="",k=jQuery.Deferred();return e=a.get("id"),f=a.get("_embedded")||{},_.isNumber(e)&&0!==e?(_.isUndefined(c)||_.isUndefined(f[c])?h={parent:e}:j=_.isUndefined(d)?f[c]:f[c][d],g=new wp.api.collections[b](j,h),_.isUndefined(g.models[0])?g.fetch({success:function(a){i(a,e),k.resolve(a)}}):(i(g,e),k.resolve(g)),k.promise()):(k.reject(),k)},i=function(a,b){_.each(a.models,function(a){a.set("parent_post",b)})},j={getMeta:function(){return h(this,"PostMeta","https://api.w.org/meta")}},k={getRevisions:function(){return h(this,"PostRevisions")}},l={getTags:function(){var a=this.get("tags"),b=new wp.api.collections.Tags;return _.isEmpty(a)?jQuery.Deferred().resolve([]):b.fetch({data:{include:a}})},setTags:function(a){var b,c,d=this,e=[];return _.isString(a)?!1:void(_.isArray(a)?(b=new wp.api.collections.Tags,b.fetch({data:{per_page:100},success:function(b){_.each(a,function(a){c=new wp.api.models.Tag(b.findWhere({slug:a})),c.set("parent_post",d.get("id")),e.push(c)}),a=new wp.api.collections.Tags(e),d.setTagsWithCollection(a)}})):this.setTagsWithCollection(a))},setTagsWithCollection:function(a){return this.set("tags",a.pluck("id")),this.save()}},m={getCategories:function(){var a=this.get("categories"),b=new wp.api.collections.Categories;return _.isEmpty(a)?jQuery.Deferred().resolve([]):b.fetch({data:{include:a}})},setCategories:function(a){var b,c,d=this,e=[];return _.isString(a)?!1:void(_.isArray(a)?(b=new wp.api.collections.Categories,b.fetch({data:{per_page:100},success:function(b){_.each(a,function(a){c=new wp.api.models.Category(b.findWhere({slug:a})),c.set("parent_post",d.get("id")),e.push(c)}),a=new wp.api.collections.Categories(e),d.setCategoriesWithCollection(a)}})):this.setCategoriesWithCollection(a))},setCategoriesWithCollection:function(a){return this.set("categories",a.pluck("id")),this.save()}},n={getAuthorUser:function(){return g(this,this.get("author"),"User","author","name")}},o={getFeaturedImage:function(){return g(this,this.get("featured_image"),"Media","https://api.w.org/featuredmedia","source_url")}};return _.isUndefined(a.prototype.args)?a:(_.each(e,function(b){_.isUndefined(a.prototype.args[b])||(d=!0)}),d&&(a=a.extend(f)),_.isUndefined(a.prototype.args.author)||(a=a.extend(n)),_.isUndefined(a.prototype.args.featured_image)||(a=a.extend(o)),_.isUndefined(a.prototype.args.categories)||(a=a.extend(m)),_.isUndefined(c.collections[b+"Meta"])||(a=a.extend(j)),_.isUndefined(a.prototype.args.tags)||(a=a.extend(l)),_.isUndefined(c.collections[b+"Revisions"])||(a=a.extend(k)),a)}}(window),function(){"use strict";var a=window.wpApiSettings||{};wp.api.WPApiBaseModel=Backbone.Model.extend({sync:function(b,c,d){var e;return d=d||{},_.isNull(c.get("date_gmt"))&&c.unset("date_gmt"),_.isEmpty(c.get("slug"))&&c.unset("slug"),_.isUndefined(a.nonce)||_.isNull(a.nonce)||(e=d.beforeSend,d.beforeSend=function(b){return b.setRequestHeader("X-WP-Nonce",a.nonce),e?e.apply(this,arguments):void 0}),this.requireForceForDelete&&"delete"===b&&(c.url=c.url()+"?force=true"),Backbone.sync(b,c,d)},save:function(a,b){return _.includes(this.methods,"PUT")||_.includes(this.methods,"POST")?Backbone.Model.prototype.save.call(this,a,b):!1},destroy:function(a){return _.includes(this.methods,"DELETE")?Backbone.Model.prototype.destroy.call(this,a):!1}}),wp.api.models.Schema=wp.api.WPApiBaseModel.extend({defaults:{_links:{},namespace:null,routes:{}},initialize:function(b,c){var d=this;c=c||{},wp.api.WPApiBaseModel.prototype.initialize.call(d,b,c),d.apiRoot=c.apiRoot||a.root,d.versionString=c.versionString||a.versionString},url:function(){return this.apiRoot+this.versionString}})}(),function(){"use strict";var a=window.wpApiSettings||{};wp.api.WPApiBaseCollection=Backbone.Collection.extend({initialize:function(a,b){this.state={data:{},currentPage:null,totalPages:null,totalObjects:null},_.isUndefined(b)?this.parent="":this.parent=b.parent},sync:function(b,c,d){var e,f,g=this;return d=d||{},e=d.beforeSend,"undefined"!=typeof a.nonce&&(d.beforeSend=function(b){return b.setRequestHeader("X-WP-Nonce",a.nonce),e?e.apply(g,arguments):void 0}),"read"===b&&(d.data?(g.state.data=_.clone(d.data),delete g.state.data.page):g.state.data=d.data={},"undefined"==typeof d.data.page?(g.state.currentPage=null,g.state.totalPages=null,g.state.totalObjects=null):g.state.currentPage=d.data.page-1,f=d.success,d.success=function(a,b,c){return _.isUndefined(c)||(g.state.totalPages=parseInt(c.getResponseHeader("x-wp-totalpages"),10),g.state.totalObjects=parseInt(c.getResponseHeader("x-wp-total"),10)),null===g.state.currentPage?g.state.currentPage=1:g.state.currentPage++,f?f.apply(this,arguments):void 0}),Backbone.sync(b,c,d)},more:function(a){if(a=a||{},a.data=a.data||{},_.extend(a.data,this.state.data),"undefined"==typeof a.data.page){if(!this.hasMore())return!1;null===this.state.currentPage||this.state.currentPage<=1?a.data.page=2:a.data.page=this.state.currentPage+1}return this.fetch(a)},hasMore:function(){return null===this.state.totalPages||null===this.state.totalObjects||null===this.state.currentPage?null:this.state.currentPage<this.state.totalPages}})}(),function(){"use strict";var a,b={},c=window.wpApiSettings||{};window.wp=window.wp||{},wp.api=wp.api||{},_.isEmpty(c)&&(c.root=window.location.origin+"/wp-json/"),a=Backbone.Model.extend({defaults:{apiRoot:c.root,versionString:wp.api.versionString,schema:null,models:{},collections:{}},initialize:function(){var a,b=this;Backbone.Model.prototype.initialize.apply(b,arguments),a=jQuery.Deferred(),b.schemaConstructed=a.promise(),b.schemaModel=new wp.api.models.Schema(null,{apiRoot:b.get("apiRoot"),versionString:b.get("versionString")}),b.schemaModel.once("change",function(){b.constructFromSchema(),a.resolve(b)}),b.get("schema")?b.schemaModel.set(b.schemaModel.parse(b.get("schema"))):!_.isUndefined(sessionStorage)&&sessionStorage.getItem("wp-api-schema-model"+b.get("apiRoot")+b.get("versionString"))?b.schemaModel.set(b.schemaModel.parse(JSON.parse(sessionStorage.getItem("wp-api-schema-model"+b.get("apiRoot")+b.get("versionString"))))):b.schemaModel.fetch({success:function(a){_.isUndefined(sessionStorage)||sessionStorage.setItem("wp-api-schema-model"+b.get("apiRoot")+b.get("versionString"),JSON.stringify(a))},error:function(){}})},constructFromSchema:function(){var a,b,d,e,f=this,g=c.mapping||{models:{Categories:"Category",Comments:"Comment",Pages:"Page",PagesMeta:"PageMeta",PagesRevisions:"PageRevision",Posts:"Post",PostsCategories:"PostCategory",PostsRevisions:"PostRevision",PostsTags:"PostTag",Schema:"Schema",Statuses:"Status",Tags:"Tag",Taxonomies:"Taxonomy",Types:"Type",Users:"User"},collections:{PagesMeta:"PageMeta",PagesRevisions:"PageRevisions",PostsCategories:"PostCategories",PostsMeta:"PostMeta",PostsRevisions:"PostRevisions",PostsTags:"PostTags"}};a=[],b=[],d=f.get("apiRoot").replace(wp.api.utils.getRootUrl(),""),e={},e.models=f.get("models"),e.collections=f.get("collections"),_.each(f.schemaModel.get("routes"),function(c,e){e!==f.get(" versionString")&&e!==d&&e!=="/"+f.get("versionString").slice(0,-1)&&(/.*[+)|me]$/.test(e)?a.push({index:e,route:c}):b.push({index:e,route:c}))}),_.each(a,function(a){var b,c=wp.api.utils.extractRoutePart(a.index,2),d=wp.api.utils.extractRoutePart(a.index,4),h=wp.api.utils.extractRoutePart(a.index,1);"me"===h&&(c="me"),""!==d&&d!==c?(b=wp.api.utils.capitalize(d)+wp.api.utils.capitalize(c),b=g.models[b]||b,e.models[b]=wp.api.WPApiBaseModel.extend({url:function(){var a=f.get("apiRoot")+f.get("versionString")+d+"/"+(_.isUndefined(this.get("parent"))||0===this.get("parent")?this.get("parent_post"):this.get("parent"))+"/"+c;return _.isUndefined(this.get("id"))||(a+="/"+this.get("id")),a},route:a,name:b,methods:a.route.methods,initialize:function(){"Posts"!==this.name&&"Pages"!==this.name&&_.includes(this.methods,"DELETE")&&(this.requireForceForDelete=!0)}})):(b=wp.api.utils.capitalize(c),b=g.models[b]||b,e.models[b]=wp.api.WPApiBaseModel.extend({url:function(){var a=f.get("apiRoot")+f.get("versionString")+("me"===c?"users/me":c);return _.isUndefined(this.get("id"))||(a+="/"+this.get("id")),a},route:a,name:b,methods:a.route.methods})),wp.api.utils.decorateFromRoute(a.route.endpoints,e.models[b])}),_.each(b,function(a){var b,c,d=a.index.slice(a.index.lastIndexOf("/")+1),h=wp.api.utils.extractRoutePart(a.index,3);""!==h&&h!==d?(b=wp.api.utils.capitalize(h)+wp.api.utils.capitalize(d),c=g.models[b]||b,b=g.collections[b]||b,e.collections[b]=wp.api.WPApiBaseCollection.extend({url:function(){return f.get("apiRoot")+f.get("versionString")+h+"/"+this.parent+"/"+d},model:e.models[c],name:b,route:a,methods:a.route.methods})):(b=wp.api.utils.capitalize(d),c=g.models[b]||b,b=g.collections[b]||b,e.collections[b]=wp.api.WPApiBaseCollection.extend({url:f.get("apiRoot")+f.get("versionString")+d,model:e.models[c],name:b,route:a,methods:a.route.methods})),wp.api.utils.decorateFromRoute(a.route.endpoints,e.collections[b])}),_.each(e.models,function(a,b){e.models[b]=wp.api.utils.addMixinsAndHelpers(a,b,e)})}}),wp.api.endpoints=new Backbone.Collection({model:a}),wp.api.init=function(d){var e,f,g,h={};return d=d||{},h.apiRoot=d.apiRoot||c.root,h.versionString=d.versionString||c.versionString,h.schema=d.schema||null,h.schema||h.apiRoot!==c.root||h.versionString!==c.versionString||(h.schema=c.schema),b[h.apiRoot+h.versionString]||(e=wp.api.endpoints.findWhere({apiRoot:h.apiRoot,versionString:h.versionString}),e||(e=new a(h),wp.api.endpoints.add(e)),f=jQuery.Deferred(),g=f.promise(),e.schemaConstructed.done(function(a){wp.api.models=_.extend(a.get("models"),wp.api.models),wp.api.collections=_.extend(a.get("collections"),wp.api.collections),f.resolveWith(wp.api,[a])}),b[h.apiRoot+h.versionString]=g),b[h.apiRoot+h.versionString]},wp.api.loadPromise=wp.api.init()}();
2
  //# sourceMappingURL=wp-api.min.map
wp-api.min.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../js/app.js","../../js/utils.js","../../js/models.js","../../js/collections.js","../../js/load.js"],"names":["window","undefined","WP_API","this","models","collections","views","wp","api","versionString","pad","r","utils","Date","prototype","toISOString","number","String","length","getUTCFullYear","getUTCMonth","getUTCDate","getUTCHours","getUTCMinutes","getUTCSeconds","getUTCMilliseconds","toFixed","slice","parseISO8601","date","timestamp","struct","i","k","minutesOffset","numericKeys","exec","UTC","parse","NaN","getRootUrl","location","origin","protocol","host","capitalize","str","_","isUndefined","charAt","toUpperCase","extractRoutePart","route","part","routeParts","replace","split","reverse","extractParentName","name","lastSlash","lastIndexOf","substr","pop","decorateFromRoute","routeEndpoints","modelInstance","each","routeEndpoint","contains","methods","isEmpty","args","defaults","union","options","addMixinsAndHelpers","model","modelClassName","loadingObjects","hasDate","parseableDates","TimeStampedMixin","toJSON","attributes","clone","key","isNull","response","buildModelGetter","parentModel","modelId","modelName","embedSourcePoint","embedCheckField","getModel","embeddeds","deferred","jQuery","Deferred","get","isNumber","findWhere","id","resolve","fetch","success","promise","reject","buildCollectionGetter","collectionName","embedIndex","postId","getObjects","classProperties","properties","parent","setHelperParentPost","collection","set","MetaMixin","getMeta","RevisionsMixin","getRevisions","TagsMixin","getTags","CategoriesMixin","getCategories","setCategories","categories","allCategories","newCategory","self","newCategories","isArray","Categories","allcats","category","PostCategories","slug","push","setCategoriesWithCollection","removedCategories","addedCategories","categoriesIds","existingCategoriesIds","done","existingCategories","pluck","difference","addedCategory","create","type","removedCategory","destroy","AuthorMixin","getAuthorUser","FeaturedImageMixin","getFeaturedImage","theDateKey","extend","author","featured_image","wpApiSettings","Backbone","WPApiBaseModel","Model","sync","method","beforeSend","nonce","xhr","setRequestHeader","apply","arguments","requireForceForDelete","url","save","attrs","call","Schema","_links","namespace","routes","initialize","apiRoot","root","WPApiBaseCollection","Collection","state","data","currentPage","totalPages","totalObjects","page","textStatus","request","parseInt","getResponseHeader","more","hasMore","Endpoint","initializedDeferreds","schema","schemaConstructed","schemaModel","once","constructFromSchema","sessionStorage","getItem","JSON","newSchemaModel","setItem","stringify","error","modelRoutes","collectionRoutes","schemaRoot","routeModel","mapping","Comments","Pages","PagesMeta","PagesRevisions","Posts","PostsCategories","PostsRevisions","PostsTags","Statuses","Tags","Taxonomies","Types","Users","PostsMeta","index","endsWith","modelRoute","routeName","parentName","endpoints","collectionRoute","collectionClassName","init","endpoint","add","resolveWith"],"mappings":"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","file":"wp-api.min.js"}
1
+ {"version":3,"sources":["../../js/app.js","../../js/utils.js","../../js/models.js","../../js/collections.js","../../js/load.js"],"names":["window","undefined","WP_API","this","models","collections","views","wp","api","versionString","_","isFunction","includes","contains","pad","r","utils","Date","prototype","toISOString","number","String","length","getUTCFullYear","getUTCMonth","getUTCDate","getUTCHours","getUTCMinutes","getUTCSeconds","getUTCMilliseconds","toFixed","slice","parseISO8601","date","timestamp","struct","i","k","minutesOffset","numericKeys","exec","UTC","parse","NaN","getRootUrl","location","origin","protocol","host","capitalize","str","isUndefined","charAt","toUpperCase","extractRoutePart","route","part","routeParts","replace","split","reverse","extractParentName","name","lastSlash","lastIndexOf","substr","pop","decorateFromRoute","routeEndpoints","modelInstance","each","routeEndpoint","methods","isEmpty","args","union","defaults","options","addMixinsAndHelpers","model","modelClassName","loadingObjects","hasDate","parseableDates","TimeStampedMixin","toJSON","attributes","clone","key","isNull","response","buildModelGetter","parentModel","modelId","modelName","embedSourcePoint","embedCheckField","getModel","embeddeds","deferred","jQuery","Deferred","get","isNumber","findWhere","id","resolve","fetch","success","promise","reject","buildCollectionGetter","collectionName","embedIndex","postId","getObjects","classProperties","properties","parent","setHelperParentPost","collection","set","MetaMixin","getMeta","RevisionsMixin","getRevisions","TagsMixin","getTags","tagIds","tags","Tags","data","include","setTags","allTags","newTag","self","newTags","isString","isArray","per_page","alltags","tag","Tag","slug","push","setTagsWithCollection","pluck","save","CategoriesMixin","getCategories","categoryIds","categories","Categories","setCategories","allCategories","newCategory","newCategories","allcats","category","Category","setCategoriesWithCollection","AuthorMixin","getAuthorUser","FeaturedImageMixin","getFeaturedImage","theDateKey","extend","author","featured_image","wpApiSettings","WPApiBaseModel","Backbone","Model","sync","method","beforeSend","unset","nonce","xhr","setRequestHeader","apply","arguments","requireForceForDelete","url","attrs","call","destroy","Schema","_links","namespace","routes","initialize","apiRoot","root","WPApiBaseCollection","Collection","state","currentPage","totalPages","totalObjects","page","textStatus","request","parseInt","getResponseHeader","more","hasMore","Endpoint","initializedDeferreds","schema","schemaConstructed","schemaModel","once","constructFromSchema","sessionStorage","getItem","JSON","newSchemaModel","setItem","stringify","error","modelRoutes","collectionRoutes","schemaRoot","routeModel","mapping","Comments","Pages","PagesMeta","PagesRevisions","Posts","PostsCategories","PostsRevisions","PostsTags","Statuses","Taxonomies","Types","Users","PostsMeta","index","test","modelRoute","routeName","parentName","routeEnd","endpoints","collectionRoute","collectionClassName","init","endpoint","add","done","resolveWith","loadPromise"],"mappings":"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","file":"wp-api.min.js"}