Wp-graphql-woocommerce: Enable support for product types: subscription and bundle

Created on 24 Mar 2020  ยท  27Comments  ยท  Source: wp-graphql/wp-graphql-woocommerce

Is your feature request related to a problem? Please describe.
We are using woocommerce subscription products and bundle products, and as there is a feature in wp graphql woo that allows us to filter on a products type, we would like to be able to filter on the types subscription and bundle which is not possible at the moment.

Describe the solution you'd like
Extend the ProductTypesEnum to allow bundle and subscription

question

Most helpful comment

@zamson I started writing a blog post on this. It's still a work-in-progress, but hopefully it'll help you get started on your implementation.

Post: https://jacobarriola.com/post/woocommerce-graphql-product-bundles
Gist: https://gist.github.com/jacobarriola/5d055ba102c001f0c556427a1ae78cd2

All 27 comments

Just realised this is possible with the taxonomyFilter like so: { products(where: {taxonomyFilter: {AND: {taxonomy: TYPE, terms: ["bundle", "subscription"]}} }) { nodes { id name } } }

Although, when trying to fetch the type here on the product it will give you an internal server error.

@ranaaterning This is because the Product Interface type doesn't know how to resolve Subscriptions or Bundle product types.

Before they can be used in the WooGraphQL schema.

  1. They must have types created and registered using register_graphql_object_type().
  2. Then they must be added to the enabled product types using this hook here.

    • key is the product type slug

    • value is the GraphQL object type for the product type.

Also trying to use Bundle product types.

I've created and registered the type using register_graphql_object_type() and I've added the type to the enabled product types using the hook graphql_enabled_wc_product_types.

(We are currently at version 0.2.0 and upgrading to latest version broke too many things, so trying to upgrade version by version to see what breaks and when. At 0.4.1 now, which is why graphql_enabled_wc_product_types is used instead of graphql_woocommerce_product_types.)

function add_bundle_to_product_types($enabled_product_types) {
    $enabled_product_types['bundle'] = "BundledProduct";
    return $enabled_product_types;
}
add_filter( 'graphql_enabled_wc_product_types', 'add_bundle_to_product_types' );

This gives me this error:

"Runtime Object type \"BundledProduct\" is not a possible type for \"Product\"."

Apart from the two steps listed above, does something else need to be done?

@niklaslovgren did you ever make any progress with product bundles?

@zamson Haven't had time to dive deeper yet, unfortunately. @kidunot89, maybe you can point us in the right direction?

@niklaslovgren are you implementing the Product interface?

You can learn more about interfaces here

Also note that the parent interface fields don't have to be redefined in WPGraphQL.

@kidunot89 I tried to implement this for bundles as well with some success, but am still missing something.

Here are the problems that I'm facing:

  1. The inline fragment for my new BundleProduct type does not show
  2. A test field for the new type does not show

Is/are there some steps that I'm missing? Thanks!

Here's my implementation ๐Ÿ‘‡๐Ÿฝ


// Register the BundleProduct type with wp-graphql
add_action( 'graphql_register_types', function () {
    register_graphql_object_type(
        'BundleProduct',
        [
            'description' => 'A product bundle object',
            'interfaces'  => [ 'Node', 'Product' ],
            'fields'      => array_merge(
                \WPGraphQL\WooCommerce\Type\WPInterface\Product::get_fields(),
                [
                    'test' => [
                        'type'     => 'String',
                        'resolve' => function () {
                            return 'hello';
                        },
                    ],
                ]
            ),
        ]
    );
} );

// Add the new type to wp-graphql-woocommerce
add_filter( 'graphql_woocommerce_product_types', function ( $product_types ) {
    $product_types['bundle'] = 'BundleProduct';

    return $product_types;
} );

No errors ๐Ÿ™Œ, but limited querying without an inline fragment
image

My new BundleProduct type does not show as an inline fragment ๐Ÿ‘‡๐Ÿฝ
image

My new test field doesn't show ๐Ÿค”
image

@jacobarriola Have you tried it like this? :point_down:

// Register the BundleProduct type with wp-graphql
add_action( 'graphql_register_types', function () {
    register_graphql_object_type(
        'BundleProduct',
        [
            'description' => 'A product bundle object',
            'interfaces'  => [ 'Node', 'Product' ],
            'fields'      => [
                'test' => [
                    'type'     => 'String',
                    'resolver' => function () {
                        return 'hello';
                    },
                ],
            ]
        ]
    );
} );

// Add the new type to wp-graphql-woocommerce
add_filter( 'graphql_woocommerce_product_types', function ( $product_types ) {
    $product_types['bundle'] = 'BundleProduct';

    return $product_types;
} );

