From 3413bb3e8445853548fb47e878392a0bf51b581e Mon Sep 17 00:00:00 2001 From: Sherv Date: Fri, 17 Apr 2026 17:10:22 +0300 Subject: [PATCH 01/31] docs(addons): add detailed PHPDoc comments for add-on views and settings --- classes/views/addons/addon.php | 4 ++++ classes/views/addons/categories.php | 2 ++ classes/views/addons/index.php | 10 ++++++++++ classes/views/addons/list.php | 12 ++++++++++++ classes/views/addons/settings.php | 8 ++++++++ 5 files changed, 36 insertions(+) diff --git a/classes/views/addons/addon.php b/classes/views/addons/addon.php index c705959370..25151414e2 100644 --- a/classes/views/addons/addon.php +++ b/classes/views/addons/addon.php @@ -3,6 +3,10 @@ * Add-Ons addon view. * * @package Formidable + * + * @var array $addon Single add-on data (slug, title, display_name, excerpt, status, docs, docs_label, is_new, etc.). + * @var string $license_type Current license type or empty string. + * @var string $pricing Upgrade URL used for CTAs. */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/classes/views/addons/categories.php b/classes/views/addons/categories.php index ab609d6be9..1825a3f48b 100644 --- a/classes/views/addons/categories.php +++ b/classes/views/addons/categories.php @@ -3,6 +3,8 @@ * Add-Ons categories. * * @package Formidable + * + * @var array $categories Categories keyed by slug. */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/classes/views/addons/index.php b/classes/views/addons/index.php index 4f8c4443b3..737d937cbb 100644 --- a/classes/views/addons/index.php +++ b/classes/views/addons/index.php @@ -3,6 +3,16 @@ * Add-Ons Page. * * @package Formidable + * + * @var string $view_path Absolute path to the views/addons/ directory, with trailing slash. + * @var array $installed_addons Installed add-on plugins keyed by slug. + * @var array $addons Available add-ons keyed by slug. + * @var array $errors API errors, if any. + * @var string $license_type Current license type or empty string. + * @var string $request_addon_url URL for requesting a new add-on. + * @var array $pro Pro add-on entry prepended to $addons. + * @var string $pricing Upgrade URL used for CTAs. + * @var array $categories Add-on categories keyed by slug, each with 'name' and 'count'. */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/classes/views/addons/list.php b/classes/views/addons/list.php index 1380063630..2f76211979 100644 --- a/classes/views/addons/list.php +++ b/classes/views/addons/list.php @@ -1,4 +1,16 @@ $addons Available add-ons keyed by slug. + * @var string $view_path Absolute path to the views/addons/ directory, with trailing slash. + * @var string $request_addon_url URL for requesting a new add-on. + * @var string $license_type Current license type or empty string. + * @var string $pricing Upgrade URL used for CTAs. + */ + if ( ! defined( 'ABSPATH' ) ) { die( 'You are not allowed to call this page directly.' ); } diff --git a/classes/views/addons/settings.php b/classes/views/addons/settings.php index d1f37c70b0..d0ca2501b6 100644 --- a/classes/views/addons/settings.php +++ b/classes/views/addons/settings.php @@ -1,4 +1,12 @@ $plugins Installed add-on plugin objects keyed by slug. Each has: is_parent_licence, needs_license, license, option_name, plugin_name. + */ + if ( ! defined( 'ABSPATH' ) ) { die( 'You are not allowed to call this page directly.' ); } From bf30bf2e805362cdba332ee5a3666daaea1aed52 Mon Sep 17 00:00:00 2001 From: Sherv Date: Fri, 17 Apr 2026 17:10:27 +0300 Subject: [PATCH 02/31] docs(header): add PHPDoc comments for applications header file --- classes/views/applications/header.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/classes/views/applications/header.php b/classes/views/applications/header.php index fb0eca3959..39b1342a41 100644 --- a/classes/views/applications/header.php +++ b/classes/views/applications/header.php @@ -1,4 +1,13 @@ Date: Fri, 17 Apr 2026 17:10:32 +0300 Subject: [PATCH 03/31] docs(dashboard): add PHPDoc comments for dashboard template files --- classes/views/dashboard/templates/counters.php | 8 ++++++++ classes/views/dashboard/templates/entries-list.php | 9 +++++++++ classes/views/dashboard/templates/license-management.php | 6 ++++++ .../views/dashboard/templates/notification-banner.php | 6 ++++++ .../views/dashboard/templates/payment-placeholder.php | 8 ++++++++ classes/views/dashboard/templates/widget-placeholder.php | 8 ++++++++ classes/views/dashboard/templates/youtube-video.php | 9 +++++++++ 7 files changed, 54 insertions(+) diff --git a/classes/views/dashboard/templates/counters.php b/classes/views/dashboard/templates/counters.php index ccdda8f6d6..6a47518900 100644 --- a/classes/views/dashboard/templates/counters.php +++ b/classes/views/dashboard/templates/counters.php @@ -1,4 +1,12 @@ Date: Fri, 17 Apr 2026 17:37:54 +0300 Subject: [PATCH 04/31] docs(entries): add PHPDoc comments for entry-related view files --- classes/views/frm-entries/_sidebar-shared-pub.php | 9 +++++++++ classes/views/frm-entries/errors.php | 11 +++++++++++ classes/views/frm-entries/show.php | 11 +++++++++++ classes/views/frm-entries/sidebar-shared.php | 11 +++++++++++ 4 files changed, 42 insertions(+) diff --git a/classes/views/frm-entries/_sidebar-shared-pub.php b/classes/views/frm-entries/_sidebar-shared-pub.php index d9d98a1ea0..f58a46cd5d 100644 --- a/classes/views/frm-entries/_sidebar-shared-pub.php +++ b/classes/views/frm-entries/_sidebar-shared-pub.php @@ -1,4 +1,13 @@ Date: Fri, 17 Apr 2026 17:38:02 +0300 Subject: [PATCH 05/31] docs(upsell): add PHPDoc comments for AI upsell button file --- .../frm-fields/back-end/upsell/ai-upsell-button.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/classes/views/frm-fields/back-end/upsell/ai-upsell-button.php b/classes/views/frm-fields/back-end/upsell/ai-upsell-button.php index 65611f8380..6580cd843e 100644 --- a/classes/views/frm-fields/back-end/upsell/ai-upsell-button.php +++ b/classes/views/frm-fields/back-end/upsell/ai-upsell-button.php @@ -1,10 +1,15 @@ true, From 2950a07ad75d3afbb2cc7e7a6d04b10d1147f2c0 Mon Sep 17 00:00:00 2001 From: Sherv Date: Fri, 17 Apr 2026 17:38:09 +0300 Subject: [PATCH 06/31] docs(fields): add PHPDoc comments for various field-related view files --- .../back-end/ajax-field-placeholder.php | 10 +++++++++ .../frm-fields/back-end/automatic-width.php | 8 +++++++ .../back-end/bulk-options-overlay.php | 8 +++++++ .../back-end/default-value-field.php | 10 +++++++++ .../back-end/default-value-setting.php | 10 +++++++++ .../frm-fields/back-end/field-captcha.php | 8 +++++++ .../frm-fields/back-end/field-choices.php | 8 +++++++ .../frm-fields/back-end/field-credit-card.php | 8 +++++++ .../frm-fields/back-end/field-description.php | 8 +++++++ .../frm-fields/back-end/field-hidden.php | 10 +++++++++ .../views/frm-fields/back-end/field-html.php | 8 +++++++ .../frm-fields/back-end/field-options.php | 9 ++++++++ .../views/frm-fields/back-end/field-total.php | 9 ++++++++ .../frm-fields/back-end/field-user-id.php | 6 +++++ .../back-end/generate-options-with-ai.php | 9 ++++++++ .../frm-fields/back-end/html-content.php | 8 +++++++ .../frm-fields/back-end/inline-modal.php | 8 +++++++ .../frm-fields/back-end/input-mask-info.php | 6 +++++ .../frm-fields/back-end/layout-classes.php | 6 +++++ classes/views/frm-fields/back-end/max.php | 9 ++++++++ .../frm-fields/back-end/number-range.php | 8 +++++++ .../views/frm-fields/back-end/pixels-wide.php | 9 ++++++++ .../frm-fields/back-end/product-options.php | 9 ++++++++ .../back-end/product-single-option.php | 17 ++++++++++++++ .../frm-fields/back-end/quantity-options.php | 8 +++++++ .../views/frm-fields/back-end/radio-field.php | 10 +++++++++ .../views/frm-fields/back-end/settings.php | 22 +++++++++++++++++++ .../frm-fields/back-end/smart-values.php | 8 +++++++ .../back-end/textarea-default-value-field.php | 10 +++++++++ .../frm-fields/back-end/value-format.php | 9 ++++++++ 30 files changed, 276 insertions(+) diff --git a/classes/views/frm-fields/back-end/ajax-field-placeholder.php b/classes/views/frm-fields/back-end/ajax-field-placeholder.php index 66e519d75c..9dfb38e4d5 100644 --- a/classes/views/frm-fields/back-end/ajax-field-placeholder.php +++ b/classes/views/frm-fields/back-end/ajax-field-placeholder.php @@ -1,4 +1,14 @@ $prepop Preset options groups keyed by label; each may contain a 'class' key. + */ + if ( ! defined( 'ABSPATH' ) ) { die( 'You are not allowed to call this page directly.' ); } diff --git a/classes/views/frm-fields/back-end/default-value-field.php b/classes/views/frm-fields/back-end/default-value-field.php index fdd30b6f6d..4a9729cb92 100644 --- a/classes/views/frm-fields/back-end/default-value-field.php +++ b/classes/views/frm-fields/back-end/default-value-field.php @@ -1,4 +1,14 @@ $data_types Product type options keyed by type slug. + */ + if ( ! defined( 'ABSPATH' ) ) { die( 'You are not allowed to call this page directly.' ); } diff --git a/classes/views/frm-fields/back-end/product-single-option.php b/classes/views/frm-fields/back-end/product-single-option.php index 3c07ac7dc7..5f7a8f51ca 100644 --- a/classes/views/frm-fields/back-end/product-single-option.php +++ b/classes/views/frm-fields/back-end/product-single-option.php @@ -1,4 +1,21 @@ Date: Fri, 17 Apr 2026 17:38:13 +0300 Subject: [PATCH 07/31] docs(fields): add PHPDoc comments for single option field settings file --- classes/views/frm-fields/single-option.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/classes/views/frm-fields/single-option.php b/classes/views/frm-fields/single-option.php index 3a9293555b..7a8e900e04 100644 --- a/classes/views/frm-fields/single-option.php +++ b/classes/views/frm-fields/single-option.php @@ -1,4 +1,20 @@ Date: Fri, 17 Apr 2026 19:03:04 +0300 Subject: [PATCH 08/31] docs(fields): enhance PHPDoc comments for field-related view files --- classes/views/frm-entries/_sidebar-shared-pub.php | 2 +- classes/views/frm-entries/show.php | 2 +- classes/views/frm-fields/back-end/default-value-field.php | 7 ++++--- classes/views/frm-fields/back-end/field-choices.php | 3 ++- classes/views/frm-fields/back-end/field-options.php | 6 ++++-- classes/views/frm-fields/back-end/field-total.php | 5 +++-- classes/views/frm-fields/back-end/settings.php | 4 ++-- 7 files changed, 17 insertions(+), 12 deletions(-) diff --git a/classes/views/frm-entries/_sidebar-shared-pub.php b/classes/views/frm-entries/_sidebar-shared-pub.php index f58a46cd5d..e5035cd7e3 100644 --- a/classes/views/frm-entries/_sidebar-shared-pub.php +++ b/classes/views/frm-entries/_sidebar-shared-pub.php @@ -31,7 +31,7 @@ * @param string $text * @param stdClass $entry */ - $additional_timestamp_text = apply_filters( 'frm_additional_timestamp_text', '', $entry ); + $additional_timestamp_text = apply_filters( 'frm_additional_timestamp_text', '', $entry ); // skipcq: PHP-W1020 printf( /* translators: %1$s: Entry status, %2$s: open tag, %3$s: The date, %4$s: Possible additional text, %5$s: close tag */ diff --git a/classes/views/frm-entries/show.php b/classes/views/frm-entries/show.php index 4f673214cc..a088498649 100644 --- a/classes/views/frm-entries/show.php +++ b/classes/views/frm-entries/show.php @@ -87,7 +87,7 @@ * @param array $show_args The arguments. * @param array $args Includes `form`. */ - $show_args = apply_filters( 'frm_entries_show_args', $show_args, compact( 'form' ) ); + $show_args = apply_filters( 'frm_entries_show_args', $show_args, compact( 'form' ) ); // skipcq: PHP-W1020 echo FrmEntriesController::show_entry_shortcode( $show_args ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> diff --git a/classes/views/frm-fields/back-end/default-value-field.php b/classes/views/frm-fields/back-end/default-value-field.php index 4a9729cb92..5ba9a7f303 100644 --- a/classes/views/frm-fields/back-end/default-value-field.php +++ b/classes/views/frm-fields/back-end/default-value-field.php @@ -4,9 +4,10 @@ * * @package Formidable * - * @var array $field Field data including 'id' and 'field_key'. - * @var string $default_name HTML name attribute for the input. - * @var mixed $default_value Current default value. + * @var FrmFieldType $this Field type handler that included this template. + * @var array $field Field data including 'id' and 'field_key'. + * @var string $default_name HTML name attribute for the input. + * @var mixed $default_value Current default value. */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/classes/views/frm-fields/back-end/field-choices.php b/classes/views/frm-fields/back-end/field-choices.php index ba13cf89e0..b25e6cb5cc 100644 --- a/classes/views/frm-fields/back-end/field-choices.php +++ b/classes/views/frm-fields/back-end/field-choices.php @@ -4,7 +4,8 @@ * * @package Formidable * - * @var array $args Arguments including 'field' (with 'post_field', 'id', 'taxonomy' keys). + * @var FrmFieldType $this Field type handler that included this template. + * @var array $args Arguments including 'field' (with 'post_field', 'id', 'taxonomy' keys). */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/classes/views/frm-fields/back-end/field-options.php b/classes/views/frm-fields/back-end/field-options.php index df1d9b224d..4e4eee6390 100644 --- a/classes/views/frm-fields/back-end/field-options.php +++ b/classes/views/frm-fields/back-end/field-options.php @@ -4,8 +4,10 @@ * * @package Formidable * - * @var array $args Arguments including 'field' and 'field_obj'. - * @var bool $should_hide_bulk_edit Whether to hide the bulk edit link. + * @var FrmFieldType $this Field type handler that included this template. + * @var array $args Arguments including 'field' and 'field_obj'. + * @var bool $should_hide_bulk_edit Whether to hide the bulk edit link. + * @var string $option_title Title attribute for the bulk edit link. */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/classes/views/frm-fields/back-end/field-total.php b/classes/views/frm-fields/back-end/field-total.php index c8cf8b502d..5f89c89260 100644 --- a/classes/views/frm-fields/back-end/field-total.php +++ b/classes/views/frm-fields/back-end/field-total.php @@ -4,8 +4,9 @@ * * @package Formidable * - * @var string $html_id HTML id attribute for the hidden input. - * @var string $field_name HTML name attribute for the hidden input. + * @var FrmFieldTotal $this Field type handler that included this template. + * @var string $html_id HTML id attribute for the hidden input. + * @var string $field_name HTML name attribute for the hidden input. */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/classes/views/frm-fields/back-end/settings.php b/classes/views/frm-fields/back-end/settings.php index c7a00240ba..c32018c966 100644 --- a/classes/views/frm-fields/back-end/settings.php +++ b/classes/views/frm-fields/back-end/settings.php @@ -106,7 +106,7 @@

