Skip to content

Commit c068671

Browse files
authored
feat: WooGraphQL settings tab added. (#726)
* feat: WooGraphQL settings tab added. * chore: WPCS compliance met * bugfix: Order Item Node ID implemented. * chore: Deprecated "AppContext::getLoader" calls replaced. * chore: WPCS compliance met. * fix: DownloadableItem "id" field implemented
1 parent 4fc9b93 commit c068671

19 files changed

+1169
-805
lines changed

composer.lock

Lines changed: 7 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

includes/admin/class-general.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
/**
3+
* Defines WooGraphQL's general settings.
4+
*
5+
* @package WPGraphQL\WooCommerce\Admin
6+
*/
7+
8+
namespace WPGraphQL\WooCommerce\Admin;
9+
10+
/**
11+
* General class
12+
*/
13+
class General extends Section {
14+
15+
/**
16+
* Returns General settings fields.
17+
*
18+
* @return array
19+
*/
20+
public static function get_fields() {
21+
return [
22+
[
23+
'name' => 'disable_ql_session_handler',
24+
'label' => __( 'Disable QL Session Handler', 'wp-graphql-woocommerce' ),
25+
'desc' => __( 'The QL Session Handler takes over management of WooCommerce Session Management on WPGraphQL request replacing the usage of HTTP Cookies with JSON Web Tokens.', 'wp-graphql-woocommerce' ),
26+
'type' => 'checkbox',
27+
'default' => 'off',
28+
],
29+
];
30+
}
31+
}

includes/admin/class-section.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
/**
3+
* The section defines the root functionality for a settings section
4+
*
5+
* @package WPGraphQL\WooCommerce\Admin
6+
*/
7+
8+
namespace WPGraphQL\WooCommerce\Admin;
9+
10+
/**
11+
* Section class
12+
*/
13+
abstract class Section {
14+
15+
/**
16+
* Returns Section settings fields.
17+
*
18+
* @return array
19+
*/
20+
abstract public static function get_fields();
21+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
/**
3+
* Defines WooGraphQL's substitutions settings.
4+
*
5+
* @package WPGraphQL\WooCommerce\Admin
6+
*/
7+
8+
namespace WPGraphQL\WooCommerce\Admin;
9+
10+
use WPGraphQL\WooCommerce\WP_GraphQL_WooCommerce as WooGraphQL;
11+
12+
/**
13+
* General class
14+
*/
15+
class Substitutions extends Section {
16+
17+
/**
18+
* Return option list of valid GraphQL types for products.
19+
*
20+
* @return array
21+
*/
22+
public static function get_dropdown_list() {
23+
$graphql_types = [];
24+
foreach ( WooGraphQL::get_enabled_product_types() as $type ) {
25+
$graphql_types[ $type ] = $type;
26+
}
27+
return $graphql_types;
28+
}
29+
30+
/**
31+
* Returns General settings fields.
32+
*
33+
* @return array
34+
*/
35+
public static function get_fields() {
36+
$type_labels = wc_get_product_types();
37+
$registered_types = array_keys( WooGraphQL::get_enabled_product_types() );
38+
$all_types = array_keys( $type_labels );
39+
40+
$unregistered_types = array_diff( $registered_types, $all_types );
41+
$fields = [];
42+
foreach ( $unregistered_types as $product_type ) {
43+
$fields[] = [
44+
'name' => "{$product_type}_substitution_type",
45+
'label' => sprintf(
46+
/* translators: product type */
47+
__( 'Substitution type for %s', 'wp-graphql-woocommerce' ),
48+
$type_labels[ $product_type ]
49+
),
50+
'desc' => sprintf(
51+
/* translators: product type */
52+
__( 'Set a replacement GraphQL type for %s because it\'s unregistered', 'wp-graphql-woocommerce' ),
53+
$type_labels[ $product_type ]
54+
),
55+
'type' => 'select',
56+
'options' => self::get_dropdown_list(),
57+
];
58+
}
59+
60+
return $fields;
61+
}
62+
}

includes/class-admin.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
/**
3+
* Initializes a WooGraphQL Pro admin settings.
4+
*
5+
* @package WPGraphQL\WooCommerce\Pro
6+
* @since 1.0.0
7+
*/
8+
9+
namespace WPGraphQL\WooCommerce;
10+
11+
use WPGraphQL\Admin\Settings\Settings;
12+
use WPGraphQL\WooCommerce\Admin\General;
13+
use WPGraphQL\WooCommerce\Admin\Substitutions;
14+
15+
/**
16+
* Class Admin
17+
*/
18+
class Admin {
19+
20+
/**
21+
* Admin constructor
22+
*/
23+
public function __construct() {
24+
add_action( 'graphql_register_settings', [ $this, 'register_settings' ] );
25+
}
26+
27+
/**
28+
* Registers the WooGraphQL Settings tab.
29+
*
30+
* @param Settings $manager Settings Manager.
31+
* @return void
32+
*/
33+
public function register_settings( Settings $manager ) {
34+
$manager->settings_api->register_section(
35+
'woographql_settings',
36+
[ 'title' => __( 'WooGraphQL', 'wp-graphql-woocommerce' ) ]
37+
);
38+
39+
$manager->settings_api->register_fields(
40+
'woographql_settings',
41+
General::get_fields(),
42+
);
43+
44+
$manager->settings_api->register_fields(
45+
'woographql_settings',
46+
Substitutions::get_fields(),
47+
);
48+
}
49+
}

includes/class-core-schema-filters.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,18 @@ public static function add_filters() {
130130
);
131131
}
132132

133+
/**
134+
* Check and returns a GraphQL type from the
135+
* "{$product_type}_substitution_type" in the WooGraphQL settings.
136+
*
137+
* @param string $product_type Product type in need of a GraphQL type.
138+
*
139+
* @return string|null
140+
*/
141+
public static function get_substitution_type( $product_type ) {
142+
return get_graphql_setting( "{$product_type}_substitution_type", null, 'woographql_settings' );
143+
}
144+
133145
/**
134146
* Registers WooCommerce post-types to be used in GraphQL schema
135147
*
@@ -152,6 +164,13 @@ public static function register_post_types( $args, $post_type ) {
152164
if ( isset( $possible_types[ $value->type ] ) ) {
153165
return $type_registry->get_type( $possible_types[ $value->type ] );
154166
}
167+
168+
// Look for substitution type.
169+
$substitution_type = self::get_substitution_type( $value->type );
170+
if ( ! empty( $substitution_type ) ) {
171+
return $type_registry->get_type( $substitution_type );
172+
}
173+
155174
throw new UserError(
156175
sprintf(
157176
/* translators: %s: Product type */

includes/class-woocommerce-filters.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public static function setup() {
2727
self::$session_header = apply_filters( 'graphql_woocommerce_cart_session_http_header', 'woocommerce-session' );
2828

2929
// Check if request is a GraphQL POST request.
30-
if ( ! defined( 'NO_QL_SESSION_HANDLER' ) ) {
30+
if ( ! self::is_session_handler_disabled() ) {
3131
add_filter( 'woocommerce_session_handler', [ __CLASS__, 'woocommerce_session_handler' ] );
3232
add_filter( 'graphql_response_headers_to_send', [ __CLASS__, 'add_session_header_to_expose_headers' ] );
3333
add_filter( 'graphql_access_control_allow_headers', [ __CLASS__, 'add_session_header_to_allow_headers' ] );
@@ -37,6 +37,15 @@ public static function setup() {
3737
add_filter( 'graphql_stripe_process_payment_args', [ __CLASS__, 'woographql_stripe_gateway_args' ], 10, 2 );
3838
}
3939

40+
/**
41+
* Returns true if the "Disable QL Session Handler" option is checked on the settings page.
42+
*
43+
* @return boolean
44+
*/
45+
public static function is_session_handler_disabled() {
46+
return 'on' === get_graphql_setting( 'disable_ql_session_handler', 'off', 'woographql_settings' );
47+
}
48+
4049
/**
4150
* WooCommerce Session Handler callback
4251
*

includes/class-wp-graphql-woocommerce.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,13 @@ private function includes() {
301301
require $include_directory_path . 'connection/class-variation-attributes.php';
302302
require $include_directory_path . 'connection/class-wc-terms.php';
303303

304+
// Include admin files.
305+
require $include_directory_path . 'admin/class-section.php';
306+
require $include_directory_path . 'admin/class-general.php';
307+
require $include_directory_path . 'admin/class-substitutions.php';
308+
304309
// Include main plugin class files.
310+
require $include_directory_path . 'class-admin.php';
305311
require $include_directory_path . 'class-core-schema-filters.php';
306312
require $include_directory_path . 'class-jwt-auth-schema-filters.php';
307313
require $include_directory_path . 'class-woocommerce-filters.php';
@@ -358,6 +364,9 @@ function () {
358364
* Sets up WooGraphQL schema.
359365
*/
360366
private function setup() {
367+
// Initialize WooGraphQL Settings.
368+
new Admin();
369+
361370
// Setup minor integrations.
362371
Functions\setup_minor_integrations();
363372

includes/data/class-factory.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public static function resolve_customer( $id, AppContext $context ) {
4949
return null;
5050
}
5151
$customer_id = absint( $id );
52-
$loader = $context->getLoader( 'wc_customer' );
52+
$loader = $context->get_loader( 'wc_customer' );
5353
$loader->buffer( [ $customer_id ] );
5454
return new Deferred(
5555
function () use ( $loader, $customer_id ) {
@@ -72,10 +72,10 @@ public static function resolve_crud_object( $id, AppContext $context ) {
7272
return null;
7373
}
7474

75-
$context->getLoader( 'wc_post' )->buffer( [ $id ] );
75+
$context->get_loader( 'wc_post' )->buffer( [ $id ] );
7676
return new Deferred(
7777
function () use ( $id, $context ) {
78-
return $context->getLoader( 'wc_post' )->load( $id );
78+
return $context->get_loader( 'wc_post' )->load( $id );
7979
}
8080
);
8181
}
@@ -114,7 +114,7 @@ public static function resolve_tax_rate( $id, AppContext $context ) {
114114
}
115115

116116
$id = absint( $id );
117-
$loader = $context->getLoader( 'tax_rate' );
117+
$loader = $context->get_loader( 'tax_rate' );
118118
$loader->buffer( [ $id ] );
119119
return new Deferred(
120120
function () use ( $loader, $id ) {
@@ -169,10 +169,10 @@ public static function resolve_cart_item( $key, AppContext $context ) {
169169
return null;
170170
}
171171

172-
$context->getLoader( 'cart_item' )->buffer( [ $key ] );
172+
$context->get_loader( 'cart_item' )->buffer( [ $key ] );
173173
return new Deferred(
174174
function () use ( $key, $context ) {
175-
return $context->getLoader( 'cart_item' )->load( $key );
175+
return $context->get_loader( 'cart_item' )->load( $key );
176176
}
177177
);
178178
}
@@ -205,7 +205,7 @@ public static function resolve_downloadable_item( $id, AppContext $context ) {
205205
return null;
206206
}
207207
$object_id = absint( $id );
208-
$loader = $context->getLoader( 'downloadable_item' );
208+
$loader = $context->get_loader( 'downloadable_item' );
209209
$loader->buffer( [ $object_id ] );
210210
return new Deferred(
211211
function () use ( $loader, $object_id ) {

includes/data/connection/class-order-item-connection-resolver.php

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,25 @@ public function get_query() {
8484
$type = 'coupon';
8585
break;
8686
default:
87-
$type = 'line_item';
87+
/**
88+
* Filter the $item_type to allow non-core item types.
89+
*
90+
* @param array $query_args The args that will be passed to the WP_Query.
91+
* @param mixed $source The source that's passed down the GraphQL queries.
92+
* @param array $args The inputArgs on the field.
93+
* @param AppContext $context The AppContext passed down the GraphQL tree.
94+
* @param ResolveInfo $info The ResolveInfo passed down the GraphQL tree.
95+
*/
96+
$type = apply_filters(
97+
'graphql_order_item_connection_item_type',
98+
'line_item',
99+
$this->source,
100+
$this->args,
101+
$this->context,
102+
$this->info
103+
);
88104
break;
89-
}
105+
}//end switch
90106

91107
$items = [];
92108
foreach ( $this->source->get_items( $type ) as $id => $item ) {

0 commit comments

Comments
 (0)