@kidunot89 it's the same result.

@kidunot89 it oddly works as expected when I fire off a random register_graphql_field() and return the new BundleProduct type. Not sure why this works, but it doesn't feel like this is the correct way to set it up.

Perhaps I'm missing something?

BTW, I'm on:

wp-graphql: 0.10.0
wp-graphql-woocommerce: 0.5.1

add_action( 'graphql_register_types', function () {
    register_graphql_object_type( 'BundleProduct', [
            'description' => 'A product bundle object',
            'interfaces'  => [ 'Node', 'Product' ],
            'fields'      => array_merge(
                \WPGraphQL\WooCommerce\Type\WPInterface\Product::get_fields(),
                [
                    'test' => [
                        'type'     => 'String',
                        'resolve' => function () {
                            return 'hello';
                        },
                    ],
                ]
            )
        ]
    );

        // The BundleProduct type only works when I have this function running
    register_graphql_field(
        'Product',
        'something',
        [
            'type'=> 'BundleProduct'
        ]
    );
} );

add_filter( 'graphql_woocommerce_product_types', function ( $product_types ) {
    $product_types['bundle'] = 'BundleProduct';

    return $product_types;
} );

@kidunot89 looks like this is expected behavior for registering a new object type on wp-graphql.

I ended up doing a RootQuery for my register_graphql_field() to mimic the other product types ๐Ÿ‘

I had to review a pair-programming session that Jason did with me to debug this issue ๐Ÿ™Œ https://youtu.be/afEKFwGUiyE?t=1299

@jacobarriola Does it appear as a child type of the Product interface?

@kidunot89

It's listed as an implementation of Product when I explore the schema on graphiql. Is that what you mean by 'child type of the the Product interface'?

image

@jacobarriola Yep.
Also in case you didn't know you can use the $source object to resolve the product fields, like this $source->get_regular_price(). The Product model forwards all unknown method calls to the source WC_Product object, which in this case would be the product bundles object.

@kidunot89 Oh great. Thanks for that.

Looks like product bundles are instances of the WC_Product_Bundle object, so I'll see what's available to me out-of-the-box with WC_Product. I may have to find a way to short-circuit $source to be an instance of WC_Product_Bundle instead.

ref: https://docs.woocommerce.com/document/bundles/bundles-data-structures-storage/#section-3

@jacobarriola the hook you need is here

Just use this filter to return instance of WC_Product_Bundle to be used as the source by the Product model.

@jacobarriola Also you don't have to redefine fields defined in the Product interface in you BundleProduct type. See definition for the core product types that implement the Product interface here to get a better understanding.

@jacobarriola is it working for you? Would you mind sharing a gist of this implementation? Also looking to implement this for a project this upcoming week.

@zamson I'm close. I'll share something real soon, ok ๐Ÿ‘

@zamson I started writing a blog post on this. It's still a work-in-progress, but hopefully it'll help you get started on your implementation.

Post: https://jacobarriola.com/post/woocommerce-graphql-product-bundles
Gist: https://gist.github.com/jacobarriola/5d055ba102c001f0c556427a1ae78cd2

@jacobarriola Love the blog post.

@jacobarriola Love the blog post.

+1

super helpful with the write up @jacobarriola

I just published a WooGraphQL extension for Product Bundles if anyone is looking to support this type in their schema: https://github.com/jacobarriola/woographql-product-bundles

@zamson sorry it took so long, but let me know if it helps you ๐Ÿ‘๐Ÿฝ

@kidunot89 we can probably close this out since you published the Subscription as well ๐Ÿ™Œ๐Ÿฝ

All of this is awesome, thank you!

@jacobarriola you mention that @kidunot89 "published the Subscription" โ€“ Am I missing a link somewhere where I can snag a snippet for creating an extension for Subscriptions?

@jchekanoff https://github.com/wp-graphql/woographql-subscriptions

Note that it's kinda buggy. I've been too swarmed to get back to it. So contributions are very welcome.

Thanks to the existing work by @jacobarriola and @kidunot89, Ive started another extension for Composite Product support. It is a WIP and i would appreciate any help getting it production ready. Currently, composite products and their components are being returned. You can also drill down to their associated settings and products. I need to figure out the necessary mutations still. Bring on the PRs!

https://github.com/sorensenjg/woographql-composite-products

Awesome, feel free to reach out in Slack, and I'll try to provide whatever help I can.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

stefanos82 picture stefanos82  ยท  7Comments

huniqcast picture huniqcast  ยท  3Comments

huniqcast picture huniqcast  ยท  4Comments

dpacmittal picture dpacmittal  ยท  5Comments

kenchoong picture kenchoong  ยท  5Comments