This commit is contained in:
emmymayo
2025-02-05 23:15:46 +01:00
commit 7269c99357
16995 changed files with 3389680 additions and 0 deletions
@@ -0,0 +1,204 @@
<?php
/**
* Jetpack_WooCommerce_Analytics_Checkout_Flow
*
* @deprecated 13.3
*
* @package automattic/jetpack
* @author Automattic
*/
/**
* Bail if accessed directly
*/
if ( ! defined( 'ABSPATH' ) ) {
exit( 0 );
}
/**
* Class Jetpack_WooCommerce_Analytics_Checkout_Flow
* Class that handles all page view events for the checkout flow (from product view to order confirmation view)
*
* @deprecated 13.3
*/
class Jetpack_WooCommerce_Analytics_Checkout_Flow {
use Jetpack_WooCommerce_Analytics_Trait;
/**
* Jetpack_WooCommerce_Analytics_Checkout_Flow constructor.
*
* @deprecated 13.3
*/
public function __construct() {
$this->find_cart_checkout_content_sources();
$this->additional_blocks_on_cart_page = $this->get_additional_blocks_on_page( 'cart' );
$this->additional_blocks_on_checkout_page = $this->get_additional_blocks_on_page( 'checkout' );
// single product page view.
add_action( 'woocommerce_after_single_product', array( $this, 'capture_product_view' ) );
// order confirmed page view
add_action( 'woocommerce_thankyou', array( $this, 'capture_order_confirmation_view' ), 10, 1 );
// cart page view
add_action( 'wp_footer', array( $this, 'capture_cart_view' ) );
// checkout page view
add_action( 'wp_footer', array( $this, 'capture_checkout_view' ) );
}
/**
* Track a product page view
*
* @deprecated 13.3
*/
public function capture_product_view() {
global $product;
if ( ! $product instanceof WC_Product ) {
return;
}
$this->record_event(
'woocommerceanalytics_product_view',
array(),
$product->get_id()
);
}
/**
* Track the order confirmation page view
*
* @deprecated 13.3
*/
public function capture_order_confirmation_view() {
$order_id = absint( get_query_var( 'order-received' ) );
if ( ! $order_id ) {
return;
}
if ( ! is_order_received_page() ) {
return;
}
$order = wc_get_order( $order_id );
$order_source = $order->get_created_via();
$checkout_page_contains_checkout_block = '0';
$checkout_page_contains_checkout_shortcode = '0';
if ( 'store-api' === $order_source ) {
$checkout_page_contains_checkout_block = '1';
$checkout_page_contains_checkout_shortcode = '0';
} elseif ( 'checkout' === $order_source ) {
$checkout_page_contains_checkout_block = '0';
$checkout_page_contains_checkout_shortcode = '1';
}
$coupons = $order->get_coupons();
$coupon_used = 0;
if ( is_countable( $coupons ) ) {
$coupon_used = count( $coupons ) ? 1 : 0;
}
if ( is_object( WC()->session ) ) {
$create_account = true === WC()->session->get( 'wc_checkout_createaccount_used' ) ? 'Yes' : 'No';
$checkout_page_used = true === WC()->session->get( 'checkout_page_used' ) ? 'Yes' : 'No';
} else {
$create_account = 'No';
$checkout_page_used = 'No';
}
$this->record_event(
'woocommerceanalytics_order_confirmation_view',
array(
'coupon_used' => $coupon_used,
'create_account' => $create_account,
'express_checkout' => 'null', // TODO: not solved yet.
'guest_checkout' => $order->get_customer_id() ? 'No' : 'Yes',
'oi' => $order->get_id(),
'order_value' => $order->get_total(),
'payment_option' => $order->get_payment_method(),
'products_count' => $order->get_item_count(),
'products' => $this->format_items_to_json( $order->get_items() ),
'order_note' => $order->get_customer_note(),
'shipping_option' => $order->get_shipping_method(),
'from_checkout' => $checkout_page_used,
'checkout_page_contains_checkout_block' => $checkout_page_contains_checkout_block,
'checkout_page_contains_checkout_shortcode' => $checkout_page_contains_checkout_shortcode,
)
);
}
/**
* Track the cart page view
*
* @deprecated 13.3
*/
public function capture_cart_view() {
if ( ! is_cart() ) {
return;
}
$this->record_event(
'woocommerceanalytics_cart_view',
array_merge(
$this->get_cart_checkout_shared_data(),
array()
)
);
}
/**
* Track the checkout page view
*
* @deprecated 13.3
*/
public function capture_checkout_view() {
global $post;
$checkout_page_id = wc_get_page_id( 'checkout' );
$is_checkout = $checkout_page_id && is_page( $checkout_page_id )
|| wc_post_content_has_shortcode( 'woocommerce_checkout' )
|| has_block( 'woocommerce/checkout', $post )
|| has_block( 'woocommerce/classic-shortcode', $post )
|| apply_filters( 'woocommerce_is_checkout', false )
|| \Automattic\Jetpack\Constants::is_defined( 'WOOCOMMERCE_CHECKOUT' );
if ( ! $is_checkout ) {
return;
}
$is_in_checkout_page = $checkout_page_id === $post->ID ? 'Yes' : 'No';
$checkout_page_contains_checkout_block = '0';
$checkout_page_contains_checkout_shortcode = '1';
$session = WC()->session;
if ( is_object( $session ) ) {
$session->set( 'checkout_page_used', true );
$session->save_data();
$draft_order_id = $session->get( 'store_api_draft_order', 0 );
if ( $draft_order_id ) {
$checkout_page_contains_checkout_block = '1';
$checkout_page_contains_checkout_shortcode = '0';
}
}
// Order received page is also a checkout page, so we need to bail out if we are on that page.
if ( is_order_received_page() ) {
return;
}
$this->record_event(
'woocommerceanalytics_checkout_view',
array_merge(
$this->get_cart_checkout_shared_data(),
array(
'from_checkout' => $is_in_checkout_page,
'checkout_page_contains_checkout_block' => $checkout_page_contains_checkout_block,
'checkout_page_contains_checkout_shortcode' => $checkout_page_contains_checkout_shortcode,
)
)
);
}
}
@@ -0,0 +1,358 @@
<?php
/**
* Jetpack_WooCommerce_Analytics_My_Account
*
* @deprecated 13.3
*
* @package automattic/jetpack
* @author Automattic
*/
/**
* Bail if accessed directly
*/
if ( ! defined( 'ABSPATH' ) ) {
exit( 0 );
}
/**
* Class Jetpack_WooCommerce_Analytics_My_Account
* Filters and Actions added to My Account pages to perform analytics
*
* @deprecated 13.3
*/
class Jetpack_WooCommerce_Analytics_My_Account {
use Jetpack_WooCommerce_Analytics_Trait;
/**
* Jetpack_WooCommerce_Analytics_My_Account constructor.
*
* @deprecated 13.3
*/
public function __construct() {
add_action( 'woocommerce_account_content', array( $this, 'track_tabs' ) );
add_action( 'woocommerce_account_content', array( $this, 'track_logouts' ) );
add_action( 'woocommerce_customer_save_address', array( $this, 'track_save_address' ), 10, 2 );
add_action( 'wp_head', array( $this, 'trigger_queued_events' ) );
add_action( 'wp', array( $this, 'track_add_payment_method' ) );
add_action( 'wp', array( $this, 'track_delete_payment_method' ) );
add_action( 'woocommerce_save_account_details', array( $this, 'track_save_account_details' ) );
add_filter( 'woocommerce_my_account_my_orders_actions', array( $this, 'add_initiator_prop_to_my_account_action_links' ) );
add_action( 'woocommerce_cancelled_order', array( $this, 'track_order_cancel_event' ), 10, 0 );
add_action( 'before_woocommerce_pay', array( $this, 'track_order_pay_event' ) );
add_action( 'woocommerce_before_account_orders', array( $this, 'add_initiator_prop_to_order_urls' ), 9 );
add_filter( 'query_vars', array( $this, 'add_initiator_param_to_query_vars' ) );
}
/**
* Track my account tabs, we only trigger an event if a tab is viewed.
*
* We also track other events here, like order number clicks, order action clicks,
* address clicks, payment method add and delete.
*
* @deprecated 13.3
*/
public function track_tabs() {
global $wp;
// WooCommerce keeps a map of my-account endpoints keys and their custom permalinks.
$core_endpoints = WC()->query->get_query_vars();
if ( ! empty( $wp->query_vars ) ) {
foreach ( $wp->query_vars as $key => $value ) {
// we skip pagename.
if ( 'pagename' === $key ) {
continue;
}
// When no permalink is set, the first page is page_id, so we skip it.
if ( 'page_id' === $key ) {
continue;
}
// We don't want to track our own analytics params.
if ( '_wca_initiator' === $key ) {
continue;
}
if ( isset( $core_endpoints['view-order'] ) && $core_endpoints['view-order'] === $key && is_numeric( $value ) ) {
$initiator = get_query_var( '_wca_initiator' );
if ( 'number' === $initiator ) {
$this->record_event( 'woocommerceanalytics_my_account_order_number_click' );
continue;
}
if ( 'action' === $initiator ) {
$this->record_event( 'woocommerceanalytics_my_account_order_action_click', array( 'action' => 'view' ) );
continue;
}
}
if ( isset( $core_endpoints['edit-address'] ) && $core_endpoints['edit-address'] === $key && in_array( $value, array( 'billing', 'shipping' ), true ) ) {
$refer = wp_get_referer();
if ( $refer === wc_get_endpoint_url( 'edit-address', $value ) ) {
// It means we're likely coming from the same page after a failed save and don't want to retrigger the address click event.
continue;
}
$this->record_event( 'woocommerceanalytics_my_account_address_click', array( 'address' => $value ) );
continue;
}
if ( isset( $core_endpoints['add-payment-method'] ) && $core_endpoints['add-payment-method'] === $key ) {
$this->record_event( 'woocommerceanalytics_my_account_payment_add' );
continue;
}
if ( isset( $core_endpoints['edit-address'] ) && $core_endpoints['edit-address'] ) {
$refer = wp_get_referer();
if ( $refer === wc_get_endpoint_url( 'edit-address', 'billing' ) || $refer === wc_get_endpoint_url( 'edit-address', 'shipping' ) ) {
// It means we're likely coming from the edit page save and don't want to retrigger the page view event.
continue;
}
}
/**
* The main dashboard view has page as key, so we rename it.
*/
if ( 'page' === $key ) {
$key = 'dashboard';
}
/**
* If a custom permalink is used for one of the pages, query_vars will have 2 keys, the custom permalink and the core endpoint key.
* To avoid triggering the event twice, we skip the core one and only track the custom one.
* Tracking the custom endpoint is safer than hoping the duplicated, redundant core endpoint is always present.
*/
if ( isset( $core_endpoints[ $key ] ) && $core_endpoints[ $key ] !== $key ) {
continue;
}
/**
* $core_endpoints is an array of core_permalink => custom_permalink,
* query_vars gives us the custom_permalink, but we want to track it as core_permalink.
*/
if ( array_search( $key, $core_endpoints, true ) ) {
$key = array_search( $key, $core_endpoints, true );
}
$this->record_event( 'woocommerceanalytics_my_account_page_view', array( 'tab' => $key ) );
}
}
}
/**
* Track address save events, this can only come from the my account page.
*
* @deprecated 13.3
*
* @param int $customer_id The customer id.
* @param string $load_address The address type (billing, shipping).
*/
public function track_save_address( $customer_id, $load_address ) {
$this->queue_event( 'woocommerceanalytics_my_account_address_save', array( 'address' => $load_address ) );
}
/**
* Track payment method add events, this can only come from the my account page.
*
* @deprecated 13.3
*/
public function track_add_payment_method() {
if ( isset( $_POST['woocommerce_add_payment_method'] ) && isset( $_POST['payment_method'] ) ) {
$nonce_value = wc_get_var( $_REQUEST['woocommerce-add-payment-method-nonce'], wc_get_var( $_REQUEST['_wpnonce'], '' ) ); // @codingStandardsIgnoreLine.
if ( ! wp_verify_nonce( $nonce_value, 'woocommerce-add-payment-method' ) ) {
return;
}
$this->queue_event( 'woocommerceanalytics_my_account_payment_save' );
return;
}
}
/**
* Track payment method delete events.
*
* @deprecated 13.3
*/
public function track_delete_payment_method() {
global $wp;
if ( isset( $wp->query_vars['delete-payment-method'] ) ) {
$this->queue_event( 'woocommerceanalytics_my_account_payment_delete' );
return;
}
}
/**
* Track order cancel events.
*
* @deprecated 13.3
*/
public function track_order_cancel_event() {
if ( isset( $_GET['_wca_initiator'] ) && ( isset( $_GET['_wpnonce'] ) && wp_verify_nonce( wp_unslash( $_GET['_wpnonce'] ), 'woocommerce-cancel_order' ) ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$this->queue_event( 'woocommerceanalytics_my_account_order_action_click', array( 'action' => 'cancel' ) );
}
}
/**
* Track order pay events.
*
* @deprecated 13.3
*/
public function track_order_pay_event() {
if ( isset( $_GET['_wca_initiator'] ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.NonceVerification.Recommended
$this->record_event( 'woocommerceanalytics_my_account_order_action_click', array( 'action' => 'pay' ) );
}
}
/**
* Track account details save events, this can only come from the my account page.
*
* @deprecated 13.3
*/
public function track_save_account_details() {
$this->queue_event( 'woocommerceanalytics_my_account_details_save' );
}
/**
* Track logout events.
*
* @deprecated 13.3
*/
public function track_logouts() {
$common_props = $this->render_properties_as_js(
$this->get_common_properties()
);
wc_enqueue_js(
"
jQuery(document).ready(function($) {
// Attach event listener to the logout link
jQuery('.woocommerce-MyAccount-navigation-link--customer-logout').on('click', function() {
_wca.push({
'_en': 'woocommerceanalytics_my_account_tab_click',
'tab': 'logout'," .
$common_props . '
});
});
});
'
);
}
/**
* Add referrer prop to my account action links
*
* @deprecated 13.3
*
* @param array $actions My account action links.
* @return array
*/
public function add_initiator_prop_to_my_account_action_links( $actions ) {
foreach ( $actions as $key => $action ) {
if ( ! isset( $action['url'] ) ) {
continue;
}
// Check if the action key is view, pay, or cancel.
if ( ! in_array( $key, array( 'view', 'pay', 'cancel' ), true ) ) {
continue;
}
$url = add_query_arg( array( '_wca_initiator' => 'action' ), $action['url'] );
$actions[ $key ]['url'] = $url;
}
return $actions;
}
/**
* Add an initiator prop to the order url.
*
* The get_view_order_url is used in a lot of places,
* so we want to limit it just to my account page.
*
* @deprecated 13.3
*/
public function add_initiator_prop_to_order_urls() {
add_filter(
'woocommerce_get_view_order_url',
function ( $url ) {
return add_query_arg( array( '_wca_initiator' => 'number' ), $url );
},
10,
1
);
add_filter(
'woocommerce_get_endpoint_url',
function ( $url, $endpoint ) {
if ( 'edit-address' === $endpoint ) {
return add_query_arg( array( '_wca_initiator' => 'action' ), $url );
}
return $url;
},
10,
2
);
}
/**
* Add initiator to query vars
*
* @deprecated 13.3
*
* @param array $query_vars Query vars.
* @return array
*/
public function add_initiator_param_to_query_vars( $query_vars ) {
$query_vars[] = '_wca_initiator';
return $query_vars;
}
/**
* Record all queued up events in session.
*
* This is called on every page load, and will record all events that were queued up in session.
*
* @deprecated 13.3
*/
public function trigger_queued_events() {
if ( is_object( WC()->session ) ) {
$events = WC()->session->get( 'wca_queued_events', array() );
foreach ( $events as $event ) {
$this->record_event(
$event['event_name'],
$event['event_props']
);
}
// Clear data, now that these events have been recorded.
WC()->session->set( 'wca_queued_events', array() );
}
}
/**
* Queue an event in session to be recorded later on next page load.
*
* @deprecated 13.3
*
* @param string $event_name The event name.
* @param array $event_props The event properties.
*/
protected function queue_event( $event_name, $event_props = array() ) {
if ( is_object( WC()->session ) ) {
$events = WC()->session->get( 'wca_queued_events', array() );
$events[] = array(
'event_name' => $event_name,
'event_props' => $event_props,
);
WC()->session->set( 'wca_queued_events', $events );
}
}
}
@@ -0,0 +1,597 @@
<?php
/**
* Jetpack_WooCommerce_Analytics_Trait
*
* @deprecated 13.3
*
* @package automattic/jetpack
* @author Automattic
*/
/**
* Bail if accessed directly
*/
if ( ! defined( 'ABSPATH' ) ) {
exit( 0 );
}
/**
* Jetpack_WooCommerce_Analytics_Trait
* Common functionality for WooCommerce Analytics classes.
*
* @deprecated 13.3
*/
trait Jetpack_WooCommerce_Analytics_Trait {
/**
* Saves whether the cart/checkout templates are in use based on WC Blocks version.
*
* @var bool true if the templates are in use.
*/
protected $cart_checkout_templates_in_use;
/**
* The content of the cart page or where the cart page is ultimately derived from if using a template.
*
* @var string
*/
protected $cart_content_source = '';
/**
* The content of the checkout page or where the cart page is ultimately derived from if using a template.
*
* @var string
*/
protected $checkout_content_source = '';
/**
* Tracks any additional blocks loaded on the Cart page.
*
* @var array
*/
protected $additional_blocks_on_cart_page;
/**
* Tracks any additional blocks loaded on the Checkout page.
*
* @var array
*/
protected $additional_blocks_on_checkout_page;
/**
* Format Cart Items or Order Items to an array
*
* @deprecated 13.3
*
* @param array|WC_Order_Item[] $items Cart Items or Order Items.
*/
protected function format_items_to_json( $items ) {
$products = array();
foreach ( $items as $item ) {
if ( $item instanceof WC_Order_Item_Product ) {
$product = wc_get_product( $item->get_product_id() );
} else {
$product = $item['data'];
}
if ( ! $product || ! $product instanceof WC_Product ) {
continue;
}
$data = $this->get_product_details( $product );
if ( $item instanceof WC_Order_Item_Product ) {
$data['pq'] = $item->get_quantity();
} else {
$data['pq'] = $item['quantity'];
}
$products[] = $data;
}
return wp_json_encode( $products );
}
/**
* Get Cart/Checkout page view shared data
*
* @deprecated 13.3
*/
protected function get_cart_checkout_shared_data() {
$cart = WC()->cart;
$guest_checkout = ucfirst( get_option( 'woocommerce_enable_guest_checkout', 'No' ) );
$create_account = ucfirst( get_option( 'woocommerce_enable_signup_and_login_from_checkout', 'No' ) );
$coupons = $cart->get_coupons();
$coupon_used = 0;
if ( is_countable( $coupons ) ) {
$coupon_used = count( $coupons ) ? 1 : 0;
}
$enabled_payment_options = array_filter(
WC()->payment_gateways->get_available_payment_gateways(),
function ( $payment_gateway ) {
if ( ! $payment_gateway instanceof WC_Payment_Gateway ) {
return false;
}
return $payment_gateway->is_available();
}
);
$enabled_payment_options = array_keys( $enabled_payment_options );
$cart_total = wc_prices_include_tax() ? $cart->get_cart_contents_total() + $cart->get_cart_contents_tax() : $cart->get_cart_contents_total();
$shared_data = array(
'products' => $this->format_items_to_json( $cart->get_cart() ),
'create_account' => $create_account,
'guest_checkout' => $guest_checkout,
'express_checkout' => 'null', // TODO: not solved yet.
'products_count' => $cart->get_cart_contents_count(),
'order_value' => $cart_total,
'shipping_options_count' => 'null', // TODO: not solved yet.
'coupon_used' => $coupon_used,
'payment_options' => $enabled_payment_options,
);
return $shared_data;
}
/**
* Gets the content of the cart/checkout page or where the cart/checkout page is ultimately derived from if using a template.
* This method sets the class properties $checkout_content_source and $cart_content_source.
*
* @deprecated 13.3
*
* @return void Does not return, but sets class properties.
*/
public function find_cart_checkout_content_sources() {
/**
* The steps we take to find the content are:
* 1. Check the transient, if that contains content and is not expired, return that.
* 2. Check if the cart/checkout templates are in use. If *not in use*, get the content from the pages and
* return it, there is no need to dig further.
* 3. If the templates *are* in use, check if the `page-content-wrapper` block is in use. If so, get the content
* from the pages (same as step 2) and return it.
* 4. If the templates are in use but `page-content-wrapper` is not, then get the content directly from the
* template and return it.
* 5. At the end of each step, assign the found content to the relevant class properties and save them in a
* transient with a 1-day lifespan. This will prevent us from having to do this work on every page load.
*/
$cart_checkout_content_cache_transient_name = 'jetpack_woocommerce_analytics_cart_checkout_content_sources';
$transient_value = get_transient( $cart_checkout_content_cache_transient_name );
if (
false !== $transient_value &&
! empty( $transient_value['checkout_content_source'] ) &&
! empty( $transient_value['cart_content_source'] )
) {
$this->cart_content_source = $transient_value['cart_content_source'];
$this->checkout_content_source = $transient_value['checkout_content_source'];
return;
}
$this->cart_checkout_templates_in_use = wp_is_block_theme() && class_exists( 'Automattic\WooCommerce\Blocks\Package' ) && version_compare( Automattic\WooCommerce\Blocks\Package::get_version(), '10.6.0', '>=' );
// Cart/Checkout *pages* are in use if the templates are not in use. Return their content and do nothing else.
if ( ! $this->cart_checkout_templates_in_use ) {
$cart_page = get_post( wc_get_page_id( 'cart' ) );
$checkout_page = get_post( wc_get_page_id( 'checkout' ) );
if ( $cart_page && isset( $cart_page->post_content ) ) {
$this->cart_content_source = $cart_page->post_content;
}
if ( $checkout_page && isset( $checkout_page->post_content ) ) {
$this->checkout_content_source = $checkout_page->post_content;
}
set_transient(
$cart_checkout_content_cache_transient_name,
array(
'cart_content_source' => $this->cart_content_source,
'checkout_content_source' => $this->checkout_content_source,
),
DAY_IN_SECONDS
);
return;
}
// We are in a Block theme - so we need to find out if the templates are being used.
if ( function_exists( 'get_block_template' ) ) {
$checkout_template = get_block_template( 'woocommerce/woocommerce//page-checkout' );
$cart_template = get_block_template( 'woocommerce/woocommerce//page-cart' );
if ( ! $checkout_template ) {
$checkout_template = get_block_template( 'woocommerce/woocommerce//checkout' );
}
if ( ! $cart_template ) {
$cart_template = get_block_template( 'woocommerce/woocommerce//cart' );
}
}
if ( ! empty( $checkout_template->content ) ) {
// Checkout template is in use, but we need to see if the page-content-wrapper is in use, or if the template is being used directly.
$this->checkout_content_source = $checkout_template->content;
$is_using_page_content = str_contains( $checkout_template->content, '<!-- wp:woocommerce/page-content-wrapper {"page":"checkout"}' );
if ( $is_using_page_content ) {
// The page-content-wrapper is in use, so we need to get the page content.
$checkout_page = get_post( wc_get_page_id( 'checkout' ) );
if ( $checkout_page && isset( $checkout_page->post_content ) ) {
$this->checkout_content_source = $checkout_page->post_content;
}
}
}
if ( ! empty( $cart_template->content ) ) {
// Cart template is in use, but we need to see if the page-content-wrapper is in use, or if the template is being used directly.
$this->cart_content_source = $cart_template->content;
$is_using_page_content = str_contains( $cart_template->content, '<!-- wp:woocommerce/page-content-wrapper {"page":"cart"}' );
if ( $is_using_page_content ) {
// The page-content-wrapper is in use, so we need to get the page content.
$cart_page = get_post( wc_get_page_id( 'cart' ) );
if ( $cart_page && isset( $cart_page->post_content ) ) {
$this->cart_content_source = $cart_page->post_content;
}
}
}
set_transient(
$cart_checkout_content_cache_transient_name,
array(
'cart_content_source' => $this->cart_content_source,
'checkout_content_source' => $this->checkout_content_source,
),
DAY_IN_SECONDS
);
}
/**
* Default event properties which should be included with all events.
*
* @deprecated 13.3
*
* @return array Array of standard event props.
*/
public function get_common_properties() {
$site_info = array(
'blog_id' => Jetpack::get_option( 'id' ),
'ui' => $this->get_user_id(),
'url' => home_url(),
'woo_version' => WC()->version,
'store_admin' => in_array( array( 'administrator', 'shop_manager' ), wp_get_current_user()->roles, true ) ? 1 : 0,
'device' => wp_is_mobile() ? 'mobile' : 'desktop',
'template_used' => $this->cart_checkout_templates_in_use ? '1' : '0',
'additional_blocks_on_cart_page' => $this->additional_blocks_on_cart_page,
'additional_blocks_on_checkout_page' => $this->additional_blocks_on_checkout_page,
'store_currency' => get_woocommerce_currency(),
);
$cart_checkout_info = $this->get_cart_checkout_info();
return array_merge( $site_info, $cart_checkout_info );
}
/**
* Render tracks event properties as string of JavaScript object props.
*
* @deprecated 13.3
*
* @param array $properties Array of key/value pairs.
* @return string String of the form "key1: value1, key2: value2, " (etc).
*/
private function render_properties_as_js( $properties ) {
$js_args_string = '';
foreach ( $properties as $key => $value ) {
if ( is_array( $value ) ) {
$js_args_string = $js_args_string . "'$key': " . wp_json_encode( $value ) . ',';
} else {
$js_args_string = $js_args_string . "'$key': '" . esc_js( $value ) . "', ";
}
}
return $js_args_string;
}
/**
* Record an event with optional product and custom properties.
*
* @deprecated 13.3
*
* @param string $event_name The name of the event to record.
* @param array $properties Optional array of (key => value) event properties.
* @param integer $product_id The id of the product relating to the event.
*
* @return string|void
*/
public function record_event( $event_name, $properties = array(), $product_id = null ) {
$js = $this->process_event_properties( $event_name, $properties, $product_id );
wc_enqueue_js( "_wca.push({$js});" );
}
/**
* Gather relevant product information
*
* @deprecated 13.3
*
* @param \WC_Product $product product.
* @return array
*/
public function get_product_details( $product ) {
return array(
'pi' => $product->get_id(),
'pn' => $product->get_title(),
'pc' => $this->get_product_categories_concatenated( $product ),
'pp' => $product->get_price(),
'pt' => $product->get_type(),
);
}
/**
* Gets product categories or varation attributes as a formatted concatenated string
*
* @deprecated 13.3
*
* @param object $product WC_Product.
* @return string
*/
public function get_product_categories_concatenated( $product ) {
if ( ! $product instanceof WC_Product ) {
return '';
}
$variation_data = $product->is_type( 'variation' ) ? wc_get_product_variation_attributes( $product->get_id() ) : '';
if ( is_array( $variation_data ) && ! empty( $variation_data ) ) {
$line = wc_get_formatted_variation( $variation_data, true );
} else {
$out = array();
$categories = get_the_terms( $product->get_id(), 'product_cat' );
if ( $categories ) {
foreach ( $categories as $category ) {
$out[] = $category->name;
}
}
$line = implode( '/', $out );
}
return $line;
}
/**
* Compose event properties.
*
* @deprecated 13.3
*
* @param string $event_name The name of the event to record.
* @param array $properties Optional array of (key => value) event properties.
* @param integer $product_id Optional id of the product relating to the event.
*
* @return string|void
*/
public function process_event_properties( $event_name, $properties = array(), $product_id = null ) {
// Only set product details if we have a product id.
if ( $product_id ) {
$product = wc_get_product( $product_id );
if ( ! $product instanceof WC_Product ) {
return;
}
$product_details = $this->get_product_details( $product );
}
/**
* Allow defining custom event properties in WooCommerce Analytics.
*
* @module woocommerce-analytics
*
* @since 12.5
*
* @param array $all_props Array of event props to be filtered.
*/
$all_props = apply_filters(
'jetpack_woocommerce_analytics_event_props',
array_merge(
$this->get_common_properties(), // We put this here to allow override of common props.
$properties
)
);
$js = "{'_en': '" . esc_js( $event_name ) . "'";
if ( isset( $product_details ) ) {
$all_props = array_merge( $all_props, $product_details );
}
$js .= ',' . $this->render_properties_as_js( $all_props ) . '}';
return $js;
}
/**
* Get the current user id
*
* @deprecated 13.3
*
* @return int
*/
public function get_user_id() {
if ( is_user_logged_in() ) {
$blogid = Jetpack::get_option( 'id' );
$userid = get_current_user_id();
return $blogid . ':' . $userid;
}
return 'null';
}
/**
* Gets the IDs of additional blocks on the Cart/Checkout pages or templates.
*
* @deprecated 13.3
*
* @param string $cart_or_checkout Whether to get blocks on the cart or checkout page.
* @return array All inner blocks on the page.
*/
public function get_additional_blocks_on_page( $cart_or_checkout = 'cart' ) {
$additional_blocks_on_page_transient_name = 'jetpack_woocommerce_analytics_additional_blocks_on_' . $cart_or_checkout . '_page';
$additional_blocks_on_page = get_transient( $additional_blocks_on_page_transient_name );
if ( false !== $additional_blocks_on_page ) {
return $additional_blocks_on_page;
}
$content = $this->cart_content_source;
if ( 'checkout' === $cart_or_checkout ) {
$content = $this->checkout_content_source;
}
$parsed_blocks = parse_blocks( $content );
$other_blocks = array_filter(
$parsed_blocks,
function ( $block ) use ( $cart_or_checkout ) {
if ( ! isset( $block['blockName'] ) ) {
return false;
}
if ( 'woocommerce/classic-shortcode' === $block['blockName'] ) {
return false;
}
if ( 'core/shortcode' === $block['blockName'] ) {
return false;
}
if ( 'checkout' === $cart_or_checkout && 'woocommerce/checkout' !== $block['blockName'] ) {
return true;
}
if ( 'cart' === $cart_or_checkout && 'woocommerce/cart' !== $block['blockName'] ) {
return true;
}
return false;
}
);
$all_inner_blocks = array();
// Loop over each "block group". In templates the blocks are grouped up.
foreach ( $other_blocks as $block ) {
// This check is necessary because sometimes this is null when using templates.
if ( ! empty( $block['blockName'] ) ) {
$all_inner_blocks[] = $block['blockName'];
}
if ( ! isset( $block['innerBlocks'] ) || ! is_array( $block['innerBlocks'] ) || 0 === count( $block['innerBlocks'] ) ) {
continue;
}
foreach ( $block['innerBlocks'] as $inner_content ) {
$all_inner_blocks = array_merge( $all_inner_blocks, $this->get_inner_blocks( $inner_content ) );
}
}
set_transient( $additional_blocks_on_page_transient_name, $all_inner_blocks, DAY_IN_SECONDS );
return $all_inner_blocks;
}
/**
* Gets an array containing the block or shortcode use properties for the Cart page.
*
* @deprecated 13.3
*
* @return array An array containing the block or shortcode use properties for the Cart page.
*/
public function get_cart_page_block_usage() {
$new_info = array();
$content = $this->cart_content_source;
$block_presence = str_contains( $content, '<!-- wp:woocommerce/cart' );
$shortcode_presence = str_contains( $content, '[woocommerce_cart]' );
$classic_shortcode_presence = str_contains( $content, '<!-- wp:woocommerce/classic-shortcode' );
$new_info['cart_page_contains_cart_block'] = $block_presence ? '1' : '0';
$new_info['cart_page_contains_cart_shortcode'] = $shortcode_presence || $classic_shortcode_presence ? '1' : '0';
return $new_info;
}
/**
* Gets an array containing the block or shortcode use properties for the Checkout page.
*
* @deprecated 13.3
*
* @return array An array containing the block or shortcode use properties for the Checkout page.
*/
public function get_checkout_page_block_usage() {
$new_info = array();
$content = $this->checkout_content_source;
$block_presence = str_contains( $content, '<!-- wp:woocommerce/checkout' );
$shortcode_presence = str_contains( $content, '[woocommerce_checkout]' );
$classic_shortcode_presence = str_contains( $content, '<!-- wp:woocommerce/classic-shortcode' );
$new_info['checkout_page_contains_checkout_block'] = $block_presence ? '1' : '0';
$new_info['checkout_page_contains_checkout_shortcode'] = $shortcode_presence || $classic_shortcode_presence ? '1' : '0';
return $new_info;
}
/**
* Get info about the cart & checkout pages, in particular
* whether the store is using shortcodes or Gutenberg blocks.
* This info is cached in a transient.
*
* Note: similar code is in a WooCommerce core PR:
* https://github.com/woocommerce/woocommerce/pull/25932
*
* @deprecated 13.3
*
* @return array
*/
public function get_cart_checkout_info() {
$info = array_merge(
$this->get_cart_page_block_usage(),
$this->get_checkout_page_block_usage()
);
return $info;
}
/**
* Search a specific post for text content.
*
* Note: similar code is in a WooCommerce core PR:
* https://github.com/woocommerce/woocommerce/pull/25932
*
* @deprecated 13.3
*
* @param integer $post_id The id of the post to search.
* @param string $text The text to search for.
* @return integer 1 if post contains $text (otherwise 0).
*/
public function post_contains_text( $post_id, $text ) {
global $wpdb;
// Search for the text anywhere in the post.
$wildcarded = "%{$text}%";
// No better way to search post content without having filters expanding blocks.
// This is already cached up in the parent function.
$result = $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
$wpdb->prepare(
"
SELECT COUNT( * ) FROM {$wpdb->prefix}posts
WHERE ID=%d
AND {$wpdb->prefix}posts.post_content LIKE %s
",
array( $post_id, $wildcarded )
)
);
return ( '0' !== $result ) ? 1 : 0;
}
}
@@ -0,0 +1,552 @@
<?php
/**
* Jetpack_WooCommerce_Analytics_Universal
*
* @deprecated 13.3
*
* @package automattic/jetpack
* @author Automattic
*/
/**
* Bail if accessed directly
*/
if ( ! defined( 'ABSPATH' ) ) {
exit( 0 );
}
/**
* Class Jetpack_WooCommerce_Analytics_Universal
* Filters and Actions added to Store pages to perform analytics
*
* @deprecated 13.3
*/
class Jetpack_WooCommerce_Analytics_Universal {
/**
* Trait to handle common analytics functions.
*/
use Jetpack_WooCommerce_Analytics_Trait;
/**
* Jetpack_WooCommerce_Analytics_Universal constructor.
*
* @deprecated 13.3
*/
public function __construct() {
$this->find_cart_checkout_content_sources();
$this->additional_blocks_on_cart_page = $this->get_additional_blocks_on_page( 'cart' );
$this->additional_blocks_on_checkout_page = $this->get_additional_blocks_on_page( 'checkout' );
// add to carts from non-product pages or lists -- search, store etc.
add_action( 'wp_head', array( $this, 'loop_session_events' ), 2 );
// Capture cart events.
add_action( 'woocommerce_add_to_cart', array( $this, 'capture_add_to_cart' ), 10, 6 );
add_action( 'woocommerce_after_cart', array( $this, 'remove_from_cart' ) );
add_action( 'woocommerce_after_mini_cart', array( $this, 'remove_from_cart' ) );
add_action( 'wcct_before_cart_widget', array( $this, 'remove_from_cart' ) );
add_filter( 'woocommerce_cart_item_remove_link', array( $this, 'remove_from_cart_attributes' ), 10, 2 );
// Checkout.
// Send events after checkout template (shortcode).
add_action( 'woocommerce_after_checkout_form', array( $this, 'checkout_process' ) );
// Send events after checkout block.
add_action( 'woocommerce_blocks_enqueue_checkout_block_scripts_after', array( $this, 'checkout_process' ) );
// order confirmed.
add_action( 'woocommerce_thankyou', array( $this, 'order_process' ), 10, 1 );
add_action( 'woocommerce_after_cart', array( $this, 'remove_from_cart_via_quantity' ), 10, 1 );
add_filter( 'woocommerce_checkout_posted_data', array( $this, 'save_checkout_post_data' ), 10, 1 );
add_action( 'woocommerce_created_customer', array( $this, 'capture_created_customer' ), 10, 2 );
}
/**
* On product lists or other non-product pages, add an event listener to "Add to Cart" button click
*
* @deprecated 13.3
*/
public function loop_session_events() {
// Check for previous events queued in session data.
if ( is_object( WC()->session ) ) {
$data = WC()->session->get( 'wca_session_data' );
if ( ! empty( $data ) ) {
foreach ( $data as $data_instance ) {
$this->record_event(
$data_instance['event'],
array(
'pq' => $data_instance['quantity'],
),
$data_instance['product_id']
);
}
// Clear data, now that these events have been recorded.
WC()->session->set( 'wca_session_data', '' );
}
}
}
/**
* On the cart page, add an event listener for removal of product click
*
* @deprecated 13.3
*/
public function remove_from_cart() {
$common_props = $this->render_properties_as_js(
$this->get_common_properties()
);
// We listen at div.woocommerce because the cart 'form' contents get forcibly
// updated and subsequent removals from cart would then not have this click
// handler attached.
wc_enqueue_js(
"jQuery( 'div.woocommerce' ).on( 'click', 'a.remove', function() {
var productID = jQuery( this ).data( 'product_id' );
var quantity = jQuery( this ).parent().parent().find( '.qty' ).val()
var productDetails = {
'id': productID,
'quantity': quantity ? quantity : '1',
};
_wca.push( {
'_en': 'woocommerceanalytics_remove_from_cart',
'pi': productDetails.id,
'pq': productDetails.quantity, " .
$common_props . '
} );
} );'
);
}
/**
* Adds the product ID to the remove product link (for use by remove_from_cart above) if not present
*
* @deprecated 13.3
*
* @param string $url Full HTML a tag of the link to remove an item from the cart.
* @param string $key Unique Key ID for a cart item.
*
* @return string
*/
public function remove_from_cart_attributes( $url, $key ) {
if ( str_contains( $url, 'data-product_id' ) ) {
return $url;
}
$item = WC()->cart->get_cart_item( $key );
$product = $item['data'];
$new_attributes = sprintf(
'" data-product_id="%s">',
esc_attr( $product->get_id() )
);
$url = str_replace( '">', $new_attributes, $url );
return $url;
}
/**
* Get the selected shipping option for a cart item. If the name cannot be found in the options table, the method's
* ID will be used.
*
* @deprecated 13.3
*
* @param string $cart_item_key the cart item key.
*
* @return mixed|bool
*/
public function get_shipping_option_for_item( $cart_item_key ) {
$packages = wc()->shipping()->get_packages();
$selected_options = wc()->session->get( 'chosen_shipping_methods' );
if ( ! is_array( $packages ) || ! is_array( $selected_options ) ) {
return false;
}
foreach ( $packages as $package_id => $package ) {
if ( ! isset( $package['contents'] ) || ! is_array( $package['contents'] ) ) {
return false;
}
foreach ( $package['contents'] as $package_item ) {
if ( ! isset( $package_item['key'] ) || $package_item['key'] !== $cart_item_key || ! isset( $selected_options[ $package_id ] ) ) {
continue;
}
$selected_rate_id = $selected_options[ $package_id ];
$method_key_id = sanitize_text_field( str_replace( ':', '_', $selected_rate_id ) );
$option_name = 'woocommerce_' . $method_key_id . '_settings';
$option_value = get_option( $option_name );
$title = '';
if ( is_array( $option_value ) && isset( $option_value['title'] ) ) {
$title = $option_value['title'];
}
if ( ! $title ) {
return $selected_rate_id;
}
return $title;
}
}
return false;
}
/**
* On the Checkout page, trigger an event for each product in the cart
*
* @deprecated 13.3
*/
public function checkout_process() {
global $post;
$checkout_page_id = wc_get_page_id( 'checkout' );
$cart = WC()->cart->get_cart();
$enabled_payment_options = array_filter(
WC()->payment_gateways->get_available_payment_gateways(),
function ( $payment_gateway ) {
if ( ! $payment_gateway instanceof WC_Payment_Gateway ) {
return false;
}
return $payment_gateway->is_available();
}
);
$enabled_payment_options = array_keys( $enabled_payment_options );
$is_in_checkout_page = $checkout_page_id === $post->ID ? 'Yes' : 'No';
$session = WC()->session;
if ( is_object( $session ) ) {
$session->set( 'checkout_page_used', true );
$session->save_data();
}
foreach ( $cart as $cart_item_key => $cart_item ) {
/**
* This filter is already documented in woocommerce/templates/cart/cart.php
*/
$product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key );
if ( ! $product || ! $product instanceof WC_Product ) {
continue;
}
$data = $this->get_cart_checkout_shared_data();
$data['from_checkout'] = $is_in_checkout_page;
if ( ! empty( $data['products'] ) ) {
unset( $data['products'] );
}
if ( ! empty( $data['shipping_options_count'] ) ) {
unset( $data['shipping_options_count'] );
}
$data['pq'] = $cart_item['quantity'];
$properties = $this->process_event_properties(
'woocommerceanalytics_product_checkout',
$data,
$product->get_id()
);
wc_enqueue_js(
"
var cartItem_{$cart_item_key}_logged = false;
var properties = {$properties};
// Check if jQuery is available
if ( typeof jQuery !== 'undefined' ) {
// This is only triggered on the checkout shortcode.
jQuery( document.body ).on( 'init_checkout', function () {
if ( true === cartItem_{$cart_item_key}_logged ) {
return;
}
wp.hooks.addAction( 'wcpay.payment-request.availability', 'wcpay', function ( args ) {
properties.express_checkout = args.paymentRequestType;
} );
properties.checkout_page_contains_checkout_block = '0';
properties.checkout_page_contains_checkout_shortcode = '1';
_wca.push( properties );
cartItem_{$cart_item_key}_logged = true;
} );
}
if (
typeof wp !== 'undefined' &&
typeof wp.data !== 'undefined' &&
typeof wp.data.subscribe !== 'undefined'
) {
wp.data.subscribe( function () {
if ( true === cartItem_{$cart_item_key}_logged ) {
return;
}
const checkoutDataStore = wp.data.select( 'wc/store/checkout' );
// Ensures we're not in Cart, but in Checkout page.
if (
typeof checkoutDataStore !== 'undefined' &&
checkoutDataStore.getOrderId() !== 0
) {
properties.express_checkout = Object.keys( wc.wcBlocksRegistry.getExpressPaymentMethods() );
properties.checkout_page_contains_checkout_block = '1';
properties.checkout_page_contains_checkout_shortcode = '0';
_wca.push( properties );
cartItem_{$cart_item_key}_logged = true;
}
} );
}
"
);
}
}
/**
* After the checkout process, fire an event for each item in the order
*
* @deprecated 13.3
*
* @param string $order_id Order Id.
*/
public function order_process( $order_id ) {
$order = wc_get_order( $order_id );
if (
! $order
|| ! $order instanceof WC_Order
) {
return;
}
$payment_option = $order->get_payment_method();
if ( is_object( WC()->session ) ) {
$create_account = true === WC()->session->get( 'wc_checkout_createaccount_used' ) ? 'Yes' : 'No';
$checkout_page_used = true === WC()->session->get( 'checkout_page_used' ) ? 'Yes' : 'No';
} else {
$create_account = 'No';
$checkout_page_used = 'No';
}
$guest_checkout = $order->get_user() ? 'No' : 'Yes';
$express_checkout = 'null';
// When the payment option is woocommerce_payment
// See if Google Pay or Apple Pay was used.
if ( 'woocommerce_payments' === $payment_option ) {
$payment_option_title = $order->get_payment_method_title();
if ( 'Google Pay (WooCommerce Payments)' === $payment_option_title ) {
$express_checkout = array( 'google_pay' );
} elseif ( 'Apple Pay (WooCommerce Payments)' === $payment_option_title ) {
$express_checkout = array( 'apple_pay' );
}
}
$checkout_page_contains_checkout_block = '0';
$checkout_page_contains_checkout_shortcode = '0';
$order_source = $order->get_created_via();
if ( 'store-api' === $order_source ) {
$checkout_page_contains_checkout_block = '1';
$checkout_page_contains_checkout_shortcode = '0';
} elseif ( 'checkout' === $order_source ) {
$checkout_page_contains_checkout_block = '0';
$checkout_page_contains_checkout_shortcode = '1';
}
// loop through products in the order and queue a purchase event.
foreach ( $order->get_items() as $order_item ) {
// @phan-suppress-next-line PhanUndeclaredMethodInCallable,PhanUndeclaredMethod -- Checked before being called. See also https://github.com/phan/phan/issues/1204.
$product_id = is_callable( array( $order_item, 'get_product_id' ) ) ? $order_item->get_product_id() : -1;
$order_items = $order->get_items();
$order_items_count = 0;
if ( is_array( $order_items ) ) {
$order_items_count = count( $order_items );
}
$order_coupons = $order->get_coupons();
$order_coupons_count = 0;
if ( is_array( $order_coupons ) ) {
$order_coupons_count = count( $order_coupons );
}
$this->record_event(
'woocommerceanalytics_product_purchase',
array(
'oi' => $order->get_order_number(),
'pq' => $order_item->get_quantity(),
'payment_option' => $payment_option,
'create_account' => $create_account,
'guest_checkout' => $guest_checkout,
'express_checkout' => $express_checkout,
'products_count' => $order_items_count,
'coupon_used' => $order_coupons_count,
'order_value' => $order->get_total(),
'from_checkout' => $checkout_page_used,
'checkout_page_contains_checkout_block' => $checkout_page_contains_checkout_block,
'checkout_page_contains_checkout_shortcode' => $checkout_page_contains_checkout_shortcode,
),
$product_id
);
}
}
/**
* Listen for clicks on the "Update Cart" button to know if an item has been removed by
* updating its quantity to zero
*
* @deprecated 13.3
*/
public function remove_from_cart_via_quantity() {
$common_props = $this->render_properties_as_js(
$this->get_common_properties()
);
wc_enqueue_js(
"
jQuery( 'button[name=update_cart]' ).on( 'click', function() {
var cartItems = jQuery( '.cart_item' );
cartItems.each( function( item ) {
var qty = jQuery( this ).find( 'input.qty' );
if ( qty && qty.val() === '0' ) {
var productID = jQuery( this ).find( '.product-remove a' ).data( 'product_id' );
_wca.push( {
'_en': 'woocommerceanalytics_remove_from_cart',
'pi': productID, " .
$common_props . '
} );
}
} );
} );'
);
}
/**
* Gets the inner blocks of a block.
*
* @deprecated 13.3
*
* @param array $inner_blocks The inner blocks.
*
* @return array
*/
private function get_inner_blocks( $inner_blocks ) {
$block_names = array();
if ( ! empty( $inner_blocks['blockName'] ) ) {
$block_names[] = $inner_blocks['blockName'];
}
if ( isset( $inner_blocks['innerBlocks'] ) && is_array( $inner_blocks['innerBlocks'] ) ) {
$block_names = array_merge( $block_names, $this->get_inner_blocks( $inner_blocks['innerBlocks'] ) );
}
return $block_names;
}
/**
* Track adding items to the cart.
*
* @deprecated 13.3
*
* @param string $cart_item_key Cart item key.
* @param int $product_id Product added to cart.
* @param int $quantity Quantity added to cart.
* @param int $variation_id Product variation.
* @param array $variation Variation attributes..
* @param array $cart_item_data Other cart data.
*/
public function capture_add_to_cart( $cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
$referer_postid = isset( $_SERVER['HTTP_REFERER'] ) ? url_to_postid( esc_url_raw( wp_unslash( $_SERVER['HTTP_REFERER'] ) ) ) : 0;
// if the referring post is not a product OR the product being added is not the same as post.
// (eg. related product list on single product page) then include a product view event.
$product_by_referer_postid = wc_get_product( $referer_postid );
if ( ! $product_by_referer_postid instanceof WC_Product || (int) $product_id !== $referer_postid ) {
$this->capture_event_in_session_data( $product_id, $quantity, 'woocommerceanalytics_product_view' );
}
// add cart event to the session data.
$this->capture_event_in_session_data( $product_id, $quantity, 'woocommerceanalytics_add_to_cart' );
}
/**
* Track in-session data.
*
* @deprecated 13.3
*
* @param int $product_id Product ID.
* @param int $quantity Quantity.
* @param string $event Fired event.
*/
public function capture_event_in_session_data( $product_id, $quantity, $event ) {
$product = wc_get_product( $product_id );
if ( ! $product instanceof WC_Product ) {
return;
}
$quantity = ( 0 === $quantity ) ? 1 : $quantity;
// check for existing data.
if ( is_object( WC()->session ) ) {
$data = WC()->session->get( 'wca_session_data' );
if ( empty( $data ) || ! is_array( $data ) ) {
$data = array();
}
} else {
$data = array();
}
// extract new event data.
$new_data = array(
'event' => $event,
'product_id' => (string) $product_id,
'quantity' => (string) $quantity,
);
// append new data.
$data[] = $new_data;
WC()->session->set( 'wca_session_data', $data );
}
/**
* Save createaccount post data to be used in $this->order_process.
*
* @deprecated 13.3
*
* @param array $data post data from the checkout page.
*
* @return array
*/
public function save_checkout_post_data( array $data ) {
$session = WC()->session;
if ( is_object( $session ) ) {
if ( isset( $data['createaccount'] ) && ! empty( $data['createaccount'] ) ) {
$session->set( 'wc_checkout_createaccount_used', true );
$session->save_data();
}
}
return $data;
}
/**
* Capture the create account event. Similar to save_checkout_post_data but works with Store API.
*
* @deprecated 13.3
*
* @param int $customer_id Customer ID.
* @param array $new_customer_data New customer data.
*/
public function capture_created_customer( $customer_id, $new_customer_data ) {
$session = WC()->session;
if ( is_object( $session ) ) {
if ( str_contains( $new_customer_data['source'], 'store-api' ) ) {
$session->set( 'wc_checkout_createaccount_used', true );
$session->save_data();
}
}
}
}