New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: AbstractConnectionResolver:set_query_class() created #2821
base: develop
Are you sure you want to change the base?
Conversation
First off, love this! (@renatonascalves just suggested something like this so the timing is perfect! ) Couple questions (for context 😬) before I look at the actual code:
The last several attempts at isolated fixes/enhancements to the Connection Resolver all resulted in regressions around cases we don't currently have unit tests for. To try and avoid that from happening again, I've been working to improve the class holistically in #2749 from which we would then backport the individual changes in a nonbreaking manner. My recommendation for this would be the same if it's "just" an enhancement and not tackling a specific regression. |
* | ||
* @return void | ||
*/ | ||
public function set_query_class( $class ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've got concerns/questions from a "holistic" POV - nothing that follows should be considering blocking since the same issues exist with the current method of setting the query class via WPConnectionType
.
I love the fact that this pattern makes local overloading in a resolver possible, and brings Comment/User connection queries the same extensibility patten, but I'm concerned about its availability on AbstractConnectionResolver
, when only 4 (including those in this PR) out of the bundled 13 Connection resolvers actually use a $query_class
. Unlike when it was buried in WPConnectionType
, the new pattern will see more (mis-)use, so I think it's an opportunity to consider this aspect of the DX.
Similarly, I'm concerned around the lack of checks around the provided $query_class
. We dont want to enforce a WP_Query
child, but we do need to make sure that the provided class string (SWP_Query
, WC_Query
, Tribe_Query
, FWP_Query
, etc etc) is actually compatible with the Connection resolver relying on it.
The latter issue can be solved with an overloadable is_valid_query_class( string $class )
that could for example check for method_exists( $class, 'query' )
.
We could even in theory use the same is_valid_query_class()
to throw an exception if ! empy( $this->query_class )
on the Connection Resolvers that don't use it (would need to figure out backwards-compatibility), but I think we should first confirm that AbstractConnectionResolver
is really the ideal home for this instead of adding what's possibly tech debt to the majority of the included connection resolvers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually it's more like 6 or 7 out of 13, because they extend one of the 4 connection resolvers and not the AbstractConnectionResolver class directly, Some of them don't even have a get_query()
function and default to parent get_query()
function in one of the 4. I agree there should be class_exists( $this->query_class )
check somewhere and a is_valid_query_class()
function is a good idea. I'll add it immediately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because they extend one of the 4 connection resolvers and not the AbstractConnectionResolver class directly, Some of them don't even have a get_query() function and default to parent get_query() function in one of the 4.
Actual numbers aside ☝️is the crux of my concern: we're exposing a setter that semantically should apply on any connection but will be ignored by most of them - something that becomes less obvious from the code the better we are at DRYing out the implementing classes. But I don't have a good alternative 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only clean solution I can think of would be make two child classes of the AbstractConnectionResolver that all other extend. One would be something like QueryConnectionResolver
and the other would be something like ConnectionResolver
. You get the picture 🤷🏿♂️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or breaking up AbstractConnectionResolver into traits, but I think either is bad DX in this particular situation since it extenders then need to know which intermediate class / trait is right for a particular WP type, but I don't see a way to have those classes/traits to use existing WP namings. 🤷♂️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exactly, but the connection resolvers not using $query_class
are highly unlikely to be extended for usage. EnqueuedScripts
, EnqueuedStylesheet
, Plugin
, Taxonomy
, Theme
, UserRole
, and ContentType
. So honestly we should be fine.
*/ | ||
public function get_query() { | ||
return new WP_Comment_Query( $this->query_args ); | ||
// Get query class. | ||
$queryClass = ! empty( $this->query_class ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seeing this alone makes me way happier than it has any right to. 🙌🙌🙌
@@ -677,4 +679,45 @@ protected function assertValidTypes( $actual ) : void { | |||
$this->assertEquals( 'TestObject', $actual['data']['testConnection']['nodes'][0]['__typename'] ); | |||
} | |||
|
|||
public function testRegisteringConnectionsWithCustomQueryClasses() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also have tests for some common edge cases: bad class name, incompatible class, and using the wrong WP_{$type}_Query
are the ones that jump to mind.
tests/wpunit/_bootstrap.php
Outdated
@@ -0,0 +1,3 @@ | |||
<?php | |||
|
|||
require __DIR__ . '/../_support/Utils/class-wp-query-custom.php'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we do this via the autoloader instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried too, and it didn't work. It was namespaced and everything. For some reason GraphQL wouldn't see the class and would throw so I eventually devolve into that in the bootstrap file, and I just removed all my PSR dev configuration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feel free to take a crack at after I make your requested changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR diff size of 9896 lines exceeds the maximum allowed for the inline comments feature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR diff size of 9958 lines exceeds the maximum allowed for the inline comments feature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR diff size of 9956 lines exceeds the maximum allowed for the inline comments feature.
Summarized from a Slack Convo with @kidunot89 (correct me if I made a mistake):
We should probably still address the actual regression in a separate PR. With this in mind, I'm going to port this over to #2749 - even if we don't decide to wait on that PR merging this, I'm betting the effort will still unearth some code suggestions we can implement here independently. |
I've updated #2749 to implement this pattern. (If this PR goes forward independently, I highly recommend backporting at least some of the changes). |
- add autoload-dev rule - update namespace for WP_Query_Custom class
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR diff size of 9933 lines exceeds the maximum allowed for the inline comments feature.
Code Climate has analyzed commit a74dcb9 and detected 0 issues on this pull request. View more on Code Climate. |
What does this implement/fix? Explain your changes.
While it started as a fix for the
queryClass
connection registration argument which is broken atm of creation in WPGraphQL v1.14.3, this PR ultimately does not fix queryClass but instead make the query class something to be set on the resolver level instead of the registration level. There is some functionality being lost here but it was actually removed a long time ago by @jasonbahl. Then patch back in by myself, @kidunot89, but in a really hacky way. Then broken again by@justlevine. And this will be the introduction of something new but achieves the same desired effect as the
queryClass
argument.query_class
andset_query_class()
to AbstractConnectionResolver class.$query_class
.testRegisteringConnectionsWithCustomQueryClasses
to theConnectionRegistrationTest
casetests/_support/utils/class-wp-query-custom.php
for testing.Example registration call using the new functionality.
Does this close any currently open issues?
…
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?
…
Where has this been tested?
Operating System: …
WordPress Version: …