From 6f3f9653499ece8766b41c1099f5f32b2b2f6f4f Mon Sep 17 00:00:00 2001 From: hammad-wpbrigade Date: Fri, 17 Jul 2026 12:58:30 +0500 Subject: [PATCH] Fix fatal error on first opt-in when plugin has no paid plans FS_Site::__construct() read \->plan_id without checking the property exists, emitting an ''Undefined property'' warning when the install object returned on first opt-in has no plan_id. _store_plans() then called count() on \->_plans while it was still its initial bool false value, triggering a fatal TypeError on PHP 8+ (count(): Argument #1 must be of type Countable|array, bool given). Guard both: only copy plan_id when set, and only iterate _plans when it is an array. --- includes/class-freemius.php | 6 ++++-- includes/entities/class-fs-site.php | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/includes/class-freemius.php b/includes/class-freemius.php index 6fc8bd9a..1cd9f925 100755 --- a/includes/class-freemius.php +++ b/includes/class-freemius.php @@ -19869,8 +19869,10 @@ private function _store_plans( $store = true ) { // Copy plans. $encrypted_plans = array(); - for ( $i = 0, $len = count( $this->_plans ); $i < $len; $i ++ ) { - $encrypted_plans[] = self::_encrypt_entity( $this->_plans[ $i ] ); + if ( is_array( $this->_plans ) ) { + for ( $i = 0, $len = count( $this->_plans ); $i < $len; $i ++ ) { + $encrypted_plans[] = self::_encrypt_entity( $this->_plans[ $i ] ); + } } $plans[ $this->_slug ] = $encrypted_plans; diff --git a/includes/entities/class-fs-site.php b/includes/entities/class-fs-site.php index 9b35f328..b288b605 100755 --- a/includes/entities/class-fs-site.php +++ b/includes/entities/class-fs-site.php @@ -119,7 +119,7 @@ class FS_Site extends FS_Scope_Entity { function __construct( $site = false ) { parent::__construct( $site ); - if ( is_object( $site ) ) { + if ( is_object( $site ) && isset( $site->plan_id ) ) { $this->plan_id = $site->plan_id; }