264 lines
6.6 KiB
PHP
264 lines
6.6 KiB
PHP
<?php
|
|
/**
|
|
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
|
|
*
|
|
* This source code is licensed under the license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @package MetaCommerce
|
|
*/
|
|
|
|
namespace WooCommerce\Facebook;
|
|
|
|
defined( 'ABSPATH' ) || exit;
|
|
|
|
use WooCommerce\Facebook\Framework\Logger;
|
|
|
|
/**
|
|
* The checkout permalink.
|
|
*
|
|
* @since 3.3.0
|
|
*/
|
|
class Checkout {
|
|
|
|
/**
|
|
* Checkout constructor.
|
|
*
|
|
* @since 3.3.0
|
|
*/
|
|
public function __construct() {
|
|
$this->add_hooks();
|
|
}
|
|
|
|
/**
|
|
* Adds the necessary action and filter hooks.
|
|
*
|
|
* @since 3.3.0
|
|
*/
|
|
public function add_hooks() {
|
|
add_action( 'init', array( $this, 'add_checkout_permalink_rewrite_rule' ) );
|
|
add_filter( 'query_vars', array( $this, 'add_checkout_permalink_query_var' ) );
|
|
add_filter( 'template_include', array( $this, 'load_checkout_permalink_template' ) );
|
|
|
|
register_activation_hook( __FILE__, array( $this, 'flush_rewrite_rules_on_activation' ) );
|
|
register_deactivation_hook( __FILE__, array( $this, 'flush_rewrite_rules_on_deactivation' ) );
|
|
}
|
|
|
|
/**
|
|
* Adds a rewrite rule for the checkout permalink.
|
|
*
|
|
* @since 3.3.0
|
|
*/
|
|
public function add_checkout_permalink_rewrite_rule() {
|
|
add_rewrite_rule( '^fb-checkout/?$', 'index.php?fb_checkout=1', 'top' );
|
|
}
|
|
|
|
/**
|
|
* Adds query vars for the checkout permalink.
|
|
*
|
|
* @since 3.3.0
|
|
*
|
|
* @param array $vars
|
|
* @return array
|
|
*/
|
|
public function add_checkout_permalink_query_var( $vars ) {
|
|
$vars[] = 'fb_checkout';
|
|
$vars[] = 'products';
|
|
$vars[] = 'coupon';
|
|
|
|
return $vars;
|
|
}
|
|
|
|
/**
|
|
* Loads the checkout permalink template.
|
|
*
|
|
* @since 3.3.0
|
|
*
|
|
* @param string $template
|
|
* @return string
|
|
*/
|
|
public function load_checkout_permalink_template( $template ) {
|
|
if ( get_query_var( 'fb_checkout' ) ) {
|
|
WC()->cart->empty_cart();
|
|
|
|
$products_param = get_query_var( 'products' );
|
|
if ( $products_param ) {
|
|
$products = explode( ',', $products_param );
|
|
|
|
foreach ( $products as $product ) {
|
|
list( $product_id, $quantity ) = explode( ':', $product );
|
|
|
|
// Parse the product ID. The input is sent in the Retailer ID format (see get_fb_retailer_id())
|
|
// The Retailer ID format is: {product_sku}_{product_id}, so we need to extract the product_id
|
|
if ( false !== strpos( $product_id, '_' ) ) {
|
|
$parts = explode( '_', $product_id );
|
|
$product_id = end( $parts );
|
|
}
|
|
|
|
$product_obj = wc_get_product( $product_id );
|
|
|
|
if (
|
|
$product_obj &&
|
|
$product_obj->is_purchasable() &&
|
|
is_numeric( $quantity ) &&
|
|
$quantity > 0
|
|
) {
|
|
$added = WC()->cart->add_to_cart( $product_id, $quantity );
|
|
if ( ! $added ) {
|
|
$error_message = sprintf(
|
|
'WC add_to_cart() failed: product_id=%s, quantity=%s',
|
|
$product_id,
|
|
$quantity
|
|
);
|
|
|
|
Logger::log(
|
|
$error_message,
|
|
array(
|
|
'flow_name' => 'checkout',
|
|
'flow_step' => 'add_to_cart',
|
|
'extra_data' => [
|
|
'products_param' => $products_param,
|
|
'product_id' => $product_id,
|
|
'quantity' => $quantity,
|
|
],
|
|
),
|
|
array(
|
|
'should_send_log_to_meta' => true,
|
|
'should_save_log_in_woocommerce' => true,
|
|
'woocommerce_log_level' => \WC_Log_Levels::ERROR,
|
|
)
|
|
);
|
|
}
|
|
} else {
|
|
$error_message = sprintf(
|
|
'Invalid product or quantity: product_id=%s, quantity=%s',
|
|
$product_id,
|
|
$quantity
|
|
);
|
|
|
|
Logger::log(
|
|
$error_message,
|
|
array(
|
|
'flow_name' => 'checkout',
|
|
'flow_step' => 'product_quantity_validation',
|
|
'extra_data' => [
|
|
'products_param' => $products_param,
|
|
'product_id' => $product_id,
|
|
'quantity' => $quantity,
|
|
],
|
|
),
|
|
array(
|
|
'should_send_log_to_meta' => true,
|
|
'should_save_log_in_woocommerce' => true,
|
|
'woocommerce_log_level' => \WC_Log_Levels::ERROR,
|
|
)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
$coupon_code = get_query_var( 'coupon' );
|
|
if ( $coupon_code ) {
|
|
$coupon_code_sanitized = sanitize_text_field( $coupon_code );
|
|
WC()->cart->apply_coupon( $coupon_code_sanitized );
|
|
|
|
if ( ! in_array( $coupon_code_sanitized, WC()->cart->get_applied_coupons(), true ) ) {
|
|
$error_message = sprintf(
|
|
'Failed to apply coupon: %s',
|
|
$coupon_code_sanitized
|
|
);
|
|
|
|
Logger::log(
|
|
$error_message,
|
|
array(
|
|
'flow_name' => 'checkout',
|
|
'flow_step' => 'apply_coupon',
|
|
'extra_data' => [
|
|
'coupon_param' => $coupon_code,
|
|
'coupon_code' => $coupon_code_sanitized,
|
|
],
|
|
),
|
|
array(
|
|
'should_send_log_to_meta' => true,
|
|
'should_save_log_in_woocommerce' => true,
|
|
'woocommerce_log_level' => \WC_Log_Levels::ERROR,
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
$checkout_url = wc_get_checkout_url();
|
|
echo '<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Checkout</title>
|
|
<style>
|
|
body, html {
|
|
margin: 0;
|
|
padding: 0;
|
|
height: 100%;
|
|
overflow: hidden;
|
|
}
|
|
iframe {
|
|
width: 100%;
|
|
height: 100vh;
|
|
border: none;
|
|
display: block;
|
|
max-width: 100%;
|
|
max-height: 100%;
|
|
box-sizing: border-box;
|
|
}
|
|
</style>
|
|
<script>
|
|
// Prevent lazy loading plugins from interfering with the checkout iframe
|
|
document.addEventListener("DOMContentLoaded", function() {
|
|
var iframe = document.querySelector("iframe");
|
|
if (iframe) {
|
|
// Ensure the iframe loads immediately
|
|
iframe.setAttribute("data-no-lazy", "1");
|
|
iframe.setAttribute("data-skip-lazy", "1");
|
|
iframe.setAttribute("loading", "eager");
|
|
iframe.removeAttribute("data-src");
|
|
iframe.removeAttribute("class");
|
|
|
|
// Force reload if src was changed to placeholder
|
|
if (iframe.src.includes("data:image/svg+xml")) {
|
|
iframe.src = "' . esc_url( $checkout_url ) . '";
|
|
}
|
|
}
|
|
});
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<iframe src="' . esc_url( $checkout_url ) . '" data-no-lazy="1" data-skip-lazy="1" loading="eager"></iframe>
|
|
</body>
|
|
</html>';
|
|
|
|
exit;
|
|
}
|
|
|
|
return $template;
|
|
}
|
|
|
|
/**
|
|
* Flushes rewrite rules when the plugin is activated.
|
|
*
|
|
* @since 3.3.0
|
|
*/
|
|
public function flush_rewrite_rules_on_activation() {
|
|
$this->add_checkout_permalink_rewrite_rule();
|
|
flush_rewrite_rules();
|
|
}
|
|
|
|
/**
|
|
* Flushes rewrite rules when the plugin is deactivated.
|
|
*
|
|
* @since 3.3.0
|
|
*/
|
|
public function flush_rewrite_rules_on_deactivation() {
|
|
flush_rewrite_rules();
|
|
}
|
|
}
|