Skip to content

Commit b095d7e

Browse files
authored
Merge pull request #22612 from Yoast/change-helpscout-beacon-behavior
Change helpscout beacon behavior
2 parents 73b94de + 10e961b commit b095d7e

File tree

6 files changed

+124
-42
lines changed

6 files changed

+124
-42
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@
107107
"Yoast\\WP\\SEO\\Composer\\Actions::check_coding_standards"
108108
],
109109
"check-cs-thresholds": [
110-
"@putenv YOASTCS_THRESHOLD_ERRORS=2395",
110+
"@putenv YOASTCS_THRESHOLD_ERRORS=2385",
111111
"@putenv YOASTCS_THRESHOLD_WARNINGS=251",
112112
"Yoast\\WP\\SEO\\Composer\\Actions::check_cs_thresholds"
113113
],

packages/js/src/support/app.js

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,17 @@ const openHelpScoutBeacon = () => {
3232
}
3333
};
3434

35+
/* eslint-disable complexity */
36+
3537
/**
3638
* @returns {JSX.Element} The app component.
39+
*
3740
*/
3841
export const App = () => {
39-
const isPremium = useSelectSupport( "selectPreference", [], "isPremium", false );
42+
const hasPremiumSubscription = useSelectSupport( "selectPreference", [], "hasPremiumSubscription", false );
43+
const hasWooSeoSubscription = useSelectSupport( "selectPreference", [], "hasWooSeoSubscription", false );
44+
const isWooCommerceActive = useSelectSupport( "selectPreference", [], "isWooCommerceActive", false );
45+
const hasAnyAddon = hasPremiumSubscription || hasWooSeoSubscription;
4046
const premiumUpsellConfig = useSelectSupport( "selectUpsellSettingsAsProps" );
4147
const pluginUrl = useSelectSupport( "selectPreference", [], "pluginUrl", "" );
4248
const linkParams = useSelectSupport( "selectLinkParams" );
@@ -48,7 +54,6 @@ export const App = () => {
4854
const githubLink = useSelectSupport( "selectLink", [], "https://yoa.st/github-repository-support-card" );
4955
const contactSupportLink = useSelectSupport( "selectLink", [], "https://yoa.st/contact-support-to-unlock-premium-support-section" );
5056
const { isPromotionActive } = useSelect( STORE_NAME );
51-
const isWooCommerceActive = useSelectSupport( "selectPreference", [], "isWooCommerceActive" );
5257

5358
const faq = useMemo( () => ( [
5459
{
@@ -87,7 +92,7 @@ export const App = () => {
8792

8893
return (
8994
<div className="yst-p-4 min-[783px]:yst-p-8">
90-
<div className={ classNames( "yst-flex yst-flex-grow yst-flex-wrap", ! isPremium && "xl:yst-pe-[17.5rem]" ) }>
95+
<div className={ classNames( "yst-flex yst-flex-grow yst-flex-wrap", ! hasAnyAddon && "xl:yst-pe-[17.5rem]" ) }>
9196
<Paper as="main" className="yst-max-w-page yst-flex-grow yst-mb-8 xl:yst-mb-0">
9297
<Paper.Header>
9398
<div className="yst-max-w-screen-sm">
@@ -182,7 +187,7 @@ export const App = () => {
182187
title={ (
183188
<div className="yst-flex yst-items-center yst-gap-1.5">
184189
<span>{ __( "Contact our support team", "wordpress-seo" ) }</span>
185-
{ isPremium && <Badge variant="upsell">Premium</Badge> }
190+
{ hasAnyAddon && <Badge variant="upsell">Premium</Badge> }
186191
</div>
187192
) }
188193
description={ (
@@ -203,7 +208,7 @@ export const App = () => {
203208
) }
204209
>
205210
<FeatureUpsell
206-
shouldUpsell={ ! isPremium }
211+
shouldUpsell={ ! hasAnyAddon }
207212
variant="card"
208213
cardLink={ contactSupportLink }
209214
cardText={ sprintf(
@@ -213,7 +218,7 @@ export const App = () => {
213218
) }
214219
{ ...premiumUpsellConfig }
215220
>
216-
<div className={ classNames( "yst-flex", ! isPremium && "yst-opacity-50" ) }>
221+
<div className={ classNames( "yst-flex", ! hasAnyAddon && "yst-opacity-50" ) }>
217222
<div className="yst-me-6">
218223
<p>{ __( "Our support team is here to answer any questions you may have. Fill out the (pop-up) contact form, and we'll get back to you as soon as possible!", "wordpress-seo" ) }</p>
219224
<Button
@@ -239,7 +244,7 @@ export const App = () => {
239244
</div>
240245
</Paper.Content>
241246
</Paper>
242-
{ ! isPremium &&
247+
{ ! hasAnyAddon &&
243248
<div className="xl:yst-max-w-3xl xl:yst-fixed xl:yst-end-8 xl:yst-w-[16rem]">
244249
<SidebarRecommendations
245250
premiumLink={ isWooCommerceActive ? wooLink : premiumLink }

src/integrations/admin/helpscout-beacon.php

Lines changed: 60 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,24 @@ class HelpScout_Beacon implements Integration_Interface {
3434
*/
3535
protected $beacon_id_tracking_users = '6b8e74c5-aa81-4295-b97b-c2a62a13ea7f';
3636

37+
/**
38+
* The id for the beacon for Premium users.
39+
*
40+
* @var string
41+
*/
42+
protected $beacon_id_premium = '1ae02e91-5865-4f13-b220-7daed946ba25';
43+
44+
/**
45+
* The id for the beacon for WooCommerce SEO users.
46+
*
47+
* @var string
48+
*/
49+
protected $beacon_id_woocommerce = '8535d745-4e80-48b9-b211-087880aa857d';
50+
3751
/**
3852
* The products the beacon is loaded for.
3953
*
40-
* @var array
54+
* @var array<string>
4155
*/
4256
protected $products = [];
4357

@@ -55,17 +69,24 @@ class HelpScout_Beacon implements Integration_Interface {
5569
*/
5670
protected $options;
5771

72+
/**
73+
* The addon manager.
74+
*
75+
* @var WPSEO_Addon_Manager
76+
*/
77+
protected $addon_manager;
78+
5879
/**
5980
* The array of pages we need to show the beacon on with their respective beacon IDs.
6081
*
61-
* @var array
82+
* @var array<string, string>
6283
*/
6384
protected $pages_ids;
6485

6586
/**
6687
* The array of pages we need to show the beacon on.
6788
*
68-
* @var array
89+
* @var array<string>
6990
*/
7091
protected $base_pages = [
7192
'wpseo_dashboard',
@@ -106,10 +127,12 @@ class HelpScout_Beacon implements Integration_Interface {
106127
* @param Options_Helper $options The options helper.
107128
* @param WPSEO_Admin_Asset_Manager $asset_manager The asset manager.
108129
* @param Migration_Status $migration_status The migrations status.
130+
* @param WPSEO_Addon_Manager $addon_manager The addon manager.
109131
*/
110-
public function __construct( Options_Helper $options, WPSEO_Admin_Asset_Manager $asset_manager, Migration_Status $migration_status ) {
132+
public function __construct( Options_Helper $options, WPSEO_Admin_Asset_Manager $asset_manager, Migration_Status $migration_status, WPSEO_Addon_Manager $addon_manager ) {
111133
$this->options = $options;
112134
$this->asset_manager = $asset_manager;
135+
$this->addon_manager = $addon_manager;
113136
$this->ask_consent = ! $this->options->get( 'tracking' );
114137
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information.
115138
if ( isset( $_GET['page'] ) && \is_string( $_GET['page'] ) ) {
@@ -121,19 +144,16 @@ public function __construct( Options_Helper $options, WPSEO_Admin_Asset_Manager
121144
}
122145
$this->migration_status = $migration_status;
123146

147+
$beacon_id = $this->get_beacon_id();
124148
foreach ( $this->base_pages as $page ) {
125-
if ( $this->ask_consent ) {
126-
// We want to be able to show surveys to people who have tracking on, so we give them a different beacon.
127-
$this->pages_ids[ $page ] = $this->beacon_id_tracking_users;
128-
}
129-
else {
130-
$this->pages_ids[ $page ] = $this->beacon_id;
131-
}
149+
$this->pages_ids[ $page ] = $beacon_id;
132150
}
133151
}
134152

135153
/**
136154
* {@inheritDoc}
155+
*
156+
* @return void
137157
*/
138158
public function register_hooks() {
139159
\add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_help_scout_script' ] );
@@ -247,7 +267,7 @@ protected function get_session_data() {
247267
/**
248268
* Returns basic info about the server software.
249269
*
250-
* @return array
270+
* @return array<string, string>
251271
*/
252272
private function get_server_info() {
253273
$server_tracking_data = new WPSEO_Tracking_Server_Data();
@@ -441,12 +461,37 @@ private function get_language_settings() {
441461
/**
442462
* Returns the conditionals based on which this integration should be active.
443463
*
444-
* @return array The array of conditionals.
464+
* @return array<string> The array of conditionals.
445465
*/
446466
public static function get_conditionals() {
447467
return [ Admin_Conditional::class ];
448468
}
449469

470+
/**
471+
* Get the beacon id to use based on the user's subscription and tracking settings.
472+
*
473+
* @return string The beacon id to use.
474+
*/
475+
private function get_beacon_id() {
476+
// Case where the user has a Yoast WooCommerce SEO plan subscription (highest priority).
477+
if ( $this->addon_manager->has_valid_subscription( WPSEO_Addon_Manager::WOOCOMMERCE_SLUG ) ) {
478+
return $this->beacon_id_woocommerce;
479+
}
480+
481+
// Case where the user has a Yoast SEO Premium plan subscription.
482+
if ( $this->addon_manager->has_valid_subscription( WPSEO_Addon_Manager::PREMIUM_SLUG ) ) {
483+
return $this->beacon_id_premium;
484+
}
485+
486+
// Case where the user has no plan active and tracking enabled.
487+
if ( $this->ask_consent ) {
488+
return $this->beacon_id_tracking_users;
489+
}
490+
491+
// Case where the user has no plan active and tracking disabled.
492+
return $this->beacon_id;
493+
}
494+
450495
/**
451496
* Allows filtering of the HelpScout settings. Hooked to admin_head to prevent timing issues, not too early, not too late.
452497
*
@@ -464,8 +509,7 @@ protected function filter_settings() {
464509
* @param string $beacon_settings The HelpScout beacon settings.
465510
*/
466511
$helpscout_settings = \apply_filters( 'wpseo_helpscout_beacon_settings', $filterable_helpscout_setting );
467-
468-
$this->products = $helpscout_settings['products'];
469-
$this->pages_ids = $helpscout_settings['pages_ids'];
512+
$this->products = $helpscout_settings['products'];
513+
$this->pages_ids = $helpscout_settings['pages_ids'];
470514
}
471515
}

src/integrations/support-integration.php

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Yoast\WP\SEO\Integrations;
44

5+
use WPSEO_Addon_Manager;
56
use WPSEO_Admin_Asset_Manager;
67
use Yoast\WP\SEO\Conditionals\Admin_Conditional;
78
use Yoast\WP\SEO\Conditionals\User_Can_Manage_Wpseo_Options_Conditional;
@@ -55,6 +56,13 @@ class Support_Integration implements Integration_Interface {
5556
*/
5657
private $woocommerce_conditional;
5758

59+
/**
60+
* Holds the WPSEO_Addon_Manager.
61+
*
62+
* @var WPSEO_Addon_Manager
63+
*/
64+
private $addon_manager;
65+
5866
/**
5967
* Constructs Support_Integration.
6068
*
@@ -63,25 +71,28 @@ class Support_Integration implements Integration_Interface {
6371
* @param Product_Helper $product_helper The Product_Helper.
6472
* @param Short_Link_Helper $shortlink_helper The Short_Link_Helper.
6573
* @param WooCommerce_Conditional $woocommerce_conditional The WooCommerce_Conditional.
74+
* @param WPSEO_Addon_Manager $addon_manager The WPSEO_Addon_Manager.
6675
*/
6776
public function __construct(
6877
WPSEO_Admin_Asset_Manager $asset_manager,
6978
Current_Page_Helper $current_page_helper,
7079
Product_Helper $product_helper,
7180
Short_Link_Helper $shortlink_helper,
72-
WooCommerce_Conditional $woocommerce_conditional
81+
WooCommerce_Conditional $woocommerce_conditional,
82+
WPSEO_Addon_Manager $addon_manager
7383
) {
7484
$this->asset_manager = $asset_manager;
7585
$this->current_page_helper = $current_page_helper;
7686
$this->product_helper = $product_helper;
7787
$this->shortlink_helper = $shortlink_helper;
7888
$this->woocommerce_conditional = $woocommerce_conditional;
89+
$this->addon_manager = $addon_manager;
7990
}
8091

8192
/**
8293
* Returns the conditionals based on which this loadable should be active.
8394
*
84-
* @return array
95+
* @return array<string>
8596
*/
8697
public static function get_conditionals() {
8798
return [ Admin_Conditional::class, User_Can_Manage_Wpseo_Options_Conditional::class ];
@@ -108,11 +119,11 @@ public function register_hooks() {
108119
/**
109120
* Adds the page.
110121
*
111-
* @param array $pages The pages.
122+
* @param array<array<string|callable>> $pages The pages.
112123
*
113-
* @return array The pages.
124+
* @return array<array<string|callable>> The pages.
114125
*/
115-
public function add_page( $pages ) {
126+
public function add_page( array $pages ) {
116127
$pages[] = [
117128
'wpseo_dashboard',
118129
'',
@@ -165,19 +176,20 @@ public function remove_notices() {
165176
/**
166177
* Creates the script data.
167178
*
168-
* @return array The script data.
179+
* @return array<string, array<array<string, bool|string|array<string>>, bool, string>> The script data.
169180
*/
170181
public function get_script_data() {
171182
return [
172183
'preferences' => [
173-
'isPremium' => $this->product_helper->is_premium(),
174-
'isRtl' => \is_rtl(),
175-
'pluginUrl' => \plugins_url( '', \WPSEO_FILE ),
176-
'upsellSettings' => [
184+
'hasPremiumSubscription' => $this->addon_manager->has_valid_subscription( WPSEO_Addon_Manager::PREMIUM_SLUG ),
185+
'hasWooSeoSubscription' => $this->addon_manager->has_valid_subscription( WPSEO_Addon_Manager::WOOCOMMERCE_SLUG ),
186+
'isRtl' => \is_rtl(),
187+
'pluginUrl' => \plugins_url( '', \WPSEO_FILE ),
188+
'upsellSettings' => [
177189
'actionId' => 'load-nfd-ctb',
178190
'premiumCtbId' => 'f6a84663-465f-4cb5-8ba5-f7a6d72224b2',
179191
],
180-
'isWooCommerceActive' => $this->woocommerce_conditional->is_met(),
192+
'isWooCommerceActive' => $this->woocommerce_conditional->is_met(),
181193
],
182194
'linkParams' => $this->shortlink_helper->get_query_params(),
183195
'currentPromotions' => \YoastSEO()->classes->get( Promotion_Manager::class )->get_current_promotions(),

0 commit comments

Comments
 (0)