| @@ -14,14 +14,11 @@ | ||
| 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 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 | |
| 18 | + * @property bool $is_network_activation | |
| 19 | + * @property int $network_install_blog_id | |
| 20 | + * @property object $sync_cron | |
| 24 | 21 | */ |
| 25 | 22 | class FS_Storage { |
| 26 | 23 | /** |
| 27 | 24 | * @var FS_Storage[] |
| @@ -74,18 +71,8 @@ | ||
| 74 | 71 | * } |
| 75 | 72 | */ |
| 76 | 73 | private static $_NETWORK_OPTIONS_MAP; |
| 77 | 74 | |
| 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 | - | |
| 88 | 75 | /** |
| 89 | 76 | * @author Leo Fajardo (@leorw) |
| 90 | 77 | * |
| 91 | 78 | * @param string $module_type |
| @@ -154,19 +141,12 @@ | ||
| 154 | 141 | * |
| 155 | 142 | * @param string $key |
| 156 | 143 | * @param mixed $value |
| 157 | 144 | * @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 | |
| 159 | 145 | * @param bool $flush |
| 160 | 146 | */ |
| 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 ) ) { | |
| 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 ) ) { | |
| 169 | 149 | $this->_network_storage->store( $key, $value, $flush ); |
| 170 | 150 | } else { |
| 171 | 151 | $storage = $this->get_site_storage( $network_level_or_blog_id ); |
| 172 | 152 | $storage->store( $key, $value, $flush ); |
| @@ -218,19 +198,13 @@ | ||
| 218 | 198 | * |
| 219 | 199 | * @param string $key |
| 220 | 200 | * @param mixed $default |
| 221 | 201 | * @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 | |
| 223 | 202 | * |
| 224 | 203 | * @return mixed |
| 225 | 204 | */ |
| 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 ) ) { | |
| 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 ) ) { | |
| 233 | 207 | return $this->_network_storage->get( $key, $default ); |
| 234 | 208 | } else { |
| 235 | 209 | $storage = $this->get_site_storage( $network_level_or_blog_id ); |
| 236 | 210 | |
| @@ -314,8 +288,21 @@ | ||
| 314 | 288 | if ( isset( $this->_storage->{$option} ) && ! isset( $this->_network_storage->{$option} ) ) { |
| 315 | 289 | // Migrate option to the network storage. |
| 316 | 290 | $this->_network_storage->store( $option, $this->_storage->{$option}, false ); |
| 317 | 291 | |
| 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 | + | |
| 318 | 305 | $updated = true; |
| 319 | 306 | } |
| 320 | 307 | } |
| 321 | 308 | |
| @@ -348,64 +335,57 @@ | ||
| 348 | 335 | */ |
| 349 | 336 | private static function load_network_options_map() { |
| 350 | 337 | self::$_NETWORK_OPTIONS_MAP = array( |
| 351 | 338 | // Network level options. |
| 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, | |
| 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, | |
| 382 | 366 | /** |
| 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. | |
| 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. | |
| 384 | 370 | */ |
| 385 | - 'is_network_activation' => self::OPTION_LEVEL_NETWORK, | |
| 386 | - 'license_migration' => self::OPTION_LEVEL_NETWORK, | |
| 371 | + 'is_network_activation' => 0, | |
| 387 | 372 | |
| 388 | 373 | // When network activated, then network level. |
| 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, | |
| 374 | + 'install_timestamp' => 1, | |
| 375 | + 'prev_is_premium' => 1, | |
| 376 | + 'require_license_activation' => 1, | |
| 392 | 377 | |
| 393 | 378 | // If not network activated OR delegated, then site level. |
| 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, | |
| 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, | |
| 404 | 385 | |
| 405 | 386 | // Site level options. |
| 406 | - 'is_anonymous' => self::OPTION_LEVEL_SITE, | |
| 407 | - 'clone_id' => self::OPTION_LEVEL_SITE, | |
| 387 | + 'is_anonymous' => 3, | |
| 408 | 388 | ); |
| 409 | 389 | } |
| 410 | 390 | |
| 411 | 391 | /** |
| @@ -414,35 +394,27 @@ | ||
| 414 | 394 | * @author Vova Feldman (@svovaf) |
| 415 | 395 | * @since 2.0.0 |
| 416 | 396 | * |
| 417 | 397 | * @param string $key |
| 418 | - * @param int $option_level Since 2.5.1 | |
| 419 | 398 | * |
| 420 | - * @return bool | |
| 399 | + * @return bool|mixed | |
| 421 | 400 | */ |
| 422 | - private function is_multisite_option( $key, $option_level = self::OPTION_LEVEL_UNDEFINED ) { | |
| 401 | + private function is_multisite_option( $key ) { | |
| 423 | 402 | if ( ! isset( self::$_NETWORK_OPTIONS_MAP ) ) { |
| 424 | 403 | self::load_network_options_map(); |
| 425 | 404 | } |
| 426 | 405 | |
| 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 ) { | |
| 406 | + if ( ! isset( self::$_NETWORK_OPTIONS_MAP[ $key ] ) ) { | |
| 435 | 407 | // Option not found -> use site level storage. |
| 436 | 408 | return false; |
| 437 | 409 | } |
| 438 | 410 | |
| 439 | - if ( self::OPTION_LEVEL_NETWORK === $option_level ) { | |
| 411 | + if ( 0 === self::$_NETWORK_OPTIONS_MAP[ $key ] ) { | |
| 440 | 412 | // Option found and set to always use the network level storage on a multisite. |
| 441 | 413 | return true; |
| 442 | 414 | } |
| 443 | 415 | |
| 444 | - if ( self::OPTION_LEVEL_SITE === $option_level ) { | |
| 416 | + if ( 3 === self::$_NETWORK_OPTIONS_MAP[ $key ] ) { | |
| 445 | 417 | // Option found and set to always use the site level storage on a multisite. |
| 446 | 418 | return false; |
| 447 | 419 | } |
| 448 | 420 | |
| @@ -449,17 +421,14 @@ | ||
| 449 | 421 | if ( ! $this->_is_network_active ) { |
| 450 | 422 | return false; |
| 451 | 423 | } |
| 452 | 424 | |
| 453 | - if ( self::OPTION_LEVEL_NETWORK_ACTIVATED === $option_level ) { | |
| 425 | + if ( 1 === self::$_NETWORK_OPTIONS_MAP[ $key ] ) { | |
| 454 | 426 | // Network activated. |
| 455 | 427 | return true; |
| 456 | 428 | } |
| 457 | 429 | |
| 458 | - if ( | |
| 459 | - self::OPTION_LEVEL_NETWORK_ACTIVATED_NOT_DELEGATED === $option_level && | |
| 460 | - ! $this->_is_delegated_connection | |
| 461 | - ) { | |
| 430 | + if ( 2 === self::$_NETWORK_OPTIONS_MAP[ $key ] && ! $this->_is_delegated_connection ) { | |
| 462 | 431 | // Network activated and not delegated. |
| 463 | 432 | return true; |
| 464 | 433 | } |
| 465 | 434 | |
| @@ -470,17 +439,12 @@ | ||
| 470 | 439 | * @author Leo Fajardo |
| 471 | 440 | * |
| 472 | 441 | * @param string $key |
| 473 | 442 | * @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 | |
| 475 | 443 | * |
| 476 | 444 | * @return bool |
| 477 | 445 | */ |
| 478 | - private function should_use_network_storage( | |
| 479 | - $key, | |
| 480 | - $network_level_or_blog_id = null, | |
| 481 | - $option_level = self::OPTION_LEVEL_UNDEFINED | |
| 482 | - ) { | |
| 446 | + private function should_use_network_storage( $key, $network_level_or_blog_id = null ) { | |
| 483 | 447 | if ( ! $this->_is_multisite ) { |
| 484 | 448 | // Not a multisite environment. |
| 485 | 449 | return false; |
| 486 | 450 | } |
| @@ -490,14 +454,14 @@ | ||
| 490 | 454 | return false; |
| 491 | 455 | } |
| 492 | 456 | |
| 493 | 457 | if ( is_bool( $network_level_or_blog_id ) ) { |
| 494 | - // Explicitly specified whether it should use the network or blog level storage. | |
| 458 | + // Explicitly specified whether should use the network or blog level storage. | |
| 495 | 459 | return $network_level_or_blog_id; |
| 496 | 460 | } |
| 497 | 461 | |
| 498 | 462 | // Determine which storage to use based on the option. |
| 499 | - return $this->is_multisite_option( $key, $option_level ); | |
| 463 | + return $this->is_multisite_option( $key ); | |
| 500 | 464 | } |
| 501 | 465 | |
| 502 | 466 | /** |
| 503 | 467 | * @author Vova Feldman (@svovaf) |
| @@ -556,5 +520,5 @@ | ||
| 556 | 520 | $this->_storage->{$k}; |
| 557 | 521 | } |
| 558 | 522 | |
| 559 | 523 | #endregion |
| 560 | - } | |
| 524 | + } | |