From 71ea770c1bfde5b281377a1fe6dfabb98a1b007b Mon Sep 17 00:00:00 2001 From: Laurence Bahiirwa Date: Thu, 21 Dec 2023 13:58:23 +0300 Subject: [PATCH 01/12] [static-analysis] Remove extra argument in the invoke of the function. 2 parameters given but 1 required. --- includes/class-freemius.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-freemius.php b/includes/class-freemius.php index 4512b47a..54066fa3 100755 --- a/includes/class-freemius.php +++ b/includes/class-freemius.php @@ -2745,7 +2745,7 @@ function cancel_subscription_or_trial_ajax_action() { $this->check_ajax_referer( 'cancel_subscription_or_trial' ); - $result = $this->cancel_subscription_or_trial( fs_request_get( 'plugin_id', $this->get_id() ), false ); + $result = $this->cancel_subscription_or_trial( fs_request_get( 'plugin_id', $this->get_id() ) ); if ( $this->is_api_error( $result ) ) { $this->shoot_ajax_failure( $result->error->message ); From 921804ba632b5efc6991f8adf2be46559d8ed5c8 Mon Sep 17 00:00:00 2001 From: Laurence Bahiirwa Date: Thu, 21 Dec 2023 14:21:15 +0300 Subject: [PATCH 02/12] [static-analysis] Fix out of block defined variables. Some of the variables are misnamed in code that follows. --- includes/class-freemius.php | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/includes/class-freemius.php b/includes/class-freemius.php index 54066fa3..d09880b2 100755 --- a/includes/class-freemius.php +++ b/includes/class-freemius.php @@ -13956,15 +13956,15 @@ private function get_parent_and_addons_installs_info() { $this->get_parent_instance() : $this; - $installed_addons_ids = array(); + $installed_addons_ids_map = array(); $installed_addons_instances = $fs->get_installed_addons(); foreach ( $installed_addons_instances as $instance ) { - $installed_addons_ids[] = $instance->get_id(); + $installed_addons_ids_map[] = $instance->get_id(); } $addons_ids = array_unique( array_merge( - $installed_addons_ids, + $installed_addons_ids_map, $fs->get_updated_account_addons() ) ); @@ -14011,7 +14011,8 @@ function _network_activate_ajax_action() { $this : $this->get_addon_instance( $plugin_id ); - $error = false; + $error = false; + $next_page = ''; $sites = fs_request_get( 'sites', array(), 'post' ); if ( is_array( $sites ) && ! empty( $sites ) ) { @@ -14027,10 +14028,7 @@ function _network_activate_ajax_action() { $total_sites = count( $sites ); $total_sites_to_delegate = count( $sites_by_action['delegate'] ); - - $next_page = ''; - - $has_any_install = fs_request_get_bool( 'has_any_install' ); + $has_any_install = fs_request_get_bool( 'has_any_install' ); if ( $total_sites === $total_sites_to_delegate && ! $this->is_network_upgrade_mode() && From 09c5c4dde3cb1bff1fb42d88f03abd9188b5aead Mon Sep 17 00:00:00 2001 From: Laurence Bahiirwa Date: Thu, 21 Dec 2023 14:35:50 +0300 Subject: [PATCH 03/12] [static-analysis] Remove extra argument not required in the function invocation. --- includes/managers/class-fs-admin-menu-manager.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/includes/managers/class-fs-admin-menu-manager.php b/includes/managers/class-fs-admin-menu-manager.php index f4d3f0b8..1c7b160a 100644 --- a/includes/managers/class-fs-admin-menu-manager.php +++ b/includes/managers/class-fs-admin-menu-manager.php @@ -321,8 +321,7 @@ function is_submenu_item_visible( $id, $default = true, $ignore_menu_existence = return fs_apply_filter( $this->_module_unique_affix, 'is_submenu_visible', - $this->get_bool_option( $this->_default_submenu_items, $id, $default ), - $id + $this->get_bool_option( $this->_default_submenu_items, $id, $default ) ); } From 525aa6fa8fb80df276a3a5bfb3e2893e7db312d8 Mon Sep 17 00:00:00 2001 From: Laurence Bahiirwa Date: Mon, 15 Jan 2024 21:31:20 +0300 Subject: [PATCH 04/12] [static-analysis] Fix undeclared variables errors. --- templates/account.php | 9 +++--- templates/account/partials/addon.php | 4 +-- templates/account/partials/site.php | 6 ++-- templates/debug.php | 23 ++++++++------- templates/forms/affiliation.php | 43 ++++++++++++++-------------- 5 files changed, 45 insertions(+), 40 deletions(-) diff --git a/templates/account.php b/templates/account.php index 89120022..9adb6ce7 100755 --- a/templates/account.php +++ b/templates/account.php @@ -468,10 +468,11 @@ class="dashicons dashicons-image-rotate"> get_module_type() ) : '' ); if ( $show_plan_row ) { $profile[] = array( 'id' => 'plan', - 'title' => ( $has_bundle_license ? ucfirst( $fs->get_module_type() ) . ' ' : '' ) . $plan_text, + 'title' => $bundle_title . ' ' . $plan_text, 'value' => strtoupper( is_string( $plan->name ) ? $plan->title : strtoupper( $free_text ) @@ -482,7 +483,7 @@ class="dashicons dashicons-image-rotate"> 'bundle_plan', 'title' => $bundle_plan_text, - 'value' => $bundle_plan_title + 'value' => $bundle_title ); } } @@ -870,8 +871,8 @@ class="fs-tag fs-can_use_premium_code() ? 'success' : 'warn' ?>" $VARS['id'], 'payments' => $payments ); - fs_require_once_template( 'account/billing.php', $view_params ); + $view_params = array( 'id' => $VARS['id'], 'payments' => $payments ); // @phpstan-ignore-line + fs_require_once_template( 'account/billing.php', $view_params ); fs_require_once_template( 'account/payments.php', $view_params ); } ?> diff --git a/templates/account/partials/addon.php b/templates/account/partials/addon.php index af9b94c2..bba624da 100644 --- a/templates/account/partials/addon.php +++ b/templates/account/partials/addon.php @@ -158,11 +158,11 @@ - + - + diff --git a/templates/account/partials/site.php b/templates/account/partials/site.php index 0be1440a..5e90522d 100644 --- a/templates/account/partials/site.php +++ b/templates/account/partials/site.php @@ -323,13 +323,13 @@ class="dashicons dashicons-arrow-right-alt2"> $downgrade_confirmation_message = sprintf( $downgrade_x_confirm_text, ( $fs->is_only_premium() ? $cancelling_subscription_text : $downgrading_plan_text ), - $plan->title, + $plan_title, $human_readable_license_expiration ); $after_downgrade_message = ! $license->is_block_features ? - sprintf( $after_downgrade_non_blocking_text, $plan->title, $fs->get_module_label( true ) ) : - sprintf( $after_downgrade_blocking_text, $plan->title ); + sprintf( $after_downgrade_non_blocking_text, $plan_title, $fs->get_module_label( true ) ) : + sprintf( $after_downgrade_blocking_text, $plan_title ); ?>
diff --git a/templates/debug.php b/templates/debug.php index b45a6ff5..cea5a13a 100644 --- a/templates/debug.php +++ b/templates/debug.php @@ -355,22 +355,25 @@ function stopCountdownManually() { } ?> id ); + $fs = freemius( $data->id ); + $has_api_connectivity = $fs->has_api_connectivity(); $active_modules_by_id[ $data->id ] = true; } ?> - has_api_connectivity(); - - if ( true === $has_api_connectivity && $fs->is_on() ) { - echo ' style="background: #E6FFE6; font-weight: bold"'; - } else { - echo ' style="background: #ffd0d0; font-weight: bold"'; + is_on() ) { + echo 'style="background: #E6FFE6; font-weight: bold"'; + } else { + echo 'style="background: #ffd0d0; font-weight: bold"'; + } } - } ?>> + ?>> id ?> version ?> diff --git a/templates/forms/affiliation.php b/templates/forms/affiliation.php index 428691ab..6f5d3867 100644 --- a/templates/forms/affiliation.php +++ b/templates/forms/affiliation.php @@ -121,28 +121,29 @@ ?>

- is_suspended() ) { - $message_text = fs_text_inline( 'Your affiliation account was temporarily suspended.', 'affiliate-account-suspended', $slug ); - $message_container_class = 'notice notice-warning'; - } else if ( $affiliate->is_rejected() ) { - $message_text = fs_text_inline( "Thank you for applying for our affiliate program, unfortunately, we've decided at this point to reject your application. Please try again in 30 days.", 'affiliate-application-rejected', $slug ); - $message_container_class = 'error'; - } else if ( $affiliate->is_blocked() ) { - $message_text = fs_text_inline( 'Due to violation of our affiliation terms, we decided to temporarily block your affiliation account. If you have any questions, please contact support.', 'affiliate-account-blocked', $slug ); - $message_container_class = 'error'; - } - ?> -
-

-
- + is_suspended() ) { + $message_text = fs_text_inline( 'Your affiliation account was temporarily suspended.', 'affiliate-account-suspended', $slug ); + $message_container_class = 'notice notice-warning'; + } else if ( $affiliate->is_rejected() ) { + $message_text = fs_text_inline( "Thank you for applying for our affiliate program, unfortunately, we've decided at this point to reject your application. Please try again in 30 days.", 'affiliate-application-rejected', $slug ); + $message_container_class = 'error'; + } else if ( $affiliate->is_blocked() ) { + $message_text = fs_text_inline( 'Due to violation of our affiliation terms, we decided to temporarily block your affiliation account. If you have any questions, please contact support.', 'affiliate-account-blocked', $slug ); + $message_container_class = 'error'; + } + ?> +
+

