Skip to content

Commit b718b87

Browse files
authored
fix: Better support for private and password protected products implemented (#925)
1 parent 6b58174 commit b718b87

File tree

5 files changed

+101
-97
lines changed

5 files changed

+101
-97
lines changed

includes/class-core-schema-filters.php

+26-44
Original file line numberDiff line numberDiff line change
@@ -130,32 +130,29 @@ public static function register_post_types( $args, $post_type ) {
130130
$args['graphql_interfaces'] = [ 'ContentNode' ];
131131
$args['graphql_register_root_field'] = false;
132132
$args['graphql_register_root_connection'] = false;
133-
$args['graphql_resolve_type'] = static function ( $value ) {
134-
$type_registry = \WPGraphQL::get_type_registry();
135-
$possible_types = WooGraphQL::get_enabled_product_types();
136-
$product_type = $value->get_type();
137-
if ( isset( $possible_types[ $product_type ] ) ) {
138-
return $type_registry->get_type( $possible_types[ $product_type ] );
139-
} elseif ( 'on' === woographql_setting( 'enable_unsupported_product_type', 'off' ) ) {
140-
$unsupported_type = WooGraphQL::get_supported_product_type();
141-
return $type_registry->get_type( $unsupported_type );
142-
}
143-
144-
throw new UserError(
145-
sprintf(
146-
/* translators: %s: Product type */
147-
__( 'The "%s" product type is not supported by the core WPGraphQL for WooCommerce (WooGraphQL) schema.', 'wp-graphql-woocommerce' ),
148-
$value->type
149-
)
150-
);
151-
};
152-
}//end if
133+
$args['graphql_resolve_type'] = [ self::class, 'resolve_product_type' ];
134+
}
153135
if ( 'product_variation' === $post_type ) {
154-
$args['show_in_graphql'] = true;
155-
$args['graphql_single_name'] = 'ProductVariation';
156-
$args['graphql_plural_name'] = 'ProductVariations';
157-
$args['publicly_queryable'] = true;
158-
$args['skip_graphql_type_registry'] = true;
136+
$args['show_in_graphql'] = true;
137+
$args['model'] = \WPGraphQL\WooCommerce\Model\Product_Variation::class;
138+
$args['graphql_single_name'] = 'ProductVariation';
139+
$args['graphql_plural_name'] = 'ProductVariations';
140+
$args['publicly_queryable'] = true;
141+
$args['graphql_kind'] = 'interface';
142+
$args['graphql_interfaces'] = [
143+
'Node',
144+
'NodeWithFeaturedImage',
145+
'ContentNode',
146+
'UniformResourceIdentifiable',
147+
'ProductUnion',
148+
'ProductWithPricing',
149+
'ProductWithDimensions',
150+
'InventoriedProduct',
151+
'DownloadableProduct',
152+
];
153+
$args['graphql_register_root_field'] = false;
154+
$args['graphql_register_root_connection'] = false;
155+
$args['graphql_resolve_type'] = [ self::class, 'resolve_product_variation_type' ];
159156
}
160157
if ( 'shop_coupon' === $post_type ) {
161158
$args['show_in_graphql'] = true;
@@ -373,22 +370,7 @@ public static function inject_type_resolver( $type, $value ) {
373370
$type = self::resolve_product_variation_type( $value );
374371
break;
375372
case 'Product':
376-
$supported_types = WooGraphQL::get_enabled_product_types();
377-
if ( in_array( $value->type, array_keys( $supported_types ), true ) ) {
378-
$type_name = $supported_types[ $value->type ];
379-
$type = $type_registry->get_type( $type_name );
380-
} elseif ( 'on' === woographql_setting( 'enable_unsupported_product_type', 'off' ) ) {
381-
$type_name = WooGraphQL::get_supported_product_type();
382-
$type = $type_registry->get_type( $type_name );
383-
} else {
384-
throw new UserError(
385-
sprintf(
386-
/* translators: %s: Product type */
387-
__( 'The "%s" product type is not supported by the core WPGraphQL for WooCommerce (WooGraphQL) schema.', 'wp-graphql-woocommerce' ),
388-
$value->type
389-
)
390-
);
391-
}
373+
$type = self::resolve_product_type( $value );
392374
}//end switch
393375

394376
return $type;
@@ -397,7 +379,7 @@ public static function inject_type_resolver( $type, $value ) {
397379
/**
398380
* Resolves GraphQL type for provided product model.
399381
*
400-
* @param \WPGraphQL\WooCommerce\Model\Product $value Product model.
382+
* @param \WPGraphQL\WooCommerce\Model\Product|\WPGraphQL\WooCommerce\Model\Product_Variation $value Product model.
401383
*
402384
* @throws \GraphQL\Error\UserError Invalid product type requested.
403385
*
@@ -409,7 +391,7 @@ public static function resolve_product_type( $value ) {
409391
$product_type = $value->get_type();
410392
if ( isset( $possible_types[ $product_type ] ) ) {
411393
return $type_registry->get_type( $possible_types[ $product_type ] );
412-
} elseif ( str_ends_with( $product_type, 'variation' ) ) {
394+
} elseif ( $value instanceof \WPGraphQL\WooCommerce\Model\Product_Variation ) {
413395
return self::resolve_product_variation_type( $value );
414396
} elseif ( 'on' === woographql_setting( 'enable_unsupported_product_type', 'off' ) ) {
415397
$unsupported_type = WooGraphQL::get_supported_product_type();
@@ -428,7 +410,7 @@ public static function resolve_product_type( $value ) {
428410
/**
429411
* Resolves GraphQL type for provided product variation model.
430412
*
431-
* @param \WPGraphQL\WooCommerce\Model\Product $value Product model.
413+
* @param \WPGraphQL\WooCommerce\Model\Product_Variation $value Product model.
432414
*
433415
* @throws \GraphQL\Error\UserError Invalid product type requested.
434416
*

includes/model/class-product-variation.php

+9
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,15 @@ public function __construct( $id ) {
8383
parent::__construct( $data );
8484
}
8585

86+
/**
87+
* Returns the product variation type.
88+
*
89+
* @return string
90+
*/
91+
public function get_type() {
92+
return $this->wc_data->get_type();
93+
}
94+
8695
/**
8796
* Initializes the ProductVariation field resolvers.
8897
*/

includes/model/class-product.php

+10
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,16 @@ public function __construct( $id ) {
128128
parent::__construct( $data );
129129
}
130130

131+
/**
132+
* {@inheritDoc}
133+
*/
134+
protected static function get_allowed_restricted_fields( $allowed_restricted_fields = [] ) {
135+
return array_merge(
136+
parent::get_allowed_restricted_fields(),
137+
[ 'type' ]
138+
);
139+
}
140+
131141
/**
132142
* Returns the product type.
133143
*

includes/model/class-wc-post.php

+26
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,14 @@ protected static function get_allowed_restricted_fields( $allowed_restricted_fie
8888
'isPublic',
8989
'id',
9090
'databaseId',
91+
'slug',
92+
'uri',
93+
'link',
94+
'name',
95+
'isPostsPage',
96+
'isFrontPage',
97+
'hasPassword',
98+
'status',
9199
];
92100
}
93101

@@ -141,6 +149,20 @@ public function delete( $force_delete = false ) {
141149
return $this->wc_data->delete( $force_delete );
142150
}
143151

152+
/**
153+
* {@inheritDoc}
154+
*/
155+
public function is_private() {
156+
/**
157+
* Published content is public, not private
158+
*/
159+
if ( 'publish' === $this->data->post_status && $this->post_type_object && empty( $this->data->post_password ) && ( true === $this->post_type_object->public || true === $this->post_type_object->publicly_queryable ) ) {
160+
return false;
161+
}
162+
163+
return parent::is_post_private( $this->data );
164+
}
165+
144166
/**
145167
* Method for determining if the data should be considered private or not
146168
*
@@ -180,6 +202,10 @@ protected function is_post_private( $post_object = null ) {
180202
return true;
181203
}
182204

205+
if ( ! empty( $post_object->post_password ) ) {
206+
return true;
207+
}
208+
183209
if ( 'auto-draft' === $this->data->post_status ) {
184210
$parent = get_post( (int) $this->data->post_parent );
185211

includes/type/interface/class-product-variation.php

+30-53
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
use GraphQL\Type\Definition\ResolveInfo;
1212
use WPGraphQL\AppContext;
13-
use WPGraphQL\WooCommerce\Core_Schema_Filters as Core;
1413
use WPGraphQL\WooCommerce\Data\Connection\Product_Connection_Resolver;
1514
use WPGraphQL\WooCommerce\Data\Connection\Variation_Attribute_Connection_Resolver;
1615
use WPGraphQL\WooCommerce\Type\WPObject\Meta_Data_Type;
@@ -24,27 +23,39 @@ class Product_Variation {
2423
* Registers the "ProductVariation" interface
2524
*
2625
* @return void
27-
* @throws \Exception
2826
*/
2927
public static function register_interface(): void {
30-
register_graphql_interface_type(
31-
'ProductVariation',
28+
register_graphql_fields( 'ProductVariation', self::get_fields() );
29+
register_graphql_connection(
3230
[
33-
'description' => __( 'A product variation.', 'wp-graphql-woocommerce' ),
34-
'interfaces' => [
35-
'Node',
36-
'NodeWithFeaturedImage',
37-
'ContentNode',
38-
'UniformResourceIdentifiable',
39-
'ProductUnion',
40-
'ProductWithPricing',
41-
'ProductWithDimensions',
42-
'InventoriedProduct',
43-
'DownloadableProduct',
44-
],
45-
'fields' => self::get_fields(),
46-
'connections' => self::get_connections(),
47-
'resolveType' => [ Core::class, 'resolve_product_variation_type' ],
31+
'fromType' => 'ProductVariation',
32+
'toType' => 'VariationAttribute',
33+
'fromFieldName' => 'attributes',
34+
'resolve' => static function ( $source, array $args, AppContext $context, ResolveInfo $info ) {
35+
$resolver = new Variation_Attribute_Connection_Resolver();
36+
37+
return $resolver->resolve( $source, $args, $context, $info );
38+
},
39+
]
40+
);
41+
register_graphql_connection(
42+
[
43+
'fromType' => 'ProductVariation',
44+
'toType' => 'Product',
45+
'fromFieldName' => 'parent',
46+
'description' => __( 'The parent of the variation', 'wp-graphql-woocommerce' ),
47+
'oneToOne' => true,
48+
'queryClass' => '\WC_Product_Query',
49+
'resolve' => static function ( $source, $args, AppContext $context, ResolveInfo $info ) {
50+
if ( empty( $source->parent_id ) ) {
51+
return null;
52+
}
53+
54+
$resolver = new Product_Connection_Resolver( $source, $args, $context, $info );
55+
$resolver->set_query_arg( 'p', $source->parent_id );
56+
57+
return $resolver->one_to_one()->get_connection();
58+
},
4859
]
4960
);
5061

@@ -271,38 +282,4 @@ public static function get_fields() {
271282
'metaData' => Meta_Data_Type::get_metadata_field_definition(),
272283
];
273284
}
274-
275-
/**
276-
* Defines connections of "ProductVariation".
277-
*
278-
* @return array
279-
*/
280-
public static function get_connections() {
281-
return [
282-
'attributes' => [
283-
'toType' => 'VariationAttribute',
284-
'resolve' => static function ( $source, array $args, AppContext $context, ResolveInfo $info ) {
285-
$resolver = new Variation_Attribute_Connection_Resolver();
286-
287-
return $resolver->resolve( $source, $args, $context, $info );
288-
},
289-
],
290-
'parent' => [
291-
'toType' => 'Product',
292-
'description' => __( 'The parent of the variation', 'wp-graphql-woocommerce' ),
293-
'oneToOne' => true,
294-
'queryClass' => '\WC_Product_Query',
295-
'resolve' => static function ( $source, $args, AppContext $context, ResolveInfo $info ) {
296-
if ( empty( $source->parent_id ) ) {
297-
return null;
298-
}
299-
300-
$resolver = new Product_Connection_Resolver( $source, $args, $context, $info );
301-
$resolver->set_query_arg( 'p', $source->parent_id );
302-
303-
return $resolver->one_to_one()->get_connection();
304-
},
305-
],
306-
];
307-
}
308285
}

0 commit comments

Comments
 (0)