PluginProbe
BlockSpare – Gutenberg Blocks for News, Magazine, Blog & Business Websites / trunk
BlockSpare – Gutenberg Blocks for News, Magazine, Blog & Business Websites vtrunk
4.1.0 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.1.0 1.1.1 1.1.2 1.2.0 1.2.1 1.2.2 1.2.3 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 2.1.2 2.5.0 2.5.3 2.6.1 All 38 releases
← All changes | freemius/includes/class-fs-storage.php +108 -79 1.2.3trunk 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,64 +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 - 'expired_license_notice_shown' => 2,
383 - 'is_whitelabeled' => 2,
384 - 'last_license_key' => 2,
385 - 'last_license_user_id' => 2,
386 - 'prev_user_id' => 2,
387 - 'sticky_optin_added' => 2,
388 - 'uninstall_reason' => 2,
389 - 'is_pending_activation' => 2,
390 - 'pending_license_key' => 2,
391 - 'is_extensions_tracking_allowed' => 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,
392 404
393 405 // Site level options.
394 - 'is_anonymous' => 3,
406 + 'is_anonymous' => self::OPTION_LEVEL_SITE,
407 + 'clone_id' => self::OPTION_LEVEL_SITE,
395 408 );
396 409 }
397 410
398 411 /**
@@ -401,27 +414,35 @@
401 414 * @author Vova Feldman (@svovaf)
402 415 * @since 2.0.0
403 416 *
404 417 * @param string $key
418 + * @param int $option_level Since 2.5.1
405 419 *
406 - * @return bool|mixed
420 + * @return bool
407 421 */
408 - private function is_multisite_option( $key ) {
422 + private function is_multisite_option( $key, $option_level = self::OPTION_LEVEL_UNDEFINED ) {
409 423 if ( ! isset( self::$_NETWORK_OPTIONS_MAP ) ) {
410 424 self::load_network_options_map();
411 425 }
412 426
413 - 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 ) {
414 435 // Option not found -> use site level storage.
415 436 return false;
416 437 }
417 438
418 - if ( 0 === self::$_NETWORK_OPTIONS_MAP[ $key ] ) {
439 + if ( self::OPTION_LEVEL_NETWORK === $option_level ) {
419 440 // Option found and set to always use the network level storage on a multisite.
420 441 return true;
421 442 }
422 443
423 - if ( 3 === self::$_NETWORK_OPTIONS_MAP[ $key ] ) {
444 + if ( self::OPTION_LEVEL_SITE === $option_level ) {
424 445 // Option found and set to always use the site level storage on a multisite.
425 446 return false;
426 447 }
427 448
@@ -428,14 +449,17 @@
428 449 if ( ! $this->_is_network_active ) {
429 450 return false;
430 451 }
431 452
432 - if ( 1 === self::$_NETWORK_OPTIONS_MAP[ $key ] ) {
453 + if ( self::OPTION_LEVEL_NETWORK_ACTIVATED === $option_level ) {
433 454 // Network activated.
434 455 return true;
435 456 }
436 457
437 - 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 + ) {
438 462 // Network activated and not delegated.
439 463 return true;
440 464 }
441 465
@@ -446,12 +470,17 @@
446 470 * @author Leo Fajardo
447 471 *
448 472 * @param string $key
449 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
450 475 *
451 476 * @return bool
452 477 */
453 - 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 + ) {
454 483 if ( ! $this->_is_multisite ) {
455 484 // Not a multisite environment.
456 485 return false;
457 486 }
@@ -461,14 +490,14 @@
461 490 return false;
462 491 }
463 492
464 493 if ( is_bool( $network_level_or_blog_id ) ) {
465 - // Explicitly specified whether should use the network or blog level storage.
494 + // Explicitly specified whether it should use the network or blog level storage.
466 495 return $network_level_or_blog_id;
467 496 }
468 497
469 498 // Determine which storage to use based on the option.
470 - return $this->is_multisite_option( $key );
499 + return $this->is_multisite_option( $key, $option_level );
471 500 }
472 501
473 502 /**
474 503 * @author Vova Feldman (@svovaf)
@@ -527,5 +556,5 @@
527 556 $this->_storage->{$k};
528 557 }
529 558
530 559 #endregion
531 - }
560 + }