Skip to content
Open
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
5 changes: 5 additions & 0 deletions includes/class-newspack.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ private function includes() {
include_once NEWSPACK_ABSPATH . 'includes/reader-activation/sync/class-woocommerce.php';
include_once NEWSPACK_ABSPATH . 'includes/reader-activation/sync/class-esp-sync.php';
include_once NEWSPACK_ABSPATH . 'includes/reader-activation/sync/class-esp-sync-admin.php';
include_once NEWSPACK_ABSPATH . 'includes/reader-activation/sync/class-integrations-init.php';
\Newspack\Reader_Activation\Sync\Integrations_Init::init();

include_once NEWSPACK_ABSPATH . 'includes/reader-activation/wisepops/class-wisepops.php';
include_once NEWSPACK_ABSPATH . 'includes/data-events/class-utils.php';
include_once NEWSPACK_ABSPATH . 'includes/data-events/class-data-events.php';
include_once NEWSPACK_ABSPATH . 'includes/data-events/class-webhooks.php';
Expand Down Expand Up @@ -167,6 +171,7 @@ private function includes() {
include_once NEWSPACK_ABSPATH . 'includes/wizards/audience/class-audience-content-gates.php';
include_once NEWSPACK_ABSPATH . 'includes/wizards/audience/class-audience-donations.php';
include_once NEWSPACK_ABSPATH . 'includes/wizards/audience/class-audience-subscriptions.php';
include_once NEWSPACK_ABSPATH . 'includes/wizards/audience/class-audience-integrations.php';

// Network Wizard.
include_once NEWSPACK_ABSPATH . 'includes/wizards/class-network-wizard.php';
Expand Down
1 change: 1 addition & 0 deletions includes/class-wizards.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public static function init_wizards() {
'audience-campaigns' => new Audience_Campaigns(),
'audience-content-gates' => new Audience_Content_Gates(),
'audience-donations' => new Audience_Donations(),
'audience-integrations' => new Audience_Integrations(),
'listings' => new Listings_Wizard(),
'network' => new Network_Wizard(),
'newsletters' => new Newsletters_Wizard(),
Expand Down
20 changes: 20 additions & 0 deletions includes/reader-activation/class-reader-activation.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ public static function init() {
\add_action( 'wp_footer', [ __CLASS__, 'render_newsletters_signup_modal' ] );
\add_action( 'wp_ajax_newspack_reader_activation_newsletters_signup', [ __CLASS__, 'newsletters_signup' ] );
\add_action( 'woocommerce_customer_reset_password', [ __CLASS__, 'login_after_password_reset' ] );
\add_action( 'wp_ajax_nopriv_newspack_reader_activation_should_register', [ __CLASS__, 'ajax_should_register' ] );

if ( self::is_enabled() ) {
\add_action( 'rest_api_init', [ __CLASS__, 'register_routes' ] );
Expand Down Expand Up @@ -127,6 +128,24 @@ public static function init() {
}
}

/**
* AJAX handler to check if an email is already registered.
*/
public static function ajax_should_register() {

// This is just a POC.
$email = \sanitize_email( $_POST['email'] ?? '' ); // phpcs:ignore
$registered = self::register_reader( $email, '', true, [] );

$response = [
'success' => is_int( $registered ),
'user_id' => is_int( $registered ) ? $registered : null,
];

wp_send_json( $response );
exit;
}

/**
* Enqueue front-end scripts.
*/
Expand All @@ -143,6 +162,7 @@ public static function enqueue_scripts() {
'auth_action_result' => Magic_Link::AUTH_ACTION_RESULT,
'account_url' => function_exists( 'wc_get_account_endpoint_url' ) ? \wc_get_account_endpoint_url( 'dashboard' ) : '',
'is_ras_enabled' => self::is_enabled(),
'ajax_url' => admin_url( 'admin-ajax.php' ),
];

if ( Recaptcha::can_use_captcha() ) {
Expand Down
77 changes: 73 additions & 4 deletions includes/reader-activation/sync/class-esp-sync.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
namespace Newspack\Reader_Activation;

use Newspack\Reader_Activation;
use Newspack\Reader_Data;
use Newspack\Data_Events;
use Newspack\Logger;
use Newspack\Reader_Activation\Sync\Integrations;

defined( 'ABSPATH' ) || exit;

Expand Down Expand Up @@ -37,6 +39,8 @@ class ESP_Sync extends Sync {
public static function init_hooks() {
add_action( 'newspack_scheduled_esp_sync', [ __CLASS__, 'scheduled_sync' ], 10, 2 );
add_action( 'shutdown', [ __CLASS__, 'run_queued_syncs' ] );

add_action( 'init', [ __CLASS__, 'pull_current_user_data' ] );
}

/**
Expand Down Expand Up @@ -125,8 +129,6 @@ public static function sync( $contact, $context = '', $existing_contact = null )
return;
}

$master_list_id = Reader_Activation::get_esp_master_list_id();

/**
* Filters the contact data before normalizing and syncing to the ESP.
*
Expand All @@ -135,9 +137,30 @@ public static function sync( $contact, $context = '', $existing_contact = null )
*/
$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, $existing_contact );

return \is_wp_error( $result ) ? $result : true;
$integrations = Integrations::get_active_integrations();

foreach ( $integrations as $integration ) {
$result = $integration->push_contact_data( $contact, $context );
if ( \is_wp_error( $result ) ) {
static::log(
sprintf(
// Translators: %1$s is the email address of the contact to be synced, %2$s is the integration name.
__( 'Failed to sync contact %1$s to %2$s.', 'newspack-plugin' ),
$contact['email'],
$integration->get_name()
),
[
'user_email' => $contact['email'],
'error' => $result->get_error_message(),
'context' => $context,
],
'error'
);
}
}

return true;
}

/**
Expand Down Expand Up @@ -296,5 +319,51 @@ public static function run_queued_syncs() {

self::$queued_syncs = [];
}

/**
* Pull current logged-in user's data from active integrations and store it in Reader Data.
*
* TODO: Pull only every X minutes...
*
* @return void
*/
public static function pull_current_user_data() {
if ( ! is_user_logged_in() ) {
return;
}

$user_id = get_current_user_id();
self::pull_reader_data( $user_id );
}

/**
* Pull reader data from active integrations and store it in Reader Data.
*
* @param int $user_id The user ID.
*
* @return true|\WP_Error True on success, WP_Error on failure.
*/
public static function pull_reader_data( $user_id ) {
$integrations = Integrations::get_active_integrations();

$user = get_userdata( $user_id );
if ( ! $user ) {
return new \WP_Error( 'user_not_found', __( 'User not found.', 'newspack-plugin' ) );
}

$contact_data = [];
foreach ( $integrations as $integration ) {
$contact = $integration->get_contact_data( $user->user_email );
if ( ! is_wp_error( $contact ) ) {
$contact_data = array_merge( $contact_data, $contact );
}
}

foreach ( $contact_data as $key => $value ) {
Reader_Data::update_item( $user_id, strtolower( $key ), wp_json_encode( $value ) );
}

return true;
}
}
ESP_Sync::init_hooks();
104 changes: 104 additions & 0 deletions includes/reader-activation/sync/class-integrations-init.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?php
/**
* Integrations Initialization
*
* @package Newspack
*/

namespace Newspack\Reader_Activation\Sync;

defined( 'ABSPATH' ) || exit;

/**
* Integrations Initialization Class.
*
* Initializes integrations system, registers example integrations,
* and sets up REST API.
*/
class Integrations_Init {
/**
* Initialize integrations system.
*/
public static function init() {
// Include required files.
require_once __DIR__ . '/class-integrations.php';
require_once __DIR__ . '/integrations/class-integration.php';
require_once __DIR__ . '/integrations/class-example-integration.php';
require_once __DIR__ . '/integrations/class-esp.php';

// Initialize REST API.
Integrations::init_rest_api();

add_action( 'init', [ __CLASS__, 'init_callback' ], 5 );

add_filter( 'newspack_content_gate_access_rules', [ __CLASS__, 'register_access_control_rules' ] );
}

/**
* Callback for init action to register integrations and popup criteria.
*/
public static function init_callback() {
// Register default integrations.
self::register_default_integrations();

self::register_popup_criteria();

// Hook for other plugins/code to register their integrations.
do_action( 'newspack_reader_activation_register_integrations' );
}

/**
* Register the default integrations.
*/
private static function register_default_integrations() {
$example_integration = new Integrations\Example_Integration();
Integrations::register( $example_integration );

$esp_integration = new Integrations\ESP();
Integrations::register( $esp_integration );
}

/**
* Register popup criteria for all active integrations.
*/
private static function register_popup_criteria() {
if ( ! class_exists( '\Newspack_Popups_Criteria' ) ) {
return;
}

$integrations = Integrations::get_active_integrations();

foreach ( $integrations as $integration ) {
$metadata = $integration->get_metadata_keys();
foreach ( $metadata as $label ) {
\Newspack_Popups_Criteria::register_criteria( $label );
}
}
}

/**
* Register access control rules for all active integrations.
*
* @param array $rules Existing access control rules.
* @return array Modified access control rules.
*/
public static function register_access_control_rules( $rules ) {
$integrations = Integrations::get_active_integrations();

foreach ( $integrations as $integration ) {
$metadata = $integration->get_metadata_keys();
foreach ( $metadata as $key ) {
$rules[ $key ] = [
'name' => $key,
'description' => 'User must have this metadata set with this value',
'type' => 'string',
'placeholder' => 'value',
'default' => '',
'callback' => [ __CLASS__, 'check_access_control' ],
];
}
}

return $rules;
}
}
Loading