@automattic/newspack-blocks 1.67.0 → 1.68.0

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.
Files changed (103) hide show
  1. package/.cache/babel/078314f1ffd302d32bbe1124c797c4a8.json.gz +0 -0
  2. package/.cache/babel/08bd669298cd26a7d3a62aadcf637516.json.gz +0 -0
  3. package/.cache/babel/0988afa42fd3fe14da7ae43c9d02661e.json.gz +0 -0
  4. package/.cache/babel/0d164bb53cdb3442a8c8ab37dde2e4ce.json.gz +0 -0
  5. package/.cache/babel/0f96392a3b96da0b4dce7a77edef76ca.json.gz +0 -0
  6. package/.cache/babel/2dc630cecd79488c7912540ac3a1ae93.json.gz +0 -0
  7. package/.cache/babel/3807c3306deecdbdb91968cb3c978235.json.gz +0 -0
  8. package/.cache/babel/45308b31d062a1fb08079849840aaa43.json.gz +0 -0
  9. package/.cache/babel/48df6fe3b45d872e1ded6f33a70e3176.json.gz +0 -0
  10. package/.cache/babel/58350a62e3ef63157722789bf187a8d1.json.gz +0 -0
  11. package/.cache/babel/5ac50f37a9913d9f63c8751f5c415ba4.json.gz +0 -0
  12. package/.cache/babel/6170ac021bca94b65aaf9d91313c47a9.json.gz +0 -0
  13. package/.cache/babel/66c747a8bdec1ed403f703e47256fa03.json.gz +0 -0
  14. package/.cache/babel/695780d53e2d31de09fc42456ad05cff.json.gz +0 -0
  15. package/.cache/babel/6bc92299b6332d48bcc944e155ce08cd.json.gz +0 -0
  16. package/.cache/babel/900ca42963bd0a74c1498a6d1212d82f.json.gz +0 -0
  17. package/.cache/babel/91e706536d45a88f098e9394344dbeb9.json.gz +0 -0
  18. package/.cache/babel/ab39cbb804689d063293f37fa4485487.json.gz +0 -0
  19. package/.cache/babel/c0e75e9017dcf69507da774f93b23422.json.gz +0 -0
  20. package/.cache/babel/c917c2bc027ccb946305c9305b05755e.json.gz +0 -0
  21. package/.cache/babel/cf24b1c63d0cf0e037eb598706a79f88.json.gz +0 -0
  22. package/.cache/babel/e452902bef688c901938b578c6834c50.json.gz +0 -0
  23. package/.cache/babel/e499e66d1cc40fb9b6c4238bf3dd2e6a.json.gz +0 -0
  24. package/.cache/babel/f7fd26614549b5cbb31416d632c38ccd.json.gz +0 -0
  25. package/.cache/babel/fa8281f6c9d0ec08fd8106dcfff2b6ba.json.gz +0 -0
  26. package/CHANGELOG.md +42 -0
  27. package/block-list.json +10 -1
  28. package/composer.lock +7 -7
  29. package/dist/carousel/view.asset.php +1 -1
  30. package/dist/carousel/view.js +1 -1
  31. package/dist/{donateCheckoutBlock.asset.php → checkout-button/view.asset.php} +1 -1
  32. package/dist/checkout-button/view.css +1 -0
  33. package/dist/checkout-button/view.rtl.css +1 -0
  34. package/dist/donate/view.asset.php +1 -1
  35. package/dist/donate/view.css +1 -1
  36. package/dist/donate/view.rtl.css +1 -1
  37. package/dist/editor.asset.php +1 -1
  38. package/dist/editor.css +1 -1
  39. package/dist/editor.js +3 -3
  40. package/dist/editor.rtl.css +1 -1
  41. package/dist/{donateCheckoutModal.asset.php → modal.asset.php} +1 -1
  42. package/dist/modal.css +1 -0
  43. package/dist/modal.js +1 -0
  44. package/dist/modal.rtl.css +1 -0
  45. package/dist/modalCheckout.asset.php +1 -0
  46. package/dist/modalCheckout.js +1 -0
  47. package/includes/class-modal-checkout.php +383 -0
  48. package/includes/class-newspack-blocks.php +30 -6
  49. package/newspack-blocks.php +3 -2
  50. package/package.json +3 -3
  51. package/src/blocks/carousel/edit.js +21 -0
  52. package/src/blocks/carousel/index.js +3 -0
  53. package/src/blocks/carousel/view.php +7 -0
  54. package/src/blocks/checkout-button/block.json +79 -0
  55. package/src/blocks/checkout-button/edit.js +247 -0
  56. package/src/blocks/checkout-button/edit.scss +40 -0
  57. package/src/blocks/checkout-button/editor.js +23 -0
  58. package/src/blocks/checkout-button/index.js +27 -0
  59. package/src/blocks/checkout-button/save.js +64 -0
  60. package/src/blocks/{donate/checkout-modal/index.js → checkout-button/view.js} +1 -1
  61. package/src/blocks/checkout-button/view.php +35 -0
  62. package/src/blocks/checkout-button/view.scss +18 -0
  63. package/src/blocks/donate/frontend/class-newspack-blocks-donate-renderer.php +1 -233
  64. package/src/blocks/donate/styles/view.scss +0 -95
  65. package/src/blocks/homepage-articles/block.json +5 -0
  66. package/src/blocks/homepage-articles/edit.js +18 -0
  67. package/src/blocks/homepage-articles/utils.ts +4 -0
  68. package/src/components/query-controls.js +60 -0
  69. package/src/{blocks/donate/checkout-modal/view.scss → modal-checkout/checkout.scss} +1 -1
  70. package/src/modal-checkout/index.js +4 -0
  71. package/src/{blocks/donate/checkout-modal/block.js → modal-checkout/modal.js} +14 -11
  72. package/src/modal-checkout/modal.scss +97 -0
  73. package/src/{blocks/donate → modal-checkout}/templates/checkout-form.php +3 -3
  74. package/src/types/index.d.ts +1 -0
  75. package/vendor/autoload.php +1 -1
  76. package/vendor/composer/autoload_real.php +4 -4
  77. package/vendor/composer/autoload_static.php +2 -2
  78. package/vendor/composer/installed.php +2 -2
  79. package/webpack.config.js +2 -2
  80. package/.cache/babel/1d8b42985da54f10a9bfd0a9f87b5844.json.gz +0 -0
  81. package/.cache/babel/37bd7f90c2e7ea1e10bf840775d1b262.json.gz +0 -0
  82. package/.cache/babel/3a66da0fe7ab175effa6a338812e46cb.json.gz +0 -0
  83. package/.cache/babel/4ba56fc2684f5bebdd2c8c488ea03683.json.gz +0 -0
  84. package/.cache/babel/60ac312fdf07fb7730b1a8a9c1b5bd5a.json.gz +0 -0
  85. package/.cache/babel/61d00fc8add441f0b915e3af4b518ead.json.gz +0 -0
  86. package/.cache/babel/646a7267e14986e70c74dc9c32ca6a14.json.gz +0 -0
  87. package/.cache/babel/7464c382b8a939e4e43f9349d76843a8.json.gz +0 -0
  88. package/.cache/babel/917cc52662d270e7c529afbf210a2703.json.gz +0 -0
  89. package/.cache/babel/a1dde270d38efa30dfbbfe2b97be9e51.json.gz +0 -0
  90. package/.cache/babel/a5447d9807699029636883e96c6aa4c6.json.gz +0 -0
  91. package/.cache/babel/a7575c7f77cb736dbfe8a4d01910cc79.json.gz +0 -0
  92. package/.cache/babel/b13e3fd47c6307f8c1f8786edc053ed9.json.gz +0 -0
  93. package/.cache/babel/b38122e026094b152ef69677468e4415.json.gz +0 -0
  94. package/.cache/babel/bb3ca1de54603d2730484164ed55902b.json.gz +0 -0
  95. package/.cache/babel/c762aee66625f48b1de4e3b329d8c9fe.json.gz +0 -0
  96. package/.cache/babel/c9d601b83fd7c6412dd9ac187c06d7c1.json.gz +0 -0
  97. package/.cache/babel/fa5e94ee19268ccad7790a312d6fca4e.json.gz +0 -0
  98. package/.cache/babel/fe8f3849250ae54c53096ec8db55a8d6.json.gz +0 -0
  99. package/.cache/babel/fe99fe0bebf3e9d74bb240487620bdd4.json.gz +0 -0
  100. package/dist/donateCheckoutBlock.js +0 -1
  101. /package/dist/{donateCheckoutModal.js → checkout-button/view.js} +0 -0
  102. /package/dist/{donateCheckoutModal.css → modalCheckout.css} +0 -0
  103. /package/dist/{donateCheckoutModal.rtl.css → modalCheckout.rtl.css} +0 -0
