: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* Activate a given license on a collection of blogs/sites that are not yet opted-in.
* @author Vova Feldman (@svovaf)
* @param string $license_key
* @return true|mixed True if successful, otherwise, the API result.
private function activate_license_on_site( FS_User $user, $license_key ) {
return $this->activate_license_on_many_sites( $user, $license_key );
* Activate a given license on a collection of blogs/sites that are not yet opted-in.
* @author Vova Feldman (@svovaf)
* @param string $license_key
* @return true|mixed True if successful, otherwise, the API result.
private function activate_license_on_many_sites(
array $site_ids = array()
foreach ( $site_ids as $site_id ) {
$sites[] = $this->get_site_info( array( 'blog_id' => $site_id ) );
$result = $this->create_installs_with_user(
if ( ! $this->is_api_result_entity( $result ) &&
! $this->is_api_result_object( $result, 'installs' )
if ( $this->is_api_result_entity( $result ) ) {
$install = new FS_Site( $result );
$this->_store_site( true, null, $install );
$this->reset_anonymous_mode();
foreach ( $result->installs as $install ) {
$installs[] = new FS_Site( $install );
// Map site addresses to their blog IDs.
$address_to_blog_map = $this->get_address_to_blog_map();
foreach ( $installs as $install ) {
$address = trailingslashit( fs_strip_url_protocol( $install->url ) );
$blog_id = $address_to_blog_map[ $address ];
$this->_store_site( true, $blog_id, $install );
$this->reset_anonymous_mode( $blog_id );
if ( is_null( $first_blog_id ) ) {
$first_blog_id = $blog_id;
if ( ! FS_Site::is_valid_id( $this->_storage->network_install_blog_id ) ) {
$this->_storage->network_install_blog_id = $first_blog_id;
* Sync site's license with user licenses.
* @author Vova Feldman (@svovaf)
* @param FS_Plugin_License|null $new_license
* @return FS_Plugin_License|null
function _update_site_license( $new_license ) {
$this->_logger->entrance();
* In case this call will be removed in the future, the `_sync_licenses()` method needs to be updated
* accordingly so that it will also handle the case when an ownership change is done via license
* @author Leo Fajardo (@leorw)
$this->set_license( $new_license );
if ( ! is_object( $new_license ) ) {
$this->_site->license_id = null;
$this->_sync_site_subscription( null );
$this->_site->license_id = $this->_license->id;
if ( ! is_array( $this->_licenses ) ) {
$this->_licenses = array();
$is_license_found = false;
for ( $i = 0, $len = count( $this->_licenses ); $i < $len; $i ++ ) {
if ( $new_license->id == $this->_licenses[ $i ]->id ) {
$this->_licenses[ $i ] = $new_license;
$is_license_found = true;
// If new license just append.
if ( ! $is_license_found ) {
$this->_licenses[] = $new_license;
$this->_sync_site_subscription( $new_license );
* @author Vova Feldman (@svovaf)
* @param \FS_Plugin_License $license
private function set_license( FS_Plugin_License $license = null ) {
$this->_license = $license;
$this->maybe_update_whitelabel_flag( $license );
* @author Leo Fajardo (@leorw)
* @param FS_Plugin_License $license
private function maybe_update_whitelabel_flag( $license ) {
$is_whitelabeled = isset( $this->_storage->is_whitelabeled ) ?
$this->_storage->is_whitelabeled :
if ( is_object( $license ) ) {
$license_user = self::_get_user_by_id( $license->user_id );
if ( ! is_object( $license_user ) ) {
// If foreign license, do not update the `is_whitelabeled` flag.
if ( $this->is_addon() ) {
* Store the last license data to the parent's storage since it's needed only when showing the
* "Start Debug" dialog which is triggered from the "Account" page. This way, there's no need to
* iterate over the add-ons just to get the last license data.
$this->get_parent_instance()->store_last_activated_license_data( $license, $license_user );
$this->store_last_activated_license_data( $license );
if ( $license->is_whitelabeled ) {
// Activated a developer license, data should be hidden.
} else if ( $this->is_registered() && $this->_user->id == $license->user_id ) {
// The account owner activated a regular license key, no need to hide the data.
$is_whitelabeled = false;
$this->_storage->is_whitelabeled = $is_whitelabeled;
// Reset the whitelabeled status after update.
$this->is_whitelabeled = null;
if ( $this->is_addon() ) {
$parent_fs = $this->get_parent_instance();
if ( is_object( $parent_fs ) ) {
$parent_fs->is_whitelabeled = null;
* @author Leo Fajardo (@leorw)
* @param FS_Plugin_License $license
* @param FS_User $license_user
private function store_last_activated_license_data( FS_Plugin_License $license, $license_user = null ) {
if ( ! is_object( $license_user ) ) {
$this->_storage->last_license_key = md5( $license->secret_key );
$this->_storage->last_license_user_id = null;
$this->_storage->last_license_user_key = md5( $license_user->secret_key );
$this->_storage->last_license_user_id = $license_user->id;
* @author Leo Fajardo (@leorw)
* @param bool $ignore_data_debug_mode
function is_whitelabeled_by_flag( $ignore_data_debug_mode = false ) {
if ( true !== $this->_storage->is_whitelabeled ) {
} else if ( $ignore_data_debug_mode ) {
$fs = $this->is_addon() ?
$this->get_parent_instance() :
return ! $fs->is_data_debug_mode();
* @author Leo Fajardo (@leorw)
function get_last_license_user_id() {
return ( FS_User::is_valid_id( $this->_storage->last_license_user_id ) ) ?
$this->_storage->last_license_user_id :
* @author Leo Fajardo (@leorw)
* @param bool $ignore_data_debug_mode
function is_whitelabeled( $ignore_data_debug_mode = false, $blog_id = null ) {
if ( ! is_null( $blog_id ) ) {
$this->switch_to_blog( $blog_id );
if ( ! is_null( $this->is_whitelabeled ) ) {
$is_whitelabeled = $this->is_whitelabeled;
$is_whitelabeled = false;
$is_whitelabeled_flag = $this->is_whitelabeled_by_flag( true );
if ( ! $this->has_addons() ) {
$is_whitelabeled = $is_whitelabeled_flag;
} else if ( $is_whitelabeled_flag ) {
if ( $this->is_registered() || $this->is_premium() ) {
$addon_ids = $this->get_updated_account_addons();
$addons = self::get_all_addons();
$plugin_addons = isset( $addons[ $this->_plugin->id ] ) ?
$addons[ $this->_plugin->id ] :
foreach ( $plugin_addons as $addon ) {
$addon_ids[] = $addon->id;
$installed_addons = $this->get_installed_addons();
foreach ( $installed_addons as $fs_addon ) {
$addon_ids[] = $fs_addon->get_id();
if ( ! empty( $addon_ids ) ) {
$addon_ids = array_unique( $addon_ids );
$this->is_network_active()
foreach ( $addon_ids as $addon_id ) {
$addon = $this->get_addon( $addon_id );
if ( ! is_object( $addon ) ) {
$addon_storage = FS_Storage::instance( WP_FS__MODULE_TYPE_PLUGIN, $addon->slug );
$fs_addon = $this->is_addon_activated( $addon_id ) ?
self::get_addon_instance( $addon_id ) :
$was_addon_network_activated = false;
if ( is_object( $fs_addon ) ) {
$was_addon_network_activated = $fs_addon->is_network_active();
} else if ( $is_network_level ) {
$was_addon_network_activated = $addon_storage->get( 'was_plugin_loaded', false, true );
$network_delegated_connection = (
$was_addon_network_activated &&
$addon_storage->get( 'is_delegated_connection', false, true )
( ! $was_addon_network_activated || $network_delegated_connection )
$sites = self::get_sites();
* If in network admin area and the add-on was not network-activated or network-activated
* and network-delegated, find any add-on whose is_whitelabeled flag is true.
foreach ( $sites as $site ) {
$site_info = $this->get_site_info( $site );
if ( $addon_storage->get( 'is_whitelabeled', false, $site_info['blog_id'] ) ) {
if ( $is_whitelabeled ) {
* This will be executed when any of the following is met:
* 1. Add-on was network-activated, not network-delegated, and in network admin area.
* 2. Add-on was network-activated, network-delegated, and in site admin area.
* 3. Add-on was not network-activated and in site admin area.
if ( true === $addon_storage->is_whitelabeled ) {
$this->is_whitelabeled = $is_whitelabeled;
if ( ! $is_whitelabeled || ! $this->is_data_debug_mode() ) {
$this->_admin_notices->remove_sticky( 'data_debug_mode_enabled' );
if ( ! is_null( $blog_id ) ) {
$this->restore_current_blog();
( $ignore_data_debug_mode || ! $this->is_data_debug_mode() )
* Sync site's subscription.
* @author Vova Feldman (@svovaf)
* @param FS_Plugin_License|null $license
* @return bool|\FS_Subscription
private function _sync_site_subscription( $license ) {
if ( ! is_object( $license ) ) {
$this->delete_unused_subscriptions();
// Load subscription details if not lifetime.
$subscription = $license->is_lifetime() ?
$this->_fetch_site_license_subscription();
if ( is_object( $subscription ) && ! isset( $subscription->error ) ) {
$this->store_subscription( $subscription );
$this->delete_unused_subscriptions();
* @author Vova Feldman (@svovaf)
* @return bool|\FS_Plugin_License
function _get_license() {
if ( ! fs_is_network_admin() || is_object( $this->_license ) ) {
return $this->_get_available_premium_license();
* @param number $license_id
* @return null|\FS_Subscription
function _get_subscription( $license_id ) {
if ( ! isset( $this->_storage->subscriptions ) ||
empty( $this->_storage->subscriptions )
foreach ( fs_get_entities( $this->_storage->subscriptions, FS_Subscription::get_class_name() ) as $subscription ) {
if ( $subscription->license_id == $license_id ) {
* @author Leo Fajardo (@leorw)
* @param FS_Subscription $subscription
function store_subscription( FS_Subscription $subscription ) {
if ( ! isset( $this->_storage->subscriptions ) ) {
$this->_storage->subscriptions = array();
if ( empty( $this->_storage->subscriptions ) || ! is_multisite() ) {
$this->_storage->subscriptions = array( $subscription );
$subscriptions = fs_get_entities( $this->_storage->subscriptions, FS_Subscription::get_class_name() );
$updated_subscription = false;
foreach ( $subscriptions as $key => $existing_subscription ) {
if ( $existing_subscription->id == $subscription->id ) {
$subscriptions[ $key ] = $subscription;
$updated_subscription = true;