init
This commit is contained in:
+204
@@ -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,
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
+358
@@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
+597
@@ -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;
|
||||
}
|
||||
}
|
||||
+552
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user