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

feat(ia): audience configuration boilerplate #3500

Merged
merged 36 commits into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
d1cad1c
feat: adds audience development configuration
jaredrethman Oct 11, 2024
842edf4
Merge remote-tracking branch 'origin/epic/ia' into feat/ia-audience
jaredrethman Oct 21, 2024
a7be15d
Merge remote-tracking branch 'origin/epic/ia' into feat/ia-audience
jaredrethman Oct 23, 2024
364ac22
refactor: added `newspack` prefix to slug
jaredrethman Oct 23, 2024
6cced4f
refactor: make css class global
jaredrethman Oct 24, 2024
da928a6
feat: add `description` prop to WizardsTab component
jaredrethman Oct 24, 2024
bd85a45
feat: wrap in `WizardsTab` component
jaredrethman Oct 24, 2024
3ff7fa3
refactor: name change `/audience-configuration` to `/audience`
jaredrethman Oct 25, 2024
84d4d43
Merge remote-tracking branch 'origin/epic/ia' into feat/ia-audience
jaredrethman Oct 25, 2024
fe1d154
Merge remote-tracking branch 'origin/epic/ia' into feat/ia-audience
jaredrethman Oct 28, 2024
035075f
refactor: allow multiple react apps through a single directory
jaredrethman Oct 30, 2024
2de1d80
fix: ci / eslint
jaredrethman Nov 1, 2024
359065f
Merge remote-tracking branch 'origin/epic/ia' into feat/ia-audience
jaredrethman Nov 1, 2024
ca7d05b
feat: add reader activation campaign link
jaredrethman Nov 1, 2024
7f90d67
feat: wip fixing newsletter enpoint
jaredrethman Nov 5, 2024
a90bfd4
Merge remote-tracking branch 'origin/epic/ia' into feat/ia-audience
jaredrethman Nov 5, 2024
f631e13
feat: update esp href for ras
jaredrethman Nov 5, 2024
5d54aec
feat: update newsletters endpoint
jaredrethman Nov 5, 2024
eb26f31
feat: update recaptcha href
jaredrethman Nov 5, 2024
52bb202
Merge remote-tracking branch 'origin/epic/ia' into feat/ia-audience
jaredrethman Nov 5, 2024
7812cc6
feat: text changes
jaredrethman Nov 5, 2024
bd8c799
refactor: final prep for review
jaredrethman Nov 6, 2024
cd5d5f4
fix: style issues on wizards not using `WizardsTab` component
jaredrethman Nov 6, 2024
a830ac0
refactor: add class `use` imports
jaredrethman Nov 7, 2024
827f70d
feat: add recaptcha scroll-to anchor
jaredrethman Nov 7, 2024
75cb7b9
feat: moved ts types to separate files
jaredrethman Nov 7, 2024
d3d0912
feat: update endpoints to audience configuration
jaredrethman Nov 7, 2024
3320b2d
feat: add `scrollToAnchor` doc comment
jaredrethman Nov 7, 2024
f433027
fix: menu order
miguelpeixe Nov 13, 2024
41af659
fix: active menu items
miguelpeixe Nov 14, 2024
03922a4
Merge branch 'epic/ia' into feat/ia-audience
ronchambers Nov 14, 2024
d87d0ab
feat(ia-audience): after merge, adjust menu ordering
ronchambers Nov 14, 2024
4ea5532
chore: remove ras from engagement wizard
miguelpeixe Nov 14, 2024
2740cf7
chore: remove duplicated components
miguelpeixe Nov 14, 2024
f572a65
fix: `#/complete` link url
miguelpeixe Nov 14, 2024
d70a121
Merge remote-tracking branch 'origin/epic/ia' into feat/ia-audience
jaredrethman Nov 19, 2024
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
4 changes: 4 additions & 0 deletions includes/class-newspack.php
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ private function includes() {
// Advertising Wizard.
include_once NEWSPACK_ABSPATH . 'includes/wizards/advertising/class-advertising-display-ads.php';
include_once NEWSPACK_ABSPATH . 'includes/wizards/advertising/class-advertising-sponsors.php';

// Audience Wizard.
include_once NEWSPACK_ABSPATH . 'includes/wizards/audience/class-audience-configuration.php';
include_once NEWSPACK_ABSPATH . 'includes/wizards/audience/class-audience-campaigns.php';

// Network Wizard.
include_once NEWSPACK_ABSPATH . 'includes/wizards/class-network-wizard.php';
Expand Down
2 changes: 2 additions & 0 deletions includes/class-wizards.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public static function init() {
),
'advertising-display-ads' => new Advertising_Display_Ads(),
'advertising-sponsors' => new Advertising_Sponsors(),
'audience-configuration' => new Audience_Configuration(),
'audience-campaigns' => new Audience_Campaigns(),
'listings' => new Listings_Wizard(),
'network' => new Network_Wizard(),
'newsletters' => new Newsletters_Wizard(),
Expand Down
7 changes: 4 additions & 3 deletions includes/reader-activation/class-reader-activation.php
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ public static function get_prerequisites_status() {
'description' => __( 'Connect to your ESP to register readers with their email addresses and send newsletters.', 'newspack-plugin' ),
'instructions' => __( 'Connect to your email service provider (ESP) and enable at least one subscription list.', 'newspack-plugin' ),
'help_url' => 'https://help.newspack.com/engagement/reader-activation-system',
'href' => \admin_url( '/admin.php?page=newspack-engagement-wizard#/newsletters' ),
'href' => \admin_url( 'edit.php?post_type=newspack_nl_cpt&page=newspack-newsletters' ),
'action_text' => __( 'ESP settings' ),
],
'emails' => [
Expand Down Expand Up @@ -536,7 +536,7 @@ public static function get_prerequisites_status() {
'description' => __( 'Connecting to a Google reCAPTCHA account enables enhanced anti-spam for all Newspack sign-up blocks.', 'newspack-plugin' ),
'instructions' => __( 'Enable reCAPTCHA and enter your account credentials.', 'newspack-plugin' ),
'help_url' => 'https://help.newspack.com/engagement/reader-activation-system',
'href' => \admin_url( '/admin.php?page=newspack-connections-wizard&scrollTo=recaptcha' ),
'href' => \admin_url( '/admin.php?page=newspack-settings&scrollTo=newspack-settings-recaptcha' ),
'action_text' => __( 'reCAPTCHA settings' ),
],
'reader_revenue' => [
Expand All @@ -550,6 +550,7 @@ public static function get_prerequisites_status() {
'description' => __( 'Setting suggested donation amounts is required for enabling a streamlined donation experience.', 'newspack-plugin' ),
'instructions' => __( 'Set platform to "Newspack" or "News Revenue Hub" and configure your default donation settings. If using News Revenue Hub, set an Organization ID and a Donor Landing Page in News Revenue Hub Settings.', 'newspack-plugin' ),
'help_url' => 'https://help.newspack.com/engagement/reader-activation-system',
// @TODO: Update when platform is added.
'href' => \admin_url( '/admin.php?page=newspack-reader-revenue-wizard' ),
'action_text' => __( 'Reader Revenue settings' ),
],
Expand All @@ -562,7 +563,7 @@ public static function get_prerequisites_status() {
'label' => __( 'Reader Activation Campaign', 'newspack-plugin' ),
'description' => __( 'Building a set of prompts with default segments and settings allows for an improved experience optimized for Reader Activation.', 'newspack-plugin' ),
'help_url' => 'https://help.newspack.com/engagement/reader-activation-system',
'href' => self::is_ras_campaign_configured() ? \admin_url( '/admin.php?page=newspack-popups-wizard#/campaigns' ) : \admin_url( '/admin.php?page=newspack-engagement-wizard#/reader-activation/campaign' ),
'href' => self::is_ras_campaign_configured() ? admin_url( '/admin.php?page=newspack-audience-campaigns' ) : admin_url( '/admin.php?page=newspack-audience-configuration#/campaign' ),
'action_enabled' => self::is_ras_ready_to_configure(),
'action_text' => __( 'Reader Activation campaign', 'newspack-plugin' ),
'disabled_text' => __( 'Waiting for all settings to be ready', 'newspack-plugin' ),
Expand Down
66 changes: 66 additions & 0 deletions includes/wizards/audience/class-audience-campaigns.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php
/**
* Audience Campaigns Wizard
*
* @package Newspack
*/

namespace Newspack;

defined( 'ABSPATH' ) || exit;

/**
* Audience Campaigns Wizard.
*/
class Audience_Campaigns extends Wizard {

/**
* Admin page slug.
*
* @var string
*/
protected $slug = 'newspack-audience-campaigns';

/**
* Parent slug.
*
* @var string
*/
protected $parent_slug = 'newspack-audience-configuration';

/**
* Get the name for this wizard.
*
* @return string The wizard name.
*/
public function get_name() {
return esc_html__( 'Audience Development / Campaigns', 'newspack-plugin' );
}

/**
* Enqueue scripts and styles.
*/
public function enqueue_scripts_and_styles() {
if ( ! $this->is_wizard_page() ) {
return;
}

parent::enqueue_scripts_and_styles();

wp_enqueue_script( 'newspack-wizards' );
}

/**
* Add Audience top-level and Campaigns subpage to the /wp-admin menu.
*/
public function add_page() {
add_submenu_page(
$this->parent_slug,
$this->get_name(),
esc_html__( 'Campaigns', 'newspack-plugin' ),
$this->capability,
$this->slug,
[ $this, 'render_wizard' ]
);
}
}
275 changes: 275 additions & 0 deletions includes/wizards/audience/class-audience-configuration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,275 @@
<?php
/**
* Audience Configuration Wizard
*
* @package Newspack
*/

namespace Newspack;

use Newspack\{
Newsletters,
Reader_Activation
};
use Newspack_Newsletters_Subscription;
use WP_REST_Request, WP_REST_Response, WP_REST_Server;

defined( 'ABSPATH' ) || exit;

/**
* Audience Configuration Wizard.
*/
class Audience_Configuration extends Wizard {

/**
* Option to skip campaign setup.
*
* @var string
*/
const SKIP_CAMPAIGN_SETUP_OPTION = '_newspack_ras_skip_campaign_setup';

/**
* Admin page slug.
*
* @var string
*/
protected $slug = 'newspack-audience-configuration';

/**
* The parent menu item name.
*
* @var string
*/
public $parent_menu = 'newspack-audience-configuration';

/**
* Order relative to the Newspack Dashboard menu item.
*
* @var int
*/
public $menu_order = 1;

/**
* Audience Configuration Constructor.
*/
public function __construct() {
parent::__construct();
add_action( 'rest_api_init', [ $this, 'register_api_endpoints' ] );
}

/**
* Get the name for this wizard.
*
* @return string The wizard name.
*/
public function get_name() {
return esc_html__( 'Audience Development / Configuration', 'newspack-plugin' );
}

/**
* Enqueue scripts and styles.
*/
public function enqueue_scripts_and_styles() {
if ( ! $this->is_wizard_page() ) {
return;
}
parent::enqueue_scripts_and_styles();
$data = [
'has_memberships' => class_exists( 'WC_Memberships' ),
'reader_activation_url' => admin_url( 'admin.php?page=newspack-audience-configuration#/' ),
'esp_metadata_fields' => Reader_Activation\Sync\Metadata::get_default_fields(),
];

if ( method_exists( 'Newspack\Newsletters\Subscription_Lists', 'get_add_new_url' ) ) {
$data['new_subscription_lists_url'] = Newsletters\Subscription_Lists::get_add_new_url();
}

if ( method_exists( 'Newspack_Newsletters_Subscription', 'get_lists' ) ) {
$data['available_newsletter_lists'] = Newspack_Newsletters_Subscription::get_lists();
}

$newspack_popups = Configuration_Managers::configuration_manager_class_for_plugin_slug( 'newspack-popups' );

if ( $newspack_popups->is_configured() ) {
$data['preview_query_keys'] = $newspack_popups->preview_query_keys();
$data['preview_post'] = $newspack_popups->preview_post();
$data['preview_archive'] = $newspack_popups->preview_archive();
}

$data['is_skipped_campaign_setup'] = get_option( static::SKIP_CAMPAIGN_SETUP_OPTION, '' );

wp_enqueue_script( 'newspack-wizards' );

wp_localize_script(
'newspack-wizards',
'newspackAudienceConfiguration',
$data
);
}

/**
* Add Audience top-level and Configuration subpage to the /wp-admin menu.
*/
public function add_page() {
// svg source - https://wphelpers.dev/icons/people
// SVG generated via https://boxy-svg.com/ with path width/height 20px.
$icon = 'data:image/svg+xml;base64,' . base64_encode(
'<svg viewBox="20 20 24 24" xmlns="http://www.w3.org/2000/svg">
<path fill="none" stroke="none" d="M 36.242 29.578 C 37.176 29.578 37.759 28.568 37.292 27.76 C 37.075 27.385 36.675 27.154 36.242 27.154 C 35.309 27.154 34.726 28.164 35.193 28.972 C 35.41 29.347 35.81 29.578 36.242 29.578 Z M 36.242 31.396 C 38.576 31.396 40.033 28.872 38.867 26.851 C 38.325 25.913 37.325 25.336 36.242 25.336 C 33.909 25.336 32.452 27.861 33.618 29.881 C 34.16 30.819 35.16 31.396 36.242 31.396 Z M 33.515 38.669 L 33.515 36.245 C 33.515 34.404 32.023 32.912 30.182 32.912 L 25.333 32.912 C 23.492 32.912 22 34.404 22 36.245 L 22 38.669 L 23.818 38.669 L 23.818 36.245 C 23.818 35.409 24.497 34.73 25.333 34.73 L 30.182 34.73 C 31.018 34.73 31.697 35.409 31.697 36.245 L 31.697 38.669 L 33.515 38.669 Z M 42 36.245 L 42 38.669 L 40.182 38.669 L 40.182 36.245 C 40.182 35.409 39.503 34.73 38.667 34.73 L 35.636 34.73 L 35.636 32.912 L 38.667 32.912 C 40.508 32.912 42 34.404 42 36.245 Z M 28.97 28.366 C 28.97 29.299 27.96 29.882 27.152 29.416 C 26.777 29.199 26.545 28.799 26.545 28.366 C 26.545 27.433 27.555 26.85 28.364 27.316 C 28.738 27.533 28.97 27.933 28.97 28.366 Z M 30.788 28.366 C 30.788 30.699 28.263 32.156 26.242 30.99 C 25.304 30.448 24.727 29.448 24.727 28.366 C 24.727 26.033 27.252 24.576 29.273 25.742 C 30.211 26.284 30.788 27.284 30.788 28.366 Z"/>
</svg>'
);
add_menu_page(
$this->get_name(),
__( 'Audience', 'newspack-plugin' ),
$this->capability,
$this->slug,
[ $this, 'render_wizard' ],
$icon,
3.6
);
add_submenu_page(
$this->slug,
$this->get_name(),
__( 'Configuration', 'newspack-plugin' ),
$this->capability,
$this->slug,
[ $this, 'render_wizard' ]
);
}

/**
* Register the endpoints needed for the wizard screens.
*/
public function register_api_endpoints() {
register_rest_route(
NEWSPACK_API_NAMESPACE,
'/wizard/' . $this->slug . '/reader-activation',
[
'methods' => WP_REST_Server::READABLE,
'callback' => [ $this, 'api_get_reader_activation_settings' ],
'permission_callback' => [ $this, 'api_permissions_check' ],
]
);
register_rest_route(
NEWSPACK_API_NAMESPACE,
'/wizard/' . $this->slug . '/reader-activation',
[
'methods' => WP_REST_Server::EDITABLE,
'callback' => [ $this, 'api_update_reader_activation_settings' ],
'permission_callback' => [ $this, 'api_permissions_check' ],
]
);
register_rest_route(
NEWSPACK_API_NAMESPACE,
'/wizard/' . $this->slug . '/reader-activation/activate',
[
'methods' => WP_REST_Server::EDITABLE,
'callback' => [ $this, 'api_activate_reader_activation' ],
'permission_callback' => [ $this, 'api_permissions_check' ],
]
);
register_rest_route(
NEWSPACK_API_NAMESPACE,
'/wizard/' . $this->slug . '/reader-activation/skip-campaign-setup',
[
'methods' => WP_REST_Server::EDITABLE,
'callback' => function( $request ) {
$skip = $request->get_param( 'skip' );
$skip_campaign_setup = update_option( static::SKIP_CAMPAIGN_SETUP_OPTION, $skip );
return rest_ensure_response(
[
'skipped' => $skip,
'updated' => $skip_campaign_setup,
]
);
},
'permission_callback' => [ $this, 'api_permissions_check' ],
]
);
}

/**
* Get reader activation settings.
*
* @return WP_REST_Response
*/
public function api_get_reader_activation_settings() {
return rest_ensure_response(
[
'config' => Reader_Activation::get_settings(),
'prerequisites_status' => Reader_Activation::get_prerequisites_status(),
'memberships' => self::get_memberships_settings(),
'can_esp_sync' => Reader_Activation\ESP_Sync::can_esp_sync( true ),
]
);
}

/**
* Update reader activation settings.
*
* @param WP_REST_Request $request Request object.
*
* @return WP_REST_Response
*/
public function api_update_reader_activation_settings( $request ) {
$args = $request->get_params();
foreach ( $args as $key => $value ) {
Reader_Activation::update_setting( $key, $value );
}

// Update Memberships options.
if ( isset( $args['memberships_require_all_plans'] ) ) {
Memberships::set_require_all_plans_setting( (bool) $args['memberships_require_all_plans'] );
}

// Update Memberships options.
if ( isset( $args['memberships_show_on_subscription_tab'] ) ) {
Memberships::set_show_on_subscription_tab_setting( (bool) $args['memberships_show_on_subscription_tab'] );
}

return rest_ensure_response(
[
'config' => Reader_Activation::get_settings(),
'prerequisites_status' => Reader_Activation::get_prerequisites_status(),
'memberships' => self::get_memberships_settings(),
'can_esp_sync' => Reader_Activation\ESP_Sync::can_esp_sync( true ),
]
);
}

/**
* Activate reader activation and publish RAS prompts/segments.
*
* @param WP_REST_Request $request WP Rest Request object.
* @return WP_REST_Response
*/
public function api_activate_reader_activation( WP_REST_Request $request ) {
$skip_activation = $request->get_param( 'skip_activation' ) ?? false;
$response = $skip_activation ? true : Reader_Activation::activate();

if ( is_wp_error( $response ) ) {
return new WP_REST_Response( [ 'message' => $response->get_error_message() ], 400 );
}

if ( true === $response ) {
Reader_Activation::update_setting( 'enabled', true );
}

return rest_ensure_response( $response );
}

/**
* Get memberships settings.
*
* @return array
*/
private static function get_memberships_settings() {
return [
'edit_gate_url' => Memberships::get_edit_gate_url(),
'gate_status' => get_post_status( Memberships::get_gate_post_id() ),
'plans' => Memberships::get_plans(),
'require_all_plans' => Memberships::get_require_all_plans_setting(),
'show_on_subscription_tab' => Memberships::get_show_on_subscription_tab_setting(),
];
}
}
Loading