Closed boxxroom closed 3 years ago
Attempting to find a work around or at the very least a quick fix for the above issue.
The Attempt
add_filter('graphql_Page_Wpgraphqlexample_FlexibleContent_RelationshipField_fields', function ($fields) {
if (isset($fields['productRelationship'])) {
$fields['productRelationship']['resolve'] = function ($root, $args, $context, $info) {
return array_map(function ($id) {
return new \WPGraphQL\WooCommerce\Model\Product($id);
}, $root['field_6041494b07558']);
};
}
return $fields;
}, 10, 1);
The Output
Understanding this falls all over the place, (not dynamic for a start), such as:
graphql_interface_fields
filter could be used but it would still require work.key => value
Could I possibly have your thoughts @jasonbahl @kidunot89
@boxxroom You want this filter. This example should work as a workaround.
function workaround( $type, $object, $wp_union ) {
if ( 'Product' === $type ) {
$type_name = \WPGraphQL\WooCommerce\Data\Factory::resolve_type( $type );
$type = $wp_union->type_registry->get_type( $type );
}
return $type;
}
add_filter( 'graphql_union_resolve_type', 'workaround', 10, 3 );
Thanks for the reply and the code @kidunot89
This filter graphql_union_resolve_type
is one we have looked at and also attempted to use, however, as strange as this may sound, it never seems to be invoked. I'm not sure if this is the case for you.
To double check this, we have added your code and additional logging inside the workaround
function (logging the $type
variable). This tends to break the GraphiQL IDE interface (when pressed play) but logs out the result to file. The output in the log is empty. Moving the logging inside the conditional if ( 'Product' === $type )
allows the GraphiQL IDE interface to work as expected but the log shows no output with the GraphiQL IDE error message returning Abstract type Page_Wpgraphqlexample_FlexibleContent_RelationshipField_ProductRelationship must resolve to an Object type at runtime.....
this would suggest this conditional is never satisfied.
@boxxroom There's an error in my example. This is the correction.
function workaround( $type, $object, $wp_union ) {
if ( 'Product' === $type ) {
$type_name = \WPGraphQL\WooCommerce\Data\Factory::resolve_type( $type, $object );
$type = $wp_union->type_registry->get_type( $type );
}
return $type;
}
add_filter( 'graphql_union_resolve_type', 'workaround', 10, 3 );
@kidunot89 Thanks for looking in to this.
Even with the updated code, the previous statement still applies with the conditional. The $type
variable never resolves to a string in turn never being satisfied.
Also to note, we were unable to locate the method resolve_type
within the \WPGraphQL\WooCommerce\Data\Factory
class, but did locate a resolve_node_type
method.
Attached below is the filter code with a var_dump
checking for a string with the output in the developers console.
Attached below is the filter code with a var_dump
checking what/if classes output in the developers console.
@kidunot89 We think we have found the issue and it's to do with the booking plugins.
WooCommerce Accommodation Bookings: 1.1.23 https://woocommerce.com/products/woocommerce-accommodation-bookings/
WooCommerce Bookings: 1.15.31 https://woocommerce.com/products/woocommerce-bookings/
In the admin area when editing a product and updating its Product data to Accommodation product
or Booking product
the error occurs, when using as a Simple product
it works but not with the filter code you provided with the workaround filter code we provided:
add_filter('graphql_Page_Wpgraphqlexample_FlexibleContent_RelationshipField_fields', function ($fields) {
if (isset($fields['productRelationship'])) {
$fields['productRelationship']['resolve'] = function ($root, $args, $context, $info) {
return array_map(function ($id) {
return new \WPGraphQL\WooCommerce\Model\Product($id);
}, $root['field_6041494b07558']);
};
}
return $fields;
}, 10, 1);
We have created two plugins to add BookingProduct and AccommodationBookingProduct as unions of a Product which can be downloaded here in an attempt to resolve this issue but the error Abstract type Page_Wpgraphqlexample_FlexibleContent_RelationshipField_ProductRelationship must resolve to an Object type at runtime.....
still occurs.
Thanks in advance.
@boxxroom I think I ran into something similar when working with the ProductBundle type (https://github.com/jacobarriola/woographql-product-bundles).
I had to to do 2 things to get it working:
graphql_acf_relationship_model
) to be able to filter the post model getting set at the relationship field type. I have a PR open for this; it may no longer be necessary as @jasonbahl is going to make some changes to better filter this more centrally.
-- this solves the problem of rendering standard WC types in relationship fieldsgraphql_union_resolve_type
filter to eliminate the error for your custom types (looks like Accomodation
and Booking
in your case)./**
* Set source Type to correct WooCommerce Type when dealing with the Relationship field.
*
* Not doing so causes GraphQL to try and resolve a WC Type (ie Product) to the Post
* model, which causes resolve errors.
*/
add_filter( 'graphql_acf_relationship_model', function ( $source, $value ) {
$post = get_post( $value );
// Bail if we're not dealing with a product
if ( $post->post_type !== 'product' ) {
return $source;
}
// Only allow published posts to go through. This causes GraphQL errors and breaks builds.
if ( 'publish' !== $post->post_status ) {
return;
}
if ( false === class_exists( 'WPGraphQL\WooCommerce\ACF_Schema_Filters' ) ) {
return $source;
}
$source = ACF_Schema_Filters::resolve_post_object_source( $source, $value );
return $source;
}, 10, 2 );
/**
* Set correct product type so that ACF relationship -> product bundles can resolve. Without this, a bundle added to
* an ACF relationship field will throw an error.
*/
add_filter( 'graphql_union_resolve_type', function ( $type, $object, $wp_union ) {
// Bail if not a Product type
if ( $type->name !== 'Product' ) {
return $type;
}
// Bail if as_WC_Data() is not available
if ( false === method_exists( $object, 'as_WC_Data') ) {
return $type;
}
// Bail if $object is not a bundle
if ( $object->as_WC_Data()->product_type !== 'bundle' ) {
return $type;
}
// Set the correct type
return $wp_union->type_registry->get_type( 'BundleProduct' );
}, 10, 3 );
@jacobarriola thanks very much for chiming in on this. We have this working with a tweak to the graphql_union_resolve_type
filter.
To test - We initially added the WPGraphQL ACF graphql_acf_relationship_model
filter to the production plugin.
We then set out adding the code you provided, but this still failed with the same error output Abstract type Page_Wpgraphqlexample_FlexibleContent_RelationshipField_ProductRelationship must resolve to an Object type at runtime.....
. After a bit of debugging and digging, we noted that as_WC_Data
isn't available so bails (as expected). We were also unable to find this method in the codebase to confirm it exists.
The way we got this working was to build the product from factory and check it is an instance of WC_Product_Accommodation_Booking
. Not sure what side effects this may have but initial tests suggest all is working ok.
/**
* Set correct product type so that ACF relationship -> product accommodations can resolve. Without this, an accommodation added to
* an ACF relationship field will throw an error.
*/
add_filter('graphql_union_resolve_type', function ($type, $object, $wp_union) {
// Bail if not a Product type
if ($type->name !== 'Product') {
return $type;
}
$product = $object->product_factory()->get_product();
// Bail if $product is not an instance of WC_Product_Accommodation_Booking
if (! $product instanceof WC_Product_Accommodation_Booking) {
return $type;
}
// Set the correct type
return $wp_union->type_registry->get_type('AccommodationBookingProduct');
}, 10, 3);
Even if this is only a temporary/workaround fix. It's ideal and allows the build to move on.
Thank you @kidunot89, @jacobarriola for your time and help resolving this.
@boxxroom glad you got it working!
as_WC_Data()
is a method of WC_Post
: https://github.com/wp-graphql/wp-graphql-woocommerce/blob/develop/includes/model/class-wc-post.php#L138
@jacobarriola. This is a small side note: Just checked this file in our codebase and it definitely doesn't have this as_WC_Data()
method or the as_WP_Post()
it finished with the delete()
method. Is it perhaps because it is the development branch you have linked to as opposed to a release branch. https://github.com/wp-graphql/wp-graphql-woocommerce/blob/release/v0.6.0/includes/model/class-wc-post.php#L108
We are using plugin version: 0.6.1
@boxxroom Looks like it was added in 0.7.0
release. https://github.com/wp-graphql/wp-graphql-woocommerce/blob/release/v0.7.0/includes/model/class-wc-post.php#L135
Since you're on a recent version of core wp-graphql, I'd consider an update. There are some breaking changes from your version to 0.8.x
, but a lot of good bug fixes too.
@jacobarriola updated to the latest versions, updated the code to reflect that of yours and all seems to be working perfect.
Thanks for your help on this.
Hi,
I have the same issue but I couldn't fix it with the code of the comments. When it will be fixed? Thanks!
Hi there,
Unfortunately I have the same issue even if i use the last version of WPGraphQL WooCommerce (WooGraphQL)
v0.8.1
Is there any other fix for that? Thank you !
Running into this issue as well.
I try to establish a relationship to WooCommerce Product
(from WooCommerce). If I change the relationship instead to a different post type Gallery
, it seems to work. Maybe WooCommerce assigns on its Product post type some private fields that are tripping GraphQL?
If so, how could we solve it?
Having the same issue. Was anyone able to get is resolved with the above-mentioned filter changes? I tried but couldn't get it to work.
Describe the bug Attaching a product relationship within a Flexible content ACF field on to a
Page post type
renders anAbstract type
error due to the resolve. The resolve is expected to resolve to anObject type
.To Reproduce Steps to reproduce the behavior:
ACF JSON Export File OR Create a new ACF Field Group (named WPGraphQL Example) with a Location > Rules equal to Page Add a Flexible Content (named Flexible Content) Field Type: Relationship (Layout name: Relationship Field, Field Label: Product Relationship) Filter by Post Type: Product Filter by Taxonomy: Simple (optional) Filters: All Checked Elements: Featured Image Checked Return Object: Post Object Save.
Navigate to Pages Choose a page: Home (take note of page ID) Add ACF Flexible Content Relationship Field Select 1+ products Save
Navigate to GraphiQL IDE > Add GraphQL statement (GraphQL Statement) OR
// Query Variables
{"id": 33}