: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* `$fs->is_registered() && $fs->is_tracking_allowed()`
* @author Vova Feldman (@svovaf)
* @param bool $ignore_anonymous_state Since 2.5.1
function is_registered( $ignore_anonymous_state = false ) {
is_object( $this->_user ) &&
$ignore_anonymous_state ||
* Returns TRUE if the user opted-in and didn't disconnect (opt-out).
* @author Leo Fajardo (@leorw)
function is_tracking_allowed( $blog_id = null, $install = null ) {
if ( is_null( $install ) ) {
$install = is_null( $blog_id ) ?
$this->get_install_by_blog_id( $blog_id );
FS_Permission_Manager::instance( $this )->is_homepage_url_tracking_allowed( $blog_id )
* Returns TRUE if the user never opted-in or manually opted-out.
* @author Vova Feldman (@svovaf)
* @param int|null $blog_id
function is_tracking_prohibited( $blog_id = null ) {
! $this->is_registered( true ) ||
! $this->is_tracking_allowed( $blog_id )
* @author Leo Fajardo (@leorw)
function is_bundle_license_auto_activation_enabled() {
return $this->is_addon() ?
( is_object( $this->_parent ) && $this->_parent->is_bundle_license_auto_activation_enabled() ) :
$this->_is_bundle_license_auto_activation_enabled;
* @author Vova Feldman (@svovaf)
* @author Vova Feldman (@svovaf)
* @author Vova Feldman (@svovaf)
* @author Leo Fajardo (@leorw)
function store_site( $site ) {
$this->_store_site( true );
* Deletes the current install with an option to back it up in case restoration will be needed (e.g., if the automatic clone resolution attempt fails).
* @author Leo Fajardo (@leorw)
function delete_current_install( $back_up ) {
// Back up and delete the unique ID.
self::$_accounts->set_option( 'prev_unique_id', $this->get_anonymous_id() );
self::$_accounts->set_option( 'unique_id', null );
// Back up the install before deleting it so that it can be restored later on if necessary (e.g., if the automatic clone resolution attempt fails).
* @author Leo Fajardo (@leorw)
function restore_backup_site() {
self::$_accounts->set_option(
self::$_accounts->get_option( 'prev_unique_id' )
$sites = self::get_all_sites( $this->_module_type, null, true );
$this->store_site( clone $sites[ $this->_slug ] );
* @author Vova Feldman (@svovaf)
* @since 1.1.7.3 If not yet loaded, fetch data from the API.
* @return FS_Plugin[]|false
function get_addons( $flush = false ) {
$this->_logger->entrance();
if ( ! $this->_has_addons ) {
$addons = $this->sync_addons( $flush );
return ( ! is_array( $addons ) || empty( $addons ) ) ?
* @author Vova Feldman (@svovaf)
function get_account_addons() {
$this->_logger->entrance();
$addons = self::get_all_account_addons();
if ( ! is_array( $addons ) ||
! isset( $addons[ $this->_plugin->id ] ) ||
! is_array( $addons[ $this->_plugin->id ] ) ||
0 === count( $addons[ $this->_plugin->id ] )
return $addons[ $this->_plugin->id ];
* @author Vova Feldman (@svovaf)
function has_account_addons() {
$addons = $this->get_account_addons();
return is_array( $addons ) && ( 0 < count( $addons ) );
* Get add-on by ID (from local data).
* @author Vova Feldman (@svovaf)
* @return FS_Plugin|false
function get_addon( $id ) {
$this->_logger->entrance();
$addons = $this->get_addons();
if ( is_array( $addons ) ) {
foreach ( $addons as $addon ) {
if ( $id == $addon->id ) {
* Get add-on by slug (from local data).
* @author Vova Feldman (@svovaf)
* @return FS_Plugin|false
function get_addon_by_slug( $slug, $flush = false ) {
$this->_logger->entrance();
$addons = $this->get_addons( $flush );
if ( is_array( $addons ) ) {
foreach ( $addons as $addon ) {
if ( $slug === $addon->slug ) {
* @var array<number,object[]> {
* @val object[] The add-on's plans and prices object.
private $plans_and_pricing_by_addon_id;
* @author Leo Fajardo (@leorw)
* @return array<number,object[]> {
* @val object[] The add-on's plans and prices object.
function _get_addons_plans_and_pricing_map_by_id() {
if ( ! isset( $this->plans_and_pricing_by_addon_id ) ) {
$result = $this->get_api_plugin_scope()->get( $this->add_show_pending( "/addons/pricing.json?type=visible" ) );
$plans_and_pricing_by_addon_id = array();
if ( $this->is_api_result_object( $result, 'addons' ) ) {
foreach ( $result->addons as $addon ) {
$plans_and_pricing_by_addon_id[ $addon->id ] = $addon->plans;
$this->plans_and_pricing_by_addon_id = $plans_and_pricing_by_addon_id;
return $this->plans_and_pricing_by_addon_id;
* @author Leo Fajardo (@leorw)
* @param number $addon_id
* @param bool $is_installed
function _get_addon_info( $addon_id, $is_installed ) {
$addon = $this->get_addon( $addon_id );
if ( ! is_object( $addon ) ) {
$addon_storage = FS_Storage::instance( WP_FS__MODULE_TYPE_PLUGIN, $slug );
if ( ! fs_is_network_admin() ) {
// Get blog-level activated installations.
$sites = self::maybe_get_entities_account_option( 'sites', array() );
if ( $this->is_addon_activated( $addon_id ) &&
$this->get_addon_instance( $addon_id )->is_network_active()
if ( FS_Site::is_valid_id( $addon_storage->network_install_blog_id ) ) {
// Get network-level activated installations.
$sites = self::maybe_get_entities_account_option(
$addon_storage->network_install_blog_id
'title' => $addon->title,
'is_whitelabeled' => $addon_storage->is_whitelabeled
$plans_and_pricing_by_addon_id = $this->_get_addons_plans_and_pricing_map_by_id();
if ( isset( $plans_and_pricing_by_addon_id[ $addon_id ] ) ) {
$plans = $plans_and_pricing_by_addon_id[ $addon_id ];
if ( is_array( $plans ) && count( $plans ) > 0 ) {
foreach ( $plans as $plan ) {
if ( isset( $plan->pricing ) &&
is_array( $plan->pricing ) &&
count( $plan->pricing ) > 0
$addon_info['has_paid_plan'] = $has_paid_plan;
if ( ! is_array( $sites ) || ! isset( $sites[ $slug ] ) ) {
$addon_info['is_connected'] = (
( $addon->parent_plugin_id == $this->get_id() ) &&
FS_Site::is_valid_id( $site->id ) &&
FS_User::is_valid_id( $site->user_id ) &&
FS_Plugin_Plan::is_valid_id( $site->plan_id )
if ( $addon_info['is_connected'] && $is_installed ) {
$addon_info['site'] = $site;
$plugins_data = self::maybe_get_entities_account_option( WP_FS__MODULE_TYPE_PLUGIN . 's', array() );
if ( isset( $plugins_data[ $slug ] ) ) {
$plugin_data = $plugins_data[ $slug ];
$addon_info['version'] = $plugin_data->version;
$all_plans = self::maybe_get_entities_account_option( 'plans', array() );
if ( isset( $all_plans[ $slug ] ) ) {
$plans = $all_plans[ $slug ];
foreach ( $plans as $plan ) {
if ( $site->plan_id == Freemius::_decrypt( $plan->id ) ) {
$addon_info['plan_name'] = Freemius::_decrypt( $plan->name );
$addon_info['plan_title'] = Freemius::_decrypt( $plan->title );
$licenses = self::maybe_get_entities_account_option( 'all_licenses', array() );
if ( is_array( $licenses ) && isset( $licenses[ $addon_id ] ) ) {
foreach ( $licenses[ $addon_id ] as $license ) {
if ( $license->id == $site->license_id ) {
$addon_info['license'] = $license;
if ( isset( $addon_info['license'] ) ) {
if ( isset( $addon_storage->subscriptions ) &&
! empty( $addon_storage->subscriptions )
$addon_subscriptions = fs_get_entities( $addon_storage->subscriptions, FS_Subscription::get_class_name() );
foreach ( $addon_subscriptions as $subscription ) {
if ( $subscription->license_id == $site->license_id ) {
$addon_info['subscription'] = $subscription;
* @author Vova Feldman (@svovaf)
static function _get_user_by_id( $user_id ) {
self::$_static_logger->entrance( "user_id = {$user_id}" );
$users = self::get_all_users();
if ( is_array( $users ) ) {
if ( isset( $users[ $user_id ] ) &&
$users[ $user_id ] instanceof FS_User &&
$user_id == $users[ $user_id ]->id
return $users[ $user_id ];
// If user wasn't found by the key, iterate over all the users collection.
foreach ( $users as $user ) {
if ( $user_id == $user->id ) {
* Checks if a Freemius user_id is associated with a super-admin.
* @author Vova Feldman (@svovaf)
private static function is_super_admin( $user_id ) {
$user = self::_get_user_by_id( $user_id );
if ( $user instanceof FS_User && ! empty( $user->email ) ) {
self::require_pluggable_essentials();
$wp_user = get_user_by( 'email', $user->email );
if ( $wp_user instanceof WP_User ) {
$super_admins = get_super_admins();
$is_super_admin = ( is_array( $super_admins ) && in_array( $wp_user->user_login, $super_admins ) );