PluginProbe
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster / trunk
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster vtrunk
2.6.0 trunk 1.1.0 1.1.4 1.2.1 1.2.2 1.2.3 1.2.5 1.2.9 1.3.1 1.3.2 1.5.0 1.5.1 1.5.4 1.5.7 1.5.8 1.5.9 1.6.2 1.6.5 1.6.8 1.7.2 1.7.4 1.7.5 1.7.9 1.8.1 All 42 releases
sellkit / includes / block-editor / blocks / checkout / index.php

index.php in SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster trunk, at includes/block-editor/blocks/checkout/index.php

378 lines 11.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Sellkit\Blocks\Render;
3
4 defined( 'ABSPATH' ) || exit;
5
6 use Sellkit\Blocks\Sellkit_Blocks;
7 use Sellkit\Global_Checkout\Checkout as Global_Checkout;
8
9 /**
10 * Checkout block.
11 *
12 * @since 2.3.0
13 */
14 class Checkout {
15 /**
16 * Check block activation.
17 *
18 * @since 2.3.0
19 * @return boolean
20 */
21 public function is_active() {
22 return true;
23 }
24
25 /**
26 * Register block from meta.
27 *
28 * @since 2.3.0
29 */
30 public function register_block_meta() {
31 register_block_type_from_metadata(
32 __DIR__,
33 [
34 'render_callback' => [ $this, 'render' ],
35 ]
36 );
37 }
38
39 /**
40 * Check block has inner blocks.
41 *
42 * @since 2.3.0
43 * @return boolean
44 */
45 public function has_inner_blocks() {
46 return true;
47 }
48
49 /**
50 * Check block has inner blocks.
51 *
52 * @since 2.3.0
53 * @return boolean
54 */
55 public function get_inner_block() {
56 $shipping_destination = get_option( 'woocommerce_ship_to_destination', true );
57
58 $inner_blocks = [
59 'checkout-contact-information' => 'block-editor/blocks/checkout/inner-blocks/contact-information/class',
60 'checkout-form-shipping' => 'block-editor/blocks/checkout/inner-blocks/form-shipping/class',
61 'checkout-cart-shipping' => 'block-editor/blocks/checkout/inner-blocks/cart-shipping/class',
62 'checkout-review-order' => 'block-editor/blocks/checkout/inner-blocks/review-order/class',
63 'checkout-billing-details' => 'block-editor/blocks/checkout/inner-blocks/billing-details/class',
64 'checkout-payment' => 'block-editor/blocks/checkout/inner-blocks/payment/class',
65 'checkout-payment-continue' => 'block-editor/blocks/checkout/inner-blocks/payment-continue/class',
66 ];
67
68 if ( 'billing_only' === $shipping_destination ) {
69 $inner_blocks = [
70 'checkout-contact-information' => 'block-editor/blocks/checkout/inner-blocks/contact-information/class',
71 'checkout-billing-details' => 'block-editor/blocks/checkout/inner-blocks/billing-details/class',
72 'checkout-cart-shipping' => 'block-editor/blocks/checkout/inner-blocks/cart-shipping/class',
73 'checkout-review-order' => 'block-editor/blocks/checkout/inner-blocks/review-order/class',
74 'checkout-payment' => 'block-editor/blocks/checkout/inner-blocks/payment/class',
75 'checkout-payment-continue' => 'block-editor/blocks/checkout/inner-blocks/payment-continue/class',
76 ];
77 }
78
79 return $inner_blocks;
80 }
81
82 /**
83 * Clears all custom actions and filters related to SellKit checkout process.
84 *
85 * @since 2.3.0
86 */
87 public function clear_sellkit_checkout_custom_hooks() {
88 remove_all_actions( 'sellkit_block_checkout_shipping_fields' );
89 remove_all_actions( 'sellkit_block_checkout_billing_fields' );
90 remove_all_actions( 'sellkit_block_checkout_after_shipping_section' );
91 remove_all_actions( 'sellkit-checkout-widget-express-methods' );
92 remove_all_actions( 'sellkit-checkout-widget-custom-coupon-form' );
93 remove_all_actions( 'sellkit-checkout-widget-custom-coupon-form' );
94 remove_all_actions( 'woocommerce_checkout_update_order_review' );
95 remove_all_filters( 'woocommerce_locate_template' );
96 }
97
98 /**
99 * Register express checkout integrations for block checkout.
100 *
101 * @since 2.3.0
102 * @return void
103 */
104 private function setup_express_checkout_integrations() {
105 sellkit()->load_files( [
106 'elementor/modules/checkout/integrations/integration',
107 'elementor/modules/checkout/integrations/paypal-for-woocommerce',
108 'elementor/modules/checkout/integrations/woo-payment-gateway',
109 'elementor/modules/checkout/integrations/stripe-for-woocommerce',
110 'elementor/modules/checkout/integrations/klarma-checkout-woocommerce',
111 'elementor/modules/checkout/integrations/amazon-pay-woocommerce',
112 'elementor/modules/checkout/integrations/stripe-woocommerce-official',
113 ] );
114
115 $gateways = [
116 'Paypal_For_Woocommerce',
117 'Woo_Payment_Gateway',
118 'Stripe_For_Woocommerce',
119 'Klarma_Checkout_Woocommerce',
120 'Amazon_Pay_Woocommerce',
121 'Stripe_Woocommerce_Official',
122 ];
123
124 foreach ( $gateways as $gateway ) {
125 $class = 'Sellkit\Elementor\Modules\Checkout\Integrations\\' . $gateway;
126 $class = new $class();
127 $class->run();
128 }
129 }
130
131 /**
132 * Render express checkout section for block checkout.
133 *
134 * @param array $attributes Checkout block attributes.
135 * @since 2.3.0
136 * @return string
137 */
138 private function express_checkout_html( $attributes ) {
139 if ( empty( $attributes['showExpressCheckout'] ) ) {
140 return '';
141 }
142
143 ob_start();
144 do_action( 'sellkit-checkout-widget-express-methods' );
145 $methods = trim( ob_get_clean() );
146
147 if ( empty( $methods ) ) {
148 return '';
149 }
150
151 ob_start();
152 ?>
153 <section class="sellkit-checkout-widget-express-checkout sellkit-checkout-express-checkout-step-1">
154 <fieldset class="express-box sellkit-checkout-widget-divider">
155 <legend class="sellkit-express-checkout-legend heading">
156 <?php echo esc_html__( 'Express Checkout', 'sellkit' ); ?>
157 </legend>
158 <div class="express-methods">
159 <?php echo wp_kses_post( $methods ); ?>
160 </div>
161 </fieldset>
162 </section>
163 <section class="sellkit-checkout-widget-express-checkout sellkit-checkout-express-checkout-step-2">
164 <fieldset id="sellkit-checkout-or-divider" class="divider-box sellkit-checkout-widget-divider">
165 <legend class="heading"><?php echo esc_html__( 'OR', 'sellkit' ); ?></legend>
166 </fieldset>
167 </section>
168 <?php
169
170 return ob_get_clean();
171 }
172
173 /**
174 * Render block in front-end.
175 *
176 * @param array $attributes Block attributes.
177 * @param string $content Block content.
178 * @param \WP_Block $block Block object.
179 * @since 2.3.0
180 * @return string
181 */
182 public function render( $attributes, $content, $block ) {
183 if ( ! function_exists( 'wc' ) ) {
184 return;
185 }
186
187 if ( ! is_admin() ) {
188 Sellkit_Blocks::load_scripts( 'checkout' );
189 Sellkit_Blocks::load_scripts( 'checkout', 'checkout-external', [ 'wc-checkout', 'wc-country-select', 'wp-api' ] );
190
191 wp_localize_script('sellkit-block-checkout-script', 'sellkit_block_checkout', [
192 'nonce' => wp_create_nonce( 'sellkit_block_checkout' ),
193 'wcNeedShipping' => ( function_exists( 'WC' ) ) ? WC()->cart->needs_shipping() : '',
194 'url' => [
195 'assets' => sellkit()->plugin_url() . 'assets/',
196 ],
197 ] );
198 }
199
200 $block_html = '';
201 $wrapper_attributes = get_block_wrapper_attributes( [
202 'class' => 'sellkit-checkout-widget-one-page-build sellkit-block-checkout-main-wrapper',
203 ] );
204
205 do_action( 'sellkit_block_before_checkout_form' );
206
207 if ( sellkit()->has_pro ) {
208 $this->setup_express_checkout_integrations();
209 $block_html .= $this->express_checkout_html( $attributes );
210 }
211
212 foreach ( $block->inner_blocks as $inner_block ) {
213 $block_name = str_replace( 'sellkit-inner-blocks/', '', $inner_block->parsed_block['blockName'] );
214 $block_name = str_replace( '-', ' ', $block_name );
215 $block_name = ucwords( $block_name );
216 $block_name = str_replace(' ', '_', $block_name );
217 $block_content = $inner_block->render();
218 $class_name = 'Sellkit\Blocks\Inner_Block\\' . ucwords( $block_name );
219
220 if ( ! class_exists( $class_name ) ) {
221 $block_html .= $inner_block->render();
222 continue;
223 }
224
225 $new_class = new $class_name();
226 if ( method_exists( $new_class, $block_name ) ) {
227 $block_html .= $new_class->$block_name( $block_content, $inner_block->attributes );
228 }
229 }
230
231 global $woocommerce;
232
233 $checkout = $woocommerce->checkout;
234
235 do_action( 'woocommerce_before_checkout_form', $checkout );
236
237 // If checkout registration is disabled and not logged in, the user cannot checkout.
238 if ( ! $checkout->is_registration_enabled() && $checkout->is_registration_required() && ! is_user_logged_in() ) {
239 echo esc_html( apply_filters( 'woocommerce_checkout_must_be_logged_in_message', esc_html__( 'You must be logged in to checkout.', 'sellkit' ) ) );
240 return;
241 }
242
243 $extra_class = '';
244
245 if ( WC()->cart && ! WC()->cart->needs_shipping() ) {
246 $extra_class = 'sellkit-checkout-virtual-session';
247 }
248
249 $block_html = sprintf(
250 '
251 <div %1$s>
252 <div class="woocommerce">
253 <div id="sellkit-checkout-widget-id">
254 <form name="checkout" method="post" class="checkout woocommerce-checkout %2$s" action="%3$s" enctype="multipart/form-data">
255 %4$s
256 </form>
257 %5$s
258 </div>
259 </div>
260 </div>
261 ',
262 wp_kses_data( $wrapper_attributes ),
263 esc_attr( $extra_class ),
264 esc_url( wc_get_checkout_url() ),
265 stripslashes( $block_html ),
266 do_action( 'woocommerce_after_checkout_form', $checkout )
267 );
268
269 $checkout_id = get_the_ID();
270 $step_data = get_post_meta( $checkout_id, 'step_data', true );
271 $global_checkout = apply_filters( 'sellkit_global_checkout_activated', false );
272 $global_checkout_id = get_option( Global_Checkout::SELLKIT_GLOBAL_CHECKOUT_OPTION, 0 );
273 $current_funnel_id = ( ! empty( $step_data ) ) ? $step_data['funnel_id'] : -1;
274 $empty_cart_msg = esc_html( $attributes['emptyCartMessage'] );
275
276 $order_key = ! empty( sellkit_htmlspecialchars( INPUT_GET, 'order-key' ) ) ? sellkit_htmlspecialchars( INPUT_GET, 'order-key' ) : sellkit_htmlspecialchars( INPUT_GET, 'key' );
277
278 if (
279 $global_checkout &&
280 is_wc_endpoint_url( 'order-received' ) &&
281 ! empty( $order_key )
282 ) {
283 $order_id = wc_get_order_id_by_order_key( $order_key );
284
285 if ( empty( $order_id ) ) {
286 $block_html = sprintf(
287 '
288 <div %1$s>
289 <div class="woocommerce">
290 <div id="sellkit-checkout-widget-id">
291 <div class="woocommerce-info">%2$s</div>
292 </div>
293 </div>
294 </div>'
295 ,
296 wp_kses_data( $wrapper_attributes ),
297 wp_kses_post( $empty_cart_msg )
298 );
299
300 return $block_html;
301 }
302
303 // Valid order on the order-received endpoint: render WooCommerce's thank-you
304 // template instead of the checkout form. SellKit's own redirect_after_purchase
305 // already runs earlier on template_redirect, but express-checkout flows that
306 // skip SellKit's hidden fields (so no sellkit_funnel_next_step_data meta is
307 // saved) fall through to here and must not show a filled-in checkout form.
308 ob_start();
309 echo '<div class="woocommerce">';
310 wc_get_template( 'checkout/thankyou.php', [ 'order' => wc_get_order( $order_id ) ] );
311 echo '</div>';
312 $thankyou_html = ob_get_clean();
313
314 return sprintf(
315 '<div %1$s>%2$s</div>',
316 wp_kses_data( $wrapper_attributes ),
317 $thankyou_html // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- WooCommerce template output.
318 );
319 }
320
321 if (
322 $global_checkout &&
323 0 === WC()->cart->get_cart_contents_count() &&
324 ! is_wc_endpoint_url( 'order-received' )
325 ) {
326 $block_html = sprintf(
327 '
328 <div %1$s>
329 <div class="woocommerce">
330 <div id="sellkit-checkout-widget-id">
331 <div class="woocommerce-info">%2$s</div>
332 </div>
333 </div>
334 </div>'
335 ,
336 wp_kses_data( $wrapper_attributes ),
337 wp_kses_post( $empty_cart_msg )
338 );
339
340 return $block_html;
341 }
342
343 if (
344 false === $global_checkout &&
345 intval( $global_checkout_id ) !== intval( $current_funnel_id ) &&
346 is_array( $step_data ) &&
347 (
348 ! array_key_exists( 'data', $step_data ) ||
349 ! array_key_exists( 'list', $step_data['data']['products'] )
350 )
351 ) {
352 $block_html = sprintf(
353 '
354 <div %1$s>
355 <div class="woocommerce">
356 <div id="sellkit-checkout-widget-id">
357 <div class="woocommerce-info">%2$s</div>
358 </div>
359 </div>
360 </div>'
361 ,
362 wp_kses_data( $wrapper_attributes ),
363 wp_kses_post( $empty_cart_msg )
364 );
365
366 return $block_html;
367 }
368
369 add_filter( 'woocommerce_is_checkout', function() {
370 return true;
371 }, 10 );
372
373 $this->clear_sellkit_checkout_custom_hooks();
374
375 return $block_html;
376 }
377 }
378