Last active
August 29, 2015 14:01
-
-
Save kadamwhite/e941506b6cf8c9cce263 to your computer and use it in GitHub Desktop.
Proposed solution for embedding custom types into taxonomies
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/lib/class-wp-json-posts.php b/lib/class-wp-json-posts.php | |
index 941c796..a06ed0f 100644 | |
--- a/lib/class-wp-json-posts.php | |
+++ b/lib/class-wp-json-posts.php | |
@@ -519,9 +519,10 @@ class WP_JSON_Posts { | |
* | |
* @param string|object $type Type name, or type object (internal use) | |
* @param boolean $_in_collection Is this in a collection? (internal use) | |
+ * @param boolean $_in_taxonomy Is this request being added to a taxonomy record? (internal use) | |
* @return array Post type data | |
*/ | |
- public function get_post_type( $type, $_in_collection = false ) { | |
+ public function get_post_type( $type, $_in_collection = false, $_in_taxonomy = false ) { | |
if ( ! is_object( $type ) ) | |
$type = get_post_type_object($type); | |
@@ -542,7 +543,7 @@ class WP_JSON_Posts { | |
), | |
); | |
- if ( $_in_collection ) | |
+ if ( $_in_collection || $_in_taxonomy ) | |
$data['meta']['links']['self'] = json_url( '/posts/types/' . $type->name ); | |
else | |
$data['meta']['links']['collection'] = json_url( '/posts/types' ); | |
@@ -554,7 +555,7 @@ class WP_JSON_Posts { | |
$data['meta']['links']['archives'] = json_url( add_query_arg( 'type', $type->name, '/posts' ) ); | |
} | |
- return apply_filters( 'json_post_type_data', $data, $type ); | |
+ return apply_filters( 'json_post_type_data', $data, $type, $_in_taxonomy ); | |
} | |
/** | |
@@ -1090,6 +1091,22 @@ class WP_JSON_Posts { | |
} | |
/** | |
+ * Embed post type data into taxonomy data | |
+ * | |
+ * @uses self::get_post_type() | |
+ * @param array $data Taxonomy data | |
+ * @param array $taxonomy Internal taxonomy data | |
+ * @return array Filtered data | |
+ */ | |
+ public function add_post_type_data( $data, $taxonomy ) { | |
+ foreach( $taxonomy->object_type as $type ) { | |
+ $data['types'][ $type ] = $this->get_post_type( $type, false, true ); | |
+ } | |
+ | |
+ return $data; | |
+ } | |
+ | |
+ /** | |
* Helper method for {@see new_post} and {@see edit_post}, containing shared logic. | |
* | |
* @since 3.4.0 | |
diff --git a/lib/class-wp-json-taxonomies.php b/lib/class-wp-json-taxonomies.php | |
index b05ca9e..cc9b0ac 100644 | |
--- a/lib/class-wp-json-taxonomies.php | |
+++ b/lib/class-wp-json-taxonomies.php | |
@@ -134,7 +134,7 @@ class WP_JSON_Taxonomies { | |
), | |
); | |
- return apply_filters( 'json_prepare_taxonomy', $data ); | |
+ return apply_filters( 'json_prepare_taxonomy', $data, $taxonomy ); | |
} | |
/** | |
@@ -142,10 +142,13 @@ class WP_JSON_Taxonomies { | |
* | |
* @param array $data Type data | |
* @param array $post Internal type data | |
+ * @param boolean $_in_taxonomy The record being filtered is a taxonomy object (internal use) | |
* @return array Filtered data | |
*/ | |
- public function add_taxonomy_data( $data, $type ) { | |
- $data['taxonomies'] = $this->get_taxonomies( $type->name ); | |
+ public function add_taxonomy_data( $data, $type, $_in_taxonomy = false ) { | |
+ if ( ! $_in_taxonomy ) { | |
+ $data['taxonomies'] = $this->get_taxonomies( $type->name ); | |
+ } | |
return $data; | |
} | |
diff --git a/plugin.php b/plugin.php | |
index 3571b04..82067b3 100644 | |
--- a/plugin.php | |
+++ b/plugin.php | |
@@ -75,6 +75,7 @@ function json_api_default_filters($server) { | |
// Posts | |
$wp_json_posts = new WP_JSON_Posts($server); | |
add_filter( 'json_endpoints', array( $wp_json_posts, 'register_routes' ), 0 ); | |
+ add_filter( 'json_prepare_taxonomy', array( $wp_json_posts, 'add_post_type_data' ), 10, 2 ); | |
// Users | |
$wp_json_users = new WP_JSON_Users($server); | |
@@ -97,7 +98,7 @@ function json_api_default_filters($server) { | |
// Posts | |
$wp_json_taxonomies = new WP_JSON_Taxonomies($server); | |
add_filter( 'json_endpoints', array( $wp_json_taxonomies, 'register_routes' ), 2 ); | |
- add_filter( 'json_post_type_data', array( $wp_json_taxonomies, 'add_taxonomy_data' ), 10, 2 ); | |
+ add_filter( 'json_post_type_data', array( $wp_json_taxonomies, 'add_taxonomy_data' ), 10, 3 ); | |
add_filter( 'json_prepare_post', array( $wp_json_taxonomies, 'add_term_data' ), 10, 3 ); | |
} | |
add_action( 'wp_json_server_before_serve', 'json_api_default_filters', 10, 1 ); | |
diff --git a/tests/test_json_taxonomies.php b/tests/test_json_taxonomies.php | |
index 4f8acd9..202d9d5 100644 | |
--- a/tests/test_json_taxonomies.php | |
+++ b/tests/test_json_taxonomies.php | |
@@ -126,4 +126,18 @@ class WP_Test_JSON_Taxonomies extends WP_UnitTestCase { | |
$this->assertEquals( $category->description, $data['description'] ); | |
$this->assertEquals( $category->count, $data['count'] ); | |
} | |
+ | |
+ public function test_add_taxonomy_data() { | |
+ // Mock type | |
+ $type = new stdClass; | |
+ $type->name = 'post'; | |
+ | |
+ // This record is not a taxonomy record: taxonomies should be embedded | |
+ $data = $this->endpoint->add_taxonomy_data( array(), $type, false ); | |
+ $this->assertArrayHasKey( 'taxonomies', $data ); | |
+ | |
+ // This record is a taxonomy record: taxonomies should NOT be embedded | |
+ $data_within_taxonomy = $this->endpoint->add_taxonomy_data( array(), $type, true ); | |
+ $this->assertArrayNotHasKey( 'taxonomies', $data_within_taxonomy ); | |
+ } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This follows what I perceived to be the model for embedding that we use to add taxonomies to types, users to posts, etcetera. Specifically,
add_post_type_data
method is added to the posts class to augment a Taxonomy data object with that taxonomy's associated post types.add_post_type_data
on thejson_prepare_taxonomy
filteradd_taxonomy_data
method (hooked to thejson_post_type_data
filter) is passed a new parameter indicating whether the post type object in question is being embedded from within a taxonomy object; this prevents circular references whereadd_post_type_data
adds post type objects which each have taxonomy objects added throughadd_taxonomy_data
which in turn again have post type objects embedded.... and so on.Passing
$_in_taxonomy
all the way through toadd_taxonomy_data
feels a little weird, but the only alternative I see is to add a separate filter and that feels even more duplicative.