Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
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
3 changes: 2 additions & 1 deletion assets/blocks/reader-registration/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,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'] );

$email = \sanitize_email( $_REQUEST['email'] );
$user_id = Reader_Activation::register_reader( $email, '', true, $metadata );

/**
Expand Down
12 changes: 10 additions & 2 deletions assets/blocks/reader-registration/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@ function domReady( callback ) {
document.addEventListener( 'DOMContentLoaded', callback );
}

const convertFormDataToObject = formData =>
const convertFormDataToObject = ( formData, ignoredKeys = [] ) =>
Array.from( formData.entries() ).reduce( ( acc, [ key, val ] ) => {
if ( ignoredKeys.includes( key ) ) {
return acc;
}
if ( key.indexOf( '[]' ) > -1 ) {
key = key.replace( '[]', '' );
acc[ key ] = acc[ key ] || [];
Expand Down Expand Up @@ -116,7 +119,12 @@ const convertFormDataToObject = formData =>
googleLoginElement.addEventListener( 'click', () => {
startLoginFlow();

const metadata = convertFormDataToObject( new FormData( form ) );
const metadata = convertFormDataToObject( new FormData( form ), [
'email',
'_wp_http_referer',
'newspack_reader_registration',
] );
metadata.current_page_url = window.location.href;
const checkLoginStatus = () => {
fetch(
`/wp-json/newspack/v1/login/google/register?metadata=${ JSON.stringify( metadata ) }`
Expand Down
3 changes: 2 additions & 1 deletion includes/class-newspack.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,11 @@ private function includes() {
include_once NEWSPACK_ABSPATH . 'includes/class-amp-enhancements.php';
include_once NEWSPACK_ABSPATH . 'includes/class-newspack-image-credits.php';

// Integrations w/ third-party plugins.
/* Integrations with other plugins. */
include_once NEWSPACK_ABSPATH . 'includes/plugins/class-jetpack.php';
include_once NEWSPACK_ABSPATH . 'includes/plugins/class-gravityforms.php';
include_once NEWSPACK_ABSPATH . 'includes/plugins/google-site-kit/class-googlesitekit.php';
include_once NEWSPACK_ABSPATH . 'includes/plugins/class-newspack-newsletters.php';

include_once NEWSPACK_ABSPATH . 'includes/class-patches.php';

Expand Down
25 changes: 0 additions & 25 deletions includes/class-reader-activation.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
* Reader Activation Class.
*/
final class Reader_Activation {

const AUTH_INTENTION_COOKIE = 'np_auth_intention';
const SCRIPT_HANDLE = 'newspack-reader-activation';
const AUTH_SCRIPT_HANDLE = 'newspack-reader-auth';
Expand Down Expand Up @@ -59,7 +58,6 @@ public static function init() {
\add_action( 'wp_footer', [ __CLASS__, 'render_auth_form' ] );
\add_action( 'template_redirect', [ __CLASS__, 'process_auth_form' ] );
\add_filter( 'amp_native_post_form_allowed', '__return_true' );
\add_action( 'newspack_newsletters_add_contact', [ __CLASS__, 'register_newsletters_contact' ], 10, 2 );
}
}

Expand Down Expand Up @@ -654,29 +652,6 @@ public static function process_auth_form() {
}
}

/**
* Register a reader from newsletter signup.
*
* @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[] $metadata Contact additional metadata. Optional.
* }
*/
public static function register_newsletters_contact( $provider, $contact ) {
// Bail if already logged in.
if ( \is_user_logged_in() ) {
return;
}

self::register_reader(
$contact['email'],
isset( $contact['name'] ) ? $contact['name'] : ''
);
}

/**
* Check if current reader has its email verified.
Expand Down
159 changes: 159 additions & 0 deletions includes/plugins/class-newspack-newsletters.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
<?php
/**
* Newspack Newsletters integration class.
*
* @package Newspack
*/

namespace Newspack;

defined( 'ABSPATH' ) || exit;

