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 -80 1.3.2trunk 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,65 +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,
374 - 'license_migration' => 0,
385 + 'is_network_activation' => self::OPTION_LEVEL_NETWORK,
386 + 'license_migration' => self::OPTION_LEVEL_NETWORK,
375 387
376 388 // When network activated, then network level.
377 - 'install_timestamp' => 1,
378 - 'prev_is_premium' => 1,
379 - '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,
380 392
381 393 // If not network activated OR delegated, then site level.
382 - 'activation_timestamp' => 2,
383 - 'expired_license_notice_shown' => 2,
384 - 'is_whitelabeled' => 2,
385 - 'last_license_key' => 2,
386 - 'last_license_user_id' => 2,
387 - 'prev_user_id' => 2,
388 - 'sticky_optin_added' => 2,
389 - 'uninstall_reason' => 2,
390 - 'is_pending_activation' => 2,
391 - 'pending_license_key' => 2,
392 - '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,
393 404
394 405 // Site level options.
395 - 'is_anonymous' => 3,
406 + 'is_anonymous' => self::OPTION_LEVEL_SITE,
407 + 'clone_id' => self::OPTION_LEVEL_SITE,
396 408 );
397 409 }
398 410
399 411 /**
@@ -402,27 +414,35 @@
402 414 * @author Vova Feldman (@svovaf)
403 415 * @since 2.0.0
404 416 *
405 417 * @param string $key
418 + * @param int $option_level Since 2.5.1
406 419 *
407 - * @return bool|mixed
420 + * @return bool
408 421 */
409 - private function is_multisite_option( $key ) {
422 + private function is_multisite_option( $key, $option_level = self::OPTION_LEVEL_UNDEFINED ) {
410 423 if ( ! isset( self::$_NETWORK_OPTIONS_MAP ) ) {
411 424 self::load_network_options_map();
412 425 }
413 426
414 - 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 ) {
415 435 // Option not found -> use site level storage.
416 436 return false;
417 437 }
418 438
419 - if ( 0 === self::$_NETWORK_OPTIONS_MAP[ $key ] ) {
439 + if ( self::OPTION_LEVEL_NETWORK === $option_level ) {
420 440 // Option found and set to always use the network level storage on a multisite.
421 441 return true;
422 442 }
423 443
424 - if ( 3 === self::$_NETWORK_OPTIONS_MAP[ $key ] ) {
444 + if ( self::OPTION_LEVEL_SITE === $option_level ) {
425 445 // Option found and set to always use the site level storage on a multisite.
426 446 return false;
427 447 }
428 448
@@ -429,14 +449,17 @@
429 449 if ( ! $this->_is_network_active ) {
430 450 return false;
431 451 }
432 452
433 - if ( 1 === self::$_NETWORK_OPTIONS_MAP[ $key ] ) {
453 + if ( self::OPTION_LEVEL_NETWORK_ACTIVATED === $option_level ) {
434 454 // Network activated.
435 455 return true;
436 456 }
437 457
438 - 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 + ) {
439 462 // Network activated and not delegated.
440 463 return true;
441 464 }
442 465
@@ -447,12 +470,17 @@
447 470 * @author Leo Fajardo
448 471 *
449 472 * @param string $key
450 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
451 475 *
452 476 * @return bool
453 477 */
454 - 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 + ) {
455 483 if ( ! $this->_is_multisite ) {
456 484 // Not a multisite environment.
457 485 return false;
458 486 }
@@ -462,14 +490,14 @@
462 490 return false;
463 491 }
464 492
465 493 if ( is_bool( $network_level_or_blog_id ) ) {
466 - // Explicitly specified whether should use the network or blog level storage.
494 + // Explicitly specified whether it should use the network or blog level storage.
467 495 return $network_level_or_blog_id;
468 496 }
469 497
470 498 // Determine which storage to use based on the option.
471 - return $this->is_multisite_option( $key );
499 + return $this->is_multisite_option( $key, $option_level );
472 500 }
473 501
474 502 /**
475 503 * @author Vova Feldman (@svovaf)
@@ -528,5 +556,5 @@
528 556 $this->_storage->{$k};
529 557 }
530 558
531 559 #endregion
532 - }
560 + }