Version Description
Download this release
Release Info
Developer | rachelbaker |
Plugin | WordPress REST API (Version 2) |
Version | 2.0-beta15 |
Comparing to | |
See all releases |
Code changes from version 2.0-beta14 to 2.0-beta15
- CHANGELOG.md +54 -0
- README.md +0 -1
- lib/endpoints/class-wp-rest-attachments-controller.php +1 -2
- lib/endpoints/class-wp-rest-comments-controller.php +28 -3
- lib/endpoints/class-wp-rest-posts-controller.php +40 -0
- lib/endpoints/class-wp-rest-settings-controller.php +182 -0
- lib/endpoints/class-wp-rest-terms-controller.php +22 -0
- lib/endpoints/class-wp-rest-users-controller.php +23 -1
- lib/fields/class-wp-rest-comment-meta-fields.php +21 -0
- lib/fields/class-wp-rest-meta-fields.php +350 -0
- lib/fields/class-wp-rest-post-meta-fields.php +37 -0
- lib/fields/class-wp-rest-term-meta-fields.php +36 -0
- lib/fields/class-wp-rest-user-meta-fields.php +21 -0
- plugin.php +166 -1
- readme.txt +58 -4
CHANGELOG.md
CHANGED
@@ -1,5 +1,59 @@
|
|
1 |
# Changelog
|
2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
## 2.0 Beta 14.0 (September 30, 2016)
|
4 |
|
5 |
- Add support for password protected posts
|
1 |
# Changelog
|
2 |
|
3 |
+
## 2.0 Beta 15.0 (October 07, 2016)
|
4 |
+
|
5 |
+
- Introduce support for Post Meta, Term Meta, User Meta, and Comment Meta in
|
6 |
+
their parent endpoints.
|
7 |
+
|
8 |
+
For your meta fields to be exposed in the REST API, you need to register
|
9 |
+
them. WordPress includes a `register_meta()` function which is not usually
|
10 |
+
required to get/set fields, but is required for API support.
|
11 |
+
|
12 |
+
To register your field, simply call register_meta and set the show_in_rest
|
13 |
+
flag to true. Note: register_meta must be called separately for each meta
|
14 |
+
key.
|
15 |
+
|
16 |
+
(props @rmccue, @danielbachhuber, @kjbenk, @duncanjbrown, [#2765][gh-2765])
|
17 |
+
|
18 |
+
- Introduce Settings endpoint.
|
19 |
+
|
20 |
+
Expose options to the REST API with the `register_setting()` function, by
|
21 |
+
passing `$args = array( 'show_in_rest' => true )`. Note: WordPress 4.7 is
|
22 |
+
required. See changeset [38635][https://core.trac.wordpress.org/changeset/38635].
|
23 |
+
|
24 |
+
(props @joehoyle, @fjarrett, @danielbachhuber, @jonathanbardo,
|
25 |
+
@greatislander, [#2739][gh-2739])
|
26 |
+
|
27 |
+
- Attachments controller, change permissions check to match core.
|
28 |
+
|
29 |
+
Check for the `upload_files` capability when creating an attachment.
|
30 |
+
|
31 |
+
(props @nullvariable, @adamsilverstein, [#2743][gh-2743])
|
32 |
+
|
33 |
+
- Add `?{taxonomy}_exclude=` query parameter
|
34 |
+
|
35 |
+
This mirrors our existing support for ?{taxonomy}= filtering in the posts
|
36 |
+
controller (which allows querying for only records with are associated with
|
37 |
+
any of the provided term IDs for the specified taxonomy) by adding an
|
38 |
+
equivalent `_exclude` variant to list IDs of terms for which associated posts
|
39 |
+
should NOT be returned.
|
40 |
+
|
41 |
+
(props @kadamwhite, [#2756][gh-2756])
|
42 |
+
|
43 |
+
- Use `get_comment_type()` when comparing updating comment status.
|
44 |
+
|
45 |
+
Comments having a empty `comment_type` within WordPress bites us again.
|
46 |
+
Fixes a bug where comments could not be updated because of bad comparison
|
47 |
+
logic.
|
48 |
+
|
49 |
+
(props @joehoyle, [#2753][gh-2753])
|
50 |
+
|
51 |
+
[gh-2765]: https://github.com/WP-API/WP-API/issues/2765
|
52 |
+
[gh-2739]: https://github.com/WP-API/WP-API/issues/2739
|
53 |
+
[gh-2743]: https://github.com/WP-API/WP-API/issues/2743
|
54 |
+
[gh-2756]: https://github.com/WP-API/WP-API/issues/2756
|
55 |
+
[gh-2753]: https://github.com/WP-API/WP-API/issues/2753
|
56 |
+
|
57 |
## 2.0 Beta 14.0 (September 30, 2016)
|
58 |
|
59 |
- Add support for password protected posts
|
README.md
CHANGED
@@ -3,7 +3,6 @@
|
|
3 |
Access your WordPress site's data through an easy-to-use HTTP REST API.
|
4 |
|
5 |
[![Build Status](https://travis-ci.org/WP-API/WP-API.svg?branch=develop)](https://travis-ci.org/WP-API/WP-API)
|
6 |
-
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/WP-API/WP-API/badges/quality-score.png?b=develop)](https://scrutinizer-ci.com/g/WP-API/WP-API/?branch=develop)
|
7 |
[![codecov.io](http://codecov.io/github/WP-API/WP-API/coverage.svg?branch=develop)](http://codecov.io/github/WP-API/WP-API?branch=develop)
|
8 |
|
9 |
The **"develop"** branch is version 2 which is "beta" but stable and recommended for production. [Read the documentation](http://v2.wp-api.org/)
|
3 |
Access your WordPress site's data through an easy-to-use HTTP REST API.
|
4 |
|
5 |
[![Build Status](https://travis-ci.org/WP-API/WP-API.svg?branch=develop)](https://travis-ci.org/WP-API/WP-API)
|
|
|
6 |
[![codecov.io](http://codecov.io/github/WP-API/WP-API/coverage.svg?branch=develop)](http://codecov.io/github/WP-API/WP-API?branch=develop)
|
7 |
|
8 |
The **"develop"** branch is version 2 which is "beta" but stable and recommended for production. [Read the documentation](http://v2.wp-api.org/)
|
lib/endpoints/class-wp-rest-attachments-controller.php
CHANGED
@@ -40,9 +40,8 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
|
|
40 |
return $ret;
|
41 |
}
|
42 |
|
43 |
-
// "upload_files" cap is returned for an attachment by $post_type_obj->cap->create_posts
|
44 |
$post_type_obj = get_post_type_object( $this->post_type );
|
45 |
-
if ( ! current_user_can(
|
46 |
return new WP_Error( 'rest_cannot_create', __( 'Sorry, you are not allowed to upload media on this site.' ), array( 'status' => 400 ) );
|
47 |
}
|
48 |
|
40 |
return $ret;
|
41 |
}
|
42 |
|
|
|
43 |
$post_type_obj = get_post_type_object( $this->post_type );
|
44 |
+
if ( ! current_user_can( 'upload_files' ) ) {
|
45 |
return new WP_Error( 'rest_cannot_create', __( 'Sorry, you are not allowed to upload media on this site.' ), array( 'status' => 400 ) );
|
46 |
}
|
47 |
|
lib/endpoints/class-wp-rest-comments-controller.php
CHANGED
@@ -8,6 +8,8 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
|
8 |
public function __construct() {
|
9 |
$this->namespace = 'wp/v2';
|
10 |
$this->rest_base = 'comments';
|
|
|
|
|
11 |
}
|
12 |
|
13 |
/**
|
@@ -374,6 +376,14 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
|
374 |
$this->handle_status_param( $request['status'], $comment );
|
375 |
}
|
376 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
377 |
$comment = get_comment( $comment_id );
|
378 |
$fields_update = $this->update_additional_fields_for_object( $comment, $request );
|
379 |
if ( is_wp_error( $fields_update ) ) {
|
@@ -432,7 +442,7 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
|
432 |
return new WP_Error( 'rest_comment_invalid_id', __( 'Invalid comment id.' ), array( 'status' => 404 ) );
|
433 |
}
|
434 |
|
435 |
-
if ( isset( $request['type'] ) && $request['type']
|
436 |
return new WP_Error( 'rest_comment_invalid_type', __( 'Sorry, you cannot change the comment type.' ), array( 'status' => 404 ) );
|
437 |
}
|
438 |
|
@@ -457,6 +467,14 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
|
457 |
}
|
458 |
}
|
459 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
460 |
$comment = get_comment( $id );
|
461 |
$fields_update = $this->update_additional_fields_for_object( $comment, $request );
|
462 |
if ( is_wp_error( $fields_update ) ) {
|
@@ -585,6 +603,10 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
|
585 |
$data['author_avatar_urls'] = rest_get_avatar_urls( $comment->comment_author_email );
|
586 |
}
|
587 |
|
|
|
|
|
|
|
|
|
588 |
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
589 |
$data = $this->add_additional_fields_to_object( $data, $request );
|
590 |
$data = $this->filter_response_by_context( $data, $context );
|
@@ -765,7 +787,8 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
|
765 |
}
|
766 |
|
767 |
if ( isset( $request['type'] ) ) {
|
768 |
-
|
|
|
769 |
}
|
770 |
|
771 |
if ( isset( $request['karma'] ) ) {
|
@@ -920,9 +943,9 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
|
920 |
'description' => __( 'Type of Comment for the object.' ),
|
921 |
'type' => 'string',
|
922 |
'context' => array( 'view', 'edit', 'embed' ),
|
|
|
923 |
'arg_options' => array(
|
924 |
'sanitize_callback' => 'sanitize_key',
|
925 |
-
'default' => '',
|
926 |
),
|
927 |
),
|
928 |
),
|
@@ -950,6 +973,8 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
|
950 |
);
|
951 |
}
|
952 |
|
|
|
|
|
953 |
return $this->add_additional_fields_schema( $schema );
|
954 |
}
|
955 |
|
8 |
public function __construct() {
|
9 |
$this->namespace = 'wp/v2';
|
10 |
$this->rest_base = 'comments';
|
11 |
+
|
12 |
+
$this->meta = new WP_REST_Comment_Meta_Fields();
|
13 |
}
|
14 |
|
15 |
/**
|
376 |
$this->handle_status_param( $request['status'], $comment );
|
377 |
}
|
378 |
|
379 |
+
$schema = $this->get_item_schema();
|
380 |
+
if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) {
|
381 |
+
$meta_update = $this->meta->update_value( $request['meta'], $comment_id );
|
382 |
+
if ( is_wp_error( $meta_update ) ) {
|
383 |
+
return $meta_update;
|
384 |
+
}
|
385 |
+
}
|
386 |
+
|
387 |
$comment = get_comment( $comment_id );
|
388 |
$fields_update = $this->update_additional_fields_for_object( $comment, $request );
|
389 |
if ( is_wp_error( $fields_update ) ) {
|
442 |
return new WP_Error( 'rest_comment_invalid_id', __( 'Invalid comment id.' ), array( 'status' => 404 ) );
|
443 |
}
|
444 |
|
445 |
+
if ( isset( $request['type'] ) && get_comment_type( $id ) !== $request['type'] ) {
|
446 |
return new WP_Error( 'rest_comment_invalid_type', __( 'Sorry, you cannot change the comment type.' ), array( 'status' => 404 ) );
|
447 |
}
|
448 |
|
467 |
}
|
468 |
}
|
469 |
|
470 |
+
$schema = $this->get_item_schema();
|
471 |
+
if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) {
|
472 |
+
$meta_update = $this->meta->update_value( $request['meta'], $id );
|
473 |
+
if ( is_wp_error( $meta_update ) ) {
|
474 |
+
return $meta_update;
|
475 |
+
}
|
476 |
+
}
|
477 |
+
|
478 |
$comment = get_comment( $id );
|
479 |
$fields_update = $this->update_additional_fields_for_object( $comment, $request );
|
480 |
if ( is_wp_error( $fields_update ) ) {
|
603 |
$data['author_avatar_urls'] = rest_get_avatar_urls( $comment->comment_author_email );
|
604 |
}
|
605 |
|
606 |
+
if ( ! empty( $schema['properties']['meta'] ) ) {
|
607 |
+
$data['meta'] = $this->meta->get_value( $comment->comment_ID, $request );
|
608 |
+
}
|
609 |
+
|
610 |
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
611 |
$data = $this->add_additional_fields_to_object( $data, $request );
|
612 |
$data = $this->filter_response_by_context( $data, $context );
|
787 |
}
|
788 |
|
789 |
if ( isset( $request['type'] ) ) {
|
790 |
+
// Comment type "comment" needs to be created as an empty string.
|
791 |
+
$prepared_comment['comment_type'] = 'comment' === $request['type'] ? '' : $request['type'];
|
792 |
}
|
793 |
|
794 |
if ( isset( $request['karma'] ) ) {
|
943 |
'description' => __( 'Type of Comment for the object.' ),
|
944 |
'type' => 'string',
|
945 |
'context' => array( 'view', 'edit', 'embed' ),
|
946 |
+
'default' => 'comment',
|
947 |
'arg_options' => array(
|
948 |
'sanitize_callback' => 'sanitize_key',
|
|
|
949 |
),
|
950 |
),
|
951 |
),
|
973 |
);
|
974 |
}
|
975 |
|
976 |
+
$schema['properties']['meta'] = $this->meta->get_field_schema();
|
977 |
+
|
978 |
return $this->add_additional_fields_schema( $schema );
|
979 |
}
|
980 |
|
lib/endpoints/class-wp-rest-posts-controller.php
CHANGED
@@ -9,6 +9,8 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
9 |
$this->namespace = 'wp/v2';
|
10 |
$obj = get_post_type_object( $post_type );
|
11 |
$this->rest_base = ! empty( $obj->rest_base ) ? $obj->rest_base : $obj->name;
|
|
|
|
|
12 |
}
|
13 |
|
14 |
/**
|
@@ -171,6 +173,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
171 |
$taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) );
|
172 |
foreach ( $taxonomies as $taxonomy ) {
|
173 |
$base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
|
|
|
174 |
|
175 |
if ( ! empty( $request[ $base ] ) ) {
|
176 |
$query_args['tax_query'][] = array(
|
@@ -180,6 +183,16 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
180 |
'include_children' => false,
|
181 |
);
|
182 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
183 |
}
|
184 |
|
185 |
$posts_query = new WP_Query();
|
@@ -415,6 +428,13 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
415 |
}
|
416 |
|
417 |
$post = $this->get_post( $post_id );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
418 |
$fields_update = $this->update_additional_fields_for_object( $post, $request );
|
419 |
if ( is_wp_error( $fields_update ) ) {
|
420 |
return $fields_update;
|
@@ -521,6 +541,14 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
521 |
}
|
522 |
|
523 |
$post = $this->get_post( $post_id );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
524 |
$fields_update = $this->update_additional_fields_for_object( $post, $request );
|
525 |
if ( is_wp_error( $fields_update ) ) {
|
526 |
return $fields_update;
|
@@ -1253,6 +1281,10 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
1253 |
}
|
1254 |
}
|
1255 |
|
|
|
|
|
|
|
|
|
1256 |
$taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) );
|
1257 |
foreach ( $taxonomies as $taxonomy ) {
|
1258 |
$base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
|
@@ -1511,6 +1543,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
1511 |
'revisions',
|
1512 |
'page-attributes',
|
1513 |
'post-formats',
|
|
|
1514 |
);
|
1515 |
$fixed_schemas = array(
|
1516 |
'post' => array(
|
@@ -1522,6 +1555,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
1522 |
'comments',
|
1523 |
'revisions',
|
1524 |
'post-formats',
|
|
|
1525 |
),
|
1526 |
'page' => array(
|
1527 |
'title',
|
@@ -1532,12 +1566,14 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
1532 |
'comments',
|
1533 |
'revisions',
|
1534 |
'page-attributes',
|
|
|
1535 |
),
|
1536 |
'attachment' => array(
|
1537 |
'title',
|
1538 |
'author',
|
1539 |
'comments',
|
1540 |
'revisions',
|
|
|
1541 |
),
|
1542 |
);
|
1543 |
foreach ( $post_type_attributes as $attribute ) {
|
@@ -1672,6 +1708,10 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|
1672 |
);
|
1673 |
break;
|
1674 |
|
|
|
|
|
|
|
|
|
1675 |
}
|
1676 |
}
|
1677 |
|
9 |
$this->namespace = 'wp/v2';
|
10 |
$obj = get_post_type_object( $post_type );
|
11 |
$this->rest_base = ! empty( $obj->rest_base ) ? $obj->rest_base : $obj->name;
|
12 |
+
|
13 |
+
$this->meta = new WP_REST_Post_Meta_Fields( $this->post_type );
|
14 |
}
|
15 |
|
16 |
/**
|
173 |
$taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) );
|
174 |
foreach ( $taxonomies as $taxonomy ) {
|
175 |
$base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
|
176 |
+
$tax_exclude = $base . '_exclude';
|
177 |
|
178 |
if ( ! empty( $request[ $base ] ) ) {
|
179 |
$query_args['tax_query'][] = array(
|
183 |
'include_children' => false,
|
184 |
);
|
185 |
}
|
186 |
+
|
187 |
+
if ( ! empty( $request[ $tax_exclude ] ) ) {
|
188 |
+
$query_args['tax_query'][] = array(
|
189 |
+
'taxonomy' => $taxonomy->name,
|
190 |
+
'field' => 'term_id',
|
191 |
+
'terms' => $request[ $tax_exclude ],
|
192 |
+
'include_children' => false,
|
193 |
+
'operator' => 'NOT IN',
|
194 |
+
);
|
195 |
+
}
|
196 |
}
|
197 |
|
198 |
$posts_query = new WP_Query();
|
428 |
}
|
429 |
|
430 |
$post = $this->get_post( $post_id );
|
431 |
+
if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) {
|
432 |
+
$meta_update = $this->meta->update_value( $request['meta'], (int) $request['id'] );
|
433 |
+
if ( is_wp_error( $meta_update ) ) {
|
434 |
+
return $meta_update;
|
435 |
+
}
|
436 |
+
}
|
437 |
+
|
438 |
$fields_update = $this->update_additional_fields_for_object( $post, $request );
|
439 |
if ( is_wp_error( $fields_update ) ) {
|
440 |
return $fields_update;
|
541 |
}
|
542 |
|
543 |
$post = $this->get_post( $post_id );
|
544 |
+
|
545 |
+
if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) {
|
546 |
+
$meta_update = $this->meta->update_value( $request['meta'], $post->ID );
|
547 |
+
if ( is_wp_error( $meta_update ) ) {
|
548 |
+
return $meta_update;
|
549 |
+
}
|
550 |
+
}
|
551 |
+
|
552 |
$fields_update = $this->update_additional_fields_for_object( $post, $request );
|
553 |
if ( is_wp_error( $fields_update ) ) {
|
554 |
return $fields_update;
|
1281 |
}
|
1282 |
}
|
1283 |
|
1284 |
+
if ( ! empty( $schema['properties']['meta'] ) ) {
|
1285 |
+
$data['meta'] = $this->meta->get_value( $post->ID, $request );
|
1286 |
+
}
|
1287 |
+
|
1288 |
$taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) );
|
1289 |
foreach ( $taxonomies as $taxonomy ) {
|
1290 |
$base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
|
1543 |
'revisions',
|
1544 |
'page-attributes',
|
1545 |
'post-formats',
|
1546 |
+
'custom-fields',
|
1547 |
);
|
1548 |
$fixed_schemas = array(
|
1549 |
'post' => array(
|
1555 |
'comments',
|
1556 |
'revisions',
|
1557 |
'post-formats',
|
1558 |
+
'custom-fields',
|
1559 |
),
|
1560 |
'page' => array(
|
1561 |
'title',
|
1566 |
'comments',
|
1567 |
'revisions',
|
1568 |
'page-attributes',
|
1569 |
+
'custom-fields',
|
1570 |
),
|
1571 |
'attachment' => array(
|
1572 |
'title',
|
1573 |
'author',
|
1574 |
'comments',
|
1575 |
'revisions',
|
1576 |
+
'custom-fields',
|
1577 |
),
|
1578 |
);
|
1579 |
foreach ( $post_type_attributes as $attribute ) {
|
1708 |
);
|
1709 |
break;
|
1710 |
|
1711 |
+
case 'custom-fields':
|
1712 |
+
$schema['properties']['meta'] = $this->meta->get_field_schema();
|
1713 |
+
break;
|
1714 |
+
|
1715 |
}
|
1716 |
}
|
1717 |
|
lib/endpoints/class-wp-rest-settings-controller.php
ADDED
@@ -0,0 +1,182 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Manage a WordPress site's settings.
|
5 |
+
*/
|
6 |
+
|
7 |
+
class WP_REST_Settings_Controller extends WP_REST_Controller {
|
8 |
+
|
9 |
+
protected $rest_base = 'settings';
|
10 |
+
protected $namespace = 'wp/v2';
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Register the routes for the objects of the controller.
|
14 |
+
*/
|
15 |
+
public function register_routes() {
|
16 |
+
register_rest_route( $this->namespace, '/' . $this->rest_base, array(
|
17 |
+
array(
|
18 |
+
'methods' => WP_REST_Server::READABLE,
|
19 |
+
'callback' => array( $this, 'get_item' ),
|
20 |
+
'args' => array(),
|
21 |
+
'permission_callback' => array( $this, 'get_item_permissions_check' ),
|
22 |
+
),
|
23 |
+
array(
|
24 |
+
'methods' => WP_REST_Server::EDITABLE,
|
25 |
+
'callback' => array( $this, 'update_item' ),
|
26 |
+
'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
|
27 |
+
'permission_callback' => array( $this, 'get_item_permissions_check' ),
|
28 |
+
),
|
29 |
+
'schema' => array( $this, 'get_public_item_schema' ),
|
30 |
+
) );
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Check if a given request has access to read and manage settings.
|
35 |
+
*
|
36 |
+
* @param WP_REST_Request $request Full details about the request.
|
37 |
+
* @return boolean
|
38 |
+
*/
|
39 |
+
public function get_item_permissions_check( $request ) {
|
40 |
+
return current_user_can( 'manage_options' );
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Get the settings.
|
45 |
+
*
|
46 |
+
* @param WP_REST_Request $request Full details about the request.
|
47 |
+
* @return WP_Error|array
|
48 |
+
*/
|
49 |
+
public function get_item( $request ) {
|
50 |
+
$options = $this->get_registered_options();
|
51 |
+
$response = array();
|
52 |
+
|
53 |
+
foreach ( $options as $name => $args ) {
|
54 |
+
// Default to a null value as "null" in the response means "not set".
|
55 |
+
$response[ $name ] = get_option( $args['option_name'], $args['schema']['default'] );
|
56 |
+
|
57 |
+
// Because get_option() is lossy, we have to
|
58 |
+
// cast values to the type they are registered with.
|
59 |
+
$response[ $name ] = $this->prepare_value( $response[ $name ], $args['schema'] );
|
60 |
+
}
|
61 |
+
|
62 |
+
return $response;
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Prepare a value for output based off a schema array.
|
67 |
+
*
|
68 |
+
* @param mixed $value
|
69 |
+
* @param array $schema
|
70 |
+
* @return mixed
|
71 |
+
*/
|
72 |
+
protected function prepare_value( $value, $schema ) {
|
73 |
+
switch ( $schema['type'] ) {
|
74 |
+
case 'string':
|
75 |
+
return strval( $value );
|
76 |
+
case 'number':
|
77 |
+
return floatval( $value );
|
78 |
+
case 'boolean':
|
79 |
+
return (bool) $value;
|
80 |
+
default:
|
81 |
+
return null;
|
82 |
+
}
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Update settings for the settings object.
|
87 |
+
*
|
88 |
+
* @param WP_REST_Request $request Full detail about the request.
|
89 |
+
* @return WP_Error|array
|
90 |
+
*/
|
91 |
+
public function update_item( $request ) {
|
92 |
+
$options = $this->get_registered_options();
|
93 |
+
$params = $request->get_params();
|
94 |
+
|
95 |
+
foreach ( $options as $name => $args ) {
|
96 |
+
if ( ! array_key_exists( $name, $params ) ) {
|
97 |
+
continue;
|
98 |
+
}
|
99 |
+
// A null value means reset the option, which is essentially deleting it
|
100 |
+
// from the database and then relying on the default value.
|
101 |
+
if ( is_null( $request[ $name ] ) ) {
|
102 |
+
delete_option( $args['option_name'] );
|
103 |
+
} else {
|
104 |
+
update_option( $args['option_name'], $request[ $name ] );
|
105 |
+
}
|
106 |
+
}
|
107 |
+
|
108 |
+
return $this->get_item( $request );
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Get all the registered options for the Settings API
|
113 |
+
*
|
114 |
+
* @return array
|
115 |
+
*/
|
116 |
+
protected function get_registered_options() {
|
117 |
+
$rest_options = array();
|
118 |
+
|
119 |
+
foreach ( get_registered_settings() as $name => $args ) {
|
120 |
+
if ( empty( $args['show_in_rest'] ) ) {
|
121 |
+
continue;
|
122 |
+
}
|
123 |
+
|
124 |
+
$rest_args = array();
|
125 |
+
if ( is_array( $args['show_in_rest'] ) ) {
|
126 |
+
$rest_args = $args['show_in_rest'];
|
127 |
+
}
|
128 |
+
|
129 |
+
$defaults = array(
|
130 |
+
'name' => ! empty( $rest_args['name'] ) ? $rest_args['name'] : $name,
|
131 |
+
'schema' => array(),
|
132 |
+
);
|
133 |
+
$rest_args = array_merge( $defaults, $rest_args );
|
134 |
+
|
135 |
+
$default_schema = array(
|
136 |
+
'type' => empty( $args['type'] ) ? null : $args['type'],
|
137 |
+
'description' => empty( $args['description'] ) ? '' : $args['description'],
|
138 |
+
'default' => isset( $args['default'] ) ? $args['default'] : null,
|
139 |
+
);
|
140 |
+
|
141 |
+
$rest_args['schema'] = array_merge( $default_schema, $rest_args['schema'] );
|
142 |
+
$rest_args['option_name'] = $name;
|
143 |
+
|
144 |
+
// Skip over settings that don't have a defined type in the schema.
|
145 |
+
if ( empty( $rest_args['schema']['type'] ) ) {
|
146 |
+
continue;
|
147 |
+
}
|
148 |
+
|
149 |
+
// Whitelist the supported types for settings, as we don't want invalid types
|
150 |
+
// to be updated with arbitrary values that we can't do decent sanitizing for.
|
151 |
+
if ( ! in_array( $rest_args['schema']['type'], array( 'number', 'string', 'boolean' ), true ) ) {
|
152 |
+
continue;
|
153 |
+
}
|
154 |
+
|
155 |
+
$rest_options[ $rest_args['name'] ] = $rest_args;
|
156 |
+
}
|
157 |
+
|
158 |
+
return $rest_options;
|
159 |
+
}
|
160 |
+
|
161 |
+
/**
|
162 |
+
* Get the site setting schema, conforming to JSON Schema.
|
163 |
+
*
|
164 |
+
* @return array
|
165 |
+
*/
|
166 |
+
public function get_item_schema() {
|
167 |
+
$options = $this->get_registered_options();
|
168 |
+
|
169 |
+
$schema = array(
|
170 |
+
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
171 |
+
'title' => 'settings',
|
172 |
+
'type' => 'object',
|
173 |
+
'properties' => array(),
|
174 |
+
);
|
175 |
+
|
176 |
+
foreach ( $options as $option_name => $option ) {
|
177 |
+
$schema['properties'][ $option_name ] = $option['schema'];
|
178 |
+
}
|
179 |
+
|
180 |
+
return $this->add_additional_fields_schema( $schema );
|
181 |
+
}
|
182 |
+
}
|
lib/endpoints/class-wp-rest-terms-controller.php
CHANGED
@@ -15,6 +15,8 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
|
|
15 |
$this->namespace = 'wp/v2';
|
16 |
$tax_obj = get_taxonomy( $taxonomy );
|
17 |
$this->rest_base = ! empty( $tax_obj->rest_base ) ? $tax_obj->rest_base : $tax_obj->name;
|
|
|
|
|
18 |
}
|
19 |
|
20 |
/**
|
@@ -371,6 +373,13 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
|
|
371 |
*/
|
372 |
do_action( "rest_insert_{$this->taxonomy}", $term, $request, true );
|
373 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
374 |
$fields_update = $this->update_additional_fields_for_object( $term, $request );
|
375 |
if ( is_wp_error( $fields_update ) ) {
|
376 |
return $fields_update;
|
@@ -445,6 +454,14 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
|
|
445 |
/* This action is documented in lib/endpoints/class-wp-rest-terms-controller.php */
|
446 |
do_action( "rest_insert_{$this->taxonomy}", $term, $request, false );
|
447 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
448 |
$fields_update = $this->update_additional_fields_for_object( $term, $request );
|
449 |
if ( is_wp_error( $fields_update ) ) {
|
450 |
return $fields_update;
|
@@ -593,6 +610,9 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
|
|
593 |
if ( ! empty( $schema['properties']['parent'] ) ) {
|
594 |
$data['parent'] = (int) $item->parent;
|
595 |
}
|
|
|
|
|
|
|
596 |
|
597 |
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
598 |
$data = $this->add_additional_fields_to_object( $data, $request );
|
@@ -739,6 +759,8 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
|
|
739 |
'context' => array( 'view', 'edit' ),
|
740 |
);
|
741 |
}
|
|
|
|
|
742 |
return $this->add_additional_fields_schema( $schema );
|
743 |
}
|
744 |
|
15 |
$this->namespace = 'wp/v2';
|
16 |
$tax_obj = get_taxonomy( $taxonomy );
|
17 |
$this->rest_base = ! empty( $tax_obj->rest_base ) ? $tax_obj->rest_base : $tax_obj->name;
|
18 |
+
|
19 |
+
$this->meta = new WP_REST_Term_Meta_Fields( $taxonomy );
|
20 |
}
|
21 |
|
22 |
/**
|
373 |
*/
|
374 |
do_action( "rest_insert_{$this->taxonomy}", $term, $request, true );
|
375 |
|
376 |
+
if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) {
|
377 |
+
$meta_update = $this->meta->update_value( $request['meta'], (int) $request['id'] );
|
378 |
+
if ( is_wp_error( $meta_update ) ) {
|
379 |
+
return $meta_update;
|
380 |
+
}
|
381 |
+
}
|
382 |
+
|
383 |
$fields_update = $this->update_additional_fields_for_object( $term, $request );
|
384 |
if ( is_wp_error( $fields_update ) ) {
|
385 |
return $fields_update;
|
454 |
/* This action is documented in lib/endpoints/class-wp-rest-terms-controller.php */
|
455 |
do_action( "rest_insert_{$this->taxonomy}", $term, $request, false );
|
456 |
|
457 |
+
$schema = $this->get_item_schema();
|
458 |
+
if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) {
|
459 |
+
$meta_update = $this->meta->update_value( $request['meta'], (int) $request['id'] );
|
460 |
+
if ( is_wp_error( $meta_update ) ) {
|
461 |
+
return $meta_update;
|
462 |
+
}
|
463 |
+
}
|
464 |
+
|
465 |
$fields_update = $this->update_additional_fields_for_object( $term, $request );
|
466 |
if ( is_wp_error( $fields_update ) ) {
|
467 |
return $fields_update;
|
610 |
if ( ! empty( $schema['properties']['parent'] ) ) {
|
611 |
$data['parent'] = (int) $item->parent;
|
612 |
}
|
613 |
+
if ( ! empty( $schema['properties']['meta'] ) ) {
|
614 |
+
$data['meta'] = $this->meta->get_value( $item->term_id, $request );
|
615 |
+
}
|
616 |
|
617 |
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
618 |
$data = $this->add_additional_fields_to_object( $data, $request );
|
759 |
'context' => array( 'view', 'edit' ),
|
760 |
);
|
761 |
}
|
762 |
+
|
763 |
+
$schema['properties']['meta'] = $this->meta->get_field_schema();
|
764 |
return $this->add_additional_fields_schema( $schema );
|
765 |
}
|
766 |
|
lib/endpoints/class-wp-rest-users-controller.php
CHANGED
@@ -8,6 +8,8 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
|
|
8 |
public function __construct() {
|
9 |
$this->namespace = 'wp/v2';
|
10 |
$this->rest_base = 'users';
|
|
|
|
|
11 |
}
|
12 |
|
13 |
/**
|
@@ -329,6 +331,13 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
|
|
329 |
array_map( array( $user, 'add_role' ), $request['roles'] );
|
330 |
}
|
331 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
332 |
$fields_update = $this->update_additional_fields_for_object( $user, $request );
|
333 |
if ( is_wp_error( $fields_update ) ) {
|
334 |
return $fields_update;
|
@@ -421,6 +430,14 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
|
|
421 |
array_map( array( $user, 'add_role' ), $request['roles'] );
|
422 |
}
|
423 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
424 |
$fields_update = $this->update_additional_fields_for_object( $user, $request );
|
425 |
if ( is_wp_error( $fields_update ) ) {
|
426 |
return $fields_update;
|
@@ -579,6 +596,10 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
|
|
579 |
$data['avatar_urls'] = rest_get_avatar_urls( $user->user_email );
|
580 |
}
|
581 |
|
|
|
|
|
|
|
|
|
582 |
$context = ! empty( $request['context'] ) ? $request['context'] : 'embed';
|
583 |
|
584 |
$data = $this->add_additional_fields_to_object( $data, $request );
|
@@ -866,9 +887,10 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
|
|
866 |
'readonly' => true,
|
867 |
'properties' => $avatar_properties,
|
868 |
);
|
869 |
-
|
870 |
}
|
871 |
|
|
|
|
|
872 |
return $this->add_additional_fields_schema( $schema );
|
873 |
}
|
874 |
|
8 |
public function __construct() {
|
9 |
$this->namespace = 'wp/v2';
|
10 |
$this->rest_base = 'users';
|
11 |
+
|
12 |
+
$this->meta = new WP_REST_User_Meta_Fields();
|
13 |
}
|
14 |
|
15 |
/**
|
331 |
array_map( array( $user, 'add_role' ), $request['roles'] );
|
332 |
}
|
333 |
|
334 |
+
if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) {
|
335 |
+
$meta_update = $this->meta->update_value( $request['meta'], $user_id );
|
336 |
+
if ( is_wp_error( $meta_update ) ) {
|
337 |
+
return $meta_update;
|
338 |
+
}
|
339 |
+
}
|
340 |
+
|
341 |
$fields_update = $this->update_additional_fields_for_object( $user, $request );
|
342 |
if ( is_wp_error( $fields_update ) ) {
|
343 |
return $fields_update;
|
430 |
array_map( array( $user, 'add_role' ), $request['roles'] );
|
431 |
}
|
432 |
|
433 |
+
$schema = $this->get_item_schema();
|
434 |
+
if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) {
|
435 |
+
$meta_update = $this->meta->update_value( $request['meta'], $id );
|
436 |
+
if ( is_wp_error( $meta_update ) ) {
|
437 |
+
return $meta_update;
|
438 |
+
}
|
439 |
+
}
|
440 |
+
|
441 |
$fields_update = $this->update_additional_fields_for_object( $user, $request );
|
442 |
if ( is_wp_error( $fields_update ) ) {
|
443 |
return $fields_update;
|
596 |
$data['avatar_urls'] = rest_get_avatar_urls( $user->user_email );
|
597 |
}
|
598 |
|
599 |
+
if ( ! empty( $schema['properties']['meta'] ) ) {
|
600 |
+
$data['meta'] = $this->meta->get_value( $user->ID, $request );
|
601 |
+
}
|
602 |
+
|
603 |
$context = ! empty( $request['context'] ) ? $request['context'] : 'embed';
|
604 |
|
605 |
$data = $this->add_additional_fields_to_object( $data, $request );
|
887 |
'readonly' => true,
|
888 |
'properties' => $avatar_properties,
|
889 |
);
|
|
|
890 |
}
|
891 |
|
892 |
+
$schema['properties']['meta'] = $this->meta->get_field_schema();
|
893 |
+
|
894 |
return $this->add_additional_fields_schema( $schema );
|
895 |
}
|
896 |
|
lib/fields/class-wp-rest-comment-meta-fields.php
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WP_REST_Comment_Meta_Fields extends WP_REST_Meta_Fields {
|
4 |
+
/**
|
5 |
+
* Get the object type for meta.
|
6 |
+
*
|
7 |
+
* @return string
|
8 |
+
*/
|
9 |
+
protected function get_meta_type() {
|
10 |
+
return 'comment';
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Get the type for `register_rest_field`.
|
15 |
+
*
|
16 |
+
* @return string
|
17 |
+
*/
|
18 |
+
public function get_rest_field_type() {
|
19 |
+
return 'comment';
|
20 |
+
}
|
21 |
+
}
|
lib/fields/class-wp-rest-meta-fields.php
ADDED
@@ -0,0 +1,350 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Manage meta values for an object.
|
5 |
+
*/
|
6 |
+
|
7 |
+
abstract class WP_REST_Meta_Fields {
|
8 |
+
/**
|
9 |
+
* Get the object type for meta.
|
10 |
+
*
|
11 |
+
* @return string One of 'post', 'comment', 'term', 'user', or anything else supported by `_get_meta_table()`
|
12 |
+
*/
|
13 |
+
abstract protected function get_meta_type();
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Get the object type for `register_rest_field`.
|
17 |
+
*
|
18 |
+
* @return string Custom post type, 'taxonomy', 'comment', or `user`
|
19 |
+
*/
|
20 |
+
abstract protected function get_rest_field_type();
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Register the meta field.
|
24 |
+
*/
|
25 |
+
public function register_field() {
|
26 |
+
register_rest_field( $this->get_rest_field_type(), 'meta', array(
|
27 |
+
'get_callback' => array( $this, 'get_value' ),
|
28 |
+
'update_callback' => array( $this, 'update_value' ),
|
29 |
+
'schema' => $this->get_field_schema(),
|
30 |
+
));
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Get the `meta` field value.
|
35 |
+
*
|
36 |
+
* @param int $id Object ID to fetch meta for.
|
37 |
+
* @param WP_REST_Request $request Full details about the request.
|
38 |
+
* @return WP_Error|array
|
39 |
+
*/
|
40 |
+
public function get_value( $id, $request ) {
|
41 |
+
$fields = $this->get_registered_fields();
|
42 |
+
$response = array();
|
43 |
+
|
44 |
+
foreach ( $fields as $name => $args ) {
|
45 |
+
$all_values = get_metadata( $this->get_meta_type(), $id, $name, false );
|
46 |
+
if ( $args['single'] ) {
|
47 |
+
if ( empty( $all_values ) ) {
|
48 |
+
$value = $args['schema']['default'];
|
49 |
+
} else {
|
50 |
+
$value = $all_values[0];
|
51 |
+
}
|
52 |
+
$value = $this->prepare_value_for_response( $value, $request, $args );
|
53 |
+
} else {
|
54 |
+
$value = array();
|
55 |
+
foreach ( $all_values as $row ) {
|
56 |
+
$value[] = $this->prepare_value_for_response( $row, $request, $args );
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
$response[ $name ] = $value;
|
61 |
+
}
|
62 |
+
|
63 |
+
return (object) $response;
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Prepare value for response.
|
68 |
+
*
|
69 |
+
* This is required because some native types cannot be stored correctly in
|
70 |
+
* the database, such as booleans. We need to cast back to the relevant type
|
71 |
+
* before passing back to JSON.
|
72 |
+
*
|
73 |
+
* @param mixed $value Value to prepare.
|
74 |
+
* @param WP_REST_Request $request Current request object.
|
75 |
+
* @param array $args Options for the field.
|
76 |
+
* @return mixed Prepared value.
|
77 |
+
*/
|
78 |
+
protected function prepare_value_for_response( $value, $request, $args ) {
|
79 |
+
if ( ! empty( $args['prepare_callback'] ) ) {
|
80 |
+
$value = call_user_func( $args['prepare_callback'], $value, $request, $args );
|
81 |
+
}
|
82 |
+
|
83 |
+
return $value;
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Update meta values.
|
88 |
+
*
|
89 |
+
* @param WP_REST_Request $request Full detail about the request.
|
90 |
+
* @return WP_Error|null Error if one occurs, null on success.
|
91 |
+
*/
|
92 |
+
public function update_value( $params, $id ) {
|
93 |
+
$fields = $this->get_registered_fields();
|
94 |
+
|
95 |
+
foreach ( $fields as $name => $args ) {
|
96 |
+
if ( ! array_key_exists( $name, $params ) ) {
|
97 |
+
continue;
|
98 |
+
}
|
99 |
+
|
100 |
+
// A null value means reset the field, which is essentially deleting it
|
101 |
+
// from the database and then relying on the default value.
|
102 |
+
if ( is_null( $params[ $name ] ) ) {
|
103 |
+
$result = $this->delete_meta_value( $id, $name );
|
104 |
+
} elseif ( $args['single'] ) {
|
105 |
+
$result = $this->update_meta_value( $id, $name, $params[ $name ] );
|
106 |
+
} else {
|
107 |
+
$result = $this->update_multi_meta_value( $id, $name, $params[ $name ] );
|
108 |
+
}
|
109 |
+
|
110 |
+
if ( is_wp_error( $result ) ) {
|
111 |
+
return $result;
|
112 |
+
}
|
113 |
+
}
|
114 |
+
|
115 |
+
return null;
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Delete meta value for an object.
|
120 |
+
*
|
121 |
+
* @param int $object Object ID the field belongs to.
|
122 |
+
* @param string $name Key for the field.
|
123 |
+
* @return bool|WP_Error True if meta field is deleted, error otherwise.
|
124 |
+
*/
|
125 |
+
protected function delete_meta_value( $object, $name ) {
|
126 |
+
if ( ! current_user_can( 'delete_post_meta', $object, $name ) ) {
|
127 |
+
return new WP_Error(
|
128 |
+
'rest_cannot_delete',
|
129 |
+
sprintf( __( 'You do not have permission to edit the %s custom field.' ), $name ),
|
130 |
+
array( 'key' => $name, 'status' => rest_authorization_required_code() )
|
131 |
+
);
|
132 |
+
}
|
133 |
+
|
134 |
+
if ( ! delete_metadata( $this->get_meta_type(), $object, wp_slash( $name ) ) ) {
|
135 |
+
return new WP_Error(
|
136 |
+
'rest_meta_database_error',
|
137 |
+
__( 'Could not delete meta value from database.' ),
|
138 |
+
array( 'key' => $name, 'status' => WP_HTTP::INTERNAL_SERVER_ERROR )
|
139 |
+
);
|
140 |
+
}
|
141 |
+
|
142 |
+
return true;
|
143 |
+
}
|
144 |
+
|
145 |
+
/**
|
146 |
+
* Update multiple meta values for an object.
|
147 |
+
*
|
148 |
+
* Alters the list of values in the database to match the list of provided values.
|
149 |
+
*
|
150 |
+
* @param int $object Object ID.
|
151 |
+
* @param string $name Key for the custom field.
|
152 |
+
* @param array $values List of values to update to.
|
153 |
+
* @return bool|WP_Error True if meta fields are updated, error otherwise.
|
154 |
+
*/
|
155 |
+
protected function update_multi_meta_value( $object, $name, $values ) {
|
156 |
+
if ( ! current_user_can( 'edit_post_meta', $object, $name ) ) {
|
157 |
+
return new WP_Error(
|
158 |
+
'rest_cannot_update',
|
159 |
+
sprintf( __( 'You do not have permission to edit the %s custom field.' ), $name ),
|
160 |
+
array( 'key' => $name, 'status' => rest_authorization_required_code() )
|
161 |
+
);
|
162 |
+
}
|
163 |
+
|
164 |
+
$current = get_metadata( $this->get_meta_type(), $object, $name, false );
|
165 |
+
|
166 |
+
$to_remove = $current;
|
167 |
+
$to_add = $values;
|
168 |
+
foreach ( $to_add as $add_key => $value ) {
|
169 |
+
$remove_keys = array_keys( $to_remove, $value, true );
|
170 |
+
if ( empty( $remove_keys ) ) {
|
171 |
+
continue;
|
172 |
+
}
|
173 |
+
|
174 |
+
if ( count( $remove_keys ) > 1 ) {
|
175 |
+
// To remove, we need to remove first, then add, so don't touch.
|
176 |
+
continue;
|
177 |
+
}
|
178 |
+
|
179 |
+
$remove_key = $remove_keys[0];
|
180 |
+
unset( $to_remove[ $remove_key ] );
|
181 |
+
unset( $to_add[ $add_key ] );
|
182 |
+
}
|
183 |
+
|
184 |
+
// `delete_metadata` removes _all_ instances of the value, so only call
|
185 |
+
// once.
|
186 |
+
$to_remove = array_unique( $to_remove );
|
187 |
+
foreach ( $to_remove as $value ) {
|
188 |
+
if ( ! delete_metadata( $this->get_meta_type(), $object, wp_slash( $name ), wp_slash( $value ) ) ) {
|
189 |
+
return new WP_Error(
|
190 |
+
'rest_meta_database_error',
|
191 |
+
__( 'Could not update meta value in database.' ),
|
192 |
+
array( 'key' => $name, 'status' => WP_HTTP::INTERNAL_SERVER_ERROR )
|
193 |
+
);
|
194 |
+
}
|
195 |
+
}
|
196 |
+
foreach ( $to_add as $value ) {
|
197 |
+
if ( ! add_metadata( $this->get_meta_type(), $object, wp_slash( $name ), wp_slash( $value ) ) ) {
|
198 |
+
return new WP_Error(
|
199 |
+
'rest_meta_database_error',
|
200 |
+
__( 'Could not update meta value in database.' ),
|
201 |
+
array( 'key' => $name, 'status' => WP_HTTP::INTERNAL_SERVER_ERROR )
|
202 |
+
);
|
203 |
+
}
|
204 |
+
}
|
205 |
+
|
206 |
+
return true;
|
207 |
+
}
|
208 |
+
|
209 |
+
/**
|
210 |
+
* Update meta value for an object.
|
211 |
+
*
|
212 |
+
* @param int $object Object ID.
|
213 |
+
* @param string $name Key for the custom field.
|
214 |
+
* @return bool|WP_Error True if meta field is deleted, error otherwise.
|
215 |
+
*/
|
216 |
+
protected function update_meta_value( $object, $name, $value ) {
|
217 |
+
if ( ! current_user_can( 'edit_post_meta', $object, $name ) ) {
|
218 |
+
return new WP_Error(
|
219 |
+
'rest_cannot_update',
|
220 |
+
sprintf( __( 'You do not have permission to edit the %s custom field.' ), $name ),
|
221 |
+
array( 'key' => $name, 'status' => rest_authorization_required_code() )
|
222 |
+
);
|
223 |
+
}
|
224 |
+
|
225 |
+
if ( ! update_metadata( $this->get_meta_type(), $object, wp_slash( $name ), wp_slash( $value ) ) ) {
|
226 |
+
return new WP_Error(
|
227 |
+
'rest_meta_database_error',
|
228 |
+
__( 'Could not update meta value in database.' ),
|
229 |
+
array( 'key' => $name, 'status' => WP_HTTP::INTERNAL_SERVER_ERROR )
|
230 |
+
);
|
231 |
+
}
|
232 |
+
|
233 |
+
return true;
|
234 |
+
}
|
235 |
+
|
236 |
+
/**
|
237 |
+
* Get all the registered meta fields.
|
238 |
+
*
|
239 |
+
* @return array
|
240 |
+
*/
|
241 |
+
protected function get_registered_fields() {
|
242 |
+
$registered = array();
|
243 |
+
|
244 |
+
foreach ( get_registered_meta_keys( $this->get_meta_type() ) as $name => $args ) {
|
245 |
+
if ( empty( $args['show_in_rest'] ) ) {
|
246 |
+
continue;
|
247 |
+
}
|
248 |
+
|
249 |
+
$rest_args = array();
|
250 |
+
if ( is_array( $args['show_in_rest'] ) ) {
|
251 |
+
$rest_args = $args['show_in_rest'];
|
252 |
+
}
|
253 |
+
|
254 |
+
$default_args = array(
|
255 |
+
'name' => $name,
|
256 |
+
'single' => $args['single'],
|
257 |
+
'schema' => array(),
|
258 |
+
'prepare_callback' => array( $this, 'prepare_value' ),
|
259 |
+
);
|
260 |
+
$default_schema = array(
|
261 |
+
'type' => null,
|
262 |
+
'description' => empty( $args['description'] ) ? '' : $args['description'],
|
263 |
+
'default' => isset( $args['default'] ) ? $args['default'] : null,
|
264 |
+
);
|
265 |
+
$rest_args = array_merge( $default_args, $rest_args );
|
266 |
+
$rest_args['schema'] = array_merge( $default_schema, $rest_args['schema'] );
|
267 |
+
|
268 |
+
if ( empty( $rest_args['schema']['type'] ) ) {
|
269 |
+
// Skip over meta fields that don't have a defined type
|
270 |
+
if ( empty( $args['type'] ) ) {
|
271 |
+
continue;
|
272 |
+
}
|
273 |
+
|
274 |
+
if ( $rest_args['single'] ) {
|
275 |
+
$rest_args['schema']['type'] = $args['type'];
|
276 |
+
} else {
|
277 |
+
$rest_args['schema']['type'] = 'array';
|
278 |
+
$rest_args['schema']['items'] = array(
|
279 |
+
'type' => $args['type'],
|
280 |
+
);
|
281 |
+
}
|
282 |
+
}
|
283 |
+
|
284 |
+
$registered[ $rest_args['name'] ] = $rest_args;
|
285 |
+
}
|
286 |
+
|
287 |
+
return $registered;
|
288 |
+
}
|
289 |
+
|
290 |
+
/**
|
291 |
+
* Get the object's `meta` schema, conforming to JSON Schema.
|
292 |
+
*
|
293 |
+
* @return array
|
294 |
+
*/
|
295 |
+
public function get_field_schema() {
|
296 |
+
$fields = $this->get_registered_fields();
|
297 |
+
|
298 |
+
$schema = array(
|
299 |
+
'description' => __( 'Meta fields.' ),
|
300 |
+
'type' => 'object',
|
301 |
+
'context' => array( 'view', 'edit' ),
|
302 |
+
'properties' => array(),
|
303 |
+
);
|
304 |
+
|
305 |
+
foreach ( $fields as $key => $args ) {
|
306 |
+
$schema['properties'][ $key ] = $args['schema'];
|
307 |
+
}
|
308 |
+
|
309 |
+
return $schema;
|
310 |
+
}
|
311 |
+
|
312 |
+
/**
|
313 |
+
* Prepare a meta value for output.
|
314 |
+
*
|
315 |
+
* Default preparation for meta fields. Override by passing the
|
316 |
+
* `prepare_callback` in your `show_in_rest` options.
|
317 |
+
*
|
318 |
+
* @param mixed $value Meta value from the database.
|
319 |
+
* @param WP_REST_Request $request Request object.
|
320 |
+
* @param array $args REST-specific options for the meta key.
|
321 |
+
* @return mixed Value prepared for output.
|
322 |
+
*/
|
323 |
+
public static function prepare_value( $value, $request, $args ) {
|
324 |
+
$type = $args['schema']['type'];
|
325 |
+
|
326 |
+
// For multi-value fields, check the item type instead.
|
327 |
+
if ( 'array' === $type && ! empty( $args['schema']['items']['type'] ) ) {
|
328 |
+
$type = $args['schema']['items']['type'];
|
329 |
+
}
|
330 |
+
|
331 |
+
switch ( $type ) {
|
332 |
+
case 'string':
|
333 |
+
$value = strval( $value );
|
334 |
+
break;
|
335 |
+
case 'number':
|
336 |
+
$value = floatval( $value );
|
337 |
+
break;
|
338 |
+
case 'boolean':
|
339 |
+
$value = (bool) $value;
|
340 |
+
break;
|
341 |
+
}
|
342 |
+
|
343 |
+
// Don't allow objects to be output.
|
344 |
+
if ( is_object( $value ) && ! ( $value instanceof JsonSerializable ) ) {
|
345 |
+
return null;
|
346 |
+
}
|
347 |
+
|
348 |
+
return $value;
|
349 |
+
}
|
350 |
+
}
|
lib/fields/class-wp-rest-post-meta-fields.php
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WP_REST_Post_Meta_Fields extends WP_REST_Meta_Fields {
|
4 |
+
/**
|
5 |
+
* Post type to register fields for.
|
6 |
+
*
|
7 |
+
* @var string
|
8 |
+
*/
|
9 |
+
protected $post_type;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Constructor.
|
13 |
+
*
|
14 |
+
* @param string $post_type Post type to register fields for.
|
15 |
+
*/
|
16 |
+
public function __construct( $post_type ) {
|
17 |
+
$this->post_type = $post_type;
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Get the object type for meta.
|
22 |
+
*
|
23 |
+
* @return string
|
24 |
+
*/
|
25 |
+
protected function get_meta_type() {
|
26 |
+
return 'post';
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Get the type for `register_rest_field`.
|
31 |
+
*
|
32 |
+
* @return string Custom post type slug.
|
33 |
+
*/
|
34 |
+
public function get_rest_field_type() {
|
35 |
+
return $this->post_type;
|
36 |
+
}
|
37 |
+
}
|
lib/fields/class-wp-rest-term-meta-fields.php
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WP_REST_Term_Meta_Fields extends WP_REST_Meta_Fields {
|
4 |
+
/**
|
5 |
+
* Taxonomy to register fields for.
|
6 |
+
*
|
7 |
+
* @var string
|
8 |
+
*/
|
9 |
+
protected $taxonomy;
|
10 |
+
/**
|
11 |
+
* Constructor.
|
12 |
+
*
|
13 |
+
* @param string $taxonomy
|
14 |
+
*/
|
15 |
+
public function __construct( $taxonomy ) {
|
16 |
+
$this->taxonomy = $taxonomy;
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Get the object type for meta.
|
21 |
+
*
|
22 |
+
* @return string
|
23 |
+
*/
|
24 |
+
protected function get_meta_type() {
|
25 |
+
return 'term';
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Get the type for `register_rest_field`.
|
30 |
+
*
|
31 |
+
* @return string
|
32 |
+
*/
|
33 |
+
public function get_rest_field_type() {
|
34 |
+
return 'post_tag' === $this->taxonomy ? 'tag' : $this->taxonomy;
|
35 |
+
}
|
36 |
+
}
|
lib/fields/class-wp-rest-user-meta-fields.php
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WP_REST_User_Meta_Fields extends WP_REST_Meta_Fields {
|
4 |
+
/**
|
5 |
+
* Get the object type for meta.
|
6 |
+
*
|
7 |
+
* @return string
|
8 |
+
*/
|
9 |
+
protected function get_meta_type() {
|
10 |
+
return 'user';
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Get the type for `register_rest_field`.
|
15 |
+
*
|
16 |
+
* @return string
|
17 |
+
*/
|
18 |
+
public function get_rest_field_type() {
|
19 |
+
return 'user';
|
20 |
+
}
|
21 |
+
}
|
plugin.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
* Description: JSON-based REST API for WordPress, originally developed as part of GSoC 2013.
|
5 |
* Author: WP REST API Team
|
6 |
* Author URI: http://v2.wp-api.org
|
7 |
-
* Version: 2.0-
|
8 |
* Plugin URI: https://github.com/WP-API/WP-API
|
9 |
* License: GPL2+
|
10 |
*/
|
@@ -79,6 +79,48 @@ if ( ! class_exists( 'WP_REST_Comments_Controller' ) ) {
|
|
79 |
require_once dirname( __FILE__ ) . '/lib/endpoints/class-wp-rest-comments-controller.php';
|
80 |
}
|
81 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
/**
|
83 |
* REST extras.
|
84 |
*/
|
@@ -87,6 +129,7 @@ require_once( dirname( __FILE__ ) . '/core-integration.php' );
|
|
87 |
|
88 |
add_filter( 'init', '_add_extra_api_post_type_arguments', 11 );
|
89 |
add_action( 'init', '_add_extra_api_taxonomy_arguments', 11 );
|
|
|
90 |
add_action( 'rest_api_init', 'create_initial_rest_routes', 0 );
|
91 |
|
92 |
/**
|
@@ -145,6 +188,121 @@ function _add_extra_api_taxonomy_arguments() {
|
|
145 |
}
|
146 |
}
|
147 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
148 |
if ( ! function_exists( 'create_initial_rest_routes' ) ) {
|
149 |
/**
|
150 |
* Registers default REST API routes.
|
@@ -206,6 +364,13 @@ if ( ! function_exists( 'create_initial_rest_routes' ) ) {
|
|
206 |
// Comments.
|
207 |
$controller = new WP_REST_Comments_Controller;
|
208 |
$controller->register_routes();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
209 |
}
|
210 |
}
|
211 |
|
4 |
* Description: JSON-based REST API for WordPress, originally developed as part of GSoC 2013.
|
5 |
* Author: WP REST API Team
|
6 |
* Author URI: http://v2.wp-api.org
|
7 |
+
* Version: 2.0-beta15
|
8 |
* Plugin URI: https://github.com/WP-API/WP-API
|
9 |
* License: GPL2+
|
10 |
*/
|
79 |
require_once dirname( __FILE__ ) . '/lib/endpoints/class-wp-rest-comments-controller.php';
|
80 |
}
|
81 |
|
82 |
+
/**
|
83 |
+
* WP_REST_Settings_Controller class.
|
84 |
+
*/
|
85 |
+
if ( ! class_exists( 'WP_REST_Settings_Controller' ) ) {
|
86 |
+
require_once dirname( __FILE__ ) . '/lib/endpoints/class-wp-rest-settings-controller.php';
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* WP_REST_Meta_Fields class.
|
91 |
+
*/
|
92 |
+
if ( ! class_exists( 'WP_REST_Meta_Fields' ) ) {
|
93 |
+
require_once dirname( __FILE__ ) . '/lib/fields/class-wp-rest-meta-fields.php';
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* WP_REST_Comment_Meta_Fields class.
|
98 |
+
*/
|
99 |
+
if ( ! class_exists( 'WP_REST_Comment_Meta_Fields' ) ) {
|
100 |
+
require_once dirname( __FILE__ ) . '/lib/fields/class-wp-rest-comment-meta-fields.php';
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* WP_REST_Post_Meta_Fields class.
|
105 |
+
*/
|
106 |
+
if ( ! class_exists( 'WP_REST_Post_Meta_Fields' ) ) {
|
107 |
+
require_once dirname( __FILE__ ) . '/lib/fields/class-wp-rest-post-meta-fields.php';
|
108 |
+
}
|
109 |
+
|
110 |
+
/**
|
111 |
+
* WP_REST_Term_Meta_Fields class.
|
112 |
+
*/
|
113 |
+
if ( ! class_exists( 'WP_REST_Term_Meta_Fields' ) ) {
|
114 |
+
require_once dirname( __FILE__ ) . '/lib/fields/class-wp-rest-term-meta-fields.php';
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* WP_REST_User_Meta_Fields class.
|
119 |
+
*/
|
120 |
+
if ( ! class_exists( 'WP_REST_User_Meta_Fields' ) ) {
|
121 |
+
require_once dirname( __FILE__ ) . '/lib/fields/class-wp-rest-user-meta-fields.php';
|
122 |
+
}
|
123 |
+
|
124 |
/**
|
125 |
* REST extras.
|
126 |
*/
|
129 |
|
130 |
add_filter( 'init', '_add_extra_api_post_type_arguments', 11 );
|
131 |
add_action( 'init', '_add_extra_api_taxonomy_arguments', 11 );
|
132 |
+
add_action( 'rest_api_init', 'rest_register_settings', 0 );
|
133 |
add_action( 'rest_api_init', 'create_initial_rest_routes', 0 );
|
134 |
|
135 |
/**
|
188 |
}
|
189 |
}
|
190 |
|
191 |
+
|
192 |
+
/**
|
193 |
+
* Register the settings to be used in the REST API.
|
194 |
+
*
|
195 |
+
* This is required are WordPress Core does not internally register
|
196 |
+
* it's settings via `register_rest_setting()`. This should be removed
|
197 |
+
* once / if core starts to register settings internally.
|
198 |
+
*/
|
199 |
+
function rest_register_settings() {
|
200 |
+
global $wp_version;
|
201 |
+
if ( version_compare( $wp_version, '4.7-alpha', '<' ) ) {
|
202 |
+
return;
|
203 |
+
}
|
204 |
+
|
205 |
+
register_setting( 'general', 'blogname', array(
|
206 |
+
'show_in_rest' => array(
|
207 |
+
'name' => 'title',
|
208 |
+
),
|
209 |
+
'type' => 'string',
|
210 |
+
'description' => __( 'Site title.' ),
|
211 |
+
) );
|
212 |
+
|
213 |
+
register_setting( 'general', 'blogdescription', array(
|
214 |
+
'show_in_rest' => array(
|
215 |
+
'name' => 'description',
|
216 |
+
),
|
217 |
+
'type' => 'string',
|
218 |
+
'description' => __( 'Site description.' ),
|
219 |
+
) );
|
220 |
+
|
221 |
+
register_setting( 'general', 'siteurl', array(
|
222 |
+
'show_in_rest' => array(
|
223 |
+
'name' => 'url',
|
224 |
+
'schema' => array(
|
225 |
+
'format' => 'uri',
|
226 |
+
),
|
227 |
+
),
|
228 |
+
'type' => 'string',
|
229 |
+
'description' => __( 'Site URL' ),
|
230 |
+
) );
|
231 |
+
|
232 |
+
register_setting( 'general', 'admin_email', array(
|
233 |
+
'show_in_rest' => array(
|
234 |
+
'name' => 'email',
|
235 |
+
'schema' => array(
|
236 |
+
'format' => 'email',
|
237 |
+
),
|
238 |
+
),
|
239 |
+
'type' => 'string',
|
240 |
+
'description' => __( 'This address is used for admin purposes. If you change this we will send you an email at your new address to confirm it. The new address will not become active until confirmed.' ),
|
241 |
+
) );
|
242 |
+
|
243 |
+
register_setting( 'general', 'timezone_string', array(
|
244 |
+
'show_in_rest' => array(
|
245 |
+
'name' => 'timezone',
|
246 |
+
),
|
247 |
+
'type' => 'string',
|
248 |
+
'description' => __( 'A city in the same timezone as you.' ),
|
249 |
+
) );
|
250 |
+
|
251 |
+
register_setting( 'general', 'date_format', array(
|
252 |
+
'show_in_rest' => true,
|
253 |
+
'type' => 'string',
|
254 |
+
'description' => __( 'A date format for all date strings.' ),
|
255 |
+
) );
|
256 |
+
|
257 |
+
register_setting( 'general', 'time_format', array(
|
258 |
+
'show_in_rest' => true,
|
259 |
+
'type' => 'string',
|
260 |
+
'description' => __( 'A time format for all time strings.' ),
|
261 |
+
) );
|
262 |
+
|
263 |
+
register_setting( 'general', 'start_of_week', array(
|
264 |
+
'show_in_rest' => true,
|
265 |
+
'type' => 'number',
|
266 |
+
'description' => __( 'A day number of the week that the week should start on.' ),
|
267 |
+
) );
|
268 |
+
|
269 |
+
register_setting( 'general', 'WPLANG', array(
|
270 |
+
'show_in_rest' => array(
|
271 |
+
'name' => 'language',
|
272 |
+
),
|
273 |
+
'type' => 'string',
|
274 |
+
'description' => __( 'WordPress locale code.' ),
|
275 |
+
'default' => 'en_US',
|
276 |
+
) );
|
277 |
+
|
278 |
+
register_setting( 'writing', 'use_smilies', array(
|
279 |
+
'show_in_rest' => true,
|
280 |
+
'type' => 'boolean',
|
281 |
+
'description' => __( 'Convert emoticons like :-) and :-P to graphics on display.' ),
|
282 |
+
'default' => true,
|
283 |
+
) );
|
284 |
+
|
285 |
+
register_setting( 'writing', 'default_category', array(
|
286 |
+
'show_in_rest' => true,
|
287 |
+
'type' => 'number',
|
288 |
+
'description' => __( 'Default category.' ),
|
289 |
+
) );
|
290 |
+
|
291 |
+
register_setting( 'writing', 'default_post_format', array(
|
292 |
+
'show_in_rest' => true,
|
293 |
+
'type' => 'string',
|
294 |
+
'description' => __( 'Default post format.' ),
|
295 |
+
) );
|
296 |
+
|
297 |
+
register_setting( 'reading', 'posts_per_page', array(
|
298 |
+
'show_in_rest' => true,
|
299 |
+
'type' => 'number',
|
300 |
+
'description' => __( 'Blog pages show at most.' ),
|
301 |
+
'default' => 10,
|
302 |
+
) );
|
303 |
+
}
|
304 |
+
|
305 |
+
|
306 |
if ( ! function_exists( 'create_initial_rest_routes' ) ) {
|
307 |
/**
|
308 |
* Registers default REST API routes.
|
364 |
// Comments.
|
365 |
$controller = new WP_REST_Comments_Controller;
|
366 |
$controller->register_routes();
|
367 |
+
|
368 |
+
// Settings. 4.7+ only.
|
369 |
+
global $wp_version;
|
370 |
+
if ( version_compare( $wp_version, '4.7-alpha', '>=' ) ) {
|
371 |
+
$controller = new WP_REST_Settings_Controller;
|
372 |
+
$controller->register_routes();
|
373 |
+
}
|
374 |
}
|
375 |
}
|
376 |
|
readme.txt
CHANGED
@@ -1,9 +1,9 @@
|
|
1 |
=== WordPress REST API (Version 2) ===
|
2 |
Contributors: rmccue, rachelbaker, danielbachhuber, joehoyle
|
3 |
-
Tags: json, rest, api, rest-api
|
4 |
-
Requires at least: 4.
|
5 |
-
Tested up to: 4.
|
6 |
-
Stable tag: 2.0-
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
@@ -38,6 +38,60 @@ Once you've installed and activated the plugin, [check out the documentation](ht
|
|
38 |
|
39 |
== Changelog ==
|
40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
= 2.0 Beta 13.0 (March 29, 2016) =
|
42 |
|
43 |
* BREAKING CHANGE: Fix Content-Disposition header parsing.
|
1 |
=== WordPress REST API (Version 2) ===
|
2 |
Contributors: rmccue, rachelbaker, danielbachhuber, joehoyle
|
3 |
+
Tags: json, rest, api, rest-api
|
4 |
+
Requires at least: 4.6
|
5 |
+
Tested up to: 4.7-alpha
|
6 |
+
Stable tag: 2.0-beta15
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
38 |
|
39 |
== Changelog ==
|
40 |
|
41 |
+
= 2.0 Beta 15.0 (October 07, 2016) =
|
42 |
+
|
43 |
+
* Introduce support for Post Meta, Term Meta, User Meta, and Comment Meta in
|
44 |
+
their parent endpoints.
|
45 |
+
|
46 |
+
For your meta fields to be exposed in the REST API, you need to register
|
47 |
+
them. WordPress includes a `register_meta()` function which is not usually
|
48 |
+
required to get/set fields, but is required for API support.
|
49 |
+
|
50 |
+
To register your field, simply call register_meta and set the show_in_rest
|
51 |
+
flag to true. Note: register_meta must be called separately for each meta
|
52 |
+
key.
|
53 |
+
|
54 |
+
(props @rmccue, @danielbachhuber, @kjbenk, @duncanjbrown, [#2765][gh-2765])
|
55 |
+
|
56 |
+
* Introduce Settings endpoint.
|
57 |
+
|
58 |
+
Expose options to the REST API with the `register_setting()` function, by
|
59 |
+
passing `$args = array( 'show_in_rest' => true )`. Note: WordPress 4.7 is
|
60 |
+
required. See changeset [38635][https://core.trac.wordpress.org/changeset/38635].
|
61 |
+
|
62 |
+
(props @joehoyle, @fjarrett, @danielbachhuber, @jonathanbardo,
|
63 |
+
@greatislander, [#2739][gh-2739])
|
64 |
+
|
65 |
+
* Attachments controller, change permissions check to match core.
|
66 |
+
|
67 |
+
Check for the `upload_files` capability when creating an attachment.
|
68 |
+
|
69 |
+
(props @nullvariable, @adamsilverstein, [#2743][gh-2743])
|
70 |
+
|
71 |
+
* Add `?{taxonomy}_exclude=` query parameter
|
72 |
+
|
73 |
+
This mirrors our existing support for ?{taxonomy}= filtering in the posts
|
74 |
+
controller (which allows querying for only records with are associated with
|
75 |
+
any of the provided term IDs for the specified taxonomy) by adding an
|
76 |
+
equivalent `_exclude` variant to list IDs of terms for which associated posts
|
77 |
+
should NOT be returned.
|
78 |
+
|
79 |
+
(props @kadamwhite, [#2756][gh-2756])
|
80 |
+
|
81 |
+
* Use `get_comment_type()` when comparing updating comment status.
|
82 |
+
|
83 |
+
Comments having a empty `comment_type` within WordPress bites us again.
|
84 |
+
Fixes a bug where comments could not be updated because of bad comparison
|
85 |
+
logic.
|
86 |
+
|
87 |
+
(props @joehoyle, [#2753][gh-2753])
|
88 |
+
|
89 |
+
[gh-2765]: https://github.com/WP-API/WP-API/issues/2765
|
90 |
+
[gh-2739]: https://github.com/WP-API/WP-API/issues/2739
|
91 |
+
[gh-2743]: https://github.com/WP-API/WP-API/issues/2743
|
92 |
+
[gh-2756]: https://github.com/WP-API/WP-API/issues/2756
|
93 |
+
[gh-2753]: https://github.com/WP-API/WP-API/issues/2753
|
94 |
+
|
95 |
= 2.0 Beta 13.0 (March 29, 2016) =
|
96 |
|
97 |
* BREAKING CHANGE: Fix Content-Disposition header parsing.
|