@@ -1 +1 @@
1
- <?php return array('dependencies' => array('wp-polyfill'), 'version' => '6ff1ed9230f6ab63475d777dd66b58b6');
1
+ <?php return array('dependencies' => array('wp-polyfill'), 'version' => '04d35452766297fb31a594fc50807f06');
package/dist/modal.css ADDED
@@ -0,0 +1 @@
1
+ @-webkit-keyframes spin{0%{transform:rotate(0deg)}50%{transform:rotate(180deg)}to{transform:rotate(1turn)}}@keyframes spin{0%{transform:rotate(0deg)}50%{transform:rotate(180deg)}to{transform:rotate(1turn)}}.newspack-blocks-checkout-modal{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.75);z-index:99999}.newspack-blocks-checkout-modal__content{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:calc(100vw - 32px);max-width:580px;min-height:200px;max-height:calc(100vh - 32px);background:#fff;border-radius:5px}.newspack-blocks-checkout-modal__content>:not(.newspack-blocks-checkout-modal__close){width:100%;height:100%;border:0;border-radius:5px}.newspack-blocks-checkout-modal__spinner{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:100%;height:100%;display:flex;align-items:center;justify-content:center;background:#fff;border-radius:5px}.newspack-blocks-checkout-modal__spinner>span{width:25px;height:25px;border:2px solid #fff;border-top-color:#767676;border-radius:50%;-webkit-animation:spin 1s linear infinite;animation:spin 1s linear infinite}.newspack-blocks-checkout-modal__close{position:absolute;top:0;right:0;padding:8px;border:0;background:transparent;color:#111;cursor:pointer}.newspack-blocks-checkout-modal__close:focus,.newspack-blocks-checkout-modal__close:hover{color:#767676}.newspack-blocks-checkout-modal__close svg{display:block}@media(max-width:600px){.newspack-blocks-checkout-modal__content{max-width:100%;width:100%;border-radius:0;top:auto;bottom:0;left:0;transform:none}.newspack-blocks-checkout-modal__content>:not(.newspack-blocks-checkout-modal__close){border-radius:0}}
package/dist/modal.js ADDED
@@ -0,0 +1 @@
1
+ (()=>{"use strict";var e={r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t);var n,o;function c(e){var t=e.querySelector("iframe");t&&(t.src="about:blank"),document.body.classList.remove("newspack-modal-checkout-open"),n.disconnect(),e.style.display="none"}o=function(){var e=document.querySelector(".newspack-blocks-checkout-modal");if(e){var t=document.querySelector(".newspack-blocks-checkout-modal__spinner"),o="newspack_modal_checkout",a=document.createElement("input");a.type="hidden",a.name="modal_checkout",a.value="1";var r=e.querySelector(".newspack-blocks-checkout-modal__content"),d=document.createElement("iframe");d.name=o,r.appendChild(d),document.querySelectorAll(".wpbnbd.wpbnbd--platform-wc,.wp-block-newspack-blocks-checkout-button").forEach((function(c){c.querySelectorAll("form").forEach((function(c){c.appendChild(a.cloneNode()),c.target=o,c.addEventListener("submit",(function(){t.style.display="flex",e.style.display="block",document.body.classList.add("newspack-modal-checkout-open"),n=new ResizeObserver((function(e){if(e&&e.length){var t=e[0].contentRect;t&&(r.style.height=t.top+t.bottom+"px")}})),d.addEventListener("load",(function(){var e=d.contentWindow.location;if(window.newspackReaderActivation&&e.href.indexOf("order-received")>-1){var o=window.newspackReaderActivation,c=new Proxy(new URLSearchParams(e.search),{get:function(e,t){return e.get(t)}});c.email&&(o.setReaderEmail(c.email),o.setAuthenticated(!0))}var a=d.contentWindow.document.querySelector("#newspack_modal_checkout");a&&n.observe(a),t.style.display="none"}))}))}))})),e.addEventListener("click",(function(t){t.target===e&&c(e)})),e.querySelectorAll(".newspack-blocks-checkout-modal__close").forEach((function(t){t.addEventListener("click",(function(t){t.preventDefault(),c(e)}))}))}},"undefined"!=typeof document&&("complete"!==document.readyState&&"interactive"!==document.readyState?document.addEventListener("DOMContentLoaded",o):o());var a=window;for(var r in t)a[r]=t[r];t.__esModule&&Object.defineProperty(a,"__esModule",{value:!0})})();
@@ -0,0 +1 @@
1
+ @-webkit-keyframes spin{0%{transform:rotate(0deg)}50%{transform:rotate(-180deg)}to{transform:rotate(-1turn)}}@keyframes spin{0%{transform:rotate(0deg)}50%{transform:rotate(-180deg)}to{transform:rotate(-1turn)}}.newspack-blocks-checkout-modal{position:fixed;top:0;right:0;width:100%;height:100%;background:rgba(0,0,0,.75);z-index:99999}.newspack-blocks-checkout-modal__content{position:absolute;top:50%;right:50%;transform:translate(50%,-50%);width:calc(100vw - 32px);max-width:580px;min-height:200px;max-height:calc(100vh - 32px);background:#fff;border-radius:5px}.newspack-blocks-checkout-modal__content>:not(.newspack-blocks-checkout-modal__close){width:100%;height:100%;border:0;border-radius:5px}.newspack-blocks-checkout-modal__spinner{position:absolute;top:50%;right:50%;transform:translate(50%,-50%);width:100%;height:100%;display:flex;align-items:center;justify-content:center;background:#fff;border-radius:5px}.newspack-blocks-checkout-modal__spinner>span{width:25px;height:25px;border:2px solid #fff;border-top-color:#767676;border-radius:50%;-webkit-animation:spin 1s linear infinite;animation:spin 1s linear infinite}.newspack-blocks-checkout-modal__close{position:absolute;top:0;left:0;padding:8px;border:0;background:transparent;color:#111;cursor:pointer}.newspack-blocks-checkout-modal__close:focus,.newspack-blocks-checkout-modal__close:hover{color:#767676}.newspack-blocks-checkout-modal__close svg{display:block}@media(max-width:600px){.newspack-blocks-checkout-modal__content{max-width:100%;width:100%;border-radius:0;top:auto;bottom:0;right:0;transform:none}.newspack-blocks-checkout-modal__content>:not(.newspack-blocks-checkout-modal__close){border-radius:0}}
@@ -0,0 +1 @@
1
+ <?php return array('dependencies' => array('wp-polyfill'), 'version' => '72f30e0b69b7efc6a193f4883a6d428d');
@@ -0,0 +1 @@
1
+ (()=>{"use strict";var e={r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},o={};e.r(o);var r=window;for(var t in o)r[t]=o[t];o.__esModule&&Object.defineProperty(r,"__esModule",{value:!0})})();
@@ -0,0 +1,383 @@
1
+ <?php
2
+ /**
3
+ * Newspack Blocks Modal Checkout
4
+ *
5
+ * @package Newspack_Blocks
6
+ */
7
+
8
+ namespace Newspack_Blocks;
9
+
10
+ defined( 'ABSPATH' ) || exit;
11
+
12
+ /**
13
+ * Modal Checkout Class.
14
+ */
15
+ final class Modal_Checkout {
16
+ /**
17
+ * Whether the modal checkout has been enqueued.
18
+ *
19
+ * @var boolean
20
+ */
21
+ private static $has_modal = false;
22
+
23
+ /**
24
+ * Initialize hooks.
25
+ */
26
+ public static function init() {
27
+ add_action( 'template_redirect', [ __CLASS__, 'process_checkout_request' ] );
28
+ add_action( 'wp_footer', [ __CLASS__, 'render_modal_markup' ], 100 );
29
+ add_action( 'wp_enqueue_scripts', [ __CLASS__, 'enqueue_scripts' ] );
30
+ add_filter( 'show_admin_bar', [ __CLASS__, 'show_admin_bar' ] );
31
+ add_action( 'template_include', [ __CLASS__, 'get_checkout_template' ] );
32
+ add_filter( 'woocommerce_get_return_url', [ __CLASS__, 'woocommerce_get_return_url' ], 10, 2 );
33
+ add_filter( 'wc_get_template', [ __CLASS__, 'wc_get_template' ], 10, 2 );
34
+ add_filter( 'woocommerce_checkout_get_value', [ __CLASS__, 'woocommerce_checkout_get_value' ], 10, 2 );
35
+ }
36
+
37
+ /**
38
+ * Process checkout request for modal.
39
+ */
40
+ public static function process_checkout_request() {
41
+ $is_newspack_checkout = filter_input( INPUT_GET, 'newspack_checkout', FILTER_SANITIZE_NUMBER_INT );
42
+ $product_id = filter_input( INPUT_GET, 'product_id', FILTER_SANITIZE_NUMBER_INT );
43
+ if ( ! $is_newspack_checkout || ! $product_id ) {
44
+ return;
45
+ }
46
+
47
+ \WC()->cart->empty_cart();
48
+
49
+ $referer = wp_get_referer();
50
+ $params = [];
51
+ $parsed_url = wp_parse_url( $referer );
52
+
53
+ // Get URL params appended to the referer URL.
54
+ if ( ! empty( $parsed_url['query'] ) ) {
55
+ wp_parse_str( $parsed_url['query'], $params );
56
+ }
57
+
58
+ if ( function_exists( 'wpcom_vip_url_to_postid' ) ) {
59
+ $referer_post_id = wpcom_vip_url_to_postid( $referer );
60
+ } else {
61
+ $referer_post_id = url_to_postid( $referer ); // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.url_to_postid_url_to_postid
62
+ }
63
+
64
+ $referer_tags = [];
65
+ $referer_categories = [];
66
+ $tags = get_the_tags( $referer_post_id );
67
+ if ( $tags && ! empty( $tags ) ) {
68
+ $referer_tags = array_map(
69
+ function ( $item ) {
70
+ return $item->slug;
71
+ },
72
+ $tags
73
+ );
74
+ }
75
+
76
+ $categories = get_the_category( $referer_post_id );
77
+ if ( $categories && ! empty( $categories ) ) {
78
+ $referer_categories = array_map(
79
+ function ( $item ) {
80
+ return $item->slug;
81
+ },
82
+ $categories
83
+ );
84
+ }
85
+
86
+ $cart_item_data = [ 'referer' => $referer ];
87
+
88
+ $newspack_popup_id = filter_input( INPUT_GET, 'newspack_popup_id', FILTER_SANITIZE_NUMBER_INT );
89
+ if ( $newspack_popup_id ) {
90
+ $cart_item_data['newspack_popup_id'] = $newspack_popup_id;
91
+ }
92
+
93
+ /** Apply NYP custom price */
94
+ if ( class_exists( 'WC_Name_Your_Price_Helpers' ) ) {
95
+ $is_product_nyp = \WC_Name_Your_Price_Helpers::is_nyp( $product_id );
96
+ $price = filter_input( INPUT_GET, 'price', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
97
+ if ( $is_product_nyp ) {
98
+ if ( empty( $price ) ) {
99
+ $price = \WC_Name_Your_Price_Helpers::get_suggested_price( $product_id );
100
+ }
101
+ $min_price = \WC_Name_Your_Price_Helpers::get_minimum_price( $product_id );
102
+ $max_price = \WC_Name_Your_Price_Helpers::get_maximum_price( $product_id );
103
+ $price = ! empty( $max_price ) ? min( $price, $max_price ) : $price;
104
+ $price = ! empty( $min_price ) ? max( $price, $min_price ) : $price;
105
+
106
+ $cart_item_data['nyp'] = (float) \WC_Name_Your_Price_Helpers::standardize_number( $price );
107
+ }
108
+ }
109
+
110
+ \WC()->cart->add_to_cart( $product_id, 1, 0, [], $cart_item_data );
111
+
112
+ $query_args = [];
113
+
114
+ if ( ! empty( $referer_tags ) ) {
115
+ $query_args['referer_tags'] = implode( ',', $referer_tags );
116
+ }
117
+ if ( ! empty( $referer_categories ) ) {
118
+ $query_args['referer_categories'] = implode( ',', $referer_categories );
119
+ }
120
+ $query_args['modal_checkout'] = 1;
121
+
122
+ // Pass through UTM params so they can be forwarded to the WooCommerce checkout flow.
123
+ foreach ( $params as $param => $value ) {
124
+ if ( 'utm' === substr( $param, 0, 3 ) ) {
125
+ $param = sanitize_text_field( $param );
126
+ $query_args[ $param ] = sanitize_text_field( $value );
127
+ }
128
+ }
129
+
130
+ $checkout_url = add_query_arg(
131
+ $query_args,
132
+ \wc_get_page_permalink( 'checkout' )
133
+ );
134
+
135
+ // Redirect to checkout.
136
+ \wp_safe_redirect( apply_filters( 'newspack_blocks_checkout_url', $checkout_url ) );
137
+ exit;
138
+ }
139
+
140
+ /**
141
+ * Render the markup necessary for the modal checkout.
142
+ */
143
+ public static function render_modal_markup() {
144
+ if ( ! self::$has_modal ) {
145
+ return;
146
+ }
147
+ ?>
148
+ <div class="newspack-blocks-checkout-modal" style="display: none;">
149
+ <div class="newspack-blocks-checkout-modal__content">
150
+ <a href="#" class="newspack-blocks-checkout-modal__close">
151
+ <span class="screen-reader-text"><?php esc_html_e( 'Close', 'newspack-blocks' ); ?></span>
152
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="img" aria-hidden="true" focusable="false">
153
+ <path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/>
154
+ </svg>
155
+ </a>
156
+ <div class="newspack-blocks-checkout-modal__spinner">
157
+ <span></span>
158
+ </div>
159
+ </div>
160
+ </div>
161
+ <?php
162
+ }
163
+
164
+ /**
165
+ * Enqueue scripts for the checkout page rendered in a modal.
166
+ */
167
+ public static function enqueue_scripts() {
168
+ if ( ! function_exists( 'is_checkout' ) || ! is_checkout() ) {
169
+ return;
170
+ }
171
+ if ( ! isset( $_REQUEST['modal_checkout'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
172
+ return;
173
+ }
174
+ wp_enqueue_script(
175
+ 'newspack-blocks-modal-checkout',
176
+ plugins_url( 'dist/modalCheckout.js', \NEWSPACK_BLOCKS__PLUGIN_FILE ),
177
+ [],
178
+ \NEWSPACK_BLOCKS__VERSION,
179
+ true
180
+ );
181
+ wp_enqueue_style(
182
+ 'newspack-blocks-modal-checkout',
183
+ plugins_url( 'dist/modalCheckout.css', \NEWSPACK_BLOCKS__PLUGIN_FILE ),
184
+ [],
185
+ \NEWSPACK_BLOCKS__VERSION
186
+ );
187
+ }
188
+
189
+ /**
190
+ * Enqueue script for triggering modal checkout.
191
+ */
192
+ public static function enqueue_modal() {
193
+ self::$has_modal = true;
194
+ wp_enqueue_script(
195
+ 'newspack-blocks-modal',
196
+ plugins_url( 'dist/modal.js', \NEWSPACK_BLOCKS__PLUGIN_FILE ),
197
+ [],
198
+ \NEWSPACK_BLOCKS__VERSION,
199
+ true
200
+ );
201
+ wp_enqueue_style(
202
+ 'newspack-blocks-modal',
203
+ plugins_url( 'dist/modal.css', \NEWSPACK_BLOCKS__PLUGIN_FILE ),
204
+ [],
205
+ \NEWSPACK_BLOCKS__VERSION
206
+ );
207
+ }
208
+
209
+ /**
210
+ * Use stripped down template for modal checkout.
211
+ *
212
+ * @param string $template The template to render.
213
+ *
214
+ * @return string
215
+ */
216
+ public static function get_checkout_template( $template ) {
217
+ if ( ! function_exists( 'is_checkout' ) || ! function_exists( 'is_order_received_page' ) ) {
218
+ return $template;
219
+ }
220
+ if ( ! is_checkout() && ! is_order_received_page() ) {
221
+ return $template;
222
+ }
223
+ if ( ! isset( $_REQUEST['modal_checkout'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
224
+ return $template;
225
+ }
226
+ ob_start();
227
+ wp_head();
228
+ while ( have_posts() ) {
229
+ the_post();
230
+ echo '<div id="newspack_modal_checkout">';
231
+ the_content();
232
+ echo '</div>';
233
+ }
234
+ wp_footer();
235
+ ob_end_flush();
236
+ }
237
+
238
+
239
+ /**
240
+ * Return URL for modal checkout "thank you" page.
241
+ *
242
+ * @param string $url The URL to redirect to.
243
+ *
244
+ * @return string
245
+ */
246
+ public static function woocommerce_get_return_url( $url ) {
247
+ if ( ! isset( $_REQUEST['modal_checkout'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
248
+ return $url;
249
+ }
250
+ return add_query_arg(
251
+ [
252
+ 'modal_checkout' => '1',
253
+ 'email' => isset( $_REQUEST['billing_email'] ) ? rawurlencode( sanitize_email( wp_unslash( $_REQUEST['billing_email'] ) ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Recommended
254
+ ],
255
+ $url
256
+ );
257
+ }
258
+
259
+ /**
260
+ * Use modal checkout template when rendering the checkout form.
261
+ *
262
+ * @param string $located Template file.
263
+ * @param string $template_name Template name.
264
+ *
265
+ * @return string Template file.
266
+ */
267
+ public static function wc_get_template( $located, $template_name ) {
268
+ if ( 'checkout/form-checkout.php' === $template_name && isset( $_REQUEST['modal_checkout'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
269
+ $located = NEWSPACK_BLOCKS__PLUGIN_DIR . 'src/modal-checkout/templates/checkout-form.php';
270
+ }
271
+ return $located;
272
+ }
273
+
274
+ /**
275
+ * Disable admin bar for modal checkout.
276
+ *
277
+ * @param bool $show Whether to show the admin bar.
278
+ *
279
+ * @return bool
280
+ */
281
+ public static function show_admin_bar( $show ) {
282
+ if ( ! isset( $_REQUEST['modal_checkout'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
283
+ return $show;
284
+ }
285
+ return false;
286
+ }
287
+
288
+ /**
289
+ * Check the nonce for the edit billing request.
290
+ *
291
+ * @return bool
292
+ */
293
+ private static function validate_edit_billing_request() {
294
+ if ( ! isset( $_REQUEST['newspack_blocks_edit_billing_nonce'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
295
+ return false;
296
+ }
297
+ if ( ! wp_verify_nonce( sanitize_key( $_REQUEST['newspack_blocks_edit_billing_nonce'] ), 'newspack_blocks_edit_billing' ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
298
+ return false;
299
+ }
300
+ return true;
301
+ }
302
+
303
+ /**
304
+ * Modify WC checkout field value.
305
+ *
306
+ * @param null $value Value.
307
+ * @param string $input Input name.
308
+ *
309
+ * @return string|null Value or null if unaltered.
310
+ */
311
+ public static function woocommerce_checkout_get_value( $value, $input ) {
312
+ if ( ! isset( $_REQUEST['modal_checkout'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
313
+ return null;
314
+ }
315
+ $valid_request = self::validate_edit_billing_request(); // This performs nonce verification.
316
+ if ( ! $valid_request ) {
317
+ return null;
318
+ }
319
+ if ( isset( $_REQUEST[ $input ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
320
+ $value = sanitize_text_field( wp_unslash( $_REQUEST[ $input ] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
321
+ }
322
+ return $value;
323
+ }
324
+
325
+ /**
326
+ * Get the prefilled values for billing fields.
327
+ *
328
+ * @return array
329
+ */
330
+ public static function get_prefilled_fields() {
331
+ $checkout = \WC()->checkout();
332
+ $fields = $checkout->get_checkout_fields( 'billing' );
333
+ $customer = new \WC_Customer( get_current_user_id() );
334
+ $customer_fields = $customer->get_billing();
335
+ // If the user is logged in and there's no billing email, use the user's email.
336
+ if ( is_user_logged_in() && empty( $customer_fields['email'] ) ) {
337
+ $customer_fields['email'] = $customer->get_email();
338
+ }
339
+ $valid_request = self::validate_edit_billing_request();
340
+ $prefilled_fields = [];
341
+ foreach ( $fields as $key => $field ) {
342
+ $key = str_replace( 'billing_', '', $key );
343
+ if ( $valid_request && isset( $_REQUEST[ 'billing_' . $key ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
344
+ $value = sanitize_text_field( wp_unslash( $_REQUEST[ 'billing_' . $key ] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
345
+ } elseif ( isset( $customer_fields[ $key ] ) ) {
346
+ $value = $customer_fields[ $key ];
347
+ }
348
+ $prefilled_fields[ $key ] = $value;
349
+ }
350
+ return $prefilled_fields;
351
+ }
352
+
353
+ /**
354
+ * Whether the current checkout session has all required billing fields filled.
355
+ *
356
+ * @return bool
357
+ */
358
+ public static function has_filled_required_fields() {
359
+ $checkout = \WC()->checkout();
360
+ $fields = $checkout->get_checkout_fields( 'billing' );
361
+ $required = array_filter(
362
+ $fields,
363
+ function( $field ) {
364
+ return isset( $field['required'] ) && $field['required'];
365
+ }
366
+ );
367
+ $required_keys = array_keys( $required );
368
+ $customer_fields = self::get_prefilled_fields();
369
+ $is_request = self::validate_edit_billing_request();
370
+ foreach ( $required_keys as $key ) {
371
+ $key = str_replace( 'billing_', '', $key );
372
+ if ( empty( $customer_fields[ $key ] ) ) {
373
+ if ( $is_request ) {
374
+ /* translators: %s: field name */
375
+ wc_add_notice( sprintf( __( '%s is a required field.', 'newspack-blocks' ), $fields[ 'billing_' . $key ]['label'] ), 'error' );
376
+ }
377
+ return false;
378
+ }
379
+ }
380
+ return true;
381
+ }
382
+ }
383
+ Modal_Checkout::init();
@@ -242,6 +242,10 @@ class Newspack_Blocks {
242
242
  $localized_data['author_custom_fields'] = \Newspack\Authors_Custom_Fields::get_custom_fields();
243
243
  }
244
244
 
245
+ if ( class_exists( 'Newspack_Multibranded_Site\Customizations\Theme_Colors' ) ) {
246
+ $localized_data['multibranded_sites_enabled'] = true;
247
+ }
248
+
245
249
  wp_localize_script(
246
250
  'newspack-blocks-editor',
247
251
  'newspack_blocks_data',
@@ -285,12 +289,12 @@ class Newspack_Blocks {
285
289
  * Can the tiers-based layout of the Donate block be rendered?
286
290
  */
287
291
  public static function can_render_tiers_based_layout() {
288
- if ( method_exists( '\Newspack\AMP_Enhancements', 'is_amp_plus_configured' ) ) {
292
+ if ( ! is_plugin_active( 'amp/amp.php' ) ) {
293
+ return true;
294
+ } elseif ( method_exists( '\Newspack\AMP_Enhancements', 'is_amp_plus_configured' ) ) {
289
295
  return \Newspack\AMP_Enhancements::is_amp_plus_configured();
290
- } else {
291
- return ! is_plugin_active( 'amp/amp.php' );
292
296
  }
293
- return true;
297
+ return false;
294
298
  }
295
299
 
296
300
  /**
@@ -587,6 +591,7 @@ class Newspack_Blocks {
587
591
  $authors = isset( $attributes['authors'] ) ? $attributes['authors'] : array();
588
592
  $categories = isset( $attributes['categories'] ) ? $attributes['categories'] : array();
589
593
  $tags = isset( $attributes['tags'] ) ? $attributes['tags'] : array();
594
+ $brands = isset( $attributes['brands'] ) ? $attributes['brands'] : array();
590
595
  $tag_exclusions = isset( $attributes['tagExclusions'] ) ? $attributes['tagExclusions'] : array();
591
596
  $category_exclusions = isset( $attributes['categoryExclusions'] ) ? $attributes['categoryExclusions'] : array();
592
597
  $specific_posts = isset( $attributes['specificPosts'] ) ? $attributes['specificPosts'] : array();
@@ -620,7 +625,6 @@ class Newspack_Blocks {
620
625
  get_the_ID() ? [ get_the_ID() ] : []
621
626
  );
622
627
  }
623
-
624
628
  if ( $categories && count( $categories ) ) {
625
629
  $args['category__in'] = $categories;
626
630
  }
@@ -633,7 +637,18 @@ class Newspack_Blocks {
633
637
  if ( $category_exclusions && count( $category_exclusions ) ) {
634
638
  $args['category__not_in'] = $category_exclusions;
635
639
  }
636
-
640
+ if ( class_exists( 'Newspack_Multibranded_Site\Customizations\Theme_Colors' ) ) {
641
+ if ( $brands && count( $brands ) ) {
642
+ $args['tax_query'] = [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query
643
+ [
644
+ 'taxonomy' => 'brand',
645
+ 'field' => 'term_id',
646
+ 'terms' => $brands,
647
+ 'include_children' => false,
648
+ ],
649
+ ];
650
+ }
651
+ }
637
652
  $is_co_authors_plus_active = class_exists( 'CoAuthors_Guest_Authors' );
638
653
 
639
654
  if ( $authors && count( $authors ) ) {
@@ -789,6 +804,15 @@ class Newspack_Blocks {
789
804
  }
790
805
  }
791
806
 
807
+ if ( class_exists( 'Newspack_Multibranded_Site\Customizations\Theme_Colors' ) ) {
808
+ $brands = get_the_terms( $post_id, 'brand' );
809
+ if ( ! empty( $brands ) ) {
810
+ foreach ( $brands as $brand ) {
811
+ $classes[] = 'brands-' . $brand->slug;
812
+ }
813
+ }
814
+ }
815
+
792
816
  $post_type = get_post_type( $post_id );
793
817
  if ( false !== $post_type ) {
794
818
  $classes[] = 'type-' . $post_type;
@@ -7,7 +7,7 @@
7
7
  * Author URI: https://newspack.blog/
8
8
  * Text Domain: newspack-blocks
9
9
  * Domain Path: /languages
10
- * Version: 1.67.0
10
+ * Version: 1.68.0
11
11
  *
12
12
  * @package Newspack_Blocks
13
13
  */
@@ -15,11 +15,12 @@
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', '1.67.0' );
18
+ define( 'NEWSPACK_BLOCKS__VERSION', '1.68.0' );
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';
22
22
  require_once NEWSPACK_BLOCKS__PLUGIN_DIR . 'includes/class-newspack-blocks-patterns.php';
23
+ require_once NEWSPACK_BLOCKS__PLUGIN_DIR . 'includes/class-modal-checkout.php';
23
24
 
24
25
  // REST Controller for Articles Block.
25
26
  require_once NEWSPACK_BLOCKS__PLUGIN_DIR . 'src/blocks/homepage-articles/class-wp-rest-newspack-articles-controller.php';
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@automattic/newspack-blocks",
3
- "version": "1.67.0",
3
+ "version": "1.68.0",
4
4
  "author": "Automattic",
5
5
  "devDependencies": {
6
6
  "@rushstack/eslint-patch": "^1.2.0",
7
7
  "@testing-library/dom": "^8.20.0",
8
8
  "@testing-library/user-event": "^14.4.3",
9
- "@types/lodash": "^4.14.192",
9
+ "@types/lodash": "^4.14.194",
10
10
  "@types/lodash.debounce": "^4.0.7",
11
11
  "eslint": "^7.32.0",
12
12
  "fetch-mock-jest": "^1.5.1",
@@ -28,7 +28,7 @@
28
28
  "redux": "^4.2.1",
29
29
  "redux-saga": "^1.2.3",
30
30
  "regenerator-runtime": "^0.13.11",
31
- "swiper": "9.2.0"
31
+ "swiper": "9.2.4"
32
32
  },
33
33
  "scripts": {
34
34
  "cm": "newspack-scripts commit",
@@ -48,6 +48,16 @@ import { postsBlockSelector, postsBlockDispatch, shouldReflow } from '../homepag
48
48
  // Max number of slides that can be shown at once.
49
49
  const MAX_NUMBER_OF_SLIDES = 6;
50
50
 
51
+ // Check if multi-branded site
52
+ let IS_MULTIBRANDED_SITE;
53
+ if (
54
+ typeof window === 'object' &&
55
+ window.newspack_blocks_data &&
56
+ window.newspack_blocks_data.multibranded_sites_enabled
57
+ ) {
58
+ IS_MULTIBRANDED_SITE = true;
59
+ }
60
+
51
61
  class Edit extends Component {
52
62
  constructor( props ) {
53
63
  super( props );
@@ -150,6 +160,7 @@ class Edit extends Component {
150
160
  authors,
151
161
  autoplay,
152
162
  categories,
163
+ brands,
153
164
  delay,
154
165
  hideControls,
155
166
  imageFit,
@@ -232,6 +243,14 @@ class Edit extends Component {
232
243
  ),
233
244
  },
234
245
  ];
246
+
247
+ const brandProps = IS_MULTIBRANDED_SITE
248
+ ? {
249
+ brands,
250
+ onBrandsChange: value => setAttributes( { brands: value } ),
251
+ }
252
+ : '';
253
+
235
254
  return (
236
255
  <Fragment>
237
256
  <div className={ classes } ref={ this.carouselRef }>
@@ -359,6 +378,7 @@ class Edit extends Component {
359
378
  </Fragment>
360
379
  ) }
361
380
  </div>
381
+
362
382
  <InspectorControls>
363
383
  <PanelBody title={ __( 'Display Settings' ) } initialOpen={ true }>
364
384
  { postsToShow && (
@@ -373,6 +393,7 @@ class Edit extends Component {
373
393
  onCategoriesChange={ value => setAttributes( { categories: value } ) }
374
394
  tags={ tags }
375
395
  onTagsChange={ value => setAttributes( { tags: value } ) }
396
+ { ...brandProps }
376
397
  specificMode={ specificMode }
377
398
  onSpecificModeChange={ _specificMode =>
378
399
  setAttributes( { specificMode: _specificMode } )
@@ -67,6 +67,9 @@ export const settings = {
67
67
  tags: {
68
68
  type: 'array',
69
69
  },
70
+ brands: {
71
+ type: 'array',
72
+ },
70
73
  showDate: {
71
74
  type: 'boolean',
72
75
  default: true,
@@ -410,6 +410,13 @@ function newspack_blocks_register_carousel() {
410
410
  'type' => 'integer',
411
411
  ),
412
412
  ),
413
+ 'brands' => array(
414
+ 'type' => 'array',
415
+ 'default' => array(),
416
+ 'items' => array(
417
+ 'type' => 'integer',
418
+ ),
419
+ ),
413
420
  'autoplay' => array(
414
421
  'type' => 'boolean',
415
422
  'default' => false,