/**
* Main class.
*/
class Newspack_Newsletters {
/**
* Initialize hooks and filters.
*/
public static function init() {
if ( Reader_Activation::is_enabled() ) {
\add_action( 'newspack_newsletters_update_contact_lists', [ __CLASS__, 'newspack_newsletters_update_contact_lists' ], 10, 5 );
\add_filter( 'newspack_newsletters_contact_data', [ __CLASS__, 'newspack_newsletters_contact_data' ], 10, 3 );
}
}

/**
* Update content metadata after a contact's lists are updated.
*
* @param string $provider The provider name.
* @param string $email Contact email address.
* @param string[] $lists_to_add Array of list IDs to subscribe the contact to.
* @param string[] $lists_to_remove Array of list IDs to remove the contact from.
* @param bool|WP_Error $result True if the contact was updated or error if failed.
*/
public static function newspack_newsletters_update_contact_lists( $provider, $email, $lists_to_add, $lists_to_remove, $result ) {
switch ( $provider ) {
case 'active_campaign':
if ( true === $result && method_exists( '\Newspack_Newsletters_Subscription', 'add_contact' ) && method_exists( '\Newspack_Newsletters_Subscription', 'get_contact_lists' ) ) {
$current_lists = \Newspack_Newsletters_Subscription::get_contact_lists( $email );
// The add_contact method is idempotent, effectively being an upsertion.
\Newspack_Newsletters_Subscription::add_contact( [ 'email' => $email ], $current_lists );
}
break;
}
}

/**
* Modify metadata for newsletter contact creation.
*
* @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[] $metadata Contact additional metadata. Optional.
* }
* @param string[] $selected_list_ids Array of list IDs to subscribe the contact to.
*/
public static function newspack_newsletters_contact_data( $provider, $contact, $selected_list_ids ) {
switch ( $provider ) {
case 'active_campaign':
$metadata = [];
if ( is_user_logged_in() ) {
$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.
try {
if ( method_exists( '\Newspack_Newsletters_Subscription', 'get_lists' ) ) {
$lists = \Newspack_Newsletters_Subscription::get_lists();
if ( ! is_wp_error( $lists ) ) {
$lists_names = [];
foreach ( $selected_list_ids as $selected_list_id ) {
foreach ( $lists as $list ) {
if ( $list['id'] === $selected_list_id ) {
$lists_names[] = $list['name'];
}
}
}
// Note: this field will be overwritten every time it's updated.
$metadata['NP_Newsletter Selection'] = implode( ', ', $lists_names );
}
}
} catch ( \Throwable $e ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch
// Move along.
}

$signup_page_url = isset( $contact['metadata'], $contact['metadata']['current_page_url'] ) ? $contact['metadata']['current_page_url'] : null;
if ( $signup_page_url ) {
unset( $contact['metadata']['current_page_url'] );
}

// If it's a new contact, add some context on the signup/registration.
if ( $is_new_contact ) {
if ( ! $signup_page_url ) {
global $wp;
$signup_page_url = home_url( add_query_arg( array(), $wp->request ) );
}
$metadata['NP_Signup page'] = $signup_page_url;

// Capture UTM params.
$parsed_url = \wp_parse_url( $signup_page_url );
if ( isset( $parsed_url['query'] ) ) {
$url_params = array_reduce(
explode( '&', $parsed_url['query'] ),
function( $acc, $item ) {
$parts = explode( '=', $item );
$acc[ $parts[0] ] = $parts[1];
return $acc;
},
[]
);
foreach ( [ 'source', 'medium', 'campaign' ] as $value ) {
$param = 'utm_' . $value;
if ( isset( $url_params[ $param ] ) ) {
$metadata[ 'NP_Signup UTM: ' . $value ] = sanitize_text_field( $url_params[ $param ] );
}
}
}
}

if ( isset( $contact['metadata'] ) ) {
$contact['metadata'] = array_merge( $contact['metadata'], $metadata );
} else {
$contact['metadata'] = $metadata;
}

return $contact;
default:
return $contact;
}
}
}
Newspack_Newsletters::init();
31 changes: 21 additions & 10 deletions includes/reader-revenue/class-stripe-connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -393,27 +393,38 @@ public static function receive_webhook( $request ) {
// Update data in Newsletters provider.
$was_customer_added_to_mailing_list = false;
$stripe_data = self::get_stripe_data();
if ( ! empty( $stripe_data['newsletter_list_id'] ) && isset( $customer['metadata']['newsletterOptIn'] ) && 'true' === $customer['metadata']['newsletterOptIn'] ) {
$newsletters_configuration_manager = Configuration_Managers::configuration_manager_class_for_plugin_slug( 'newspack-newsletters' );

$has_opted_in_to_newsletters = isset( $customer['metadata']['newsletterOptIn'] ) && 'true' === $customer['metadata']['newsletterOptIn'];
if ( $has_opted_in_to_newsletters || Reader_Activation::is_enabled() ) {
$contact = [
'email' => $customer['email'],
'name' => $customer['name'],
'metadata' => [
'donation_date' => gmdate( 'Y-m-d', $payment['created'] ),
'donation_amount' => $amount_normalised,
'donation_frequency' => $frequency,
'donation_recurring' => 'once' !== $frequency,
'NP_Last Payment Date' => gmdate( 'Y-m-d', $payment['created'] ),
'NP_Last Payment Amount' => $amount_normalised,
],
];

if ( 'once' !== $frequency ) {
$contact['metadata']['NP_Billing Cycle'] = $frequency;
$contact['metadata']['NP_Recurring Payment'] = $amount_normalised;
}

if ( ! empty( $client_id ) ) {
$contact['client_id'] = $client_id;
}
if ( isset( $customer['metadata']['userId'] ) ) {
$contact['metadata']['NP_Account'] = $customer['metadata']['userId'];
}

// Note: With Mailchimp, this is adding the contact as 'pending' - the subscriber has to confirm.
$newsletters_configuration_manager->add_contact( $contact, $stripe_data['newsletter_list_id'] );
$was_customer_added_to_mailing_list = true;
if ( method_exists( '\Newspack_Newsletters_Subscription', 'add_contact' ) ) {
// Note: With Mailchimp, this is adding the contact as 'pending' - the subscriber has to confirm.
if ( ! empty( $stripe_data['newsletter_list_id'] ) && $has_opted_in_to_newsletters ) {
\Newspack_Newsletters_Subscription::add_contact( $contact, $stripe_data['newsletter_list_id'] );
} else {
\Newspack_Newsletters_Subscription::add_contact( $contact );
}
$was_customer_added_to_mailing_list = true;
}
}

// Update data in Campaigns plugin.
Expand Down