feat: schema customization with post type args#2399
feat: schema customization with post type args#2399jasonbahl merged 36 commits intowp-graphql:developfrom
Conversation
| * | ||
| * @return array | ||
| */ | ||
| public static function setup_default_taxonomies( $args, $taxonomy ) { |
There was a problem hiding this comment.
Similar blocks of code found in 2 locations. Consider refactoring.
| * | ||
| * @return array | ||
| */ | ||
| public static function setup_default_post_types( $args, $post_type ) { |
There was a problem hiding this comment.
Similar blocks of code found in 2 locations. Consider refactoring.
c43ca34 to
1390d13
Compare
| @@ -419,50 +421,112 @@ public function init_admin() { | |||
| * @return void | |||
| */ | |||
| public static function show_in_graphql() { | |||
There was a problem hiding this comment.
This whole file is getting pretty large. Might be time to break the post type / taxonomy registration stuff to a separate class.
If so what should we name it? (Extensions use WPGraphQL/CoreSchemaFilters, but that doesn't really mesh with our file structure.
jasonbahl
left a comment
There was a problem hiding this comment.
did a quick scan and left some comments. will come back and look in more depth shortly
2d38d1f to
e62b7b8
Compare
|
Apologies for the status spam. commit justlevine@2d38d1f broke my git history. On the bright side, its now rebased on the latest |
|
@jasonbahl I dont see a clear path towards model/dataloader support as those are usually hard-coded and called devoid of the I'm open to suggestions, but it might make sense to polish this off with the remaining tests, and leave that part for a future PR. |
@justlevine ya, let's hold off on that. I have some ideas for sure, but we can tackle it separately. |
|
Ooops. Accidentally clicked "Close with comment" instead of "Comment" 🤦🏻♂️ |
|
@justlevine ok, so I'm running through some scenarios and finding some issues. I'll document. We'll start with this basic post_type registration: add_action( 'init', function() {
$args = [
'label' => 'Test Type',
'public' => true,
'supports' => ['comments', 'title', 'author', 'editor', 'thumbnail', 'custom-fields' ],
'show_in_graphql' => true,
'graphql_single_name' => 'TestType',
'graphql_plural_name' => 'TestTypes',
];
register_post_type( 'test_type', $args );
} );graphql_exclude_connectionBecause the post type has support for "comments" and "author", this gives us connections: I can query like so now: {
testTypes {
nodes {
title
author {
node {
name
}
}
comments {
nodes {
content
}
}
}
}
}Let's say I want to "exclude" the Author and Comments connection. According to this PR I should be able to add: If I do that, the We can see that in the screenshot below, that the I've not investigated the code, but I suspect this has something to do with one-to-one connections vs. plural connections? graphql_exclude_interfacesUsing the registration above for the If we want this type to not apply the 'graphql_exclude_interfaces' => [ 'ContentNode' ],If we do this, the (full registration here): $args = [
'label' => 'Test Type',
'public' => true,
'show_in_graphql' => true,
'graphql_single_name' => 'TestType',
'graphql_plural_name' => 'TestTypes',
'supports' => ['comments', 'title', 'author', 'editor', 'thumbnail', 'custom-fields' ],
'graphql_exclude_interfaces' => [ 'ContentNode' ],
];
register_post_type( 'test-type', $args );If I remove the |
jasonbahl
left a comment
There was a problem hiding this comment.
I discovered some issues while testing: #2399 (comment)
I haven't looked yet at the code causing these issues.
That's because the author isn't registered on the type, but on the
This should work, will investigate 🧐 |
Gah! Yes, this is a documentation thing, not a code thing. 🤦🏻♂️ Thanks for reminding me 😄 |
Not by my computer to test, but pretty sure the issue is that NodeWiithFeaturedImage includes Not sure why this inherits those interfaces when other |
Ah! Yes! 💪🏻 This seems right. And this is likely due to my identity crisis of "what is a content node?" (i.e. #2355) I think sometimes in my mind I think we need to still solve that problem. 🤔 That said, I think this could be a documentation thing, then, too. If you I excluded Now. . .the question is, do we remove |
I think I agree with your instincts.
True, we could address the extra interfaces on |
- correct typos / copy pasta in some code comments
src/Registry/Utils/TermObject.php
Outdated
| } | ||
|
|
||
| // Remove excluded connections. | ||
| foreach ( $tax_object->graphql_exclude_connections as $connection_name ) { |
There was a problem hiding this comment.
Does it make sense to support graphql_exclude_connections at a lower level?
For example, in the WPObjectType and WPInterfaceType?
For example, we could then do something like this:
apply_filters( 'graphql_wp_object_type_config', function( $config ) {
$config['graphql_exclude_connections'] = [ 'someConnectionToExclude'];
return $config;
});And this functionality could then work for all types, not just types that were added to the graph by register_post_type and register_taxonomy?
Like, I know some folks using WPGraphQL to get data from external data sources, like shopify, etc.
If they had some connections registered, and a plugin author wanted to quickly exclude them, they could use the filter above, and it would work for any type, not just Post/Term types. 🤔
There was a problem hiding this comment.
I suppose even in the situation I brought up, we could just use apply_filters( 'graphql_wp_object_type_config', ... ); and unset the connections manually as well.
Maybe not a big deal 🤔
There was a problem hiding this comment.
I think a whole slew of lower-level filters, along with some additional (de)register_graphql_* access methods would be great.
This PR though is about making it easier to for devs to handle auto registering CPTs/Terms without the use of multiple actions/filters.
We can always adjust the underlying logic used to handle the WP_Type class properties in a future PR, and I think that by handling it separately/incrementally we can make a more informed design decision about where these new filters should go, instead of implementing them now and possibly needing to adjust/deprecate them once we have a concrete list of additional use cases/considerations.
…pe and register_taxonomy - update stubs to include graphql_exclude_mutations - update TypeRegistry.php to respect graphql_exclude_mutations - add tests to ensure graphql_exclude_mutations is respected by register_post_type and register_taxonomy
… consistent with the other `NodeBy*` interfaces
…nomy stubs - ensure graphql_exclude_fields and graphql_exclude_connections are populated before iterating over them
| * @return array | ||
| * @todo make protected after \Type\ObjectType\PostObject::get_fields() is removed. | ||
| */ | ||
| public static function get_fields( WP_Post_Type $post_type_object ) { |
There was a problem hiding this comment.
Method get_fields has 60 lines of code (exceeds 40 allowed). Consider refactoring.
| * | ||
| * @return array | ||
| */ | ||
| protected static function get_connections( WP_Post_Type $post_type_object ) { |
There was a problem hiding this comment.
Method get_connections has 102 lines of code (exceeds 40 allowed). Consider refactoring.
| * | ||
| * @return array | ||
| */ | ||
| protected static function get_connections( WP_Taxonomy $tax_object ) { |
There was a problem hiding this comment.
Method get_connections has 114 lines of code (exceeds 40 allowed). Consider refactoring.
| * | ||
| * @return array | ||
| */ | ||
| protected static function get_connections( WP_Post_Type $post_type_object ) { |
There was a problem hiding this comment.
Function get_connections has a Cognitive Complexity of 28 (exceeds 5 allowed). Consider refactoring.
| @@ -0,0 +1,578 @@ | |||
| <?php | |||
There was a problem hiding this comment.
File PostObject.php has 419 lines of code (exceeds 250 allowed). Consider refactoring.
| * | ||
| * @return array | ||
| */ | ||
| protected static function get_connections( WP_Taxonomy $tax_object ) { |
There was a problem hiding this comment.
Function get_connections has a Cognitive Complexity of 19 (exceeds 5 allowed). Consider refactoring.
| * | ||
| * @return array | ||
| */ | ||
| protected static function get_fields( WP_Taxonomy $tax_object ) { |
There was a problem hiding this comment.
Function get_fields has a Cognitive Complexity of 7 (exceeds 5 allowed). Consider refactoring.
| * @return array | ||
| * @todo make protected after \Type\ObjectType\PostObject::get_fields() is removed. | ||
| */ | ||
| public static function get_fields( WP_Post_Type $post_type_object ) { |
There was a problem hiding this comment.
Function get_fields has a Cognitive Complexity of 8 (exceeds 5 allowed). Consider refactoring.
- add tests for graphql_fields / graphql_exclude_fields for post types and taxonomies
|
Code Climate has analyzed commit e8af672 and detected 43 issues on this pull request. Here's the issue category breakdown:
View more on Code Climate. |
|
UPGRADE NOTICE: This PR removes the This is considered a breaking change (see: https://github.com/wp-graphql/wp-graphql/actions/runs/3200436057/jobs/5227330295) affecting any queries that are using a The following filter can be used to add back the add_filter( 'graphql_wp_interface_type_config', function( $config ) {
if ( $config['name'] === 'NodeWithFeaturedImage' ) {
$config['interfaces'][] = 'ContentNode';
$config['interfaces'][] = 'DatabaseIdentifier';
}
return $config;
}, 10, 1 ); |



What does this implement/fix? Explain your changes.
Adds additional WPGraphQL-specific
$argstoWP_Post_TypeandWP_Taxonomyfor granular registration/modification of PostObject and TermObject GraphQL types.Builds off of #1486, with feedback from #2394.
What's changed
register_post_type_argsandregister_taxonomy_argsfilters for setting WPGraphQL default args (instead of directly on the globals ), so they can be overruled by the user.WP_Post_TypeandWP_Taxonomy:PostObjectandTermObjectregistration logic intoWPGraphQL\Registry\Utils\PostObjectandWPGraphQL\Registry\Utils\TermObject.To do:
Allow user to set custom DataLoader / Model.(punted to Add post type / taxonomy args for defining the GraphQL model #2466)Does this close any currently open issues?
#1486
Any relevant logs, error output, GraphiQL screenshots, etc?
(If it’s long, please paste to https://ghostbin.com/ and insert the link here.)
Any other comments?
Had to cherry-pick from chore: merge master branch to develop #2396 to get this to work with(Rebased onwp-graphql-testcase.develop).WPGraphQL\Type\ObjectType\PostObjectandWPGraphQL\Type\ObjectType\TermObject, since those namespaces dont make sense when a Post / Term object can be aninterface | object | uniontype.todotags need to be replaced with the correct version number.I might need help with overloading the dataloader/model. I'm not 100% percent clear where in the lifecycle these need to be replaced, and how to do this in a way that doesn't cripple the connection resolvers.(punted to Add post type / taxonomy args for defining the GraphQL model #2466)connect_to_comments,connect_to_taxonomies,supports_content_node- can be handled withgraphql_exclude_{interfaces|connections}.resolve_from_uriregister_schema_typesupports_menu_item_object_unionsupports_post_object_unionSome of these are unnecessary, whereas others seem to require more discussion / a clear use case.
Where has this been tested?
Operating System: Ubuntu 20.04 ( WSL2 + devilbox + PHP 8.0.15 )
WordPress Version: 6.0