@automattic/newspack-blocks 4.28.0-alpha.1 → 4.28.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,20 +1,16 @@
|
|
|
1
|
-
# @automattic/newspack-blocks [4.28.0-alpha.
|
|
1
|
+
# @automattic/newspack-blocks [4.28.0-alpha.2](https://github.com/Automattic/newspack-workspace/compare/newspack-blocks@4.28.0-alpha.1...newspack-blocks@4.28.0-alpha.2) (2026-07-14)
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
### Bug Fixes
|
|
5
5
|
|
|
6
|
-
* **
|
|
6
|
+
* **blocks:** fix express checkout address validation in modal checkout ([#597](https://github.com/Automattic/newspack-workspace/issues/597)) ([09e001f](https://github.com/Automattic/newspack-workspace/commit/09e001fb8333ae9ab5f7d03c894e9bbeefe3144c))
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
### Features
|
|
10
|
-
|
|
11
|
-
* add tag labels support to Content Loop block ([#2282](https://github.com/Automattic/newspack-workspace/issues/2282)) ([b5ef988](https://github.com/Automattic/newspack-workspace/commit/b5ef988bc2007bdc509ef872ffc54e6220216786))
|
|
12
|
-
* **newsletters:** add redirect-to-URL option to subscription form ([#432](https://github.com/Automattic/newspack-workspace/issues/432)) ([5c56caa](https://github.com/Automattic/newspack-workspace/commit/5c56caa5c3e8dc93eb09548f45ffb93084ce42ee))
|
|
8
|
+
## @automattic/newspack-blocks [4.27.1](https://github.com/Automattic/newspack-workspace/compare/newspack-blocks@4.27.0...newspack-blocks@4.27.1) (2026-07-14)
|
|
13
9
|
|
|
14
10
|
|
|
15
|
-
###
|
|
11
|
+
### Bug Fixes
|
|
16
12
|
|
|
17
|
-
* **
|
|
13
|
+
* **blocks:** fix express checkout address validation in modal checkout ([#597](https://github.com/Automattic/newspack-workspace/issues/597)) ([09e001f](https://github.com/Automattic/newspack-workspace/commit/09e001fb8333ae9ab5f7d03c894e9bbeefe3144c))
|
|
18
14
|
|
|
19
15
|
# @automattic/newspack-blocks [4.27.0](https://github.com/Automattic/newspack-workspace/compare/newspack-blocks@4.26.8...newspack-blocks@4.27.0) (2026-07-08)
|
|
20
16
|
|
|
@@ -29,6 +29,17 @@ final class Modal_Checkout {
|
|
|
29
29
|
*/
|
|
30
30
|
const CHECKOUT_REGISTRATION_ORDER_META_KEY = '_newspack_checkout_registration_meta';
|
|
31
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Billing fields with server-side format validation in the Store API,
|
|
34
|
+
* mapped from their classic checkout keys to Store API address keys.
|
|
35
|
+
*
|
|
36
|
+
* @var string[]
|
|
37
|
+
*/
|
|
38
|
+
const STORE_API_VALIDATED_ADDRESS_FIELDS = [
|
|
39
|
+
'billing_state' => 'state',
|
|
40
|
+
'billing_postcode' => 'postcode',
|
|
41
|
+
];
|
|
42
|
+
|
|
32
43
|
/**
|
|
33
44
|
* Whether the modal checkout has been enqueued.
|
|
34
45
|
*
|
|
@@ -157,6 +168,8 @@ final class Modal_Checkout {
|
|
|
157
168
|
add_filter( 'woocommerce_get_checkout_order_received_url', [ __CLASS__, 'woocommerce_get_return_url' ], 10, 2 );
|
|
158
169
|
add_filter( 'wc_get_template', [ __CLASS__, 'wc_get_template' ], 10, 2 );
|
|
159
170
|
add_filter( 'woocommerce_checkout_fields', [ __CLASS__, 'woocommerce_checkout_fields' ] );
|
|
171
|
+
add_filter( 'rest_pre_dispatch', [ __CLASS__, 'scrub_store_api_checkout_address' ], 10, 3 );
|
|
172
|
+
add_filter( 'woocommerce_get_country_locale', [ __CLASS__, 'relax_configured_off_locale_fields' ] );
|
|
160
173
|
add_filter( 'woocommerce_update_order_review_fragments', [ __CLASS__, 'order_review_fragments' ] );
|
|
161
174
|
add_filter( 'woocommerce_cart_needs_payment', [ __CLASS__, 'cart_needs_payment' ] );
|
|
162
175
|
add_filter( 'newspack_recaptcha_verify_captcha', [ __CLASS__, 'recaptcha_verify_captcha' ], 10, 3 );
|
|
@@ -1332,7 +1345,13 @@ final class Modal_Checkout {
|
|
|
1332
1345
|
}
|
|
1333
1346
|
|
|
1334
1347
|
/**
|
|
1335
|
-
*
|
|
1348
|
+
* Remove the configured-off billing fields from modal checkout requests.
|
|
1349
|
+
*
|
|
1350
|
+
* Deliberately scoped to modal checkout: some publishers rely on standard
|
|
1351
|
+
* Woo checkout flows that predate Audience Management, so those keep the
|
|
1352
|
+
* stock field set. The express checkout gap this leaves (wallets submitting
|
|
1353
|
+
* values for fields the buyer cannot see) is handled for modal-originated
|
|
1354
|
+
* requests by scrub_store_api_checkout_address() below.
|
|
1336
1355
|
*
|
|
1337
1356
|
* @param array $fields Checkout fields.
|
|
1338
1357
|
*
|
|
@@ -1343,8 +1362,8 @@ final class Modal_Checkout {
|
|
|
1343
1362
|
return $fields;
|
|
1344
1363
|
}
|
|
1345
1364
|
$cart = \WC()->cart;
|
|
1346
|
-
// Don't modify fields if shipping is required.
|
|
1347
|
-
if ( $cart->needs_shipping_address() ) {
|
|
1365
|
+
// Don't modify fields if there is no cart or shipping is required.
|
|
1366
|
+
if ( ! $cart || $cart->needs_shipping_address() ) {
|
|
1348
1367
|
return $fields;
|
|
1349
1368
|
}
|
|
1350
1369
|
/**
|
|
@@ -1375,6 +1394,199 @@ final class Modal_Checkout {
|
|
|
1375
1394
|
return $fields;
|
|
1376
1395
|
}
|
|
1377
1396
|
|
|
1397
|
+
/**
|
|
1398
|
+
* Scrub invalid address values from Store API checkout requests when the
|
|
1399
|
+
* corresponding billing fields are configured off.
|
|
1400
|
+
*
|
|
1401
|
+
* Express checkout wallets submit to wc/store/v1/checkout and can supply
|
|
1402
|
+
* values the buyer never sees or corrects (e.g. Apple Pay sending a suburb
|
|
1403
|
+
* as the state), which hard-fails Store API address validation. Values the
|
|
1404
|
+
* validation would accept are left untouched, and only the billing address
|
|
1405
|
+
* is scrubbed. Runs on rest_pre_dispatch because the validation happens
|
|
1406
|
+
* during dispatch.
|
|
1407
|
+
*
|
|
1408
|
+
* The shipping address is intentionally out of scope. Carts that need a
|
|
1409
|
+
* shipping address bail below, and wallets return only billing contact when
|
|
1410
|
+
* shipping is not requested, so a virtual-cart request carries no shipping
|
|
1411
|
+
* address to scrub.
|
|
1412
|
+
*
|
|
1413
|
+
* Scoped to requests originating from the modal checkout, so any Store API
|
|
1414
|
+
* checkout outside the modal (e.g. the blocks checkout page or express
|
|
1415
|
+
* buttons on product pages) keeps stock behavior.
|
|
1416
|
+
*
|
|
1417
|
+
* @param mixed $result Response to replace the requested version with.
|
|
1418
|
+
* @param \WP_REST_Server $server Server instance.
|
|
1419
|
+
* @param \WP_REST_Request $request Request used to generate the response.
|
|
1420
|
+
*
|
|
1421
|
+
* @return mixed
|
|
1422
|
+
*/
|
|
1423
|
+
public static function scrub_store_api_checkout_address( $result, $server, $request ) {
|
|
1424
|
+
if ( null !== $result ) {
|
|
1425
|
+
return $result;
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
if (
|
|
1429
|
+
! $request instanceof \WP_REST_Request ||
|
|
1430
|
+
'POST' !== $request->get_method() ||
|
|
1431
|
+
0 !== strpos( $request->get_route(), '/wc/store/v1/checkout' )
|
|
1432
|
+
) {
|
|
1433
|
+
return $result;
|
|
1434
|
+
}
|
|
1435
|
+
|
|
1436
|
+
if ( ! self::is_modal_checkout_referer() ) {
|
|
1437
|
+
return $result;
|
|
1438
|
+
}
|
|
1439
|
+
|
|
1440
|
+
if ( ! function_exists( 'WC' ) || ! class_exists( 'WC_Validation' ) ) {
|
|
1441
|
+
return $result;
|
|
1442
|
+
}
|
|
1443
|
+
|
|
1444
|
+
$billing_fields = apply_filters( 'newspack_blocks_donate_billing_fields_keys', [] );
|
|
1445
|
+
|
|
1446
|
+
if ( empty( $billing_fields ) ) {
|
|
1447
|
+
return $result;
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1450
|
+
// Physical-goods flows are never modified. The cart is not always
|
|
1451
|
+
// initialized this early in Store API requests; when it is, bail for
|
|
1452
|
+
// carts that need a shipping address. Only the billing address is
|
|
1453
|
+
// scrubbed, so shipping data is never touched either way.
|
|
1454
|
+
if ( \WC()->cart && \WC()->cart->needs_shipping_address() ) {
|
|
1455
|
+
return $result;
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
$address = $request->get_param( 'billing_address' );
|
|
1459
|
+
|
|
1460
|
+
if ( is_array( $address ) ) {
|
|
1461
|
+
$scrubbed = self::scrub_invalid_address_values( $address, $billing_fields );
|
|
1462
|
+
|
|
1463
|
+
if ( $scrubbed !== $address ) {
|
|
1464
|
+
$request->set_param( 'billing_address', $scrubbed );
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
return $result;
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
/**
|
|
1472
|
+
* Whether the current request originates from the modal checkout, based on
|
|
1473
|
+
* the referer.
|
|
1474
|
+
*
|
|
1475
|
+
* Express checkout submissions go to the Store API as JSON, so the usual
|
|
1476
|
+
* modal_checkout request params are absent. The requests are made from the
|
|
1477
|
+
* modal checkout iframe, whose URL carries modal_checkout=1, so it shows up
|
|
1478
|
+
* as the (same-origin) referer.
|
|
1479
|
+
*
|
|
1480
|
+
* @return bool
|
|
1481
|
+
*/
|
|
1482
|
+
private static function is_modal_checkout_referer() {
|
|
1483
|
+
$referer = isset( $_SERVER['HTTP_REFERER'] ) ? esc_url_raw( wp_unslash( $_SERVER['HTTP_REFERER'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
|
1484
|
+
|
|
1485
|
+
if ( ! $referer ) {
|
|
1486
|
+
return false;
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
$query_string = \wp_parse_url( $referer, PHP_URL_QUERY );
|
|
1490
|
+
\wp_parse_str( (string) $query_string, $query_params );
|
|
1491
|
+
|
|
1492
|
+
return ! empty( $query_params['modal_checkout'] );
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1495
|
+
/**
|
|
1496
|
+
* Drop configured-off address values that would fail Store API validation.
|
|
1497
|
+
*
|
|
1498
|
+
* @param array $address Store API address (billing or shipping).
|
|
1499
|
+
* @param string[] $billing_fields Configured billing field keys.
|
|
1500
|
+
*
|
|
1501
|
+
* @return array Scrubbed address.
|
|
1502
|
+
*/
|
|
1503
|
+
private static function scrub_invalid_address_values( $address, $billing_fields ) {
|
|
1504
|
+
$country = isset( $address['country'] ) ? $address['country'] : '';
|
|
1505
|
+
|
|
1506
|
+
if (
|
|
1507
|
+
! in_array( 'billing_state', $billing_fields, true ) &&
|
|
1508
|
+
! empty( $address['state'] ) &&
|
|
1509
|
+
is_string( $address['state'] ) &&
|
|
1510
|
+
$country
|
|
1511
|
+
) {
|
|
1512
|
+
$states = \WC()->countries->get_states( $country );
|
|
1513
|
+
|
|
1514
|
+
if ( is_array( $states ) && ! empty( $states ) ) {
|
|
1515
|
+
$code_match = array_key_exists( strtoupper( $address['state'] ), array_change_key_case( $states, CASE_UPPER ) );
|
|
1516
|
+
$name_match = in_array( strtolower( $address['state'] ), array_map( 'strtolower', $states ), true );
|
|
1517
|
+
|
|
1518
|
+
if ( ! $code_match && ! $name_match ) {
|
|
1519
|
+
$address['state'] = '';
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
if (
|
|
1525
|
+
! in_array( 'billing_postcode', $billing_fields, true ) &&
|
|
1526
|
+
! empty( $address['postcode'] ) &&
|
|
1527
|
+
is_string( $address['postcode'] ) &&
|
|
1528
|
+
! \WC_Validation::is_postcode( $address['postcode'], $country )
|
|
1529
|
+
) {
|
|
1530
|
+
$address['postcode'] = '';
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
return $address;
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
/**
|
|
1537
|
+
* Relax locale-required flags for configured-off billing fields.
|
|
1538
|
+
*
|
|
1539
|
+
* After an invalid wallet value is scrubbed (see
|
|
1540
|
+
* scrub_store_api_checkout_address), the Store API order validation would
|
|
1541
|
+
* still reject the checkout when the country locale marks the field as
|
|
1542
|
+
* required. A field the site is configured not to collect cannot be
|
|
1543
|
+
* required.
|
|
1544
|
+
*
|
|
1545
|
+
* Scoped to modal-originated requests so standard Woo flows keep the stock
|
|
1546
|
+
* locale rules.
|
|
1547
|
+
*
|
|
1548
|
+
* @param array $locale Country locale field settings.
|
|
1549
|
+
*
|
|
1550
|
+
* @return array
|
|
1551
|
+
*/
|
|
1552
|
+
public static function relax_configured_off_locale_fields( $locale ) {
|
|
1553
|
+
if ( ! self::is_modal_checkout_referer() && ! self::is_modal_checkout() ) {
|
|
1554
|
+
return $locale;
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
$billing_fields = apply_filters( 'newspack_blocks_donate_billing_fields_keys', [] );
|
|
1558
|
+
|
|
1559
|
+
if ( empty( $billing_fields ) ) {
|
|
1560
|
+
return $locale;
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
// Never relax requirements when the cart needs a shipping address:
|
|
1564
|
+
// physical-goods flows keep the full locale rules.
|
|
1565
|
+
if ( function_exists( 'WC' ) && \WC()->cart && \WC()->cart->needs_shipping_address() ) {
|
|
1566
|
+
return $locale;
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1569
|
+
$off = [];
|
|
1570
|
+
|
|
1571
|
+
foreach ( self::STORE_API_VALIDATED_ADDRESS_FIELDS as $config_key => $address_key ) {
|
|
1572
|
+
if ( ! in_array( $config_key, $billing_fields, true ) ) {
|
|
1573
|
+
$off[] = $address_key;
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
|
|
1577
|
+
if ( empty( $off ) ) {
|
|
1578
|
+
return $locale;
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1581
|
+
foreach ( array_keys( $locale ) as $country ) {
|
|
1582
|
+
foreach ( $off as $address_key ) {
|
|
1583
|
+
$locale[ $country ][ $address_key ]['required'] = false;
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
|
|
1587
|
+
return $locale;
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1378
1590
|
/**
|
|
1379
1591
|
* If WooCommerce Subscriptions Gifting extension is available, render its fields.
|
|
1380
1592
|
*
|
package/newspack-blocks.php
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Author URI: https://newspack.com/
|
|
8
8
|
* Text Domain: newspack-blocks
|
|
9
9
|
* Domain Path: /languages
|
|
10
|
-
* Version: 4.28.0-alpha.
|
|
10
|
+
* Version: 4.28.0-alpha.2
|
|
11
11
|
*
|
|
12
12
|
* @package Newspack_Blocks
|
|
13
13
|
*/
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
define( 'NEWSPACK_BLOCKS__PLUGIN_FILE', __FILE__ );
|
|
16
16
|
define( 'NEWSPACK_BLOCKS__BLOCKS_DIRECTORY', 'dist/' );
|
|
17
17
|
define( 'NEWSPACK_BLOCKS__PLUGIN_DIR', plugin_dir_path( NEWSPACK_BLOCKS__PLUGIN_FILE ) );
|
|
18
|
-
define( 'NEWSPACK_BLOCKS__VERSION', '4.28.0-alpha.
|
|
18
|
+
define( 'NEWSPACK_BLOCKS__VERSION', '4.28.0-alpha.2' );
|
|
19
19
|
|
|
20
20
|
require_once NEWSPACK_BLOCKS__PLUGIN_DIR . 'includes/class-newspack-blocks.php';
|
|
21
21
|
require_once NEWSPACK_BLOCKS__PLUGIN_DIR . 'includes/class-newspack-blocks-api.php';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automattic/newspack-blocks",
|
|
3
|
-
"version": "4.28.0-alpha.
|
|
3
|
+
"version": "4.28.0-alpha.2",
|
|
4
4
|
"author": "Automattic",
|
|
5
5
|
"description": "=== Newspack Blocks === Contributors: (this should be a list of wordpress.org userid's) Donate link: https://example.com/ Tags: comments, spam Requires at least: 4.5 Tested up to: 5.1.1 Stable tag: 0.1.0 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html",
|
|
6
6
|
"repository": {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
'name' => 'automattic/newspack-blocks',
|
|
4
4
|
'pretty_version' => 'dev-main',
|
|
5
5
|
'version' => 'dev-main',
|
|
6
|
-
'reference' => '
|
|
6
|
+
'reference' => '2f93be95742dd767b39b811608d05fab0d2955fb',
|
|
7
7
|
'type' => 'wordpress-plugin',
|
|
8
8
|
'install_path' => __DIR__ . '/../../',
|
|
9
9
|
'aliases' => array(),
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
'automattic/newspack-blocks' => array(
|
|
14
14
|
'pretty_version' => 'dev-main',
|
|
15
15
|
'version' => 'dev-main',
|
|
16
|
-
'reference' => '
|
|
16
|
+
'reference' => '2f93be95742dd767b39b811608d05fab0d2955fb',
|
|
17
17
|
'type' => 'wordpress-plugin',
|
|
18
18
|
'install_path' => __DIR__ . '/../../',
|
|
19
19
|
'aliases' => array(),
|