diff --git a/includes/class-admin.php b/includes/class-admin.php index 5ef77d1a..20abf1ed 100644 --- a/includes/class-admin.php +++ b/includes/class-admin.php @@ -198,11 +198,6 @@ public static function enqueue_scripts() { * @return bool True if experimental auditing features are enabled. */ public static function use_experimental_auditing_features() { - $user_slug = defined( 'NEWSPACK_NETWORK_EXPERIMENTAL_AUDITING_USER' ) ? NEWSPACK_NETWORK_EXPERIMENTAL_AUDITING_USER : false; - if ( ! $user_slug ) { - return false; - } - $user = get_user_by( 'login', $user_slug ); - return $user && get_current_user_id() === $user->ID; + return defined( 'NEWSPACK_NETWORK_EXPERIMENTAL_AUDITING_FEATURES' ) ? NEWSPACK_NETWORK_EXPERIMENTAL_AUDITING_FEATURES : false; } } diff --git a/includes/class-esp-metadata-sync.php b/includes/class-esp-metadata-sync.php index 20cabc3b..9f7f599e 100644 --- a/includes/class-esp-metadata-sync.php +++ b/includes/class-esp-metadata-sync.php @@ -7,6 +7,8 @@ namespace Newspack_Network; +use Newspack_Network\Utils\Users as User_Utils; + /** * Class to handle Node settings page */ @@ -21,6 +23,8 @@ public static function init() { \add_filter( 'newspack_ras_metadata_keys', [ __CLASS__, 'add_custom_metadata_fields' ] ); \add_filter( 'newspack_register_reader_metadata', [ __CLASS__, 'handle_custom_metadata_fields' ], 10, 2 ); \add_filter( 'newspack_data_events_reader_registered_metadata', [ __CLASS__, 'handle_custom_metadata_fields' ], 10, 2 ); + \add_action( 'newspack_network_network_reader', [ __CLASS__, 'handle_custom_metadata_for_network_readers' ] ); + \add_action( 'newspack_network_new_network_reader', [ __CLASS__, 'handle_custom_metadata_for_network_readers' ] ); } /** @@ -48,9 +52,62 @@ public static function add_custom_metadata_fields( $metadata_fields ) { */ public static function handle_custom_metadata_fields( $metadata, $user_id ) { if ( $user_id ) { - $metadata['network_registration_site'] = \esc_url( \get_site_url() ); + $remote_site = \get_user_meta( $user_id, User_Utils::USER_META_REMOTE_SITE, true ); + $registration_site = \esc_url( ! empty( \wp_http_validate_url( $remote_site ) ) ? $remote_site : \get_site_url() ); + $metadata['network_registration_site'] = $registration_site; } return $metadata; } + + /** + * Trigger a reader data sync to the connected ESP. + * + * @param array $contact The contact data to sync. + */ + public static function sync_contact( $contact ) { + // Only if Reader Activation and Newspack Newsletters are available. + if ( ! class_exists( 'Newspack\Reader_Activation' ) || ! method_exists( 'Newspack_Newsletters', 'service_provider' ) ) { + return; + } + + // Only if RAS + ESP sync is enabled. + if ( ! \Newspack\Reader_Activation::is_enabled() || ! \Newspack\Reader_Activation::get_setting( 'sync_esp' ) ) { + return; + } + + // Only if we have the ESP Data Events connectors. + if ( ! class_exists( 'Newspack\Data_Events\Connectors\Mailchimp' ) || ! class_exists( 'Newspack\Data_Events\Connectors\ActiveCampaign' ) ) { + return; + } + + $service_provider = \Newspack_Newsletters::service_provider(); + if ( 'mailchimp' === $service_provider ) { + return \Newspack\Data_Events\Connectors\Mailchimp::put( $contact ); + } elseif ( 'active_campaign' === $service_provider ) { + return \Newspack\Data_Events\Connectors\ActiveCampaign::put( $contact ); + } + } + + /** + * Sync custom metadata fields for network readers. + * + * @param WP_User $user The newly created or existing user. + */ + public static function handle_custom_metadata_for_network_readers( $user ) { + if ( ! $user ) { + return; + } + $contact = \Newspack\WooCommerce_Connection::get_contact_from_customer( new \WC_Customer( $user->ID ) ); + $metadata = $contact['metadata'] ?? []; + + // Ensure email is set as the user probably won't have a billing email. + if ( ! isset( $contact['email'] ) ) { + $contact['email'] = $user->user_email; + } + + $contact['metadata'] = self::handle_custom_metadata_fields( $metadata, $user->ID ); + + self::sync_contact( $contact ); + } } diff --git a/includes/cli/backfillers/class-reader-registered.php b/includes/cli/backfillers/class-reader-registered.php index 7d13a1ea..b801e7d7 100644 --- a/includes/cli/backfillers/class-reader-registered.php +++ b/includes/cli/backfillers/class-reader-registered.php @@ -35,7 +35,7 @@ public function get_events() { if ( empty( $roles_to_sync ) ) { WP_CLI::error( 'Incompatible Newspack plugin version or no roles to sync.' ); } - // Get all users registered between this-> and $end. + // Get all users registered between specified dates. $users = get_users( [ 'role__in' => $roles_to_sync, @@ -44,6 +44,7 @@ public function get_events() { 'before' => $this->end, 'inclusive' => true, ], + 'orderby' => 'user_registered', 'fields' => [ 'id', 'user_email', 'user_registered' ], 'number' => -1, 'meta_query' => [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query @@ -76,9 +77,12 @@ function( $args ) { foreach ( $users as $user ) { $registration_method = get_user_meta( $user->ID, \Newspack\Reader_Activation::REGISTRATION_METHOD, true ); $user_data = [ - 'user_id' => $user->ID, - 'email' => $user->user_email, - 'metadata' => [ + 'user_id' => $user->ID, + 'email' => $user->user_email, + 'user_registered' => $user->user_registered, + 'first_name' => get_user_meta( $user->ID, 'first_name', true ), + 'last_name' => get_user_meta( $user->ID, 'last_name', true ), + 'meta_input' => [ // 'current_page_url' is not saved, can't be backfilled. 'registration_method' => empty( $registration_method ) ? 'backfill-script' : $registration_method, ], diff --git a/includes/cli/backfillers/class-woocommerce-membership-updated.php b/includes/cli/backfillers/class-woocommerce-membership-updated.php index 1939654d..6a30c52f 100644 --- a/includes/cli/backfillers/class-woocommerce-membership-updated.php +++ b/includes/cli/backfillers/class-woocommerce-membership-updated.php @@ -77,10 +77,20 @@ public function get_events() { 'membership_id' => $membership->get_id(), 'new_status' => $status, ]; - if ( $status === 'active' ) { + switch ( $status ) { + case 'paused': + $timestamp = strtotime( $membership->get_paused_date() ); + break; + case 'cancelled': + $timestamp = strtotime( $membership->get_cancelled_date() ); + break; + case 'expired': + $timestamp = strtotime( $membership->get_end_date() ); + break; + } + + if ( ! $timestamp ) { $timestamp = strtotime( $membership->get_start_date() ); - } else { - $timestamp = strtotime( $membership->get_end_date() ); } $events[] = new \Newspack_Network\Incoming_Events\Woocommerce_Membership_Updated( get_bloginfo( 'url' ), $membership_data, $timestamp ); diff --git a/includes/utils/class-users.php b/includes/utils/class-users.php index cb88ef91..fe6d5128 100644 --- a/includes/utils/class-users.php +++ b/includes/utils/class-users.php @@ -30,6 +30,13 @@ public static function get_or_create_user_by_email( $email, $remote_site_url, $r $existing_user = get_user_by( 'email', $email ); if ( $existing_user ) { + /** + * Fires when fetching an existing network reader account. + * + * @param WP_User $new_user The existing user. + */ + do_action( 'newspack_network_network_reader', $existing_user ); + return $existing_user; } @@ -43,6 +50,10 @@ public static function get_or_create_user_by_email( $email, $remote_site_url, $r $user_array = array_merge( $user_array, $insert_array ); + if ( isset( $user_array['meta_input'] ) ) { + $user_array['meta_input'] = (array) $user_array['meta_input']; + } + $user_id = wp_insert_user( $user_array ); if ( is_wp_error( $user_id ) ) { @@ -53,7 +64,16 @@ public static function get_or_create_user_by_email( $email, $remote_site_url, $r update_user_meta( $user_id, self::USER_META_REMOTE_SITE, $remote_site_url ); update_user_meta( $user_id, self::USER_META_REMOTE_ID, $remote_id ); - return get_user_by( 'id', $user_id ); + $new_user = get_user_by( 'id', $user_id ); + + /** + * Fires when a new network reader account is created and all network user meta has been added. + * + * @param WP_User $new_user The newly created user. + */ + do_action( 'newspack_network_new_network_reader', $new_user ); + + return $new_user; } /**