PluginProbe
Tiered Pricing Table for WooCommerce / 8.0.2
Tiered Pricing Table for WooCommerce v8.0.2
8.0.2 7.1.7 7.1.5 7.1.4 7.1.1 6.5.0 6.4.0 6.1.0 trunk 1.0 1.1 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.2.0 2.2.1 2.2.2 2.2.3 2.3.0 2.3.1 2.3.2 2.3.3 All 91 releases
← All changes | freemius/includes/class-fs-storage.php +108 -72 2.2.2 → 8.0.2 View file →
@@ -14,11 +14,14 @@
14 14 * Class FS_Storage
15 15 *
16 16 * A wrapper class for handling network level and single site level storage.
17 17 *
18 - * @property bool $is_network_activation
19 - * @property int $network_install_blog_id
20 - * @property object $sync_cron
18 + * @property bool $is_network_activation
19 + * @property int $network_install_blog_id
20 + * @property bool|null $is_extensions_tracking_allowed
21 + * @property bool|null $is_diagnostic_tracking_allowed
22 + * @property object $sync_cron
23 + * @property bool|int $install_timestamp
21 24 */
22 25 class FS_Storage {
23 26 /**
24 27 * @var FS_Storage[]
@@ -71,8 +74,18 @@
71 74 * }
72 75 */
73 76 private static $_NETWORK_OPTIONS_MAP;
74 77
78 + const OPTION_LEVEL_UNDEFINED = -1;
79 + // The option should be stored on the network level.
80 + const OPTION_LEVEL_NETWORK = 0;
81 + // The option should be stored on the network level when the plugin is network-activated.
82 + const OPTION_LEVEL_NETWORK_ACTIVATED = 1;
83 + // The option should be stored on the network level when the plugin is network-activated and the opt-in connection was NOT delegated to the sub-site admin.
84 + const OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED = 2;
85 + // The option should be stored on the site level.
86 + const OPTION_LEVEL_SITE = 3;
87 +
75 88 /**
76 89 * @author Leo Fajardo (@leorw)
77 90 *
78 91 * @param string $module_type
@@ -141,12 +154,19 @@
141 154 *
142 155 * @param string $key
143 156 * @param mixed $value
144 157 * @param null|bool|int $network_level_or_blog_id When an integer, use the given blog storage. When `true` use the multisite storage (if there's a network). When `false`, use the current context blog storage. When `null`, the decision which storage to use (MS vs. Current S) will be handled internally and determined based on the $option (based on self::$_BINARY_MAP).
158 + * @param int $option_level Since 2.5.1
145 159 * @param bool $flush
146 160 */
147 - function store( $key, $value, $network_level_or_blog_id = null, $flush = true ) {
148 - if ( $this->should_use_network_storage( $key, $network_level_or_blog_id ) ) {
161 + function store(
162 + $key,
163 + $value,
164 + $network_level_or_blog_id = null,
165 + $option_level = self::OPTION_LEVEL_UNDEFINED,
166 + $flush = true
167 + ) {
168 + if ( $this->should_use_network_storage( $key, $network_level_or_blog_id, $option_level ) ) {
149 169 $this->_network_storage->store( $key, $value, $flush );
150 170 } else {
151 171 $storage = $this->get_site_storage( $network_level_or_blog_id );
152 172 $storage->store( $key, $value, $flush );
@@ -198,13 +218,19 @@
198 218 *
199 219 * @param string $key
200 220 * @param mixed $default
201 221 * @param null|bool|int $network_level_or_blog_id When an integer, use the given blog storage. When `true` use the multisite storage (if there's a network). When `false`, use the current context blog storage. When `null`, the decision which storage to use (MS vs. Current S) will be handled internally and determined based on the $option (based on self::$_BINARY_MAP).
222 + * @param int $option_level Since 2.5.1
202 223 *
203 224 * @return mixed
204 225 */
205 - function get( $key, $default = false, $network_level_or_blog_id = null ) {
206 - if ( $this->should_use_network_storage( $key, $network_level_or_blog_id ) ) {
226 + function get(
227 + $key,
228 + $default = false,
229 + $network_level_or_blog_id = null,
230 + $option_level = self::OPTION_LEVEL_UNDEFINED
231 + ) {
232 + if ( $this->should_use_network_storage( $key, $network_level_or_blog_id, $option_level ) ) {
207 233 return $this->_network_storage->get( $key, $default );
208 234 } else {
209 235 $storage = $this->get_site_storage( $network_level_or_blog_id );
210 236
@@ -288,21 +314,8 @@
288 314 if ( isset( $this->_storage->{$option} ) && ! isset( $this->_network_storage->{$option} ) ) {
289 315 // Migrate option to the network storage.
290 316 $this->_network_storage->store( $option, $this->_storage->{$option}, false );
291 317
292 - /**
293 - * Remove the option from site level storage.
294 - *
295 - * IMPORTANT:
296 - * The line below is intentionally commented since we want to preserve the option
297 - * on the site storage level for "downgrade compatibility". Basically, if the user
298 - * will downgrade to an older version of the plugin with the prev storage structure,
299 - * it will continue working.
300 - *
301 - * @todo After a few releases we can remove this.
302 - */
303 -// $this->_storage->remove($option, false);
304 -
305 318 $updated = true;
306 319 }
307 320 }
308 321
@@ -335,57 +348,64 @@
335 348 */
336 349 private static function load_network_options_map() {
337 350 self::$_NETWORK_OPTIONS_MAP = array(
338 351 // Network level options.
339 - 'affiliate_application_data' => 0,
340 - 'connectivity_test' => 0,
341 - 'handle_gdpr_admin_notice' => 0,
342 - 'has_trial_plan' => 0,
343 - 'install_sync_timestamp' => 0,
344 - 'install_sync_cron' => 0,
345 - 'is_anonymous_ms' => 0,
346 - 'is_on' => 0,
347 - 'is_plugin_new_install' => 0,
348 - 'network_install_blog_id' => 0,
349 - 'pending_sites_info' => 0,
350 - 'plugin_last_version' => 0,
351 - 'plugin_main_file' => 0,
352 - 'plugin_version' => 0,
353 - 'sdk_downgrade_mode' => 0,
354 - 'sdk_last_version' => 0,
355 - 'sdk_upgrade_mode' => 0,
356 - 'sdk_version' => 0,
357 - 'sticky_optin_added_ms' => 0,
358 - 'subscriptions' => 0,
359 - 'sync_timestamp' => 0,
360 - 'sync_cron' => 0,
361 - 'was_plugin_loaded' => 0,
362 - 'network_user_id' => 0,
363 - 'plugin_upgrade_mode' => 0,
364 - 'plugin_downgrade_mode' => 0,
365 - 'is_network_connected' => 0,
352 + 'affiliate_application_data' => self::OPTION_LEVEL_NETWORK,
353 + 'beta_data' => self::OPTION_LEVEL_NETWORK,
354 + 'connectivity_test' => self::OPTION_LEVEL_NETWORK,
355 + 'handle_gdpr_admin_notice' => self::OPTION_LEVEL_NETWORK,
356 + 'has_trial_plan' => self::OPTION_LEVEL_NETWORK,
357 + 'install_sync_timestamp' => self::OPTION_LEVEL_NETWORK,
358 + 'install_sync_cron' => self::OPTION_LEVEL_NETWORK,
359 + 'is_anonymous_ms' => self::OPTION_LEVEL_NETWORK,
360 + 'is_network_activated' => self::OPTION_LEVEL_NETWORK,
361 + 'is_on' => self::OPTION_LEVEL_NETWORK,
362 + 'is_plugin_new_install' => self::OPTION_LEVEL_NETWORK,
363 + 'last_load_timestamp' => self::OPTION_LEVEL_NETWORK,
364 + 'network_install_blog_id' => self::OPTION_LEVEL_NETWORK,
365 + 'pending_sites_info' => self::OPTION_LEVEL_NETWORK,
366 + 'plugin_last_version' => self::OPTION_LEVEL_NETWORK,
367 + 'plugin_main_file' => self::OPTION_LEVEL_NETWORK,
368 + 'plugin_version' => self::OPTION_LEVEL_NETWORK,
369 + 'sdk_downgrade_mode' => self::OPTION_LEVEL_NETWORK,
370 + 'sdk_last_version' => self::OPTION_LEVEL_NETWORK,
371 + 'sdk_upgrade_mode' => self::OPTION_LEVEL_NETWORK,
372 + 'sdk_version' => self::OPTION_LEVEL_NETWORK,
373 + 'sticky_optin_added_ms' => self::OPTION_LEVEL_NETWORK,
374 + 'subscriptions' => self::OPTION_LEVEL_NETWORK,
375 + 'sync_timestamp' => self::OPTION_LEVEL_NETWORK,
376 + 'sync_cron' => self::OPTION_LEVEL_NETWORK,
377 + 'was_plugin_loaded' => self::OPTION_LEVEL_NETWORK,
378 + 'network_user_id' => self::OPTION_LEVEL_NETWORK,
379 + 'plugin_upgrade_mode' => self::OPTION_LEVEL_NETWORK,
380 + 'plugin_downgrade_mode' => self::OPTION_LEVEL_NETWORK,
381 + 'is_network_connected' => self::OPTION_LEVEL_NETWORK,
366 382 /**
367 - * Special flag that is used when a super-admin upgrades to the new version of the SDK that
368 - * supports network level integration, when the connection decision wasn't made for all of the
369 - * sites in the network.
383 + * Special flag that is used when a super-admin upgrades to the new version of the SDK that supports network level integration, when the connection decision wasn't made for all the sites in the network.
370 384 */
371 - 'is_network_activation' => 0,
385 + 'is_network_activation' => self::OPTION_LEVEL_NETWORK,
386 + 'license_migration' => self::OPTION_LEVEL_NETWORK,
372 387
373 388 // When network activated, then network level.
374 - 'install_timestamp' => 1,
375 - 'prev_is_premium' => 1,
376 - 'require_license_activation' => 1,
389 + 'install_timestamp' => self::OPTION_LEVEL_NETWORK_ACTIVATED,
390 + 'prev_is_premium' => self::OPTION_LEVEL_NETWORK_ACTIVATED,
391 + 'require_license_activation' => self::OPTION_LEVEL_NETWORK_ACTIVATED,
377 392
378 393 // If not network activated OR delegated, then site level.
379 - 'activation_timestamp' => 2,
380 - 'prev_user_id' => 2,
381 - 'sticky_optin_added' => 2,
382 - 'uninstall_reason' => 2,
383 - 'is_pending_activation' => 2,
384 - 'pending_license_key' => 2,
394 + 'activation_timestamp' => self::OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED,
395 + 'expired_license_notice_shown' => self::OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED,
396 + 'is_whitelabeled' => self::OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED,
397 + 'last_license_key' => self::OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED,
398 + 'last_license_user_id' => self::OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED,
399 + 'prev_user_id' => self::OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED,
400 + 'sticky_optin_added' => self::OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED,
401 + 'uninstall_reason' => self::OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED,
402 + 'is_pending_activation' => self::OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED,
403 + 'pending_license_key' => self::OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED,
385 404
386 405 // Site level options.
387 - 'is_anonymous' => 3,
406 + 'is_anonymous' => self::OPTION_LEVEL_SITE,
407 + 'clone_id' => self::OPTION_LEVEL_SITE,
388 408 );
389 409 }
390 410
391 411 /**
@@ -394,27 +414,35 @@
394 414 * @author Vova Feldman (@svovaf)
395 415 * @since 2.0.0
396 416 *
397 417 * @param string $key
418 + * @param int $option_level Since 2.5.1
398 419 *
399 - * @return bool|mixed
420 + * @return bool
400 421 */
401 - private function is_multisite_option( $key ) {
422 + private function is_multisite_option( $key, $option_level = self::OPTION_LEVEL_UNDEFINED ) {
402 423 if ( ! isset( self::$_NETWORK_OPTIONS_MAP ) ) {
403 424 self::load_network_options_map();
404 425 }
405 426
406 - if ( ! isset( self::$_NETWORK_OPTIONS_MAP[ $key ] ) ) {
427 + if (
428 + self::OPTION_LEVEL_UNDEFINED === $option_level &&
429 + isset( self::$_NETWORK_OPTIONS_MAP[ $key ] )
430 + ) {
431 + $option_level = self::$_NETWORK_OPTIONS_MAP[ $key ];
432 + }
433 +
434 + if ( self::OPTION_LEVEL_UNDEFINED === $option_level ) {
407 435 // Option not found -> use site level storage.
408 436 return false;
409 437 }
410 438
411 - if ( 0 === self::$_NETWORK_OPTIONS_MAP[ $key ] ) {
439 + if ( self::OPTION_LEVEL_NETWORK === $option_level ) {
412 440 // Option found and set to always use the network level storage on a multisite.
413 441 return true;
414 442 }
415 443
416 - if ( 3 === self::$_NETWORK_OPTIONS_MAP[ $key ] ) {
444 + if ( self::OPTION_LEVEL_SITE === $option_level ) {
417 445 // Option found and set to always use the site level storage on a multisite.
418 446 return false;
419 447 }
420 448
@@ -421,14 +449,17 @@
421 449 if ( ! $this->_is_network_active ) {
422 450 return false;
423 451 }
424 452
425 - if ( 1 === self::$_NETWORK_OPTIONS_MAP[ $key ] ) {
453 + if ( self::OPTION_LEVEL_NETWORK_ACTIVATED === $option_level ) {
426 454 // Network activated.
427 455 return true;
428 456 }
429 457
430 - if ( 2 === self::$_NETWORK_OPTIONS_MAP[ $key ] && ! $this->_is_delegated_connection ) {
458 + if (
459 + self::OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED === $option_level &&
460 + ! $this->_is_delegated_connection
461 + ) {
431 462 // Network activated and not delegated.
432 463 return true;
433 464 }
434 465
@@ -439,12 +470,17 @@
439 470 * @author Leo Fajardo
440 471 *
441 472 * @param string $key
442 473 * @param null|bool|int $network_level_or_blog_id When an integer, use the given blog storage. When `true` use the multisite storage (if there's a network). When `false`, use the current context blog storage. When `null`, the decision which storage to use (MS vs. Current S) will be handled internally and determined based on the $option (based on self::$_BINARY_MAP).
474 + * @param int $option_level Since 2.5.1
443 475 *
444 476 * @return bool
445 477 */
446 - private function should_use_network_storage( $key, $network_level_or_blog_id = null ) {
478 + private function should_use_network_storage(
479 + $key,
480 + $network_level_or_blog_id = null,
481 + $option_level = self::OPTION_LEVEL_UNDEFINED
482 + ) {
447 483 if ( ! $this->_is_multisite ) {
448 484 // Not a multisite environment.
449 485 return false;
450 486 }
@@ -454,14 +490,14 @@
454 490 return false;
455 491 }
456 492
457 493 if ( is_bool( $network_level_or_blog_id ) ) {
458 - // Explicitly specified whether should use the network or blog level storage.
494 + // Explicitly specified whether it should use the network or blog level storage.
459 495 return $network_level_or_blog_id;
460 496 }
461 497
462 498 // Determine which storage to use based on the option.
463 - return $this->is_multisite_option( $key );
499 + return $this->is_multisite_option( $key, $option_level );
464 500 }
465 501
466 502 /**
467 503 * @author Vova Feldman (@svovaf)
@@ -520,5 +556,5 @@
520 556 $this->_storage->{$k};
521 557 }
522 558
523 559 #endregion
524 - }
560 + }