Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
96.18% covered (success)
96.18%
126 / 131
83.33% covered (warning)
83.33%
10 / 12
CRAP
0.00% covered (danger)
0.00%
0 / 1
WPCOM_Features
96.18% covered (success)
96.18%
126 / 131
83.33% covered (warning)
83.33%
10 / 12
82
0.00% covered (danger)
0.00%
0 / 1
 feature_exists
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 in_array_recursive
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
5
 has_feature
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
8
 add_free_plan_purchase
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 resolve_blog_id
60.00% covered (warning)
60.00%
3 / 5
0.00% covered (danger)
0.00%
0 / 1
3.58
 site_has_sticker
40.00% covered (danger)
40.00%
2 / 5
0.00% covered (danger)
0.00%
0 / 1
10.40
 is_legacy_gating_site
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
8
 get_map_sticker_slugs
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
7
 get_cohort_sensitive_features
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
6
 get_site_gating_cache_suffix
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
 purchase_in_products_map
100.00% covered (success)
100.00%
51 / 51
100.00% covered (success)
100.00%
1 / 1
33
 get_feature_slugs
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * THIS FILE EXISTS VERBATIM IN WPCOM AND WPCOMSH.
4 *
5 * DANGER DANGER DANGER!!!
6 * If you make any changes to this class you must MANUALLY update this file in both WPCOM and WPCOMSH.
7 *
8 * @package WPCOM_Features
9 */
10
11/**
12 * Map features to purchases.
13 */
14class WPCOM_Features {
15
16    /**
17     * Key used to exclude plans from features.
18     */
19    public const EXCLUDE_PLANS = 'exclude_plans';
20
21    /**
22     * Sticker marking a site that has switched from legacy features to 2026 feature gating
23     * after plan upgrade/downgrade. One-way change.
24     */
25    public const STICKER_FEATURE_GATING_2026 = 'feature-gating-2026';
26
27    /**
28     * Sticker marking a site that stays on the pre-2026 feature gating regardless of its blog ID.
29     * Only needed for staging sites since they could be created after the cutoff.
30     */
31    public const STICKER_PRE_FEATURE_GATING_2026 = 'pre-feature-gating-2026';
32
33    /**
34     * The original pricing-differentiation sticker. Used for identifying sites with new features
35     * which were created before the cutoff, as part of an experiment.
36     */
37    public const STICKER_GATING_BUSINESS_Q1 = 'gating-business-q1';
38
39    /**
40     * First blog ID guaranteed to carry `gating-business-q1` from creation, after the universal
41     * creation hook was deployed. Using blog ID since we can't get
42     * the blog creation date on WPCloud sites.
43     */
44    public const FEATURE_GATING_2026_CUTOFF_BLOG_ID = 256966305;
45
46    /*
47     * Private const for every mapped purchase, sorted by product_id.
48     */
49    private const SPACE_1GB                                   = 'wordpress_com_1gb_space_addon_yearly';
50    private const SPACE_10GB                                  = '1gb_space_upgrade'; // 9
51    private const SPACE_25GB                                  = '5gb_space_upgrade'; // 10
52    private const SPACE_50GB                                  = '10gb_space_upgrade'; // 11
53    private const NO_ADS                                      = 'no-adverts/no-adverts.php'; // 12
54    private const WPCOM_VIDEOPRESS                            = 'videopress'; // 15
55    private const SPACE_100GB                                 = '50gb_space_upgrade'; // 19
56    private const SPACE_200GB                                 = '100gb_space_upgrade'; // 20
57    private const SPACE_3GB                                   = '3gb_space_upgrade'; // 21
58    private const WPCOM_CUSTOM_DESIGN                         = 'custom-design'; // 45
59    private const WPCOM_VIDEOPRESS_PRO                        = 'videopress-pro'; // 47
60    private const WPCOM_UNLIMITED_THEMES                      = 'unlimited_themes'; // 49
61    private const GAPPS                                       = 'gapps'; // 69
62    private const GAPPS_UNLIMITED                             = 'gapps_unlimited'; // 70
63    private const WP_TITAN_MAIL_MONTHLY                       = 'wp_titan_mail_monthly'; // 400
64    private const WP_TITAN_MAIL_YEARLY                        = 'wp_titan_mail_yearly'; // 401
65    private const WP_TITAN_MAIL_PREMIUM_MONTHLY               = 'wp_titan_mail_premium_monthly'; // 402
66    private const WP_TITAN_MAIL_PREMIUM_YEARLY                = 'wp_titan_mail_premium_yearly'; // 403
67    private const WP_TITAN_MAIL_ULTRA_MONTHLY                 = 'wp_titan_mail_ultra_monthly'; // 404
68    private const WP_TITAN_MAIL_ULTRA_YEARLY                  = 'wp_titan_mail_ultra_yearly'; // 405
69    private const WP_GOOGLE_WORKSPACE_BUSINESS_STARTER_YEARLY = 'wp_google_workspace_business_starter_yearly'; // 690
70    private const WPCOM_SEARCH                                = 'wpcom_search'; // 800
71    private const WPCOM_SEARCH_MONTHLY                        = 'wpcom_search_monthly'; // 801
72    private const YOAST_PREMIUM                               = 'yoast_premium'; // 900
73    private const VALUE_BUNDLE                                = 'value_bundle'; // 1003
74    private const BUNDLE_PRO                                  = 'bundle_pro'; // 1004
75    private const BUNDLE_SUPER                                = 'bundle_super'; // 1005
76    private const BUNDLE_ENTERPRISE                           = 'wpcom-enterprise'; // 1007
77    private const BUSINESS_BUNDLE                             = 'business-bundle'; // 1008
78    private const PERSONAL_BUNDLE                             = 'personal-bundle'; // 1009
79    private const BLOGGER_BUNDLE                              = 'blogger-bundle'; // 1010
80    private const ECOMMERCE_BUNDLE                            = 'ecommerce-bundle'; // 1011
81    private const VALUE_BUNDLE_MONTHLY                        = 'value_bundle_monthly'; // 1013
82    private const PRO_PLAN_MONTHLY                            = 'pro-plan-monthly'; // 1034
83    private const BUSINESS_BUNDLE_MONTHLY                     = 'business-bundle-monthly'; // 1018
84    private const PERSONAL_BUNDLE_MONTHLY                     = 'personal-bundle-monthly'; // 1019
85    private const ECOMMERCE_BUNDLE_MONTHLY                    = 'ecommerce-bundle-monthly'; // 1021
86    private const VALUE_BUNDLE_2Y                             = 'value_bundle-2y'; // 1023
87    private const BUSINESS_BUNDLE_2Y                          = 'business-bundle-2y'; // 1028
88    private const PERSONAL_BUNDLE_2Y                          = 'personal-bundle-2y'; // 1029
89    private const BLOGGER_BUNDLE_2Y                           = 'blogger-bundle-2y'; // 1030
90    private const ECOMMERCE_BUNDLE_2Y                         = 'ecommerce-bundle-2y'; // 1031
91    private const VALUE_BUNDLE_3Y                             = 'value_bundle-3y'; // 1043
92    private const BUSINESS_BUNDLE_3Y                          = 'business-bundle-3y'; // 1048
93    private const PERSONAL_BUNDLE_3Y                          = 'personal-bundle-3y'; // 1049
94    private const ECOMMERCE_BUNDLE_3Y                         = 'ecommerce-bundle-3y'; // 1051
95    private const PRO_PLAN_2Y                                 = 'pro-plan-2y'; // 1035
96    private const PRO_PLAN                                    = 'pro-plan'; // 1032
97    private const STARTER_PLAN                                = 'starter-plan'; // 1033
98    private const WP_P2_PLUS_MONTHLY                          = 'wp_p2_plus_monthly'; // 1040
99    private const ECOMMERCE_TRIAL_BUNDLE_MONTHLY              = 'ecommerce-trial-bundle-monthly'; // 1052
100    private const WPCOM_WOOEXPRESS_MEDIUM_BUNDLE_MONTHLY      = 'wooexpress-medium-bundle-monthly'; // 1053
101    private const WPCOM_WOOEXPRESS_MEDIUM_BUNDLE_YEARLY       = 'wooexpress-medium-bundle-yearly'; // 1055
102    private const WPCOM_WOOEXPRESS_SMALL_BUNDLE_MONTHLY       = 'wooexpress-small-bundle-monthly'; // 1054
103    private const WPCOM_WOOEXPRESS_SMALL_BUNDLE_YEARLY        = 'wooexpress-small-bundle-yearly'; // 1056
104    private const WPCOM_MIGRATION_TRIAL_BUNDLE_MONTHLY        = 'wp_bundle_migration_trial_monthly'; // 1057
105    private const WPCOM_HOSTING_TRIAL_BUNDLE_MONTHLY          = 'wp_bundle_hosting_trial_monthly'; // 1058
106    private const WPCOM_STAGING_PRODUCT                       = 'wp_staging_site_lifetime'; // 1060
107    private const WPCOM_HUNDRED_YEAR_BUNDLE                   = 'wp_com_hundred_year_bundle_centennially'; // 1061
108    private const STUDENT_BUNDLE                              = 'wp_bundle_student_yearly'; // 1090
109    private const JETPACK_PREMIUM                             = 'jetpack_premium'; // 2000
110    private const JETPACK_BUSINESS                            = 'jetpack_business'; // 2001
111    private const JETPACK_FREE                                = 'jetpack_free'; // 2002
112    private const JETPACK_PREMIUM_MONTHLY                     = 'jetpack_premium_monthly'; // 2003
113    private const JETPACK_BUSINESS_MONTHLY                    = 'jetpack_business_monthly'; // 2004
114    private const JETPACK_PERSONAL                            = 'jetpack_personal'; // 2005
115    private const JETPACK_PERSONAL_MONTHLY                    = 'jetpack_personal_monthly'; // 2006
116    private const JETPACK_SECURITY_DAILY                      = 'jetpack_security_daily'; // 2010
117    private const JETPACK_SECURITY_DAILY_MONTHLY              = 'jetpack_security_daily_monthly'; // 2011
118    private const JETPACK_SECURITY_REALTIME                   = 'jetpack_security_realtime'; // 2012
119    private const JETPACK_SECURITY_REALTIME_MONTHLY           = 'jetpack_security_realtime_monthly'; // 2013
120    private const JETPACK_GROWTH_BI_YEARLY                    = 'jetpack_growth_bi_yearly'; // 2023
121    private const JETPACK_GROWTH_YEARLY                       = 'jetpack_growth_yearly'; // 2022
122    private const JETPACK_GROWTH_MONTHLY                      = 'jetpack_growth_monthly'; // 2021
123    private const JETPACK_COMPLETE_BI_YEARLY                  = 'jetpack_complete_bi_yearly'; // 2035
124    private const JETPACK_COMPLETE                            = 'jetpack_complete'; // 2014
125    private const JETPACK_COMPLETE_MONTHLY                    = 'jetpack_complete_monthly'; // 2015
126    private const JETPACK_PRO_BI_YEARLY                       = 'jetpack_pro_bi_yearly'; // 2026
127    private const JETPACK_PRO_YEARLY                          = 'jetpack_pro_yearly'; // 2025
128    private const JETPACK_PRO_MONTHLY                         = 'jetpack_pro_monthly'; // 2024
129    private const JETPACK_SECURITY_T0_YEARLY                  = 'jetpack_security_t0_yearly'; // 10237
130    private const JETPACK_SECURITY_T0_MONTHLY                 = 'jetpack_security_t0_monthly'; // 10238
131    private const JETPACK_SECURITY_T1_BI_YEARLY               = 'jetpack_security_t1_bi_yearly'; // 2034
132    private const JETPACK_SECURITY_T1_YEARLY                  = 'jetpack_security_t1_yearly'; // 2016
133    private const JETPACK_SECURITY_T1_MONTHLY                 = 'jetpack_security_t1_monthly'; // 2017
134    private const JETPACK_SECURITY_T2_YEARLY                  = 'jetpack_security_t2_yearly'; // 2019
135    private const JETPACK_SECURITY_T2_MONTHLY                 = 'jetpack_security_t2_monthly'; // 2020
136    private const JETPACK_STARTER_YEARLY                      = 'jetpack_starter_yearly'; // 2030
137    private const JETPACK_STARTER_MONTHLY                     = 'jetpack_starter_monthly'; // 2031
138    private const JETPACK_BACKUP_DAILY                        = 'jetpack_backup_daily'; // 2100
139    private const JETPACK_BACKUP_DAILY_MONTHLY                = 'jetpack_backup_daily_monthly'; // 2101
140    private const JETPACK_BACKUP_REALTIME                     = 'jetpack_backup_realtime'; // 2102
141    private const JETPACK_BACKUP_REALTIME_MONTHLY             = 'jetpack_backup_realtime_monthly'; // 2103
142    private const JETPACK_SEARCH_BI_YEARLY                    = 'jetpack_search_bi_yearly'; // 2031
143    private const JETPACK_SEARCH                              = 'jetpack_search'; // 2104
144    private const JETPACK_SEARCH_MONTHLY                      = 'jetpack_search_monthly'; // 2105
145    private const JETPACK_SCAN_BI_YEARLY                      = 'jetpack_scan_bi_yearly'; // 2038
146    private const JETPACK_SCAN                                = 'jetpack_scan'; // 2106
147    private const JETPACK_SCAN_MONTHLY                        = 'jetpack_scan_monthly'; // 2107
148    private const JETPACK_SCAN_REALTIME                       = 'jetpack_scan_realtime'; // 2108
149    private const JETPACK_SCAN_REALTIME_MONTHLY               = 'jetpack_scan_realtime_monthly'; // 2109
150    private const JETPACK_ANTI_SPAM_BI_YEARLY                 = 'jetpack_anti_spam_bi_yearly'; // 2039
151    private const JETPACK_ANTI_SPAM                           = 'jetpack_anti_spam'; // 2110
152    private const JETPACK_ANTI_SPAM_MONTHLY                   = 'jetpack_anti_spam_monthly'; // 2111
153    private const JETPACK_BACKUP_T1_BI_YEARLY                 = 'jetpack_backup_t1_bi_yearly'; // 2123
154    private const JETPACK_BACKUP_T1_YEARLY                    = 'jetpack_backup_t1_yearly'; // 2112
155    private const JETPACK_BACKUP_T1_MONTHLY                   = 'jetpack_backup_t1_monthly'; // 2113
156    private const JETPACK_BACKUP_T2_YEARLY                    = 'jetpack_backup_t2_yearly'; // 2114
157    private const JETPACK_BACKUP_T2_MONTHLY                   = 'jetpack_backup_t2_monthly'; // 2115
158    private const JETPACK_BACKUP_ADDON_STORAGE_10GB_MONTHLY   = 'jetpack_backup_addon_storage_10gb_monthly'; // 2040
159    private const JETPACK_BACKUP_ADDON_STORAGE_100GB_MONTHLY  = 'jetpack_backup_addon_storage_100gb_monthly'; // 2044
160    private const JETPACK_BACKUP_ADDON_STORAGE_1TB_MONTHLY    = 'jetpack_backup_addon_storage_1tb_monthly'; // 2048
161    private const JETPACK_BACKUP_ADDON_STORAGE_3TB_MONTHLY    = 'jetpack_backup_addon_storage_3tb_monthly'; // 2052
162    private const JETPACK_BACKUP_ADDON_STORAGE_5TB_MONTHLY    = 'jetpack_backup_addon_storage_5tb_monthly'; // 2056
163    private const JETPACK_VIDEOPRESS_BI_YEARLY                = 'jetpack_videopress_bi_yearly'; // 2119
164    private const JETPACK_VIDEOPRESS                          = 'jetpack_videopress'; // 2116
165    private const JETPACK_VIDEOPRESS_MONTHLY                  = 'jetpack_videopress_monthly'; // 2117
166    private const JETPACK_BACKUP_T0_YEARLY                    = 'jetpack_backup_t0_yearly'; // 2120
167    private const JETPACK_BACKUP_T0_MONTHLY                   = 'jetpack_backup_t0_monthly'; // 2121
168    private const JETPACK_SEARCH_FREE                         = 'jetpack_search_free'; // 2130
169    private const JETPACK_BACKUP_ONE_TIME                     = 'jetpack_backup_one_time'; // 2201
170    private const JETPACK_STATS_FREE                          = 'jetpack_stats_free_yearly'; // 2221
171    private const JETPACK_STATS_PWYW                          = 'jetpack_stats_pwyw_yearly'; // 2222
172    private const JETPACK_STATS_MONTHLY                       = 'jetpack_stats_monthly'; // 2220
173    private const JETPACK_STATS_YEARLY                        = 'jetpack_stats_yearly'; // 2219
174    private const JETPACK_STATS_BI_YEARLY                     = 'jetpack_stats_bi_yearly'; // 2223
175    private const JETPACK_MONITOR_MONTHLY                     = 'jetpack_monitor_monthly'; // 2241
176    private const JETPACK_MONITOR_YEARLY                      = 'jetpack_monitor_yearly'; // 2242
177    private const AKISMET_FREE                                = 'ak_free_yearly'; // 2300
178    private const AKISMET_PERSONAL_MONTHLY                    = 'ak_personal_monthly'; // 2309
179    private const AKISMET_PERSONAL_YEARLY                     = 'ak_personal_yearly'; // 2310
180    private const AKISMET_PLUS_BI_YEARLY                      = 'ak_plus_bi_yearly_1'; // 2327
181    private const AKISMET_PLUS_YEARLY                         = 'ak_plus_yearly_1'; // 2311
182    private const AKISMET_PLUS_MONTHLY                        = 'ak_plus_monthly_1'; // 2312
183    private const AKISMET_PLUS_20K_BI_YEARLY                  = 'ak_plus_bi_yearly_2'; // 2328
184    private const AKISMET_PLUS_20K_YEARLY                     = 'ak_plus_yearly_2'; // 2313
185    private const AKISMET_PLUS_20K_MONTHLY                    = 'ak_plus_monthly_2'; // 2314
186    private const AKISMET_PLUS_30K_BI_YEARLY                  = 'ak_plus_bi_yearly_3'; // 2329
187    private const AKISMET_PLUS_30K_YEARLY                     = 'ak_plus_yearly_3'; // 2315
188    private const AKISMET_PLUS_30K_MONTHLY                    = 'ak_plus_monthly_3'; // 2316
189    private const AKISMET_PLUS_40K_BI_YEARLY                  = 'ak_plus_bi_yearly_4'; // 2330
190    private const AKISMET_PLUS_40K_YEARLY                     = 'ak_plus_yearly_4'; // 2317
191    private const AKISMET_PLUS_40K_MONTHLY                    = 'ak_plus_monthly_4'; // 2318
192    private const AKISMET_ENTERPRISE_BI_YEARLY                = 'ak_ent_bi_yearly_1'; // 2331
193    private const AKISMET_ENTERPRISE_YEARLY                   = 'ak_ent_yearly_1'; // 2319
194    private const AKISMET_ENTERPRISE_MONTHLY                  = 'ak_ent_monthly_1'; // 2320
195    private const AKISMET_ENTERPRISE_350K_YEARLY              = 'ak_ep350k_yearly_1'; // 2321
196    private const AKISMET_ENTERPRISE_350K_MONTHLY             = 'ak_ep350k_monthly_1'; // 2322
197    private const AKISMET_ENTERPRISE_2M_YEARLY                = 'ak_ep2m_yearly_1'; // 2323
198    private const AKISMET_ENTERPRISE_2M_MONTHLY               = 'ak_ep2m_monthly_1'; // 2324
199    private const AKISMET_ENTERPRISE_GT2M_YEARLY              = 'ak_epgt2m_yearly_1'; // 2325
200    private const AKISMET_ENTERPRISE_GT2M_MONTHLY             = 'ak_epgt2m_monthly_1'; // 2326
201    private const AKISMET_PRO_500_MONTHLY                     = 'ak_pro5h_monthly'; // 2332
202    private const AKISMET_PRO_500_YEARLY                      = 'ak_pro5h_yearly'; // 2333
203    private const AKISMET_PRO_500_BI_YEARLY                   = 'ak_pro5h_bi_yearly'; // 2334
204    private const AKISMET_BUSINESS_5K_MONTHLY                 = 'ak_bus5k_monthly'; // 2335
205    private const AKISMET_BUSINESS_5K_YEARLY                  = 'ak_bus5k_yearly'; // 2336
206    private const AKISMET_BUSINESS_5K_BI_YEARLY               = 'ak_bus5k_bi_yearly'; // 2337
207    private const AKISMET_ENTERPRISE_15K_MONTHLY              = 'ak_ep15k_monthly'; // 2338
208    private const AKISMET_ENTERPRISE_15K_YEARLY               = 'ak_ep15k_yearly'; // 2339
209    private const AKISMET_ENTERPRISE_15K_BI_YEARLY            = 'ak_ep15k_bi_yearly'; // 2340
210    private const AKISMET_ENTERPRISE_25K_MONTHLY              = 'ak_ep25k_monthly'; // 2341
211    private const AKISMET_ENTERPRISE_25K_YEARLY               = 'ak_ep25k_yearly'; // 2342
212    private const AKISMET_ENTERPRISE_25K_BI_YEARLY            = 'ak_ep25k_bi_yearly'; // 2343
213    private const JETPACK_BOOST_BI_YEARLY                     = 'jetpack_boost_bi_yearly'; // 2036
214    private const JETPACK_BOOST                               = 'jetpack_boost_yearly'; // 2401
215    private const JETPACK_BOOST_MONTHLY                       = 'jetpack_boost_monthly'; // 2400
216    private const JETPACK_AI_MONTHLY                          = 'jetpack_ai_monthly'; // 2450
217    private const JETPACK_AI_YEARLY                           = 'jetpack_ai_yearly'; // 2451
218    private const JETPACK_AI_BI_YEARLY                        = 'jetpack_ai_bi_yearly'; // 2452
219    private const JETPACK_SOCIAL_BASIC_MONTHLY_LEGACY         = 'jetpack_social_monthly'; // 2500
220    private const JETPACK_SOCIAL_BASIC_BI_YEARLY              = 'jetpack_social_basic_bi_yearly'; // 2037
221    private const JETPACK_SOCIAL_BASIC                        = 'jetpack_social_basic_yearly'; // 2503
222    private const JETPACK_SOCIAL_BASIC_MONTHLY                = 'jetpack_social_basic_monthly'; // 2504
223    private const JETPACK_SOCIAL_ADVANCED_BI_YEARLY           = 'jetpack_social_advanced_bi_yearly'; // 2604
224    private const JETPACK_SOCIAL_ADVANCED                     = 'jetpack_social_advanced_yearly'; // 2602
225    private const JETPACK_SOCIAL_ADVANCED_MONTHLY             = 'jetpack_social_advanced_monthly'; // 2603
226    private const JETPACK_GOLDEN_TOKEN                        = 'jetpack_golden_token_lifetime'; // 2900
227    private const JETPACK_CREATOR_MONTHLY                     = 'jetpack_creator_monthly'; // 2610
228    private const JETPACK_CREATOR_YEARLY                      = 'jetpack_creator_yearly'; // 2611
229    private const JETPACK_CREATOR_BI_YEARLY                   = 'jetpack_creator_bi_yearly'; // 2612
230    private const JETPACK_SOCIAL_V1_MONTHLY                   = 'jetpack_social_v1_monthly'; // 2606
231    private const JETPACK_SOCIAL_V1_YEARLY                    = 'jetpack_social_v1_yearly'; // 2605
232    private const JETPACK_SOCIAL_V1_BI_YEARLY                 = 'jetpack_social_v1_bi_yearly'; // 2607
233    private const A4A_WPCOM_BUSINESS_BUNDLE_YEARLY            = 'a4a_wp_bundle_business_yearly'; // 3300
234    private const A4A_WPCOM_BUSINESS_BUNDLE_MONTHLY           = 'a4a_wp_bundle_business_monthly'; // 3301
235    private const A4A_JETPACK_COMPLETE_YEARLY                 = 'a4a_jetpack_complete_yearly'; // 3302
236    private const A4A_JETPACK_COMPLETE_MONTHLY                = 'a4a_jetpack_complete_monthly'; // 3303
237    private const A4A_JETPACK_SECURITY_TIER_1_YEARLY          = 'a4a_jetpack_security_t1_yearly'; // 3304
238    private const A4A_JETPACK_SECURITY_TIER_1_MONTHLY         = 'a4a_jetpack_security_t1_monthly'; // 3305
239    private const A4A_JETPACK_SECURITY_TIER_2_YEARLY          = 'a4a_jetpack_security_t2_yearly'; // 3306
240    private const A4A_JETPACK_SECURITY_TIER_2_MONTHLY         = 'a4a_jetpack_security_t2_monthly'; // 3307
241    private const A4A_JETPACK_SEARCH_YEARLY                   = 'a4a_jetpack_search_yearly'; // 3318
242    private const A4A_JETPACK_SEARCH_MONTHLY                  = 'a4a_jetpack_search_monthly'; // 3319
243    private const A4A_JETPACK_SCAN_YEARLY                     = 'a4a_jetpack_scan_yearly'; // 3320
244    private const A4A_JETPACK_SCAN_MONTHLY                    = 'a4a_jetpack_scan_monthly'; // 3321
245    private const A4A_JETPACK_ANTI_SPAM_YEARLY                = 'a4a_jetpack_anti_spam_yearly'; // 3322
246    private const A4A_JETPACK_ANTI_SPAM_MONTHLY               = 'a4a_jetpack_anti_spam_monthly'; // 3323
247    private const A4A_JETPACK_BACKUP_TIER_1_YEARLY            = 'a4a_jetpack_backup_t1_yearly'; // 3324
248    private const A4A_JETPACK_BACKUP_TIER_1_MONTHLY           = 'a4a_jetpack_backup_t1_monthly'; // 3325
249    private const A4A_JETPACK_BACKUP_TIER_2_YEARLY            = 'a4a_jetpack_backup_t2_yearly'; // 3326
250    private const A4A_JETPACK_BACKUP_TIER_2_MONTHLY           = 'a4a_jetpack_backup_t2_monthly'; // 3327
251    private const A4A_JETPACK_VIDEOPRESS_YEARLY               = 'a4a_jetpack_videopress_yearly'; // 3328
252    private const A4A_JETPACK_VIDEOPRESS_MONTHLY              = 'a4a_jetpack_videopress_monthly'; // 3329
253    private const A4A_JETPACK_STATS_YEARLY                    = 'a4a_jetpack_stats_yearly'; // 3330
254    private const A4A_JETPACK_STATS_MONTHLY                   = 'a4a_jetpack_stats_monthly'; // 3331
255    private const A4A_JETPACK_MONITOR_YEARLY                  = 'a4a_jetpack_monitor_yearly'; // 3332
256    private const A4A_JETPACK_MONITOR_MONTHLY                 = 'a4a_jetpack_monitor_monthly'; // 3333
257    private const A4A_JETPACK_BOOST_YEARLY                    = 'a4a_jetpack_boost_yearly'; // 3334
258    private const A4A_JETPACK_BOOST_MONTHLY                   = 'a4a_jetpack_boost_monthly'; // 3335
259    private const A4A_JETPACK_AI_YEARLY                       = 'a4a_jetpack_ai_yearly'; // 3336
260    private const A4A_JETPACK_AI_MONTHLY                      = 'a4a_jetpack_ai_monthly'; // 3337
261    private const A4A_JETPACK_SOCIAL_V1_YEARLY                = 'a4a_jetpack_social_v1_yearly'; // 3338
262    private const A4A_JETPACK_SOCIAL_V1_MONTHLY               = 'a4a_jetpack_social_v1_monthly'; // 3339
263    private const A4A_JETPACK_CREATOR_YEARLY                  = 'a4a_jetpack_creator_yearly'; // 3340
264    private const A4A_JETPACK_CREATOR_MONTHLY                 = 'a4a_jetpack_creator_monthly'; // 3341
265    private const WOO_HOSTED_BASIC_PLAN_MONTHLY               = 'woo_hosted_basic_plan_monthly'; // 4001
266    private const WOO_HOSTED_BASIC_PLAN_YEARLY                = 'woo_hosted_basic_plan_yearly'; // 4002
267    private const WOO_HOSTED_PRO_PLAN_MONTHLY                 = 'woo_hosted_pro_plan_monthly'; // 4003
268    private const WOO_HOSTED_PRO_PLAN_YEARLY                  = 'woo_hosted_pro_plan_yearly'; // 4004
269
270    // WPCOM "Level 2": Groups of level 1s.
271    private const WPCOM_BLOGGER_PLANS           = array( self::BLOGGER_BUNDLE, self::BLOGGER_BUNDLE_2Y );
272    private const WPCOM_PERSONAL_PLANS          = array( self::PERSONAL_BUNDLE, self::PERSONAL_BUNDLE_MONTHLY, self::PERSONAL_BUNDLE_2Y, self::PERSONAL_BUNDLE_3Y );
273    private const WPCOM_STARTER_PLANS           = array( self::STARTER_PLAN );
274    private const WPCOM_PREMIUM_PLANS           = array( self::BUNDLE_PRO, self::VALUE_BUNDLE, self::VALUE_BUNDLE_MONTHLY, self::VALUE_BUNDLE_2Y, self::VALUE_BUNDLE_3Y );
275    private const WPCOM_PRO_PLANS               = array( self::PRO_PLAN, self::PRO_PLAN_MONTHLY, self::PRO_PLAN_2Y );
276    private const WPCOM_MIGRATION_TRIAL_PLANS   = array( self::WPCOM_MIGRATION_TRIAL_BUNDLE_MONTHLY );
277    private const WPCOM_HOSTING_TRIAL_PLANS     = array( self::WPCOM_HOSTING_TRIAL_BUNDLE_MONTHLY );
278    private const WPCOM_STUDENT_PLANS           = array( self::STUDENT_BUNDLE );
279    private const WPCOM_BUSINESS_PLANS          = array( self::BUSINESS_BUNDLE, self::BUSINESS_BUNDLE_MONTHLY, self::BUSINESS_BUNDLE_2Y, self::BUSINESS_BUNDLE_3Y, self::WPCOM_MIGRATION_TRIAL_PLANS, self::WPCOM_HUNDRED_YEAR_BUNDLE, self::WPCOM_HOSTING_TRIAL_BUNDLE_MONTHLY, self::A4A_WPCOM_BUSINESS_BUNDLE_YEARLY, self::A4A_WPCOM_BUSINESS_BUNDLE_MONTHLY, self::WPCOM_STUDENT_PLANS );
280    private const WPCOM_ECOMMERCE_PLANS         = array( self::ECOMMERCE_BUNDLE, self::ECOMMERCE_BUNDLE_MONTHLY, self::ECOMMERCE_BUNDLE_2Y, self::ECOMMERCE_BUNDLE_3Y );
281    private const WPCOM_ECOMMERCE_TRIAL_PLANS   = array( self::ECOMMERCE_TRIAL_BUNDLE_MONTHLY );
282    private const WPCOM_WOOEXPRESS_MEDIUM_PLANS = array( self::WPCOM_WOOEXPRESS_MEDIUM_BUNDLE_MONTHLY, self::WPCOM_WOOEXPRESS_MEDIUM_BUNDLE_YEARLY );
283    private const WPCOM_WOOEXPRESS_SMALL_PLANS  = array( self::WPCOM_WOOEXPRESS_SMALL_BUNDLE_MONTHLY, self::WPCOM_WOOEXPRESS_SMALL_BUNDLE_YEARLY );
284    private const WOO_HOSTED_PLANS              = array( self::WOO_HOSTED_BASIC_PLAN_MONTHLY, self::WOO_HOSTED_BASIC_PLAN_YEARLY, self::WOO_HOSTED_PRO_PLAN_MONTHLY, self::WOO_HOSTED_PRO_PLAN_YEARLY );
285    private const GOOGLE_WORKSPACE_PRODUCTS     = array( self::WP_GOOGLE_WORKSPACE_BUSINESS_STARTER_YEARLY );
286    private const GSUITE_PRODUCTS               = array( self::GAPPS, self::GAPPS_UNLIMITED );
287    private const WPCOM_TITAN_MAIL_PRODUCTS     = array( self::WP_TITAN_MAIL_MONTHLY, self::WP_TITAN_MAIL_YEARLY, self::WP_TITAN_MAIL_PREMIUM_MONTHLY, self::WP_TITAN_MAIL_PREMIUM_YEARLY, self::WP_TITAN_MAIL_ULTRA_MONTHLY, self::WP_TITAN_MAIL_ULTRA_YEARLY );
288
289    private const WPCOM_PERSONAL_AND_PREMIUM_PLANS = array( self::WPCOM_PERSONAL_PLANS, self::WPCOM_PREMIUM_PLANS );
290    // Unlock Business-gated features for sites with the flex-cache-site sticker via the free plan.
291    private const WPCOM_FLEX_CACHE_SITE_FREE_PLANS = array(
292        'required_sticker' => 'flex-cache-site',
293        self::JETPACK_ALL_SITES,
294    );
295
296    // WPCOM "Level 3" A: Groups of level 2s.
297    private const WPCOM_BLOGGER_AND_HIGHER_PLANS  = array( self::WPCOM_BLOGGER_PLANS, self::WPCOM_PERSONAL_PLANS, self::WPCOM_STARTER_PLANS, self::WPCOM_PREMIUM_PLANS, self::WPCOM_PRO_PLANS, self::WPCOM_BUSINESS_PLANS, self::WPCOM_ECOMMERCE_PLANS, self::WPCOM_ECOMMERCE_TRIAL_PLANS, self::WPCOM_WOOEXPRESS_PLANS );
298    private const WPCOM_PERSONAL_AND_HIGHER_PLANS = array( self::WPCOM_PERSONAL_PLANS, self::WPCOM_STARTER_PLANS, self::WPCOM_PREMIUM_PLANS, self::WPCOM_PRO_PLANS, self::WPCOM_BUSINESS_PLANS, self::WPCOM_ECOMMERCE_PLANS, self::WPCOM_ECOMMERCE_TRIAL_PLANS, self::WPCOM_WOOEXPRESS_PLANS );
299    private const WPCOM_STARTER_AND_HIGHER_PLANS  = array( self::WPCOM_STARTER_PLANS, self::WPCOM_PREMIUM_PLANS, self::WPCOM_PRO_PLANS, self::WPCOM_BUSINESS_PLANS, self::WPCOM_ECOMMERCE_PLANS, self::WPCOM_ECOMMERCE_TRIAL_PLANS, self::WPCOM_WOOEXPRESS_PLANS );
300    private const WPCOM_PREMIUM_AND_HIGHER_PLANS  = array( self::WPCOM_PREMIUM_PLANS, self::WPCOM_PRO_PLANS, self::WPCOM_BUSINESS_PLANS, self::WPCOM_ECOMMERCE_PLANS, self::WPCOM_ECOMMERCE_TRIAL_PLANS, self::WPCOM_WOOEXPRESS_PLANS );
301    private const WPCOM_BUSINESS_AND_HIGHER_PLANS = array( self::WPCOM_BUSINESS_PLANS, self::WPCOM_ECOMMERCE_PLANS, self::WPCOM_ECOMMERCE_TRIAL_PLANS, self::WPCOM_WOOEXPRESS_PLANS );
302    private const WPCOM_WOOEXPRESS_PLANS          = array( self::WPCOM_WOOEXPRESS_MEDIUM_PLANS, self::WPCOM_WOOEXPRESS_SMALL_PLANS );
303
304    // WPCOM "Level 3" C: Misc product groupings unrelated to free plan trials.
305    private const WPCOM_EMAIL_PRODUCTS = array( self::GOOGLE_WORKSPACE_PRODUCTS, self::GSUITE_PRODUCTS, self::WPCOM_TITAN_MAIL_PRODUCTS );
306
307    // Jetpack "Level 2": Groups of level 1s.
308    private const JETPACK_BUSINESS_PLANS = array( self::JETPACK_BUSINESS, self::JETPACK_BUSINESS_MONTHLY );
309    private const JETPACK_PREMIUM_PLANS  = array( self::JETPACK_PREMIUM, self::JETPACK_PREMIUM_MONTHLY );
310    private const JETPACK_PERSONAL_PLANS = array( self::JETPACK_PERSONAL, self::JETPACK_PERSONAL_MONTHLY );
311    private const JETPACK_GROWTH_PLANS   = array( self::JETPACK_GROWTH_BI_YEARLY, self::JETPACK_GROWTH_YEARLY, self::JETPACK_GROWTH_MONTHLY );
312    private const JETPACK_COMPLETE_PLANS = array( self::JETPACK_COMPLETE_BI_YEARLY, self::JETPACK_COMPLETE, self::JETPACK_COMPLETE_MONTHLY, self::A4A_JETPACK_COMPLETE_YEARLY, self::A4A_JETPACK_COMPLETE_MONTHLY );
313    private const JETPACK_STARTER_PLANS  = array( self::JETPACK_STARTER_YEARLY, self::JETPACK_STARTER_MONTHLY );
314    private const JETPACK_PRO_PLANS      = array( self::JETPACK_PRO_BI_YEARLY, self::JETPACK_PRO_YEARLY, self::JETPACK_PRO_MONTHLY );
315
316    private const JETPACK_SECURITY_DAILY_PLANS    = array( self::JETPACK_SECURITY_DAILY, self::JETPACK_SECURITY_DAILY_MONTHLY );
317    private const JETPACK_SECURITY_REALTIME_PLANS = array( self::JETPACK_SECURITY_REALTIME, self::JETPACK_SECURITY_REALTIME_MONTHLY );
318    private const JETPACK_SECURITY_T0_PLANS       = array( self::JETPACK_SECURITY_T0_MONTHLY, self::JETPACK_SECURITY_T0_YEARLY );
319    private const JETPACK_SECURITY_T1_PLANS       = array( self::JETPACK_SECURITY_T1_MONTHLY, self::JETPACK_SECURITY_T1_YEARLY, self::JETPACK_SECURITY_T1_BI_YEARLY, self::A4A_JETPACK_SECURITY_TIER_1_MONTHLY, self::A4A_JETPACK_SECURITY_TIER_1_YEARLY );
320    private const JETPACK_SECURITY_T2_PLANS       = array( self::JETPACK_SECURITY_T2_MONTHLY, self::JETPACK_SECURITY_T2_YEARLY, self::A4A_JETPACK_SECURITY_TIER_2_MONTHLY, self::A4A_JETPACK_SECURITY_TIER_2_YEARLY );
321
322    private const JETPACK_SCAN_PLANS = array( self::JETPACK_SCAN_BI_YEARLY, self::JETPACK_SCAN, self::JETPACK_SCAN_MONTHLY, self::JETPACK_SCAN_REALTIME, self::JETPACK_SCAN_REALTIME_MONTHLY, self::A4A_JETPACK_SCAN_YEARLY, self::A4A_JETPACK_SCAN_MONTHLY );
323
324    private const JETPACK_SOCIAL_PLANS          = array( self::JETPACK_SOCIAL_BASIC_BI_YEARLY, self::JETPACK_SOCIAL_BASIC, self::JETPACK_SOCIAL_BASIC_MONTHLY, self::JETPACK_SOCIAL_BASIC_MONTHLY_LEGACY );
325    private const JETPACK_SOCIAL_ADVANCED_PLANS = array( self::JETPACK_SOCIAL_ADVANCED_BI_YEARLY, self::JETPACK_SOCIAL_ADVANCED, self::JETPACK_SOCIAL_ADVANCED_MONTHLY );
326    private const JETPACK_SOCIAL_V1_PLANS       = array( self::JETPACK_SOCIAL_V1_YEARLY, self::JETPACK_SOCIAL_V1_MONTHLY, self::JETPACK_SOCIAL_V1_BI_YEARLY, self::A4A_JETPACK_SOCIAL_V1_YEARLY, self::A4A_JETPACK_SOCIAL_V1_MONTHLY );
327
328    private const JETPACK_STATS_PLANS = array( self::JETPACK_STATS_BI_YEARLY, self::JETPACK_STATS_YEARLY, self::JETPACK_STATS_MONTHLY, self::JETPACK_STATS_PWYW, self::JETPACK_STATS_FREE, self::A4A_JETPACK_STATS_YEARLY, self::A4A_JETPACK_STATS_MONTHLY );
329
330    private const JETPACK_VIDEOPRESS_PLANS = array( self::JETPACK_VIDEOPRESS_BI_YEARLY, self::JETPACK_VIDEOPRESS, self::JETPACK_VIDEOPRESS_MONTHLY, self::A4A_JETPACK_VIDEOPRESS_YEARLY, self::A4A_JETPACK_VIDEOPRESS_MONTHLY );
331
332    private const JETPACK_SEARCH_PLANS = array( self::JETPACK_SEARCH_FREE, self::JETPACK_SEARCH_BI_YEARLY, self::JETPACK_SEARCH, self::JETPACK_SEARCH_MONTHLY, self::A4A_JETPACK_SEARCH_YEARLY, self::A4A_JETPACK_SEARCH_MONTHLY );
333
334    private const JETPACK_AI_PLANS = array( self::JETPACK_AI_BI_YEARLY, self::JETPACK_AI_YEARLY, self::JETPACK_AI_MONTHLY, self::A4A_JETPACK_AI_YEARLY, self::A4A_JETPACK_AI_MONTHLY );
335
336    private const JETPACK_BOOST_PLANS = array( self::JETPACK_BOOST_BI_YEARLY, self::JETPACK_BOOST, self::JETPACK_BOOST_MONTHLY, self::A4A_JETPACK_BOOST_YEARLY, self::A4A_JETPACK_BOOST_MONTHLY );
337
338    private const JETPACK_BACKUP_DAILY_PLANS    = array( self::JETPACK_BACKUP_DAILY, self::JETPACK_BACKUP_DAILY_MONTHLY );
339    private const JETPACK_BACKUP_REALTIME_PLANS = array( self::JETPACK_BACKUP_REALTIME, self::JETPACK_BACKUP_REALTIME_MONTHLY );
340    private const JETPACK_BACKUP_T0_PLANS       = array( self::JETPACK_BACKUP_T0_MONTHLY, self::JETPACK_BACKUP_T0_YEARLY );
341    private const JETPACK_BACKUP_T1_PLANS       = array( self::JETPACK_BACKUP_T1_MONTHLY, self::JETPACK_BACKUP_T1_YEARLY, self::JETPACK_BACKUP_T1_BI_YEARLY, self::A4A_JETPACK_BACKUP_TIER_1_YEARLY, self::A4A_JETPACK_BACKUP_TIER_1_MONTHLY );
342    private const JETPACK_BACKUP_T2_PLANS       = array( self::JETPACK_BACKUP_T2_MONTHLY, self::JETPACK_BACKUP_T2_YEARLY, self::A4A_JETPACK_BACKUP_TIER_2_YEARLY, self::A4A_JETPACK_BACKUP_TIER_2_MONTHLY );
343
344    private const JETPACK_CREATOR_PLANS = array( self::JETPACK_CREATOR_MONTHLY, self::JETPACK_CREATOR_YEARLY, self::JETPACK_CREATOR_BI_YEARLY, self::A4A_JETPACK_CREATOR_YEARLY, self::A4A_JETPACK_CREATOR_MONTHLY );
345
346    // Jetpack "Level 3": Groups of level 2.
347    private const JETPACK_PERSONAL_AND_HIGHER = array(
348        self::JETPACK_PERSONAL_PLANS,
349        self::JETPACK_PREMIUM_PLANS,
350        self::JETPACK_BUSINESS_PLANS,
351        self::JETPACK_COMPLETE_PLANS,
352        self::JETPACK_PRO_PLANS,
353        self::JETPACK_SECURITY_DAILY_PLANS,
354        self::JETPACK_SECURITY_REALTIME_PLANS,
355        self::JETPACK_SECURITY_T0_PLANS,
356        self::JETPACK_SECURITY_T1_PLANS,
357        self::JETPACK_SECURITY_T2_PLANS,
358        self::JETPACK_STARTER_PLANS,
359    );
360    private const JETPACK_PREMIUM_AND_HIGHER  = array(
361        self::JETPACK_PREMIUM_PLANS,
362        self::JETPACK_BUSINESS_PLANS,
363        self::JETPACK_COMPLETE_PLANS,
364        self::JETPACK_PRO_PLANS,
365        self::JETPACK_SECURITY_DAILY_PLANS,
366        self::JETPACK_SECURITY_REALTIME_PLANS,
367        self::JETPACK_SECURITY_T0_PLANS,
368        self::JETPACK_SECURITY_T1_PLANS,
369        self::JETPACK_SECURITY_T2_PLANS,
370    );
371
372    private const AKISMET_PLANS = array(
373        self::AKISMET_FREE,
374        self::AKISMET_PERSONAL_MONTHLY,
375        self::AKISMET_PERSONAL_YEARLY,
376        self::AKISMET_PLUS_MONTHLY,
377        self::AKISMET_PLUS_YEARLY,
378        self::AKISMET_PLUS_BI_YEARLY,
379        self::AKISMET_PLUS_20K_MONTHLY,
380        self::AKISMET_PLUS_20K_YEARLY,
381        self::AKISMET_PLUS_20K_BI_YEARLY,
382        self::AKISMET_PLUS_30K_MONTHLY,
383        self::AKISMET_PLUS_30K_YEARLY,
384        self::AKISMET_PLUS_30K_BI_YEARLY,
385        self::AKISMET_PLUS_40K_MONTHLY,
386        self::AKISMET_PLUS_40K_YEARLY,
387        self::AKISMET_PLUS_40K_BI_YEARLY,
388        self::AKISMET_ENTERPRISE_MONTHLY,
389        self::AKISMET_ENTERPRISE_YEARLY,
390        self::AKISMET_ENTERPRISE_BI_YEARLY,
391        self::AKISMET_ENTERPRISE_350K_MONTHLY,
392        self::AKISMET_ENTERPRISE_350K_YEARLY,
393        self::AKISMET_ENTERPRISE_2M_MONTHLY,
394        self::AKISMET_ENTERPRISE_2M_YEARLY,
395        self::AKISMET_PRO_500_MONTHLY,
396        self::AKISMET_PRO_500_YEARLY,
397        self::AKISMET_PRO_500_BI_YEARLY,
398        self::AKISMET_BUSINESS_5K_MONTHLY,
399        self::AKISMET_BUSINESS_5K_YEARLY,
400        self::AKISMET_BUSINESS_5K_BI_YEARLY,
401        self::AKISMET_ENTERPRISE_15K_MONTHLY,
402        self::AKISMET_ENTERPRISE_15K_YEARLY,
403        self::AKISMET_ENTERPRISE_15K_BI_YEARLY,
404        self::AKISMET_ENTERPRISE_25K_MONTHLY,
405        self::AKISMET_ENTERPRISE_25K_YEARLY,
406        self::AKISMET_ENTERPRISE_25K_BI_YEARLY,
407    );
408
409    // Features automatically granted to all sites regardless of their purchases are mapped to these constants.
410    private const WPCOM_ALL_SITES   = 'wpcom-all-sites';
411    private const JETPACK_ALL_SITES = 'jetpack-all-sites';
412
413    /*
414     * Public const for every mapped feature, sorted alphabetically.
415     */
416    public const AI_ASSISTANT                      = 'ai-assistant';
417    public const AI_CREDITS_WPCOM_BUSINESS         = 'ai-credits-wpcom-business';
418    public const AI_CREDITS_WPCOM_COMMERCE         = 'ai-credits-wpcom-commerce';
419    public const AI_CREDITS_WPCOM_PERSONAL         = 'ai-credits-wpcom-personal';
420    public const AI_CREDITS_WPCOM_PREMIUM          = 'ai-credits-wpcom-premium';
421    public const AI_SEO_ENHANCER                   = 'ai-seo-enhancer';
422    public const AD_CREDIT_VOUCHERS                = 'ad-credit';
423    public const ADVANCED_SEO                      = 'advanced-seo';
424    public const AKISMET                           = 'akismet';
425    public const ANTISPAM                          = 'antispam';
426    public const ARCHIVE_CONTENT                   = 'archive-content';
427    public const ATOMIC                            = 'atomic';
428    public const BACKUPS                           = 'backups';
429    public const BACKUPS_DAILY                     = 'backups-daily';
430    public const BACKUPS_RESTORE                   = 'restore';
431    public const BIG_SKY                           = 'big-sky';
432    public const BACKUPS_SELF_SERVE                = 'backups-self-serve';
433    public const BACKUP_ONE_TIME                   = 'backup-one-time';
434    public const BLAZE_CREDITS_VOUCHER             = 'blaze-credits-voucher';
435    public const BLOG_DOMAIN_ONLY                  = 'blog-domain-only';
436    public const CALENDLY                          = 'calendly';
437    public const CDN                               = 'cdn';
438    public const CLASSIC_SEARCH                    = 'search';
439    public const CLOUD_CRITICAL_CSS                = 'cloud-critical-css';
440    public const CORNERSTONE_TEN_PAGES             = 'cornerstone-10-pages';
441    public const CLOUDFLARE_ANALYTICS              = 'cloudflare-analytics';
442    public const CLOUDFLARE_CDN                    = 'cloudflare-cdn';
443    public const CONCIERGE                         = 'concierge';
444    public const CONCIERGE_BUSINESS                = 'concierge-business';
445    public const COPY_SITE                         = 'copy-site';
446    public const CORE_AUDIO                        = 'core/audio';
447    public const CORE_COVER                        = 'core/cover';
448    public const CORE_VIDEO                        = 'core/video';
449    public const CREDIT_VOUCHERS                   = 'credit-vouchers';
450    public const CUSTOM_DESIGN                     = 'custom-design';
451    public const CUSTOM_DOMAIN                     = 'custom-domain';
452    public const DOMAIN_MAPPING                    = 'domain-mapping';
453    public const DONATIONS                         = 'donations';
454    public const ECOMMERCE_MANAGED_PLUGINS         = 'ecommerce-managed-plugins';
455    public const ECOMMERCE_MANAGED_PLUGINS_SMALL   = 'ecommerce-managed-plugins-small';
456    public const ECOMMERCE_MANAGED_PLUGINS_MEDIUM  = 'ecommerce-managed-plugins-medium';
457    public const ECOMMERCE_MANAGED_PLUGINS_TRIAL   = 'ecommerce-managed-plugins-trial';
458    public const EDIT_PLUGINS                      = 'edit-plugins';
459    public const EDIT_THEMES                       = 'edit-themes';
460    public const EMAIL_PROFESSIONAL                = 'email-professional';
461    public const EMAIL_SUBSCRIPTION                = 'email-subscription';
462    public const EMAIL_FORWARDS_EXTENDED_LIMIT     = 'email-forwards-extended-limit';
463    public const FIELD_FILE                        = 'field-file';
464    public const FORM_CONDITIONAL_LOGIC            = 'form-conditional-logic';
465    public const FORM_INTEGRATIONS                 = 'form-integrations';
466    public const FORM_WEBHOOKS                     = 'form-webhooks';
467    public const FREE_BLOG                         = 'free-blog';
468    public const FULL_ACTIVITY_LOG                 = 'full-activity-log';
469    public const GITHUB_DEPLOYMENTS                = 'github-deployments';
470    public const GLOBAL_STYLES                     = 'global-styles';
471    public const GOOGLE_ANALYTICS                  = 'google-analytics';
472    public const GOOGLE_MY_BUSINESS                = 'google-my-business';
473    public const IMAGE_CDN_LIAR                    = 'image-cdn-liar';
474    public const IMAGE_CDN_QUALITY                 = 'image-cdn-quality';
475    public const IMAGE_SIZE_ANALYSIS               = 'image-size-analysis';
476    public const INSTALL_PLUGINS                   = 'install-plugins';
477    public const INSTALL_PURCHASED_PLUGINS         = 'install-purchased-plugins';
478    public const INSTALL_THEMES                    = 'install-themes';
479    public const INSTALL_WOO_ONBOARDING_PLUGINS    = 'install-woo-onboarding-plugins';
480    public const INSTANT_SEARCH                    = 'instant-search';
481    public const JETPACK_DASHBOARD                 = 'jetpack-dashboard';
482    public const LEGACY_CONTACT                    = 'legacy-contact';
483    public const LIST_INSTALLED_PLUGINS            = 'list-installed-plugins';
484    public const LIVE_SUPPORT                      = 'live_support';
485    public const LOCKED_MODE                       = 'locked-mode';
486    public const LOGS                              = 'logs';
487    public const MAILPOET_BUSINESS                 = 'mailpoet-business';
488    public const MANAGE_PLUGINS                    = 'manage-plugins';
489    public const MONITORING                        = 'monitoring';
490    public const MONITOR_1_MINUTE_CHECK_INTERVAL   = 'monitor-1-minute-check-interval';
491    public const MONITOR_MULTIPLE_EMAIL_RECIPIENTS = 'monitor-multiple-email-recipients';
492    public const MONITOR_SMS_NOTIFICATIONS         = 'monitor-sms-notifications';
493    public const MULTISTEP_FORM                    = 'multistep-form';
494    public const NO_ADVERTS_NO_ADVERTS_PHP         = 'no-adverts/no-adverts.php';
495    public const NO_WPCOM_BRANDING                 = 'no-wpcom-branding';
496    public const OPENTABLE                         = 'opentable';
497    public const PAYMENTS                          = 'payments';
498    public const PAYMENT_BUTTONS                   = 'payment-buttons';
499    public const PAYPAL_PAYMENT_BUTTONS            = 'paypal-payment-buttons';
500    public const PERFORMANCE                       = 'performance';
501    public const PERFORMANCE_HISTORY               = 'performance-history';
502    public const PODCASTING                        = 'podcasting';
503    public const POLLDADDY                         = 'polldaddy';
504    public const POSTS_TO_PODCAST_TIER_1           = 'posts-to-podcast-tier-1';
505    public const POSTS_TO_PODCAST_TIER_2           = 'posts-to-podcast-tier-2';
506    public const POSTS_TO_PODCAST_TIER_3           = 'posts-to-podcast-tier-3';
507    public const PREMIUM_CONTENT_CONTAINER         = 'premium-content/container';
508    public const PERSONAL_THEMES                   = 'personal-themes';
509    public const PREMIUM_THEMES                    = 'premium-themes';
510    public const PARTNER_THEMES                    = 'partner-themes';
511    public const COMMUNITY_THEMES                  = 'community-themes';
512    public const WOOCOMMERCE_THEMES                = 'woocommerce-themes';
513    public const SENSEI_THEMES                     = 'sensei-themes';
514    public const PRIORITY_SUPPORT                  = 'priority_support';
515    public const PRIVATE_WHOIS                     = 'private_whois';
516    public const REAL_TIME_BACKUPS                 = 'real-time-backups';
517    public const REAL_TIME_COLLABORATION           = 'real-time-collaboration';
518    public const RECURRING_PAYMENTS                = 'recurring-payments';
519    public const REDUCED_ATOMIC_EMAIL_PRIORITY     = 'reduced-email-priority';
520    public const REPUBLICIZE                       = 'republicize';
521    public const SCAN                              = 'scan';
522    public const SCAN_MANAGED                      = 'scan-managed';
523    public const SCAN_SELF_SERVE                   = 'scan-self-serve';
524    public const SCHEDULED_UPDATES                 = 'scheduled-updates';
525    public const SECURITY_SETTINGS                 = 'security-settings';
526    public const SEO_ADMIN_UI                      = 'seo-admin-ui';
527    public const SEO_PREVIEW_TOOLS                 = 'seo-preview-tools';
528    public const SEND_A_MESSAGE                    = 'send-a-message';
529    public const SET_PRIMARY_CUSTOM_DOMAIN         = 'set-primary-custom-domain';
530    public const SFTP                              = 'sftp';
531    public const SIMPLE_PAYMENTS                   = 'simple-payments';
532    public const SITE_PREVIEW_LINKS                = 'site-preview-links';
533    public const SOCIAL_ADMIN_UI_V2                = 'social-admin-ui-v2';
534    public const SOCIAL_IMAGE_FOCAL_POINT          = 'social-image-focal-point';
535    public const SOCIAL_IMAGE_GENERATOR            = 'social-image-generator';
536    public const SOCIAL_MESSAGE_TEMPLATES          = 'social-message-templates';
537    public const SOCIAL_SHARES_1000                = 'social-shares-1000';
538    public const SOCIAL_ENHANCED_PUBLISHING        = 'social-enhanced-publishing';
539    public const SOCIAL_IMAGE_AUTO_CONVERT         = 'social-image-auto-convert';
540    public const SPACE                             = 'space';
541    public const SPACE_UPGRADED_STORAGE            = 'space-upgraded-storage';
542    public const SSH                               = 'ssh';
543    public const STAGING_SITES                     = 'staging-sites';
544    public const STATS_BASIC_TEMP                  = 'stats-basic';
545    public const STATS_COMMERCIAL                  = 'stats-commercial';
546    public const STATS_FREE                        = 'stats-free';
547    public const STATS_PAID                        = 'stats-paid';
548    public const STUDIO_SYNC                       = 'studio-sync';
549    public const SUBSCRIBER_UNLIMITED_IMPORTS      = 'subscriber-unlimited-imports';
550    public const SUBSCRIPTION_GIFTING              = 'subscription-gifting';
551    public const SUPPORT                           = 'support';
552    public const TITAN_MAIL_1YEAR_TRIAL            = 'titan_mail_1year_trial';
553    public const UPGRADED_UPLOAD_FILETYPES         = 'upgraded_upload_filetypes';
554    public const UPLOAD_AUDIO_FILES                = 'upload-audio-files';
555    public const UPLOAD_PLUGINS                    = 'upload-plugins';
556    public const UPLOAD_SPACE_1GB                  = 'upload-space-1gb-addon';
557    public const UPLOAD_SPACE_3GB                  = 'upload-space-3gb';
558    public const UPLOAD_SPACE_10GB                 = 'upload-space-10gb';
559    public const UPLOAD_SPACE_25GB                 = 'upload-space-25gb';
560    public const UPLOAD_SPACE_50GB                 = 'upload-space-50gb';
561    public const UPLOAD_SPACE_100GB                = 'upload-space-100gb';
562    public const UPLOAD_SPACE_200GB                = 'upload-space-200gb';
563    public const UPLOAD_SPACE_UNLIMITED            = 'upload-space-unlimited';
564    public const UPLOAD_THEMES                     = 'upload-themes';
565    public const UPLOAD_VIDEO_FILES                = 'upload-video-files';
566    public const VAULTPRESS_AUTOMATED_RESTORES     = 'vaultpress-automated-restores';
567    public const VAULTPRESS_BACKUP_ARCHIVE         = 'vaultpress-backup-archive';
568    public const VAULTPRESS_BACKUPS                = 'vaultpress-backups';
569    public const VAULTPRESS_SECURITY_SCANNING      = 'vaultpress-security-scanning';
570    public const VAULTPRESS_STORAGE_SPACE          = 'vaultpress-storage-space';
571    public const VIDEO_HOSTING                     = 'video-hosting';
572    public const VIDEOPRESS                        = 'videopress';
573    public const VIDEOPRESS_1TB_STORAGE            = 'videopress-1tb-storage';
574    public const VIDEOPRESS_VIDEO                  = 'videopress/video';
575    public const VIDEOPRESS_UNLIMITED_STORAGE      = 'videopress-unlimited-storage';
576    public const WHATSAPP_BUTTON                   = 'whatsapp-button';
577    public const WOOP                              = 'woop';
578    public const WORDADS                           = 'wordads';
579    public const WORDADS_JETPACK                   = 'wordads-jetpack';
580
581    /*
582     * Private const array of features with sub-array of purchases that include that feature. Sorted alphabetically.
583     */
584    private const FEATURES_MAP = array(
585        self::AI_ASSISTANT                      => array(
586            self::JETPACK_AI_PLANS,
587            self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
588            self::JETPACK_COMPLETE_PLANS,
589            self::JETPACK_PRO_PLANS,
590        ),
591        // AI_CREDITS_WPCOM_* - the WordPress Agent's monthly AI credit allowance tier. Trials get no credits.
592        self::AI_CREDITS_WPCOM_BUSINESS         => array(
593            self::WPCOM_BUSINESS_PLANS,
594            self::EXCLUDE_PLANS => array(
595                self::WPCOM_MIGRATION_TRIAL_PLANS,
596                self::WPCOM_HOSTING_TRIAL_PLANS,
597            ),
598        ),
599        self::AI_CREDITS_WPCOM_COMMERCE         => array(
600            self::WPCOM_ECOMMERCE_PLANS,
601        ),
602        self::AI_CREDITS_WPCOM_PERSONAL         => array(
603            self::WPCOM_BLOGGER_PLANS,
604            self::WPCOM_PERSONAL_PLANS,
605            self::WPCOM_STARTER_PLANS,
606        ),
607        self::AI_CREDITS_WPCOM_PREMIUM          => array(
608            self::WPCOM_PREMIUM_PLANS,
609            self::WPCOM_PRO_PLANS,
610        ),
611        self::AI_SEO_ENHANCER                   => array(
612            self::WPCOM_PREMIUM_PLANS,
613            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
614            self::JETPACK_COMPLETE_PLANS,
615            self::JETPACK_PRO_PLANS,
616        ),
617        self::AD_CREDIT_VOUCHERS                => array(
618            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
619            self::WPCOM_PRO_PLANS,
620        ),
621
622        /*
623         * ADVANCED_SEO - Called seo-tools in Jetpack.
624         *
625         * Active for:
626         * - Simple and Atomic sites with Premium or up plan.
627         * - Jetpack sites with any plan.
628         * - Not VIP sites.
629         */
630        self::ADVANCED_SEO                      => array(
631            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
632            self::JETPACK_ALL_SITES,
633        ),
634        self::AKISMET                           => array(
635            self::AKISMET_PLANS,
636            self::JETPACK_PERSONAL_AND_HIGHER,
637            self::WPCOM_ALL_SITES,
638        ),
639        self::ANTISPAM                          => array(
640            self::JETPACK_ANTI_SPAM_BI_YEARLY,
641            self::JETPACK_ANTI_SPAM,
642            self::JETPACK_ANTI_SPAM_MONTHLY,
643            self::A4A_JETPACK_ANTI_SPAM_YEARLY,
644            self::A4A_JETPACK_ANTI_SPAM_MONTHLY,
645            self::JETPACK_PERSONAL_AND_HIGHER,
646            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
647            self::WPCOM_PRO_PLANS,
648        ),
649
650        // Automatically syncs content to the Internet Archive on publish and update.
651        self::ARCHIVE_CONTENT                   => array(
652            self::WPCOM_HUNDRED_YEAR_BUNDLE,
653        ),
654
655        self::ATOMIC                            => array(
656            self::WPCOM_PRO_PLANS,
657            self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
658            self::WPCOM_STAGING_PRODUCT,
659            array( 'product_type' => array( 'marketplace_plugin', 'saas_plugin' ) ),
660            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
661        ),
662        // BACKUPS - Site has *any* kind of backups.
663        self::BACKUPS                           => array(
664            self::JETPACK_BACKUP_DAILY_PLANS,
665            self::JETPACK_BACKUP_ONE_TIME,
666            self::JETPACK_BACKUP_REALTIME_PLANS,
667            self::JETPACK_BACKUP_T0_PLANS,
668            self::JETPACK_BACKUP_T1_PLANS,
669            self::JETPACK_BACKUP_T2_PLANS,
670            self::JETPACK_PERSONAL_AND_HIGHER,
671            self::JETPACK_PRO_PLANS,
672            self::JETPACK_GOLDEN_TOKEN,
673            self::WPCOM_PRO_PLANS,
674            self::WPCOM_STAGING_PRODUCT,
675            self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
676            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
677        ),
678        // BACKUPS_DAILY - Site has product that includes daily backups.
679        self::BACKUPS_DAILY                     => array(
680            self::JETPACK_BACKUP_DAILY_PLANS,
681            self::JETPACK_PERSONAL_AND_HIGHER,
682            self::JETPACK_SECURITY_DAILY_PLANS,
683        ),
684        self::BACKUPS_RESTORE                   => array(
685            self::WPCOM_PRO_PLANS,
686            self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
687            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
688        ),
689        self::BACKUPS_SELF_SERVE                => array(
690            self::JETPACK_BACKUP_DAILY_PLANS,
691            self::JETPACK_BACKUP_ONE_TIME,
692            self::JETPACK_BACKUP_REALTIME_PLANS,
693            self::JETPACK_BACKUP_T0_PLANS,
694            self::JETPACK_BACKUP_T1_PLANS,
695            self::JETPACK_BACKUP_T2_PLANS,
696            self::JETPACK_PERSONAL_AND_HIGHER,
697            self::JETPACK_PRO_PLANS,
698            self::JETPACK_GOLDEN_TOKEN,
699            self::WPCOM_PRO_PLANS,
700            self::WPCOM_STAGING_PRODUCT,
701            // Business and higher can self serve restoring backups.
702            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
703            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
704        ),
705
706        /*
707         * BACKUP_ONE_TIME - Site has purchased a one-time backup.
708         * Note the jetpack_backup_one_time product never expires. So any feature gated with BACKUP_ONE_TIME will
709         * likewise, never expire.
710         */
711        self::BACKUP_ONE_TIME                   => array(
712            self::JETPACK_BACKUP_ONE_TIME,
713        ),
714        // Plans that grant unlimited Big Sky usage and exit the Big Sky free trial.
715        self::BIG_SKY                           => array(
716            self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
717        ),
718        self::BLAZE_CREDITS_VOUCHER             => array(
719            array(
720                // Business.
721                self::BUSINESS_BUNDLE,
722                self::BUSINESS_BUNDLE_MONTHLY,
723                self::BUSINESS_BUNDLE_2Y,
724                self::BUSINESS_BUNDLE_3Y,
725                // Ecommerce.
726                self::ECOMMERCE_BUNDLE,
727                self::ECOMMERCE_BUNDLE_MONTHLY,
728                self::ECOMMERCE_BUNDLE_2Y,
729                self::ECOMMERCE_BUNDLE_3Y,
730            ),
731        ),
732        // BLOG_DOMAIN_ONLY - Users on Blogger plan can only purchase .blog domains.
733        self::BLOG_DOMAIN_ONLY                  => array(
734            self::WPCOM_BLOGGER_PLANS,
735        ),
736        self::CALENDLY                          => array(
737            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
738            self::JETPACK_BUSINESS_PLANS,
739            self::JETPACK_PREMIUM_PLANS,
740            self::WP_P2_PLUS_MONTHLY,
741        ),
742        self::CDN                               => array(
743            self::JETPACK_ALL_SITES,
744            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
745            self::WPCOM_PRO_PLANS,
746        ),
747        self::CLASSIC_SEARCH                    => array(
748            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
749            self::WPCOM_PRO_PLANS,
750            self::JETPACK_SEARCH_PLANS,
751            self::JETPACK_COMPLETE_PLANS,
752            self::JETPACK_PRO_PLANS,
753            self::JETPACK_BUSINESS_PLANS,
754            self::WPCOM_SEARCH,
755            self::WPCOM_SEARCH_MONTHLY,
756            self::WP_P2_PLUS_MONTHLY,
757        ),
758        self::CLOUD_CRITICAL_CSS                => array(
759            self::JETPACK_BOOST_PLANS,
760            self::JETPACK_COMPLETE_PLANS,
761            self::JETPACK_PRO_PLANS,
762        ),
763        self::CORNERSTONE_TEN_PAGES             => array(
764            self::JETPACK_BOOST_PLANS,
765            self::JETPACK_COMPLETE_PLANS,
766            self::JETPACK_PRO_PLANS,
767        ),
768        self::CLOUDFLARE_ANALYTICS              => array(
769            self::JETPACK_PREMIUM_AND_HIGHER,
770            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
771            self::WPCOM_PRO_PLANS,
772        ),
773        self::CLOUDFLARE_CDN                    => array(
774            self::JETPACK_PREMIUM_AND_HIGHER,
775            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
776            self::WPCOM_PRO_PLANS,
777        ),
778        self::CONCIERGE                         => array(
779            self::WPCOM_BUSINESS_PLANS,
780            self::WPCOM_ECOMMERCE_PLANS,
781        ),
782        self::CONCIERGE_BUSINESS                => array(
783            self::WPCOM_BUSINESS_PLANS,
784        ),
785        self::COPY_SITE                         => array(
786            self::WPCOM_PRO_PLANS,
787            self::EXCLUDE_PLANS => array(
788                self::WPCOM_ECOMMERCE_TRIAL_PLANS,
789            ),
790            // Copy a site requires an Atomic site, so this mirrors the plans that can be
791            // Atomic: Personal, Premium, and Business or higher plans (not all paid plans).
792            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
793            self::WPCOM_PERSONAL_AND_PREMIUM_PLANS,
794            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
795        ),
796        // CORE_AUDIO - core/audio requires a paid plan for uploading audio files.
797        self::CORE_AUDIO                        => array(
798            self::WP_P2_PLUS_MONTHLY,
799            self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
800            self::JETPACK_PERSONAL_AND_HIGHER,
801        ),
802        // CORE_COVER - core/cover requires a paid plan for uploading video files.
803        self::CORE_COVER                        => array(
804            self::WP_P2_PLUS_MONTHLY,
805            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
806            self::JETPACK_BUSINESS_PLANS,
807            self::JETPACK_PREMIUM_PLANS,
808        ),
809        // CORE_VIDEO - core/video requires a paid plan.
810        self::CORE_VIDEO                        => array(
811            self::WP_P2_PLUS_MONTHLY,
812            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
813            self::JETPACK_BUSINESS_PLANS,
814            self::JETPACK_PREMIUM_PLANS,
815        ),
816        self::CREDIT_VOUCHERS                   => array(
817            self::BUNDLE_PRO,
818            self::BUNDLE_SUPER,
819            self::BUNDLE_ENTERPRISE,
820            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
821        ),
822        self::CUSTOM_DESIGN                     => array(
823            self::WPCOM_CUSTOM_DESIGN,
824            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
825        ),
826        self::CUSTOM_DOMAIN                     => array(
827            self::WPCOM_BLOGGER_AND_HIGHER_PLANS,
828            self::WOO_HOSTED_PLANS,
829        ),
830        self::DOMAIN_MAPPING                    => array(
831            self::WPCOM_BLOGGER_AND_HIGHER_PLANS,
832            self::WPCOM_PRO_PLANS,
833            self::WOO_HOSTED_PLANS,
834        ),
835        self::DONATIONS                         => array(
836            array(
837                'before_feature_gating_2026' => true,
838                self::WPCOM_ALL_SITES,
839            ),
840            array(
841                'before_feature_gating_2026' => true,
842                self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
843            ),
844            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
845            self::JETPACK_ALL_SITES,
846        ),
847        // ECOMMERCE_MANAGED_PLUGINS - Can install the plugin bundle that comes with eCommerce plans.
848        self::ECOMMERCE_MANAGED_PLUGINS         => array(
849            self::WPCOM_ECOMMERCE_PLANS,
850            self::WPCOM_ECOMMERCE_TRIAL_PLANS,
851            self::WPCOM_WOOEXPRESS_PLANS,
852        ),
853        // ECOMMERCE_MANAGED_PLUGINS_SMALL - Can install the plugin bundle that comes with eCommerce Small plans.
854        self::ECOMMERCE_MANAGED_PLUGINS_SMALL   => array(
855            self::WPCOM_WOOEXPRESS_SMALL_PLANS,
856        ),
857        // ECOMMERCE_MANAGED_PLUGINS_MEDIUM - Can install the plugin bundle that comes with eCommerce Medium plans.
858        self::ECOMMERCE_MANAGED_PLUGINS_MEDIUM  => array(
859            self::WPCOM_ECOMMERCE_PLANS,
860            self::WPCOM_WOOEXPRESS_MEDIUM_PLANS,
861        ),
862        // ECOMMERCE_MANAGED_PLUGINS_TRIAL - Can install the plugin bundle that comes with eCommerce Trial plans.
863        self::ECOMMERCE_MANAGED_PLUGINS_TRIAL   => array(
864            self::WPCOM_ECOMMERCE_TRIAL_PLANS,
865        ),
866        // EDIT_PLUGINS - Provides the edit_plugins capability on atomic sites, does nothing on simple sites.
867        self::EDIT_PLUGINS                      => array(
868            self::WPCOM_PRO_PLANS,
869            self::EXCLUDE_PLANS => array(
870                self::WPCOM_ECOMMERCE_TRIAL_PLANS,
871            ),
872            self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
873            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
874        ),
875        // EDIT_THEMES - Provides the edit_themes capability on atomic sites, does nothing on simple sites.
876        self::EDIT_THEMES                       => array(
877            self::WPCOM_PRO_PLANS,
878            self::EXCLUDE_PLANS => array(
879                self::WPCOM_ECOMMERCE_TRIAL_PLANS,
880            ),
881            self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
882            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
883        ),
884        // EMAIL_PROFESSIONAL - Access to Titan email hosting, often referred to as WordPress.com "Professional Email".
885        self::EMAIL_PROFESSIONAL                => array(
886            self::WPCOM_TITAN_MAIL_PRODUCTS,
887        ),
888        // EMAIL_SUBSCRIPTION - Represents having at least one product providing email.
889        self::EMAIL_SUBSCRIPTION                => array(
890            self::WPCOM_EMAIL_PRODUCTS,
891        ),
892        self::EMAIL_FORWARDS_EXTENDED_LIMIT     => array(
893            self::BUNDLE_ENTERPRISE,
894            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
895            self::WPCOM_PRO_PLANS,
896        ),
897        // FIELD_FILE - Premium block/feature (jetpack/field-file) for uploading files with cloud backend.
898        // See: https://github.com/Automattic/jetpack/pull/43177 / https://github.a8c.com/Automattic/wpcom/pull/179247
899        self::FIELD_FILE                        => array(
900            array(
901                'before_feature_gating_2026' => true,
902                self::WPCOM_PERSONAL_PLANS,
903                self::WPCOM_PREMIUM_PLANS,
904            ),
905            self::WPCOM_PRO_PLANS,
906            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
907            self::JETPACK_COMPLETE_PLANS,
908            self::JETPACK_PRO_PLANS,
909        ),
910        self::FORM_CONDITIONAL_LOGIC            => array(
911            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
912            self::JETPACK_ALL_SITES,
913        ),
914        self::FORM_INTEGRATIONS                 => array(
915            array(
916                'before_feature_gating_2026' => true,
917                self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
918            ),
919            self::WPCOM_PRO_PLANS,
920            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
921            self::JETPACK_ALL_SITES,
922        ),
923        self::FORM_WEBHOOKS                     => array(
924            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
925            self::JETPACK_ALL_SITES,
926        ),
927        self::FREE_BLOG                         => array(
928            self::WPCOM_ALL_SITES,
929        ),
930        self::FULL_ACTIVITY_LOG                 => array(
931            self::JETPACK_BACKUP_DAILY_PLANS,
932            self::JETPACK_BACKUP_REALTIME_PLANS,
933            self::JETPACK_BACKUP_T0_PLANS,
934            self::JETPACK_BACKUP_T1_PLANS,
935            self::JETPACK_BACKUP_T2_PLANS,
936            self::JETPACK_PERSONAL_AND_HIGHER,
937            self::JETPACK_GOLDEN_TOKEN,
938            self::WPCOM_BLOGGER_AND_HIGHER_PLANS,
939            self::WPCOM_PRO_PLANS,
940        ),
941        self::GITHUB_DEPLOYMENTS                => array(
942            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
943            self::WPCOM_PERSONAL_AND_PREMIUM_PLANS,
944            self::WPCOM_PRO_PLANS,
945            self::EXCLUDE_PLANS => array(
946                self::WPCOM_ECOMMERCE_TRIAL_PLANS,
947            ),
948        ),
949        self::GLOBAL_STYLES                     => array(
950            self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
951        ),
952        self::GOOGLE_ANALYTICS                  => array(
953            self::JETPACK_PREMIUM_AND_HIGHER,
954            self::WPCOM_STARTER_AND_HIGHER_PLANS,
955        ),
956        self::GOOGLE_MY_BUSINESS                => array(
957            self::WPCOM_PRO_PLANS,
958            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
959            self::JETPACK_BUSINESS_PLANS,
960            self::JETPACK_SECURITY_REALTIME_PLANS,
961            self::JETPACK_COMPLETE_PLANS,
962            self::JETPACK_PRO_PLANS,
963            self::JETPACK_SECURITY_T1_PLANS,
964            self::JETPACK_SECURITY_T2_PLANS,
965        ),
966        self::IMAGE_CDN_LIAR                    => array(
967            self::JETPACK_BOOST_PLANS,
968            self::JETPACK_COMPLETE_PLANS,
969            self::JETPACK_PRO_PLANS,
970        ),
971        self::IMAGE_CDN_QUALITY                 => array(
972            self::JETPACK_BOOST_PLANS,
973            self::JETPACK_COMPLETE_PLANS,
974            self::JETPACK_PRO_PLANS,
975        ),
976        self::IMAGE_SIZE_ANALYSIS               => array(
977            self::JETPACK_BOOST_PLANS,
978            self::JETPACK_COMPLETE_PLANS,
979            self::JETPACK_PRO_PLANS,
980        ),
981        self::INSTALL_PLUGINS                   => array(
982            self::WPCOM_PRO_PLANS,
983            self::EXCLUDE_PLANS => array(
984                self::WPCOM_ECOMMERCE_TRIAL_PLANS,
985            ),
986            self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
987            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
988        ),
989        self::INSTALL_PURCHASED_PLUGINS         => array(
990            self::WPCOM_PRO_PLANS,
991            self::WPCOM_STARTER_PLANS,
992            self::EXCLUDE_PLANS => array(
993                self::WPCOM_ECOMMERCE_TRIAL_PLANS,
994            ),
995            self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
996            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
997        ),
998        self::INSTALL_THEMES                    => array(
999            self::WPCOM_PRO_PLANS,
1000            self::JETPACK_ALL_SITES,
1001            self::EXCLUDE_PLANS => array(
1002                self::WPCOM_ECOMMERCE_TRIAL_PLANS,
1003            ),
1004            self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
1005            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
1006        ),
1007        self::INSTALL_WOO_ONBOARDING_PLUGINS    => array(
1008            self::WPCOM_ECOMMERCE_TRIAL_PLANS,
1009        ),
1010        self::INSTANT_SEARCH                    => array(
1011            self::WPCOM_SEARCH,
1012            self::WPCOM_SEARCH_MONTHLY,
1013            self::WP_P2_PLUS_MONTHLY,
1014            self::JETPACK_SEARCH_PLANS,
1015            self::JETPACK_COMPLETE_PLANS,
1016            self::JETPACK_PRO_PLANS,
1017        ),
1018        self::JETPACK_DASHBOARD                 => array(
1019            self::WPCOM_PRO_PLANS,
1020            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1021            self::JETPACK_ALL_SITES,
1022        ),
1023
1024        // Allows sites to designate a contact person to look after their site after they pass away.
1025        self::LEGACY_CONTACT                    => array(
1026            self::WPCOM_HUNDRED_YEAR_BUNDLE,
1027        ),
1028        self::LIST_INSTALLED_PLUGINS            => array(
1029            self::WPCOM_PRO_PLANS,
1030            self::WPCOM_STARTER_PLANS,
1031            self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
1032            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
1033        ),
1034        // LIVE_SUPPORT - Monthly plans do not get live support. p7DVsv-a9N-p2.
1035        self::LIVE_SUPPORT                      => array(
1036            // Premium (Excluding Monthly).
1037            self::BUNDLE_PRO,
1038            self::VALUE_BUNDLE,
1039            self::VALUE_BUNDLE_2Y,
1040            self::VALUE_BUNDLE_3Y,
1041            // Pro.
1042            self::PRO_PLAN,
1043            self::PRO_PLAN_2Y,
1044            // Business (Excluding Monthly).
1045            self::BUSINESS_BUNDLE,
1046            self::BUSINESS_BUNDLE_2Y,
1047            self::BUSINESS_BUNDLE_3Y,
1048            // Student (yearly).
1049            self::STUDENT_BUNDLE,
1050            // Ecommerce (Excluding Monthly).
1051            self::ECOMMERCE_BUNDLE,
1052            self::ECOMMERCE_BUNDLE_2Y,
1053            self::ECOMMERCE_BUNDLE_3Y,
1054            // Woo Express (Small and Medium plans), excluding monthly.
1055            self::WPCOM_WOOEXPRESS_MEDIUM_BUNDLE_YEARLY,
1056            self::WPCOM_WOOEXPRESS_SMALL_BUNDLE_YEARLY,
1057        ),
1058
1059        // Enables a setting to lock the site content to prevent changes (incl. disabling comments site-wide).
1060        self::LOCKED_MODE                       => array(
1061            self::WPCOM_HUNDRED_YEAR_BUNDLE,
1062        ),
1063        self::LOGS                              => array(
1064            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1065            self::WPCOM_PRO_PLANS,
1066            self::WPCOM_PERSONAL_AND_PREMIUM_PLANS,
1067            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
1068        ),
1069        self::MAILPOET_BUSINESS                 => array(
1070            self::WPCOM_BUSINESS_PLANS,
1071            self::WPCOM_ECOMMERCE_PLANS,
1072            self::WPCOM_WOOEXPRESS_PLANS,
1073            self::WOO_HOSTED_PLANS,
1074        ),
1075        // MANAGE_PLUGINS - Atomic only feature. Can upload, install, and activate any 3rd party plugin.
1076        self::MANAGE_PLUGINS                    => array(
1077            self::WPCOM_PRO_PLANS,
1078            self::EXCLUDE_PLANS => array(
1079                self::WPCOM_ECOMMERCE_TRIAL_PLANS,
1080            ),
1081            self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
1082            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
1083        ),
1084        self::MONITORING                        => array(
1085            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1086            self::WPCOM_PRO_PLANS,
1087        ),
1088
1089        // MONITOR_1_MINUTE_CHECK_INTERVAL - Jetpack Monitor checks site uptime once per minute
1090        self::MONITOR_1_MINUTE_CHECK_INTERVAL   => array(
1091            self::JETPACK_MONITOR_MONTHLY,
1092            self::JETPACK_MONITOR_YEARLY,
1093            self::A4A_JETPACK_MONITOR_MONTHLY,
1094            self::A4A_JETPACK_MONITOR_YEARLY,
1095        ),
1096        // MONITOR_MULTIPLE_EMAIL_RECIPIENTS - Jetpack Monitor can email more than one recipient when a site goes down
1097        self::MONITOR_MULTIPLE_EMAIL_RECIPIENTS => array(
1098            self::JETPACK_MONITOR_MONTHLY,
1099            self::JETPACK_MONITOR_YEARLY,
1100            self::A4A_JETPACK_MONITOR_MONTHLY,
1101            self::A4A_JETPACK_MONITOR_YEARLY,
1102        ),
1103        // MONITOR_SMS_NOTIFICATIONS - Jetpack Monitor can send notifications via SMS when a site goes down
1104        self::MONITOR_SMS_NOTIFICATIONS         => array(
1105            self::JETPACK_MONITOR_MONTHLY,
1106            self::JETPACK_MONITOR_YEARLY,
1107            self::A4A_JETPACK_MONITOR_MONTHLY,
1108            self::A4A_JETPACK_MONITOR_YEARLY,
1109        ),
1110        self::MULTISTEP_FORM                    => array(
1111            array(
1112                'before_feature_gating_2026' => true,
1113                self::WPCOM_PERSONAL_PLANS,
1114                self::WPCOM_PREMIUM_PLANS,
1115            ),
1116            self::WPCOM_PRO_PLANS,
1117            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1118            self::JETPACK_ALL_SITES,
1119        ),
1120        self::NO_ADVERTS_NO_ADVERTS_PHP         => array(
1121            self::NO_ADS,
1122            // Deliberately leaves out the Starter plan.
1123            self::WPCOM_BLOGGER_PLANS,
1124            self::WPCOM_PERSONAL_PLANS,
1125            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
1126        ),
1127        // NO_WPCOM_BRANDING - Enable the ability to hide the WP.com branding in the site footer.
1128        self::NO_WPCOM_BRANDING                 => array(
1129            self::WPCOM_PRO_PLANS,
1130            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1131            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
1132        ),
1133        self::OPENTABLE                         => array(
1134            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
1135            self::JETPACK_BUSINESS_PLANS,
1136            self::JETPACK_PREMIUM_PLANS,
1137        ),
1138        self::PAYMENTS                          => array(
1139            array(
1140                'before_feature_gating_2026' => true,
1141                self::WPCOM_PERSONAL_PLANS,
1142            ),
1143            self::WPCOM_STARTER_PLANS,
1144            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
1145        ),
1146        self::PAYMENT_BUTTONS                   => array(
1147            array(
1148                'before_feature_gating_2026' => true,
1149                self::WPCOM_ALL_SITES,
1150            ),
1151            array(
1152                'before_feature_gating_2026' => true,
1153                self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
1154            ),
1155            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
1156            self::JETPACK_ALL_SITES,
1157        ),
1158        self::PAYPAL_PAYMENT_BUTTONS            => array(
1159            array(
1160                'before_feature_gating_2026' => true,
1161                self::WPCOM_ALL_SITES,
1162            ),
1163            array(
1164                'before_feature_gating_2026' => true,
1165                self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
1166            ),
1167            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
1168            self::JETPACK_ALL_SITES,
1169        ),
1170        self::PERFORMANCE                       => array(
1171            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1172            self::WPCOM_PRO_PLANS,
1173        ),
1174        self::PERFORMANCE_HISTORY               => array(
1175            self::JETPACK_BOOST_PLANS,
1176            self::JETPACK_COMPLETE_PLANS,
1177            self::JETPACK_PRO_PLANS,
1178        ),
1179        self::PODCASTING                        => array(
1180            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
1181            self::JETPACK_ALL_SITES,
1182        ),
1183        self::POLLDADDY                         => array(
1184            self::JETPACK_BUSINESS_PLANS,
1185        ),
1186        // POSTS_TO_PODCAST_TIER_{1,2,3} â€” generates a podcast-style episode
1187        // from recent posts. Monthly quotas: TIER_1 = 5, TIER_2 = 10,
1188        // TIER_3 = 20. Sites accumulate tiers via the _AND_HIGHER cascades;
1189        // the lib's quota helper takes the highest tier present.
1190        self::POSTS_TO_PODCAST_TIER_1           => array(
1191            self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
1192        ),
1193        self::POSTS_TO_PODCAST_TIER_2           => array(
1194            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
1195        ),
1196        self::POSTS_TO_PODCAST_TIER_3           => array(
1197            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1198        ),
1199        // PREMIUM_CONTENT_CONTAINER - premium-content requires a paid wpcom plan.
1200        self::PREMIUM_CONTENT_CONTAINER         => array(
1201            self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
1202            self::WP_P2_PLUS_MONTHLY,
1203        ),
1204        self::PERSONAL_THEMES                   => array(
1205            self::WPCOM_UNLIMITED_THEMES,
1206            self::BUNDLE_ENTERPRISE,
1207            self::WPCOM_PRO_PLANS,
1208            self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
1209            self::JETPACK_BUSINESS_PLANS,
1210        ),
1211        self::PREMIUM_THEMES                    => array(
1212            self::WPCOM_UNLIMITED_THEMES,
1213            self::BUNDLE_ENTERPRISE,
1214            self::WPCOM_PRO_PLANS,
1215            self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
1216            self::JETPACK_BUSINESS_PLANS,
1217        ),
1218        self::PARTNER_THEMES                    => array(
1219            // We do not want all paid plans to have the feature, just Personal, Premium, and Business or higher plans.
1220            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1221            self::WPCOM_PERSONAL_AND_PREMIUM_PLANS,
1222            self::WPCOM_PRO_PLANS,
1223            self::EXCLUDE_PLANS => array(
1224                self::WPCOM_ECOMMERCE_TRIAL_PLANS,
1225            ),
1226        ),
1227        self::COMMUNITY_THEMES                  => array(
1228            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1229            self::WPCOM_PRO_PLANS,
1230            self::EXCLUDE_PLANS => array(
1231                self::WPCOM_ECOMMERCE_TRIAL_PLANS,
1232            ),
1233            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
1234        ),
1235        self::WOOCOMMERCE_THEMES                => array(
1236            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1237            self::WPCOM_PRO_PLANS,
1238            self::EXCLUDE_PLANS => array(
1239                self::WPCOM_ECOMMERCE_TRIAL_PLANS,
1240            ),
1241            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
1242        ),
1243        self::SENSEI_THEMES                     => array(
1244            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1245            self::WPCOM_PRO_PLANS,
1246            self::EXCLUDE_PLANS => array(
1247                self::WPCOM_ECOMMERCE_TRIAL_PLANS,
1248            ),
1249        ),
1250        self::PRIORITY_SUPPORT                  => array(
1251            self::JETPACK_BACKUP_T1_PLANS,
1252            self::JETPACK_BACKUP_T2_PLANS,
1253            self::JETPACK_PERSONAL_AND_HIGHER,
1254            self::JETPACK_GOLDEN_TOKEN,
1255            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1256            self::WPCOM_PRO_PLANS,
1257        ),
1258        self::PRIVATE_WHOIS                     => array(
1259            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
1260        ),
1261        self::REAL_TIME_BACKUPS                 => array(
1262            self::JETPACK_BACKUP_REALTIME_PLANS,
1263            self::JETPACK_BACKUP_T0_PLANS,
1264            self::JETPACK_BACKUP_T1_PLANS,
1265            self::JETPACK_BACKUP_T2_PLANS,
1266            self::JETPACK_BUSINESS_PLANS,
1267            self::JETPACK_COMPLETE_PLANS,
1268            self::JETPACK_PRO_PLANS,
1269            self::JETPACK_SECURITY_REALTIME_PLANS,
1270            self::JETPACK_SECURITY_T0_PLANS,
1271            self::JETPACK_SECURITY_T1_PLANS,
1272            self::JETPACK_SECURITY_T2_PLANS,
1273            self::JETPACK_STARTER_PLANS,
1274            self::JETPACK_GOLDEN_TOKEN,
1275            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1276            self::WPCOM_PRO_PLANS,
1277            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
1278        ),
1279
1280        self::REAL_TIME_COLLABORATION           => array(
1281            self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
1282        ),
1283
1284        self::RECURRING_PAYMENTS                => array(
1285            self::WPCOM_ALL_SITES,
1286            self::WPCOM_STARTER_PLANS,
1287            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
1288            self::JETPACK_ALL_SITES,
1289        ),
1290
1291        /*
1292         * Reduced email priority when sending emails via SMTP via the Atomic platform.
1293         */
1294        self::REDUCED_ATOMIC_EMAIL_PRIORITY     => array(
1295            self::WPCOM_ECOMMERCE_TRIAL_PLANS,
1296            self::WPCOM_MIGRATION_TRIAL_PLANS,
1297            self::WPCOM_HOSTING_TRIAL_PLANS,
1298        ),
1299
1300        /*
1301         * REPUBLICIZE
1302         *
1303         * Active for:
1304         * - Simple and Atomic sites with Premium or up plan.
1305         * - Jetpack sites with Premium or up plan, or a Jetpack Social plan.
1306         */
1307        self::REPUBLICIZE                       => array(
1308            self::WP_P2_PLUS_MONTHLY,
1309            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
1310            self::JETPACK_ALL_SITES,
1311        ),
1312        self::SCAN                              => array(
1313            self::JETPACK_PREMIUM_AND_HIGHER,
1314            self::JETPACK_SCAN_PLANS,
1315            self::JETPACK_GOLDEN_TOKEN,
1316            self::WPCOM_PERSONAL_AND_PREMIUM_PLANS,
1317            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1318            self::WPCOM_PRO_PLANS,
1319            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
1320        ),
1321
1322        /*
1323         * SCAN_MANAGED - Scan results are managed internally by Atomic guild HEs and not shown in user UI.
1324         * See D57207-code.
1325         */
1326        self::SCAN_MANAGED                      => array(
1327            self::WPCOM_PERSONAL_AND_PREMIUM_PLANS,
1328            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1329            self::WPCOM_PRO_PLANS,
1330            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
1331        ),
1332
1333        // This governs UI access to Jetpack Scan.
1334        // All WoW sites should perform scans, however we don't want to expose the UI to sites on lower wpcom plans.
1335        // It's not completely clear how this differs from SCAN_MANAGED.
1336        self::SCAN_SELF_SERVE                   => array(
1337            self::JETPACK_PREMIUM_AND_HIGHER,
1338            self::JETPACK_SCAN_PLANS,
1339            self::JETPACK_GOLDEN_TOKEN,
1340            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1341            self::WPCOM_PRO_PLANS,
1342            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
1343        ),
1344
1345        /*
1346         * SCHEDULED_UPDATES - Allows users to schedule plugin and (eventually) theme updates for their sites.
1347         *
1348         * @see pcmemI-2O3-p2
1349         */
1350        self::SCHEDULED_UPDATES                 => array(
1351            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1352            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
1353        ),
1354
1355        /*
1356         * SECURITY_SETTINGS - Initially added to determine whether to show /settings/security.
1357         * More info: https://github.com/Automattic/wp-calypso/issues/51820
1358         *
1359         * Active for:
1360         * - Simple and Atomic sites with Business or up plan.
1361         * - Jetpack sites with any plan.
1362         */
1363        self::SECURITY_SETTINGS                 => array(
1364            self::WPCOM_PRO_PLANS,
1365            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1366            self::JETPACK_ALL_SITES,
1367            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
1368        ),
1369        self::SEO_ADMIN_UI                      => array(
1370            // For now, this is controlled via a blog sticker in Store_Product_List.
1371            array(
1372                'before' => '2004-12-12',
1373                self::WPCOM_ALL_SITES,
1374            ),
1375        ),
1376        self::SEO_PREVIEW_TOOLS                 => array(
1377            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
1378            self::BUNDLE_ENTERPRISE,
1379            self::JETPACK_ALL_SITES,
1380            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
1381        ),
1382        self::SEND_A_MESSAGE                    => array(
1383            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
1384            self::JETPACK_ALL_SITES,
1385        ),
1386
1387        /*
1388         * SET_PRIMARY_CUSTOM_DOMAIN - Set custom domain as primary.
1389         * It allows to set a custom domain of the site as primary.
1390         *
1391         * Active for:
1392         * - Simple and Atomic sites with any standard WordPress.com plan
1393         */
1394        self::SET_PRIMARY_CUSTOM_DOMAIN         => array(
1395            self::WPCOM_BLOGGER_AND_HIGHER_PLANS,
1396            self::WOO_HOSTED_PLANS,
1397            self::YOAST_PREMIUM,
1398        ),
1399        // Hosting Configuration.
1400        self::SFTP                              => array(
1401            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1402            self::WPCOM_PERSONAL_AND_PREMIUM_PLANS,
1403            self::WPCOM_PRO_PLANS,
1404            self::EXCLUDE_PLANS => array(
1405                self::WPCOM_ECOMMERCE_TRIAL_PLANS,
1406            ),
1407            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
1408        ),
1409
1410        self::SSH                               => array(
1411            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1412            self::WPCOM_PERSONAL_AND_PREMIUM_PLANS,
1413            self::WPCOM_PRO_PLANS,
1414            self::EXCLUDE_PLANS => array(
1415                self::WPCOM_ECOMMERCE_TRIAL_PLANS,
1416            ),
1417            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
1418        ),
1419        self::SIMPLE_PAYMENTS                   => array(
1420            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
1421            self::JETPACK_PREMIUM_AND_HIGHER,
1422            self::JETPACK_CREATOR_PLANS,
1423            self::JETPACK_GROWTH_PLANS,
1424        ),
1425        self::SITE_PREVIEW_LINKS                => array(
1426            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1427        ),
1428
1429        /*
1430         * SOCIAL_SHARES_1000 - This feature is linked to the ability to share upto 1000 social media shares on the Jetpack Social Plugin.
1431         *
1432         */
1433        self::SOCIAL_SHARES_1000                => array(
1434            self::JETPACK_ALL_SITES,
1435            self::BUNDLE_ENTERPRISE,
1436        ),
1437
1438        self::SOCIAL_ENHANCED_PUBLISHING        => array(
1439            self::JETPACK_SOCIAL_ADVANCED_PLANS,
1440            self::JETPACK_COMPLETE_PLANS,
1441            self::JETPACK_PRO_PLANS,
1442            self::BUNDLE_ENTERPRISE,
1443            self::JETPACK_SOCIAL_V1_PLANS,
1444            self::JETPACK_SOCIAL_PLANS,
1445            self::JETPACK_GROWTH_PLANS,
1446            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1447        ),
1448        self::SOCIAL_ADMIN_UI_V2                => array(
1449            // For now, this is controlled via a blog sticker in Store_Product_List.
1450            array(
1451                'before' => '2004-12-12',
1452                self::WPCOM_ALL_SITES,
1453            ),
1454        ),
1455        self::SOCIAL_IMAGE_FOCAL_POINT          => array(
1456            // For now, this is controlled via a blog sticker in Store_Product_List.
1457            array(
1458                'before' => '2004-12-12',
1459                self::WPCOM_ALL_SITES,
1460            ),
1461        ),
1462        self::SOCIAL_IMAGE_GENERATOR            => array(
1463            self::JETPACK_SOCIAL_ADVANCED_PLANS,
1464            self::JETPACK_COMPLETE_PLANS,
1465            self::JETPACK_PRO_PLANS,
1466            self::BUNDLE_ENTERPRISE,
1467            self::JETPACK_SOCIAL_V1_PLANS,
1468            self::JETPACK_SOCIAL_PLANS,
1469            self::JETPACK_GROWTH_PLANS,
1470            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1471        ),
1472        self::SOCIAL_MESSAGE_TEMPLATES          => array(
1473            // Gated on the paid social plans, matching SOCIAL_ENHANCED_PUBLISHING.
1474            self::JETPACK_SOCIAL_ADVANCED_PLANS,
1475            self::JETPACK_COMPLETE_PLANS,
1476            self::JETPACK_PRO_PLANS,
1477            self::BUNDLE_ENTERPRISE,
1478            self::JETPACK_SOCIAL_V1_PLANS,
1479            self::JETPACK_SOCIAL_PLANS,
1480            self::JETPACK_GROWTH_PLANS,
1481            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1482        ),
1483        self::SOCIAL_IMAGE_AUTO_CONVERT         => array(
1484            self::WPCOM_ALL_SITES,
1485        ),
1486        self::SPACE                             => array(
1487            self::WPCOM_ALL_SITES,
1488        ),
1489
1490        /*
1491         * Products that have upgraded storage space on WordPress.com, beyond
1492         * the bare minimum advertised for free sites. This list includes all
1493         * WordPress.com plans and space upgrade products.
1494         */
1495        self::SPACE_UPGRADED_STORAGE            => array(
1496            self::WPCOM_BLOGGER_AND_HIGHER_PLANS,
1497            self::BUNDLE_SUPER,
1498            self::BUNDLE_ENTERPRISE,
1499            self::WP_P2_PLUS_MONTHLY,
1500            self::SPACE_1GB,
1501            self::SPACE_3GB,
1502            self::SPACE_10GB,
1503            self::SPACE_25GB,
1504            self::SPACE_50GB,
1505            self::SPACE_100GB,
1506            self::SPACE_200GB,
1507            self::EXCLUDE_PLANS => array(
1508                self::WPCOM_HOSTING_TRIAL_PLANS,
1509            ),
1510        ),
1511        self::STAGING_SITES                     => array(
1512            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1513            self::EXCLUDE_PLANS => array(
1514                self::WPCOM_ECOMMERCE_TRIAL_PLANS,
1515            ),
1516            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
1517        ),
1518        // Gives near full access to all stats features. All features except new commercial level modules like UTM and device stats.
1519        self::STATS_FREE                        => array(
1520            self::JETPACK_STATS_PLANS,
1521            self::JETPACK_GROWTH_PLANS,
1522            // Provides legacy access for free and personal sites created before 2024-01-09.
1523            // Can be removed once we are ready to paywall all free and/or old personal sites.
1524            array(
1525                'before' => '2024-01-09',
1526                self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
1527                self::WPCOM_ALL_SITES,
1528            ),
1529        ),
1530        // Provides limited stats for free and personal sites created before 2024-12-06.
1531        // Features: Posts/Locations/Emails/File downloads
1532        // Can be removed once we are ready to paywall all free sites.
1533        self::STATS_BASIC_TEMP                  => array(
1534            array(
1535                'before' => '2024-12-12',
1536                self::WPCOM_ALL_SITES,
1537            ),
1538        ),
1539        // Provides personal sites and higher access to all stats features except commercial level modules.
1540        // Features: Posts/Locations/Emails/File downloads/Referrers/Clicks
1541        self::STATS_PAID                        => array(
1542            self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
1543            self::WP_P2_PLUS_MONTHLY,
1544            self::JETPACK_STATS_PWYW,
1545            self::JETPACK_STATS_MONTHLY,
1546            self::JETPACK_STATS_BI_YEARLY,
1547            self::JETPACK_STATS_YEARLY,
1548            self::JETPACK_COMPLETE_PLANS,
1549            self::JETPACK_PRO_PLANS,
1550            self::JETPACK_BUSINESS_PLANS,
1551            self::JETPACK_GROWTH_PLANS,
1552        ),
1553        // Provides premium sites and higher access to all stats features.
1554        // Features: STATS_PAID + UTM & Devices modules
1555        self::STATS_COMMERCIAL                  => array(
1556            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
1557            self::JETPACK_STATS_MONTHLY,
1558            self::JETPACK_STATS_BI_YEARLY,
1559            self::JETPACK_STATS_YEARLY,
1560            self::JETPACK_COMPLETE_PLANS,
1561            self::JETPACK_PRO_PLANS,
1562            self::JETPACK_BUSINESS_PLANS,
1563            self::JETPACK_GROWTH_PLANS,
1564            // A4A Jetpack Stats plans
1565            self::A4A_JETPACK_STATS_MONTHLY,
1566            self::A4A_JETPACK_STATS_YEARLY,
1567        ),
1568        self::STUDIO_SYNC                       => array(
1569            self::WPCOM_PRO_PLANS,
1570            self::WPCOM_PERSONAL_AND_PREMIUM_PLANS,
1571            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1572            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
1573        ),
1574
1575        // Importing subscribers to the site without limits.
1576        self::SUBSCRIBER_UNLIMITED_IMPORTS      => array(
1577            self::WP_P2_PLUS_MONTHLY,
1578            self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
1579            self::JETPACK_PERSONAL_AND_HIGHER,
1580            self::JETPACK_SOCIAL_PLANS,
1581            self::JETPACK_SOCIAL_ADVANCED_PLANS,
1582            self::JETPACK_SOCIAL_V1_PLANS,
1583            self::JETPACK_CREATOR_PLANS,
1584            self::JETPACK_GROWTH_PLANS,
1585            self::EXCLUDE_PLANS => array(
1586                self::WPCOM_MIGRATION_TRIAL_PLANS,
1587                self::WPCOM_HOSTING_TRIAL_PLANS,
1588            ),
1589            // A4A Jetpack Stats plans
1590            self::A4A_JETPACK_STATS_MONTHLY,
1591            self::A4A_JETPACK_STATS_YEARLY,
1592        ),
1593
1594        self::SUBSCRIPTION_GIFTING              => array(
1595            self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
1596            self::EXCLUDE_PLANS => array(
1597                self::WPCOM_MIGRATION_TRIAL_PLANS,
1598                self::WPCOM_HOSTING_TRIAL_PLANS,
1599                self::WPCOM_ECOMMERCE_TRIAL_PLANS,
1600            ),
1601        ),
1602
1603        // SUPPORT - Everybody needs somebody.
1604        self::SUPPORT                           => array(
1605            self::WPCOM_ALL_SITES,
1606            self::JETPACK_PERSONAL_AND_HIGHER,
1607            self::JETPACK_GOLDEN_TOKEN,
1608        ),
1609        self::TITAN_MAIL_1YEAR_TRIAL            => array(
1610            array(
1611                self::WPCOM_BUSINESS_PLANS,
1612                self::WPCOM_ECOMMERCE_PLANS,
1613            ),
1614            self::EXCLUDE_PLANS => array(
1615                self::BUSINESS_BUNDLE_MONTHLY,
1616                self::ECOMMERCE_BUNDLE_MONTHLY,
1617                self::A4A_WPCOM_BUSINESS_BUNDLE_MONTHLY,
1618                self::WPCOM_MIGRATION_TRIAL_PLANS,
1619                self::WPCOM_HOSTING_TRIAL_PLANS,
1620            ),
1621        ),
1622        self::UPGRADED_UPLOAD_FILETYPES         => array(
1623            self::SPACE_1GB,
1624            self::SPACE_3GB,
1625            self::SPACE_10GB,
1626            self::SPACE_25GB,
1627            self::SPACE_50GB,
1628            self::SPACE_100GB,
1629            self::SPACE_200GB,
1630            self::WPCOM_BLOGGER_AND_HIGHER_PLANS,
1631            self::WP_P2_PLUS_MONTHLY,
1632        ),
1633        self::UPLOAD_AUDIO_FILES                => array(
1634            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
1635            self::JETPACK_ALL_SITES,
1636        ),
1637        self::UPLOAD_PLUGINS                    => array(
1638            self::WPCOM_PRO_PLANS,
1639            self::EXCLUDE_PLANS => array(
1640                self::WPCOM_ECOMMERCE_TRIAL_PLANS,
1641            ),
1642            self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
1643            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
1644        ),
1645        self::UPLOAD_SPACE_1GB                  => array(
1646            self::SPACE_1GB,
1647        ),
1648        self::UPLOAD_SPACE_3GB                  => array(
1649            self::SPACE_3GB,
1650        ),
1651        self::UPLOAD_SPACE_10GB                 => array(
1652            self::SPACE_10GB,
1653        ),
1654        self::UPLOAD_SPACE_25GB                 => array(
1655            self::SPACE_25GB,
1656        ),
1657        self::UPLOAD_SPACE_50GB                 => array(
1658            self::SPACE_50GB,
1659        ),
1660        self::UPLOAD_SPACE_100GB                => array(
1661            self::SPACE_100GB,
1662        ),
1663        self::UPLOAD_SPACE_200GB                => array(
1664            self::SPACE_200GB,
1665            array(
1666                'before' => LEGACY_200GB_CUTOFF_DATE,
1667                self::WPCOM_BUSINESS_PLANS,
1668                self::WPCOM_ECOMMERCE_PLANS,
1669            ),
1670            array(
1671                'required_sticker' => 'legacy-200gb-storage',
1672                self::WPCOM_BUSINESS_PLANS,
1673                self::WPCOM_ECOMMERCE_PLANS,
1674            ),
1675        ),
1676        self::UPLOAD_SPACE_UNLIMITED            => array(
1677            array(
1678                'before' => '2019-08-01',
1679                self::WPCOM_BUSINESS_PLANS,
1680                self::WPCOM_ECOMMERCE_PLANS,
1681            ),
1682        ),
1683        self::UPLOAD_THEMES                     => array(
1684            self::WPCOM_PRO_PLANS,
1685            self::EXCLUDE_PLANS => array(
1686                self::WPCOM_ECOMMERCE_TRIAL_PLANS,
1687            ),
1688            self::WPCOM_PERSONAL_AND_HIGHER_PLANS,
1689            self::WPCOM_FLEX_CACHE_SITE_FREE_PLANS,
1690        ),
1691
1692        /*
1693         * UPLOAD_VIDEO_FILES - This feature is linked to the ability to upload video files to the website.
1694         *
1695         * Active for:
1696         * - Simple and Atomic sites with Premium or up plan.
1697         * - Jetpack sites with any plan.
1698         */
1699        self::UPLOAD_VIDEO_FILES                => array(
1700            self::WP_P2_PLUS_MONTHLY,
1701            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
1702            self::JETPACK_ALL_SITES,
1703        ),
1704
1705        self::VAULTPRESS_AUTOMATED_RESTORES     => array(
1706            self::JETPACK_PREMIUM_PLANS,
1707            self::JETPACK_BUSINESS_PLANS,
1708        ),
1709        self::VAULTPRESS_BACKUP_ARCHIVE         => array(
1710            self::JETPACK_PREMIUM_PLANS,
1711            self::JETPACK_BUSINESS_PLANS,
1712        ),
1713        self::VAULTPRESS_BACKUPS                => array(
1714            self::JETPACK_PERSONAL_AND_HIGHER,
1715        ),
1716        self::VAULTPRESS_SECURITY_SCANNING      => array(
1717            self::JETPACK_BUSINESS_PLANS,
1718        ),
1719        self::VAULTPRESS_STORAGE_SPACE          => array(
1720            self::JETPACK_PREMIUM_PLANS,
1721            self::JETPACK_BUSINESS_PLANS,
1722        ),
1723
1724        /*
1725         * VIDEO_HOSTING - Host video effortlessly and deliver it at high speeds to your viewers.
1726         * https://jetpack.com/features/design/video-hosting/
1727         *
1728         * Active for:
1729         * - Simple and Atomic sites with Premium or up plan.
1730         * - Jetpack sites with Premium or up plan.
1731         */
1732        self::VIDEO_HOSTING                     => array(
1733            array(
1734                'before_feature_gating_2026' => true,
1735                self::WPCOM_PREMIUM_PLANS,
1736            ),
1737            self::WPCOM_PRO_PLANS,
1738            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1739            self::JETPACK_PREMIUM_AND_HIGHER,
1740            self::EXCLUDE_PLANS => array(
1741                self::WPCOM_ECOMMERCE_TRIAL_PLANS,
1742            ),
1743        ),
1744        self::VIDEOPRESS                        => array(
1745            self::JETPACK_BUSINESS_PLANS,
1746            self::JETPACK_COMPLETE_PLANS,
1747            self::JETPACK_PRO_PLANS,
1748            self::JETPACK_PERSONAL_PLANS,
1749            self::JETPACK_PREMIUM_PLANS,
1750            self::JETPACK_VIDEOPRESS_PLANS,
1751            array(
1752                'before_feature_gating_2026' => true,
1753                self::WPCOM_PREMIUM_PLANS,
1754            ),
1755            // Provisioned VideoPress channels keep VideoPress on current Premium plans.
1756            array(
1757                'required_sticker' => 'videopress-channel',
1758                self::WPCOM_PREMIUM_PLANS,
1759            ),
1760            self::WPCOM_PRO_PLANS,
1761            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1762            self::WPCOM_VIDEOPRESS,
1763            self::WPCOM_VIDEOPRESS_PRO,
1764            self::WP_P2_PLUS_MONTHLY,
1765            array(
1766                'before' => '2021-10-07',
1767                self::JETPACK_SECURITY_DAILY_PLANS,
1768                self::JETPACK_SECURITY_REALTIME_PLANS,
1769                self::JETPACK_SECURITY_T0_PLANS,
1770                self::JETPACK_SECURITY_T1_PLANS,
1771                self::JETPACK_SECURITY_T2_PLANS,
1772            ),
1773        ),
1774
1775        /*
1776         * Note: VIDEOPRESS_1TB_STORAGE and VIDEOPRESS_UNLIMITED_STORAGE are
1777         * currently only checked on standalone Jetpack sites.
1778         * For example, adding VIDEOPRESS_UNLIMITED_STORAGE to a WP.com plan
1779         * will not provide it with unlimited VideoPress storage.
1780         *
1781         * All WoA VIDEOPRESS sites currently get 2TB storage on their cache
1782         * site for VideoPress.
1783         */
1784        self::VIDEOPRESS_1TB_STORAGE            => array(
1785            array(
1786                self::JETPACK_COMPLETE_PLANS,
1787                self::JETPACK_PRO_PLANS,
1788                self::JETPACK_VIDEOPRESS_PLANS,
1789                self::JETPACK_PREMIUM_PLANS,
1790                self::JETPACK_BUSINESS_PLANS,
1791            ),
1792        ),
1793        // VIDEOPRESS_VIDEO - videopress/video requires a paid plan.
1794        self::VIDEOPRESS_VIDEO                  => array(
1795            self::WP_P2_PLUS_MONTHLY,
1796            array(
1797                'before_feature_gating_2026' => true,
1798                self::WPCOM_PREMIUM_PLANS,
1799            ),
1800            self::WPCOM_PRO_PLANS,
1801            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1802            self::JETPACK_BUSINESS_PLANS,
1803            self::JETPACK_PREMIUM_PLANS,
1804            self::EXCLUDE_PLANS => array(
1805                self::WPCOM_ECOMMERCE_TRIAL_PLANS,
1806            ),
1807        ),
1808        self::VIDEOPRESS_UNLIMITED_STORAGE      => array(
1809            array(
1810                'before' => '2021-10-07',
1811                self::JETPACK_COMPLETE_PLANS,
1812                self::JETPACK_SECURITY_DAILY_PLANS,
1813                self::JETPACK_SECURITY_REALTIME_PLANS,
1814                self::JETPACK_SECURITY_T0_PLANS,
1815                self::JETPACK_SECURITY_T1_PLANS,
1816                self::JETPACK_SECURITY_T2_PLANS,
1817                self::JETPACK_PREMIUM_PLANS,
1818                self::JETPACK_BUSINESS_PLANS,
1819            ),
1820        ),
1821        self::WHATSAPP_BUTTON                   => array(
1822            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
1823            self::JETPACK_ALL_SITES,
1824        ),
1825
1826        /*
1827         * WOOP - WooCommerce on all Plans is available to install.
1828         *
1829         * Active for:
1830         * - Simple and Atomic sites with Business or up plan.
1831         * - Not Jetpack sites
1832         */
1833        self::WOOP                              => array(
1834            self::WPCOM_PRO_PLANS,
1835            self::WPCOM_BUSINESS_AND_HIGHER_PLANS,
1836        ),
1837        self::WORDADS                           => array(
1838            self::JETPACK_STARTER_PLANS,
1839            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
1840            self::JETPACK_PREMIUM_AND_HIGHER,
1841            self::JETPACK_CREATOR_PLANS,
1842            self::JETPACK_GROWTH_PLANS,
1843        ),
1844
1845        /*
1846         * WORDADS_JETPACK - `wordads-jetpack` is maintained as a legacy alias of `wordads` which was used to gate
1847         * the feature in old versions of Jetpack.
1848         * @see https://github.com/Automattic/jetpack/blob/c4f8fe120e1286e85f49e20e0f7fe22e44641449/projects/plugins/jetpack/class.jetpack-plan.php#L330.
1849         */
1850        self::WORDADS_JETPACK                   => array(
1851            self::WPCOM_PREMIUM_AND_HIGHER_PLANS,
1852            self::JETPACK_PREMIUM_AND_HIGHER,
1853        ),
1854    );
1855    /**
1856     * Some A8C owned sites have additional features enabled. e.g. Jetpack SEO.
1857     * This is an array of blog IDs where these features are enabled.
1858     */
1859    public const A8C_SITES_WITH_ADDITIONAL_SEO_FEATURES = array(
1860        1, // https://wordpress.com/
1861        69197545, // br.support.wordpress.com
1862        69197545, // br.support.wordpress.com
1863        12084301, // he.support.wordpress.com
1864        12358344, // pt.support.wordpress.com
1865        20614491, // de.support.wordpress.com
1866        110643074, // es.support.wordpress.com
1867        9619154, // en.support.wordpress.com
1868        9620355, // fr.support.wordpress.com
1869        22718864, // ru.support.wordpress.com
1870        26068228, // ja.support.wordpress.com
1871        151395884, // ko.support.wordpress.com
1872        151398260, // sv.support.wordpress.com
1873        151398564, // ar.support.wordpress.com
1874        150300509, // it.support.wordpress.com
1875        150381433, // nl.support.wordpress.com
1876        150645278, // id.support.wordpress.com
1877        150881074, // tr.support.wordpress.com
1878        151397720, // zh-cn.support.wordpress.com
1879        151397956, // zh-tw.support.wordpress.com
1880        3584907, // en.blog.wordpress.com
1881        7944537, // ja.blog.wordpress.com
1882        11241806, // es.blog.wordpress.com
1883        8181651, // pt.blog.wordpress.com
1884        8994420, // fr.blog.wordpress.com
1885        66243751, // br.blog.wordpress.com
1886        196931530, // enwpgo.wordpress.com
1887        173323553, // eswpgo.wordpress.com
1888        173331416, // dewpgo.wordpress.com
1889        162814143, // frwpgo.wordpress.com
1890        173328699, // itwpgo.wordpress.com
1891        163161552, // brwpgo.wordpress.com
1892        53424024, // discover.wordpress.com
1893        489937, // dailypost.wordpress.com
1894        33534099,  // developer.wordpress.com
1895        233643880, // eswpcomdeveloper.wordpress.com
1896        244311505, // jawpcomdeveloper.wordpress.com
1897        244447807, // frwpcomdeveloper.wordpress.com
1898        244448116, // dewpcomdeveloper.wordpress.com
1899        244448279, // ptbrwpcomdeveloper.wordpress.com
1900        244517526, // idwpcomdeveloper.wordpress.com
1901        244516213, // itwpcomdeveloper.wordpress.com
1902        244518337, // nlwpcomdeveloper.wordpress.com
1903        22994, // theme.wordpress.com
1904        16390, // learn.wordpress.com
1905        54117, // automattic.wordpress.com
1906    );
1907
1908    /**
1909     * Checks whether the given feature is declared in our map.
1910     *
1911     * @param string $feature The feature to check.
1912     *
1913     * @return bool Whether the given feature exists.
1914     */
1915    public static function feature_exists( $feature ) {
1916        return ! empty( self::FEATURES_MAP[ $feature ] );
1917    }
1918
1919    /**
1920     * Given a primitive type $needle, and an array $haystack, recursively
1921     * search $haystack for an instance of $needle. If arrays are encountered,
1922     * they will also be searched. Only strict comparisons are used.
1923     *
1924     * @param mixed $needle   What to look for.
1925     * @param array $haystack Array of items to check, may contain other arrays.
1926     *
1927     * @return bool Is the needle in the haystack somewhere?
1928     */
1929    public static function in_array_recursive( $needle, $haystack ) {
1930        foreach ( $haystack as $item ) {
1931            if ( is_array( $item ) ) {
1932                if ( self::in_array_recursive( $needle, $item ) ) {
1933                    return true;
1934                }
1935            } elseif ( $item === $needle ) {
1936                return true;
1937            }
1938        }
1939        return false;
1940    }
1941
1942    /**
1943     * Given an array of $purchases and a single feature name, consult the FEATURES_MAP to determine if the feature
1944     * is included in one of the $purchases.
1945     *
1946     * Use the function wpcom_site_has_feature( $feature ) to determine if a site has access to a certain feature.
1947     *
1948     * @param string    $feature       A singular feature.
1949     * @param array     $purchases     A collection of purchases.
1950     * @param string    $site_type     Site type to check. Can be 'wpcom' or 'jetpack'. Default empty string.
1951     * @param int|null  $blog_id       The blog ID to check. Default null.
1952     * @param bool|null $assume_legacy Cohort to assume instead of the site's own; null reads it from the site.
1953     *
1954     * @return bool Is the feature included in one of the purchases.
1955     */
1956    public static function has_feature( $feature, $purchases, $site_type = '', $blog_id = null, $assume_legacy = null ) {
1957        if ( ! self::feature_exists( $feature ) ) {
1958            return false;
1959        }
1960
1961        $products_map = self::FEATURES_MAP[ $feature ];
1962
1963        // Automatically grant features that don't require any purchase.
1964        if (
1965            ( 'wpcom' === $site_type && in_array( self::WPCOM_ALL_SITES, $products_map, true ) ) ||
1966            ( 'jetpack' === $site_type && in_array( self::JETPACK_ALL_SITES, $products_map, true ) )
1967        ) {
1968            return true;
1969        }
1970
1971        foreach ( $purchases as $purchase ) {
1972            if ( self::purchase_in_products_map( $purchase, $products_map, $blog_id, $assume_legacy ) ) {
1973                return true;
1974            }
1975        }
1976        return false;
1977    }
1978
1979    /**
1980     * Treat free plan as a purchase so the logic for purchase_in_products_map are applied when checking for legacy features.
1981     * As the free plan isn't actually a purchase, there is no subscribed_date, so we use the blog_registered_date instead.
1982     *
1983     * @param array  $purchases Reference to an array of purchases, this function adds a free plan to the end of the array passed in.
1984     * @param string $site_type Site type to check. Can be 'wpcom' or 'jetpack'.
1985     * @param string $blog_registered_date The date the blog was registered.
1986     */
1987    public static function add_free_plan_purchase( &$purchases, $site_type, $blog_registered_date ) {
1988        $free_purchase_object                  = new stdClass();
1989        $free_purchase_object->product_slug    = "{$site_type}-all-sites";
1990        $free_purchase_object->subscribed_date = $blog_registered_date;
1991
1992        $purchases[] = $free_purchase_object;
1993    }
1994
1995    /**
1996     * Resolve the WordPress.com blog ID to check stickers and the gating cutoff against.
1997     *
1998     * @param int|null $blog_id Blog ID, or null to resolve from the environment.
1999     *
2000     * @return int
2001     */
2002    private static function resolve_blog_id( $blog_id = null ) {
2003        if ( null !== $blog_id ) {
2004            return (int) $blog_id;
2005        }
2006
2007        if ( function_exists( '_wpcom_get_current_blog_id' ) ) {
2008            return (int) _wpcom_get_current_blog_id();
2009        }
2010
2011        return (int) get_current_blog_id();
2012    }
2013
2014    /**
2015     * Whether a site carries a blog sticker, on Simple or in WPCOMSH.
2016     *
2017     * `$blog_id` is ignored on WoW, WPCOMSH reads Atomic Persistent Data, there is no way to read
2018     * another site's from there. A caller that needs a specific site's stickers has to establish
2019     * that it is the current site first, e.g `is_legacy_gating_site()`.
2020     *
2021     * @param string   $sticker Sticker slug.
2022     * @param int|null $blog_id Blog ID, or null to resolve from the environment. Ignored on Atomic.
2023     *
2024     * @return bool
2025     */
2026    private static function site_has_sticker( $sticker, $blog_id = null ) {
2027        if ( defined( 'IS_ATOMIC' ) && IS_ATOMIC && function_exists( 'wpcomsh_is_site_sticker_active' ) ) {
2028            return (bool) wpcomsh_is_site_sticker_active( $sticker );
2029        }
2030
2031        if ( function_exists( 'has_blog_sticker' ) ) {
2032            return (bool) has_blog_sticker( $sticker, self::resolve_blog_id( $blog_id ) );
2033        }
2034
2035        return false;
2036    }
2037
2038    /**
2039     * Whether a site is still on the pre-2026 feature gating.
2040     *
2041     * 1. A legacy site that switches to new features is never legacy again.
2042     * 2. `pre-feature-gating-2026` wins over `gating-business-q1`, because a staging site cloned
2043     *    from a legacy production site could have both: the creation hook stickers every new blog,
2044     *    and the staging hook then marks it as mirroring a legacy site.
2045     * 3. `gating-business-q1` covers the ~2.0M sites below the cutoff that are already on the new
2046     *    gating -- the Jan-Jun experiment cohort plus everything `POST /sites/new` stickered
2047     *    between June and August 2026. "No sticker" is not the same as "old site".
2048     * 4. Otherwise the blog ID decides.
2049     *
2050     * @param int $blog_id Blog ID. Required: pass the site being asked about, never a guess.
2051     *
2052     * @return bool
2053     */
2054    public static function is_legacy_gating_site( $blog_id ) {
2055        $blog_id = (int) $blog_id;
2056
2057        // On WoW the sticker checks read the current site's persistent data.
2058        if ( defined( 'IS_ATOMIC' ) && IS_ATOMIC && $blog_id !== self::resolve_blog_id() ) {
2059            if ( function_exists( '_doing_it_wrong' ) ) {
2060                _doing_it_wrong(
2061                    __METHOD__,
2062                    'Atomic sites cannot resolve stickers for a site other than the current one.',
2063                    '' // No version.
2064                );
2065            }
2066
2067            return true;
2068        }
2069
2070        if ( self::site_has_sticker( self::STICKER_FEATURE_GATING_2026, $blog_id ) ) {
2071            return false;
2072        }
2073
2074        if ( self::site_has_sticker( self::STICKER_PRE_FEATURE_GATING_2026, $blog_id ) ) {
2075            return true;
2076        }
2077
2078        if ( self::site_has_sticker( self::STICKER_GATING_BUSINESS_Q1, $blog_id ) ) {
2079            return false;
2080        }
2081
2082        return $blog_id < self::FEATURE_GATING_2026_CUTOFF_BLOG_ID;
2083    }
2084
2085    /**
2086     * Every blog sticker the products map gates on, in a stable order.
2087     *
2088     * @return string[]
2089     */
2090    private static function get_map_sticker_slugs() {
2091        static $slugs = null;
2092
2093        if ( null !== $slugs ) {
2094            return $slugs;
2095        }
2096
2097        $found = array();
2098        $walk  = static function ( $node ) use ( &$walk, &$found ) {
2099            foreach ( $node as $key => $value ) {
2100                if ( 'required_sticker' === $key || 'sticker_not_present' === $key ) {
2101                    foreach ( (array) $value as $slug ) {
2102                        $found[ $slug ] = true;
2103                    }
2104                } elseif ( is_array( $value ) ) {
2105                    $walk( $value );
2106                }
2107            }
2108        };
2109        $walk( self::FEATURES_MAP );
2110
2111        $slugs = array_keys( $found );
2112        sort( $slugs );
2113
2114        return $slugs;
2115    }
2116
2117    /**
2118     * Features whose grant depends on which side of the 2026 flip a site is on.
2119     *
2120     * These are the only features a plan change can take away from a site still on the pre-2026
2121     * gating, so a caller comparing before and after only has to evaluate these. Derived from the map
2122     * so a new `before_feature_gating_2026` branch is covered without an edit here.
2123     *
2124     * @return string[]
2125     */
2126    public static function get_cohort_sensitive_features() {
2127        static $features = null;
2128
2129        if ( null !== $features ) {
2130            return $features;
2131        }
2132
2133        $features = array();
2134
2135        foreach ( self::FEATURES_MAP as $feature => $products_map ) {
2136            foreach ( $products_map as $branch ) {
2137                if ( is_array( $branch ) && isset( $branch['before_feature_gating_2026'] ) ) {
2138                    $features[] = $feature;
2139                    continue 2;
2140                }
2141            }
2142        }
2143
2144        return $features;
2145    }
2146
2147    /**
2148     * A cache-key fragment covering every per-site input the products map consults.
2149     *
2150     * Feature resolution for a given product is not the same for every site, so anything caching it
2151     * outside a per-site key has to vary on this. The inputs are: before_feature_gating_2026 and
2152     * required_sticker / sticker_not_present.
2153     *
2154     * @param int $blog_id Blog ID to describe.
2155     *
2156     * @return string
2157     */
2158    public static function get_site_gating_cache_suffix( $blog_id ) {
2159        $suffix = self::is_legacy_gating_site( $blog_id ) ? '_pre_gating_2026' : '_gating_2026';
2160
2161        foreach ( self::get_map_sticker_slugs() as $slug ) {
2162            if ( self::site_has_sticker( $slug, $blog_id ) ) {
2163                $suffix .= '_' . $slug;
2164            }
2165        }
2166
2167        return $suffix;
2168    }
2169
2170    /**
2171     * The products definition array ($products_map) may contain 1st-level sub-arrays with 'before' and/or 'after' keys
2172     * used to restrict access to a feature based on when the purchase was made. If the $purchase is included in
2173     * $products_map, and it was purchased within the defined date range (if a date range is defined), return true.
2174     *
2175     * Additionally, the 1st level of the array may contain the key 'excluded_plans' which is an array of plans that
2176     * should be excluded from the feature. This is useful for when there are very specific exceptions that would
2177     * otherwise require a lot of configuration to be added. If a plan is excluded, no further checks will be done.
2178     *
2179     * @param object    $purchase A single purchase.
2180     * @param array     $products_map A feature map definition array.
2181     * @param int|null  $blog_id The blog ID to check. Default null.
2182     * @param bool|null $assume_legacy Cohort to assume instead of the site's own; null reads it from the site.
2183     *
2184     * @return bool If the purchase is included in $products_map and meets any purchase date-range rules.
2185     */
2186    public static function purchase_in_products_map( $purchase, $products_map, $blog_id = null, $assume_legacy = null ) {
2187
2188        // First check if the current purchase is excluded in the product definition.
2189        if ( isset( $products_map[ self::EXCLUDE_PLANS ] ) ) {
2190            $excluded_plans = $products_map[ self::EXCLUDE_PLANS ] ?? array();
2191            if ( ! empty( $excluded_plans ) && self::in_array_recursive( $purchase->product_slug, array( $excluded_plans ) ) ) {
2192                return false;
2193            }
2194            unset( $products_map[ self::EXCLUDE_PLANS ] );
2195        }
2196
2197        // Loop through the first level of the $products_map array to identify potential legacy feature date ranges.
2198        foreach ( $products_map as $product_definition ) {
2199
2200            if ( ! empty( $product_definition['product_type'] ) ) {
2201                if ( ! empty( $purchase->product_type ) && in_array( $purchase->product_type, $product_definition['product_type'], true ) ) {
2202                    return true;
2203                }
2204                continue;
2205            }
2206
2207            $purchase_eligible_by_date    = false;
2208            $purchase_eligible_by_sticker = false;
2209
2210            // Check if sticker requirement exists.
2211            $required_sticker = $product_definition['required_sticker'] ?? null;
2212            if ( $required_sticker ) {
2213                $purchase_eligible_by_sticker = self::site_has_sticker( $required_sticker, $blog_id );
2214                // Remove the sticker key so $product_definition is clean for in_array_recursive search.
2215                unset( $product_definition['required_sticker'] );
2216            } else {
2217                $purchase_eligible_by_sticker = true; // No sticker requirement, so eligible by default.
2218            }
2219
2220            // Check if sticker_not_present requirement exists (feature only available when sticker is NOT present).
2221            $sticker_not_present = $product_definition['sticker_not_present'] ?? null;
2222            if ( $sticker_not_present ) {
2223                $has_sticker = self::site_has_sticker( $sticker_not_present, $blog_id );
2224                // Only eligible if the sticker is NOT present.
2225                $purchase_eligible_by_sticker = $purchase_eligible_by_sticker && ! $has_sticker;
2226                // Remove the sticker key so $product_definition is clean for in_array_recursive search.
2227                unset( $product_definition['sticker_not_present'] );
2228            }
2229
2230            // Check if the site has legacy/current features, previously use gating-business-q1 sticker
2231            if ( isset( $product_definition['before_feature_gating_2026'] ) ) {
2232                $purchase_eligible_by_sticker = $purchase_eligible_by_sticker
2233                    && (bool) $product_definition['before_feature_gating_2026'] === (
2234                        null === $assume_legacy
2235                            ? self::is_legacy_gating_site( self::resolve_blog_id( $blog_id ) )
2236                            : (bool) $assume_legacy
2237                    );
2238                // Remove the key so $product_definition is clean for in_array_recursive search.
2239                unset( $product_definition['before_feature_gating_2026'] );
2240            }
2241
2242            // If 'before' & 'after' are empty, this is not a legacy feature.
2243            if ( empty( $product_definition['before'] ) && empty( $product_definition['after'] ) ) {
2244                $purchase_eligible_by_date = true;
2245            } else {
2246                // If the date key is defined, set its variable to its Unix timestamp, else set invalid or undefined dates to false.
2247                $before          = isset( $product_definition['before'] ) ? strtotime( $product_definition['before'] ) : false;
2248                $after           = isset( $product_definition['after'] ) ? strtotime( $product_definition['after'] ) : false;
2249                $subscribed_date = isset( $purchase->subscribed_date ) ? strtotime( $purchase->subscribed_date ) : false;
2250
2251                // Remove the date keys so $product_definition is clean for in_array_recursive search.
2252                unset( $product_definition['before'], $product_definition['after'] );
2253
2254                // If 'before' or 'after', & the subscribed_date are valid, check if the legacy feature is available.
2255                if ( ( false !== $before || false !== $after ) && false !== $subscribed_date ) {
2256                    if ( false !== $before && false !== $after ) {
2257                        if (
2258                            $subscribed_date >= $after &&
2259                            $subscribed_date <= $before ) {
2260                            $purchase_eligible_by_date = true;
2261                        }
2262                    } elseif ( false !== $before ) {
2263                        if ( $subscribed_date <= $before ) {
2264                            $purchase_eligible_by_date = true;
2265                        }
2266                    } elseif ( false !== $after ) {
2267                        if ( $subscribed_date >= $after ) {
2268                            $purchase_eligible_by_date = true;
2269                        }
2270                    }
2271                }
2272            }
2273
2274            // If the date range and sticker requirements are cleared, check if the purchase is included in the $product_definition.
2275            if ( $purchase_eligible_by_date && $purchase_eligible_by_sticker ) {
2276                if ( self::in_array_recursive( $purchase->product_slug ?? null, array( $product_definition ) ) ) {
2277                    return true;
2278                }
2279            }
2280        }
2281
2282        return false;
2283    }
2284
2285    /**
2286     * Return a list of all possible feature slugs.
2287     *
2288     * @return array An array of strings like 'premium-themes', one for each possible feature slug.
2289     */
2290    public static function get_feature_slugs() {
2291        return array_keys( self::FEATURES_MAP );
2292    }
2293}