@@ -486,7 +486,7 @@ } FrmHtmlHelper::echo_dropdown_option( - is_array( $ftype ) ? $ftype['name'] : $ftyp, + is_array( $ftype ) ? $ftype['name'] : $ftype, $fkey === $field['type'], $type_option_params ); From 1f928e2f8a93e9509654509c8719585f8b2429ba Mon Sep 17 00:00:00 2001 From: Sherv Date: Fri, 17 Apr 2026 19:20:17 +0300 Subject: [PATCH 09/31] refactor: update PHPDoc comments in various view files to improve clarity --- classes/views/frm-entries/_sidebar-shared-pub.php | 3 ++- classes/views/frm-entries/show.php | 3 ++- classes/views/frm-fields/back-end/settings.php | 5 ++++- .../views/frm-fields/back-end/upsell/ai-upsell-button.php | 1 + 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/classes/views/frm-entries/_sidebar-shared-pub.php b/classes/views/frm-entries/_sidebar-shared-pub.php index e5035cd7e3..8ba1824cf5 100644 --- a/classes/views/frm-entries/_sidebar-shared-pub.php +++ b/classes/views/frm-entries/_sidebar-shared-pub.php @@ -31,7 +31,8 @@ * @param string $text * @param stdClass $entry */ - $additional_timestamp_text = apply_filters( 'frm_additional_timestamp_text', '', $entry ); // skipcq: PHP-W1020 + // Skipcq: PHP-W1020 + $additional_timestamp_text = apply_filters( 'frm_additional_timestamp_text', '', $entry ); printf( /* translators: %1$s: Entry status, %2$s: open tag, %3$s: The date, %4$s: Possible additional text, %5$s: close tag */ diff --git a/classes/views/frm-entries/show.php b/classes/views/frm-entries/show.php index a088498649..f4404c38b9 100644 --- a/classes/views/frm-entries/show.php +++ b/classes/views/frm-entries/show.php @@ -87,7 +87,8 @@ * @param array $show_args The arguments. * @param array $args Includes `form`. */ - $show_args = apply_filters( 'frm_entries_show_args', $show_args, compact( 'form' ) ); // skipcq: PHP-W1020 + // Skipcq: PHP-W1020 + $show_args = apply_filters( 'frm_entries_show_args', $show_args, compact( 'form' ) ); echo FrmEntriesController::show_entry_shortcode( $show_args ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> diff --git a/classes/views/frm-fields/back-end/settings.php b/classes/views/frm-fields/back-end/settings.php index c32018c966..6cb0afd227 100644 --- a/classes/views/frm-fields/back-end/settings.php +++ b/classes/views/frm-fields/back-end/settings.php @@ -106,7 +106,10 @@