+
+
From 87c37e6f108ed7ef5c56432097e83e33585f86b6 Mon Sep 17 00:00:00 2001 From: Laurence Bahiirwa Date: Mon, 15 Jan 2024 21:31:56 +0300 Subject: [PATCH 05/12] [static-analysis] Fix truthy/false statements. --- includes/class-freemius.php | 9 +++++---- includes/class-fs-plugin-updater.php | 3 ++- includes/fs-plugin-info-dialog.php | 2 +- includes/managers/class-fs-admin-menu-manager.php | 12 ++++-------- templates/account.php | 2 +- 5 files changed, 13 insertions(+), 15 deletions(-) diff --git a/includes/class-freemius.php b/includes/class-freemius.php index d09880b2..f037f404 100755 --- a/includes/class-freemius.php +++ b/includes/class-freemius.php @@ -7688,6 +7688,7 @@ private function maybe_network_activate_addon_license( $license = null ) { } } + // @phpstan-ignore-next-line if ( ! empty( $site_ids ) ) { $this->activate_license_on_many_sites( $user, $license->secret_key, $site_ids ); } @@ -8183,7 +8184,7 @@ function _deactivate_plugin_hook() { unset( $this->_storage->sticky_optin_added_ms ); } - if ( ! empty( $storage_keys_for_removal ) ) { + if ( count( $storage_keys_for_removal ) > 0 ) { $sites = self::get_sites(); foreach ( $sites as $site ) { @@ -13757,7 +13758,7 @@ private function activate_license( $result = $fs->activate_license_on_many_installs( $user, $license_key, $blog_2_install_map ); } - if ( true === $result && ! empty( $site_ids ) ) { + if ( true === $result && count( $site_ids ) > 0 ) { $result = $fs->activate_license_on_many_sites( $user, $license_key, $site_ids ); } } else { @@ -19640,7 +19641,7 @@ private function _store_site( $store = true, $network_level_or_blog_id = null, F $site = $this->_site; } - if ( !isset( $site ) || !is_object($site) || empty( $site->id ) ) { + if ( !is_object($site) || empty( $site->id ) ) { $this->_logger->error( "Empty install ID, can't store site." ); return; @@ -19774,7 +19775,7 @@ private function _store_licenses( $store = true, $module_id = false, $licenses = } } - if ( ! empty( $new_user_licenses_map ) ) { + if ( count( $new_user_licenses_map ) > 0 ) { // Add new licenses. $all_licenses[ $module_id ] = array_merge( array_values( $new_user_licenses_map ), $all_licenses[ $module_id ] ); } diff --git a/includes/class-fs-plugin-updater.php b/includes/class-fs-plugin-updater.php index dc233da4..5f76e114 100755 --- a/includes/class-fs-plugin-updater.php +++ b/includes/class-fs-plugin-updater.php @@ -534,6 +534,7 @@ function pre_set_site_transient_update_plugins_filter( $transient_data ) { return $transient_data; } + // @phpstan-ignore-next-line if ( empty( $transient_data ) || defined( 'WP_FS__UNINSTALL_MODE' ) ) { @@ -1093,7 +1094,7 @@ function plugins_api_filter( $data, $action = '', $args = null ) { false ); - if ( ! empty( $addon_plugin_data ) ) { + if ( is_array( $addon_plugin_data ) && $addon_plugin_data['Version'] ) { $addon_version = $addon_plugin_data['Version']; } } diff --git a/includes/fs-plugin-info-dialog.php b/includes/fs-plugin-info-dialog.php index 69bb6ce4..a0539e4c 100755 --- a/includes/fs-plugin-info-dialog.php +++ b/includes/fs-plugin-info-dialog.php @@ -229,7 +229,7 @@ function _get_addon_info_filter( $data, $action = '', $args = null ) { false ); - if ( ! empty( $addon_plugin_data ) ) { + if ( is_array( $addon_plugin_data ) && $addon_plugin_data['Version'] ) { $current_addon_version = $addon_plugin_data['Version']; } } diff --git a/includes/managers/class-fs-admin-menu-manager.php b/includes/managers/class-fs-admin-menu-manager.php index 1c7b160a..00ad4346 100644 --- a/includes/managers/class-fs-admin-menu-manager.php +++ b/includes/managers/class-fs-admin-menu-manager.php @@ -154,7 +154,7 @@ private function get_bool_option( &$options, $key, $default = false ) { * @param bool $is_addon */ function init( $menu, $is_addon = false ) { - $this->_menu_exists = ( isset( $menu['slug'] ) && ! empty( $menu['slug'] ) ); + $this->_menu_exists = ( ! empty( $menu['slug'] ) ); $this->_network_menu_exists = ( ! empty( $menu['network'] ) && true === $menu['network'] ); $this->_menu_slug = ( $this->_menu_exists ? $menu['slug'] : $this->_module_unique_affix ); @@ -168,7 +168,7 @@ function init( $menu, $is_addon = false ) { // @deprecated $this->_parent_type = 'page'; - if ( isset( $menu ) ) { + if ( is_array( $menu ) ) { if ( ! $is_addon ) { $this->_default_submenu_items = array( 'contact' => $this->get_bool_option( $menu, 'contact', true ), @@ -318,12 +318,8 @@ function is_submenu_item_visible( $id, $default = true, $ignore_menu_existence = return false; } - return fs_apply_filter( - $this->_module_unique_affix, - 'is_submenu_visible', - $this->get_bool_option( $this->_default_submenu_items, $id, $default ) - ); - } + return fs_apply_filter( $this->_module_unique_affix, 'is_submenu_visible', $this->get_bool_option( $this->_default_submenu_items, $id, $default ), $id ); // @phpstan-ignore-line + } /** * Calculates admin settings menu slug. diff --git a/templates/account.php b/templates/account.php index 9adb6ce7..66f19c6c 100755 --- a/templates/account.php +++ b/templates/account.php @@ -157,7 +157,7 @@ $site_view_params[] = $view_params; - if ( empty( $install ) ) { + if ( null === $install ) { continue; } From 3bfd75727278477127ac035642ab70a579710952 Mon Sep 17 00:00:00 2001 From: Laurence Bahiirwa Date: Mon, 15 Jan 2024 21:32:26 +0300 Subject: [PATCH 06/12] [static-analysis] Bump PHP stan checks to version 1 passing. --- phpstan.neon | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 02b7cc4b..fe3aa1ab 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,5 +1,5 @@ parameters: - level: 0 + level: 1 paths: - config.php - start.php @@ -11,4 +11,8 @@ parameters: ignoreErrors: - message: '#will always evaluate to true#' - path: includes/class-fs-plugin-updater.php \ No newline at end of file + path: includes/class-fs-plugin-updater.php + - + message: '#Variable \$VARS might not be defined#' + paths: + - templates/* From a19788fa49f72ae8616e5b2cc0b55593085d7d10 Mon Sep 17 00:00:00 2001 From: Laurence Bahiirwa Date: Tue, 16 Jan 2024 11:10:09 +0300 Subject: [PATCH 07/12] [code-convention] Maintain the coding standard. --- includes/managers/class-fs-admin-menu-manager.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/includes/managers/class-fs-admin-menu-manager.php b/includes/managers/class-fs-admin-menu-manager.php index 00ad4346..904cf3df 100644 --- a/includes/managers/class-fs-admin-menu-manager.php +++ b/includes/managers/class-fs-admin-menu-manager.php @@ -318,7 +318,13 @@ function is_submenu_item_visible( $id, $default = true, $ignore_menu_existence = return false; } - return fs_apply_filter( $this->_module_unique_affix, 'is_submenu_visible', $this->get_bool_option( $this->_default_submenu_items, $id, $default ), $id ); // @phpstan-ignore-line + // @phpstan-ignore-next-line + return fs_apply_filter( + $this->_module_unique_affix, + 'is_submenu_visible', + $this->get_bool_option( $this->_default_submenu_items, $id, $default ), + $id + ); } /** From 37ed17df8ac3645b6ffb3b475e44e5301519a340 Mon Sep 17 00:00:00 2001 From: Laurence Bahiirwa Date: Tue, 9 Apr 2024 12:10:06 +0300 Subject: [PATCH 08/12] [static-analysis] Fix php errors from static analysis --- includes/class-freemius.php | 31 +++++++------------ includes/class-fs-plugin-updater.php | 20 ++++++------ includes/entities/class-fs-entity.php | 4 +-- includes/fs-core-functions.php | 4 +-- includes/fs-essential-functions.php | 2 +- includes/fs-plugin-info-dialog.php | 4 +-- includes/managers/class-fs-cache-manager.php | 3 +- .../managers/class-fs-permission-manager.php | 2 +- phpstan.neon | 16 +++++++++- templates/add-ons.php | 6 ++-- templates/plugin-info/features.php | 4 ++- 11 files changed, 53 insertions(+), 43 deletions(-) diff --git a/includes/class-freemius.php b/includes/class-freemius.php index f037f404..fe8e0e2f 100755 --- a/includes/class-freemius.php +++ b/includes/class-freemius.php @@ -996,7 +996,7 @@ private static function migrate_install_plan_to_plan_id( FS_Storage $storage, $b if ( isset( $install->plan ) && is_object( $install->plan ) ) { if ( isset( $install->plan->id ) && ! empty( $install->plan->id ) ) { - $install->plan_id = self::_decrypt( $install->plan->id ); + $install->plan_id = self::_decrypt( $install->plan->id ); // @phpstan-ignore-line } unset( $install->plan ); @@ -1891,7 +1891,7 @@ private function clear_module_main_file_cache( $store_prev_path = true ) { $plugin_main_file = clone $this->_storage->plugin_main_file; // Store cached path (2nd layer cache). - $plugin_main_file->prev_path = $plugin_main_file->path; + $plugin_main_file->prev_path = $plugin_main_file->path; // @phpstan-ignore-line // Clear cached path. unset( $plugin_main_file->path ); @@ -5960,9 +5960,6 @@ function is_org_repo_compliant() { private function get_cron_data( $name ) { $this->_logger->entrance( $name ); - /** - * @var object $cron_data - */ return $this->_storage->get( "{$name}_cron", null ); } @@ -8594,7 +8591,6 @@ function skip_connection( $network_or_blog_ids = false ) { * @since 2.0.0 * * @param int|null $blog_id - * @param bool $send_skip */ private function skip_site_connection( $blog_id = null ) { $this->_logger->entrance(); @@ -8628,7 +8624,7 @@ private function update_plugin_version_event() { * @author Vova Feldman (@svovaf) * @since 2.0.0 * - * @param array [string]array $plugins + * @param string[] $plugins * * @return string */ @@ -9043,7 +9039,7 @@ private function get_install_data_for_api( * @author Vova Feldman (@svovaf) * @since 2.0.0 * - * @param string[] string $override + * @param string[] $override * @param bool $only_diff * @param bool $is_keepalive * @param bool $include_plugins Since 1.1.8 by default include plugin changes. @@ -9230,7 +9226,7 @@ private function get_installs_data_for_api( * * @param array $site * @param FS_Site $install - * @param string[] string $override + * @param string[] $override * * @return array */ @@ -9352,7 +9348,7 @@ function send_clone_resolution_update( $resolution_type, $clone_context_install * @author Vova Feldman (@svovaf) * @since 1.0.9 * - * @param string[] string $override + * @param string[] $override * @param bool $flush * @param bool $is_two_way_sync @since 2.5.0 If true and there's a successful API request, the install sync cron will be cleared. * @@ -9425,7 +9421,7 @@ private function send_install_update( $override = array(), $flush = false, $is_t * @author Vova Feldman (@svovaf) * @since 2.0.0 * - * @param string[] string $override + * @param string[] $override * @param bool $flush * @param bool $is_two_way_sync @since 2.5.0 If true and there's a successful API request, the install sync cron will be cleared. * @@ -9512,7 +9508,7 @@ private function maybe_sync_install_user() { * @author Vova Feldman (@svovaf) * @since 1.0.9 * - * @param string[] string $override + * @param string[] $override * @param bool $flush */ function sync_install( $override = array(), $flush = false ) { @@ -9541,7 +9537,7 @@ function sync_install( $override = array(), $flush = false ) { * @author Vova Feldman (@svovaf) * @since 1.0.9 * - * @param string[] string $override + * @param string[] $override * @param bool $flush */ private function sync_installs( $override = array(), $flush = false ) { @@ -19614,7 +19610,7 @@ function has_filter( $tag, $function_to_check = false ) { * @author Vova Feldman (@svovaf) * @since 1.1.6 * - * @param string[] string $key_value + * @param string[] $key_value * * @uses fs_override_i18n() */ @@ -22575,8 +22571,8 @@ private function complete_change_owner() { * @author Leo Fajardo (@leorw) * @since 2.3.2 * - * @param number $user_id - * @param array[string]number $install_ids_by_slug_map + * @param number $user_id + * @param string[]|int[] $install_ids_by_slug_map * */ private function complete_ownership_change_by_license( $user_id, $install_ids_by_slug_map ) { @@ -25777,9 +25773,6 @@ function _maybe_show_gdpr_admin_notice() { return; } - /** - * @var $current_wp_user WP_User - */ $current_wp_user = self::_get_current_wp_user(); /** diff --git a/includes/class-fs-plugin-updater.php b/includes/class-fs-plugin-updater.php index 5f76e114..3e02893a 100755 --- a/includes/class-fs-plugin-updater.php +++ b/includes/class-fs-plugin-updater.php @@ -1115,11 +1115,9 @@ function plugins_api_filter( $data, $action = '', $args = null ) { // Fetch as much as possible info from local files. $plugin_local_data = $this->_fs->get_plugin_data(); - $data->name = $plugin_local_data['Name']; - $data->author = $plugin_local_data['Author']; - $data->sections = array( - 'description' => 'Upgrade ' . $plugin_local_data['Name'] . ' to latest.', - ); + $data->name = $plugin_local_data['Name']; // @phpstan-ignore-line + $data->author = $plugin_local_data['Author']; // @phpstan-ignore-line + $data->sections = array( 'description' => 'Upgrade ' . $plugin_local_data['Name'] . ' to latest.' ); // @phpstan-ignore-line // @todo Store extra plugin info on Freemius or parse readme.txt markup. /*$info = $this->_fs->get_api_site_scope()->call('/information.json'); @@ -1143,18 +1141,18 @@ function plugins_api_filter( $data, $action = '', $args = null ) { $data->name = $addon->title . ' ' . $this->_fs->get_text_inline( 'Add-On', 'addon' ); $data->slug = $addon->slug; $data->url = WP_FS__ADDRESS; - $data->package = $new_version->url; + $data->package = $new_version->url; // @phpstan-ignore-line } if ( ! $plugin_in_repo ) { - $data->last_updated = ! is_null( $new_version->updated ) ? $new_version->updated : $new_version->created; - $data->requires = $new_version->requires_platform_version; - $data->requires_php = $new_version->requires_programming_language_version; - $data->tested = $new_version->tested_up_to_version; + $data->last_updated = ! is_null( $new_version->updated ) ? $new_version->updated : $new_version->created; // @phpstan-ignore-line + $data->requires = $new_version->requires_platform_version; // @phpstan-ignore-line + $data->requires_php = $new_version->requires_programming_language_version; // @phpstan-ignore-line + $data->tested = $new_version->tested_up_to_version; // @phpstan-ignore-line } $data->version = $new_version->version; - $data->download_link = $new_version->url; + $data->download_link = $new_version->url; // @phpstan-ignore-line if ( isset( $new_version->readme ) && is_object( $new_version->readme ) ) { $new_version_readme_data = $new_version->readme; diff --git a/includes/entities/class-fs-entity.php b/includes/entities/class-fs-entity.php index ce281f45..735cbb02 100755 --- a/includes/entities/class-fs-entity.php +++ b/includes/entities/class-fs-entity.php @@ -88,8 +88,8 @@ static function equals( $entity1, $entity2 ) { * @author Vova Feldman (@svovaf) * @since 1.0.9 * - * @param string|array[string]mixed $key - * @param string|bool $val + * @param array|string[] $key + * @param string|bool $val * * @return bool */ diff --git a/includes/fs-core-functions.php b/includes/fs-core-functions.php index 09bb0b48..283953fb 100755 --- a/includes/fs-core-functions.php +++ b/includes/fs-core-functions.php @@ -1389,8 +1389,8 @@ function fs_esc_html_echo_inline( $text, $key = '', $slug = 'freemius' ) { * @author Vova Feldman (@svovaf) * @since 1.1.6 * - * @param array[string]string $key_value - * @param string $slug + * @param array|string[] $key_value + * @param string $slug * * @global $fs_text_overrides */ diff --git a/includes/fs-essential-functions.php b/includes/fs-essential-functions.php index 84ffcbe0..b9f7301e 100644 --- a/includes/fs-essential-functions.php +++ b/includes/fs-essential-functions.php @@ -264,7 +264,7 @@ function fs_update_sdk_newest_version( $sdk_relative_path, $plugin_file = false $in_activation = ( ! is_plugin_active( $plugin_file ) ); } else { $theme = wp_get_theme(); - $in_activation = ( $newest_sdk->plugin_path == $theme->stylesheet ); + $in_activation = ( $newest_sdk->plugin_path == $theme->stylesheet ); // @phpstan-ignore-line } $fs_active_plugins->newest = (object) array( diff --git a/includes/fs-plugin-info-dialog.php b/includes/fs-plugin-info-dialog.php index a0539e4c..7183a71c 100755 --- a/includes/fs-plugin-info-dialog.php +++ b/includes/fs-plugin-info-dialog.php @@ -527,7 +527,7 @@ private function get_checkout_cta( $api, $plan = null ) { $plan->plugin_id, $plan->pricing[0]->id, $this->get_billing_cycle( $plan ), - $plan->has_trial(), + $plan->has_trial(), // @phpstan-ignore-line ( $has_valid_blog_id ? false : null ) ); @@ -536,7 +536,7 @@ private function get_checkout_cta( $api, $plan = null ) { } return '' . - esc_html( ! $plan->has_trial() ? + esc_html( ! $plan->has_trial() ? // @phpstan-ignore-line ( $api->has_purchased_license ? fs_text_inline( 'Purchase More', 'purchase-more', $api->slug ) : diff --git a/includes/managers/class-fs-cache-manager.php b/includes/managers/class-fs-cache-manager.php index 7f2d850c..0bde407b 100755 --- a/includes/managers/class-fs-cache-manager.php +++ b/includes/managers/class-fs-cache-manager.php @@ -166,7 +166,8 @@ function get( $key, $default = null ) { isset( $cache_entry->timestamp ) && is_numeric( $cache_entry->timestamp ) ) { - return $cache_entry->result; + return $cache_entry->result; // @phpstan-ignore-line + } return is_object( $default ) ? clone $default : $default; diff --git a/includes/managers/class-fs-permission-manager.php b/includes/managers/class-fs-permission-manager.php index 4fff146a..bbf632ec 100644 --- a/includes/managers/class-fs-permission-manager.php +++ b/includes/managers/class-fs-permission-manager.php @@ -638,7 +638,7 @@ function render_permissions_group( array $permissions_group ) { fs_require_template( 'connect/permissions-group.php', $permissions_group ); } - function require_permissions_js() { + function require_permissions_js( $params ) { fs_require_once_template( 'js/permissions.php', $params ); } diff --git a/phpstan.neon b/phpstan.neon index fe3aa1ab..2063c9e1 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,5 +1,5 @@ parameters: - level: 1 + level: 2 paths: - config.php - start.php @@ -9,6 +9,20 @@ parameters: bootstrapFiles: - .phpstan/exceptions.php ignoreErrors: + - + message: '#PHPDoc tag @var has invalid value#' + path: includes/managers/class-fs-plugin-manager.php + - + message: '#PHPDoc tag @use has invalid value#' + path: includes/class-freemius.php + - + message: '#PHPDoc tag @var above a method has no effect.#' + path: includes/class-freemius.php + - + message: '#Access to an undefined property#' + paths: + - includes/class-freemius.php + - includes/fs-plugin-info-dialog.php - message: '#will always evaluate to true#' path: includes/class-fs-plugin-updater.php diff --git a/templates/add-ons.php b/templates/add-ons.php index 77329799..6534d9bc 100755 --- a/templates/add-ons.php +++ b/templates/add-ons.php @@ -141,9 +141,11 @@ continue; } - $has_paid_plan = true; - $has_trial = $has_trial || ( is_numeric( $plan->trial_period ) && ( $plan->trial_period > 0 ) ); + + if ( isset( $plan->trial_period ) ) { + $has_trial = ( is_numeric( $plan->trial_period ) && ( $plan->trial_period > 0 ) ); + } $min_price = 999999; foreach ( $plan->pricing as $pricing ) { diff --git a/templates/plugin-info/features.php b/templates/plugin-info/features.php index 62256fda..8f316ccb 100644 --- a/templates/plugin-info/features.php +++ b/templates/plugin-info/features.php @@ -27,7 +27,9 @@ $features_plan_map[ $feature->id ] = array( 'feature' => $feature, 'plans' => array() ); } - $features_plan_map[ $feature->id ]['plans'][ $plan->id ] = $feature; + if ( ! empty( $plan->id ) ) { + $features_plan_map[ $feature->id ]['plans'][ $plan->id ] = $feature; + } } } From e4040cbe888a21772b5f8a61e51f619ad307feca Mon Sep 17 00:00:00 2001 From: Laurence Bahiirwa Date: Tue, 16 Apr 2024 19:13:36 +0300 Subject: [PATCH 09/12] [static-analysis] Fix php errors from static analysis. --- includes/class-freemius.php | 7 ++++--- includes/class-fs-plugin-updater.php | 2 +- includes/fs-plugin-info-dialog.php | 2 +- templates/account.php | 8 ++++---- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/includes/class-freemius.php b/includes/class-freemius.php index fe8e0e2f..a725028c 100755 --- a/includes/class-freemius.php +++ b/includes/class-freemius.php @@ -13953,15 +13953,15 @@ private function get_parent_and_addons_installs_info() { $this->get_parent_instance() : $this; - $installed_addons_ids_map = array(); + $installed_addons_ids = array(); $installed_addons_instances = $fs->get_installed_addons(); foreach ( $installed_addons_instances as $instance ) { - $installed_addons_ids_map[] = $instance->get_id(); + $installed_addons_ids[] = $instance->get_id(); } $addons_ids = array_unique( array_merge( - $installed_addons_ids_map, + $installed_addons_ids, $fs->get_updated_account_addons() ) ); @@ -13973,6 +13973,7 @@ private function get_parent_and_addons_installs_info() { ) ); + $installed_addons_ids_map = array_flip( $installed_addons_ids ); foreach ( $addons_ids as $addon_id ) { $is_installed = isset( $installed_addons_ids_map[ $addon_id ] ); diff --git a/includes/class-fs-plugin-updater.php b/includes/class-fs-plugin-updater.php index 3e02893a..67bf3272 100755 --- a/includes/class-fs-plugin-updater.php +++ b/includes/class-fs-plugin-updater.php @@ -1094,7 +1094,7 @@ function plugins_api_filter( $data, $action = '', $args = null ) { false ); - if ( is_array( $addon_plugin_data ) && $addon_plugin_data['Version'] ) { + if ( is_array( $addon_plugin_data ) && isset( $addon_plugin_data['Version'] ) ) { $addon_version = $addon_plugin_data['Version']; } } diff --git a/includes/fs-plugin-info-dialog.php b/includes/fs-plugin-info-dialog.php index 7183a71c..a57d348a 100755 --- a/includes/fs-plugin-info-dialog.php +++ b/includes/fs-plugin-info-dialog.php @@ -229,7 +229,7 @@ function _get_addon_info_filter( $data, $action = '', $args = null ) { false ); - if ( is_array( $addon_plugin_data ) && $addon_plugin_data['Version'] ) { + if ( is_array( $addon_plugin_data ) && isset( $addon_plugin_data['Version'] ) ) { $current_addon_version = $addon_plugin_data['Version']; } } diff --git a/templates/account.php b/templates/account.php index 66f19c6c..fcd34710 100755 --- a/templates/account.php +++ b/templates/account.php @@ -157,7 +157,7 @@ $site_view_params[] = $view_params; - if ( null === $install ) { + if ( is_object( $install ) ) { continue; } @@ -186,6 +186,7 @@ $bundle_subscription = null; $is_bundle_first_payment_pending = false; + $bundle_plan_title = ''; if ( $show_plan_row && @@ -468,11 +469,10 @@ class="dashicons dashicons-image-rotate"> get_module_type() ) : '' ); if ( $show_plan_row ) { $profile[] = array( 'id' => 'plan', - 'title' => $bundle_title . ' ' . $plan_text, + 'title' => ( $has_bundle_license ? ucfirst( $fs->get_module_type() ) . ' ' : '' ) . $plan_text, 'value' => strtoupper( is_string( $plan->name ) ? $plan->title : strtoupper( $free_text ) @@ -483,7 +483,7 @@ class="dashicons dashicons-image-rotate"> 'bundle_plan', 'title' => $bundle_plan_text, - 'value' => $bundle_title + 'value' => $bundle_plan_title ); } } From c7ba0820c794cc7d33825d094416a7ff2b774624 Mon Sep 17 00:00:00 2001 From: Laurence Bahiirwa Date: Sun, 8 Sep 2024 18:23:59 +0300 Subject: [PATCH 10/12] [static-analysis] Fixes PHPStan errors minus - access to an undefined property object. --- .../includes/entities/class-fs-entity.php | 93 ++++++++ .../stubs/includes/fs-plugin-info-dialog.php | 129 ++++++++++++ includes/class-freemius.php | 103 +++++---- includes/class-fs-plugin-updater.php | 34 ++- includes/class-fs-storage.php | 198 ++++++++++++++++++ includes/entities/class-fs-entity.php | 6 +- includes/fs-core-functions.php | 4 +- includes/fs-essential-functions.php | 4 +- includes/fs-plugin-info-dialog.php | 14 +- .../managers/class-fs-admin-menu-manager.php | 2 +- includes/managers/class-fs-cache-manager.php | 5 +- includes/managers/class-fs-debug-manager.php | 5 + includes/managers/class-fs-plugin-manager.php | 8 +- phpstan.neon | 29 ++- templates/account.php | 14 +- templates/account/partials/addon.php | 8 +- templates/add-ons.php | 8 +- templates/debug.php | 15 +- templates/plugin-info/features.php | 8 +- 19 files changed, 555 insertions(+), 132 deletions(-) create mode 100644 .phpstan/stubs/includes/entities/class-fs-entity.php create mode 100644 .phpstan/stubs/includes/fs-plugin-info-dialog.php diff --git a/.phpstan/stubs/includes/entities/class-fs-entity.php b/.phpstan/stubs/includes/entities/class-fs-entity.php new file mode 100644 index 00000000..a453a619 --- /dev/null +++ b/.phpstan/stubs/includes/entities/class-fs-entity.php @@ -0,0 +1,93 @@ + + */ + function fs_get_object_public_vars($object) { + return []; + } + + class FS_Entity { + + /** + * @var int + */ + public $id; + + /** + * @var string + */ + public $updated; + + /** + * @var string + */ + public $created; + + /** + * FS_Entity constructor. + * @param mixed $entity + */ + function __construct($entity = false) { + // Implementation here + } + + /** + * @return string + */ + static function get_type() { + // Implementation here + return ''; + } + + /** + * @param mixed $entity1 + * @param mixed $entity2 + * @return bool + */ + static function equals($entity1, $entity2) { + // Implementation here + return false; + } + + /** + * @var bool + */ + private $_is_updated = false; + + /** + * @param string $key + * @param bool $val + * @return bool + */ + function update($key, $val = false) { + return false; + } + + /** + * @return bool + */ + function is_updated() { + // Implementation here + return $this->_is_updated; + } + + /** + * @param int $id + * @return bool + */ + static function is_valid_id($id) { + // Implementation here + return false; + } + + /** + * @return string + */ + public static function get_class_name() { + // Implementation here + return ''; + } + } diff --git a/.phpstan/stubs/includes/fs-plugin-info-dialog.php b/.phpstan/stubs/includes/fs-plugin-info-dialog.php new file mode 100644 index 00000000..5e5d134c --- /dev/null +++ b/.phpstan/stubs/includes/fs-plugin-info-dialog.php @@ -0,0 +1,129 @@ + + */ + public $pricing; + + /** + * @var array + */ + public $features; + + /** + * FS_Plugin_Plan constructor. + * @param object|bool $plan + */ + public function __construct($plan = false) {} + + /** + * @return string + */ + public static function get_type() {} + + /** + * @return bool + */ + public function is_free() {} + + /** + * @return bool + */ + public function has_technical_support() {} + + /** + * @return bool + */ + public function has_trial() {} + } diff --git a/includes/class-freemius.php b/includes/class-freemius.php index a725028c..c7f3c998 100755 --- a/includes/class-freemius.php +++ b/includes/class-freemius.php @@ -996,7 +996,7 @@ private static function migrate_install_plan_to_plan_id( FS_Storage $storage, $b if ( isset( $install->plan ) && is_object( $install->plan ) ) { if ( isset( $install->plan->id ) && ! empty( $install->plan->id ) ) { - $install->plan_id = self::_decrypt( $install->plan->id ); // @phpstan-ignore-line + $install->plan_id = self::_decrypt( $install->plan->id ); } unset( $install->plan ); @@ -1571,8 +1571,8 @@ private function register_constructor_hooks() { ); $this->add_filter( 'after_code_type_change', array( &$this, '_after_code_type_change' ) ); - add_action( 'admin_init', array( &$this, '_add_trial_notice' ) ); // @phpstan-ignore-line - add_action( 'admin_init', array( &$this, '_add_affiliate_program_notice' ) ); // @phpstan-ignore-line + add_action( 'admin_init', array( &$this, '_add_trial_notice' ) ); + add_action( 'admin_init', array( &$this, '_add_affiliate_program_notice' ) ); add_action( 'admin_enqueue_scripts', array( &$this, '_enqueue_common_css' ) ); /** @@ -1872,7 +1872,8 @@ private function unregister_uninstall_hook() { */ private function clear_module_main_file_cache( $store_prev_path = true ) { if ( ! isset( $this->_storage->plugin_main_file ) || - empty( $this->_storage->plugin_main_file->path ) + ! is_object( $this->_storage->plugin_main_file ) || + empty( $this->_storage->plugin_main_file->path ) ) { return; } @@ -1891,7 +1892,7 @@ private function clear_module_main_file_cache( $store_prev_path = true ) { $plugin_main_file = clone $this->_storage->plugin_main_file; // Store cached path (2nd layer cache). - $plugin_main_file->prev_path = $plugin_main_file->path; // @phpstan-ignore-line + $plugin_main_file->prev_path = $plugin_main_file->path; // Clear cached path. unset( $plugin_main_file->path ); @@ -7685,8 +7686,7 @@ private function maybe_network_activate_addon_license( $license = null ) { } } - // @phpstan-ignore-next-line - if ( ! empty( $site_ids ) ) { + if ( 0 < count( $site_ids ) ) { $this->activate_license_on_many_sites( $user, $license->secret_key, $site_ids ); } } @@ -8624,7 +8624,7 @@ private function update_plugin_version_event() { * @author Vova Feldman (@svovaf) * @since 2.0.0 * - * @param string[] $plugins + * @param array $plugins * * @return string */ @@ -9425,7 +9425,7 @@ private function send_install_update( $override = array(), $flush = false, $is_t * @param bool $flush * @param bool $is_two_way_sync @since 2.5.0 If true and there's a successful API request, the install sync cron will be cleared. * - * @return false|object|string + * @return object */ private function send_installs_update( $override = array(), $flush = false, $is_two_way_sync = false ) { $this->_logger->entrance(); @@ -9441,7 +9441,7 @@ private function send_installs_update( $override = array(), $flush = false, $is_ $installs_data = $this->get_installs_data_for_api( $override, ! $flush, $should_send_keepalive ); if ( empty( $installs_data ) ) { - return false; + return; } if ( $is_two_way_sync ) { @@ -9544,12 +9544,6 @@ private function sync_installs( $override = array(), $flush = false ) { $this->_logger->entrance(); $result = $this->send_installs_update( $override, $flush, true ); - - if ( false === $result ) { - // No sync required. - return; - } - if ( ! $this->is_api_result_object( $result, 'installs' ) ) { // Failed to sync, don't update locally. return; @@ -9672,7 +9666,7 @@ function _uninstall_plugin_event( $check_user = true ) { $params = array(); $uninstall_reason = null; - if ( isset( $this->_storage->uninstall_reason ) ) { + if ( isset( $this->_storage->uninstall_reason ) && is_object( $this->_storage->uninstall_reason ) ) { $uninstall_reason = $this->_storage->uninstall_reason; $params['reason_id'] = $uninstall_reason->id; $params['reason_info'] = $uninstall_reason->info; @@ -9680,8 +9674,8 @@ function _uninstall_plugin_event( $check_user = true ) { if ( ! $this->is_registered() ) { // Send anonymous uninstall event only if user submitted a feedback. - if ( isset( $uninstall_reason ) ) { - if ( isset( $uninstall_reason->is_anonymous ) && ! $uninstall_reason->is_anonymous ) { + if ( $uninstall_reason !== null ) { + if ( ! empty( $uninstall_reason->is_anonymous ) ) { $this->opt_in( false, false, false, false, true ); } else { $params['uid'] = $this->get_anonymous_id(); @@ -13559,13 +13553,11 @@ function is_migration() { * @param array $sites * @param int $blog_id * - * @return array { - * @var bool $success - * @var string $error - * @var string $next_page - * } + * @return array * - * @uses Freemius::activate_license() + * @property bool $success + * @property string $error + * @property string $next_page */ function activate_migrated_license( $license_key, @@ -13662,11 +13654,11 @@ function should_use_external_pricing() { * @param bool|null $is_diagnostic_tracking_allowed Since 2.5.0.2 to allow license activation with minimal data footprint. * * - * @return array { - * @var bool $success - * @var string $error - * @var string $next_page - * } + * @return array + * + * @property bool $success + * @property string $error + * @property string $next_page */ private function activate_license( $license_key, @@ -13754,7 +13746,7 @@ private function activate_license( $result = $fs->activate_license_on_many_installs( $user, $license_key, $blog_2_install_map ); } - if ( true === $result && count( $site_ids ) > 0 ) { + if ( true === $result && ! count( $site_ids ) > 0 ) { $result = $fs->activate_license_on_many_sites( $user, $license_key, $site_ids ); } } else { @@ -16375,6 +16367,11 @@ private static function _encrypt( $str ) { return $fn( $str ); } + /** + * @param $str + * + * @return mixed|null + */ static function _decrypt( $str ) { if ( is_null( $str ) ) { return null; @@ -16976,7 +16973,6 @@ function get_opt_in_params( $override_with = array(), $network_level_or_blog_id * @param bool $redirect * * @return string|object - * @use WP_Error */ function opt_in( $email = false, @@ -17150,7 +17146,7 @@ function opt_in( json_decode( $response['body'] ) : null; - if ( empty( $decoded ) ) { + if ( empty( $decoded ) && ! is_object( $decoded ) ) { return false; } @@ -19638,7 +19634,7 @@ private function _store_site( $store = true, $network_level_or_blog_id = null, F $site = $this->_site; } - if ( !is_object($site) || empty( $site->id ) ) { + if ( ! is_object( $site ) || empty( $site->id ) ) { $this->_logger->error( "Empty install ID, can't store site." ); return; @@ -19772,10 +19768,8 @@ private function _store_licenses( $store = true, $module_id = false, $licenses = } } - if ( count( $new_user_licenses_map ) > 0 ) { - // Add new licenses. - $all_licenses[ $module_id ] = array_merge( array_values( $new_user_licenses_map ), $all_licenses[ $module_id ] ); - } + // Add new licenses. + $all_licenses[ $module_id ] = array_merge( array_values( $new_user_licenses_map ), $all_licenses[ $module_id ] ); $licenses = $all_licenses[ $module_id ]; } @@ -21018,14 +21012,16 @@ private function _sync_plugin_license( // Find the current context install. $site = null; - foreach ( $result->installs as $install ) { - if ( $install->id == $this->_site->id ) { - $site = new FS_Site( $install ); - } else { - $address = trailingslashit( fs_strip_url_protocol( $install->url ) ); - $blog_id = $address_to_blog_map[ $address ]; + if ( is_array( $result ) ) { + foreach ( $result->installs as $install ) { + if ( $install->id == $this->_site->id ) { + $site = new FS_Site( $install ); + } else { + $address = trailingslashit( fs_strip_url_protocol( $install->url ) ); + $blog_id = $address_to_blog_map[ $address ]; - $this->_store_site( true, $blog_id, new FS_Site( $install ) ); + $this->_store_site( true, $blog_id, new FS_Site( $install ) ); + } } } } @@ -22443,6 +22439,23 @@ private function init_change_owner( $candidate_email, $transfer_type ) { return ! $this->is_api_error( $result ); } + /** + * Retrieves all module sites. + * + * @return array $all_sites Get all module sites. + */ + public static function get_all_modules_sites() { + $all_sites = []; + + foreach ( self::$_instances as $instance ) { + if ( method_exists( $instance, 'get_sites' ) ) { + $all_sites = array_merge( $all_sites, $instance->get_sites() ); + } + } + + return $all_sites; + } + /** * Handle install ownership change. * diff --git a/includes/class-fs-plugin-updater.php b/includes/class-fs-plugin-updater.php index 67bf3272..9bae5ecb 100755 --- a/includes/class-fs-plugin-updater.php +++ b/includes/class-fs-plugin-updater.php @@ -534,10 +534,7 @@ function pre_set_site_transient_update_plugins_filter( $transient_data ) { return $transient_data; } - // @phpstan-ignore-next-line - if ( empty( $transient_data ) || - defined( 'WP_FS__UNINSTALL_MODE' ) - ) { + if ( defined( 'WP_FS__UNINSTALL_MODE' ) ) { return $transient_data; } @@ -872,7 +869,7 @@ function delete_update_data() { * @param string $action * @param object $args * - * @return bool|mixed + * @return object The plugin information or false on failure. */ static function _fetch_plugin_info_from_repository( $action, $args ) { $url = $http_url = 'http://api.wordpress.org/plugins/info/1.2/'; @@ -892,7 +889,7 @@ static function _fetch_plugin_info_from_repository( $action, $args ) { $request = wp_remote_get( $url, array( 'timeout' => 15 ) ); if ( is_wp_error( $request ) ) { - return false; + return; } $res = json_decode( wp_remote_retrieve_body( $request ), true ); @@ -903,7 +900,7 @@ static function _fetch_plugin_info_from_repository( $action, $args ) { } if ( ! is_object( $res ) || isset( $res->error ) ) { - return false; + return; } return $res; @@ -1094,7 +1091,7 @@ function plugins_api_filter( $data, $action = '', $args = null ) { false ); - if ( is_array( $addon_plugin_data ) && isset( $addon_plugin_data['Version'] ) ) { + if ( ! empty( $addon_plugin_data['Version'] ) ) { $addon_version = $addon_plugin_data['Version']; } } @@ -1115,9 +1112,11 @@ function plugins_api_filter( $data, $action = '', $args = null ) { // Fetch as much as possible info from local files. $plugin_local_data = $this->_fs->get_plugin_data(); - $data->name = $plugin_local_data['Name']; // @phpstan-ignore-line - $data->author = $plugin_local_data['Author']; // @phpstan-ignore-line - $data->sections = array( 'description' => 'Upgrade ' . $plugin_local_data['Name'] . ' to latest.' ); // @phpstan-ignore-line + $data->name = $plugin_local_data['Name']; + $data->author = $plugin_local_data['Author']; + $data->sections = array( + 'description' => 'Upgrade ' . $plugin_local_data['Name'] . ' to latest.' + ); // @todo Store extra plugin info on Freemius or parse readme.txt markup. /*$info = $this->_fs->get_api_site_scope()->call('/information.json'); @@ -1141,18 +1140,18 @@ function plugins_api_filter( $data, $action = '', $args = null ) { $data->name = $addon->title . ' ' . $this->_fs->get_text_inline( 'Add-On', 'addon' ); $data->slug = $addon->slug; $data->url = WP_FS__ADDRESS; - $data->package = $new_version->url; // @phpstan-ignore-line + $data->package = $new_version->url; } if ( ! $plugin_in_repo ) { - $data->last_updated = ! is_null( $new_version->updated ) ? $new_version->updated : $new_version->created; // @phpstan-ignore-line - $data->requires = $new_version->requires_platform_version; // @phpstan-ignore-line - $data->requires_php = $new_version->requires_programming_language_version; // @phpstan-ignore-line - $data->tested = $new_version->tested_up_to_version; // @phpstan-ignore-line + $data->last_updated = ! is_null( $new_version->updated ) ? $new_version->updated : $new_version->created; + $data->requires = $new_version->requires_platform_version; + $data->requires_php = $new_version->requires_programming_language_version; + $data->tested = $new_version->tested_up_to_version; } $data->version = $new_version->version; - $data->download_link = $new_version->url; // @phpstan-ignore-line + $data->download_link = $new_version->url; if ( isset( $new_version->readme ) && is_object( $new_version->readme ) ) { $new_version_readme_data = $new_version->readme; @@ -1442,7 +1441,6 @@ function install_and_activate_plugin( $plugin_id = false ) { // Pass through the error from WP_Filesystem if one was raised. if ( $wp_filesystem instanceof WP_Filesystem_Base && - is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->get_error_code() ) { $error_message = $wp_filesystem->errors->get_error_message(); diff --git a/includes/class-fs-storage.php b/includes/class-fs-storage.php index 1028b113..e0bee32c 100644 --- a/includes/class-fs-storage.php +++ b/includes/class-fs-storage.php @@ -21,6 +21,14 @@ * @property bool|null $is_diagnostic_tracking_allowed * @property object $sync_cron * @property bool|int $install_timestamp + * @property bool $is_whitelabeled + * @property mixed $beta_data + * @property bool $expired_license_notice_shown + * @property bool $has_trial_plan + * @property bool $trial_promotion_shown + * @property bool $affiliate_program_notice_shown + * @property bool $is_pending_activation + * @property bool $pending_license_key */ class FS_Storage { /** @@ -32,6 +40,196 @@ class FS_Storage { */ private $_storage; + /** + * @var int Timestamp of the last load. + */ + public $last_load_timestamp; + + /** + * @var bool Indicates if the network is activated. + */ + public $is_network_activated; + + /** + * @var string Last version of the SDK. + */ + public $sdk_last_version; + + /** + * @var string Current version of the SDK. + */ + public $sdk_version; + + /** + * @var bool Indicates if the SDK upgrade mode is active. + */ + public $sdk_upgrade_mode; + + /** + * @var bool Indicates if the SDK downgrade mode is active. + */ + public $sdk_downgrade_mode; + + /** + * @var string Last version of the plugin. + */ + public $plugin_last_version; + + /** + * @var string Current version of the plugin. + */ + public $plugin_version; + + /** + * @var bool Indicates if the plugin upgrade mode is active. + */ + public $plugin_upgrade_mode; + + /** + * @var bool Indicates if the plugin downgrade mode is active. + */ + public $plugin_downgrade_mode; + + /** + * @var bool Indicates if the plugin is a new install. + */ + public $is_plugin_new_install; + + /** + * @var bool Indicates if the user is anonymous. + */ + public $is_anonymous; + + /** + * @var bool Indicates if the user is anonymous in multisite. + */ + public $is_anonymous_ms; + + /** + * @var bool Indicates if the network is connected. + */ + public $is_network_connected; + + /** + * @var int Network user ID. + */ + public $network_user_id; + + /** + * @var bool Indicates if the plugin was loaded. + */ + public $was_plugin_loaded; + + /** + * @var bool Handle GDPR admin notice. + */ + public $handle_gdpr_admin_notice; + + /** + * @var object Main file of the plugin. + */ + public $plugin_main_file; + + /** + * @var bool Indicates if license activation is required. + */ + public $require_license_activation; + + /** + * @var bool Connectivity test status. + */ + public $connectivity_test; + + /** + * @var bool Indicates if the previous state was premium. + */ + public $prev_is_premium; + + /** + * @var int Activation timestamp. + */ + public $activation_timestamp; + + /** + * @var bool Indicates if sticky opt-in was added. + */ + public $sticky_optin_added; + + /** + * @var bool Indicates if sticky opt-in was added in multisite. + */ + public $sticky_optin_added_ms; + + /** + * @var string Previous theme. + */ + public $previous_theme; + + /** + * @var int Clone ID. + */ + public $clone_id; + + /** + * @var string Last license key. + */ + public $last_license_key; + + /** + * @var int Last license user ID. + */ + public $last_license_user_id; + + /** + * @var string Last license user key. + */ + public $last_license_user_key; + + /** + * @var array Subscriptions. + */ + public $subscriptions; + + /** + * @var bool License migration status. + */ + public $license_migration; + + /** + * @var array Affiliate application data. + */ + public $affiliate_application_data; + + /** + * @var int Previous user ID. + */ + public $prev_user_id; + + /** + * @var bool Indicates if the user was recovered from install. + */ + public $user_was_recovered_from_install; + + /** + * @var int Number of user recovery attempts from install. + */ + public $user_recovery_from_install_attempts; + + /** + * @var int Timestamp of the last user recovery attempt from install. + */ + public $user_recovery_from_install_last_attempt_timestamp; + + /** + * @var object Reason for uninstall. + */ + public $uninstall_reason; + + /** + * @var array Pending sites information. + */ + public $pending_sites_info; + /** * @var FS_Key_Value_Storage Network level storage. */ diff --git a/includes/entities/class-fs-entity.php b/includes/entities/class-fs-entity.php index 735cbb02..7558ff3e 100755 --- a/includes/entities/class-fs-entity.php +++ b/includes/entities/class-fs-entity.php @@ -88,8 +88,8 @@ static function equals( $entity1, $entity2 ) { * @author Vova Feldman (@svovaf) * @since 1.0.9 * - * @param array|string[] $key - * @param string|bool $val + * @param string|array $key + * @param string|bool $val * * @return bool */ @@ -156,4 +156,4 @@ static function is_valid_id($id){ public static function get_class_name() { return get_called_class(); } - } \ No newline at end of file + } diff --git a/includes/fs-core-functions.php b/includes/fs-core-functions.php index 283953fb..83b36e82 100755 --- a/includes/fs-core-functions.php +++ b/includes/fs-core-functions.php @@ -1389,8 +1389,8 @@ function fs_esc_html_echo_inline( $text, $key = '', $slug = 'freemius' ) { * @author Vova Feldman (@svovaf) * @since 1.1.6 * - * @param array|string[] $key_value - * @param string $slug + * @param array $key_value + * @param string $slug * * @global $fs_text_overrides */ diff --git a/includes/fs-essential-functions.php b/includes/fs-essential-functions.php index b9f7301e..189660d6 100644 --- a/includes/fs-essential-functions.php +++ b/includes/fs-essential-functions.php @@ -264,7 +264,7 @@ function fs_update_sdk_newest_version( $sdk_relative_path, $plugin_file = false $in_activation = ( ! is_plugin_active( $plugin_file ) ); } else { $theme = wp_get_theme(); - $in_activation = ( $newest_sdk->plugin_path == $theme->stylesheet ); // @phpstan-ignore-line + $in_activation = ( $newest_sdk->plugin_path == $theme->stylesheet ); } $fs_active_plugins->newest = (object) array( @@ -415,4 +415,4 @@ function fs_fallback_to_newest_active_sdk() { fs_update_sdk_newest_version( $newest_sdk_path, $newest_sdk_data->plugin_path ); } } - } \ No newline at end of file + } diff --git a/includes/fs-plugin-info-dialog.php b/includes/fs-plugin-info-dialog.php index a57d348a..1d343cfd 100755 --- a/includes/fs-plugin-info-dialog.php +++ b/includes/fs-plugin-info-dialog.php @@ -201,7 +201,7 @@ function _get_addon_info_filter( $data, $action = '', $args = null ) { ) ) ); - if ( ! empty( $repo_data ) ) { + if ( ! is_object( $repo_data ) ) { $data = $repo_data; $data->wp_org_missing = false; } else { @@ -229,7 +229,7 @@ function _get_addon_info_filter( $data, $action = '', $args = null ) { false ); - if ( is_array( $addon_plugin_data ) && isset( $addon_plugin_data['Version'] ) ) { + if ( ! empty( $addon_plugin_data['Version'] ) ) { $current_addon_version = $addon_plugin_data['Version']; } } @@ -493,12 +493,12 @@ private function get_actions_dropdown( $api, $plan = null ) { * @author Vova Feldman (@svovaf) * @since 1.1.7 * - * @param object $api - * @param FS_Plugin_Plan $plan + * @param object $api + * @param bool|FS_Plugin_Plan $plan * * @return string */ - private function get_checkout_cta( $api, $plan = null ) { + private function get_checkout_cta( $api, $plan = false ) { if ( empty( $api->checkout_link ) || ! isset( $api->plans ) || ! is_array( $api->plans ) || @@ -527,7 +527,7 @@ private function get_checkout_cta( $api, $plan = null ) { $plan->plugin_id, $plan->pricing[0]->id, $this->get_billing_cycle( $plan ), - $plan->has_trial(), // @phpstan-ignore-line + $plan->has_trial(), ( $has_valid_blog_id ? false : null ) ); @@ -536,7 +536,7 @@ private function get_checkout_cta( $api, $plan = null ) { } return '' . - esc_html( ! $plan->has_trial() ? // @phpstan-ignore-line + esc_html( ! $plan->has_trial() ? ( $api->has_purchased_license ? fs_text_inline( 'Purchase More', 'purchase-more', $api->slug ) : diff --git a/includes/managers/class-fs-admin-menu-manager.php b/includes/managers/class-fs-admin-menu-manager.php index 904cf3df..e01a5709 100644 --- a/includes/managers/class-fs-admin-menu-manager.php +++ b/includes/managers/class-fs-admin-menu-manager.php @@ -1004,4 +1004,4 @@ function add_subpage_and_update( $function ); } - } \ No newline at end of file + } diff --git a/includes/managers/class-fs-cache-manager.php b/includes/managers/class-fs-cache-manager.php index 0bde407b..78edd8c8 100755 --- a/includes/managers/class-fs-cache-manager.php +++ b/includes/managers/class-fs-cache-manager.php @@ -166,8 +166,7 @@ function get( $key, $default = null ) { isset( $cache_entry->timestamp ) && is_numeric( $cache_entry->timestamp ) ) { - return $cache_entry->result; // @phpstan-ignore-line - + return $cache_entry->result; } return is_object( $default ) ? clone $default : $default; @@ -324,4 +323,4 @@ function migrate_to_network() { } #endregion - } \ No newline at end of file + } diff --git a/includes/managers/class-fs-debug-manager.php b/includes/managers/class-fs-debug-manager.php index 5364712d..72ff7aa9 100644 --- a/includes/managers/class-fs-debug-manager.php +++ b/includes/managers/class-fs-debug-manager.php @@ -9,6 +9,11 @@ class FS_DebugManager { + /** + * @var mixed + */ + private static $_accounts; + /** * @author Vova Feldman (@svovaf) * Moved from Freemius diff --git a/includes/managers/class-fs-plugin-manager.php b/includes/managers/class-fs-plugin-manager.php index a3ae55b1..78d9e990 100755 --- a/includes/managers/class-fs-plugin-manager.php +++ b/includes/managers/class-fs-plugin-manager.php @@ -106,11 +106,7 @@ function load() { } foreach ( $all_modules as $modules ) { - /** - * @since 1.2.2 - * - * @var $modules FS_Plugin[] - */ + foreach ( $modules as $module ) { $found_module = false; @@ -230,4 +226,4 @@ function get() { return $plugin; } - } \ No newline at end of file + } diff --git a/phpstan.neon b/phpstan.neon index 2063c9e1..61f6301f 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -8,25 +8,24 @@ parameters: - templates/ bootstrapFiles: - .phpstan/exceptions.php + stubFiles: + - .phpstan/stubs/includes/fs-plugin-info-dialog.php + - .phpstan/stubs/includes/entities/class-fs-entity.php ignoreErrors: - - message: '#PHPDoc tag @var has invalid value#' - path: includes/managers/class-fs-plugin-manager.php - - - message: '#PHPDoc tag @use has invalid value#' - path: includes/class-freemius.php - - - message: '#PHPDoc tag @var above a method has no effect.#' + messages: + - '#Action callback returns bool but should not return anything.#' path: includes/class-freemius.php - - - message: '#Access to an undefined property#' - paths: - - includes/class-freemius.php - - includes/fs-plugin-info-dialog.php - - - message: '#will always evaluate to true#' - path: includes/class-fs-plugin-updater.php - message: '#Variable \$VARS might not be defined#' paths: - templates/* + - + message: '#Access to an undefined property object#' + paths: + - start.php + - includes/class-freemius.php + - includes/fs-plugin-info-dialog.php + - includes/fs-essential-functions.php + - includes/class-fs-plugin-updater.php + - includes/managers/class-fs-cache-manager.php diff --git a/templates/account.php b/templates/account.php index fcd34710..edc199eb 100755 --- a/templates/account.php +++ b/templates/account.php @@ -96,14 +96,13 @@ ) ); } + $payments = []; $show_billing = ( ! $is_whitelabeled && ! $fs->apply_filters( 'hide_billing_and_payments_info', false ) ); if ( $show_billing ) { - $payments = $fs->_fetch_payments(); - - $show_billing = ( is_array( $payments ) && 0 < count( $payments ) ); + $payments = $fs->_fetch_payments(); + $show_billing = ( 0 < count( $payments ) ); } - $has_tabs = $fs->_add_tabs_before_content(); // Aliases. @@ -137,8 +136,7 @@ $show_plan_row = true; $show_license_row = is_object( $license ); - - $site_view_params = array(); + $site_view_params = array(); if ( fs_is_network_admin() ) { $sites = Freemius::get_sites(); @@ -157,7 +155,7 @@ $site_view_params[] = $view_params; - if ( is_object( $install ) ) { + if ( ! is_object( $install ) ) { continue; } @@ -871,7 +869,7 @@ class="fs-tag fs-can_use_premium_code() ? 'success' : 'warn' ?>" $VARS['id'], 'payments' => $payments ); // @phpstan-ignore-line + $view_params = array( 'id' => $VARS['id'], 'payments' => $payments ); fs_require_once_template( 'account/billing.php', $view_params ); fs_require_once_template( 'account/payments.php', $view_params ); } diff --git a/templates/account/partials/addon.php b/templates/account/partials/addon.php index bba624da..f7fa1c62 100644 --- a/templates/account/partials/addon.php +++ b/templates/account/partials/addon.php @@ -67,6 +67,10 @@ $show_upgrade = false; $is_whitelabeled = $VARS['is_whitelabeled']; + $version = ''; + $plan_name = ''; + $plan_title = ''; + if ( is_object( $fs_addon ) ) { $is_paying = $fs_addon->is_paying(); $user = $fs_addon->get_user(); @@ -158,11 +162,11 @@ - + - + diff --git a/templates/add-ons.php b/templates/add-ons.php index 6534d9bc..eccd83ab 100755 --- a/templates/add-ons.php +++ b/templates/add-ons.php @@ -142,12 +142,8 @@ } $has_paid_plan = true; - - if ( isset( $plan->trial_period ) ) { - $has_trial = ( is_numeric( $plan->trial_period ) && ( $plan->trial_period > 0 ) ); - } - - $min_price = 999999; + $has_trial = isset( $plan->trial_period ) && is_numeric( $plan->trial_period ) && $plan->trial_period > 0; + $min_price = 999999; foreach ( $plan->pricing as $pricing ) { $pricing = new FS_Pricing( $pricing ); diff --git a/templates/debug.php b/templates/debug.php index cea5a13a..92c3ddb2 100644 --- a/templates/debug.php +++ b/templates/debug.php @@ -359,21 +359,18 @@ function stopCountdownManually() { $has_api_connectivity = false; if ( $is_active ) { - $fs = freemius( $data->id ); - $has_api_connectivity = $fs->has_api_connectivity(); - + $fs = freemius( $data->id ); $active_modules_by_id[ $data->id ] = true; } ?> - has_api_connectivity(); if ( true === $has_api_connectivity && $fs->is_on() ) { - echo 'style="background: #E6FFE6; font-weight: bold"'; + echo ' style="background: #E6FFE6; font-weight: bold"'; } else { - echo 'style="background: #ffd0d0; font-weight: bold"'; + echo ' style="background: #ffd0d0; font-weight: bold"'; } - } - ?>> + } ?>> id ?> version ?> diff --git a/templates/plugin-info/features.php b/templates/plugin-info/features.php index 8f316ccb..2702903e 100644 --- a/templates/plugin-info/features.php +++ b/templates/plugin-info/features.php @@ -23,12 +23,10 @@ foreach ( $plans as $plan ) { if (!empty($plan->features) && is_array($plan->features)) { foreach ( $plan->features as $feature ) { - if ( ! isset( $features_plan_map[ $feature->id ] ) ) { - $features_plan_map[ $feature->id ] = array( 'feature' => $feature, 'plans' => array() ); - } + $features_plan_map[ $feature->id ] = array( 'feature' => $feature, 'plans' => array() ); if ( ! empty( $plan->id ) ) { - $features_plan_map[ $feature->id ]['plans'][ $plan->id ] = $feature; + $features_plan_map[ $feature->id ]['plans'][ $plan->id ] = $feature; } } } @@ -113,4 +111,4 @@ -
\ No newline at end of file + From f4a6e684342562695fff4c56051c483eafe99a4d Mon Sep 17 00:00:00 2001 From: Laurence Bahiirwa Date: Tue, 10 Sep 2024 16:29:33 +0300 Subject: [PATCH 11/12] [static-analysis] Fix rule - Access to an undefined property object . --- includes/class-freemius.php | 31 +++++++++++++------- includes/class-fs-plugin-updater.php | 22 ++++++++++---- includes/fs-essential-functions.php | 3 ++ includes/fs-plugin-info-dialog.php | 22 +++++++++++--- includes/managers/class-fs-cache-manager.php | 9 ++++++ phpstan.neon | 9 ------ start.php | 9 ++++++ templates/plugin-info/features.php | 10 ++++--- 8 files changed, 82 insertions(+), 33 deletions(-) diff --git a/includes/class-freemius.php b/includes/class-freemius.php index c7f3c998..e2bfd6e4 100755 --- a/includes/class-freemius.php +++ b/includes/class-freemius.php @@ -987,10 +987,13 @@ private static function migrate_install_plan_to_plan_id( FS_Storage $storage, $b $module_type = $storage->get_module_type(); $module_slug = $storage->get_module_slug(); + /** + * @var FS_Site[] $installs + */ $installs = self::get_all_sites( $module_type, $blog_id ); $install = isset( $installs[ $module_slug ] ) ? $installs[ $module_slug ] : null; - if ( ! is_object( $install ) ) { + if ( is_null( $install ) ) { return; } @@ -1872,7 +1875,6 @@ private function unregister_uninstall_hook() { */ private function clear_module_main_file_cache( $store_prev_path = true ) { if ( ! isset( $this->_storage->plugin_main_file ) || - ! is_object( $this->_storage->plugin_main_file ) || empty( $this->_storage->plugin_main_file->path ) ) { return; @@ -1889,6 +1891,9 @@ private function clear_module_main_file_cache( $store_prev_path = true ) { */ unset( $this->_storage->plugin_main_file->path ); } else { + /** + * @var stdClass $plugin_main_file + */ $plugin_main_file = clone $this->_storage->plugin_main_file; // Store cached path (2nd layer cache). @@ -17141,12 +17146,14 @@ function opt_in( * @link https://themes.trac.wordpress.org/ticket/46134#comment:9 * @link https://themes.trac.wordpress.org/ticket/46134#comment:12 * @link https://themes.trac.wordpress.org/ticket/46134#comment:14 + * + * @var stdClass $decoded The decoded object is expected to be UserPlugin entity, but since we do not have this Entity in the SDK, we made this a StdClass */ $decoded = is_string( $response['body'] ) ? json_decode( $response['body'] ) : null; - if ( empty( $decoded ) && ! is_object( $decoded ) ) { + if ( ! is_object( $decoded ) ) { return false; } @@ -19634,9 +19641,9 @@ private function _store_site( $store = true, $network_level_or_blog_id = null, F $site = $this->_site; } - if ( ! is_object( $site ) || empty( $site->id ) ) { + // @phpstan-ignore-next-line Variable $site in isset() always exists and is not nullable + if ( !isset( $site ) || !is_object( $site ) || empty( $site->id ) ) { $this->_logger->error( "Empty install ID, can't store site." ); - return; } @@ -20083,7 +20090,11 @@ private function _handle_account_user_sync() { $api = $this->get_api_user_scope(); - // Get user's information. + /** + * Get user's information. + * + * @var FS_User $user + */ $user = $api->get( '/', true ); if ( isset( $user->id ) ) { @@ -21012,7 +21023,7 @@ private function _sync_plugin_license( // Find the current context install. $site = null; - if ( is_array( $result ) ) { + if ( is_object( $result ) && is_array( $result->installs ) ) { foreach ( $result->installs as $install ) { if ( $install->id == $this->_site->id ) { $site = new FS_Site( $install ); @@ -22442,7 +22453,7 @@ private function init_change_owner( $candidate_email, $transfer_type ) { /** * Retrieves all module sites. * - * @return array $all_sites Get all module sites. + * @return array $all_sites */ public static function get_all_modules_sites() { $all_sites = []; @@ -22585,8 +22596,8 @@ private function complete_change_owner() { * @author Leo Fajardo (@leorw) * @since 2.3.2 * - * @param number $user_id - * @param string[]|int[] $install_ids_by_slug_map + * @param number $user_id + * @param array $install_ids_by_slug_map * */ private function complete_ownership_change_by_license( $user_id, $install_ids_by_slug_map ) { diff --git a/includes/class-fs-plugin-updater.php b/includes/class-fs-plugin-updater.php index 9bae5ecb..aae43de1 100755 --- a/includes/class-fs-plugin-updater.php +++ b/includes/class-fs-plugin-updater.php @@ -534,7 +534,8 @@ function pre_set_site_transient_update_plugins_filter( $transient_data ) { return $transient_data; } - if ( defined( 'WP_FS__UNINSTALL_MODE' ) ) { + // @phpstan-ignore-next-line + if ( empty( $transient_data ) || defined( 'WP_FS__UNINSTALL_MODE' ) ) { return $transient_data; } @@ -869,7 +870,7 @@ function delete_update_data() { * @param string $action * @param object $args * - * @return object The plugin information or false on failure. + * @return bool|object The plugin information or false on failure. */ static function _fetch_plugin_info_from_repository( $action, $args ) { $url = $http_url = 'http://api.wordpress.org/plugins/info/1.2/'; @@ -889,7 +890,7 @@ static function _fetch_plugin_info_from_repository( $action, $args ) { $request = wp_remote_get( $url, array( 'timeout' => 15 ) ); if ( is_wp_error( $request ) ) { - return; + return false; } $res = json_decode( wp_remote_retrieve_body( $request ), true ); @@ -900,7 +901,7 @@ static function _fetch_plugin_info_from_repository( $action, $args ) { } if ( ! is_object( $res ) || isset( $res->error ) ) { - return; + return false; } return $res; @@ -1110,7 +1111,11 @@ function plugins_api_filter( $data, $action = '', $args = null ) { if ( ! $plugin_in_repo ) { $data = $args; - // Fetch as much as possible info from local files. + /** + * Fetch as much as possible info from local files. + * + * @var stdClass $data + */ $plugin_local_data = $this->_fs->get_plugin_data(); $data->name = $plugin_local_data['Name']; $data->author = $plugin_local_data['Author']; @@ -1130,7 +1135,12 @@ function plugins_api_filter( $data, $action = '', $args = null ) { $addon_version : $this->_fs->get_plugin_version(); - // Get plugin's newest update. + /** + * Get plugin's newest update. + * + * @var FS_Plugin_Tag $new_version + * @var object $data + */ $new_version = $this->get_latest_download_details( $is_addon ? $addon->id : false, $plugin_version ); if ( ! is_object( $new_version ) || empty( $new_version->version ) ) { diff --git a/includes/fs-essential-functions.php b/includes/fs-essential-functions.php index 189660d6..ffd98e41 100644 --- a/includes/fs-essential-functions.php +++ b/includes/fs-essential-functions.php @@ -250,6 +250,9 @@ function fs_update_sdk_newest_version( $sdk_relative_path, $plugin_file = false global $fs_active_plugins; + /** + * @var stdClass $newest_sdk + */ $newest_sdk = $fs_active_plugins->plugins[ $sdk_relative_path ]; if ( ! is_string( $plugin_file ) ) { diff --git a/includes/fs-plugin-info-dialog.php b/includes/fs-plugin-info-dialog.php index 1d343cfd..04df244f 100755 --- a/includes/fs-plugin-info-dialog.php +++ b/includes/fs-plugin-info-dialog.php @@ -78,9 +78,9 @@ function __construct( Freemius $fs ) { * @author Vova Feldman (@svovaf) * @since 1.0.6 * - * @param array $data - * @param string $action - * @param object|null $args + * @param object|array $data + * @param string $action + * @param object|null $args * * @return array|null */ @@ -188,6 +188,9 @@ function _get_addon_info_filter( $data, $action = '', $args = null ) { $latest = null; + /** + * @var stdClass $data + */ if ( ! $has_paid_plan && $selected_addon->is_wp_org_compliant ) { $repo_data = FS_Plugin_Updater::_fetch_plugin_info_from_repository( 'plugin_information', (object) array( @@ -202,7 +205,6 @@ function _get_addon_info_filter( $data, $action = '', $args = null ) { ) ); if ( ! is_object( $repo_data ) ) { - $data = $repo_data; $data->wp_org_missing = false; } else { // Couldn't find plugin on .org. @@ -535,6 +537,9 @@ private function get_checkout_cta( $api, $plan = false ) { restore_current_blog(); } + /** + * @var stdClass $api + */ return '' . esc_html( ! $plan->has_trial() ? ( @@ -763,6 +768,9 @@ private function get_plugin_actions( $api ) { $download_latest_action = ''; + /** + * @var stdClass $api + */ if ( ! empty( $api->download_link ) && ( $can_download_free_version || $can_download_premium_version ) @@ -1092,6 +1100,7 @@ function install_plugin_information() { /** * @var FS_Plugin_Plan $plan + * @var stdClass $api */ ?> pricing[0] ?> @@ -1310,6 +1319,11 @@ class="fs-annual-discount">

slug ) ?>

    + version ) ) { ?>
  • slug ); ?> diff --git a/includes/managers/class-fs-cache-manager.php b/includes/managers/class-fs-cache-manager.php index 78edd8c8..d1fbb377 100755 --- a/includes/managers/class-fs-cache-manager.php +++ b/includes/managers/class-fs-cache-manager.php @@ -160,6 +160,9 @@ function has_valid( $key, $expiration = null ) { function get( $key, $default = null ) { $this->_logger->entrance( 'key = ' . $key ); + /** + * @var stdClass $cache_entry + */ $cache_entry = $this->_options->get_option( $key, false ); if ( is_object( $cache_entry ) && @@ -184,6 +187,9 @@ function get( $key, $default = null ) { function get_valid( $key, $default = null ) { $this->_logger->entrance( 'key = ' . $key ); + /** + * @var stdClass $cache_entry + */ $cache_entry = $this->_options->get_option( $key, false ); if ( is_object( $cache_entry ) && @@ -271,6 +277,9 @@ function purge( $key ) { function update_expiration( $key, $expiration = WP_FS__TIME_24_HOURS_IN_SEC ) { $this->_logger->entrance( 'key = ' . $key ); + /** + * @var stdClass $cache_entry + */ $cache_entry = $this->_options->get_option( $key, false ); if ( ! is_object( $cache_entry ) || diff --git a/phpstan.neon b/phpstan.neon index 61f6301f..314e3ab1 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -20,12 +20,3 @@ parameters: message: '#Variable \$VARS might not be defined#' paths: - templates/* - - - message: '#Access to an undefined property object#' - paths: - - start.php - - includes/class-freemius.php - - includes/fs-plugin-info-dialog.php - - includes/fs-essential-functions.php - - includes/class-fs-plugin-updater.php - - includes/managers/class-fs-cache-manager.php diff --git a/start.php b/start.php index bc8db040..17da5023 100644 --- a/start.php +++ b/start.php @@ -102,11 +102,17 @@ function_exists( 'wp_is_json_request' ) && $fs_active_plugins = new stdClass(); } + /** + * @var stdClass $fs_active_plugins + */ if ( ! isset( $fs_active_plugins->plugins ) ) { $fs_active_plugins->plugins = array(); } } + /** + * @var stdClass $fs_active_plugins + */ if ( empty( $fs_active_plugins->abspath ) ) { /** * Store the WP install absolute path reference to identify environment change @@ -229,6 +235,9 @@ function_exists( 'wp_is_json_request' ) && $is_newest_sdk_plugin_active = is_plugin_active( $fs_newest_sdk->plugin_path ); } else { $current_theme = wp_get_theme(); + /** + * @var stdClass $fs_newest_sdk + */ $is_newest_sdk_plugin_active = ( $current_theme->stylesheet === $fs_newest_sdk->plugin_path ); $current_theme_parent = $current_theme->parent(); diff --git a/templates/plugin-info/features.php b/templates/plugin-info/features.php index 2702903e..6e91160e 100644 --- a/templates/plugin-info/features.php +++ b/templates/plugin-info/features.php @@ -21,13 +21,15 @@ $features_plan_map = array(); foreach ( $plans as $plan ) { + /** + * @var FS_Plugin_Plan $plan + */ if (!empty($plan->features) && is_array($plan->features)) { foreach ( $plan->features as $feature ) { - $features_plan_map[ $feature->id ] = array( 'feature' => $feature, 'plans' => array() ); - - if ( ! empty( $plan->id ) ) { - $features_plan_map[ $feature->id ]['plans'][ $plan->id ] = $feature; + if ( ! isset( $features_plan_map[ $feature->id ] ) ) { + $features_plan_map[ $feature->id ] = array( 'feature' => $feature, 'plans' => array() ); } + $features_plan_map[ $feature->id ]['plans'][ $plan->id ] = $feature; } } From 522f0e1dab14710b22ea2c01e0a64adfe5ba965c Mon Sep 17 00:00:00 2001 From: Laurence Bahiirwa Date: Sun, 22 Sep 2024 14:41:54 +0300 Subject: [PATCH 12/12] [version-control] Rebase and remove false function addition. --- includes/class-freemius.php | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/includes/class-freemius.php b/includes/class-freemius.php index e2bfd6e4..119f0731 100755 --- a/includes/class-freemius.php +++ b/includes/class-freemius.php @@ -22450,23 +22450,6 @@ private function init_change_owner( $candidate_email, $transfer_type ) { return ! $this->is_api_error( $result ); } - /** - * Retrieves all module sites. - * - * @return array $all_sites - */ - public static function get_all_modules_sites() { - $all_sites = []; - - foreach ( self::$_instances as $instance ) { - if ( method_exists( $instance, 'get_sites' ) ) { - $all_sites = array_merge( $all_sites, $instance->get_sites() ); - } - } - - return $all_sites; - } - /** * Handle install ownership change. *