-
Notifications
You must be signed in to change notification settings - Fork 798
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add extra properties to woocommerceanalytics events #15028
Changes from all commits
37f89bf
7766ae8
0e12300
32b0409
220eddb
40e0171
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -76,37 +76,84 @@ public function enqueue_tracking_script() { | |
wp_enqueue_script( 'woocommerce-analytics', esc_url( $filename ), array(), null, false ); | ||
} | ||
|
||
/** | ||
* Default event properties which should be included with all events. | ||
* | ||
* @return array Array of standard event props. | ||
*/ | ||
public function get_common_properties() { | ||
return array( | ||
'blog_id' => Jetpack::get_option( 'id' ), | ||
'ui' => $this->get_user_id(), | ||
'url' => home_url(), | ||
'woo_version' => WC()->version, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about keeping this inline with other property names: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prefer clarity over terseness here. See also @deltaWhiskey comment in support of clearer props names: #15028 (comment) |
||
); | ||
} | ||
|
||
/** | ||
* Render tracks event properties as string of JavaScript object props. | ||
* | ||
* @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 ) { | ||
$js_args_string = $js_args_string . "'$key': '" . esc_js( $value ) . "', "; | ||
} | ||
return $js_args_string; | ||
} | ||
|
||
/** | ||
* Record an event with optional custom properties. | ||
* | ||
* @param string $event_name The name of the event to record. | ||
* @param integer $product_id The id of the product relating to the event. | ||
* @param array $properties Optional array of (key => value) event properties. | ||
*/ | ||
public function record_event( $event_name, $product_id, $properties = array() ) { | ||
$product = wc_get_product( $product_id ); | ||
if ( ! $product instanceof WC_Product ) { | ||
return; | ||
} | ||
$product_details = $this->get_product_details( $product ); | ||
|
||
$all_props = array_merge( | ||
$properties, | ||
$this->get_common_properties() | ||
); | ||
|
||
wc_enqueue_js( | ||
"_wca.push( { | ||
'_en': '" . esc_js( $event_name ) . "', | ||
'pi': '" . esc_js( $product_id ) . "', | ||
'pn': '" . esc_js( $product_details['name'] ) . "', | ||
'pc': '" . esc_js( $product_details['category'] ) . "', | ||
'pp': '" . esc_js( $product_details['price'] ) . "', | ||
'pt': '" . esc_js( $product_details['type'] ) . "'," . | ||
$this->render_properties_as_js( $all_props ) . ' | ||
} );' | ||
); | ||
} | ||
|
||
/** | ||
* On product lists or other non-product pages, add an event listener to "Add to Cart" button click | ||
*/ | ||
public function loop_session_events() { | ||
$blogid = Jetpack::get_option( 'id' ); | ||
|
||
// check for previous add-to-cart cart events | ||
// Check for previous events queued in session data. | ||
if ( is_object( WC()->session ) ) { | ||
jeherve marked this conversation as resolved.
Show resolved
Hide resolved
|
||
$data = WC()->session->get( 'wca_session_data' ); | ||
if ( ! empty( $data ) ) { | ||
foreach ( $data as $data_instance ) { | ||
$product = wc_get_product( $data_instance['product_id'] ); | ||
if ( ! $product instanceof WC_Product ) { | ||
continue; | ||
} | ||
$product_details = $this->get_product_details( $product ); | ||
wc_enqueue_js( | ||
"_wca.push( { | ||
'_en': '" . esc_js( $data_instance['event'] ) . "', | ||
'blog_id': '" . esc_js( $blogid ) . "', | ||
'pi': '" . esc_js( $data_instance['product_id'] ) . "', | ||
'pn': '" . esc_js( $product_details['name'] ) . "', | ||
'pc': '" . esc_js( $product_details['category'] ) . "', | ||
'pp': '" . esc_js( $product_details['price'] ) . "', | ||
'pq': '" . esc_js( $data_instance['quantity'] ) . "', | ||
'pt': '" . esc_js( $product_details['type'] ) . "', | ||
'ui': '" . esc_js( $this->get_user_id() ) . "', | ||
} );" | ||
$this->record_event( | ||
$data_instance['event'], | ||
$data_instance['product_id'], | ||
array( | ||
'pq' => $data_instance['quantity'], | ||
) | ||
); | ||
} | ||
// clear data | ||
// Clear data, now that these events have been recorded. | ||
WC()->session->set( 'wca_session_data', '' ); | ||
} | ||
} | ||
|
@@ -116,11 +163,13 @@ public function loop_session_events() { | |
* On the cart page, add an event listener for removal of product click | ||
*/ | ||
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. | ||
$blogid = Jetpack::get_option( 'id' ); | ||
wc_enqueue_js( | ||
"jQuery( 'div.woocommerce' ).on( 'click', 'a.remove', function() { | ||
var productID = jQuery( this ).data( 'product_id' ); | ||
|
@@ -131,12 +180,11 @@ public function remove_from_cart() { | |
}; | ||
_wca.push( { | ||
'_en': 'woocommerceanalytics_remove_from_cart', | ||
'blog_id': '" . esc_js( $blogid ) . "', | ||
'pi': productDetails.id, | ||
'pq': productDetails.quantity, | ||
'ui': '" . esc_js( $this->get_user_id() ) . "', | ||
'pq': productDetails.quantity, " . | ||
$common_props . ' | ||
} ); | ||
} );" | ||
} );' | ||
); | ||
} | ||
|
||
|
@@ -185,33 +233,18 @@ public function get_product_details( $product ) { | |
* Track a product page view | ||
*/ | ||
public function capture_product_view() { | ||
|
||
global $product; | ||
$blogid = Jetpack::get_option( 'id' ); | ||
$product_details = $this->get_product_details( $product ); | ||
|
||
wc_enqueue_js( | ||
"_wca.push( { | ||
'_en': 'woocommerceanalytics_product_view', | ||
'blog_id': '" . esc_js( $blogid ) . "', | ||
'pi': '" . esc_js( $product_details['id'] ) . "', | ||
'pn': '" . esc_js( $product_details['name'] ) . "', | ||
'pc': '" . esc_js( $product_details['category'] ) . "', | ||
'pp': '" . esc_js( $product_details['price'] ) . "', | ||
'pt': '" . esc_js( $product_details['type'] ) . "', | ||
'ui': '" . esc_js( $this->get_user_id() ) . "', | ||
} );" | ||
$this->record_event( | ||
'woocommerceanalytics_product_view', | ||
$product->get_id() | ||
jeherve marked this conversation as resolved.
Show resolved
Hide resolved
|
||
); | ||
} | ||
|
||
/** | ||
* On the Checkout page, trigger an event for each product in the cart | ||
*/ | ||
public function checkout_process() { | ||
|
||
$universal_commands = array(); | ||
$cart = WC()->cart->get_cart(); | ||
$blogid = Jetpack::get_option( 'id' ); | ||
$cart = WC()->cart->get_cart(); | ||
|
||
foreach ( $cart as $cart_item_key => $cart_item ) { | ||
/** | ||
|
@@ -223,22 +256,14 @@ public function checkout_process() { | |
continue; | ||
} | ||
|
||
$product_details = $this->get_product_details( $product ); | ||
|
||
$universal_commands[] = "_wca.push( { | ||
'_en': 'woocommerceanalytics_product_checkout', | ||
'blog_id': '" . esc_js( $blogid ) . "', | ||
'pi': '" . esc_js( $product_details['id'] ) . "', | ||
'pn': '" . esc_js( $product_details['name'] ) . "', | ||
'pc': '" . esc_js( $product_details['category'] ) . "', | ||
'pp': '" . esc_js( $product_details['price'] ) . "', | ||
'pq': '" . esc_js( $cart_item['quantity'] ) . "', | ||
'pt': '" . esc_js( $product_details['type'] ) . "', | ||
'ui': '" . esc_js( $this->get_user_id() ) . "', | ||
} );"; | ||
$this->record_event( | ||
'woocommerceanalytics_product_checkout', | ||
$product->get_id(), | ||
array( | ||
'pq' => $cart_item['quantity'], | ||
) | ||
); | ||
} | ||
|
||
wc_enqueue_js( implode( "\r\n", $universal_commands ) ); | ||
jeherve marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
/** | ||
|
@@ -247,39 +272,31 @@ public function checkout_process() { | |
* @param string $order_id Order Id. | ||
*/ | ||
public function order_process( $order_id ) { | ||
$order = wc_get_order( $order_id ); | ||
$universal_commands = array(); | ||
$blogid = Jetpack::get_option( 'id' ); | ||
$order = wc_get_order( $order_id ); | ||
|
||
// loop through products in the order and queue a purchase event. | ||
foreach ( $order->get_items() as $order_item_id => $order_item ) { | ||
$product = $order->get_product_from_item( $order_item ); | ||
|
||
$product_details = $this->get_product_details( $product ); | ||
|
||
$universal_commands[] = "_wca.push( { | ||
'_en': 'woocommerceanalytics_product_purchase', | ||
'blog_id': '" . esc_js( $blogid ) . "', | ||
'pi': '" . esc_js( $product_details['id'] ) . "', | ||
'pn': '" . esc_js( $product_details['name'] ) . "', | ||
'pc': '" . esc_js( $product_details['category'] ) . "', | ||
'pp': '" . esc_js( $product_details['price'] ) . "', | ||
'pq': '" . esc_js( $order_item->get_quantity() ) . "', | ||
'pt': '" . esc_js( $product_details['type'] ) . "', | ||
'oi': '" . esc_js( $order->get_order_number() ) . "', | ||
'ui': '" . esc_js( $this->get_user_id() ) . "', | ||
} );"; | ||
$this->record_event( | ||
'woocommerceanalytics_product_purchase', | ||
$product->get_id(), | ||
array( | ||
'oi' => $order->get_order_number(), | ||
'pq' => $order_item->get_quantity(), | ||
) | ||
); | ||
} | ||
|
||
wc_enqueue_js( implode( "\r\n", $universal_commands ) ); | ||
} | ||
|
||
/** | ||
* Listen for clicks on the "Update Cart" button to know if an item has been removed by | ||
* updating its quantity to zero | ||
*/ | ||
public function remove_from_cart_via_quantity() { | ||
$blogid = Jetpack::get_option( 'id' ); | ||
$common_props = $this->render_properties_as_js( | ||
$this->get_common_properties() | ||
); | ||
|
||
wc_enqueue_js( | ||
" | ||
|
@@ -291,14 +308,12 @@ public function remove_from_cart_via_quantity() { | |
var productID = jQuery( this ).find( '.product-remove a' ).data( 'product_id' ); | ||
_wca.push( { | ||
'_en': 'woocommerceanalytics_remove_from_cart', | ||
'blog_id': '" . esc_js( $blogid ) . "', | ||
'pi': productID, | ||
'ui': '" . esc_js( $this->get_user_id() ) . "', | ||
'pi': productID, " . | ||
$common_props . ' | ||
} ); | ||
} | ||
} ); | ||
} ); | ||
" | ||
} );' | ||
); | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious what the url is for. We already have browser document location in
_dl
property. Are you looking for a unique way to identify sites? If so, wouldblog_id
suffice?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
home_url()
is to give a way to map to data collected by WC Tracker, which does not haveblog_id
. There have been experiments in the past with using document location, but that comes with some challenges.