Version Description
Download this release
Release Info
| Developer | danielbachhuber |
| Plugin | |
| Version | 2.0-beta11 |
| Comparing to | |
| See all releases | |
Code changes from version 2.0-beta10 to 2.0-beta11
- CHANGELOG.md +147 -0
- extras.php +57 -43
- lib/endpoints/class-wp-rest-attachments-controller.php +72 -29
- lib/endpoints/class-wp-rest-comments-controller.php +226 -188
- lib/endpoints/class-wp-rest-controller.php +33 -34
- lib/endpoints/class-wp-rest-meta-controller.php +4 -3
- lib/endpoints/class-wp-rest-post-statuses-controller.php +4 -3
- lib/endpoints/class-wp-rest-post-types-controller.php +5 -4
- lib/endpoints/class-wp-rest-posts-controller.php +280 -236
- lib/endpoints/class-wp-rest-posts-terms-controller.php +0 -319
- lib/endpoints/class-wp-rest-revisions-controller.php +43 -46
- lib/endpoints/class-wp-rest-taxonomies-controller.php +19 -18
- lib/endpoints/class-wp-rest-terms-controller.php +172 -111
- lib/endpoints/class-wp-rest-users-controller.php +131 -123
- plugin.php +87 -76
- readme.txt +148 -1
- wp-api.js +864 -618
- wp-api.min.js +2 -0
- wp-api.min.map +1 -0
CHANGELOG.md
CHANGED
|
@@ -1,5 +1,152 @@
|
|
| 1 |
# Changelog
|
| 2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
## 2.0 Beta 10.0
|
| 4 |
|
| 5 |
- SECURITY: Ensure media of private posts are private too.
|
| 1 |
# Changelog
|
| 2 |
|
| 3 |
+
## 2.0 Beta 11.0
|
| 4 |
+
|
| 5 |
+
- BREAKING CHANGE: Moves Post->Term relations to the Post Resource
|
| 6 |
+
|
| 7 |
+
Previously, a client would fetch a Post's Tags with `GET /wp/v2/posts/<id>/tags`.
|
| 8 |
+
|
| 9 |
+
In Beta 11, an array of term ids is included on the Post resource.
|
| 10 |
+
|
| 11 |
+
The collection of terms for a Post can be fetched with `GET /wp/v2/tags?post=<id>`.
|
| 12 |
+
|
| 13 |
+
The `WP_REST_Posts_Terms_Controller` class no longer exists.
|
| 14 |
+
|
| 15 |
+
(props @joehoyle, [#2063](https://github.com/WP-API/WP-API/pull/2063))
|
| 16 |
+
|
| 17 |
+
- BREAKING CHANGE: Adds latest JS client including a minified version.
|
| 18 |
+
|
| 19 |
+
See pull request for a summarized changelog.
|
| 20 |
+
|
| 21 |
+
(props @adamsilverstein, [#1981](https://github.com/WP-API/WP-API/pull/1981))
|
| 22 |
+
|
| 23 |
+
- BREAKING CHANGE: Changes `featured_image` attribute on Posts to `featured_media`.
|
| 24 |
+
|
| 25 |
+
While featuring other attachment types isn't yet officially supported, this makes it easier for us to introduce the possibility in the future.
|
| 26 |
+
|
| 27 |
+
(props @danielbachhuber, [#2044](https://github.com/WP-API/WP-API/pull/2044))
|
| 28 |
+
|
| 29 |
+
- BREAKING CHANGE: Uses discrete schema title for categories and tags.
|
| 30 |
+
|
| 31 |
+
If you've used `register_rest_field( 'term' )`, you'll need to change `'term'` to `'tag'` and/or `'category'`.
|
| 32 |
+
|
| 33 |
+
(props @danielbachhuber, [#2005](https://github.com/WP-API/WP-API/pull/2005))
|
| 34 |
+
|
| 35 |
+
- BREAKING CHANGE: Makes many filters dynamic based on the controller type.
|
| 36 |
+
|
| 37 |
+
If you were using the `rest_prepare_term` filter, you'll need to change it to `rest_prepare_post_tag` or `rest_prepare_category`.
|
| 38 |
+
|
| 39 |
+
If you were using `rest_post_query` or `rest_terms_query`, you'll need update your use to `rest_page_query`, etc.
|
| 40 |
+
|
| 41 |
+
If you were using `rest_post_trashable`, `rest_insert_post` or `rest_delete_post`, they are now dynamic based on the post type slug.
|
| 42 |
+
|
| 43 |
+
(props @danielbachhuber, [#2008](https://github.com/WP-API/WP-API/pull/2008), [#2010](https://github.com/WP-API/WP-API/pull/2010), [#2057](https://github.com/WP-API/WP-API/pull/2057), [#2058](https://github.com/WP-API/WP-API/pull/2058))
|
| 44 |
+
|
| 45 |
+
- Renames `GET /wp/v2/comments` `user` param to `author` to match resource attribute.
|
| 46 |
+
|
| 47 |
+
Not a breaking change, because it didn't work in the first place.
|
| 48 |
+
|
| 49 |
+
(props @danielbachhuber, [#2105](https://github.com/WP-API/WP-API/pull/2105))
|
| 50 |
+
|
| 51 |
+
- Adds support for `GET /wp/v2/pages parent=1,2,3`.
|
| 52 |
+
|
| 53 |
+
(props @danielbachhuber, [#2101](https://github.com/WP-API/WP-API/pull/2101))
|
| 54 |
+
|
| 55 |
+
- Persists image metadata title and caption when not present in the request.
|
| 56 |
+
|
| 57 |
+
(props @danielbachhuber, [#2079](https://github.com/WP-API/WP-API/pull/2079))
|
| 58 |
+
|
| 59 |
+
- Add `parent_exclude` param to `GET /wp/v2/posts`.
|
| 60 |
+
|
| 61 |
+
(props @danielbachhuber, [#2077](https://github.com/WP-API/WP-API/pull/2077))
|
| 62 |
+
|
| 63 |
+
- Adds `slug` param support for collections of Posts, Users, and Taxonomy Terms.
|
| 64 |
+
|
| 65 |
+
(props @danielbachhuber, [#2071](https://github.com/WP-API/WP-API/pull/2071), [#2072](https://github.com/WP-API/WP-API/pull/2072), [#2103](https://github.com/WP-API/WP-API/pull/2103))
|
| 66 |
+
|
| 67 |
+
- When a comment is already trashed, returns `410:rest_already_trashed`.
|
| 68 |
+
|
| 69 |
+
(props @danielbachhuber, [#2069](https://github.com/WP-API/WP-API/pull/2069))
|
| 70 |
+
|
| 71 |
+
- Filter the responses by context after processing additional fields.
|
| 72 |
+
|
| 73 |
+
(props @danielbachhuber, [#2067](https://github.com/WP-API/WP-API/pull/2067))
|
| 74 |
+
|
| 75 |
+
- Adds `offset` param support for collections of Posts, Users, Comments, and Taxonomy Terms.
|
| 76 |
+
|
| 77 |
+
(props @danielbachhuber, [#2061](https://github.com/WP-API/WP-API/pull/2061), [#2062](https://github.com/WP-API/WP-API/pull/2062), [#2064](https://github.com/WP-API/WP-API/pull/2064), [#2076](https://github.com/WP-API/WP-API/pull/2076))
|
| 78 |
+
|
| 79 |
+
- Adds `rest_insert_{$taxonomy}` and `rest_delete_{$taxonomy}` actions.
|
| 80 |
+
|
| 81 |
+
(props @danielbachhuber, [#2060](https://github.com/WP-API/WP-API/pull/2060))
|
| 82 |
+
|
| 83 |
+
- Provides more helpful error message/code on Post Create/Update fail.
|
| 84 |
+
|
| 85 |
+
(props @danielbachhuber, [#2053](https://github.com/WP-API/WP-API/pull/2053))
|
| 86 |
+
|
| 87 |
+
- Forces `GET /wp/v2/media` to be limited to `'status' => [ inherit, private, trash ]`
|
| 88 |
+
|
| 89 |
+
(props @danielbachhuber, [#2026](https://github.com/WP-API/WP-API/pull/2026))
|
| 90 |
+
|
| 91 |
+
- Uses more correct error code for `Comment::delete` permission check.
|
| 92 |
+
|
| 93 |
+
(props @danielbachhuber, [#2054](https://github.com/WP-API/WP-API/pull/2054))
|
| 94 |
+
|
| 95 |
+
- Calls `prepare_item_for_response()` directly in create and update methods.
|
| 96 |
+
|
| 97 |
+
This lets us pass the original request through, giving the method and its filter genuine context, and avoids an
|
| 98 |
+
unnecessary call to `get_item()`.
|
| 99 |
+
|
| 100 |
+
(props @danielbachhuber, [#2038](https://github.com/WP-API/WP-API/pull/2038), [#2040](https://github.com/WP-API/WP-API/pull/2040), [#2041](https://github.com/WP-API/WP-API/pull/2041), [#2043](https://github.com/WP-API/WP-API/pull/2043), [#2042](https://github.com/WP-API/WP-API/pull/2042))
|
| 101 |
+
|
| 102 |
+
- Moves permission check methods across controllers.
|
| 103 |
+
|
| 104 |
+
Placing them above the method they're supposed to check makes the code more readable.
|
| 105 |
+
|
| 106 |
+
(props @danielbachhuber, [#2030](https://github.com/WP-API/WP-API/pull/2030), [#2029](https://github.com/WP-API/WP-API/pull/2029), [#2034](https://github.com/WP-API/WP-API/pull/2034), [#2036](https://github.com/WP-API/WP-API/pull/2036), [#2037](https://github.com/WP-API/WP-API/pull/2037), [#2035](https://github.com/WP-API/WP-API/pull/2035), [#2039](https://github.com/WP-API/WP-API/pull/2039))
|
| 107 |
+
|
| 108 |
+
- Requires `force` argument for `DELETE /wp/v2/<taxonomy>/<id>`.
|
| 109 |
+
|
| 110 |
+
(props @danielbachhuber, [#2028](https://github.com/WP-API/WP-API/pull/2028))
|
| 111 |
+
|
| 112 |
+
- Conditionally requires and defines REST API classes and functions.
|
| 113 |
+
|
| 114 |
+
(props @danielbachhuber, [#2023](https://github.com/WP-API/WP-API/pull/2023), [#2024](https://github.com/WP-API/WP-API/pull/2024))
|
| 115 |
+
|
| 116 |
+
- Avoid a duplicate query for the comment count.
|
| 117 |
+
|
| 118 |
+
(props @rmccue, [#2015](https://github.com/WP-API/WP-API/pull/2015))
|
| 119 |
+
|
| 120 |
+
- Parses `$date` if available in `prepare_date_response()`
|
| 121 |
+
|
| 122 |
+
(props @adamsilverstein, [#1951](https://github.com/WP-API/WP-API/pull/1951))
|
| 123 |
+
|
| 124 |
+
- Abstracts `POST /wp/v2/media` permissions check.
|
| 125 |
+
|
| 126 |
+
(props @danielbachhuber, [#2003](https://github.com/WP-API/WP-API/pull/2003))
|
| 127 |
+
|
| 128 |
+
- Adds `exclude` param to getting collections of Posts, Users, Comments, and Taxonomy Terms.
|
| 129 |
+
|
| 130 |
+
(props @danielbachhuber, [#1998](https://github.com/WP-API/WP-API/pull/1998), [#1999](https://github.com/WP-API/WP-API/pull/1999), [#2000](https://github.com/WP-API/WP-API/pull/2000), [#2002](https://github.com/WP-API/WP-API/pull/2002))
|
| 131 |
+
|
| 132 |
+
- Adds `rest_comment_query` for filtering `GET /wp/v2/comments`.
|
| 133 |
+
|
| 134 |
+
(props @danielbachhuber, [#2007](https://github.com/WP-API/WP-API/pull/2007))
|
| 135 |
+
|
| 136 |
+
- Uses HTTP status code `500` for `db_update_error` when creating an attachment.
|
| 137 |
+
|
| 138 |
+
(props @danielbachhuber, [#1993](https://github.com/WP-API/WP-API/pull/1993))
|
| 139 |
+
|
| 140 |
+
- Adds helpful description to `force` param across all `DELETE` registrations
|
| 141 |
+
|
| 142 |
+
(props @danielbachhuber, [#2004](https://github.com/WP-API/WP-API/pull/2004), [#2027](https://github.com/WP-API/WP-API/pull/2027))
|
| 143 |
+
|
| 144 |
+
- In `GET /wp/v2/<taxonomy>`, drops support for `orderby=>term_id`.
|
| 145 |
+
|
| 146 |
+
Only one `id` is exposed through the REST API.
|
| 147 |
+
|
| 148 |
+
(props @danielbachhuber, [#1990](https://github.com/WP-API/WP-API/pull/1990))
|
| 149 |
+
|
| 150 |
## 2.0 Beta 10.0
|
| 151 |
|
| 152 |
- SECURITY: Ensure media of private posts are private too.
|
extras.php
CHANGED
|
@@ -11,61 +11,75 @@
|
|
| 11 |
add_action( 'wp_enqueue_scripts', 'rest_register_scripts', -100 );
|
| 12 |
add_action( 'admin_enqueue_scripts', 'rest_register_scripts', -100 );
|
| 13 |
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
}
|
| 27 |
|
| 28 |
-
|
| 29 |
-
* Retrieves the avatar urls in various sizes based on a given email address.
|
| 30 |
-
*
|
| 31 |
-
* @since 4.4.0
|
| 32 |
-
*
|
| 33 |
-
* @see get_avatar_url()
|
| 34 |
-
*
|
| 35 |
-
* @param string $email Email address.
|
| 36 |
-
* @return array $urls Gravatar url for each size.
|
| 37 |
-
*/
|
| 38 |
-
function rest_get_avatar_urls( $email ) {
|
| 39 |
-
$avatar_sizes = rest_get_avatar_sizes();
|
| 40 |
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
|
|
|
|
|
|
|
|
|
| 44 |
}
|
| 45 |
-
|
| 46 |
-
return $urls;
|
| 47 |
}
|
| 48 |
|
| 49 |
-
|
| 50 |
-
* Retrieves the pixel sizes for avatars.
|
| 51 |
-
*
|
| 52 |
-
* @since 4.4.0
|
| 53 |
-
*
|
| 54 |
-
* @return array List of pixel sizes for avatars. Default `[ 24, 48, 96 ]`.
|
| 55 |
-
*/
|
| 56 |
-
function rest_get_avatar_sizes() {
|
| 57 |
/**
|
| 58 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
| 59 |
*
|
| 60 |
-
*
|
| 61 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
*
|
| 63 |
* @since 4.4.0
|
| 64 |
*
|
| 65 |
-
* @
|
| 66 |
-
* Default `[ 24, 48, 96 ]`.
|
| 67 |
*/
|
| 68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
}
|
| 70 |
|
| 71 |
/**
|
| 11 |
add_action( 'wp_enqueue_scripts', 'rest_register_scripts', -100 );
|
| 12 |
add_action( 'admin_enqueue_scripts', 'rest_register_scripts', -100 );
|
| 13 |
|
| 14 |
+
if ( ! function_exists( 'rest_register_scripts' ) ) {
|
| 15 |
+
/**
|
| 16 |
+
* Registers REST API JavaScript helpers.
|
| 17 |
+
*
|
| 18 |
+
* @since 4.4.0
|
| 19 |
+
*
|
| 20 |
+
* @see wp_register_scripts()
|
| 21 |
+
*/
|
| 22 |
+
function rest_register_scripts() {
|
| 23 |
|
| 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() ),
|
| 31 |
+
'nonce' => wp_create_nonce( 'wp_rest' ),
|
| 32 |
+
'versionString' => 'wp/v2/',
|
| 33 |
+
);
|
| 34 |
+
wp_localize_script( 'wp-api', 'wpApiSettings', $settings );
|
| 35 |
}
|
|
|
|
|
|
|
| 36 |
}
|
| 37 |
|
| 38 |
+
if ( ! function_exists( 'rest_get_avatar_urls' ) ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
/**
|
| 40 |
+
* Retrieves the avatar urls in various sizes based on a given email address.
|
| 41 |
+
*
|
| 42 |
+
* @since 4.4.0
|
| 43 |
+
*
|
| 44 |
+
* @see get_avatar_url()
|
| 45 |
*
|
| 46 |
+
* @param string $email Email address.
|
| 47 |
+
* @return array $urls Gravatar url for each size.
|
| 48 |
+
*/
|
| 49 |
+
function rest_get_avatar_urls( $email ) {
|
| 50 |
+
$avatar_sizes = rest_get_avatar_sizes();
|
| 51 |
+
|
| 52 |
+
$urls = array();
|
| 53 |
+
foreach ( $avatar_sizes as $size ) {
|
| 54 |
+
$urls[ $size ] = get_avatar_url( $email, array( 'size' => $size ) );
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
return $urls;
|
| 58 |
+
}
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
if ( ! function_exists( 'rest_get_avatar_sizes' ) ) {
|
| 62 |
+
/**
|
| 63 |
+
* Retrieves the pixel sizes for avatars.
|
| 64 |
*
|
| 65 |
* @since 4.4.0
|
| 66 |
*
|
| 67 |
+
* @return array List of pixel sizes for avatars. Default `[ 24, 48, 96 ]`.
|
|
|
|
| 68 |
*/
|
| 69 |
+
function rest_get_avatar_sizes() {
|
| 70 |
+
/**
|
| 71 |
+
* Filter the REST avatar sizes.
|
| 72 |
+
*
|
| 73 |
+
* Use this filter to adjust the array of sizes returned by the
|
| 74 |
+
* `rest_get_avatar_sizes` function.
|
| 75 |
+
*
|
| 76 |
+
* @since 4.4.0
|
| 77 |
+
*
|
| 78 |
+
* @param array $sizes An array of int values that are the pixel sizes for avatars.
|
| 79 |
+
* Default `[ 24, 48, 96 ]`.
|
| 80 |
+
*/
|
| 81 |
+
return apply_filters( 'rest_avatar_sizes', array( 24, 48, 96 ) );
|
| 82 |
+
}
|
| 83 |
}
|
| 84 |
|
| 85 |
/**
|
lib/endpoints/class-wp-rest-attachments-controller.php
CHANGED
|
@@ -3,28 +3,58 @@
|
|
| 3 |
class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
|
| 4 |
|
| 5 |
/**
|
| 6 |
-
*
|
|
|
|
| 7 |
*
|
| 8 |
-
* @param
|
| 9 |
-
* @return
|
| 10 |
*/
|
| 11 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
|
| 13 |
-
//
|
| 14 |
$post_type_obj = get_post_type_object( $this->post_type );
|
| 15 |
if ( ! current_user_can( $post_type_obj->cap->create_posts ) || ! current_user_can( $post_type_obj->cap->edit_posts ) ) {
|
| 16 |
-
return new WP_Error( 'rest_cannot_create', __( 'Sorry, you are not allowed to
|
| 17 |
}
|
| 18 |
|
| 19 |
-
//
|
| 20 |
if ( ! empty( $request['post'] ) ) {
|
| 21 |
$parent = get_post( (int) $request['post'] );
|
| 22 |
$post_parent_type = get_post_type_object( $parent->post_type );
|
| 23 |
if ( ! current_user_can( $post_parent_type->cap->edit_post, $request['post'] ) ) {
|
| 24 |
-
return new WP_Error( 'rest_cannot_edit', __( 'Sorry, you are not allowed to
|
| 25 |
}
|
| 26 |
}
|
| 27 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
// Get the file via $_FILES or raw data
|
| 29 |
$files = $request->get_file_params();
|
| 30 |
$headers = $request->get_headers();
|
|
@@ -45,8 +75,6 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
|
|
| 45 |
$url = $file['url'];
|
| 46 |
$type = $file['type'];
|
| 47 |
$file = $file['file'];
|
| 48 |
-
$title = $name;
|
| 49 |
-
$caption = '';
|
| 50 |
|
| 51 |
// use image exif/iptc data for title and caption defaults if possible
|
| 52 |
// @codingStandardsIgnoreStart
|
|
@@ -54,11 +82,11 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
|
|
| 54 |
// @codingStandardsIgnoreEnd
|
| 55 |
if ( ! empty( $image_meta ) ) {
|
| 56 |
if ( empty( $request['title'] ) && trim( $image_meta['title'] ) && ! is_numeric( sanitize_title( $image_meta['title'] ) ) ) {
|
| 57 |
-
$title = $image_meta['title'];
|
| 58 |
}
|
| 59 |
|
| 60 |
if ( empty( $request['caption'] ) && trim( $image_meta['caption'] ) ) {
|
| 61 |
-
$caption = $image_meta['caption'];
|
| 62 |
}
|
| 63 |
}
|
| 64 |
|
|
@@ -68,8 +96,14 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
|
|
| 68 |
$attachment->guid = $url;
|
| 69 |
$id = wp_insert_post( $attachment, true );
|
| 70 |
if ( is_wp_error( $id ) ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
return $id;
|
| 72 |
}
|
|
|
|
| 73 |
|
| 74 |
/** Include admin functions to get access to wp_generate_attachment_metadata() */
|
| 75 |
require_once ABSPATH . 'wp-admin/includes/admin.php';
|
|
@@ -82,10 +116,8 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
|
|
| 82 |
|
| 83 |
$this->update_additional_fields_for_object( $attachment, $request );
|
| 84 |
|
| 85 |
-
$
|
| 86 |
-
$
|
| 87 |
-
$get_request->set_param( 'context', 'edit' );
|
| 88 |
-
$response = $this->get_item( $get_request );
|
| 89 |
$response = rest_ensure_response( $response );
|
| 90 |
$response->set_status( 201 );
|
| 91 |
$response->header( 'Location', rest_url( '/wp/v2/' . $this->get_post_type_base( $attachment->post_type ) . '/' . $id ) );
|
|
@@ -95,7 +127,7 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
|
|
| 95 |
*
|
| 96 |
* @param object $attachment Inserted attachment.
|
| 97 |
* @param WP_REST_Request $request The request sent to the API.
|
| 98 |
-
* @param
|
| 99 |
*/
|
| 100 |
do_action( 'rest_insert_attachment', $attachment, $request, true );
|
| 101 |
|
|
@@ -122,15 +154,15 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
|
|
| 122 |
update_post_meta( $data['id'], '_wp_attachment_image_alt', $request['alt_text'] );
|
| 123 |
}
|
| 124 |
|
| 125 |
-
$
|
| 126 |
-
$
|
| 127 |
-
$
|
| 128 |
-
$response =
|
| 129 |
|
| 130 |
/* This action is documented in lib/endpoints/class-wp-rest-attachments-controller.php */
|
| 131 |
do_action( 'rest_insert_attachment', $data, $request, false );
|
| 132 |
|
| 133 |
-
return
|
| 134 |
}
|
| 135 |
|
| 136 |
/**
|
|
@@ -162,7 +194,7 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
|
|
| 162 |
*
|
| 163 |
* @param WP_Post $post Post object
|
| 164 |
* @param WP_REST_Request $request Request object
|
| 165 |
-
* @return
|
| 166 |
*/
|
| 167 |
public function prepare_item_for_response( $post, $request ) {
|
| 168 |
$response = parent::prepare_item_for_response( $post, $request );
|
|
@@ -389,15 +421,26 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
|
|
| 389 |
*/
|
| 390 |
public function get_collection_params() {
|
| 391 |
$params = parent::get_collection_params();
|
| 392 |
-
$params['
|
| 393 |
-
|
| 394 |
-
'type' => 'integer',
|
| 395 |
-
'default' => null,
|
| 396 |
-
'sanitize_callback' => 'absint',
|
| 397 |
-
);
|
| 398 |
return $params;
|
| 399 |
}
|
| 400 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 401 |
/**
|
| 402 |
* Handle an upload via multipart/form-data ($_FILES)
|
| 403 |
*
|
| 3 |
class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
|
| 4 |
|
| 5 |
/**
|
| 6 |
+
* Determine the allowed query_vars for a get_items() response and
|
| 7 |
+
* prepare for WP_Query.
|
| 8 |
*
|
| 9 |
+
* @param array $prepared_args
|
| 10 |
+
* @return array $query_args
|
| 11 |
*/
|
| 12 |
+
protected function prepare_items_query( $prepared_args = array() ) {
|
| 13 |
+
$query_args = parent::prepare_items_query( $prepared_args );
|
| 14 |
+
if ( empty( $query_args['post_status'] ) || ! in_array( $query_args['post_status'], array( 'inherit', 'private', 'trash' ) ) ) {
|
| 15 |
+
$query_args['post_status'] = 'inherit';
|
| 16 |
+
}
|
| 17 |
+
return $query_args;
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
/**
|
| 21 |
+
* Check if a given request has access to create an attachment.
|
| 22 |
+
*
|
| 23 |
+
* @param WP_REST_Request $request Full details about the request.
|
| 24 |
+
* @return WP_Error|boolean
|
| 25 |
+
*/
|
| 26 |
+
public function create_item_permissions_check( $request ) {
|
| 27 |
+
$ret = parent::create_item_permissions_check( $request );
|
| 28 |
+
if ( ! $ret || is_wp_error( $ret ) ) {
|
| 29 |
+
return $ret;
|
| 30 |
+
}
|
| 31 |
|
| 32 |
+
// "upload_files" cap is returned for an attachment by $post_type_obj->cap->create_posts
|
| 33 |
$post_type_obj = get_post_type_object( $this->post_type );
|
| 34 |
if ( ! current_user_can( $post_type_obj->cap->create_posts ) || ! current_user_can( $post_type_obj->cap->edit_posts ) ) {
|
| 35 |
+
return new WP_Error( 'rest_cannot_create', __( 'Sorry, you are not allowed to upload media on this site.' ), array( 'status' => 400 ) );
|
| 36 |
}
|
| 37 |
|
| 38 |
+
// Attaching media to a post requires ability to edit said post
|
| 39 |
if ( ! empty( $request['post'] ) ) {
|
| 40 |
$parent = get_post( (int) $request['post'] );
|
| 41 |
$post_parent_type = get_post_type_object( $parent->post_type );
|
| 42 |
if ( ! current_user_can( $post_parent_type->cap->edit_post, $request['post'] ) ) {
|
| 43 |
+
return new WP_Error( 'rest_cannot_edit', __( 'Sorry, you are not allowed to upload media to this post.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 44 |
}
|
| 45 |
}
|
| 46 |
|
| 47 |
+
return true;
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
/**
|
| 51 |
+
* Create a single attachment
|
| 52 |
+
*
|
| 53 |
+
* @param WP_REST_Request $request Full details about the request
|
| 54 |
+
* @return WP_Error|WP_REST_Response
|
| 55 |
+
*/
|
| 56 |
+
public function create_item( $request ) {
|
| 57 |
+
|
| 58 |
// Get the file via $_FILES or raw data
|
| 59 |
$files = $request->get_file_params();
|
| 60 |
$headers = $request->get_headers();
|
| 75 |
$url = $file['url'];
|
| 76 |
$type = $file['type'];
|
| 77 |
$file = $file['file'];
|
|
|
|
|
|
|
| 78 |
|
| 79 |
// use image exif/iptc data for title and caption defaults if possible
|
| 80 |
// @codingStandardsIgnoreStart
|
| 82 |
// @codingStandardsIgnoreEnd
|
| 83 |
if ( ! empty( $image_meta ) ) {
|
| 84 |
if ( empty( $request['title'] ) && trim( $image_meta['title'] ) && ! is_numeric( sanitize_title( $image_meta['title'] ) ) ) {
|
| 85 |
+
$request['title'] = $image_meta['title'];
|
| 86 |
}
|
| 87 |
|
| 88 |
if ( empty( $request['caption'] ) && trim( $image_meta['caption'] ) ) {
|
| 89 |
+
$request['caption'] = $image_meta['caption'];
|
| 90 |
}
|
| 91 |
}
|
| 92 |
|
| 96 |
$attachment->guid = $url;
|
| 97 |
$id = wp_insert_post( $attachment, true );
|
| 98 |
if ( is_wp_error( $id ) ) {
|
| 99 |
+
if ( in_array( $id->get_error_code(), array( 'db_update_error' ) ) ) {
|
| 100 |
+
$id->add_data( array( 'status' => 500 ) );
|
| 101 |
+
} else {
|
| 102 |
+
$id->add_data( array( 'status' => 400 ) );
|
| 103 |
+
}
|
| 104 |
return $id;
|
| 105 |
}
|
| 106 |
+
$attachment = get_post( $id );
|
| 107 |
|
| 108 |
/** Include admin functions to get access to wp_generate_attachment_metadata() */
|
| 109 |
require_once ABSPATH . 'wp-admin/includes/admin.php';
|
| 116 |
|
| 117 |
$this->update_additional_fields_for_object( $attachment, $request );
|
| 118 |
|
| 119 |
+
$request->set_param( 'context', 'edit' );
|
| 120 |
+
$response = $this->prepare_item_for_response( $attachment, $request );
|
|
|
|
|
|
|
| 121 |
$response = rest_ensure_response( $response );
|
| 122 |
$response->set_status( 201 );
|
| 123 |
$response->header( 'Location', rest_url( '/wp/v2/' . $this->get_post_type_base( $attachment->post_type ) . '/' . $id ) );
|
| 127 |
*
|
| 128 |
* @param object $attachment Inserted attachment.
|
| 129 |
* @param WP_REST_Request $request The request sent to the API.
|
| 130 |
+
* @param boolean $creating True when creating an attachment, false when updating.
|
| 131 |
*/
|
| 132 |
do_action( 'rest_insert_attachment', $attachment, $request, true );
|
| 133 |
|
| 154 |
update_post_meta( $data['id'], '_wp_attachment_image_alt', $request['alt_text'] );
|
| 155 |
}
|
| 156 |
|
| 157 |
+
$attachment = get_post( $request['id'] );
|
| 158 |
+
$request->set_param( 'context', 'edit' );
|
| 159 |
+
$response = $this->prepare_item_for_response( $attachment, $request );
|
| 160 |
+
$response = rest_ensure_response( $response );
|
| 161 |
|
| 162 |
/* This action is documented in lib/endpoints/class-wp-rest-attachments-controller.php */
|
| 163 |
do_action( 'rest_insert_attachment', $data, $request, false );
|
| 164 |
|
| 165 |
+
return $response;
|
| 166 |
}
|
| 167 |
|
| 168 |
/**
|
| 194 |
*
|
| 195 |
* @param WP_Post $post Post object
|
| 196 |
* @param WP_REST_Request $request Request object
|
| 197 |
+
* @return WP_REST_Response $response
|
| 198 |
*/
|
| 199 |
public function prepare_item_for_response( $post, $request ) {
|
| 200 |
$response = parent::prepare_item_for_response( $post, $request );
|
| 421 |
*/
|
| 422 |
public function get_collection_params() {
|
| 423 |
$params = parent::get_collection_params();
|
| 424 |
+
$params['status']['default'] = 'inherit';
|
| 425 |
+
$params['status']['enum'] = array( 'inherit', 'private', 'trash' );
|
|
|
|
|
|
|
|
|
|
|
|
|
| 426 |
return $params;
|
| 427 |
}
|
| 428 |
|
| 429 |
+
/**
|
| 430 |
+
* Validate whether the user can query private statuses
|
| 431 |
+
*
|
| 432 |
+
* @param mixed $value
|
| 433 |
+
* @param WP_REST_Request $request
|
| 434 |
+
* @param string $parameter
|
| 435 |
+
* @return WP_Error|boolean
|
| 436 |
+
*/
|
| 437 |
+
public function validate_user_can_query_private_statuses( $value, $request, $parameter ) {
|
| 438 |
+
if ( 'inherit' === $value ) {
|
| 439 |
+
return true;
|
| 440 |
+
}
|
| 441 |
+
return parent::validate_user_can_query_private_statuses( $value, $request, $parameter );
|
| 442 |
+
}
|
| 443 |
+
|
| 444 |
/**
|
| 445 |
* Handle an upload via multipart/form-data ($_FILES)
|
| 446 |
*
|
lib/endpoints/class-wp-rest-comments-controller.php
CHANGED
|
@@ -47,7 +47,10 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
|
| 47 |
'callback' => array( $this, 'delete_item' ),
|
| 48 |
'permission_callback' => array( $this, 'delete_item_permissions_check' ),
|
| 49 |
'args' => array(
|
| 50 |
-
'force' => array(
|
|
|
|
|
|
|
|
|
|
| 51 |
),
|
| 52 |
),
|
| 53 |
|
|
@@ -55,6 +58,30 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
|
| 55 |
) );
|
| 56 |
}
|
| 57 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
/**
|
| 59 |
* Get a list of comments.
|
| 60 |
*
|
|
@@ -62,7 +89,51 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
|
| 62 |
* @return WP_Error|WP_REST_Response
|
| 63 |
*/
|
| 64 |
public function get_items( $request ) {
|
| 65 |
-
$prepared_args =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
|
| 67 |
$query = new WP_Comment_Query;
|
| 68 |
$query_result = $query->query( $prepared_args );
|
|
@@ -71,7 +142,6 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
|
| 71 |
foreach ( $query_result as $comment ) {
|
| 72 |
$post = get_post( $comment->comment_post_ID );
|
| 73 |
if ( ! $this->check_read_post_permission( $post ) || ! $this->check_read_permission( $comment ) ) {
|
| 74 |
-
|
| 75 |
continue;
|
| 76 |
}
|
| 77 |
|
|
@@ -79,15 +149,22 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
|
| 79 |
$comments[] = $this->prepare_response_for_collection( $data );
|
| 80 |
}
|
| 81 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 82 |
$response = rest_ensure_response( $comments );
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
$query = new WP_Comment_Query;
|
| 86 |
-
$prepared_args['count'] = true;
|
| 87 |
-
$total_comments = $query->query( $prepared_args );
|
| 88 |
-
$response->header( 'X-WP-Total', (int) $total_comments );
|
| 89 |
-
$max_pages = ceil( $total_comments / $request['per_page'] );
|
| 90 |
-
$response->header( 'X-WP-TotalPages', (int) $max_pages );
|
| 91 |
|
| 92 |
$base = add_query_arg( $request->get_query_params(), rest_url( '/wp/v2/comments' ) );
|
| 93 |
if ( $request['page'] > 1 ) {
|
|
@@ -107,6 +184,38 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
|
| 107 |
return $response;
|
| 108 |
}
|
| 109 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
/**
|
| 111 |
* Get a comment.
|
| 112 |
*
|
|
@@ -134,6 +243,43 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
|
| 134 |
return $response;
|
| 135 |
}
|
| 136 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 137 |
/**
|
| 138 |
* Create a comment.
|
| 139 |
*
|
|
@@ -216,13 +362,32 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
|
| 216 |
*
|
| 217 |
* @param array $prepared_comment Inserted comment data.
|
| 218 |
* @param WP_REST_Request $request The request sent to the API.
|
| 219 |
-
* @param
|
| 220 |
*/
|
| 221 |
do_action( 'rest_insert_comment', $prepared_comment, $request, true );
|
| 222 |
|
| 223 |
return $response;
|
| 224 |
}
|
| 225 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 226 |
/**
|
| 227 |
* Edit a comment
|
| 228 |
*
|
|
@@ -262,12 +427,11 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
|
| 262 |
}
|
| 263 |
}
|
| 264 |
|
| 265 |
-
$
|
|
|
|
| 266 |
|
| 267 |
-
$
|
| 268 |
-
$
|
| 269 |
-
$get_request->set_param( 'context', 'edit' );
|
| 270 |
-
$response = $this->get_item( $get_request );
|
| 271 |
|
| 272 |
/* This action is documented in lib/endpoints/class-wp-rest-comments-controller.php */
|
| 273 |
do_action( 'rest_insert_comment', $prepared_args, $request, false );
|
|
@@ -275,6 +439,24 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
|
| 275 |
return rest_ensure_response( $response );
|
| 276 |
}
|
| 277 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 278 |
/**
|
| 279 |
* Delete a comment.
|
| 280 |
*
|
|
@@ -314,6 +496,10 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
|
| 314 |
return new WP_Error( 'rest_trash_not_supported', __( 'The comment does not support trashing.' ), array( 'status' => 501 ) );
|
| 315 |
}
|
| 316 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 317 |
$result = wp_trash_comment( $comment->comment_ID );
|
| 318 |
$status = 'trashed';
|
| 319 |
}
|
|
@@ -341,135 +527,12 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
|
| 341 |
return $response;
|
| 342 |
}
|
| 343 |
|
| 344 |
-
|
| 345 |
-
/**
|
| 346 |
-
* Check if a given request has access to read comments
|
| 347 |
-
*
|
| 348 |
-
* @param WP_REST_Request $request Full details about the request.
|
| 349 |
-
* @return bool|WP_Error
|
| 350 |
-
*/
|
| 351 |
-
public function get_items_permissions_check( $request ) {
|
| 352 |
-
|
| 353 |
-
// If the post id is specified, check that we can read the post
|
| 354 |
-
if ( isset( $request['post'] ) ) {
|
| 355 |
-
$post = get_post( (int) $request['post'] );
|
| 356 |
-
|
| 357 |
-
if ( $post && ! $this->check_read_post_permission( $post ) ) {
|
| 358 |
-
return new WP_Error( 'rest_cannot_read_post', __( 'Sorry, you cannot read the post for this comment.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 359 |
-
}
|
| 360 |
-
}
|
| 361 |
-
|
| 362 |
-
if ( ! empty( $request['context'] ) && 'edit' === $request['context'] && ! current_user_can( 'moderate_comments' ) ) {
|
| 363 |
-
return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you cannot view comments with edit context.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 364 |
-
}
|
| 365 |
-
|
| 366 |
-
return true;
|
| 367 |
-
}
|
| 368 |
-
|
| 369 |
-
/**
|
| 370 |
-
* Check if a given request has access to read the comment
|
| 371 |
-
*
|
| 372 |
-
* @param WP_REST_Request $request Full details about the request.
|
| 373 |
-
* @return bool|WP_Error
|
| 374 |
-
*/
|
| 375 |
-
public function get_item_permissions_check( $request ) {
|
| 376 |
-
$id = (int) $request['id'];
|
| 377 |
-
|
| 378 |
-
$comment = get_comment( $id );
|
| 379 |
-
|
| 380 |
-
if ( ! $comment ) {
|
| 381 |
-
return true;
|
| 382 |
-
}
|
| 383 |
-
|
| 384 |
-
if ( ! $this->check_read_permission( $comment ) ) {
|
| 385 |
-
return new WP_Error( 'rest_cannot_read', __( 'Sorry, you cannot read this comment.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 386 |
-
}
|
| 387 |
-
|
| 388 |
-
$post = get_post( $comment->comment_post_ID );
|
| 389 |
-
|
| 390 |
-
if ( $post && ! $this->check_read_post_permission( $post ) ) {
|
| 391 |
-
return new WP_Error( 'rest_cannot_read_post', __( 'Sorry, you cannot read the post for this comment.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 392 |
-
}
|
| 393 |
-
|
| 394 |
-
if ( ! empty( $request['context'] ) && 'edit' === $request['context'] && ! current_user_can( 'moderate_comments' ) ) {
|
| 395 |
-
return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you cannot view this comment with edit context.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 396 |
-
}
|
| 397 |
-
|
| 398 |
-
return true;
|
| 399 |
-
}
|
| 400 |
-
|
| 401 |
-
/**
|
| 402 |
-
* Check if a given request has access to create a comment
|
| 403 |
-
*
|
| 404 |
-
* @param WP_REST_Request $request Full details about the request.
|
| 405 |
-
* @return bool|WP_Error
|
| 406 |
-
*/
|
| 407 |
-
public function create_item_permissions_check( $request ) {
|
| 408 |
-
|
| 409 |
-
if ( ! is_user_logged_in() && get_option( 'comment_registration' ) ) {
|
| 410 |
-
return new WP_Error( 'rest_comment_login_required', __( 'Sorry, you must be logged in to comment.' ), array( 'status' => 401 ) );
|
| 411 |
-
}
|
| 412 |
-
|
| 413 |
-
// Limit who can set comment `author`, `karma` or `status` to anything other than the default.
|
| 414 |
-
if ( isset( $request['author'] ) && get_current_user_id() !== $request['author'] && ! current_user_can( 'moderate_comments' ) ) {
|
| 415 |
-
return new WP_Error( 'rest_comment_invalid_author', __( 'Comment author invalid.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 416 |
-
}
|
| 417 |
-
if ( isset( $request['karma'] ) && $request['karma'] > 0 && ! current_user_can( 'moderate_comments' ) ) {
|
| 418 |
-
return new WP_Error( 'rest_comment_invalid_karma', __( 'Sorry, you cannot set karma for comments.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 419 |
-
}
|
| 420 |
-
if ( isset( $request['status'] ) && ! current_user_can( 'moderate_comments' ) ) {
|
| 421 |
-
return new WP_Error( 'rest_comment_invalid_status', __( 'Sorry, you cannot set status for comments.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 422 |
-
}
|
| 423 |
-
|
| 424 |
-
if ( ! empty( $request['post'] ) && $post = get_post( (int) $request['post'] ) ) {
|
| 425 |
-
|
| 426 |
-
if ( ! $this->check_read_post_permission( $post ) ) {
|
| 427 |
-
return new WP_Error( 'rest_cannot_read_post', __( 'Sorry, you cannot read the post for this comment.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 428 |
-
}
|
| 429 |
-
|
| 430 |
-
if ( ! comments_open( $post->ID ) ) {
|
| 431 |
-
return new WP_Error( 'rest_comment_closed', __( 'Sorry, comments are closed on this post.' ), array( 'status' => 403 ) );
|
| 432 |
-
}
|
| 433 |
-
}
|
| 434 |
-
|
| 435 |
-
return true;
|
| 436 |
-
}
|
| 437 |
-
|
| 438 |
-
/**
|
| 439 |
-
* Check if a given request has access to update a comment
|
| 440 |
-
*
|
| 441 |
-
* @param WP_REST_Request $request Full details about the request.
|
| 442 |
-
* @return bool|WP_Error
|
| 443 |
-
*/
|
| 444 |
-
public function update_item_permissions_check( $request ) {
|
| 445 |
-
|
| 446 |
-
$id = (int) $request['id'];
|
| 447 |
-
|
| 448 |
-
$comment = get_comment( $id );
|
| 449 |
-
|
| 450 |
-
if ( $comment && ! $this->check_edit_permission( $comment ) ) {
|
| 451 |
-
return new WP_Error( 'rest_cannot_edit', __( 'Sorry, you can not edit this comment.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 452 |
-
}
|
| 453 |
-
|
| 454 |
-
return true;
|
| 455 |
-
}
|
| 456 |
-
|
| 457 |
-
/**
|
| 458 |
-
* Check if a given request has access to delete a comment
|
| 459 |
-
*
|
| 460 |
-
* @param WP_REST_Request $request Full details about the request.
|
| 461 |
-
* @return bool|WP_Error
|
| 462 |
-
*/
|
| 463 |
-
public function delete_item_permissions_check( $request ) {
|
| 464 |
-
return $this->update_item_permissions_check( $request );
|
| 465 |
-
}
|
| 466 |
-
|
| 467 |
/**
|
| 468 |
* Prepare a single comment output for response.
|
| 469 |
*
|
| 470 |
* @param object $comment Comment object.
|
| 471 |
* @param WP_REST_Request $request Request object.
|
| 472 |
-
* @return WP_REST_Response
|
| 473 |
*/
|
| 474 |
public function prepare_item_for_response( $comment, $request ) {
|
| 475 |
$data = array(
|
|
@@ -496,8 +559,8 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
|
| 496 |
);
|
| 497 |
|
| 498 |
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
| 499 |
-
$data = $this->filter_response_by_context( $data, $context );
|
| 500 |
$data = $this->add_additional_fields_to_object( $data, $request );
|
|
|
|
| 501 |
|
| 502 |
// Wrap the data in a response object
|
| 503 |
$response = rest_ensure_response( $data );
|
|
@@ -563,50 +626,6 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
|
| 563 |
return $links;
|
| 564 |
}
|
| 565 |
|
| 566 |
-
/**
|
| 567 |
-
* Filter query parameters for comments collection endpoint.
|
| 568 |
-
*
|
| 569 |
-
* Prepares arguments before passing them along to WP_Comment_Query.
|
| 570 |
-
*
|
| 571 |
-
* @param WP_REST_Request $request Request object.
|
| 572 |
-
* @return array $prepared_args
|
| 573 |
-
*/
|
| 574 |
-
protected function prepare_items_query( $request ) {
|
| 575 |
-
|
| 576 |
-
$prepared_args = array(
|
| 577 |
-
'comment__in' => $request['include'],
|
| 578 |
-
'number' => $request['per_page'],
|
| 579 |
-
'post_id' => $request['post'] ? $request['post'] : '',
|
| 580 |
-
'parent' => isset( $request['parent'] ) ? $request['parent'] : '',
|
| 581 |
-
'search' => $request['search'],
|
| 582 |
-
'orderby' => $this->normalize_query_param( $request['orderby'] ),
|
| 583 |
-
'order' => $request['order'],
|
| 584 |
-
'status' => 'approve',
|
| 585 |
-
'type' => 'comment',
|
| 586 |
-
);
|
| 587 |
-
|
| 588 |
-
$prepared_args['offset'] = $prepared_args['number'] * ( absint( $request['page'] ) - 1 );
|
| 589 |
-
|
| 590 |
-
if ( current_user_can( 'edit_posts' ) ) {
|
| 591 |
-
$protected_args = array(
|
| 592 |
-
'user' => $request['user'] ? $request['user'] : '',
|
| 593 |
-
'status' => $request['status'],
|
| 594 |
-
'type' => isset( $request['type'] ) ? $request['type'] : '',
|
| 595 |
-
'author_email' => isset( $request['author_email'] ) ? $request['author_email'] : '',
|
| 596 |
-
'karma' => isset( $request['karma'] ) ? $request['karma'] : '',
|
| 597 |
-
'post_author' => isset( $request['post_author'] ) ? $request['post_author'] : '',
|
| 598 |
-
'post_name' => isset( $request['post_slug'] ) ? $request['post_slug'] : '',
|
| 599 |
-
'post_parent' => isset( $request['post_parent'] ) ? $request['post_parent'] : '',
|
| 600 |
-
'post_status' => isset( $request['post_status'] ) ? $request['post_status'] : '',
|
| 601 |
-
'post_type' => isset( $request['post_type'] ) ? $request['post_type'] : '',
|
| 602 |
-
);
|
| 603 |
-
|
| 604 |
-
$prepared_args = array_merge( $prepared_args, $protected_args );
|
| 605 |
-
}
|
| 606 |
-
|
| 607 |
-
return $prepared_args;
|
| 608 |
-
}
|
| 609 |
-
|
| 610 |
/**
|
| 611 |
* Prepend internal property prefix to query parameters to match our response fields.
|
| 612 |
*
|
|
@@ -902,6 +921,12 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
|
| 902 |
'sanitize_callback' => 'sanitize_email',
|
| 903 |
'type' => 'string',
|
| 904 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 905 |
$query_params['include'] = array(
|
| 906 |
'description' => __( 'Limit result set to specific ids.' ),
|
| 907 |
'type' => 'array',
|
|
@@ -914,6 +939,11 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
|
| 914 |
'sanitize_callback' => 'absint',
|
| 915 |
'type' => 'integer',
|
| 916 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 917 |
$query_params['order'] = array(
|
| 918 |
'description' => __( 'Order sort attribute ascending or descending.' ),
|
| 919 |
'type' => 'string',
|
|
@@ -929,6 +959,15 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
|
| 929 |
'type' => 'string',
|
| 930 |
'sanitize_callback' => 'sanitize_key',
|
| 931 |
'default' => 'date_gmt',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 932 |
);
|
| 933 |
$query_params['parent'] = array(
|
| 934 |
'default' => null,
|
|
@@ -984,8 +1023,7 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
|
| 984 |
'sanitize_callback' => 'sanitize_key',
|
| 985 |
'type' => 'string',
|
| 986 |
);
|
| 987 |
-
$query_params['
|
| 988 |
-
'default' => null,
|
| 989 |
'description' => __( 'Limit result set to comments assigned to a specific user id.' ),
|
| 990 |
'sanitize_callback' => 'absint',
|
| 991 |
'type' => 'integer',
|
| 47 |
'callback' => array( $this, 'delete_item' ),
|
| 48 |
'permission_callback' => array( $this, 'delete_item_permissions_check' ),
|
| 49 |
'args' => array(
|
| 50 |
+
'force' => array(
|
| 51 |
+
'default' => false,
|
| 52 |
+
'description' => __( 'Whether to bypass trash and force deletion.' ),
|
| 53 |
+
),
|
| 54 |
),
|
| 55 |
),
|
| 56 |
|
| 58 |
) );
|
| 59 |
}
|
| 60 |
|
| 61 |
+
/**
|
| 62 |
+
* Check if a given request has access to read comments
|
| 63 |
+
*
|
| 64 |
+
* @param WP_REST_Request $request Full details about the request.
|
| 65 |
+
* @return WP_Error|boolean
|
| 66 |
+
*/
|
| 67 |
+
public function get_items_permissions_check( $request ) {
|
| 68 |
+
|
| 69 |
+
// If the post id is specified, check that we can read the post
|
| 70 |
+
if ( isset( $request['post'] ) ) {
|
| 71 |
+
$post = get_post( (int) $request['post'] );
|
| 72 |
+
|
| 73 |
+
if ( $post && ! $this->check_read_post_permission( $post ) ) {
|
| 74 |
+
return new WP_Error( 'rest_cannot_read_post', __( 'Sorry, you cannot read the post for this comment.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 75 |
+
}
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
if ( ! empty( $request['context'] ) && 'edit' === $request['context'] && ! current_user_can( 'moderate_comments' ) ) {
|
| 79 |
+
return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you cannot view comments with edit context.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
return true;
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
/**
|
| 86 |
* Get a list of comments.
|
| 87 |
*
|
| 89 |
* @return WP_Error|WP_REST_Response
|
| 90 |
*/
|
| 91 |
public function get_items( $request ) {
|
| 92 |
+
$prepared_args = array(
|
| 93 |
+
'comment__in' => $request['include'],
|
| 94 |
+
'comment__not_in' => $request['exclude'],
|
| 95 |
+
'number' => $request['per_page'],
|
| 96 |
+
'post_id' => $request['post'] ? $request['post'] : '',
|
| 97 |
+
'parent' => isset( $request['parent'] ) ? $request['parent'] : '',
|
| 98 |
+
'search' => $request['search'],
|
| 99 |
+
'offset' => $request['offset'],
|
| 100 |
+
'orderby' => $this->normalize_query_param( $request['orderby'] ),
|
| 101 |
+
'order' => $request['order'],
|
| 102 |
+
'status' => 'approve',
|
| 103 |
+
'type' => 'comment',
|
| 104 |
+
'no_found_rows' => false,
|
| 105 |
+
);
|
| 106 |
+
|
| 107 |
+
if ( empty( $request['offset'] ) ) {
|
| 108 |
+
$prepared_args['offset'] = $prepared_args['number'] * ( absint( $request['page'] ) - 1 );
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
if ( current_user_can( 'edit_posts' ) ) {
|
| 112 |
+
$protected_args = array(
|
| 113 |
+
'user_id' => $request['author'] ? $request['author'] : '',
|
| 114 |
+
'status' => $request['status'],
|
| 115 |
+
'type' => isset( $request['type'] ) ? $request['type'] : '',
|
| 116 |
+
'author_email' => isset( $request['author_email'] ) ? $request['author_email'] : '',
|
| 117 |
+
'karma' => isset( $request['karma'] ) ? $request['karma'] : '',
|
| 118 |
+
'post_author' => isset( $request['post_author'] ) ? $request['post_author'] : '',
|
| 119 |
+
'post_name' => isset( $request['post_slug'] ) ? $request['post_slug'] : '',
|
| 120 |
+
'post_parent' => isset( $request['post_parent'] ) ? $request['post_parent'] : '',
|
| 121 |
+
'post_status' => isset( $request['post_status'] ) ? $request['post_status'] : '',
|
| 122 |
+
'post_type' => isset( $request['post_type'] ) ? $request['post_type'] : '',
|
| 123 |
+
);
|
| 124 |
+
|
| 125 |
+
$prepared_args = array_merge( $prepared_args, $protected_args );
|
| 126 |
+
}
|
| 127 |
+
|
| 128 |
+
/**
|
| 129 |
+
* Filter arguments, before passing to WP_Comment_Query, when querying comments via the REST API.
|
| 130 |
+
*
|
| 131 |
+
* @see https://developer.wordpress.org/reference/classes/wp_comment_query/
|
| 132 |
+
*
|
| 133 |
+
* @param array $prepared_args Array of arguments for WP_Comment_Query.
|
| 134 |
+
* @param WP_REST_Request $request The current request.
|
| 135 |
+
*/
|
| 136 |
+
$prepared_args = apply_filters( 'rest_comment_query', $prepared_args, $request );
|
| 137 |
|
| 138 |
$query = new WP_Comment_Query;
|
| 139 |
$query_result = $query->query( $prepared_args );
|
| 142 |
foreach ( $query_result as $comment ) {
|
| 143 |
$post = get_post( $comment->comment_post_ID );
|
| 144 |
if ( ! $this->check_read_post_permission( $post ) || ! $this->check_read_permission( $comment ) ) {
|
|
|
|
| 145 |
continue;
|
| 146 |
}
|
| 147 |
|
| 149 |
$comments[] = $this->prepare_response_for_collection( $data );
|
| 150 |
}
|
| 151 |
|
| 152 |
+
$total_comments = (int) $query->found_comments;
|
| 153 |
+
$max_pages = (int) $query->max_num_pages;
|
| 154 |
+
if ( $total_comments < 1 ) {
|
| 155 |
+
// Out-of-bounds, run the query again without LIMIT for total count
|
| 156 |
+
unset( $prepared_args['number'] );
|
| 157 |
+
unset( $prepared_args['offset'] );
|
| 158 |
+
$query = new WP_Comment_Query;
|
| 159 |
+
$prepared_args['count'] = true;
|
| 160 |
+
|
| 161 |
+
$total_comments = $query->query( $prepared_args );
|
| 162 |
+
$max_pages = ceil( $total_comments / $request['per_page'] );
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
$response = rest_ensure_response( $comments );
|
| 166 |
+
$response->header( 'X-WP-Total', $total_comments );
|
| 167 |
+
$response->header( 'X-WP-TotalPages', $max_pages );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 168 |
|
| 169 |
$base = add_query_arg( $request->get_query_params(), rest_url( '/wp/v2/comments' ) );
|
| 170 |
if ( $request['page'] > 1 ) {
|
| 184 |
return $response;
|
| 185 |
}
|
| 186 |
|
| 187 |
+
/**
|
| 188 |
+
* Check if a given request has access to read the comment
|
| 189 |
+
*
|
| 190 |
+
* @param WP_REST_Request $request Full details about the request.
|
| 191 |
+
* @return WP_Error|boolean
|
| 192 |
+
*/
|
| 193 |
+
public function get_item_permissions_check( $request ) {
|
| 194 |
+
$id = (int) $request['id'];
|
| 195 |
+
|
| 196 |
+
$comment = get_comment( $id );
|
| 197 |
+
|
| 198 |
+
if ( ! $comment ) {
|
| 199 |
+
return true;
|
| 200 |
+
}
|
| 201 |
+
|
| 202 |
+
if ( ! $this->check_read_permission( $comment ) ) {
|
| 203 |
+
return new WP_Error( 'rest_cannot_read', __( 'Sorry, you cannot read this comment.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 204 |
+
}
|
| 205 |
+
|
| 206 |
+
$post = get_post( $comment->comment_post_ID );
|
| 207 |
+
|
| 208 |
+
if ( $post && ! $this->check_read_post_permission( $post ) ) {
|
| 209 |
+
return new WP_Error( 'rest_cannot_read_post', __( 'Sorry, you cannot read the post for this comment.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 210 |
+
}
|
| 211 |
+
|
| 212 |
+
if ( ! empty( $request['context'] ) && 'edit' === $request['context'] && ! current_user_can( 'moderate_comments' ) ) {
|
| 213 |
+
return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you cannot view this comment with edit context.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 214 |
+
}
|
| 215 |
+
|
| 216 |
+
return true;
|
| 217 |
+
}
|
| 218 |
+
|
| 219 |
/**
|
| 220 |
* Get a comment.
|
| 221 |
*
|
| 243 |
return $response;
|
| 244 |
}
|
| 245 |
|
| 246 |
+
/**
|
| 247 |
+
* Check if a given request has access to create a comment
|
| 248 |
+
*
|
| 249 |
+
* @param WP_REST_Request $request Full details about the request.
|
| 250 |
+
* @return WP_Error|boolean
|
| 251 |
+
*/
|
| 252 |
+
public function create_item_permissions_check( $request ) {
|
| 253 |
+
|
| 254 |
+
if ( ! is_user_logged_in() && get_option( 'comment_registration' ) ) {
|
| 255 |
+
return new WP_Error( 'rest_comment_login_required', __( 'Sorry, you must be logged in to comment.' ), array( 'status' => 401 ) );
|
| 256 |
+
}
|
| 257 |
+
|
| 258 |
+
// Limit who can set comment `author`, `karma` or `status` to anything other than the default.
|
| 259 |
+
if ( isset( $request['author'] ) && get_current_user_id() !== $request['author'] && ! current_user_can( 'moderate_comments' ) ) {
|
| 260 |
+
return new WP_Error( 'rest_comment_invalid_author', __( 'Comment author invalid.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 261 |
+
}
|
| 262 |
+
if ( isset( $request['karma'] ) && $request['karma'] > 0 && ! current_user_can( 'moderate_comments' ) ) {
|
| 263 |
+
return new WP_Error( 'rest_comment_invalid_karma', __( 'Sorry, you cannot set karma for comments.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 264 |
+
}
|
| 265 |
+
if ( isset( $request['status'] ) && ! current_user_can( 'moderate_comments' ) ) {
|
| 266 |
+
return new WP_Error( 'rest_comment_invalid_status', __( 'Sorry, you cannot set status for comments.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 267 |
+
}
|
| 268 |
+
|
| 269 |
+
if ( ! empty( $request['post'] ) && $post = get_post( (int) $request['post'] ) ) {
|
| 270 |
+
|
| 271 |
+
if ( ! $this->check_read_post_permission( $post ) ) {
|
| 272 |
+
return new WP_Error( 'rest_cannot_read_post', __( 'Sorry, you cannot read the post for this comment.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 273 |
+
}
|
| 274 |
+
|
| 275 |
+
if ( ! comments_open( $post->ID ) ) {
|
| 276 |
+
return new WP_Error( 'rest_comment_closed', __( 'Sorry, comments are closed on this post.' ), array( 'status' => 403 ) );
|
| 277 |
+
}
|
| 278 |
+
}
|
| 279 |
+
|
| 280 |
+
return true;
|
| 281 |
+
}
|
| 282 |
+
|
| 283 |
/**
|
| 284 |
* Create a comment.
|
| 285 |
*
|
| 362 |
*
|
| 363 |
* @param array $prepared_comment Inserted comment data.
|
| 364 |
* @param WP_REST_Request $request The request sent to the API.
|
| 365 |
+
* @param boolean $creating True when creating a comment, false when updating.
|
| 366 |
*/
|
| 367 |
do_action( 'rest_insert_comment', $prepared_comment, $request, true );
|
| 368 |
|
| 369 |
return $response;
|
| 370 |
}
|
| 371 |
|
| 372 |
+
/**
|
| 373 |
+
* Check if a given request has access to update a comment
|
| 374 |
+
*
|
| 375 |
+
* @param WP_REST_Request $request Full details about the request.
|
| 376 |
+
* @return WP_Error|boolean
|
| 377 |
+
*/
|
| 378 |
+
public function update_item_permissions_check( $request ) {
|
| 379 |
+
|
| 380 |
+
$id = (int) $request['id'];
|
| 381 |
+
|
| 382 |
+
$comment = get_comment( $id );
|
| 383 |
+
|
| 384 |
+
if ( $comment && ! $this->check_edit_permission( $comment ) ) {
|
| 385 |
+
return new WP_Error( 'rest_cannot_edit', __( 'Sorry, you can not edit this comment.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 386 |
+
}
|
| 387 |
+
|
| 388 |
+
return true;
|
| 389 |
+
}
|
| 390 |
+
|
| 391 |
/**
|
| 392 |
* Edit a comment
|
| 393 |
*
|
| 427 |
}
|
| 428 |
}
|
| 429 |
|
| 430 |
+
$comment = get_comment( $id );
|
| 431 |
+
$this->update_additional_fields_for_object( $comment, $request );
|
| 432 |
|
| 433 |
+
$request->set_param( 'context', 'edit' );
|
| 434 |
+
$response = $this->prepare_item_for_response( $comment, $request );
|
|
|
|
|
|
|
| 435 |
|
| 436 |
/* This action is documented in lib/endpoints/class-wp-rest-comments-controller.php */
|
| 437 |
do_action( 'rest_insert_comment', $prepared_args, $request, false );
|
| 439 |
return rest_ensure_response( $response );
|
| 440 |
}
|
| 441 |
|
| 442 |
+
/**
|
| 443 |
+
* Check if a given request has access to delete a comment
|
| 444 |
+
*
|
| 445 |
+
* @param WP_REST_Request $request Full details about the request.
|
| 446 |
+
* @return WP_Error|boolean
|
| 447 |
+
*/
|
| 448 |
+
public function delete_item_permissions_check( $request ) {
|
| 449 |
+
$id = (int) $request['id'];
|
| 450 |
+
$comment = get_comment( $id );
|
| 451 |
+
if ( ! $comment ) {
|
| 452 |
+
return new WP_Error( 'rest_comment_invalid_id', __( 'Invalid comment id.' ), array( 'status' => 404 ) );
|
| 453 |
+
}
|
| 454 |
+
if ( ! $this->check_edit_permission( $comment ) ) {
|
| 455 |
+
return new WP_Error( 'rest_cannot_delete', __( 'Sorry, you can not delete this comment.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 456 |
+
}
|
| 457 |
+
return true;
|
| 458 |
+
}
|
| 459 |
+
|
| 460 |
/**
|
| 461 |
* Delete a comment.
|
| 462 |
*
|
| 496 |
return new WP_Error( 'rest_trash_not_supported', __( 'The comment does not support trashing.' ), array( 'status' => 501 ) );
|
| 497 |
}
|
| 498 |
|
| 499 |
+
if ( 'trash' === $comment->comment_approved ) {
|
| 500 |
+
return new WP_Error( 'rest_already_trashed', __( 'The comment has already been trashed.' ), array( 'status' => 410 ) );
|
| 501 |
+
}
|
| 502 |
+
|
| 503 |
$result = wp_trash_comment( $comment->comment_ID );
|
| 504 |
$status = 'trashed';
|
| 505 |
}
|
| 527 |
return $response;
|
| 528 |
}
|
| 529 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 530 |
/**
|
| 531 |
* Prepare a single comment output for response.
|
| 532 |
*
|
| 533 |
* @param object $comment Comment object.
|
| 534 |
* @param WP_REST_Request $request Request object.
|
| 535 |
+
* @return WP_REST_Response $response
|
| 536 |
*/
|
| 537 |
public function prepare_item_for_response( $comment, $request ) {
|
| 538 |
$data = array(
|
| 559 |
);
|
| 560 |
|
| 561 |
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
|
|
|
| 562 |
$data = $this->add_additional_fields_to_object( $data, $request );
|
| 563 |
+
$data = $this->filter_response_by_context( $data, $context );
|
| 564 |
|
| 565 |
// Wrap the data in a response object
|
| 566 |
$response = rest_ensure_response( $data );
|
| 626 |
return $links;
|
| 627 |
}
|
| 628 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 629 |
/**
|
| 630 |
* Prepend internal property prefix to query parameters to match our response fields.
|
| 631 |
*
|
| 921 |
'sanitize_callback' => 'sanitize_email',
|
| 922 |
'type' => 'string',
|
| 923 |
);
|
| 924 |
+
$query_params['exclude'] = array(
|
| 925 |
+
'description' => __( 'Ensure result set excludes specific ids.' ),
|
| 926 |
+
'type' => 'array',
|
| 927 |
+
'default' => array(),
|
| 928 |
+
'sanitize_callback' => 'wp_parse_id_list',
|
| 929 |
+
);
|
| 930 |
$query_params['include'] = array(
|
| 931 |
'description' => __( 'Limit result set to specific ids.' ),
|
| 932 |
'type' => 'array',
|
| 939 |
'sanitize_callback' => 'absint',
|
| 940 |
'type' => 'integer',
|
| 941 |
);
|
| 942 |
+
$query_params['offset'] = array(
|
| 943 |
+
'description' => __( 'Offset the result set by a specific number of comments.' ),
|
| 944 |
+
'type' => 'integer',
|
| 945 |
+
'sanitize_callback' => 'absint',
|
| 946 |
+
);
|
| 947 |
$query_params['order'] = array(
|
| 948 |
'description' => __( 'Order sort attribute ascending or descending.' ),
|
| 949 |
'type' => 'string',
|
| 959 |
'type' => 'string',
|
| 960 |
'sanitize_callback' => 'sanitize_key',
|
| 961 |
'default' => 'date_gmt',
|
| 962 |
+
'enum' => array(
|
| 963 |
+
'date',
|
| 964 |
+
'date_gmt',
|
| 965 |
+
'id',
|
| 966 |
+
'include',
|
| 967 |
+
'post',
|
| 968 |
+
'parent',
|
| 969 |
+
'type',
|
| 970 |
+
),
|
| 971 |
);
|
| 972 |
$query_params['parent'] = array(
|
| 973 |
'default' => null,
|
| 1023 |
'sanitize_callback' => 'sanitize_key',
|
| 1024 |
'type' => 'string',
|
| 1025 |
);
|
| 1026 |
+
$query_params['author'] = array(
|
|
|
|
| 1027 |
'description' => __( 'Limit result set to comments assigned to a specific user id.' ),
|
| 1028 |
'sanitize_callback' => 'absint',
|
| 1029 |
'type' => 'integer',
|
lib/endpoints/class-wp-rest-controller.php
CHANGED
|
@@ -11,102 +11,102 @@ abstract class WP_REST_Controller {
|
|
| 11 |
}
|
| 12 |
|
| 13 |
/**
|
| 14 |
-
*
|
| 15 |
*
|
| 16 |
* @param WP_REST_Request $request Full data about the request.
|
| 17 |
-
* @return WP_Error|
|
| 18 |
*/
|
| 19 |
-
public function
|
| 20 |
return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be over-ridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) );
|
| 21 |
}
|
| 22 |
|
| 23 |
/**
|
| 24 |
-
* Get
|
| 25 |
*
|
| 26 |
* @param WP_REST_Request $request Full data about the request.
|
| 27 |
* @return WP_Error|WP_REST_Response
|
| 28 |
*/
|
| 29 |
-
public function
|
| 30 |
return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be over-ridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) );
|
| 31 |
}
|
| 32 |
|
| 33 |
/**
|
| 34 |
-
*
|
| 35 |
*
|
| 36 |
* @param WP_REST_Request $request Full data about the request.
|
| 37 |
-
* @return WP_Error|
|
| 38 |
*/
|
| 39 |
-
public function
|
| 40 |
return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be over-ridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) );
|
| 41 |
}
|
| 42 |
|
| 43 |
/**
|
| 44 |
-
*
|
| 45 |
*
|
| 46 |
* @param WP_REST_Request $request Full data about the request.
|
| 47 |
* @return WP_Error|WP_REST_Response
|
| 48 |
*/
|
| 49 |
-
public function
|
| 50 |
return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be over-ridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) );
|
| 51 |
}
|
| 52 |
|
| 53 |
/**
|
| 54 |
-
*
|
| 55 |
*
|
| 56 |
* @param WP_REST_Request $request Full data about the request.
|
| 57 |
-
* @return WP_Error|
|
| 58 |
*/
|
| 59 |
-
public function
|
| 60 |
return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be over-ridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) );
|
| 61 |
}
|
| 62 |
|
| 63 |
/**
|
| 64 |
-
*
|
| 65 |
*
|
| 66 |
* @param WP_REST_Request $request Full data about the request.
|
| 67 |
-
* @return WP_Error|
|
| 68 |
*/
|
| 69 |
-
public function
|
| 70 |
return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be over-ridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) );
|
| 71 |
}
|
| 72 |
|
| 73 |
/**
|
| 74 |
-
* Check if a given request has access to
|
| 75 |
*
|
| 76 |
* @param WP_REST_Request $request Full data about the request.
|
| 77 |
-
* @return WP_Error|
|
| 78 |
*/
|
| 79 |
-
public function
|
| 80 |
return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be over-ridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) );
|
| 81 |
}
|
| 82 |
|
| 83 |
/**
|
| 84 |
-
*
|
| 85 |
*
|
| 86 |
* @param WP_REST_Request $request Full data about the request.
|
| 87 |
-
* @return WP_Error|
|
| 88 |
*/
|
| 89 |
-
public function
|
| 90 |
return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be over-ridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) );
|
| 91 |
}
|
| 92 |
|
| 93 |
/**
|
| 94 |
-
* Check if a given request has access to
|
| 95 |
*
|
| 96 |
* @param WP_REST_Request $request Full data about the request.
|
| 97 |
-
* @return WP_Error|
|
| 98 |
*/
|
| 99 |
-
public function
|
| 100 |
return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be over-ridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) );
|
| 101 |
}
|
| 102 |
|
| 103 |
/**
|
| 104 |
-
*
|
| 105 |
*
|
| 106 |
* @param WP_REST_Request $request Full data about the request.
|
| 107 |
-
* @return WP_Error|
|
| 108 |
*/
|
| 109 |
-
public function
|
| 110 |
return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be over-ridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) );
|
| 111 |
}
|
| 112 |
|
|
@@ -125,7 +125,7 @@ abstract class WP_REST_Controller {
|
|
| 125 |
*
|
| 126 |
* @param mixed $item WordPress representation of the item.
|
| 127 |
* @param WP_REST_Request $request Request object.
|
| 128 |
-
* @return
|
| 129 |
*/
|
| 130 |
public function prepare_item_for_response( $item, $request ) {
|
| 131 |
return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be over-ridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) );
|
|
@@ -254,7 +254,6 @@ abstract class WP_REST_Controller {
|
|
| 254 |
'type' => 'string',
|
| 255 |
);
|
| 256 |
$schema = $this->get_item_schema();
|
| 257 |
-
$contexts = array();
|
| 258 |
if ( empty( $schema['properties'] ) ) {
|
| 259 |
return array_merge( $param_details, $args );
|
| 260 |
}
|
|
@@ -315,7 +314,7 @@ abstract class WP_REST_Controller {
|
|
| 315 |
continue;
|
| 316 |
}
|
| 317 |
|
| 318 |
-
|
| 319 |
}
|
| 320 |
}
|
| 321 |
|
|
@@ -327,7 +326,7 @@ abstract class WP_REST_Controller {
|
|
| 327 |
* @param array $schema Schema array.
|
| 328 |
*/
|
| 329 |
protected function add_additional_fields_schema( $schema ) {
|
| 330 |
-
if (
|
| 331 |
return $schema;
|
| 332 |
}
|
| 333 |
|
|
@@ -446,7 +445,7 @@ abstract class WP_REST_Controller {
|
|
| 446 |
* @param mixed $value
|
| 447 |
* @param WP_REST_Request $request
|
| 448 |
* @param string $parameter
|
| 449 |
-
* @return WP_Error|
|
| 450 |
*/
|
| 451 |
public function validate_schema_property( $value, $request, $parameter ) {
|
| 452 |
|
|
@@ -506,7 +505,7 @@ abstract class WP_REST_Controller {
|
|
| 506 |
* @param mixed $value
|
| 507 |
* @param WP_REST_Request $request
|
| 508 |
* @param string $parameter
|
| 509 |
-
* @return
|
| 510 |
*/
|
| 511 |
public function sanitize_schema_property( $value, $request, $parameter ) {
|
| 512 |
|
| 11 |
}
|
| 12 |
|
| 13 |
/**
|
| 14 |
+
* Check if a given request has access to get items.
|
| 15 |
*
|
| 16 |
* @param WP_REST_Request $request Full data about the request.
|
| 17 |
+
* @return WP_Error|boolean
|
| 18 |
*/
|
| 19 |
+
public function get_items_permissions_check( $request ) {
|
| 20 |
return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be over-ridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) );
|
| 21 |
}
|
| 22 |
|
| 23 |
/**
|
| 24 |
+
* Get a collection of items.
|
| 25 |
*
|
| 26 |
* @param WP_REST_Request $request Full data about the request.
|
| 27 |
* @return WP_Error|WP_REST_Response
|
| 28 |
*/
|
| 29 |
+
public function get_items( $request ) {
|
| 30 |
return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be over-ridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) );
|
| 31 |
}
|
| 32 |
|
| 33 |
/**
|
| 34 |
+
* Check if a given request has access to get a specific item.
|
| 35 |
*
|
| 36 |
* @param WP_REST_Request $request Full data about the request.
|
| 37 |
+
* @return WP_Error|boolean
|
| 38 |
*/
|
| 39 |
+
public function get_item_permissions_check( $request ) {
|
| 40 |
return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be over-ridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) );
|
| 41 |
}
|
| 42 |
|
| 43 |
/**
|
| 44 |
+
* Get one item from the collection.
|
| 45 |
*
|
| 46 |
* @param WP_REST_Request $request Full data about the request.
|
| 47 |
* @return WP_Error|WP_REST_Response
|
| 48 |
*/
|
| 49 |
+
public function get_item( $request ) {
|
| 50 |
return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be over-ridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) );
|
| 51 |
}
|
| 52 |
|
| 53 |
/**
|
| 54 |
+
* Check if a given request has access to create items.
|
| 55 |
*
|
| 56 |
* @param WP_REST_Request $request Full data about the request.
|
| 57 |
+
* @return WP_Error|boolean
|
| 58 |
*/
|
| 59 |
+
public function create_item_permissions_check( $request ) {
|
| 60 |
return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be over-ridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) );
|
| 61 |
}
|
| 62 |
|
| 63 |
/**
|
| 64 |
+
* Create one item from the collection.
|
| 65 |
*
|
| 66 |
* @param WP_REST_Request $request Full data about the request.
|
| 67 |
+
* @return WP_Error|WP_REST_Response
|
| 68 |
*/
|
| 69 |
+
public function create_item( $request ) {
|
| 70 |
return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be over-ridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) );
|
| 71 |
}
|
| 72 |
|
| 73 |
/**
|
| 74 |
+
* Check if a given request has access to update a specific item.
|
| 75 |
*
|
| 76 |
* @param WP_REST_Request $request Full data about the request.
|
| 77 |
+
* @return WP_Error|boolean
|
| 78 |
*/
|
| 79 |
+
public function update_item_permissions_check( $request ) {
|
| 80 |
return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be over-ridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) );
|
| 81 |
}
|
| 82 |
|
| 83 |
/**
|
| 84 |
+
* Update one item from the collection.
|
| 85 |
*
|
| 86 |
* @param WP_REST_Request $request Full data about the request.
|
| 87 |
+
* @return WP_Error|WP_REST_Response
|
| 88 |
*/
|
| 89 |
+
public function update_item( $request ) {
|
| 90 |
return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be over-ridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) );
|
| 91 |
}
|
| 92 |
|
| 93 |
/**
|
| 94 |
+
* Check if a given request has access to delete a specific item.
|
| 95 |
*
|
| 96 |
* @param WP_REST_Request $request Full data about the request.
|
| 97 |
+
* @return WP_Error|boolean
|
| 98 |
*/
|
| 99 |
+
public function delete_item_permissions_check( $request ) {
|
| 100 |
return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be over-ridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) );
|
| 101 |
}
|
| 102 |
|
| 103 |
/**
|
| 104 |
+
* Delete one item from the collection.
|
| 105 |
*
|
| 106 |
* @param WP_REST_Request $request Full data about the request.
|
| 107 |
+
* @return WP_Error|WP_REST_Response
|
| 108 |
*/
|
| 109 |
+
public function delete_item( $request ) {
|
| 110 |
return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be over-ridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) );
|
| 111 |
}
|
| 112 |
|
| 125 |
*
|
| 126 |
* @param mixed $item WordPress representation of the item.
|
| 127 |
* @param WP_REST_Request $request Request object.
|
| 128 |
+
* @return WP_REST_Response $response
|
| 129 |
*/
|
| 130 |
public function prepare_item_for_response( $item, $request ) {
|
| 131 |
return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be over-ridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) );
|
| 254 |
'type' => 'string',
|
| 255 |
);
|
| 256 |
$schema = $this->get_item_schema();
|
|
|
|
| 257 |
if ( empty( $schema['properties'] ) ) {
|
| 258 |
return array_merge( $param_details, $args );
|
| 259 |
}
|
| 314 |
continue;
|
| 315 |
}
|
| 316 |
|
| 317 |
+
call_user_func( $field_options['update_callback'], $request[ $field_name ], $object, $field_name, $request, $this->get_object_type() );
|
| 318 |
}
|
| 319 |
}
|
| 320 |
|
| 326 |
* @param array $schema Schema array.
|
| 327 |
*/
|
| 328 |
protected function add_additional_fields_schema( $schema ) {
|
| 329 |
+
if ( empty( $schema['title'] ) ) {
|
| 330 |
return $schema;
|
| 331 |
}
|
| 332 |
|
| 445 |
* @param mixed $value
|
| 446 |
* @param WP_REST_Request $request
|
| 447 |
* @param string $parameter
|
| 448 |
+
* @return WP_Error|boolean
|
| 449 |
*/
|
| 450 |
public function validate_schema_property( $value, $request, $parameter ) {
|
| 451 |
|
| 505 |
* @param mixed $value
|
| 506 |
* @param WP_REST_Request $request
|
| 507 |
* @param string $parameter
|
| 508 |
+
* @return mixed
|
| 509 |
*/
|
| 510 |
public function sanitize_schema_property( $value, $request, $parameter ) {
|
| 511 |
|
lib/endpoints/class-wp-rest-meta-controller.php
CHANGED
|
@@ -71,8 +71,9 @@ abstract class WP_REST_Meta_Controller extends WP_REST_Controller {
|
|
| 71 |
'callback' => array( $this, 'delete_item' ),
|
| 72 |
'permission_callback' => array( $this, 'delete_item_permissions_check' ),
|
| 73 |
'args' => array(
|
| 74 |
-
'force'
|
| 75 |
-
'default'
|
|
|
|
| 76 |
),
|
| 77 |
),
|
| 78 |
),
|
|
@@ -340,7 +341,7 @@ abstract class WP_REST_Meta_Controller extends WP_REST_Controller {
|
|
| 340 |
*
|
| 341 |
* @param array $value The inserted meta data.
|
| 342 |
* @param WP_REST_Request $request The request sent to the API.
|
| 343 |
-
* @param
|
| 344 |
*/
|
| 345 |
do_action( 'rest_insert_meta', $value, $request, false );
|
| 346 |
|
| 71 |
'callback' => array( $this, 'delete_item' ),
|
| 72 |
'permission_callback' => array( $this, 'delete_item_permissions_check' ),
|
| 73 |
'args' => array(
|
| 74 |
+
'force' => array(
|
| 75 |
+
'default' => false,
|
| 76 |
+
'description' => __( 'Required to be true, as resource does not support trashing.' ),
|
| 77 |
),
|
| 78 |
),
|
| 79 |
),
|
| 341 |
*
|
| 342 |
* @param array $value The inserted meta data.
|
| 343 |
* @param WP_REST_Request $request The request sent to the API.
|
| 344 |
+
* @param boolean $creating True when adding meta, false when updating.
|
| 345 |
*/
|
| 346 |
do_action( 'rest_insert_meta', $value, $request, false );
|
| 347 |
|
lib/endpoints/class-wp-rest-post-statuses-controller.php
CHANGED
|
@@ -48,7 +48,7 @@ class WP_REST_Post_Statuses_Controller extends WP_REST_Controller {
|
|
| 48 |
}
|
| 49 |
$data[ $obj->name ] = $this->prepare_response_for_collection( $status );
|
| 50 |
}
|
| 51 |
-
return $data;
|
| 52 |
}
|
| 53 |
|
| 54 |
/**
|
|
@@ -62,7 +62,8 @@ class WP_REST_Post_Statuses_Controller extends WP_REST_Controller {
|
|
| 62 |
if ( empty( $obj ) ) {
|
| 63 |
return new WP_Error( 'rest_status_invalid', __( 'Invalid status.' ), array( 'status' => 404 ) );
|
| 64 |
}
|
| 65 |
-
|
|
|
|
| 66 |
}
|
| 67 |
|
| 68 |
/**
|
|
@@ -88,8 +89,8 @@ class WP_REST_Post_Statuses_Controller extends WP_REST_Controller {
|
|
| 88 |
);
|
| 89 |
|
| 90 |
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
| 91 |
-
$data = $this->filter_response_by_context( $data, $context );
|
| 92 |
$data = $this->add_additional_fields_to_object( $data, $request );
|
|
|
|
| 93 |
|
| 94 |
$response = rest_ensure_response( $data );
|
| 95 |
|
| 48 |
}
|
| 49 |
$data[ $obj->name ] = $this->prepare_response_for_collection( $status );
|
| 50 |
}
|
| 51 |
+
return rest_ensure_response( $data );
|
| 52 |
}
|
| 53 |
|
| 54 |
/**
|
| 62 |
if ( empty( $obj ) ) {
|
| 63 |
return new WP_Error( 'rest_status_invalid', __( 'Invalid status.' ), array( 'status' => 404 ) );
|
| 64 |
}
|
| 65 |
+
$data = $this->prepare_item_for_response( $obj, $request );
|
| 66 |
+
return rest_ensure_response( $data );
|
| 67 |
}
|
| 68 |
|
| 69 |
/**
|
| 89 |
);
|
| 90 |
|
| 91 |
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
|
|
|
| 92 |
$data = $this->add_additional_fields_to_object( $data, $request );
|
| 93 |
+
$data = $this->filter_response_by_context( $data, $context );
|
| 94 |
|
| 95 |
$response = rest_ensure_response( $data );
|
| 96 |
|
lib/endpoints/class-wp-rest-post-types-controller.php
CHANGED
|
@@ -43,7 +43,7 @@ class WP_REST_Post_Types_Controller extends WP_REST_Controller {
|
|
| 43 |
$post_type = $this->prepare_item_for_response( $obj, $request );
|
| 44 |
$data[ $obj->name ] = $this->prepare_response_for_collection( $post_type );
|
| 45 |
}
|
| 46 |
-
return $data;
|
| 47 |
}
|
| 48 |
|
| 49 |
/**
|
|
@@ -63,7 +63,8 @@ class WP_REST_Post_Types_Controller extends WP_REST_Controller {
|
|
| 63 |
if ( 'edit' === $request['context'] && ! current_user_can( $obj->cap->edit_posts ) ) {
|
| 64 |
return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to manage this type.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 65 |
}
|
| 66 |
-
|
|
|
|
| 67 |
}
|
| 68 |
|
| 69 |
/**
|
|
@@ -71,7 +72,7 @@ class WP_REST_Post_Types_Controller extends WP_REST_Controller {
|
|
| 71 |
*
|
| 72 |
* @param stdClass $post_type Post type data
|
| 73 |
* @param WP_REST_Request $request
|
| 74 |
-
* @return
|
| 75 |
*/
|
| 76 |
public function prepare_item_for_response( $post_type, $request ) {
|
| 77 |
$data = array(
|
|
@@ -82,8 +83,8 @@ class WP_REST_Post_Types_Controller extends WP_REST_Controller {
|
|
| 82 |
'slug' => $post_type->name,
|
| 83 |
);
|
| 84 |
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
| 85 |
-
$data = $this->filter_response_by_context( $data, $context );
|
| 86 |
$data = $this->add_additional_fields_to_object( $data, $request );
|
|
|
|
| 87 |
|
| 88 |
// Wrap the data in a response object.
|
| 89 |
$response = rest_ensure_response( $data );
|
| 43 |
$post_type = $this->prepare_item_for_response( $obj, $request );
|
| 44 |
$data[ $obj->name ] = $this->prepare_response_for_collection( $post_type );
|
| 45 |
}
|
| 46 |
+
return rest_ensure_response( $data );
|
| 47 |
}
|
| 48 |
|
| 49 |
/**
|
| 63 |
if ( 'edit' === $request['context'] && ! current_user_can( $obj->cap->edit_posts ) ) {
|
| 64 |
return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to manage this type.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 65 |
}
|
| 66 |
+
$data = $this->prepare_item_for_response( $obj, $request );
|
| 67 |
+
return rest_ensure_response( $data );
|
| 68 |
}
|
| 69 |
|
| 70 |
/**
|
| 72 |
*
|
| 73 |
* @param stdClass $post_type Post type data
|
| 74 |
* @param WP_REST_Request $request
|
| 75 |
+
* @return WP_REST_Response $response
|
| 76 |
*/
|
| 77 |
public function prepare_item_for_response( $post_type, $request ) {
|
| 78 |
$data = array(
|
| 83 |
'slug' => $post_type->name,
|
| 84 |
);
|
| 85 |
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
|
|
|
| 86 |
$data = $this->add_additional_fields_to_object( $data, $request );
|
| 87 |
+
$data = $this->filter_response_by_context( $data, $context );
|
| 88 |
|
| 89 |
// Wrap the data in a response object.
|
| 90 |
$response = rest_ensure_response( $data );
|
lib/endpoints/class-wp-rest-posts-controller.php
CHANGED
|
@@ -53,6 +53,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 53 |
'args' => array(
|
| 54 |
'force' => array(
|
| 55 |
'default' => false,
|
|
|
|
| 56 |
),
|
| 57 |
),
|
| 58 |
),
|
|
@@ -61,6 +62,23 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 61 |
) );
|
| 62 |
}
|
| 63 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
/**
|
| 65 |
* Get a collection of posts.
|
| 66 |
*
|
|
@@ -68,16 +86,20 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 68 |
* @return WP_Error|WP_REST_Response
|
| 69 |
*/
|
| 70 |
public function get_items( $request ) {
|
| 71 |
-
$args
|
| 72 |
-
$args['author']
|
| 73 |
-
$args['
|
| 74 |
-
$args['
|
| 75 |
-
$args['
|
| 76 |
-
$args['
|
| 77 |
-
$args['
|
| 78 |
-
$args['
|
| 79 |
-
$args['
|
| 80 |
-
$args['
|
|
|
|
|
|
|
|
|
|
|
|
|
| 81 |
|
| 82 |
if ( is_array( $request['filter'] ) ) {
|
| 83 |
$args = array_merge( $args, $request['filter'] );
|
|
@@ -93,10 +115,12 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 93 |
* Enables adding extra arguments or setting defaults for a post
|
| 94 |
* collection request.
|
| 95 |
*
|
|
|
|
|
|
|
| 96 |
* @param array $args Key value array of query var to query value.
|
| 97 |
* @param WP_REST_Request $request The request used.
|
| 98 |
*/
|
| 99 |
-
$args = apply_filters(
|
| 100 |
$query_args = $this->prepare_items_query( $args );
|
| 101 |
|
| 102 |
$posts_query = new WP_Query();
|
|
@@ -112,17 +136,21 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 112 |
$posts[] = $this->prepare_response_for_collection( $data );
|
| 113 |
}
|
| 114 |
|
| 115 |
-
$response = rest_ensure_response( $posts );
|
| 116 |
-
$count_query = new WP_Query();
|
| 117 |
-
|
| 118 |
-
// Store paged value for pagination headers then unset for count query.
|
| 119 |
$page = (int) $query_args['paged'];
|
| 120 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
|
| 122 |
-
$query_result = $count_query->query( $query_args );
|
| 123 |
-
$total_posts = $count_query->found_posts;
|
| 124 |
-
$response->header( 'X-WP-Total', (int) $total_posts );
|
| 125 |
$max_pages = ceil( $total_posts / (int) $query_args['posts_per_page'] );
|
|
|
|
|
|
|
|
|
|
| 126 |
$response->header( 'X-WP-TotalPages', (int) $max_pages );
|
| 127 |
|
| 128 |
$request_params = $request->get_query_params();
|
|
@@ -150,6 +178,27 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 150 |
return $response;
|
| 151 |
}
|
| 152 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 153 |
/**
|
| 154 |
* Get a single post.
|
| 155 |
*
|
|
@@ -172,6 +221,34 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 172 |
return $response;
|
| 173 |
}
|
| 174 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 175 |
/**
|
| 176 |
* Create a single post.
|
| 177 |
*
|
|
@@ -212,8 +289,8 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 212 |
}
|
| 213 |
}
|
| 214 |
|
| 215 |
-
if ( ! empty( $schema['properties']['
|
| 216 |
-
$this->
|
| 217 |
}
|
| 218 |
|
| 219 |
if ( ! empty( $schema['properties']['format'] ) && ! empty( $request['format'] ) ) {
|
|
@@ -223,22 +300,25 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 223 |
if ( ! empty( $schema['properties']['template'] ) && isset( $request['template'] ) ) {
|
| 224 |
$this->handle_template( $request['template'], $post->ID );
|
| 225 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 226 |
|
| 227 |
-
$
|
|
|
|
| 228 |
|
| 229 |
/**
|
| 230 |
* Fires after a single post is created or updated via the REST API.
|
| 231 |
*
|
| 232 |
* @param object $post Inserted Post object (not a WP_Post object).
|
| 233 |
* @param WP_REST_Request $request Request object.
|
| 234 |
-
* @param
|
| 235 |
*/
|
| 236 |
-
do_action(
|
| 237 |
|
| 238 |
-
$
|
| 239 |
-
$
|
| 240 |
-
$get_request->set_param( 'context', 'edit' );
|
| 241 |
-
$response = $this->get_item( $get_request );
|
| 242 |
$response = rest_ensure_response( $response );
|
| 243 |
$response->set_status( 201 );
|
| 244 |
$response->header( 'Location', rest_url( '/wp/v2/' . $this->get_post_type_base( $post->post_type ) . '/' . $post_id ) );
|
|
@@ -246,6 +326,36 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 246 |
return $response;
|
| 247 |
}
|
| 248 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 249 |
/**
|
| 250 |
* Update a single post.
|
| 251 |
*
|
|
@@ -281,8 +391,8 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 281 |
set_post_format( $post, $request['format'] );
|
| 282 |
}
|
| 283 |
|
| 284 |
-
if ( ! empty( $schema['properties']['
|
| 285 |
-
$this->
|
| 286 |
}
|
| 287 |
|
| 288 |
if ( ! empty( $schema['properties']['sticky'] ) && isset( $request['sticky'] ) ) {
|
|
@@ -297,25 +407,39 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 297 |
$this->handle_template( $request['template'], $post->ID );
|
| 298 |
}
|
| 299 |
|
| 300 |
-
$this->
|
|
|
|
|
|
|
|
|
|
| 301 |
|
| 302 |
-
|
| 303 |
-
|
| 304 |
-
* Media Controller has been migrated to new style.
|
| 305 |
-
*
|
| 306 |
-
* do_action( 'rest_insert_post', $post, $request );
|
| 307 |
-
*/
|
| 308 |
|
| 309 |
/* This action is documented in lib/endpoints/class-wp-rest-controller.php */
|
| 310 |
-
do_action(
|
| 311 |
|
| 312 |
-
$
|
| 313 |
-
$
|
| 314 |
-
$get_request->set_param( 'context', 'edit' );
|
| 315 |
-
$response = $this->get_item( $get_request );
|
| 316 |
return rest_ensure_response( $response );
|
| 317 |
}
|
| 318 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 319 |
/**
|
| 320 |
* Delete a single post.
|
| 321 |
*
|
|
@@ -345,15 +469,14 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 345 |
* @param boolean $supports_trash Whether the post type support trashing.
|
| 346 |
* @param WP_Post $post The Post object being considered for trashing support.
|
| 347 |
*/
|
| 348 |
-
$supports_trash = apply_filters(
|
| 349 |
|
| 350 |
if ( ! $this->check_delete_permission( $post ) ) {
|
| 351 |
return new WP_Error( 'rest_user_cannot_delete_post', __( 'Sorry, you are not allowed to delete this post.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 352 |
}
|
| 353 |
|
| 354 |
-
$request = new WP_REST_Request( 'GET', '/wp/v2/' . $this->get_post_type_base( $this->post_type ) . '/' . $post->ID );
|
| 355 |
$request->set_param( 'context', 'edit' );
|
| 356 |
-
$response =
|
| 357 |
|
| 358 |
// If we're forcing, then delete permanently.
|
| 359 |
if ( $force ) {
|
|
@@ -367,7 +490,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 367 |
|
| 368 |
// Otherwise, only trash if we haven't already.
|
| 369 |
if ( 'trash' === $post->post_status ) {
|
| 370 |
-
return new WP_Error( '
|
| 371 |
}
|
| 372 |
|
| 373 |
// (Note that internally this falls through to `wp_delete_post` if
|
|
@@ -394,121 +517,11 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 394 |
* @param array $data The response data.
|
| 395 |
* @param WP_REST_Request $request The request sent to the API.
|
| 396 |
*/
|
| 397 |
-
do_action(
|
| 398 |
|
| 399 |
return $response;
|
| 400 |
}
|
| 401 |
|
| 402 |
-
/**
|
| 403 |
-
* Check if a given request has access to read /posts.
|
| 404 |
-
*
|
| 405 |
-
* @param WP_REST_Request $request Full details about the request.
|
| 406 |
-
* @return bool|WP_Error
|
| 407 |
-
*/
|
| 408 |
-
public function get_items_permissions_check( $request ) {
|
| 409 |
-
|
| 410 |
-
$post_type = get_post_type_object( $this->post_type );
|
| 411 |
-
|
| 412 |
-
if ( 'edit' === $request['context'] && ! current_user_can( $post_type->cap->edit_posts ) ) {
|
| 413 |
-
return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit these posts in this post type' ), array( 'status' => rest_authorization_required_code() ) );
|
| 414 |
-
}
|
| 415 |
-
|
| 416 |
-
return true;
|
| 417 |
-
}
|
| 418 |
-
|
| 419 |
-
/**
|
| 420 |
-
* Check if a given request has access to read a post.
|
| 421 |
-
*
|
| 422 |
-
* @param WP_REST_Request $request Full details about the request.
|
| 423 |
-
* @return bool|WP_Error
|
| 424 |
-
*/
|
| 425 |
-
public function get_item_permissions_check( $request ) {
|
| 426 |
-
|
| 427 |
-
$post = get_post( (int) $request['id'] );
|
| 428 |
-
|
| 429 |
-
if ( 'edit' === $request['context'] && $post && ! $this->check_update_permission( $post ) ) {
|
| 430 |
-
return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit this post' ), array( 'status' => rest_authorization_required_code() ) );
|
| 431 |
-
}
|
| 432 |
-
|
| 433 |
-
if ( $post ) {
|
| 434 |
-
return $this->check_read_permission( $post );
|
| 435 |
-
}
|
| 436 |
-
|
| 437 |
-
return true;
|
| 438 |
-
}
|
| 439 |
-
|
| 440 |
-
/**
|
| 441 |
-
* Check if a given request has access to create a post.
|
| 442 |
-
*
|
| 443 |
-
* @param WP_REST_Request $request Full details about the request.
|
| 444 |
-
* @return bool|WP_Error
|
| 445 |
-
*/
|
| 446 |
-
public function create_item_permissions_check( $request ) {
|
| 447 |
-
|
| 448 |
-
$post_type = get_post_type_object( $this->post_type );
|
| 449 |
-
|
| 450 |
-
if ( ! empty( $request['password'] ) && ! current_user_can( $post_type->cap->publish_posts ) ) {
|
| 451 |
-
return new WP_Error( 'rest_cannot_publish', __( 'Sorry, you are not allowed to create password protected posts in this post type' ), array( 'status' => rest_authorization_required_code() ) );
|
| 452 |
-
}
|
| 453 |
-
|
| 454 |
-
if ( ! empty( $request['author'] ) && get_current_user_id() !== $request['author'] && ! current_user_can( $post_type->cap->edit_others_posts ) ) {
|
| 455 |
-
return new WP_Error( 'rest_cannot_edit_others', __( 'You are not allowed to create posts as this user.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 456 |
-
}
|
| 457 |
-
|
| 458 |
-
if ( ! empty( $request['sticky'] ) && ! current_user_can( $post_type->cap->edit_others_posts ) ) {
|
| 459 |
-
return new WP_Error( 'rest_cannot_assign_sticky', __( 'You do not have permission to make posts sticky.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 460 |
-
}
|
| 461 |
-
|
| 462 |
-
return current_user_can( $post_type->cap->create_posts );
|
| 463 |
-
}
|
| 464 |
-
|
| 465 |
-
/**
|
| 466 |
-
* Check if a given request has access to update a post.
|
| 467 |
-
*
|
| 468 |
-
* @param WP_REST_Request $request Full details about the request.
|
| 469 |
-
* @return bool|WP_Error
|
| 470 |
-
*/
|
| 471 |
-
public function update_item_permissions_check( $request ) {
|
| 472 |
-
|
| 473 |
-
$post = get_post( $request['id'] );
|
| 474 |
-
$post_type = get_post_type_object( $this->post_type );
|
| 475 |
-
|
| 476 |
-
if ( $post && ! $this->check_update_permission( $post ) ) {
|
| 477 |
-
return false;
|
| 478 |
-
}
|
| 479 |
-
|
| 480 |
-
if ( ! empty( $request['password'] ) && ! current_user_can( $post_type->cap->publish_posts ) ) {
|
| 481 |
-
return new WP_Error( 'rest_cannot_publish', __( 'Sorry, you are not allowed to create password protected posts in this post type' ), array( 'status' => rest_authorization_required_code() ) );
|
| 482 |
-
}
|
| 483 |
-
|
| 484 |
-
if ( ! empty( $request['author'] ) && get_current_user_id() !== $request['author'] && ! current_user_can( $post_type->cap->edit_others_posts ) ) {
|
| 485 |
-
return new WP_Error( 'rest_cannot_edit_others', __( 'You are not allowed to update posts as this user.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 486 |
-
}
|
| 487 |
-
|
| 488 |
-
if ( ! empty( $request['sticky'] ) && ! current_user_can( $post_type->cap->edit_others_posts ) ) {
|
| 489 |
-
return new WP_Error( 'rest_cannot_assign_sticky', __( 'You do not have permission to make posts sticky.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 490 |
-
}
|
| 491 |
-
|
| 492 |
-
return true;
|
| 493 |
-
}
|
| 494 |
-
|
| 495 |
-
/**
|
| 496 |
-
* Check if a given request has access to delete a post.
|
| 497 |
-
*
|
| 498 |
-
* @param WP_REST_Request $request Full details about the request.
|
| 499 |
-
* @return bool|WP_Error
|
| 500 |
-
*/
|
| 501 |
-
public function delete_item_permissions_check( $request ) {
|
| 502 |
-
|
| 503 |
-
$post = get_post( $request['id'] );
|
| 504 |
-
|
| 505 |
-
if ( $post && ! $this->check_delete_permission( $post ) ) {
|
| 506 |
-
return new WP_Error( 'rest_cannot_delete', __( 'Sorry, you are not allowed to delete posts.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 507 |
-
}
|
| 508 |
-
|
| 509 |
-
return true;
|
| 510 |
-
}
|
| 511 |
-
|
| 512 |
/**
|
| 513 |
* Determine the allowed query_vars for a get_items() response and
|
| 514 |
* prepare for WP_Query.
|
|
@@ -534,10 +547,6 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 534 |
}
|
| 535 |
}
|
| 536 |
|
| 537 |
-
if ( empty( $query_args['post_status'] ) && 'attachment' === $this->post_type ) {
|
| 538 |
-
$query_args['post_status'] = 'inherit';
|
| 539 |
-
}
|
| 540 |
-
|
| 541 |
if ( 'post' !== $this->post_type || ! isset( $query_args['ignore_sticky_posts'] ) ) {
|
| 542 |
$query_args['ignore_sticky_posts'] = true;
|
| 543 |
}
|
|
@@ -585,7 +594,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 585 |
$valid_vars = array_merge( $valid_vars, $private );
|
| 586 |
}
|
| 587 |
// Define our own in addition to WP's normal vars.
|
| 588 |
-
$rest_valid = array( 'post__in', 'posts_per_page', 'ignore_sticky_posts', 'post_parent' );
|
| 589 |
$valid_vars = array_merge( $valid_vars, $rest_valid );
|
| 590 |
|
| 591 |
/**
|
|
@@ -636,14 +645,17 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 636 |
* @return string|null ISO8601/RFC3339 formatted datetime.
|
| 637 |
*/
|
| 638 |
protected function prepare_date_response( $date_gmt, $date = null ) {
|
| 639 |
-
|
| 640 |
-
return null;
|
| 641 |
-
}
|
| 642 |
-
|
| 643 |
if ( isset( $date ) ) {
|
| 644 |
return mysql_to_rfc3339( $date );
|
| 645 |
}
|
| 646 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 647 |
return mysql_to_rfc3339( $date_gmt );
|
| 648 |
}
|
| 649 |
|
|
@@ -746,12 +758,14 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 746 |
|
| 747 |
// Author
|
| 748 |
if ( ! empty( $schema['properties']['author'] ) && ! empty( $request['author'] ) ) {
|
| 749 |
-
$
|
| 750 |
-
if (
|
| 751 |
-
|
|
|
|
|
|
|
|
|
|
| 752 |
}
|
| 753 |
-
|
| 754 |
-
$prepared_post->post_author = $author;
|
| 755 |
}
|
| 756 |
|
| 757 |
// Post password.
|
|
@@ -774,7 +788,6 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 774 |
}
|
| 775 |
|
| 776 |
// Parent.
|
| 777 |
-
$post_type_obj = get_post_type_object( $this->post_type );
|
| 778 |
if ( ! empty( $schema['properties']['parent'] ) && ! empty( $request['parent'] ) ) {
|
| 779 |
$parent = get_post( (int) $request['parent'] );
|
| 780 |
if ( empty( $parent ) ) {
|
|
@@ -820,7 +833,6 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 820 |
* @return WP_Error|string $post_status
|
| 821 |
*/
|
| 822 |
protected function handle_status_param( $post_status, $post_type ) {
|
| 823 |
-
$post_status = $post_status;
|
| 824 |
|
| 825 |
switch ( $post_status ) {
|
| 826 |
case 'draft':
|
|
@@ -848,50 +860,20 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 848 |
}
|
| 849 |
|
| 850 |
/**
|
| 851 |
-
* Determine
|
| 852 |
-
*
|
| 853 |
-
* @param object|integer $post_author
|
| 854 |
-
* @param object $post_type
|
| 855 |
-
* @return WP_Error|integer $post_author
|
| 856 |
-
*/
|
| 857 |
-
protected function handle_author_param( $post_author, $post_type ) {
|
| 858 |
-
if ( is_object( $post_author ) ) {
|
| 859 |
-
if ( empty( $post_author->id ) ) {
|
| 860 |
-
return new WP_Error( 'rest_invalid_author', __( 'Invalid author object.' ), array( 'status' => 400 ) );
|
| 861 |
-
}
|
| 862 |
-
$post_author = (int) $post_author->id;
|
| 863 |
-
} else {
|
| 864 |
-
$post_author = (int) $post_author;
|
| 865 |
-
}
|
| 866 |
-
|
| 867 |
-
// Only check edit others' posts if we are another user.
|
| 868 |
-
if ( get_current_user_id() !== $post_author ) {
|
| 869 |
-
|
| 870 |
-
$author = get_userdata( $post_author );
|
| 871 |
-
|
| 872 |
-
if ( ! $author ) {
|
| 873 |
-
return new WP_Error( 'rest_invalid_author', __( 'Invalid author id.' ), array( 'status' => 400 ) );
|
| 874 |
-
}
|
| 875 |
-
}
|
| 876 |
-
|
| 877 |
-
return $post_author;
|
| 878 |
-
}
|
| 879 |
-
|
| 880 |
-
/**
|
| 881 |
-
* Determine the featured image based on a request param.
|
| 882 |
*
|
| 883 |
-
* @param int $
|
| 884 |
* @param int $post_id
|
| 885 |
*/
|
| 886 |
-
protected function
|
| 887 |
|
| 888 |
-
$
|
| 889 |
-
if ( $
|
| 890 |
-
$result = set_post_thumbnail( $post_id, $
|
| 891 |
if ( $result ) {
|
| 892 |
return true;
|
| 893 |
} else {
|
| 894 |
-
return new WP_Error( '
|
| 895 |
}
|
| 896 |
} else {
|
| 897 |
return delete_post_thumbnail( $post_id );
|
|
@@ -913,11 +895,34 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 913 |
}
|
| 914 |
}
|
| 915 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 916 |
/**
|
| 917 |
* Check if a given post type should be viewed or managed.
|
| 918 |
*
|
| 919 |
* @param object|string $post_type
|
| 920 |
-
* @return
|
| 921 |
*/
|
| 922 |
protected function check_is_post_type_allowed( $post_type ) {
|
| 923 |
if ( ! is_object( $post_type ) ) {
|
|
@@ -937,7 +942,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 937 |
* Correctly handles posts with the inherit status.
|
| 938 |
*
|
| 939 |
* @param object $post Post object.
|
| 940 |
-
* @return
|
| 941 |
*/
|
| 942 |
public function check_read_permission( $post ) {
|
| 943 |
if ( ! empty( $post->post_password ) && ! $this->check_update_permission( $post ) ) {
|
|
@@ -978,7 +983,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 978 |
* Check if we can edit a post.
|
| 979 |
*
|
| 980 |
* @param object $post Post object.
|
| 981 |
-
* @return
|
| 982 |
*/
|
| 983 |
protected function check_update_permission( $post ) {
|
| 984 |
$post_type = get_post_type_object( $post->post_type );
|
|
@@ -994,7 +999,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 994 |
* Check if we can create a post.
|
| 995 |
*
|
| 996 |
* @param object $post Post object.
|
| 997 |
-
* @return
|
| 998 |
*/
|
| 999 |
protected function check_create_permission( $post ) {
|
| 1000 |
$post_type = get_post_type_object( $post->post_type );
|
|
@@ -1010,7 +1015,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 1010 |
* Check if we can delete a post.
|
| 1011 |
*
|
| 1012 |
* @param object $post Post object.
|
| 1013 |
-
* @return
|
| 1014 |
*/
|
| 1015 |
protected function check_delete_permission( $post ) {
|
| 1016 |
$post_type = get_post_type_object( $post->post_type );
|
|
@@ -1106,8 +1111,8 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 1106 |
$data['author'] = (int) $post->post_author;
|
| 1107 |
}
|
| 1108 |
|
| 1109 |
-
if ( ! empty( $schema['properties']['
|
| 1110 |
-
$data['
|
| 1111 |
}
|
| 1112 |
|
| 1113 |
if ( ! empty( $schema['properties']['parent'] ) ) {
|
|
@@ -1146,10 +1151,15 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 1146 |
}
|
| 1147 |
}
|
| 1148 |
|
| 1149 |
-
$
|
| 1150 |
-
|
|
|
|
|
|
|
|
|
|
| 1151 |
|
|
|
|
| 1152 |
$data = $this->add_additional_fields_to_object( $data, $request );
|
|
|
|
| 1153 |
|
| 1154 |
// Wrap the data in a response object.
|
| 1155 |
$response = rest_ensure_response( $data );
|
|
@@ -1166,7 +1176,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 1166 |
* @param WP_Post $post Post object.
|
| 1167 |
* @param WP_REST_Request $request Request object.
|
| 1168 |
*/
|
| 1169 |
-
return apply_filters(
|
| 1170 |
}
|
| 1171 |
|
| 1172 |
/**
|
|
@@ -1221,9 +1231,9 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 1221 |
);
|
| 1222 |
}
|
| 1223 |
|
| 1224 |
-
// If we have a featured
|
| 1225 |
-
if ( $
|
| 1226 |
-
$image_url = rest_url( 'wp/v2/media/' . $
|
| 1227 |
$links['https://api.w.org/featuredmedia'] = array(
|
| 1228 |
'href' => $image_url,
|
| 1229 |
'embeddable' => true,
|
|
@@ -1244,12 +1254,16 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 1244 |
foreach ( $taxonomies as $tax ) {
|
| 1245 |
$taxonomy_obj = get_taxonomy( $tax );
|
| 1246 |
// Skip taxonomies that are not public.
|
| 1247 |
-
if (
|
| 1248 |
continue;
|
| 1249 |
}
|
| 1250 |
|
| 1251 |
$tax_base = ! empty( $taxonomy_obj->rest_base ) ? $taxonomy_obj->rest_base : $tax;
|
| 1252 |
-
$terms_url =
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1253 |
|
| 1254 |
$links['https://api.w.org/term'][] = array(
|
| 1255 |
'href' => $terms_url,
|
|
@@ -1276,7 +1290,6 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 1276 |
*/
|
| 1277 |
public function get_item_schema() {
|
| 1278 |
|
| 1279 |
-
$base = $this->get_post_type_base( $this->post_type );
|
| 1280 |
$schema = array(
|
| 1281 |
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
| 1282 |
'title' => $this->post_type,
|
|
@@ -1496,8 +1509,8 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 1496 |
break;
|
| 1497 |
|
| 1498 |
case 'thumbnail':
|
| 1499 |
-
$schema['properties']['
|
| 1500 |
-
'description' => __( 'The id of the featured
|
| 1501 |
'type' => 'integer',
|
| 1502 |
'context' => array( 'view', 'edit' ),
|
| 1503 |
);
|
|
@@ -1555,6 +1568,16 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 1555 |
);
|
| 1556 |
}
|
| 1557 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1558 |
return $this->add_additional_fields_schema( $schema );
|
| 1559 |
}
|
| 1560 |
|
|
@@ -1576,12 +1599,23 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 1576 |
'sanitize_callback' => 'absint',
|
| 1577 |
);
|
| 1578 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1579 |
$params['include'] = array(
|
| 1580 |
'description' => __( 'Limit result set to specific ids.' ),
|
| 1581 |
'type' => 'array',
|
| 1582 |
'default' => array(),
|
| 1583 |
'sanitize_callback' => 'wp_parse_id_list',
|
| 1584 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1585 |
$params['order'] = array(
|
| 1586 |
'description' => __( 'Order sort attribute ascending or descending.' ),
|
| 1587 |
'type' => 'string',
|
|
@@ -1602,17 +1636,27 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 1602 |
);
|
| 1603 |
|
| 1604 |
$post_type_obj = get_post_type_object( $this->post_type );
|
| 1605 |
-
if ( $post_type_obj->hierarchical ) {
|
| 1606 |
$params['parent'] = array(
|
| 1607 |
-
'description' => _( 'Limit result set to
|
| 1608 |
-
'type' => '
|
| 1609 |
-
'sanitize_callback' => '
|
| 1610 |
-
'default' =>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1611 |
);
|
| 1612 |
}
|
| 1613 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1614 |
$params['status'] = array(
|
| 1615 |
-
'default' => '
|
| 1616 |
'description' => __( 'Limit result set to posts assigned a specific status.' ),
|
| 1617 |
'sanitize_callback' => 'sanitize_key',
|
| 1618 |
'type' => 'string',
|
|
@@ -1630,10 +1674,10 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
| 1630 |
* @param mixed $value
|
| 1631 |
* @param WP_REST_Request $request
|
| 1632 |
* @param string $parameter
|
| 1633 |
-
* @return WP_Error|
|
| 1634 |
*/
|
| 1635 |
public function validate_user_can_query_private_statuses( $value, $request, $parameter ) {
|
| 1636 |
-
if ( 'publish' === $value
|
| 1637 |
return true;
|
| 1638 |
}
|
| 1639 |
$post_type_obj = get_post_type_object( $this->post_type );
|
| 53 |
'args' => array(
|
| 54 |
'force' => array(
|
| 55 |
'default' => false,
|
| 56 |
+
'description' => __( 'Whether to bypass trash and force deletion.' ),
|
| 57 |
),
|
| 58 |
),
|
| 59 |
),
|
| 62 |
) );
|
| 63 |
}
|
| 64 |
|
| 65 |
+
/**
|
| 66 |
+
* Check if a given request has access to read /posts.
|
| 67 |
+
*
|
| 68 |
+
* @param WP_REST_Request $request Full details about the request.
|
| 69 |
+
* @return WP_Error|boolean
|
| 70 |
+
*/
|
| 71 |
+
public function get_items_permissions_check( $request ) {
|
| 72 |
+
|
| 73 |
+
$post_type = get_post_type_object( $this->post_type );
|
| 74 |
+
|
| 75 |
+
if ( 'edit' === $request['context'] && ! current_user_can( $post_type->cap->edit_posts ) ) {
|
| 76 |
+
return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit these posts in this post type' ), array( 'status' => rest_authorization_required_code() ) );
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
return true;
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
/**
|
| 83 |
* Get a collection of posts.
|
| 84 |
*
|
| 86 |
* @return WP_Error|WP_REST_Response
|
| 87 |
*/
|
| 88 |
public function get_items( $request ) {
|
| 89 |
+
$args = array();
|
| 90 |
+
$args['author'] = $request['author'];
|
| 91 |
+
$args['offset'] = $request['offset'];
|
| 92 |
+
$args['order'] = $request['order'];
|
| 93 |
+
$args['orderby'] = $request['orderby'];
|
| 94 |
+
$args['paged'] = $request['page'];
|
| 95 |
+
$args['post__in'] = $request['include'];
|
| 96 |
+
$args['post__not_in'] = $request['exclude'];
|
| 97 |
+
$args['posts_per_page'] = $request['per_page'];
|
| 98 |
+
$args['name'] = $request['slug'];
|
| 99 |
+
$args['post_parent__in'] = $request['parent'];
|
| 100 |
+
$args['post_parent__not_in'] = $request['parent_exclude'];
|
| 101 |
+
$args['post_status'] = $request['status'];
|
| 102 |
+
$args['s'] = $request['search'];
|
| 103 |
|
| 104 |
if ( is_array( $request['filter'] ) ) {
|
| 105 |
$args = array_merge( $args, $request['filter'] );
|
| 115 |
* Enables adding extra arguments or setting defaults for a post
|
| 116 |
* collection request.
|
| 117 |
*
|
| 118 |
+
* @see https://developer.wordpress.org/reference/classes/wp_user_query/
|
| 119 |
+
*
|
| 120 |
* @param array $args Key value array of query var to query value.
|
| 121 |
* @param WP_REST_Request $request The request used.
|
| 122 |
*/
|
| 123 |
+
$args = apply_filters( "rest_{$this->post_type}_query", $args, $request );
|
| 124 |
$query_args = $this->prepare_items_query( $args );
|
| 125 |
|
| 126 |
$posts_query = new WP_Query();
|
| 136 |
$posts[] = $this->prepare_response_for_collection( $data );
|
| 137 |
}
|
| 138 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 139 |
$page = (int) $query_args['paged'];
|
| 140 |
+
$total_posts = $posts_query->found_posts;
|
| 141 |
+
|
| 142 |
+
if ( $total_posts < 1 ) {
|
| 143 |
+
// Out-of-bounds, run the query again without LIMIT for total count
|
| 144 |
+
unset( $query_args['paged'] );
|
| 145 |
+
$count_query = new WP_Query();
|
| 146 |
+
$count_query->query( $query_args );
|
| 147 |
+
$total_posts = $count_query->found_posts;
|
| 148 |
+
}
|
| 149 |
|
|
|
|
|
|
|
|
|
|
| 150 |
$max_pages = ceil( $total_posts / (int) $query_args['posts_per_page'] );
|
| 151 |
+
|
| 152 |
+
$response = rest_ensure_response( $posts );
|
| 153 |
+
$response->header( 'X-WP-Total', (int) $total_posts );
|
| 154 |
$response->header( 'X-WP-TotalPages', (int) $max_pages );
|
| 155 |
|
| 156 |
$request_params = $request->get_query_params();
|
| 178 |
return $response;
|
| 179 |
}
|
| 180 |
|
| 181 |
+
/**
|
| 182 |
+
* Check if a given request has access to read a post.
|
| 183 |
+
*
|
| 184 |
+
* @param WP_REST_Request $request Full details about the request.
|
| 185 |
+
* @return WP_Error|boolean
|
| 186 |
+
*/
|
| 187 |
+
public function get_item_permissions_check( $request ) {
|
| 188 |
+
|
| 189 |
+
$post = get_post( (int) $request['id'] );
|
| 190 |
+
|
| 191 |
+
if ( 'edit' === $request['context'] && $post && ! $this->check_update_permission( $post ) ) {
|
| 192 |
+
return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit this post' ), array( 'status' => rest_authorization_required_code() ) );
|
| 193 |
+
}
|
| 194 |
+
|
| 195 |
+
if ( $post ) {
|
| 196 |
+
return $this->check_read_permission( $post );
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
return true;
|
| 200 |
+
}
|
| 201 |
+
|
| 202 |
/**
|
| 203 |
* Get a single post.
|
| 204 |
*
|
| 221 |
return $response;
|
| 222 |
}
|
| 223 |
|
| 224 |
+
/**
|
| 225 |
+
* Check if a given request has access to create a post.
|
| 226 |
+
*
|
| 227 |
+
* @param WP_REST_Request $request Full details about the request.
|
| 228 |
+
* @return WP_Error|boolean
|
| 229 |
+
*/
|
| 230 |
+
public function create_item_permissions_check( $request ) {
|
| 231 |
+
|
| 232 |
+
$post_type = get_post_type_object( $this->post_type );
|
| 233 |
+
|
| 234 |
+
if ( ! empty( $request['password'] ) && ! current_user_can( $post_type->cap->publish_posts ) ) {
|
| 235 |
+
return new WP_Error( 'rest_cannot_publish', __( 'Sorry, you are not allowed to create password protected posts in this post type' ), array( 'status' => rest_authorization_required_code() ) );
|
| 236 |
+
}
|
| 237 |
+
|
| 238 |
+
if ( ! empty( $request['author'] ) && get_current_user_id() !== $request['author'] && ! current_user_can( $post_type->cap->edit_others_posts ) ) {
|
| 239 |
+
return new WP_Error( 'rest_cannot_edit_others', __( 'You are not allowed to create posts as this user.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 240 |
+
}
|
| 241 |
+
|
| 242 |
+
if ( ! empty( $request['sticky'] ) && ! current_user_can( $post_type->cap->edit_others_posts ) ) {
|
| 243 |
+
return new WP_Error( 'rest_cannot_assign_sticky', __( 'You do not have permission to make posts sticky.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 244 |
+
}
|
| 245 |
+
|
| 246 |
+
if ( ! current_user_can( $post_type->cap->create_posts ) ) {
|
| 247 |
+
return new WP_Error( 'rest_cannot_create', __( 'Sorry, you are not allowed to create new posts.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 248 |
+
}
|
| 249 |
+
return true;
|
| 250 |
+
}
|
| 251 |
+
|
| 252 |
/**
|
| 253 |
* Create a single post.
|
| 254 |
*
|
| 289 |
}
|
| 290 |
}
|
| 291 |
|
| 292 |
+
if ( ! empty( $schema['properties']['featured_media'] ) && isset( $request['featured_media'] ) ) {
|
| 293 |
+
$this->handle_featured_media( $request['featured_media'], $post->ID );
|
| 294 |
}
|
| 295 |
|
| 296 |
if ( ! empty( $schema['properties']['format'] ) && ! empty( $request['format'] ) ) {
|
| 300 |
if ( ! empty( $schema['properties']['template'] ) && isset( $request['template'] ) ) {
|
| 301 |
$this->handle_template( $request['template'], $post->ID );
|
| 302 |
}
|
| 303 |
+
$terms_update = $this->handle_terms( $post->ID, $request );
|
| 304 |
+
if ( is_wp_error( $terms_update ) ) {
|
| 305 |
+
return $terms_update;
|
| 306 |
+
}
|
| 307 |
|
| 308 |
+
$post = get_post( $post_id );
|
| 309 |
+
$this->update_additional_fields_for_object( $post, $request );
|
| 310 |
|
| 311 |
/**
|
| 312 |
* Fires after a single post is created or updated via the REST API.
|
| 313 |
*
|
| 314 |
* @param object $post Inserted Post object (not a WP_Post object).
|
| 315 |
* @param WP_REST_Request $request Request object.
|
| 316 |
+
* @param boolean $creating True when creating post, false when updating.
|
| 317 |
*/
|
| 318 |
+
do_action( "rest_insert_{$this->post_type}", $post, $request, true );
|
| 319 |
|
| 320 |
+
$request->set_param( 'context', 'edit' );
|
| 321 |
+
$response = $this->prepare_item_for_response( $post, $request );
|
|
|
|
|
|
|
| 322 |
$response = rest_ensure_response( $response );
|
| 323 |
$response->set_status( 201 );
|
| 324 |
$response->header( 'Location', rest_url( '/wp/v2/' . $this->get_post_type_base( $post->post_type ) . '/' . $post_id ) );
|
| 326 |
return $response;
|
| 327 |
}
|
| 328 |
|
| 329 |
+
/**
|
| 330 |
+
* Check if a given request has access to update a post.
|
| 331 |
+
*
|
| 332 |
+
* @param WP_REST_Request $request Full details about the request.
|
| 333 |
+
* @return WP_Error|boolean
|
| 334 |
+
*/
|
| 335 |
+
public function update_item_permissions_check( $request ) {
|
| 336 |
+
|
| 337 |
+
$post = get_post( $request['id'] );
|
| 338 |
+
$post_type = get_post_type_object( $this->post_type );
|
| 339 |
+
|
| 340 |
+
if ( $post && ! $this->check_update_permission( $post ) ) {
|
| 341 |
+
return new WP_Error( 'rest_cannot_edit', __( 'Sorry, you are not allowed to update this post.' ), array( 'status' => rest_authorization_required_code() ) );;
|
| 342 |
+
}
|
| 343 |
+
|
| 344 |
+
if ( ! empty( $request['password'] ) && ! current_user_can( $post_type->cap->publish_posts ) ) {
|
| 345 |
+
return new WP_Error( 'rest_cannot_publish', __( 'Sorry, you are not allowed to create password protected posts in this post type' ), array( 'status' => rest_authorization_required_code() ) );
|
| 346 |
+
}
|
| 347 |
+
|
| 348 |
+
if ( ! empty( $request['author'] ) && get_current_user_id() !== $request['author'] && ! current_user_can( $post_type->cap->edit_others_posts ) ) {
|
| 349 |
+
return new WP_Error( 'rest_cannot_edit_others', __( 'You are not allowed to update posts as this user.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 350 |
+
}
|
| 351 |
+
|
| 352 |
+
if ( ! empty( $request['sticky'] ) && ! current_user_can( $post_type->cap->edit_others_posts ) ) {
|
| 353 |
+
return new WP_Error( 'rest_cannot_assign_sticky', __( 'You do not have permission to make posts sticky.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 354 |
+
}
|
| 355 |
+
|
| 356 |
+
return true;
|
| 357 |
+
}
|
| 358 |
+
|
| 359 |
/**
|
| 360 |
* Update a single post.
|
| 361 |
*
|
| 391 |
set_post_format( $post, $request['format'] );
|
| 392 |
}
|
| 393 |
|
| 394 |
+
if ( ! empty( $schema['properties']['featured_media'] ) && isset( $request['featured_media'] ) ) {
|
| 395 |
+
$this->handle_featured_media( $request['featured_media'], $post_id );
|
| 396 |
}
|
| 397 |
|
| 398 |
if ( ! empty( $schema['properties']['sticky'] ) && isset( $request['sticky'] ) ) {
|
| 407 |
$this->handle_template( $request['template'], $post->ID );
|
| 408 |
}
|
| 409 |
|
| 410 |
+
$terms_update = $this->handle_terms( $post->ID, $request );
|
| 411 |
+
if ( is_wp_error( $terms_update ) ) {
|
| 412 |
+
return $terms_update;
|
| 413 |
+
}
|
| 414 |
|
| 415 |
+
$post = get_post( $post_id );
|
| 416 |
+
$this->update_additional_fields_for_object( $post, $request );
|
|
|
|
|
|
|
|
|
|
|
|
|
| 417 |
|
| 418 |
/* This action is documented in lib/endpoints/class-wp-rest-controller.php */
|
| 419 |
+
do_action( "rest_insert_{$this->post_type}", $post, $request, false );
|
| 420 |
|
| 421 |
+
$request->set_param( 'context', 'edit' );
|
| 422 |
+
$response = $this->prepare_item_for_response( $post, $request );
|
|
|
|
|
|
|
| 423 |
return rest_ensure_response( $response );
|
| 424 |
}
|
| 425 |
|
| 426 |
+
/**
|
| 427 |
+
* Check if a given request has access to delete a post.
|
| 428 |
+
*
|
| 429 |
+
* @param WP_REST_Request $request Full details about the request.
|
| 430 |
+
* @return bool|WP_Error
|
| 431 |
+
*/
|
| 432 |
+
public function delete_item_permissions_check( $request ) {
|
| 433 |
+
|
| 434 |
+
$post = get_post( $request['id'] );
|
| 435 |
+
|
| 436 |
+
if ( $post && ! $this->check_delete_permission( $post ) ) {
|
| 437 |
+
return new WP_Error( 'rest_cannot_delete', __( 'Sorry, you are not allowed to delete posts.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 438 |
+
}
|
| 439 |
+
|
| 440 |
+
return true;
|
| 441 |
+
}
|
| 442 |
+
|
| 443 |
/**
|
| 444 |
* Delete a single post.
|
| 445 |
*
|
| 469 |
* @param boolean $supports_trash Whether the post type support trashing.
|
| 470 |
* @param WP_Post $post The Post object being considered for trashing support.
|
| 471 |
*/
|
| 472 |
+
$supports_trash = apply_filters( "rest_{$this->post_type}_trashable", $supports_trash, $post );
|
| 473 |
|
| 474 |
if ( ! $this->check_delete_permission( $post ) ) {
|
| 475 |
return new WP_Error( 'rest_user_cannot_delete_post', __( 'Sorry, you are not allowed to delete this post.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 476 |
}
|
| 477 |
|
|
|
|
| 478 |
$request->set_param( 'context', 'edit' );
|
| 479 |
+
$response = $this->prepare_item_for_response( $post, $request );
|
| 480 |
|
| 481 |
// If we're forcing, then delete permanently.
|
| 482 |
if ( $force ) {
|
| 490 |
|
| 491 |
// Otherwise, only trash if we haven't already.
|
| 492 |
if ( 'trash' === $post->post_status ) {
|
| 493 |
+
return new WP_Error( 'rest_already_trashed', __( 'The post has already been deleted.' ), array( 'status' => 410 ) );
|
| 494 |
}
|
| 495 |
|
| 496 |
// (Note that internally this falls through to `wp_delete_post` if
|
| 517 |
* @param array $data The response data.
|
| 518 |
* @param WP_REST_Request $request The request sent to the API.
|
| 519 |
*/
|
| 520 |
+
do_action( "rest_delete_{$this->post_type}", $post, $data, $request );
|
| 521 |
|
| 522 |
return $response;
|
| 523 |
}
|
| 524 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 525 |
/**
|
| 526 |
* Determine the allowed query_vars for a get_items() response and
|
| 527 |
* prepare for WP_Query.
|
| 547 |
}
|
| 548 |
}
|
| 549 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 550 |
if ( 'post' !== $this->post_type || ! isset( $query_args['ignore_sticky_posts'] ) ) {
|
| 551 |
$query_args['ignore_sticky_posts'] = true;
|
| 552 |
}
|
| 594 |
$valid_vars = array_merge( $valid_vars, $private );
|
| 595 |
}
|
| 596 |
// Define our own in addition to WP's normal vars.
|
| 597 |
+
$rest_valid = array( 'offset', 'post__in', 'post__not_in', 'posts_per_page', 'ignore_sticky_posts', 'post_parent', 'post_parent__in', 'post_parent__not_in' );
|
| 598 |
$valid_vars = array_merge( $valid_vars, $rest_valid );
|
| 599 |
|
| 600 |
/**
|
| 645 |
* @return string|null ISO8601/RFC3339 formatted datetime.
|
| 646 |
*/
|
| 647 |
protected function prepare_date_response( $date_gmt, $date = null ) {
|
| 648 |
+
// Use the date if passed.
|
|
|
|
|
|
|
|
|
|
| 649 |
if ( isset( $date ) ) {
|
| 650 |
return mysql_to_rfc3339( $date );
|
| 651 |
}
|
| 652 |
|
| 653 |
+
// Return null if $date_gmt is empty/zeros.
|
| 654 |
+
if ( '0000-00-00 00:00:00' === $date_gmt ) {
|
| 655 |
+
return null;
|
| 656 |
+
}
|
| 657 |
+
|
| 658 |
+
// Return the formatted datetime.
|
| 659 |
return mysql_to_rfc3339( $date_gmt );
|
| 660 |
}
|
| 661 |
|
| 758 |
|
| 759 |
// Author
|
| 760 |
if ( ! empty( $schema['properties']['author'] ) && ! empty( $request['author'] ) ) {
|
| 761 |
+
$post_author = (int) $request['author'];
|
| 762 |
+
if ( get_current_user_id() !== $post_author ) {
|
| 763 |
+
$user_obj = get_userdata( $post_author );
|
| 764 |
+
if ( ! $user_obj ) {
|
| 765 |
+
return new WP_Error( 'rest_invalid_author', __( 'Invalid author id.' ), array( 'status' => 400 ) );
|
| 766 |
+
}
|
| 767 |
}
|
| 768 |
+
$prepared_post->post_author = $post_author;
|
|
|
|
| 769 |
}
|
| 770 |
|
| 771 |
// Post password.
|
| 788 |
}
|
| 789 |
|
| 790 |
// Parent.
|
|
|
|
| 791 |
if ( ! empty( $schema['properties']['parent'] ) && ! empty( $request['parent'] ) ) {
|
| 792 |
$parent = get_post( (int) $request['parent'] );
|
| 793 |
if ( empty( $parent ) ) {
|
| 833 |
* @return WP_Error|string $post_status
|
| 834 |
*/
|
| 835 |
protected function handle_status_param( $post_status, $post_type ) {
|
|
|
|
| 836 |
|
| 837 |
switch ( $post_status ) {
|
| 838 |
case 'draft':
|
| 860 |
}
|
| 861 |
|
| 862 |
/**
|
| 863 |
+
* Determine the featured media based on a request param.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 864 |
*
|
| 865 |
+
* @param int $featured_media
|
| 866 |
* @param int $post_id
|
| 867 |
*/
|
| 868 |
+
protected function handle_featured_media( $featured_media, $post_id ) {
|
| 869 |
|
| 870 |
+
$featured_media = (int) $featured_media;
|
| 871 |
+
if ( $featured_media ) {
|
| 872 |
+
$result = set_post_thumbnail( $post_id, $featured_media );
|
| 873 |
if ( $result ) {
|
| 874 |
return true;
|
| 875 |
} else {
|
| 876 |
+
return new WP_Error( 'rest_invalid_featured_media', __( 'Invalid featured media id.' ), array( 'status' => 400 ) );
|
| 877 |
}
|
| 878 |
} else {
|
| 879 |
return delete_post_thumbnail( $post_id );
|
| 895 |
}
|
| 896 |
}
|
| 897 |
|
| 898 |
+
/**
|
| 899 |
+
* Update the post's terms from a REST request.
|
| 900 |
+
*
|
| 901 |
+
* @param int $post_id The post ID to update the terms form.
|
| 902 |
+
* @param WP_REST_Request $request The request object with post and terms data.
|
| 903 |
+
* @return null|WP_Error WP_Error on an error assigning any of ther terms.
|
| 904 |
+
*/
|
| 905 |
+
protected function handle_terms( $post_id, $request ) {
|
| 906 |
+
$taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) );
|
| 907 |
+
foreach ( $taxonomies as $taxonomy ) {
|
| 908 |
+
$base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
|
| 909 |
+
|
| 910 |
+
if ( ! isset( $request[ $base ] ) ) {
|
| 911 |
+
continue;
|
| 912 |
+
}
|
| 913 |
+
$terms = array_map( 'absint', $request[ $base ] );
|
| 914 |
+
$result = wp_set_object_terms( $post_id, $terms, $taxonomy->name );
|
| 915 |
+
if ( is_wp_error( $result ) ) {
|
| 916 |
+
return $result;
|
| 917 |
+
}
|
| 918 |
+
}
|
| 919 |
+
}
|
| 920 |
+
|
| 921 |
/**
|
| 922 |
* Check if a given post type should be viewed or managed.
|
| 923 |
*
|
| 924 |
* @param object|string $post_type
|
| 925 |
+
* @return boolean Is post type allowed?
|
| 926 |
*/
|
| 927 |
protected function check_is_post_type_allowed( $post_type ) {
|
| 928 |
if ( ! is_object( $post_type ) ) {
|
| 942 |
* Correctly handles posts with the inherit status.
|
| 943 |
*
|
| 944 |
* @param object $post Post object.
|
| 945 |
+
* @return boolean Can we read it?
|
| 946 |
*/
|
| 947 |
public function check_read_permission( $post ) {
|
| 948 |
if ( ! empty( $post->post_password ) && ! $this->check_update_permission( $post ) ) {
|
| 983 |
* Check if we can edit a post.
|
| 984 |
*
|
| 985 |
* @param object $post Post object.
|
| 986 |
+
* @return boolean Can we edit it?
|
| 987 |
*/
|
| 988 |
protected function check_update_permission( $post ) {
|
| 989 |
$post_type = get_post_type_object( $post->post_type );
|
| 999 |
* Check if we can create a post.
|
| 1000 |
*
|
| 1001 |
* @param object $post Post object.
|
| 1002 |
+
* @return boolean Can we create it?.
|
| 1003 |
*/
|
| 1004 |
protected function check_create_permission( $post ) {
|
| 1005 |
$post_type = get_post_type_object( $post->post_type );
|
| 1015 |
* Check if we can delete a post.
|
| 1016 |
*
|
| 1017 |
* @param object $post Post object.
|
| 1018 |
+
* @return boolean Can we delete it?
|
| 1019 |
*/
|
| 1020 |
protected function check_delete_permission( $post ) {
|
| 1021 |
$post_type = get_post_type_object( $post->post_type );
|
| 1111 |
$data['author'] = (int) $post->post_author;
|
| 1112 |
}
|
| 1113 |
|
| 1114 |
+
if ( ! empty( $schema['properties']['featured_media'] ) ) {
|
| 1115 |
+
$data['featured_media'] = (int) get_post_thumbnail_id( $post->ID );
|
| 1116 |
}
|
| 1117 |
|
| 1118 |
if ( ! empty( $schema['properties']['parent'] ) ) {
|
| 1151 |
}
|
| 1152 |
}
|
| 1153 |
|
| 1154 |
+
$taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) );
|
| 1155 |
+
foreach ( $taxonomies as $taxonomy ) {
|
| 1156 |
+
$base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
|
| 1157 |
+
$data[ $base ] = wp_get_object_terms( $post->ID, $taxonomy->name, array( 'fields' => 'ids' ) );
|
| 1158 |
+
}
|
| 1159 |
|
| 1160 |
+
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
| 1161 |
$data = $this->add_additional_fields_to_object( $data, $request );
|
| 1162 |
+
$data = $this->filter_response_by_context( $data, $context );
|
| 1163 |
|
| 1164 |
// Wrap the data in a response object.
|
| 1165 |
$response = rest_ensure_response( $data );
|
| 1176 |
* @param WP_Post $post Post object.
|
| 1177 |
* @param WP_REST_Request $request Request object.
|
| 1178 |
*/
|
| 1179 |
+
return apply_filters( "rest_prepare_{$this->post_type}", $response, $post, $request );
|
| 1180 |
}
|
| 1181 |
|
| 1182 |
/**
|
| 1231 |
);
|
| 1232 |
}
|
| 1233 |
|
| 1234 |
+
// If we have a featured media, add that.
|
| 1235 |
+
if ( $featured_media = get_post_thumbnail_id( $post->ID ) ) {
|
| 1236 |
+
$image_url = rest_url( 'wp/v2/media/' . $featured_media );
|
| 1237 |
$links['https://api.w.org/featuredmedia'] = array(
|
| 1238 |
'href' => $image_url,
|
| 1239 |
'embeddable' => true,
|
| 1254 |
foreach ( $taxonomies as $tax ) {
|
| 1255 |
$taxonomy_obj = get_taxonomy( $tax );
|
| 1256 |
// Skip taxonomies that are not public.
|
| 1257 |
+
if ( empty( $taxonomy_obj->show_in_rest ) ) {
|
| 1258 |
continue;
|
| 1259 |
}
|
| 1260 |
|
| 1261 |
$tax_base = ! empty( $taxonomy_obj->rest_base ) ? $taxonomy_obj->rest_base : $tax;
|
| 1262 |
+
$terms_url = add_query_arg(
|
| 1263 |
+
'post',
|
| 1264 |
+
$post->ID,
|
| 1265 |
+
rest_url( 'wp/v2/' . $tax_base )
|
| 1266 |
+
);
|
| 1267 |
|
| 1268 |
$links['https://api.w.org/term'][] = array(
|
| 1269 |
'href' => $terms_url,
|
| 1290 |
*/
|
| 1291 |
public function get_item_schema() {
|
| 1292 |
|
|
|
|
| 1293 |
$schema = array(
|
| 1294 |
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
| 1295 |
'title' => $this->post_type,
|
| 1509 |
break;
|
| 1510 |
|
| 1511 |
case 'thumbnail':
|
| 1512 |
+
$schema['properties']['featured_media'] = array(
|
| 1513 |
+
'description' => __( 'The id of the featured media for the object.' ),
|
| 1514 |
'type' => 'integer',
|
| 1515 |
'context' => array( 'view', 'edit' ),
|
| 1516 |
);
|
| 1568 |
);
|
| 1569 |
}
|
| 1570 |
|
| 1571 |
+
$taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) );
|
| 1572 |
+
foreach ( $taxonomies as $taxonomy ) {
|
| 1573 |
+
$base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
|
| 1574 |
+
$schema['properties'][ $base ] = array(
|
| 1575 |
+
'description' => sprintf( __( 'The terms assigned to the object in the %s taxonomy.' ), $taxonomy->name ),
|
| 1576 |
+
'type' => 'array',
|
| 1577 |
+
'context' => array( 'view', 'edit' ),
|
| 1578 |
+
);
|
| 1579 |
+
}
|
| 1580 |
+
|
| 1581 |
return $this->add_additional_fields_schema( $schema );
|
| 1582 |
}
|
| 1583 |
|
| 1599 |
'sanitize_callback' => 'absint',
|
| 1600 |
);
|
| 1601 |
}
|
| 1602 |
+
$params['exclude'] = array(
|
| 1603 |
+
'description' => __( 'Ensure result set excludes specific ids.' ),
|
| 1604 |
+
'type' => 'array',
|
| 1605 |
+
'default' => array(),
|
| 1606 |
+
'sanitize_callback' => 'wp_parse_id_list',
|
| 1607 |
+
);
|
| 1608 |
$params['include'] = array(
|
| 1609 |
'description' => __( 'Limit result set to specific ids.' ),
|
| 1610 |
'type' => 'array',
|
| 1611 |
'default' => array(),
|
| 1612 |
'sanitize_callback' => 'wp_parse_id_list',
|
| 1613 |
);
|
| 1614 |
+
$params['offset'] = array(
|
| 1615 |
+
'description' => __( 'Offset the result set by a specific number of items.' ),
|
| 1616 |
+
'type' => 'integer',
|
| 1617 |
+
'sanitize_callback' => 'absint',
|
| 1618 |
+
);
|
| 1619 |
$params['order'] = array(
|
| 1620 |
'description' => __( 'Order sort attribute ascending or descending.' ),
|
| 1621 |
'type' => 'string',
|
| 1636 |
);
|
| 1637 |
|
| 1638 |
$post_type_obj = get_post_type_object( $this->post_type );
|
| 1639 |
+
if ( $post_type_obj->hierarchical || 'attachment' === $this->post_type ) {
|
| 1640 |
$params['parent'] = array(
|
| 1641 |
+
'description' => _( 'Limit result set to those of particular parent ids.' ),
|
| 1642 |
+
'type' => 'array',
|
| 1643 |
+
'sanitize_callback' => 'wp_parse_id_list',
|
| 1644 |
+
'default' => array(),
|
| 1645 |
+
);
|
| 1646 |
+
$params['parent_exclude'] = array(
|
| 1647 |
+
'description' => _( 'Limit result set to all items except those of a particular parent id.' ),
|
| 1648 |
+
'type' => 'array',
|
| 1649 |
+
'sanitize_callback' => 'wp_parse_id_list',
|
| 1650 |
+
'default' => array(),
|
| 1651 |
);
|
| 1652 |
}
|
| 1653 |
|
| 1654 |
+
$params['slug'] = array(
|
| 1655 |
+
'description' => __( 'Limit result set to posts with a specific slug.' ),
|
| 1656 |
+
'type' => 'string',
|
| 1657 |
+
);
|
| 1658 |
$params['status'] = array(
|
| 1659 |
+
'default' => 'publish',
|
| 1660 |
'description' => __( 'Limit result set to posts assigned a specific status.' ),
|
| 1661 |
'sanitize_callback' => 'sanitize_key',
|
| 1662 |
'type' => 'string',
|
| 1674 |
* @param mixed $value
|
| 1675 |
* @param WP_REST_Request $request
|
| 1676 |
* @param string $parameter
|
| 1677 |
+
* @return WP_Error|boolean
|
| 1678 |
*/
|
| 1679 |
public function validate_user_can_query_private_statuses( $value, $request, $parameter ) {
|
| 1680 |
+
if ( 'publish' === $value ) {
|
| 1681 |
return true;
|
| 1682 |
}
|
| 1683 |
$post_type_obj = get_post_type_object( $this->post_type );
|
lib/endpoints/class-wp-rest-posts-terms-controller.php
DELETED
|
@@ -1,319 +0,0 @@
|
|
| 1 |
-
<?php
|
| 2 |
-
|
| 3 |
-
class WP_REST_Posts_Terms_Controller extends WP_REST_Controller {
|
| 4 |
-
|
| 5 |
-
protected $post_type;
|
| 6 |
-
|
| 7 |
-
public function __construct( $post_type, $taxonomy ) {
|
| 8 |
-
$this->post_type = $post_type;
|
| 9 |
-
$this->taxonomy = $taxonomy;
|
| 10 |
-
$this->posts_controller = new WP_REST_Posts_Controller( $post_type );
|
| 11 |
-
$this->terms_controller = new WP_REST_Terms_Controller( $taxonomy );
|
| 12 |
-
}
|
| 13 |
-
|
| 14 |
-
/**
|
| 15 |
-
* Register the routes for the objects of the controller.
|
| 16 |
-
*/
|
| 17 |
-
public function register_routes() {
|
| 18 |
-
|
| 19 |
-
$base = $this->posts_controller->get_post_type_base( $this->post_type );
|
| 20 |
-
$tax_base = $this->terms_controller->get_taxonomy_base( $this->taxonomy );
|
| 21 |
-
|
| 22 |
-
register_rest_route( 'wp/v2', sprintf( '/%s/(?P<post_id>[\d]+)/%s', $base, $tax_base ), array(
|
| 23 |
-
array(
|
| 24 |
-
'methods' => WP_REST_Server::READABLE,
|
| 25 |
-
'callback' => array( $this, 'get_items' ),
|
| 26 |
-
'permission_callback' => array( $this, 'get_items_permissions_check' ),
|
| 27 |
-
'args' => $this->get_collection_params(),
|
| 28 |
-
),
|
| 29 |
-
'schema' => array( $this, 'get_public_item_schema' ),
|
| 30 |
-
) );
|
| 31 |
-
|
| 32 |
-
register_rest_route( 'wp/v2', sprintf( '/%s/(?P<post_id>[\d]+)/%s/(?P<term_id>[\d]+)', $base, $tax_base ), array(
|
| 33 |
-
array(
|
| 34 |
-
'methods' => WP_REST_Server::READABLE,
|
| 35 |
-
'callback' => array( $this, 'get_item' ),
|
| 36 |
-
'permission_callback' => array( $this, 'get_items_permissions_check' ),
|
| 37 |
-
'args' => array(
|
| 38 |
-
'context' => $this->get_context_param( array( 'default' => 'view' ) ),
|
| 39 |
-
),
|
| 40 |
-
),
|
| 41 |
-
array(
|
| 42 |
-
'methods' => WP_REST_Server::CREATABLE,
|
| 43 |
-
'callback' => array( $this, 'create_item' ),
|
| 44 |
-
'permission_callback' => array( $this, 'manage_item_permissions_check' ),
|
| 45 |
-
),
|
| 46 |
-
array(
|
| 47 |
-
'methods' => WP_REST_Server::DELETABLE,
|
| 48 |
-
'callback' => array( $this, 'delete_item' ),
|
| 49 |
-
'permission_callback' => array( $this, 'manage_item_permissions_check' ),
|
| 50 |
-
'args' => array(
|
| 51 |
-
'force' => array(
|
| 52 |
-
'default' => false,
|
| 53 |
-
),
|
| 54 |
-
),
|
| 55 |
-
),
|
| 56 |
-
'schema' => array( $this, 'get_public_item_schema' ),
|
| 57 |
-
) );
|
| 58 |
-
}
|
| 59 |
-
|
| 60 |
-
/**
|
| 61 |
-
* Get all the terms that are attached to a post
|
| 62 |
-
*
|
| 63 |
-
* @param WP_REST_Request $request Full details about the request
|
| 64 |
-
* @return WP_Error|WP_REST_Response
|
| 65 |
-
*/
|
| 66 |
-
public function get_items( $request ) {
|
| 67 |
-
|
| 68 |
-
$post = get_post( absint( $request['post_id'] ) );
|
| 69 |
-
|
| 70 |
-
$is_request_valid = $this->validate_request( $request );
|
| 71 |
-
if ( is_wp_error( $is_request_valid ) ) {
|
| 72 |
-
return $is_request_valid;
|
| 73 |
-
}
|
| 74 |
-
|
| 75 |
-
$args = array(
|
| 76 |
-
'order' => $request['order'],
|
| 77 |
-
'orderby' => $request['orderby'],
|
| 78 |
-
);
|
| 79 |
-
$terms = wp_get_object_terms( $post->ID, $this->taxonomy, $args );
|
| 80 |
-
|
| 81 |
-
$response = array();
|
| 82 |
-
foreach ( $terms as $term ) {
|
| 83 |
-
$data = $this->terms_controller->prepare_item_for_response( $term, $request );
|
| 84 |
-
$response[] = $this->prepare_response_for_collection( $data );
|
| 85 |
-
}
|
| 86 |
-
|
| 87 |
-
$response = rest_ensure_response( $response );
|
| 88 |
-
|
| 89 |
-
return $response;
|
| 90 |
-
}
|
| 91 |
-
|
| 92 |
-
/**
|
| 93 |
-
* Get a term that is attached to a post
|
| 94 |
-
*
|
| 95 |
-
* @param WP_REST_Request $request Full details about the request
|
| 96 |
-
* @return WP_Error|WP_REST_Response
|
| 97 |
-
*/
|
| 98 |
-
public function get_item( $request ) {
|
| 99 |
-
$post = get_post( absint( $request['post_id'] ) );
|
| 100 |
-
$term_id = absint( $request['term_id'] );
|
| 101 |
-
|
| 102 |
-
$is_request_valid = $this->validate_request( $request );
|
| 103 |
-
if ( is_wp_error( $is_request_valid ) ) {
|
| 104 |
-
return $is_request_valid;
|
| 105 |
-
}
|
| 106 |
-
|
| 107 |
-
$terms = wp_get_object_terms( $post->ID, $this->taxonomy );
|
| 108 |
-
|
| 109 |
-
if ( ! in_array( $term_id, wp_list_pluck( $terms, 'term_id' ) ) ) {
|
| 110 |
-
return new WP_Error( 'rest_post_not_in_term', __( 'Invalid taxonomy for post id.' ), array( 'status' => 404 ) );
|
| 111 |
-
}
|
| 112 |
-
|
| 113 |
-
$term = $this->terms_controller->prepare_item_for_response( get_term( $term_id, $this->taxonomy ), $request );
|
| 114 |
-
|
| 115 |
-
$response = rest_ensure_response( $term );
|
| 116 |
-
|
| 117 |
-
return $response;
|
| 118 |
-
}
|
| 119 |
-
|
| 120 |
-
/**
|
| 121 |
-
* Add a term to a post
|
| 122 |
-
*
|
| 123 |
-
* @param WP_REST_Request $request Full details about the request
|
| 124 |
-
* @return WP_Error|WP_REST_Response
|
| 125 |
-
*/
|
| 126 |
-
public function create_item( $request ) {
|
| 127 |
-
$post = get_post( $request['post_id'] );
|
| 128 |
-
$term_id = absint( $request['term_id'] );
|
| 129 |
-
|
| 130 |
-
$is_request_valid = $this->validate_request( $request );
|
| 131 |
-
if ( is_wp_error( $is_request_valid ) ) {
|
| 132 |
-
return $is_request_valid;
|
| 133 |
-
}
|
| 134 |
-
|
| 135 |
-
$term = get_term( $term_id, $this->taxonomy );
|
| 136 |
-
$tt_ids = wp_set_object_terms( $post->ID, $term->term_id, $this->taxonomy, true );
|
| 137 |
-
|
| 138 |
-
if ( is_wp_error( $tt_ids ) ) {
|
| 139 |
-
return $tt_ids;
|
| 140 |
-
}
|
| 141 |
-
|
| 142 |
-
$term = $this->terms_controller->prepare_item_for_response( get_term( $term_id, $this->taxonomy ), $request );
|
| 143 |
-
|
| 144 |
-
$response = rest_ensure_response( $term );
|
| 145 |
-
$response->set_status( 201 );
|
| 146 |
-
|
| 147 |
-
/**
|
| 148 |
-
* Fires after a term is added to a post via the REST API.
|
| 149 |
-
*
|
| 150 |
-
* @param array $term The added term data.
|
| 151 |
-
* @param WP_Post $post The post the term was added to.
|
| 152 |
-
* @param WP_REST_Request $request The request sent to the API.
|
| 153 |
-
*/
|
| 154 |
-
do_action( 'rest_insert_term', $term, $post, $request );
|
| 155 |
-
|
| 156 |
-
return $term;
|
| 157 |
-
}
|
| 158 |
-
|
| 159 |
-
/**
|
| 160 |
-
* Remove a term from a post.
|
| 161 |
-
*
|
| 162 |
-
* @param WP_REST_Request $request Full details about the request
|
| 163 |
-
* @return WP_Error|null
|
| 164 |
-
*/
|
| 165 |
-
public function delete_item( $request ) {
|
| 166 |
-
$post = get_post( absint( $request['post_id'] ) );
|
| 167 |
-
$term_id = absint( $request['term_id'] );
|
| 168 |
-
$force = isset( $request['force'] ) ? (bool) $request['force'] : false;
|
| 169 |
-
|
| 170 |
-
// We don't support trashing for this type, error out
|
| 171 |
-
if ( ! $force ) {
|
| 172 |
-
return new WP_Error( 'rest_trash_not_supported', __( 'Terms do not support trashing.' ), array( 'status' => 501 ) );
|
| 173 |
-
}
|
| 174 |
-
|
| 175 |
-
$is_request_valid = $this->validate_request( $request );
|
| 176 |
-
if ( is_wp_error( $is_request_valid ) ) {
|
| 177 |
-
return $is_request_valid;
|
| 178 |
-
}
|
| 179 |
-
|
| 180 |
-
$previous_item = $this->get_item( $request );
|
| 181 |
-
|
| 182 |
-
$remove = wp_remove_object_terms( $post->ID, $term_id, $this->taxonomy );
|
| 183 |
-
|
| 184 |
-
if ( is_wp_error( $remove ) ) {
|
| 185 |
-
return $remove;
|
| 186 |
-
}
|
| 187 |
-
|
| 188 |
-
/**
|
| 189 |
-
* Fires after a term is removed from a post via the REST API.
|
| 190 |
-
*
|
| 191 |
-
* @param array $previous_item The removed term data.
|
| 192 |
-
* @param WP_Post $post The post the term was removed from.
|
| 193 |
-
* @param WP_REST_Request $request The request sent to the API.
|
| 194 |
-
*/
|
| 195 |
-
do_action( 'rest_remove_term', $previous_item, $post, $request );
|
| 196 |
-
|
| 197 |
-
return $previous_item;
|
| 198 |
-
}
|
| 199 |
-
|
| 200 |
-
/**
|
| 201 |
-
* Get the Term schema, conforming to JSON Schema.
|
| 202 |
-
*
|
| 203 |
-
* @return array
|
| 204 |
-
*/
|
| 205 |
-
public function get_item_schema() {
|
| 206 |
-
return $this->terms_controller->get_item_schema();
|
| 207 |
-
}
|
| 208 |
-
|
| 209 |
-
/**
|
| 210 |
-
* Validate the API request for relationship requests.
|
| 211 |
-
*
|
| 212 |
-
* @param WP_REST_Request $request Full data about the request.
|
| 213 |
-
* @return WP_Error|true
|
| 214 |
-
*/
|
| 215 |
-
protected function validate_request( $request ) {
|
| 216 |
-
$post = get_post( (int) $request['post_id'] );
|
| 217 |
-
|
| 218 |
-
if ( empty( $post ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) {
|
| 219 |
-
return new WP_Error( 'rest_post_invalid_id', __( 'Invalid post id.' ), array( 'status' => 404 ) );
|
| 220 |
-
}
|
| 221 |
-
|
| 222 |
-
if ( ! $this->posts_controller->check_read_permission( $post ) ) {
|
| 223 |
-
return new WP_Error( 'rest_forbidden', __( 'Sorry, you cannot view this post.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 224 |
-
}
|
| 225 |
-
|
| 226 |
-
if ( ! empty( $request['term_id'] ) ) {
|
| 227 |
-
$term_id = absint( $request['term_id'] );
|
| 228 |
-
|
| 229 |
-
$term = get_term( $term_id, $this->taxonomy );
|
| 230 |
-
if ( ! $term || $term->taxonomy !== $this->taxonomy ) {
|
| 231 |
-
return new WP_Error( 'rest_term_invalid', __( "Term doesn't exist." ), array( 'status' => 404 ) );
|
| 232 |
-
}
|
| 233 |
-
}
|
| 234 |
-
|
| 235 |
-
return true;
|
| 236 |
-
}
|
| 237 |
-
|
| 238 |
-
/**
|
| 239 |
-
* Check if a given request has access to read a post's term.
|
| 240 |
-
*
|
| 241 |
-
* @param WP_REST_Request $request Full details about the request.
|
| 242 |
-
* @return bool|WP_Error
|
| 243 |
-
*/
|
| 244 |
-
public function get_items_permissions_check( $request ) {
|
| 245 |
-
|
| 246 |
-
$post_request = new WP_REST_Request();
|
| 247 |
-
$post_request->set_param( 'id', $request['post_id'] );
|
| 248 |
-
|
| 249 |
-
$post_check = $this->posts_controller->get_item_permissions_check( $post_request );
|
| 250 |
-
|
| 251 |
-
if ( ! $post_check || is_wp_error( $post_check ) ) {
|
| 252 |
-
return $post_check;
|
| 253 |
-
}
|
| 254 |
-
|
| 255 |
-
$term_request = new WP_REST_Request();
|
| 256 |
-
$term_request->set_param( 'id', $request['term_id'] );
|
| 257 |
-
|
| 258 |
-
$terms_check = $this->terms_controller->get_item_permissions_check( $term_request );
|
| 259 |
-
|
| 260 |
-
if ( ! $terms_check || is_wp_error( $terms_check ) ) {
|
| 261 |
-
return $terms_check;
|
| 262 |
-
}
|
| 263 |
-
|
| 264 |
-
return true;
|
| 265 |
-
}
|
| 266 |
-
|
| 267 |
-
/**
|
| 268 |
-
* Check if a given request has access to manage a post/term relationship.
|
| 269 |
-
*
|
| 270 |
-
* @param WP_REST_Request $request Full details about the request.
|
| 271 |
-
* @return bool|WP_Error
|
| 272 |
-
*/
|
| 273 |
-
public function manage_item_permissions_check( $request ) {
|
| 274 |
-
|
| 275 |
-
$taxonomy_obj = get_taxonomy( $this->taxonomy );
|
| 276 |
-
if ( ! current_user_can( $taxonomy_obj->cap->assign_terms ) ) {
|
| 277 |
-
return new WP_Error( 'rest_cannot_assign', __( 'Sorry, you are not allowed to assign terms.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 278 |
-
}
|
| 279 |
-
|
| 280 |
-
$post_request = new WP_REST_Request();
|
| 281 |
-
$post_request->set_param( 'id', $request['post_id'] );
|
| 282 |
-
$post_check = $this->posts_controller->update_item_permissions_check( $post_request );
|
| 283 |
-
|
| 284 |
-
if ( ! $post_check || is_wp_error( $post_check ) ) {
|
| 285 |
-
return $post_check;
|
| 286 |
-
}
|
| 287 |
-
|
| 288 |
-
return true;
|
| 289 |
-
}
|
| 290 |
-
|
| 291 |
-
/**
|
| 292 |
-
* Get the query params for collections
|
| 293 |
-
*
|
| 294 |
-
* @return array
|
| 295 |
-
*/
|
| 296 |
-
public function get_collection_params() {
|
| 297 |
-
$query_params = array();
|
| 298 |
-
$query_params['context'] = $this->get_context_param( array( 'default' => 'view' ) );
|
| 299 |
-
$query_params['order'] = array(
|
| 300 |
-
'description' => __( 'Order sort attribute ascending or descending.' ),
|
| 301 |
-
'type' => 'string',
|
| 302 |
-
'default' => 'asc',
|
| 303 |
-
'enum' => array( 'asc', 'desc' ),
|
| 304 |
-
);
|
| 305 |
-
$query_params['orderby'] = array(
|
| 306 |
-
'description' => __( 'Sort collection by object attribute.' ),
|
| 307 |
-
'type' => 'string',
|
| 308 |
-
'default' => 'name',
|
| 309 |
-
'enum' => array(
|
| 310 |
-
'count',
|
| 311 |
-
'name',
|
| 312 |
-
'slug',
|
| 313 |
-
'term_order',
|
| 314 |
-
),
|
| 315 |
-
);
|
| 316 |
-
return $query_params;
|
| 317 |
-
}
|
| 318 |
-
|
| 319 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/endpoints/class-wp-rest-revisions-controller.php
CHANGED
|
@@ -48,6 +48,26 @@ class WP_REST_Revisions_Controller extends WP_REST_Controller {
|
|
| 48 |
|
| 49 |
}
|
| 50 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
/**
|
| 52 |
* Get a collection of revisions
|
| 53 |
*
|
|
@@ -68,27 +88,17 @@ class WP_REST_Revisions_Controller extends WP_REST_Controller {
|
|
| 68 |
$data = $this->prepare_item_for_response( $revision, $request );
|
| 69 |
$response[] = $this->prepare_response_for_collection( $data );
|
| 70 |
}
|
| 71 |
-
return $response;
|
| 72 |
}
|
| 73 |
|
| 74 |
/**
|
| 75 |
-
* Check if a given request has access to get
|
| 76 |
*
|
| 77 |
* @param WP_REST_Request $request Full data about the request.
|
| 78 |
-
* @return WP_Error|
|
| 79 |
*/
|
| 80 |
-
public function
|
| 81 |
-
|
| 82 |
-
$parent = get_post( $request['parent_id'] );
|
| 83 |
-
if ( ! $parent ) {
|
| 84 |
-
return true;
|
| 85 |
-
}
|
| 86 |
-
$parent_post_type_obj = get_post_type_object( $parent->post_type );
|
| 87 |
-
if ( ! current_user_can( $parent_post_type_obj->cap->edit_post, $parent->ID ) ) {
|
| 88 |
-
return new WP_Error( 'rest_cannot_read', __( 'Sorry, you cannot view revisions of this post.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 89 |
-
}
|
| 90 |
-
|
| 91 |
-
return true;
|
| 92 |
}
|
| 93 |
|
| 94 |
/**
|
|
@@ -110,24 +120,32 @@ class WP_REST_Revisions_Controller extends WP_REST_Controller {
|
|
| 110 |
}
|
| 111 |
|
| 112 |
$response = $this->prepare_item_for_response( $revision, $request );
|
| 113 |
-
return $response;
|
| 114 |
}
|
| 115 |
|
| 116 |
/**
|
| 117 |
-
* Check if a given request has access to
|
| 118 |
*
|
| 119 |
-
* @param
|
| 120 |
-
* @return WP_Error|
|
| 121 |
*/
|
| 122 |
-
public function
|
| 123 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 124 |
}
|
| 125 |
|
| 126 |
/**
|
| 127 |
* Delete a single revision
|
| 128 |
*
|
| 129 |
* @param WP_REST_Request $request Full details about the request
|
| 130 |
-
* @return
|
| 131 |
*/
|
| 132 |
public function delete_item( $request ) {
|
| 133 |
$result = wp_delete_post( $request['id'], true );
|
|
@@ -149,30 +167,12 @@ class WP_REST_Revisions_Controller extends WP_REST_Controller {
|
|
| 149 |
}
|
| 150 |
}
|
| 151 |
|
| 152 |
-
/**
|
| 153 |
-
* Check if a given request has access to delete a revision
|
| 154 |
-
*
|
| 155 |
-
* @param WP_REST_Request $request Full details about the request.
|
| 156 |
-
* @return bool|WP_Error
|
| 157 |
-
*/
|
| 158 |
-
public function delete_item_permissions_check( $request ) {
|
| 159 |
-
|
| 160 |
-
$response = $this->get_items_permissions_check( $request );
|
| 161 |
-
if ( ! $response || is_wp_error( $response ) ) {
|
| 162 |
-
return $response;
|
| 163 |
-
}
|
| 164 |
-
|
| 165 |
-
$post = get_post( $request['id'] );
|
| 166 |
-
$post_type = get_post_type_object( 'revision' );
|
| 167 |
-
return current_user_can( $post_type->cap->delete_post, $post->ID );
|
| 168 |
-
}
|
| 169 |
-
|
| 170 |
/**
|
| 171 |
* Prepare the revision for the REST response
|
| 172 |
*
|
| 173 |
* @param WP_Post $post Post revision object.
|
| 174 |
* @param WP_REST_Request $request Request object.
|
| 175 |
-
* @return
|
| 176 |
*/
|
| 177 |
public function prepare_item_for_response( $post, $request ) {
|
| 178 |
|
|
@@ -204,12 +204,9 @@ class WP_REST_Revisions_Controller extends WP_REST_Controller {
|
|
| 204 |
}
|
| 205 |
|
| 206 |
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
| 207 |
-
$data = $this->filter_response_by_context( $data, $context );
|
| 208 |
$data = $this->add_additional_fields_to_object( $data, $request );
|
|
|
|
| 209 |
$response = rest_ensure_response( $data );
|
| 210 |
-
if ( is_wp_error( $response ) ) {
|
| 211 |
-
return $response;
|
| 212 |
-
}
|
| 213 |
|
| 214 |
if ( ! empty( $data['parent'] ) ) {
|
| 215 |
$response->add_link( 'parent', rest_url( sprintf( 'wp/%s/%d', $this->parent_base, $data['parent'] ) ) );
|
|
@@ -255,7 +252,7 @@ class WP_REST_Revisions_Controller extends WP_REST_Controller {
|
|
| 255 |
public function get_item_schema() {
|
| 256 |
$schema = array(
|
| 257 |
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
| 258 |
-
'title' => "{$this->
|
| 259 |
'type' => 'object',
|
| 260 |
/*
|
| 261 |
* Base properties for every Revision
|
| 48 |
|
| 49 |
}
|
| 50 |
|
| 51 |
+
/**
|
| 52 |
+
* Check if a given request has access to get revisions
|
| 53 |
+
*
|
| 54 |
+
* @param WP_REST_Request $request Full data about the request.
|
| 55 |
+
* @return WP_Error|boolean
|
| 56 |
+
*/
|
| 57 |
+
public function get_items_permissions_check( $request ) {
|
| 58 |
+
|
| 59 |
+
$parent = get_post( $request['parent_id'] );
|
| 60 |
+
if ( ! $parent ) {
|
| 61 |
+
return true;
|
| 62 |
+
}
|
| 63 |
+
$parent_post_type_obj = get_post_type_object( $parent->post_type );
|
| 64 |
+
if ( ! current_user_can( $parent_post_type_obj->cap->edit_post, $parent->ID ) ) {
|
| 65 |
+
return new WP_Error( 'rest_cannot_read', __( 'Sorry, you cannot view revisions of this post.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
return true;
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
/**
|
| 72 |
* Get a collection of revisions
|
| 73 |
*
|
| 88 |
$data = $this->prepare_item_for_response( $revision, $request );
|
| 89 |
$response[] = $this->prepare_response_for_collection( $data );
|
| 90 |
}
|
| 91 |
+
return rest_ensure_response( $response );
|
| 92 |
}
|
| 93 |
|
| 94 |
/**
|
| 95 |
+
* Check if a given request has access to get a specific revision
|
| 96 |
*
|
| 97 |
* @param WP_REST_Request $request Full data about the request.
|
| 98 |
+
* @return WP_Error|boolean
|
| 99 |
*/
|
| 100 |
+
public function get_item_permissions_check( $request ) {
|
| 101 |
+
return $this->get_items_permissions_check( $request );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 102 |
}
|
| 103 |
|
| 104 |
/**
|
| 120 |
}
|
| 121 |
|
| 122 |
$response = $this->prepare_item_for_response( $revision, $request );
|
| 123 |
+
return rest_ensure_response( $response );
|
| 124 |
}
|
| 125 |
|
| 126 |
/**
|
| 127 |
+
* Check if a given request has access to delete a revision
|
| 128 |
*
|
| 129 |
+
* @param WP_REST_Request $request Full details about the request.
|
| 130 |
+
* @return WP_Error|boolean
|
| 131 |
*/
|
| 132 |
+
public function delete_item_permissions_check( $request ) {
|
| 133 |
+
|
| 134 |
+
$response = $this->get_items_permissions_check( $request );
|
| 135 |
+
if ( ! $response || is_wp_error( $response ) ) {
|
| 136 |
+
return $response;
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
$post = get_post( $request['id'] );
|
| 140 |
+
$post_type = get_post_type_object( 'revision' );
|
| 141 |
+
return current_user_can( $post_type->cap->delete_post, $post->ID );
|
| 142 |
}
|
| 143 |
|
| 144 |
/**
|
| 145 |
* Delete a single revision
|
| 146 |
*
|
| 147 |
* @param WP_REST_Request $request Full details about the request
|
| 148 |
+
* @return WP_Error|boolean
|
| 149 |
*/
|
| 150 |
public function delete_item( $request ) {
|
| 151 |
$result = wp_delete_post( $request['id'], true );
|
| 167 |
}
|
| 168 |
}
|
| 169 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 170 |
/**
|
| 171 |
* Prepare the revision for the REST response
|
| 172 |
*
|
| 173 |
* @param WP_Post $post Post revision object.
|
| 174 |
* @param WP_REST_Request $request Request object.
|
| 175 |
+
* @return WP_REST_Response $response
|
| 176 |
*/
|
| 177 |
public function prepare_item_for_response( $post, $request ) {
|
| 178 |
|
| 204 |
}
|
| 205 |
|
| 206 |
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
|
|
|
| 207 |
$data = $this->add_additional_fields_to_object( $data, $request );
|
| 208 |
+
$data = $this->filter_response_by_context( $data, $context );
|
| 209 |
$response = rest_ensure_response( $data );
|
|
|
|
|
|
|
|
|
|
| 210 |
|
| 211 |
if ( ! empty( $data['parent'] ) ) {
|
| 212 |
$response->add_link( 'parent', rest_url( sprintf( 'wp/%s/%d', $this->parent_base, $data['parent'] ) ) );
|
| 252 |
public function get_item_schema() {
|
| 253 |
$schema = array(
|
| 254 |
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
| 255 |
+
'title' => "{$this->parent_post_type}-revision",
|
| 256 |
'type' => 'object',
|
| 257 |
/*
|
| 258 |
* Base properties for every Revision
|
lib/endpoints/class-wp-rest-taxonomies-controller.php
CHANGED
|
@@ -50,28 +50,14 @@ class WP_REST_Taxonomies_Controller extends WP_REST_Controller {
|
|
| 50 |
$tax = $this->prepare_response_for_collection( $tax );
|
| 51 |
$data[ $tax_type ] = $tax;
|
| 52 |
}
|
| 53 |
-
return $data;
|
| 54 |
-
}
|
| 55 |
-
|
| 56 |
-
/**
|
| 57 |
-
* Get a specific taxonomy
|
| 58 |
-
*
|
| 59 |
-
* @param WP_REST_Request $request
|
| 60 |
-
* @return array|WP_Error
|
| 61 |
-
*/
|
| 62 |
-
public function get_item( $request ) {
|
| 63 |
-
$tax_obj = get_taxonomy( $request['taxonomy'] );
|
| 64 |
-
if ( empty( $tax_obj ) ) {
|
| 65 |
-
return new WP_Error( 'rest_taxonomy_invalid', __( 'Invalid taxonomy.' ), array( 'status' => 404 ) );
|
| 66 |
-
}
|
| 67 |
-
return $this->prepare_item_for_response( $tax_obj, $request );
|
| 68 |
}
|
| 69 |
|
| 70 |
/**
|
| 71 |
* Check if a given request has access a taxonomy
|
| 72 |
*
|
| 73 |
* @param WP_REST_Request $request Full details about the request.
|
| 74 |
-
* @return
|
| 75 |
*/
|
| 76 |
public function get_item_permissions_check( $request ) {
|
| 77 |
|
|
@@ -89,12 +75,27 @@ class WP_REST_Taxonomies_Controller extends WP_REST_Controller {
|
|
| 89 |
return true;
|
| 90 |
}
|
| 91 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
/**
|
| 93 |
* Prepare a taxonomy object for serialization
|
| 94 |
*
|
| 95 |
* @param stdClass $taxonomy Taxonomy data
|
| 96 |
* @param WP_REST_Request $request
|
| 97 |
-
* @return
|
| 98 |
*/
|
| 99 |
public function prepare_item_for_response( $taxonomy, $request ) {
|
| 100 |
|
|
@@ -109,8 +110,8 @@ class WP_REST_Taxonomies_Controller extends WP_REST_Controller {
|
|
| 109 |
);
|
| 110 |
|
| 111 |
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
| 112 |
-
$data = $this->filter_response_by_context( $data, $context );
|
| 113 |
$data = $this->add_additional_fields_to_object( $data, $request );
|
|
|
|
| 114 |
|
| 115 |
// Wrap the data in a response object.
|
| 116 |
$response = rest_ensure_response( $data );
|
| 50 |
$tax = $this->prepare_response_for_collection( $tax );
|
| 51 |
$data[ $tax_type ] = $tax;
|
| 52 |
}
|
| 53 |
+
return rest_ensure_response( $data );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
}
|
| 55 |
|
| 56 |
/**
|
| 57 |
* Check if a given request has access a taxonomy
|
| 58 |
*
|
| 59 |
* @param WP_REST_Request $request Full details about the request.
|
| 60 |
+
* @return WP_Error|boolean
|
| 61 |
*/
|
| 62 |
public function get_item_permissions_check( $request ) {
|
| 63 |
|
| 75 |
return true;
|
| 76 |
}
|
| 77 |
|
| 78 |
+
/**
|
| 79 |
+
* Get a specific taxonomy
|
| 80 |
+
*
|
| 81 |
+
* @param WP_REST_Request $request
|
| 82 |
+
* @return array|WP_Error
|
| 83 |
+
*/
|
| 84 |
+
public function get_item( $request ) {
|
| 85 |
+
$tax_obj = get_taxonomy( $request['taxonomy'] );
|
| 86 |
+
if ( empty( $tax_obj ) ) {
|
| 87 |
+
return new WP_Error( 'rest_taxonomy_invalid', __( 'Invalid taxonomy.' ), array( 'status' => 404 ) );
|
| 88 |
+
}
|
| 89 |
+
$data = $this->prepare_item_for_response( $tax_obj, $request );
|
| 90 |
+
return rest_ensure_response( $data );
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
/**
|
| 94 |
* Prepare a taxonomy object for serialization
|
| 95 |
*
|
| 96 |
* @param stdClass $taxonomy Taxonomy data
|
| 97 |
* @param WP_REST_Request $request
|
| 98 |
+
* @return WP_REST_Response $response
|
| 99 |
*/
|
| 100 |
public function prepare_item_for_response( $taxonomy, $request ) {
|
| 101 |
|
| 110 |
);
|
| 111 |
|
| 112 |
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
|
|
|
| 113 |
$data = $this->add_additional_fields_to_object( $data, $request );
|
| 114 |
+
$data = $this->filter_response_by_context( $data, $context );
|
| 115 |
|
| 116 |
// Wrap the data in a response object.
|
| 117 |
$response = rest_ensure_response( $data );
|
lib/endpoints/class-wp-rest-terms-controller.php
CHANGED
|
@@ -55,12 +55,28 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
|
|
| 55 |
'methods' => WP_REST_Server::DELETABLE,
|
| 56 |
'callback' => array( $this, 'delete_item' ),
|
| 57 |
'permission_callback' => array( $this, 'delete_item_permissions_check' ),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
),
|
| 59 |
|
| 60 |
'schema' => array( $this, 'get_public_item_schema' ),
|
| 61 |
) );
|
| 62 |
}
|
| 63 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
/**
|
| 65 |
* Get terms associated with a taxonomy
|
| 66 |
*
|
|
@@ -69,15 +85,22 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
|
|
| 69 |
*/
|
| 70 |
public function get_items( $request ) {
|
| 71 |
$prepared_args = array(
|
|
|
|
| 72 |
'include' => $request['include'],
|
| 73 |
'order' => $request['order'],
|
| 74 |
'orderby' => $request['orderby'],
|
|
|
|
| 75 |
'hide_empty' => $request['hide_empty'],
|
| 76 |
'number' => $request['per_page'],
|
| 77 |
'search' => $request['search'],
|
|
|
|
| 78 |
);
|
| 79 |
|
| 80 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 81 |
|
| 82 |
$taxonomy_obj = get_taxonomy( $this->taxonomy );
|
| 83 |
|
|
@@ -104,9 +127,17 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
|
|
| 104 |
* passed to get_terms.
|
| 105 |
* @param WP_REST_Request $request The current request.
|
| 106 |
*/
|
| 107 |
-
$prepared_args = apply_filters(
|
| 108 |
|
| 109 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
$response = array();
|
| 111 |
foreach ( $query_result as $term ) {
|
| 112 |
$data = $this->prepare_item_for_response( $term, $request );
|
|
@@ -150,6 +181,16 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
|
|
| 150 |
return $response;
|
| 151 |
}
|
| 152 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 153 |
/**
|
| 154 |
* Get a single term from a taxonomy
|
| 155 |
*
|
|
@@ -171,6 +212,26 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
|
|
| 171 |
return rest_ensure_response( $response );
|
| 172 |
}
|
| 173 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 174 |
/**
|
| 175 |
* Create a single term for a taxonomy
|
| 176 |
*
|
|
@@ -217,18 +278,51 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
|
|
| 217 |
return $term;
|
| 218 |
}
|
| 219 |
|
| 220 |
-
$
|
| 221 |
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 225 |
|
|
|
|
|
|
|
|
|
|
| 226 |
$response = rest_ensure_response( $response );
|
| 227 |
$response->set_status( 201 );
|
| 228 |
-
$response->header( 'Location', rest_url( '/wp/v2/' . $this->get_taxonomy_base( $this->taxonomy ) . '/' . $term
|
| 229 |
return $response;
|
| 230 |
}
|
| 231 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 232 |
/**
|
| 233 |
* Update a single term from a taxonomy
|
| 234 |
*
|
|
@@ -272,134 +366,79 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
|
|
| 272 |
}
|
| 273 |
}
|
| 274 |
|
| 275 |
-
$this->update_additional_fields_for_object( get_term( (int) $request['id'], $this->taxonomy ), $request );
|
| 276 |
-
|
| 277 |
-
$get_request = new WP_REST_Request;
|
| 278 |
-
$get_request->set_param( 'id', (int) $request['id'] );
|
| 279 |
-
$response = $this->get_item( $get_request );
|
| 280 |
-
|
| 281 |
-
return rest_ensure_response( $response );
|
| 282 |
-
}
|
| 283 |
-
|
| 284 |
-
/**
|
| 285 |
-
* Delete a single term from a taxonomy
|
| 286 |
-
*
|
| 287 |
-
* @param WP_REST_Request $request Full details about the request
|
| 288 |
-
* @return WP_REST_Response|WP_Error
|
| 289 |
-
*/
|
| 290 |
-
public function delete_item( $request ) {
|
| 291 |
-
|
| 292 |
-
// Get the actual term_id
|
| 293 |
$term = get_term( (int) $request['id'], $this->taxonomy );
|
| 294 |
-
$get_request = new WP_REST_Request;
|
| 295 |
-
$get_request->set_param( 'id', (int) $request['id'] );
|
| 296 |
-
$get_request->set_param( 'context', 'view' );
|
| 297 |
-
$response = $this->prepare_item_for_response( $term, $get_request );
|
| 298 |
-
|
| 299 |
-
$data = $response->get_data();
|
| 300 |
-
$data = array(
|
| 301 |
-
'data' => $data,
|
| 302 |
-
'deleted' => true,
|
| 303 |
-
);
|
| 304 |
-
$response->set_data( $data );
|
| 305 |
-
|
| 306 |
-
$retval = wp_delete_term( $term->term_id, $term->taxonomy );
|
| 307 |
-
if ( ! $retval ) {
|
| 308 |
-
return new WP_Error( 'rest_cannot_delete', __( 'The term cannot be deleted.' ), array( 'status' => 500 ) );
|
| 309 |
-
}
|
| 310 |
-
|
| 311 |
-
return $response;
|
| 312 |
-
}
|
| 313 |
-
|
| 314 |
-
/**
|
| 315 |
-
* Check if a given request has access to read the terms.
|
| 316 |
-
*
|
| 317 |
-
* @param WP_REST_Request $request Full details about the request.
|
| 318 |
-
* @return bool|WP_Error
|
| 319 |
-
*/
|
| 320 |
-
public function get_items_permissions_check( $request ) {
|
| 321 |
-
return $this->check_is_taxonomy_allowed( $this->taxonomy );
|
| 322 |
-
}
|
| 323 |
-
|
| 324 |
-
/**
|
| 325 |
-
* Check if a given request has access to read a term.
|
| 326 |
-
*
|
| 327 |
-
* @param WP_REST_Request $request Full details about the request.
|
| 328 |
-
* @return bool|WP_Error
|
| 329 |
-
*/
|
| 330 |
-
public function get_item_permissions_check( $request ) {
|
| 331 |
-
return $this->check_is_taxonomy_allowed( $this->taxonomy );
|
| 332 |
-
}
|
| 333 |
-
|
| 334 |
-
|
| 335 |
-
/**
|
| 336 |
-
* Check if a given request has access to create a term
|
| 337 |
-
*
|
| 338 |
-
* @param WP_REST_Request $request Full details about the request.
|
| 339 |
-
* @return bool|WP_Error
|
| 340 |
-
*/
|
| 341 |
-
public function create_item_permissions_check( $request ) {
|
| 342 |
|
| 343 |
-
|
| 344 |
-
|
| 345 |
-
}
|
| 346 |
|
| 347 |
-
$
|
| 348 |
-
|
| 349 |
-
|
| 350 |
-
|
| 351 |
-
|
| 352 |
-
return true;
|
| 353 |
}
|
| 354 |
|
| 355 |
/**
|
| 356 |
-
* Check if a given request has access to
|
| 357 |
*
|
| 358 |
* @param WP_REST_Request $request Full details about the request.
|
| 359 |
-
* @return
|
| 360 |
*/
|
| 361 |
-
public function
|
| 362 |
-
|
| 363 |
if ( ! $this->check_is_taxonomy_allowed( $this->taxonomy ) ) {
|
| 364 |
return false;
|
| 365 |
}
|
| 366 |
-
|
| 367 |
$term = get_term( (int) $request['id'], $this->taxonomy );
|
| 368 |
if ( ! $term ) {
|
| 369 |
return new WP_Error( 'rest_term_invalid', __( "Term doesn't exist." ), array( 'status' => 404 ) );
|
| 370 |
}
|
| 371 |
-
|
| 372 |
$taxonomy_obj = get_taxonomy( $this->taxonomy );
|
| 373 |
-
if ( ! current_user_can( $taxonomy_obj->cap->
|
| 374 |
-
return new WP_Error( '
|
| 375 |
}
|
| 376 |
-
|
| 377 |
return true;
|
| 378 |
}
|
| 379 |
|
| 380 |
/**
|
| 381 |
-
*
|
| 382 |
*
|
| 383 |
-
* @param
|
| 384 |
-
* @return
|
| 385 |
*/
|
| 386 |
-
public function
|
| 387 |
|
| 388 |
-
|
| 389 |
-
|
|
|
|
|
|
|
|
|
|
| 390 |
}
|
| 391 |
|
| 392 |
$term = get_term( (int) $request['id'], $this->taxonomy );
|
| 393 |
-
|
| 394 |
-
|
| 395 |
-
}
|
| 396 |
|
| 397 |
-
$
|
| 398 |
-
|
| 399 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 400 |
}
|
| 401 |
|
| 402 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 403 |
}
|
| 404 |
|
| 405 |
/**
|
|
@@ -423,6 +462,7 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
|
|
| 423 |
*
|
| 424 |
* @param obj $item Term object
|
| 425 |
* @param WP_REST_Request $request
|
|
|
|
| 426 |
*/
|
| 427 |
public function prepare_item_for_response( $item, $request ) {
|
| 428 |
|
|
@@ -441,8 +481,8 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
|
|
| 441 |
}
|
| 442 |
|
| 443 |
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
| 444 |
-
$data = $this->filter_response_by_context( $data, $context );
|
| 445 |
$data = $this->add_additional_fields_to_object( $data, $request );
|
|
|
|
| 446 |
|
| 447 |
$response = rest_ensure_response( $data );
|
| 448 |
|
|
@@ -457,7 +497,7 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
|
|
| 457 |
* @param object $item The original term object.
|
| 458 |
* @param WP_REST_Request $request Request used to generate the response.
|
| 459 |
*/
|
| 460 |
-
return apply_filters(
|
| 461 |
}
|
| 462 |
|
| 463 |
/**
|
|
@@ -501,7 +541,7 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
|
|
| 501 |
public function get_item_schema() {
|
| 502 |
$schema = array(
|
| 503 |
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
| 504 |
-
'title' => '
|
| 505 |
'type' => 'object',
|
| 506 |
'properties' => array(
|
| 507 |
'id' => array(
|
|
@@ -575,15 +615,29 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
|
|
| 575 |
*/
|
| 576 |
public function get_collection_params() {
|
| 577 |
$query_params = parent::get_collection_params();
|
|
|
|
| 578 |
|
| 579 |
$query_params['context']['default'] = 'view';
|
| 580 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 581 |
$query_params['include'] = array(
|
| 582 |
'description' => __( 'Limit result set to specific ids.' ),
|
| 583 |
'type' => 'array',
|
| 584 |
'default' => array(),
|
| 585 |
'sanitize_callback' => 'wp_parse_id_list',
|
| 586 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 587 |
$query_params['order'] = array(
|
| 588 |
'description' => __( 'Order sort attribute ascending or descending.' ),
|
| 589 |
'type' => 'string',
|
|
@@ -605,7 +659,6 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
|
|
| 605 |
'name',
|
| 606 |
'slug',
|
| 607 |
'term_group',
|
| 608 |
-
'term_id',
|
| 609 |
'description',
|
| 610 |
'count',
|
| 611 |
),
|
|
@@ -615,7 +668,6 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
|
|
| 615 |
'type' => 'boolean',
|
| 616 |
'default' => false,
|
| 617 |
);
|
| 618 |
-
$taxonomy = get_taxonomy( $this->taxonomy );
|
| 619 |
if ( $taxonomy->hierarchical ) {
|
| 620 |
$query_params['parent'] = array(
|
| 621 |
'description' => __( 'Limit result set to terms assigned to a specific parent term.' ),
|
|
@@ -623,6 +675,15 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
|
|
| 623 |
'sanitize_callback' => 'absint',
|
| 624 |
);
|
| 625 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 626 |
return $query_params;
|
| 627 |
}
|
| 628 |
|
|
@@ -630,7 +691,7 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
|
|
| 630 |
* Check that the taxonomy is valid
|
| 631 |
*
|
| 632 |
* @param string
|
| 633 |
-
* @return
|
| 634 |
*/
|
| 635 |
protected function check_is_taxonomy_allowed( $taxonomy ) {
|
| 636 |
$taxonomy_obj = get_taxonomy( $taxonomy );
|
| 55 |
'methods' => WP_REST_Server::DELETABLE,
|
| 56 |
'callback' => array( $this, 'delete_item' ),
|
| 57 |
'permission_callback' => array( $this, 'delete_item_permissions_check' ),
|
| 58 |
+
'args' => array(
|
| 59 |
+
'force' => array(
|
| 60 |
+
'default' => false,
|
| 61 |
+
'description' => __( 'Required to be true, as resource does not support trashing.' ),
|
| 62 |
+
),
|
| 63 |
+
),
|
| 64 |
),
|
| 65 |
|
| 66 |
'schema' => array( $this, 'get_public_item_schema' ),
|
| 67 |
) );
|
| 68 |
}
|
| 69 |
|
| 70 |
+
/**
|
| 71 |
+
* Check if a given request has access to read the terms.
|
| 72 |
+
*
|
| 73 |
+
* @param WP_REST_Request $request Full details about the request.
|
| 74 |
+
* @return WP_Error|boolean
|
| 75 |
+
*/
|
| 76 |
+
public function get_items_permissions_check( $request ) {
|
| 77 |
+
return $this->check_is_taxonomy_allowed( $this->taxonomy );
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
/**
|
| 81 |
* Get terms associated with a taxonomy
|
| 82 |
*
|
| 85 |
*/
|
| 86 |
public function get_items( $request ) {
|
| 87 |
$prepared_args = array(
|
| 88 |
+
'exclude' => $request['exclude'],
|
| 89 |
'include' => $request['include'],
|
| 90 |
'order' => $request['order'],
|
| 91 |
'orderby' => $request['orderby'],
|
| 92 |
+
'post' => $request['post'],
|
| 93 |
'hide_empty' => $request['hide_empty'],
|
| 94 |
'number' => $request['per_page'],
|
| 95 |
'search' => $request['search'],
|
| 96 |
+
'slug' => $request['slug'],
|
| 97 |
);
|
| 98 |
|
| 99 |
+
if ( ! empty( $request['offset'] ) ) {
|
| 100 |
+
$prepared_args['offset'] = $request['offset'];
|
| 101 |
+
} else {
|
| 102 |
+
$prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number'];
|
| 103 |
+
}
|
| 104 |
|
| 105 |
$taxonomy_obj = get_taxonomy( $this->taxonomy );
|
| 106 |
|
| 127 |
* passed to get_terms.
|
| 128 |
* @param WP_REST_Request $request The current request.
|
| 129 |
*/
|
| 130 |
+
$prepared_args = apply_filters( "rest_{$this->taxonomy}_query", $prepared_args, $request );
|
| 131 |
|
| 132 |
+
if ( ! empty( $prepared_args['post'] ) ) {
|
| 133 |
+
$terms_args = array(
|
| 134 |
+
'order' => $prepared_args['order'],
|
| 135 |
+
'orderby' => $prepared_args['orderby'],
|
| 136 |
+
);
|
| 137 |
+
$query_result = wp_get_object_terms( $prepared_args['post'], $this->taxonomy, $terms_args );
|
| 138 |
+
} else {
|
| 139 |
+
$query_result = get_terms( $this->taxonomy, $prepared_args );
|
| 140 |
+
}
|
| 141 |
$response = array();
|
| 142 |
foreach ( $query_result as $term ) {
|
| 143 |
$data = $this->prepare_item_for_response( $term, $request );
|
| 181 |
return $response;
|
| 182 |
}
|
| 183 |
|
| 184 |
+
/**
|
| 185 |
+
* Check if a given request has access to read a term.
|
| 186 |
+
*
|
| 187 |
+
* @param WP_REST_Request $request Full details about the request.
|
| 188 |
+
* @return WP_Error|boolean
|
| 189 |
+
*/
|
| 190 |
+
public function get_item_permissions_check( $request ) {
|
| 191 |
+
return $this->check_is_taxonomy_allowed( $this->taxonomy );
|
| 192 |
+
}
|
| 193 |
+
|
| 194 |
/**
|
| 195 |
* Get a single term from a taxonomy
|
| 196 |
*
|
| 212 |
return rest_ensure_response( $response );
|
| 213 |
}
|
| 214 |
|
| 215 |
+
/**
|
| 216 |
+
* Check if a given request has access to create a term
|
| 217 |
+
*
|
| 218 |
+
* @param WP_REST_Request $request Full details about the request.
|
| 219 |
+
* @return WP_Error|boolean
|
| 220 |
+
*/
|
| 221 |
+
public function create_item_permissions_check( $request ) {
|
| 222 |
+
|
| 223 |
+
if ( ! $this->check_is_taxonomy_allowed( $this->taxonomy ) ) {
|
| 224 |
+
return false;
|
| 225 |
+
}
|
| 226 |
+
|
| 227 |
+
$taxonomy_obj = get_taxonomy( $this->taxonomy );
|
| 228 |
+
if ( ! current_user_can( $taxonomy_obj->cap->manage_terms ) ) {
|
| 229 |
+
return new WP_Error( 'rest_cannot_create', __( 'Sorry, you cannot create new terms.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 230 |
+
}
|
| 231 |
+
|
| 232 |
+
return true;
|
| 233 |
+
}
|
| 234 |
+
|
| 235 |
/**
|
| 236 |
* Create a single term for a taxonomy
|
| 237 |
*
|
| 278 |
return $term;
|
| 279 |
}
|
| 280 |
|
| 281 |
+
$term = get_term( $term['term_id'], $this->taxonomy );
|
| 282 |
|
| 283 |
+
/**
|
| 284 |
+
* Fires after a single term is created or updated via the REST API.
|
| 285 |
+
*
|
| 286 |
+
* @param WP_Term $term Inserted Term object.
|
| 287 |
+
* @param WP_REST_Request $request Request object.
|
| 288 |
+
* @param boolean $creating True when creating term, false when updating.
|
| 289 |
+
*/
|
| 290 |
+
do_action( "rest_insert_{$this->taxonomy}", $term, $request, true );
|
| 291 |
|
| 292 |
+
$this->update_additional_fields_for_object( $term, $request );
|
| 293 |
+
$request->set_param( 'context', 'view' );
|
| 294 |
+
$response = $this->prepare_item_for_response( $term, $request );
|
| 295 |
$response = rest_ensure_response( $response );
|
| 296 |
$response->set_status( 201 );
|
| 297 |
+
$response->header( 'Location', rest_url( '/wp/v2/' . $this->get_taxonomy_base( $this->taxonomy ) . '/' . $term->term_id ) );
|
| 298 |
return $response;
|
| 299 |
}
|
| 300 |
|
| 301 |
+
/**
|
| 302 |
+
* Check if a given request has access to update a term
|
| 303 |
+
*
|
| 304 |
+
* @param WP_REST_Request $request Full details about the request.
|
| 305 |
+
* @return WP_Error|boolean
|
| 306 |
+
*/
|
| 307 |
+
public function update_item_permissions_check( $request ) {
|
| 308 |
+
|
| 309 |
+
if ( ! $this->check_is_taxonomy_allowed( $this->taxonomy ) ) {
|
| 310 |
+
return false;
|
| 311 |
+
}
|
| 312 |
+
|
| 313 |
+
$term = get_term( (int) $request['id'], $this->taxonomy );
|
| 314 |
+
if ( ! $term ) {
|
| 315 |
+
return new WP_Error( 'rest_term_invalid', __( "Term doesn't exist." ), array( 'status' => 404 ) );
|
| 316 |
+
}
|
| 317 |
+
|
| 318 |
+
$taxonomy_obj = get_taxonomy( $this->taxonomy );
|
| 319 |
+
if ( ! current_user_can( $taxonomy_obj->cap->edit_terms ) ) {
|
| 320 |
+
return new WP_Error( 'rest_cannot_update', __( 'Sorry, you cannot update terms.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 321 |
+
}
|
| 322 |
+
|
| 323 |
+
return true;
|
| 324 |
+
}
|
| 325 |
+
|
| 326 |
/**
|
| 327 |
* Update a single term from a taxonomy
|
| 328 |
*
|
| 366 |
}
|
| 367 |
}
|
| 368 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 369 |
$term = get_term( (int) $request['id'], $this->taxonomy );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 370 |
|
| 371 |
+
/* This action is documented in lib/endpoints/class-wp-rest-terms-controller.php */
|
| 372 |
+
do_action( "rest_insert_{$this->taxonomy}", $term, $request, false );
|
|
|
|
| 373 |
|
| 374 |
+
$this->update_additional_fields_for_object( $term, $request );
|
| 375 |
+
$request->set_param( 'context', 'view' );
|
| 376 |
+
$response = $this->prepare_item_for_response( $term, $request );
|
| 377 |
+
return rest_ensure_response( $response );
|
|
|
|
|
|
|
| 378 |
}
|
| 379 |
|
| 380 |
/**
|
| 381 |
+
* Check if a given request has access to delete a term
|
| 382 |
*
|
| 383 |
* @param WP_REST_Request $request Full details about the request.
|
| 384 |
+
* @return WP_Error|boolean
|
| 385 |
*/
|
| 386 |
+
public function delete_item_permissions_check( $request ) {
|
|
|
|
| 387 |
if ( ! $this->check_is_taxonomy_allowed( $this->taxonomy ) ) {
|
| 388 |
return false;
|
| 389 |
}
|
|
|
|
| 390 |
$term = get_term( (int) $request['id'], $this->taxonomy );
|
| 391 |
if ( ! $term ) {
|
| 392 |
return new WP_Error( 'rest_term_invalid', __( "Term doesn't exist." ), array( 'status' => 404 ) );
|
| 393 |
}
|
|
|
|
| 394 |
$taxonomy_obj = get_taxonomy( $this->taxonomy );
|
| 395 |
+
if ( ! current_user_can( $taxonomy_obj->cap->delete_terms ) ) {
|
| 396 |
+
return new WP_Error( 'rest_cannot_delete', __( 'Sorry, you cannot delete terms.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 397 |
}
|
|
|
|
| 398 |
return true;
|
| 399 |
}
|
| 400 |
|
| 401 |
/**
|
| 402 |
+
* Delete a single term from a taxonomy
|
| 403 |
*
|
| 404 |
+
* @param WP_REST_Request $request Full details about the request
|
| 405 |
+
* @return WP_REST_Response|WP_Error
|
| 406 |
*/
|
| 407 |
+
public function delete_item( $request ) {
|
| 408 |
|
| 409 |
+
$force = isset( $request['force'] ) ? (bool) $request['force'] : false;
|
| 410 |
+
|
| 411 |
+
// We don't support trashing for this type, error out
|
| 412 |
+
if ( ! $force ) {
|
| 413 |
+
return new WP_Error( 'rest_trash_not_supported', __( 'Terms do not support trashing.' ), array( 'status' => 501 ) );
|
| 414 |
}
|
| 415 |
|
| 416 |
$term = get_term( (int) $request['id'], $this->taxonomy );
|
| 417 |
+
$request->set_param( 'context', 'view' );
|
| 418 |
+
$response = $this->prepare_item_for_response( $term, $request );
|
|
|
|
| 419 |
|
| 420 |
+
$data = $response->get_data();
|
| 421 |
+
$data = array(
|
| 422 |
+
'data' => $data,
|
| 423 |
+
'deleted' => true,
|
| 424 |
+
);
|
| 425 |
+
$response->set_data( $data );
|
| 426 |
+
|
| 427 |
+
$retval = wp_delete_term( $term->term_id, $term->taxonomy );
|
| 428 |
+
if ( ! $retval ) {
|
| 429 |
+
return new WP_Error( 'rest_cannot_delete', __( 'The term cannot be deleted.' ), array( 'status' => 500 ) );
|
| 430 |
}
|
| 431 |
|
| 432 |
+
/**
|
| 433 |
+
* Fires after a single term is deleted via the REST API.
|
| 434 |
+
*
|
| 435 |
+
* @param WP_Term $term The deleted term.
|
| 436 |
+
* @param array $data The response data.
|
| 437 |
+
* @param WP_REST_Request $request The request sent to the API.
|
| 438 |
+
*/
|
| 439 |
+
do_action( "rest_delete_{$this->taxonomy}", $term, $data, $request );
|
| 440 |
+
|
| 441 |
+
return $response;
|
| 442 |
}
|
| 443 |
|
| 444 |
/**
|
| 462 |
*
|
| 463 |
* @param obj $item Term object
|
| 464 |
* @param WP_REST_Request $request
|
| 465 |
+
* @return WP_REST_Response $response
|
| 466 |
*/
|
| 467 |
public function prepare_item_for_response( $item, $request ) {
|
| 468 |
|
| 481 |
}
|
| 482 |
|
| 483 |
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
|
|
|
| 484 |
$data = $this->add_additional_fields_to_object( $data, $request );
|
| 485 |
+
$data = $this->filter_response_by_context( $data, $context );
|
| 486 |
|
| 487 |
$response = rest_ensure_response( $data );
|
| 488 |
|
| 497 |
* @param object $item The original term object.
|
| 498 |
* @param WP_REST_Request $request Request used to generate the response.
|
| 499 |
*/
|
| 500 |
+
return apply_filters( "rest_prepare_{$this->taxonomy}", $response, $item, $request );
|
| 501 |
}
|
| 502 |
|
| 503 |
/**
|
| 541 |
public function get_item_schema() {
|
| 542 |
$schema = array(
|
| 543 |
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
| 544 |
+
'title' => 'post_tag' === $this->taxonomy ? 'tag' : $this->taxonomy,
|
| 545 |
'type' => 'object',
|
| 546 |
'properties' => array(
|
| 547 |
'id' => array(
|
| 615 |
*/
|
| 616 |
public function get_collection_params() {
|
| 617 |
$query_params = parent::get_collection_params();
|
| 618 |
+
$taxonomy = get_taxonomy( $this->taxonomy );
|
| 619 |
|
| 620 |
$query_params['context']['default'] = 'view';
|
| 621 |
|
| 622 |
+
$query_params['exclude'] = array(
|
| 623 |
+
'description' => __( 'Ensure result set excludes specific ids.' ),
|
| 624 |
+
'type' => 'array',
|
| 625 |
+
'default' => array(),
|
| 626 |
+
'sanitize_callback' => 'wp_parse_id_list',
|
| 627 |
+
);
|
| 628 |
$query_params['include'] = array(
|
| 629 |
'description' => __( 'Limit result set to specific ids.' ),
|
| 630 |
'type' => 'array',
|
| 631 |
'default' => array(),
|
| 632 |
'sanitize_callback' => 'wp_parse_id_list',
|
| 633 |
);
|
| 634 |
+
if ( ! $taxonomy->hierarchical ) {
|
| 635 |
+
$query_params['offset'] = array(
|
| 636 |
+
'description' => __( 'Offset the result set by a specific number of items.' ),
|
| 637 |
+
'type' => 'integer',
|
| 638 |
+
'sanitize_callback' => 'absint',
|
| 639 |
+
);
|
| 640 |
+
}
|
| 641 |
$query_params['order'] = array(
|
| 642 |
'description' => __( 'Order sort attribute ascending or descending.' ),
|
| 643 |
'type' => 'string',
|
| 659 |
'name',
|
| 660 |
'slug',
|
| 661 |
'term_group',
|
|
|
|
| 662 |
'description',
|
| 663 |
'count',
|
| 664 |
),
|
| 668 |
'type' => 'boolean',
|
| 669 |
'default' => false,
|
| 670 |
);
|
|
|
|
| 671 |
if ( $taxonomy->hierarchical ) {
|
| 672 |
$query_params['parent'] = array(
|
| 673 |
'description' => __( 'Limit result set to terms assigned to a specific parent term.' ),
|
| 675 |
'sanitize_callback' => 'absint',
|
| 676 |
);
|
| 677 |
}
|
| 678 |
+
$query_params['post'] = array(
|
| 679 |
+
'description' => __( 'Limit result set to terms assigned to a specific post.' ),
|
| 680 |
+
'type' => 'number',
|
| 681 |
+
'default' => false,
|
| 682 |
+
);
|
| 683 |
+
$query_params['slug'] = array(
|
| 684 |
+
'description' => __( 'Limit result set to terms with a specific slug.' ),
|
| 685 |
+
'type' => 'string',
|
| 686 |
+
);
|
| 687 |
return $query_params;
|
| 688 |
}
|
| 689 |
|
| 691 |
* Check that the taxonomy is valid
|
| 692 |
*
|
| 693 |
* @param string
|
| 694 |
+
* @return WP_Error|boolean
|
| 695 |
*/
|
| 696 |
protected function check_is_taxonomy_allowed( $taxonomy ) {
|
| 697 |
$taxonomy_obj = get_taxonomy( $taxonomy );
|
lib/endpoints/class-wp-rest-users-controller.php
CHANGED
|
@@ -52,7 +52,8 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
|
|
| 52 |
'permission_callback' => array( $this, 'delete_item_permissions_check' ),
|
| 53 |
'args' => array(
|
| 54 |
'force' => array(
|
| 55 |
-
'default'
|
|
|
|
| 56 |
),
|
| 57 |
'reassign' => array(),
|
| 58 |
),
|
|
@@ -80,10 +81,15 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
|
|
| 80 |
public function get_items( $request ) {
|
| 81 |
|
| 82 |
$prepared_args = array();
|
|
|
|
| 83 |
$prepared_args['include'] = $request['include'];
|
| 84 |
$prepared_args['order'] = $request['order'];
|
| 85 |
$prepared_args['number'] = $request['per_page'];
|
| 86 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 87 |
$orderby_possibles = array(
|
| 88 |
'id' => 'ID',
|
| 89 |
'include' => 'include',
|
|
@@ -104,10 +110,15 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
|
|
| 104 |
$prepared_args['search'] = '*' . $prepared_args['search'] . '*';
|
| 105 |
}
|
| 106 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
/**
|
| 108 |
* Filter arguments, before passing to WP_User_Query, when querying users via the REST API.
|
| 109 |
*
|
| 110 |
-
* @see https://
|
| 111 |
*
|
| 112 |
* @param array $prepared_args Array of arguments for WP_User_Query.
|
| 113 |
* @param WP_REST_Request $request The current request.
|
|
@@ -115,9 +126,6 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
|
|
| 115 |
$prepared_args = apply_filters( 'rest_user_query', $prepared_args, $request );
|
| 116 |
|
| 117 |
$query = new WP_User_Query( $prepared_args );
|
| 118 |
-
if ( is_wp_error( $query ) ) {
|
| 119 |
-
return $query;
|
| 120 |
-
}
|
| 121 |
|
| 122 |
$users = array();
|
| 123 |
foreach ( $query->results as $user ) {
|
|
@@ -130,13 +138,17 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
|
|
| 130 |
// Store pagation values for headers then unset for count query.
|
| 131 |
$per_page = (int) $prepared_args['number'];
|
| 132 |
$page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 );
|
| 133 |
-
unset( $prepared_args['number'] );
|
| 134 |
-
unset( $prepared_args['offset'] );
|
| 135 |
|
| 136 |
$prepared_args['fields'] = 'ID';
|
| 137 |
|
| 138 |
-
$
|
| 139 |
-
$total_users
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 140 |
$response->header( 'X-WP-Total', (int) $total_users );
|
| 141 |
$max_pages = ceil( $total_users / $per_page );
|
| 142 |
$response->header( 'X-WP-TotalPages', (int) $max_pages );
|
|
@@ -159,6 +171,38 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
|
|
| 159 |
return $response;
|
| 160 |
}
|
| 161 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 162 |
/**
|
| 163 |
* Get a single user
|
| 164 |
*
|
|
@@ -191,14 +235,8 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
|
|
| 191 |
return new WP_Error( 'rest_not_logged_in', __( 'You are not currently logged in.' ), array( 'status' => 401 ) );
|
| 192 |
}
|
| 193 |
|
| 194 |
-
$
|
| 195 |
-
$
|
| 196 |
-
$get_request->set_param( 'context', $request['context'] );
|
| 197 |
-
$response = $this->get_item( $get_request );
|
| 198 |
-
if ( is_wp_error( $response ) ) {
|
| 199 |
-
return $response;
|
| 200 |
-
}
|
| 201 |
-
|
| 202 |
$response = rest_ensure_response( $response );
|
| 203 |
$response->header( 'Location', rest_url( sprintf( '/wp/v2/users/%d', $current_user_id ) ) );
|
| 204 |
$response->set_status( 302 );
|
|
@@ -206,6 +244,21 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
|
|
| 206 |
return $response;
|
| 207 |
}
|
| 208 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 209 |
/**
|
| 210 |
* Create a single user
|
| 211 |
*
|
|
@@ -243,9 +296,9 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
|
|
| 243 |
if ( is_wp_error( $user_id ) ) {
|
| 244 |
return $user_id;
|
| 245 |
}
|
| 246 |
-
$user->ID = $user_id;
|
| 247 |
}
|
| 248 |
|
|
|
|
| 249 |
$this->update_additional_fields_for_object( $user, $request );
|
| 250 |
|
| 251 |
/**
|
|
@@ -253,14 +306,12 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
|
|
| 253 |
*
|
| 254 |
* @param object $user Data used to create the user (not a WP_User object).
|
| 255 |
* @param WP_REST_Request $request Request object.
|
| 256 |
-
* @param
|
| 257 |
*/
|
| 258 |
do_action( 'rest_insert_user', $user, $request, true );
|
| 259 |
|
| 260 |
-
$
|
| 261 |
-
$
|
| 262 |
-
$get_request->set_param( 'context', 'edit' );
|
| 263 |
-
$response = $this->get_item( $get_request );
|
| 264 |
$response = rest_ensure_response( $response );
|
| 265 |
$response->set_status( 201 );
|
| 266 |
$response->header( 'Location', rest_url( '/wp/v2/users/' . $user_id ) );
|
|
@@ -268,6 +319,27 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
|
|
| 268 |
return $response;
|
| 269 |
}
|
| 270 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 271 |
/**
|
| 272 |
* Update a single user
|
| 273 |
*
|
|
@@ -311,17 +383,33 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
|
|
| 311 |
return $user_id;
|
| 312 |
}
|
| 313 |
|
|
|
|
| 314 |
$this->update_additional_fields_for_object( $user, $request );
|
| 315 |
|
| 316 |
/* This action is documented in lib/endpoints/class-wp-rest-users-controller.php */
|
| 317 |
do_action( 'rest_insert_user', $user, $request, false );
|
| 318 |
|
| 319 |
-
$
|
| 320 |
-
$
|
| 321 |
-
$
|
| 322 |
-
$response
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 323 |
|
| 324 |
-
return
|
| 325 |
}
|
| 326 |
|
| 327 |
/**
|
|
@@ -351,10 +439,8 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
|
|
| 351 |
}
|
| 352 |
}
|
| 353 |
|
| 354 |
-
$
|
| 355 |
-
$
|
| 356 |
-
$get_request->set_param( 'context', 'edit' );
|
| 357 |
-
$orig_user = $this->prepare_item_for_response( $user, $get_request );
|
| 358 |
|
| 359 |
$data = $orig_user->get_data();
|
| 360 |
$data = array(
|
|
@@ -383,98 +469,12 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
|
|
| 383 |
return $orig_user;
|
| 384 |
}
|
| 385 |
|
| 386 |
-
/**
|
| 387 |
-
* Check if a given request has access to read a user
|
| 388 |
-
*
|
| 389 |
-
* @param WP_REST_Request $request Full details about the request.
|
| 390 |
-
* @return bool|WP_Error
|
| 391 |
-
*/
|
| 392 |
-
public function get_item_permissions_check( $request ) {
|
| 393 |
-
|
| 394 |
-
$id = (int) $request['id'];
|
| 395 |
-
$user = get_userdata( $id );
|
| 396 |
-
|
| 397 |
-
if ( empty( $id ) || empty( $user->ID ) ) {
|
| 398 |
-
return new WP_Error( 'rest_user_invalid_id', __( 'Invalid user id.' ), array( 'status' => 404 ) );
|
| 399 |
-
}
|
| 400 |
-
|
| 401 |
-
if ( get_current_user_id() === $id ) {
|
| 402 |
-
return true;
|
| 403 |
-
}
|
| 404 |
-
|
| 405 |
-
$context = ! empty( $request['context'] ) && in_array( $request['context'], array( 'edit', 'view', 'embed' ) ) ? $request['context'] : 'embed';
|
| 406 |
-
|
| 407 |
-
if ( 'edit' === $context && ! current_user_can( 'edit_user', $id ) ) {
|
| 408 |
-
return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you cannot view this user with edit context' ), array( 'status' => rest_authorization_required_code() ) );
|
| 409 |
-
} else if ( 'view' === $context && ! current_user_can( 'list_users' ) ) {
|
| 410 |
-
return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you cannot view this user with view context' ), array( 'status' => rest_authorization_required_code() ) );
|
| 411 |
-
} else if ( 'embed' === $context && ! count_user_posts( $id ) && ! current_user_can( 'edit_user', $id ) && ! current_user_can( 'list_users' ) ) {
|
| 412 |
-
return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you cannot view this user' ), array( 'status' => rest_authorization_required_code() ) );
|
| 413 |
-
}
|
| 414 |
-
|
| 415 |
-
return true;
|
| 416 |
-
}
|
| 417 |
-
|
| 418 |
-
/**
|
| 419 |
-
* Check if a given request has access create users
|
| 420 |
-
*
|
| 421 |
-
* @param WP_REST_Request $request Full details about the request.
|
| 422 |
-
* @return bool
|
| 423 |
-
*/
|
| 424 |
-
public function create_item_permissions_check( $request ) {
|
| 425 |
-
|
| 426 |
-
if ( ! current_user_can( 'create_users' ) ) {
|
| 427 |
-
return new WP_Error( 'rest_cannot_create_user', __( 'Sorry, you are not allowed to create users.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 428 |
-
}
|
| 429 |
-
|
| 430 |
-
return true;
|
| 431 |
-
}
|
| 432 |
-
|
| 433 |
-
/**
|
| 434 |
-
* Check if a given request has access update a user
|
| 435 |
-
*
|
| 436 |
-
* @param WP_REST_Request $request Full details about the request.
|
| 437 |
-
* @return bool
|
| 438 |
-
*/
|
| 439 |
-
public function update_item_permissions_check( $request ) {
|
| 440 |
-
|
| 441 |
-
$id = (int) $request['id'];
|
| 442 |
-
|
| 443 |
-
if ( ! current_user_can( 'edit_user', $id ) ) {
|
| 444 |
-
return new WP_Error( 'rest_cannot_edit', __( 'Sorry, you are not allowed to edit users.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 445 |
-
}
|
| 446 |
-
|
| 447 |
-
if ( ! empty( $request['role'] ) && ! current_user_can( 'edit_users' ) ) {
|
| 448 |
-
return new WP_Error( 'rest_cannot_edit_roles', __( 'Sorry, you are not allowed to edit roles of users.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 449 |
-
}
|
| 450 |
-
|
| 451 |
-
return true;
|
| 452 |
-
}
|
| 453 |
-
|
| 454 |
-
/**
|
| 455 |
-
* Check if a given request has access delete a user
|
| 456 |
-
*
|
| 457 |
-
* @param WP_REST_Request $request Full details about the request.
|
| 458 |
-
* @return bool
|
| 459 |
-
*/
|
| 460 |
-
public function delete_item_permissions_check( $request ) {
|
| 461 |
-
|
| 462 |
-
$id = (int) $request['id'];
|
| 463 |
-
$reassign = isset( $request['reassign'] ) ? absint( $request['reassign'] ) : null;
|
| 464 |
-
|
| 465 |
-
if ( ! current_user_can( 'delete_user', $id ) ) {
|
| 466 |
-
return new WP_Error( 'rest_user_cannot_delete', __( 'Sorry, you are not allowed to delete this user.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 467 |
-
}
|
| 468 |
-
|
| 469 |
-
return true;
|
| 470 |
-
}
|
| 471 |
-
|
| 472 |
/**
|
| 473 |
* Prepare a single user output for response
|
| 474 |
*
|
| 475 |
* @param object $user User object.
|
| 476 |
* @param WP_REST_Request $request Request object.
|
| 477 |
-
* @return WP_REST_Response Response data.
|
| 478 |
*/
|
| 479 |
public function prepare_item_for_response( $user, $request ) {
|
| 480 |
$data = array(
|
|
@@ -497,9 +497,8 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
|
|
| 497 |
);
|
| 498 |
|
| 499 |
$context = ! empty( $request['context'] ) ? $request['context'] : 'embed';
|
| 500 |
-
$data = $this->filter_response_by_context( $data, $context );
|
| 501 |
-
|
| 502 |
$data = $this->add_additional_fields_to_object( $data, $request );
|
|
|
|
| 503 |
|
| 504 |
// Wrap the data in a response object
|
| 505 |
$response = rest_ensure_response( $data );
|
|
@@ -598,7 +597,7 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
|
|
| 598 |
*
|
| 599 |
* @param integer $user_id
|
| 600 |
* @param string $role
|
| 601 |
-
* @return
|
| 602 |
*/
|
| 603 |
protected function check_role_update( $user_id, $role ) {
|
| 604 |
global $wp_roles;
|
|
@@ -789,6 +788,11 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
|
|
| 789 |
'default' => array(),
|
| 790 |
'sanitize_callback' => 'wp_parse_id_list',
|
| 791 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 792 |
$query_params['order'] = array(
|
| 793 |
'default' => 'asc',
|
| 794 |
'description' => __( 'Order sort attribute ascending or descending.' ),
|
|
@@ -808,6 +812,10 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
|
|
| 808 |
'sanitize_callback' => 'sanitize_key',
|
| 809 |
'type' => 'string',
|
| 810 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
| 811 |
return $query_params;
|
| 812 |
}
|
| 813 |
}
|
| 52 |
'permission_callback' => array( $this, 'delete_item_permissions_check' ),
|
| 53 |
'args' => array(
|
| 54 |
'force' => array(
|
| 55 |
+
'default' => false,
|
| 56 |
+
'description' => __( 'Required to be true, as resource does not support trashing.' ),
|
| 57 |
),
|
| 58 |
'reassign' => array(),
|
| 59 |
),
|
| 81 |
public function get_items( $request ) {
|
| 82 |
|
| 83 |
$prepared_args = array();
|
| 84 |
+
$prepared_args['exclude'] = $request['exclude'];
|
| 85 |
$prepared_args['include'] = $request['include'];
|
| 86 |
$prepared_args['order'] = $request['order'];
|
| 87 |
$prepared_args['number'] = $request['per_page'];
|
| 88 |
+
if ( ! empty( $request['offset'] ) ) {
|
| 89 |
+
$prepared_args['offset'] = $request['offset'];
|
| 90 |
+
} else {
|
| 91 |
+
$prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number'];
|
| 92 |
+
}
|
| 93 |
$orderby_possibles = array(
|
| 94 |
'id' => 'ID',
|
| 95 |
'include' => 'include',
|
| 110 |
$prepared_args['search'] = '*' . $prepared_args['search'] . '*';
|
| 111 |
}
|
| 112 |
|
| 113 |
+
if ( ! empty( $request['slug'] ) ) {
|
| 114 |
+
$prepared_args['search'] = $request['slug'];
|
| 115 |
+
$prepared_args['search_columns'] = array( 'user_nicename' );
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
/**
|
| 119 |
* Filter arguments, before passing to WP_User_Query, when querying users via the REST API.
|
| 120 |
*
|
| 121 |
+
* @see https://developer.wordpress.org/reference/classes/wp_user_query/
|
| 122 |
*
|
| 123 |
* @param array $prepared_args Array of arguments for WP_User_Query.
|
| 124 |
* @param WP_REST_Request $request The current request.
|
| 126 |
$prepared_args = apply_filters( 'rest_user_query', $prepared_args, $request );
|
| 127 |
|
| 128 |
$query = new WP_User_Query( $prepared_args );
|
|
|
|
|
|
|
|
|
|
| 129 |
|
| 130 |
$users = array();
|
| 131 |
foreach ( $query->results as $user ) {
|
| 138 |
// Store pagation values for headers then unset for count query.
|
| 139 |
$per_page = (int) $prepared_args['number'];
|
| 140 |
$page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 );
|
|
|
|
|
|
|
| 141 |
|
| 142 |
$prepared_args['fields'] = 'ID';
|
| 143 |
|
| 144 |
+
$total_users = $query->get_total();
|
| 145 |
+
if ( $total_users < 1 ) {
|
| 146 |
+
// Out-of-bounds, run the query again without LIMIT for total count
|
| 147 |
+
unset( $prepared_args['number'] );
|
| 148 |
+
unset( $prepared_args['offset'] );
|
| 149 |
+
$count_query = new WP_User_Query( $prepared_args );
|
| 150 |
+
$total_users = $count_query->get_total();
|
| 151 |
+
}
|
| 152 |
$response->header( 'X-WP-Total', (int) $total_users );
|
| 153 |
$max_pages = ceil( $total_users / $per_page );
|
| 154 |
$response->header( 'X-WP-TotalPages', (int) $max_pages );
|
| 171 |
return $response;
|
| 172 |
}
|
| 173 |
|
| 174 |
+
/**
|
| 175 |
+
* Check if a given request has access to read a user
|
| 176 |
+
*
|
| 177 |
+
* @param WP_REST_Request $request Full details about the request.
|
| 178 |
+
* @return WP_Error|boolean
|
| 179 |
+
*/
|
| 180 |
+
public function get_item_permissions_check( $request ) {
|
| 181 |
+
|
| 182 |
+
$id = (int) $request['id'];
|
| 183 |
+
$user = get_userdata( $id );
|
| 184 |
+
|
| 185 |
+
if ( empty( $id ) || empty( $user->ID ) ) {
|
| 186 |
+
return new WP_Error( 'rest_user_invalid_id', __( 'Invalid user id.' ), array( 'status' => 404 ) );
|
| 187 |
+
}
|
| 188 |
+
|
| 189 |
+
if ( get_current_user_id() === $id ) {
|
| 190 |
+
return true;
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
$context = ! empty( $request['context'] ) && in_array( $request['context'], array( 'edit', 'view', 'embed' ) ) ? $request['context'] : 'embed';
|
| 194 |
+
|
| 195 |
+
if ( 'edit' === $context && ! current_user_can( 'edit_user', $id ) ) {
|
| 196 |
+
return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you cannot view this user with edit context' ), array( 'status' => rest_authorization_required_code() ) );
|
| 197 |
+
} else if ( 'view' === $context && ! current_user_can( 'list_users' ) ) {
|
| 198 |
+
return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you cannot view this user with view context' ), array( 'status' => rest_authorization_required_code() ) );
|
| 199 |
+
} else if ( 'embed' === $context && ! count_user_posts( $id ) && ! current_user_can( 'edit_user', $id ) && ! current_user_can( 'list_users' ) ) {
|
| 200 |
+
return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you cannot view this user' ), array( 'status' => rest_authorization_required_code() ) );
|
| 201 |
+
}
|
| 202 |
+
|
| 203 |
+
return true;
|
| 204 |
+
}
|
| 205 |
+
|
| 206 |
/**
|
| 207 |
* Get a single user
|
| 208 |
*
|
| 235 |
return new WP_Error( 'rest_not_logged_in', __( 'You are not currently logged in.' ), array( 'status' => 401 ) );
|
| 236 |
}
|
| 237 |
|
| 238 |
+
$user = wp_get_current_user();
|
| 239 |
+
$response = $this->prepare_item_for_response( $user, $request );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 240 |
$response = rest_ensure_response( $response );
|
| 241 |
$response->header( 'Location', rest_url( sprintf( '/wp/v2/users/%d', $current_user_id ) ) );
|
| 242 |
$response->set_status( 302 );
|
| 244 |
return $response;
|
| 245 |
}
|
| 246 |
|
| 247 |
+
/**
|
| 248 |
+
* Check if a given request has access create users
|
| 249 |
+
*
|
| 250 |
+
* @param WP_REST_Request $request Full details about the request.
|
| 251 |
+
* @return boolean
|
| 252 |
+
*/
|
| 253 |
+
public function create_item_permissions_check( $request ) {
|
| 254 |
+
|
| 255 |
+
if ( ! current_user_can( 'create_users' ) ) {
|
| 256 |
+
return new WP_Error( 'rest_cannot_create_user', __( 'Sorry, you are not allowed to create users.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 257 |
+
}
|
| 258 |
+
|
| 259 |
+
return true;
|
| 260 |
+
}
|
| 261 |
+
|
| 262 |
/**
|
| 263 |
* Create a single user
|
| 264 |
*
|
| 296 |
if ( is_wp_error( $user_id ) ) {
|
| 297 |
return $user_id;
|
| 298 |
}
|
|
|
|
| 299 |
}
|
| 300 |
|
| 301 |
+
$user = get_user_by( 'id', $user_id );
|
| 302 |
$this->update_additional_fields_for_object( $user, $request );
|
| 303 |
|
| 304 |
/**
|
| 306 |
*
|
| 307 |
* @param object $user Data used to create the user (not a WP_User object).
|
| 308 |
* @param WP_REST_Request $request Request object.
|
| 309 |
+
* @param boolean $creating True when creating user, false when updating user.
|
| 310 |
*/
|
| 311 |
do_action( 'rest_insert_user', $user, $request, true );
|
| 312 |
|
| 313 |
+
$request->set_param( 'context', 'edit' );
|
| 314 |
+
$response = $this->prepare_item_for_response( $user, $request );
|
|
|
|
|
|
|
| 315 |
$response = rest_ensure_response( $response );
|
| 316 |
$response->set_status( 201 );
|
| 317 |
$response->header( 'Location', rest_url( '/wp/v2/users/' . $user_id ) );
|
| 319 |
return $response;
|
| 320 |
}
|
| 321 |
|
| 322 |
+
/**
|
| 323 |
+
* Check if a given request has access update a user
|
| 324 |
+
*
|
| 325 |
+
* @param WP_REST_Request $request Full details about the request.
|
| 326 |
+
* @return boolean
|
| 327 |
+
*/
|
| 328 |
+
public function update_item_permissions_check( $request ) {
|
| 329 |
+
|
| 330 |
+
$id = (int) $request['id'];
|
| 331 |
+
|
| 332 |
+
if ( ! current_user_can( 'edit_user', $id ) ) {
|
| 333 |
+
return new WP_Error( 'rest_cannot_edit', __( 'Sorry, you are not allowed to edit users.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 334 |
+
}
|
| 335 |
+
|
| 336 |
+
if ( ! empty( $request['role'] ) && ! current_user_can( 'edit_users' ) ) {
|
| 337 |
+
return new WP_Error( 'rest_cannot_edit_roles', __( 'Sorry, you are not allowed to edit roles of users.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 338 |
+
}
|
| 339 |
+
|
| 340 |
+
return true;
|
| 341 |
+
}
|
| 342 |
+
|
| 343 |
/**
|
| 344 |
* Update a single user
|
| 345 |
*
|
| 383 |
return $user_id;
|
| 384 |
}
|
| 385 |
|
| 386 |
+
$user = get_user_by( 'id', $id );
|
| 387 |
$this->update_additional_fields_for_object( $user, $request );
|
| 388 |
|
| 389 |
/* This action is documented in lib/endpoints/class-wp-rest-users-controller.php */
|
| 390 |
do_action( 'rest_insert_user', $user, $request, false );
|
| 391 |
|
| 392 |
+
$request->set_param( 'context', 'edit' );
|
| 393 |
+
$response = $this->prepare_item_for_response( $user, $request );
|
| 394 |
+
$response = rest_ensure_response( $response );
|
| 395 |
+
return $response;
|
| 396 |
+
}
|
| 397 |
+
|
| 398 |
+
/**
|
| 399 |
+
* Check if a given request has access delete a user
|
| 400 |
+
*
|
| 401 |
+
* @param WP_REST_Request $request Full details about the request.
|
| 402 |
+
* @return boolean
|
| 403 |
+
*/
|
| 404 |
+
public function delete_item_permissions_check( $request ) {
|
| 405 |
+
|
| 406 |
+
$id = (int) $request['id'];
|
| 407 |
+
|
| 408 |
+
if ( ! current_user_can( 'delete_user', $id ) ) {
|
| 409 |
+
return new WP_Error( 'rest_user_cannot_delete', __( 'Sorry, you are not allowed to delete this user.' ), array( 'status' => rest_authorization_required_code() ) );
|
| 410 |
+
}
|
| 411 |
|
| 412 |
+
return true;
|
| 413 |
}
|
| 414 |
|
| 415 |
/**
|
| 439 |
}
|
| 440 |
}
|
| 441 |
|
| 442 |
+
$request->set_param( 'context', 'edit' );
|
| 443 |
+
$orig_user = $this->prepare_item_for_response( $user, $request );
|
|
|
|
|
|
|
| 444 |
|
| 445 |
$data = $orig_user->get_data();
|
| 446 |
$data = array(
|
| 469 |
return $orig_user;
|
| 470 |
}
|
| 471 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 472 |
/**
|
| 473 |
* Prepare a single user output for response
|
| 474 |
*
|
| 475 |
* @param object $user User object.
|
| 476 |
* @param WP_REST_Request $request Request object.
|
| 477 |
+
* @return WP_REST_Response $response Response data.
|
| 478 |
*/
|
| 479 |
public function prepare_item_for_response( $user, $request ) {
|
| 480 |
$data = array(
|
| 497 |
);
|
| 498 |
|
| 499 |
$context = ! empty( $request['context'] ) ? $request['context'] : 'embed';
|
|
|
|
|
|
|
| 500 |
$data = $this->add_additional_fields_to_object( $data, $request );
|
| 501 |
+
$data = $this->filter_response_by_context( $data, $context );
|
| 502 |
|
| 503 |
// Wrap the data in a response object
|
| 504 |
$response = rest_ensure_response( $data );
|
| 597 |
*
|
| 598 |
* @param integer $user_id
|
| 599 |
* @param string $role
|
| 600 |
+
* @return WP_Error|boolean
|
| 601 |
*/
|
| 602 |
protected function check_role_update( $user_id, $role ) {
|
| 603 |
global $wp_roles;
|
| 788 |
'default' => array(),
|
| 789 |
'sanitize_callback' => 'wp_parse_id_list',
|
| 790 |
);
|
| 791 |
+
$query_params['offset'] = array(
|
| 792 |
+
'description' => __( 'Offset the result set by a specific number of items.' ),
|
| 793 |
+
'type' => 'integer',
|
| 794 |
+
'sanitize_callback' => 'absint',
|
| 795 |
+
);
|
| 796 |
$query_params['order'] = array(
|
| 797 |
'default' => 'asc',
|
| 798 |
'description' => __( 'Order sort attribute ascending or descending.' ),
|
| 812 |
'sanitize_callback' => 'sanitize_key',
|
| 813 |
'type' => 'string',
|
| 814 |
);
|
| 815 |
+
$query_params['slug'] = array(
|
| 816 |
+
'description' => __( 'Limit result set to users with a specific slug.' ),
|
| 817 |
+
'type' => 'string',
|
| 818 |
+
);
|
| 819 |
return $query_params;
|
| 820 |
}
|
| 821 |
}
|
plugin.php
CHANGED
|
@@ -4,7 +4,7 @@
|
|
| 4 |
* Description: JSON-based REST API for WordPress, developed as part of GSoC 2013.
|
| 5 |
* Author: WP REST API Team
|
| 6 |
* Author URI: http://wp-api.org
|
| 7 |
-
* Version: 2.0-
|
| 8 |
* Plugin URI: https://github.com/WP-API/WP-API
|
| 9 |
* License: GPL2+
|
| 10 |
*/
|
|
@@ -12,67 +12,86 @@
|
|
| 12 |
/**
|
| 13 |
* WP_REST_Controller class.
|
| 14 |
*/
|
| 15 |
-
|
|
|
|
|
|
|
| 16 |
|
| 17 |
/**
|
| 18 |
* WP_REST_Posts_Controller class.
|
| 19 |
*/
|
| 20 |
-
|
|
|
|
|
|
|
| 21 |
|
| 22 |
/**
|
| 23 |
* WP_REST_Attachments_Controller class.
|
| 24 |
*/
|
| 25 |
-
|
|
|
|
|
|
|
| 26 |
|
| 27 |
/**
|
| 28 |
* WP_REST_Post_Types_Controller class.
|
| 29 |
*/
|
| 30 |
-
|
|
|
|
|
|
|
| 31 |
|
| 32 |
/**
|
| 33 |
* WP_REST_Post_Statuses_Controller class.
|
| 34 |
*/
|
| 35 |
-
|
|
|
|
|
|
|
| 36 |
|
| 37 |
/**
|
| 38 |
* WP_REST_Revisions_Controller class.
|
| 39 |
*/
|
| 40 |
-
|
|
|
|
|
|
|
| 41 |
|
| 42 |
/**
|
| 43 |
* WP_REST_Taxonomies_Controller class.
|
| 44 |
*/
|
| 45 |
-
|
|
|
|
|
|
|
| 46 |
|
| 47 |
/**
|
| 48 |
* WP_REST_Terms_Controller class.
|
| 49 |
*/
|
| 50 |
-
|
|
|
|
|
|
|
| 51 |
|
| 52 |
/**
|
| 53 |
* WP_REST_Users_Controller class.
|
| 54 |
*/
|
| 55 |
-
|
|
|
|
|
|
|
| 56 |
|
| 57 |
/**
|
| 58 |
* WP_REST_Comments_Controller class.
|
| 59 |
*/
|
| 60 |
-
|
|
|
|
|
|
|
| 61 |
|
| 62 |
/**
|
| 63 |
* WP_REST_Meta_Controller class.
|
| 64 |
*/
|
| 65 |
-
|
|
|
|
|
|
|
| 66 |
|
| 67 |
/**
|
| 68 |
* WP_REST_Meta_Posts_Controller class.
|
| 69 |
*/
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
* WP_REST_Posts_Terms_Controller class.
|
| 74 |
-
*/
|
| 75 |
-
include_once dirname( __FILE__ ) . '/lib/endpoints/class-wp-rest-posts-terms-controller.php';
|
| 76 |
|
| 77 |
/**
|
| 78 |
* REST extras.
|
|
@@ -139,80 +158,72 @@ function _add_extra_api_taxonomy_arguments() {
|
|
| 139 |
}
|
| 140 |
}
|
| 141 |
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
|
|
|
| 148 |
|
| 149 |
-
|
| 150 |
-
|
| 151 |
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 158 |
}
|
| 159 |
|
|
|
|
|
|
|
| 160 |
$controller->register_routes();
|
| 161 |
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
}
|
| 170 |
|
| 171 |
-
|
|
|
|
|
|
|
| 172 |
|
| 173 |
-
if (
|
|
|
|
|
|
|
|
|
|
|
|
|
| 174 |
continue;
|
| 175 |
}
|
| 176 |
|
| 177 |
-
$
|
| 178 |
-
$posts_terms_controller->register_routes();
|
| 179 |
}
|
| 180 |
-
}
|
| 181 |
-
|
| 182 |
-
// Post types.
|
| 183 |
-
$controller = new WP_REST_Post_Types_Controller;
|
| 184 |
-
$controller->register_routes();
|
| 185 |
-
|
| 186 |
-
// Post statuses.
|
| 187 |
-
$controller = new WP_REST_Post_Statuses_Controller;
|
| 188 |
-
$controller->register_routes();
|
| 189 |
-
|
| 190 |
-
// Taxonomies.
|
| 191 |
-
$controller = new WP_REST_Taxonomies_Controller;
|
| 192 |
-
$controller->register_routes();
|
| 193 |
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
$
|
| 197 |
-
|
| 198 |
-
if ( ! class_exists( $class ) ) {
|
| 199 |
-
continue;
|
| 200 |
-
}
|
| 201 |
-
$controller = new $class( $taxonomy->name );
|
| 202 |
-
if ( ! is_subclass_of( $controller, 'WP_REST_Controller' ) ) {
|
| 203 |
-
continue;
|
| 204 |
-
}
|
| 205 |
|
|
|
|
|
|
|
| 206 |
$controller->register_routes();
|
| 207 |
}
|
| 208 |
-
|
| 209 |
-
// Users.
|
| 210 |
-
$controller = new WP_REST_Users_Controller;
|
| 211 |
-
$controller->register_routes();
|
| 212 |
-
|
| 213 |
-
// Comments.
|
| 214 |
-
$controller = new WP_REST_Comments_Controller;
|
| 215 |
-
$controller->register_routes();
|
| 216 |
}
|
| 217 |
|
| 218 |
if ( ! function_exists( 'rest_authorization_required_code' ) ) {
|
| 4 |
* Description: JSON-based REST API for WordPress, developed as part of GSoC 2013.
|
| 5 |
* Author: WP REST API Team
|
| 6 |
* Author URI: http://wp-api.org
|
| 7 |
+
* Version: 2.0-beta11
|
| 8 |
* Plugin URI: https://github.com/WP-API/WP-API
|
| 9 |
* License: GPL2+
|
| 10 |
*/
|
| 12 |
/**
|
| 13 |
* WP_REST_Controller class.
|
| 14 |
*/
|
| 15 |
+
if ( ! class_exists( 'WP_REST_Controller' ) ) {
|
| 16 |
+
require_once dirname( __FILE__ ) . '/lib/endpoints/class-wp-rest-controller.php';
|
| 17 |
+
}
|
| 18 |
|
| 19 |
/**
|
| 20 |
* WP_REST_Posts_Controller class.
|
| 21 |
*/
|
| 22 |
+
if ( ! class_exists( 'WP_REST_Posts_Controller' ) ) {
|
| 23 |
+
require_once dirname( __FILE__ ) . '/lib/endpoints/class-wp-rest-posts-controller.php';
|
| 24 |
+
}
|
| 25 |
|
| 26 |
/**
|
| 27 |
* WP_REST_Attachments_Controller class.
|
| 28 |
*/
|
| 29 |
+
if ( ! class_exists( 'WP_REST_Attachments_Controller' ) ) {
|
| 30 |
+
require_once dirname( __FILE__ ) . '/lib/endpoints/class-wp-rest-attachments-controller.php';
|
| 31 |
+
}
|
| 32 |
|
| 33 |
/**
|
| 34 |
* WP_REST_Post_Types_Controller class.
|
| 35 |
*/
|
| 36 |
+
if ( ! class_exists( 'WP_REST_Post_Types_Controller' ) ) {
|
| 37 |
+
require_once dirname( __FILE__ ) . '/lib/endpoints/class-wp-rest-post-types-controller.php';
|
| 38 |
+
}
|
| 39 |
|
| 40 |
/**
|
| 41 |
* WP_REST_Post_Statuses_Controller class.
|
| 42 |
*/
|
| 43 |
+
if ( ! class_exists( 'WP_REST_Post_Statuses_Controller' ) ) {
|
| 44 |
+
require_once dirname( __FILE__ ) . '/lib/endpoints/class-wp-rest-post-statuses-controller.php';
|
| 45 |
+
}
|
| 46 |
|
| 47 |
/**
|
| 48 |
* WP_REST_Revisions_Controller class.
|
| 49 |
*/
|
| 50 |
+
if ( ! class_exists( 'WP_REST_Revisions_Controller' ) ) {
|
| 51 |
+
require_once dirname( __FILE__ ) . '/lib/endpoints/class-wp-rest-revisions-controller.php';
|
| 52 |
+
}
|
| 53 |
|
| 54 |
/**
|
| 55 |
* WP_REST_Taxonomies_Controller class.
|
| 56 |
*/
|
| 57 |
+
if ( ! class_exists( 'WP_REST_Taxonomies_Controller' ) ) {
|
| 58 |
+
require_once dirname( __FILE__ ) . '/lib/endpoints/class-wp-rest-taxonomies-controller.php';
|
| 59 |
+
}
|
| 60 |
|
| 61 |
/**
|
| 62 |
* WP_REST_Terms_Controller class.
|
| 63 |
*/
|
| 64 |
+
if ( ! class_exists( 'WP_REST_Terms_Controller' ) ) {
|
| 65 |
+
require_once dirname( __FILE__ ) . '/lib/endpoints/class-wp-rest-terms-controller.php';
|
| 66 |
+
}
|
| 67 |
|
| 68 |
/**
|
| 69 |
* WP_REST_Users_Controller class.
|
| 70 |
*/
|
| 71 |
+
if ( ! class_exists( 'WP_REST_Users_Controller' ) ) {
|
| 72 |
+
require_once dirname( __FILE__ ) . '/lib/endpoints/class-wp-rest-users-controller.php';
|
| 73 |
+
}
|
| 74 |
|
| 75 |
/**
|
| 76 |
* WP_REST_Comments_Controller class.
|
| 77 |
*/
|
| 78 |
+
if ( ! class_exists( 'WP_REST_Comments_Controller' ) ) {
|
| 79 |
+
require_once dirname( __FILE__ ) . '/lib/endpoints/class-wp-rest-comments-controller.php';
|
| 80 |
+
}
|
| 81 |
|
| 82 |
/**
|
| 83 |
* WP_REST_Meta_Controller class.
|
| 84 |
*/
|
| 85 |
+
if ( ! class_exists( 'WP_REST_Meta_Controller' ) ) {
|
| 86 |
+
require_once dirname( __FILE__ ) . '/lib/endpoints/class-wp-rest-meta-controller.php';
|
| 87 |
+
}
|
| 88 |
|
| 89 |
/**
|
| 90 |
* WP_REST_Meta_Posts_Controller class.
|
| 91 |
*/
|
| 92 |
+
if ( ! class_exists( 'WP_REST_Meta_Posts_Controller' ) ) {
|
| 93 |
+
require_once dirname( __FILE__ ) . '/lib/endpoints/class-wp-rest-meta-posts-controller.php';
|
| 94 |
+
}
|
|
|
|
|
|
|
|
|
|
| 95 |
|
| 96 |
/**
|
| 97 |
* REST extras.
|
| 158 |
}
|
| 159 |
}
|
| 160 |
|
| 161 |
+
if ( ! function_exists( 'create_initial_rest_routes' ) ) {
|
| 162 |
+
/**
|
| 163 |
+
* Registers default REST API routes.
|
| 164 |
+
*
|
| 165 |
+
* @since 4.4.0
|
| 166 |
+
*/
|
| 167 |
+
function create_initial_rest_routes() {
|
| 168 |
|
| 169 |
+
foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) {
|
| 170 |
+
$class = ! empty( $post_type->rest_controller_class ) ? $post_type->rest_controller_class : 'WP_REST_Posts_Controller';
|
| 171 |
|
| 172 |
+
if ( ! class_exists( $class ) ) {
|
| 173 |
+
continue;
|
| 174 |
+
}
|
| 175 |
+
$controller = new $class( $post_type->name );
|
| 176 |
+
if ( ! is_subclass_of( $controller, 'WP_REST_Controller' ) ) {
|
| 177 |
+
continue;
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
$controller->register_routes();
|
| 181 |
+
|
| 182 |
+
if ( post_type_supports( $post_type->name, 'custom-fields' ) ) {
|
| 183 |
+
$meta_controller = new WP_REST_Meta_Posts_Controller( $post_type->name );
|
| 184 |
+
$meta_controller->register_routes();
|
| 185 |
+
}
|
| 186 |
+
if ( post_type_supports( $post_type->name, 'revisions' ) ) {
|
| 187 |
+
$revisions_controller = new WP_REST_Revisions_Controller( $post_type->name );
|
| 188 |
+
$revisions_controller->register_routes();
|
| 189 |
+
}
|
| 190 |
}
|
| 191 |
|
| 192 |
+
// Post types.
|
| 193 |
+
$controller = new WP_REST_Post_Types_Controller;
|
| 194 |
$controller->register_routes();
|
| 195 |
|
| 196 |
+
// Post statuses.
|
| 197 |
+
$controller = new WP_REST_Post_Statuses_Controller;
|
| 198 |
+
$controller->register_routes();
|
| 199 |
+
|
| 200 |
+
// Taxonomies.
|
| 201 |
+
$controller = new WP_REST_Taxonomies_Controller;
|
| 202 |
+
$controller->register_routes();
|
|
|
|
| 203 |
|
| 204 |
+
// Terms.
|
| 205 |
+
foreach ( get_taxonomies( array( 'show_in_rest' => true ), 'object' ) as $taxonomy ) {
|
| 206 |
+
$class = ! empty( $taxonomy->rest_controller_class ) ? $taxonomy->rest_controller_class : 'WP_REST_Terms_Controller';
|
| 207 |
|
| 208 |
+
if ( ! class_exists( $class ) ) {
|
| 209 |
+
continue;
|
| 210 |
+
}
|
| 211 |
+
$controller = new $class( $taxonomy->name );
|
| 212 |
+
if ( ! is_subclass_of( $controller, 'WP_REST_Controller' ) ) {
|
| 213 |
continue;
|
| 214 |
}
|
| 215 |
|
| 216 |
+
$controller->register_routes();
|
|
|
|
| 217 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 218 |
|
| 219 |
+
// Users.
|
| 220 |
+
$controller = new WP_REST_Users_Controller;
|
| 221 |
+
$controller->register_routes();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 222 |
|
| 223 |
+
// Comments.
|
| 224 |
+
$controller = new WP_REST_Comments_Controller;
|
| 225 |
$controller->register_routes();
|
| 226 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 227 |
}
|
| 228 |
|
| 229 |
if ( ! function_exists( 'rest_authorization_required_code' ) ) {
|
readme.txt
CHANGED
|
@@ -3,7 +3,7 @@ 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-
|
| 7 |
License: GPLv2 or later
|
| 8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
| 9 |
|
|
@@ -36,6 +36,153 @@ For full-flavoured API support, you'll need to be using pretty permalinks to use
|
|
| 36 |
|
| 37 |
== Changelog ==
|
| 38 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
= 2.0 Beta 10.0 =
|
| 40 |
|
| 41 |
* SECURITY: Ensure media of private posts are private too.
|
| 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-beta11
|
| 7 |
License: GPLv2 or later
|
| 8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
| 9 |
|
| 36 |
|
| 37 |
== Changelog ==
|
| 38 |
|
| 39 |
+
= 2.0 Beta 11.0 =
|
| 40 |
+
|
| 41 |
+
* BREAKING CHANGE: Moves Post->Term relations to the Post Resource
|
| 42 |
+
|
| 43 |
+
Previously, a client would fetch a Post's Tags with `GET /wp/v2/posts/<id>/tags`.
|
| 44 |
+
|
| 45 |
+
In Beta 11, an array of term ids is included on the Post resource.
|
| 46 |
+
|
| 47 |
+
The collection of terms for a Post can be fetched with `GET /wp/v2/tags?post=<id>`.
|
| 48 |
+
|
| 49 |
+
The `WP_REST_Posts_Terms_Controller` class no longer exists.
|
| 50 |
+
|
| 51 |
+
(props @joehoyle, [#2063](https://github.com/WP-API/WP-API/pull/2063))
|
| 52 |
+
|
| 53 |
+
* BREAKING CHANGE: Adds latest JS client including a minified version.
|
| 54 |
+
|
| 55 |
+
See pull request for a summarized changelog.
|
| 56 |
+
|
| 57 |
+
(props @adamsilverstein, [#1981](https://github.com/WP-API/WP-API/pull/1981))
|
| 58 |
+
|
| 59 |
+
* BREAKING CHANGE: Changes `featured_image` attribute on Posts to `featured_media`.
|
| 60 |
+
|
| 61 |
+
While featuring other attachment types isn't yet officially supported, this makes it easier for us to introduce the possibility in the future.
|
| 62 |
+
|
| 63 |
+
(props @danielbachhuber, [#2044](https://github.com/WP-API/WP-API/pull/2044))
|
| 64 |
+
|
| 65 |
+
* BREAKING CHANGE: Uses discrete schema title for categories and tags.
|
| 66 |
+
|
| 67 |
+
If you've used `register_rest_field( 'term' )`, you'll need to change `'term'` to `'tag'` and/or `'category'`.
|
| 68 |
+
|
| 69 |
+
(props @danielbachhuber, [#2005](https://github.com/WP-API/WP-API/pull/2005))
|
| 70 |
+
|
| 71 |
+
* BREAKING CHANGE: Makes many filters dynamic based on the controller type.
|
| 72 |
+
|
| 73 |
+
If you were using the `rest_prepare_term` filter, you'll need to change it to `rest_prepare_post_tag` or `rest_prepare_category`.
|
| 74 |
+
|
| 75 |
+
If you were using `rest_post_query` or `rest_terms_query`, you'll need update your use to `rest_page_query`, etc.
|
| 76 |
+
|
| 77 |
+
If you were using `rest_post_trashable`, `rest_insert_post` or `rest_delete_post`, they are now dynamic based on the post type slug.
|
| 78 |
+
|
| 79 |
+
(props @danielbachhuber, [#2008](https://github.com/WP-API/WP-API/pull/2008), [#2010](https://github.com/WP-API/WP-API/pull/2010), [#2057](https://github.com/WP-API/WP-API/pull/2057), [#2058](https://github.com/WP-API/WP-API/pull/2058))
|
| 80 |
+
|
| 81 |
+
* Renames `GET /wp/v2/comments` `user` param to `author` to match resource attribute.
|
| 82 |
+
|
| 83 |
+
Not a breaking change, because it didn't work in the first place.
|
| 84 |
+
|
| 85 |
+
(props @danielbachhuber, [#2105](https://github.com/WP-API/WP-API/pull/2105))
|
| 86 |
+
|
| 87 |
+
* Adds support for `GET /wp/v2/pages parent=1,2,3`.
|
| 88 |
+
|
| 89 |
+
(props @danielbachhuber, [#2101](https://github.com/WP-API/WP-API/pull/2101))
|
| 90 |
+
|
| 91 |
+
* Persists image metadata title and caption when not present in the request.
|
| 92 |
+
|
| 93 |
+
(props @danielbachhuber, [#2079](https://github.com/WP-API/WP-API/pull/2079))
|
| 94 |
+
|
| 95 |
+
* Add `parent_exclude` param to `GET /wp/v2/posts`.
|
| 96 |
+
|
| 97 |
+
(props @danielbachhuber, [#2077](https://github.com/WP-API/WP-API/pull/2077))
|
| 98 |
+
|
| 99 |
+
* Adds `slug` param support for collections of Posts, Users, and Taxonomy Terms.
|
| 100 |
+
|
| 101 |
+
(props @danielbachhuber, [#2071](https://github.com/WP-API/WP-API/pull/2071), [#2072](https://github.com/WP-API/WP-API/pull/2072), [#2103](https://github.com/WP-API/WP-API/pull/2103))
|
| 102 |
+
|
| 103 |
+
* When a comment is already trashed, returns `410:rest_already_trashed`.
|
| 104 |
+
|
| 105 |
+
(props @danielbachhuber, [#2069](https://github.com/WP-API/WP-API/pull/2069))
|
| 106 |
+
|
| 107 |
+
* Filter the responses by context after processing additional fields.
|
| 108 |
+
|
| 109 |
+
(props @danielbachhuber, [#2067](https://github.com/WP-API/WP-API/pull/2067))
|
| 110 |
+
|
| 111 |
+
* Adds `offset` param support for collections of Posts, Users, Comments, and Taxonomy Terms.
|
| 112 |
+
|
| 113 |
+
(props @danielbachhuber, [#2061](https://github.com/WP-API/WP-API/pull/2061), [#2062](https://github.com/WP-API/WP-API/pull/2062), [#2064](https://github.com/WP-API/WP-API/pull/2064), [#2076](https://github.com/WP-API/WP-API/pull/2076))
|
| 114 |
+
|
| 115 |
+
* Adds `rest_insert_{$taxonomy}` and `rest_delete_{$taxonomy}` actions.
|
| 116 |
+
|
| 117 |
+
(props @danielbachhuber, [#2060](https://github.com/WP-API/WP-API/pull/2060))
|
| 118 |
+
|
| 119 |
+
* Provides more helpful error message/code on Post Create/Update fail.
|
| 120 |
+
|
| 121 |
+
(props @danielbachhuber, [#2053](https://github.com/WP-API/WP-API/pull/2053))
|
| 122 |
+
|
| 123 |
+
* Forces `GET /wp/v2/media` to be limited to `'status' => [ inherit, private, trash ]`
|
| 124 |
+
|
| 125 |
+
(props @danielbachhuber, [#2026](https://github.com/WP-API/WP-API/pull/2026))
|
| 126 |
+
|
| 127 |
+
* Uses more correct error code for `Comment::delete` permission check.
|
| 128 |
+
|
| 129 |
+
(props @danielbachhuber, [#2054](https://github.com/WP-API/WP-API/pull/2054))
|
| 130 |
+
|
| 131 |
+
* Calls `prepare_item_for_response()` directly in create and update methods.
|
| 132 |
+
|
| 133 |
+
This lets us pass the original request through, giving the method and its filter genuine context, and avoids an
|
| 134 |
+
unnecessary call to `get_item()`.
|
| 135 |
+
|
| 136 |
+
(props @danielbachhuber, [#2038](https://github.com/WP-API/WP-API/pull/2038), [#2040](https://github.com/WP-API/WP-API/pull/2040), [#2041](https://github.com/WP-API/WP-API/pull/2041), [#2043](https://github.com/WP-API/WP-API/pull/2043), [#2042](https://github.com/WP-API/WP-API/pull/2042))
|
| 137 |
+
|
| 138 |
+
* Moves permission check methods across controllers.
|
| 139 |
+
|
| 140 |
+
Placing them above the method they're supposed to check makes the code more readable.
|
| 141 |
+
|
| 142 |
+
(props @danielbachhuber, [#2030](https://github.com/WP-API/WP-API/pull/2030), [#2029](https://github.com/WP-API/WP-API/pull/2029), [#2034](https://github.com/WP-API/WP-API/pull/2034), [#2036](https://github.com/WP-API/WP-API/pull/2036), [#2037](https://github.com/WP-API/WP-API/pull/2037), [#2035](https://github.com/WP-API/WP-API/pull/2035), [#2039](https://github.com/WP-API/WP-API/pull/2039))
|
| 143 |
+
|
| 144 |
+
* Requires `force` argument for `DELETE /wp/v2/<taxonomy>/<id>`.
|
| 145 |
+
|
| 146 |
+
(props @danielbachhuber, [#2028](https://github.com/WP-API/WP-API/pull/2028))
|
| 147 |
+
|
| 148 |
+
* Conditionally requires and defines REST API classes and functions.
|
| 149 |
+
|
| 150 |
+
(props @danielbachhuber, [#2023](https://github.com/WP-API/WP-API/pull/2023), [#2024](https://github.com/WP-API/WP-API/pull/2024))
|
| 151 |
+
|
| 152 |
+
* Avoid a duplicate query for the comment count.
|
| 153 |
+
|
| 154 |
+
(props @rmccue, [#2015](https://github.com/WP-API/WP-API/pull/2015))
|
| 155 |
+
|
| 156 |
+
* Parses `$date` if available in `prepare_date_response()`
|
| 157 |
+
|
| 158 |
+
(props @adamsilverstein, [#1951](https://github.com/WP-API/WP-API/pull/1951))
|
| 159 |
+
|
| 160 |
+
* Abstracts `POST /wp/v2/media` permissions check.
|
| 161 |
+
|
| 162 |
+
(props @danielbachhuber, [#2003](https://github.com/WP-API/WP-API/pull/2003))
|
| 163 |
+
|
| 164 |
+
* Adds `exclude` param to getting collections of Posts, Users, Comments, and Taxonomy Terms.
|
| 165 |
+
|
| 166 |
+
(props @danielbachhuber, [#1998](https://github.com/WP-API/WP-API/pull/1998), [#1999](https://github.com/WP-API/WP-API/pull/1999), [#2000](https://github.com/WP-API/WP-API/pull/2000), [#2002](https://github.com/WP-API/WP-API/pull/2002))
|
| 167 |
+
|
| 168 |
+
* Adds `rest_comment_query` for filtering `GET /wp/v2/comments`.
|
| 169 |
+
|
| 170 |
+
(props @danielbachhuber, [#2007](https://github.com/WP-API/WP-API/pull/2007))
|
| 171 |
+
|
| 172 |
+
* Uses HTTP status code `500` for `db_update_error` when creating an attachment.
|
| 173 |
+
|
| 174 |
+
(props @danielbachhuber, [#1993](https://github.com/WP-API/WP-API/pull/1993))
|
| 175 |
+
|
| 176 |
+
* Adds helpful description to `force` param across all `DELETE` registrations
|
| 177 |
+
|
| 178 |
+
(props @danielbachhuber, [#2004](https://github.com/WP-API/WP-API/pull/2004), [#2027](https://github.com/WP-API/WP-API/pull/2027))
|
| 179 |
+
|
| 180 |
+
* In `GET /wp/v2/<taxonomy>`, drops support for `orderby=>term_id`.
|
| 181 |
+
|
| 182 |
+
Only one `id` is exposed through the REST API.
|
| 183 |
+
|
| 184 |
+
(props @danielbachhuber, [#1990](https://github.com/WP-API/WP-API/pull/1990))
|
| 185 |
+
|
| 186 |
= 2.0 Beta 10.0 =
|
| 187 |
|
| 188 |
* SECURITY: Ensure media of private posts are private too.
|
wp-api.js
CHANGED
|
@@ -8,8 +8,9 @@
|
|
| 8 |
this.views = {};
|
| 9 |
}
|
| 10 |
|
| 11 |
-
window.wp
|
| 12 |
-
wp.api
|
|
|
|
| 13 |
|
| 14 |
})( window );
|
| 15 |
|
|
@@ -17,18 +18,20 @@
|
|
| 17 |
|
| 18 |
'use strict';
|
| 19 |
|
|
|
|
|
|
|
| 20 |
window.wp = window.wp || {};
|
| 21 |
wp.api = wp.api || {};
|
| 22 |
wp.api.utils = wp.api.utils || {};
|
| 23 |
|
| 24 |
/**
|
| 25 |
-
* ECMAScript 5 shim, from MDN.
|
| 26 |
* @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString
|
| 27 |
*/
|
| 28 |
if ( ! Date.prototype.toISOString ) {
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
if ( r.length
|
| 32 |
r = '0' + r;
|
| 33 |
}
|
| 34 |
|
|
@@ -62,6 +65,7 @@
|
|
| 62 |
// implementations could be faster.
|
| 63 |
// 1 YYYY 2 MM 3 DD 4 HH 5 mm 6 ss 7 msec 8 Z 9 ± 10 tzHH 11 tzmm
|
| 64 |
if ( ( struct = /^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/.exec( date ) ) ) {
|
|
|
|
| 65 |
// Avoid NaN timestamps caused by “undefined” values being passed to Date.UTC.
|
| 66 |
for ( i = 0; ( k = numericKeys[i] ); ++i ) {
|
| 67 |
struct[k] = +struct[k] || 0;
|
|
@@ -71,10 +75,10 @@
|
|
| 71 |
struct[2] = ( +struct[2] || 1 ) - 1;
|
| 72 |
struct[3] = +struct[3] || 1;
|
| 73 |
|
| 74 |
-
if ( struct[8] !==
|
| 75 |
minutesOffset = struct[10] * 60 + struct[11];
|
| 76 |
|
| 77 |
-
if ( struct[9]
|
| 78 |
minutesOffset = 0 - minutesOffset;
|
| 79 |
}
|
| 80 |
}
|
|
@@ -87,585 +91,667 @@
|
|
| 87 |
return timestamp;
|
| 88 |
};
|
| 89 |
|
| 90 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
|
| 97 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 98 |
|
| 99 |
/**
|
| 100 |
-
*
|
| 101 |
*
|
| 102 |
-
* @
|
| 103 |
*/
|
| 104 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
|
| 106 |
/**
|
| 107 |
-
*
|
| 108 |
*
|
| 109 |
-
* @
|
|
|
|
|
|
|
| 110 |
*/
|
| 111 |
-
|
|
|
|
| 112 |
/**
|
| 113 |
-
*
|
| 114 |
-
*
|
| 115 |
-
* @returns {*}.
|
| 116 |
*/
|
| 117 |
-
|
| 118 |
-
var attributes = _.clone( this.attributes );
|
| 119 |
|
| 120 |
-
//
|
| 121 |
-
_.
|
| 122 |
-
if ( key in attributes ) {
|
| 123 |
-
attributes[key] = attributes[key].toISOString();
|
| 124 |
-
}
|
| 125 |
-
});
|
| 126 |
|
| 127 |
-
|
| 128 |
-
|
| 129 |
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
* @returns {*}.
|
| 135 |
-
*/
|
| 136 |
-
parse: function( response ) {
|
| 137 |
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
return;
|
| 142 |
}
|
|
|
|
| 143 |
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 147 |
|
| 148 |
-
|
| 149 |
-
if ( 'undefined' !== typeof response.author ) {
|
| 150 |
-
response.author = new wp.api.models.User( response.author );
|
| 151 |
}
|
| 152 |
|
| 153 |
-
|
| 154 |
-
|
| 155 |
};
|
| 156 |
|
| 157 |
/**
|
| 158 |
-
*
|
| 159 |
*
|
| 160 |
-
* @
|
|
|
|
|
|
|
| 161 |
*/
|
| 162 |
-
|
| 163 |
-
/**
|
| 164 |
-
* Get parent object.
|
| 165 |
-
*
|
| 166 |
-
* @returns {Backbone.Model}
|
| 167 |
-
*/
|
| 168 |
-
parent: function() {
|
| 169 |
|
| 170 |
-
|
| 171 |
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
|
| 179 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 180 |
/**
|
| 181 |
-
*
|
| 182 |
-
*
|
|
|
|
| 183 |
*/
|
| 184 |
-
|
| 185 |
-
|
| 186 |
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
} else {
|
| 191 |
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
|
|
|
|
|
|
| 196 |
|
| 197 |
-
|
| 198 |
-
|
| 199 |
|
| 200 |
-
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 204 |
|
| 205 |
-
/**
|
| 206 |
-
* Private Backbone base model for all models.
|
| 207 |
-
*/
|
| 208 |
-
var WPApiBaseModel = Backbone.Model.extend(
|
| 209 |
-
/** @lends WPApiBaseModel.prototype */
|
| 210 |
-
{
|
| 211 |
/**
|
| 212 |
-
*
|
| 213 |
*
|
| 214 |
-
* @param
|
| 215 |
-
* @param
|
| 216 |
-
* @param
|
| 217 |
-
* @
|
|
|
|
|
|
|
|
|
|
| 218 |
*/
|
| 219 |
-
|
| 220 |
-
|
| 221 |
|
| 222 |
-
|
| 223 |
-
|
| 224 |
|
| 225 |
-
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
|
| 229 |
-
return beforeSend.apply( this, arguments );
|
| 230 |
-
}
|
| 231 |
-
};
|
| 232 |
}
|
| 233 |
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
|
| 238 |
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
|
| 242 |
-
|
| 243 |
-
* @param {Object} attributes
|
| 244 |
-
* @param {int} attributes.id The user id. Optional. Defaults to 'me', fetching the current user.
|
| 245 |
-
*/
|
| 246 |
-
wp.api.models.User = WPApiBaseModel.extend(
|
| 247 |
-
/** @lends User.prototype */
|
| 248 |
-
{
|
| 249 |
-
idAttribute: 'id',
|
| 250 |
|
| 251 |
-
|
|
|
|
| 252 |
|
| 253 |
-
|
| 254 |
-
|
| 255 |
-
|
| 256 |
-
|
| 257 |
-
|
| 258 |
-
|
| 259 |
-
|
| 260 |
-
|
| 261 |
-
last_name: '',
|
| 262 |
-
link: '',
|
| 263 |
-
name: '',
|
| 264 |
-
nickname: '',
|
| 265 |
-
registered_date: new Date(),
|
| 266 |
-
roles: [],
|
| 267 |
-
slug: '',
|
| 268 |
-
url: '',
|
| 269 |
-
username: '',
|
| 270 |
-
_links: {}
|
| 271 |
-
}
|
| 272 |
-
}
|
| 273 |
-
);
|
| 274 |
|
| 275 |
-
|
| 276 |
-
|
| 277 |
-
|
| 278 |
-
* @param {Object} attributes
|
| 279 |
-
* @param {string} attributes.slug The taxonomy slug.
|
| 280 |
-
*/
|
| 281 |
-
wp.api.models.Taxonomy = WPApiBaseModel.extend(
|
| 282 |
-
/** @lends Taxonomy.prototype */
|
| 283 |
-
{
|
| 284 |
-
idAttribute: 'slug',
|
| 285 |
|
| 286 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 287 |
|
| 288 |
-
|
| 289 |
-
|
| 290 |
-
slug: null,
|
| 291 |
-
description: '',
|
| 292 |
-
labels: {},
|
| 293 |
-
types: [],
|
| 294 |
-
show_cloud: false,
|
| 295 |
-
hierarchical: false
|
| 296 |
-
}
|
| 297 |
-
}
|
| 298 |
-
);
|
| 299 |
|
| 300 |
-
|
| 301 |
-
|
| 302 |
-
*
|
| 303 |
-
* @param {Object} attributes
|
| 304 |
-
* @param {int} id attributesm id.
|
| 305 |
-
*/
|
| 306 |
-
wp.api.models.Term = WPApiBaseModel.extend(
|
| 307 |
-
/** @lends Term.prototype */
|
| 308 |
-
{
|
| 309 |
-
idAttribute: 'id',
|
| 310 |
|
| 311 |
-
|
|
|
|
|
|
|
| 312 |
|
| 313 |
-
|
| 314 |
-
|
| 315 |
-
|
| 316 |
-
|
| 317 |
-
description: '',
|
| 318 |
-
parent: null,
|
| 319 |
-
count: 0,
|
| 320 |
-
link: '',
|
| 321 |
-
taxonomy: '',
|
| 322 |
-
_links: {}
|
| 323 |
-
}
|
| 324 |
|
| 325 |
-
|
| 326 |
-
|
|
|
|
| 327 |
|
| 328 |
-
|
| 329 |
-
|
| 330 |
-
*
|
| 331 |
-
* @param {Object} attributes
|
| 332 |
-
* @param {int} attributes.id The post id.
|
| 333 |
-
*/
|
| 334 |
-
wp.api.models.Post = WPApiBaseModel.extend( _.extend(
|
| 335 |
-
/** @lends Post.prototype */
|
| 336 |
-
{
|
| 337 |
-
idAttribute: 'id',
|
| 338 |
|
| 339 |
-
|
|
|
|
|
|
|
| 340 |
|
| 341 |
-
|
| 342 |
-
|
| 343 |
-
|
| 344 |
-
|
| 345 |
-
|
| 346 |
-
link: '',
|
| 347 |
-
modified: new Date(),
|
| 348 |
-
modified_gmt: new Date(),
|
| 349 |
-
password: '',
|
| 350 |
-
status: 'draft',
|
| 351 |
-
type: 'post',
|
| 352 |
-
title: {},
|
| 353 |
-
content: {},
|
| 354 |
-
author: null,
|
| 355 |
-
excerpt: {},
|
| 356 |
-
featured_image: null,
|
| 357 |
-
comment_status: 'open',
|
| 358 |
-
ping_status: 'open',
|
| 359 |
-
sticky: false,
|
| 360 |
-
format: 'standard',
|
| 361 |
-
_links: {}
|
| 362 |
-
}
|
| 363 |
-
}, TimeStampedMixin, HierarchicalMixin )
|
| 364 |
-
);
|
| 365 |
|
| 366 |
-
|
| 367 |
-
|
| 368 |
-
|
| 369 |
-
|
| 370 |
-
* @param {int} attributes.id The page id.
|
| 371 |
-
*/
|
| 372 |
-
wp.api.models.Page = WPApiBaseModel.extend( _.extend(
|
| 373 |
-
/** @lends Page.prototype */
|
| 374 |
-
{
|
| 375 |
-
idAttribute: 'id',
|
| 376 |
|
| 377 |
-
|
|
|
|
| 378 |
|
| 379 |
-
|
| 380 |
-
id: null,
|
| 381 |
-
date: new Date(),
|
| 382 |
-
date_gmt: new Date(),
|
| 383 |
-
guid: {},
|
| 384 |
-
link: '',
|
| 385 |
-
modified: new Date(),
|
| 386 |
-
modified_gmt: new Date(),
|
| 387 |
-
password: '',
|
| 388 |
-
slug: '',
|
| 389 |
-
status: 'draft',
|
| 390 |
-
type: 'page',
|
| 391 |
-
title: {},
|
| 392 |
-
content: {},
|
| 393 |
-
author: null,
|
| 394 |
-
excerpt: {},
|
| 395 |
-
featured_image: null,
|
| 396 |
-
comment_status: 'closed',
|
| 397 |
-
ping_status: 'closed',
|
| 398 |
-
menu_order: null,
|
| 399 |
-
template: '',
|
| 400 |
-
_links: {}
|
| 401 |
-
}
|
| 402 |
-
}, TimeStampedMixin, HierarchicalMixin )
|
| 403 |
-
);
|
| 404 |
|
| 405 |
-
|
| 406 |
-
|
| 407 |
-
|
| 408 |
-
|
| 409 |
-
* @param {int} attributes.parent The id of the post that this revision belongs to.
|
| 410 |
-
* @param {int} attributes.id The revision id.
|
| 411 |
-
*/
|
| 412 |
-
wp.api.models.PostRevision = WPApiBaseModel.extend( _.extend(
|
| 413 |
-
/** @lends PostRevision.prototype */
|
| 414 |
-
{
|
| 415 |
-
idAttribute: 'id',
|
| 416 |
|
| 417 |
-
|
| 418 |
-
|
| 419 |
-
|
| 420 |
-
|
| 421 |
-
date_gmt: new Date(),
|
| 422 |
-
guid: {},
|
| 423 |
-
modified: new Date(),
|
| 424 |
-
modified_gmt: new Date(),
|
| 425 |
-
parent: 0,
|
| 426 |
-
slug: '',
|
| 427 |
-
title: {},
|
| 428 |
-
content: {},
|
| 429 |
-
excerpt: {},
|
| 430 |
-
_links: {}
|
| 431 |
},
|
| 432 |
|
| 433 |
/**
|
| 434 |
-
*
|
| 435 |
-
*
|
| 436 |
-
* @returns {string}.
|
| 437 |
*/
|
| 438 |
-
|
| 439 |
-
|
| 440 |
-
|
|
|
|
|
|
|
| 441 |
|
| 442 |
-
|
| 443 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 444 |
|
| 445 |
-
|
| 446 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 447 |
|
| 448 |
-
|
| 449 |
-
|
| 450 |
-
|
| 451 |
-
|
| 452 |
-
|
| 453 |
-
|
| 454 |
-
|
| 455 |
-
|
| 456 |
-
|
| 457 |
-
|
|
|
|
|
|
|
| 458 |
|
| 459 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 460 |
|
| 461 |
-
|
| 462 |
-
|
| 463 |
-
|
| 464 |
-
date_gmt: new Date(),
|
| 465 |
-
guid: {},
|
| 466 |
-
link: '',
|
| 467 |
-
modified: new Date(),
|
| 468 |
-
modified_gmt: new Date(),
|
| 469 |
-
password: '',
|
| 470 |
-
slug: '',
|
| 471 |
-
status: 'draft',
|
| 472 |
-
type: 'attachment',
|
| 473 |
-
title: {},
|
| 474 |
-
author: null,
|
| 475 |
-
comment_status: 'open',
|
| 476 |
-
ping_status: 'open',
|
| 477 |
-
alt_text: '',
|
| 478 |
-
caption: '',
|
| 479 |
-
description: '',
|
| 480 |
-
media_type: '',
|
| 481 |
-
media_details: {},
|
| 482 |
-
post: null,
|
| 483 |
-
source_url: '',
|
| 484 |
-
_links: {}
|
| 485 |
-
}
|
| 486 |
|
| 487 |
-
|
| 488 |
-
);
|
| 489 |
|
| 490 |
-
|
| 491 |
-
|
| 492 |
-
|
| 493 |
-
|
| 494 |
-
|
| 495 |
-
|
| 496 |
-
|
| 497 |
-
|
| 498 |
-
|
| 499 |
-
|
| 500 |
|
| 501 |
-
|
|
|
|
| 502 |
|
| 503 |
-
|
| 504 |
-
|
| 505 |
-
|
| 506 |
-
author_email: '',
|
| 507 |
-
author_ip: '',
|
| 508 |
-
author_name: '',
|
| 509 |
-
author_url: '',
|
| 510 |
-
author_user_agent: '',
|
| 511 |
-
content: {},
|
| 512 |
-
date: new Date(),
|
| 513 |
-
date_gmt: new Date(),
|
| 514 |
-
karma: 0,
|
| 515 |
-
link: '',
|
| 516 |
-
parent: 0,
|
| 517 |
-
status: 'hold',
|
| 518 |
-
type: '',
|
| 519 |
-
_links: {}
|
| 520 |
-
}
|
| 521 |
|
| 522 |
-
|
| 523 |
-
|
|
|
|
| 524 |
|
| 525 |
-
|
| 526 |
-
|
| 527 |
-
*
|
| 528 |
-
* @param {Object} attributes
|
| 529 |
-
* @param {string} attributes.slug The post type slug.
|
| 530 |
-
*/
|
| 531 |
-
wp.api.models.PostType = WPApiBaseModel.extend(
|
| 532 |
-
/** @lends PostType.prototype */
|
| 533 |
-
{
|
| 534 |
-
idAttribute: 'slug',
|
| 535 |
|
| 536 |
-
|
|
|
|
|
|
|
| 537 |
|
| 538 |
-
|
| 539 |
-
|
| 540 |
-
|
| 541 |
-
|
| 542 |
-
|
| 543 |
-
|
| 544 |
},
|
| 545 |
|
| 546 |
/**
|
| 547 |
-
*
|
| 548 |
-
*
|
| 549 |
-
* @returns {boolean}.
|
| 550 |
*/
|
| 551 |
-
|
| 552 |
-
|
|
|
|
|
|
|
| 553 |
},
|
| 554 |
|
| 555 |
/**
|
| 556 |
-
*
|
| 557 |
-
*
|
| 558 |
-
* @returns {boolean}.
|
| 559 |
*/
|
| 560 |
-
|
| 561 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 562 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 563 |
}
|
| 564 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 565 |
|
| 566 |
/**
|
| 567 |
-
* Backbone model for
|
| 568 |
-
*
|
| 569 |
-
* @param {Object} attributes
|
| 570 |
-
* @param {string} attributes.slug The post status slug.
|
| 571 |
*/
|
| 572 |
-
wp.api.
|
| 573 |
-
/** @lends
|
| 574 |
{
|
| 575 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 576 |
|
| 577 |
-
|
| 578 |
|
| 579 |
-
|
| 580 |
-
|
| 581 |
-
|
| 582 |
-
|
| 583 |
-
|
| 584 |
-
|
| 585 |
-
|
| 586 |
-
|
| 587 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 588 |
},
|
| 589 |
|
| 590 |
/**
|
| 591 |
-
*
|
| 592 |
-
*
|
| 593 |
-
* @returns {boolean}.
|
| 594 |
*/
|
| 595 |
-
save: function() {
|
| 596 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 597 |
},
|
| 598 |
|
| 599 |
/**
|
| 600 |
-
*
|
| 601 |
-
*
|
| 602 |
-
* @returns {boolean}.
|
| 603 |
*/
|
| 604 |
-
destroy: function() {
|
| 605 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 606 |
}
|
|
|
|
| 607 |
}
|
| 608 |
);
|
| 609 |
|
| 610 |
/**
|
| 611 |
* API Schema model. Contains meta information about the API.
|
| 612 |
*/
|
| 613 |
-
wp.api.models.Schema = WPApiBaseModel.extend(
|
| 614 |
-
/** @lends
|
| 615 |
{
|
| 616 |
-
url: WP_API_Settings.root + 'wp/v2',
|
| 617 |
-
|
| 618 |
defaults: {
|
| 619 |
-
|
| 620 |
-
|
| 621 |
routes: {}
|
| 622 |
},
|
| 623 |
|
| 624 |
-
|
| 625 |
-
|
| 626 |
-
|
| 627 |
-
|
| 628 |
-
|
| 629 |
-
|
| 630 |
-
|
|
|
|
| 631 |
},
|
| 632 |
|
| 633 |
-
|
| 634 |
-
|
| 635 |
-
*
|
| 636 |
-
* @returns {boolean}.
|
| 637 |
-
*/
|
| 638 |
-
destroy: function() {
|
| 639 |
-
return false;
|
| 640 |
}
|
| 641 |
}
|
| 642 |
);
|
|
|
|
| 643 |
|
| 644 |
-
|
| 645 |
-
|
| 646 |
-
|
| 647 |
-
/* global WP_API_Settings:false */
|
| 648 |
-
(function( wp, WP_API_Settings, Backbone, _, window, undefined ) {
|
| 649 |
|
| 650 |
'use strict';
|
| 651 |
|
| 652 |
/**
|
| 653 |
* Contains basic collection functionality such as pagination.
|
| 654 |
*/
|
| 655 |
-
|
| 656 |
/** @lends BaseCollection.prototype */
|
| 657 |
{
|
| 658 |
|
| 659 |
/**
|
| 660 |
* Setup default state.
|
| 661 |
*/
|
| 662 |
-
initialize: function() {
|
| 663 |
this.state = {
|
| 664 |
data: {},
|
| 665 |
currentPage: null,
|
| 666 |
totalPages: null,
|
| 667 |
totalObjects: null
|
| 668 |
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 669 |
},
|
| 670 |
|
| 671 |
/**
|
|
@@ -679,13 +765,15 @@
|
|
| 679 |
* @returns {*}.
|
| 680 |
*/
|
| 681 |
sync: function( method, model, options ) {
|
| 682 |
-
|
| 683 |
-
var beforeSend = options.beforeSend,
|
| 684 |
self = this;
|
| 685 |
|
| 686 |
-
|
|
|
|
|
|
|
|
|
|
| 687 |
options.beforeSend = function( xhr ) {
|
| 688 |
-
xhr.setRequestHeader( 'X-WP-Nonce',
|
| 689 |
|
| 690 |
if ( beforeSend ) {
|
| 691 |
return beforeSend.apply( self, arguments );
|
|
@@ -710,12 +798,12 @@
|
|
| 710 |
self.state.currentPage = options.data.page - 1;
|
| 711 |
}
|
| 712 |
|
| 713 |
-
|
| 714 |
options.success = function( data, textStatus, request ) {
|
| 715 |
self.state.totalPages = parseInt( request.getResponseHeader( 'x-wp-totalpages' ), 10 );
|
| 716 |
self.state.totalObjects = parseInt( request.getResponseHeader( 'x-wp-total' ), 10 );
|
| 717 |
|
| 718 |
-
if ( self.state.currentPage
|
| 719 |
self.state.currentPage = 1;
|
| 720 |
} else {
|
| 721 |
self.state.currentPage++;
|
|
@@ -747,7 +835,7 @@
|
|
| 747 |
return false;
|
| 748 |
}
|
| 749 |
|
| 750 |
-
if ( this.state.currentPage
|
| 751 |
options.data.page = 2;
|
| 752 |
} else {
|
| 753 |
options.data.page = this.state.currentPage + 1;
|
|
@@ -763,9 +851,9 @@
|
|
| 763 |
* @returns null|boolean.
|
| 764 |
*/
|
| 765 |
hasMore: function() {
|
| 766 |
-
if ( this.state.totalPages
|
| 767 |
-
this.state.totalObjects
|
| 768 |
-
this.state.currentPage
|
| 769 |
return null;
|
| 770 |
} else {
|
| 771 |
return ( this.state.currentPage < this.state.totalPages );
|
|
@@ -774,209 +862,367 @@
|
|
| 774 |
}
|
| 775 |
);
|
| 776 |
|
| 777 |
-
|
| 778 |
-
* Backbone collection for posts.
|
| 779 |
-
*/
|
| 780 |
-
wp.api.collections.Posts = BaseCollection.extend(
|
| 781 |
-
/** @lends Posts.prototype */
|
| 782 |
-
{
|
| 783 |
-
url: WP_API_Settings.root + 'wp/v2/posts',
|
| 784 |
|
| 785 |
-
|
| 786 |
-
|
| 787 |
-
);
|
| 788 |
|
| 789 |
-
|
| 790 |
-
* Backbone collection for pages.
|
| 791 |
-
*/
|
| 792 |
-
wp.api.collections.Pages = BaseCollection.extend(
|
| 793 |
-
/** @lends Pages.prototype */
|
| 794 |
-
{
|
| 795 |
-
url: WP_API_Settings.root + 'wp/v2/pages',
|
| 796 |
|
| 797 |
-
|
| 798 |
-
}
|
| 799 |
-
);
|
| 800 |
|
| 801 |
-
|
| 802 |
-
|
| 803 |
-
*/
|
| 804 |
-
wp.api.collections.Users = BaseCollection.extend(
|
| 805 |
-
/** @lends Users.prototype */
|
| 806 |
-
{
|
| 807 |
-
url: WP_API_Settings.root + 'wp/v2/users',
|
| 808 |
|
| 809 |
-
|
| 810 |
-
|
| 811 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 812 |
|
| 813 |
-
|
| 814 |
-
|
| 815 |
-
*/
|
| 816 |
-
wp.api.collections.PostStatuses = BaseCollection.extend(
|
| 817 |
-
/** @lends PostStatuses.prototype */
|
| 818 |
-
{
|
| 819 |
-
url: WP_API_Settings.root + 'wp/v2/statuses',
|
| 820 |
|
| 821 |
-
|
| 822 |
|
| 823 |
-
|
| 824 |
-
|
| 825 |
|
| 826 |
-
|
| 827 |
-
|
| 828 |
-
|
| 829 |
-
|
| 830 |
-
}
|
| 831 |
|
| 832 |
-
|
| 833 |
-
|
| 834 |
-
|
| 835 |
-
|
| 836 |
|
| 837 |
-
|
| 838 |
-
* Backbone media library collection.
|
| 839 |
-
*/
|
| 840 |
-
wp.api.collections.MediaLibrary = BaseCollection.extend(
|
| 841 |
-
/** @lends MediaLibrary.prototype */
|
| 842 |
-
{
|
| 843 |
-
url: WP_API_Settings.root + 'wp/v2/media',
|
| 844 |
|
| 845 |
-
|
| 846 |
-
|
| 847 |
-
|
| 848 |
|
| 849 |
-
|
| 850 |
-
|
| 851 |
-
|
| 852 |
-
|
| 853 |
-
|
| 854 |
-
|
| 855 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 856 |
|
| 857 |
-
|
| 858 |
-
|
| 859 |
-
|
|
|
|
|
|
|
|
|
|
| 860 |
|
| 861 |
-
|
| 862 |
-
|
| 863 |
-
*/
|
| 864 |
-
wp.api.collections.Comments = BaseCollection.extend(
|
| 865 |
-
/** @lends Comments.prototype */
|
| 866 |
-
{
|
| 867 |
-
model: wp.api.models.Comment,
|
| 868 |
|
| 869 |
/**
|
| 870 |
-
*
|
|
|
|
|
|
|
|
|
|
| 871 |
*
|
| 872 |
-
* @returns {string}.
|
| 873 |
*/
|
| 874 |
-
|
| 875 |
-
|
| 876 |
-
|
| 877 |
-
|
| 878 |
-
|
| 879 |
-
|
| 880 |
-
|
| 881 |
-
|
| 882 |
-
|
| 883 |
-
|
| 884 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 885 |
|
| 886 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 887 |
|
| 888 |
-
|
| 889 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 890 |
|
| 891 |
-
|
| 892 |
-
|
| 893 |
-
|
|
|
|
| 894 |
}
|
| 895 |
}
|
| 896 |
-
|
| 897 |
-
return this.constructor.__super__.parse.call( this, responseArray );
|
| 898 |
-
}
|
| 899 |
-
}
|
| 900 |
-
);
|
| 901 |
-
|
| 902 |
-
/**
|
| 903 |
-
* Backbone terms collection.
|
| 904 |
-
*
|
| 905 |
-
* Usage: new wp.api.collections.Terms( {}, { taxonomy: 'taxonomy-slug' } )
|
| 906 |
-
*/
|
| 907 |
-
wp.api.collections.Terms = BaseCollection.extend(
|
| 908 |
-
/** @lends Terms.prototype */
|
| 909 |
-
{
|
| 910 |
-
model: wp.api.models.Term,
|
| 911 |
-
|
| 912 |
-
taxonomy: 'category',
|
| 913 |
|
| 914 |
/**
|
| 915 |
-
*
|
| 916 |
-
*
|
| 917 |
-
*
|
| 918 |
*/
|
| 919 |
-
|
| 920 |
-
|
| 921 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 922 |
}
|
| 923 |
|
| 924 |
-
|
| 925 |
-
|
|
|
|
|
|
|
| 926 |
|
| 927 |
/**
|
| 928 |
-
*
|
| 929 |
*
|
| 930 |
-
*
|
| 931 |
*/
|
| 932 |
-
|
| 933 |
-
return WP_API_Settings.root + 'wp/v2/terms/' + this.taxonomy;
|
| 934 |
-
}
|
| 935 |
-
}
|
| 936 |
-
);
|
| 937 |
|
| 938 |
-
|
| 939 |
-
|
| 940 |
-
|
| 941 |
-
|
| 942 |
-
*/
|
| 943 |
-
wp.api.collections.Revisions = BaseCollection.extend(
|
| 944 |
-
/** @lends Revisions.prototype */
|
| 945 |
-
{
|
| 946 |
-
model: wp.api.models.Revision,
|
| 947 |
|
| 948 |
-
|
|
|
|
| 949 |
|
| 950 |
-
|
| 951 |
-
|
| 952 |
-
|
| 953 |
-
|
| 954 |
-
*/
|
| 955 |
-
initialize: function( models, options ) {
|
| 956 |
-
BaseCollection.prototype.initialize.apply( this, arguments );
|
| 957 |
|
| 958 |
-
|
| 959 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 960 |
}
|
| 961 |
-
},
|
| 962 |
|
| 963 |
-
|
| 964 |
-
|
| 965 |
-
|
| 966 |
-
|
| 967 |
-
|
| 968 |
-
|
| 969 |
-
|
| 970 |
-
}
|
|
|
|
| 971 |
}
|
| 972 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 973 |
|
| 974 |
/**
|
| 975 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 976 |
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 977 |
|
| 978 |
/**
|
| 979 |
-
*
|
| 980 |
*/
|
| 981 |
|
| 982 |
-
|
|
|
|
|
|
|
|
|
| 8 |
this.views = {};
|
| 9 |
}
|
| 10 |
|
| 11 |
+
window.wp = window.wp || {};
|
| 12 |
+
wp.api = wp.api || new WP_API();
|
| 13 |
+
wp.api.versionString = wp.api.versionString || 'wp/v2/';
|
| 14 |
|
| 15 |
})( window );
|
| 16 |
|
| 18 |
|
| 19 |
'use strict';
|
| 20 |
|
| 21 |
+
var pad, r;
|
| 22 |
+
|
| 23 |
window.wp = window.wp || {};
|
| 24 |
wp.api = wp.api || {};
|
| 25 |
wp.api.utils = wp.api.utils || {};
|
| 26 |
|
| 27 |
/**
|
| 28 |
+
* ECMAScript 5 shim, adapted from MDN.
|
| 29 |
* @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString
|
| 30 |
*/
|
| 31 |
if ( ! Date.prototype.toISOString ) {
|
| 32 |
+
pad = function( number ) {
|
| 33 |
+
r = String( number );
|
| 34 |
+
if ( 1 === r.length ) {
|
| 35 |
r = '0' + r;
|
| 36 |
}
|
| 37 |
|
| 65 |
// implementations could be faster.
|
| 66 |
// 1 YYYY 2 MM 3 DD 4 HH 5 mm 6 ss 7 msec 8 Z 9 ± 10 tzHH 11 tzmm
|
| 67 |
if ( ( struct = /^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/.exec( date ) ) ) {
|
| 68 |
+
|
| 69 |
// Avoid NaN timestamps caused by “undefined” values being passed to Date.UTC.
|
| 70 |
for ( i = 0; ( k = numericKeys[i] ); ++i ) {
|
| 71 |
struct[k] = +struct[k] || 0;
|
| 75 |
struct[2] = ( +struct[2] || 1 ) - 1;
|
| 76 |
struct[3] = +struct[3] || 1;
|
| 77 |
|
| 78 |
+
if ( 'Z' !== struct[8] && undefined !== struct[9] ) {
|
| 79 |
minutesOffset = struct[10] * 60 + struct[11];
|
| 80 |
|
| 81 |
+
if ( '+' === struct[9] ) {
|
| 82 |
minutesOffset = 0 - minutesOffset;
|
| 83 |
}
|
| 84 |
}
|
| 91 |
return timestamp;
|
| 92 |
};
|
| 93 |
|
| 94 |
+
/**
|
| 95 |
+
* Helper function for getting the root URL.
|
| 96 |
+
* @return {[type]} [description]
|
| 97 |
+
*/
|
| 98 |
+
wp.api.utils.getRootUrl = function() {
|
| 99 |
+
return window.location.origin ?
|
| 100 |
+
window.location.origin + '/' :
|
| 101 |
+
window.location.protocol + '/' + window.location.host + '/';
|
| 102 |
+
};
|
| 103 |
|
| 104 |
+
/**
|
| 105 |
+
* Helper for capitalizing strings.
|
| 106 |
+
*/
|
| 107 |
+
wp.api.utils.capitalize = function( str ) {
|
| 108 |
+
if ( _.isUndefined( str ) ) {
|
| 109 |
+
return str;
|
| 110 |
+
}
|
| 111 |
+
return str.charAt( 0 ).toUpperCase() + str.slice( 1 );
|
| 112 |
+
};
|
| 113 |
|
| 114 |
+
/**
|
| 115 |
+
* Extract a route part based on negitive index.
|
| 116 |
+
*
|
| 117 |
+
* @param {string} route The endpoint route.
|
| 118 |
+
* @param {int} part The number of parts from the end of the route to retrieve. Default 1.
|
| 119 |
+
* Example route `/a/b/c`: part 1 is `c`, part 2 is `b`, part 3 is `a`.
|
| 120 |
+
*/
|
| 121 |
+
wp.api.utils.extractRoutePart = function( route, part ) {
|
| 122 |
+
var routeParts;
|
| 123 |
+
|
| 124 |
+
part = part || 1;
|
| 125 |
+
|
| 126 |
+
// Remove versions string from route to avoid returning it.
|
| 127 |
+
route = route.replace( wp.api.versionString, '' );
|
| 128 |
+
routeParts = route.split( '/' ).reverse();
|
| 129 |
+
if ( _.isUndefined( routeParts[ --part ] ) ) {
|
| 130 |
+
return '';
|
| 131 |
+
}
|
| 132 |
+
return routeParts[ part ];
|
| 133 |
+
};
|
| 134 |
|
| 135 |
/**
|
| 136 |
+
* Extract a parent name from a passed route.
|
| 137 |
*
|
| 138 |
+
* @param {string} route The route to extract a name from.
|
| 139 |
*/
|
| 140 |
+
wp.api.utils.extractParentName = function( route ) {
|
| 141 |
+
var name,
|
| 142 |
+
lastSlash = route.lastIndexOf( '_id>[\\d]+)/' );
|
| 143 |
+
|
| 144 |
+
if ( lastSlash < 0 ) {
|
| 145 |
+
return '';
|
| 146 |
+
}
|
| 147 |
+
name = route.substr( 0, lastSlash - 1 );
|
| 148 |
+
name = name.split( '/' );
|
| 149 |
+
name.pop();
|
| 150 |
+
name = name.pop();
|
| 151 |
+
return name;
|
| 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 |
|
| 201 |
+
}
|
|
|
|
|
|
|
| 202 |
}
|
| 203 |
|
| 204 |
+
} );
|
| 205 |
+
|
| 206 |
};
|
| 207 |
|
| 208 |
/**
|
| 209 |
+
* Add mixins and helpers to models depending on their defaults.
|
| 210 |
*
|
| 211 |
+
* @param {Backbone Model} model The model to attach helpers and mixins to.
|
| 212 |
+
* @param {string} modelClassName The classname of the constructed model.
|
| 213 |
+
* @param {Object} loadingObjects An object containing the models and collections we are building.
|
| 214 |
*/
|
| 215 |
+
wp.api.utils.addMixinsAndHelpers = function( model, modelClassName, loadingObjects ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 216 |
|
| 217 |
+
var hasDate = false,
|
| 218 |
|
| 219 |
+
/**
|
| 220 |
+
* Array of parseable dates.
|
| 221 |
+
*
|
| 222 |
+
* @type {string[]}.
|
| 223 |
+
*/
|
| 224 |
+
parseableDates = [ 'date', 'modified', 'date_gmt', 'modified_gmt' ],
|
| 225 |
|
| 226 |
+
/**
|
| 227 |
+
* Mixin for all content that is time stamped.
|
| 228 |
+
*
|
| 229 |
+
* This mixin converts between mysql timestamps and JavaScript Dates when syncing a model
|
| 230 |
+
* to or from the server. For example, a date stored as `2015-12-27T21:22:24` on the server
|
| 231 |
+
* gets expanded to `Sun Dec 27 2015 14:22:24 GMT-0700 (MST)` when the model is fetched.
|
| 232 |
+
*
|
| 233 |
+
* @type {{toJSON: toJSON, parse: parse}}.
|
| 234 |
+
*/
|
| 235 |
+
TimeStampedMixin = {
|
| 236 |
/**
|
| 237 |
+
* Serialize the entity pre-sync.
|
| 238 |
+
*
|
| 239 |
+
* @returns {*}.
|
| 240 |
*/
|
| 241 |
+
toJSON: function() {
|
| 242 |
+
var attributes = _.clone( this.attributes );
|
| 243 |
|
| 244 |
+
// Serialize Date objects back into 8601 strings.
|
| 245 |
+
_.each( parseableDates, function( key ) {
|
| 246 |
+
if ( key in attributes ) {
|
|
|
|
| 247 |
|
| 248 |
+
// Don't convert null values
|
| 249 |
+
if ( ! _.isNull( attributes[ key ] ) ) {
|
| 250 |
+
attributes[ key ] = attributes[ key ].toISOString();
|
| 251 |
+
}
|
| 252 |
+
}
|
| 253 |
+
} );
|
| 254 |
|
| 255 |
+
return attributes;
|
| 256 |
+
},
|
| 257 |
|
| 258 |
+
/**
|
| 259 |
+
* Unserialize the fetched response.
|
| 260 |
+
*
|
| 261 |
+
* @param {*} response.
|
| 262 |
+
* @returns {*}.
|
| 263 |
+
*/
|
| 264 |
+
parse: function( response ) {
|
| 265 |
+
var timestamp;
|
| 266 |
+
|
| 267 |
+
// Parse dates into native Date objects.
|
| 268 |
+
_.each( parseableDates, function( key ) {
|
| 269 |
+
if ( ! ( key in response ) ) {
|
| 270 |
+
return;
|
| 271 |
+
}
|
| 272 |
+
|
| 273 |
+
// Don't convert null values
|
| 274 |
+
if ( ! _.isNull( response[ key ] ) ) {
|
| 275 |
+
timestamp = wp.api.utils.parseISO8601( response[ key ] );
|
| 276 |
+
response[ key ] = new Date( timestamp );
|
| 277 |
+
}
|
| 278 |
+
});
|
| 279 |
+
|
| 280 |
+
return response;
|
| 281 |
+
}
|
| 282 |
+
},
|
| 283 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 284 |
/**
|
| 285 |
+
* Build a helper function to retrieve related model.
|
| 286 |
*
|
| 287 |
+
* @param {string} parentModel The parent model.
|
| 288 |
+
* @param {int} modelId The model ID if the object to request
|
| 289 |
+
* @param {string} modelName The model name to use when constructing the model.
|
| 290 |
+
* @param {string} embedSourcePoint Where to check the embedds object for _embed data.
|
| 291 |
+
* @param {string} embedCheckField Which model field to check to see if the model has data.
|
| 292 |
+
*
|
| 293 |
+
* @return {Deferred.promise} A promise which resolves to the constructed model.
|
| 294 |
*/
|
| 295 |
+
buildModelGetter = function( parentModel, modelId, modelName, embedSourcePoint, embedCheckField ) {
|
| 296 |
+
var getModel, embeddeds, attributes, deferred;
|
| 297 |
|
| 298 |
+
deferred = jQuery.Deferred();
|
| 299 |
+
embeddeds = parentModel.get( '_embedded' ) || {};
|
| 300 |
|
| 301 |
+
// Verify that we have a valied author id.
|
| 302 |
+
if ( ! _.isNumber( modelId ) ) {
|
| 303 |
+
deferred.reject();
|
| 304 |
+
return deferred;
|
|
|
|
|
|
|
|
|
|
| 305 |
}
|
| 306 |
|
| 307 |
+
// If we have embedded object data, use that when constructing the getModel.
|
| 308 |
+
if ( embeddeds[ embedSourcePoint ] ) {
|
| 309 |
+
attributes = _.findWhere( embeddeds[ embedSourcePoint ], { id: modelId } );
|
| 310 |
+
}
|
| 311 |
|
| 312 |
+
// Otherwise use the modelId.
|
| 313 |
+
if ( ! attributes ) {
|
| 314 |
+
attributes = { id: modelId };
|
| 315 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 316 |
|
| 317 |
+
// Create the new getModel model.
|
| 318 |
+
getModel = new wp.api.models[ modelName ]( attributes );
|
| 319 |
|
| 320 |
+
// If we didn’t have an embedded getModel, fetch the getModel data.
|
| 321 |
+
if ( ! getModel.get( embedCheckField ) ) {
|
| 322 |
+
getModel.fetch( { success: function( getModel ) {
|
| 323 |
+
deferred.resolve( getModel );
|
| 324 |
+
} } );
|
| 325 |
+
} else {
|
| 326 |
+
deferred.resolve( getModel );
|
| 327 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 328 |
|
| 329 |
+
// Return a promise.
|
| 330 |
+
return deferred.promise();
|
| 331 |
+
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 332 |
|
| 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 |
+
/**
|
| 345 |
+
* Returns a promise that resolves to the requested collection
|
| 346 |
+
*
|
| 347 |
+
* Uses the embedded data if available, otherwises fetches the
|
| 348 |
+
* data from the server.
|
| 349 |
+
*
|
| 350 |
+
* @return {Deferred.promise} promise Resolves to a wp.api.collections[ collectionName ]
|
| 351 |
+
* collection.
|
| 352 |
+
*/
|
| 353 |
+
var postId, embeddeds, getObjects,
|
| 354 |
+
classProperties = '',
|
| 355 |
+
properties = '',
|
| 356 |
+
deferred = jQuery.Deferred();
|
| 357 |
+
|
| 358 |
+
postId = parentModel.get( 'id' );
|
| 359 |
+
embeddeds = parentModel.get( '_embedded' ) || {};
|
| 360 |
+
|
| 361 |
+
// Verify that we have a valied post id.
|
| 362 |
+
if ( ! _.isNumber( postId ) || 0 === postId ) {
|
| 363 |
+
deferred.reject();
|
| 364 |
+
return deferred;
|
| 365 |
+
}
|
| 366 |
|
| 367 |
+
// If we have embedded getObjects data, use that when constructing the getObjects.
|
| 368 |
+
if ( ! _.isUndefined( embedSourcePoint ) && ! _.isUndefined( embeddeds[ embedSourcePoint ] ) ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 369 |
|
| 370 |
+
// Some embeds also include an index offset, check for that.
|
| 371 |
+
if ( _.isUndefined( embedIndex ) ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 372 |
|
| 373 |
+
// Use the embed source point directly.
|
| 374 |
+
properties = embeddeds[ embedSourcePoint ];
|
| 375 |
+
} else {
|
| 376 |
|
| 377 |
+
// Add the index to the embed source point.
|
| 378 |
+
properties = embeddeds[ embedSourcePoint ][ embedIndex ];
|
| 379 |
+
}
|
| 380 |
+
} else {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 381 |
|
| 382 |
+
// Otherwise use the postId.
|
| 383 |
+
classProperties = { parent: postId };
|
| 384 |
+
}
|
| 385 |
|
| 386 |
+
// Create the new getObjects collection.
|
| 387 |
+
getObjects = new wp.api.collections[ collectionName ]( properties, classProperties );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 388 |
|
| 389 |
+
// If we didn’t have embedded getObjects, fetch the getObjects data.
|
| 390 |
+
if ( _.isUndefined( getObjects.models[0] ) ) {
|
| 391 |
+
getObjects.fetch( { success: function( getObjects ) {
|
| 392 |
|
| 393 |
+
// Add a helper 'parent_post' attribute onto the model.
|
| 394 |
+
setHelperParentPost( getObjects, postId );
|
| 395 |
+
deferred.resolve( getObjects );
|
| 396 |
+
} } );
|
| 397 |
+
} else {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 398 |
|
| 399 |
+
// Add a helper 'parent_post' attribute onto the model.
|
| 400 |
+
setHelperParentPost( getObjects, postId );
|
| 401 |
+
deferred.resolve( getObjects );
|
| 402 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 403 |
|
| 404 |
+
// Return a promise.
|
| 405 |
+
return deferred.promise();
|
| 406 |
|
| 407 |
+
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 408 |
|
| 409 |
+
/**
|
| 410 |
+
* Set the model post parent.
|
| 411 |
+
*/
|
| 412 |
+
setHelperParentPost = function( collection, postId ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 413 |
|
| 414 |
+
// Attach post_parent id to the collection.
|
| 415 |
+
_.each( collection.models, function( model ) {
|
| 416 |
+
model.set( 'parent_post', postId );
|
| 417 |
+
} );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 418 |
},
|
| 419 |
|
| 420 |
/**
|
| 421 |
+
* Add a helper funtion to handle post Meta.
|
|
|
|
|
|
|
| 422 |
*/
|
| 423 |
+
MetaMixin = {
|
| 424 |
+
getMeta: function() {
|
| 425 |
+
return buildCollectionGetter( this, 'PostMeta', 'https://api.w.org/meta' );
|
| 426 |
+
}
|
| 427 |
+
},
|
| 428 |
|
| 429 |
+
/**
|
| 430 |
+
* Add a helper funtion to handle post Revisions.
|
| 431 |
+
*/
|
| 432 |
+
RevisionsMixin = {
|
| 433 |
+
getRevisions: function() {
|
| 434 |
+
return buildCollectionGetter( this, 'PostRevisions' );
|
| 435 |
+
}
|
| 436 |
+
},
|
| 437 |
|
| 438 |
+
/**
|
| 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 |
+
*
|
| 471 |
+
*/
|
| 472 |
+
setCategories: function( categories ) {
|
| 473 |
+
var allCategories, newCategory,
|
| 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' ) );
|
| 491 |
+
|
| 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 |
+
} );
|
| 499 |
|
| 500 |
+
} else {
|
| 501 |
+
this.setCategoriesWithCollection( categories );
|
| 502 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 503 |
|
| 504 |
+
},
|
|
|
|
| 505 |
|
| 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 |
|
| 543 |
/**
|
| 544 |
+
* Add a helper function to retrieve the author user model.
|
|
|
|
|
|
|
| 545 |
*/
|
| 546 |
+
AuthorMixin = {
|
| 547 |
+
getAuthorUser: function() {
|
| 548 |
+
return buildModelGetter( this, this.get( 'author' ), 'User', 'author', 'name' );
|
| 549 |
+
}
|
| 550 |
},
|
| 551 |
|
| 552 |
/**
|
| 553 |
+
* Add a helper function to retrieve the featured image.
|
|
|
|
|
|
|
| 554 |
*/
|
| 555 |
+
FeaturedImageMixin = {
|
| 556 |
+
getFeaturedImage: function() {
|
| 557 |
+
return buildModelGetter( this, this.get( 'featured_image' ), 'Media', 'https://api.w.org/featuredmedia', 'source_url' );
|
| 558 |
+
}
|
| 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 |
+
} );
|
| 572 |
+
|
| 573 |
+
// Add the TimeStampedMixin for models that contain a date field.
|
| 574 |
+
if ( hasDate ) {
|
| 575 |
+
model = model.extend( TimeStampedMixin );
|
| 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 |
+
|
| 593 |
+
// Add the MetaMixin for models that support meta collections.
|
| 594 |
+
if ( ! _.isUndefined( loadingObjects.collections[ modelClassName + 'Meta' ] ) ) {
|
| 595 |
+
model = model.extend( MetaMixin );
|
| 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 |
+
|
| 603 |
+
// Add the RevisionsMixin for models that support revisions collections.
|
| 604 |
+
if ( ! _.isUndefined( loadingObjects.collections[ modelClassName + 'Revisions' ] ) ) {
|
| 605 |
+
model = model.extend( RevisionsMixin );
|
| 606 |
+
}
|
| 607 |
+
|
| 608 |
+
return model;
|
| 609 |
+
};
|
| 610 |
+
|
| 611 |
+
})( window );
|
| 612 |
+
|
| 613 |
+
/* global wpApiSettings:false */
|
| 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 |
*/
|
| 624 |
+
wp.api.WPApiBaseModel = Backbone.Model.extend(
|
| 625 |
+
/** @lends WPApiBaseModel.prototype */
|
| 626 |
{
|
| 627 |
+
/**
|
| 628 |
+
* Set nonce header before every Backbone sync.
|
| 629 |
+
*
|
| 630 |
+
* @param {string} method.
|
| 631 |
+
* @param {Backbone.Model} model.
|
| 632 |
+
* @param {{beforeSend}, *} options.
|
| 633 |
+
* @returns {*}.
|
| 634 |
+
*/
|
| 635 |
+
sync: function( method, model, options ) {
|
| 636 |
+
var beforeSend;
|
| 637 |
|
| 638 |
+
options = options || {};
|
| 639 |
|
| 640 |
+
if ( ! _.isUndefined( wpApiSettings.nonce ) && ! _.isNull( wpApiSettings.nonce ) ) {
|
| 641 |
+
beforeSend = options.beforeSend;
|
| 642 |
+
|
| 643 |
+
// @todo enable option for jsonp endpoints
|
| 644 |
+
// options.dataType = 'jsonp';
|
| 645 |
+
|
| 646 |
+
options.beforeSend = function( xhr ) {
|
| 647 |
+
xhr.setRequestHeader( 'X-WP-Nonce', wpApiSettings.nonce );
|
| 648 |
+
|
| 649 |
+
if ( beforeSend ) {
|
| 650 |
+
return beforeSend.apply( this, arguments );
|
| 651 |
+
}
|
| 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 |
+
}
|
| 659 |
+
return Backbone.sync( method, model, options );
|
| 660 |
},
|
| 661 |
|
| 662 |
/**
|
| 663 |
+
* Save is only allowed when the PUT OR POST methods are available for the endpoint.
|
|
|
|
|
|
|
| 664 |
*/
|
| 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 );
|
| 672 |
+
} else {
|
| 673 |
+
|
| 674 |
+
// Otherwise bail, disallowing action.
|
| 675 |
+
return false;
|
| 676 |
+
}
|
| 677 |
},
|
| 678 |
|
| 679 |
/**
|
| 680 |
+
* Delete is only allowed when the DELETE method is available for the endpoint.
|
|
|
|
|
|
|
| 681 |
*/
|
| 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 );
|
| 689 |
+
} else {
|
| 690 |
+
|
| 691 |
+
// Otherwise bail, disallowing action.
|
| 692 |
+
return false;
|
| 693 |
+
}
|
| 694 |
}
|
| 695 |
+
|
| 696 |
}
|
| 697 |
);
|
| 698 |
|
| 699 |
/**
|
| 700 |
* API Schema model. Contains meta information about the API.
|
| 701 |
*/
|
| 702 |
+
wp.api.models.Schema = wp.api.WPApiBaseModel.extend(
|
| 703 |
+
/** @lends Schema.prototype */
|
| 704 |
{
|
|
|
|
|
|
|
| 705 |
defaults: {
|
| 706 |
+
_links: {},
|
| 707 |
+
namespace: null,
|
| 708 |
routes: {}
|
| 709 |
},
|
| 710 |
|
| 711 |
+
initialize: function( attributes, options ) {
|
| 712 |
+
var model = this;
|
| 713 |
+
options = options || {};
|
| 714 |
+
|
| 715 |
+
wp.api.WPApiBaseModel.prototype.initialize.call( model, attributes, options );
|
| 716 |
+
|
| 717 |
+
model.apiRoot = options.apiRoot || wpApiSettings.root;
|
| 718 |
+
model.versionString = options.versionString || wpApiSettings.versionString;
|
| 719 |
},
|
| 720 |
|
| 721 |
+
url: function() {
|
| 722 |
+
return this.apiRoot + this.versionString;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
*/
|
| 736 |
+
wp.api.WPApiBaseCollection = Backbone.Collection.extend(
|
| 737 |
/** @lends BaseCollection.prototype */
|
| 738 |
{
|
| 739 |
|
| 740 |
/**
|
| 741 |
* Setup default state.
|
| 742 |
*/
|
| 743 |
+
initialize: function( models, options ) {
|
| 744 |
this.state = {
|
| 745 |
data: {},
|
| 746 |
currentPage: null,
|
| 747 |
totalPages: null,
|
| 748 |
totalObjects: null
|
| 749 |
};
|
| 750 |
+
if ( _.isUndefined( options ) ) {
|
| 751 |
+
this.parent = '';
|
| 752 |
+
} else {
|
| 753 |
+
this.parent = options.parent;
|
| 754 |
+
}
|
| 755 |
},
|
| 756 |
|
| 757 |
/**
|
| 765 |
* @returns {*}.
|
| 766 |
*/
|
| 767 |
sync: function( method, model, options ) {
|
| 768 |
+
var beforeSend, success,
|
|
|
|
| 769 |
self = this;
|
| 770 |
|
| 771 |
+
options = options || {};
|
| 772 |
+
beforeSend = options.beforeSend;
|
| 773 |
+
|
| 774 |
+
if ( 'undefined' !== typeof wpApiSettings.nonce ) {
|
| 775 |
options.beforeSend = function( xhr ) {
|
| 776 |
+
xhr.setRequestHeader( 'X-WP-Nonce', wpApiSettings.nonce );
|
| 777 |
|
| 778 |
if ( beforeSend ) {
|
| 779 |
return beforeSend.apply( self, arguments );
|
| 798 |
self.state.currentPage = options.data.page - 1;
|
| 799 |
}
|
| 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;
|
| 808 |
} else {
|
| 809 |
self.state.currentPage++;
|
| 835 |
return false;
|
| 836 |
}
|
| 837 |
|
| 838 |
+
if ( null === this.state.currentPage || this.state.currentPage <= 1 ) {
|
| 839 |
options.data.page = 2;
|
| 840 |
} else {
|
| 841 |
options.data.page = this.state.currentPage + 1;
|
| 851 |
* @returns null|boolean.
|
| 852 |
*/
|
| 853 |
hasMore: function() {
|
| 854 |
+
if ( null === this.state.totalPages ||
|
| 855 |
+
null === this.state.totalObjects ||
|
| 856 |
+
null === this.state.currentPage ) {
|
| 857 |
return null;
|
| 858 |
} else {
|
| 859 |
return ( this.state.currentPage < this.state.totalPages );
|
| 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: {
|
| 879 |
+
apiRoot: wpApiSettings.root,
|
| 880 |
+
versionString: wp.api.versionString,
|
| 881 |
+
schema: null,
|
| 882 |
+
models: {},
|
| 883 |
+
collections: {}
|
| 884 |
+
},
|
| 885 |
|
| 886 |
+
initialize: function() {
|
| 887 |
+
var model = this, deferred;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 888 |
|
| 889 |
+
Backbone.Model.prototype.initialize.apply( model, arguments );
|
| 890 |
|
| 891 |
+
deferred = jQuery.Deferred();
|
| 892 |
+
model.schemaConstructed = deferred.promise();
|
| 893 |
|
| 894 |
+
model.schemaModel = new wp.api.models.Schema( null, {
|
| 895 |
+
apiRoot: model.get( 'apiRoot' ),
|
| 896 |
+
versionString: model.get( 'versionString' )
|
| 897 |
+
});
|
|
|
|
| 898 |
|
| 899 |
+
model.schemaModel.once( 'change', function() {
|
| 900 |
+
model.constructFromSchema();
|
| 901 |
+
deferred.resolve( model );
|
| 902 |
+
} );
|
| 903 |
|
| 904 |
+
if ( model.get( 'schema' ) ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 905 |
|
| 906 |
+
// Use schema supplied as model attribute.
|
| 907 |
+
model.schemaModel.set( model.schemaModel.parse( model.get( 'schema' ) ) );
|
| 908 |
+
} else if ( ! _.isUndefined( sessionStorage ) && sessionStorage.getItem( 'wp-api-schema-model' + model.get( 'apiRoot' ) + model.get( 'versionString' ) ) ) {
|
| 909 |
|
| 910 |
+
// Used a cached copy of the schema model if available.
|
| 911 |
+
model.schemaModel.set( model.schemaModel.parse( JSON.parse( sessionStorage.getItem( 'wp-api-schema-model' + model.get( 'apiRoot' ) + model.get( 'versionString' ) ) ) ) );
|
| 912 |
+
} else {
|
| 913 |
+
model.schemaModel.fetch({
|
| 914 |
+
/**
|
| 915 |
+
* When the server return the schema model data, store the data in a sessionCache so we don't
|
| 916 |
+
* have to retrieve it again for this session. Then, construct the models and collections based
|
| 917 |
+
* on the schema model data.
|
| 918 |
+
*/
|
| 919 |
+
success: function( newSchemaModel ) {
|
| 920 |
+
|
| 921 |
+
// Store a copy of the schema model in the session cache if available.
|
| 922 |
+
if ( ! _.isUndefined( sessionStorage ) ) {
|
| 923 |
+
sessionStorage.setItem( 'wp-api-schema-model' + model.get( 'apiRoot' ) + model.get( 'versionString' ), JSON.stringify( newSchemaModel ) );
|
| 924 |
+
}
|
| 925 |
+
},
|
| 926 |
|
| 927 |
+
// @todo Handle the error condition.
|
| 928 |
+
error: function() {
|
| 929 |
+
}
|
| 930 |
+
});
|
| 931 |
+
}
|
| 932 |
+
},
|
| 933 |
|
| 934 |
+
constructFromSchema: function() {
|
| 935 |
+
var routeModel = this, modelRoutes, collectionRoutes, schemaRoot, loadingObjects,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 936 |
|
| 937 |
/**
|
| 938 |
+
* Set up the model and collection name mapping options. As the schema is built, the
|
| 939 |
+
* model and collection names will be adjusted if they are found in the mapping object.
|
| 940 |
+
*
|
| 941 |
+
* Localizing a variable wpApiSettings.mapping will over-ride the default mapping options.
|
| 942 |
*
|
|
|
|
| 943 |
*/
|
| 944 |
+
mapping = wpApiSettings.mapping || {
|
| 945 |
+
models: {
|
| 946 |
+
'Categories': 'Category',
|
| 947 |
+
'Comments': 'Comment',
|
| 948 |
+
'Pages': 'Page',
|
| 949 |
+
'PagesMeta': 'PageMeta',
|
| 950 |
+
'PagesRevisions': 'PageRevision',
|
| 951 |
+
'Posts': 'Post',
|
| 952 |
+
'PostsCategories': 'PostCategory',
|
| 953 |
+
'PostsRevisions': 'PostRevision',
|
| 954 |
+
'PostsTags': 'PostTag',
|
| 955 |
+
'Schema': 'Schema',
|
| 956 |
+
'Statuses': 'Status',
|
| 957 |
+
'Tags': 'Tag',
|
| 958 |
+
'Taxonomies': 'Taxonomy',
|
| 959 |
+
'Types': 'Type',
|
| 960 |
+
'Users': 'User'
|
| 961 |
+
},
|
| 962 |
+
collections: {
|
| 963 |
+
'PagesMeta': 'PageMeta',
|
| 964 |
+
'PagesRevisions': 'PageRevisions',
|
| 965 |
+
'PostsCategories': 'PostCategories',
|
| 966 |
+
'PostsMeta': 'PostMeta',
|
| 967 |
+
'PostsRevisions': 'PostRevisions',
|
| 968 |
+
'PostsTags': 'PostTags'
|
| 969 |
+
}
|
| 970 |
+
};
|
| 971 |
|
| 972 |
+
/**
|
| 973 |
+
* Iterate thru the routes, picking up models and collections to build. Builds two arrays,
|
| 974 |
+
* one for models and one for collections.
|
| 975 |
+
*/
|
| 976 |
+
modelRoutes = [];
|
| 977 |
+
collectionRoutes = [];
|
| 978 |
+
schemaRoot = routeModel.get( 'apiRoot' ).replace( wp.api.utils.getRootUrl(), '' );
|
| 979 |
+
loadingObjects = {};
|
| 980 |
|
| 981 |
+
/**
|
| 982 |
+
* Tracking objects for models and collections.
|
| 983 |
+
*/
|
| 984 |
+
loadingObjects.models = routeModel.get( 'models' );
|
| 985 |
+
loadingObjects.collections = routeModel.get( 'collections' );
|
| 986 |
+
|
| 987 |
+
_.each( routeModel.schemaModel.get( 'routes' ), function( route, index ) {
|
| 988 |
+
|
| 989 |
+
// Skip the schema root if included in the schema.
|
| 990 |
+
if ( index !== routeModel.get( ' versionString' ) &&
|
| 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 |
+
} );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1010 |
|
| 1011 |
/**
|
| 1012 |
+
* Construct the models.
|
| 1013 |
+
*
|
| 1014 |
+
* Base the class name on the route endpoint.
|
| 1015 |
*/
|
| 1016 |
+
_.each( modelRoutes, function( modelRoute ) {
|
| 1017 |
+
|
| 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 ) {
|
| 1025 |
+
modelClassName = wp.api.utils.capitalize( parentName ) + wp.api.utils.capitalize( routeName );
|
| 1026 |
+
modelClassName = mapping.models[ modelClassName ] || modelClassName;
|
| 1027 |
+
loadingObjects.models[ modelClassName ] = wp.api.WPApiBaseModel.extend( {
|
| 1028 |
+
|
| 1029 |
+
// Function that returns a constructed url based on the parent and id.
|
| 1030 |
+
url: function() {
|
| 1031 |
+
var url = routeModel.get( 'apiRoot' ) + routeModel.get( 'versionString' ) +
|
| 1032 |
+
parentName + '/' +
|
| 1033 |
+
( ( _.isUndefined( this.get( 'parent' ) ) || 0 === this.get( 'parent' ) ) ?
|
| 1034 |
+
this.get( 'parent_post' ) :
|
| 1035 |
+
this.get( 'parent' ) ) + '/' +
|
| 1036 |
+
routeName;
|
| 1037 |
+
if ( ! _.isUndefined( this.get( 'id' ) ) ) {
|
| 1038 |
+
url += '/' + this.get( 'id' );
|
| 1039 |
+
}
|
| 1040 |
+
return url;
|
| 1041 |
+
},
|
| 1042 |
+
|
| 1043 |
+
// Include a reference to the original route object.
|
| 1044 |
+
route: modelRoute,
|
| 1045 |
+
|
| 1046 |
+
// Include a reference to the original class name.
|
| 1047 |
+
name: modelClassName,
|
| 1048 |
+
|
| 1049 |
+
// Include the array of route methods for easy reference.
|
| 1050 |
+
methods: modelRoute.route.methods,
|
| 1051 |
+
|
| 1052 |
+
initialize: function() {
|
| 1053 |
+
/**
|
| 1054 |
+
* Posts and pages support trashing, other types don't support a trash
|
| 1055 |
+
* and require that you pass ?force=true to actually delete them.
|
| 1056 |
+
*
|
| 1057 |
+
* @todo we should be getting trashability from the Schema, not hard coding types here.
|
| 1058 |
+
*/
|
| 1059 |
+
if (
|
| 1060 |
+
'Posts' !== this.name &&
|
| 1061 |
+
'Pages' !== this.name &&
|
| 1062 |
+
_.contains( this.methods, 'DELETE' )
|
| 1063 |
+
) {
|
| 1064 |
+
this.requireForceForDelete = true;
|
| 1065 |
+
}
|
| 1066 |
+
}
|
| 1067 |
+
} );
|
| 1068 |
+
} else {
|
| 1069 |
+
|
| 1070 |
+
// This is a model without a parent in its route
|
| 1071 |
+
modelClassName = wp.api.utils.capitalize( routeName );
|
| 1072 |
+
modelClassName = mapping.models[ modelClassName ] || modelClassName;
|
| 1073 |
+
loadingObjects.models[ modelClassName ] = wp.api.WPApiBaseModel.extend( {
|
| 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 |
+
}
|
| 1081 |
+
return url;
|
| 1082 |
+
},
|
| 1083 |
+
|
| 1084 |
+
// Include a reference to the original route object.
|
| 1085 |
+
route: modelRoute,
|
| 1086 |
+
|
| 1087 |
+
// Include a reference to the original class name.
|
| 1088 |
+
name: modelClassName,
|
| 1089 |
+
|
| 1090 |
+
// Include the array of route methods for easy reference.
|
| 1091 |
+
methods: modelRoute.route.methods
|
| 1092 |
+
} );
|
| 1093 |
}
|
| 1094 |
|
| 1095 |
+
// Add defaults to the new model, pulled form the endpoint
|
| 1096 |
+
wp.api.utils.decorateFromRoute( modelRoute.route.endpoints, loadingObjects.models[ modelClassName ] );
|
| 1097 |
+
|
| 1098 |
+
} );
|
| 1099 |
|
| 1100 |
/**
|
| 1101 |
+
* Construct the collections.
|
| 1102 |
*
|
| 1103 |
+
* Base the class name on the route endpoint.
|
| 1104 |
*/
|
| 1105 |
+
_.each( collectionRoutes, function( collectionRoute ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1106 |
|
| 1107 |
+
// Extract the name and any parent from the route.
|
| 1108 |
+
var collectionClassName, modelClassName,
|
| 1109 |
+
routeName = collectionRoute.index.slice( collectionRoute.index.lastIndexOf( '/' ) + 1 ),
|
| 1110 |
+
parentName = wp.api.utils.extractRoutePart( collectionRoute.index, 3 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1111 |
|
| 1112 |
+
// If the collection has a parent in its route, add that to its class name/
|
| 1113 |
+
if ( '' !== parentName && parentName !== routeName ) {
|
| 1114 |
|
| 1115 |
+
collectionClassName = wp.api.utils.capitalize( parentName ) + wp.api.utils.capitalize( routeName );
|
| 1116 |
+
modelClassName = mapping.models[ collectionClassName ] || collectionClassName;
|
| 1117 |
+
collectionClassName = mapping.collections[ collectionClassName ] || collectionClassName;
|
| 1118 |
+
loadingObjects.collections[ collectionClassName ] = wp.api.WPApiBaseCollection.extend( {
|
|
|
|
|
|
|
|
|
|
| 1119 |
|
| 1120 |
+
// Function that returns a constructed url passed on the parent.
|
| 1121 |
+
url: function() {
|
| 1122 |
+
return routeModel.get( 'apiRoot' ) + routeModel.get( 'versionString' ) +
|
| 1123 |
+
parentName + '/' + this.parent + '/' +
|
| 1124 |
+
routeName;
|
| 1125 |
+
},
|
| 1126 |
+
|
| 1127 |
+
// Specify the model that this collection contains.
|
| 1128 |
+
model: loadingObjects.models[ modelClassName ],
|
| 1129 |
+
|
| 1130 |
+
// Include a reference to the original class name.
|
| 1131 |
+
name: collectionClassName,
|
| 1132 |
+
|
| 1133 |
+
// Include a reference to the original route object.
|
| 1134 |
+
route: collectionRoute,
|
| 1135 |
+
|
| 1136 |
+
// Include the array of route methods for easy reference.
|
| 1137 |
+
methods: collectionRoute.route.methods
|
| 1138 |
+
} );
|
| 1139 |
+
} else {
|
| 1140 |
+
|
| 1141 |
+
// This is a collection without a parent in its route.
|
| 1142 |
+
collectionClassName = wp.api.utils.capitalize( routeName );
|
| 1143 |
+
modelClassName = mapping.models[ collectionClassName ] || collectionClassName;
|
| 1144 |
+
collectionClassName = mapping.collections[ collectionClassName ] || collectionClassName;
|
| 1145 |
+
loadingObjects.collections[ collectionClassName ] = wp.api.WPApiBaseCollection.extend( {
|
| 1146 |
+
|
| 1147 |
+
// For the url of a root level collection, use a string.
|
| 1148 |
+
url: routeModel.get( 'apiRoot' ) + routeModel.get( 'versionString' ) + routeName,
|
| 1149 |
+
|
| 1150 |
+
// Specify the model that this collection contains.
|
| 1151 |
+
model: loadingObjects.models[ modelClassName ],
|
| 1152 |
+
|
| 1153 |
+
// Include a reference to the original class name.
|
| 1154 |
+
name: collectionClassName,
|
| 1155 |
+
|
| 1156 |
+
// Include a reference to the original route object.
|
| 1157 |
+
route: collectionRoute,
|
| 1158 |
+
|
| 1159 |
+
// Include the array of route methods for easy reference.
|
| 1160 |
+
methods: collectionRoute.route.methods
|
| 1161 |
+
} );
|
| 1162 |
}
|
|
|
|
| 1163 |
|
| 1164 |
+
// Add defaults to the new model, pulled form the endpoint
|
| 1165 |
+
wp.api.utils.decorateFromRoute( collectionRoute.route.endpoints, loadingObjects.collections[ collectionClassName ] );
|
| 1166 |
+
} );
|
| 1167 |
+
|
| 1168 |
+
// Add mixins and helpers for each of the models.
|
| 1169 |
+
_.each( loadingObjects.models, function( model, index ) {
|
| 1170 |
+
loadingObjects.models[ index ] = wp.api.utils.addMixinsAndHelpers( model, index, loadingObjects );
|
| 1171 |
+
} );
|
| 1172 |
+
|
| 1173 |
}
|
| 1174 |
+
|
| 1175 |
+
});
|
| 1176 |
+
|
| 1177 |
+
wp.api.endpoints = new Backbone.Collection({
|
| 1178 |
+
model: Endpoint
|
| 1179 |
+
});
|
| 1180 |
|
| 1181 |
/**
|
| 1182 |
+
* Initialize the wp-api, optionally passing the API root.
|
| 1183 |
+
*
|
| 1184 |
+
* @param {object} [args]
|
| 1185 |
+
* @param {string} [args.apiRoot] The api root. Optional, defaults to wpApiSettings.root.
|
| 1186 |
+
* @param {string} [args.versionString] The version string. Optional, defaults to wpApiSettings.root.
|
| 1187 |
+
* @param {object} [args.schema] The schema. Optional, will be fetched from API if not provided.
|
| 1188 |
*/
|
| 1189 |
+
wp.api.init = function( args ) {
|
| 1190 |
+
var endpoint, attributes = {}, deferred, promise;
|
| 1191 |
+
|
| 1192 |
+
args = args || {};
|
| 1193 |
+
attributes.apiRoot = args.apiRoot || wpApiSettings.root;
|
| 1194 |
+
attributes.versionString = args.versionString || wpApiSettings.versionString;
|
| 1195 |
+
attributes.schema = args.schema || null;
|
| 1196 |
+
if ( ! attributes.schema && attributes.apiRoot === wpApiSettings.root && attributes.versionString === wpApiSettings.versionString ) {
|
| 1197 |
+
attributes.schema = wpApiSettings.schema;
|
| 1198 |
+
}
|
| 1199 |
+
|
| 1200 |
+
if ( ! initializedDeferreds[ attributes.apiRoot + attributes.versionString ] ) {
|
| 1201 |
+
endpoint = wp.api.endpoints.findWhere( { apiRoot: attributes.apiRoot, versionString: attributes.versionString } );
|
| 1202 |
+
if ( ! endpoint ) {
|
| 1203 |
+
endpoint = new Endpoint( attributes );
|
| 1204 |
+
wp.api.endpoints.add( endpoint );
|
| 1205 |
+
}
|
| 1206 |
+
deferred = jQuery.Deferred();
|
| 1207 |
+
promise = deferred.promise();
|
| 1208 |
+
|
| 1209 |
+
endpoint.schemaConstructed.done( function( endpoint ) {
|
| 1210 |
+
|
| 1211 |
+
// Map the default endpoints, extending any already present items (including Schema model).
|
| 1212 |
+
wp.api.models = _.extend( endpoint.get( 'models' ), wp.api.models );
|
| 1213 |
+
wp.api.collections = _.extend( endpoint.get( 'collections' ), wp.api.collections );
|
| 1214 |
+
deferred.resolveWith( wp.api, [ endpoint ] );
|
| 1215 |
+
} );
|
| 1216 |
+
initializedDeferreds[ attributes.apiRoot + attributes.versionString ] = promise;
|
| 1217 |
+
}
|
| 1218 |
+
return initializedDeferreds[ attributes.apiRoot + attributes.versionString ];
|
| 1219 |
+
};
|
| 1220 |
|
| 1221 |
/**
|
| 1222 |
+
* Construct the default endpoints and add to an endpoints collection.
|
| 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 );
|
wp-api.min.js
ADDED
|
@@ -0,0 +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
|
wp-api.min.map
ADDED
|
@@ -0,0 +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"}
|
