: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
#----------------------------------------------------------------------------------
#region Plans & Licensing
#----------------------------------------------------------------------------------
* Check if running premium plugin code.
* @author Vova Feldman (@svovaf)
* `$this->_plugin` will be `false` when `is_activation_mode` calls this method directly from the
* `register_constructor_hooks` method.
* @author Leo Fajardo (@leorw)
return is_object( $this->_plugin ) ?
$this->_plugin->is_premium :
* @author Vova Feldman (@svovaf)
return $this->_site->plan_id;
* @author Vova Feldman (@svovaf)
function get_plan_title() {
$plan = $this->get_plan();
return is_object( $plan ) ? $plan->title : 'PLAN_TITLE';
* @author Vova Feldman (@svovaf)
function get_plan_name() {
$plan = $this->get_plan();
return is_object( $plan ) ? $plan->name : 'PLAN_NAME';
* @author Vova Feldman (@svovaf)
* @return FS_Plugin_Plan|false
if ( ! is_object( $this->_site ) ) {
return FS_Plugin_Plan::is_valid_id( $this->_site->plan_id ) ?
$this->_get_plan_by_id( $this->_site->plan_id ) :
* @author Vova Feldman (@svovaf)
$this->_logger->entrance();
if ( ! $this->is_registered( true ) || ! is_object( $this->_site ) ) {
return $this->_site->is_trial();
* Check if currently in a trial with payment method (credit card or paypal).
* @author Vova Feldman (@svovaf)
function is_paid_trial() {
$this->_logger->entrance();
if ( ! $this->is_trial() ) {
if ( ! $this->has_active_valid_license() ) {
if ( $this->_site->trial_plan_id != $this->_license->plan_id ) {
* @var FS_Subscription $subscription
$subscription = $this->_get_subscription( $this->_license->id );
return ( is_object( $subscription ) && $subscription->is_active() );
* Check if trial already utilized.
function is_trial_utilized() {
$this->_logger->entrance();
if ( ! $this->is_registered() ) {
return $this->_site->is_trial_utilized();
* Get trial plan information (if in trial).
* @author Vova Feldman (@svovaf)
* @return bool|FS_Plugin_Plan
function get_trial_plan() {
$this->_logger->entrance();
if ( ! $this->is_trial() ) {
// Try to load plan from local cache.
$trial_plan = $this->_get_plan_by_id( $this->_site->trial_plan_id );
if ( ! is_object( $trial_plan ) ) {
$trial_plan = $this->_fetch_site_plan( $this->_site->trial_plan_id );
* If managed to fetch the plan, add it to the plans collection.
if ( $trial_plan instanceof FS_Plugin_Plan ) {
if ( ! is_array( $this->_plans ) ) {
$this->_plans[] = $trial_plan;
if ( $trial_plan instanceof FS_Plugin_Plan ) {
* If for some reason failed to get the trial plan, fallback to a dummy name and title.
$trial_plan = new FS_Plugin_Plan();
$trial_plan->id = $this->_site->trial_plan_id;
$trial_plan->name = 'pro';
$trial_plan->title = 'Pro';
* Check if the user has an activate, non-expired license on current plugin's install.
$this->_logger->entrance();
if ( ! $this->is_registered( true ) ) {
if ( ! $this->has_paid_plan() ) {
'free' !== $this->get_plan_name() &&
$this->has_active_valid_license()
* @author Vova Feldman (@svovaf)
function is_free_plan() {
if ( ! $this->is_registered() ) {
if ( ! $this->has_paid_plan() ) {
'free' === $this->get_plan_name() ||
! $this->has_features_enabled_license()
* @author Vova Feldman (@svovaf)
function _has_premium_license() {
$this->_logger->entrance();
$premium_license = $this->_get_available_premium_license();
return ( false !== $premium_license );
* Check if user has any licenses associated with the plugin (including expired or blocking).
* @author Vova Feldman (@svovaf)
* @param bool $including_foreign
function has_any_license( $including_foreign = true ) {
if ( ! is_array( $this->_licenses ) || 0 === count( $this->_licenses ) ) {
if ( $including_foreign ) {
foreach ( $this->_licenses as $license ) {
if ( $this->_user->id == $license->user_id ) {
* @author Vova Feldman (@svovaf)
* @param bool|null $is_localhost
* @return FS_Plugin_License|false
function _get_available_premium_license( $is_localhost = null ) {
$this->_logger->entrance();
$licenses = $this->get_available_premium_licenses( $is_localhost );
if ( ! empty( $licenses ) ) {
* @author Vova Feldman (@svovaf)
* @param bool|null $is_localhost
* @return FS_Plugin_License[]
function get_available_premium_licenses( $is_localhost = null ) {
$this->_logger->entrance();
if ( ! $this->has_paid_plan() ) {
if ( is_array( $this->_licenses ) ) {
foreach ( $this->_licenses as $license ) {
if ( ! $license->can_activate( $is_localhost ) ) {
* Sync local plugin plans with remote server.
* IMPORTANT: If for some reason a site is associated with deleted plan, we'll preserve the plan's information and append it as the last plan. This means that if plan is deleted, the is_plan() method will ALWAYS return true for any given argument (it becomes the most inclusive plan).
* @author Vova Feldman (@svovaf)
* @return FS_Plugin_Plan[]|object
$plans = $this->_fetch_plugin_plans();
if ( $this->is_array_instanceof( $plans, 'FS_Plugin_Plan' ) ) {
foreach ( $plans as $plan ) {
$plans_map[ $plan->id ] = true;
$plans_ids_to_keep = $this->get_plans_ids_associated_with_installs();
foreach ( $plans_ids_to_keep as $plan_id ) {
if ( isset( $plans_map[ $plan_id ] ) ) {
$missing_plan = self::_get_plan_by_id( $plan_id );
if ( is_object( $missing_plan ) ) {
$plans[] = $missing_plan;
$this->do_action( 'after_plans_sync', $plans );
* Check if specified plan exists locally. If not, fetch it and store it.
* @author Vova Feldman (@svovaf)
* @return \FS_Plugin_Plan|object The plan entity or the API error object on failure.
private function sync_plan_if_not_exist( $plan_id ) {
$plan = self::_get_plan_by_id( $plan_id );
if ( is_object( $plan ) ) {
$plan = $this->fetch_plan_by_id( $plan_id );
if ( $plan instanceof FS_Plugin_Plan ) {
* Check if specified license exists locally. If not, fetch it and store it.
* @author Vova Feldman (@svovaf)
* @param number $license_id
* @param string $license_key
* @return \FS_Plugin_Plan|object The plan entity or the API error object on failure.
private function sync_license_if_not_exist( $license_id, $license_key ) {
$license = $this->_get_license_by_id( $license_id );
if ( is_object( $license ) ) {
// License already exists.
$license = $this->fetch_license_by_key( $license_id, $license_key );
if ( $license instanceof FS_Plugin_License ) {
$this->_licenses[] = $license;
$this->set_license( $license );
$this->_store_licenses();
* Get a collection of unique plan IDs that are associated with any installs in the network.
* @author Leo Fajardo (@leorw)
private function get_plans_ids_associated_with_installs() {
if ( ! is_multisite() ) {
if ( ! is_object( $this->_site ) ||
! FS_Plugin_Plan::is_valid_id( $this->_site->plan_id )
return array( $this->_site->plan_id );
$sites = self::get_sites();
foreach ( $sites as $site ) {
$blog_id = self::get_site_blog_id( $site );
$install = $this->get_install_by_blog_id( $blog_id );
if ( ! is_object( $install ) ||
! FS_Plugin_Plan::is_valid_id( $install->plan_id )
$plan_ids[ $install->plan_id ] = true;
return array_keys( $plan_ids );
* Get a collection of unique license IDs that are associated with any installs in the network.
* @author Leo Fajardo (@leorw)
private function get_license_ids_associated_with_installs() {
if ( ! $this->_is_network_active ) {
if ( ! is_object( $this->_site ) ||
! FS_Plugin_License::is_valid_id( $this->_site->license_id )
return array( $this->_site->license_id );
$sites = self::get_sites();
foreach ( $sites as $site ) {
$blog_id = self::get_site_blog_id( $site );
$install = $this->get_install_by_blog_id( $blog_id );
if ( ! is_object( $install ) ||
! FS_Plugin_License::is_valid_id( $install->license_id )