Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions assets/blocks/reader-registration/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,9 @@ function process_form() {
if ( ! empty( $lists ) ) {
$metadata['lists'] = $lists;
}
$metadata['current_page_url'] = home_url( add_query_arg( array(), \wp_get_referer() ) );
$email = \sanitize_email( $_REQUEST['email'] );
$metadata['current_page_url'] = home_url( add_query_arg( array(), \wp_get_referer() ) );
$metadata['registration_method'] = 'registration-block';
$email = \sanitize_email( $_REQUEST['email'] );

$user_id = Reader_Activation::register_reader( $email, '', true, $metadata );

Expand All @@ -289,10 +290,6 @@ function process_form() {

$user_logged_in = false !== $user_id;

if ( $user_logged_in ) {
Reader_Activation::save_current_user_login_method( 'registration-block' );
}

return send_form_response(
[
'email' => $email,
Expand Down
89 changes: 89 additions & 0 deletions includes/class-analytics.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ public function __construct() {
add_action( 'woocommerce_login_form_end', [ __CLASS__, 'prepare_login_events' ] );
add_action( 'woocommerce_register_form_end', [ __CLASS__, 'prepare_registration_events' ] );
add_action( 'woocommerce_after_checkout_registration_form', [ __CLASS__, 'prepare_checkout_registration_events' ] );

// Reader Activation hooks.
add_action( 'newspack_registered_reader', [ __CLASS__, 'newspack_registered_reader' ], 10, 5 );
add_action( 'newspack_newsletters_add_contact', [ __CLASS__, 'newspack_newsletters_add_contact' ], 10, 4 );
}

/**
Expand Down Expand Up @@ -863,5 +867,90 @@ protected static function output_js_ini_load_event( $event ) {
</script>
<?php
}

/**
* When a new reader registers, sent an event to GA.
*
* @param string $email Email address.
* @param bool $authenticate Whether to authenticate after registering.
* @param false|int $user_id The created user id.
* @param false|\WP_User $existing_user The existing user object.
* @param array $metadata Metadata.
*/
public static function newspack_registered_reader( $email, $authenticate, $user_id, $existing_user, $metadata ) {
if ( $existing_user ) {
return;
}
$event_spec = [
'category' => __( 'Newspack Reader Activation', 'newspack' ),
'action' => __( 'Registration', 'newspack' ),
];

if ( isset( $metadata['registration_method'] ) ) {
$event_spec['action'] .= ' (' . $metadata['registration_method'] . ')';
}

if ( isset( $metadata['lists'] ) ) {
$event_spec['label'] = __( 'Signed up for lists:', 'newspack' ) . ' ' . implode( ', ', $metadata['lists'] );
}

if ( isset( $metadata['current_page_url'] ) ) {
$parsed_url = \wp_parse_url( $metadata['current_page_url'] );
if ( $parsed_url ) {
if ( isset( $parsed_url['host'] ) ) {
$event_spec['host'] = $parsed_url['host'];
}
if ( isset( $parsed_url['path'] ) ) {
$event_spec['path'] = $parsed_url['path'];
}
}
}

\Newspack\Google_Services_Connection::send_custom_event( $event_spec );

if ( Analytics_Wizard::ntg_events_enabled() ) {
\Newspack\Google_Services_Connection::send_custom_event(
[
'category' => __( 'NTG account', 'newspack' ),
'action' => __( 'registration', 'newspack' ),
'label' => 'success',
]
);
}
}

/**
* When a reader signs up for the newsletter, send an event to GA.
*
* @param string $provider The provider name.
* @param array $contact {
* Contact information.
*
* @type string $email Contact email address.
* @type string $name Contact name. Optional.
* @type string $existing_contact_data Existing contact data, if updating a contact. The hook will be also called when
* @type string[] $metadata Contact additional metadata. Optional.
* }
* @param string[]|false $lists Array of list IDs to subscribe the contact to.
* @param bool|WP_Error $result True if the contact was added or error if failed.
*/
public static function newspack_newsletters_add_contact( $provider, $contact, $lists, $result ) {
if (
! Analytics_Wizard::ntg_events_enabled()
|| ! method_exists( '\Newspack_Newsletters_Subscription', 'get_contact_data' )
// Don't send events for updates to a contact.
|| $contact['existing_contact_data']
) {
return;
}

\Newspack\Google_Services_Connection::send_custom_event(
[
'category' => __( 'NTG newsletter', 'newspack' ),
'action' => __( 'newsletter signup', 'newspack' ),
'label' => 'success',
]
);
}
}
new Analytics();
1 change: 0 additions & 1 deletion includes/class-magic-link.php
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,6 @@ private static function authenticate( $user_id, $token ) {

Reader_Activation::set_reader_verified( $user );
Reader_Activation::set_current_reader( $user->ID );
Reader_Activation::save_current_user_login_method( 'magic-link' );

/**
* Fires after a reader has been authenticated via magic link.
Expand Down
30 changes: 8 additions & 22 deletions includes/class-reader-activation.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ final class Reader_Activation {
/**
* Reader user meta keys.
*/
const READER = 'np_reader';
const EMAIL_VERIFIED = 'np_reader_email_verified';
const LOGIN_METHOD = 'np_reader_login_method';
const READER = 'np_reader';
const EMAIL_VERIFIED = 'np_reader_email_verified';
const REGISTRATION_METHOD = 'np_reader_registration_method';

/**
* Auth form.
Expand Down Expand Up @@ -1033,6 +1033,11 @@ public static function register_reader( $email, $display_name = '', $authenticat
}
}

// Note the user's login method for later use.
if ( isset( $metadata['registration_method'] ) ) {
\update_user_meta( $user_id, self::REGISTRATION_METHOD, $metadata['registration_method'] );
}

/**
* Action after registering and authenticating a reader.
*
Expand All @@ -1047,25 +1052,6 @@ public static function register_reader( $email, $display_name = '', $authenticat
return $user_id;
}

/**
* Note reader's login method.
*
* @param int $user_id User ID.
* @param string $login_method Login method used.
*/
public static function save_user_login_method( $user_id, $login_method ) {
\update_user_meta( $user_id, self::LOGIN_METHOD, $login_method );
}

/**
* Note current reader's login method.
*
* @param string $login_method Login method used.
*/
public static function save_current_user_login_method( $login_method ) {
self::save_user_login_method( \get_current_user_id(), $login_method );
}

/**
* Get value of the client ID bearing cookie.
*/
Expand Down
2 changes: 1 addition & 1 deletion includes/oauth/class-google-login.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ public static function api_google_login_register( $request ) {
// Fail silently.
}
}
$metadata['registration_method'] = 'google';
if ( $email ) {
$existing_user = \get_user_by( 'email', $email );
$message = __( 'Thank you for registering!', 'newspack' );
Expand All @@ -181,7 +182,6 @@ public static function api_google_login_register( $request ) {
if ( is_wp_error( $result ) ) {
return $result;
}
Reader_Activation::save_current_user_login_method( 'google' );

return \rest_ensure_response(
[
Expand Down
61 changes: 61 additions & 0 deletions includes/oauth/class-google-services-connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,65 @@ public static function get_site_kit_analytics_module() {
public static function get_oauth2_credentials() {
return \Newspack\Google_OAuth::get_oauth2_credentials();
}

/**
* Send a custom event to GA.
*
* @param array $event_spec Event details.
*/
public static function send_custom_event( $event_spec ) {
Logger::log( 'Sending custom event of category "' . $event_spec['category'] . '" to GA.' );
try {
$analytics = self::get_site_kit_analytics_module();
if ( $analytics->is_connected() ) {
$tracking_id = $analytics->get_settings()->get()['propertyID'];
$analytics_ping_url = 'https://www.google-analytics.com/collect';

// Params docs: https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters.
$analytics_ping_params = array(
'v' => 1,
'tid' => $tracking_id, // Tracking ID/ Web Property ID.
't' => 'event', // Hit type.
'an' => 'Newspack', // Application Name.
'ec' => $event_spec['category'], // Event Category.
'ea' => $event_spec['action'], // Event Action.
);

// Client ID.
if ( isset( $event_spec['cid'] ) ) {
$analytics_ping_params['cid'] = $event_spec['cid'];
} elseif ( isset( $_COOKIE['_ga'] ) ) {
list($version, $domain_depth, $cid1, $cid2) = explode( '.', $_COOKIE['_ga'], 4 ); // phpcs:ignore WordPressVIPMinimum.Variables.RestrictedVariables.cache_constraints___COOKIE, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$analytics_ping_params['cid'] = $cid1 . '.' . $cid2;
} else {
$analytics_ping_params['cid'] = '555'; // Anonymous client.
}

if ( isset( $event_spec['label'] ) ) {
$analytics_ping_params['el'] = $event_spec['label']; // Event label.
}
if ( isset( $event_spec['value'] ) ) {
$analytics_ping_params['ev'] = $event_spec['value']; // Event value.
}
if ( isset( $event_spec['referer'] ) ) {
$analytics_ping_params['dr'] = $event_spec['referer']; // Document Referrer.
}
if ( isset( $event_spec['host'] ) ) {
$analytics_ping_params['dh'] = $event_spec['host']; // Document Host.
}
if ( isset( $event_spec['path'] ) ) {
$analytics_ping_params['dp'] = $event_spec['path']; // Document Page.
}

$ga_url = $analytics_ping_url . '?' . http_build_query( $analytics_ping_params );
if ( function_exists( 'vip_safe_wp_remote_get' ) ) {
return vip_safe_wp_remote_get( $ga_url );
} else {
return wp_remote_get( $ga_url ); // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.wp_remote_get_wp_remote_get
}
}
} catch ( \Throwable $th ) {
Logger::log( 'Failed sending custom event to GA: ' . $th->getMessage() );
}
}
}
51 changes: 19 additions & 32 deletions includes/plugins/class-newspack-newsletters.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,10 @@ public static function update_contact_lists( $provider, $email, $lists_to_add, $
* @param array $contact {
* Contact information.
*
* @type string $email Contact email address.
* @type string $name Contact name. Optional.
* @type string[] $metadata Contact additional metadata. Optional.
* @type string $email Contact email address.
* @type string $name Contact name. Optional.
* @type string $existing_contact_data Existing contact data, if updating a contact. The hook will be also called when
* @type string[] $metadata Contact additional metadata. Optional.
* }
* @param string[]|false $selected_list_ids Array of list IDs the contact will be subscribed to, or false.
* @param string $provider The provider name.
Expand All @@ -66,30 +67,6 @@ public static function contact_data( $contact, $selected_list_ids, $provider ) {
$metadata['NP_Account'] = get_current_user_id();
}

// If it's a new contact, add a registration or signup date.
$is_new_contact = null;
try {
if ( method_exists( '\Newspack_Newsletters_Subscription', 'get_contact_data' ) ) {
$existing_contact = \Newspack_Newsletters_Subscription::get_contact_data( $contact['email'] );
if ( is_wp_error( $existing_contact ) ) {
Logger::log( 'Adding metadata to a new contact.' );
$is_new_contact = true;
if ( empty( $selected_list_ids ) ) {
// Registration only, as a side effect of Reader Activation.
$contact['metadata']['NP_Registration Date'] = gmdate( 'm/d/Y' );
} else {
// Registration and signup, the former implicit.
$contact['metadata']['NP_Newsletter Signup Date'] = gmdate( 'm/d/Y' );
}
} else {
Logger::log( 'Adding metadata to an existing contact.' );
$is_new_contact = false;
}
}
} catch ( \Throwable $e ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch
// Move along.
}

// Translate list IDs to list names and store as metadata, if lists are supplied.
// The list ids can be an empty array, which means the contact has been unsubscribed from all lists.
if ( false !== $selected_list_ids ) {
Expand Down Expand Up @@ -119,8 +96,17 @@ public static function contact_data( $contact, $selected_list_ids, $provider ) {
unset( $contact['metadata']['current_page_url'] );
}

// If it's a new contact, add some context on the signup/registration.
$is_new_contact = ! $contact['existing_contact_data'];
if ( $is_new_contact ) {
if ( empty( $selected_list_ids ) ) {
// Registration only, as a side effect of Reader Activation.
$contact['metadata']['NP_Registration Date'] = gmdate( 'm/d/Y' );
} else {
// Registration and signup, the former implicit.
$contact['metadata']['NP_Newsletter Signup Date'] = gmdate( 'm/d/Y' );
}

// Add some context on the signup/registration.
if ( ! $signup_page_url ) {
global $wp;
$signup_page_url = home_url( add_query_arg( array(), $wp->request ) );
Expand Down Expand Up @@ -166,11 +152,12 @@ function( $acc, $item ) {
*
* @param string[]|false $lists Array of list IDs the contact will be subscribed to, or false.
* @param array $contact {
* Contact information.
* Contact information.
*
* @type string $email Contact email address.
* @type string $name Contact name. Optional.
* @type string[] $metadata Contact additional metadata. Optional.
* @type string $email Contact email address.
* @type string $name Contact name. Optional.
* @type string $existing_contact_data Existing contact data, if updating a contact. The hook will be also called when
* @type string[] $metadata Contact additional metadata. Optional.
* }
* @param string $provider The provider name.
*
Expand Down
34 changes: 12 additions & 22 deletions includes/reader-revenue/class-stripe-connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -449,27 +449,15 @@ public static function receive_webhook( $request ) {
}

// Send custom event to GA.
$analytics = \Newspack\Google_Services_Connection::get_site_kit_analytics_module();
if ( $analytics->is_connected() ) {
$tracking_id = $analytics->get_settings()->get()['propertyID'];
$analytics_ping_url = 'https://www.google-analytics.com/collect?v=1';

// Params docs: https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters.
$analytics_ping_params = array(
'tid' => $tracking_id, // Tracking ID/ Web Property ID.
'cid' => '555', // Client ID.
't' => 'event', // Hit type.
'an' => 'Newspack', // Application Name.
'ec' => __( 'Newspack Donation', 'newspack' ), // Event Category.
'ea' => __( 'Stripe', 'newspack' ), // Event Action.
'el' => $frequency, // Event Label.
'ev' => $amount_normalised, // Event Value.
'dr' => $referer, // Document Referrer.
);

wp_remote_post( $analytics_ping_url . '&' . http_build_query( $analytics_ping_params ) );
}

\Newspack\Google_Services_Connection::send_custom_event(
[
'category' => __( 'Newspack Donation', 'newspack' ),
'action' => __( 'Stripe', 'newspack' ),
'label' => $frequency,
'value' => $amount_normalised,
'referer' => $referer,
]
);

// Add a transaction to WooCommerce.
if ( Donations::is_woocommerce_suite_active() ) {
Expand Down Expand Up @@ -804,7 +792,9 @@ public static function handle_donation( $config ) {
$payment_method_id = $config['payment_method_id'];

if ( ! isset( $client_metadata['userId'] ) && Reader_Activation::is_enabled() ) {
$user_id = Reader_Activation::register_reader( $email_address, $full_name, true, $client_metadata );
$reader_metadata = $client_metadata;
$reader_metadata['registration_method'] = 'stripe-donation';
$user_id = Reader_Activation::register_reader( $email_address, $full_name, true, $reader_metadata );
if ( ! \is_wp_error( $user_id ) && false !== $user_id ) {
$client_metadata['userId'] = $user_id;
}
Expand Down
Loading