Skip to content

Commit

Permalink
feat(ras-acc) add welcome email template for checkout registration (#…
Browse files Browse the repository at this point in the history
…1754)

This adds a new welcome email template for readers who register via checkout.
  • Loading branch information
chickenn00dle authored Jun 26, 2024
1 parent bc20739 commit 494b930
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 87 deletions.
220 changes: 136 additions & 84 deletions includes/class-modal-checkout.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,20 @@
* Modal Checkout Class.
*/
final class Modal_Checkout {
/**
* Checkout registration flag.
*
* @var string
*/
const CHECKOUT_REGISTRATION_FLAG = '_newspack_checkout_registration';

/**
* Checkout registration order meta key.
*
* @var string
*/
const CHECKOUT_REGISTRATION_ORDER_META_KEY = '_newspack_checkout_registration_meta';

/**
* Whether the modal checkout has been enqueued.
*
Expand Down Expand Up @@ -70,6 +84,7 @@ public static function init() {
/** Custom handling for registered users. */
add_filter( 'woocommerce_checkout_customer_id', [ __CLASS__, 'associate_existing_user' ] );
add_filter( 'woocommerce_checkout_posted_data', [ __CLASS__, 'skip_account_creation' ], 11 );
add_filter( 'woocommerce_checkout_create_order', [ __CLASS__, 'maybe_add_checkout_registration_order_meta' ], 10, 1 );

// Remove some stuff from the modal checkout page. It's displayed in an iframe, so it should not be treated as a separate page.
add_action( 'wp_enqueue_scripts', [ __CLASS__, 'dequeue_scripts' ], 11 );
Expand All @@ -85,6 +100,7 @@ public static function init() {
add_filter( 'googlesitekit_adsense_tag_blocked', [ __CLASS__, 'is_modal_checkout' ] );
add_filter( 'googlesitekit_tagmanager_tag_blocked', [ __CLASS__, 'is_modal_checkout' ] );
add_filter( 'jetpack_active_modules', [ __CLASS__, 'jetpack_active_modules' ] );
add_filter( 'woocommerce_checkout_update_order_review_expired', [ __CLASS__, 'is_not_modal_checkout_filter' ] );

/**
* Ensure that options to limit the number of subscriptions per product are respected.
Expand Down Expand Up @@ -137,116 +153,128 @@ public static function process_checkout_request() {
}

$is_newspack_checkout = filter_input( INPUT_GET, 'newspack_checkout', FILTER_SANITIZE_NUMBER_INT );
$is_newspack_donate = filter_input( INPUT_GET, 'newspack_donate', FILTER_SANITIZE_NUMBER_INT );
$product_id = filter_input( INPUT_GET, 'product_id', FILTER_SANITIZE_NUMBER_INT );
$variation_id = filter_input( INPUT_GET, 'variation_id', FILTER_SANITIZE_NUMBER_INT );
$after_success_behavior = filter_input( INPUT_GET, 'after_success_behavior', FILTER_SANITIZE_SPECIAL_CHARS );
$after_success_url = filter_input( INPUT_GET, 'after_success_url', FILTER_SANITIZE_URL );
$after_success_button_label = filter_input( INPUT_GET, 'after_success_button_label', FILTER_SANITIZE_SPECIAL_CHARS );
$is_checkout_registration = filter_input( INPUT_GET, self::CHECKOUT_REGISTRATION_FLAG, FILTER_SANITIZE_NUMBER_INT );

if ( ! $is_newspack_checkout || ! $product_id ) {
if ( ! $is_newspack_checkout && ! $is_newspack_donate ) {
return;
}
if ( $variation_id ) {
$product_id = $variation_id;

// Flag the checkout as a registration.
if ( $is_checkout_registration ) {
\WC()->session->set( self::CHECKOUT_REGISTRATION_FLAG, true );
}

\WC()->cart->empty_cart();
if ( $is_newspack_checkout ) {
if ( ! $product_id ) {
return;
}

$referer = wp_get_referer();
$params = [];
$parsed_url = wp_parse_url( $referer );
if ( $variation_id ) {
$product_id = $variation_id;
}

// Get URL params appended to the referer URL.
if ( ! empty( $parsed_url['query'] ) ) {
wp_parse_str( $parsed_url['query'], $params );
}
$referer = wp_get_referer();
$params = [];
$parsed_url = wp_parse_url( $referer );

$params = array_merge( $params, compact( 'after_success_behavior', 'after_success_url', 'after_success_button_label' ) );
// Get URL params appended to the referer URL.
if ( ! empty( $parsed_url['query'] ) ) {
wp_parse_str( $parsed_url['query'], $params );
}

if ( function_exists( 'wpcom_vip_url_to_postid' ) ) {
$referer_post_id = wpcom_vip_url_to_postid( $referer );
} else {
$referer_post_id = url_to_postid( $referer ); // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.url_to_postid_url_to_postid
}
$params = array_merge( $params, compact( 'after_success_behavior', 'after_success_url', 'after_success_button_label' ) );

$referer_tags = [];
$referer_categories = [];
$tags = get_the_tags( $referer_post_id );
if ( $tags && ! empty( $tags ) ) {
$referer_tags = array_map(
function ( $item ) {
return $item->slug;
},
$tags
);
}
if ( function_exists( 'wpcom_vip_url_to_postid' ) ) {
$referer_post_id = wpcom_vip_url_to_postid( $referer );
} else {
$referer_post_id = url_to_postid( $referer ); // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.url_to_postid_url_to_postid
}

$categories = get_the_category( $referer_post_id );
if ( $categories && ! empty( $categories ) ) {
$referer_categories = array_map(
function ( $item ) {
return $item->slug;
},
$categories
);
}
$referer_tags = [];
$referer_categories = [];
$tags = get_the_tags( $referer_post_id );
if ( $tags && ! empty( $tags ) ) {
$referer_tags = array_map(
function ( $item ) {
return $item->slug;
},
$tags
);
}

$cart_item_data = self::amend_cart_item_data( [ 'referer' => $referer ] );
$categories = get_the_category( $referer_post_id );
if ( $categories && ! empty( $categories ) ) {
$referer_categories = array_map(
function ( $item ) {
return $item->slug;
},
$categories
);
}

$newspack_popup_id = filter_input( INPUT_GET, 'newspack_popup_id', FILTER_SANITIZE_NUMBER_INT );
if ( $newspack_popup_id ) {
$cart_item_data['newspack_popup_id'] = $newspack_popup_id;
}
$cart_item_data = self::amend_cart_item_data( [ 'referer' => $referer ] );

/** Apply NYP custom price */
$price = filter_input( INPUT_GET, 'price', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
if ( \Newspack_Blocks::can_use_name_your_price() ? \WC_Name_Your_Price_Helpers::is_nyp( $product_id ) : false ) {
if ( empty( $price ) ) {
$price = \WC_Name_Your_Price_Helpers::get_suggested_price( $product_id );
$newspack_popup_id = filter_input( INPUT_GET, 'newspack_popup_id', FILTER_SANITIZE_NUMBER_INT );
if ( $newspack_popup_id ) {
$cart_item_data['newspack_popup_id'] = $newspack_popup_id;
}
$min_price = \WC_Name_Your_Price_Helpers::get_minimum_price( $product_id );
$max_price = \WC_Name_Your_Price_Helpers::get_maximum_price( $product_id );
$price = ! empty( $max_price ) ? min( $price, $max_price ) : $price;
$price = ! empty( $min_price ) ? max( $price, $min_price ) : $price;

$cart_item_data['nyp'] = (float) \WC_Name_Your_Price_Helpers::standardize_number( $price );
}
/** Apply NYP custom price */
$price = filter_input( INPUT_GET, 'price', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
if ( \Newspack_Blocks::can_use_name_your_price() ? \WC_Name_Your_Price_Helpers::is_nyp( $product_id ) : false ) {
if ( empty( $price ) ) {
$price = \WC_Name_Your_Price_Helpers::get_suggested_price( $product_id );
}
$min_price = \WC_Name_Your_Price_Helpers::get_minimum_price( $product_id );
$max_price = \WC_Name_Your_Price_Helpers::get_maximum_price( $product_id );
$price = ! empty( $max_price ) ? min( $price, $max_price ) : $price;
$price = ! empty( $min_price ) ? max( $price, $min_price ) : $price;

/**
* Filters the cart item data for the modal checkout.
*
* @param array $cart_item_data Cart item data.
*/
$cart_item_data = apply_filters( 'newspack_blocks_modal_checkout_cart_item_data', $cart_item_data );
$cart_item_data['nyp'] = (float) \WC_Name_Your_Price_Helpers::standardize_number( $price );
}

\WC()->cart->add_to_cart( $product_id, 1, 0, [], $cart_item_data );
/**
* Filters the cart item data for the modal checkout.
*
* @param array $cart_item_data Cart item data.
*/
$cart_item_data = apply_filters( 'newspack_blocks_modal_checkout_cart_item_data', $cart_item_data );

$query_args = [];
\WC()->cart->empty_cart();
\WC()->cart->add_to_cart( $product_id, 1, 0, [], $cart_item_data );

if ( ! empty( $referer_tags ) ) {
$query_args['referer_tags'] = implode( ',', $referer_tags );
}
if ( ! empty( $referer_categories ) ) {
$query_args['referer_categories'] = implode( ',', $referer_categories );
}
$query_args['modal_checkout'] = 1;
$query_args = [];
if ( ! empty( $referer_tags ) ) {
$query_args['referer_tags'] = implode( ',', $referer_tags );
}
if ( ! empty( $referer_categories ) ) {
$query_args['referer_categories'] = implode( ',', $referer_categories );
}
$query_args['modal_checkout'] = 1;

// Pass through UTM and after_success params so they can be forwarded to the WooCommerce checkout flow.
foreach ( $params as $param => $value ) {
if ( 'utm' === substr( $param, 0, 3 ) || 'after_success' === substr( $param, 0, 13 ) ) {
$param = sanitize_text_field( $param );
$query_args[ $param ] = sanitize_text_field( $value );
// Pass through UTM and after_success params so they can be forwarded to the WooCommerce checkout flow.
foreach ( $params as $param => $value ) {
if ( 'utm' === substr( $param, 0, 3 ) || 'after_success' === substr( $param, 0, 13 ) ) {
$param = sanitize_text_field( $param );
$query_args[ $param ] = sanitize_text_field( $value );
}
}
}

$checkout_url = add_query_arg(
$query_args,
\wc_get_page_permalink( 'checkout' )
);
$checkout_url = add_query_arg(
$query_args,
\wc_get_page_permalink( 'checkout' )
);

// Redirect to checkout.
\wp_safe_redirect( apply_filters( 'newspack_blocks_checkout_url', $checkout_url ) );
exit;
// Redirect to checkout.
\wp_safe_redirect( apply_filters( 'newspack_blocks_checkout_url', $checkout_url ) );
exit;
}
}

/**
Expand Down Expand Up @@ -571,8 +599,9 @@ public static function enqueue_modal( $product_id = null ) {
'newspack-blocks-modal',
'newspackBlocksModal',
[
'newspack_class_prefix' => self::get_class_prefix(),
'labels' => [
'checkout_registration_flag' => self::CHECKOUT_REGISTRATION_FLAG,
'newspack_class_prefix' => self::get_class_prefix(),
'labels' => [
'auth_modal_title' => self::get_modal_checkout_labels( 'auth_modal_title' ),
'signin_modal_title' => self::get_modal_checkout_labels( 'signin_modal_title' ),
'register_modal_title' => self::get_modal_checkout_labels( 'register_modal_title' ),
Expand Down Expand Up @@ -683,6 +712,11 @@ public static function woocommerce_get_return_url( $url, $order ) {
$args['key'] = $order->get_order_key();
}

// Pass checkout registration flag.
if ( isset( $_REQUEST[ self::CHECKOUT_REGISTRATION_FLAG ] ) && $_REQUEST[ self::CHECKOUT_REGISTRATION_FLAG ] ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
$args[ self::CHECKOUT_REGISTRATION_FLAG ] = '1';
}

return add_query_arg(
$args,
$url
Expand Down Expand Up @@ -1393,7 +1427,6 @@ public static function get_modal_checkout_labels( $key = null ) {
return self::$modal_checkout_labels[ $key ] ?? '';
}


/**
* Get price string for the price summary card to render in auth flow.
*
Expand Down Expand Up @@ -1425,5 +1458,24 @@ public static function get_summary_card_price_string( $name, $price = '', $frequ
// translators: 1 is the name of the item. 2 is the price of the item.
return sprintf( __( '%1$s: %2$s', 'newspack-blocks' ), $name, $price );
}

/**
* Conditionally adds the checkout registration order meta flag.
*
* @param WC_Order $order The order object.
*
* @return void.
*/
public static function maybe_add_checkout_registration_order_meta( $order ) {
if ( ! self::is_modal_checkout() ) {
return;
}

$is_checkout_registration = \WC()->session->get( self::CHECKOUT_REGISTRATION_FLAG );
if ( $is_checkout_registration ) {
$order->add_meta_data( self::CHECKOUT_REGISTRATION_ORDER_META_KEY, true, true );
\WC()->session->set( self::CHECKOUT_REGISTRATION_FLAG, null );
}
}
}
Modal_Checkout::init();
1 change: 1 addition & 0 deletions src/modal-checkout/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ domReady(
} else {
$nyp.find( 'input[name="price"]' ).focus();
}
$( document.body ).trigger( 'update_checkout' );
},
complete: () => {
input.attr( 'disabled', false );
Expand Down
11 changes: 8 additions & 3 deletions src/modal-checkout/modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ domReady( () => {
}

const modalContent = modalCheckout.querySelector( `.${ MODAL_CLASS_PREFIX }__content` );
const spinner = modalContent.querySelector( `.${ CLASS_PREFIX }__spinner` );
const modalCheckoutHiddenInput = createHiddenInput( 'modal_checkout', '1' );
const spinner = modalContent.querySelector( `.${ CLASS_PREFIX }__spinner` );

// Initialize empty iframe.
const iframe = document.createElement( 'iframe' );
Expand Down Expand Up @@ -300,9 +300,14 @@ domReady( () => {
// Initialize auth flow if reader is not authenticated.
window.newspackReaderActivation.openAuthModal( {
title: newspackBlocksModal.labels.auth_modal_title,
callback: () =>
callback: () => {
// Signal checkout registration.
form.appendChild(
createHiddenInput( newspackBlocksModal.checkout_registration_flag, '1' )
);
// form.submit does not trigger submit event listener, so we use requestSubmit.
form.requestSubmit( form.querySelector( 'button[type="submit"]' ) ),
form.requestSubmit( form.querySelector( 'button[type="submit"]' ) );
},
skipSuccess: true,
labels: {
signin: {
Expand Down

0 comments on commit 494b930

Please sign in to comment.