diff --git a/classes/views/frm-fields/back-end/upsell/ai-upsell-button.php b/classes/views/frm-fields/back-end/upsell/ai-upsell-button.php index 6580cd843e..d8ed8c1b9b 100644 --- a/classes/views/frm-fields/back-end/upsell/ai-upsell-button.php +++ b/classes/views/frm-fields/back-end/upsell/ai-upsell-button.php @@ -10,6 +10,7 @@ if ( ! defined( 'ABSPATH' ) ) { die( 'You are not allowed to call this page directly.' ); } + FrmFieldsHelper::render_ai_generate_options_button( array( 'show_pill' => true, From 99e39e7c99825723ddfa03bf2a6bb7023c543a3f Mon Sep 17 00:00:00 2001 From: Sherv Date: Fri, 17 Apr 2026 19:20:22 +0300 Subject: [PATCH 10/31] chore: update PHPStan configuration to include additional file paths for analysis --- js/src/admin/admin.js | 16 +++++++++------- phpstan.neon | 2 ++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/js/src/admin/admin.js b/js/src/admin/admin.js index b32976ed29..e2078263ce 100644 --- a/js/src/admin/admin.js +++ b/js/src/admin/admin.js @@ -7482,8 +7482,8 @@ window.frmAdminBuildJS = function() { const actionType = targetSettings.querySelector( '.frm_action_name' )?.value; const sourceTitle = targetSettings.querySelector( '.widget-title h4 span:not(.frm-border-icon)' )?.textContent.trim() ?? ''; const uniqueTitle = getUniqueActionTitle( sourceTitle.replace( / \(\d+\)$/, '' ), getExistingActionTitles( actionType ) ); - $action[0].querySelector( '.widget-title h4 span:not(.frm-border-icon)' ).textContent = uniqueTitle; - $action[0].querySelector( `input[name$="[${ currentID }][post_title]"]` ).value = uniqueTitle; + $action[ 0 ].querySelector( '.widget-title h4 span:not(.frm-border-icon)' ).textContent = uniqueTitle; + $action[ 0 ].querySelector( `input[name$="[${ currentID }][post_title]"]` ).value = uniqueTitle; $action.find( '.frm_action_id, .frm-btn-group' ).remove(); $action.find( `input[name$="[${ currentID }][ID]"]` ).val( '' ); @@ -7589,7 +7589,7 @@ window.frmAdminBuildJS = function() { function getExistingActionTitles( actionType ) { return Array.from( document.querySelectorAll( `.frm_single_${ actionType }_settings .widget-title h4 span:not(.frm-border-icon)` ), - ( el ) => el.textContent.trim() + el => el.textContent.trim() ); } @@ -7598,15 +7598,17 @@ window.frmAdminBuildJS = function() { * * @since x.x * - * @param {string} baseTitle The base title without any numeric suffix. - * @param {string[]} existingTitles Titles currently in use. - * @return {string} + * @param {string} baseTitle The base title without any numeric suffix. + * @param {string[]} existingTitles Titles currently in use. + * @return {string} The first title not present in existingTitles. */ function getUniqueActionTitle( baseTitle, existingTitles ) { const taken = new Set( existingTitles ); let title = baseTitle; - for ( let n = 2; taken.has( title ); n++ ) { + let n = 2; + while ( taken.has( title ) ) { title = `${ baseTitle } (${ n })`; + n++; } return title; } diff --git a/phpstan.neon b/phpstan.neon index 40b55a9dd6..4aa2695839 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -99,6 +99,7 @@ parameters: message: '#Call to protected method+#' paths: - classes/views/frm-fields/back-end/combo-field/sub-field-options.php + - classes/views/frm-fields/back-end/field-options.php - classes/views/frm-fields/back-end/phone/phone-type.php - classes/views/frm-fields/front-end/combo-field/combo-field.php - @@ -325,6 +326,7 @@ parameters: - classes/helpers/FrmFormsHelper.php - classes/helpers/FrmXMLHelper.php - classes/models/FrmEntryValidate.php + - classes/views/frm-entries/_sidebar-shared-pub.php - message: '#Possibly invalid array key#' - message: '#should return array<(string|array)> but returns array#' From 4a742cae95e5810d6da60aa39e60a03445aa16f9 Mon Sep 17 00:00:00 2001 From: Sherv Date: Fri, 17 Apr 2026 19:32:19 +0300 Subject: [PATCH 11/31] fix: standardize comment formatting in PHP files by correcting case in skipcq annotations --- classes/views/frm-entries/_sidebar-shared-pub.php | 2 +- classes/views/frm-entries/show.php | 2 +- classes/views/frm-fields/back-end/field-options.php | 7 ++++++- classes/views/frm-fields/back-end/settings.php | 2 +- js/src/admin/admin.js | 2 +- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/classes/views/frm-entries/_sidebar-shared-pub.php b/classes/views/frm-entries/_sidebar-shared-pub.php index 8ba1824cf5..077e6790ac 100644 --- a/classes/views/frm-entries/_sidebar-shared-pub.php +++ b/classes/views/frm-entries/_sidebar-shared-pub.php @@ -31,7 +31,7 @@ * @param string $text * @param stdClass $entry */ - // Skipcq: PHP-W1020 + // skipcq: PHP-W1020 $additional_timestamp_text = apply_filters( 'frm_additional_timestamp_text', '', $entry ); printf( diff --git a/classes/views/frm-entries/show.php b/classes/views/frm-entries/show.php index f4404c38b9..b382ecd14a 100644 --- a/classes/views/frm-entries/show.php +++ b/classes/views/frm-entries/show.php @@ -87,7 +87,7 @@ * @param array $show_args The arguments. * @param array $args Includes `form`. */ - // Skipcq: PHP-W1020 + // skipcq: PHP-W1020 $show_args = apply_filters( 'frm_entries_show_args', $show_args, compact( 'form' ) ); echo FrmEntriesController::show_entry_shortcode( $show_args ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped diff --git a/classes/views/frm-fields/back-end/field-options.php b/classes/views/frm-fields/back-end/field-options.php index 4e4eee6390..36bf422c6f 100644 --- a/classes/views/frm-fields/back-end/field-options.php +++ b/classes/views/frm-fields/back-end/field-options.php @@ -31,6 +31,7 @@ ); ?> + get_bulk_edit_string() ); ?> @@ -38,7 +39,10 @@
    - show_single_option( $args ); ?> + show_single_option( $args ); + ?>
+ get_add_option_string() ); ?> diff --git a/classes/views/frm-fields/back-end/settings.php b/classes/views/frm-fields/back-end/settings.php index 6cb0afd227..0ddfe1b3f6 100644 --- a/classes/views/frm-fields/back-end/settings.php +++ b/classes/views/frm-fields/back-end/settings.php @@ -107,7 +107,7 @@

diff --git a/js/src/admin/admin.js b/js/src/admin/admin.js index e2078263ce..e0eeab14cc 100644 --- a/js/src/admin/admin.js +++ b/js/src/admin/admin.js @@ -7598,7 +7598,7 @@ window.frmAdminBuildJS = function() { * * @since x.x * - * @param {string} baseTitle The base title without any numeric suffix. + * @param {string} baseTitle The base title without any numeric suffix. * @param {string[]} existingTitles Titles currently in use. * @return {string} The first title not present in existingTitles. */ From c537710e45d2d593ae6c616b5794f97106e86ce1 Mon Sep 17 00:00:00 2001 From: Sherv Date: Fri, 17 Apr 2026 19:43:54 +0300 Subject: [PATCH 12/31] fix: improve comment formatting and spacing in field options and comment spacing sniff files --- .../views/frm-fields/back-end/field-options.php | 16 ++++++++++++---- .../Sniffs/Commenting/CommentSpacingSniff.php | 4 ++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/classes/views/frm-fields/back-end/field-options.php b/classes/views/frm-fields/back-end/field-options.php index 36bf422c6f..0d94c6d4f7 100644 --- a/classes/views/frm-fields/back-end/field-options.php +++ b/classes/views/frm-fields/back-end/field-options.php @@ -31,8 +31,12 @@ ); ?> - - get_bulk_edit_string() ); ?> + + get_bulk_edit_string() ); + ?> + @@ -52,8 +56,12 @@

diff --git a/phpcs-sniffs/Formidable/Sniffs/Commenting/CommentSpacingSniff.php b/phpcs-sniffs/Formidable/Sniffs/Commenting/CommentSpacingSniff.php index cad5605e2f..50990c0628 100644 --- a/phpcs-sniffs/Formidable/Sniffs/Commenting/CommentSpacingSniff.php +++ b/phpcs-sniffs/Formidable/Sniffs/Commenting/CommentSpacingSniff.php @@ -84,7 +84,7 @@ public function process( File $phpcsFile, $stackPtr ) { && ! $isSingleWord && ! $startsWithSpecialWord && ! $isContinuationComment - && ! preg_match( '/^(end\b|phpcs:|eslint|TODO|FIXME|translators:|e\.g\.|i\.e\.|etc\.|iDeal)/i', $trimmedText ); + && ! preg_match( '/^(end\b|phpcs:|skipcq:|eslint|TODO|FIXME|translators:|e\.g\.|i\.e\.|etc\.|iDeal)/i', $trimmedText ); if ( ! $hasSpaceAfterSlash ) { $fix = $phpcsFile->addFixableError( @@ -97,7 +97,7 @@ public function process( File $phpcsFile, $stackPtr ) { $newText = $trimmedText; // Also capitalize if needed (but not for code-like comments, single words, underscore/hyphen words, abbreviations, or continuation comments). - if ( preg_match( '/^[a-z]/', $firstChar ) && ! $looksLikeCode && ! $isSingleWord && ! $startsWithSpecialWord && ! $isContinuationComment && ! preg_match( '/^(end\b|phpcs:|eslint|translators:|e\.g\.|i\.e\.|etc\.|iDeal)/i', $trimmedText ) ) { + if ( preg_match( '/^[a-z]/', $firstChar ) && ! $looksLikeCode && ! $isSingleWord && ! $startsWithSpecialWord && ! $isContinuationComment && ! preg_match( '/^(end\b|phpcs:|skipcq:|eslint|translators:|e\.g\.|i\.e\.|etc\.|iDeal)/i', $trimmedText ) ) { $newText = ucfirst( $trimmedText ); } From cd7bd4bbfe85cdfa5eac7980a00e700f968233fa Mon Sep 17 00:00:00 2001 From: Sherv Date: Fri, 17 Apr 2026 19:44:00 +0300 Subject: [PATCH 13/31] refactor: rename variables for clarity and improve code readability in admin.js --- js/src/admin/admin.js | 53 ++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/js/src/admin/admin.js b/js/src/admin/admin.js index e0eeab14cc..957fa361ff 100644 --- a/js/src/admin/admin.js +++ b/js/src/admin/admin.js @@ -848,11 +848,11 @@ window.frmAdminBuildJS = function() { return; } - const c = t.replace( '#', '.' ); + const classSelector = t.replace( '#', '.' ); link.closest( 'li' ).addClass( 'frm-tabs active' ).siblings( 'li' ).removeClass( 'frm-tabs active starttab' ); if ( link.closest( 'div' ).find( '.tabs-panel' ).length ) { - link.closest( 'div' ).children( '.tabs-panel' ).not( t ).not( c ).hide(); + link.closest( 'div' ).children( '.tabs-panel' ).not( t ).not( classSelector ).hide(); } else if ( document.getElementById( 'form_global_settings' ) !== null ) { /* global settings */ const ajax = link.data( 'frmajax' ); @@ -865,7 +865,7 @@ window.frmAdminBuildJS = function() { jQuery( '#frm-categorydiv .tabs-panel, .hide_with_tabs' ).hide(); } jQuery( t ).show(); - jQuery( c ).show(); + jQuery( classSelector ).show(); hideShortcodes(); @@ -1075,18 +1075,18 @@ window.frmAdminBuildJS = function() { $postBodyContent.scrollTop( ( _, v ) => { const moved = event.clientY; - const h = postBodyContent.offsetHeight; + const contentHeight = postBodyContent.offsetHeight; const relativePos = event.clientY - postBodyContent.offsetTop; - const y = relativePos - ( h / 2 ); + const offsetFromCenter = relativePos - ( contentHeight / 2 ); - if ( relativePos > ( h - 50 ) && moved > 5 ) { + if ( relativePos > ( contentHeight - 50 ) && moved > 5 ) { // Scrolling down. - return v + ( y * 0.1 ); + return v + ( offsetFromCenter * 0.1 ); } if ( relativePos < 70 && moved < 130 ) { // Scrolling up. - return v - Math.abs( y * 0.1 ); + return v - Math.abs( offsetFromCenter * 0.1 ); } return v; @@ -1974,7 +1974,7 @@ window.frmAdminBuildJS = function() { } const isSubmitBtn = draggable.classList.contains( 'edit_field_type_submit' ); - const containSubmitBtn = ! draggable.classList.contains( 'form_field' ) && !! draggable.querySelector( '.edit_field_type_submit' ); + const containSubmitBtn = ! draggable.classList.contains( 'form_field' ) && Boolean( draggable.querySelector( '.edit_field_type_submit' ) ); if ( 'frm-show-fields' === droppable.id ) { const draggableIndex = determineIndexBasedOffOfMousePositionInList( jQuery( droppable ), event.clientY ); @@ -2058,7 +2058,7 @@ window.frmAdminBuildJS = function() { * @return {boolean} True if the element is the last row. */ function isLastRow( element ) { - return element && element.matches( '#frm-show-fields > li:last-child' ); + return element?.matches( '#frm-show-fields > li:last-child' ); } // Don't allow a new page break or hidden field in a field group. @@ -2142,13 +2142,9 @@ window.frmAdminBuildJS = function() { return false; } + // Do not allow a section inside of a section. const draggableIncludesSection = draggable.classList.contains( 'edit_field_type_divider' ) || draggable.querySelector( '.edit_field_type_divider' ); - if ( draggableIncludesSection ) { - // Do not allow a section inside of a section. - return false; - } - - return true; + return ! draggableIncludesSection; } function allowMoveFieldToGroup( draggable, group ) { @@ -2163,15 +2159,11 @@ window.frmAdminBuildJS = function() { return false; } + // Do not allow a section or an embed field inside of a section. const draggableIncludesASection = draggable.classList.contains( 'edit_field_type_divider' ) || draggable.querySelector( '.edit_field_type_divider' ); const draggableIsEmbedField = draggable.classList.contains( 'edit_field_type_form' ); const groupIsInASection = null !== group.closest( '.start_divider' ); - if ( groupIsInASection && ( draggableIncludesASection || draggableIsEmbedField ) ) { - // Do not allow a section or an embed field inside of a section. - return false; - } - - return true; + return ! ( groupIsInASection && ( draggableIncludesASection || draggableIsEmbedField ) ); } function groupIncludesBreakOrHiddenOrUserId( group ) { @@ -2242,6 +2234,9 @@ window.frmAdminBuildJS = function() { html = JSON.parse( html ); for ( key in html ) { + if ( ! Object.prototype.hasOwnProperty.call( html, key ) ) { + continue; + } jQuery( `#frm_field_id_${ key }` ).replaceWith( html[ key ] ); const newReplacedField = document.getElementById( `frm_field_id_${ key }` ); @@ -3238,17 +3233,17 @@ window.frmAdminBuildJS = function() { continue; } - const a = document.createElement( 'a' ); - a.setAttribute( 'href', '#' ); - a.setAttribute( 'data-code', fields[ i ].fieldId ); - a.classList.add( 'frm_insert_code' ); - a.append( span( fields[ i ].fieldName ) ); - a.append( span( { className: 'frm-text-sm frm-text-grey-500', text: `[${ fields[ i ].fieldId }]` } ) ); + const anchor = document.createElement( 'a' ); + anchor.setAttribute( 'href', '#' ); + anchor.setAttribute( 'data-code', fields[ i ].fieldId ); + anchor.classList.add( 'frm_insert_code' ); + anchor.append( span( fields[ i ].fieldName ) ); + anchor.append( span( { className: 'frm-text-sm frm-text-grey-500', text: `[${ fields[ i ].fieldId }]` } ) ); const li = document.createElement( 'li' ); li.classList.add( `frm-field-list-${ fieldId }` ); li.classList.add( `frm-field-list-${ fields[ i ].fieldType }` ); - li.append( a ); + li.append( anchor ); list.append( li ); } } From 3b2c2f8977e919af3462f4d8d977ab4c83e34ca7 Mon Sep 17 00:00:00 2001 From: Sherv Date: Fri, 17 Apr 2026 19:50:05 +0300 Subject: [PATCH 14/31] refactor: update variable names for consistency and enhance readability in admin.js --- js/src/admin/admin.js | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/js/src/admin/admin.js b/js/src/admin/admin.js index 957fa361ff..25659a8ea8 100644 --- a/js/src/admin/admin.js +++ b/js/src/admin/admin.js @@ -818,18 +818,18 @@ window.frmAdminBuildJS = function() { function clickNewTab() { /*jshint validthis:true */ - const t = this.getAttribute( 'href' ); - if ( t === undefined ) { + const href = this.getAttribute( 'href' ); + if ( href === undefined ) { return false; } - const c = t.replace( '#', '.' ); + const classSelector = href.replace( '#', '.' ); const $link = jQuery( this ); $link.closest( 'li' ).addClass( 'frm-tabs active' ).siblings( 'li' ).removeClass( 'frm-tabs active starttab' ); - $link.closest( 'div' ).children( '.tabs-panel' ).not( t ).not( c ).hide(); + $link.closest( 'div' ).children( '.tabs-panel' ).not( href ).not( classSelector ).hide(); - const tabContent = document.getElementById( t.replace( '#', '' ) ); + const tabContent = document.getElementById( href.replace( '#', '' ) ); if ( tabContent ) { tabContent.style.display = 'block'; } @@ -843,28 +843,28 @@ window.frmAdminBuildJS = function() { function clickTab( link, auto ) { link = jQuery( link ); - const t = link.attr( 'href' ); - if ( t === undefined ) { + const href = link.attr( 'href' ); + if ( href === undefined ) { return; } - const classSelector = t.replace( '#', '.' ); + const classSelector = href.replace( '#', '.' ); link.closest( 'li' ).addClass( 'frm-tabs active' ).siblings( 'li' ).removeClass( 'frm-tabs active starttab' ); if ( link.closest( 'div' ).find( '.tabs-panel' ).length ) { - link.closest( 'div' ).children( '.tabs-panel' ).not( t ).not( classSelector ).hide(); + link.closest( 'div' ).children( '.tabs-panel' ).not( href ).not( classSelector ).hide(); } else if ( document.getElementById( 'form_global_settings' ) !== null ) { /* global settings */ const ajax = link.data( 'frmajax' ); link.closest( '.frm_wrap' ).find( '.tabs-panel, .hide_with_tabs' ).hide(); if ( ajax !== undefined && ajax == '1' ) { - loadSettingsTab( t ); + loadSettingsTab( href ); } } else { /* form settings page */ jQuery( '#frm-categorydiv .tabs-panel, .hide_with_tabs' ).hide(); } - jQuery( t ).show(); + jQuery( href ).show(); jQuery( classSelector ).show(); hideShortcodes(); @@ -880,9 +880,9 @@ window.frmAdminBuildJS = function() { } if ( jQuery( '.frm_form_settings' ).length ) { - jQuery( '.frm_form_settings' ).attr( 'action', `?page=formidable&frm_action=settings&id=${ jQuery( '.frm_form_settings input[name="id"]' ).val() }&t=${ t.replace( '#', '' ) }` ); + jQuery( '.frm_form_settings' ).attr( 'action', `?page=formidable&frm_action=settings&id=${ jQuery( '.frm_form_settings input[name="id"]' ).val() }&t=${ href.replace( '#', '' ) }` ); } else { - jQuery( '.frm_settings_form' ).attr( 'action', `?page=formidable-settings&t=${ t.replace( '#', '' ) }` ); + jQuery( '.frm_settings_form' ).attr( 'action', `?page=formidable-settings&t=${ href.replace( '#', '' ) }` ); } } @@ -2234,7 +2234,7 @@ window.frmAdminBuildJS = function() { html = JSON.parse( html ); for ( key in html ) { - if ( ! Object.prototype.hasOwnProperty.call( html, key ) ) { + if ( ! Object.hasOwn( html, key ) ) { continue; } jQuery( `#frm_field_id_${ key }` ).replaceWith( html[ key ] ); From 0500b1d737eb8489c661a5c55841cfddc4227180 Mon Sep 17 00:00:00 2001 From: Sherv Date: Fri, 17 Apr 2026 20:20:53 +0300 Subject: [PATCH 15/31] chore: replace manual Mago installation with setup action and streamline linting and analysis commands --- .github/workflows/mago.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/mago.yml b/.github/workflows/mago.yml index 7727e33ba6..a6772747a3 100644 --- a/.github/workflows/mago.yml +++ b/.github/workflows/mago.yml @@ -15,12 +15,10 @@ jobs: run: composer install --dev --prefer-dist --no-progress - name: "⚡ Install Mago" - run: | - mkdir -p bin - curl --proto '=https' --tlsv1.2 -sSf https://carthage.software/mago.sh | bash -s -- --install-dir=bin + uses: nhedger/setup-mago@v1 - name: "✅ Mago Lint" - run: ./bin/mago lint + run: mago lint - name: "🔎 Mago Analyze" - run: ./bin/mago analyze + run: mago analyze From 56fff756fc0a0535160cf50c498a2defd7335b30 Mon Sep 17 00:00:00 2001 From: Sherv Date: Fri, 17 Apr 2026 20:52:19 +0300 Subject: [PATCH 16/31] fix: update assertion in Add-Ons page test to check for partial text match --- tests/cypress/e2e/Add-Ons/validateAddOnsPage.cy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cypress/e2e/Add-Ons/validateAddOnsPage.cy.js b/tests/cypress/e2e/Add-Ons/validateAddOnsPage.cy.js index 8d24b8f4f1..1548c95dbf 100644 --- a/tests/cypress/e2e/Add-Ons/validateAddOnsPage.cy.js +++ b/tests/cypress/e2e/Add-Ons/validateAddOnsPage.cy.js @@ -160,7 +160,7 @@ describe( 'Add-Ons page', () => { } ); cy.origin( 'https://formidableforms.com', () => { - cy.get( 'h1' ).should( 'have.text', 'What is the difference between the Lite (free) and Pro version?' ); + cy.get( 'h1' ).should( 'contain.text', 'What is the difference between the Lite' ); } ); cy.visit( '/wp-admin/admin.php?page=formidable-addons' ); From 16ff629f827d1cab85a6a59baf2713323f8008ad Mon Sep 17 00:00:00 2001 From: Sherv Date: Mon, 20 Apr 2026 22:47:19 +0300 Subject: [PATCH 17/31] chore: add Carthage software Mago to composer dependencies and update workflow commands for linting and analysis --- .github/workflows/mago.yml | 7 ++----- composer.json | 6 ++++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/mago.yml b/.github/workflows/mago.yml index a6772747a3..7f50616c17 100644 --- a/.github/workflows/mago.yml +++ b/.github/workflows/mago.yml @@ -14,11 +14,8 @@ jobs: - name: Install dependencies run: composer install --dev --prefer-dist --no-progress - - name: "⚡ Install Mago" - uses: nhedger/setup-mago@v1 - - name: "✅ Mago Lint" - run: mago lint + run: ./vendor/bin/mago lint - name: "🔎 Mago Analyze" - run: mago analyze + run: ./vendor/bin/mago analyze diff --git a/composer.json b/composer.json index afe67d4359..7c7bd42c63 100644 --- a/composer.json +++ b/composer.json @@ -41,13 +41,15 @@ "friendsofphp/php-cs-fixer": "^3.54", "rector/rector": "^2.3.4", "phpstan/phpstan-strict-rules": "^2.0", - "kubawerlos/php-cs-fixer-custom-fixers": "^3.36" + "kubawerlos/php-cs-fixer-custom-fixers": "^3.36", + "carthage-software/mago": "^1.23" }, "config": { "allow-plugins": { "composer/installers": true, "phpstan/extension-installer": true, - "dealerdirect/phpcodesniffer-composer-installer": true + "dealerdirect/phpcodesniffer-composer-installer": true, + "carthage-software/mago": true } } } From e02c88064a0656605a521fba819b945a0fc23d3f Mon Sep 17 00:00:00 2001 From: Sherv Date: Mon, 20 Apr 2026 22:56:26 +0300 Subject: [PATCH 18/31] chore: remove Carthage software Mago from composer dependencies and update GitHub Actions workflow to install Mago directly --- .github/workflows/mago.yml | 9 +++++++-- composer.json | 6 ++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/mago.yml b/.github/workflows/mago.yml index 7f50616c17..7727e33ba6 100644 --- a/.github/workflows/mago.yml +++ b/.github/workflows/mago.yml @@ -14,8 +14,13 @@ jobs: - name: Install dependencies run: composer install --dev --prefer-dist --no-progress + - name: "⚡ Install Mago" + run: | + mkdir -p bin + curl --proto '=https' --tlsv1.2 -sSf https://carthage.software/mago.sh | bash -s -- --install-dir=bin + - name: "✅ Mago Lint" - run: ./vendor/bin/mago lint + run: ./bin/mago lint - name: "🔎 Mago Analyze" - run: ./vendor/bin/mago analyze + run: ./bin/mago analyze diff --git a/composer.json b/composer.json index 7c7bd42c63..afe67d4359 100644 --- a/composer.json +++ b/composer.json @@ -41,15 +41,13 @@ "friendsofphp/php-cs-fixer": "^3.54", "rector/rector": "^2.3.4", "phpstan/phpstan-strict-rules": "^2.0", - "kubawerlos/php-cs-fixer-custom-fixers": "^3.36", - "carthage-software/mago": "^1.23" + "kubawerlos/php-cs-fixer-custom-fixers": "^3.36" }, "config": { "allow-plugins": { "composer/installers": true, "phpstan/extension-installer": true, - "dealerdirect/phpcodesniffer-composer-installer": true, - "carthage-software/mago": true + "dealerdirect/phpcodesniffer-composer-installer": true } } } From 6964b74be405f5b475b12ecf074176fcafa624fd Mon Sep 17 00:00:00 2001 From: Sherv Date: Mon, 20 Apr 2026 23:31:20 +0300 Subject: [PATCH 19/31] fix: update PHPDoc comment to specify that entry object can be null in _sidebar-shared-pub.php --- classes/views/frm-entries/_sidebar-shared-pub.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/views/frm-entries/_sidebar-shared-pub.php b/classes/views/frm-entries/_sidebar-shared-pub.php index 077e6790ac..243c13fe56 100644 --- a/classes/views/frm-entries/_sidebar-shared-pub.php +++ b/classes/views/frm-entries/_sidebar-shared-pub.php @@ -4,7 +4,7 @@ * * @package Formidable * - * @var stdClass $entry Entry object (falls back to $record). + * @var stdClass|null $entry Entry object (falls back to $record). * @var stdClass|null $record Legacy entry object used when $entry is not set. */ From 18ad5b31846d781d116d861cb19f85197d2eb0d8 Mon Sep 17 00:00:00 2001 From: Sherv Date: Mon, 20 Apr 2026 23:31:34 +0300 Subject: [PATCH 20/31] fix: correct PHPDoc type for Entry ID in sidebar-shared.php --- classes/views/frm-entries/sidebar-shared.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/views/frm-entries/sidebar-shared.php b/classes/views/frm-entries/sidebar-shared.php index 20dff42e33..1aa5273715 100644 --- a/classes/views/frm-entries/sidebar-shared.php +++ b/classes/views/frm-entries/sidebar-shared.php @@ -4,7 +4,7 @@ * * @package Formidable * - * @var int $id Entry ID. + * @var string $id Entry ID. * @var stdClass $entry Entry object. * @var string|null $browser Browser info string if available. * @var array|null $data Additional entry meta data (referrer, user_journey, etc.). From 9c5811e38e7641d4b7e0f1040d44d75bdb94ef0c Mon Sep 17 00:00:00 2001 From: Sherv Date: Mon, 20 Apr 2026 23:43:04 +0300 Subject: [PATCH 21/31] fix: update PHPDoc type for default_value to allow int, float, or string in default-value-field.php --- classes/views/frm-fields/back-end/default-value-field.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/classes/views/frm-fields/back-end/default-value-field.php b/classes/views/frm-fields/back-end/default-value-field.php index 5ba9a7f303..0eb4807b74 100644 --- a/classes/views/frm-fields/back-end/default-value-field.php +++ b/classes/views/frm-fields/back-end/default-value-field.php @@ -4,10 +4,10 @@ * * @package Formidable * - * @var FrmFieldType $this Field type handler that included this template. - * @var array $field Field data including 'id' and 'field_key'. - * @var string $default_name HTML name attribute for the input. - * @var mixed $default_value Current default value. + * @var FrmFieldType $this Field type handler that included this template. + * @var array $field Field data including 'id' and 'field_key'. + * @var string $default_name HTML name attribute for the input. + * @var int|float|string $default_value Current default value. */ if ( ! defined( 'ABSPATH' ) ) { From 548a5b86c9c22e8ff3c3055c8e0d42999fdd7f1e Mon Sep 17 00:00:00 2001 From: Sherv Date: Mon, 20 Apr 2026 23:43:14 +0300 Subject: [PATCH 22/31] fix: update PHPDoc type for field variable to specify it as an array in field-credit-card.php --- classes/views/frm-fields/back-end/field-credit-card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/views/frm-fields/back-end/field-credit-card.php b/classes/views/frm-fields/back-end/field-credit-card.php index 1f11178791..2e1164bd29 100644 --- a/classes/views/frm-fields/back-end/field-credit-card.php +++ b/classes/views/frm-fields/back-end/field-credit-card.php @@ -4,7 +4,7 @@ * * @package Formidable * - * @var array|object $field Field data including 'form_id'. + * @var array $field Field data including 'form_id'. */ if ( ! defined( 'ABSPATH' ) ) { From a0d5bf0bcb80068bc4ad6297757b400f465bb425 Mon Sep 17 00:00:00 2001 From: Sherv Date: Mon, 20 Apr 2026 23:43:29 +0300 Subject: [PATCH 23/31] fix: update PHPDoc types for upsell visibility variables to allow null values in settings.php --- classes/views/frm-fields/back-end/settings.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/classes/views/frm-fields/back-end/settings.php b/classes/views/frm-fields/back-end/settings.php index 0ddfe1b3f6..a1f5d35061 100644 --- a/classes/views/frm-fields/back-end/settings.php +++ b/classes/views/frm-fields/back-end/settings.php @@ -14,11 +14,11 @@ * @var array $default_value_types Default value types available for this field. * @var array $unique_values_label_atts Label attributes for the Unique checkbox. * @var array $read_only_label_atts Label attributes for the Read Only checkbox. - * @var bool $show_upsell_for_unique_value Whether to show upsell for Unique. - * @var bool $show_upsell_for_read_only Whether to show upsell for Read Only. - * @var bool $show_upsell_for_before_after_contents Whether to show upsell for before/after contents. - * @var bool $show_upsell_for_autocomplete Whether to show upsell for autocomplete. - * @var bool $show_upsell_for_visibility Whether to show upsell for visibility. + * @var bool|null $show_upsell_for_unique_value Whether to show upsell for Unique. + * @var bool|null $show_upsell_for_read_only Whether to show upsell for Read Only. + * @var bool|null $show_upsell_for_before_after_contents Whether to show upsell for before/after contents. + * @var bool|null $show_upsell_for_autocomplete Whether to show upsell for autocomplete. + * @var bool|null $show_upsell_for_visibility Whether to show upsell for visibility. */ if ( ! defined( 'ABSPATH' ) ) { From 40a1cfcf90e8d202e24dca05def6d08be4ec835d Mon Sep 17 00:00:00 2001 From: Sherv Date: Mon, 20 Apr 2026 23:43:37 +0300 Subject: [PATCH 24/31] fix: update PHPDoc types for default_value to allow int, float, or string in textarea-default-value-field.php --- .../frm-fields/back-end/textarea-default-value-field.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/classes/views/frm-fields/back-end/textarea-default-value-field.php b/classes/views/frm-fields/back-end/textarea-default-value-field.php index 3263783896..7d56e59e41 100644 --- a/classes/views/frm-fields/back-end/textarea-default-value-field.php +++ b/classes/views/frm-fields/back-end/textarea-default-value-field.php @@ -4,9 +4,9 @@ * * @package Formidable * - * @var array $field Field data including 'id' and 'field_key'. - * @var string $default_name HTML name attribute for the textarea. - * @var mixed $default_value Current default value. + * @var array $field Field data including 'id' and 'field_key'. + * @var string $default_name HTML name attribute for the textarea. + * @var int|float|string $default_value Current default value. */ if ( ! defined( 'ABSPATH' ) ) { From 89569fdf4c61ee8521ed140eff0552abbe2449b7 Mon Sep 17 00:00:00 2001 From: Sherv Date: Mon, 20 Apr 2026 23:43:44 +0300 Subject: [PATCH 25/31] fix: change href check from undefined to null in admin.js --- js/src/admin/admin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/src/admin/admin.js b/js/src/admin/admin.js index 25659a8ea8..a753c14596 100644 --- a/js/src/admin/admin.js +++ b/js/src/admin/admin.js @@ -819,7 +819,7 @@ window.frmAdminBuildJS = function() { function clickNewTab() { /*jshint validthis:true */ const href = this.getAttribute( 'href' ); - if ( href === undefined ) { + if ( href === null ) { return false; } From 7f9c93f0eb002f85cb0cca243595de32596f391b Mon Sep 17 00:00:00 2001 From: Sherv Date: Mon, 20 Apr 2026 23:43:53 +0300 Subject: [PATCH 26/31] fix: remove deprecated reference to _sidebar-shared-pub.php in PHPStan configuration --- phpstan.neon | 1 - 1 file changed, 1 deletion(-) diff --git a/phpstan.neon b/phpstan.neon index 4aa2695839..542c6b36d7 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -326,7 +326,6 @@ parameters: - classes/helpers/FrmFormsHelper.php - classes/helpers/FrmXMLHelper.php - classes/models/FrmEntryValidate.php - - classes/views/frm-entries/_sidebar-shared-pub.php - message: '#Possibly invalid array key#' - message: '#should return array<(string|array)> but returns array#' From 953d734acfee535382bb06a64fd115c3166cb6f9 Mon Sep 17 00:00:00 2001 From: Sherv Date: Tue, 21 Apr 2026 14:05:13 +0300 Subject: [PATCH 27/31] fix: refactor variable names for clarity in admin.js --- js/src/admin/admin.js | 44 +++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/js/src/admin/admin.js b/js/src/admin/admin.js index a753c14596..7a280caf72 100644 --- a/js/src/admin/admin.js +++ b/js/src/admin/admin.js @@ -8500,12 +8500,12 @@ window.frmAdminBuildJS = function() { obj.value = obj.value.substr( 0, obj.selectionStart ) + variable + obj.value.substr( obj.selectionEnd, obj.value.length ); - const s = e + variable.length; + const cursorPos = e + variable.length; maybeRemoveLayoutClasses( obj, variable ); obj.focus(); - obj.setSelectionRange( s, s ); + obj.setSelectionRange( cursorPos, cursorPos ); } triggerChange( contentBox ); } @@ -9257,21 +9257,21 @@ window.frmAdminBuildJS = function() { /*jshint validthis:true */ e.preventDefault(); - let s = false; + let status = false; const $exportForms = jQuery( 'input[name="frm_export_forms[]"]' ); if ( ! jQuery( 'input[name="frm_export_forms[]"]:checked' ).val() ) { $exportForms.closest( '.frm-table-box' ).addClass( 'frm_blank_field' ); - s = 'stop'; + status = 'stop'; } const $exportType = jQuery( 'input[name="type[]"]' ); if ( ! jQuery( 'input[name="type[]"]:checked' ).val() && $exportType.attr( 'type' ) === 'checkbox' ) { $exportType.closest( 'p' ).addClass( 'frm_blank_field' ); - s = 'stop'; + status = 'stop'; } - if ( s === 'stop' ) { + if ( status === 'stop' ) { return false; } @@ -9281,24 +9281,24 @@ window.frmAdminBuildJS = function() { function removeExportError() { /*jshint validthis:true */ - const t = jQuery( this ).closest( '.frm_blank_field' ); - if ( t === undefined ) { + const $blankField = jQuery( this ).closest( '.frm_blank_field' ); + if ( $blankField === undefined ) { return; } const $thisName = this.name; if ( $thisName === 'type[]' && jQuery( 'input[name="type[]"]:checked' ).val() ) { - t.removeClass( 'frm_blank_field' ); + $blankField.removeClass( 'frm_blank_field' ); } else if ( $thisName === 'frm_export_forms[]' && jQuery( this ).val() ) { - t.removeClass( 'frm_blank_field' ); + $blankField.removeClass( 'frm_blank_field' ); } } function checkCSVExtension() { /*jshint validthis:true */ - const f = jQuery( this ).val(); + const fileName = jQuery( this ).val(); const re = /\.csv$/i; - if ( f.match( re ) !== null ) { + if ( fileName.match( re ) !== null ) { jQuery( '.show_csv' ).fadeIn(); } else { jQuery( '.show_csv' ).fadeOut(); @@ -9334,12 +9334,12 @@ window.frmAdminBuildJS = function() { /*jshint validthis:true */ const $dropdown = jQuery( this ); const $selected = $dropdown.find( ':selected' ); - const s = $selected.data( 'support' ); + const support = $selected.data( 'support' ); - const multiple = s.indexOf( '|' ); + const multiple = support.indexOf( '|' ); jQuery( 'input[name="type[]"]' ).each( function() { this.checked = false; - if ( s.includes( this.value ) ) { + if ( support.includes( this.value ) ) { this.disabled = false; if ( multiple === -1 ) { this.checked = true; @@ -9357,9 +9357,9 @@ window.frmAdminBuildJS = function() { jQuery( '.xml_opts' ).show(); } - const c = $selected.data( 'count' ); + const count = $selected.data( 'count' ); const exportField = jQuery( 'input[name="frm_export_forms[]"]' ); - if ( c === 'single' ) { + if ( count === 'single' ) { exportField.prop( 'multiple', false ); exportField.prop( 'checked', false ); } else { @@ -9770,9 +9770,9 @@ window.frmAdminBuildJS = function() { function removeWPUnload() { window.onbeforeunload = null; - const w = jQuery( window ); - w.off( 'beforeunload.widgets' ); - w.off( 'beforeunload.edit-post' ); + const $window = jQuery( window ); + $window.off( 'beforeunload.widgets' ); + $window.off( 'beforeunload.edit-post' ); } function addMultiselectLabelListener() { @@ -10446,9 +10446,9 @@ window.frmAdminBuildJS = function() { // Bootstrap dropdown button jQuery( '.wp-admin' ).on( 'click', function( e ) { - const t = jQuery( e.target ); + const $target = jQuery( e.target ); const $openDrop = jQuery( '.dropdown.open' ); - if ( $openDrop.length && ! t.hasClass( 'dropdown' ) && ! t.closest( '.dropdown' ).length ) { + if ( $openDrop.length && ! $target.hasClass( 'dropdown' ) && ! $target.closest( '.dropdown' ).length ) { $openDrop.removeClass( 'open' ); } } ); From ff81c98a14a4af1da507010a8938a0815711c3d5 Mon Sep 17 00:00:00 2001 From: Sherv Date: Tue, 21 Apr 2026 14:05:22 +0300 Subject: [PATCH 28/31] fix: update PHPDoc types for default_value to allow float, int, or string in default-value-field.php and textarea-default-value-field.php --- classes/views/frm-fields/back-end/default-value-field.php | 2 +- .../views/frm-fields/back-end/textarea-default-value-field.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/classes/views/frm-fields/back-end/default-value-field.php b/classes/views/frm-fields/back-end/default-value-field.php index 0eb4807b74..83a94a66f2 100644 --- a/classes/views/frm-fields/back-end/default-value-field.php +++ b/classes/views/frm-fields/back-end/default-value-field.php @@ -7,7 +7,7 @@ * @var FrmFieldType $this Field type handler that included this template. * @var array $field Field data including 'id' and 'field_key'. * @var string $default_name HTML name attribute for the input. - * @var int|float|string $default_value Current default value. + * @var float|int|string $default_value Current default value. */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/classes/views/frm-fields/back-end/textarea-default-value-field.php b/classes/views/frm-fields/back-end/textarea-default-value-field.php index 7d56e59e41..a64c5dc310 100644 --- a/classes/views/frm-fields/back-end/textarea-default-value-field.php +++ b/classes/views/frm-fields/back-end/textarea-default-value-field.php @@ -6,7 +6,7 @@ * * @var array $field Field data including 'id' and 'field_key'. * @var string $default_name HTML name attribute for the textarea. - * @var int|float|string $default_value Current default value. + * @var float|int|string $default_value Current default value. */ if ( ! defined( 'ABSPATH' ) ) { From 446ecbea2e1c0084e160fa8a72071761529414b7 Mon Sep 17 00:00:00 2001 From: Sherv Date: Tue, 21 Apr 2026 14:23:28 +0300 Subject: [PATCH 29/31] refactor: improve variable naming for clarity in admin.js --- js/src/admin/admin.js | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/js/src/admin/admin.js b/js/src/admin/admin.js index 7a280caf72..470efe77dd 100644 --- a/js/src/admin/admin.js +++ b/js/src/admin/admin.js @@ -8084,15 +8084,15 @@ window.frmAdminBuildJS = function() { /*jshint validthis:true */ const postField = jQuery( 'select.frm_single_post_field' ); postField.css( 'border-color', '' ); - const $t = this; - const v = jQuery( $t ).val(); - if ( v === '' || v === 'checkbox' ) { + const currentField = this; + const selectedValue = jQuery( currentField ).val(); + if ( selectedValue === '' || selectedValue === 'checkbox' ) { return false; } postField.each( function() { - if ( jQuery( this ).val() === v && this.name !== $t.name ) { + if ( jQuery( this ).val() === selectedValue && this.name !== currentField.name ) { this.style.borderColor = 'red'; - jQuery( $t ).val( '' ); + jQuery( currentField ).val( '' ); infoModal( frmAdminJs.field_already_used ); return false; } @@ -8101,11 +8101,11 @@ window.frmAdminBuildJS = function() { function togglePostContent() { /*jshint validthis:true */ - const v = jQuery( this ).val(); - if ( '' === v ) { + const selectedValue = jQuery( this ).val(); + if ( '' === selectedValue ) { jQuery( '.frm_post_content_opt, select.frm_dyncontent_opt' ).hide().val( '' ); jQuery( '.frm_dyncontent_opt' ).hide(); - } else if ( 'post_content' === v ) { + } else if ( 'post_content' === selectedValue ) { jQuery( '.frm_post_content_opt' ).show(); jQuery( '.frm_dyncontent_opt' ).hide(); jQuery( 'select.frm_dyncontent_opt' ).val( '' ); @@ -8117,15 +8117,15 @@ window.frmAdminBuildJS = function() { function fillDyncontent() { /*jshint validthis:true */ - const v = jQuery( this ).val(); + const selectedValue = jQuery( this ).val(); const $dyn = jQuery( document.getElementById( 'frm_dyncontent' ) ); - if ( '' === v || 'new' === v ) { + if ( '' === selectedValue || 'new' === selectedValue ) { $dyn.val( '' ); jQuery( '.frm_dyncontent_opt' ).show(); } else { jQuery.ajax( { type: 'POST', url: ajaxurl, - data: { action: 'frm_display_get_content', id: v, nonce: frmGlobal.nonce }, + data: { action: 'frm_display_get_content', id: selectedValue, nonce: frmGlobal.nonce }, success( val ) { $dyn.val( val ); jQuery( '.frm_dyncontent_opt' ).show(); @@ -8436,24 +8436,24 @@ window.frmAdminBuildJS = function() { } if ( variable === '[default-html]' || variable === '[default-plain]' ) { - let p = 0; + let plainText = 0; if ( variable === '[default-plain]' ) { - p = 1; + plainText = 1; } jQuery.ajax( { type: 'POST', url: ajaxurl, data: { action: 'frm_get_default_html', form_id: jQuery( 'input[name="id"]' ).val(), - plain_text: p, + plain_text: plainText, nonce: frmGlobal.nonce }, elementId, success( msg ) { if ( rich ) { - const p = document.createElement( 'p' ); - p.innerText = msg; - send_to_editor( p.innerHTML ); + const paragraph = document.createElement( 'p' ); + paragraph.innerText = msg; + send_to_editor( paragraph.innerHTML ); } else { insertContent( contentBox, msg ); } @@ -8494,13 +8494,13 @@ window.frmAdminBuildJS = function() { document.selection.createRange().text = variable; } else { const obj = contentBox[ 0 ]; - const e = obj.selectionEnd; + const selectionEnd = obj.selectionEnd; - variable = maybeFormatInsertedContent( contentBox, variable, obj.selectionStart, e ); + variable = maybeFormatInsertedContent( contentBox, variable, obj.selectionStart, selectionEnd ); obj.value = obj.value.substr( 0, obj.selectionStart ) + variable + obj.value.substr( obj.selectionEnd, obj.value.length ); - const cursorPos = e + variable.length; + const cursorPos = selectionEnd + variable.length; maybeRemoveLayoutClasses( obj, variable ); From 5a10886eba233c54392ff98d2d2a01aeeede3509 Mon Sep 17 00:00:00 2001 From: Sherv Date: Tue, 21 Apr 2026 14:33:51 +0300 Subject: [PATCH 30/31] fix: update PHPStan configuration to streamline error handling and improve ignored error patterns --- phpstan.neon | 775 +++++++++++++++++++++++++-------------------------- 1 file changed, 387 insertions(+), 388 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 542c6b36d7..30a8ffb658 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,388 +1,387 @@ -parameters: - level: max - reportUnmatchedIgnoredErrors: false - bootstrapFiles: - - vendor/php-stubs/wordpress-stubs/wordpress-stubs.php - - stubs.php - excludePaths: - - */node_modules/* - - */tests/* - - */bin/* - - */images/* - - */languages/* - - */js/* - - */vendor/* - - */fonts/* - - */rector.php - - */phpcs-sniffs/* - ignoreErrors: - - '#Access to an undefined property#' - - '#Cannot access (offset|property)+#' - - '#Cannot (call method|cast|assign offset)+#' - - '#Function (apply_filters)+ invoked with#' - - '#code above always terminates.#' - - '#does not (accept|exist on)+#' - - '#expects (array|string|int|callable|object|stdClass|float|bool)+#' - - '#is always (false|true)+.#' - - '#no value type specified.#' - - '#only iterables are supported#' - - '#will always evaluate to#' - - - message: '#in isset\(\) does not exist.#' - paths: - - classes/controllers/FrmEntriesController.php - - classes/controllers/FrmStylesController.php - - stripe/controllers/FrmTransLiteActionsController.php - - stripe/helpers/FrmTransLiteAppHelper.php - - stripe/models/FrmTransLiteAction.php - - '#get_gateway_for_action\(\) never returns array so it can be removed from the return type#' - - - message: '#has an unused parameter#' - paths: - - classes/models/FrmFieldOption.php - - classes/models/FrmSolution.php - - stubs.php - - - message: '#has invalid type#' - path: stubs.php - - - message: '#Possibly invalid array key type#' - paths: - - classes/helpers/FrmFormsListHelper.php - - - message: '#get_mailer\(\) expects#' - path: classes/controllers/FrmSMTPController.php - - - message: '#has invalid return type#' - path: classes/controllers/FrmSMTPController.php - - - message: '#has an unused use#' - path: classes/views/styles/manage.php - - - message: '#Cannot access an offset on mixed.#' - paths: - - classes/helpers/FrmFormMigratorsHelper.php - - classes/models/FrmEntryMeta.php - - - message: '#callback of function spl_autoload_register expects#' - path: formidable.php - - - message: '#Call to an undefined method FrmFieldType::get\_file\_id#' - path: classes/helpers/FrmXMLHelper.php - - - message: '#Cannot use array destructuring on#' - path: classes/helpers/FrmStylesHelper.php - - - message: '#Call to an undefined method FrmFieldType::get_export_headings#' - path: classes/helpers/FrmCSVExportHelper.php - - - message: '#Call to an undefined method object::(get\_pagenum|prepare\_items|get_pagination\_arg)#' - paths: - - classes/controllers/FrmEntriesController.php - - classes/controllers/FrmFormsController.php - - - message: '#Call to an undefined method object::prepare_items#' - path: classes/helpers/FrmDashboardHelper.php - - - message: '#Access to protected property FrmFieldType::\$field#' - path: classes/controllers/FrmFieldsController.php - - - message: '#might not be defined.#' - paths: - - classes/views/* - - stripe/views/* - - css/* - - classes/controllers/FrmApplicationsController.php - - classes/controllers/FrmFieldsController.php - - classes/controllers/FrmStylesController.php - - - message: '#Call to protected method+#' - paths: - - classes/views/frm-fields/back-end/combo-field/sub-field-options.php - - classes/views/frm-fields/back-end/field-options.php - - classes/views/frm-fields/back-end/phone/phone-type.php - - classes/views/frm-fields/front-end/combo-field/combo-field.php - - - message: '#Call to function compact\(\) contains possibly undefined variable#' - paths: - - classes/views/* - - stripe/views/action-settings/payments-options.php - - - message: '#FrmFormAction::prepare_action\(\) expects WP_Post, mixed given#' - path: classes/models/FrmFormAction.php - - - message: '#has no return type specified#' - paths: - - classes/controllers/FrmEmailStylesController.php - - classes/controllers/FrmFieldsController.php - - classes/helpers/FrmXMLHelper.php - - square/helpers/FrmSquareLiteConnectHelper.php - - classes/helpers/FrmListHelper.php - - classes/helpers/FrmAppHelper.php - - classes/controllers/FrmFormActionsController.php - - classes/controllers/FrmAddonsController.php - - classes/controllers/FrmAppController.php - - classes/controllers/FrmFormsController.php - - classes/controllers/FrmStylesController.php - - classes/models/FrmSalesApi.php - - square/controllers/FrmSquareLiteAppController.php - - stripe/helpers/FrmStrpLiteConnectHelper.php - - classes/models/FrmInstallerSkin.php - - classes/controllers/FrmSettingsController.php - - stripe/helpers/FrmStrpLiteLinkRedirectHelper.php - - classes/models/FrmMigrate.php - - stubs.php - - - message: '#with no type specified#' - paths: - - stubs.php - - - message: '#in isset\(\) is not nullable#' - path: stripe/helpers/FrmTransLiteAppHelper.php - - - message: '#of echo cannot be converted to string.#' - paths: - - classes/controllers/FrmFormsController.php - - classes/controllers/FrmStylesController.php - - classes/helpers/FrmAppHelper.php - - classes/helpers/FrmListHelper.php - - classes/views/frm-entries/show.php - - classes/views/frm-forms/add_field.php - - - message: '#is unused.#' - paths: - - classes/controllers/FrmSimpleBlocksController.php - - - message: '#on left side of \?\?#' - path: stripe/controllers/FrmTransLiteActionsController.php - - - message: '#fwrite expects resource, resource\|null given#' - path: classes/helpers/FrmCSVExportHelper.php - - - message: '#should return#' - paths: - - stubs.php - - classes/controllers/FrmAddonsController.php - - classes/controllers/FrmAntiSpamController.php - - classes/controllers/FrmAppController.php - - classes/controllers/FrmDashboardController.php - - classes/controllers/FrmEmailStylesController.php - - classes/controllers/FrmEntriesController.php - - classes/controllers/FrmFieldsController.php - - classes/controllers/FrmFormActionsController.php - - classes/controllers/FrmFormTemplatesController.php - - classes/controllers/FrmFormsController.php - - classes/controllers/FrmStylesController.php - - classes/helpers/FrmAppHelper.php - - classes/helpers/FrmCSVExportHelper.php - - classes/helpers/FrmEntriesHelper.php - - classes/helpers/FrmEntriesListHelper.php - - classes/helpers/FrmFieldsHelper.php - - classes/helpers/FrmFormsHelper.php - - classes/helpers/FrmListHelper.php - - classes/helpers/FrmStylesHelper.php - - classes/helpers/FrmXMLHelper.php - - classes/models/FrmDb.php - - classes/models/FrmEntry.php - - classes/models/FrmEntryMeta.php - - classes/models/FrmField.php - - classes/models/FrmForm.php - - classes/models/FrmFormAction.php - - classes/models/FrmSettings.php - - classes/models/FrmStyle.php - - classes/models/fields/FrmFieldType.php - - stripe/controllers/FrmStrpLiteActionsController.php - - stripe/controllers/FrmTransLiteActionsController.php - - stripe/helpers/FrmStrpLiteConnectHelper.php - - stripe/helpers/FrmTransLiteAppHelper.php - - stripe/models/FrmStrpLiteAuth.php - - stripe/models/FrmTransLiteAction.php - - classes/controllers/FrmOnboardingWizardController.php - - classes/controllers/FrmTestModeController.php - - classes/controllers/FrmUsageController.php - - classes/controllers/FrmWelcomeTourController.php - - classes/controllers/FrmXMLController.php - - classes/factories/FrmCaptchaFactory.php - - classes/factories/FrmEntryFactory.php - - classes/factories/FrmFieldFactory.php - - classes/helpers/FrmEmailHelper.php - - classes/helpers/FrmEmailSummaryHelper.php - - classes/helpers/FrmOnSubmitHelper.php - - classes/helpers/FrmStylesCardHelper.php - - classes/helpers/FrmStylesPreviewHelper.php - - classes/helpers/FrmSubmitHelper.php - - classes/models/FrmAddon.php - - classes/models/FrmAntiSpam.php - - classes/models/FrmCreateFile.php - - classes/models/FrmEmailSummary.php - - classes/models/FrmEntryFormatter.php - - classes/models/FrmEntryValidate.php - - classes/models/FrmEntryValues.php - - classes/models/FrmFieldValue.php - - classes/models/FrmFormApi.php - - classes/models/FrmFormMigrator.php - - classes/models/FrmFormState.php - - classes/models/FrmFormTemplateApi.php - - classes/models/FrmHoneypot.php - - classes/models/FrmInbox.php - - classes/models/FrmOnSubmitAction.php - - classes/models/FrmPluginSearch.php - - classes/models/FrmSpamCheckDenylist.php - - classes/models/FrmSpamCheckWPDisallowedWords.php - - classes/models/FrmUsage.php - - classes/models/fields/FrmFieldCaptcha.php - - classes/models/fields/FrmFieldCombo.php - - classes/models/fields/FrmFieldCreditCard.php - - classes/models/fields/FrmFieldHTML.php - - classes/models/fields/FrmFieldName.php - - classes/models/fields/FrmFieldNumber.php - - classes/models/fields/FrmFieldSubmit.php - - classes/models/fields/FrmFieldUserID.php - - classes/views/frm-form-actions/email_action.php - - classes/views/styles/components/FrmSliderStyleComponent.php - - square/controllers/FrmSquareLiteActionsController.php - - square/helpers/FrmSquareLiteConnectHelper.php - - square/models/FrmSquareLiteSettings.php - - stripe/controllers/FrmStrpLiteEventsController.php - - stripe/controllers/FrmTransLitePaymentsController.php - - stripe/helpers/FrmStrpLiteAppHelper.php - - stripe/helpers/FrmStrpLiteConnectApiAdapter.php - - stripe/helpers/FrmTransLiteListHelper.php - - stripe/models/FrmStrpLiteSettings.php - - message: '#results in an error.#' - - message: '#Possibly invalid array key type mixed#' - - message: '#of encapsed string cannot be cast to string#' - - - message: '#but returns mixed#' - paths: - - classes/controllers/FrmSMTPController.php - - classes/controllers/FrmSimpleBlocksController.php - - classes/helpers/FrmCurrencyHelper.php - - classes/helpers/FrmShortcodeHelper.php - - classes/helpers/FrmTipsHelper.php - - classes/models/FrmApplicationTemplate.php - - classes/models/FrmFieldCaptchaSettings.php - - classes/models/FrmFieldTypeOptionData.php - - classes/models/FrmMigrate.php - - classes/models/FrmSalesApi.php - - classes/models/FrmTableHTMLGenerator.php - - classes/models/FrmYoutubeFeedApi.php - - square/controllers/FrmSquareLiteAppController.php - - stripe/controllers/FrmStrpLiteLinkController.php - - stripe/controllers/FrmTransLiteCRUDController.php - - stripe/helpers/FrmStrpLiteLinkRedirectHelper.php - - stripe/helpers/FrmStrpLiteSubscriptionHelper.php - - stripe/helpers/FrmStrpLiteUrlParamHelper.php - - stripe/models/FrmStrpLitePaymentTypeHandler.php - - stripe/models/FrmTransLiteDb.php - - stripe/models/FrmTransLiteSubscription.php - - - message: '#mixed given#' - paths: - - classes/controllers/FrmFormActionsController.php - - classes/controllers/FrmFormsController.php - - classes/helpers/FrmXMLHelper.php - - classes/models/FrmCreateFile.php - - classes/views/frm-settings/general.php - - classes/views/styles/_styles-list.php - - css/_single_theme.css.php - - css/custom_theme.css.php - - square/controllers/FrmSquareLiteActionsController.php - - square/controllers/FrmSquareLiteAppController.php - - stripe/controllers/FrmStrpLiteLinkController.php - - stripe/controllers/FrmTransLiteActionsController.php - - stripe/helpers/FrmStrpLiteSubscriptionHelper.php - - stripe/models/FrmStrpLiteAuth.php - - - message: '#cannot be converted to string.#' - paths: - - classes/views/styles/_style-preview-container.php - - classes/views/styles/components/templates/text-toggle.php - - - message: '#Cannot access an offset on mixed#' - paths: - - classes/controllers/FrmFormActionsController.php - - classes/controllers/FrmFormTemplatesController.php - - classes/controllers/FrmStylesController.php - - classes/helpers/FrmAppHelper.php - - classes/helpers/FrmCSVExportHelper.php - - classes/helpers/FrmXMLHelper.php - - classes/models/FrmEntry.php - - classes/models/FrmEntryValidate.php - - classes/models/FrmForm.php - - classes/models/FrmFormMigrator.php - - classes/models/FrmHoneypot.php - - classes/models/fields/FrmFieldType.php - - classes/views/xml/posts_xml.php - - stripe/controllers/FrmTransLiteActionsController.php - - message: '#might not exist on#' - - message: '#is not a file or it does not exist#' - - message: '#Cannot use \+\+ on mixed#' - - message: '#Cannot use -- on mixed#' - - message: '#Cannot use array destructuring on mixed#' - - - message: '#always exists and is not nullable#' - paths: - - classes/helpers/FrmFormsHelper.php - - classes/helpers/FrmXMLHelper.php - - classes/models/FrmEntryValidate.php - - message: '#Possibly invalid array key#' - - - message: '#should return array<(string|array)> but returns array#' - paths: - - classes/controllers/FrmApplicationsController.php - - stripe/models/FrmStrpLitePaymentTypeHandler.php - - - message: '#should return string but returns float#' - path: classes/models/FrmEmailStats.php - - message: '#on a separate line has no effect#' - - message: '#Cannot clone non-object variable#' - - - message: '#so it can be removed from the by-ref type#' - paths: - - classes/controllers/FrmFormsController.php - - classes/controllers/FrmXMLController.php - - classes/models/FrmDb.php - - - message: '#function array_map expects#' - paths: - - classes/helpers/FrmAppHelper.php - - classes/helpers/FrmHtmlHelper.php - - classes/models/FrmEntry.php - - classes/models/fields/FrmFieldType.php - - message: '#expects resource#' - - message: '#might not be defined#' - - - message: '#array given#' - path: classes/helpers/FrmFieldsHelper.php - - message: '#Cannot use \+\+ on int\|false#' - - message: '#Only booleans are allowed in an (elseif|if) condition#' - - message: '#Only booleans are allowed in a negated boolean#' - - message: '#Only booleans are allowed in a ternary operator condition#' - - message: '#Loose comparison via "(!=|==)" is not allowed#' - - message: '#Variable property access on#' - - message: '#does not call parent constructor#' - - message: '#Only booleans are allowed in (&&|\|\|)#' - - message: '#Variable method call on#' - - message: '#requires parameter \#[\d]* to be set#' - - message: '#array_filter\(\) requires parameter \#2 to be passed to avoid loose comparison semantics.#' - - message: '#Static call to __construct\(\) is only allowed on a parent class in the constructor#' - - message: '#Variable static method call on#' - - '#Construct empty\(\) is not allowed. Use more strict comparison#' - - - message: '#Foreach overwrites \$ip with its value variable.#' - path: classes/helpers/FrmAppHelper.php - - - message: '#Only numeric types are allowed#' - paths: - - classes/helpers/FrmCSVExportHelper.php - - classes/models/FrmStyle.php - - - message: "#Casting to int something that's already int#" - paths: - - classes/helpers/FrmXMLHelper.php - - '#Method FrmShortcodeHelper::get_shortcode_tag\(\) should return string but returns array\|string#' - - - message: '#always exists and is not falsy.#' - paths: - - classes/models/FrmAddon.php +parameters: + level: max + reportUnmatchedIgnoredErrors: false + bootstrapFiles: + - vendor/php-stubs/wordpress-stubs/wordpress-stubs.php + - stubs.php + excludePaths: + - */node_modules/* + - */tests/* + - */bin/* + - */images/* + - */languages/* + - */js/* + - */vendor/* + - */fonts/* + - */rector.php + - */phpcs-sniffs/* + ignoreErrors: + - '#Access to an undefined property#' + - '#Cannot access (offset|property)+#' + - '#Cannot (call method|cast|assign offset)+#' + - '#Function (apply_filters)+ invoked with#' + - '#code above always terminates.#' + - '#does not (accept|exist on)+#' + - '#expects (array|string|int|callable|object|stdClass|float|bool)+#' + - '#is always (false|true)+.#' + - '#no value type specified.#' + - '#only iterables are supported#' + - '#will always evaluate to#' + - + message: '#in isset\(\) does not exist.#' + paths: + - classes/controllers/FrmEntriesController.php + - classes/controllers/FrmStylesController.php + - stripe/controllers/FrmTransLiteActionsController.php + - stripe/helpers/FrmTransLiteAppHelper.php + - stripe/models/FrmTransLiteAction.php + - '#get_gateway_for_action\(\) never returns array so it can be removed from the return type#' + - + message: '#has an unused parameter#' + paths: + - classes/models/FrmFieldOption.php + - classes/models/FrmSolution.php + - stubs.php + - + message: '#has invalid type#' + path: stubs.php + - + message: '#Possibly invalid array key type#' + paths: + - classes/helpers/FrmFormsListHelper.php + - + message: '#get_mailer\(\) expects#' + path: classes/controllers/FrmSMTPController.php + - + message: '#has invalid return type#' + path: classes/controllers/FrmSMTPController.php + - + message: '#has an unused use#' + path: classes/views/styles/manage.php + - + message: '#Cannot access an offset on mixed.#' + paths: + - classes/helpers/FrmFormMigratorsHelper.php + - classes/models/FrmEntryMeta.php + - + message: '#callback of function spl_autoload_register expects#' + path: formidable.php + - + message: '#Call to an undefined method FrmFieldType::get\_file\_id#' + path: classes/helpers/FrmXMLHelper.php + - + message: '#Cannot use array destructuring on#' + path: classes/helpers/FrmStylesHelper.php + - + message: '#Call to an undefined method FrmFieldType::get_export_headings#' + path: classes/helpers/FrmCSVExportHelper.php + - + message: '#Call to an undefined method object::(get\_pagenum|prepare\_items|get_pagination\_arg)#' + paths: + - classes/controllers/FrmEntriesController.php + - classes/controllers/FrmFormsController.php + - + message: '#Call to an undefined method object::prepare_items#' + path: classes/helpers/FrmDashboardHelper.php + - + message: '#Access to protected property FrmFieldType::\$field#' + path: classes/controllers/FrmFieldsController.php + - + message: '#might not be defined.#' + paths: + - classes/views/* + - stripe/views/* + - css/* + - classes/controllers/FrmApplicationsController.php + - classes/controllers/FrmFieldsController.php + - classes/controllers/FrmStylesController.php + - + message: '#Call to protected method+#' + paths: + - classes/views/frm-fields/back-end/combo-field/sub-field-options.php + - classes/views/frm-fields/back-end/phone/phone-type.php + - classes/views/frm-fields/front-end/combo-field/combo-field.php + - + message: '#Call to function compact\(\) contains possibly undefined variable#' + paths: + - classes/views/* + - stripe/views/action-settings/payments-options.php + - + message: '#FrmFormAction::prepare_action\(\) expects WP_Post, mixed given#' + path: classes/models/FrmFormAction.php + - + message: '#has no return type specified#' + paths: + - classes/controllers/FrmEmailStylesController.php + - classes/controllers/FrmFieldsController.php + - classes/helpers/FrmXMLHelper.php + - square/helpers/FrmSquareLiteConnectHelper.php + - classes/helpers/FrmListHelper.php + - classes/helpers/FrmAppHelper.php + - classes/controllers/FrmFormActionsController.php + - classes/controllers/FrmAddonsController.php + - classes/controllers/FrmAppController.php + - classes/controllers/FrmFormsController.php + - classes/controllers/FrmStylesController.php + - classes/models/FrmSalesApi.php + - square/controllers/FrmSquareLiteAppController.php + - stripe/helpers/FrmStrpLiteConnectHelper.php + - classes/models/FrmInstallerSkin.php + - classes/controllers/FrmSettingsController.php + - stripe/helpers/FrmStrpLiteLinkRedirectHelper.php + - classes/models/FrmMigrate.php + - stubs.php + - + message: '#with no type specified#' + paths: + - stubs.php + - + message: '#in isset\(\) is not nullable#' + path: stripe/helpers/FrmTransLiteAppHelper.php + - + message: '#of echo cannot be converted to string.#' + paths: + - classes/controllers/FrmFormsController.php + - classes/controllers/FrmStylesController.php + - classes/helpers/FrmAppHelper.php + - classes/helpers/FrmListHelper.php + - classes/views/frm-entries/show.php + - classes/views/frm-forms/add_field.php + - + message: '#is unused.#' + paths: + - classes/controllers/FrmSimpleBlocksController.php + - + message: '#on left side of \?\?#' + path: stripe/controllers/FrmTransLiteActionsController.php + - + message: '#fwrite expects resource, resource\|null given#' + path: classes/helpers/FrmCSVExportHelper.php + - + message: '#should return#' + paths: + - stubs.php + - classes/controllers/FrmAddonsController.php + - classes/controllers/FrmAntiSpamController.php + - classes/controllers/FrmAppController.php + - classes/controllers/FrmDashboardController.php + - classes/controllers/FrmEmailStylesController.php + - classes/controllers/FrmEntriesController.php + - classes/controllers/FrmFieldsController.php + - classes/controllers/FrmFormActionsController.php + - classes/controllers/FrmFormTemplatesController.php + - classes/controllers/FrmFormsController.php + - classes/controllers/FrmStylesController.php + - classes/helpers/FrmAppHelper.php + - classes/helpers/FrmCSVExportHelper.php + - classes/helpers/FrmEntriesHelper.php + - classes/helpers/FrmEntriesListHelper.php + - classes/helpers/FrmFieldsHelper.php + - classes/helpers/FrmFormsHelper.php + - classes/helpers/FrmListHelper.php + - classes/helpers/FrmStylesHelper.php + - classes/helpers/FrmXMLHelper.php + - classes/models/FrmDb.php + - classes/models/FrmEntry.php + - classes/models/FrmEntryMeta.php + - classes/models/FrmField.php + - classes/models/FrmForm.php + - classes/models/FrmFormAction.php + - classes/models/FrmSettings.php + - classes/models/FrmStyle.php + - classes/models/fields/FrmFieldType.php + - stripe/controllers/FrmStrpLiteActionsController.php + - stripe/controllers/FrmTransLiteActionsController.php + - stripe/helpers/FrmStrpLiteConnectHelper.php + - stripe/helpers/FrmTransLiteAppHelper.php + - stripe/models/FrmStrpLiteAuth.php + - stripe/models/FrmTransLiteAction.php + - classes/controllers/FrmOnboardingWizardController.php + - classes/controllers/FrmTestModeController.php + - classes/controllers/FrmUsageController.php + - classes/controllers/FrmWelcomeTourController.php + - classes/controllers/FrmXMLController.php + - classes/factories/FrmCaptchaFactory.php + - classes/factories/FrmEntryFactory.php + - classes/factories/FrmFieldFactory.php + - classes/helpers/FrmEmailHelper.php + - classes/helpers/FrmEmailSummaryHelper.php + - classes/helpers/FrmOnSubmitHelper.php + - classes/helpers/FrmStylesCardHelper.php + - classes/helpers/FrmStylesPreviewHelper.php + - classes/helpers/FrmSubmitHelper.php + - classes/models/FrmAddon.php + - classes/models/FrmAntiSpam.php + - classes/models/FrmCreateFile.php + - classes/models/FrmEmailSummary.php + - classes/models/FrmEntryFormatter.php + - classes/models/FrmEntryValidate.php + - classes/models/FrmEntryValues.php + - classes/models/FrmFieldValue.php + - classes/models/FrmFormApi.php + - classes/models/FrmFormMigrator.php + - classes/models/FrmFormState.php + - classes/models/FrmFormTemplateApi.php + - classes/models/FrmHoneypot.php + - classes/models/FrmInbox.php + - classes/models/FrmOnSubmitAction.php + - classes/models/FrmPluginSearch.php + - classes/models/FrmSpamCheckDenylist.php + - classes/models/FrmSpamCheckWPDisallowedWords.php + - classes/models/FrmUsage.php + - classes/models/fields/FrmFieldCaptcha.php + - classes/models/fields/FrmFieldCombo.php + - classes/models/fields/FrmFieldCreditCard.php + - classes/models/fields/FrmFieldHTML.php + - classes/models/fields/FrmFieldName.php + - classes/models/fields/FrmFieldNumber.php + - classes/models/fields/FrmFieldSubmit.php + - classes/models/fields/FrmFieldUserID.php + - classes/views/frm-form-actions/email_action.php + - classes/views/styles/components/FrmSliderStyleComponent.php + - square/controllers/FrmSquareLiteActionsController.php + - square/helpers/FrmSquareLiteConnectHelper.php + - square/models/FrmSquareLiteSettings.php + - stripe/controllers/FrmStrpLiteEventsController.php + - stripe/controllers/FrmTransLitePaymentsController.php + - stripe/helpers/FrmStrpLiteAppHelper.php + - stripe/helpers/FrmStrpLiteConnectApiAdapter.php + - stripe/helpers/FrmTransLiteListHelper.php + - stripe/models/FrmStrpLiteSettings.php + - message: '#results in an error.#' + - message: '#Possibly invalid array key type mixed#' + - message: '#of encapsed string cannot be cast to string#' + - + message: '#but returns mixed#' + paths: + - classes/controllers/FrmSMTPController.php + - classes/controllers/FrmSimpleBlocksController.php + - classes/helpers/FrmCurrencyHelper.php + - classes/helpers/FrmShortcodeHelper.php + - classes/helpers/FrmTipsHelper.php + - classes/models/FrmApplicationTemplate.php + - classes/models/FrmFieldCaptchaSettings.php + - classes/models/FrmFieldTypeOptionData.php + - classes/models/FrmMigrate.php + - classes/models/FrmSalesApi.php + - classes/models/FrmTableHTMLGenerator.php + - classes/models/FrmYoutubeFeedApi.php + - square/controllers/FrmSquareLiteAppController.php + - stripe/controllers/FrmStrpLiteLinkController.php + - stripe/controllers/FrmTransLiteCRUDController.php + - stripe/helpers/FrmStrpLiteLinkRedirectHelper.php + - stripe/helpers/FrmStrpLiteSubscriptionHelper.php + - stripe/helpers/FrmStrpLiteUrlParamHelper.php + - stripe/models/FrmStrpLitePaymentTypeHandler.php + - stripe/models/FrmTransLiteDb.php + - stripe/models/FrmTransLiteSubscription.php + - + message: '#mixed given#' + paths: + - classes/controllers/FrmFormActionsController.php + - classes/controllers/FrmFormsController.php + - classes/helpers/FrmXMLHelper.php + - classes/models/FrmCreateFile.php + - classes/views/frm-settings/general.php + - classes/views/styles/_styles-list.php + - css/_single_theme.css.php + - css/custom_theme.css.php + - square/controllers/FrmSquareLiteActionsController.php + - square/controllers/FrmSquareLiteAppController.php + - stripe/controllers/FrmStrpLiteLinkController.php + - stripe/controllers/FrmTransLiteActionsController.php + - stripe/helpers/FrmStrpLiteSubscriptionHelper.php + - stripe/models/FrmStrpLiteAuth.php + - + message: '#cannot be converted to string.#' + paths: + - classes/views/styles/_style-preview-container.php + - classes/views/styles/components/templates/text-toggle.php + - + message: '#Cannot access an offset on mixed#' + paths: + - classes/controllers/FrmFormActionsController.php + - classes/controllers/FrmFormTemplatesController.php + - classes/controllers/FrmStylesController.php + - classes/helpers/FrmAppHelper.php + - classes/helpers/FrmCSVExportHelper.php + - classes/helpers/FrmXMLHelper.php + - classes/models/FrmEntry.php + - classes/models/FrmEntryValidate.php + - classes/models/FrmForm.php + - classes/models/FrmFormMigrator.php + - classes/models/FrmHoneypot.php + - classes/models/fields/FrmFieldType.php + - classes/views/xml/posts_xml.php + - stripe/controllers/FrmTransLiteActionsController.php + - message: '#might not exist on#' + - message: '#is not a file or it does not exist#' + - message: '#Cannot use \+\+ on mixed#' + - message: '#Cannot use -- on mixed#' + - message: '#Cannot use array destructuring on mixed#' + - + message: '#always exists and is not nullable#' + paths: + - classes/helpers/FrmFormsHelper.php + - classes/helpers/FrmXMLHelper.php + - classes/models/FrmEntryValidate.php + - message: '#Possibly invalid array key#' + - + message: '#should return array<(string|array)> but returns array#' + paths: + - classes/controllers/FrmApplicationsController.php + - stripe/models/FrmStrpLitePaymentTypeHandler.php + - + message: '#should return string but returns float#' + path: classes/models/FrmEmailStats.php + - message: '#on a separate line has no effect#' + - message: '#Cannot clone non-object variable#' + - + message: '#so it can be removed from the by-ref type#' + paths: + - classes/controllers/FrmFormsController.php + - classes/controllers/FrmXMLController.php + - classes/models/FrmDb.php + - + message: '#function array_map expects#' + paths: + - classes/helpers/FrmAppHelper.php + - classes/helpers/FrmHtmlHelper.php + - classes/models/FrmEntry.php + - classes/models/fields/FrmFieldType.php + - message: '#expects resource#' + - message: '#might not be defined#' + - + message: '#array given#' + path: classes/helpers/FrmFieldsHelper.php + - message: '#Cannot use \+\+ on int\|false#' + - message: '#Only booleans are allowed in an (elseif|if) condition#' + - message: '#Only booleans are allowed in a negated boolean#' + - message: '#Only booleans are allowed in a ternary operator condition#' + - message: '#Loose comparison via "(!=|==)" is not allowed#' + - message: '#Variable property access on#' + - message: '#does not call parent constructor#' + - message: '#Only booleans are allowed in (&&|\|\|)#' + - message: '#Variable method call on#' + - message: '#requires parameter \#[\d]* to be set#' + - message: '#array_filter\(\) requires parameter \#2 to be passed to avoid loose comparison semantics.#' + - message: '#Static call to __construct\(\) is only allowed on a parent class in the constructor#' + - message: '#Variable static method call on#' + - '#Construct empty\(\) is not allowed. Use more strict comparison#' + - + message: '#Foreach overwrites \$ip with its value variable.#' + path: classes/helpers/FrmAppHelper.php + - + message: '#Only numeric types are allowed#' + paths: + - classes/helpers/FrmCSVExportHelper.php + - classes/models/FrmStyle.php + - + message: "#Casting to int something that's already int#" + paths: + - classes/helpers/FrmXMLHelper.php + - '#Method FrmShortcodeHelper::get_shortcode_tag\(\) should return string but returns array\|string#' + - + message: '#always exists and is not falsy.#' + paths: + - classes/models/FrmAddon.php From 2e532f2b23e5a2a5955683c4f29f556207728efe Mon Sep 17 00:00:00 2001 From: Sherv Date: Tue, 21 Apr 2026 14:51:47 +0300 Subject: [PATCH 31/31] fix: add new path to PHPStan configuration for ignored error patterns in field-options.php --- phpstan.neon | 1 + 1 file changed, 1 insertion(+) diff --git a/phpstan.neon b/phpstan.neon index 30a8ffb658..cd7f5e1bd1 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -99,6 +99,7 @@ parameters: message: '#Call to protected method+#' paths: - classes/views/frm-fields/back-end/combo-field/sub-field-options.php + - classes/views/frm-fields/back-end/field-options.php - classes/views/frm-fields/back-end/phone/phone-type.php - classes/views/frm-fields/front-end/combo-field/combo-field.php -