• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

wp-graphql / wp-graphql-woocommerce / 23666268821

27 Mar 2026 08:32PM UTC coverage: 89.424% (+0.3%) from 89.165%
23666268821

push

github

web-flow
feat: WC Settings API, compatibility refactor, HPOS fix (#1002)

* feat: WC Settings API, compatibility refactor, HPOS fix, CI improvements

WC Settings GraphQL API:
- Add WCSetting interface with common fields and type-safe resolveType
- Add concrete types: WCStringSetting, WCArraySetting, WCRelativeDateSetting,
  WCImageWidthSetting with typed value/default fields
- Add WCSettingGroup type with nested settings field
- Add wcSettingGroups and wcSettings root query fields (admin only)
- Add updateWCSetting and updateWCSettings mutations
- Dynamic WCSettingTypeEnum collected from registered WC settings
- Filters: graphql_woocommerce_setting_type_map, graphql_woocommerce_setting_types
- Register WC admin settings for GraphQL requests via Compatibility class

Compatibility refactor:
- Consolidate ACF, JWT Auth, and QL Search filters into Compatibility class
- Remove class-acf-schema-filters.php, class-jwt-auth-schema-filters.php, functions.php

HPOS compatibility fix:
- Replace hardcoded directory name check with dirname(__DIR__) === WP_PLUGIN_DIR
- Works with any plugin folder name while still skipping nested vendor installs

CI improvements:
- Remove STRIPE_API_PUBLISHABLE_KEY restriction from coverage job
- Add HPOS to coverage matrix entries
- Sort type registry and includes alphabetically

Other fixes:
- Fix Settings_Mutation::validate_setting_checkbox_field to be static
- Update ShippingZone settings field type to WCStringSetting

Closes #864, closes #969

* refactor: Rename and split core classes, add order cursor pagination tests

Class renames:
- WooCommerce_Filters → WooCommerce (class-woocommerce.php), setup() → init()
- Core_Schema_Filters → Post_Types (class-post-types.php)

Class split:
- Extract taxonomy registration from Core_Schema_Filters into Taxonomies (class-taxonomies.php)

Access functions:
- Add wc_graphql_resolve_product_type() for interface resolveType callbacks
- Add wc_graphql_is_session_handler_disabled()
- Add wc_graphql_ena... (continued)

575 of 643 new or added lines in 21 files covered. (89.42%)

15812 of 17682 relevant lines covered (89.42%)

142.36 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.63
/includes/mutation/class-setting-update.php
1
<?php
2
/**
3
 * Mutation - updateWCSetting
4
 *
5
 * Registers mutation for updating a single WooCommerce setting.
6
 *
7
 * @package WPGraphQL\WooCommerce\Mutation
8
 * @since   TBD
9
 */
10

11
namespace WPGraphQL\WooCommerce\Mutation;
12

13
use GraphQL\Error\UserError;
14
use WPGraphQL\WooCommerce\Data\Mutation\Settings_Mutation;
15

16
/**
17
 * Class Setting_Update
18
 */
19
class Setting_Update {
20
        /**
21
         * Registers mutation
22
         *
23
         * @return void
24
         */
25
        public static function register_mutation() {
26
                register_graphql_mutation(
280✔
27
                        'updateWCSetting',
280✔
28
                        [
280✔
29
                                'inputFields'         => self::get_input_fields(),
280✔
30
                                'outputFields'        => self::get_output_fields(),
280✔
31
                                'mutateAndGetPayload' => self::mutate_and_get_payload(),
280✔
32
                        ]
280✔
33
                );
280✔
34
        }
35

36
        /**
37
         * Defines the mutation input field configuration
38
         *
39
         * @return array
40
         */
41
        public static function get_input_fields() {
42
                return [
280✔
43
                        'group' => [
280✔
44
                                'type'        => [ 'non_null' => 'String' ],
280✔
45
                                'description' => __( 'Settings group ID.', 'wp-graphql-woocommerce' ),
280✔
46
                        ],
280✔
47
                        'id'    => [
280✔
48
                                'type'        => [ 'non_null' => 'String' ],
280✔
49
                                'description' => __( 'Setting ID.', 'wp-graphql-woocommerce' ),
280✔
50
                        ],
280✔
51
                        'value' => [
280✔
52
                                'type'        => [ 'non_null' => 'String' ],
280✔
53
                                'description' => __( 'Setting value.', 'wp-graphql-woocommerce' ),
280✔
54
                        ],
280✔
55
                ];
280✔
56
        }
57

58
        /**
59
         * Defines the mutation output field configuration
60
         *
61
         * @return array
62
         */
63
        public static function get_output_fields() {
64
                return [
280✔
65
                        'setting' => [
280✔
66
                                'type'        => 'WCSetting',
280✔
67
                                'description' => __( 'The updated setting.', 'wp-graphql-woocommerce' ),
280✔
68
                                'resolve'     => static function ( $payload ) {
280✔
69
                                        return $payload['setting'];
5✔
70
                                },
280✔
71
                        ],
280✔
72
                ];
280✔
73
        }
74

75
        /**
76
         * Defines the mutation data modification closure.
77
         *
78
         * @return callable
79
         */
80
        public static function mutate_and_get_payload() {
81
                return static function ( $input ) {
280✔
82
                        if ( ! \wc_rest_check_manager_permissions( 'settings', 'edit' ) ) {
7✔
83
                                throw new UserError( __( 'Sorry, you cannot update settings.', 'wp-graphql-woocommerce' ) );
1✔
84
                        }
85

86
                        $group_id   = $input['group'];
6✔
87
                        $setting_id = $input['id'];
6✔
88
                        $value      = $input['value'];
6✔
89

90
                        $controller = new \WC_REST_Setting_Options_Controller();
6✔
91

92
                        /** @var array|\WP_Error $setting */
93
                        $setting = $controller->get_setting( $group_id, $setting_id );
6✔
94

95
                        if ( is_wp_error( $setting ) ) {
6✔
96
                                throw new UserError( $setting->get_error_message() );
1✔
97
                        }
98

99
                        $validated = self::validate_value( $value, $setting );
5✔
100
                        self::save_setting( $setting, $validated );
5✔
101

102
                        /** @var array|\WP_Error $updated */
103
                        $updated = $controller->get_setting( $group_id, $setting_id );
5✔
104
                        if ( is_wp_error( $updated ) ) {
5✔
NEW
105
                                throw new UserError( $updated->get_error_message() );
×
106
                        }
107

108
                        return [ 'setting' => $updated ];
5✔
109
                };
280✔
110
        }
111

112
        /**
113
         * Validate a setting value based on its type.
114
         *
115
         * @param mixed $value   Value to validate.
116
         * @param array $setting Setting definition.
117
         *
118
         * @throws \GraphQL\Error\UserError If validation fails.
119
         *
120
         * @return mixed
121
         */
122
        public static function validate_value( $value, $setting ) {
123
                $type   = $setting['type'];
6✔
124
                $method = 'validate_setting_' . $type . '_field';
6✔
125

126
                if ( method_exists( Settings_Mutation::class, $method ) ) {
6✔
127
                        return Settings_Mutation::$method( $value, $setting );
5✔
128
                }
129

130
                return Settings_Mutation::validate_setting_text_field( $value, $setting );
1✔
131
        }
132

133
        /**
134
         * Save a validated setting value.
135
         *
136
         * @param array $setting Setting definition.
137
         * @param mixed $value   Validated value.
138
         *
139
         * @return void
140
         */
141
        public static function save_setting( $setting, $value ) {
142
                $option_key = $setting['option_key'];
6✔
143

144
                if ( is_array( $option_key ) ) {
6✔
NEW
145
                        $option = get_option( $option_key[0], [] );
×
NEW
146
                        if ( ! is_array( $option ) ) {
×
NEW
147
                                $option = [];
×
148
                        }
NEW
149
                        $option[ $option_key[1] ] = $value;
×
NEW
150
                        update_option( $option_key[0], $option );
×
151
                } else {
152
                        \WC_Admin_Settings::save_fields(
6✔
153
                                [ $setting ],
6✔
154
                                [ $setting['id'] => $value ]
6✔
155
                        );
6✔
156
                }
157
        }
158
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc