Skip to content
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

fix(nrh): fixes for ESP contact syncing w/ NRH, newsletter signups #3779

Open
wants to merge 9 commits into
base: release
Choose a base branch
from
3 changes: 3 additions & 0 deletions includes/cli/class-ras-esp-sync.php
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,9 @@ private static function sync_contacts( $config ) {
* @return bool
*/
private static function user_has_active_subscriptions( $user_id ) {
if ( ! function_exists( 'wcs_get_users_subscriptions' ) ) {
return false;
}
$subcriptions = array_reduce(
array_keys( \wcs_get_users_subscriptions( $user_id ) ),
function( $acc, $subscription_id ) {
Expand Down
24 changes: 12 additions & 12 deletions includes/data-events/connectors/class-esp-connector.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,9 @@ public static function subscription_renewal_attempt( $timestamp, $data, $client_
return;
}

/**
* When a renewal happens, it triggers two syncs to the ESP, one setting the subscription as on hold, and a
* second one setting it back to active. This sometimes creates a race condition on the ESP side.
/**
* When a renewal happens, it triggers two syncs to the ESP, one setting the subscription as on hold, and a
* second one setting it back to active. This sometimes creates a race condition on the ESP side.
* This third request will make sure the ESP always has the correct and most up to date data about the reader.
*/
self::schedule_sync(
Expand Down Expand Up @@ -200,9 +200,10 @@ public static function reader_deleted( $timestamp, $data, $client_id ) {
* @param array $data Data.
*/
public static function newsletter_updated( $timestamp, $data ) {
if ( empty( $data['user_id'] ) || empty( $data['email'] ) ) {
if ( empty( $data['user_id'] ) || empty( $data['email'] ) || empty( $data['contact'] ) ) {
return;
}
$contact = $data['contact'];
$subscribed_lists = \Newspack_Newsletters_Subscription::get_contact_lists( $data['email'] );
if ( is_wp_error( $subscribed_lists ) || ! is_array( $subscribed_lists ) ) {
return;
Expand All @@ -220,14 +221,13 @@ public static function newsletter_updated( $timestamp, $data ) {
}
}

$metadata = [
'account' => $data['user_id'],
'newsletter_selection' => implode( ', ', $lists_names ),
];
$contact = [
'email' => $data['email'],
'metadata' => $metadata,
];
$contact['metadata'] = array_merge(
$contact['metadata'],
[
'account' => $data['user_id'],
'newsletter_selection' => implode( ', ', $lists_names ),
]
);
self::sync( $contact, 'Updating newsletter_selection field after a change in the subscription lists.' );
}

Expand Down
3 changes: 2 additions & 1 deletion includes/plugins/class-teams-for-memberships.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

defined( 'ABSPATH' ) || exit;

use Newspack\Donations;
use Newspack\Reader_Activation\Sync;

/**
Expand All @@ -31,7 +32,7 @@ public static function init() {
* @return bool True if enabled, false otherwise.
*/
private static function is_enabled() {
return class_exists( 'WC_Memberships_For_Teams_Loader' );
return Donations::is_platform_wc() && class_exists( 'WC_Memberships_For_Teams_Loader' );
}

/**
Expand Down
32 changes: 22 additions & 10 deletions includes/reader-activation/sync/class-esp-sync.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,18 @@ public static function sync( $contact, $context = '' ) {
}

// If we're running in a data event, queue the sync to run on shutdown.
if ( ! isset( self::$queued_syncs[ $contact['email'] ] ) ) {
self::$queued_syncs[ $contact['email'] ] = [
'contexts' => [],
'contact' => [],
];
}
if ( ! empty( self::$queued_syncs[ $contact['email'] ]['contact']['metadata'] ) ) {
$contact['metadata'] = array_merge( self::$queued_syncs[ $contact['email'] ]['contact']['metadata'], $contact['metadata'] );
}
self::$queued_syncs[ $contact['email'] ]['contexts'][] = $context;
self::$queued_syncs[ $contact['email'] ]['contact'] = $contact;
if ( Data_Events::current_event() && ! did_action( 'shutdown' ) ) {
if ( ! isset( self::$queued_syncs[ $contact['email'] ] ) ) {
self::$queued_syncs[ $contact['email'] ] = [];
}
self::$queued_syncs[ $contact['email'] ][] = $context;
return;
}

Expand All @@ -126,10 +133,8 @@ public static function sync( $contact, $context = '' ) {
* @param string $context The context of the sync.
*/
$contact = \apply_filters( 'newspack_esp_sync_contact', $contact, $context );

$contact = Sync\Metadata::normalize_contact_data( $contact );

$result = \Newspack_Newsletters_Contacts::upsert( $contact, $master_list_id, $context );
$result = \Newspack_Newsletters_Contacts::upsert( $contact, $master_list_id, $context );

return \is_wp_error( $result ) ? $result : true;
}
Expand Down Expand Up @@ -207,7 +212,14 @@ protected static function get_contact_data( $user_id ) {
$customer->save();
}

return Sync\WooCommerce::get_contact_from_customer( $customer );
$contact = Sync\WooCommerce::get_contact_from_customer( $customer );

// Include data from queued syncs too.
if ( ! empty( self::$queued_syncs[ $contact['email'] ]['contact']['metadata'] ) ) {
$contact['metadata'] = array_merge( self::$queued_syncs[ $contact['email'] ]['contact']['metadata'], $contact['metadata'] );
}

return $contact;
}

/**
Expand Down Expand Up @@ -256,7 +268,7 @@ public static function run_queued_syncs() {
return;
}

foreach ( self::$queued_syncs as $email => $contexts ) {
foreach ( self::$queued_syncs as $email => $queued_sync ) {
$user = get_user_by( 'email', $email );
if ( ! $user ) {
continue;
Expand All @@ -266,7 +278,7 @@ public static function run_queued_syncs() {
if ( ! $contact ) {
continue;
}

$contexts = $queued_sync['contexts'];
self::sync( $contact, implode( '; ', $contexts ) );
}

Expand Down
12 changes: 8 additions & 4 deletions includes/reader-activation/sync/class-metadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace Newspack\Reader_Activation\Sync;

use Newspack\Donations;
use Newspack\Reader_Activation;
use Newspack\Logger;

Expand Down Expand Up @@ -42,12 +43,15 @@ class Metadata {
*/
public static function get_keys() {
if ( empty( self::$keys ) ) {
// Only get Woo fields if using Woo.
$fields = Donations::is_platform_wc() ? self::get_all_fields() : self::get_basic_fields();

/**
* Filters the list of key/value pairs for metadata fields to be synced to the connected ESP.
*
* @param array $keys The list of key/value pairs for metadata fields to be synced to the connected ESP.
*/
self::$keys = \apply_filters( 'newspack_ras_metadata_keys', self::get_all_fields() );
self::$keys = \apply_filters( 'newspack_ras_metadata_keys', $fields );
}
return self::$keys;
}
Expand Down Expand Up @@ -355,9 +359,9 @@ private static function add_registration_data( $metadata ) {
public static function add_utm_data( $metadata ) {
// Capture UTM params and signup/payment page URLs as meta for registration or payment.
if ( self::has_key( 'current_page_url', $metadata ) || self::has_key( 'registration_page', $metadata ) || self::has_key( 'payment_page', $metadata ) ) {
$is_payment = self::has_key( 'payment_page', $metadata );
$payment_page = self::has_key( 'payment_page', $metadata ) ? self::get_key_value( 'payment_page', $metadata ) : false;
$raw_url = false;
if ( $is_payment ) {
if ( ! empty( $payment_page ) ) {
$raw_url = self::get_key_value( 'payment_page', $metadata );
} elseif ( self::has_key( 'current_page_url', $metadata ) ) {
$raw_url = self::get_key_value( 'current_page_url', $metadata );
Expand All @@ -369,7 +373,7 @@ public static function add_utm_data( $metadata ) {

// Maybe set UTM meta.
if ( ! empty( $parsed_url['query'] ) ) {
$utm_key_prefix = $is_payment ? 'payment_page_utm' : 'signup_page_utm';
$utm_key_prefix = ! empty( $payment_page ) ? 'payment_page_utm' : 'signup_page_utm';
$params = [];
\wp_parse_str( $parsed_url['query'], $params );
foreach ( $params as $param => $value ) {
Expand Down
7 changes: 5 additions & 2 deletions includes/reader-activation/sync/class-woocommerce.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public static function should_sync_order( $order ) {
* @return \WC_Order|false Order object or false.
*/
private static function get_current_product_order_for_sync( $customer ) {
if ( ! is_a( $customer, 'WC_Customer' ) ) {
if ( ! class_exists( 'WC_Customer' ) || ! is_a( $customer, 'WC_Customer' ) ) {
return false;
}

Expand Down Expand Up @@ -99,6 +99,9 @@ private static function get_current_product_order_for_sync( $customer ) {
* @return ?WCS_Subscription A Subscription object or null.
*/
private static function get_most_recent_cancelled_or_expired_subscription( $user_id ) {
if ( ! function_exists( 'wcs_get_users_subscriptions' ) ) {
return;
}
$subscriptions = array_reduce(
array_keys( \wcs_get_users_subscriptions( $user_id ) ),
function( $acc, $subscription_id ) {
Expand Down Expand Up @@ -376,7 +379,7 @@ private static function get_order_metadata( $order, $payment_page_url = false )
* @return array|false Contact data or false.
*/
public static function get_contact_from_customer( $customer, $payment_page_url = false ) {
if ( ! is_a( $customer, 'WC_Customer' ) ) {
if ( ! class_exists( 'WC_Customer' ) || ! is_a( $customer, 'WC_Customer' ) ) {
$customer = new \WC_Customer( $customer );
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,9 @@ public static function rate_limit_payment_methods( $is_valid ) {
* @return int[] Array of active subscription IDs.
*/
public static function get_active_subscriptions_for_user( $user_id, $product_ids = [] ) {
if ( ! function_exists( 'wcs_get_users_subscriptions' ) ) {
return [];
}
$subcriptions = array_reduce(
array_keys( \wcs_get_users_subscriptions( $user_id ) ),
function( $acc, $subscription_id ) use ( $product_ids ) {
Expand Down
8 changes: 5 additions & 3 deletions src/wizards/readerRevenue/views/donation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
TextControl,
Wizard,
} from '../../../../components/src';
import { READER_REVENUE_WIZARD_SLUG } from '../../constants';
import { NEWSPACK, READER_REVENUE_WIZARD_SLUG } from '../../constants';

type FrequencySlug = 'once' | 'month' | 'year';

Expand Down Expand Up @@ -371,6 +371,8 @@ const BillingFields = () => {
const Donation = () => {
const wizardData = Wizard.useWizardData( 'reader-revenue' ) as WizardData;
const { saveWizardSettings } = useDispatch( Wizard.STORE_NAMESPACE );
const { platform_data } = wizardData;
const usedPlatform = platform_data?.platform;
const onSaveDonationSettings = () =>
saveWizardSettings( {
slug: READER_REVENUE_WIZARD_SLUG,
Expand Down Expand Up @@ -429,7 +431,7 @@ const Donation = () => {
) }
<DonationAmounts />
</ActionCard>
<ActionCard
{ NEWSPACK === usedPlatform && ( <ActionCard
description={ __( 'Configure options for modal checkouts.', 'newspack-plugin' ) }
hasGreyHeader={ true }
isMedium
Expand All @@ -441,7 +443,7 @@ const Donation = () => {
}
>
<BillingFields />
</ActionCard>
</ActionCard> ) }
</>
);
};
Expand Down