Skip to content
Draft
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: changed

Newsletter: default the modernized Subscribers experience on for all WordPress.com sites, retiring the legacy Calypso Subscribers submenu.
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
use Automattic\Jetpack\Newsletter\Settings as Newsletter_Settings;
use Automattic\Jetpack\Podcast\Admin_Page as Podcast_Admin_Page;
use Automattic\Jetpack\Redirect;
use Automattic\Jetpack\Status\Host;
use Automattic\Jetpack\Status\Visitor;

require_once __DIR__ . '/../../common/wpcom-callout.php';

Expand Down Expand Up @@ -392,52 +390,18 @@ function () {
// Jetpack > Subscribers. Always hide the auto-added Calypso redirect link.
wpcom_hide_submenu_page( 'jetpack', esc_url( Redirect::get_url( 'jetpack-menu-jetpack-manage-subscribers', array( 'site' => $blog_id ) ) ) );

// When the Newsletter modernization filter is on, the unified Newsletter page
// owns the Subscribers tab and the legacy Calypso "Subscribers" submenu is
// retired, replaced by a transitional announcement page that points there;
// otherwise we keep the legacy Calypso submenu. (The wp-admin
// subscriber-management variant was removed with the subscribers-dashboard
// package and isn't restored.)
//
// The filter default is the staged-rollout cohort: on for Automatticians (so
// a12s can dogfood and test fixes) and for the percentage cohort, bucketed by
// the site's stable wpcom blog ID. This mirrors the canonical
// Newsletter\Settings::is_modernization_rollout_enabled(); the newsletter
// package isn't a dependency of jetpack-mu-wpcom and this runs unconditionally —
// ahead of the class_exists-guarded Subscribers_Announcement use below — so the
// a11n check and the bucket math are inlined rather than referenced from the
// class. The rollout percentage — the one value that moves to widen the rollout —
// is read from the canonical MODERNIZATION_ROLLOUT_PERCENTAGE constant when the
// newsletter package is loaded (always so on WordPress.com), falling back to 0
// otherwise, so there is no second copy of the number to keep in sync. The
// percentage is currently 0 — the Simple-site rollout is driven from the
// WordPress.com backend instead.
//
// The cohort keys on the wpcom blog ID (current blog ID on Simple, stored wpcom
// ID on WoA) rather than the transient `IS_WPCOM` constant, so a site keeps its
// cohort decision when it is upgraded from Simple to Atomic and doesn't lose the
// modernized experience on transfer. The a12s check mirrors the canonical helper:
// `is_automattician()` is a WordPress.com global that only exists on Simple sites,
// so WoA falls back to the proxied-request check. (This mu-plugin only loads on
// WordPress.com, so the canonical helper's all-sites percentage gate reduces to
// the wpcom-blog-ID bucket here.)
// The unified Newsletter page now owns the Subscribers tab on every site: the
// legacy Calypso "Subscribers" submenu is retired and replaced by a transitional
// announcement page that points there. (The wp-admin subscriber-management variant
// was removed with the subscribers-dashboard package and isn't restored.) Hosts
// (and a11ns who want the legacy view back) can still force the old submenu back
// with add_filter( 'rsm_jetpack_ui_modernization_newsletter', '__return_false' ).
//
// On WordPress.com (Simple and WoA) this menu is the canonical owner of the
// Subscribers entry, so the announcement page is registered here for both
// platforms; the standalone plugin's subscriptions module defers to it on
// wpcom to avoid a duplicate.
$rollout_percentage = defined( '\Automattic\Jetpack\Newsletter\Settings::MODERNIZATION_ROLLOUT_PERCENTAGE' )
? (int) constant( '\Automattic\Jetpack\Newsletter\Settings::MODERNIZATION_ROLLOUT_PERCENTAGE' )
: 0;
$host = new Host();
$is_automattician = ( function_exists( 'is_automattician' ) && is_automattician() )
|| ( new Visitor() )->is_automattician_feature_flags_only();
$rollout_blog_id = $host->is_wpcom_simple()
? (int) get_current_blog_id()
: (int) \Jetpack_Options::get_option( 'id' );
$modernization_rollout_default = $is_automattician
|| ( $rollout_blog_id > 0 && ( $rollout_blog_id % 100 ) < $rollout_percentage );
if ( ! apply_filters( 'rsm_jetpack_ui_modernization_newsletter', $modernization_rollout_default ) ) {
if ( ! apply_filters( 'rsm_jetpack_ui_modernization_newsletter', true ) ) {
add_submenu_page(
'jetpack',
__( 'Subscribers', 'jetpack-mu-wpcom' ),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,43 +97,38 @@ private function get_legacy_subscribers_submenu_slug() {
}

/**
* By default — outside the staged-rollout cohort (percentage held at 0%, no
* Automattician) — `wpcom_add_jetpack_submenu()` keeps the legacy Calypso
* "Subscribers" submenu. This drives the non-Simple arm of the inlined cohort
* gate: with no `IS_WPCOM`, the site is bucketed on its stored wpcom blog ID
* (`jetpack_options['id']`), and `200 % 100 = 0` is not `< 0`, so it isn't
* enrolled.
* The Newsletter modernization gate now defaults on for every site, so by default
* `wpcom_add_jetpack_submenu()` retires the legacy Calypso "Subscribers" submenu —
* the unified Newsletter page owns the Subscribers tab. (The transitional
* announcement page is registered by the Newsletter package, which isn't a
* dependency of jetpack-mu-wpcom, so here the legacy link is simply absent.)
*/
public function test_jetpack_submenu_keeps_legacy_subscribers_link_by_default_on_non_simple_site() {
public function test_jetpack_submenu_retires_legacy_subscribers_link_by_default() {
\Jetpack_Options::update_option( 'id', 200 );

wpcom_add_jetpack_submenu();

$this->assertSame(
'https://wordpress.com/subscribers/' . self::$domain,
$this->assertNull(
$this->get_legacy_subscribers_submenu_slug(),
'The legacy Subscribers submenu must remain when the site is outside the rollout cohort.'
'The legacy Subscribers submenu must be retired by default now that the rollout is at 100%.'
);
}

/**
* The same default on a WordPress.com Simple site, which buckets on the current
* blog ID rather than the stored option — exercising the Simple arm of the cohort
* gate. `Constants::set_constant` flips `Host::is_wpcom_simple()` without an
* irreversible `define()`; the stored option still satisfies the connection's
* site-ID lookup so the function doesn't bail early.
* Hosts (and a11ns who want the legacy view back) can still opt out with
* `add_filter( 'rsm_jetpack_ui_modernization_newsletter', '__return_false' )`,
* which keeps the legacy Calypso "Subscribers" submenu instead of retiring it.
*/
public function test_jetpack_submenu_keeps_legacy_subscribers_link_by_default_on_simple_site() {
Constants::set_constant( 'IS_WPCOM', true );
Status_Cache::clear();
public function test_jetpack_submenu_keeps_legacy_subscribers_link_when_modernization_filter_off() {
\Jetpack_Options::update_option( 'id', 200 );
add_filter( 'rsm_jetpack_ui_modernization_newsletter', '__return_false' );

wpcom_add_jetpack_submenu();

$this->assertSame(
'https://wordpress.com/subscribers/' . self::$domain,
$this->get_legacy_subscribers_submenu_slug(),
'A Simple site outside the rollout cohort must keep the legacy Subscribers submenu.'
'The legacy Subscribers submenu must remain when the modernization gate is filtered off.'
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: changed

Roll the modernized Newsletter dashboard out to all sites and remove the staged-rollout cohort scaffolding.
95 changes: 6 additions & 89 deletions projects/packages/newsletter/src/class-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
use Automattic\Jetpack\Redirect;
use Automattic\Jetpack\Status;
use Automattic\Jetpack\Status\Host;
use Automattic\Jetpack\Status\Visitor;
use Jetpack_Tracks_Client;

/**
Expand All @@ -34,22 +33,6 @@ class Settings {
*/
const MODERNIZATION_FILTER = 'rsm_jetpack_ui_modernization_newsletter';

/**
* Percentage of sites the modernized Newsletter experience defaults on for
* during the staged rollout.
*
* Currently 0: the Simple-site rollout is driven from the WordPress.com backend
* instead (a server-side feature-flag value that can be rolled back instantly),
* so the Jetpack-side cohort is held at zero. The cohort code stays in place for
* Atomic (WoA) and self-hosted Jetpack sites; bumping this single number is the
* one-line change that widens the rollout once the Simple cohort is validated.
* Automatticians get the experience regardless of this percentage.
*
* Sites are bucketed deterministically by their wpcom blog ID, so every gate
* that reads this lands on the same answer for a given site.
*/
const MODERNIZATION_ROLLOUT_PERCENTAGE = 0;

/**
* Whether the class has been initialized
*
Expand Down Expand Up @@ -286,7 +269,7 @@ public function add_script_data( $data ) {
$is_block_theme = wp_is_block_theme();
$setup_payment_plan_url = ( $is_wpcom ? 'https://wordpress.com/earn/payments/' : 'https://cloud.jetpack.com/monetize/payments/' ) . $site_suffix;

$wp_admin_subscriber_management_enabled = apply_filters( 'jetpack_wp_admin_subscriber_management_enabled', self::is_modernization_rollout_enabled() );
$wp_admin_subscriber_management_enabled = apply_filters( 'jetpack_wp_admin_subscriber_management_enabled', true );

// Populate blog_id which is needed for API calls on Simple sites.
$data['site']['wpcom']['blog_id'] = $blog_id;
Expand Down Expand Up @@ -505,84 +488,18 @@ public static function alias_screen_id_for_wp_build( $screen ) {
$screen->id = 'jetpack-newsletter-dashboard';
}

/**
* Whether the modernized Newsletter experience should default on for this site.
*
* The release is staged: the modernized dashboard, wp-admin subscriber
* management, and the retired Calypso Subscribers submenu all default on for a
* deterministic slice of sites, keyed on the wpcom blog ID, plus all
* Automatticians.
*
* The percentage cohort (see `MODERNIZATION_ROLLOUT_PERCENTAGE`) spans *all*
* sites — Simple, WoA (Atomic) and self-hosted Jetpack — and is bucketed on the
* wpcom blog ID (`get_current_blog_id()` on Simple, `jetpack_options['id']`
* elsewhere), which is preserved when a Simple site is upgraded to Atomic. Keying
* on the wpcom blog ID rather than the transient `IS_WPCOM` constant means a site
* keeps its cohort decision across the transfer. The percentage is currently 0:
* the Simple-site rollout is driven from the WordPress.com backend instead, and
* this gate stays at zero until the wider rollout is opened by bumping the
* constant. A site with no resolvable wpcom blog ID (e.g. a self-hosted Jetpack
* site that isn't connected) is never bucketed in.
*
* Automatticians get the modernized experience by default regardless of the
* percentage cohort, so a12s can dogfood it and test fixes ahead of the wider
* rollout. This is a dogfooding gate, not an authorization check, so the Simple
* `is_automattician()` global is used without the usual proxied-request pairing;
* Atomic has no non-proxied a12s signal, so it falls back to
* `Visitor::is_automattician_feature_flags_only()` (true for proxied a8c requests).
*
* This is only the filter *default*: hosts (and a11ns who want the legacy view
* back) can still force the experience on or off with the
* `rsm_jetpack_ui_modernization_newsletter` /
* `jetpack_wp_admin_subscriber_management_enabled` filters.
*
* @return bool
*/
public static function is_modernization_rollout_enabled() {
// Automatticians are enrolled regardless of the percentage cohort so they
// can dogfood ahead of the wider rollout. Simple exposes the
// `is_automattician()` global; Atomic has no non-proxied a12s signal, so we
// fall back to the proxied-request check. (Dogfooding gate, so no
// `wpcom_is_proxied_request()` pairing on the Simple branch.)
if (
( function_exists( 'is_automattician' ) && is_automattician() )
|| ( new Visitor() )->is_automattician_feature_flags_only()
) {
return true;
}

// Bucket on the wpcom blog ID, which is stable across a Simple→Atomic
// transfer: the current blog ID on Simple, the stored wpcom ID elsewhere. We
// read the WoA/Jetpack ID from Jetpack options directly rather than via
// `Host::get_wpcom_site_id()`, which additionally requires the Jetpack
// connection to be "ready" — that would drop a freshly transferred site out
// of the cohort until its connection settles. Guard against an unresolvable
// ID so a site without one isn't bucketed as blog ID 0 and enrolled by
// accident once the percentage is non-zero.
$host = new Host();
$blog_id = $host->is_wpcom_simple()
? (int) get_current_blog_id()
: (int) \Jetpack_Options::get_option( 'id' );
if ( $blog_id <= 0 ) {
return false;
}

return ( $blog_id % 100 ) < self::MODERNIZATION_ROLLOUT_PERCENTAGE;
}

/**
* Returns true when the wp-build modernization filter is enabled.
*
* Defaults to the staged-rollout cohort (see
* `is_modernization_rollout_enabled()`): on for Automatticians and for the
* percentage cohort (currently 0%), off everywhere else. Hosts can opt in or out
* explicitly with
* `add_filter( self::MODERNIZATION_FILTER, '__return_true' / '__return_false' );`.
* The modernized Newsletter dashboard, wp-admin subscriber management, and the
* retired Calypso Subscribers submenu now default on for every site. Hosts (and
* a11ns who want the legacy view back) can still force the legacy experience with
* `add_filter( self::MODERNIZATION_FILTER, '__return_false' );`.
*
* @return bool
*/
private static function is_modernized() {
return (bool) apply_filters( self::MODERNIZATION_FILTER, self::is_modernization_rollout_enabled() );
return (bool) apply_filters( self::MODERNIZATION_FILTER, true );
}

/**
Expand Down
Loading
Loading