PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 9.8.1
Jetpack – WP Security, Backup, Speed, & Growth v9.8.1
15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / class.jetpack-plan.php
jetpack Last commit date
3rd-party 5 years ago _inc 4 years ago css 4 years ago extensions 4 years ago images 5 years ago json-endpoints 4 years ago modules 4 years ago sal 5 years ago src 5 years ago vendor 4 years ago views 5 years ago CHANGELOG.md 4 years ago LICENSE.txt 5 years ago SECURITY.md 5 years ago class-jetpack-connection-status.php 5 years ago class-jetpack-pre-connection-jitms.php 5 years ago class-jetpack-recommendations-banner.php 5 years ago class-jetpack-wizard-banner.php 5 years ago class-jetpack-xmlrpc-methods.php 5 years ago class.frame-nonce-preview.php 6 years ago class.jetpack-admin.php 5 years ago class.jetpack-affiliate.php 6 years ago class.jetpack-autoupdate.php 5 years ago class.jetpack-bbpress-json-api.compat.php 5 years ago class.jetpack-cli.php 5 years ago class.jetpack-client-server.php 5 years ago class.jetpack-connection-banner.php 5 years ago class.jetpack-data.php 5 years ago class.jetpack-gutenberg.php 5 years ago class.jetpack-heartbeat.php 5 years ago class.jetpack-idc.php 6 years ago class.jetpack-ixr-client.php 5 years ago class.jetpack-modules-list-table.php 5 years ago class.jetpack-network-sites-list-table.php 5 years ago class.jetpack-network.php 5 years ago class.jetpack-plan.php 5 years ago class.jetpack-post-images.php 5 years ago class.jetpack-twitter-cards.php 5 years ago class.jetpack-user-agent.php 5 years ago class.jetpack.php 5 years ago class.json-api-endpoints.php 5 years ago class.json-api.php 5 years ago class.photon.php 5 years ago composer.json 4 years ago functions.compat.php 5 years ago functions.cookies.php 5 years ago functions.gallery.php 6 years ago functions.global.php 5 years ago functions.opengraph.php 5 years ago functions.photon.php 5 years ago jest.config.js 5 years ago jetpack.php 4 years ago json-api-config.php 5 years ago json-endpoints.php 7 years ago load-jetpack.php 5 years ago locales.php 7 years ago readme.txt 4 years ago require-lib.php 5 years ago uninstall.php 5 years ago wpml-config.xml 10 years ago
class.jetpack-plan.php
347 lines
1 <?php //phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2 /**
3 * Handles fetching of the site's plan and products from WordPress.com and caching values locally.
4 *
5 * Not to be confused with the `Jetpack_Plans` class (in `_inc/lib/plans.php`), which
6 * fetches general information about all available plans from WordPress.com, side-effect free.
7 *
8 * @package automattic/jetpack
9 */
10
11 use Automattic\Jetpack\Connection\Client;
12
13 /**
14 * Provides methods methods for fetching the site's plan and products from WordPress.com.
15 */
16 class Jetpack_Plan {
17 /**
18 * A cache variable to hold the active plan for the current request.
19 *
20 * @var array
21 */
22 private static $active_plan_cache;
23
24 /**
25 * The name of the option that will store the site's plan.
26 *
27 * @var string
28 */
29 const PLAN_OPTION = 'jetpack_active_plan';
30
31 /**
32 * The name of the option that will store the site's products.
33 *
34 * @var string
35 */
36 const SITE_PRODUCTS_OPTION = 'jetpack_site_products';
37
38 const PLAN_DATA = array(
39 'free' => array(
40 'plans' => array(
41 'jetpack_free',
42 ),
43 'supports' => array(
44 'opentable',
45 'calendly',
46 'send-a-message',
47 'whatsapp-button',
48 'social-previews',
49
50 'core/video',
51 'core/cover',
52 'core/audio',
53 ),
54 ),
55 'personal' => array(
56 'plans' => array(
57 'jetpack_personal',
58 'jetpack_personal_monthly',
59 'personal-bundle',
60 'personal-bundle-monthly',
61 'personal-bundle-2y',
62 ),
63 'supports' => array(
64 'akismet',
65 'recurring-payments',
66 'premium-content/container',
67 ),
68 ),
69 'premium' => array(
70 'plans' => array(
71 'jetpack_premium',
72 'jetpack_premium_monthly',
73 'value_bundle',
74 'value_bundle-monthly',
75 'value_bundle-2y',
76 ),
77 'supports' => array(
78 'donations',
79 'simple-payments',
80 'vaultpress',
81 'videopress',
82 ),
83 ),
84 'security' => array(
85 'plans' => array(
86 'jetpack_security_daily',
87 'jetpack_security_daily_monthly',
88 'jetpack_security_realtime',
89 'jetpack_security_realtime_monthly',
90 ),
91 'supports' => array(),
92 ),
93 'business' => array(
94 'plans' => array(
95 'jetpack_business',
96 'jetpack_business_monthly',
97 'business-bundle',
98 'business-bundle-monthly',
99 'business-bundle-2y',
100 'ecommerce-bundle',
101 'ecommerce-bundle-monthly',
102 'ecommerce-bundle-2y',
103 'vip',
104 ),
105 'supports' => array(),
106 ),
107
108 'complete' => array(
109 'plans' => array(
110 'jetpack_complete',
111 'jetpack_complete_monthly',
112 ),
113 'supports' => array(),
114 ),
115 );
116
117 /**
118 * Given a response to the `/sites/%d` endpoint, will parse the response and attempt to set the
119 * site's plan and products from the response.
120 *
121 * @param array $response The response from `/sites/%d`.
122 * @return bool Was the plan successfully updated?
123 */
124 public static function update_from_sites_response( $response ) {
125 // Bail if there was an error or malformed response.
126 if ( is_wp_error( $response ) || ! is_array( $response ) || ! isset( $response['body'] ) ) {
127 return false;
128 }
129
130 $body = wp_remote_retrieve_body( $response );
131 if ( is_wp_error( $body ) ) {
132 return false;
133 }
134
135 // Decode the results.
136 $results = json_decode( $body, true );
137
138 if ( ! is_array( $results ) ) {
139 return false;
140 }
141
142 if ( isset( $results['products'] ) ) {
143 // Store the site's products in an option and return true if updated.
144 self::store_data_in_option( self::SITE_PRODUCTS_OPTION, $results['products'] );
145 }
146
147 if ( ! isset( $results['plan'] ) ) {
148 return false;
149 }
150
151 $current_plan = get_option( self::PLAN_OPTION, array() );
152
153 if ( ! empty( $current_plan ) && $current_plan === $results['plan'] ) {
154 // Bail if the plans array hasn't changed.
155 return false;
156 }
157
158 // Store the new plan in an option and return true if updated.
159 $result = self::store_data_in_option( self::PLAN_OPTION, $results['plan'] );
160
161 if ( $result ) {
162 // Reset the cache since we've just updated the plan.
163 self::$active_plan_cache = null;
164 }
165
166 return $result;
167 }
168
169 /**
170 * Store data in an option.
171 *
172 * @param string $option The name of the option that will store the data.
173 * @param array $data Data to be store in an option.
174 * @return bool Were the subscriptions successfully updated?
175 */
176 private static function store_data_in_option( $option, $data ) {
177 $result = update_option( $option, $data, true );
178
179 // If something goes wrong with the update, so delete the current option and then update it.
180 if ( ! $result ) {
181 delete_option( $option );
182 $result = update_option( $option, $data, true );
183 }
184
185 return $result;
186 }
187
188 /**
189 * Make an API call to WordPress.com for plan status
190 *
191 * @uses Jetpack_Options::get_option()
192 * @uses Client::wpcom_json_api_request_as_blog()
193 * @uses update_option()
194 *
195 * @access public
196 * @static
197 *
198 * @return bool True if plan is updated, false if no update
199 */
200 public static function refresh_from_wpcom() {
201 // Make the API request.
202 $request = sprintf( '/sites/%d', Jetpack_Options::get_option( 'id' ) );
203 $response = Client::wpcom_json_api_request_as_blog( $request, '1.1' );
204
205 return self::update_from_sites_response( $response );
206 }
207
208 /**
209 * Get the plan that this Jetpack site is currently using.
210 *
211 * @uses get_option()
212 *
213 * @access public
214 * @static
215 *
216 * @return array Active Jetpack plan details
217 */
218 public static function get() {
219 // this can be expensive to compute so we cache for the duration of a request.
220 if ( is_array( self::$active_plan_cache ) && ! empty( self::$active_plan_cache ) ) {
221 return self::$active_plan_cache;
222 }
223
224 $plan = get_option( self::PLAN_OPTION, array() );
225
226 // Set the default options.
227 $plan = wp_parse_args(
228 $plan,
229 array(
230 'product_slug' => 'jetpack_free',
231 'class' => 'free',
232 'features' => array(
233 'active' => array(),
234 ),
235 )
236 );
237
238 list( $plan['class'], $supports ) = self::get_class_and_features( $plan['product_slug'] );
239
240 // get available features.
241 foreach ( Jetpack::get_available_modules() as $module_slug ) {
242 $module = Jetpack::get_module( $module_slug );
243 if ( ! isset( $module ) || ! is_array( $module ) ) {
244 continue;
245 }
246 if ( in_array( 'free', $module['plan_classes'], true ) || in_array( $plan['class'], $module['plan_classes'], true ) ) {
247 $supports[] = $module_slug;
248 }
249 }
250
251 $plan['supports'] = $supports;
252
253 self::$active_plan_cache = $plan;
254
255 return $plan;
256 }
257
258 /**
259 * Get the site's products.
260 *
261 * @uses get_option()
262 *
263 * @access public
264 * @static
265 *
266 * @return array Active Jetpack products
267 */
268 public static function get_products() {
269 return get_option( self::SITE_PRODUCTS_OPTION, array() );
270 }
271
272 /**
273 * Get the class of plan and a list of features it supports
274 *
275 * @param string $plan_slug The plan that we're interested in.
276 * @return array Two item array, the plan class and the an array of features.
277 */
278 private static function get_class_and_features( $plan_slug ) {
279 $features = array();
280 foreach ( self::PLAN_DATA as $class => $details ) {
281 $features = array_merge( $features, $details['supports'] );
282 if ( in_array( $plan_slug, $details['plans'], true ) ) {
283 return array( $class, $features );
284 }
285 }
286 return array( 'free', self::PLAN_DATA['free']['supports'] );
287 }
288
289 /**
290 * Gets the minimum plan slug that supports the given feature
291 *
292 * @param string $feature The name of the feature.
293 * @return string|bool The slug for the minimum plan that supports.
294 * the feature or false if not found
295 */
296 public static function get_minimum_plan_for_feature( $feature ) {
297 foreach ( self::PLAN_DATA as $details ) {
298 if ( in_array( $feature, $details['supports'], true ) ) {
299 return $details['plans'][0];
300 }
301 }
302 return false;
303 }
304
305 /**
306 * Determine whether the active plan supports a particular feature
307 *
308 * @uses Jetpack_Plan::get()
309 *
310 * @access public
311 * @static
312 *
313 * @param string $feature The module or feature to check.
314 *
315 * @return bool True if plan supports feature, false if not
316 */
317 public static function supports( $feature ) {
318 // Search product bypasses plan feature check.
319 if ( 'search' === $feature && (bool) get_option( 'has_jetpack_search_product' ) ) {
320 return true;
321 }
322
323 $plan = self::get();
324
325 // Manually mapping WordPress.com features to Jetpack module slugs.
326 foreach ( $plan['features']['active'] as $wpcom_feature ) {
327 switch ( $wpcom_feature ) {
328 case 'wordads-jetpack':
329 // WordAds are supported for this site.
330 if ( 'wordads' === $feature ) {
331 return true;
332 }
333 break;
334 }
335 }
336
337 if (
338 in_array( $feature, $plan['supports'], true )
339 || in_array( $feature, $plan['features']['active'], true )
340 ) {
341 return true;
342 }
343
344 return false;
345 }
346 }
347