diff --git a/includes/class-freemius.php b/includes/class-freemius.php index 6fc8bd9a..f4249b8f 100755 --- a/includes/class-freemius.php +++ b/includes/class-freemius.php @@ -19869,8 +19869,15 @@ 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 ] ); + + // `_plans` defaults to `false` and is only assigned once the account carries a plan + // list (`_set_account()` skips the assignment when `$plans === false`). On a fresh + // first opt-in of a product without paid plans it can therefore still be `false` here, + // and `count( false )` is a fatal TypeError on PHP 8. Treat a missing list as empty. + $plans_to_encrypt = is_array( $this->_plans ) ? $this->_plans : array(); + + for ( $i = 0, $len = count( $plans_to_encrypt ); $i < $len; $i ++ ) { + $encrypted_plans[] = self::_encrypt_entity( $plans_to_encrypt[ $i ] ); } $plans[ $this->_slug ] = $encrypted_plans; diff --git a/includes/entities/class-fs-site.php b/includes/entities/class-fs-site.php index 9b35f328..c167d7d4 100755 --- a/includes/entities/class-fs-site.php +++ b/includes/entities/class-fs-site.php @@ -120,7 +120,10 @@ function __construct( $site = false ) { parent::__construct( $site ); if ( is_object( $site ) ) { - $this->plan_id = $site->plan_id; + // The install payload can arrive without `plan_id` (e.g. a fresh/new-user + // connection of a product without paid plans), which raised an + // "Undefined property: stdClass::$plan_id" warning on PHP 8. + $this->plan_id = isset( $site->plan_id ) ? $site->plan_id : null; } if ( ! is_bool( $this->is_disconnected ) ) {