-
Notifications
You must be signed in to change notification settings - Fork 463
fix: cleanup WPInterfaceTrait
logic
#3383
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
fix: cleanup WPInterfaceTrait
logic
#3383
Conversation
@justlevine thanks for the PR! I'll take a look this evening or tomorrow and share any thoughts I might have 🙏🏻 |
aed7e55
to
e21f262
Compare
@justlevine this looks good. I'll see if I can get a test written for this case tomorrow 🤞🏻 |
src/Type/WPInterfaceTrait.php
Outdated
* | ||
* @return array<\GraphQL\Type\Definition\InterfaceType> | ||
*/ | ||
private function get_all_interfaces( InterfaceType $interface_type, TypeRegistry $registry ): array { |
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.
Function get_all_interfaces
has a Cognitive Complexity of 14 (exceeds 5 allowed). Consider refactoring.
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.
What does this do, why do we need it, how is it different than the all the other times in this (and implementing) class that'were trying to get interfaces?
@justlevine I pushed up some tests that pass on this PR but fail on Master (see #3388). I made some tweaks to the WPInterfaceTrait as well. Might be good to confirm that my changes to help support the test cases are also practical for your real-world scenarios. |
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.
Pull Request Overview
This PR refactors the WPInterfaceTrait to improve recursive handling of inherited interfaces and field configurations. Key changes include:
- Fallback to parent interfaces when none are explicitly provided.
- Recursive resolution of inherited interfaces with improved validation.
- More robust merging of field configurations from implemented interfaces.
Comments suppressed due to low confidence (1)
src/Type/WPInterfaceTrait.php:133
- The docblock uses '@@param-out' which appears to be a typo. It should likely be corrected to '@param-out' to adhere to proper docblock conventions.
* @@param-out array<string, \GraphQL\Type\Definition\InterfaceType> $target_interfaces The array to add interfaces to (passed by reference).
// We use array_unique as a final safeguard against duplicate entries. | ||
// While we're already using interface names as array keys which generally prevents duplicates, | ||
// this provides an extra layer of protection for edge cases or future modifications. | ||
return array_unique( $implemented_interfaces ); |
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.
Since $implemented_interfaces is built as an associative array keyed by interface names, using array_unique may be redundant. Consider removing it or using array_values if a sequentially indexed array is needed.
// We use array_unique as a final safeguard against duplicate entries. | |
// While we're already using interface names as array keys which generally prevents duplicates, | |
// this provides an extra layer of protection for edge cases or future modifications. | |
return array_unique( $implemented_interfaces ); | |
// Since $implemented_interfaces is an associative array keyed by interface names, | |
// duplicates are inherently prevented. We return the values as a sequentially indexed array. | |
return array_values( $implemented_interfaces ); |
Copilot uses AI. Check for mistakes.
@jasonbahl I'm having trouble making sense of the diff from mobile, will get to the computer to review shortly. |
src/Type/WPInterfaceTrait.php
Outdated
foreach ( $fields as $field_name => $field ) { | ||
$merged_field_config = $this->inherit_field_config_from_interface( $field_name, $field, $interface_fields ); | ||
// Get all interfaces that define this field | ||
$interfaces_with_field = []; | ||
foreach ( $this->getInterfaces() as $interface ) { | ||
if ( ! $interface instanceof InterfaceType ) { | ||
$interface = $type_registry->get_type( $interface ); | ||
} | ||
|
||
if ( null === $merged_field_config ) { | ||
unset( $fields[ $field_name ] ); | ||
continue; | ||
if ( ! $interface instanceof InterfaceType ) { | ||
continue; | ||
} | ||
|
||
$interface_fields = $interface->getFields(); | ||
if ( isset( $interface_fields[ $field_name ] ) ) { | ||
$interfaces_with_field[] = $interface; | ||
} | ||
} |
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.
How is this different from what happens in ::get_fields_from_implemented_interfaces()
?
src/Type/WPInterfaceTrait.php
Outdated
// If this field is defined in any interfaces, merge their configs | ||
if ( ! empty( $interfaces_with_field ) ) { | ||
$merged_field_config = $field; | ||
foreach ( $interfaces_with_field as $interface ) { | ||
$interface_fields = $interface->getFields(); | ||
$interface_field = $interface_fields[ $field_name ]; | ||
$merged_field_config = $this->inherit_field_config_from_interface( $field_name, $merged_field_config, [ $field_name => $interface_field->config ] ); | ||
} | ||
|
||
if ( null === $merged_field_config ) { | ||
unset( $fields[ $field_name ] ); | ||
continue; | ||
} | ||
|
||
// Update the field. | ||
$fields[ $field_name ] = $merged_field_config; | ||
} |
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.
What does this level of nesting do?
src/Type/WPInterfaceTrait.php
Outdated
@@ -227,20 +252,65 @@ private function get_fields_from_implemented_interfaces( TypeRegistry $registry | |||
continue; | |||
} | |||
|
|||
$interface_config_fields = $interface_type->getFields(); | |||
// Get all interfaces in the inheritance chain | |||
$all_interfaces = $this->get_all_interfaces( $interface_type, $registry ); |
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.
but ::get_type()
gives us the constructed type with all the resolved fields (including from the interface) because of our get_fields()
this seems like weird recursion or am I missing something?
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
8920bbe
to
f81098b
Compare
(force-push was a rebase on develop to test again GF with the other regression merged) |
@jasonbahl tests are still passing with WPGraphQL for GF, so whatever changes you made seem to have no breaking effect there, but I havn't performance tested the new code. However, even after pulling I cannot make sense of the changes you made. I left feedback how I could above since my availability is limited. I'd also stress that the PR (before your last commit) was aimed at a regression in WPGraphQL v2.0x that has prevented dozens of teams that I'm aware of from upgrading their dev environments, and affects production environments for anything relying on WPGraphQL Smart Cache + varying extensions. If these change's relevant to addressing the regression - maybe they can happen in a separate PR (perhaps even after the patch release has been cut?) |
@justlevine ok, I was working on adding some test cases for what I believe were some missing cases with the merging of interfaces. The test |
Code Climate has analyzed commit 2f84d5b and detected 2 issues on this pull request. Here's the issue category breakdown:
View more on Code Climate. |
That test case sounds strangely similar to #3096 🤔👀🤞 |
What does this implement/fix? Explain your changes.
This PR refactors
WPInterfaceTrait
to improve the recursive handling of inherited interfaces.The code quality and cyclomatic complexity of the class has been improved as well.
Important
This PR is based on #3382 which should be merged first.Relevant diff: https://github.com/wp-graphql/wp-graphql/pull/3383/files/3eaa153b2399bfd4ca5732cecd9595093d145326..9d85d28915c2e71d58f7203cf6dd993cb507fc02Rebased on develop
Does this close any currently open issues?
Return value must be of type GraphQL\\Utils\\InterfaceImplementations
#3341Any other comments?