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 -74 2.2.3 → 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,59 +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 - 'beta_data' => 0,
341 - 'connectivity_test' => 0,
342 - 'handle_gdpr_admin_notice' => 0,
343 - 'has_trial_plan' => 0,
344 - 'install_sync_timestamp' => 0,
345 - 'install_sync_cron' => 0,
346 - 'is_anonymous_ms' => 0,
347 - 'is_network_activated' => 0,
348 - 'is_on' => 0,
349 - 'is_plugin_new_install' => 0,
350 - 'network_install_blog_id' => 0,
351 - 'pending_sites_info' => 0,
352 - 'plugin_last_version' => 0,
353 - 'plugin_main_file' => 0,
354 - 'plugin_version' => 0,
355 - 'sdk_downgrade_mode' => 0,
356 - 'sdk_last_version' => 0,
357 - 'sdk_upgrade_mode' => 0,
358 - 'sdk_version' => 0,
359 - 'sticky_optin_added_ms' => 0,
360 - 'subscriptions' => 0,
361 - 'sync_timestamp' => 0,
362 - 'sync_cron' => 0,
363 - 'was_plugin_loaded' => 0,
364 - 'network_user_id' => 0,
365 - 'plugin_upgrade_mode' => 0,
366 - 'plugin_downgrade_mode' => 0,
367 - '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,
368 382 /**
369 - * Special flag that is used when a super-admin upgrades to the new version of the SDK that
370 - * supports network level integration, when the connection decision wasn't made for all of the
371 - * 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.
372 384 */
373 - 'is_network_activation' => 0,
385 + 'is_network_activation' => self::OPTION_LEVEL_NETWORK,
386 + 'license_migration' => self::OPTION_LEVEL_NETWORK,
374 387
375 388 // When network activated, then network level.
376 - 'install_timestamp' => 1,
377 - 'prev_is_premium' => 1,
378 - '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,
379 392
380 393 // If not network activated OR delegated, then site level.
381 - 'activation_timestamp' => 2,
382 - 'prev_user_id' => 2,
383 - 'sticky_optin_added' => 2,
384 - 'uninstall_reason' => 2,
385 - 'is_pending_activation' => 2,
386 - '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,
387 404
388 405 // Site level options.
389 - 'is_anonymous' => 3,
406 + 'is_anonymous' => self::OPTION_LEVEL_SITE,
407 + 'clone_id' => self::OPTION_LEVEL_SITE,
390 408 );
391 409 }
392 410
393 411 /**
@@ -396,27 +414,35 @@
396 414 * @author Vova Feldman (@svovaf)
397 415 * @since 2.0.0
398 416 *
399 417 * @param string $key
418 + * @param int $option_level Since 2.5.1
400 419 *
401 - * @return bool|mixed
420 + * @return bool
402 421 */
403 - private function is_multisite_option( $key ) {
422 + private function is_multisite_option( $key, $option_level = self::OPTION_LEVEL_UNDEFINED ) {
404 423 if ( ! isset( self::$_NETWORK_OPTIONS_MAP ) ) {
405 424 self::load_network_options_map();
406 425 }
407 426
408 - 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 ) {
409 435 // Option not found -> use site level storage.
410 436 return false;
411 437 }
412 438
413 - if ( 0 === self::$_NETWORK_OPTIONS_MAP[ $key ] ) {
439 + if ( self::OPTION_LEVEL_NETWORK === $option_level ) {
414 440 // Option found and set to always use the network level storage on a multisite.
415 441 return true;
416 442 }
417 443
418 - if ( 3 === self::$_NETWORK_OPTIONS_MAP[ $key ] ) {
444 + if ( self::OPTION_LEVEL_SITE === $option_level ) {
419 445 // Option found and set to always use the site level storage on a multisite.
420 446 return false;
421 447 }
422 448
@@ -423,14 +449,17 @@
423 449 if ( ! $this->_is_network_active ) {
424 450 return false;
425 451 }
426 452
427 - if ( 1 === self::$_NETWORK_OPTIONS_MAP[ $key ] ) {
453 + if ( self::OPTION_LEVEL_NETWORK_ACTIVATED === $option_level ) {
428 454 // Network activated.
429 455 return true;
430 456 }
431 457
432 - 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 + ) {
433 462 // Network activated and not delegated.
434 463 return true;
435 464 }
436 465
@@ -441,12 +470,17 @@
441 470 * @author Leo Fajardo
442 471 *
443 472 * @param string $key
444 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
445 475 *
446 476 * @return bool
447 477 */
448 - 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 + ) {
449 483 if ( ! $this->_is_multisite ) {
450 484 // Not a multisite environment.
451 485 return false;
452 486 }
@@ -456,14 +490,14 @@
456 490 return false;
457 491 }
458 492
459 493 if ( is_bool( $network_level_or_blog_id ) ) {
460 - // Explicitly specified whether should use the network or blog level storage.
494 + // Explicitly specified whether it should use the network or blog level storage.
461 495 return $network_level_or_blog_id;
462 496 }
463 497
464 498 // Determine which storage to use based on the option.
465 - return $this->is_multisite_option( $key );
499 + return $this->is_multisite_option( $key, $option_level );
466 500 }
467 501
468 502 /**
469 503 * @author Vova Feldman (@svovaf)
@@ -522,5 +556,5 @@
522 556 $this->_storage->{$k};
523 557 }
524 558
525 559 #endregion
526 - }
560 + }