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

wp-graphql / wp-graphql-woocommerce / 6152083608

11 Sep 2023 09:42PM UTC coverage: 84.557% (+1.7%) from 82.825%
6152083608

push

github

web-flow
fix: ProductUnion interface added (#797)

* fix: ProductUnion interface added

* chore: Linter and PHPStan compliance met

65 of 65 new or added lines in 9 files covered. (100.0%)

10327 of 12213 relevant lines covered (84.56%)

56.04 hits per line

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

62.14
/access-functions.php
1
<?php
2
/**
3
 * This file contains access functions for various class methods
4
 *
5
 * @package WPGraphQL\WooCommerce
6
 * @since 0.0.1
7
 */
8

9
if ( ! function_exists( 'str_starts_with' ) ) {
10
        /**
11
         * Polyfill for PHP 8 str_starts_with function.
12
         * Checks if a string starts with a given substring.
13
         *
14
         * @see https://www.php.net/manual/en/function.str-starts-with.php
15
         *
16
         * @param string $haystack - Source string.
17
         * @param string $needle - Target string.
18
         *
19
         * @return bool - True if $haystack starts with $needle, false otherwise.
20
         */
21
        function str_starts_with( $haystack, $needle ) {
22
                $length = strlen( $needle );
×
23
                return ( substr( $haystack, 0, $length ) === $needle );
×
24
        }
25
}
26

27
if ( ! function_exists( 'str_ends_with' ) ) {
28
        /**
29
         * Polyfill for PHP 8 str_ends_with function.
30
         * Checks if a string ends with a given substring.
31
         *
32
         * @see https://www.php.net/manual/en/function.str-ends-with.php
33
         *
34
         * @param string $haystack - Source string.
35
         * @param string $needle - Target string.
36
         *
37
         * @return bool - True if $haystack ends with $needle, false otherwise.
38
         */
39
        function str_ends_with( $haystack, $needle ) {
40
                $length = strlen( $needle );
×
41
                if ( 0 === $length ) {
×
42
                        return true;
×
43
                }
44

45
                return ( substr( $haystack, -$length ) === $needle );
×
46
        }
47
}//end if
48

49
if ( ! function_exists( 'wc_graphql_map_tax_statements' ) ) {
50
        /**
51
         * Returns formatted array of tax statement objects.
52
         *
53
         * @param array $raw_taxes - array of raw taxes object from WC_Order_Item crud objects.
54
         *
55
         * @return array
56
         */
57
        function wc_graphql_map_tax_statements( $raw_taxes ) {
58
                $taxes = [];
×
59
                foreach ( $raw_taxes as $field => $values ) {
×
60
                        foreach ( $values as $id => $amount ) {
×
61
                                if ( empty( $taxes[ $id ] ) ) {
×
62
                                        $taxes[ $id ] = [];
×
63
                                }
64
                                $taxes[ $id ]['ID']     = $id;
×
65
                                $taxes[ $id ][ $field ] = $amount;
×
66
                        }
67
                }
68

69
                return array_values( $taxes );
×
70
        }
71
}//end if
72

73
if ( ! function_exists( 'wc_graphql_get_order_statuses' ) ) {
74
        /**
75
         * Get order statuses without prefixes.
76
         *
77
         * @return array
78
         */
79
        function wc_graphql_get_order_statuses() {
80
                $order_statuses = [];
×
81
                foreach ( array_keys( wc_get_order_statuses() ) as $status ) {
×
82
                        $order_statuses[] = str_replace( 'wc-', '', $status );
×
83
                }
84
                return $order_statuses;
×
85
        }
86
}
87

88
if ( ! function_exists( 'wc_graphql_price' ) ) {
89
        /**
90
         * Format the price with a currency symbol.
91
         *
92
         * @param  float|string $price Raw price.
93
         * @param  array        $args  Arguments to format a price {
94
         *            Array of arguments.
95
         *            Defaults to empty array.
96
         *
97
         *     @type string $currency           Currency code.
98
         *                                      Defaults to empty string (Use the result from get_woocommerce_currency()).
99
         *     @type string $decimal_separator  Decimal separator.
100
         *                                      Defaults the result of wc_get_price_decimal_separator().
101
         *     @type string $thousand_separator Thousand separator.
102
         *                                      Defaults the result of wc_get_price_thousand_separator().
103
         *     @type string $decimals           Number of decimals.
104
         *                                      Defaults the result of wc_get_price_decimals().
105
         *     @type string $price_format       Price format depending on the currency position.
106
         *                                      Defaults the result of get_woocommerce_price_format().
107
         * }
108
         * @return string
109
         */
110
        function wc_graphql_price( $price, $args = [] ) {
111
                $price = floatval( $price );
23✔
112
                $args  = apply_filters(
23✔
113
                        'wc_price_args', // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
23✔
114
                        wp_parse_args(
23✔
115
                                $args,
23✔
116
                                [
23✔
117
                                        'currency'           => '',
23✔
118
                                        'decimal_separator'  => wc_get_price_decimal_separator(),
23✔
119
                                        'thousand_separator' => wc_get_price_thousand_separator(),
23✔
120
                                        'decimals'           => wc_get_price_decimals(),
23✔
121
                                        'price_format'       => get_woocommerce_price_format(),
23✔
122
                                ]
23✔
123
                        )
23✔
124
                );
23✔
125

126
                $unformatted_price = $price;
23✔
127
                $negative          = $price < 0;
23✔
128

129
                // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
130
                $price = apply_filters( 'raw_woocommerce_price', floatval( $negative ? $price * -1 : $price ) );
23✔
131

132
                $price = apply_filters(
23✔
133
                        // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
134
                        'formatted_woocommerce_price',
23✔
135
                        number_format(
23✔
136
                                $price,
23✔
137
                                $args['decimals'],
23✔
138
                                $args['decimal_separator'],
23✔
139
                                $args['thousand_separator']
23✔
140
                        ),
23✔
141
                        $price,
23✔
142
                        $args['decimals'],
23✔
143
                        $args['decimal_separator'],
23✔
144
                        $args['thousand_separator']
23✔
145
                );
23✔
146

147
                // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
148
                if ( apply_filters( 'woocommerce_price_trim_zeros', false ) && $args['decimals'] > 0 ) {
23✔
149
                        $price = wc_trim_zeros( $price );
×
150
                }
151

152
                // phpcs:ignore PHPCompatibility.ParameterValues.NewHTMLEntitiesEncodingDefault.NotSet
153
                $symbol = html_entity_decode( get_woocommerce_currency_symbol( $args['currency'] ) );
23✔
154
                $return = ( $negative ? '-' : '' ) . sprintf( $args['price_format'], $symbol, $price );
23✔
155

156
                /**
157
                 * Filters the string of price markup.
158
                 *
159
                 * @param string $return            Price HTML markup.
160
                 * @param string $price             Formatted price.
161
                 * @param array  $args              Pass on the args.
162
                 * @param float  $unformatted_price Price as float to allow plugins custom formatting.
163
                 * @param string $symbol            Currency symbol.
164
                 */
165
                return apply_filters( 'graphql_woocommerce_price', $return, $price, $args, $unformatted_price, $symbol );
23✔
166
        }
167
}//end if
168

169
if ( ! function_exists( 'wc_graphql_price_range' ) ) {
170
        /**
171
         * Format a price range for display.
172
         *
173
         * @param  string|float $from Price from.
174
         * @param  string|float $to   Price to.
175
         * @return string
176
         */
177
        function wc_graphql_price_range( $from, $to ) {
178
                if ( $from === $to ) {
2✔
179
                        return wc_graphql_price( $from );
×
180
                }
181

182
                $price = sprintf(
2✔
183
                        /* translators: 1: price from 2: price to */
184
                        _x( '%1$s %2$s %3$s', 'Price range: from-to', 'wp-graphql-woocommerce' ),
2✔
185
                        is_numeric( $from ) ? wc_graphql_price( $from ) : $from,
2✔
186
                        apply_filters( 'graphql_woocommerce_format_price_range_separator', '-', $from, $to ),
2✔
187
                        is_numeric( $to ) ? wc_graphql_price( $to ) : $to
2✔
188
                );
2✔
189

190
                return apply_filters( 'graphql_woocommerce_format_price_range', $price, $from, $to );
2✔
191
        }
192
}//end if
193

194
if ( ! function_exists( 'wc_graphql_underscore_to_camel_case' ) ) {
195
        /**
196
         * Converts a camel case formatted string to a underscore formatted string.
197
         *
198
         * @param string  $string      String to be formatted.
199
         * @param boolean $capitalize  Capitalize first letter of string.
200
         *
201
         * @return string
202
         */
203
        function wc_graphql_underscore_to_camel_case( $string, $capitalize = false ) {
204
                $str = str_replace( ' ', '', ucwords( str_replace( '-', ' ', $string ) ) );
×
205

206
                if ( ! $capitalize ) {
×
207
                        $str[0] = strtolower( $str[0] );
×
208
                }
209

210
                return $str;
×
211
        }
212
}
213

214
if ( ! function_exists( 'wc_graphql_camel_case_to_underscore' ) ) {
215
        /**
216
         * Converts a camel case formatted string to a underscore formatted string.
217
         *
218
         * @param string $string  String to be formatted.
219
         *
220
         * @return string
221
         */
222
        function wc_graphql_camel_case_to_underscore( $string ) {
223
                preg_match_all(
4✔
224
                        '!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!',
4✔
225
                        $string,
4✔
226
                        $matches
4✔
227
                );
4✔
228

229
                $ret = $matches[0];
4✔
230

231
                foreach ( $ret as &$match ) {
4✔
232
                        $match = strtoupper( $match ) === $match ? strtolower( $match ) : lcfirst( $match );
4✔
233
                }
234

235
                return implode( '_', $ret );
4✔
236
        }
237
}//end if
238

239
if ( ! function_exists( 'woographql_setting' ) ) :
240
        /**
241
         * Get an option value from WooGraphQL settings
242
         *
243
         * @param string $option_name  The key of the option to return.
244
         * @param mixed  $default      The default value the setting should return if no value is set.
245
         * @param string $section_name The settings section name.
246
         *
247
         * @return mixed|string|int|boolean
248
         */
249
        function woographql_setting( string $option_name, $default = '', $section_name = 'woographql_settings' ) {
250
                $section_fields = get_option( $section_name );
111✔
251

252
                /**
253
                 * Filter the section fields
254
                 *
255
                 * @param array  $section_fields The values of the fields stored for the section
256
                 * @param string $section_name   The name of the section
257
                 * @param mixed  $default        The default value for the option being retrieved
258
                 */
259
                $section_fields = apply_filters( 'woographql_settings_section_fields', $section_fields, $section_name, $default );
111✔
260

261
                /**
262
                 * Get the value from the stored data, or return the default
263
                 */
264
                if ( is_array( $default ) ) {
111✔
265
                        $value = is_array( $section_fields ) && ! empty( $section_fields[ $option_name ] ) ? $section_fields[ $option_name ] : $default;
×
266
                } else {
267
                        $value = isset( $section_fields[ $option_name ] ) ? $section_fields[ $option_name ] : $default;
111✔
268
                }
269

270
                /**
271
                 * Filter the value before returning it
272
                 *
273
                 * @param mixed  $value          The value of the field
274
                 * @param mixed  $default        The default value if there is no value set
275
                 * @param string $option_name    The name of the option
276
                 * @param array  $section_fields The setting values within the section
277
                 * @param string $section_name   The name of the section the setting belongs to
278
                 */
279
                return apply_filters( 'woographql_settings_section_field_value', $value, $default, $option_name, $section_fields, $section_name );
111✔
280
        }
281
endif;
282

283
if ( ! function_exists( 'woographql_get_session_uid' ) ) :
284
        /**
285
         * Returns end-user's customer ID.
286
         *
287
         * @return int
288
         */
289
        function woographql_get_session_uid() {
290
                /**
291
                 * Session Handler
292
                 *
293
                 * @var \WPGraphQL\WooCommerce\Utils\QL_Session_Handler|\WPGraphQL\WooCommerce\Utils\Transfer_Session_Handler $session
294
                 */
295
                $session = WC()->session;
1✔
296
                return $session->get_customer_id();
1✔
297
        }
298
endif;
299

300
if ( ! function_exists( 'woographql_get_session_token' ) ) :
301
        /**
302
         * Returns session user's "client_session_id"
303
         *
304
         * @return string
305
         */
306
        function woographql_get_session_token() {
307
                /**
308
                 * Session Handler
309
                 *
310
                 * @var \WPGraphQL\WooCommerce\Utils\QL_Session_Handler|\WPGraphQL\WooCommerce\Utils\Transfer_Session_Handler $session
311
                 */
312
                $session = WC()->session;
1✔
313
                return $session->get_client_session_id();
1✔
314
        }
315
endif;
316

317
if ( ! function_exists( 'woographql_create_nonce' ) ) :
318
        /**
319
         * Creates WooGraphQL session transfer nonces.
320
         *
321
         * @param string|int $action  Nonce name.
322
         *
323
         * @return string The nonce.
324
         */
325
        function woographql_create_nonce( $action = -1 ) {
326
                $uid   = woographql_get_session_uid();
1✔
327
                $token = woographql_get_session_token();
1✔
328
                $i     = wp_nonce_tick( $action );
1✔
329

330
                return substr( wp_hash( $i . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), -12, 10 );
1✔
331
        }
332
endif;
333

334
if ( ! function_exists( 'woographql_verify_nonce' ) ) :
335
        /**
336
         * Validate WooGraphQL session transfer nonces.
337
         *
338
         * @param string         $nonce   Nonce to validated.
339
         * @param integer|string $action  Nonce name.
340
         *
341
         * @return false|int
342
         */
343
        function woographql_verify_nonce( $nonce, $action = -1 ) {
344
                $nonce = (string) $nonce;
×
345
                $uid   = woographql_get_session_uid();
×
346

347
                if ( empty( $nonce ) ) {
×
348
                        return false;
×
349
                }
350

351
                $token = woographql_get_session_token();
×
352
                $i     = wp_nonce_tick( $action );
×
353

354
                // Nonce generated 0-12 hours ago.
355
                $expected = substr( wp_hash( $i . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), -12, 10 );
×
356
                if ( hash_equals( $expected, $nonce ) ) {
×
357
                        return 1;
×
358
                }
359

360
                // Nonce generated 12-24 hours ago.
361
                $expected = substr( wp_hash( ( $i - 1 ) . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), -12, 10 );
×
362
                if ( hash_equals( $expected, $nonce ) ) {
×
363
                        return 2;
×
364
                }
365

366
                /**
367
                 * Fires when nonce verification fails.
368
                 *
369
                 * @since 4.4.0
370
                 *
371
                 * @param string     $nonce  The invalid nonce.
372
                 * @param string|int $action The nonce action.
373
                 * @param string|int $uid    User ID.
374
                 * @param string     $token  The user's session token.
375
                 */
376
                do_action( 'graphql_verify_nonce_failed', $nonce, $action, $uid, $token );
×
377

378
                // Invalid nonce.
379
                return false;
×
380
        }
381
endif;
382

383

384

385

386

387

388

389

390

391

392

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