Version Description
Download this release
Release Info
Developer | danielbachhuber |
Plugin | WordPress REST API (Version 2) |
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"}
|