From 8b8e56165c1c23764630384d997ba963662b6748 Mon Sep 17 00:00:00 2001 From: Rahul Verma Date: Wed, 15 Apr 2026 10:11:58 +0530 Subject: [PATCH 01/24] Fix: Prevent phone field country flag from changing on autocomplete/input The intlTelInput library's input handler calls _updateCountryFromNumber() on every input event, which auto-detects the country code and changes the flag. This causes the flag to jump around when browser autocomplete fills the field or when the user edits/removes the country code. Override _updateCountryFromNumber to a no-op after initialization so the flag only changes when the user explicitly picks a country from the dropdown (_selectListItem -> _setCountry bypasses this method). Fixes #2598 Co-Authored-By: Claude Opus 4.6 (1M context) --- assets/js/unminified/blocks/phone.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/assets/js/unminified/blocks/phone.js b/assets/js/unminified/blocks/phone.js index e8463d914..7f4715283 100644 --- a/assets/js/unminified/blocks/phone.js +++ b/assets/js/unminified/blocks/phone.js @@ -139,6 +139,13 @@ function initializePhoneField() { } const iti = window.intlTelInput( phoneNumber, itlOptions ); + + // Prevent the country flag from changing based on input value changes + // (e.g., browser autocomplete, typing, or deleting the country code). + // The flag should only change when the user explicitly selects a country from the dropdown. + // Dropdown selection goes through _selectListItem -> _setCountry directly, so it still works. + iti._updateCountryFromNumber = () => false; + const countriesData = iti?.countryList.querySelectorAll( '.iti__country' ); From c8b0df23ef2b9a3867cc6980f289139d447f156a Mon Sep 17 00:00:00 2001 From: Rahul Verma Date: Wed, 15 Apr 2026 00:17:52 +0530 Subject: [PATCH 02/24] Fix: Background color not applied in non-iframe editor mode Pass `shouldIframe` prop to StyleSettings and use it to resolve the correct root element. When the editor is not in iframe mode, query `.editor-styles-wrapper` from `iframeBody` so style overrides target the right container. Fixes #2567 Co-Authored-By: Claude Opus 4.6 (1M context) --- src/admin/single-form-settings/Editor.js | 1 + src/admin/single-form-settings/tabs/StyleSettings.js | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/admin/single-form-settings/Editor.js b/src/admin/single-form-settings/Editor.js index dcb112ce7..1c843657b 100644 --- a/src/admin/single-form-settings/Editor.js +++ b/src/admin/single-form-settings/Editor.js @@ -612,6 +612,7 @@ const SureformsFormSpecificSettings = () => { iframeBody={ documentBody } rootHtmlTag={ rootHtmlTag } editorMode={ editorMode } + shouldIframe={ shouldIframe } /> ) } diff --git a/src/admin/single-form-settings/tabs/StyleSettings.js b/src/admin/single-form-settings/tabs/StyleSettings.js index 6195ddbe6..96356e07a 100644 --- a/src/admin/single-form-settings/tabs/StyleSettings.js +++ b/src/admin/single-form-settings/tabs/StyleSettings.js @@ -34,6 +34,7 @@ function StyleSettings( props ) { iframeBody, editorMode, rootHtmlTag, + shouldIframe, } = props; let sureformsKeys = useSelect( @@ -45,7 +46,7 @@ function StyleSettings( props ) { [ editorStore ] ); const formStyling = sureformsKeys?._srfm_forms_styling || {}; - const rootRef = iframeBody; + const rootRef = shouldIframe ? iframeBody : iframeBody?.querySelector( '.editor-styles-wrapper' ); const deviceType = useDeviceType(); const [ submitBtn, setSubmitBtn ] = useState( null ); From bcbe7a8050a1f81b8453d0b3f124258b5578f553 Mon Sep 17 00:00:00 2001 From: rahulv8085 Date: Fri, 17 Apr 2026 15:31:56 +0530 Subject: [PATCH 03/24] Feature: Add dynamic default value for dropdown and multi-choice fields Add URL parameter and smart tag based pre-selection for single-select dropdown and multi-choice fields. Users can set a Dynamic Default Value using smart tags like {get_input:param} to pre-select an option based on URL query parameters (e.g., ?service=development). - Add dynamicDefaultValue attribute to dropdown and multichoice block.json - Add Dynamic Default Value control in editor (visible only in single select mode) - Process smart tags on frontend to resolve and match option labels - Clear dynamic default when switching to multi-select mode Co-Authored-By: Claude Opus 4.6 (1M context) --- inc/blocks/dropdown/block.json | 4 ++++ inc/blocks/multichoice/block.json | 4 ++++ inc/fields/dropdown-markup.php | 35 +++++++++++++++++++++++++++++++ inc/fields/multichoice-markup.php | 35 +++++++++++++++++++++++++++++++ src/blocks/dropdown/edit.js | 26 ++++++++++++++++++++++- src/blocks/multi-choice/edit.js | 26 ++++++++++++++++++++++- 6 files changed, 128 insertions(+), 2 deletions(-) diff --git a/inc/blocks/dropdown/block.json b/inc/blocks/dropdown/block.json index 270475cc1..2312c3fde 100644 --- a/inc/blocks/dropdown/block.json +++ b/inc/blocks/dropdown/block.json @@ -87,6 +87,10 @@ "preselectedOptions": { "type": "array", "default": [] + }, + "dynamicDefaultValue": { + "type": "string", + "default": "" } } } diff --git a/inc/blocks/multichoice/block.json b/inc/blocks/multichoice/block.json index 8715e3bb1..69ddb6c43 100644 --- a/inc/blocks/multichoice/block.json +++ b/inc/blocks/multichoice/block.json @@ -98,6 +98,10 @@ "preselectedOptions": { "type": "array", "default": [] + }, + "dynamicDefaultValue": { + "type": "string", + "default": "" } } } diff --git a/inc/fields/dropdown-markup.php b/inc/fields/dropdown-markup.php index aaa208ac7..3e1d101d9 100644 --- a/inc/fields/dropdown-markup.php +++ b/inc/fields/dropdown-markup.php @@ -12,6 +12,7 @@ use Spec_Gb_Helper; use SRFM\Inc\Helper; +use SRFM\Inc\Smart_Tags; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. @@ -85,6 +86,7 @@ public function __construct( $attributes ) { $this->multi_select_attr = ! empty( $attributes['multiSelect'] ) ? 'true' : 'false'; $this->search_attr = ! empty( $attributes['searchable'] ) ? 'true' : 'false'; $this->preselected_options = $attributes['preselectedOptions'] ?? []; + $this->resolve_dynamic_default( $attributes ); $this->set_markup_properties(); $this->set_aria_described_by(); @@ -186,6 +188,39 @@ function( $i ) { ); } + /** + * Resolve dynamic default value from smart tags and override preselected options. + * + * @param array $attributes Block attributes. + * @since x.x.x + * @return void + */ + protected function resolve_dynamic_default( $attributes ) { + $dynamic_default = $attributes['dynamicDefaultValue'] ?? ''; + if ( empty( $dynamic_default ) || ! empty( $attributes['multiSelect'] ) ) { + return; + } + + $smart_tags = new Smart_Tags(); + $resolved = $smart_tags->process_smart_tags( $dynamic_default ); + + if ( empty( $resolved ) || ! is_string( $resolved ) ) { + return; + } + + $resolved = trim( $resolved ); + + if ( is_array( $this->options ) ) { + foreach ( $this->options as $i => $option ) { + $option_label = is_array( $option ) ? ( $option['label'] ?? '' ) : ''; + if ( strcasecmp( $option_label, $resolved ) === 0 ) { + $this->preselected_options = [ $i ]; + return; + } + } + } + } + /** * Data attribute markup for min and max value * diff --git a/inc/fields/multichoice-markup.php b/inc/fields/multichoice-markup.php index c2029ad83..1af7ad913 100644 --- a/inc/fields/multichoice-markup.php +++ b/inc/fields/multichoice-markup.php @@ -10,6 +10,7 @@ use Spec_Gb_Helper; use SRFM\Inc\Helper; +use SRFM\Inc\Smart_Tags; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. @@ -122,6 +123,7 @@ public function __construct( $attributes ) { $this->choice_width_attr = $this->choice_width ? 'srfm-choice-width-' . str_replace( '.', '-', $this->choice_width ) : ''; $this->show_values = apply_filters( 'srfm_show_options_values', false, $attributes['showValues'] ?? false ); $this->preselected_options = $attributes['preselectedOptions'] ?? []; + $this->resolve_dynamic_default( $attributes ); $this->set_markup_properties(); $this->set_aria_described_by(); } @@ -201,6 +203,39 @@ class="srfm-input-slug ); ?>-single" $attributes Block attributes. + * @since x.x.x + * @return void + */ + protected function resolve_dynamic_default( $attributes ) { + $dynamic_default = $attributes['dynamicDefaultValue'] ?? ''; + if ( empty( $dynamic_default ) || ! $this->single_selection ) { + return; + } + + $smart_tags = new Smart_Tags(); + $resolved = $smart_tags->process_smart_tags( $dynamic_default ); + + if ( empty( $resolved ) || ! is_string( $resolved ) ) { + return; + } + + $resolved = trim( $resolved ); + + if ( is_array( $this->options ) ) { + foreach ( $this->options as $i => $option ) { + $option_title = $option['optionTitle'] ?? ''; + if ( strcasecmp( $option_title, $resolved ) === 0 ) { + $this->preselected_options = [ $i ]; + return; + } + } + } + } + /** * Data attribute markup for min and max value * diff --git a/src/blocks/dropdown/edit.js b/src/blocks/dropdown/edit.js index 320c5739a..9de169548 100644 --- a/src/blocks/dropdown/edit.js +++ b/src/blocks/dropdown/edit.js @@ -58,6 +58,7 @@ const Edit = ( props ) => { maxValue, showValues, preselectedOptions = [], + dynamicDefaultValue, } = attributes; const currentFormId = useGetCurrentFormId( clientId ); const [ newOption, setNewOption ] = useState( '' ); @@ -524,11 +525,34 @@ const Edit = ( props ) => { label={ __( 'Allow Multiple', 'sureforms' ) } checked={ multiSelect } onChange={ ( checked ) => - setAttributes( { multiSelect: checked } ) + setAttributes( { + multiSelect: checked, + ...( checked && { + dynamicDefaultValue: '', + } ), + } ) } /> ), }, + { + id: 'dynamicDefaultValue', + component: ! multiSelect ? ( + + setAttributes( { dynamicDefaultValue: value } ) + } + /> + ) : null, + }, { id: 'minMaxComponent', component: minMaxComponent, diff --git a/src/blocks/multi-choice/edit.js b/src/blocks/multi-choice/edit.js index c4cb04785..6ca3740f4 100644 --- a/src/blocks/multi-choice/edit.js +++ b/src/blocks/multi-choice/edit.js @@ -61,6 +61,7 @@ const Edit = ( props ) => { maxValue, showValues, preselectedOptions = [], + dynamicDefaultValue, } = attributes; const currentFormId = useGetCurrentFormId( clientId ); @@ -619,11 +620,34 @@ const Edit = ( props ) => { label={ __( 'Single Choice Only', 'sureforms' ) } checked={ singleSelection } onChange={ ( checked ) => - setAttributes( { singleSelection: checked } ) + setAttributes( { + singleSelection: checked, + ...( ! checked && { + dynamicDefaultValue: '', + } ), + } ) } /> ), }, + { + id: 'dynamicDefaultValue', + component: singleSelection ? ( + + setAttributes( { dynamicDefaultValue: value } ) + } + /> + ) : null, + }, { id: 'min-max', component: minMaxValue, From 554decc75fc8e9db2708f525c4c708e654bad82b Mon Sep 17 00:00:00 2001 From: rahulv8085 Date: Fri, 17 Apr 2026 15:41:21 +0530 Subject: [PATCH 04/24] Test: Add PHPUnit tests for dynamic default value feature Add test coverage for dynamic default value in dropdown and multi-choice fields. Tests cover GET param preselection, case-insensitive matching, no-match scenarios, multi-select mode guard, static preselection override, and empty dynamic default preservation. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../fields/test-dropdown-dynamic-default.php | 225 ++++++++++++++++++ .../test-multichoice-dynamic-default.php | 203 ++++++++++++++++ 2 files changed, 428 insertions(+) create mode 100644 tests/unit/inc/fields/test-dropdown-dynamic-default.php create mode 100644 tests/unit/inc/fields/test-multichoice-dynamic-default.php diff --git a/tests/unit/inc/fields/test-dropdown-dynamic-default.php b/tests/unit/inc/fields/test-dropdown-dynamic-default.php new file mode 100644 index 000000000..960ef3a06 --- /dev/null +++ b/tests/unit/inc/fields/test-dropdown-dynamic-default.php @@ -0,0 +1,225 @@ + + */ + private $base_attributes; + + protected function setUp(): void { + $this->base_attributes = [ + 'required' => false, + 'fieldWidth' => '', + 'label' => 'Select Plan', + 'help' => '', + 'block_id' => 'dd-dyn-001', + 'formId' => '1', + 'slug' => 'select-plan', + 'placeholder' => 'Select an option', + 'defaultValue' => '', + 'checked' => '', + 'isUnique' => false, + 'options' => [ + [ 'label' => 'Basic', 'icon' => '' ], + [ 'label' => 'Professional', 'icon' => '' ], + [ 'label' => 'Enterprise', 'icon' => '' ], + ], + 'multiSelect' => false, + 'searchable' => false, + 'preselectedOptions' => [], + 'errorMsg' => '', + 'minValue' => '', + 'maxValue' => '', + 'dynamicDefaultValue' => '', + ]; + } + + protected function tearDown(): void { + unset( $_SERVER['QUERY_STRING'] ); + } + + /** + * Test that GET param smart tag pre-selects the matching dropdown option. + */ + public function test_get_param_preselects_matching_option() { + $_SERVER['QUERY_STRING'] = 'plan=Professional'; + + $attributes = $this->base_attributes; + $attributes['dynamicDefaultValue'] = '{get_input:plan}'; + + $dd = new Dropdown_Markup( $attributes ); + $markup = $dd->markup(); + + // "Professional" is at index 1, should have "selected" attribute. + $this->assert_option_selected( $markup, 'Professional' ); + } + + /** + * Test case-insensitive matching of GET param value against option labels. + */ + public function test_get_param_case_insensitive_match() { + $_SERVER['QUERY_STRING'] = 'plan=ENTERPRISE'; + + $attributes = $this->base_attributes; + $attributes['dynamicDefaultValue'] = '{get_input:plan}'; + + $dd = new Dropdown_Markup( $attributes ); + $markup = $dd->markup(); + + $this->assert_option_selected( $markup, 'Enterprise' ); + } + + /** + * Test that no option is selected when GET param value doesn't match any option. + */ + public function test_get_param_no_match_leaves_unselected() { + $_SERVER['QUERY_STRING'] = 'plan=Premium'; + + $attributes = $this->base_attributes; + $attributes['dynamicDefaultValue'] = '{get_input:plan}'; + + $dd = new Dropdown_Markup( $attributes ); + $markup = $dd->markup(); + + // Only the placeholder should have "selected", not any real option. + $this->assert_no_option_selected( $markup ); + } + + /** + * Test that empty GET param does not pre-select any option. + */ + public function test_empty_get_param_no_preselection() { + $_SERVER['QUERY_STRING'] = ''; + + $attributes = $this->base_attributes; + $attributes['dynamicDefaultValue'] = '{get_input:plan}'; + + $dd = new Dropdown_Markup( $attributes ); + $markup = $dd->markup(); + + $this->assert_no_option_selected( $markup ); + } + + /** + * Test that dynamic default is ignored when multiSelect is true. + */ + public function test_dynamic_default_ignored_in_multi_select_mode() { + $_SERVER['QUERY_STRING'] = 'plan=Professional'; + + $attributes = $this->base_attributes; + $attributes['multiSelect'] = true; + $attributes['dynamicDefaultValue'] = '{get_input:plan}'; + + $dd = new Dropdown_Markup( $attributes ); + $markup = $dd->markup(); + + $this->assert_no_option_selected( $markup ); + } + + /** + * Test that dynamic default overrides static preselected options. + */ + public function test_dynamic_default_overrides_static_preselection() { + $_SERVER['QUERY_STRING'] = 'plan=Enterprise'; + + $attributes = $this->base_attributes; + $attributes['preselectedOptions'] = [ 0 ]; // Static: "Basic" preselected. + $attributes['dynamicDefaultValue'] = '{get_input:plan}'; + + $dd = new Dropdown_Markup( $attributes ); + $markup = $dd->markup(); + + // "Enterprise" should be selected, not "Basic". + $this->assert_option_selected( $markup, 'Enterprise' ); + $this->assert_option_not_selected( $markup, 'Basic' ); + } + + /** + * Test that empty dynamicDefaultValue preserves static preselected options. + */ + public function test_empty_dynamic_default_preserves_static_preselection() { + $attributes = $this->base_attributes; + $attributes['preselectedOptions'] = [ 0 ]; + $attributes['dynamicDefaultValue'] = ''; + + $dd = new Dropdown_Markup( $attributes ); + $markup = $dd->markup(); + + $this->assert_option_selected( $markup, 'Basic' ); + } + + /** + * Test the first option can be selected via GET param. + */ + public function test_get_param_selects_first_option() { + $_SERVER['QUERY_STRING'] = 'plan=Basic'; + + $attributes = $this->base_attributes; + $attributes['dynamicDefaultValue'] = '{get_input:plan}'; + + $dd = new Dropdown_Markup( $attributes ); + $markup = $dd->markup(); + + $this->assert_option_selected( $markup, 'Basic' ); + } + + /** + * Test that data-preselected attribute is set when dynamic default resolves. + */ + public function test_data_preselected_attribute_set_on_match() { + $_SERVER['QUERY_STRING'] = 'plan=Professional'; + + $attributes = $this->base_attributes; + $attributes['dynamicDefaultValue'] = '{get_input:plan}'; + + $dd = new Dropdown_Markup( $attributes ); + $markup = $dd->markup(); + + $this->assertStringContainsString( 'data-preselected', $markup ); + $this->assertStringContainsString( 'Professional', $markup ); + } + + /** + * Assert that a dropdown option with the given label is selected. + * + * @param string $markup The rendered HTML markup. + * @param string $label The option label to check. + */ + private function assert_option_selected( $markup, $label ) { + $pattern = '/]*value="' . preg_quote( $label, '/' ) . '"[^>]*selected/'; + $this->assertMatchesRegularExpression( $pattern, $markup, "Option '{$label}' should be selected." ); + } + + /** + * Assert that a dropdown option with the given label is NOT selected. + * + * @param string $markup The rendered HTML markup. + * @param string $label The option label to check. + */ + private function assert_option_not_selected( $markup, $label ) { + $pattern = '/]*value="' . preg_quote( $label, '/' ) . '"[^>]*selected/'; + $this->assertDoesNotMatchRegularExpression( $pattern, $markup, "Option '{$label}' should NOT be selected." ); + } + + /** + * Assert that no real option (excluding placeholder) is selected. + * + * @param string $markup The rendered HTML markup. + */ + private function assert_no_option_selected( $markup ) { + // Count "selected" occurrences — only the placeholder should have it. + $count = substr_count( $markup, 'selected' ); + $this->assertLessThanOrEqual( 1, $count, 'Only the placeholder option should have "selected" attribute.' ); + } +} diff --git a/tests/unit/inc/fields/test-multichoice-dynamic-default.php b/tests/unit/inc/fields/test-multichoice-dynamic-default.php new file mode 100644 index 000000000..c768e3943 --- /dev/null +++ b/tests/unit/inc/fields/test-multichoice-dynamic-default.php @@ -0,0 +1,203 @@ + + */ + private $base_attributes; + + protected function setUp(): void { + $this->base_attributes = [ + 'required' => false, + 'fieldWidth' => '', + 'label' => 'Select Service', + 'help' => '', + 'block_id' => 'mc-dyn-001', + 'formId' => '1', + 'slug' => 'select-service', + 'placeholder' => '', + 'defaultValue' => '', + 'checked' => '', + 'isUnique' => false, + 'options' => [ + [ 'optionTitle' => 'Development', 'icon' => '', 'image' => '' ], + [ 'optionTitle' => 'Design', 'icon' => '', 'image' => '' ], + [ 'optionTitle' => 'Consulting', 'icon' => '', 'image' => '' ], + ], + 'singleSelection' => true, + 'choiceWidth' => '', + 'verticalLayout' => false, + 'optionType' => 'icon', + 'errorMsg' => '', + 'minValue' => '', + 'maxValue' => '', + 'preselectedOptions' => [], + 'dynamicDefaultValue' => '', + ]; + } + + protected function tearDown(): void { + unset( $_SERVER['QUERY_STRING'] ); + } + + /** + * Test that GET param smart tag pre-selects the matching option. + */ + public function test_get_param_preselects_matching_option() { + $_SERVER['QUERY_STRING'] = 'service=Design'; + + $attributes = $this->base_attributes; + $attributes['dynamicDefaultValue'] = '{get_input:service}'; + + $mc = new Multichoice_Markup( $attributes ); + $markup = $mc->markup(); + + // "Design" is at index 1, its input should be checked. + $this->assertStringContainsString( 'type="radio"', $markup ); + $this->assert_option_checked( $markup, 'mc-dyn-001', 1 ); + } + + /** + * Test case-insensitive matching of GET param value against option titles. + */ + public function test_get_param_case_insensitive_match() { + $_SERVER['QUERY_STRING'] = 'service=CONSULTING'; + + $attributes = $this->base_attributes; + $attributes['dynamicDefaultValue'] = '{get_input:service}'; + + $mc = new Multichoice_Markup( $attributes ); + $markup = $mc->markup(); + + // "Consulting" is at index 2. + $this->assert_option_checked( $markup, 'mc-dyn-001', 2 ); + } + + /** + * Test that no option is checked when GET param value doesn't match any option. + */ + public function test_get_param_no_match_leaves_unchecked() { + $_SERVER['QUERY_STRING'] = 'service=Marketing'; + + $attributes = $this->base_attributes; + $attributes['dynamicDefaultValue'] = '{get_input:service}'; + + $mc = new Multichoice_Markup( $attributes ); + $markup = $mc->markup(); + + $this->assertStringNotContainsString( 'checked', $markup ); + } + + /** + * Test that empty GET param does not pre-select any option. + */ + public function test_empty_get_param_no_preselection() { + $_SERVER['QUERY_STRING'] = ''; + + $attributes = $this->base_attributes; + $attributes['dynamicDefaultValue'] = '{get_input:service}'; + + $mc = new Multichoice_Markup( $attributes ); + $markup = $mc->markup(); + + $this->assertStringNotContainsString( 'checked', $markup ); + } + + /** + * Test that dynamic default is ignored when singleSelection is false (multi-select mode). + */ + public function test_dynamic_default_ignored_in_multi_select_mode() { + $_SERVER['QUERY_STRING'] = 'service=Design'; + + $attributes = $this->base_attributes; + $attributes['singleSelection'] = false; + $attributes['dynamicDefaultValue'] = '{get_input:service}'; + + $mc = new Multichoice_Markup( $attributes ); + $markup = $mc->markup(); + + $this->assertStringNotContainsString( 'checked', $markup ); + } + + /** + * Test that dynamic default overrides static preselected options. + */ + public function test_dynamic_default_overrides_static_preselection() { + $_SERVER['QUERY_STRING'] = 'service=Consulting'; + + $attributes = $this->base_attributes; + $attributes['preselectedOptions'] = [ 0 ]; // Static: "Development" preselected. + $attributes['dynamicDefaultValue'] = '{get_input:service}'; + + $mc = new Multichoice_Markup( $attributes ); + $markup = $mc->markup(); + + // "Consulting" (index 2) should be checked, not "Development" (index 0). + $this->assert_option_checked( $markup, 'mc-dyn-001', 2 ); + $this->assert_option_not_checked( $markup, 'mc-dyn-001', 0 ); + } + + /** + * Test that empty dynamicDefaultValue preserves static preselected options. + */ + public function test_empty_dynamic_default_preserves_static_preselection() { + $attributes = $this->base_attributes; + $attributes['preselectedOptions'] = [ 0 ]; + $attributes['dynamicDefaultValue'] = ''; + + $mc = new Multichoice_Markup( $attributes ); + $markup = $mc->markup(); + + $this->assert_option_checked( $markup, 'mc-dyn-001', 0 ); + } + + /** + * Test the first matching option is selected when GET param matches. + */ + public function test_get_param_selects_first_option() { + $_SERVER['QUERY_STRING'] = 'service=Development'; + + $attributes = $this->base_attributes; + $attributes['dynamicDefaultValue'] = '{get_input:service}'; + + $mc = new Multichoice_Markup( $attributes ); + $markup = $mc->markup(); + + $this->assert_option_checked( $markup, 'mc-dyn-001', 0 ); + } + + /** + * Assert that a specific multi-choice option is checked in the markup. + * + * @param string $markup The rendered HTML markup. + * @param string $block_id The block ID. + * @param int $index The option index. + */ + private function assert_option_checked( $markup, $block_id, $index ) { + $pattern = '/id="srfm-multi-choice-' . preg_quote( $block_id . '-' . $index, '/' ) . '"[^>]*checked/'; + $this->assertMatchesRegularExpression( $pattern, $markup, "Option at index {$index} should be checked." ); + } + + /** + * Assert that a specific multi-choice option is NOT checked in the markup. + * + * @param string $markup The rendered HTML markup. + * @param string $block_id The block ID. + * @param int $index The option index. + */ + private function assert_option_not_checked( $markup, $block_id, $index ) { + $pattern = '/id="srfm-multi-choice-' . preg_quote( $block_id . '-' . $index, '/' ) . '"[^>]*checked/'; + $this->assertDoesNotMatchRegularExpression( $pattern, $markup, "Option at index {$index} should NOT be checked." ); + } +} From 1bb27383b75a837867dff4cd28d41313f5f48e16 Mon Sep 17 00:00:00 2001 From: rahulv8085 Date: Fri, 17 Apr 2026 16:15:09 +0530 Subject: [PATCH 05/24] Fix: Resolve PHPStan type error and move tests to existing test files - Cast dynamicDefaultValue to string before passing to process_smart_tags() to satisfy PHPStan level 9 type checking - Move test_resolve_dynamic_default() into existing test-dropdown-markup.php and test-multichoice-markup.php per linting convention - Remove standalone test files Co-Authored-By: Claude Opus 4.6 (1M context) --- inc/fields/dropdown-markup.php | 2 +- inc/fields/multichoice-markup.php | 2 +- .../fields/test-dropdown-dynamic-default.php | 225 ------------------ .../unit/inc/fields/test-dropdown-markup.php | 44 ++++ .../test-multichoice-dynamic-default.php | 203 ---------------- .../inc/fields/test-multichoice-markup.php | 46 ++++ 6 files changed, 92 insertions(+), 430 deletions(-) delete mode 100644 tests/unit/inc/fields/test-dropdown-dynamic-default.php delete mode 100644 tests/unit/inc/fields/test-multichoice-dynamic-default.php diff --git a/inc/fields/dropdown-markup.php b/inc/fields/dropdown-markup.php index 3e1d101d9..dc6b55ecc 100644 --- a/inc/fields/dropdown-markup.php +++ b/inc/fields/dropdown-markup.php @@ -196,7 +196,7 @@ function( $i ) { * @return void */ protected function resolve_dynamic_default( $attributes ) { - $dynamic_default = $attributes['dynamicDefaultValue'] ?? ''; + $dynamic_default = is_string( $attributes['dynamicDefaultValue'] ?? '' ) ? $attributes['dynamicDefaultValue'] : ''; if ( empty( $dynamic_default ) || ! empty( $attributes['multiSelect'] ) ) { return; } diff --git a/inc/fields/multichoice-markup.php b/inc/fields/multichoice-markup.php index 1af7ad913..0f237f073 100644 --- a/inc/fields/multichoice-markup.php +++ b/inc/fields/multichoice-markup.php @@ -211,7 +211,7 @@ class="srfm-input-slug ); ?>-single" single_selection ) { return; } diff --git a/tests/unit/inc/fields/test-dropdown-dynamic-default.php b/tests/unit/inc/fields/test-dropdown-dynamic-default.php deleted file mode 100644 index 960ef3a06..000000000 --- a/tests/unit/inc/fields/test-dropdown-dynamic-default.php +++ /dev/null @@ -1,225 +0,0 @@ - - */ - private $base_attributes; - - protected function setUp(): void { - $this->base_attributes = [ - 'required' => false, - 'fieldWidth' => '', - 'label' => 'Select Plan', - 'help' => '', - 'block_id' => 'dd-dyn-001', - 'formId' => '1', - 'slug' => 'select-plan', - 'placeholder' => 'Select an option', - 'defaultValue' => '', - 'checked' => '', - 'isUnique' => false, - 'options' => [ - [ 'label' => 'Basic', 'icon' => '' ], - [ 'label' => 'Professional', 'icon' => '' ], - [ 'label' => 'Enterprise', 'icon' => '' ], - ], - 'multiSelect' => false, - 'searchable' => false, - 'preselectedOptions' => [], - 'errorMsg' => '', - 'minValue' => '', - 'maxValue' => '', - 'dynamicDefaultValue' => '', - ]; - } - - protected function tearDown(): void { - unset( $_SERVER['QUERY_STRING'] ); - } - - /** - * Test that GET param smart tag pre-selects the matching dropdown option. - */ - public function test_get_param_preselects_matching_option() { - $_SERVER['QUERY_STRING'] = 'plan=Professional'; - - $attributes = $this->base_attributes; - $attributes['dynamicDefaultValue'] = '{get_input:plan}'; - - $dd = new Dropdown_Markup( $attributes ); - $markup = $dd->markup(); - - // "Professional" is at index 1, should have "selected" attribute. - $this->assert_option_selected( $markup, 'Professional' ); - } - - /** - * Test case-insensitive matching of GET param value against option labels. - */ - public function test_get_param_case_insensitive_match() { - $_SERVER['QUERY_STRING'] = 'plan=ENTERPRISE'; - - $attributes = $this->base_attributes; - $attributes['dynamicDefaultValue'] = '{get_input:plan}'; - - $dd = new Dropdown_Markup( $attributes ); - $markup = $dd->markup(); - - $this->assert_option_selected( $markup, 'Enterprise' ); - } - - /** - * Test that no option is selected when GET param value doesn't match any option. - */ - public function test_get_param_no_match_leaves_unselected() { - $_SERVER['QUERY_STRING'] = 'plan=Premium'; - - $attributes = $this->base_attributes; - $attributes['dynamicDefaultValue'] = '{get_input:plan}'; - - $dd = new Dropdown_Markup( $attributes ); - $markup = $dd->markup(); - - // Only the placeholder should have "selected", not any real option. - $this->assert_no_option_selected( $markup ); - } - - /** - * Test that empty GET param does not pre-select any option. - */ - public function test_empty_get_param_no_preselection() { - $_SERVER['QUERY_STRING'] = ''; - - $attributes = $this->base_attributes; - $attributes['dynamicDefaultValue'] = '{get_input:plan}'; - - $dd = new Dropdown_Markup( $attributes ); - $markup = $dd->markup(); - - $this->assert_no_option_selected( $markup ); - } - - /** - * Test that dynamic default is ignored when multiSelect is true. - */ - public function test_dynamic_default_ignored_in_multi_select_mode() { - $_SERVER['QUERY_STRING'] = 'plan=Professional'; - - $attributes = $this->base_attributes; - $attributes['multiSelect'] = true; - $attributes['dynamicDefaultValue'] = '{get_input:plan}'; - - $dd = new Dropdown_Markup( $attributes ); - $markup = $dd->markup(); - - $this->assert_no_option_selected( $markup ); - } - - /** - * Test that dynamic default overrides static preselected options. - */ - public function test_dynamic_default_overrides_static_preselection() { - $_SERVER['QUERY_STRING'] = 'plan=Enterprise'; - - $attributes = $this->base_attributes; - $attributes['preselectedOptions'] = [ 0 ]; // Static: "Basic" preselected. - $attributes['dynamicDefaultValue'] = '{get_input:plan}'; - - $dd = new Dropdown_Markup( $attributes ); - $markup = $dd->markup(); - - // "Enterprise" should be selected, not "Basic". - $this->assert_option_selected( $markup, 'Enterprise' ); - $this->assert_option_not_selected( $markup, 'Basic' ); - } - - /** - * Test that empty dynamicDefaultValue preserves static preselected options. - */ - public function test_empty_dynamic_default_preserves_static_preselection() { - $attributes = $this->base_attributes; - $attributes['preselectedOptions'] = [ 0 ]; - $attributes['dynamicDefaultValue'] = ''; - - $dd = new Dropdown_Markup( $attributes ); - $markup = $dd->markup(); - - $this->assert_option_selected( $markup, 'Basic' ); - } - - /** - * Test the first option can be selected via GET param. - */ - public function test_get_param_selects_first_option() { - $_SERVER['QUERY_STRING'] = 'plan=Basic'; - - $attributes = $this->base_attributes; - $attributes['dynamicDefaultValue'] = '{get_input:plan}'; - - $dd = new Dropdown_Markup( $attributes ); - $markup = $dd->markup(); - - $this->assert_option_selected( $markup, 'Basic' ); - } - - /** - * Test that data-preselected attribute is set when dynamic default resolves. - */ - public function test_data_preselected_attribute_set_on_match() { - $_SERVER['QUERY_STRING'] = 'plan=Professional'; - - $attributes = $this->base_attributes; - $attributes['dynamicDefaultValue'] = '{get_input:plan}'; - - $dd = new Dropdown_Markup( $attributes ); - $markup = $dd->markup(); - - $this->assertStringContainsString( 'data-preselected', $markup ); - $this->assertStringContainsString( 'Professional', $markup ); - } - - /** - * Assert that a dropdown option with the given label is selected. - * - * @param string $markup The rendered HTML markup. - * @param string $label The option label to check. - */ - private function assert_option_selected( $markup, $label ) { - $pattern = '/]*value="' . preg_quote( $label, '/' ) . '"[^>]*selected/'; - $this->assertMatchesRegularExpression( $pattern, $markup, "Option '{$label}' should be selected." ); - } - - /** - * Assert that a dropdown option with the given label is NOT selected. - * - * @param string $markup The rendered HTML markup. - * @param string $label The option label to check. - */ - private function assert_option_not_selected( $markup, $label ) { - $pattern = '/]*value="' . preg_quote( $label, '/' ) . '"[^>]*selected/'; - $this->assertDoesNotMatchRegularExpression( $pattern, $markup, "Option '{$label}' should NOT be selected." ); - } - - /** - * Assert that no real option (excluding placeholder) is selected. - * - * @param string $markup The rendered HTML markup. - */ - private function assert_no_option_selected( $markup ) { - // Count "selected" occurrences — only the placeholder should have it. - $count = substr_count( $markup, 'selected' ); - $this->assertLessThanOrEqual( 1, $count, 'Only the placeholder option should have "selected" attribute.' ); - } -} diff --git a/tests/unit/inc/fields/test-dropdown-markup.php b/tests/unit/inc/fields/test-dropdown-markup.php index ca01dacc2..5708e0e8d 100644 --- a/tests/unit/inc/fields/test-dropdown-markup.php +++ b/tests/unit/inc/fields/test-dropdown-markup.php @@ -62,6 +62,50 @@ public function test_data_attribute_markup_empty_for_single_select() { $this->assertSame( '', $result ); } + /** + * Test resolve_dynamic_default pre-selects the matching option via GET param. + */ + public function test_resolve_dynamic_default() { + $_SERVER['QUERY_STRING'] = 'country=Canada'; + + $attributes = [ + 'required' => false, + 'fieldWidth' => '', + 'label' => 'Select Country', + 'help' => '', + 'block_id' => 'dd002', + 'formId' => '1', + 'slug' => 'select-country', + 'placeholder' => 'Select an option', + 'defaultValue' => '', + 'checked' => '', + 'isUnique' => false, + 'options' => [ + [ 'label' => 'USA', 'icon' => '' ], + [ 'label' => 'Canada', 'icon' => '' ], + [ 'label' => 'UK', 'icon' => '' ], + ], + 'multiSelect' => false, + 'searchable' => false, + 'preselectedOptions' => [], + 'errorMsg' => '', + 'minValue' => '', + 'maxValue' => '', + 'dynamicDefaultValue' => '{get_input:country}', + ]; + $dd = new Dropdown_Markup( $attributes ); + $markup = $dd->markup(); + + // "Canada" should have "selected" attribute. + $this->assertMatchesRegularExpression( + '/]*value="Canada"[^>]*selected/', + $markup, + 'Option "Canada" should be selected.' + ); + + unset( $_SERVER['QUERY_STRING'] ); + } + private function call_private_method( $object, $method_name, $parameters = [] ) { $reflection = new \ReflectionClass( get_class( $object ) ); $method = $reflection->getMethod( $method_name ); diff --git a/tests/unit/inc/fields/test-multichoice-dynamic-default.php b/tests/unit/inc/fields/test-multichoice-dynamic-default.php deleted file mode 100644 index c768e3943..000000000 --- a/tests/unit/inc/fields/test-multichoice-dynamic-default.php +++ /dev/null @@ -1,203 +0,0 @@ - - */ - private $base_attributes; - - protected function setUp(): void { - $this->base_attributes = [ - 'required' => false, - 'fieldWidth' => '', - 'label' => 'Select Service', - 'help' => '', - 'block_id' => 'mc-dyn-001', - 'formId' => '1', - 'slug' => 'select-service', - 'placeholder' => '', - 'defaultValue' => '', - 'checked' => '', - 'isUnique' => false, - 'options' => [ - [ 'optionTitle' => 'Development', 'icon' => '', 'image' => '' ], - [ 'optionTitle' => 'Design', 'icon' => '', 'image' => '' ], - [ 'optionTitle' => 'Consulting', 'icon' => '', 'image' => '' ], - ], - 'singleSelection' => true, - 'choiceWidth' => '', - 'verticalLayout' => false, - 'optionType' => 'icon', - 'errorMsg' => '', - 'minValue' => '', - 'maxValue' => '', - 'preselectedOptions' => [], - 'dynamicDefaultValue' => '', - ]; - } - - protected function tearDown(): void { - unset( $_SERVER['QUERY_STRING'] ); - } - - /** - * Test that GET param smart tag pre-selects the matching option. - */ - public function test_get_param_preselects_matching_option() { - $_SERVER['QUERY_STRING'] = 'service=Design'; - - $attributes = $this->base_attributes; - $attributes['dynamicDefaultValue'] = '{get_input:service}'; - - $mc = new Multichoice_Markup( $attributes ); - $markup = $mc->markup(); - - // "Design" is at index 1, its input should be checked. - $this->assertStringContainsString( 'type="radio"', $markup ); - $this->assert_option_checked( $markup, 'mc-dyn-001', 1 ); - } - - /** - * Test case-insensitive matching of GET param value against option titles. - */ - public function test_get_param_case_insensitive_match() { - $_SERVER['QUERY_STRING'] = 'service=CONSULTING'; - - $attributes = $this->base_attributes; - $attributes['dynamicDefaultValue'] = '{get_input:service}'; - - $mc = new Multichoice_Markup( $attributes ); - $markup = $mc->markup(); - - // "Consulting" is at index 2. - $this->assert_option_checked( $markup, 'mc-dyn-001', 2 ); - } - - /** - * Test that no option is checked when GET param value doesn't match any option. - */ - public function test_get_param_no_match_leaves_unchecked() { - $_SERVER['QUERY_STRING'] = 'service=Marketing'; - - $attributes = $this->base_attributes; - $attributes['dynamicDefaultValue'] = '{get_input:service}'; - - $mc = new Multichoice_Markup( $attributes ); - $markup = $mc->markup(); - - $this->assertStringNotContainsString( 'checked', $markup ); - } - - /** - * Test that empty GET param does not pre-select any option. - */ - public function test_empty_get_param_no_preselection() { - $_SERVER['QUERY_STRING'] = ''; - - $attributes = $this->base_attributes; - $attributes['dynamicDefaultValue'] = '{get_input:service}'; - - $mc = new Multichoice_Markup( $attributes ); - $markup = $mc->markup(); - - $this->assertStringNotContainsString( 'checked', $markup ); - } - - /** - * Test that dynamic default is ignored when singleSelection is false (multi-select mode). - */ - public function test_dynamic_default_ignored_in_multi_select_mode() { - $_SERVER['QUERY_STRING'] = 'service=Design'; - - $attributes = $this->base_attributes; - $attributes['singleSelection'] = false; - $attributes['dynamicDefaultValue'] = '{get_input:service}'; - - $mc = new Multichoice_Markup( $attributes ); - $markup = $mc->markup(); - - $this->assertStringNotContainsString( 'checked', $markup ); - } - - /** - * Test that dynamic default overrides static preselected options. - */ - public function test_dynamic_default_overrides_static_preselection() { - $_SERVER['QUERY_STRING'] = 'service=Consulting'; - - $attributes = $this->base_attributes; - $attributes['preselectedOptions'] = [ 0 ]; // Static: "Development" preselected. - $attributes['dynamicDefaultValue'] = '{get_input:service}'; - - $mc = new Multichoice_Markup( $attributes ); - $markup = $mc->markup(); - - // "Consulting" (index 2) should be checked, not "Development" (index 0). - $this->assert_option_checked( $markup, 'mc-dyn-001', 2 ); - $this->assert_option_not_checked( $markup, 'mc-dyn-001', 0 ); - } - - /** - * Test that empty dynamicDefaultValue preserves static preselected options. - */ - public function test_empty_dynamic_default_preserves_static_preselection() { - $attributes = $this->base_attributes; - $attributes['preselectedOptions'] = [ 0 ]; - $attributes['dynamicDefaultValue'] = ''; - - $mc = new Multichoice_Markup( $attributes ); - $markup = $mc->markup(); - - $this->assert_option_checked( $markup, 'mc-dyn-001', 0 ); - } - - /** - * Test the first matching option is selected when GET param matches. - */ - public function test_get_param_selects_first_option() { - $_SERVER['QUERY_STRING'] = 'service=Development'; - - $attributes = $this->base_attributes; - $attributes['dynamicDefaultValue'] = '{get_input:service}'; - - $mc = new Multichoice_Markup( $attributes ); - $markup = $mc->markup(); - - $this->assert_option_checked( $markup, 'mc-dyn-001', 0 ); - } - - /** - * Assert that a specific multi-choice option is checked in the markup. - * - * @param string $markup The rendered HTML markup. - * @param string $block_id The block ID. - * @param int $index The option index. - */ - private function assert_option_checked( $markup, $block_id, $index ) { - $pattern = '/id="srfm-multi-choice-' . preg_quote( $block_id . '-' . $index, '/' ) . '"[^>]*checked/'; - $this->assertMatchesRegularExpression( $pattern, $markup, "Option at index {$index} should be checked." ); - } - - /** - * Assert that a specific multi-choice option is NOT checked in the markup. - * - * @param string $markup The rendered HTML markup. - * @param string $block_id The block ID. - * @param int $index The option index. - */ - private function assert_option_not_checked( $markup, $block_id, $index ) { - $pattern = '/id="srfm-multi-choice-' . preg_quote( $block_id . '-' . $index, '/' ) . '"[^>]*checked/'; - $this->assertDoesNotMatchRegularExpression( $pattern, $markup, "Option at index {$index} should NOT be checked." ); - } -} diff --git a/tests/unit/inc/fields/test-multichoice-markup.php b/tests/unit/inc/fields/test-multichoice-markup.php index 9d0b5cb7b..853279bdb 100644 --- a/tests/unit/inc/fields/test-multichoice-markup.php +++ b/tests/unit/inc/fields/test-multichoice-markup.php @@ -92,4 +92,50 @@ public function test_markup_uses_radio_in_single_selection() { $this->assertStringContainsString( 'srfm-radio-mode', $markup ); $this->assertStringContainsString( 'name="srfm-input-multi-choice-mc002"', $markup ); } + + /** + * Test resolve_dynamic_default pre-selects the matching option via GET param. + */ + public function test_resolve_dynamic_default() { + $_SERVER['QUERY_STRING'] = 'service=Blue'; + + $attributes = [ + 'required' => false, + 'fieldWidth' => '', + 'label' => 'Pick Color', + 'help' => '', + 'block_id' => 'mc003', + 'formId' => '1', + 'slug' => 'pick-color', + 'placeholder' => '', + 'defaultValue' => '', + 'checked' => '', + 'isUnique' => false, + 'options' => [ + [ 'optionTitle' => 'Red', 'icon' => '', 'image' => '' ], + [ 'optionTitle' => 'Blue', 'icon' => '', 'image' => '' ], + [ 'optionTitle' => 'Green', 'icon' => '', 'image' => '' ], + ], + 'singleSelection' => true, + 'choiceWidth' => '', + 'verticalLayout' => false, + 'optionType' => 'icon', + 'errorMsg' => '', + 'minValue' => '', + 'maxValue' => '', + 'preselectedOptions' => [], + 'dynamicDefaultValue' => '{get_input:service}', + ]; + $mc = new Multichoice_Markup( $attributes ); + $markup = $mc->markup(); + + // "Blue" is at index 1, its input should be checked. + $this->assertMatchesRegularExpression( + '/id="srfm-multi-choice-mc003-1"[^>]*checked/', + $markup, + 'Option "Blue" at index 1 should be checked.' + ); + + unset( $_SERVER['QUERY_STRING'] ); + } } From a226ff2d4bedd9ae0f07e2362a34a59049a36599 Mon Sep 17 00:00:00 2001 From: mohitbsftester Date: Mon, 20 Apr 2026 00:26:03 +0530 Subject: [PATCH 06/24] fix(payments): add PLN currency Fixes #2652 --- inc/database/tables/payments.php | 1 + inc/payments/payment-helper.php | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/inc/database/tables/payments.php b/inc/database/tables/payments.php index 74580d4bd..6a85b9fd0 100644 --- a/inc/database/tables/payments.php +++ b/inc/database/tables/payments.php @@ -117,6 +117,7 @@ class Payments extends Base { 'SGD', 'HKD', 'NOK', + 'PLN', 'TRY', 'RUB', 'INR', diff --git a/inc/payments/payment-helper.php b/inc/payments/payment-helper.php index cc9e1db98..b8376d736 100644 --- a/inc/payments/payment-helper.php +++ b/inc/payments/payment-helper.php @@ -255,6 +255,11 @@ public static function get_all_currencies_data() { 'symbol' => 'kr', 'decimal_places' => 2, ], + 'PLN' => [ + 'name' => __( 'Polish Złoty', 'sureforms' ), + 'symbol' => 'zł', + 'decimal_places' => 2, + ], 'KRW' => [ 'name' => __( 'South Korean Won', 'sureforms' ), 'symbol' => '₩', From 3aa4700275144c3f0508c91b832564d57d347d52 Mon Sep 17 00:00:00 2001 From: rahulv8085 Date: Mon, 20 Apr 2026 01:12:20 +0530 Subject: [PATCH 07/24] Fix: Pass block type slug via block_args in srfm_field_options filter When a field block (e.g., dropdown, multi-choice) is placed inside a repeater, the field's `slug` attribute gets prefixed with the parent repeater's slug (e.g., `srfm-repeater-srfm-dropdown` instead of `dropdown`). This caused the `srfm_field_options` filter consumers to fail block-type identification since they relied on `$attributes['slug']` matching the block type name. This change injects the block type slug (`$this->slug`) into a dedicated `block_args` key before passing the attributes to the filter, giving filter consumers a reliable way to identify the block type regardless of nesting context. Fixes brainstormforce/sureforms#2639 Co-Authored-By: Claude Opus 4.6 (1M context) --- inc/fields/base.php | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/inc/fields/base.php b/inc/fields/base.php index 4f7e0baa7..b43408212 100644 --- a/inc/fields/base.php +++ b/inc/fields/base.php @@ -392,20 +392,24 @@ protected function set_properties( $attributes ) { $filter_classes = apply_filters( 'srfm_field_classes', $default_classes, [ 'attributes' => $attributes ] ); $field_config = apply_filters( 'srfm_field_config', [], [ 'attributes' => $attributes ] ); - $this->field_config = $field_config ? htmlspecialchars( Helper::get_string_value( wp_json_encode( $field_config, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) ), ENT_QUOTES, 'UTF-8' ) : ''; - $this->attributes = $attributes; - $this->required = $attributes['required'] ?? false; - $this->field_width = $attributes['fieldWidth'] ?? ''; - $this->label = $attributes['label'] ?? ''; - $this->help = $attributes['help'] ?? ''; - $this->block_id = isset( $attributes['block_id'] ) ? Helper::get_string_value( $attributes['block_id'] ) : ''; - $this->form_id = isset( $attributes['formId'] ) ? Helper::get_string_value( $attributes['formId'] ) : ''; - $this->block_slug = $attributes['slug'] ?? ''; - $this->class_name = $filter_classes; - $this->placeholder = $attributes['placeholder'] ?? ''; - $this->default = $attributes['defaultValue'] ?? ''; - $this->checked = $attributes['checked'] ?? ''; - $this->options = apply_filters( 'srfm_field_options', $attributes['options'] ?? '', $attributes ); + $this->field_config = $field_config ? htmlspecialchars( Helper::get_string_value( wp_json_encode( $field_config, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) ), ENT_QUOTES, 'UTF-8' ) : ''; + $this->attributes = $attributes; + $this->required = $attributes['required'] ?? false; + $this->field_width = $attributes['fieldWidth'] ?? ''; + $this->label = $attributes['label'] ?? ''; + $this->help = $attributes['help'] ?? ''; + $this->block_id = isset( $attributes['block_id'] ) ? Helper::get_string_value( $attributes['block_id'] ) : ''; + $this->form_id = isset( $attributes['formId'] ) ? Helper::get_string_value( $attributes['formId'] ) : ''; + $this->block_slug = $attributes['slug'] ?? ''; + $this->class_name = $filter_classes; + $this->placeholder = $attributes['placeholder'] ?? ''; + $this->default = $attributes['defaultValue'] ?? ''; + $this->checked = $attributes['checked'] ?? ''; + // Inject the block type slug (e.g. 'dropdown', 'multi-choice') into the attributes passed to + // the filter. The field's `slug` attribute can be prefixed when the block is inside a repeater + // (e.g. 'srfm-repeater-srfm-dropdown'), so filter consumers need a reliable block type identifier. + $block_args = [ 'block_args' => [ 'slug' => $this->slug ] ]; + $this->options = apply_filters( 'srfm_field_options', $attributes['options'] ?? '', array_merge( $attributes, $block_args ) ); $this->is_unique = $attributes['isUnique'] ?? false; $this->conditional_class = apply_filters( 'srfm_conditional_logic_classes', $this->form_id, $this->block_id ); $this->data_require_attr = $this->required ? 'true' : 'false'; From 3da0ae8f05821b723c3ef42508b24f0d2e1caa3a Mon Sep 17 00:00:00 2001 From: Vansh Kapoor Date: Mon, 20 Apr 2026 16:48:38 +0530 Subject: [PATCH 08/24] chore: update astra-notices to 1.2.1 and bsf-analytics to 1.1.26 Coordinated bump of both vendored libraries: - astra-notices 1.1.14 -> 1.2.1 (brainstormforce/astra-notices#87): - main file renamed class-astra-notices.php -> class-bsf-admin-notices.php - class renamed Astra_Notices -> BSF_Admin_Notices with class_alias BC - dual-emits legacy astra_notice_* hooks alongside new bsf_admin_notice_* - bsf-analytics 1.1.25 -> 1.1.26 (brainstormforce/bsf-analytics#95): - switches internal call sites to BSF_Admin_Notices and bsf_admin_notice_* - class_exists guard keeps older consumers fatal-free Consumer edits are limited to the two class-load guards forced by the upstream file rename (admin/admin.php, admin/analytics.php). Existing Astra_Notices:: usages and astra_notice_after_markup_* hook listeners continue to work via the alias + dual-emit contract. --- admin/admin.php | 4 +- admin/analytics.php | 4 +- composer.lock | 24 ++-- ...otices.php => class-bsf-admin-notices.php} | 136 +++++++++++------- inc/lib/astra-notices/notices.css | 2 +- inc/lib/astra-notices/notices.js | 2 +- inc/lib/bsf-analytics/changelog.txt | 3 + inc/lib/bsf-analytics/class-bsf-analytics.php | 7 +- inc/lib/bsf-analytics/version.json | 2 +- 9 files changed, 109 insertions(+), 75 deletions(-) rename inc/lib/astra-notices/{class-astra-notices.php => class-bsf-admin-notices.php} (75%) diff --git a/admin/admin.php b/admin/admin.php index ed3090236..40d94391a 100644 --- a/admin/admin.php +++ b/admin/admin.php @@ -20,8 +20,8 @@ exit; // Exit if accessed directly. } -if ( ! class_exists( 'Astra_Notices' ) ) { - require_once SRFM_DIR . 'inc/lib/astra-notices/class-astra-notices.php'; +if ( ! class_exists( 'BSF_Admin_Notices' ) ) { + require_once SRFM_DIR . 'inc/lib/astra-notices/class-bsf-admin-notices.php'; } /** * Admin handler class. diff --git a/admin/analytics.php b/admin/analytics.php index 4481b73dc..20c78ab4b 100644 --- a/admin/analytics.php +++ b/admin/analytics.php @@ -44,8 +44,8 @@ public function __construct() { require_once SRFM_DIR . 'inc/lib/bsf-analytics/class-bsf-analytics-loader.php'; } - if ( ! class_exists( 'Astra_Notices' ) ) { - require_once SRFM_DIR . 'inc/lib/astra-notices/class-astra-notices.php'; + if ( ! class_exists( 'BSF_Admin_Notices' ) ) { + require_once SRFM_DIR . 'inc/lib/astra-notices/class-bsf-admin-notices.php'; } add_filter( diff --git a/composer.lock b/composer.lock index 269982543..f852bdf35 100644 --- a/composer.lock +++ b/composer.lock @@ -8,16 +8,16 @@ "packages": [ { "name": "brainstormforce/astra-notices", - "version": "1.1.14", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/brainstormforce/astra-notices.git", - "reference": "0b28968693e979a3a7920bc527d1d56e9b7953f5" + "reference": "79430df6cc3bf97efeb287989c1c4a848dbd8039" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brainstormforce/astra-notices/zipball/0b28968693e979a3a7920bc527d1d56e9b7953f5", - "reference": "0b28968693e979a3a7920bc527d1d56e9b7953f5", + "url": "https://api.github.com/repos/brainstormforce/astra-notices/zipball/79430df6cc3bf97efeb287989c1c4a848dbd8039", + "reference": "79430df6cc3bf97efeb287989c1c4a848dbd8039", "shasum": "" }, "require": { @@ -56,23 +56,23 @@ ], "description": "Easily create admin notices", "support": { - "source": "https://github.com/brainstormforce/astra-notices/tree/1.1.14", + "source": "https://github.com/brainstormforce/astra-notices/tree/1.2.1", "issues": "https://github.com/brainstormforce/astra-notices/issues" }, - "time": "2025-03-17T06:09:37+00:00" + "time": "2026-04-20T10:30:34+00:00" }, { "name": "brainstormforce/bsf-analytics", - "version": "1.1.25", + "version": "1.1.26", "source": { "type": "git", "url": "git@github.com:brainstormforce/bsf-analytics.git", - "reference": "20e4c1b4766cf959075cee55cc65e3eda269aadb" + "reference": "e9079f78d4cf7a3e85ea61e94f842e2f8e00ee68" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brainstormforce/bsf-analytics/zipball/20e4c1b4766cf959075cee55cc65e3eda269aadb", - "reference": "20e4c1b4766cf959075cee55cc65e3eda269aadb", + "url": "https://api.github.com/repos/brainstormforce/bsf-analytics/zipball/e9079f78d4cf7a3e85ea61e94f842e2f8e00ee68", + "reference": "e9079f78d4cf7a3e85ea61e94f842e2f8e00ee68", "shasum": "" }, "require-dev": { @@ -111,10 +111,10 @@ }, "description": "Library to gather non sensitive analytics data to enhance bsf products.", "support": { - "source": "https://github.com/brainstormforce/bsf-analytics/tree/1.1.25", + "source": "https://github.com/brainstormforce/bsf-analytics/tree/1.1.26", "issues": "https://github.com/brainstormforce/bsf-analytics/issues" }, - "time": "2026-04-13T08:45:00+00:00" + "time": "2026-04-20T10:30:24+00:00" }, { "name": "composer/ca-bundle", diff --git a/inc/lib/astra-notices/class-astra-notices.php b/inc/lib/astra-notices/class-bsf-admin-notices.php similarity index 75% rename from inc/lib/astra-notices/class-astra-notices.php rename to inc/lib/astra-notices/class-bsf-admin-notices.php index 9f9940c54..080f0f952 100644 --- a/inc/lib/astra-notices/class-astra-notices.php +++ b/inc/lib/astra-notices/class-bsf-admin-notices.php @@ -1,57 +1,62 @@ get_notice_by_id( $notice_id ); $capability = isset( $notice['capability'] ) ? $notice['capability'] : 'manage_options'; - if ( ! apply_filters( 'astra_notices_user_cap_check', current_user_can( $capability ) ) ) { - return; + $has_cap = current_user_can( $capability ); + + /** + * Filters whether the current user passes the capability check for notice dismissal. + * + * Both the legacy and new filter names are fired for backward compatibility. + * Filters can only restrict access (return false), never grant it — if the + * underlying current_user_can() check fails, filters cannot override to true. + */ + $cap_check = apply_filters( 'astra_notices_user_cap_check', $has_cap ); + $cap_check = apply_filters( 'bsf_admin_notices_user_cap_check', $cap_check ); + + if ( ! $has_cap || ! $cap_check ) { + wp_send_json_error( esc_html__( 'Permission denied.', 'astra-notices' ) ); } $allowed_notices = get_option( 'allowed_astra_notices', array() ); // Get allowed notices. - // Define restricted user meta keys. + // Define restricted user meta keys using the dynamic table prefix. + global $wpdb; $wp_default_meta_keys = array( - 'wp_capabilities', - 'wp_user_level', - 'wp_user-settings', + $wpdb->prefix . 'capabilities', + $wpdb->prefix . 'user_level', + $wpdb->prefix . 'user-settings', 'account_status', 'session_tokens', ); // if $notice_id does not start with astra-notices-id and notice_id is not from the allowed notices, then return. - if ( strpos( $notice_id, 'astra-notices-id-' ) !== 0 && ( ! in_array( $notice_id, $allowed_notices, true ) ) ) { - return; - } - - if ( false === wp_verify_nonce( $nonce, 'astra-notices' ) ) { - wp_send_json_error( esc_html_e( 'WordPress Nonce not validated.' ) ); + if ( 0 !== strpos( $notice_id, 'astra-notices-id-' ) && ( ! in_array( $notice_id, $allowed_notices, true ) ) ) { + wp_send_json_error( esc_html__( 'Invalid notice ID.', 'astra-notices' ) ); } // Valid inputs? if ( ! empty( $notice_id ) ) { if ( in_array( $notice_id, $wp_default_meta_keys, true ) ) { - wp_send_json_error( esc_html_e( 'Invalid notice ID.' ) ); + wp_send_json_error( esc_html__( 'Invalid notice ID.', 'astra-notices' ) ); } if ( ! empty( $repeat_notice_after ) ) { @@ -168,7 +183,7 @@ public function dismiss_notice() { /** * Enqueue Scripts. * - * @since 1.0.0 + * @since 1.2.0 * @return void */ public function enqueue_scripts() { @@ -187,7 +202,7 @@ public function enqueue_scripts() { * Sort the notices based on the given priority of the notice. * This function is called from usort() * - * @since 1.5.2 + * @since 1.2.0 * @param array $notice_1 First notice. * @param array $notice_2 Second Notice. * @return array @@ -205,7 +220,6 @@ public function sort_notices( $notice_1, $notice_2 ) { /** * Get all registered notices. - * Since v1.1.8 it is recommended to register the notices on * * @return array|null */ @@ -216,7 +230,7 @@ private function get_notices() { } /** - * Get notice by notice_id + * Get notice by notice_id. * * @param string $notice_id Notice id. * @@ -241,7 +255,7 @@ private function get_notice_by_id( $notice_id ) { /** * Display the notices in the WordPress admin. * - * @since 1.0.0 + * @since 1.2.0 * @return void */ public function show_notices() { @@ -254,7 +268,7 @@ public function show_notices() { 'display-notice-after' => false, // Optional, Dismiss-able notice time. It'll auto show after given time. 'class' => '', // Optional, Additional notice wrapper class. 'priority' => 10, // Priority of the notice. - 'display-with-other-notices' => true, // Should the notice be displayed if other notices are being displayed from Astra_Notices. + 'display-with-other-notices' => true, // Should the notice be displayed if other notices are being displayed from BSF_Admin_Notices. 'is_dismissible' => true, 'capability' => 'manage_options', // User capability - This capability is required for the current user to see this notice. ); @@ -294,7 +308,7 @@ public function show_notices() { /** * Render a notice. * - * @since 1.0.0 + * @since 1.2.0 * @param array $notice Notice markup. * @return void */ @@ -302,28 +316,35 @@ public static function markup( $notice = array() ) { wp_enqueue_script( 'astra-notices' ); wp_enqueue_style( 'astra-notices' ); + // Dual-emit: legacy (astra_notice_*) + new (bsf_admin_notice_*) hooks for backward compat. + // Note: consumers hooking BOTH names for the same event will be called twice. do_action( 'astra_notice_before_markup' ); + do_action( 'bsf_admin_notice_before_markup' ); do_action( "astra_notice_before_markup_{$notice['id']}" ); + do_action( "bsf_admin_notice_before_markup_{$notice['id']}" ); ?> -
+
+
entities as $key => $data ) { - add_action( 'astra_notice_before_markup_' . $key . '-optin-notice', array( $this, 'enqueue_assets' ) ); + add_action( 'bsf_admin_notice_before_markup_' . $key . '-optin-notice', array( $this, 'enqueue_assets' ) ); add_action( 'update_option_' . $key . '_usage_optin', array( $this, 'update_analytics_option_callback' ), 10, 3 ); add_action( 'add_option_' . $key . '_usage_optin', array( $this, 'add_analytics_option_callback' ), 10, 2 ); } @@ -235,6 +235,9 @@ public function get_usage_doc_link( $product_key, $context = 'notice' ) { * @since 1.0.0 */ public function option_notice() { + if ( ! class_exists( 'BSF_Admin_Notices' ) ) { + return; + } if ( ! current_user_can( 'manage_options' ) ) { return; @@ -279,7 +282,7 @@ public function option_notice() { $language_dir = is_rtl() ? 'rtl' : 'ltr'; - Astra_Notices::add_notice( + BSF_Admin_Notices::add_notice( array( 'id' => $key . '-optin-notice', 'type' => '', diff --git a/inc/lib/bsf-analytics/version.json b/inc/lib/bsf-analytics/version.json index 401a49d0d..6f450d022 100644 --- a/inc/lib/bsf-analytics/version.json +++ b/inc/lib/bsf-analytics/version.json @@ -1,3 +1,3 @@ { - "bsf-analytics-ver": "1.1.25" + "bsf-analytics-ver": "1.1.26" } From 2ec8081df50141585233d27d01f1eb20e9b8cfea Mon Sep 17 00:00:00 2001 From: Avinash Kumar Sharma Date: Tue, 21 Apr 2026 21:17:54 +0530 Subject: [PATCH 09/24] Feature: add {entry_id} smart tag for emails, confirmations, PDFs, and integrations - Register {entry_id} in Smart_Tags::smart_tag_list() so it appears in the editor tag picker - Handle {entry_id} in smart_tags_callback() reading from $form_data or $submission_data - Move send_email() to after Entries::add() so entry ID is available at send time - Inject $form_data['entry_id'] before confirmation, redirect, and email processing Co-Authored-By: Claude Sonnet 4.6 --- inc/form-submit.php | 24 +++++++++++++++++------- inc/smart-tags.php | 14 +++++++++++++- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/inc/form-submit.php b/inc/form-submit.php index 782e5c42f..425b11a43 100644 --- a/inc/form-submit.php +++ b/inc/form-submit.php @@ -525,17 +525,18 @@ public function handle_form_entry( $form_data ) { */ do_action( 'srfm_before_submission', $form_before_submission_data ); - $name = sanitize_text_field( get_the_title( intval( $id ) ) ); - $send_email = $this->send_email( $id, $submission_data, $form_data ); - $emails = []; - - if ( $send_email ) { - $emails = $send_email['emails']; - } + $name = sanitize_text_field( get_the_title( intval( $id ) ) ); // Check if GDPR is enabled and do not store entries is enabled. // If so, send email and do not store entries. if ( $gdpr && $do_not_store_entries ) { + // No entry is stored in this path, so {entry_id} resolves to ''. + $send_email = $this->send_email( $id, $submission_data, $form_data ); + $emails = []; + + if ( $send_email ) { + $emails = $send_email['emails']; + } $form_submit_response = [ 'success' => true, @@ -614,6 +615,15 @@ public function handle_form_entry( $form_data ) { $entry_id = Entries::add( $entries_data ); if ( $entry_id ) { + // Inject entry_id so {entry_id} smart tag resolves in emails, confirmations, redirects, and integrations. + $form_data['entry_id'] = intval( $entry_id ); + + $send_email = $this->send_email( $id, $submission_data, $form_data ); + $emails = []; + + if ( $send_email ) { + $emails = $send_email['emails']; + } $confirmation_message = Generate_Form_Markup::get_confirmation_markup( $form_data, $submission_data ); diff --git a/inc/smart-tags.php b/inc/smart-tags.php index 58cb99883..22fdce1cd 100644 --- a/inc/smart-tags.php +++ b/inc/smart-tags.php @@ -125,6 +125,7 @@ public static function smart_tag_list() { '{browser_platform}' => __( 'Browser Platform', 'sureforms' ), '{embed_post_id}' => __( 'Embedded Post/Page ID', 'sureforms' ), '{embed_post_title}' => __( 'Embedded Post/Page Title', 'sureforms' ), + '{entry_id}' => __( 'Entry ID', 'sureforms' ), '{get_input:param}' => __( 'Populate by GET Param', 'sureforms' ), '{get_cookie:cookie_name}' => __( 'Cookie Value', 'sureforms' ), ] @@ -326,7 +327,18 @@ public static function smart_tags_callback( $tag, $submission_data = null, $form case '{embed_post_title}': case '{embed_post_url}': return self::parse_post_props( $tag ); - case '{current_page_url}': + case '{entry_id}': + // Check $form_data first (normal submission path). + if ( ! empty( $form_data ) && is_array( $form_data ) && ! empty( $form_data['entry_id'] ) ) { + return absint( $form_data['entry_id'] ); + } + // Webhooks pass form_data as $submission_data; check there too. + if ( ! empty( $submission_data ) && is_array( $submission_data ) && ! empty( $submission_data['entry_id'] ) ) { + return absint( $submission_data['entry_id'] ); + } + return ''; + + case '{current_page_url}': if ( isset( $form_data['_wp_http_referer'] ) ) { $request_uri = sanitize_text_field( Helper::get_string_value( wp_unslash( $form_data['_wp_http_referer'] ) ) ); return esc_url( site_url( $request_uri ) ); From 62782aa33708bce6a74c5f081bc5382a3275380d Mon Sep 17 00:00:00 2001 From: Avinash Kumar Sharma Date: Wed, 22 Apr 2026 11:38:32 +0530 Subject: [PATCH 10/24] Chore: clarify {entry_id} is post-submission only in tag picker label MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tag resolves after Entries::add() — it has no value at form render time, so it cannot be used in Default Value fields or other pre-submission contexts. Surface this in the editor smart tag picker to prevent confusion. Co-Authored-By: Claude Sonnet 4.6 --- inc/smart-tags.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/smart-tags.php b/inc/smart-tags.php index 22fdce1cd..d0116f3ae 100644 --- a/inc/smart-tags.php +++ b/inc/smart-tags.php @@ -125,7 +125,7 @@ public static function smart_tag_list() { '{browser_platform}' => __( 'Browser Platform', 'sureforms' ), '{embed_post_id}' => __( 'Embedded Post/Page ID', 'sureforms' ), '{embed_post_title}' => __( 'Embedded Post/Page Title', 'sureforms' ), - '{entry_id}' => __( 'Entry ID', 'sureforms' ), + '{entry_id}' => __( 'Entry ID (post-submission only)', 'sureforms' ), '{get_input:param}' => __( 'Populate by GET Param', 'sureforms' ), '{get_cookie:cookie_name}' => __( 'Cookie Value', 'sureforms' ), ] From 97b97da985beeb2e5842efa49964cebfa3a36fa0 Mon Sep 17 00:00:00 2001 From: Avinash Kumar Sharma Date: Wed, 22 Apr 2026 12:21:57 +0530 Subject: [PATCH 11/24] Chore: remove {entry_id} from editor dropdown, keep processing valid Removing from smart_tag_list() hides it from all block editor tag pickers (including Default Value fields) since it cannot resolve before submission. Adding it as a hardcoded exception in the is_valid_tag check ensures it is still processed correctly in email templates, confirmation messages, redirect URLs, and other post-submission contexts where it has a value. Co-Authored-By: Claude Sonnet 4.6 --- inc/smart-tags.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/smart-tags.php b/inc/smart-tags.php index d0116f3ae..1c32d20cc 100644 --- a/inc/smart-tags.php +++ b/inc/smart-tags.php @@ -125,7 +125,6 @@ public static function smart_tag_list() { '{browser_platform}' => __( 'Browser Platform', 'sureforms' ), '{embed_post_id}' => __( 'Embedded Post/Page ID', 'sureforms' ), '{embed_post_title}' => __( 'Embedded Post/Page Title', 'sureforms' ), - '{entry_id}' => __( 'Entry ID (post-submission only)', 'sureforms' ), '{get_input:param}' => __( 'Populate by GET Param', 'sureforms' ), '{get_cookie:cookie_name}' => __( 'Cookie Value', 'sureforms' ), ] @@ -174,7 +173,8 @@ public function process_smart_tags( $content, $submission_data = null, $form_dat strpos( $tag, 'get_input:' ) || strpos( $tag, 'get_cookie:' ) || 0 === strpos( $tag, '{form:' ) || - 0 === strpos( $tag, '{form-payment:' ); + 0 === strpos( $tag, '{form-payment:' ) || + '{entry_id}' === $tag; // Post-submission only — excluded from editor dropdowns intentionally. /** * Filter whether a smart tag should be treated as valid for processing. From bad8f74f13cce02b18e64406bd56f528131c4af6 Mon Sep 17 00:00:00 2001 From: Avinash Kumar Sharma Date: Wed, 22 Apr 2026 13:39:28 +0530 Subject: [PATCH 12/24] Revert: restore {entry_id} in smart_tag_list and remove is_valid_tag exception MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Filtering {entry_id} from only the Default Value picker (not email/confirmation) requires JS changes — both pickers share the same smart_tags_array source. Reverting to a clean state: {entry_id} appears in all editor dropdowns and is processed correctly in all post-submission contexts. Co-Authored-By: Claude Sonnet 4.6 --- inc/smart-tags.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/smart-tags.php b/inc/smart-tags.php index 1c32d20cc..22fdce1cd 100644 --- a/inc/smart-tags.php +++ b/inc/smart-tags.php @@ -125,6 +125,7 @@ public static function smart_tag_list() { '{browser_platform}' => __( 'Browser Platform', 'sureforms' ), '{embed_post_id}' => __( 'Embedded Post/Page ID', 'sureforms' ), '{embed_post_title}' => __( 'Embedded Post/Page Title', 'sureforms' ), + '{entry_id}' => __( 'Entry ID', 'sureforms' ), '{get_input:param}' => __( 'Populate by GET Param', 'sureforms' ), '{get_cookie:cookie_name}' => __( 'Cookie Value', 'sureforms' ), ] @@ -173,8 +174,7 @@ public function process_smart_tags( $content, $submission_data = null, $form_dat strpos( $tag, 'get_input:' ) || strpos( $tag, 'get_cookie:' ) || 0 === strpos( $tag, '{form:' ) || - 0 === strpos( $tag, '{form-payment:' ) || - '{entry_id}' === $tag; // Post-submission only — excluded from editor dropdowns intentionally. + 0 === strpos( $tag, '{form-payment:' ); /** * Filter whether a smart tag should be treated as valid for processing. From 6300e347f6dec86a5b43eedbd7ef222527842a76 Mon Sep 17 00:00:00 2001 From: Om Kolte Date: Wed, 22 Apr 2026 17:39:02 +0530 Subject: [PATCH 13/24] Fix: correct case indentation in smart_tags_callback() The '{current_page_url}' case statement was indented with 2 tabs instead of 3, causing PHPCS (Generic.WhiteSpace.ScopeIndent.IncorrectExact) and PHP Insights (PSR2.ControlStructures.SwitchDeclaration.BreakIndent) to fail in the Code Analysis check. --- inc/smart-tags.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/smart-tags.php b/inc/smart-tags.php index 22fdce1cd..222233727 100644 --- a/inc/smart-tags.php +++ b/inc/smart-tags.php @@ -338,7 +338,7 @@ public static function smart_tags_callback( $tag, $submission_data = null, $form } return ''; - case '{current_page_url}': + case '{current_page_url}': if ( isset( $form_data['_wp_http_referer'] ) ) { $request_uri = sanitize_text_field( Helper::get_string_value( wp_unslash( $form_data['_wp_http_referer'] ) ) ); return esc_url( site_url( $request_uri ) ); From 6ac997345fb3c011cb005771a34becfc8ce87fea Mon Sep 17 00:00:00 2001 From: Om Kolte Date: Wed, 22 Apr 2026 18:47:58 +0530 Subject: [PATCH 14/24] Fix: restore send_email() position to avoid regression when Entries::add() fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Revert the send_email() relocation. Keeping the pre-existing call before the GDPR branch preserves the existing behavior where admin notifications fire even if Entries::add() returns falsy. {entry_id} continues to resolve in the confirmation message, redirect URL, and downstream integrations (PDF, webhook) via the $form_data['entry_id'] injection after Entries::add(). In email bodies it now resolves to '' — consistent with the GDPR do-not-store path and safer than the prior behavior change. --- inc/form-submit.php | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/inc/form-submit.php b/inc/form-submit.php index 425b11a43..d7b506ee4 100644 --- a/inc/form-submit.php +++ b/inc/form-submit.php @@ -525,18 +525,17 @@ public function handle_form_entry( $form_data ) { */ do_action( 'srfm_before_submission', $form_before_submission_data ); - $name = sanitize_text_field( get_the_title( intval( $id ) ) ); + $name = sanitize_text_field( get_the_title( intval( $id ) ) ); + $send_email = $this->send_email( $id, $submission_data, $form_data ); + $emails = []; + + if ( $send_email ) { + $emails = $send_email['emails']; + } // Check if GDPR is enabled and do not store entries is enabled. // If so, send email and do not store entries. if ( $gdpr && $do_not_store_entries ) { - // No entry is stored in this path, so {entry_id} resolves to ''. - $send_email = $this->send_email( $id, $submission_data, $form_data ); - $emails = []; - - if ( $send_email ) { - $emails = $send_email['emails']; - } $form_submit_response = [ 'success' => true, @@ -615,16 +614,9 @@ public function handle_form_entry( $form_data ) { $entry_id = Entries::add( $entries_data ); if ( $entry_id ) { - // Inject entry_id so {entry_id} smart tag resolves in emails, confirmations, redirects, and integrations. + // Inject entry_id so {entry_id} smart tag resolves in confirmation message, redirect URL, and downstream integrations. $form_data['entry_id'] = intval( $entry_id ); - $send_email = $this->send_email( $id, $submission_data, $form_data ); - $emails = []; - - if ( $send_email ) { - $emails = $send_email['emails']; - } - $confirmation_message = Generate_Form_Markup::get_confirmation_markup( $form_data, $submission_data ); $response = [ From 1bd588d8feb8aa890e04df3c0b2c87c3d9e1c148 Mon Sep 17 00:00:00 2001 From: Rahul Verma Date: Thu, 23 Apr 2026 20:28:13 +0530 Subject: [PATCH 15/24] Added minor pr comment --- src/admin/single-form-settings/tabs/StyleSettings.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/admin/single-form-settings/tabs/StyleSettings.js b/src/admin/single-form-settings/tabs/StyleSettings.js index 96356e07a..9af385fee 100644 --- a/src/admin/single-form-settings/tabs/StyleSettings.js +++ b/src/admin/single-form-settings/tabs/StyleSettings.js @@ -125,9 +125,9 @@ function StyleSettings( props ) { useEffect( () => { setTimeout( () => { setSubmitBtnCtn( - rootRef.querySelector( '.srfm-submit-btn-container' ) + rootRef?.querySelector( '.srfm-submit-btn-container' ) ); - setSubmitBtn( rootRef.querySelector( '.srfm-submit-richtext' ) ); + setSubmitBtn( rootRef?.querySelector( '.srfm-submit-richtext' ) ); submitButtonInherit(); }, 1000 ); }, [ From 9ee275bc998e4d7dbe63116e780833f4185a359d Mon Sep 17 00:00:00 2001 From: Vansh Kapoor Date: Fri, 24 Apr 2026 14:59:57 +0530 Subject: [PATCH 16/24] fix: localize MCP endpoint REST URL via rest_url() The MCP settings page built the endpoint URL by concatenating `srfm_admin.site_url` with `/wp-json/sureforms/v1/mcp`. That string is incorrect on sites using Plain permalinks (which need `?rest_route=/sureforms/v1/mcp`), sites with a custom REST prefix via the `rest_url_prefix` filter, or other non-standard REST routing. - admin/admin.php: add `mcp_endpoint_url` to the srfm_admin localization, computed with `esc_url_raw( rest_url( 'sureforms/v1/mcp' ) )`. - src/admin/settings/pages/MCP.js: consume `srfm_admin.mcp_endpoint_url` instead of hand-building the path. --- admin/admin.php | 1 + src/admin/settings/pages/MCP.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/admin/admin.php b/admin/admin.php index 40d94391a..bc68cef59 100644 --- a/admin/admin.php +++ b/admin/admin.php @@ -943,6 +943,7 @@ public function enqueue_scripts() { 'mcp_adapter_status' => file_exists( WP_PLUGIN_DIR . '/mcp-adapter/mcp-adapter.php' ) ? ( is_plugin_active( 'mcp-adapter/mcp-adapter.php' ) ? 'active' : 'installed' ) : 'not_installed', + 'mcp_endpoint_url' => esc_url_raw( rest_url( 'sureforms/v1/mcp' ) ), ]; $is_screen_sureforms_menu = Helper::validate_request_context( 'sureforms_menu', 'page' ); diff --git a/src/admin/settings/pages/MCP.js b/src/admin/settings/pages/MCP.js index d6fad8e78..e89c41cc8 100644 --- a/src/admin/settings/pages/MCP.js +++ b/src/admin/settings/pages/MCP.js @@ -347,7 +347,7 @@ const McpAdapterPrompt = ( { adapterStatus: initialStatus } ) => { }; const MCPPage = ( { loading, mcpTabOptions, updateGlobalSettings } ) => { - const mcpEndpointUrl = `${ srfm_admin.site_url }/wp-json/sureforms/v1/mcp`; + const mcpEndpointUrl = srfm_admin.mcp_endpoint_url; const adapterStatus = srfm_admin?.mcp_adapter_status || 'not_installed'; const isAdapterActive = 'active' === adapterStatus; From 81f08c54eeedfefd7f97773e47d835565017f9aa Mon Sep 17 00:00:00 2001 From: Vansh Kapoor Date: Fri, 24 Apr 2026 16:12:03 +0530 Subject: [PATCH 17/24] Version Bump 2.8.1 --- README.md | 21 +- inc/fields/dropdown-markup.php | 2 +- inc/fields/multichoice-markup.php | 2 +- languages/sureforms.pot | 361 +++++++++++++++--------------- package-lock.json | 4 +- package.json | 2 +- readme.txt | 21 +- sureforms.php | 6 +- 8 files changed, 213 insertions(+), 206 deletions(-) diff --git a/README.md b/README.md index 4db15793c..8e857afd5 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ **Requires at least:** 6.4 **Tested up to:** 6.9.4 **Requires PHP:** 7.4 -**Stable tag:** 2.8.0 +**Stable tag:** 2.8.1 **License:** GPLv2 or later **License URI:** http://www.gnu.org/licenses/gpl-2.0.html @@ -478,6 +478,15 @@ You can collect payments securely through Stripe in the free version. PayPal pay You can report the issue through our [Bug Bounty Program](https://brainstormforce.com/bug-bounty-program/). We collaborate with Patchstack to provide opportunities for researchers to report vulnerabilities. The Patchstack team will help validate, triage, and handle any reported security issues. ## Changelog ## +### 2.8.1 - 24th April 2026 ### +* New: Added dynamic default value support for Dropdown and Multi Choice fields. +* New: Added PLN (Polish Zloty) currency support to payment fields. +* New: Added {entry_id} smart tag for use in emails, confirmations, PDFs, and integrations. +* Improvement: Updated Astra Notices to 1.2.1 and BSF Analytics to 1.1.26. +* Fix: Background color not applied in non-iframe editor mode. +* Fix: Dynamic options repeater generated incorrect field slugs. +* Fix: MCP endpoint REST URL ignored sites with a custom REST path prefix. +* Fix: Phone field country flag changed unexpectedly on browser autofill or input. ### 2.8.0 - 16th April 2026 ### * New: Added My Account page allowing users to view and manage their payment history and subscriptions. * Improvement: Phone number country detection moved to backend with caching, reducing multiple API calls. @@ -494,16 +503,6 @@ You can report the issue through our [Bug Bounty Program](https://brainstormforc * Fix: Fixed slugs with underscores not mapping correctly during smart tag and integration processing. * Fix: Fixed textarea values losing line breaks in {form:field} smart tags. * Fix: Fixed {current_page_url} smart tag resolving to REST API URL in email notifications. -### 2.7.0 - 31st March 2026 ### -* New: Added styling options for Gutenberg SureForms Form Block. -* New: Added styling options for Bricks Builder SureForms Form Element. -* New: Added styling options for Elementor SureForms Form Widget. -* Fix: Fixed "Send as Raw HTML" email option wrapping content in unwanted template markup. -* Fix: Fixed Multi Choice option labels with extra whitespace failing to resolve numeric values in payment calculations. -* Fix: Fixed block slug not locking when a smart tag is inserted via the pro plugin. -* Fix: Fixed dynamic tag URLs being auto-linked with HTML markup when used in redirect query parameters. -* Fix: Fixed theme text-transform styles cascading into form input fields. -* Fix: Fixed unique field validation endpoint exposing submitted data to unauthenticated enumeration attacks. The full changelog is available [here](https://sureforms.com/whats-new/). ## Upgrade Notice ## diff --git a/inc/fields/dropdown-markup.php b/inc/fields/dropdown-markup.php index dc6b55ecc..c5223b6e5 100644 --- a/inc/fields/dropdown-markup.php +++ b/inc/fields/dropdown-markup.php @@ -192,7 +192,7 @@ function( $i ) { * Resolve dynamic default value from smart tags and override preselected options. * * @param array $attributes Block attributes. - * @since x.x.x + * @since 2.8.1 * @return void */ protected function resolve_dynamic_default( $attributes ) { diff --git a/inc/fields/multichoice-markup.php b/inc/fields/multichoice-markup.php index 0f237f073..95f19f80c 100644 --- a/inc/fields/multichoice-markup.php +++ b/inc/fields/multichoice-markup.php @@ -207,7 +207,7 @@ class="srfm-input-slug ); ?>-single" $attributes Block attributes. - * @since x.x.x + * @since 2.8.1 * @return void */ protected function resolve_dynamic_default( $attributes ) { diff --git a/languages/sureforms.pot b/languages/sureforms.pot index 0021d0d0d..30939bd29 100644 --- a/languages/sureforms.pot +++ b/languages/sureforms.pot @@ -2,14 +2,14 @@ # This file is distributed under the GPLv2 or later. msgid "" msgstr "" -"Project-Id-Version: SureForms 2.8.0\n" +"Project-Id-Version: SureForms 2.8.1\n" "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/sureforms\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"POT-Creation-Date: 2026-04-15T10:24:05+00:00\n" +"POT-Creation-Date: 2026-04-24T10:40:54+00:00\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "X-Generator: WP-CLI 2.12.0\n" "X-Domain: sureforms\n" @@ -19,7 +19,7 @@ msgstr "" #: sureforms.php #: admin/admin.php:320 #: admin/admin.php:321 -#: admin/admin.php:1812 +#: admin/admin.php:1813 #: inc/abilities/abilities-registrar.php:133 #: inc/gutenberg-hooks.php:109 #: inc/page-builders/bricks/elements/form-widget.php:67 @@ -83,7 +83,7 @@ msgstr "" #: admin/admin.php:409 #: admin/admin.php:410 -#: admin/admin.php:2021 +#: admin/admin.php:2022 #: assets/build/blocks.js:172 #: assets/build/dashboard.js:172 #: assets/build/entries.js:172 @@ -96,7 +96,7 @@ msgid "Quiz Entries" msgstr "" #: admin/admin.php:426 -#: admin/admin.php:974 +#: admin/admin.php:975 #: assets/build/formEditor.js:172 msgid "Quizzes" msgstr "" @@ -108,7 +108,7 @@ msgstr "" #: admin/admin.php:458 #: admin/admin.php:459 -#: admin/admin.php:979 +#: admin/admin.php:980 msgid "Survey Reports" msgstr "" @@ -154,7 +154,7 @@ msgstr "" #: admin/admin.php:601 #: admin/admin.php:602 -#: admin/admin.php:1849 +#: admin/admin.php:1850 #: inc/global-settings/email-summary.php:225 #: assets/build/dashboard.js:172 #: assets/build/entries.js:172 @@ -223,68 +223,68 @@ msgid "Installed" msgstr "" #. translators: %1$s: SureForms version, %2$s: SureForms Pro Plugin Name, %3$s: SureForms Pro Version. -#: admin/admin.php:1376 +#: admin/admin.php:1377 #, php-format msgid "SureForms %1$s requires minimum %2$s %3$s to work properly. Please update to the latest version." msgstr "" -#: admin/admin.php:1389 +#: admin/admin.php:1390 msgid "Update Now" msgstr "" #. translators: %1$s: Opening anchor tag with URL, %2$s: Closing anchor tag, %3$s: SureForms Pro Plugin Name. -#: admin/admin.php:1441 +#: admin/admin.php:1442 #, php-format msgid "Please %1$sactivate%2$s your copy of %3$s to get new features, access support, receive update notifications, and more." msgstr "" #. translators: %1$s: SureForms version, %2$s: SureForms Pro Plugin Name, %3$s: SureForms Pro Version, %4$s: Anchor tag open, %5$s: Closing anchor tag. -#: admin/admin.php:1459 +#: admin/admin.php:1460 #, php-format msgid "SureForms %1$s requires minimum %2$s %3$s to work properly. Please update to the latest version from %4$shere%5$s." msgstr "" -#: admin/admin.php:1502 +#: admin/admin.php:1503 msgid "Amazing! SureForms is powering your forms and submissions - let's keep growing together!" msgstr "" -#: admin/admin.php:1503 +#: admin/admin.php:1504 msgid "If SureForms has been helpful, would you mind taking a moment to leave a 5-star review on WordPress.org?" msgstr "" -#: admin/admin.php:1505 +#: admin/admin.php:1506 msgid "Rate SureForms" msgstr "" -#: admin/admin.php:1506 -#: admin/admin.php:1550 +#: admin/admin.php:1507 +#: admin/admin.php:1551 msgid "Maybe later" msgstr "" -#: admin/admin.php:1507 +#: admin/admin.php:1508 msgid "I already did" msgstr "" -#: admin/admin.php:1546 +#: admin/admin.php:1547 msgid "SureForms is ready to power your forms — explore what's possible!" msgstr "" -#: admin/admin.php:1547 +#: admin/admin.php:1548 msgid "Manage your forms, track submissions, and discover features like AI Form Builder, payment integrations, and more from the SureForms dashboard." msgstr "" -#: admin/admin.php:1549 +#: admin/admin.php:1550 msgid "Go to Dashboard" msgstr "" -#: admin/admin.php:1551 +#: admin/admin.php:1552 msgid "I already know" msgstr "" -#: admin/admin.php:1607 -#: admin/admin.php:1706 -#: admin/admin.php:1744 -#: admin/admin.php:1765 +#: admin/admin.php:1608 +#: admin/admin.php:1707 +#: admin/admin.php:1745 +#: admin/admin.php:1766 #: inc/admin-ajax.php:162 #: inc/payments/admin/admin-handler.php:638 #: inc/payments/stripe/admin-stripe-handler.php:80 @@ -292,91 +292,91 @@ msgstr "" msgid "Invalid nonce." msgstr "" -#: admin/admin.php:1611 -#: admin/admin.php:1702 -#: admin/admin.php:1740 -#: admin/admin.php:1761 +#: admin/admin.php:1612 +#: admin/admin.php:1703 +#: admin/admin.php:1741 +#: admin/admin.php:1762 msgid "Unauthorized user." msgstr "" -#: admin/admin.php:1631 +#: admin/admin.php:1632 msgid "Invalid parameters." msgstr "" #. translators: 1: opening span, 2: opening strong (inline), 3: closing strong, 4: closing span, 5: opening strong (block), 6: closing strong -#: admin/admin.php:1711 +#: admin/admin.php:1712 #, php-format msgid "%1$sGet started by %2$sbuilding your first form%3$s.%4$s%5$sExperience the power of our intuitive AI Form Builder%6$s" msgstr "" -#: admin/admin.php:1722 +#: admin/admin.php:1723 msgid "SureForms is waiting for you!" msgstr "" -#: admin/admin.php:1724 +#: admin/admin.php:1725 msgid "Build My First Form" msgstr "" -#: admin/admin.php:1725 +#: admin/admin.php:1726 msgid "Dismiss" msgstr "" -#: admin/admin.php:1836 +#: admin/admin.php:1837 msgid "Recent Entries" msgstr "" -#: admin/admin.php:1837 +#: admin/admin.php:1838 msgid "( Last 7 days )" msgstr "" -#: admin/admin.php:1840 +#: admin/admin.php:1841 msgid "View" msgstr "" -#: admin/admin.php:1848 +#: admin/admin.php:1849 #: inc/global-settings/email-summary.php:224 #: assets/build/entries.js:172 #: assets/build/payments.js:172 msgid "Form Name" msgstr "" -#: admin/admin.php:1957 +#: admin/admin.php:1958 msgid "Use Conditional Logic to show only what matters" msgstr "" -#: admin/admin.php:1958 +#: admin/admin.php:1959 msgid "Split your form into steps to keep it easy" msgstr "" -#: admin/admin.php:1959 +#: admin/admin.php:1960 msgid "Let people upload files directly to your form" msgstr "" -#: admin/admin.php:1960 +#: admin/admin.php:1961 msgid "Turn responses into downloadable PDFs automatically" msgstr "" -#: admin/admin.php:1961 +#: admin/admin.php:1962 msgid "Let users sign with a simple signature field" msgstr "" -#: admin/admin.php:1962 +#: admin/admin.php:1963 msgid "Connect your form to other tools using webhooks" msgstr "" -#: admin/admin.php:1963 +#: admin/admin.php:1964 msgid "Use Conversational Forms for a chat-like experience" msgstr "" -#: admin/admin.php:1964 +#: admin/admin.php:1965 msgid "Let users register or log in through your form" msgstr "" -#: admin/admin.php:1965 +#: admin/admin.php:1966 msgid "Build forms that create WordPress user accounts" msgstr "" -#: admin/admin.php:1966 +#: admin/admin.php:1967 msgid "Add calculations to auto-total scores or prices" msgstr "" @@ -937,7 +937,7 @@ msgid "OttoKit is not configured properly." msgstr "" #: inc/admin-ajax.php:182 -#: inc/form-submit.php:970 +#: inc/form-submit.php:972 msgid "Invalid form ID." msgstr "" @@ -1237,6 +1237,7 @@ msgid "Unable to generate export file." msgstr "" #: inc/entries.php:729 +#: inc/smart-tags.php:128 #: assets/build/entries.js:172 msgid "Entry ID" msgstr "" @@ -1288,11 +1289,11 @@ msgstr "" msgid "Checkbox" msgstr "" -#: inc/fields/dropdown-markup.php:83 +#: inc/fields/dropdown-markup.php:84 msgid "Dropdown" msgstr "" -#: inc/fields/dropdown-markup.php:106 +#: inc/fields/dropdown-markup.php:108 #: inc/gutenberg-hooks.php:220 msgid "Select an option" msgstr "" @@ -1325,7 +1326,7 @@ msgstr "" msgid "Text field" msgstr "" -#: inc/fields/multichoice-markup.php:113 +#: inc/fields/multichoice-markup.php:114 msgid "Multi Choice" msgstr "" @@ -1334,7 +1335,7 @@ msgid "Number" msgstr "" #: inc/fields/payment-markup.php:249 -#: inc/payments/payment-helper.php:538 +#: inc/payments/payment-helper.php:543 msgid "Subscription Plan" msgstr "" @@ -1453,7 +1454,7 @@ msgstr "" #: inc/form-submit.php:99 #: inc/form-submit.php:400 #: inc/form-submit.php:445 -#: inc/form-submit.php:966 +#: inc/form-submit.php:968 #: inc/payments/front-end.php:77 #: inc/payments/front-end.php:258 #: inc/rest-api.php:98 @@ -1523,81 +1524,81 @@ msgstr "" msgid "Form data was not found." msgstr "" -#: inc/form-submit.php:649 +#: inc/form-submit.php:651 msgid "Unable to submit form. Please try again." msgstr "" -#: inc/form-submit.php:821 +#: inc/form-submit.php:823 msgid "Email notification passed to the sending server" msgstr "" #. translators: Here, %s is the comma separated emails list. -#: inc/form-submit.php:894 +#: inc/form-submit.php:896 #, php-format msgid "Email notification recipient: %s" msgstr "" -#: inc/form-submit.php:901 +#: inc/form-submit.php:903 msgid "No SMTP plugin detected. Please configure an SMTP plugin to enable email sending." msgstr "" -#: inc/form-submit.php:902 +#: inc/form-submit.php:904 msgid "Email sending failed for an unknown reason." msgstr "" #. translators: Here, %1$s is the comma separated emails list and %2$s is error report ( if any ). -#: inc/form-submit.php:911 +#: inc/form-submit.php:913 #, php-format msgid "Email server was unable to send the email notification. Recipient: %1$s. Reason: %2$s" msgstr "" -#: inc/form-submit.php:941 +#: inc/form-submit.php:943 msgid "No emails were sent." msgstr "" -#: inc/form-submit.php:975 +#: inc/form-submit.php:977 msgid "Invalid form." msgstr "" -#: inc/form-submit.php:980 +#: inc/form-submit.php:982 msgid "Too many requests. Please try again shortly." msgstr "" -#: inc/form-submit.php:1091 +#: inc/form-submit.php:1093 msgid "Captcha validation failed. No error code provided." msgstr "" -#: inc/form-submit.php:1092 +#: inc/form-submit.php:1094 msgid "Captcha validation failed." msgstr "" -#: inc/form-submit.php:1147 +#: inc/form-submit.php:1149 #: assets/build/formEditor.js:172 #: assets/build/settings.js:172 msgid "Google reCAPTCHA" msgstr "" -#: inc/form-submit.php:1151 +#: inc/form-submit.php:1153 #: assets/build/formEditor.js:172 #: assets/build/settings.js:172 msgid "hCaptcha" msgstr "" -#: inc/form-submit.php:1155 +#: inc/form-submit.php:1157 #: assets/build/settings.js:172 msgid "Cloudflare Turnstile" msgstr "" -#: inc/form-submit.php:1159 +#: inc/form-submit.php:1161 msgid "Unknown Captcha" msgstr "" -#: inc/form-submit.php:1160 +#: inc/form-submit.php:1162 msgid "Invalid captcha type." msgstr "" #. translators: %s is the captcha title. -#: inc/form-submit.php:1173 +#: inc/form-submit.php:1175 #, php-format msgid "%s verification failed. Please contact your site administrator." msgstr "" @@ -2792,7 +2793,7 @@ msgstr "" #: inc/payments/front-end.php:97 #: inc/payments/front-end.php:298 -#: inc/payments/payment-helper.php:589 +#: inc/payments/payment-helper.php:594 msgid "Invalid form configuration." msgstr "" @@ -3121,399 +3122,403 @@ msgid "Norwegian Krone" msgstr "" #: inc/payments/payment-helper.php:259 -msgid "South Korean Won" +msgid "Polish Złoty" msgstr "" #: inc/payments/payment-helper.php:264 -msgid "Turkish Lira" +msgid "South Korean Won" msgstr "" #: inc/payments/payment-helper.php:269 -msgid "Russian Ruble" +msgid "Turkish Lira" msgstr "" #: inc/payments/payment-helper.php:274 -msgid "Indian Rupee" +msgid "Russian Ruble" msgstr "" #: inc/payments/payment-helper.php:279 -msgid "Brazilian Real" +msgid "Indian Rupee" msgstr "" #: inc/payments/payment-helper.php:284 -msgid "South African Rand" +msgid "Brazilian Real" msgstr "" #: inc/payments/payment-helper.php:289 -msgid "UAE Dirham" +msgid "South African Rand" msgstr "" #: inc/payments/payment-helper.php:294 -msgid "Philippine Peso" +msgid "UAE Dirham" msgstr "" #: inc/payments/payment-helper.php:299 -msgid "Indonesian Rupiah" +msgid "Philippine Peso" msgstr "" #: inc/payments/payment-helper.php:304 -msgid "Malaysian Ringgit" +msgid "Indonesian Rupiah" msgstr "" #: inc/payments/payment-helper.php:309 -msgid "Thai Baht" +msgid "Malaysian Ringgit" msgstr "" #: inc/payments/payment-helper.php:314 -msgid "Burundian Franc" +msgid "Thai Baht" msgstr "" #: inc/payments/payment-helper.php:319 -msgid "Chilean Peso" +msgid "Burundian Franc" msgstr "" #: inc/payments/payment-helper.php:324 -msgid "Djiboutian Franc" +msgid "Chilean Peso" msgstr "" #: inc/payments/payment-helper.php:329 -msgid "Guinean Franc" +msgid "Djiboutian Franc" msgstr "" #: inc/payments/payment-helper.php:334 -msgid "Comorian Franc" +msgid "Guinean Franc" msgstr "" #: inc/payments/payment-helper.php:339 -msgid "Malagasy Ariary" +msgid "Comorian Franc" msgstr "" #: inc/payments/payment-helper.php:344 -msgid "Paraguayan Guaraní" +msgid "Malagasy Ariary" msgstr "" #: inc/payments/payment-helper.php:349 -msgid "Rwandan Franc" +msgid "Paraguayan Guaraní" msgstr "" #: inc/payments/payment-helper.php:354 -msgid "Ugandan Shilling" +msgid "Rwandan Franc" msgstr "" #: inc/payments/payment-helper.php:359 -msgid "Vietnamese Đồng" +msgid "Ugandan Shilling" msgstr "" #: inc/payments/payment-helper.php:364 -msgid "Vanuatu Vatu" +msgid "Vietnamese Đồng" msgstr "" #: inc/payments/payment-helper.php:369 -msgid "Central African CFA Franc" +msgid "Vanuatu Vatu" msgstr "" #: inc/payments/payment-helper.php:374 -msgid "West African CFA Franc" +msgid "Central African CFA Franc" msgstr "" #: inc/payments/payment-helper.php:379 +msgid "West African CFA Franc" +msgstr "" + +#: inc/payments/payment-helper.php:384 msgid "CFP Franc" msgstr "" -#: inc/payments/payment-helper.php:475 +#: inc/payments/payment-helper.php:480 msgid "An unknown error occurred. Please try again or contact the site administrator." msgstr "" -#: inc/payments/payment-helper.php:477 +#: inc/payments/payment-helper.php:482 msgid "Payment is currently unavailable. Please contact the site administrator." msgstr "" -#: inc/payments/payment-helper.php:478 +#: inc/payments/payment-helper.php:483 msgid "Payment is currently unavailable. Please contact the site administrator to configure the payment amount." msgstr "" -#: inc/payments/payment-helper.php:479 +#: inc/payments/payment-helper.php:484 msgid "Invalid payment amount" msgstr "" -#: inc/payments/payment-helper.php:480 +#: inc/payments/payment-helper.php:485 msgid "Payment amount must be at least {symbol}{amount}." msgstr "" -#: inc/payments/payment-helper.php:483 +#: inc/payments/payment-helper.php:488 msgid "Payment is currently unavailable. Please contact the site administrator to configure the customer name field." msgstr "" -#: inc/payments/payment-helper.php:484 +#: inc/payments/payment-helper.php:489 msgid "Payment is currently unavailable. Please contact the site administrator to configure the customer email field." msgstr "" -#: inc/payments/payment-helper.php:485 +#: inc/payments/payment-helper.php:490 msgid "Please enter your name." msgstr "" -#: inc/payments/payment-helper.php:486 +#: inc/payments/payment-helper.php:491 msgid "Please enter your email." msgstr "" -#: inc/payments/payment-helper.php:489 +#: inc/payments/payment-helper.php:494 msgid "Payment failed" msgstr "" -#: inc/payments/payment-helper.php:490 +#: inc/payments/payment-helper.php:495 msgid "Payment successful" msgstr "" -#: inc/payments/payment-helper.php:491 +#: inc/payments/payment-helper.php:496 msgid "Unable to complete payment. Please try again or contact support." msgstr "" -#: inc/payments/payment-helper.php:494 -#: inc/payments/payment-helper.php:495 +#: inc/payments/payment-helper.php:499 +#: inc/payments/payment-helper.php:500 msgid "Your card was declined. Please try a different payment method or contact your bank." msgstr "" -#: inc/payments/payment-helper.php:496 +#: inc/payments/payment-helper.php:501 msgid "Your card has insufficient funds. Please use a different payment method." msgstr "" -#: inc/payments/payment-helper.php:497 +#: inc/payments/payment-helper.php:502 msgid "Your card was declined because it has been reported as lost. Please contact your bank." msgstr "" -#: inc/payments/payment-helper.php:498 +#: inc/payments/payment-helper.php:503 msgid "Your card was declined because it has been reported as stolen. Please contact your bank." msgstr "" -#: inc/payments/payment-helper.php:499 +#: inc/payments/payment-helper.php:504 msgid "Your card has expired. Please use a different payment method." msgstr "" -#: inc/payments/payment-helper.php:500 -#: inc/payments/payment-helper.php:521 +#: inc/payments/payment-helper.php:505 +#: inc/payments/payment-helper.php:526 msgid "Your card was declined. Please contact your bank for more information." msgstr "" -#: inc/payments/payment-helper.php:501 +#: inc/payments/payment-helper.php:506 msgid "Your card was declined due to restrictions. Please contact your bank." msgstr "" -#: inc/payments/payment-helper.php:502 +#: inc/payments/payment-helper.php:507 msgid "Your card was declined due to a security violation. Please contact your bank." msgstr "" -#: inc/payments/payment-helper.php:503 +#: inc/payments/payment-helper.php:508 msgid "Your card does not support this type of purchase. Please use a different payment method." msgstr "" -#: inc/payments/payment-helper.php:504 +#: inc/payments/payment-helper.php:509 msgid "A stop payment order has been placed on this card. Please contact your bank." msgstr "" -#: inc/payments/payment-helper.php:505 +#: inc/payments/payment-helper.php:510 msgid "A test card was used in a live environment. Please use a real card." msgstr "" -#: inc/payments/payment-helper.php:506 +#: inc/payments/payment-helper.php:511 msgid "Your card has exceeded its withdrawal limit. Please contact your bank." msgstr "" -#: inc/payments/payment-helper.php:507 +#: inc/payments/payment-helper.php:512 msgid "Your card's security code is incorrect. Please check and try again." msgstr "" -#: inc/payments/payment-helper.php:508 +#: inc/payments/payment-helper.php:513 msgid "Your card number is incorrect. Please check and try again." msgstr "" -#: inc/payments/payment-helper.php:509 +#: inc/payments/payment-helper.php:514 msgid "Your card's security code is invalid. Please check and try again." msgstr "" -#: inc/payments/payment-helper.php:510 +#: inc/payments/payment-helper.php:515 msgid "Your card's expiration month is invalid. Please check and try again." msgstr "" -#: inc/payments/payment-helper.php:511 +#: inc/payments/payment-helper.php:516 msgid "Your card's expiration year is invalid. Please check and try again." msgstr "" -#: inc/payments/payment-helper.php:512 +#: inc/payments/payment-helper.php:517 msgid "Your card number is invalid. Please check and try again." msgstr "" -#: inc/payments/payment-helper.php:513 +#: inc/payments/payment-helper.php:518 msgid "Unable to process card. Please try again." msgstr "" -#: inc/payments/payment-helper.php:514 +#: inc/payments/payment-helper.php:519 msgid "Unable to process transaction. Please try again." msgstr "" -#: inc/payments/payment-helper.php:515 +#: inc/payments/payment-helper.php:520 msgid "Your card is not supported for this transaction. Please use a different payment method." msgstr "" -#: inc/payments/payment-helper.php:516 +#: inc/payments/payment-helper.php:521 msgid "Your card does not support the currency used for this transaction. Please use a different payment method." msgstr "" -#: inc/payments/payment-helper.php:517 +#: inc/payments/payment-helper.php:522 msgid "A transaction with identical details was submitted recently. Please wait a moment and try again." msgstr "" -#: inc/payments/payment-helper.php:518 +#: inc/payments/payment-helper.php:523 msgid "The account associated with your card is invalid. Please contact your bank." msgstr "" -#: inc/payments/payment-helper.php:519 +#: inc/payments/payment-helper.php:524 msgid "The payment amount is invalid. Please contact the site administrator." msgstr "" -#: inc/payments/payment-helper.php:520 +#: inc/payments/payment-helper.php:525 msgid "Unable to reach card issuer. Please try again later." msgstr "" -#: inc/payments/payment-helper.php:522 +#: inc/payments/payment-helper.php:527 msgid "Your card information needs to be updated. Please contact your bank." msgstr "" -#: inc/payments/payment-helper.php:523 +#: inc/payments/payment-helper.php:528 msgid "The card cannot be used for this transaction. Please contact your bank." msgstr "" -#: inc/payments/payment-helper.php:524 +#: inc/payments/payment-helper.php:529 msgid "The transaction is not permitted. Please contact your bank." msgstr "" -#: inc/payments/payment-helper.php:525 +#: inc/payments/payment-helper.php:530 msgid "Your card requires offline PIN authentication. Please try again." msgstr "" -#: inc/payments/payment-helper.php:526 +#: inc/payments/payment-helper.php:531 msgid "Your card requires PIN authentication. Please try again." msgstr "" -#: inc/payments/payment-helper.php:527 +#: inc/payments/payment-helper.php:532 msgid "You have exceeded the maximum number of PIN attempts. Please contact your bank." msgstr "" -#: inc/payments/payment-helper.php:528 +#: inc/payments/payment-helper.php:533 msgid "All authorizations for this card have been revoked. Please contact your bank." msgstr "" -#: inc/payments/payment-helper.php:529 +#: inc/payments/payment-helper.php:534 msgid "The authorization for this transaction has been revoked. Please try again." msgstr "" -#: inc/payments/payment-helper.php:530 +#: inc/payments/payment-helper.php:535 msgid "This transaction is not allowed. Please contact your bank." msgstr "" -#: inc/payments/payment-helper.php:531 +#: inc/payments/payment-helper.php:536 msgid "Unable to process transaction. Please try again later." msgstr "" -#: inc/payments/payment-helper.php:532 +#: inc/payments/payment-helper.php:537 msgid "Your card was declined. Your request was in live mode, but used a known test card." msgstr "" -#: inc/payments/payment-helper.php:533 +#: inc/payments/payment-helper.php:538 msgid "Your card was declined. Your request was in test mode, but used a non test card. For a list of valid test cards, visit: https://stripe.com/docs/testing." msgstr "" -#: inc/payments/payment-helper.php:536 +#: inc/payments/payment-helper.php:541 msgid "SureForms Subscription" msgstr "" -#: inc/payments/payment-helper.php:537 +#: inc/payments/payment-helper.php:542 msgid "SureForms Payment" msgstr "" -#: inc/payments/payment-helper.php:539 +#: inc/payments/payment-helper.php:544 msgid "SureForms Customer" msgstr "" -#: inc/payments/payment-helper.php:541 +#: inc/payments/payment-helper.php:546 msgid "Complete the form to view the amount." msgstr "" -#: inc/payments/payment-helper.php:542 +#: inc/payments/payment-helper.php:547 msgid "Unable to create payment. Please contact support." msgstr "" -#: inc/payments/payment-helper.php:559 +#: inc/payments/payment-helper.php:564 msgid "Unknown error" msgstr "" -#: inc/payments/payment-helper.php:597 +#: inc/payments/payment-helper.php:602 msgid "Payment configuration not found for this form." msgstr "" #. translators: 1: expected currency, 2: received currency -#: inc/payments/payment-helper.php:608 +#: inc/payments/payment-helper.php:613 #, php-format msgid "Currency mismatch: expected %1$s, received %2$s." msgstr "" #. translators: 1: expected amount with currency -#: inc/payments/payment-helper.php:625 +#: inc/payments/payment-helper.php:630 #, php-format msgid "Payment amount must be exactly %1$s." msgstr "" #. translators: 1: minimum amount with currency -#: inc/payments/payment-helper.php:636 +#: inc/payments/payment-helper.php:641 #, php-format msgid "Payment amount must be at least %1$s." msgstr "" -#: inc/payments/payment-helper.php:712 +#: inc/payments/payment-helper.php:717 msgid "Invalid payment verification parameters." msgstr "" -#: inc/payments/payment-helper.php:723 +#: inc/payments/payment-helper.php:728 msgid "Payment verification failed. Invalid payment intent." msgstr "" -#: inc/payments/payment-helper.php:809 -#: inc/payments/payment-helper.php:947 +#: inc/payments/payment-helper.php:814 +#: inc/payments/payment-helper.php:952 msgid "Variable amount field configuration not found." msgstr "" -#: inc/payments/payment-helper.php:830 +#: inc/payments/payment-helper.php:835 msgid "No payment options are configured for this field." msgstr "" #. translators: %s: currency code -#: inc/payments/payment-helper.php:856 +#: inc/payments/payment-helper.php:861 msgid "Invalid payment amount. Please select a valid amount from the available options." msgstr "" #. translators: %1$s: expected amount, %2$s: payment amount -#: inc/payments/payment-helper.php:891 +#: inc/payments/payment-helper.php:896 msgid "Payment configuration not found." msgstr "" #. translators: %1$s: expected amount, %2$s: payment amount -#: inc/payments/payment-helper.php:907 -#: inc/payments/payment-helper.php:959 -#: inc/payments/payment-helper.php:995 +#: inc/payments/payment-helper.php:912 +#: inc/payments/payment-helper.php:964 +#: inc/payments/payment-helper.php:1000 #, php-format msgid "Payment amount mismatch. Expected %1$s, received %2$s." msgstr "" -#: inc/payments/payment-helper.php:936 -#: inc/payments/payment-helper.php:986 +#: inc/payments/payment-helper.php:941 +#: inc/payments/payment-helper.php:991 msgid "Variable amount field value is required." msgstr "" -#: inc/payments/payment-helper.php:969 +#: inc/payments/payment-helper.php:974 msgid "Number field configuration not found." msgstr "" #. translators: %1$s: minimum amount, %2$s: payment amount -#: inc/payments/payment-helper.php:1007 +#: inc/payments/payment-helper.php:1012 #, php-format msgid "Payment amount below minimum. Minimum: %1$s, received %2$s." msgstr "" @@ -4541,7 +4546,7 @@ msgid "Current Page URL" msgstr "" #: inc/smart-tags.php:111 -#: inc/smart-tags.php:142 +#: inc/smart-tags.php:143 msgid "Admin Email" msgstr "" @@ -4582,7 +4587,7 @@ msgid "User Last Name" msgstr "" #: inc/smart-tags.php:122 -#: inc/smart-tags.php:143 +#: inc/smart-tags.php:144 msgid "User Email" msgstr "" @@ -4606,11 +4611,11 @@ msgstr "" msgid "Embedded Post/Page Title" msgstr "" -#: inc/smart-tags.php:128 +#: inc/smart-tags.php:129 msgid "Populate by GET Param" msgstr "" -#: inc/smart-tags.php:129 +#: inc/smart-tags.php:130 msgid "Cookie Value" msgstr "" @@ -12818,6 +12823,10 @@ msgstr "" msgid "Single Choice Only" msgstr "" +#: assets/build/blocks.js:172 +msgid "Dynamic Default Value" +msgstr "" + #: assets/build/blocks.js:172 msgid "Select Country" msgstr "" diff --git a/package-lock.json b/package-lock.json index 0248f0cdd..98846cdaf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "sureforms", - "version": "2.8.0", + "version": "2.8.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "sureforms", - "version": "2.8.0", + "version": "2.8.1", "license": "GPL", "dependencies": { "@bsf/force-ui": "git+https://github.com/brainstormforce/bsf-admin-ui#v1.7.7", diff --git a/package.json b/package.json index 78f61d8c3..701ad5377 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sureforms", - "version": "2.8.0", + "version": "2.8.1", "description": "A simple yet powerful way to add forms to your website.", "main": "index.js", "scripts": { diff --git a/readme.txt b/readme.txt index 30d0bb2b2..afaf85707 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ Tags: forms, contact form, custom form, payment form, form builder Requires at least: 6.4 Tested up to: 6.9.4 Requires PHP: 7.4 -Stable tag: 2.8.0 +Stable tag: 2.8.1 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html @@ -478,6 +478,15 @@ You can collect payments securely through Stripe in the free version. PayPal pay You can report the issue through our [Bug Bounty Program](https://brainstormforce.com/bug-bounty-program/). We collaborate with Patchstack to provide opportunities for researchers to report vulnerabilities. The Patchstack team will help validate, triage, and handle any reported security issues. == Changelog == += 2.8.1 - 24th April 2026 = +* New: Added dynamic default value support for Dropdown and Multi Choice fields. +* New: Added PLN (Polish Zloty) currency support to payment fields. +* New: Added {entry_id} smart tag for use in emails, confirmations, PDFs, and integrations. +* Improvement: Updated Astra Notices to 1.2.1 and BSF Analytics to 1.1.26. +* Fix: Background color not applied in non-iframe editor mode. +* Fix: Dynamic options repeater generated incorrect field slugs. +* Fix: MCP endpoint REST URL ignored sites with a custom REST path prefix. +* Fix: Phone field country flag changed unexpectedly on browser autofill or input. = 2.8.0 - 16th April 2026 = * New: Added My Account page allowing users to view and manage their payment history and subscriptions. * Improvement: Phone number country detection moved to backend with caching, reducing multiple API calls. @@ -494,16 +503,6 @@ You can report the issue through our [Bug Bounty Program](https://brainstormforc * Fix: Fixed slugs with underscores not mapping correctly during smart tag and integration processing. * Fix: Fixed textarea values losing line breaks in {form:field} smart tags. * Fix: Fixed {current_page_url} smart tag resolving to REST API URL in email notifications. -= 2.7.0 - 31st March 2026 = -* New: Added styling options for Gutenberg SureForms Form Block. -* New: Added styling options for Bricks Builder SureForms Form Element. -* New: Added styling options for Elementor SureForms Form Widget. -* Fix: Fixed "Send as Raw HTML" email option wrapping content in unwanted template markup. -* Fix: Fixed Multi Choice option labels with extra whitespace failing to resolve numeric values in payment calculations. -* Fix: Fixed block slug not locking when a smart tag is inserted via the pro plugin. -* Fix: Fixed dynamic tag URLs being auto-linked with HTML markup when used in redirect query parameters. -* Fix: Fixed theme text-transform styles cascading into form input fields. -* Fix: Fixed unique field validation endpoint exposing submitted data to unauthenticated enumeration attacks. The full changelog is available [here](https://sureforms.com/whats-new/). == Upgrade Notice == diff --git a/sureforms.php b/sureforms.php index 3ab44be0e..6681276cc 100644 --- a/sureforms.php +++ b/sureforms.php @@ -7,7 +7,7 @@ * Requires PHP: 7.4 * Author: SureForms * Author URI: https://sureforms.com/ - * Version: 2.8.0 + * Version: 2.8.1 * License: GPLv2 or later * Text Domain: sureforms * @@ -25,7 +25,7 @@ define( 'SRFM_BASENAME', plugin_basename( SRFM_FILE ) ); define( 'SRFM_DIR', plugin_dir_path( SRFM_FILE ) ); define( 'SRFM_URL', plugins_url( '/', SRFM_FILE ) ); -define( 'SRFM_VER', '2.8.0' ); +define( 'SRFM_VER', '2.8.1' ); define( 'SRFM_SLUG', 'srfm' ); // ------ ADDITIONAL CONSTANTS ------- // define( 'SRFM_FORMS_POST_TYPE', 'sureforms_form' ); @@ -35,7 +35,7 @@ define( 'SRFM_AI_MIDDLEWARE', 'https://credits.startertemplates.com/sureforms/' ); define( 'SRFM_MIDDLEWARE_BASE_URL', 'https://api.sureforms.com/' ); define( 'SRFM_BILLING_PORTAL', 'https://billing.sureforms.com/' ); -define( 'SRFM_PRO_RECOMMENDED_VER', '2.8.0' ); +define( 'SRFM_PRO_RECOMMENDED_VER', '2.8.2' ); define( 'SRFM_SURETRIGGERS_INTEGRATION_BASE_URL', 'https://app.ottokit.com/' ); From 27a2520df6436c3dbeeb2ff9cc1bcace8d6e2ce2 Mon Sep 17 00:00:00 2001 From: Vansh Kapoor Date: Fri, 24 Apr 2026 16:14:14 +0530 Subject: [PATCH 18/24] Update 2.8.1 changelog release date to 27th April 2026 --- README.md | 2 +- readme.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8e857afd5..3ebb5106e 100644 --- a/README.md +++ b/README.md @@ -478,7 +478,7 @@ You can collect payments securely through Stripe in the free version. PayPal pay You can report the issue through our [Bug Bounty Program](https://brainstormforce.com/bug-bounty-program/). We collaborate with Patchstack to provide opportunities for researchers to report vulnerabilities. The Patchstack team will help validate, triage, and handle any reported security issues. ## Changelog ## -### 2.8.1 - 24th April 2026 ### +### 2.8.1 - 27th April 2026 ### * New: Added dynamic default value support for Dropdown and Multi Choice fields. * New: Added PLN (Polish Zloty) currency support to payment fields. * New: Added {entry_id} smart tag for use in emails, confirmations, PDFs, and integrations. diff --git a/readme.txt b/readme.txt index afaf85707..bb83065fc 100644 --- a/readme.txt +++ b/readme.txt @@ -478,7 +478,7 @@ You can collect payments securely through Stripe in the free version. PayPal pay You can report the issue through our [Bug Bounty Program](https://brainstormforce.com/bug-bounty-program/). We collaborate with Patchstack to provide opportunities for researchers to report vulnerabilities. The Patchstack team will help validate, triage, and handle any reported security issues. == Changelog == -= 2.8.1 - 24th April 2026 = += 2.8.1 - 27th April 2026 = * New: Added dynamic default value support for Dropdown and Multi Choice fields. * New: Added PLN (Polish Zloty) currency support to payment fields. * New: Added {entry_id} smart tag for use in emails, confirmations, PDFs, and integrations. From c737015861058b1eb9ff87a787e8dd44f97b40fd Mon Sep 17 00:00:00 2001 From: Vansh Kapoor Date: Fri, 24 Apr 2026 16:15:31 +0530 Subject: [PATCH 19/24] Update 2.8.1 changelog to final curated bullets --- README.md | 17 +++++++++-------- readme.txt | 17 +++++++++-------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 3ebb5106e..e7eb96899 100644 --- a/README.md +++ b/README.md @@ -479,14 +479,15 @@ You can report the issue through our [Bug Bounty Program](https://brainstormforc ## Changelog ## ### 2.8.1 - 27th April 2026 ### -* New: Added dynamic default value support for Dropdown and Multi Choice fields. -* New: Added PLN (Polish Zloty) currency support to payment fields. -* New: Added {entry_id} smart tag for use in emails, confirmations, PDFs, and integrations. -* Improvement: Updated Astra Notices to 1.2.1 and BSF Analytics to 1.1.26. -* Fix: Background color not applied in non-iframe editor mode. -* Fix: Dynamic options repeater generated incorrect field slugs. -* Fix: MCP endpoint REST URL ignored sites with a custom REST path prefix. -* Fix: Phone field country flag changed unexpectedly on browser autofill or input. +* New: Added support for dynamic default values on Dropdown and Multi-Choice fields. +* New: Added {entry_id} smart tag for use in email templates, confirmations, and dynamic content. +* Improvement: Added PLN (Polish Złoty) to the currency dropdown. +* Improvement: Updated bundled libraries: astra-notices to 1.2.1 and bsf-analytics to 1.1.26. +* Fix: Fixed background color not applying correctly in non-iframe editor mode. +* Fix: Fixed dynamic options not loading for Dropdown and Multi-Choice fields placed inside a Repeater. +* Fix: Fixed MCP endpoint REST URL resolution so it uses the correct site URL. +* Fix: Fixed Phone field country flag unexpectedly changing during browser autocomplete. +* Fix: Fixed review/validation issues in Global Settings. ### 2.8.0 - 16th April 2026 ### * New: Added My Account page allowing users to view and manage their payment history and subscriptions. * Improvement: Phone number country detection moved to backend with caching, reducing multiple API calls. diff --git a/readme.txt b/readme.txt index bb83065fc..b0bf63615 100644 --- a/readme.txt +++ b/readme.txt @@ -479,14 +479,15 @@ You can report the issue through our [Bug Bounty Program](https://brainstormforc == Changelog == = 2.8.1 - 27th April 2026 = -* New: Added dynamic default value support for Dropdown and Multi Choice fields. -* New: Added PLN (Polish Zloty) currency support to payment fields. -* New: Added {entry_id} smart tag for use in emails, confirmations, PDFs, and integrations. -* Improvement: Updated Astra Notices to 1.2.1 and BSF Analytics to 1.1.26. -* Fix: Background color not applied in non-iframe editor mode. -* Fix: Dynamic options repeater generated incorrect field slugs. -* Fix: MCP endpoint REST URL ignored sites with a custom REST path prefix. -* Fix: Phone field country flag changed unexpectedly on browser autofill or input. +* New: Added support for dynamic default values on Dropdown and Multi-Choice fields. +* New: Added {entry_id} smart tag for use in email templates, confirmations, and dynamic content. +* Improvement: Added PLN (Polish Złoty) to the currency dropdown. +* Improvement: Updated bundled libraries: astra-notices to 1.2.1 and bsf-analytics to 1.1.26. +* Fix: Fixed background color not applying correctly in non-iframe editor mode. +* Fix: Fixed dynamic options not loading for Dropdown and Multi-Choice fields placed inside a Repeater. +* Fix: Fixed MCP endpoint REST URL resolution so it uses the correct site URL. +* Fix: Fixed Phone field country flag unexpectedly changing during browser autocomplete. +* Fix: Fixed review/validation issues in Global Settings. = 2.8.0 - 16th April 2026 = * New: Added My Account page allowing users to view and manage their payment history and subscriptions. * Improvement: Phone number country detection moved to backend with caching, reducing multiple API calls. From 674a5700a3beba9b5ff4ce6ede8ae1205bfa6b28 Mon Sep 17 00:00:00 2001 From: Vansh Kapoor Date: Fri, 24 Apr 2026 16:24:37 +0530 Subject: [PATCH 20/24] Remove bundled libraries bullet from 2.8.1 changelog --- README.md | 1 - readme.txt | 1 - 2 files changed, 2 deletions(-) diff --git a/README.md b/README.md index e7eb96899..4f114e7df 100644 --- a/README.md +++ b/README.md @@ -482,7 +482,6 @@ You can report the issue through our [Bug Bounty Program](https://brainstormforc * New: Added support for dynamic default values on Dropdown and Multi-Choice fields. * New: Added {entry_id} smart tag for use in email templates, confirmations, and dynamic content. * Improvement: Added PLN (Polish Złoty) to the currency dropdown. -* Improvement: Updated bundled libraries: astra-notices to 1.2.1 and bsf-analytics to 1.1.26. * Fix: Fixed background color not applying correctly in non-iframe editor mode. * Fix: Fixed dynamic options not loading for Dropdown and Multi-Choice fields placed inside a Repeater. * Fix: Fixed MCP endpoint REST URL resolution so it uses the correct site URL. diff --git a/readme.txt b/readme.txt index b0bf63615..0056ab757 100644 --- a/readme.txt +++ b/readme.txt @@ -482,7 +482,6 @@ You can report the issue through our [Bug Bounty Program](https://brainstormforc * New: Added support for dynamic default values on Dropdown and Multi-Choice fields. * New: Added {entry_id} smart tag for use in email templates, confirmations, and dynamic content. * Improvement: Added PLN (Polish Złoty) to the currency dropdown. -* Improvement: Updated bundled libraries: astra-notices to 1.2.1 and bsf-analytics to 1.1.26. * Fix: Fixed background color not applying correctly in non-iframe editor mode. * Fix: Fixed dynamic options not loading for Dropdown and Multi-Choice fields placed inside a Repeater. * Fix: Fixed MCP endpoint REST URL resolution so it uses the correct site URL. From c4927fa642d96b8c606602442f2843b2e6fd77b5 Mon Sep 17 00:00:00 2001 From: Vansh Kapoor Date: Mon, 27 Apr 2026 15:22:23 +0530 Subject: [PATCH 21/24] fix notices in survey page --- src/admin/tw-base.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/admin/tw-base.scss b/src/admin/tw-base.scss index 1557c91a4..225cf68d5 100644 --- a/src/admin/tw-base.scss +++ b/src/admin/tw-base.scss @@ -70,7 +70,7 @@ } } // Hide WP notices in entries screen -#wpbody:has( #srfm-entries-root, #srfm-survey-reports-root, #srfm-quiz-entries-root, #srfm-payments-react-container, #srfm-learn-root ) { +#wpbody:has( #srfm-entries-root, #srfm-survey-reports-root, #srfm-survey-empty-state-root, #srfm-quiz-entries-root, #srfm-payments-react-container, #srfm-learn-root ) { #wpbody-content > .notice { display: none; } From b310de0c269cf323b625dc20f83d1bf8939c32e7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 27 Apr 2026 09:58:26 +0000 Subject: [PATCH 22/24] chore: update i18n translations Auto-generated by /i18n command on PR #2670 --- ...e_DE-4b62e3f004dea2c587b5a3069263d994.json | 2 +- ...e_DE-51635fe6489fc8288d603fe596c755ca.json | 2 +- languages/sureforms-de_DE.mo | Bin 293442 -> 293552 bytes languages/sureforms-de_DE.po | 361 ++++++++--------- ...s_ES-4b62e3f004dea2c587b5a3069263d994.json | 2 +- ...s_ES-51635fe6489fc8288d603fe596c755ca.json | 2 +- languages/sureforms-es_ES.mo | Bin 295640 -> 295752 bytes languages/sureforms-es_ES.po | 361 ++++++++--------- ...r_FR-4b62e3f004dea2c587b5a3069263d994.json | 2 +- ...r_FR-51635fe6489fc8288d603fe596c755ca.json | 2 +- languages/sureforms-fr_FR.mo | Bin 299555 -> 299667 bytes languages/sureforms-fr_FR.po | 361 ++++++++--------- ...t_IT-4b62e3f004dea2c587b5a3069263d994.json | 2 +- ...t_IT-51635fe6489fc8288d603fe596c755ca.json | 2 +- languages/sureforms-it_IT.mo | Bin 290280 -> 290390 bytes languages/sureforms-it_IT.po | 361 ++++++++--------- ...l_NL-4b62e3f004dea2c587b5a3069263d994.json | 2 +- ...l_NL-51635fe6489fc8288d603fe596c755ca.json | 2 +- languages/sureforms-nl_NL.mo | Bin 283333 -> 283441 bytes languages/sureforms-nl_NL.po | 361 ++++++++--------- ...l_PL-4b62e3f004dea2c587b5a3069263d994.json | 2 +- ...l_PL-51635fe6489fc8288d603fe596c755ca.json | 2 +- languages/sureforms-pl_PL.mo | Bin 290824 -> 290993 bytes languages/sureforms-pl_PL.po | 363 +++++++++--------- ...t_PT-4b62e3f004dea2c587b5a3069263d994.json | 2 +- ...t_PT-51635fe6489fc8288d603fe596c755ca.json | 2 +- languages/sureforms-pt_PT.mo | Bin 292945 -> 293052 bytes languages/sureforms-pt_PT.po | 361 ++++++++--------- 28 files changed, 1310 insertions(+), 1247 deletions(-) diff --git a/languages/sureforms-de_DE-4b62e3f004dea2c587b5a3069263d994.json b/languages/sureforms-de_DE-4b62e3f004dea2c587b5a3069263d994.json index 9de018f52..23d4e69fb 100644 --- a/languages/sureforms-de_DE-4b62e3f004dea2c587b5a3069263d994.json +++ b/languages/sureforms-de_DE-4b62e3f004dea2c587b5a3069263d994.json @@ -1 +1 @@ -{"translation-revision-date":"2024-12-13T16:14:52+00:00","generator":"WP-CLI\/2.12.0","source":"assets\/build\/blocks.js","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","lang":"en","plural-forms":"nplurals=2; plural=(n != 1);"},"Settings":["Einstellungen"],"Search":["Suche"],"Fields":["Felder"],"Image":["Bild"],"Submit":["Einreichen"],"Required":["Erforderlich"],"Form Title":["Formulartitel"],"Show":["Zeigen"],"Hide":["Verbergen"],"Edit Form":["Formular bearbeiten"],"Icon":["Symbol"],"Desktop":["Desktop"],"Medium":["Mittel"],"Mobile":["Mobil"],"Repeat":["Wiederholen"],"Scroll":["Scrollen"],"Tablet":["Tablet"],"Basic":["Grundlegend"],"(no title)":["(kein Titel)"],"Select a Form":["W\u00e4hlen Sie ein Formular aus"],"No forms found\u2026":["Keine Formulare gefunden\u2026"],"Choose":["W\u00e4hlen"],"Create New":["Neu erstellen"],"Change Form":["Formular \u00e4ndern"],"This form has been deleted or is unavailable.":["Dieses Formular wurde gel\u00f6scht oder ist nicht verf\u00fcgbar."],"Form Settings":["Formulareinstellungen"],"Show Form Title on this Page":["Formulartitel auf dieser Seite anzeigen"],"Note: For editing SureForms, please refer to the SureForms Editor - ":["Hinweis: F\u00fcr die Bearbeitung von SureForms, bitte den SureForms-Editor verwenden -"],"Field preview":["Feldvorschau"],"General":["Allgemein"],"Style":["Stil"],"Advanced":["Fortgeschritten"],"No tags available":["Keine Tags verf\u00fcgbar"],"Device":["Ger\u00e4t"],"Select Shortcodes":["Shortcodes ausw\u00e4hlen"],"Page Break Label":["Seitenumbruch-Label"],"Next":["Weiter"],"Back":["Zur\u00fcck"],"Reset":["Zur\u00fccksetzen"],"Generic tags":["Allgemeine Tags"],"Pixel":["Pixel"],"Em":["Em"],"Select Units":["Einheiten ausw\u00e4hlen"],"%s units":["%s Einheiten"],"Margin":["Marge"],"Attributes":["Attribute"],"Input Pattern":["Eingabemuster"],"None":["Keine"],"(###) ###-####":["(###) ###-####"],"(##) ####-####":["(##) ####-####"],"27\/08\/2024":["27.08.2024"],"23:59:59":["23:59:59"],"27\/08\/2024 23:59:59":["27.08.2024 23:59:59"],"Custom":["Benutzerdefiniert"],"Custom Mask":["Benutzerdefinierte Maske"],"Please check the documentation to manage custom input pattern ":["Bitte \u00fcberpr\u00fcfen Sie die Dokumentation, um das benutzerdefinierte Eingabemuster zu verwalten"],"here":["hier"],"Default Value":["Standardwert"],"Error Message":["Fehlermeldung"],"Help Text":["Hilfetext"],"Number Format":["Zahlenformat"],"US Style (Eg: 9,999.99)":["US-Stil (z. B.: 9.999,99)"],"EU Style (Eg: 9.999,99)":["EU-Stil (z. B.: 9.999,99)"],"Minimum Value":["Mindestwert"],"Maximum Value":["Maximalwert"],"Please check the Minimum and Maximum value":["Bitte \u00fcberpr\u00fcfen Sie den Mindest- und H\u00f6chstwert"],"Enable Email Confirmation":["E-Mail-Best\u00e4tigung aktivieren"],"Checked by Default":["Standardm\u00e4\u00dfig aktiviert"],"Error message":["Fehlermeldung"],"Checked by default":["Standardm\u00e4\u00dfig ausgew\u00e4hlt"],"Please add a option props to MultiButtonsControl":["Bitte f\u00fcgen Sie eine Option props zu MultiButtonsControl hinzu"],"Icon Library":["Icon-Bibliothek"],"Close":["Schlie\u00dfen"],"All Icons":["Alle Symbole"],"Other":["Andere"],"No Icons Found":["Keine Symbole gefunden"],"Insert Icon":["Symbol einf\u00fcgen"],"Change Icon":["Symbol \u00e4ndern"],"Choose Icon":["Symbol ausw\u00e4hlen"],"Confirm":["Best\u00e4tigen"],"Cancel":["Abbrechen"],"Processing\u2026":["Verarbeitung\u2026"],"Select Video":["Video ausw\u00e4hlen"],"Change Video":["Video \u00e4ndern"],"Select Lottie Animation":["Lottie-Animation ausw\u00e4hlen"],"Change Lottie Animation":["Lottie-Animation \u00e4ndern"],"Upload SVG":["SVG hochladen"],"Change SVG":["SVG \u00e4ndern"],"Select Image":["Bild ausw\u00e4hlen"],"Change Image":["Bild \u00e4ndern"],"Upload SVG?":["SVG hochladen?"],"Upload SVG can be potentially risky. Are you sure?":["Das Hochladen von SVG kann potenziell riskant sein. Bist du sicher?"],"Upload Anyway":["Trotzdem hochladen"],"Bulk Add":["Massenhinzuf\u00fcgen"],"Bulk Add Options":["Optionen in gro\u00dfen Mengen hinzuf\u00fcgen"],"Enter each option on a new line.":["Geben Sie jede Option in einer neuen Zeile ein."],"Insert Options":["Optionen einf\u00fcgen"],"Full Width":["Volle Breite"],"Option Type":["Optionstyp"],"Edit Options":["Optionen bearbeiten"],"Add New Option":["Neue Option hinzuf\u00fcgen"],"ADD":["HINZUF\u00dcGEN"],"Enable Auto Country Detection":["Automatische L\u00e4nderdetektion aktivieren"],"%s Width":["%s Breite"],"Upgrade":["Aktualisieren"],"Clear":["Klar"],"Select Color":["Farbe ausw\u00e4hlen"],"Primary Color":["Prim\u00e4rfarbe"],"Text Color":["Textfarbe"],"Field Spacing":["Feldabstand"],"Small":["Klein"],"Large":["Gro\u00df"],"Left":["Links"],"Center":["Zentrum"],"Right":["Richtig"],"Color":["Farbe"],"Background Color":["Hintergrundfarbe"],"Auto":["Auto"],"Default":["Standard"],"Normal":["Normal"],"%":["%"],"Top":["Oben"],"Bottom":["Unten"],"Width":["Breite"],"Size":["Gr\u00f6\u00dfe"],"EM":["EM"],"Padding":["Polsterung"],"Color 1":["Farbe 1"],"Color 2":["Farbe 2"],"Type":["Typ"],"Linear":["Linear"],"Radial":["Radial"],"Location 1":["Standort 1"],"Location 2":["Standort 2"],"Angle":["Winkel"],"Classic":["Klassisch"],"Gradient":["Gradient"],"Horizontal":["Horizontal"],"Vertical":["Vertikal"],"Background":["Hintergrund"],"Cover":["Abdeckung"],"Contain":["Enthalten"],"Layout":["Layout"],"Overlay":["\u00dcberlagerung"],"No Repeat":["Keine Wiederholung"],"Overlay Opacity":["\u00dcberlagerungsdeckkraft"],"Conditional Logic":["Bedingte Logik"],"Upgrade to the SureForms Starter Plan to create dynamic forms that adapt based on user input, offering a personalised and efficient form experience.":["Wechseln Sie zum SureForms Starter-Plan, um dynamische Formulare zu erstellen, die sich basierend auf Benutzereingaben anpassen und ein personalisiertes und effizientes Formularerlebnis bieten."],"Enable Conditional Logic":["Bedingte Logik aktivieren"],"this field if":["dieses Feld, wenn"],"Configure Conditions":["Bedingungen konfigurieren"],"Premium":["Premium"],"Overlay Type":["Overlay-Typ"],"Image Overlay Color":["Bild\u00fcberlagerungsfarbe"],"Image Position":["Bildposition"],"Attachment":["Anhang"],"Fixed":["Fest"],"Blend Mode":["Mischmodus"],"Multiply":["Multiplizieren"],"Screen":["Bildschirm"],"Darken":["Verdunkeln"],"Lighten":["Erleichtern"],"Color Dodge":["Farb-Abwedeln"],"Saturation":["S\u00e4ttigung"],"Repeat-x":["Wiederholen-x"],"Repeat-y":["Wiederhole-y"],"PX":["PX"],"Button":["Schaltfl\u00e4che"],"Prefix Label":["Pr\u00e4fix-Label"],"Suffix Label":["Suffix-Label"],"Border Radius":["Randradius"],"Form Theme":["Formular-Thema"],"Select Gradient":["Gradient ausw\u00e4hlen"],"Unlock Conditional Logic Editor":["Conditional Logic Editor entsperren"],"Rich Text Editor":["Rich-Text-Editor"],"Read Only":["Nur Lesen"],"Select Country":["Land ausw\u00e4hlen"],"Default Country":["Standardland"],"Subscription":["Abonnement"],"One Time":["Einmal"],"Unique Entry":["Einzigartiger Eintrag"],"Maximum Characters":["Maximale Zeichen"],"Textarea Height":["Textbereichsh\u00f6he"],"Minimum Selections":["Mindestanzahl an Auswahlen"],"Maximum Selections":["Maximale Auswahlen"],"Add Numeric Values to Options":["F\u00fcgen Sie numerische Werte zu Optionen hinzu"],"Single Choice Only":["Nur eine Auswahl m\u00f6glich"],"Enable Dropdown Search":["Dropdown-Suche aktivieren"],"Allow Multiple":["Mehrfach erlauben"],"%1$s fields are required. Please configure these fields in the block settings.":["%1$s Felder sind erforderlich. Bitte konfigurieren Sie diese Felder in den Blockeinstellungen."],"%1$s field is required. Please configure this field in the block settings.":["%1$s Feld ist erforderlich. Bitte konfigurieren Sie dieses Feld in den Blockeinstellungen."],"You need to configure a payment account to collect payments from this form. Please configure your payment provider to proceed.":["Sie m\u00fcssen ein Zahlungskonto einrichten, um Zahlungen \u00fcber dieses Formular zu sammeln. Bitte konfigurieren Sie Ihren Zahlungsanbieter, um fortzufahren."],"Configure Payment Account":["Zahlungskonto konfigurieren"],"This is a placeholder for the Payment block. The actual payment fields for your configured payment provider(s) will only appear when you preview or publish the form.":["Dies ist ein Platzhalter f\u00fcr den Zahlungsblock. Die tats\u00e4chlichen Zahlungsfelder f\u00fcr Ihre konfigurierten Zahlungsanbieter werden nur angezeigt, wenn Sie das Formular in der Vorschau anzeigen oder ver\u00f6ffentlichen."],"2 Payments":["2 Zahlungen"],"3 Payments":["3 Zahlungen"],"4 Payments":["4 Zahlungen"],"5 Payments":["5 Zahlungen"],"Never":["Niemals"],"Stop Subscription After":["Abonnement beenden nach"],"Choose when to automatically stop the subscription":["W\u00e4hlen Sie, wann das Abonnement automatisch beendet werden soll"],"Number of Payments":["Anzahl der Zahlungen"],"Enter a number between 1 to 100":["Geben Sie eine Zahl zwischen 1 und 100 ein"],"Form Field":["Formularfeld"],"Payment Type":["Zahlungsart"],"Subscription Plan Name":["Abonnementplanname"],"Billing Interval":["Abrechnungsintervall"],"Daily":["T\u00e4glich"],"Weekly":["W\u00f6chentlich"],"Monthly":["Monatlich"],"Quarterly":["Viertelj\u00e4hrlich"],"Yearly":["J\u00e4hrlich"],"Amount Type":["Betragstyp"],"Fixed Amount":["Fester Betrag"],"Dynamic Amount":["Dynamischer Betrag"],"Choose whether to charge a fixed amount or charge the amount based on user input in other form fields.":["W\u00e4hlen Sie, ob ein fester Betrag berechnet werden soll oder ob der Betrag basierend auf Benutzereingaben in anderen Formularfeldern berechnet werden soll."],"Set the exact amount you want to charge. Users won\u2019t be able to change it":["Legen Sie den genauen Betrag fest, den Sie berechnen m\u00f6chten. Benutzer k\u00f6nnen ihn nicht \u00e4ndern"],"Choose Amount Field":["Betragsfeld ausw\u00e4hlen"],"Select a field\u2026":["W\u00e4hlen Sie ein Feld aus\u2026"],"Pick a field from your form like a number, dropdown, or multichoice whose value should decide the payment amount.":["W\u00e4hlen Sie ein Feld aus Ihrem Formular, wie eine Zahl, ein Dropdown-Men\u00fc oder eine Mehrfachauswahl, dessen Wert den Zahlungsbetrag bestimmen soll."],"Minimum Amount":["Mindestbetrag"],"Set the minimum amount users can enter (0 for no minimum)":["Legen Sie den Mindestbetrag fest, den Benutzer eingeben k\u00f6nnen (0 f\u00fcr kein Minimum)"],"Customer Name Field (Required)":["Kundenname-Feld (erforderlich)"],"Customer Name Field (Optional)":["Kundenname-Feld (Optional)"],"Select the input field that contains the customer name (Required for subscriptions)":["W\u00e4hlen Sie das Eingabefeld aus, das den Kundennamen enth\u00e4lt (Erforderlich f\u00fcr Abonnements)"],"Select the input field that contains the customer name":["W\u00e4hlen Sie das Eingabefeld aus, das den Kundennamen enth\u00e4lt"],"Customer Email Field (Required)":["Kunden-E-Mail-Feld (erforderlich)"],"Select the email field that contains the customer email":["W\u00e4hlen Sie das E-Mail-Feld aus, das die Kunden-E-Mail enth\u00e4lt"],"Payment":["Zahlung"],"%s - Order ID":["%s - Bestell-ID"],"%s - Amount":["%s - Betrag"],"%s - Customer Email":["%s - Kunden-E-Mail"],"%s - Customer Name":["%s - Kundenname"],"%s - Status":["%s - Status"],"Button Alignment":["Schaltfl\u00e4chenanordnung"],"Placeholder":["Platzhalter"],"Preselect this option":["Diese Option vorausw\u00e4hlen"],"Restrict Country Codes":["L\u00e4ndercodes einschr\u00e4nken"],"Restriction Type":["Einschr\u00e4nkungstyp"],"Allow":["Erlauben"],"Block":["Blockieren"],"Select Allowed Countries":["Zul\u00e4ssige L\u00e4nder ausw\u00e4hlen"],"Choose countries\u2026":["L\u00e4nder ausw\u00e4hlen\u2026"],"Choose which country codes users can select in the phone number field. Leave empty to allow all country codes.":["W\u00e4hlen Sie aus, welche L\u00e4ndercodes Benutzer im Telefonnummernfeld ausw\u00e4hlen k\u00f6nnen. Lassen Sie das Feld leer, um alle L\u00e4ndercodes zuzulassen."],"Select Blocked Countries":["Gesperrte L\u00e4nder ausw\u00e4hlen"],"These countries will be hidden from the dropdown.":["Diese L\u00e4nder werden im Dropdown-Men\u00fc ausgeblendet."],"Bulk Edit":["Massenbearbeitung"],"Select Layout":["Layout ausw\u00e4hlen"],"Number of Columns":["Anzahl der Spalten"],"Validation Message for Duplicate":["Validierungsnachricht f\u00fcr Duplikat"],"Click here to insert a form":["Klicken Sie hier, um ein Formular einzuf\u00fcgen"],"Inherit Form's Original Style":["Urspr\u00fcnglichen Stil des Formulars \u00fcbernehmen"],"Text on Primary":["Text auf Prim\u00e4r"],"%s - Description":["%s - Beschreibung"],"Upgrade to Unlock":["Upgrade zum Freischalten"],"Custom (Premium)":["Benutzerdefiniert (Premium)"],"Select a theme style for this form embed.":["W\u00e4hlen Sie einen Themenstil f\u00fcr dieses Formulareinbettung aus."],"Colors":["Farben"],"Advanced Styling":["Erweitertes Styling"],"Unlock Custom Styling":["Benutzerdefinierte Gestaltung freischalten"],"Switch to Custom Mode to take full control of your form's design and spacing.":["Wechseln Sie in den benutzerdefinierten Modus, um die volle Kontrolle \u00fcber das Design und den Abstand Ihres Formulars zu \u00fcbernehmen."],"Full color control (buttons, fields, text)":["Volle Farbkontrolle (Schaltfl\u00e4chen, Felder, Text)"],"Row and column gap control":["Steuerung von Zeilen- und Spaltenabst\u00e4nden"],"Field spacing and layout precision":["Feldabst\u00e4nde und Layoutpr\u00e4zision"],"Complete button styling":["Komplette Schaltfl\u00e4chen-Stilgestaltung"],"Payment Description":["Zahlungsbeschreibung"],"Shown on payment receipts and in your payment dashboard (Stripe and PayPal). Leave blank to use the default.":["Auf Zahlungsbelegen und in Ihrem Zahlungs-Dashboard (Stripe und PayPal) angezeigt. Leer lassen, um den Standard zu verwenden."],"Slug":["Schnecke"],"Auto-generated on save":["Automatisch beim Speichern generiert"],"This slug is already used by another field. It will revert to the previous value.":["Dieser Slug wird bereits von einem anderen Feld verwendet. Er wird auf den vorherigen Wert zur\u00fcckgesetzt."],"Changing the slug may break form submissions, conditional logic, integrations, or any other feature currently referencing this slug. You will need to update all such references manually.":["Das \u00c4ndern des Slugs kann Formular\u00fcbermittlungen, bedingte Logik, Integrationen oder andere Funktionen, die derzeit auf diesen Slug verweisen, beeintr\u00e4chtigen. Sie m\u00fcssen alle derartigen Verweise manuell aktualisieren."],"Field Slug":["Feld-Slug"],"Location Services":["Standortdienste"],"Unlock Address Autocomplete":["Adresse-Autovervollst\u00e4ndigung freischalten"],"Upgrade to enable Google Address Autocomplete with interactive map preview, making address entry faster and more accurate for your users.":["Upgrade, um die Google Address Autocomplete-Funktion mit interaktiver Kartenansicht zu aktivieren, wodurch die Adresseingabe f\u00fcr Ihre Nutzer schneller und genauer wird."],"Enable Google Autocomplete":["Google Autovervollst\u00e4ndigung aktivieren"],"Show Interactive Map":["Interaktive Karte anzeigen"],"Payments Per Page":["Zahlungen pro Seite"],"Show Subscriptions Section":["Abonnement-Bereich anzeigen"],"Show a dedicated subscriptions section above payment history.":["Zeige einen eigenen Abonnementbereich \u00fcber der Zahlungshistorie an."],"Payment Dashboard":["Zahlungs\u00fcbersicht"],"View your payments and manage subscriptions in a single dashboard.":["Sehen Sie Ihre Zahlungen ein und verwalten Sie Abonnements in einem einzigen Dashboard."]}}} \ No newline at end of file +{"translation-revision-date":"2024-12-13T16:14:52+00:00","generator":"WP-CLI\/2.12.0","source":"assets\/build\/blocks.js","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","lang":"en","plural-forms":"nplurals=2; plural=(n != 1);"},"Settings":["Einstellungen"],"Search":["Suche"],"Fields":["Felder"],"Image":["Bild"],"Submit":["Einreichen"],"Required":["Erforderlich"],"Form Title":["Formulartitel"],"Show":["Zeigen"],"Hide":["Verbergen"],"Edit Form":["Formular bearbeiten"],"Icon":["Symbol"],"Desktop":["Desktop"],"Medium":["Mittel"],"Mobile":["Mobil"],"Repeat":["Wiederholen"],"Scroll":["Scrollen"],"Tablet":["Tablet"],"Basic":["Grundlegend"],"(no title)":["(kein Titel)"],"Select a Form":["W\u00e4hlen Sie ein Formular aus"],"No forms found\u2026":["Keine Formulare gefunden\u2026"],"Choose":["W\u00e4hlen"],"Create New":["Neu erstellen"],"Change Form":["Formular \u00e4ndern"],"This form has been deleted or is unavailable.":["Dieses Formular wurde gel\u00f6scht oder ist nicht verf\u00fcgbar."],"Form Settings":["Formulareinstellungen"],"Show Form Title on this Page":["Formulartitel auf dieser Seite anzeigen"],"Note: For editing SureForms, please refer to the SureForms Editor - ":["Hinweis: F\u00fcr die Bearbeitung von SureForms, bitte den SureForms-Editor verwenden -"],"Field preview":["Feldvorschau"],"General":["Allgemein"],"Style":["Stil"],"Advanced":["Fortgeschritten"],"No tags available":["Keine Tags verf\u00fcgbar"],"Device":["Ger\u00e4t"],"Select Shortcodes":["Shortcodes ausw\u00e4hlen"],"Page Break Label":["Seitenumbruch-Label"],"Next":["Weiter"],"Back":["Zur\u00fcck"],"Reset":["Zur\u00fccksetzen"],"Generic tags":["Allgemeine Tags"],"Pixel":["Pixel"],"Em":["Em"],"Select Units":["Einheiten ausw\u00e4hlen"],"%s units":["%s Einheiten"],"Margin":["Marge"],"Attributes":["Attribute"],"Input Pattern":["Eingabemuster"],"None":["Keine"],"(###) ###-####":["(###) ###-####"],"(##) ####-####":["(##) ####-####"],"27\/08\/2024":["27.08.2024"],"23:59:59":["23:59:59"],"27\/08\/2024 23:59:59":["27.08.2024 23:59:59"],"Custom":["Benutzerdefiniert"],"Custom Mask":["Benutzerdefinierte Maske"],"Please check the documentation to manage custom input pattern ":["Bitte \u00fcberpr\u00fcfen Sie die Dokumentation, um das benutzerdefinierte Eingabemuster zu verwalten"],"here":["hier"],"Default Value":["Standardwert"],"Error Message":["Fehlermeldung"],"Help Text":["Hilfetext"],"Number Format":["Zahlenformat"],"US Style (Eg: 9,999.99)":["US-Stil (z. B.: 9.999,99)"],"EU Style (Eg: 9.999,99)":["EU-Stil (z. B.: 9.999,99)"],"Minimum Value":["Mindestwert"],"Maximum Value":["Maximalwert"],"Please check the Minimum and Maximum value":["Bitte \u00fcberpr\u00fcfen Sie den Mindest- und H\u00f6chstwert"],"Enable Email Confirmation":["E-Mail-Best\u00e4tigung aktivieren"],"Checked by Default":["Standardm\u00e4\u00dfig aktiviert"],"Error message":["Fehlermeldung"],"Checked by default":["Standardm\u00e4\u00dfig ausgew\u00e4hlt"],"Please add a option props to MultiButtonsControl":["Bitte f\u00fcgen Sie eine Option props zu MultiButtonsControl hinzu"],"Icon Library":["Icon-Bibliothek"],"Close":["Schlie\u00dfen"],"All Icons":["Alle Symbole"],"Other":["Andere"],"No Icons Found":["Keine Symbole gefunden"],"Insert Icon":["Symbol einf\u00fcgen"],"Change Icon":["Symbol \u00e4ndern"],"Choose Icon":["Symbol ausw\u00e4hlen"],"Confirm":["Best\u00e4tigen"],"Cancel":["Abbrechen"],"Processing\u2026":["Verarbeitung\u2026"],"Select Video":["Video ausw\u00e4hlen"],"Change Video":["Video \u00e4ndern"],"Select Lottie Animation":["Lottie-Animation ausw\u00e4hlen"],"Change Lottie Animation":["Lottie-Animation \u00e4ndern"],"Upload SVG":["SVG hochladen"],"Change SVG":["SVG \u00e4ndern"],"Select Image":["Bild ausw\u00e4hlen"],"Change Image":["Bild \u00e4ndern"],"Upload SVG?":["SVG hochladen?"],"Upload SVG can be potentially risky. Are you sure?":["Das Hochladen von SVG kann potenziell riskant sein. Bist du sicher?"],"Upload Anyway":["Trotzdem hochladen"],"Bulk Add":["Massenhinzuf\u00fcgen"],"Bulk Add Options":["Optionen in gro\u00dfen Mengen hinzuf\u00fcgen"],"Enter each option on a new line.":["Geben Sie jede Option in einer neuen Zeile ein."],"Insert Options":["Optionen einf\u00fcgen"],"Full Width":["Volle Breite"],"Option Type":["Optionstyp"],"Edit Options":["Optionen bearbeiten"],"Add New Option":["Neue Option hinzuf\u00fcgen"],"ADD":["HINZUF\u00dcGEN"],"Enable Auto Country Detection":["Automatische L\u00e4nderdetektion aktivieren"],"%s Width":["%s Breite"],"Upgrade":["Aktualisieren"],"Clear":["Klar"],"Select Color":["Farbe ausw\u00e4hlen"],"Primary Color":["Prim\u00e4rfarbe"],"Text Color":["Textfarbe"],"Field Spacing":["Feldabstand"],"Small":["Klein"],"Large":["Gro\u00df"],"Left":["Links"],"Center":["Zentrum"],"Right":["Richtig"],"Color":["Farbe"],"Background Color":["Hintergrundfarbe"],"Auto":["Auto"],"Default":["Standard"],"Normal":["Normal"],"%":["%"],"Top":["Oben"],"Bottom":["Unten"],"Width":["Breite"],"Size":["Gr\u00f6\u00dfe"],"EM":["EM"],"Padding":["Polsterung"],"Color 1":["Farbe 1"],"Color 2":["Farbe 2"],"Type":["Typ"],"Linear":["Linear"],"Radial":["Radial"],"Location 1":["Standort 1"],"Location 2":["Standort 2"],"Angle":["Winkel"],"Classic":["Klassisch"],"Gradient":["Gradient"],"Horizontal":["Horizontal"],"Vertical":["Vertikal"],"Background":["Hintergrund"],"Cover":["Abdeckung"],"Contain":["Enthalten"],"Layout":["Layout"],"Overlay":["\u00dcberlagerung"],"No Repeat":["Keine Wiederholung"],"Overlay Opacity":["\u00dcberlagerungsdeckkraft"],"Conditional Logic":["Bedingte Logik"],"Upgrade to the SureForms Starter Plan to create dynamic forms that adapt based on user input, offering a personalised and efficient form experience.":["Wechseln Sie zum SureForms Starter-Plan, um dynamische Formulare zu erstellen, die sich basierend auf Benutzereingaben anpassen und ein personalisiertes und effizientes Formularerlebnis bieten."],"Enable Conditional Logic":["Bedingte Logik aktivieren"],"this field if":["dieses Feld, wenn"],"Configure Conditions":["Bedingungen konfigurieren"],"Premium":["Premium"],"Overlay Type":["Overlay-Typ"],"Image Overlay Color":["Bild\u00fcberlagerungsfarbe"],"Image Position":["Bildposition"],"Attachment":["Anhang"],"Fixed":["Fest"],"Blend Mode":["Mischmodus"],"Multiply":["Multiplizieren"],"Screen":["Bildschirm"],"Darken":["Verdunkeln"],"Lighten":["Erleichtern"],"Color Dodge":["Farb-Abwedeln"],"Saturation":["S\u00e4ttigung"],"Repeat-x":["Wiederholen-x"],"Repeat-y":["Wiederhole-y"],"PX":["PX"],"Button":["Schaltfl\u00e4che"],"Prefix Label":["Pr\u00e4fix-Label"],"Suffix Label":["Suffix-Label"],"Border Radius":["Randradius"],"Form Theme":["Formular-Thema"],"Select Gradient":["Gradient ausw\u00e4hlen"],"Unlock Conditional Logic Editor":["Conditional Logic Editor entsperren"],"Rich Text Editor":["Rich-Text-Editor"],"Read Only":["Nur Lesen"],"Select Country":["Land ausw\u00e4hlen"],"Default Country":["Standardland"],"Subscription":["Abonnement"],"One Time":["Einmal"],"Unique Entry":["Einzigartiger Eintrag"],"Maximum Characters":["Maximale Zeichen"],"Textarea Height":["Textbereichsh\u00f6he"],"Minimum Selections":["Mindestanzahl an Auswahlen"],"Maximum Selections":["Maximale Auswahlen"],"Add Numeric Values to Options":["F\u00fcgen Sie numerische Werte zu Optionen hinzu"],"Single Choice Only":["Nur eine Auswahl m\u00f6glich"],"Enable Dropdown Search":["Dropdown-Suche aktivieren"],"Allow Multiple":["Mehrfach erlauben"],"%1$s fields are required. Please configure these fields in the block settings.":["%1$s Felder sind erforderlich. Bitte konfigurieren Sie diese Felder in den Blockeinstellungen."],"%1$s field is required. Please configure this field in the block settings.":["%1$s Feld ist erforderlich. Bitte konfigurieren Sie dieses Feld in den Blockeinstellungen."],"You need to configure a payment account to collect payments from this form. Please configure your payment provider to proceed.":["Sie m\u00fcssen ein Zahlungskonto einrichten, um Zahlungen \u00fcber dieses Formular zu sammeln. Bitte konfigurieren Sie Ihren Zahlungsanbieter, um fortzufahren."],"Configure Payment Account":["Zahlungskonto konfigurieren"],"This is a placeholder for the Payment block. The actual payment fields for your configured payment provider(s) will only appear when you preview or publish the form.":["Dies ist ein Platzhalter f\u00fcr den Zahlungsblock. Die tats\u00e4chlichen Zahlungsfelder f\u00fcr Ihre konfigurierten Zahlungsanbieter werden nur angezeigt, wenn Sie das Formular in der Vorschau anzeigen oder ver\u00f6ffentlichen."],"2 Payments":["2 Zahlungen"],"3 Payments":["3 Zahlungen"],"4 Payments":["4 Zahlungen"],"5 Payments":["5 Zahlungen"],"Never":["Niemals"],"Stop Subscription After":["Abonnement beenden nach"],"Choose when to automatically stop the subscription":["W\u00e4hlen Sie, wann das Abonnement automatisch beendet werden soll"],"Number of Payments":["Anzahl der Zahlungen"],"Enter a number between 1 to 100":["Geben Sie eine Zahl zwischen 1 und 100 ein"],"Form Field":["Formularfeld"],"Payment Type":["Zahlungsart"],"Subscription Plan Name":["Abonnementplanname"],"Billing Interval":["Abrechnungsintervall"],"Daily":["T\u00e4glich"],"Weekly":["W\u00f6chentlich"],"Monthly":["Monatlich"],"Quarterly":["Viertelj\u00e4hrlich"],"Yearly":["J\u00e4hrlich"],"Amount Type":["Betragstyp"],"Fixed Amount":["Fester Betrag"],"Dynamic Amount":["Dynamischer Betrag"],"Choose whether to charge a fixed amount or charge the amount based on user input in other form fields.":["W\u00e4hlen Sie, ob ein fester Betrag berechnet werden soll oder ob der Betrag basierend auf Benutzereingaben in anderen Formularfeldern berechnet werden soll."],"Set the exact amount you want to charge. Users won\u2019t be able to change it":["Legen Sie den genauen Betrag fest, den Sie berechnen m\u00f6chten. Benutzer k\u00f6nnen ihn nicht \u00e4ndern"],"Choose Amount Field":["Betragsfeld ausw\u00e4hlen"],"Select a field\u2026":["W\u00e4hlen Sie ein Feld aus\u2026"],"Pick a field from your form like a number, dropdown, or multichoice whose value should decide the payment amount.":["W\u00e4hlen Sie ein Feld aus Ihrem Formular, wie eine Zahl, ein Dropdown-Men\u00fc oder eine Mehrfachauswahl, dessen Wert den Zahlungsbetrag bestimmen soll."],"Minimum Amount":["Mindestbetrag"],"Set the minimum amount users can enter (0 for no minimum)":["Legen Sie den Mindestbetrag fest, den Benutzer eingeben k\u00f6nnen (0 f\u00fcr kein Minimum)"],"Customer Name Field (Required)":["Kundenname-Feld (erforderlich)"],"Customer Name Field (Optional)":["Kundenname-Feld (Optional)"],"Select the input field that contains the customer name (Required for subscriptions)":["W\u00e4hlen Sie das Eingabefeld aus, das den Kundennamen enth\u00e4lt (Erforderlich f\u00fcr Abonnements)"],"Select the input field that contains the customer name":["W\u00e4hlen Sie das Eingabefeld aus, das den Kundennamen enth\u00e4lt"],"Customer Email Field (Required)":["Kunden-E-Mail-Feld (erforderlich)"],"Select the email field that contains the customer email":["W\u00e4hlen Sie das E-Mail-Feld aus, das die Kunden-E-Mail enth\u00e4lt"],"Payment":["Zahlung"],"%s - Order ID":["%s - Bestell-ID"],"%s - Amount":["%s - Betrag"],"%s - Customer Email":["%s - Kunden-E-Mail"],"%s - Customer Name":["%s - Kundenname"],"%s - Status":["%s - Status"],"Button Alignment":["Schaltfl\u00e4chenanordnung"],"Placeholder":["Platzhalter"],"Preselect this option":["Diese Option vorausw\u00e4hlen"],"Restrict Country Codes":["L\u00e4ndercodes einschr\u00e4nken"],"Restriction Type":["Einschr\u00e4nkungstyp"],"Allow":["Erlauben"],"Block":["Blockieren"],"Select Allowed Countries":["Zul\u00e4ssige L\u00e4nder ausw\u00e4hlen"],"Choose countries\u2026":["L\u00e4nder ausw\u00e4hlen\u2026"],"Choose which country codes users can select in the phone number field. Leave empty to allow all country codes.":["W\u00e4hlen Sie aus, welche L\u00e4ndercodes Benutzer im Telefonnummernfeld ausw\u00e4hlen k\u00f6nnen. Lassen Sie das Feld leer, um alle L\u00e4ndercodes zuzulassen."],"Select Blocked Countries":["Gesperrte L\u00e4nder ausw\u00e4hlen"],"These countries will be hidden from the dropdown.":["Diese L\u00e4nder werden im Dropdown-Men\u00fc ausgeblendet."],"Bulk Edit":["Massenbearbeitung"],"Select Layout":["Layout ausw\u00e4hlen"],"Number of Columns":["Anzahl der Spalten"],"Validation Message for Duplicate":["Validierungsnachricht f\u00fcr Duplikat"],"Click here to insert a form":["Klicken Sie hier, um ein Formular einzuf\u00fcgen"],"Inherit Form's Original Style":["Urspr\u00fcnglichen Stil des Formulars \u00fcbernehmen"],"Text on Primary":["Text auf Prim\u00e4r"],"%s - Description":["%s - Beschreibung"],"Upgrade to Unlock":["Upgrade zum Freischalten"],"Custom (Premium)":["Benutzerdefiniert (Premium)"],"Select a theme style for this form embed.":["W\u00e4hlen Sie einen Themenstil f\u00fcr dieses Formulareinbettung aus."],"Colors":["Farben"],"Advanced Styling":["Erweitertes Styling"],"Unlock Custom Styling":["Benutzerdefinierte Gestaltung freischalten"],"Switch to Custom Mode to take full control of your form's design and spacing.":["Wechseln Sie in den benutzerdefinierten Modus, um die volle Kontrolle \u00fcber das Design und den Abstand Ihres Formulars zu \u00fcbernehmen."],"Full color control (buttons, fields, text)":["Volle Farbkontrolle (Schaltfl\u00e4chen, Felder, Text)"],"Row and column gap control":["Steuerung von Zeilen- und Spaltenabst\u00e4nden"],"Field spacing and layout precision":["Feldabst\u00e4nde und Layoutpr\u00e4zision"],"Complete button styling":["Komplette Schaltfl\u00e4chen-Stilgestaltung"],"Payment Description":["Zahlungsbeschreibung"],"Shown on payment receipts and in your payment dashboard (Stripe and PayPal). Leave blank to use the default.":["Auf Zahlungsbelegen und in Ihrem Zahlungs-Dashboard (Stripe und PayPal) angezeigt. Leer lassen, um den Standard zu verwenden."],"Slug":["Schnecke"],"Auto-generated on save":["Automatisch beim Speichern generiert"],"This slug is already used by another field. It will revert to the previous value.":["Dieser Slug wird bereits von einem anderen Feld verwendet. Er wird auf den vorherigen Wert zur\u00fcckgesetzt."],"Changing the slug may break form submissions, conditional logic, integrations, or any other feature currently referencing this slug. You will need to update all such references manually.":["Das \u00c4ndern des Slugs kann Formular\u00fcbermittlungen, bedingte Logik, Integrationen oder andere Funktionen, die derzeit auf diesen Slug verweisen, beeintr\u00e4chtigen. Sie m\u00fcssen alle derartigen Verweise manuell aktualisieren."],"Field Slug":["Feld-Slug"],"Location Services":["Standortdienste"],"Unlock Address Autocomplete":["Adresse-Autovervollst\u00e4ndigung freischalten"],"Upgrade to enable Google Address Autocomplete with interactive map preview, making address entry faster and more accurate for your users.":["Upgrade, um die Google Address Autocomplete-Funktion mit interaktiver Kartenansicht zu aktivieren, wodurch die Adresseingabe f\u00fcr Ihre Nutzer schneller und genauer wird."],"Enable Google Autocomplete":["Google Autovervollst\u00e4ndigung aktivieren"],"Show Interactive Map":["Interaktive Karte anzeigen"],"Payments Per Page":["Zahlungen pro Seite"],"Show Subscriptions Section":["Abonnement-Bereich anzeigen"],"Show a dedicated subscriptions section above payment history.":["Zeige einen eigenen Abonnementbereich \u00fcber der Zahlungshistorie an."],"Payment Dashboard":["Zahlungs\u00fcbersicht"],"View your payments and manage subscriptions in a single dashboard.":["Sehen Sie Ihre Zahlungen ein und verwalten Sie Abonnements in einem einzigen Dashboard."],"Dynamic Default Value":["Dynamischer Standardwert"]}}} \ No newline at end of file diff --git a/languages/sureforms-de_DE-51635fe6489fc8288d603fe596c755ca.json b/languages/sureforms-de_DE-51635fe6489fc8288d603fe596c755ca.json index 23b9b2a5f..ab2dae3aa 100644 --- a/languages/sureforms-de_DE-51635fe6489fc8288d603fe596c755ca.json +++ b/languages/sureforms-de_DE-51635fe6489fc8288d603fe596c755ca.json @@ -1 +1 @@ -{"translation-revision-date":"2024-12-13T16:14:52+00:00","generator":"WP-CLI\/2.12.0","source":"assets\/build\/settings.js","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","lang":"en","plural-forms":"nplurals=2; plural=(n != 1);"},"Dashboard":["Armaturenbrett"],"Settings":["Einstellungen"],"Entries":["Eintr\u00e4ge"],"Activated":["Aktiviert"],"Activate":["Aktivieren"],"Monday":["Montag"],"Forms":["Formulare"],"GitHub":["GitHub"],"General":["Allgemein"],"Other":["Andere"],"Confirm":["Best\u00e4tigen"],"Cancel":["Abbrechen"],"Install":["Installieren"],"Plugin Installation failed, Please try again later.":["Plugin-Installation fehlgeschlagen, bitte versuchen Sie es sp\u00e4ter erneut."],"Plugin activation failed, Please try again later.":["Plugin-Aktivierung fehlgeschlagen, bitte versuchen Sie es sp\u00e4ter erneut."],"Integrations":["Integrationen"],"What's New?":["Was gibt's Neues?"],"Core":["Kern"],"Unlicensed":["Ohne Lizenz"],"Connecting\u2026":["Verbinden\u2026"],"Install & Activate":["Installieren & Aktivieren"],"Send Email To":["E-Mail senden an"],"Google reCAPTCHA":["Google reCAPTCHA"],"hCaptcha":["hCaptcha"],"reCAPTCHA v2 Invisible":["reCAPTCHA v2 Unsichtbar"],"reCAPTCHA v3":["reCAPTCHA v3"],"Validations":["Validierungen"],"Spam Protection":["Spam-Schutz"],"Email Summaries":["E-Mail-Zusammenfassungen"],"Tuesday":["Dienstag"],"Wednesday":["Mittwoch"],"Thursday":["Donnerstag"],"Friday":["Freitag"],"Saturday":["Samstag"],"Sunday":["Sonntag"],"Test Email":["Test-E-Mail"],"Schedule Reports":["Berichte planen"],"IP Logging":["IP-Protokollierung"],"If this option is turned on, the user's IP address will be saved with the form data":["Wenn diese Option aktiviert ist, wird die IP-Adresse des Benutzers zusammen mit den Formulardaten gespeichert."],"%s represents the minimum selections needed. For example: \u201cMinimum 2 selections are required.\u201d":["%s repr\u00e4sentiert die minimal erforderlichen Auswahlen. Zum Beispiel: \u201eMindestens 2 Auswahlen sind erforderlich.\u201c"],"%s represents the maximum selections allowed. For example: \u201cMaximum 4 selections are allowed.\u201d":["%s repr\u00e4sentiert die maximal erlaubten Auswahlen. Zum Beispiel: \u201eMaximal 4 Auswahlen sind erlaubt.\u201c"],"%s represents the minimum choices needed. For example: \u201cMinimum 1 selection is required.\u201d":["%s repr\u00e4sentiert die minimal erforderlichen Auswahlm\u00f6glichkeiten. Zum Beispiel: \u201eMindestens 1 Auswahl ist erforderlich.\u201c"],"%s represents the maximum choices allowed. For example: \u201cMaximum 3 selections are allowed.\u201d":["%s repr\u00e4sentiert die maximal erlaubten Auswahlm\u00f6glichkeiten. Zum Beispiel: \u201eMaximal 3 Auswahlen sind erlaubt.\u201c"]," Error Message":["Fehlermeldung"],"Auto":["Auto"],"Light":["Licht"],"Dark":["Dunkel"],"Turnstile":["Drehkreuz"],"Honeypot":["Honigtopf"],"Get Keys":["Schl\u00fcssel holen"],"Documentation":["Dokumentation"],"Site Key":["Standortschl\u00fcssel"],"Secret Key":["Geheimer Schl\u00fcssel"],"Cloudflare Turnstile":["Cloudflare-Drehkreuz"],"Appearance Mode":["Erscheinungsmodus"],"Enable Honeypot Security":["Honeypot-Sicherheit aktivieren"],"Enable Honeypot Security for better spam protection":["Aktivieren Sie Honeypot-Sicherheit f\u00fcr besseren Spamschutz"],"This field cannot be left blank.":["Dieses Feld darf nicht leer gelassen werden."],"Confirmation Email Mismatch Message":["Best\u00e4tigungs-E-Mail-Unstimmigkeitsnachricht"],"%s represents the minimum input value. For example: \"Minimum value is 10.\"":["%s repr\u00e4sentiert den minimalen Eingabewert. Zum Beispiel: \"Der Mindestwert ist 10.\""],"%s represents the maximum input value. For example: \"Maximum value is 100.\"":["%s repr\u00e4sentiert den maximalen Eingabewert. Zum Beispiel: \"Der Maximalwert ist 100.\""],"OttoKit":["OttoKit"],"Connect with OttoKit":["Mit OttoKit verbinden"],"reCAPTCHA":["reCAPTCHA"],"Ready to go beyond free plan?":["Bereit, \u00fcber den kostenlosen Plan hinauszugehen?"],"Upgrade now":["Jetzt upgraden"],"and unlock the full power of SureForms!":["und die volle Kraft von SureForms freischalten!"],"Upgrade SureForms":["SureForms aktualisieren"],"Upgrade Now":["Jetzt upgraden"],"Form Validation":["Formularvalidierung"],"Required Error Messages":["Erforderliche Fehlermeldungen"],"Other Error Messages":["Andere Fehlermeldungen"],"Input Field Unique":["Eingabefeld eindeutig"],"Email Field Unique":["E-Mail-Feld eindeutig"],"Invalid URL":["Ung\u00fcltige URL"],"Phone Field Unique":["Telefonfeld eindeutig"],"Invalid Field Number Block":["Ung\u00fcltiger Feldnummernblock"],"Invalid Email":["Ung\u00fcltige E-Mail"],"Number Minimum Value":["Zahlen-Mindestwert"],"Number Maximum Value":["Zahlen Maximalwert"],"Dropdown Minimum Selections":["Dropdown Minimale Auswahlen"],"Dropdown Maximum Selections":["Dropdown Maximale Auswahlen"],"Multiple Choice Minimum Selections":["Mehrfachauswahl Mindestanzahl der Auswahlen"],"Multiple Choice Maximum Selections":["Mehrfachauswahl Maximale Auswahlm\u00f6glichkeiten"],"Input Field":["Eingabefeld"],"Email Field":["E-Mail-Feld"],"URL Field":["URL-Feld"],"Phone Field":["Telefonfeld"],"Textarea Field":["Textbereichsfeld"],"Checkbox Field":["Kontrollk\u00e4stchenfeld"],"Dropdown Field":["Dropdown-Feld"],"Multiple Choice Field":["Mehrfachauswahlfeld"],"Address Field":["Adressfeld"],"Number Field":["Zahlenfeld"],"reCAPTCHA v2":["reCAPTCHA v2"],"To enable reCAPTCHA feature on your SureForms Please enable reCAPTCHA option on your blocks setting and select version. Add google reCAPTCHA secret and site key here. reCAPTCHA will be added to your page on front-end.":["Um die reCAPTCHA-Funktion in Ihren SureForms zu aktivieren, aktivieren Sie bitte die reCAPTCHA-Option in Ihren Blockeinstellungen und w\u00e4hlen Sie die Version aus. F\u00fcgen Sie hier den Google reCAPTCHA Secret und den Site Key hinzu. reCAPTCHA wird auf der Vorderseite Ihrer Seite hinzugef\u00fcgt."],"Enter your %s here":["Geben Sie hier Ihr %s ein"],"To enable hCAPTCHA, please add your site key and secret key. Configure these settings within the individual form.":["Um hCAPTCHA zu aktivieren, f\u00fcgen Sie bitte Ihren Site-Schl\u00fcssel und Geheimschl\u00fcssel hinzu. Konfigurieren Sie diese Einstellungen innerhalb des einzelnen Formulars."],"To enable Cloudflare Turnstile, please add your site key and secret key. Configure these settings within the individual form.":["Um Cloudflare Turnstile zu aktivieren, f\u00fcgen Sie bitte Ihren Site-Schl\u00fcssel und Geheimschl\u00fcssel hinzu. Konfigurieren Sie diese Einstellungen innerhalb des einzelnen Formulars."],"Save":["Speichern"],"Anonymous Analytics":["Anonyme Analysen"],"Learn More":["Mehr erfahren"],"Admin Notification":["Administratorbenachrichtigung"],"Enable Admin Notification":["Admin-Benachrichtigung aktivieren"],"Admin notifications keep you informed about new form entries since your last visit.":["Admin-Benachrichtigungen halten Sie \u00fcber neue Formulareintr\u00e4ge seit Ihrem letzten Besuch auf dem Laufenden."],"Continue":["Fortfahren"],"Get Started":["Loslegen"],"Integration":["Integration"],"Connect Native Integrations with SureForms":["Native Integrationen mit SureForms verbinden"],"Unlock powerful integrations in the Premium plan to automate your workflows and connect SureForms directly with your favourite tools.":["Schalten Sie leistungsstarke Integrationen im Premium-Plan frei, um Ihre Arbeitsabl\u00e4ufe zu automatisieren und SureForms direkt mit Ihren Lieblingstools zu verbinden."],"Send form submissions straight to CRMs, email, and marketing platforms":["Senden Sie Formulareinsendungen direkt an CRMs, E-Mail- und Marketingplattformen"],"Automate repetitive tasks with seamless data syncing":["Automatisieren Sie repetitive Aufgaben mit nahtloser Datensynchronisierung"],"Access exclusive native integrations for faster workflows":["Zugriff auf exklusive native Integrationen f\u00fcr schnellere Arbeitsabl\u00e4ufe"],"Payments":["Zahlungen"],"Stripe account disconnected successfully.":["Stripe-Konto erfolgreich getrennt."],"Failed to create webhook.":["Fehler beim Erstellen des Webhooks."],"Failed to connect to Stripe.":["Verbindung zu Stripe fehlgeschlagen."],"Webhook":["Webhook"],"Knowledge Base":["Wissensdatenbank"],"What\u2019s New":["Was gibt's Neues"],"delete":["l\u00f6schen"],"Please type \"%s\" in the input box":["Bitte geben Sie \"%s\" in das Eingabefeld ein"],"To confirm, type \"%s\" in the box below:":["Um zu best\u00e4tigen, geben Sie \"%s\" in das Feld unten ein:"],"Type \"%s\"":["Geben Sie \"%s\" ein"],"Go to OttoKit Settings":["Gehe zu den OttoKit-Einstellungen"],"USD - US Dollar":["USD - US-Dollar"],"Payment Mode":["Zahlungsart"],"Test Mode":["Testmodus"],"Live Mode":["Live-Modus"],"General Settings":["Allgemeine Einstellungen"],"Set up email summaries, admin alerts, and data preferences to manage your forms with ease.":["Richten Sie E-Mail-Zusammenfassungen, Admin-Benachrichtigungen und Datenpr\u00e4ferenzen ein, um Ihre Formulare m\u00fchelos zu verwalten."],"Customize default error messages shown when users submit invalid or incomplete form entries.":["Passen Sie die Standardfehlermeldungen an, die angezeigt werden, wenn Benutzer ung\u00fcltige oder unvollst\u00e4ndige Formulareintr\u00e4ge \u00fcbermitteln."],"Enable spam protection for your forms using CAPTCHA services or honeypot security.":["Aktivieren Sie den Spam-Schutz f\u00fcr Ihre Formulare mithilfe von CAPTCHA-Diensten oder Honeypot-Sicherheit."],"Connect and manage your payment gateways to securely accept transactions through your forms.":["Verbinden und verwalten Sie Ihre Zahlungsgateways, um Transaktionen sicher \u00fcber Ihre Formulare zu akzeptieren."],"1% transaction and payment gateway fees apply.":["1% Transaktions- und Zahlungsgateway-Geb\u00fchren fallen an."],"2.9% transaction and payment gateway fees apply. Activate license to reduce transaction fees.":["2,9 % Transaktions- und Zahlungsgateway-Geb\u00fchren fallen an. Aktivieren Sie die Lizenz, um die Transaktionsgeb\u00fchren zu reduzieren."],"2.9% transaction and payment gateway fees apply.":["Es fallen 2,9 % Transaktions- und Zahlungs-Gateway-Geb\u00fchren an."],"Please visit %1$s, delete an unused webhook, then click below to retry.":["Bitte besuchen Sie %1$s, l\u00f6schen Sie einen ungenutzten Webhook und klicken Sie dann unten, um es erneut zu versuchen."],"SureForms could not create a webhook because your Stripe account has run out of free slots. Webhooks are needed to receive updates about payments.":["SureForms konnte keinen Webhook erstellen, da Ihr Stripe-Konto keine freien Slots mehr hat. Webhooks sind erforderlich, um Updates zu Zahlungen zu erhalten."],"Stripe Dashboard":["Stripe-Dashboard"],"Creating\u2026":["Erstellen\u2026"],"Create Webhook":["Webhook erstellen"],"Successfully connected to Stripe!":["Erfolgreich mit Stripe verbunden!"],"Invalid response from server. Please try again.":["Ung\u00fcltige Antwort vom Server. Bitte versuchen Sie es erneut."],"Failed to disconnect Stripe account.":["Trennen des Stripe-Kontos fehlgeschlagen."],"Webhook created successfully!":["Webhook erfolgreich erstellt!"],"Select Currency":["W\u00e4hrung ausw\u00e4hlen"],"Select the default currency for payment forms.":["W\u00e4hlen Sie die Standardw\u00e4hrung f\u00fcr Zahlungsformulare aus."],"Connection Status":["Verbindungsstatus"],"Disconnect Stripe Account":["Stripe-Konto trennen"],"Are you sure you want to disconnect your Stripe account? This will stop all active payments, subscriptions, and form transactions connected to this account.":["Sind Sie sicher, dass Sie Ihr Stripe-Konto trennen m\u00f6chten? Dadurch werden alle aktiven Zahlungen, Abonnements und Formulartransaktionen, die mit diesem Konto verbunden sind, gestoppt."],"Disconnect":["Trennen"],"Disconnecting\u2026":["Trennen\u2026"],"Webhook successfully connected, all Stripe events are being tracked.":["Webhook erfolgreich verbunden, alle Stripe-Ereignisse werden verfolgt."],"Connect your Stripe account to start accepting payments through your forms.":["Verbinden Sie Ihr Stripe-Konto, um Zahlungen \u00fcber Ihre Formulare zu akzeptieren."],"Connect to Stripe":["Mit Stripe verbinden"],"Securely connect to Stripe with just a few clicks to begin accepting payments! ":["Verbinden Sie sich sicher mit Stripe, um mit nur wenigen Klicks Zahlungen zu akzeptieren!"],"Payment Methods":["Zahlungsmethoden"],"Test mode allows you to process payments without real charges. Switch to Live mode for actual transactions.":["Der Testmodus erm\u00f6glicht es Ihnen, Zahlungen ohne echte Belastungen zu verarbeiten. Wechseln Sie in den Live-Modus f\u00fcr tats\u00e4chliche Transaktionen."],"General Payment Settings":["Allgemeine Zahlungseinstellungen"],"These settings apply to all payment gateways.":["Diese Einstellungen gelten f\u00fcr alle Zahlungs-Gateways."],"Stripe Settings":["Stripe-Einstellungen"],"Left ($100)":["Links ($100)"],"Right (100$)":["Richtig (100$)"],"Left Space ($ 100)":["Verbleibender Platz ($ 100)"],"Right Space (100 $)":["Rechter Raum (100 $)"],"Currency Sign Position":["Position des W\u00e4hrungszeichens"],"Select the position of the currency symbol relative to the amount.":["W\u00e4hlen Sie die Position des W\u00e4hrungssymbols relativ zum Betrag aus."],"Learn":["Lernen"],"Enable email summaries":["E-Mail-Zusammenfassungen aktivieren"],"Enable IP logging":["IP-Protokollierung aktivieren"],"Turn on Admin Notification from here.":["Aktivieren Sie hier die Admin-Benachrichtigung."],"Send entries to 100+ popular apps.":["Eintr\u00e4ge an \u00fcber 100 beliebte Apps senden."],"Build automated workflows that run instantly.":["Erstellen Sie automatisierte Workflows, die sofort ausgef\u00fchrt werden."],"Create custom app integrations using our Custom App feature.":["Erstellen Sie benutzerdefinierte App-Integrationen mit unserer benutzerdefinierten App-Funktion."],"Keep your tools in sync automatically.":["Halten Sie Ihre Werkzeuge automatisch synchron."],"This will install and activate OttoKit on your WordPress site to enable automation features.":["Dies wird OttoKit auf Ihrer WordPress-Seite installieren und aktivieren, um Automatisierungsfunktionen zu erm\u00f6glichen."],"Automate Your Forms with OttoKit":["Automatisieren Sie Ihre Formulare mit OttoKit"],"Every form submission should trigger something \u2014 a Slack alert, a CRM lead, a follow-up email, or a new row in Google Sheets.":["Jede Formular\u00fcbermittlung sollte etwas ausl\u00f6sen \u2014 eine Slack-Benachrichtigung, einen CRM-Lead, eine Follow-up-E-Mail oder eine neue Zeile in Google Sheets."],"MCP":["MCP"],"Configure AI client permissions and MCP server settings.":["Konfigurieren Sie die Berechtigungen des KI-Clients und die Einstellungen des MCP-Servers."],"View documentation":["Dokumentation anzeigen"],"Copy to clipboard":["In die Zwischenablage kopieren"],"Claude Desktop":["Claude Desktop"],"~\/Library\/Application Support\/Claude\/claude_desktop_config.json (macOS) or %APPDATA%\\Claude\\claude_desktop_config.json (Windows)":["~\/Library\/Application Support\/Claude\/claude_desktop_config.json (macOS) oder %APPDATA%\\Claude\\claude_desktop_config.json (Windows)"],"Claude Code":["Claude-Code"],".mcp.json (project) or ~\/.claude.json (global)":[".mcp.json (Projekt) oder ~\/.claude.json (global)"],"Cursor":["Cursor"],"~\/.cursor\/mcp.json":["~\/.cursor\/mcp.json"],"VS Code (Copilot)":["VS Code (Copilot)"],".vscode\/mcp.json (project) or settings.json > mcp.servers (global)":[".vscode\/mcp.json (Projekt) oder settings.json > mcp.servers (global)"],"~\/.continue\/config.yaml or config.json":["~\/.continue\/config.yaml oder config.json"],"Your client's MCP configuration file":["Die MCP-Konfigurationsdatei Ihres Kunden"],"Connect Your AI Client":["Verbinden Sie Ihren KI-Client"],"AI Client":["KI-Client"],"Create an Application Password \u2014 ":["Erstellen Sie ein Anwendungskennwort \u2014"],"Open Application Passwords":["Anwendungspassw\u00f6rter \u00f6ffnen"],"Or use this CLI command to add the server quickly (you will still need to set the environment variables):":["Oder verwenden Sie diesen CLI-Befehl, um den Server schnell hinzuzuf\u00fcgen (Sie m\u00fcssen dennoch die Umgebungsvariablen festlegen):"],"Copy the JSON config below into: ":["Kopiere die JSON-Konfiguration unten in:"],"Replace \"your-application-password\" with the password from Step 1.":["Ersetzen Sie \"your-application-password\" durch das Passwort aus Schritt 1."],"WP_API_URL \u2014 your site's MCP endpoint. WP_API_USERNAME \u2014 your WordPress username. WP_API_PASSWORD \u2014 the application password you generated.":["WP_API_URL \u2014 der MCP-Endpunkt Ihrer Website. WP_API_USERNAME \u2014 Ihr WordPress-Benutzername. WP_API_PASSWORD \u2014 das Anwendungskennwort, das Sie erstellt haben."],"View setup docs":["Einrichtungsdokumente anzeigen"],"The MCP Adapter plugin is installed but not active. Activate it to configure MCP settings.":["Das MCP Adapter-Plugin ist installiert, aber nicht aktiv. Aktivieren Sie es, um die MCP-Einstellungen zu konfigurieren."],"The MCP Adapter plugin is required to connect AI clients to your forms. Download and install it from GitHub, then activate it.":["Das MCP Adapter-Plugin ist erforderlich, um AI-Clients mit Ihren Formularen zu verbinden. Laden Sie es von GitHub herunter, installieren Sie es und aktivieren Sie es dann."],"Download the latest release from":["Laden Sie die neueste Version herunter von"],"Install the plugin via Plugins > Add New Plugin > Upload Plugin.":["Installieren Sie das Plugin \u00fcber Plugins > Neues Plugin hinzuf\u00fcgen > Plugin hochladen."],"Activate the MCP Adapter plugin.":["Aktivieren Sie das MCP Adapter-Plugin."],"Activating\u2026":["Aktivierung\u2026"],"Activate MCP Adapter":["MCP-Adapter aktivieren"],"Download MCP Adapter":["MCP-Adapter herunterladen"],"Experimental":["Experimentell"],"Enable Abilities":["F\u00e4higkeiten aktivieren"],"Register SureForms abilities with the WordPress Abilities API. When enabled, AI clients can list, read, create, edit, and delete your forms and entries. When disabled, no abilities are registered and AI clients cannot perform any actions on your forms.":["Registriere die F\u00e4higkeiten von SureForms mit der WordPress Abilities API. Wenn aktiviert, k\u00f6nnen KI-Clients Ihre Formulare und Eintr\u00e4ge auflisten, lesen, erstellen, bearbeiten und l\u00f6schen. Wenn deaktiviert, werden keine F\u00e4higkeiten registriert und KI-Clients k\u00f6nnen keine Aktionen an Ihren Formularen durchf\u00fchren."],"Abilities API \u2014 Edit":["F\u00e4higkeiten-API \u2014 Bearbeiten"],"Enable Edit Abilities":["Bearbeitungsf\u00e4higkeiten aktivieren"],"When enabled, AI clients can create new forms, update form titles, fields, and settings, duplicate forms, and modify entry statuses. When disabled, these abilities are unregistered and AI clients can only read your data.":["Wenn aktiviert, k\u00f6nnen KI-Clients neue Formulare erstellen, Formulartitel, Felder und Einstellungen aktualisieren, Formulare duplizieren und Eintragsstatus \u00e4ndern. Wenn deaktiviert, werden diese F\u00e4higkeiten abgemeldet und KI-Clients k\u00f6nnen nur Ihre Daten lesen."],"Abilities API \u2014 Delete":["F\u00e4higkeiten-API \u2014 L\u00f6schen"],"Enable Delete Abilities":["L\u00f6schf\u00e4higkeiten aktivieren"],"When enabled, AI clients can permanently delete forms and entries. Deleted data cannot be recovered. When disabled, delete abilities are unregistered and AI clients cannot remove any data.":["Wenn aktiviert, k\u00f6nnen KI-Clients Formulare und Eintr\u00e4ge dauerhaft l\u00f6schen. Gel\u00f6schte Daten k\u00f6nnen nicht wiederhergestellt werden. Wenn deaktiviert, werden L\u00f6schf\u00e4higkeiten abgemeldet und KI-Clients k\u00f6nnen keine Daten entfernen."],"MCP Server":["MCP-Server"],"Enable MCP Server":["MCP-Server aktivieren"],"Creates a dedicated SureForms MCP endpoint that AI clients like Claude can connect to. When disabled, the endpoint is removed and external AI clients cannot discover or call any SureForms abilities.":["Erstellt einen dedizierten SureForms MCP-Endpunkt, mit dem sich KI-Clients wie Claude verbinden k\u00f6nnen. Wenn er deaktiviert ist, wird der Endpunkt entfernt und externe KI-Clients k\u00f6nnen keine SureForms-Funktionen entdecken oder aufrufen."],"Learn more":["Mehr erfahren"],"MCP Adapter Required":["MCP-Adapter erforderlich"],"Google Maps":["Google Maps"],"Configure Google Maps API key for address autocomplete and map preview.":["Konfigurieren Sie den Google Maps API-Schl\u00fcssel f\u00fcr die Adressvervollst\u00e4ndigung und die Kartenansichtsvorschau."],"Help shape the future of SureForms":["Helfen Sie mit, die Zukunft von SureForms zu gestalten"],"Share how you use the plugin so we can build features that matter, fix issues faster, and make smarter decisions. ":["Teilen Sie uns mit, wie Sie das Plugin verwenden, damit wir Funktionen entwickeln k\u00f6nnen, die wichtig sind, Probleme schneller beheben und kl\u00fcgere Entscheidungen treffen k\u00f6nnen. "],"Enable Google Address Autocomplete":["Google-Adress-Autovervollst\u00e4ndigung aktivieren"],"Upgrade to the SureForms Business Plan to add Google-powered address autocomplete with interactive map preview to your forms.":["Upgrade auf den SureForms Business-Plan, um Google-gest\u00fctzte Adressvervollst\u00e4ndigung mit interaktiver Kartenansicht zu Ihren Formularen hinzuzuf\u00fcgen."],"Auto-suggest addresses as users type for faster, error-free submissions":["Adressen automatisch vorschlagen, w\u00e4hrend Benutzer tippen, f\u00fcr schnellere und fehlerfreie Eingaben"],"Show an interactive map preview with draggable pin for precise locations":["Zeige eine interaktive Kartenansicht mit verschiebbarem Pin f\u00fcr pr\u00e4zise Standorte"],"Automatically populate address fields like city, state, and postal code":["Adressfelder wie Stadt, Bundesland und Postleitzahl automatisch ausf\u00fcllen"]}}} \ No newline at end of file +{"translation-revision-date":"2024-12-13T16:14:52+00:00","generator":"WP-CLI\/2.12.0","source":"assets\/build\/settings.js","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","lang":"en","plural-forms":"nplurals=2; plural=(n != 1);"},"Dashboard":["Armaturenbrett"],"Settings":["Einstellungen"],"Entries":["Eintr\u00e4ge"],"Activated":["Aktiviert"],"Activate":["Aktivieren"],"Monday":["Montag"],"Forms":["Formulare"],"GitHub":["GitHub"],"General":["Allgemein"],"Other":["Andere"],"Confirm":["Best\u00e4tigen"],"Cancel":["Abbrechen"],"Install":["Installieren"],"Plugin Installation failed, Please try again later.":["Plugin-Installation fehlgeschlagen, bitte versuchen Sie es sp\u00e4ter erneut."],"Plugin activation failed, Please try again later.":["Plugin-Aktivierung fehlgeschlagen, bitte versuchen Sie es sp\u00e4ter erneut."],"Integrations":["Integrationen"],"What's New?":["Was gibt's Neues?"],"Core":["Kern"],"Unlicensed":["Ohne Lizenz"],"Connecting\u2026":["Verbinden\u2026"],"Install & Activate":["Installieren & Aktivieren"],"Send Email To":["E-Mail senden an"],"Google reCAPTCHA":["Google reCAPTCHA"],"hCaptcha":["hCaptcha"],"reCAPTCHA v2 Invisible":["reCAPTCHA v2 Unsichtbar"],"reCAPTCHA v3":["reCAPTCHA v3"],"Validations":["Validierungen"],"Spam Protection":["Spam-Schutz"],"Email Summaries":["E-Mail-Zusammenfassungen"],"Tuesday":["Dienstag"],"Wednesday":["Mittwoch"],"Thursday":["Donnerstag"],"Friday":["Freitag"],"Saturday":["Samstag"],"Sunday":["Sonntag"],"Test Email":["Test-E-Mail"],"Schedule Reports":["Berichte planen"],"IP Logging":["IP-Protokollierung"],"If this option is turned on, the user's IP address will be saved with the form data":["Wenn diese Option aktiviert ist, wird die IP-Adresse des Benutzers zusammen mit den Formulardaten gespeichert."],"%s represents the minimum selections needed. For example: \u201cMinimum 2 selections are required.\u201d":["%s repr\u00e4sentiert die minimal erforderlichen Auswahlen. Zum Beispiel: \u201eMindestens 2 Auswahlen sind erforderlich.\u201c"],"%s represents the maximum selections allowed. For example: \u201cMaximum 4 selections are allowed.\u201d":["%s repr\u00e4sentiert die maximal erlaubten Auswahlen. Zum Beispiel: \u201eMaximal 4 Auswahlen sind erlaubt.\u201c"],"%s represents the minimum choices needed. For example: \u201cMinimum 1 selection is required.\u201d":["%s repr\u00e4sentiert die minimal erforderlichen Auswahlm\u00f6glichkeiten. Zum Beispiel: \u201eMindestens 1 Auswahl ist erforderlich.\u201c"],"%s represents the maximum choices allowed. For example: \u201cMaximum 3 selections are allowed.\u201d":["%s repr\u00e4sentiert die maximal erlaubten Auswahlm\u00f6glichkeiten. Zum Beispiel: \u201eMaximal 3 Auswahlen sind erlaubt.\u201c"]," Error Message":["Fehlermeldung"],"Auto":["Auto"],"Light":["Licht"],"Dark":["Dunkel"],"Turnstile":["Drehkreuz"],"Honeypot":["Honigtopf"],"Get Keys":["Schl\u00fcssel holen"],"Documentation":["Dokumentation"],"Site Key":["Standortschl\u00fcssel"],"Secret Key":["Geheimer Schl\u00fcssel"],"Cloudflare Turnstile":["Cloudflare-Drehkreuz"],"Appearance Mode":["Erscheinungsmodus"],"Enable Honeypot Security":["Honeypot-Sicherheit aktivieren"],"Enable Honeypot Security for better spam protection":["Aktivieren Sie Honeypot-Sicherheit f\u00fcr besseren Spamschutz"],"This field cannot be left blank.":["Dieses Feld darf nicht leer gelassen werden."],"Confirmation Email Mismatch Message":["Best\u00e4tigungs-E-Mail-Unstimmigkeitsnachricht"],"%s represents the minimum input value. For example: \"Minimum value is 10.\"":["%s repr\u00e4sentiert den minimalen Eingabewert. Zum Beispiel: \"Der Mindestwert ist 10.\""],"%s represents the maximum input value. For example: \"Maximum value is 100.\"":["%s repr\u00e4sentiert den maximalen Eingabewert. Zum Beispiel: \"Der Maximalwert ist 100.\""],"OttoKit":["OttoKit"],"Connect with OttoKit":["Mit OttoKit verbinden"],"reCAPTCHA":["reCAPTCHA"],"Ready to go beyond free plan?":["Bereit, \u00fcber den kostenlosen Plan hinauszugehen?"],"Upgrade now":["Jetzt upgraden"],"and unlock the full power of SureForms!":["und die volle Kraft von SureForms freischalten!"],"Upgrade SureForms":["SureForms aktualisieren"],"Upgrade Now":["Jetzt upgraden"],"Form Validation":["Formularvalidierung"],"Required Error Messages":["Erforderliche Fehlermeldungen"],"Other Error Messages":["Andere Fehlermeldungen"],"Input Field Unique":["Eingabefeld eindeutig"],"Email Field Unique":["E-Mail-Feld eindeutig"],"Invalid URL":["Ung\u00fcltige URL"],"Phone Field Unique":["Telefonfeld eindeutig"],"Invalid Field Number Block":["Ung\u00fcltiger Feldnummernblock"],"Invalid Email":["Ung\u00fcltige E-Mail"],"Number Minimum Value":["Zahlen-Mindestwert"],"Number Maximum Value":["Zahlen Maximalwert"],"Dropdown Minimum Selections":["Dropdown Minimale Auswahlen"],"Dropdown Maximum Selections":["Dropdown Maximale Auswahlen"],"Multiple Choice Minimum Selections":["Mehrfachauswahl Mindestanzahl der Auswahlen"],"Multiple Choice Maximum Selections":["Mehrfachauswahl Maximale Auswahlm\u00f6glichkeiten"],"Input Field":["Eingabefeld"],"Email Field":["E-Mail-Feld"],"URL Field":["URL-Feld"],"Phone Field":["Telefonfeld"],"Textarea Field":["Textbereichsfeld"],"Checkbox Field":["Kontrollk\u00e4stchenfeld"],"Dropdown Field":["Dropdown-Feld"],"Multiple Choice Field":["Mehrfachauswahlfeld"],"Address Field":["Adressfeld"],"Number Field":["Zahlenfeld"],"reCAPTCHA v2":["reCAPTCHA v2"],"To enable reCAPTCHA feature on your SureForms Please enable reCAPTCHA option on your blocks setting and select version. Add google reCAPTCHA secret and site key here. reCAPTCHA will be added to your page on front-end.":["Um die reCAPTCHA-Funktion in Ihren SureForms zu aktivieren, aktivieren Sie bitte die reCAPTCHA-Option in Ihren Blockeinstellungen und w\u00e4hlen Sie die Version aus. F\u00fcgen Sie hier den Google reCAPTCHA Secret und den Site Key hinzu. reCAPTCHA wird auf der Vorderseite Ihrer Seite hinzugef\u00fcgt."],"Enter your %s here":["Geben Sie hier Ihr %s ein"],"To enable hCAPTCHA, please add your site key and secret key. Configure these settings within the individual form.":["Um hCAPTCHA zu aktivieren, f\u00fcgen Sie bitte Ihren Site-Schl\u00fcssel und Geheimschl\u00fcssel hinzu. Konfigurieren Sie diese Einstellungen innerhalb des einzelnen Formulars."],"To enable Cloudflare Turnstile, please add your site key and secret key. Configure these settings within the individual form.":["Um Cloudflare Turnstile zu aktivieren, f\u00fcgen Sie bitte Ihren Site-Schl\u00fcssel und Geheimschl\u00fcssel hinzu. Konfigurieren Sie diese Einstellungen innerhalb des einzelnen Formulars."],"Save":["Speichern"],"Anonymous Analytics":["Anonyme Analysen"],"Learn More":["Mehr erfahren"],"Admin Notification":["Administratorbenachrichtigung"],"Enable Admin Notification":["Admin-Benachrichtigung aktivieren"],"Admin notifications keep you informed about new form entries since your last visit.":["Admin-Benachrichtigungen halten Sie \u00fcber neue Formulareintr\u00e4ge seit Ihrem letzten Besuch auf dem Laufenden."],"Continue":["Fortfahren"],"Get Started":["Loslegen"],"Integration":["Integration"],"Connect Native Integrations with SureForms":["Native Integrationen mit SureForms verbinden"],"Unlock powerful integrations in the Premium plan to automate your workflows and connect SureForms directly with your favourite tools.":["Schalten Sie leistungsstarke Integrationen im Premium-Plan frei, um Ihre Arbeitsabl\u00e4ufe zu automatisieren und SureForms direkt mit Ihren Lieblingstools zu verbinden."],"Send form submissions straight to CRMs, email, and marketing platforms":["Senden Sie Formulareinsendungen direkt an CRMs, E-Mail- und Marketingplattformen"],"Automate repetitive tasks with seamless data syncing":["Automatisieren Sie repetitive Aufgaben mit nahtloser Datensynchronisierung"],"Access exclusive native integrations for faster workflows":["Zugriff auf exklusive native Integrationen f\u00fcr schnellere Arbeitsabl\u00e4ufe"],"Payments":["Zahlungen"],"Stripe account disconnected successfully.":["Stripe-Konto erfolgreich getrennt."],"Failed to create webhook.":["Fehler beim Erstellen des Webhooks."],"Failed to connect to Stripe.":["Verbindung zu Stripe fehlgeschlagen."],"Webhook":["Webhook"],"Knowledge Base":["Wissensdatenbank"],"What\u2019s New":["Was gibt's Neues"],"delete":["l\u00f6schen"],"Please type \"%s\" in the input box":["Bitte geben Sie \"%s\" in das Eingabefeld ein"],"To confirm, type \"%s\" in the box below:":["Um zu best\u00e4tigen, geben Sie \"%s\" in das Feld unten ein:"],"Type \"%s\"":["Geben Sie \"%s\" ein"],"Go to OttoKit Settings":["Gehe zu den OttoKit-Einstellungen"],"USD - US Dollar":["USD - US-Dollar"],"Payment Mode":["Zahlungsart"],"Test Mode":["Testmodus"],"Live Mode":["Live-Modus"],"General Settings":["Allgemeine Einstellungen"],"Set up email summaries, admin alerts, and data preferences to manage your forms with ease.":["Richten Sie E-Mail-Zusammenfassungen, Admin-Benachrichtigungen und Datenpr\u00e4ferenzen ein, um Ihre Formulare m\u00fchelos zu verwalten."],"Customize default error messages shown when users submit invalid or incomplete form entries.":["Passen Sie die Standardfehlermeldungen an, die angezeigt werden, wenn Benutzer ung\u00fcltige oder unvollst\u00e4ndige Formulareintr\u00e4ge \u00fcbermitteln."],"Enable spam protection for your forms using CAPTCHA services or honeypot security.":["Aktivieren Sie den Spam-Schutz f\u00fcr Ihre Formulare mithilfe von CAPTCHA-Diensten oder Honeypot-Sicherheit."],"Connect and manage your payment gateways to securely accept transactions through your forms.":["Verbinden und verwalten Sie Ihre Zahlungsgateways, um Transaktionen sicher \u00fcber Ihre Formulare zu akzeptieren."],"1% transaction and payment gateway fees apply.":["1% Transaktions- und Zahlungsgateway-Geb\u00fchren fallen an."],"2.9% transaction and payment gateway fees apply. Activate license to reduce transaction fees.":["2,9 % Transaktions- und Zahlungsgateway-Geb\u00fchren fallen an. Aktivieren Sie die Lizenz, um die Transaktionsgeb\u00fchren zu reduzieren."],"2.9% transaction and payment gateway fees apply.":["Es fallen 2,9 % Transaktions- und Zahlungs-Gateway-Geb\u00fchren an."],"Please visit %1$s, delete an unused webhook, then click below to retry.":["Bitte besuchen Sie %1$s, l\u00f6schen Sie einen ungenutzten Webhook und klicken Sie dann unten, um es erneut zu versuchen."],"SureForms could not create a webhook because your Stripe account has run out of free slots. Webhooks are needed to receive updates about payments.":["SureForms konnte keinen Webhook erstellen, da Ihr Stripe-Konto keine freien Slots mehr hat. Webhooks sind erforderlich, um Updates zu Zahlungen zu erhalten."],"Stripe Dashboard":["Stripe-Dashboard"],"Creating\u2026":["Erstellen\u2026"],"Create Webhook":["Webhook erstellen"],"Successfully connected to Stripe!":["Erfolgreich mit Stripe verbunden!"],"Invalid response from server. Please try again.":["Ung\u00fcltige Antwort vom Server. Bitte versuchen Sie es erneut."],"Failed to disconnect Stripe account.":["Trennen des Stripe-Kontos fehlgeschlagen."],"Webhook created successfully!":["Webhook erfolgreich erstellt!"],"Select Currency":["W\u00e4hrung ausw\u00e4hlen"],"Select the default currency for payment forms.":["W\u00e4hlen Sie die Standardw\u00e4hrung f\u00fcr Zahlungsformulare aus."],"Connection Status":["Verbindungsstatus"],"Disconnect Stripe Account":["Stripe-Konto trennen"],"Are you sure you want to disconnect your Stripe account? This will stop all active payments, subscriptions, and form transactions connected to this account.":["Sind Sie sicher, dass Sie Ihr Stripe-Konto trennen m\u00f6chten? Dadurch werden alle aktiven Zahlungen, Abonnements und Formulartransaktionen, die mit diesem Konto verbunden sind, gestoppt."],"Disconnect":["Trennen"],"Disconnecting\u2026":["Trennen\u2026"],"Webhook successfully connected, all Stripe events are being tracked.":["Webhook erfolgreich verbunden, alle Stripe-Ereignisse werden verfolgt."],"Connect your Stripe account to start accepting payments through your forms.":["Verbinden Sie Ihr Stripe-Konto, um Zahlungen \u00fcber Ihre Formulare zu akzeptieren."],"Connect to Stripe":["Mit Stripe verbinden"],"Securely connect to Stripe with just a few clicks to begin accepting payments! ":["Verbinden Sie sich sicher mit Stripe, um mit nur wenigen Klicks Zahlungen zu akzeptieren!"],"Payment Methods":["Zahlungsmethoden"],"Test mode allows you to process payments without real charges. Switch to Live mode for actual transactions.":["Der Testmodus erm\u00f6glicht es Ihnen, Zahlungen ohne echte Belastungen zu verarbeiten. Wechseln Sie in den Live-Modus f\u00fcr tats\u00e4chliche Transaktionen."],"General Payment Settings":["Allgemeine Zahlungseinstellungen"],"These settings apply to all payment gateways.":["Diese Einstellungen gelten f\u00fcr alle Zahlungs-Gateways."],"Stripe Settings":["Stripe-Einstellungen"],"Left ($100)":["Links ($100)"],"Right (100$)":["Richtig (100$)"],"Left Space ($ 100)":["Verbleibender Platz ($ 100)"],"Right Space (100 $)":["Rechter Raum (100 $)"],"Currency Sign Position":["Position des W\u00e4hrungszeichens"],"Select the position of the currency symbol relative to the amount.":["W\u00e4hlen Sie die Position des W\u00e4hrungssymbols relativ zum Betrag aus."],"Learn":["Lernen"],"Enable email summaries":["E-Mail-Zusammenfassungen aktivieren"],"Enable IP logging":["IP-Protokollierung aktivieren"],"Turn on Admin Notification from here.":["Aktivieren Sie hier die Admin-Benachrichtigung."],"Send entries to 100+ popular apps.":["Eintr\u00e4ge an \u00fcber 100 beliebte Apps senden."],"Build automated workflows that run instantly.":["Erstellen Sie automatisierte Workflows, die sofort ausgef\u00fchrt werden."],"Create custom app integrations using our Custom App feature.":["Erstellen Sie benutzerdefinierte App-Integrationen mit unserer benutzerdefinierten App-Funktion."],"Keep your tools in sync automatically.":["Halten Sie Ihre Werkzeuge automatisch synchron."],"This will install and activate OttoKit on your WordPress site to enable automation features.":["Dies wird OttoKit auf Ihrer WordPress-Seite installieren und aktivieren, um Automatisierungsfunktionen zu erm\u00f6glichen."],"Automate Your Forms with OttoKit":["Automatisieren Sie Ihre Formulare mit OttoKit"],"Every form submission should trigger something \u2014 a Slack alert, a CRM lead, a follow-up email, or a new row in Google Sheets.":["Jede Formular\u00fcbermittlung sollte etwas ausl\u00f6sen \u2014 eine Slack-Benachrichtigung, einen CRM-Lead, eine Follow-up-E-Mail oder eine neue Zeile in Google Sheets."],"MCP":["MCP"],"Configure AI client permissions and MCP server settings.":["Konfigurieren Sie die Berechtigungen des KI-Clients und die Einstellungen des MCP-Servers."],"View documentation":["Dokumentation anzeigen"],"Copy to clipboard":["In die Zwischenablage kopieren"],"Claude Desktop":["Claude Desktop"],"~\/Library\/Application Support\/Claude\/claude_desktop_config.json (macOS) or %APPDATA%\\Claude\\claude_desktop_config.json (Windows)":["~\/Library\/Application Support\/Claude\/claude_desktop_config.json (macOS) oder %APPDATA%\\Claude\\claude_desktop_config.json (Windows)"],"Claude Code":["Claude-Code"],".mcp.json (project) or ~\/.claude.json (global)":[".mcp.json (Projekt) oder ~\/.claude.json (global)"],"Cursor":["Cursor"],"~\/.cursor\/mcp.json":["~\/.cursor\/mcp.json"],"VS Code (Copilot)":["VS Code (Copilot)"],".vscode\/mcp.json (project) or settings.json > mcp.servers (global)":[".vscode\/mcp.json (Projekt) oder settings.json > mcp.servers (global)"],"~\/.continue\/config.yaml or config.json":["~\/.continue\/config.yaml oder config.json"],"Your client's MCP configuration file":["Die MCP-Konfigurationsdatei Ihres Kunden"],"Connect Your AI Client":["Verbinden Sie Ihren KI-Client"],"AI Client":["KI-Client"],"Create an Application Password \u2014 ":["Erstellen Sie ein Anwendungskennwort \u2014"],"Open Application Passwords":["Anwendungspassw\u00f6rter \u00f6ffnen"],"Or use this CLI command to add the server quickly (you will still need to set the environment variables):":["Oder verwenden Sie diesen CLI-Befehl, um den Server schnell hinzuzuf\u00fcgen (Sie m\u00fcssen dennoch die Umgebungsvariablen festlegen):"],"Copy the JSON config below into: ":["Kopiere die JSON-Konfiguration unten in:"],"Replace \"your-application-password\" with the password from Step 1.":["Ersetzen Sie \"your-application-password\" durch das Passwort aus Schritt 1."],"WP_API_URL \u2014 your site's MCP endpoint. WP_API_USERNAME \u2014 your WordPress username. WP_API_PASSWORD \u2014 the application password you generated.":["WP_API_URL \u2014 der MCP-Endpunkt Ihrer Website. WP_API_USERNAME \u2014 Ihr WordPress-Benutzername. WP_API_PASSWORD \u2014 das Anwendungskennwort, das Sie erstellt haben."],"View setup docs":["Einrichtungsdokumente anzeigen"],"The MCP Adapter plugin is installed but not active. Activate it to configure MCP settings.":["Das MCP Adapter-Plugin ist installiert, aber nicht aktiv. Aktivieren Sie es, um die MCP-Einstellungen zu konfigurieren."],"The MCP Adapter plugin is required to connect AI clients to your forms. Download and install it from GitHub, then activate it.":["Das MCP Adapter-Plugin ist erforderlich, um AI-Clients mit Ihren Formularen zu verbinden. Laden Sie es von GitHub herunter, installieren Sie es und aktivieren Sie es dann."],"Download the latest release from":["Laden Sie die neueste Version herunter von"],"Install the plugin via Plugins > Add New Plugin > Upload Plugin.":["Installieren Sie das Plugin \u00fcber Plugins > Neues Plugin hinzuf\u00fcgen > Plugin hochladen."],"Activate the MCP Adapter plugin.":["Aktivieren Sie das MCP Adapter-Plugin."],"Activating\u2026":["Aktivierung\u2026"],"Activate MCP Adapter":["MCP-Adapter aktivieren"],"Download MCP Adapter":["MCP-Adapter herunterladen"],"Experimental":["Experimentell"],"Enable Abilities":["F\u00e4higkeiten aktivieren"],"Register SureForms abilities with the WordPress Abilities API. When enabled, AI clients can list, read, create, edit, and delete your forms and entries. When disabled, no abilities are registered and AI clients cannot perform any actions on your forms.":["Registriere die F\u00e4higkeiten von SureForms mit der WordPress Abilities API. Wenn aktiviert, k\u00f6nnen KI-Clients Ihre Formulare und Eintr\u00e4ge auflisten, lesen, erstellen, bearbeiten und l\u00f6schen. Wenn deaktiviert, werden keine F\u00e4higkeiten registriert und KI-Clients k\u00f6nnen keine Aktionen an Ihren Formularen durchf\u00fchren."],"Abilities API \u2014 Edit":["F\u00e4higkeiten-API \u2014 Bearbeiten"],"Enable Edit Abilities":["Bearbeitungsf\u00e4higkeiten aktivieren"],"When enabled, AI clients can create new forms, update form titles, fields, and settings, duplicate forms, and modify entry statuses. When disabled, these abilities are unregistered and AI clients can only read your data.":["Wenn aktiviert, k\u00f6nnen KI-Clients neue Formulare erstellen, Formulartitel, Felder und Einstellungen aktualisieren, Formulare duplizieren und Eintragsstatus \u00e4ndern. Wenn deaktiviert, werden diese F\u00e4higkeiten abgemeldet und KI-Clients k\u00f6nnen nur Ihre Daten lesen."],"Abilities API \u2014 Delete":["F\u00e4higkeiten-API \u2014 L\u00f6schen"],"Enable Delete Abilities":["L\u00f6schf\u00e4higkeiten aktivieren"],"When enabled, AI clients can permanently delete forms and entries. Deleted data cannot be recovered. When disabled, delete abilities are unregistered and AI clients cannot remove any data.":["Wenn aktiviert, k\u00f6nnen KI-Clients Formulare und Eintr\u00e4ge dauerhaft l\u00f6schen. Gel\u00f6schte Daten k\u00f6nnen nicht wiederhergestellt werden. Wenn deaktiviert, werden L\u00f6schf\u00e4higkeiten abgemeldet und KI-Clients k\u00f6nnen keine Daten entfernen."],"MCP Server":["MCP-Server"],"Enable MCP Server":["MCP-Server aktivieren"],"Creates a dedicated SureForms MCP endpoint that AI clients like Claude can connect to. When disabled, the endpoint is removed and external AI clients cannot discover or call any SureForms abilities.":["Erstellt einen dedizierten SureForms MCP-Endpunkt, mit dem sich KI-Clients wie Claude verbinden k\u00f6nnen. Wenn er deaktiviert ist, wird der Endpunkt entfernt und externe KI-Clients k\u00f6nnen keine SureForms-Funktionen entdecken oder aufrufen."],"Learn more":["Mehr erfahren"],"MCP Adapter Required":["MCP-Adapter erforderlich"],"Google Maps":["Google Maps"],"Configure Google Maps API key for address autocomplete and map preview.":["Konfigurieren Sie den Google Maps API-Schl\u00fcssel f\u00fcr die Adressvervollst\u00e4ndigung und die Kartenansichtsvorschau."],"Help shape the future of SureForms":["Helfen Sie mit, die Zukunft von SureForms zu gestalten"],"Share how you use the plugin so we can build features that matter, fix issues faster, and make smarter decisions. ":["Teilen Sie uns mit, wie Sie das Plugin verwenden, damit wir Funktionen entwickeln k\u00f6nnen, die wichtig sind, Probleme schneller beheben und kl\u00fcgere Entscheidungen treffen k\u00f6nnen."],"Enable Google Address Autocomplete":["Google-Adress-Autovervollst\u00e4ndigung aktivieren"],"Upgrade to the SureForms Business Plan to add Google-powered address autocomplete with interactive map preview to your forms.":["Upgrade auf den SureForms Business-Plan, um Google-gest\u00fctzte Adressvervollst\u00e4ndigung mit interaktiver Kartenansicht zu Ihren Formularen hinzuzuf\u00fcgen."],"Auto-suggest addresses as users type for faster, error-free submissions":["Adressen automatisch vorschlagen, w\u00e4hrend Benutzer tippen, f\u00fcr schnellere und fehlerfreie Eingaben"],"Show an interactive map preview with draggable pin for precise locations":["Zeige eine interaktive Kartenansicht mit verschiebbarem Pin f\u00fcr pr\u00e4zise Standorte"],"Automatically populate address fields like city, state, and postal code":["Adressfelder wie Stadt, Bundesland und Postleitzahl automatisch ausf\u00fcllen"]}}} \ No newline at end of file diff --git a/languages/sureforms-de_DE.mo b/languages/sureforms-de_DE.mo index 841a434677dc5b0d75ba5ec2afb99d5b8bea9a9e..8361d41a6376b9b0bfaa372337e41cb4126d2039 100644 GIT binary patch delta 66542 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 z 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 b>%K0K_Sm9zlio

xzsBo-qnWv)NU#jr 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 ABLDyZ diff --git a/languages/sureforms-fr_FR.po b/languages/sureforms-fr_FR.po index 3441bdb34..5c00795a5 100644 --- a/languages/sureforms-fr_FR.po +++ b/languages/sureforms-fr_FR.po @@ -16,7 +16,7 @@ msgstr "" #: sureforms.php #: admin/admin.php:320 #: admin/admin.php:321 -#: admin/admin.php:1812 +#: admin/admin.php:1813 #: inc/abilities/abilities-registrar.php:133 #: inc/gutenberg-hooks.php:109 #: inc/page-builders/bricks/elements/form-widget.php:67 @@ -82,7 +82,7 @@ msgstr "Nouveau formulaire" #: admin/admin.php:601 #: admin/admin.php:602 -#: admin/admin.php:1849 +#: admin/admin.php:1850 #: inc/global-settings/email-summary.php:225 #: assets/build/dashboard.js:172 #: assets/build/entries.js:172 @@ -118,12 +118,12 @@ msgid "Nonce verification failed." msgstr "La vérification du nonce a échoué." #. translators: %1$s: Opening anchor tag with URL, %2$s: Closing anchor tag, %3$s: SureForms Pro Plugin Name. -#: admin/admin.php:1441 +#: admin/admin.php:1442 #, php-format msgid "Please %1$sactivate%2$s your copy of %3$s to get new features, access support, receive update notifications, and more." msgstr "Veuillez %1$sactiver%2$s votre copie de %3$s pour obtenir de nouvelles fonctionnalités, accéder au support, recevoir des notifications de mise à jour, et plus encore." -#: admin/admin.php:1848 +#: admin/admin.php:1849 #: inc/global-settings/email-summary.php:224 #: assets/build/entries.js:172 #: assets/build/payments.js:172 @@ -191,7 +191,7 @@ msgstr "Poubelle" msgid "Published" msgstr "Publié" -#: admin/admin.php:1840 +#: admin/admin.php:1841 msgid "View" msgstr "Voir" @@ -312,10 +312,10 @@ msgstr "Installé" msgid "You do not have permission to access this page." msgstr "Vous n'avez pas la permission d'accéder à cette page." -#: admin/admin.php:1607 -#: admin/admin.php:1706 -#: admin/admin.php:1744 -#: admin/admin.php:1765 +#: admin/admin.php:1608 +#: admin/admin.php:1707 +#: admin/admin.php:1745 +#: admin/admin.php:1766 #: inc/admin-ajax.php:162 #: inc/payments/admin/admin-handler.php:638 #: inc/payments/stripe/admin-stripe-handler.php:80 @@ -328,7 +328,7 @@ msgid "Form ID is required." msgstr "L'identifiant du formulaire est requis." #: inc/admin-ajax.php:182 -#: inc/form-submit.php:970 +#: inc/form-submit.php:972 msgid "Invalid form ID." msgstr "ID de formulaire invalide." @@ -502,11 +502,11 @@ msgstr "Case à cocher" msgid "Required" msgstr "Requis" -#: inc/fields/dropdown-markup.php:83 +#: inc/fields/dropdown-markup.php:84 msgid "Dropdown" msgstr "Menu déroulant" -#: inc/fields/dropdown-markup.php:106 +#: inc/fields/dropdown-markup.php:108 #: inc/gutenberg-hooks.php:220 msgid "Select an option" msgstr "Sélectionnez une option" @@ -534,7 +534,7 @@ msgstr "Je consens à ce que ce site web stocke les informations que j'ai soumis msgid "Please verify that you are not a robot." msgstr "Veuillez vérifier que vous n'êtes pas un robot." -#: inc/fields/multichoice-markup.php:113 +#: inc/fields/multichoice-markup.php:114 msgid "Multi Choice" msgstr "Choix multiple" @@ -775,7 +775,7 @@ msgid "Site URL" msgstr "URL du site" #: inc/smart-tags.php:111 -#: inc/smart-tags.php:142 +#: inc/smart-tags.php:143 msgid "Admin Email" msgstr "Email de l'administrateur" @@ -816,7 +816,7 @@ msgid "User Last Name" msgstr "Nom de famille de l'utilisateur" #: inc/smart-tags.php:122 -#: inc/smart-tags.php:143 +#: inc/smart-tags.php:144 msgid "User Email" msgstr "Email de l'utilisateur" @@ -840,11 +840,11 @@ msgstr "ID de publication/page intégrée" msgid "Embedded Post/Page Title" msgstr "Titre de l'article/page intégré" -#: inc/smart-tags.php:128 +#: inc/smart-tags.php:129 msgid "Populate by GET Param" msgstr "Remplir par paramètre GET" -#: inc/smart-tags.php:129 +#: inc/smart-tags.php:130 msgid "Cookie Value" msgstr "Valeur du cookie" @@ -8827,7 +8827,7 @@ msgstr "Réorganiser le bloc dans la barre d'action rapide" #: admin/admin.php:409 #: admin/admin.php:410 -#: admin/admin.php:2021 +#: admin/admin.php:2022 #: assets/build/blocks.js:172 #: assets/build/dashboard.js:172 #: assets/build/entries.js:172 @@ -9170,7 +9170,7 @@ msgstr "Centre" msgid "Right" msgstr "D'accord" -#: inc/form-submit.php:1147 +#: inc/form-submit.php:1149 #: assets/build/formEditor.js:172 #: assets/build/settings.js:172 msgid "Google reCAPTCHA" @@ -9180,7 +9180,7 @@ msgstr "Google reCAPTCHA" msgid "CloudFlare Turnstile" msgstr "Tourniquet CloudFlare" -#: inc/form-submit.php:1151 +#: inc/form-submit.php:1153 #: assets/build/formEditor.js:172 #: assets/build/settings.js:172 msgid "hCaptcha" @@ -9454,7 +9454,7 @@ msgstr "Clé du site" msgid "Secret Key" msgstr "Clé secrète" -#: inc/form-submit.php:1155 +#: inc/form-submit.php:1157 #: assets/build/settings.js:172 msgid "Cloudflare Turnstile" msgstr "Tourniquet Cloudflare" @@ -10407,7 +10407,7 @@ msgid "icon" msgstr "icône" #. translators: %1$s: SureForms version, %2$s: SureForms Pro Plugin Name, %3$s: SureForms Pro Version, %4$s: Anchor tag open, %5$s: Closing anchor tag. -#: admin/admin.php:1459 +#: admin/admin.php:1460 #, php-format msgid "SureForms %1$s requires minimum %2$s %3$s to work properly. Please update to the latest version from %4$shere%5$s." msgstr "SureForms %1$s nécessite au minimum %2$s %3$s pour fonctionner correctement. Veuillez mettre à jour vers la dernière version depuis %4$scet endroit%5$s." @@ -10429,7 +10429,7 @@ msgstr "Journalisation IP" msgid "Honeypot" msgstr "Pot de miel" -#: admin/admin.php:1505 +#: admin/admin.php:1506 msgid "Rate SureForms" msgstr "Évaluez SureForms" @@ -10485,18 +10485,18 @@ msgstr "Déverrouiller Ajouter une note" msgid "With the SureForms Starter plan, enhance your submitted form entries by adding personalized notes for better clarity and tracking." msgstr "Avec le plan SureForms Starter, améliorez vos entrées de formulaire soumises en ajoutant des notes personnalisées pour une meilleure clarté et un suivi amélioré." -#: inc/form-submit.php:821 +#: inc/form-submit.php:823 msgid "Email notification passed to the sending server" msgstr "Notification par e-mail transmise au serveur d'envoi" #. translators: Here, %s is the comma separated emails list. -#: inc/form-submit.php:894 +#: inc/form-submit.php:896 #, php-format msgid "Email notification recipient: %s" msgstr "Destinataire de la notification par e-mail : %s" #. translators: Here, %1$s is the comma separated emails list and %2$s is error report ( if any ). -#: inc/form-submit.php:911 +#: inc/form-submit.php:913 #, php-format msgid "Email server was unable to send the email notification. Recipient: %1$s. Reason: %2$s" msgstr "Le serveur de messagerie n'a pas pu envoyer la notification par e-mail. Destinataire : %1$s. Raison : %2$s" @@ -10740,24 +10740,24 @@ msgstr "Sélectionner le dégradé" msgid "reCAPTCHA" msgstr "reCAPTCHA" -#: inc/form-submit.php:1091 +#: inc/form-submit.php:1093 msgid "Captcha validation failed. No error code provided." msgstr "La validation du captcha a échoué. Aucun code d'erreur fourni." -#: inc/form-submit.php:1092 +#: inc/form-submit.php:1094 msgid "Captcha validation failed." msgstr "La validation du captcha a échoué." -#: inc/form-submit.php:1159 +#: inc/form-submit.php:1161 msgid "Unknown Captcha" msgstr "Captcha inconnu" -#: inc/form-submit.php:1160 +#: inc/form-submit.php:1162 msgid "Invalid captcha type." msgstr "Type de captcha invalide." #. translators: %s is the captcha title. -#: inc/form-submit.php:1173 +#: inc/form-submit.php:1175 #, php-format msgid "%s verification failed. Please contact your site administrator." msgstr "La vérification de %s a échoué. Veuillez contacter votre administrateur de site." @@ -11274,28 +11274,28 @@ msgstr "Activer la notification administrateur" msgid "Admin notifications keep you informed about new form entries since your last visit." msgstr "Les notifications administratives vous informent des nouvelles entrées de formulaire depuis votre dernière visite." -#: admin/admin.php:1611 -#: admin/admin.php:1702 -#: admin/admin.php:1740 -#: admin/admin.php:1761 +#: admin/admin.php:1612 +#: admin/admin.php:1703 +#: admin/admin.php:1741 +#: admin/admin.php:1762 msgid "Unauthorized user." msgstr "Utilisateur non autorisé." #. translators: 1: opening span, 2: opening strong (inline), 3: closing strong, 4: closing span, 5: opening strong (block), 6: closing strong -#: admin/admin.php:1711 +#: admin/admin.php:1712 #, php-format msgid "%1$sGet started by %2$sbuilding your first form%3$s.%4$s%5$sExperience the power of our intuitive AI Form Builder%6$s" msgstr "%1$sCommencez par %2$scréer votre premier formulaire%3$s.%4$s%5$sDécouvrez la puissance de notre créateur de formulaires intuitif alimenté par l'IA%6$s" -#: admin/admin.php:1722 +#: admin/admin.php:1723 msgid "SureForms is waiting for you!" msgstr "SureForms vous attend !" -#: admin/admin.php:1724 +#: admin/admin.php:1725 msgid "Build My First Form" msgstr "Construire mon premier formulaire" -#: admin/admin.php:1725 +#: admin/admin.php:1726 msgid "Dismiss" msgstr "Rejeter" @@ -11315,51 +11315,51 @@ msgstr "Connexion" msgid "Register" msgstr "Inscrire" -#: admin/admin.php:1836 +#: admin/admin.php:1837 msgid "Recent Entries" msgstr "Entrées récentes" -#: admin/admin.php:1837 +#: admin/admin.php:1838 msgid "( Last 7 days )" msgstr "( 7 derniers jours )" -#: admin/admin.php:1957 +#: admin/admin.php:1958 msgid "Use Conditional Logic to show only what matters" msgstr "Utilisez la logique conditionnelle pour montrer uniquement ce qui compte" -#: admin/admin.php:1958 +#: admin/admin.php:1959 msgid "Split your form into steps to keep it easy" msgstr "Divisez votre formulaire en étapes pour le rendre facile." -#: admin/admin.php:1959 +#: admin/admin.php:1960 msgid "Let people upload files directly to your form" msgstr "Permettez aux gens de télécharger des fichiers directement sur votre formulaire" -#: admin/admin.php:1960 +#: admin/admin.php:1961 msgid "Turn responses into downloadable PDFs automatically" msgstr "Transformez les réponses en PDF téléchargeables automatiquement" -#: admin/admin.php:1961 +#: admin/admin.php:1962 msgid "Let users sign with a simple signature field" msgstr "Permettez aux utilisateurs de signer avec un simple champ de signature" -#: admin/admin.php:1962 +#: admin/admin.php:1963 msgid "Connect your form to other tools using webhooks" msgstr "Connectez votre formulaire à d'autres outils en utilisant des webhooks" -#: admin/admin.php:1963 +#: admin/admin.php:1964 msgid "Use Conversational Forms for a chat-like experience" msgstr "Utilisez des formulaires conversationnels pour une expérience de type chat" -#: admin/admin.php:1964 +#: admin/admin.php:1965 msgid "Let users register or log in through your form" msgstr "Permettez aux utilisateurs de s'inscrire ou de se connecter via votre formulaire" -#: admin/admin.php:1965 +#: admin/admin.php:1966 msgid "Build forms that create WordPress user accounts" msgstr "Créez des formulaires qui génèrent des comptes utilisateurs WordPress" -#: admin/admin.php:1966 +#: admin/admin.php:1967 msgid "Add calculations to auto-total scores or prices" msgstr "Ajoutez des calculs pour totaliser automatiquement les scores ou les prix" @@ -11917,6 +11917,7 @@ msgid "Unable to create ZIP file." msgstr "Impossible de créer le fichier ZIP." #: inc/entries.php:729 +#: inc/smart-tags.php:128 #: assets/build/entries.js:172 msgid "Entry ID" msgstr "ID d'entrée" @@ -11934,7 +11935,7 @@ msgid "Invalid form data structure provided." msgstr "Structure de données de formulaire invalide fournie." #: inc/fields/payment-markup.php:249 -#: inc/payments/payment-helper.php:538 +#: inc/payments/payment-helper.php:543 msgid "Subscription Plan" msgstr "Plan d'abonnement" @@ -12555,301 +12556,301 @@ msgstr "Dollar de Hong Kong" msgid "Norwegian Krone" msgstr "Couronne norvégienne" -#: inc/payments/payment-helper.php:259 +#: inc/payments/payment-helper.php:264 msgid "South Korean Won" msgstr "Won sud-coréen" -#: inc/payments/payment-helper.php:264 +#: inc/payments/payment-helper.php:269 msgid "Turkish Lira" msgstr "Lire turque" -#: inc/payments/payment-helper.php:269 +#: inc/payments/payment-helper.php:274 msgid "Russian Ruble" msgstr "Rouble russe" -#: inc/payments/payment-helper.php:274 +#: inc/payments/payment-helper.php:279 msgid "Indian Rupee" msgstr "Roupie indienne" -#: inc/payments/payment-helper.php:279 +#: inc/payments/payment-helper.php:284 msgid "Brazilian Real" msgstr "Réel brésilien" -#: inc/payments/payment-helper.php:284 +#: inc/payments/payment-helper.php:289 msgid "South African Rand" msgstr "Rand sud-africain" -#: inc/payments/payment-helper.php:289 +#: inc/payments/payment-helper.php:294 msgid "UAE Dirham" msgstr "Dirham des Émirats arabes unis" -#: inc/payments/payment-helper.php:294 +#: inc/payments/payment-helper.php:299 msgid "Philippine Peso" msgstr "Peso philippin" -#: inc/payments/payment-helper.php:299 +#: inc/payments/payment-helper.php:304 msgid "Indonesian Rupiah" msgstr "Roupie indonésienne" -#: inc/payments/payment-helper.php:304 +#: inc/payments/payment-helper.php:309 msgid "Malaysian Ringgit" msgstr "Ringgit malaisien" -#: inc/payments/payment-helper.php:309 +#: inc/payments/payment-helper.php:314 msgid "Thai Baht" msgstr "Baht thaïlandais" -#: inc/payments/payment-helper.php:314 +#: inc/payments/payment-helper.php:319 msgid "Burundian Franc" msgstr "Franc burundais" -#: inc/payments/payment-helper.php:319 +#: inc/payments/payment-helper.php:324 msgid "Chilean Peso" msgstr "Peso chilien" -#: inc/payments/payment-helper.php:324 +#: inc/payments/payment-helper.php:329 msgid "Djiboutian Franc" msgstr "Franc djiboutien" -#: inc/payments/payment-helper.php:329 +#: inc/payments/payment-helper.php:334 msgid "Guinean Franc" msgstr "Franc guinéen" -#: inc/payments/payment-helper.php:334 +#: inc/payments/payment-helper.php:339 msgid "Comorian Franc" msgstr "Franc comorien" -#: inc/payments/payment-helper.php:339 +#: inc/payments/payment-helper.php:344 msgid "Malagasy Ariary" msgstr "Ariary malgache" -#: inc/payments/payment-helper.php:344 +#: inc/payments/payment-helper.php:349 msgid "Paraguayan Guaraní" msgstr "Guaraní paraguayen" -#: inc/payments/payment-helper.php:349 +#: inc/payments/payment-helper.php:354 msgid "Rwandan Franc" msgstr "Franc rwandais" -#: inc/payments/payment-helper.php:354 +#: inc/payments/payment-helper.php:359 msgid "Ugandan Shilling" msgstr "Shilling ougandais" -#: inc/payments/payment-helper.php:359 +#: inc/payments/payment-helper.php:364 msgid "Vietnamese Đồng" msgstr "Đồng vietnamien" -#: inc/payments/payment-helper.php:364 +#: inc/payments/payment-helper.php:369 msgid "Vanuatu Vatu" msgstr "Vanuatu Vatu" -#: inc/payments/payment-helper.php:369 +#: inc/payments/payment-helper.php:374 msgid "Central African CFA Franc" msgstr "Franc CFA d'Afrique centrale" -#: inc/payments/payment-helper.php:374 +#: inc/payments/payment-helper.php:379 msgid "West African CFA Franc" msgstr "Franc CFA d'Afrique de l'Ouest" -#: inc/payments/payment-helper.php:379 +#: inc/payments/payment-helper.php:384 msgid "CFP Franc" msgstr "Franc CFP" -#: inc/payments/payment-helper.php:475 +#: inc/payments/payment-helper.php:480 msgid "An unknown error occurred. Please try again or contact the site administrator." msgstr "Une erreur inconnue s'est produite. Veuillez réessayer ou contacter l'administrateur du site." -#: inc/payments/payment-helper.php:477 +#: inc/payments/payment-helper.php:482 msgid "Payment is currently unavailable. Please contact the site administrator." msgstr "Le paiement est actuellement indisponible. Veuillez contacter l'administrateur du site." -#: inc/payments/payment-helper.php:478 +#: inc/payments/payment-helper.php:483 msgid "Payment is currently unavailable. Please contact the site administrator to configure the payment amount." msgstr "Le paiement est actuellement indisponible. Veuillez contacter l'administrateur du site pour configurer le montant du paiement." -#: inc/payments/payment-helper.php:479 +#: inc/payments/payment-helper.php:484 msgid "Invalid payment amount" msgstr "Montant de paiement invalide" -#: inc/payments/payment-helper.php:480 +#: inc/payments/payment-helper.php:485 msgid "Payment amount must be at least {symbol}{amount}." msgstr "Le montant du paiement doit être d'au moins {symbol}{amount}." -#: inc/payments/payment-helper.php:483 +#: inc/payments/payment-helper.php:488 msgid "Payment is currently unavailable. Please contact the site administrator to configure the customer name field." msgstr "Le paiement est actuellement indisponible. Veuillez contacter l'administrateur du site pour configurer le champ du nom du client." -#: inc/payments/payment-helper.php:484 +#: inc/payments/payment-helper.php:489 msgid "Payment is currently unavailable. Please contact the site administrator to configure the customer email field." msgstr "Le paiement est actuellement indisponible. Veuillez contacter l'administrateur du site pour configurer le champ de l'email client." -#: inc/payments/payment-helper.php:485 +#: inc/payments/payment-helper.php:490 msgid "Please enter your name." msgstr "Veuillez entrer votre nom." -#: inc/payments/payment-helper.php:486 +#: inc/payments/payment-helper.php:491 msgid "Please enter your email." msgstr "Veuillez entrer votre e-mail." -#: inc/payments/payment-helper.php:489 +#: inc/payments/payment-helper.php:494 msgid "Payment failed" msgstr "Échec du paiement" -#: inc/payments/payment-helper.php:490 +#: inc/payments/payment-helper.php:495 msgid "Payment successful" msgstr "Paiement réussi" -#: inc/payments/payment-helper.php:494 -#: inc/payments/payment-helper.php:495 +#: inc/payments/payment-helper.php:499 +#: inc/payments/payment-helper.php:500 msgid "Your card was declined. Please try a different payment method or contact your bank." msgstr "Votre carte a été refusée. Veuillez essayer un autre mode de paiement ou contacter votre banque." -#: inc/payments/payment-helper.php:496 +#: inc/payments/payment-helper.php:501 msgid "Your card has insufficient funds. Please use a different payment method." msgstr "Votre carte ne dispose pas de fonds suffisants. Veuillez utiliser un autre moyen de paiement." -#: inc/payments/payment-helper.php:497 +#: inc/payments/payment-helper.php:502 msgid "Your card was declined because it has been reported as lost. Please contact your bank." msgstr "Votre carte a été refusée car elle a été signalée comme perdue. Veuillez contacter votre banque." -#: inc/payments/payment-helper.php:498 +#: inc/payments/payment-helper.php:503 msgid "Your card was declined because it has been reported as stolen. Please contact your bank." msgstr "Votre carte a été refusée car elle a été signalée comme volée. Veuillez contacter votre banque." -#: inc/payments/payment-helper.php:499 +#: inc/payments/payment-helper.php:504 msgid "Your card has expired. Please use a different payment method." msgstr "Votre carte a expiré. Veuillez utiliser un autre moyen de paiement." -#: inc/payments/payment-helper.php:500 -#: inc/payments/payment-helper.php:521 +#: inc/payments/payment-helper.php:505 +#: inc/payments/payment-helper.php:526 msgid "Your card was declined. Please contact your bank for more information." msgstr "Votre carte a été refusée. Veuillez contacter votre banque pour plus d'informations." -#: inc/payments/payment-helper.php:501 +#: inc/payments/payment-helper.php:506 msgid "Your card was declined due to restrictions. Please contact your bank." msgstr "Votre carte a été refusée en raison de restrictions. Veuillez contacter votre banque." -#: inc/payments/payment-helper.php:502 +#: inc/payments/payment-helper.php:507 msgid "Your card was declined due to a security violation. Please contact your bank." msgstr "Votre carte a été refusée en raison d'une violation de sécurité. Veuillez contacter votre banque." -#: inc/payments/payment-helper.php:503 +#: inc/payments/payment-helper.php:508 msgid "Your card does not support this type of purchase. Please use a different payment method." msgstr "Votre carte ne prend pas en charge ce type d'achat. Veuillez utiliser un autre moyen de paiement." -#: inc/payments/payment-helper.php:504 +#: inc/payments/payment-helper.php:509 msgid "A stop payment order has been placed on this card. Please contact your bank." msgstr "Un ordre d'arrêt de paiement a été placé sur cette carte. Veuillez contacter votre banque." -#: inc/payments/payment-helper.php:505 +#: inc/payments/payment-helper.php:510 msgid "A test card was used in a live environment. Please use a real card." msgstr "Une carte de test a été utilisée dans un environnement réel. Veuillez utiliser une vraie carte." -#: inc/payments/payment-helper.php:506 +#: inc/payments/payment-helper.php:511 msgid "Your card has exceeded its withdrawal limit. Please contact your bank." msgstr "Votre carte a dépassé sa limite de retrait. Veuillez contacter votre banque." -#: inc/payments/payment-helper.php:507 +#: inc/payments/payment-helper.php:512 msgid "Your card's security code is incorrect. Please check and try again." msgstr "Le code de sécurité de votre carte est incorrect. Veuillez vérifier et réessayer." -#: inc/payments/payment-helper.php:508 +#: inc/payments/payment-helper.php:513 msgid "Your card number is incorrect. Please check and try again." msgstr "Votre numéro de carte est incorrect. Veuillez vérifier et réessayer." -#: inc/payments/payment-helper.php:509 +#: inc/payments/payment-helper.php:514 msgid "Your card's security code is invalid. Please check and try again." msgstr "Le code de sécurité de votre carte est invalide. Veuillez vérifier et réessayer." -#: inc/payments/payment-helper.php:510 +#: inc/payments/payment-helper.php:515 msgid "Your card's expiration month is invalid. Please check and try again." msgstr "Le mois d'expiration de votre carte est invalide. Veuillez vérifier et réessayer." -#: inc/payments/payment-helper.php:511 +#: inc/payments/payment-helper.php:516 msgid "Your card's expiration year is invalid. Please check and try again." msgstr "L'année d'expiration de votre carte est invalide. Veuillez vérifier et réessayer." -#: inc/payments/payment-helper.php:512 +#: inc/payments/payment-helper.php:517 msgid "Your card number is invalid. Please check and try again." msgstr "Votre numéro de carte est invalide. Veuillez vérifier et réessayer." -#: inc/payments/payment-helper.php:515 +#: inc/payments/payment-helper.php:520 msgid "Your card is not supported for this transaction. Please use a different payment method." msgstr "Votre carte n'est pas prise en charge pour cette transaction. Veuillez utiliser un autre moyen de paiement." -#: inc/payments/payment-helper.php:516 +#: inc/payments/payment-helper.php:521 msgid "Your card does not support the currency used for this transaction. Please use a different payment method." msgstr "Votre carte ne prend pas en charge la devise utilisée pour cette transaction. Veuillez utiliser un autre mode de paiement." -#: inc/payments/payment-helper.php:517 +#: inc/payments/payment-helper.php:522 msgid "A transaction with identical details was submitted recently. Please wait a moment and try again." msgstr "Une transaction avec des détails identiques a été soumise récemment. Veuillez patienter un moment et réessayer." -#: inc/payments/payment-helper.php:518 +#: inc/payments/payment-helper.php:523 msgid "The account associated with your card is invalid. Please contact your bank." msgstr "Le compte associé à votre carte est invalide. Veuillez contacter votre banque." -#: inc/payments/payment-helper.php:519 +#: inc/payments/payment-helper.php:524 msgid "The payment amount is invalid. Please contact the site administrator." msgstr "Le montant du paiement est invalide. Veuillez contacter l'administrateur du site." -#: inc/payments/payment-helper.php:522 +#: inc/payments/payment-helper.php:527 msgid "Your card information needs to be updated. Please contact your bank." msgstr "Vos informations de carte doivent être mises à jour. Veuillez contacter votre banque." -#: inc/payments/payment-helper.php:523 +#: inc/payments/payment-helper.php:528 msgid "The card cannot be used for this transaction. Please contact your bank." msgstr "La carte ne peut pas être utilisée pour cette transaction. Veuillez contacter votre banque." -#: inc/payments/payment-helper.php:524 +#: inc/payments/payment-helper.php:529 msgid "The transaction is not permitted. Please contact your bank." msgstr "La transaction n'est pas autorisée. Veuillez contacter votre banque." -#: inc/payments/payment-helper.php:525 +#: inc/payments/payment-helper.php:530 msgid "Your card requires offline PIN authentication. Please try again." msgstr "Votre carte nécessite une authentification par code PIN hors ligne. Veuillez réessayer." -#: inc/payments/payment-helper.php:526 +#: inc/payments/payment-helper.php:531 msgid "Your card requires PIN authentication. Please try again." msgstr "Votre carte nécessite une authentification par code PIN. Veuillez réessayer." -#: inc/payments/payment-helper.php:527 +#: inc/payments/payment-helper.php:532 msgid "You have exceeded the maximum number of PIN attempts. Please contact your bank." msgstr "Vous avez dépassé le nombre maximum de tentatives de code PIN. Veuillez contacter votre banque." -#: inc/payments/payment-helper.php:528 +#: inc/payments/payment-helper.php:533 msgid "All authorizations for this card have been revoked. Please contact your bank." msgstr "Toutes les autorisations pour cette carte ont été révoquées. Veuillez contacter votre banque." -#: inc/payments/payment-helper.php:529 +#: inc/payments/payment-helper.php:534 msgid "The authorization for this transaction has been revoked. Please try again." msgstr "L'autorisation pour cette transaction a été révoquée. Veuillez réessayer." -#: inc/payments/payment-helper.php:530 +#: inc/payments/payment-helper.php:535 msgid "This transaction is not allowed. Please contact your bank." msgstr "Cette transaction n'est pas autorisée. Veuillez contacter votre banque." -#: inc/payments/payment-helper.php:532 +#: inc/payments/payment-helper.php:537 msgid "Your card was declined. Your request was in live mode, but used a known test card." msgstr "Votre carte a été refusée. Votre demande était en mode réel, mais vous avez utilisé une carte de test connue." -#: inc/payments/payment-helper.php:533 +#: inc/payments/payment-helper.php:538 msgid "Your card was declined. Your request was in test mode, but used a non test card. For a list of valid test cards, visit: https://stripe.com/docs/testing." msgstr "Votre carte a été refusée. Votre demande était en mode test, mais vous avez utilisé une carte non test. Pour obtenir une liste des cartes de test valides, visitez : https://stripe.com/docs/testing." -#: inc/payments/payment-helper.php:536 +#: inc/payments/payment-helper.php:541 msgid "SureForms Subscription" msgstr "Abonnement SureForms" -#: inc/payments/payment-helper.php:537 +#: inc/payments/payment-helper.php:542 msgid "SureForms Payment" msgstr "Paiement SureForms" -#: inc/payments/payment-helper.php:539 +#: inc/payments/payment-helper.php:544 msgid "SureForms Customer" msgstr "Client SureForms" -#: inc/payments/payment-helper.php:559 +#: inc/payments/payment-helper.php:564 msgid "Unknown error" msgstr "Erreur inconnue" @@ -14980,74 +14981,74 @@ msgstr "Échec de la création du formulaire en double." #: inc/payments/front-end.php:97 #: inc/payments/front-end.php:298 -#: inc/payments/payment-helper.php:589 +#: inc/payments/payment-helper.php:594 msgid "Invalid form configuration." msgstr "Configuration de formulaire invalide." -#: inc/payments/payment-helper.php:597 +#: inc/payments/payment-helper.php:602 msgid "Payment configuration not found for this form." msgstr "Configuration de paiement introuvable pour ce formulaire." #. translators: 1: expected currency, 2: received currency -#: inc/payments/payment-helper.php:608 +#: inc/payments/payment-helper.php:613 #, php-format msgid "Currency mismatch: expected %1$s, received %2$s." msgstr "Incohérence de devise : attendu %1$s, reçu %2$s." #. translators: 1: expected amount with currency -#: inc/payments/payment-helper.php:625 +#: inc/payments/payment-helper.php:630 #, php-format msgid "Payment amount must be exactly %1$s." msgstr "Le montant du paiement doit être exactement %1$s." #. translators: 1: minimum amount with currency -#: inc/payments/payment-helper.php:636 +#: inc/payments/payment-helper.php:641 #, php-format msgid "Payment amount must be at least %1$s." msgstr "Le montant du paiement doit être d'au moins %1$s." -#: inc/payments/payment-helper.php:712 +#: inc/payments/payment-helper.php:717 msgid "Invalid payment verification parameters." msgstr "Paramètres de vérification de paiement invalides." -#: inc/payments/payment-helper.php:723 +#: inc/payments/payment-helper.php:728 msgid "Payment verification failed. Invalid payment intent." msgstr "Échec de la vérification du paiement. Intention de paiement invalide." -#: inc/payments/payment-helper.php:809 -#: inc/payments/payment-helper.php:947 +#: inc/payments/payment-helper.php:814 +#: inc/payments/payment-helper.php:952 msgid "Variable amount field configuration not found." msgstr "Configuration du champ de montant variable introuvable." -#: inc/payments/payment-helper.php:830 +#: inc/payments/payment-helper.php:835 msgid "No payment options are configured for this field." msgstr "Aucune option de paiement n'est configurée pour ce champ." #. translators: %s: currency code -#: inc/payments/payment-helper.php:856 +#: inc/payments/payment-helper.php:861 msgid "Invalid payment amount. Please select a valid amount from the available options." msgstr "Montant de paiement invalide. Veuillez sélectionner un montant valide parmi les options disponibles." #. translators: %1$s: expected amount, %2$s: payment amount -#: inc/payments/payment-helper.php:891 +#: inc/payments/payment-helper.php:896 msgid "Payment configuration not found." msgstr "Configuration de paiement introuvable." #. translators: %1$s: expected amount, %2$s: payment amount -#: inc/payments/payment-helper.php:907 -#: inc/payments/payment-helper.php:959 -#: inc/payments/payment-helper.php:995 +#: inc/payments/payment-helper.php:912 +#: inc/payments/payment-helper.php:964 +#: inc/payments/payment-helper.php:1000 #, php-format msgid "Payment amount mismatch. Expected %1$s, received %2$s." msgstr "Incohérence du montant du paiement. Montant attendu %1$s, reçu %2$s." -#: inc/payments/payment-helper.php:936 -#: inc/payments/payment-helper.php:986 +#: inc/payments/payment-helper.php:941 +#: inc/payments/payment-helper.php:991 msgid "Variable amount field value is required." msgstr "La valeur du champ de montant variable est requise." #. translators: %1$s: minimum amount, %2$s: payment amount -#: inc/payments/payment-helper.php:1007 +#: inc/payments/payment-helper.php:1012 #, php-format msgid "Payment amount below minimum. Minimum: %1$s, received %2$s." msgstr "Montant du paiement inférieur au minimum. Minimum : %1$s, reçu %2$s." @@ -15133,7 +15134,7 @@ msgstr "Passerelle de paiement introuvable." msgid "Refund processing is not supported for %s gateway." msgstr "Le traitement des remboursements n'est pas pris en charge pour la passerelle %s." -#: inc/payments/payment-helper.php:969 +#: inc/payments/payment-helper.php:974 msgid "Number field configuration not found." msgstr "Configuration du champ numérique introuvable." @@ -15252,12 +15253,12 @@ msgid "Stripe Settings" msgstr "Paramètres Stripe" #. translators: %1$s: SureForms version, %2$s: SureForms Pro Plugin Name, %3$s: SureForms Pro Version. -#: admin/admin.php:1376 +#: admin/admin.php:1377 #, php-format msgid "SureForms %1$s requires minimum %2$s %3$s to work properly. Please update to the latest version." msgstr "SureForms %1$s nécessite au minimum %2$s %3$s pour fonctionner correctement. Veuillez mettre à jour vers la dernière version." -#: admin/admin.php:1389 +#: admin/admin.php:1390 msgid "Update Now" msgstr "Mettez à jour maintenant" @@ -15319,40 +15320,40 @@ msgstr "Sélectionnez la position du symbole monétaire par rapport au montant." msgid "Learn" msgstr "Apprendre" -#: admin/admin.php:1502 +#: admin/admin.php:1503 msgid "Amazing! SureForms is powering your forms and submissions - let's keep growing together!" msgstr "Incroyable ! SureForms alimente vos formulaires et soumissions - continuons à grandir ensemble !" -#: admin/admin.php:1503 +#: admin/admin.php:1504 msgid "If SureForms has been helpful, would you mind taking a moment to leave a 5-star review on WordPress.org?" msgstr "Si SureForms vous a été utile, pourriez-vous prendre un moment pour laisser un avis 5 étoiles sur WordPress.org ?" -#: admin/admin.php:1506 -#: admin/admin.php:1550 +#: admin/admin.php:1507 +#: admin/admin.php:1551 msgid "Maybe later" msgstr "Peut-être plus tard" -#: admin/admin.php:1507 +#: admin/admin.php:1508 msgid "I already did" msgstr "Je l'ai déjà fait" -#: admin/admin.php:1546 +#: admin/admin.php:1547 msgid "SureForms is ready to power your forms — explore what's possible!" msgstr "SureForms est prêt à dynamiser vos formulaires — explorez ce qui est possible !" -#: admin/admin.php:1547 +#: admin/admin.php:1548 msgid "Manage your forms, track submissions, and discover features like AI Form Builder, payment integrations, and more from the SureForms dashboard." msgstr "Gérez vos formulaires, suivez les soumissions et découvrez des fonctionnalités telles que le constructeur de formulaires IA, les intégrations de paiement et bien plus encore depuis le tableau de bord SureForms." -#: admin/admin.php:1549 +#: admin/admin.php:1550 msgid "Go to Dashboard" msgstr "Aller au tableau de bord" -#: admin/admin.php:1551 +#: admin/admin.php:1552 msgid "I already know" msgstr "Je sais déjà" -#: admin/admin.php:1631 +#: admin/admin.php:1632 msgid "Invalid parameters." msgstr "Paramètres invalides." @@ -15742,7 +15743,7 @@ msgstr "Ce formulaire n'est pas encore disponible. Revenez après l'heure de dé #: inc/form-submit.php:99 #: inc/form-submit.php:400 #: inc/form-submit.php:445 -#: inc/form-submit.php:966 +#: inc/form-submit.php:968 #: inc/payments/front-end.php:77 #: inc/payments/front-end.php:258 #: inc/rest-api.php:98 @@ -15791,19 +15792,19 @@ msgstr "Veuillez vérifier le formulaire pour les erreurs." msgid "Your submission was flagged as spam. Please try again." msgstr "Votre soumission a été signalée comme spam. Veuillez réessayer." -#: inc/form-submit.php:649 +#: inc/form-submit.php:651 msgid "Unable to submit form. Please try again." msgstr "Impossible de soumettre le formulaire. Veuillez réessayer." -#: inc/form-submit.php:901 +#: inc/form-submit.php:903 msgid "No SMTP plugin detected. Please configure an SMTP plugin to enable email sending." msgstr "Aucun plugin SMTP détecté. Veuillez configurer un plugin SMTP pour activer l'envoi d'e-mails." -#: inc/form-submit.php:902 +#: inc/form-submit.php:904 msgid "Email sending failed for an unknown reason." msgstr "L'envoi de l'email a échoué pour une raison inconnue." -#: inc/form-submit.php:941 +#: inc/form-submit.php:943 msgid "No emails were sent." msgstr "Aucun e-mail n'a été envoyé." @@ -15956,31 +15957,31 @@ msgstr "Impossible de supprimer les paiements. Veuillez réessayer." msgid "Unable to process refund. Please try again." msgstr "Impossible de traiter le remboursement. Veuillez réessayer." -#: inc/payments/payment-helper.php:491 +#: inc/payments/payment-helper.php:496 msgid "Unable to complete payment. Please try again or contact support." msgstr "Impossible de terminer le paiement. Veuillez réessayer ou contacter le support." -#: inc/payments/payment-helper.php:513 +#: inc/payments/payment-helper.php:518 msgid "Unable to process card. Please try again." msgstr "Impossible de traiter la carte. Veuillez réessayer." -#: inc/payments/payment-helper.php:514 +#: inc/payments/payment-helper.php:519 msgid "Unable to process transaction. Please try again." msgstr "Impossible de traiter la transaction. Veuillez réessayer." -#: inc/payments/payment-helper.php:520 +#: inc/payments/payment-helper.php:525 msgid "Unable to reach card issuer. Please try again later." msgstr "Impossible de joindre l'émetteur de la carte. Veuillez réessayer plus tard." -#: inc/payments/payment-helper.php:531 +#: inc/payments/payment-helper.php:536 msgid "Unable to process transaction. Please try again later." msgstr "Impossible de traiter la transaction. Veuillez réessayer plus tard." -#: inc/payments/payment-helper.php:541 +#: inc/payments/payment-helper.php:546 msgid "Complete the form to view the amount." msgstr "Complétez le formulaire pour voir le montant." -#: inc/payments/payment-helper.php:542 +#: inc/payments/payment-helper.php:547 msgid "Unable to create payment. Please contact support." msgstr "Impossible de créer le paiement. Veuillez contacter le support." @@ -16696,7 +16697,7 @@ msgid "Invalid webhook signature." msgstr "Signature de webhook invalide." #: admin/admin.php:426 -#: admin/admin.php:974 +#: admin/admin.php:975 #: assets/build/formEditor.js:172 msgid "Quizzes" msgstr "Quiz" @@ -16710,11 +16711,11 @@ msgstr "Participations au quiz" msgid "New" msgstr "Nouveau" -#: inc/form-submit.php:975 +#: inc/form-submit.php:977 msgid "Invalid form." msgstr "Formulaire invalide." -#: inc/form-submit.php:980 +#: inc/form-submit.php:982 msgid "Too many requests. Please try again shortly." msgstr "Trop de demandes. Veuillez réessayer sous peu." @@ -17228,7 +17229,7 @@ msgstr "Sélectionnez ceci pour créer un quiz avec des questions notées et des #: admin/admin.php:458 #: admin/admin.php:459 -#: admin/admin.php:979 +#: admin/admin.php:980 msgid "Survey Reports" msgstr "Rapports d'enquête" @@ -17494,7 +17495,7 @@ msgstr "Aidez à façonner l'avenir de SureForms" #: assets/build/settings.js:172 msgid "Share how you use the plugin so we can build features that matter, fix issues faster, and make smarter decisions. " -msgstr "Partagez comment vous utilisez le plugin afin que nous puissions développer des fonctionnalités qui comptent, résoudre les problèmes plus rapidement et prendre des décisions plus éclairées. " +msgstr "Partagez comment vous utilisez le plugin afin que nous puissions développer des fonctionnalités qui comptent, résoudre les problèmes plus rapidement et prendre des décisions plus éclairées." #: assets/build/settings.js:172 msgid "Enable Google Address Autocomplete" @@ -17572,6 +17573,14 @@ msgstr "Afficher les résultats en direct aux répondants" msgid "Perfect for feedback, polls, and research" msgstr "Parfait pour les retours, les sondages et la recherche" +#: inc/payments/payment-helper.php:259 +msgid "Polish Złoty" +msgstr "Złoty polonais" + +#: assets/build/blocks.js:172 +msgid "Dynamic Default Value" +msgstr "Valeur par défaut dynamique" + #: inc/post-types.php:205 msgctxt "post type general name" msgid "Forms" diff --git a/languages/sureforms-it_IT-4b62e3f004dea2c587b5a3069263d994.json b/languages/sureforms-it_IT-4b62e3f004dea2c587b5a3069263d994.json index 5548a9dce..7a85419c9 100644 --- a/languages/sureforms-it_IT-4b62e3f004dea2c587b5a3069263d994.json +++ b/languages/sureforms-it_IT-4b62e3f004dea2c587b5a3069263d994.json @@ -1 +1 @@ -{"translation-revision-date":"2025-01-01T06:16:29+00:00","generator":"WP-CLI\/2.12.0","source":"assets\/build\/blocks.js","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","lang":"en","plural-forms":"nplurals=2; plural=(n != 1);"},"Settings":["Impostazioni"],"Search":["Cerca"],"Fields":["Campi"],"Image":["Immagine"],"Submit":["Invia"],"Required":["Richiesto"],"Form Title":["Titolo del modulo"],"Show":["Mostra"],"Hide":["Nascondi"],"Edit Form":["Modifica modulo"],"Icon":["Icona"],"Desktop":["Desktop"],"Medium":["Medio"],"Mobile":["Cellulare"],"Repeat":["Ripeti"],"Scroll":["Scorri"],"Tablet":["Tablet"],"Basic":["Base"],"(no title)":["(nessun titolo)"],"Select a Form":["Seleziona un modulo"],"No forms found\u2026":["Nessun modulo trovato\u2026"],"Choose":["Scegli"],"Create New":["Crea Nuovo"],"Change Form":["Modifica modulo"],"This form has been deleted or is unavailable.":["Questo modulo \u00e8 stato eliminato o non \u00e8 disponibile."],"Form Settings":["Impostazioni del modulo"],"Show Form Title on this Page":["Mostra il titolo del modulo su questa pagina"],"Note: For editing SureForms, please refer to the SureForms Editor - ":["Nota: Per modificare i SureForms, fare riferimento all'Editor di SureForms -"],"Field preview":["Anteprima del campo"],"General":["Generale"],"Style":["Stile"],"Advanced":["Avanzato"],"No tags available":["Nessun tag disponibile"],"Device":["Dispositivo"],"Select Shortcodes":["Seleziona i codici brevi"],"Page Break Label":["Etichetta di interruzione di pagina"],"Next":["Avanti"],"Back":["Indietro"],"Reset":["Reimposta"],"Generic tags":["Tag generici"],"Pixel":["Pixel"],"Em":["Em"],"Select Units":["Seleziona unit\u00e0"],"%s units":["%s unit\u00e0"],"Margin":["Margine"],"Attributes":["Attributi"],"Input Pattern":["Schema di input"],"None":["Nessuno"],"(###) ###-####":["(###) ###-####"],"(##) ####-####":["(##) ####-####"],"27\/08\/2024":["27\/08\/2024"],"23:59:59":["23:59:59"],"27\/08\/2024 23:59:59":["27\/08\/2024 23:59:59"],"Custom":["Personalizzato"],"Custom Mask":["Maschera personalizzata"],"Please check the documentation to manage custom input pattern ":["Si prega di controllare la documentazione per gestire il modello di input personalizzato"],"here":["qui"],"Default Value":["Valore predefinito"],"Error Message":["Messaggio di errore"],"Help Text":["Testo di aiuto"],"Number Format":["Formato numero"],"US Style (Eg: 9,999.99)":["Stile USA (Es: 9.999,99)"],"EU Style (Eg: 9.999,99)":["Stile UE (Es: 9.999,99)"],"Minimum Value":["Valore minimo"],"Maximum Value":["Valore massimo"],"Please check the Minimum and Maximum value":["Si prega di controllare il valore minimo e massimo"],"Enable Email Confirmation":["Abilita la conferma email"],"Checked by Default":["Selezionato per impostazione predefinita"],"Error message":["Messaggio di errore"],"Checked by default":["Selezionato per impostazione predefinita"],"Please add a option props to MultiButtonsControl":["Si prega di aggiungere un'opzione props a MultiButtonsControl"],"Icon Library":["Libreria di icone"],"Close":["Chiudi"],"All Icons":["Tutte le icone"],"Other":["Altro"],"No Icons Found":["Nessuna icona trovata"],"Insert Icon":["Inserisci icona"],"Change Icon":["Cambia icona"],"Choose Icon":["Scegli icona"],"Confirm":["Conferma"],"Cancel":["Annulla"],"Processing\u2026":["Elaborazione\u2026"],"Select Video":["Seleziona video"],"Change Video":["Cambia video"],"Select Lottie Animation":["Seleziona animazione Lottie"],"Change Lottie Animation":["Cambia animazione Lottie"],"Upload SVG":["Carica SVG"],"Change SVG":["Cambia SVG"],"Select Image":["Seleziona immagine"],"Change Image":["Cambia immagine"],"Upload SVG?":["Caricare SVG?"],"Upload SVG can be potentially risky. Are you sure?":["Caricare SVG pu\u00f2 essere potenzialmente rischioso. Sei sicuro?"],"Upload Anyway":["Carica comunque"],"Bulk Add":["Aggiunta in blocco"],"Bulk Add Options":["Aggiungi opzioni in blocco"],"Enter each option on a new line.":["Inserisci ogni opzione su una nuova riga."],"Insert Options":["Inserisci opzioni"],"Full Width":["Larghezza completa"],"Option Type":["Tipo di opzione"],"Edit Options":["Opzioni di modifica"],"Add New Option":["Aggiungi nuova opzione"],"ADD":["AGGIUNGI"],"Enable Auto Country Detection":["Abilita il rilevamento automatico del paese"],"%s Width":["Larghezza %s"],"Upgrade":["Aggiornamento"],"Clear":["Chiaro"],"Select Color":["Seleziona colore"],"Primary Color":["Colore primario"],"Text Color":["Colore del testo"],"Field Spacing":["Spaziatura del campo"],"Small":["Piccolo"],"Large":["Grande"],"Left":["Sinistra"],"Center":["Centro"],"Right":["Destra"],"Color":["Colore"],"Background Color":["Colore di sfondo"],"Auto":["Auto"],"Default":["Predefinito"],"Normal":["Normale"],"%":["%"],"Top":["In alto"],"Bottom":["Fondo"],"Width":["Larghezza"],"Size":["Dimensione"],"EM":["EM"],"Padding":["Riempimento"],"Color 1":["Colore 1"],"Color 2":["Colore 2"],"Type":["Tipo"],"Linear":["Lineare"],"Radial":["Radiale"],"Location 1":["Posizione 1"],"Location 2":["Posizione 2"],"Angle":["Angolo"],"Classic":["Classico"],"Gradient":["Gradiente"],"Horizontal":["Orizzontale"],"Vertical":["Verticale"],"Background":["Sfondo"],"Cover":["Copertina"],"Contain":["Contenere"],"Layout":["Layout"],"Overlay":["Sovrapposizione"],"No Repeat":["Nessuna ripetizione"],"Overlay Opacity":["Opacit\u00e0 dell'overlay"],"Conditional Logic":["Logica Condizionale"],"Upgrade to the SureForms Starter Plan to create dynamic forms that adapt based on user input, offering a personalised and efficient form experience.":["Passa al piano Starter di SureForms per creare moduli dinamici che si adattano in base all'input dell'utente, offrendo un'esperienza modulare personalizzata ed efficiente."],"Enable Conditional Logic":["Abilita la logica condizionale"],"this field if":["questo campo se"],"Configure Conditions":["Configura condizioni"],"Premium":["Premium"],"Overlay Type":["Tipo di sovrapposizione"],"Image Overlay Color":["Colore di sovrapposizione dell'immagine"],"Image Position":["Posizione dell'immagine"],"Attachment":["Allegato"],"Fixed":["Fisso"],"Blend Mode":["Modalit\u00e0 di fusione"],"Multiply":["Moltiplica"],"Screen":["Schermo"],"Darken":["Scurisci"],"Lighten":["Alleggerire"],"Color Dodge":["Schiarisci colore"],"Saturation":["Saturazione"],"Repeat-x":["Ripeti-x"],"Repeat-y":["Ripeti-y"],"PX":["PX"],"Button":["Pulsante"],"Prefix Label":["Etichetta prefisso"],"Suffix Label":["Etichetta suffisso"],"Border Radius":["Raggio del bordo"],"Form Theme":["Tema del modulo"],"Select Gradient":["Seleziona sfumatura"],"Unlock Conditional Logic Editor":["Sblocca l'editor di logica condizionale"],"Rich Text Editor":["Editor di testo ricco"],"Read Only":["Solo lettura"],"Select Country":["Seleziona Paese"],"Default Country":["Paese predefinito"],"Subscription":["Abbonamento"],"One Time":["Una volta"],"Unique Entry":["Ingresso Unico"],"Maximum Characters":["Caratteri massimi"],"Textarea Height":["Altezza dell'area di testo"],"Minimum Selections":["Selezioni Minime"],"Maximum Selections":["Selezioni massime"],"Add Numeric Values to Options":["Aggiungi valori numerici alle opzioni"],"Single Choice Only":["Solo una scelta"],"Enable Dropdown Search":["Abilita la ricerca a discesa"],"Allow Multiple":["Consenti multipli"],"%1$s fields are required. Please configure these fields in the block settings.":["I campi %1$s sono obbligatori. Si prega di configurare questi campi nelle impostazioni del blocco."],"%1$s field is required. Please configure this field in the block settings.":["Il campo %1$s \u00e8 obbligatorio. Si prega di configurare questo campo nelle impostazioni del blocco."],"You need to configure a payment account to collect payments from this form. Please configure your payment provider to proceed.":["\u00c8 necessario configurare un account di pagamento per raccogliere i pagamenti da questo modulo. Si prega di configurare il proprio fornitore di pagamento per procedere."],"Configure Payment Account":["Configura l'account di pagamento"],"This is a placeholder for the Payment block. The actual payment fields for your configured payment provider(s) will only appear when you preview or publish the form.":["Questo \u00e8 un segnaposto per il blocco di pagamento. I campi di pagamento effettivi per il\/i fornitore\/i di pagamento configurato\/i appariranno solo quando visualizzi in anteprima o pubblichi il modulo."],"2 Payments":["2 Pagamenti"],"3 Payments":["3 Pagamenti"],"4 Payments":["4 Pagamenti"],"5 Payments":["5 Pagamenti"],"Never":["Mai"],"Stop Subscription After":["Interrompi l'abbonamento dopo"],"Choose when to automatically stop the subscription":["Scegli quando interrompere automaticamente l'abbonamento"],"Number of Payments":["Numero di pagamenti"],"Enter a number between 1 to 100":["Inserisci un numero tra 1 e 100"],"Form Field":["Campo del modulo"],"Payment Type":["Tipo di pagamento"],"Subscription Plan Name":["Nome del piano di abbonamento"],"Billing Interval":["Intervallo di fatturazione"],"Daily":["Quotidiano"],"Weekly":["Settimanale"],"Monthly":["Mensile"],"Quarterly":["Trimestrale"],"Yearly":["Annuale"],"Amount Type":["Tipo di importo"],"Fixed Amount":["Importo fisso"],"Dynamic Amount":["Importo Dinamico"],"Choose whether to charge a fixed amount or charge the amount based on user input in other form fields.":["Scegli se addebitare un importo fisso o addebitare l'importo in base all'input dell'utente in altri campi del modulo."],"Set the exact amount you want to charge. Users won\u2019t be able to change it":["Imposta l'importo esatto che desideri addebitare. Gli utenti non potranno modificarlo"],"Choose Amount Field":["Scegli il campo Importo"],"Select a field\u2026":["Seleziona un campo\u2026"],"Pick a field from your form like a number, dropdown, or multichoice whose value should decide the payment amount.":["Scegli un campo dal tuo modulo, come un numero, un menu a tendina o una scelta multipla, il cui valore dovrebbe determinare l'importo del pagamento."],"Minimum Amount":["Importo minimo"],"Set the minimum amount users can enter (0 for no minimum)":["Imposta l'importo minimo che gli utenti possono inserire (0 per nessun minimo)"],"Customer Name Field (Required)":["Campo Nome Cliente (Obbligatorio)"],"Customer Name Field (Optional)":["Campo Nome Cliente (Facoltativo)"],"Select the input field that contains the customer name (Required for subscriptions)":["Seleziona il campo di input che contiene il nome del cliente (Richiesto per gli abbonamenti)"],"Select the input field that contains the customer name":["Seleziona il campo di input che contiene il nome del cliente"],"Customer Email Field (Required)":["Campo Email Cliente (Obbligatorio)"],"Select the email field that contains the customer email":["Seleziona il campo email che contiene l'email del cliente"],"Payment":["Pagamento"],"%s - Order ID":["%s - ID Ordine"],"%s - Amount":["%s - Importo"],"%s - Customer Email":["%s - Email del cliente"],"%s - Customer Name":["%s - Nome del cliente"],"%s - Status":["%s - Stato"],"Button Alignment":["Allineamento del pulsante"],"Placeholder":["Segnaposto"],"Preselect this option":["Preseleziona questa opzione"],"Restrict Country Codes":["Limita i codici paese"],"Restriction Type":["Tipo di restrizione"],"Allow":["Permetti"],"Block":["Blocca"],"Select Allowed Countries":["Seleziona i Paesi consentiti"],"Choose countries\u2026":["Scegli i paesi\u2026"],"Choose which country codes users can select in the phone number field. Leave empty to allow all country codes.":["Scegli quali codici paese gli utenti possono selezionare nel campo del numero di telefono. Lascia vuoto per consentire tutti i codici paese."],"Select Blocked Countries":["Seleziona Paesi Bloccati"],"These countries will be hidden from the dropdown.":["Questi paesi saranno nascosti dal menu a tendina."],"Bulk Edit":["Modifica in blocco"],"Select Layout":["Seleziona layout"],"Number of Columns":["Numero di colonne"],"Validation Message for Duplicate":["Messaggio di convalida per duplicato"],"Click here to insert a form":["Fai clic qui per inserire un modulo"],"Inherit Form's Original Style":["Eredita lo stile originale del modulo"],"Text on Primary":["Testo su Primario"],"%s - Description":["%s - Descrizione"],"Upgrade to Unlock":["Aggiorna per sbloccare"],"Custom (Premium)":["Personalizzato (Premium)"],"Select a theme style for this form embed.":["Seleziona uno stile tema per questo modulo incorporato."],"Colors":["Colori"],"Advanced Styling":["Stile avanzato"],"Unlock Custom Styling":["Sblocca lo stile personalizzato"],"Switch to Custom Mode to take full control of your form's design and spacing.":["Passa alla Modalit\u00e0 Personalizzata per avere il pieno controllo del design e della spaziatura del tuo modulo."],"Full color control (buttons, fields, text)":["Controllo completo del colore (bottoni, campi, testo)"],"Row and column gap control":["Controllo dello spazio tra righe e colonne"],"Field spacing and layout precision":["Spaziatura dei campi e precisione del layout"],"Complete button styling":["Completare lo stile del pulsante"],"Payment Description":["Descrizione del pagamento"],"Shown on payment receipts and in your payment dashboard (Stripe and PayPal). Leave blank to use the default.":["Mostrato sulle ricevute di pagamento e nel tuo cruscotto dei pagamenti (Stripe e PayPal). Lascia vuoto per utilizzare il predefinito."],"Slug":["Lumaca"],"Auto-generated on save":["Generato automaticamente al salvataggio"],"This slug is already used by another field. It will revert to the previous value.":["Questo slug \u00e8 gi\u00e0 utilizzato da un altro campo. Torner\u00e0 al valore precedente."],"Changing the slug may break form submissions, conditional logic, integrations, or any other feature currently referencing this slug. You will need to update all such references manually.":["La modifica dello slug potrebbe interrompere l'invio dei moduli, la logica condizionale, le integrazioni o qualsiasi altra funzione che attualmente fa riferimento a questo slug. Dovrai aggiornare manualmente tutti questi riferimenti."],"Field Slug":["Slug del campo"],"Location Services":["Servizi di localizzazione"],"Unlock Address Autocomplete":["Sblocca il completamento automatico degli indirizzi"],"Upgrade to enable Google Address Autocomplete with interactive map preview, making address entry faster and more accurate for your users.":["Aggiorna per abilitare il completamento automatico degli indirizzi di Google con l'anteprima interattiva della mappa, rendendo l'inserimento degli indirizzi pi\u00f9 veloce e preciso per i tuoi utenti."],"Enable Google Autocomplete":["Abilita il completamento automatico di Google"],"Show Interactive Map":["Mostra mappa interattiva"],"Payments Per Page":["Pagamenti per pagina"],"Show Subscriptions Section":["Mostra la sezione Abbonamenti"],"Show a dedicated subscriptions section above payment history.":["Mostra una sezione dedicata agli abbonamenti sopra la cronologia dei pagamenti."],"Payment Dashboard":["Dashboard dei pagamenti"],"View your payments and manage subscriptions in a single dashboard.":["Visualizza i tuoi pagamenti e gestisci gli abbonamenti in un'unica dashboard."]}}} \ No newline at end of file +{"translation-revision-date":"2025-01-01T06:16:29+00:00","generator":"WP-CLI\/2.12.0","source":"assets\/build\/blocks.js","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","lang":"en","plural-forms":"nplurals=2; plural=(n != 1);"},"Settings":["Impostazioni"],"Search":["Cerca"],"Fields":["Campi"],"Image":["Immagine"],"Submit":["Invia"],"Required":["Richiesto"],"Form Title":["Titolo del modulo"],"Show":["Mostra"],"Hide":["Nascondi"],"Edit Form":["Modifica modulo"],"Icon":["Icona"],"Desktop":["Desktop"],"Medium":["Medio"],"Mobile":["Cellulare"],"Repeat":["Ripeti"],"Scroll":["Scorri"],"Tablet":["Tablet"],"Basic":["Base"],"(no title)":["(nessun titolo)"],"Select a Form":["Seleziona un modulo"],"No forms found\u2026":["Nessun modulo trovato\u2026"],"Choose":["Scegli"],"Create New":["Crea Nuovo"],"Change Form":["Modifica modulo"],"This form has been deleted or is unavailable.":["Questo modulo \u00e8 stato eliminato o non \u00e8 disponibile."],"Form Settings":["Impostazioni del modulo"],"Show Form Title on this Page":["Mostra il titolo del modulo su questa pagina"],"Note: For editing SureForms, please refer to the SureForms Editor - ":["Nota: Per modificare i SureForms, fare riferimento all'Editor di SureForms -"],"Field preview":["Anteprima del campo"],"General":["Generale"],"Style":["Stile"],"Advanced":["Avanzato"],"No tags available":["Nessun tag disponibile"],"Device":["Dispositivo"],"Select Shortcodes":["Seleziona i codici brevi"],"Page Break Label":["Etichetta di interruzione di pagina"],"Next":["Avanti"],"Back":["Indietro"],"Reset":["Reimposta"],"Generic tags":["Tag generici"],"Pixel":["Pixel"],"Em":["Em"],"Select Units":["Seleziona unit\u00e0"],"%s units":["%s unit\u00e0"],"Margin":["Margine"],"Attributes":["Attributi"],"Input Pattern":["Schema di input"],"None":["Nessuno"],"(###) ###-####":["(###) ###-####"],"(##) ####-####":["(##) ####-####"],"27\/08\/2024":["27\/08\/2024"],"23:59:59":["23:59:59"],"27\/08\/2024 23:59:59":["27\/08\/2024 23:59:59"],"Custom":["Personalizzato"],"Custom Mask":["Maschera personalizzata"],"Please check the documentation to manage custom input pattern ":["Si prega di controllare la documentazione per gestire il modello di input personalizzato"],"here":["qui"],"Default Value":["Valore predefinito"],"Error Message":["Messaggio di errore"],"Help Text":["Testo di aiuto"],"Number Format":["Formato numero"],"US Style (Eg: 9,999.99)":["Stile USA (Es: 9.999,99)"],"EU Style (Eg: 9.999,99)":["Stile UE (Es: 9.999,99)"],"Minimum Value":["Valore minimo"],"Maximum Value":["Valore massimo"],"Please check the Minimum and Maximum value":["Si prega di controllare il valore minimo e massimo"],"Enable Email Confirmation":["Abilita la conferma email"],"Checked by Default":["Selezionato per impostazione predefinita"],"Error message":["Messaggio di errore"],"Checked by default":["Selezionato per impostazione predefinita"],"Please add a option props to MultiButtonsControl":["Si prega di aggiungere un'opzione props a MultiButtonsControl"],"Icon Library":["Libreria di icone"],"Close":["Chiudi"],"All Icons":["Tutte le icone"],"Other":["Altro"],"No Icons Found":["Nessuna icona trovata"],"Insert Icon":["Inserisci icona"],"Change Icon":["Cambia icona"],"Choose Icon":["Scegli icona"],"Confirm":["Conferma"],"Cancel":["Annulla"],"Processing\u2026":["Elaborazione\u2026"],"Select Video":["Seleziona video"],"Change Video":["Cambia video"],"Select Lottie Animation":["Seleziona animazione Lottie"],"Change Lottie Animation":["Cambia animazione Lottie"],"Upload SVG":["Carica SVG"],"Change SVG":["Cambia SVG"],"Select Image":["Seleziona immagine"],"Change Image":["Cambia immagine"],"Upload SVG?":["Caricare SVG?"],"Upload SVG can be potentially risky. Are you sure?":["Caricare SVG pu\u00f2 essere potenzialmente rischioso. Sei sicuro?"],"Upload Anyway":["Carica comunque"],"Bulk Add":["Aggiunta in blocco"],"Bulk Add Options":["Aggiungi opzioni in blocco"],"Enter each option on a new line.":["Inserisci ogni opzione su una nuova riga."],"Insert Options":["Inserisci opzioni"],"Full Width":["Larghezza completa"],"Option Type":["Tipo di opzione"],"Edit Options":["Opzioni di modifica"],"Add New Option":["Aggiungi nuova opzione"],"ADD":["AGGIUNGI"],"Enable Auto Country Detection":["Abilita il rilevamento automatico del paese"],"%s Width":["Larghezza %s"],"Upgrade":["Aggiornamento"],"Clear":["Chiaro"],"Select Color":["Seleziona colore"],"Primary Color":["Colore primario"],"Text Color":["Colore del testo"],"Field Spacing":["Spaziatura del campo"],"Small":["Piccolo"],"Large":["Grande"],"Left":["Sinistra"],"Center":["Centro"],"Right":["Destra"],"Color":["Colore"],"Background Color":["Colore di sfondo"],"Auto":["Auto"],"Default":["Predefinito"],"Normal":["Normale"],"%":["%"],"Top":["In alto"],"Bottom":["Fondo"],"Width":["Larghezza"],"Size":["Dimensione"],"EM":["EM"],"Padding":["Riempimento"],"Color 1":["Colore 1"],"Color 2":["Colore 2"],"Type":["Tipo"],"Linear":["Lineare"],"Radial":["Radiale"],"Location 1":["Posizione 1"],"Location 2":["Posizione 2"],"Angle":["Angolo"],"Classic":["Classico"],"Gradient":["Gradiente"],"Horizontal":["Orizzontale"],"Vertical":["Verticale"],"Background":["Sfondo"],"Cover":["Copertina"],"Contain":["Contenere"],"Layout":["Layout"],"Overlay":["Sovrapposizione"],"No Repeat":["Nessuna ripetizione"],"Overlay Opacity":["Opacit\u00e0 dell'overlay"],"Conditional Logic":["Logica Condizionale"],"Upgrade to the SureForms Starter Plan to create dynamic forms that adapt based on user input, offering a personalised and efficient form experience.":["Passa al piano Starter di SureForms per creare moduli dinamici che si adattano in base all'input dell'utente, offrendo un'esperienza modulare personalizzata ed efficiente."],"Enable Conditional Logic":["Abilita la logica condizionale"],"this field if":["questo campo se"],"Configure Conditions":["Configura condizioni"],"Premium":["Premium"],"Overlay Type":["Tipo di sovrapposizione"],"Image Overlay Color":["Colore di sovrapposizione dell'immagine"],"Image Position":["Posizione dell'immagine"],"Attachment":["Allegato"],"Fixed":["Fisso"],"Blend Mode":["Modalit\u00e0 di fusione"],"Multiply":["Moltiplica"],"Screen":["Schermo"],"Darken":["Scurisci"],"Lighten":["Alleggerire"],"Color Dodge":["Schiarisci colore"],"Saturation":["Saturazione"],"Repeat-x":["Ripeti-x"],"Repeat-y":["Ripeti-y"],"PX":["PX"],"Button":["Pulsante"],"Prefix Label":["Etichetta prefisso"],"Suffix Label":["Etichetta suffisso"],"Border Radius":["Raggio del bordo"],"Form Theme":["Tema del modulo"],"Select Gradient":["Seleziona sfumatura"],"Unlock Conditional Logic Editor":["Sblocca l'editor di logica condizionale"],"Rich Text Editor":["Editor di testo ricco"],"Read Only":["Solo lettura"],"Select Country":["Seleziona Paese"],"Default Country":["Paese predefinito"],"Subscription":["Abbonamento"],"One Time":["Una volta"],"Unique Entry":["Ingresso Unico"],"Maximum Characters":["Caratteri massimi"],"Textarea Height":["Altezza dell'area di testo"],"Minimum Selections":["Selezioni Minime"],"Maximum Selections":["Selezioni massime"],"Add Numeric Values to Options":["Aggiungi valori numerici alle opzioni"],"Single Choice Only":["Solo una scelta"],"Enable Dropdown Search":["Abilita la ricerca a discesa"],"Allow Multiple":["Consenti multipli"],"%1$s fields are required. Please configure these fields in the block settings.":["I campi %1$s sono obbligatori. Si prega di configurare questi campi nelle impostazioni del blocco."],"%1$s field is required. Please configure this field in the block settings.":["Il campo %1$s \u00e8 obbligatorio. Si prega di configurare questo campo nelle impostazioni del blocco."],"You need to configure a payment account to collect payments from this form. Please configure your payment provider to proceed.":["\u00c8 necessario configurare un account di pagamento per raccogliere i pagamenti da questo modulo. Si prega di configurare il proprio fornitore di pagamento per procedere."],"Configure Payment Account":["Configura l'account di pagamento"],"This is a placeholder for the Payment block. The actual payment fields for your configured payment provider(s) will only appear when you preview or publish the form.":["Questo \u00e8 un segnaposto per il blocco di pagamento. I campi di pagamento effettivi per il\/i fornitore\/i di pagamento configurato\/i appariranno solo quando visualizzi in anteprima o pubblichi il modulo."],"2 Payments":["2 Pagamenti"],"3 Payments":["3 Pagamenti"],"4 Payments":["4 Pagamenti"],"5 Payments":["5 Pagamenti"],"Never":["Mai"],"Stop Subscription After":["Interrompi l'abbonamento dopo"],"Choose when to automatically stop the subscription":["Scegli quando interrompere automaticamente l'abbonamento"],"Number of Payments":["Numero di pagamenti"],"Enter a number between 1 to 100":["Inserisci un numero tra 1 e 100"],"Form Field":["Campo del modulo"],"Payment Type":["Tipo di pagamento"],"Subscription Plan Name":["Nome del piano di abbonamento"],"Billing Interval":["Intervallo di fatturazione"],"Daily":["Quotidiano"],"Weekly":["Settimanale"],"Monthly":["Mensile"],"Quarterly":["Trimestrale"],"Yearly":["Annuale"],"Amount Type":["Tipo di importo"],"Fixed Amount":["Importo fisso"],"Dynamic Amount":["Importo Dinamico"],"Choose whether to charge a fixed amount or charge the amount based on user input in other form fields.":["Scegli se addebitare un importo fisso o addebitare l'importo in base all'input dell'utente in altri campi del modulo."],"Set the exact amount you want to charge. Users won\u2019t be able to change it":["Imposta l'importo esatto che desideri addebitare. Gli utenti non potranno modificarlo"],"Choose Amount Field":["Scegli il campo Importo"],"Select a field\u2026":["Seleziona un campo\u2026"],"Pick a field from your form like a number, dropdown, or multichoice whose value should decide the payment amount.":["Scegli un campo dal tuo modulo, come un numero, un menu a tendina o una scelta multipla, il cui valore dovrebbe determinare l'importo del pagamento."],"Minimum Amount":["Importo minimo"],"Set the minimum amount users can enter (0 for no minimum)":["Imposta l'importo minimo che gli utenti possono inserire (0 per nessun minimo)"],"Customer Name Field (Required)":["Campo Nome Cliente (Obbligatorio)"],"Customer Name Field (Optional)":["Campo Nome Cliente (Facoltativo)"],"Select the input field that contains the customer name (Required for subscriptions)":["Seleziona il campo di input che contiene il nome del cliente (Richiesto per gli abbonamenti)"],"Select the input field that contains the customer name":["Seleziona il campo di input che contiene il nome del cliente"],"Customer Email Field (Required)":["Campo Email Cliente (Obbligatorio)"],"Select the email field that contains the customer email":["Seleziona il campo email che contiene l'email del cliente"],"Payment":["Pagamento"],"%s - Order ID":["%s - ID Ordine"],"%s - Amount":["%s - Importo"],"%s - Customer Email":["%s - Email del cliente"],"%s - Customer Name":["%s - Nome del cliente"],"%s - Status":["%s - Stato"],"Button Alignment":["Allineamento del pulsante"],"Placeholder":["Segnaposto"],"Preselect this option":["Preseleziona questa opzione"],"Restrict Country Codes":["Limita i codici paese"],"Restriction Type":["Tipo di restrizione"],"Allow":["Permetti"],"Block":["Blocca"],"Select Allowed Countries":["Seleziona i Paesi consentiti"],"Choose countries\u2026":["Scegli i paesi\u2026"],"Choose which country codes users can select in the phone number field. Leave empty to allow all country codes.":["Scegli quali codici paese gli utenti possono selezionare nel campo del numero di telefono. Lascia vuoto per consentire tutti i codici paese."],"Select Blocked Countries":["Seleziona Paesi Bloccati"],"These countries will be hidden from the dropdown.":["Questi paesi saranno nascosti dal menu a tendina."],"Bulk Edit":["Modifica in blocco"],"Select Layout":["Seleziona layout"],"Number of Columns":["Numero di colonne"],"Validation Message for Duplicate":["Messaggio di convalida per duplicato"],"Click here to insert a form":["Fai clic qui per inserire un modulo"],"Inherit Form's Original Style":["Eredita lo stile originale del modulo"],"Text on Primary":["Testo su Primario"],"%s - Description":["%s - Descrizione"],"Upgrade to Unlock":["Aggiorna per sbloccare"],"Custom (Premium)":["Personalizzato (Premium)"],"Select a theme style for this form embed.":["Seleziona uno stile tema per questo modulo incorporato."],"Colors":["Colori"],"Advanced Styling":["Stile avanzato"],"Unlock Custom Styling":["Sblocca lo stile personalizzato"],"Switch to Custom Mode to take full control of your form's design and spacing.":["Passa alla Modalit\u00e0 Personalizzata per avere il pieno controllo del design e della spaziatura del tuo modulo."],"Full color control (buttons, fields, text)":["Controllo completo del colore (bottoni, campi, testo)"],"Row and column gap control":["Controllo dello spazio tra righe e colonne"],"Field spacing and layout precision":["Spaziatura dei campi e precisione del layout"],"Complete button styling":["Completare lo stile del pulsante"],"Payment Description":["Descrizione del pagamento"],"Shown on payment receipts and in your payment dashboard (Stripe and PayPal). Leave blank to use the default.":["Mostrato sulle ricevute di pagamento e nel tuo cruscotto dei pagamenti (Stripe e PayPal). Lascia vuoto per utilizzare il predefinito."],"Slug":["Lumaca"],"Auto-generated on save":["Generato automaticamente al salvataggio"],"This slug is already used by another field. It will revert to the previous value.":["Questo slug \u00e8 gi\u00e0 utilizzato da un altro campo. Torner\u00e0 al valore precedente."],"Changing the slug may break form submissions, conditional logic, integrations, or any other feature currently referencing this slug. You will need to update all such references manually.":["La modifica dello slug potrebbe interrompere l'invio dei moduli, la logica condizionale, le integrazioni o qualsiasi altra funzione che attualmente fa riferimento a questo slug. Dovrai aggiornare manualmente tutti questi riferimenti."],"Field Slug":["Slug del campo"],"Location Services":["Servizi di localizzazione"],"Unlock Address Autocomplete":["Sblocca il completamento automatico degli indirizzi"],"Upgrade to enable Google Address Autocomplete with interactive map preview, making address entry faster and more accurate for your users.":["Aggiorna per abilitare il completamento automatico degli indirizzi di Google con l'anteprima interattiva della mappa, rendendo l'inserimento degli indirizzi pi\u00f9 veloce e preciso per i tuoi utenti."],"Enable Google Autocomplete":["Abilita il completamento automatico di Google"],"Show Interactive Map":["Mostra mappa interattiva"],"Payments Per Page":["Pagamenti per pagina"],"Show Subscriptions Section":["Mostra la sezione Abbonamenti"],"Show a dedicated subscriptions section above payment history.":["Mostra una sezione dedicata agli abbonamenti sopra la cronologia dei pagamenti."],"Payment Dashboard":["Dashboard dei pagamenti"],"View your payments and manage subscriptions in a single dashboard.":["Visualizza i tuoi pagamenti e gestisci gli abbonamenti in un'unica dashboard."],"Dynamic Default Value":["Valore predefinito dinamico"]}}} \ No newline at end of file diff --git a/languages/sureforms-it_IT-51635fe6489fc8288d603fe596c755ca.json b/languages/sureforms-it_IT-51635fe6489fc8288d603fe596c755ca.json index 5e0b1b760..a090ecf27 100644 --- a/languages/sureforms-it_IT-51635fe6489fc8288d603fe596c755ca.json +++ b/languages/sureforms-it_IT-51635fe6489fc8288d603fe596c755ca.json @@ -1 +1 @@ -{"translation-revision-date":"2025-01-01T06:16:29+00:00","generator":"WP-CLI\/2.12.0","source":"assets\/build\/settings.js","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","lang":"en","plural-forms":"nplurals=2; plural=(n != 1);"},"Dashboard":["Cruscotto"],"Settings":["Impostazioni"],"Entries":["Voci"],"Activated":["Attivato"],"Activate":["Attiva"],"Monday":["Luned\u00ec"],"Forms":["Moduli"],"GitHub":["GitHub"],"General":["Generale"],"Other":["Altro"],"Confirm":["Conferma"],"Cancel":["Annulla"],"Install":["Installa"],"Plugin Installation failed, Please try again later.":["Installazione del plugin fallita, per favore riprova pi\u00f9 tardi."],"Plugin activation failed, Please try again later.":["Attivazione del plugin fallita, riprova pi\u00f9 tardi."],"Integrations":["Integrazioni"],"What's New?":["Novit\u00e0?"],"Core":["Nucleo"],"Unlicensed":["Senza licenza"],"Connecting\u2026":["Connessione in corso\u2026"],"Install & Activate":["Installa e attiva"],"Send Email To":["Invia email a"],"Google reCAPTCHA":["Google reCAPTCHA"],"hCaptcha":["hCaptcha"],"reCAPTCHA v2 Invisible":["reCAPTCHA v2 Invisibile"],"reCAPTCHA v3":["reCAPTCHA v3"],"Validations":["Convalide"],"Spam Protection":["Protezione antispam"],"Email Summaries":["Riepiloghi email"],"Tuesday":["Marted\u00ec"],"Wednesday":["Mercoled\u00ec"],"Thursday":["Gioved\u00ec"],"Friday":["Venerd\u00ec"],"Saturday":["Sabato"],"Sunday":["Domenica"],"Test Email":["Email di prova"],"Schedule Reports":["Programma rapporti"],"IP Logging":["Registrazione IP"],"If this option is turned on, the user's IP address will be saved with the form data":["Se questa opzione \u00e8 attivata, l'indirizzo IP dell'utente verr\u00e0 salvato con i dati del modulo"],"Confirmation Email Mismatch Message":["Messaggio di mancata corrispondenza dell'email di conferma"],"%s represents the minimum input value. For example: \"Minimum value is 10.\"":["%s rappresenta il valore minimo di input. Ad esempio: \"Il valore minimo \u00e8 10.\""],"%s represents the maximum input value. For example: \"Maximum value is 100.\"":["%s rappresenta il valore massimo di input. Ad esempio: \"Il valore massimo \u00e8 100.\""],"%s represents the minimum selections needed. For example: \u201cMinimum 2 selections are required.\u201d":["%s rappresenta le selezioni minime necessarie. Ad esempio: \"Sono necessarie almeno 2 selezioni.\""],"%s represents the maximum selections allowed. For example: \u201cMaximum 4 selections are allowed.\u201d":["%s rappresenta il numero massimo di selezioni consentite. Ad esempio: \"Sono consentite al massimo 4 selezioni.\""],"%s represents the minimum choices needed. For example: \u201cMinimum 1 selection is required.\u201d":["%s rappresenta le scelte minime necessarie. Ad esempio: \"\u00c8 richiesta almeno 1 selezione.\""],"%s represents the maximum choices allowed. For example: \u201cMaximum 3 selections are allowed.\u201d":["%s rappresenta il numero massimo di scelte consentite. Ad esempio: \"Sono consentite un massimo di 3 selezioni.\""]," Error Message":["Messaggio di errore"],"Auto":["Auto"],"Light":["Luce"],"Dark":["Scuro"],"Turnstile":["Tornello"],"Honeypot":["Trappola"],"Get Keys":["Ottieni chiavi"],"Documentation":["Documentazione"],"Site Key":["Chiave del sito"],"Secret Key":["Chiave segreta"],"Cloudflare Turnstile":["Cloudflare Turnstile"],"Appearance Mode":["Modalit\u00e0 Aspetto"],"Enable Honeypot Security":["Abilita la Sicurezza Honeypot"],"Enable Honeypot Security for better spam protection":["Abilita la Sicurezza Honeypot per una migliore protezione dallo spam"],"This field cannot be left blank.":["Questo campo non pu\u00f2 essere lasciato vuoto."],"OttoKit":["OttoKit"],"Connect with OttoKit":["Connettiti con OttoKit"],"reCAPTCHA":["reCAPTCHA"],"Ready to go beyond free plan?":["Pronto a superare il piano gratuito?"],"Upgrade now":["Aggiorna ora"],"and unlock the full power of SureForms!":["e sblocca tutta la potenza di SureForms!"],"Upgrade SureForms":["Aggiorna SureForms"],"Upgrade Now":["Aggiorna ora"],"Form Validation":["Validazione del modulo"],"Required Error Messages":["Messaggi di errore richiesti"],"Other Error Messages":["Altri messaggi di errore"],"Input Field Unique":["Campo di input univoco"],"Email Field Unique":["Campo email univoco"],"Invalid URL":["URL non valido"],"Phone Field Unique":["Campo Telefono Unico"],"Invalid Field Number Block":["Blocco Numero Campo Non Valido"],"Invalid Email":["Email non valido"],"Number Minimum Value":["Valore Minimo Numero"],"Number Maximum Value":["Valore Massimo Numero"],"Dropdown Minimum Selections":["Selezioni Minime del Menu a Tendina"],"Dropdown Maximum Selections":["Selezioni massime del menu a tendina"],"Multiple Choice Minimum Selections":["Selezioni Minime a Scelta Multipla"],"Multiple Choice Maximum Selections":["Selezioni massime a scelta multipla"],"Input Field":["Campo di input"],"Email Field":["Campo Email"],"URL Field":["Campo URL"],"Phone Field":["Campo Telefono"],"Textarea Field":["Campo di testo"],"Checkbox Field":["Campo di selezione"],"Dropdown Field":["Campo a discesa"],"Multiple Choice Field":["Campo a scelta multipla"],"Address Field":["Campo Indirizzo"],"Number Field":["Campo numerico"],"reCAPTCHA v2":["reCAPTCHA v2"],"To enable reCAPTCHA feature on your SureForms Please enable reCAPTCHA option on your blocks setting and select version. Add google reCAPTCHA secret and site key here. reCAPTCHA will be added to your page on front-end.":["Per abilitare la funzione reCAPTCHA su SureForms, attiva l'opzione reCAPTCHA nelle impostazioni dei tuoi blocchi e seleziona la versione. Aggiungi qui la chiave segreta e la chiave del sito di Google reCAPTCHA. reCAPTCHA verr\u00e0 aggiunto alla tua pagina nel front-end."],"Enter your %s here":["Inserisci qui il tuo %s"],"To enable hCAPTCHA, please add your site key and secret key. Configure these settings within the individual form.":["Per abilitare hCAPTCHA, aggiungi la tua chiave del sito e la chiave segreta. Configura queste impostazioni all'interno del modulo individuale."],"To enable Cloudflare Turnstile, please add your site key and secret key. Configure these settings within the individual form.":["Per abilitare Cloudflare Turnstile, aggiungi la tua chiave del sito e la chiave segreta. Configura queste impostazioni all'interno del modulo individuale."],"Save":["Salva"],"Anonymous Analytics":["Analisi Anonime"],"Learn More":["Scopri di pi\u00f9"],"Admin Notification":["Notifica dell'amministratore"],"Enable Admin Notification":["Abilita la Notifica Amministratore"],"Admin notifications keep you informed about new form entries since your last visit.":["Le notifiche dell'amministratore ti tengono informato sui nuovi invii di moduli dalla tua ultima visita."],"Continue":["Continua"],"Get Started":["Inizia"],"Integration":["Integrazione"],"Connect Native Integrations with SureForms":["Collega le integrazioni native con SureForms"],"Unlock powerful integrations in the Premium plan to automate your workflows and connect SureForms directly with your favourite tools.":["Sblocca potenti integrazioni nel piano Premium per automatizzare i tuoi flussi di lavoro e collegare SureForms direttamente con i tuoi strumenti preferiti."],"Send form submissions straight to CRMs, email, and marketing platforms":["Invia le sottomissioni dei moduli direttamente ai CRM, email e piattaforme di marketing"],"Automate repetitive tasks with seamless data syncing":["Automatizza le attivit\u00e0 ripetitive con una sincronizzazione dei dati senza interruzioni"],"Access exclusive native integrations for faster workflows":["Accedi a integrazioni native esclusive per flussi di lavoro pi\u00f9 veloci"],"Payments":["Pagamenti"],"Stripe account disconnected successfully.":["Account Stripe disconnesso con successo."],"Failed to create webhook.":["Impossibile creare il webhook."],"Failed to connect to Stripe.":["Connessione a Stripe non riuscita."],"Webhook":["Webhook"],"Knowledge Base":["Base di conoscenza"],"What\u2019s New":["Novit\u00e0"],"delete":["elimina"],"Please type \"%s\" in the input box":["Per favore digita \"%s\" nella casella di input"],"To confirm, type \"%s\" in the box below:":["Per confermare, digita \"%s\" nella casella sottostante:"],"Type \"%s\"":["Digita \"%s\""],"Go to OttoKit Settings":["Vai alle Impostazioni di OttoKit"],"USD - US Dollar":["USD - Dollaro statunitense"],"Payment Mode":["Modalit\u00e0 di pagamento"],"Test Mode":["Modalit\u00e0 di test"],"Live Mode":["Modalit\u00e0 Live"],"General Settings":["Impostazioni generali"],"Set up email summaries, admin alerts, and data preferences to manage your forms with ease.":["Imposta i riepiloghi delle email, gli avvisi amministrativi e le preferenze sui dati per gestire i tuoi moduli con facilit\u00e0."],"Customize default error messages shown when users submit invalid or incomplete form entries.":["Personalizza i messaggi di errore predefiniti mostrati quando gli utenti inviano voci di modulo non valide o incomplete."],"Enable spam protection for your forms using CAPTCHA services or honeypot security.":["Abilita la protezione antispam per i tuoi moduli utilizzando servizi CAPTCHA o la sicurezza honeypot."],"Connect and manage your payment gateways to securely accept transactions through your forms.":["Collega e gestisci i tuoi gateway di pagamento per accettare transazioni in modo sicuro attraverso i tuoi moduli."],"1% transaction and payment gateway fees apply.":["Si applicano commissioni di transazione e gateway di pagamento dell'1%."],"2.9% transaction and payment gateway fees apply. Activate license to reduce transaction fees.":["Si applicano commissioni di transazione e gateway di pagamento del 2,9%. Attiva la licenza per ridurre le commissioni di transazione."],"2.9% transaction and payment gateway fees apply.":["Si applicano commissioni di transazione e gateway di pagamento del 2,9%."],"Please visit %1$s, delete an unused webhook, then click below to retry.":["Si prega di visitare %1$s, eliminare un webhook non utilizzato, quindi fare clic qui sotto per riprovare."],"SureForms could not create a webhook because your Stripe account has run out of free slots. Webhooks are needed to receive updates about payments.":["SureForms non \u00e8 riuscito a creare un webhook perch\u00e9 il tuo account Stripe ha esaurito gli slot gratuiti. I webhook sono necessari per ricevere aggiornamenti sui pagamenti."],"Stripe Dashboard":["Dashboard di Stripe"],"Creating\u2026":["Creando\u2026"],"Create Webhook":["Crea Webhook"],"Successfully connected to Stripe!":["Connessione a Stripe riuscita!"],"Invalid response from server. Please try again.":["Risposta non valida dal server. Per favore riprova."],"Failed to disconnect Stripe account.":["Impossibile disconnettere l'account Stripe."],"Webhook created successfully!":["Webhook creato con successo!"],"Select Currency":["Seleziona valuta"],"Select the default currency for payment forms.":["Seleziona la valuta predefinita per i moduli di pagamento."],"Connection Status":["Stato della connessione"],"Disconnect Stripe Account":["Disconnetti l'account Stripe"],"Are you sure you want to disconnect your Stripe account? This will stop all active payments, subscriptions, and form transactions connected to this account.":["Sei sicuro di voler scollegare il tuo account Stripe? Questo interromper\u00e0 tutti i pagamenti attivi, gli abbonamenti e le transazioni dei moduli collegati a questo account."],"Disconnect":["Disconnetti"],"Disconnecting\u2026":["Disconnessione in corso\u2026"],"Webhook successfully connected, all Stripe events are being tracked.":["Webhook collegato con successo, tutti gli eventi di Stripe vengono tracciati."],"Connect your Stripe account to start accepting payments through your forms.":["Collega il tuo account Stripe per iniziare ad accettare pagamenti tramite i tuoi moduli."],"Connect to Stripe":["Connetti a Stripe"],"Securely connect to Stripe with just a few clicks to begin accepting payments! ":["Collegati in modo sicuro a Stripe con pochi clic per iniziare ad accettare pagamenti!"],"Payment Methods":["Metodi di pagamento"],"Test mode allows you to process payments without real charges. Switch to Live mode for actual transactions.":["La modalit\u00e0 di test ti consente di elaborare pagamenti senza addebiti reali. Passa alla modalit\u00e0 Live per le transazioni effettive."],"General Payment Settings":["Impostazioni generali di pagamento"],"These settings apply to all payment gateways.":["Queste impostazioni si applicano a tutti i gateway di pagamento."],"Stripe Settings":["Impostazioni di Stripe"],"Left ($100)":["Sinistra ($100)"],"Right (100$)":["Destra (100$)"],"Left Space ($ 100)":["Spazio Sinistro ($ 100)"],"Right Space (100 $)":["Spazio destro (100 $)"],"Currency Sign Position":["Posizione del simbolo di valuta"],"Select the position of the currency symbol relative to the amount.":["Seleziona la posizione del simbolo della valuta rispetto all'importo."],"Learn":["Impara"],"Enable email summaries":["Abilita i riepiloghi email"],"Enable IP logging":["Abilita la registrazione IP"],"Turn on Admin Notification from here.":["Attiva la notifica amministratore da qui."],"Send entries to 100+ popular apps.":["Invia voci a oltre 100 app popolari."],"Build automated workflows that run instantly.":["Crea flussi di lavoro automatizzati che vengono eseguiti istantaneamente."],"Create custom app integrations using our Custom App feature.":["Crea integrazioni di app personalizzate utilizzando la nostra funzione App personalizzata."],"Keep your tools in sync automatically.":["Mantieni i tuoi strumenti sincronizzati automaticamente."],"This will install and activate OttoKit on your WordPress site to enable automation features.":["Questo installer\u00e0 e attiver\u00e0 OttoKit sul tuo sito WordPress per abilitare le funzionalit\u00e0 di automazione."],"Automate Your Forms with OttoKit":["Automatizza i tuoi moduli con OttoKit"],"Every form submission should trigger something \u2014 a Slack alert, a CRM lead, a follow-up email, or a new row in Google Sheets.":["Ogni invio di modulo dovrebbe attivare qualcosa: un avviso Slack, un lead CRM, un'email di follow-up o una nuova riga in Google Sheets."],"MCP":["MCP"],"Configure AI client permissions and MCP server settings.":["Configura le autorizzazioni del client AI e le impostazioni del server MCP."],"View documentation":["Visualizza la documentazione"],"Copy to clipboard":["Copia negli appunti"],"Claude Desktop":["Claude Desktop"],"~\/Library\/Application Support\/Claude\/claude_desktop_config.json (macOS) or %APPDATA%\\Claude\\claude_desktop_config.json (Windows)":["~\/Library\/Application Support\/Claude\/claude_desktop_config.json (macOS) o %APPDATA%\\Claude\\claude_desktop_config.json (Windows)"],"Claude Code":["Codice Claude"],".mcp.json (project) or ~\/.claude.json (global)":[".mcp.json (progetto) o ~\/.claude.json (globale)"],"Cursor":["Cursore"],"~\/.cursor\/mcp.json":["~\/.cursor\/mcp.json"],"VS Code (Copilot)":["VS Code (Copilot)"],".vscode\/mcp.json (project) or settings.json > mcp.servers (global)":[".vscode\/mcp.json (progetto) o settings.json > mcp.servers (globale)"],"~\/.continue\/config.yaml or config.json":["~\/.continue\/config.yaml o config.json"],"Your client's MCP configuration file":["Il file di configurazione MCP del tuo cliente"],"Connect Your AI Client":["Collega il tuo client AI"],"AI Client":["Cliente AI"],"Create an Application Password \u2014 ":["Crea una Password per l'Applicazione \u2014"],"Open Application Passwords":["Apri Password Applicazioni"],"Or use this CLI command to add the server quickly (you will still need to set the environment variables):":["Oppure usa questo comando CLI per aggiungere rapidamente il server (dovrai comunque impostare le variabili d'ambiente):"],"Copy the JSON config below into: ":["Copia la configurazione JSON qui sotto in:"],"Replace \"your-application-password\" with the password from Step 1.":["Sostituisci \"your-application-password\" con la password del Passo 1."],"WP_API_URL \u2014 your site's MCP endpoint. WP_API_USERNAME \u2014 your WordPress username. WP_API_PASSWORD \u2014 the application password you generated.":["WP_API_URL \u2014 l'endpoint MCP del tuo sito. WP_API_USERNAME \u2014 il tuo nome utente WordPress. WP_API_PASSWORD \u2014 la password dell'applicazione che hai generato."],"View setup docs":["Visualizza i documenti di configurazione"],"The MCP Adapter plugin is installed but not active. Activate it to configure MCP settings.":["Il plugin MCP Adapter \u00e8 installato ma non attivo. Attivalo per configurare le impostazioni MCP."],"The MCP Adapter plugin is required to connect AI clients to your forms. Download and install it from GitHub, then activate it.":["Il plugin MCP Adapter \u00e8 necessario per connettere i client AI ai tuoi moduli. Scaricalo e installalo da GitHub, quindi attivalo."],"Download the latest release from":["Scarica l'ultima versione da"],"Install the plugin via Plugins > Add New Plugin > Upload Plugin.":["Installa il plugin tramite Plugin > Aggiungi nuovo plugin > Carica plugin."],"Activate the MCP Adapter plugin.":["Attiva il plugin dell'adattatore MCP."],"Activating\u2026":["Attivazione in corso\u2026"],"Activate MCP Adapter":["Attiva l'adattatore MCP"],"Download MCP Adapter":["Scarica l'adattatore MCP"],"Experimental":["Sperimentale"],"Enable Abilities":["Abilita Abilit\u00e0"],"Register SureForms abilities with the WordPress Abilities API. When enabled, AI clients can list, read, create, edit, and delete your forms and entries. When disabled, no abilities are registered and AI clients cannot perform any actions on your forms.":["Registra le abilit\u00e0 di SureForms con l'API Abilities di WordPress. Quando \u00e8 abilitato, i client AI possono elencare, leggere, creare, modificare e eliminare i tuoi moduli e le voci. Quando \u00e8 disabilitato, nessuna abilit\u00e0 \u00e8 registrata e i client AI non possono eseguire alcuna azione sui tuoi moduli."],"Abilities API \u2014 Edit":["API delle abilit\u00e0 \u2014 Modifica"],"Enable Edit Abilities":["Abilita le capacit\u00e0 di modifica"],"When enabled, AI clients can create new forms, update form titles, fields, and settings, duplicate forms, and modify entry statuses. When disabled, these abilities are unregistered and AI clients can only read your data.":["Quando abilitato, i client AI possono creare nuovi moduli, aggiornare i titoli dei moduli, i campi e le impostazioni, duplicare i moduli e modificare gli stati delle voci. Quando disabilitato, queste capacit\u00e0 vengono annullate e i client AI possono solo leggere i tuoi dati."],"Abilities API \u2014 Delete":["API delle abilit\u00e0 \u2014 Elimina"],"Enable Delete Abilities":["Abilita Elimina Abilit\u00e0"],"When enabled, AI clients can permanently delete forms and entries. Deleted data cannot be recovered. When disabled, delete abilities are unregistered and AI clients cannot remove any data.":["Quando abilitato, i client AI possono eliminare permanentemente moduli e voci. I dati eliminati non possono essere recuperati. Quando disabilitato, le capacit\u00e0 di eliminazione vengono annullate e i client AI non possono rimuovere alcun dato."],"MCP Server":["Server MCP"],"Enable MCP Server":["Abilita server MCP"],"Creates a dedicated SureForms MCP endpoint that AI clients like Claude can connect to. When disabled, the endpoint is removed and external AI clients cannot discover or call any SureForms abilities.":["Crea un endpoint SureForms MCP dedicato a cui i clienti AI come Claude possono connettersi. Quando \u00e8 disabilitato, l'endpoint viene rimosso e i clienti AI esterni non possono scoprire o chiamare alcuna funzionalit\u00e0 di SureForms."],"Learn more":["Scopri di pi\u00f9"],"MCP Adapter Required":["Adattatore MCP richiesto"],"Google Maps":["Google Maps"],"Configure Google Maps API key for address autocomplete and map preview.":["Configura la chiave API di Google Maps per il completamento automatico degli indirizzi e l'anteprima della mappa."],"Help shape the future of SureForms":["Aiuta a plasmare il futuro di SureForms"],"Share how you use the plugin so we can build features that matter, fix issues faster, and make smarter decisions. ":["Condividi come utilizzi il plugin in modo che possiamo sviluppare funzionalit\u00e0 che contano, risolvere i problemi pi\u00f9 velocemente e prendere decisioni pi\u00f9 intelligenti. "],"Enable Google Address Autocomplete":["Abilita il completamento automatico degli indirizzi di Google"],"Upgrade to the SureForms Business Plan to add Google-powered address autocomplete with interactive map preview to your forms.":["Passa al piano SureForms Business per aggiungere il completamento automatico degli indirizzi con tecnologia Google e l'anteprima della mappa interattiva ai tuoi moduli."],"Auto-suggest addresses as users type for faster, error-free submissions":["Suggerisci automaticamente gli indirizzi mentre gli utenti digitano per invii pi\u00f9 rapidi e senza errori"],"Show an interactive map preview with draggable pin for precise locations":["Mostra un'anteprima della mappa interattiva con un segnaposto trascinabile per posizioni precise"],"Automatically populate address fields like city, state, and postal code":["Compila automaticamente i campi dell'indirizzo come citt\u00e0, stato e codice postale"]}}} \ No newline at end of file +{"translation-revision-date":"2025-01-01T06:16:29+00:00","generator":"WP-CLI\/2.12.0","source":"assets\/build\/settings.js","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","lang":"en","plural-forms":"nplurals=2; plural=(n != 1);"},"Dashboard":["Cruscotto"],"Settings":["Impostazioni"],"Entries":["Voci"],"Activated":["Attivato"],"Activate":["Attiva"],"Monday":["Luned\u00ec"],"Forms":["Moduli"],"GitHub":["GitHub"],"General":["Generale"],"Other":["Altro"],"Confirm":["Conferma"],"Cancel":["Annulla"],"Install":["Installa"],"Plugin Installation failed, Please try again later.":["Installazione del plugin fallita, per favore riprova pi\u00f9 tardi."],"Plugin activation failed, Please try again later.":["Attivazione del plugin fallita, riprova pi\u00f9 tardi."],"Integrations":["Integrazioni"],"What's New?":["Novit\u00e0?"],"Core":["Nucleo"],"Unlicensed":["Senza licenza"],"Connecting\u2026":["Connessione in corso\u2026"],"Install & Activate":["Installa e attiva"],"Send Email To":["Invia email a"],"Google reCAPTCHA":["Google reCAPTCHA"],"hCaptcha":["hCaptcha"],"reCAPTCHA v2 Invisible":["reCAPTCHA v2 Invisibile"],"reCAPTCHA v3":["reCAPTCHA v3"],"Validations":["Convalide"],"Spam Protection":["Protezione antispam"],"Email Summaries":["Riepiloghi email"],"Tuesday":["Marted\u00ec"],"Wednesday":["Mercoled\u00ec"],"Thursday":["Gioved\u00ec"],"Friday":["Venerd\u00ec"],"Saturday":["Sabato"],"Sunday":["Domenica"],"Test Email":["Email di prova"],"Schedule Reports":["Programma rapporti"],"IP Logging":["Registrazione IP"],"If this option is turned on, the user's IP address will be saved with the form data":["Se questa opzione \u00e8 attivata, l'indirizzo IP dell'utente verr\u00e0 salvato con i dati del modulo"],"Confirmation Email Mismatch Message":["Messaggio di mancata corrispondenza dell'email di conferma"],"%s represents the minimum input value. For example: \"Minimum value is 10.\"":["%s rappresenta il valore minimo di input. Ad esempio: \"Il valore minimo \u00e8 10.\""],"%s represents the maximum input value. For example: \"Maximum value is 100.\"":["%s rappresenta il valore massimo di input. Ad esempio: \"Il valore massimo \u00e8 100.\""],"%s represents the minimum selections needed. For example: \u201cMinimum 2 selections are required.\u201d":["%s rappresenta le selezioni minime necessarie. Ad esempio: \"Sono necessarie almeno 2 selezioni.\""],"%s represents the maximum selections allowed. For example: \u201cMaximum 4 selections are allowed.\u201d":["%s rappresenta il numero massimo di selezioni consentite. Ad esempio: \"Sono consentite al massimo 4 selezioni.\""],"%s represents the minimum choices needed. For example: \u201cMinimum 1 selection is required.\u201d":["%s rappresenta le scelte minime necessarie. Ad esempio: \"\u00c8 richiesta almeno 1 selezione.\""],"%s represents the maximum choices allowed. For example: \u201cMaximum 3 selections are allowed.\u201d":["%s rappresenta il numero massimo di scelte consentite. Ad esempio: \"Sono consentite un massimo di 3 selezioni.\""]," Error Message":["Messaggio di errore"],"Auto":["Auto"],"Light":["Luce"],"Dark":["Scuro"],"Turnstile":["Tornello"],"Honeypot":["Trappola"],"Get Keys":["Ottieni chiavi"],"Documentation":["Documentazione"],"Site Key":["Chiave del sito"],"Secret Key":["Chiave segreta"],"Cloudflare Turnstile":["Cloudflare Turnstile"],"Appearance Mode":["Modalit\u00e0 Aspetto"],"Enable Honeypot Security":["Abilita la Sicurezza Honeypot"],"Enable Honeypot Security for better spam protection":["Abilita la Sicurezza Honeypot per una migliore protezione dallo spam"],"This field cannot be left blank.":["Questo campo non pu\u00f2 essere lasciato vuoto."],"OttoKit":["OttoKit"],"Connect with OttoKit":["Connettiti con OttoKit"],"reCAPTCHA":["reCAPTCHA"],"Ready to go beyond free plan?":["Pronto a superare il piano gratuito?"],"Upgrade now":["Aggiorna ora"],"and unlock the full power of SureForms!":["e sblocca tutta la potenza di SureForms!"],"Upgrade SureForms":["Aggiorna SureForms"],"Upgrade Now":["Aggiorna ora"],"Form Validation":["Validazione del modulo"],"Required Error Messages":["Messaggi di errore richiesti"],"Other Error Messages":["Altri messaggi di errore"],"Input Field Unique":["Campo di input univoco"],"Email Field Unique":["Campo email univoco"],"Invalid URL":["URL non valido"],"Phone Field Unique":["Campo Telefono Unico"],"Invalid Field Number Block":["Blocco Numero Campo Non Valido"],"Invalid Email":["Email non valido"],"Number Minimum Value":["Valore Minimo Numero"],"Number Maximum Value":["Valore Massimo Numero"],"Dropdown Minimum Selections":["Selezioni Minime del Menu a Tendina"],"Dropdown Maximum Selections":["Selezioni massime del menu a tendina"],"Multiple Choice Minimum Selections":["Selezioni Minime a Scelta Multipla"],"Multiple Choice Maximum Selections":["Selezioni massime a scelta multipla"],"Input Field":["Campo di input"],"Email Field":["Campo Email"],"URL Field":["Campo URL"],"Phone Field":["Campo Telefono"],"Textarea Field":["Campo di testo"],"Checkbox Field":["Campo di selezione"],"Dropdown Field":["Campo a discesa"],"Multiple Choice Field":["Campo a scelta multipla"],"Address Field":["Campo Indirizzo"],"Number Field":["Campo numerico"],"reCAPTCHA v2":["reCAPTCHA v2"],"To enable reCAPTCHA feature on your SureForms Please enable reCAPTCHA option on your blocks setting and select version. Add google reCAPTCHA secret and site key here. reCAPTCHA will be added to your page on front-end.":["Per abilitare la funzione reCAPTCHA su SureForms, attiva l'opzione reCAPTCHA nelle impostazioni dei tuoi blocchi e seleziona la versione. Aggiungi qui la chiave segreta e la chiave del sito di Google reCAPTCHA. reCAPTCHA verr\u00e0 aggiunto alla tua pagina nel front-end."],"Enter your %s here":["Inserisci qui il tuo %s"],"To enable hCAPTCHA, please add your site key and secret key. Configure these settings within the individual form.":["Per abilitare hCAPTCHA, aggiungi la tua chiave del sito e la chiave segreta. Configura queste impostazioni all'interno del modulo individuale."],"To enable Cloudflare Turnstile, please add your site key and secret key. Configure these settings within the individual form.":["Per abilitare Cloudflare Turnstile, aggiungi la tua chiave del sito e la chiave segreta. Configura queste impostazioni all'interno del modulo individuale."],"Save":["Salva"],"Anonymous Analytics":["Analisi Anonime"],"Learn More":["Scopri di pi\u00f9"],"Admin Notification":["Notifica dell'amministratore"],"Enable Admin Notification":["Abilita la Notifica Amministratore"],"Admin notifications keep you informed about new form entries since your last visit.":["Le notifiche dell'amministratore ti tengono informato sui nuovi invii di moduli dalla tua ultima visita."],"Continue":["Continua"],"Get Started":["Inizia"],"Integration":["Integrazione"],"Connect Native Integrations with SureForms":["Collega le integrazioni native con SureForms"],"Unlock powerful integrations in the Premium plan to automate your workflows and connect SureForms directly with your favourite tools.":["Sblocca potenti integrazioni nel piano Premium per automatizzare i tuoi flussi di lavoro e collegare SureForms direttamente con i tuoi strumenti preferiti."],"Send form submissions straight to CRMs, email, and marketing platforms":["Invia le sottomissioni dei moduli direttamente ai CRM, email e piattaforme di marketing"],"Automate repetitive tasks with seamless data syncing":["Automatizza le attivit\u00e0 ripetitive con una sincronizzazione dei dati senza interruzioni"],"Access exclusive native integrations for faster workflows":["Accedi a integrazioni native esclusive per flussi di lavoro pi\u00f9 veloci"],"Payments":["Pagamenti"],"Stripe account disconnected successfully.":["Account Stripe disconnesso con successo."],"Failed to create webhook.":["Impossibile creare il webhook."],"Failed to connect to Stripe.":["Connessione a Stripe non riuscita."],"Webhook":["Webhook"],"Knowledge Base":["Base di conoscenza"],"What\u2019s New":["Novit\u00e0"],"delete":["elimina"],"Please type \"%s\" in the input box":["Per favore digita \"%s\" nella casella di input"],"To confirm, type \"%s\" in the box below:":["Per confermare, digita \"%s\" nella casella sottostante:"],"Type \"%s\"":["Digita \"%s\""],"Go to OttoKit Settings":["Vai alle Impostazioni di OttoKit"],"USD - US Dollar":["USD - Dollaro statunitense"],"Payment Mode":["Modalit\u00e0 di pagamento"],"Test Mode":["Modalit\u00e0 di test"],"Live Mode":["Modalit\u00e0 Live"],"General Settings":["Impostazioni generali"],"Set up email summaries, admin alerts, and data preferences to manage your forms with ease.":["Imposta i riepiloghi delle email, gli avvisi amministrativi e le preferenze sui dati per gestire i tuoi moduli con facilit\u00e0."],"Customize default error messages shown when users submit invalid or incomplete form entries.":["Personalizza i messaggi di errore predefiniti mostrati quando gli utenti inviano voci di modulo non valide o incomplete."],"Enable spam protection for your forms using CAPTCHA services or honeypot security.":["Abilita la protezione antispam per i tuoi moduli utilizzando servizi CAPTCHA o la sicurezza honeypot."],"Connect and manage your payment gateways to securely accept transactions through your forms.":["Collega e gestisci i tuoi gateway di pagamento per accettare transazioni in modo sicuro attraverso i tuoi moduli."],"1% transaction and payment gateway fees apply.":["Si applicano commissioni di transazione e gateway di pagamento dell'1%."],"2.9% transaction and payment gateway fees apply. Activate license to reduce transaction fees.":["Si applicano commissioni di transazione e gateway di pagamento del 2,9%. Attiva la licenza per ridurre le commissioni di transazione."],"2.9% transaction and payment gateway fees apply.":["Si applicano commissioni di transazione e gateway di pagamento del 2,9%."],"Please visit %1$s, delete an unused webhook, then click below to retry.":["Si prega di visitare %1$s, eliminare un webhook non utilizzato, quindi fare clic qui sotto per riprovare."],"SureForms could not create a webhook because your Stripe account has run out of free slots. Webhooks are needed to receive updates about payments.":["SureForms non \u00e8 riuscito a creare un webhook perch\u00e9 il tuo account Stripe ha esaurito gli slot gratuiti. I webhook sono necessari per ricevere aggiornamenti sui pagamenti."],"Stripe Dashboard":["Dashboard di Stripe"],"Creating\u2026":["Creando\u2026"],"Create Webhook":["Crea Webhook"],"Successfully connected to Stripe!":["Connessione a Stripe riuscita!"],"Invalid response from server. Please try again.":["Risposta non valida dal server. Per favore riprova."],"Failed to disconnect Stripe account.":["Impossibile disconnettere l'account Stripe."],"Webhook created successfully!":["Webhook creato con successo!"],"Select Currency":["Seleziona valuta"],"Select the default currency for payment forms.":["Seleziona la valuta predefinita per i moduli di pagamento."],"Connection Status":["Stato della connessione"],"Disconnect Stripe Account":["Disconnetti l'account Stripe"],"Are you sure you want to disconnect your Stripe account? This will stop all active payments, subscriptions, and form transactions connected to this account.":["Sei sicuro di voler scollegare il tuo account Stripe? Questo interromper\u00e0 tutti i pagamenti attivi, gli abbonamenti e le transazioni dei moduli collegati a questo account."],"Disconnect":["Disconnetti"],"Disconnecting\u2026":["Disconnessione in corso\u2026"],"Webhook successfully connected, all Stripe events are being tracked.":["Webhook collegato con successo, tutti gli eventi di Stripe vengono tracciati."],"Connect your Stripe account to start accepting payments through your forms.":["Collega il tuo account Stripe per iniziare ad accettare pagamenti tramite i tuoi moduli."],"Connect to Stripe":["Connetti a Stripe"],"Securely connect to Stripe with just a few clicks to begin accepting payments! ":["Collegati in modo sicuro a Stripe con pochi clic per iniziare ad accettare pagamenti!"],"Payment Methods":["Metodi di pagamento"],"Test mode allows you to process payments without real charges. Switch to Live mode for actual transactions.":["La modalit\u00e0 di test ti consente di elaborare pagamenti senza addebiti reali. Passa alla modalit\u00e0 Live per le transazioni effettive."],"General Payment Settings":["Impostazioni generali di pagamento"],"These settings apply to all payment gateways.":["Queste impostazioni si applicano a tutti i gateway di pagamento."],"Stripe Settings":["Impostazioni di Stripe"],"Left ($100)":["Sinistra ($100)"],"Right (100$)":["Destra (100$)"],"Left Space ($ 100)":["Spazio Sinistro ($ 100)"],"Right Space (100 $)":["Spazio destro (100 $)"],"Currency Sign Position":["Posizione del simbolo di valuta"],"Select the position of the currency symbol relative to the amount.":["Seleziona la posizione del simbolo della valuta rispetto all'importo."],"Learn":["Impara"],"Enable email summaries":["Abilita i riepiloghi email"],"Enable IP logging":["Abilita la registrazione IP"],"Turn on Admin Notification from here.":["Attiva la notifica amministratore da qui."],"Send entries to 100+ popular apps.":["Invia voci a oltre 100 app popolari."],"Build automated workflows that run instantly.":["Crea flussi di lavoro automatizzati che vengono eseguiti istantaneamente."],"Create custom app integrations using our Custom App feature.":["Crea integrazioni di app personalizzate utilizzando la nostra funzione App personalizzata."],"Keep your tools in sync automatically.":["Mantieni i tuoi strumenti sincronizzati automaticamente."],"This will install and activate OttoKit on your WordPress site to enable automation features.":["Questo installer\u00e0 e attiver\u00e0 OttoKit sul tuo sito WordPress per abilitare le funzionalit\u00e0 di automazione."],"Automate Your Forms with OttoKit":["Automatizza i tuoi moduli con OttoKit"],"Every form submission should trigger something \u2014 a Slack alert, a CRM lead, a follow-up email, or a new row in Google Sheets.":["Ogni invio di modulo dovrebbe attivare qualcosa: un avviso Slack, un lead CRM, un'email di follow-up o una nuova riga in Google Sheets."],"MCP":["MCP"],"Configure AI client permissions and MCP server settings.":["Configura le autorizzazioni del client AI e le impostazioni del server MCP."],"View documentation":["Visualizza la documentazione"],"Copy to clipboard":["Copia negli appunti"],"Claude Desktop":["Claude Desktop"],"~\/Library\/Application Support\/Claude\/claude_desktop_config.json (macOS) or %APPDATA%\\Claude\\claude_desktop_config.json (Windows)":["~\/Library\/Application Support\/Claude\/claude_desktop_config.json (macOS) o %APPDATA%\\Claude\\claude_desktop_config.json (Windows)"],"Claude Code":["Codice Claude"],".mcp.json (project) or ~\/.claude.json (global)":[".mcp.json (progetto) o ~\/.claude.json (globale)"],"Cursor":["Cursore"],"~\/.cursor\/mcp.json":["~\/.cursor\/mcp.json"],"VS Code (Copilot)":["VS Code (Copilot)"],".vscode\/mcp.json (project) or settings.json > mcp.servers (global)":[".vscode\/mcp.json (progetto) o settings.json > mcp.servers (globale)"],"~\/.continue\/config.yaml or config.json":["~\/.continue\/config.yaml o config.json"],"Your client's MCP configuration file":["Il file di configurazione MCP del tuo cliente"],"Connect Your AI Client":["Collega il tuo client AI"],"AI Client":["Cliente AI"],"Create an Application Password \u2014 ":["Crea una Password per l'Applicazione \u2014"],"Open Application Passwords":["Apri Password Applicazioni"],"Or use this CLI command to add the server quickly (you will still need to set the environment variables):":["Oppure usa questo comando CLI per aggiungere rapidamente il server (dovrai comunque impostare le variabili d'ambiente):"],"Copy the JSON config below into: ":["Copia la configurazione JSON qui sotto in:"],"Replace \"your-application-password\" with the password from Step 1.":["Sostituisci \"your-application-password\" con la password del Passo 1."],"WP_API_URL \u2014 your site's MCP endpoint. WP_API_USERNAME \u2014 your WordPress username. WP_API_PASSWORD \u2014 the application password you generated.":["WP_API_URL \u2014 l'endpoint MCP del tuo sito. WP_API_USERNAME \u2014 il tuo nome utente WordPress. WP_API_PASSWORD \u2014 la password dell'applicazione che hai generato."],"View setup docs":["Visualizza i documenti di configurazione"],"The MCP Adapter plugin is installed but not active. Activate it to configure MCP settings.":["Il plugin MCP Adapter \u00e8 installato ma non attivo. Attivalo per configurare le impostazioni MCP."],"The MCP Adapter plugin is required to connect AI clients to your forms. Download and install it from GitHub, then activate it.":["Il plugin MCP Adapter \u00e8 necessario per connettere i client AI ai tuoi moduli. Scaricalo e installalo da GitHub, quindi attivalo."],"Download the latest release from":["Scarica l'ultima versione da"],"Install the plugin via Plugins > Add New Plugin > Upload Plugin.":["Installa il plugin tramite Plugin > Aggiungi nuovo plugin > Carica plugin."],"Activate the MCP Adapter plugin.":["Attiva il plugin dell'adattatore MCP."],"Activating\u2026":["Attivazione in corso\u2026"],"Activate MCP Adapter":["Attiva l'adattatore MCP"],"Download MCP Adapter":["Scarica l'adattatore MCP"],"Experimental":["Sperimentale"],"Enable Abilities":["Abilita Abilit\u00e0"],"Register SureForms abilities with the WordPress Abilities API. When enabled, AI clients can list, read, create, edit, and delete your forms and entries. When disabled, no abilities are registered and AI clients cannot perform any actions on your forms.":["Registra le abilit\u00e0 di SureForms con l'API Abilities di WordPress. Quando \u00e8 abilitato, i client AI possono elencare, leggere, creare, modificare e eliminare i tuoi moduli e le voci. Quando \u00e8 disabilitato, nessuna abilit\u00e0 \u00e8 registrata e i client AI non possono eseguire alcuna azione sui tuoi moduli."],"Abilities API \u2014 Edit":["API delle abilit\u00e0 \u2014 Modifica"],"Enable Edit Abilities":["Abilita le capacit\u00e0 di modifica"],"When enabled, AI clients can create new forms, update form titles, fields, and settings, duplicate forms, and modify entry statuses. When disabled, these abilities are unregistered and AI clients can only read your data.":["Quando abilitato, i client AI possono creare nuovi moduli, aggiornare i titoli dei moduli, i campi e le impostazioni, duplicare i moduli e modificare gli stati delle voci. Quando disabilitato, queste capacit\u00e0 vengono annullate e i client AI possono solo leggere i tuoi dati."],"Abilities API \u2014 Delete":["API delle abilit\u00e0 \u2014 Elimina"],"Enable Delete Abilities":["Abilita Elimina Abilit\u00e0"],"When enabled, AI clients can permanently delete forms and entries. Deleted data cannot be recovered. When disabled, delete abilities are unregistered and AI clients cannot remove any data.":["Quando abilitato, i client AI possono eliminare permanentemente moduli e voci. I dati eliminati non possono essere recuperati. Quando disabilitato, le capacit\u00e0 di eliminazione vengono annullate e i client AI non possono rimuovere alcun dato."],"MCP Server":["Server MCP"],"Enable MCP Server":["Abilita server MCP"],"Creates a dedicated SureForms MCP endpoint that AI clients like Claude can connect to. When disabled, the endpoint is removed and external AI clients cannot discover or call any SureForms abilities.":["Crea un endpoint SureForms MCP dedicato a cui i clienti AI come Claude possono connettersi. Quando \u00e8 disabilitato, l'endpoint viene rimosso e i clienti AI esterni non possono scoprire o chiamare alcuna funzionalit\u00e0 di SureForms."],"Learn more":["Scopri di pi\u00f9"],"MCP Adapter Required":["Adattatore MCP richiesto"],"Google Maps":["Google Maps"],"Configure Google Maps API key for address autocomplete and map preview.":["Configura la chiave API di Google Maps per il completamento automatico degli indirizzi e l'anteprima della mappa."],"Help shape the future of SureForms":["Aiuta a plasmare il futuro di SureForms"],"Share how you use the plugin so we can build features that matter, fix issues faster, and make smarter decisions. ":["Condividi come utilizzi il plugin in modo che possiamo sviluppare funzionalit\u00e0 che contano, risolvere i problemi pi\u00f9 velocemente e prendere decisioni pi\u00f9 intelligenti."],"Enable Google Address Autocomplete":["Abilita il completamento automatico degli indirizzi di Google"],"Upgrade to the SureForms Business Plan to add Google-powered address autocomplete with interactive map preview to your forms.":["Passa al piano SureForms Business per aggiungere il completamento automatico degli indirizzi con tecnologia Google e l'anteprima della mappa interattiva ai tuoi moduli."],"Auto-suggest addresses as users type for faster, error-free submissions":["Suggerisci automaticamente gli indirizzi mentre gli utenti digitano per invii pi\u00f9 rapidi e senza errori"],"Show an interactive map preview with draggable pin for precise locations":["Mostra un'anteprima della mappa interattiva con un segnaposto trascinabile per posizioni precise"],"Automatically populate address fields like city, state, and postal code":["Compila automaticamente i campi dell'indirizzo come citt\u00e0, stato e codice postale"]}}} \ No newline at end of file diff --git a/languages/sureforms-it_IT.mo b/languages/sureforms-it_IT.mo index c52d3ac27eb4c8f2df4c0aa8c14e66cdf7b1f319..f20702528a66a413fb4f178164287b017aba2c1c 100644 GIT binary patch delta 66534 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

C+WlPU@NP6e1TW&F=!}g# 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 diff --git a/languages/sureforms-it_IT.po b/languages/sureforms-it_IT.po index 0f9070feb..4dbff1017 100644 --- a/languages/sureforms-it_IT.po +++ b/languages/sureforms-it_IT.po @@ -16,7 +16,7 @@ msgstr "" #: sureforms.php #: admin/admin.php:320 #: admin/admin.php:321 -#: admin/admin.php:1812 +#: admin/admin.php:1813 #: inc/abilities/abilities-registrar.php:133 #: inc/gutenberg-hooks.php:109 #: inc/page-builders/bricks/elements/form-widget.php:67 @@ -82,7 +82,7 @@ msgstr "Nuovo modulo" #: admin/admin.php:601 #: admin/admin.php:602 -#: admin/admin.php:1849 +#: admin/admin.php:1850 #: inc/global-settings/email-summary.php:225 #: assets/build/dashboard.js:172 #: assets/build/entries.js:172 @@ -118,18 +118,18 @@ msgid "Nonce verification failed." msgstr "Verifica del nonce fallita." #. translators: %1$s: Opening anchor tag with URL, %2$s: Closing anchor tag, %3$s: SureForms Pro Plugin Name. -#: admin/admin.php:1441 +#: admin/admin.php:1442 #, php-format msgid "Please %1$sactivate%2$s your copy of %3$s to get new features, access support, receive update notifications, and more." msgstr "Per favore %1$sattiva%2$s la tua copia di %3$s per ottenere nuove funzionalità, accedere al supporto, ricevere notifiche di aggiornamento e altro ancora." #. translators: %1$s: SureForms version, %2$s: SureForms Pro Plugin Name, %3$s: SureForms Pro Version, %4$s: Anchor tag open, %5$s: Closing anchor tag. -#: admin/admin.php:1459 +#: admin/admin.php:1460 #, php-format msgid "SureForms %1$s requires minimum %2$s %3$s to work properly. Please update to the latest version from %4$shere%5$s." msgstr "SureForms %1$s richiede almeno %2$s %3$s per funzionare correttamente. Si prega di aggiornare all'ultima versione da %4$squi%5$s." -#: admin/admin.php:1848 +#: admin/admin.php:1849 #: inc/global-settings/email-summary.php:224 #: assets/build/entries.js:172 #: assets/build/payments.js:172 @@ -197,7 +197,7 @@ msgstr "Spazzatura" msgid "Published" msgstr "Pubblicato" -#: admin/admin.php:1840 +#: admin/admin.php:1841 msgid "View" msgstr "Visualizza" @@ -323,10 +323,10 @@ msgstr "Installato" msgid "You do not have permission to access this page." msgstr "Non hai il permesso di accedere a questa pagina." -#: admin/admin.php:1607 -#: admin/admin.php:1706 -#: admin/admin.php:1744 -#: admin/admin.php:1765 +#: admin/admin.php:1608 +#: admin/admin.php:1707 +#: admin/admin.php:1745 +#: admin/admin.php:1766 #: inc/admin-ajax.php:162 #: inc/payments/admin/admin-handler.php:638 #: inc/payments/stripe/admin-stripe-handler.php:80 @@ -339,7 +339,7 @@ msgid "Form ID is required." msgstr "L'ID del modulo è obbligatorio." #: inc/admin-ajax.php:182 -#: inc/form-submit.php:970 +#: inc/form-submit.php:972 msgid "Invalid form ID." msgstr "ID modulo non valido." @@ -513,11 +513,11 @@ msgstr "Casella di controllo" msgid "Required" msgstr "Richiesto" -#: inc/fields/dropdown-markup.php:83 +#: inc/fields/dropdown-markup.php:84 msgid "Dropdown" msgstr "Menu a tendina" -#: inc/fields/dropdown-markup.php:106 +#: inc/fields/dropdown-markup.php:108 #: inc/gutenberg-hooks.php:220 msgid "Select an option" msgstr "Seleziona un'opzione" @@ -545,7 +545,7 @@ msgstr "Acconsento a che questo sito web memorizzi le informazioni che ho inviat msgid "Please verify that you are not a robot." msgstr "Per favore verifica che tu non sia un robot." -#: inc/fields/multichoice-markup.php:113 +#: inc/fields/multichoice-markup.php:114 msgid "Multi Choice" msgstr "Scelta multipla" @@ -642,7 +642,7 @@ msgstr "Il valore deve essere unico." msgid "Sorry, you are not allowed to perform this action." msgstr "Spiacente, non ti è permesso eseguire questa azione." -#: admin/admin.php:1505 +#: admin/admin.php:1506 msgid "Rate SureForms" msgstr "Valuta SureForms" @@ -790,7 +790,7 @@ msgid "Site URL" msgstr "URL del sito" #: inc/smart-tags.php:111 -#: inc/smart-tags.php:142 +#: inc/smart-tags.php:143 msgid "Admin Email" msgstr "Email dell'amministratore" @@ -831,7 +831,7 @@ msgid "User Last Name" msgstr "Cognome utente" #: inc/smart-tags.php:122 -#: inc/smart-tags.php:143 +#: inc/smart-tags.php:144 msgid "User Email" msgstr "Email utente" @@ -855,11 +855,11 @@ msgstr "ID del post/pagina incorporato" msgid "Embedded Post/Page Title" msgstr "Titolo del Post/Pagina incorporato" -#: inc/smart-tags.php:128 +#: inc/smart-tags.php:129 msgid "Populate by GET Param" msgstr "Popola tramite parametro GET" -#: inc/smart-tags.php:129 +#: inc/smart-tags.php:130 msgid "Cookie Value" msgstr "Valore del cookie" @@ -8842,7 +8842,7 @@ msgstr "Riorganizza il blocco all'interno della Barra delle Azioni Rapide" #: admin/admin.php:409 #: admin/admin.php:410 -#: admin/admin.php:2021 +#: admin/admin.php:2022 #: assets/build/blocks.js:172 #: assets/build/dashboard.js:172 #: assets/build/entries.js:172 @@ -9185,7 +9185,7 @@ msgstr "Centro" msgid "Right" msgstr "Destra" -#: inc/form-submit.php:1147 +#: inc/form-submit.php:1149 #: assets/build/formEditor.js:172 #: assets/build/settings.js:172 msgid "Google reCAPTCHA" @@ -9195,7 +9195,7 @@ msgstr "Google reCAPTCHA" msgid "CloudFlare Turnstile" msgstr "CloudFlare Turnstile" -#: inc/form-submit.php:1151 +#: inc/form-submit.php:1153 #: assets/build/formEditor.js:172 #: assets/build/settings.js:172 msgid "hCaptcha" @@ -9487,7 +9487,7 @@ msgstr "Chiave del sito" msgid "Secret Key" msgstr "Chiave segreta" -#: inc/form-submit.php:1155 +#: inc/form-submit.php:1157 #: assets/build/settings.js:172 msgid "Cloudflare Turnstile" msgstr "Cloudflare Turnstile" @@ -10485,18 +10485,18 @@ msgstr "Sblocca Aggiungi Nota" msgid "With the SureForms Starter plan, enhance your submitted form entries by adding personalized notes for better clarity and tracking." msgstr "Con il piano SureForms Starter, migliora le tue voci di modulo inviate aggiungendo note personalizzate per una maggiore chiarezza e tracciabilità." -#: inc/form-submit.php:821 +#: inc/form-submit.php:823 msgid "Email notification passed to the sending server" msgstr "Notifica email passata al server di invio" #. translators: Here, %s is the comma separated emails list. -#: inc/form-submit.php:894 +#: inc/form-submit.php:896 #, php-format msgid "Email notification recipient: %s" msgstr "Destinatario della notifica email: %s" #. translators: Here, %1$s is the comma separated emails list and %2$s is error report ( if any ). -#: inc/form-submit.php:911 +#: inc/form-submit.php:913 #, php-format msgid "Email server was unable to send the email notification. Recipient: %1$s. Reason: %2$s" msgstr "Il server di posta elettronica non è riuscito a inviare la notifica email. Destinatario: %1$s. Motivo: %2$s" @@ -10740,24 +10740,24 @@ msgstr "Seleziona sfumatura" msgid "reCAPTCHA" msgstr "reCAPTCHA" -#: inc/form-submit.php:1091 +#: inc/form-submit.php:1093 msgid "Captcha validation failed. No error code provided." msgstr "La validazione del captcha non è riuscita. Nessun codice di errore fornito." -#: inc/form-submit.php:1092 +#: inc/form-submit.php:1094 msgid "Captcha validation failed." msgstr "La validazione del captcha è fallita." -#: inc/form-submit.php:1159 +#: inc/form-submit.php:1161 msgid "Unknown Captcha" msgstr "Captcha sconosciuto" -#: inc/form-submit.php:1160 +#: inc/form-submit.php:1162 msgid "Invalid captcha type." msgstr "Tipo di captcha non valido." #. translators: %s is the captcha title. -#: inc/form-submit.php:1173 +#: inc/form-submit.php:1175 #, php-format msgid "%s verification failed. Please contact your site administrator." msgstr "La verifica di %s non è riuscita. Si prega di contattare l'amministratore del sito." @@ -11274,28 +11274,28 @@ msgstr "Abilita la Notifica Amministratore" msgid "Admin notifications keep you informed about new form entries since your last visit." msgstr "Le notifiche dell'amministratore ti tengono informato sui nuovi invii di moduli dalla tua ultima visita." -#: admin/admin.php:1611 -#: admin/admin.php:1702 -#: admin/admin.php:1740 -#: admin/admin.php:1761 +#: admin/admin.php:1612 +#: admin/admin.php:1703 +#: admin/admin.php:1741 +#: admin/admin.php:1762 msgid "Unauthorized user." msgstr "Utente non autorizzato." #. translators: 1: opening span, 2: opening strong (inline), 3: closing strong, 4: closing span, 5: opening strong (block), 6: closing strong -#: admin/admin.php:1711 +#: admin/admin.php:1712 #, php-format msgid "%1$sGet started by %2$sbuilding your first form%3$s.%4$s%5$sExperience the power of our intuitive AI Form Builder%6$s" msgstr "%1$sInizia %2$scostruendo il tuo primo modulo%3$s.%4$s%5$sScopri la potenza del nostro intuitivo Costruttore di Moduli AI%6$s" -#: admin/admin.php:1722 +#: admin/admin.php:1723 msgid "SureForms is waiting for you!" msgstr "SureForms ti sta aspettando!" -#: admin/admin.php:1724 +#: admin/admin.php:1725 msgid "Build My First Form" msgstr "Crea il mio primo modulo" -#: admin/admin.php:1725 +#: admin/admin.php:1726 msgid "Dismiss" msgstr "Chiudi" @@ -11315,51 +11315,51 @@ msgstr "Accesso" msgid "Register" msgstr "Registrati" -#: admin/admin.php:1836 +#: admin/admin.php:1837 msgid "Recent Entries" msgstr "Voci recenti" -#: admin/admin.php:1837 +#: admin/admin.php:1838 msgid "( Last 7 days )" msgstr "( Ultimi 7 giorni )" -#: admin/admin.php:1957 +#: admin/admin.php:1958 msgid "Use Conditional Logic to show only what matters" msgstr "Usa la logica condizionale per mostrare solo ciò che conta" -#: admin/admin.php:1958 +#: admin/admin.php:1959 msgid "Split your form into steps to keep it easy" msgstr "Dividi il tuo modulo in passaggi per mantenerlo semplice" -#: admin/admin.php:1959 +#: admin/admin.php:1960 msgid "Let people upload files directly to your form" msgstr "Consenti alle persone di caricare file direttamente nel tuo modulo" -#: admin/admin.php:1960 +#: admin/admin.php:1961 msgid "Turn responses into downloadable PDFs automatically" msgstr "Trasforma automaticamente le risposte in PDF scaricabili" -#: admin/admin.php:1961 +#: admin/admin.php:1962 msgid "Let users sign with a simple signature field" msgstr "Consenti agli utenti di firmare con un semplice campo firma" -#: admin/admin.php:1962 +#: admin/admin.php:1963 msgid "Connect your form to other tools using webhooks" msgstr "Collega il tuo modulo ad altri strumenti utilizzando i webhook" -#: admin/admin.php:1963 +#: admin/admin.php:1964 msgid "Use Conversational Forms for a chat-like experience" msgstr "Usa moduli conversazionali per un'esperienza simile a una chat" -#: admin/admin.php:1964 +#: admin/admin.php:1965 msgid "Let users register or log in through your form" msgstr "Consenti agli utenti di registrarsi o accedere tramite il tuo modulo" -#: admin/admin.php:1965 +#: admin/admin.php:1966 msgid "Build forms that create WordPress user accounts" msgstr "Crea moduli che creano account utente WordPress" -#: admin/admin.php:1966 +#: admin/admin.php:1967 msgid "Add calculations to auto-total scores or prices" msgstr "Aggiungi calcoli per totalizzare automaticamente i punteggi o i prezzi" @@ -11917,6 +11917,7 @@ msgid "Unable to create ZIP file." msgstr "Impossibile creare il file ZIP." #: inc/entries.php:729 +#: inc/smart-tags.php:128 #: assets/build/entries.js:172 msgid "Entry ID" msgstr "ID di ingresso" @@ -11934,7 +11935,7 @@ msgid "Invalid form data structure provided." msgstr "Struttura dei dati del modulo non valida fornita." #: inc/fields/payment-markup.php:249 -#: inc/payments/payment-helper.php:538 +#: inc/payments/payment-helper.php:543 msgid "Subscription Plan" msgstr "Piano di abbonamento" @@ -12552,301 +12553,301 @@ msgstr "Dollaro di Hong Kong" msgid "Norwegian Krone" msgstr "Corona Norvegese" -#: inc/payments/payment-helper.php:259 +#: inc/payments/payment-helper.php:264 msgid "South Korean Won" msgstr "Won sudcoreano" -#: inc/payments/payment-helper.php:264 +#: inc/payments/payment-helper.php:269 msgid "Turkish Lira" msgstr "Lira Turca" -#: inc/payments/payment-helper.php:269 +#: inc/payments/payment-helper.php:274 msgid "Russian Ruble" msgstr "Rublo Russo" -#: inc/payments/payment-helper.php:274 +#: inc/payments/payment-helper.php:279 msgid "Indian Rupee" msgstr "Rupia indiana" -#: inc/payments/payment-helper.php:279 +#: inc/payments/payment-helper.php:284 msgid "Brazilian Real" msgstr "Real brasiliano" -#: inc/payments/payment-helper.php:284 +#: inc/payments/payment-helper.php:289 msgid "South African Rand" msgstr "Rand sudafricano" -#: inc/payments/payment-helper.php:289 +#: inc/payments/payment-helper.php:294 msgid "UAE Dirham" msgstr "Dirham degli Emirati Arabi Uniti" -#: inc/payments/payment-helper.php:294 +#: inc/payments/payment-helper.php:299 msgid "Philippine Peso" msgstr "Peso filippino" -#: inc/payments/payment-helper.php:299 +#: inc/payments/payment-helper.php:304 msgid "Indonesian Rupiah" msgstr "Rupia indonesiana" -#: inc/payments/payment-helper.php:304 +#: inc/payments/payment-helper.php:309 msgid "Malaysian Ringgit" msgstr "Ringgit malese" -#: inc/payments/payment-helper.php:309 +#: inc/payments/payment-helper.php:314 msgid "Thai Baht" msgstr "Baht thailandese" -#: inc/payments/payment-helper.php:314 +#: inc/payments/payment-helper.php:319 msgid "Burundian Franc" msgstr "Franco Burundese" -#: inc/payments/payment-helper.php:319 +#: inc/payments/payment-helper.php:324 msgid "Chilean Peso" msgstr "Peso cileno" -#: inc/payments/payment-helper.php:324 +#: inc/payments/payment-helper.php:329 msgid "Djiboutian Franc" msgstr "Franco Gibutiano" -#: inc/payments/payment-helper.php:329 +#: inc/payments/payment-helper.php:334 msgid "Guinean Franc" msgstr "Franco Guineano" -#: inc/payments/payment-helper.php:334 +#: inc/payments/payment-helper.php:339 msgid "Comorian Franc" msgstr "Franco Comoriano" -#: inc/payments/payment-helper.php:339 +#: inc/payments/payment-helper.php:344 msgid "Malagasy Ariary" msgstr "Ariary Malgascio" -#: inc/payments/payment-helper.php:344 +#: inc/payments/payment-helper.php:349 msgid "Paraguayan Guaraní" msgstr "Guaraní paraguaiano" -#: inc/payments/payment-helper.php:349 +#: inc/payments/payment-helper.php:354 msgid "Rwandan Franc" msgstr "Franco Ruandese" -#: inc/payments/payment-helper.php:354 +#: inc/payments/payment-helper.php:359 msgid "Ugandan Shilling" msgstr "Scellino Ugandese" -#: inc/payments/payment-helper.php:359 +#: inc/payments/payment-helper.php:364 msgid "Vietnamese Đồng" msgstr "Đồng vietnamita" -#: inc/payments/payment-helper.php:364 +#: inc/payments/payment-helper.php:369 msgid "Vanuatu Vatu" msgstr "Vatu di Vanuatu" -#: inc/payments/payment-helper.php:369 +#: inc/payments/payment-helper.php:374 msgid "Central African CFA Franc" msgstr "Franco CFA dell'Africa Centrale" -#: inc/payments/payment-helper.php:374 +#: inc/payments/payment-helper.php:379 msgid "West African CFA Franc" msgstr "Franco CFA dell'Africa Occidentale" -#: inc/payments/payment-helper.php:379 +#: inc/payments/payment-helper.php:384 msgid "CFP Franc" msgstr "Franco CFP" -#: inc/payments/payment-helper.php:475 +#: inc/payments/payment-helper.php:480 msgid "An unknown error occurred. Please try again or contact the site administrator." msgstr "Si è verificato un errore sconosciuto. Si prega di riprovare o contattare l'amministratore del sito." -#: inc/payments/payment-helper.php:477 +#: inc/payments/payment-helper.php:482 msgid "Payment is currently unavailable. Please contact the site administrator." msgstr "Il pagamento è attualmente non disponibile. Si prega di contattare l'amministratore del sito." -#: inc/payments/payment-helper.php:478 +#: inc/payments/payment-helper.php:483 msgid "Payment is currently unavailable. Please contact the site administrator to configure the payment amount." msgstr "Il pagamento è attualmente non disponibile. Si prega di contattare l'amministratore del sito per configurare l'importo del pagamento." -#: inc/payments/payment-helper.php:479 +#: inc/payments/payment-helper.php:484 msgid "Invalid payment amount" msgstr "Importo di pagamento non valido" -#: inc/payments/payment-helper.php:480 +#: inc/payments/payment-helper.php:485 msgid "Payment amount must be at least {symbol}{amount}." msgstr "L'importo del pagamento deve essere almeno {symbol}{amount}." -#: inc/payments/payment-helper.php:483 +#: inc/payments/payment-helper.php:488 msgid "Payment is currently unavailable. Please contact the site administrator to configure the customer name field." msgstr "Il pagamento non è attualmente disponibile. Si prega di contattare l'amministratore del sito per configurare il campo del nome cliente." -#: inc/payments/payment-helper.php:484 +#: inc/payments/payment-helper.php:489 msgid "Payment is currently unavailable. Please contact the site administrator to configure the customer email field." msgstr "Il pagamento non è attualmente disponibile. Si prega di contattare l'amministratore del sito per configurare il campo email del cliente." -#: inc/payments/payment-helper.php:485 +#: inc/payments/payment-helper.php:490 msgid "Please enter your name." msgstr "Per favore inserisci il tuo nome." -#: inc/payments/payment-helper.php:486 +#: inc/payments/payment-helper.php:491 msgid "Please enter your email." msgstr "Per favore, inserisci la tua email." -#: inc/payments/payment-helper.php:489 +#: inc/payments/payment-helper.php:494 msgid "Payment failed" msgstr "Pagamento non riuscito" -#: inc/payments/payment-helper.php:490 +#: inc/payments/payment-helper.php:495 msgid "Payment successful" msgstr "Pagamento riuscito" -#: inc/payments/payment-helper.php:494 -#: inc/payments/payment-helper.php:495 +#: inc/payments/payment-helper.php:499 +#: inc/payments/payment-helper.php:500 msgid "Your card was declined. Please try a different payment method or contact your bank." msgstr "La tua carta è stata rifiutata. Prova un metodo di pagamento diverso o contatta la tua banca." -#: inc/payments/payment-helper.php:496 +#: inc/payments/payment-helper.php:501 msgid "Your card has insufficient funds. Please use a different payment method." msgstr "La tua carta ha fondi insufficienti. Si prega di utilizzare un metodo di pagamento diverso." -#: inc/payments/payment-helper.php:497 +#: inc/payments/payment-helper.php:502 msgid "Your card was declined because it has been reported as lost. Please contact your bank." msgstr "La tua carta è stata rifiutata perché è stata segnalata come smarrita. Si prega di contattare la propria banca." -#: inc/payments/payment-helper.php:498 +#: inc/payments/payment-helper.php:503 msgid "Your card was declined because it has been reported as stolen. Please contact your bank." msgstr "La tua carta è stata rifiutata perché è stata segnalata come rubata. Si prega di contattare la propria banca." -#: inc/payments/payment-helper.php:499 +#: inc/payments/payment-helper.php:504 msgid "Your card has expired. Please use a different payment method." msgstr "La tua carta è scaduta. Si prega di utilizzare un metodo di pagamento diverso." -#: inc/payments/payment-helper.php:500 -#: inc/payments/payment-helper.php:521 +#: inc/payments/payment-helper.php:505 +#: inc/payments/payment-helper.php:526 msgid "Your card was declined. Please contact your bank for more information." msgstr "La tua carta è stata rifiutata. Si prega di contattare la propria banca per ulteriori informazioni." -#: inc/payments/payment-helper.php:501 +#: inc/payments/payment-helper.php:506 msgid "Your card was declined due to restrictions. Please contact your bank." msgstr "La tua carta è stata rifiutata a causa di restrizioni. Si prega di contattare la propria banca." -#: inc/payments/payment-helper.php:502 +#: inc/payments/payment-helper.php:507 msgid "Your card was declined due to a security violation. Please contact your bank." msgstr "La tua carta è stata rifiutata a causa di una violazione della sicurezza. Si prega di contattare la propria banca." -#: inc/payments/payment-helper.php:503 +#: inc/payments/payment-helper.php:508 msgid "Your card does not support this type of purchase. Please use a different payment method." msgstr "La tua carta non supporta questo tipo di acquisto. Si prega di utilizzare un metodo di pagamento diverso." -#: inc/payments/payment-helper.php:504 +#: inc/payments/payment-helper.php:509 msgid "A stop payment order has been placed on this card. Please contact your bank." msgstr "È stato emesso un ordine di blocco del pagamento su questa carta. Si prega di contattare la propria banca." -#: inc/payments/payment-helper.php:505 +#: inc/payments/payment-helper.php:510 msgid "A test card was used in a live environment. Please use a real card." msgstr "Una carta di prova è stata utilizzata in un ambiente reale. Si prega di utilizzare una carta reale." -#: inc/payments/payment-helper.php:506 +#: inc/payments/payment-helper.php:511 msgid "Your card has exceeded its withdrawal limit. Please contact your bank." msgstr "La tua carta ha superato il limite di prelievo. Si prega di contattare la propria banca." -#: inc/payments/payment-helper.php:507 +#: inc/payments/payment-helper.php:512 msgid "Your card's security code is incorrect. Please check and try again." msgstr "Il codice di sicurezza della tua carta è errato. Per favore controlla e riprova." -#: inc/payments/payment-helper.php:508 +#: inc/payments/payment-helper.php:513 msgid "Your card number is incorrect. Please check and try again." msgstr "Il numero della tua carta è errato. Per favore controlla e riprova." -#: inc/payments/payment-helper.php:509 +#: inc/payments/payment-helper.php:514 msgid "Your card's security code is invalid. Please check and try again." msgstr "Il codice di sicurezza della tua carta non è valido. Controlla e riprova." -#: inc/payments/payment-helper.php:510 +#: inc/payments/payment-helper.php:515 msgid "Your card's expiration month is invalid. Please check and try again." msgstr "Il mese di scadenza della tua carta non è valido. Si prega di controllare e riprovare." -#: inc/payments/payment-helper.php:511 +#: inc/payments/payment-helper.php:516 msgid "Your card's expiration year is invalid. Please check and try again." msgstr "L'anno di scadenza della tua carta non è valido. Si prega di controllare e riprovare." -#: inc/payments/payment-helper.php:512 +#: inc/payments/payment-helper.php:517 msgid "Your card number is invalid. Please check and try again." msgstr "Il numero della tua carta non è valido. Controlla e riprova." -#: inc/payments/payment-helper.php:515 +#: inc/payments/payment-helper.php:520 msgid "Your card is not supported for this transaction. Please use a different payment method." msgstr "La tua carta non è supportata per questa transazione. Si prega di utilizzare un metodo di pagamento diverso." -#: inc/payments/payment-helper.php:516 +#: inc/payments/payment-helper.php:521 msgid "Your card does not support the currency used for this transaction. Please use a different payment method." msgstr "La tua carta non supporta la valuta utilizzata per questa transazione. Si prega di utilizzare un metodo di pagamento diverso." -#: inc/payments/payment-helper.php:517 +#: inc/payments/payment-helper.php:522 msgid "A transaction with identical details was submitted recently. Please wait a moment and try again." msgstr "Una transazione con dettagli identici è stata inviata di recente. Attendere un momento e riprovare." -#: inc/payments/payment-helper.php:518 +#: inc/payments/payment-helper.php:523 msgid "The account associated with your card is invalid. Please contact your bank." msgstr "L'account associato alla tua carta non è valido. Si prega di contattare la propria banca." -#: inc/payments/payment-helper.php:519 +#: inc/payments/payment-helper.php:524 msgid "The payment amount is invalid. Please contact the site administrator." msgstr "L'importo del pagamento non è valido. Si prega di contattare l'amministratore del sito." -#: inc/payments/payment-helper.php:522 +#: inc/payments/payment-helper.php:527 msgid "Your card information needs to be updated. Please contact your bank." msgstr "I tuoi dati della carta devono essere aggiornati. Si prega di contattare la tua banca." -#: inc/payments/payment-helper.php:523 +#: inc/payments/payment-helper.php:528 msgid "The card cannot be used for this transaction. Please contact your bank." msgstr "La carta non può essere utilizzata per questa transazione. Si prega di contattare la propria banca." -#: inc/payments/payment-helper.php:524 +#: inc/payments/payment-helper.php:529 msgid "The transaction is not permitted. Please contact your bank." msgstr "La transazione non è consentita. Si prega di contattare la propria banca." -#: inc/payments/payment-helper.php:525 +#: inc/payments/payment-helper.php:530 msgid "Your card requires offline PIN authentication. Please try again." msgstr "La tua carta richiede l'autenticazione PIN offline. Per favore riprova." -#: inc/payments/payment-helper.php:526 +#: inc/payments/payment-helper.php:531 msgid "Your card requires PIN authentication. Please try again." msgstr "La tua carta richiede l'autenticazione tramite PIN. Per favore riprova." -#: inc/payments/payment-helper.php:527 +#: inc/payments/payment-helper.php:532 msgid "You have exceeded the maximum number of PIN attempts. Please contact your bank." msgstr "Hai superato il numero massimo di tentativi di inserimento del PIN. Si prega di contattare la propria banca." -#: inc/payments/payment-helper.php:528 +#: inc/payments/payment-helper.php:533 msgid "All authorizations for this card have been revoked. Please contact your bank." msgstr "Tutte le autorizzazioni per questa carta sono state revocate. Si prega di contattare la propria banca." -#: inc/payments/payment-helper.php:529 +#: inc/payments/payment-helper.php:534 msgid "The authorization for this transaction has been revoked. Please try again." msgstr "L'autorizzazione per questa transazione è stata revocata. Per favore, riprova." -#: inc/payments/payment-helper.php:530 +#: inc/payments/payment-helper.php:535 msgid "This transaction is not allowed. Please contact your bank." msgstr "Questa transazione non è consentita. Si prega di contattare la propria banca." -#: inc/payments/payment-helper.php:532 +#: inc/payments/payment-helper.php:537 msgid "Your card was declined. Your request was in live mode, but used a known test card." msgstr "La tua carta è stata rifiutata. La tua richiesta era in modalità live, ma è stata utilizzata una carta di test conosciuta." -#: inc/payments/payment-helper.php:533 +#: inc/payments/payment-helper.php:538 msgid "Your card was declined. Your request was in test mode, but used a non test card. For a list of valid test cards, visit: https://stripe.com/docs/testing." msgstr "La tua carta è stata rifiutata. La tua richiesta era in modalità di test, ma è stata utilizzata una carta non di test. Per un elenco di carte di test valide, visita: https://stripe.com/docs/testing." -#: inc/payments/payment-helper.php:536 +#: inc/payments/payment-helper.php:541 msgid "SureForms Subscription" msgstr "Abbonamento SureForms" -#: inc/payments/payment-helper.php:537 +#: inc/payments/payment-helper.php:542 msgid "SureForms Payment" msgstr "Pagamento SureForms" -#: inc/payments/payment-helper.php:539 +#: inc/payments/payment-helper.php:544 msgid "SureForms Customer" msgstr "Cliente SureForms" -#: inc/payments/payment-helper.php:559 +#: inc/payments/payment-helper.php:564 msgid "Unknown error" msgstr "Errore sconosciuto" @@ -14977,74 +14978,74 @@ msgstr "Impossibile creare un modulo duplicato." #: inc/payments/front-end.php:97 #: inc/payments/front-end.php:298 -#: inc/payments/payment-helper.php:589 +#: inc/payments/payment-helper.php:594 msgid "Invalid form configuration." msgstr "Configurazione del modulo non valida." -#: inc/payments/payment-helper.php:597 +#: inc/payments/payment-helper.php:602 msgid "Payment configuration not found for this form." msgstr "Configurazione di pagamento non trovata per questo modulo." #. translators: 1: expected currency, 2: received currency -#: inc/payments/payment-helper.php:608 +#: inc/payments/payment-helper.php:613 #, php-format msgid "Currency mismatch: expected %1$s, received %2$s." msgstr "Discrepanza di valuta: previsto %1$s, ricevuto %2$s." #. translators: 1: expected amount with currency -#: inc/payments/payment-helper.php:625 +#: inc/payments/payment-helper.php:630 #, php-format msgid "Payment amount must be exactly %1$s." msgstr "L'importo del pagamento deve essere esattamente %1$s." #. translators: 1: minimum amount with currency -#: inc/payments/payment-helper.php:636 +#: inc/payments/payment-helper.php:641 #, php-format msgid "Payment amount must be at least %1$s." msgstr "L'importo del pagamento deve essere almeno %1$s." -#: inc/payments/payment-helper.php:712 +#: inc/payments/payment-helper.php:717 msgid "Invalid payment verification parameters." msgstr "Parametri di verifica del pagamento non validi." -#: inc/payments/payment-helper.php:723 +#: inc/payments/payment-helper.php:728 msgid "Payment verification failed. Invalid payment intent." msgstr "Verifica del pagamento fallita. Intento di pagamento non valido." -#: inc/payments/payment-helper.php:809 -#: inc/payments/payment-helper.php:947 +#: inc/payments/payment-helper.php:814 +#: inc/payments/payment-helper.php:952 msgid "Variable amount field configuration not found." msgstr "Configurazione del campo dell'importo variabile non trovata." -#: inc/payments/payment-helper.php:830 +#: inc/payments/payment-helper.php:835 msgid "No payment options are configured for this field." msgstr "Nessuna opzione di pagamento è configurata per questo campo." #. translators: %s: currency code -#: inc/payments/payment-helper.php:856 +#: inc/payments/payment-helper.php:861 msgid "Invalid payment amount. Please select a valid amount from the available options." msgstr "Importo di pagamento non valido. Si prega di selezionare un importo valido tra le opzioni disponibili." #. translators: %1$s: expected amount, %2$s: payment amount -#: inc/payments/payment-helper.php:891 +#: inc/payments/payment-helper.php:896 msgid "Payment configuration not found." msgstr "Configurazione del pagamento non trovata." #. translators: %1$s: expected amount, %2$s: payment amount -#: inc/payments/payment-helper.php:907 -#: inc/payments/payment-helper.php:959 -#: inc/payments/payment-helper.php:995 +#: inc/payments/payment-helper.php:912 +#: inc/payments/payment-helper.php:964 +#: inc/payments/payment-helper.php:1000 #, php-format msgid "Payment amount mismatch. Expected %1$s, received %2$s." msgstr "Importo del pagamento non corrispondente. Previsto %1$s, ricevuto %2$s." -#: inc/payments/payment-helper.php:936 -#: inc/payments/payment-helper.php:986 +#: inc/payments/payment-helper.php:941 +#: inc/payments/payment-helper.php:991 msgid "Variable amount field value is required." msgstr "È richiesto il valore del campo importo variabile." #. translators: %1$s: minimum amount, %2$s: payment amount -#: inc/payments/payment-helper.php:1007 +#: inc/payments/payment-helper.php:1012 #, php-format msgid "Payment amount below minimum. Minimum: %1$s, received %2$s." msgstr "Importo del pagamento inferiore al minimo. Minimo: %1$s, ricevuto %2$s." @@ -15130,7 +15131,7 @@ msgstr "Gateway di pagamento non trovato." msgid "Refund processing is not supported for %s gateway." msgstr "Il rimborso non è supportato per il gateway %s." -#: inc/payments/payment-helper.php:969 +#: inc/payments/payment-helper.php:974 msgid "Number field configuration not found." msgstr "Configurazione del campo numerico non trovata." @@ -15249,12 +15250,12 @@ msgid "Stripe Settings" msgstr "Impostazioni di Stripe" #. translators: %1$s: SureForms version, %2$s: SureForms Pro Plugin Name, %3$s: SureForms Pro Version. -#: admin/admin.php:1376 +#: admin/admin.php:1377 #, php-format msgid "SureForms %1$s requires minimum %2$s %3$s to work properly. Please update to the latest version." msgstr "SureForms %1$s richiede almeno %2$s %3$s per funzionare correttamente. Si prega di aggiornare all'ultima versione." -#: admin/admin.php:1389 +#: admin/admin.php:1390 msgid "Update Now" msgstr "Aggiorna ora" @@ -15316,40 +15317,40 @@ msgstr "Seleziona la posizione del simbolo della valuta rispetto all'importo." msgid "Learn" msgstr "Impara" -#: admin/admin.php:1502 +#: admin/admin.php:1503 msgid "Amazing! SureForms is powering your forms and submissions - let's keep growing together!" msgstr "Incredibile! SureForms sta alimentando i tuoi moduli e le tue sottomissioni - continuiamo a crescere insieme!" -#: admin/admin.php:1503 +#: admin/admin.php:1504 msgid "If SureForms has been helpful, would you mind taking a moment to leave a 5-star review on WordPress.org?" msgstr "Se SureForms ti è stato utile, ti dispiacerebbe prendere un momento per lasciare una recensione a 5 stelle su WordPress.org?" -#: admin/admin.php:1506 -#: admin/admin.php:1550 +#: admin/admin.php:1507 +#: admin/admin.php:1551 msgid "Maybe later" msgstr "Forse più tardi" -#: admin/admin.php:1507 +#: admin/admin.php:1508 msgid "I already did" msgstr "L'ho già fatto" -#: admin/admin.php:1546 +#: admin/admin.php:1547 msgid "SureForms is ready to power your forms — explore what's possible!" msgstr "SureForms è pronto a potenziare i tuoi moduli — scopri cosa è possibile!" -#: admin/admin.php:1547 +#: admin/admin.php:1548 msgid "Manage your forms, track submissions, and discover features like AI Form Builder, payment integrations, and more from the SureForms dashboard." msgstr "Gestisci i tuoi moduli, traccia le sottomissioni e scopri funzionalità come AI Form Builder, integrazioni di pagamento e altro ancora dalla dashboard di SureForms." -#: admin/admin.php:1549 +#: admin/admin.php:1550 msgid "Go to Dashboard" msgstr "Vai al cruscotto" -#: admin/admin.php:1551 +#: admin/admin.php:1552 msgid "I already know" msgstr "Lo so già" -#: admin/admin.php:1631 +#: admin/admin.php:1632 msgid "Invalid parameters." msgstr "Parametri non validi." @@ -15739,7 +15740,7 @@ msgstr "Questo modulo non è ancora disponibile. Ricontrolla dopo l'orario di in #: inc/form-submit.php:99 #: inc/form-submit.php:400 #: inc/form-submit.php:445 -#: inc/form-submit.php:966 +#: inc/form-submit.php:968 #: inc/payments/front-end.php:77 #: inc/payments/front-end.php:258 #: inc/rest-api.php:98 @@ -15788,19 +15789,19 @@ msgstr "Si prega di controllare il modulo per eventuali errori." msgid "Your submission was flagged as spam. Please try again." msgstr "Il tuo invio è stato segnalato come spam. Per favore riprova." -#: inc/form-submit.php:649 +#: inc/form-submit.php:651 msgid "Unable to submit form. Please try again." msgstr "Impossibile inviare il modulo. Per favore riprova." -#: inc/form-submit.php:901 +#: inc/form-submit.php:903 msgid "No SMTP plugin detected. Please configure an SMTP plugin to enable email sending." msgstr "Nessun plugin SMTP rilevato. Si prega di configurare un plugin SMTP per abilitare l'invio di email." -#: inc/form-submit.php:902 +#: inc/form-submit.php:904 msgid "Email sending failed for an unknown reason." msgstr "Invio email fallito per una ragione sconosciuta." -#: inc/form-submit.php:941 +#: inc/form-submit.php:943 msgid "No emails were sent." msgstr "Nessuna email è stata inviata." @@ -15953,31 +15954,31 @@ msgstr "Impossibile eliminare i pagamenti. Si prega di riprovare." msgid "Unable to process refund. Please try again." msgstr "Impossibile elaborare il rimborso. Si prega di riprovare." -#: inc/payments/payment-helper.php:491 +#: inc/payments/payment-helper.php:496 msgid "Unable to complete payment. Please try again or contact support." msgstr "Impossibile completare il pagamento. Si prega di riprovare o contattare l'assistenza." -#: inc/payments/payment-helper.php:513 +#: inc/payments/payment-helper.php:518 msgid "Unable to process card. Please try again." msgstr "Impossibile elaborare la carta. Per favore riprova." -#: inc/payments/payment-helper.php:514 +#: inc/payments/payment-helper.php:519 msgid "Unable to process transaction. Please try again." msgstr "Impossibile elaborare la transazione. Si prega di riprovare." -#: inc/payments/payment-helper.php:520 +#: inc/payments/payment-helper.php:525 msgid "Unable to reach card issuer. Please try again later." msgstr "Impossibile contattare l'emittente della carta. Si prega di riprovare più tardi." -#: inc/payments/payment-helper.php:531 +#: inc/payments/payment-helper.php:536 msgid "Unable to process transaction. Please try again later." msgstr "Impossibile elaborare la transazione. Si prega di riprovare più tardi." -#: inc/payments/payment-helper.php:541 +#: inc/payments/payment-helper.php:546 msgid "Complete the form to view the amount." msgstr "Compila il modulo per visualizzare l'importo." -#: inc/payments/payment-helper.php:542 +#: inc/payments/payment-helper.php:547 msgid "Unable to create payment. Please contact support." msgstr "Impossibile creare il pagamento. Si prega di contattare il supporto." @@ -16693,7 +16694,7 @@ msgid "Invalid webhook signature." msgstr "Firma del webhook non valida." #: admin/admin.php:426 -#: admin/admin.php:974 +#: admin/admin.php:975 #: assets/build/formEditor.js:172 msgid "Quizzes" msgstr "Quiz" @@ -16707,11 +16708,11 @@ msgstr "Voci del quiz" msgid "New" msgstr "Nuovo" -#: inc/form-submit.php:975 +#: inc/form-submit.php:977 msgid "Invalid form." msgstr "Modulo non valido." -#: inc/form-submit.php:980 +#: inc/form-submit.php:982 msgid "Too many requests. Please try again shortly." msgstr "Troppe richieste. Si prega di riprovare a breve." @@ -17225,7 +17226,7 @@ msgstr "Seleziona questo per creare un quiz con domande a punteggio e risultati #: admin/admin.php:458 #: admin/admin.php:459 -#: admin/admin.php:979 +#: admin/admin.php:980 msgid "Survey Reports" msgstr "Rapporti di indagine" @@ -17491,7 +17492,7 @@ msgstr "Aiuta a plasmare il futuro di SureForms" #: assets/build/settings.js:172 msgid "Share how you use the plugin so we can build features that matter, fix issues faster, and make smarter decisions. " -msgstr "Condividi come utilizzi il plugin in modo che possiamo sviluppare funzionalità che contano, risolvere i problemi più velocemente e prendere decisioni più intelligenti. " +msgstr "Condividi come utilizzi il plugin in modo che possiamo sviluppare funzionalità che contano, risolvere i problemi più velocemente e prendere decisioni più intelligenti." #: assets/build/settings.js:172 msgid "Enable Google Address Autocomplete" @@ -17569,6 +17570,14 @@ msgstr "Mostra i risultati in tempo reale ai rispondenti" msgid "Perfect for feedback, polls, and research" msgstr "Perfetto per feedback, sondaggi e ricerche" +#: inc/payments/payment-helper.php:259 +msgid "Polish Złoty" +msgstr "Złoty polacco" + +#: assets/build/blocks.js:172 +msgid "Dynamic Default Value" +msgstr "Valore predefinito dinamico" + #: inc/post-types.php:205 msgctxt "post type general name" msgid "Forms" diff --git a/languages/sureforms-nl_NL-4b62e3f004dea2c587b5a3069263d994.json b/languages/sureforms-nl_NL-4b62e3f004dea2c587b5a3069263d994.json index 60ab44130..1d9668d18 100644 --- a/languages/sureforms-nl_NL-4b62e3f004dea2c587b5a3069263d994.json +++ b/languages/sureforms-nl_NL-4b62e3f004dea2c587b5a3069263d994.json @@ -1 +1 @@ -{"translation-revision-date":"2024-12-13T12:33:48+00:00","generator":"WP-CLI\/2.12.0","source":"assets\/build\/blocks.js","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","lang":"en","plural-forms":"nplurals=2; plural=(n != 1);"},"Settings":["Instellingen"],"Search":["Zoeken"],"Fields":["Velden"],"Image":["Afbeelding"],"Submit":["Indienen"],"Required":["Vereist"],"Form Title":["Formuliertitel"],"Show":["Tonen"],"Hide":["Verbergen"],"Edit Form":["Formulier bewerken"],"Icon":["Icoon"],"Desktop":["Bureaublad"],"Medium":["Middelgroot"],"Mobile":["Mobiel"],"Repeat":["Herhaal"],"Scroll":["Scrollen"],"Tablet":["Tablet"],"Basic":["Basis"],"(no title)":["(geen titel)"],"Select a Form":["Selecteer een formulier"],"No forms found\u2026":["Geen formulieren gevonden\u2026"],"Choose":["Kies"],"Create New":["Nieuw maken"],"Change Form":["Formulier wijzigen"],"This form has been deleted or is unavailable.":["Dit formulier is verwijderd of is niet beschikbaar."],"Form Settings":["Formulierinstellingen"],"Show Form Title on this Page":["Toon formulier titel op deze pagina"],"Note: For editing SureForms, please refer to the SureForms Editor - ":["Opmerking: Voor het bewerken van SureForms, raadpleeg de SureForms Editor -"],"Field preview":["Veldvoorbeeld"],"General":["Algemeen"],"Style":["Stijl"],"Advanced":["Geavanceerd"],"No tags available":["Geen tags beschikbaar"],"Device":["Apparaat"],"Select Shortcodes":["Selecteer shortcodes"],"Page Break Label":["Pagina-einde label"],"Next":["Volgende"],"Back":["Terug"],"Reset":["Resetten"],"Generic tags":["Algemene tags"],"Pixel":["Pixel"],"Em":["Em"],"Select Units":["Selecteer eenheden"],"%s units":["%s eenheden"],"Margin":["Marge"],"Attributes":["Kenmerken"],"Input Pattern":["Invoermuster"],"None":["Geen"],"(###) ###-####":["(###) ###-####"],"(##) ####-####":["(##) ####-####"],"27\/08\/2024":["27\/08\/2024"],"23:59:59":["23:59:59"],"27\/08\/2024 23:59:59":["27\/08\/2024 23:59:59"],"Custom":["Aangepast"],"Custom Mask":["Aangepast masker"],"Please check the documentation to manage custom input pattern ":["Controleer de documentatie om het aangepaste invoerpatroon te beheren"],"here":["hier"],"Default Value":["Standaardwaarde"],"Error Message":["Foutmelding"],"Help Text":["Helptekst"],"Number Format":["Getalnotatie"],"US Style (Eg: 9,999.99)":["VS-stijl (Bijv: 9.999,99)"],"EU Style (Eg: 9.999,99)":["EU-stijl (Bijv: 9.999,99)"],"Minimum Value":["Minimumwaarde"],"Maximum Value":["Maximale waarde"],"Please check the Minimum and Maximum value":["Controleer de minimum- en maximumwaarde"],"Enable Email Confirmation":["E-mailbevestiging inschakelen"],"Checked by Default":["Standaard aangevinkt"],"Error message":["Foutmelding"],"Checked by default":["Standaard aangevinkt"],"Please add a option props to MultiButtonsControl":["Voeg alstublieft een optie-eigenschap toe aan MultiButtonsControl"],"Icon Library":["Iconenbibliotheek"],"Close":["Sluiten"],"All Icons":["Alle pictogrammen"],"Other":["Anders"],"No Icons Found":["Geen pictogrammen gevonden"],"Insert Icon":["Pictogram invoegen"],"Change Icon":["Pictogram wijzigen"],"Choose Icon":["Kies pictogram"],"Confirm":["Bevestigen"],"Cancel":["Annuleren"],"Processing\u2026":["Bezig met verwerken\u2026"],"Select Video":["Selecteer video"],"Change Video":["Video wijzigen"],"Select Lottie Animation":["Selecteer Lottie-animatie"],"Change Lottie Animation":["Wijzig Lottie-animatie"],"Upload SVG":["SVG uploaden"],"Change SVG":["SVG wijzigen"],"Select Image":["Selecteer afbeelding"],"Change Image":["Afbeelding wijzigen"],"Upload SVG?":["SVG uploaden?"],"Upload SVG can be potentially risky. Are you sure?":["Het uploaden van SVG kan potentieel riskant zijn. Weet je het zeker?"],"Upload Anyway":["Toch uploaden"],"Bulk Add":["Bulk toevoegen"],"Bulk Add Options":["Bulkopties toevoegen"],"Enter each option on a new line.":["Voer elke optie op een nieuwe regel in."],"Insert Options":["Opties invoegen"],"Full Width":["Volledige breedte"],"Option Type":["Optietype"],"Edit Options":["Bewerk opties"],"Add New Option":["Nieuwe optie toevoegen"],"ADD":["TOEVOEGEN"],"Enable Auto Country Detection":["Automatische landdetectie inschakelen"],"%s Width":["%s Breedte"],"Upgrade":["Upgrade"],"Clear":["Duidelijk"],"Select Color":["Selecteer kleur"],"Primary Color":["Primaire kleur"],"Text Color":["Tekstkleur"],"Field Spacing":["Veldafstand"],"Small":["Klein"],"Large":["Groot"],"Left":["Links"],"Center":["Centrum"],"Right":["Rechts"],"Color":["Kleur"],"Background Color":["Achtergrondkleur"],"Auto":["Auto"],"Default":["Standaard"],"Normal":["Normaal"],"%":["%"],"Top":["Top"],"Bottom":["Onderkant"],"Width":["Breedte"],"Size":["Grootte"],"EM":["EM"],"Padding":["Opvulling"],"Color 1":["Kleur 1"],"Color 2":["Kleur 2"],"Type":["Type"],"Linear":["Lineair"],"Radial":["Radiaal"],"Location 1":["Locatie 1"],"Location 2":["Locatie 2"],"Angle":["Hoek"],"Classic":["Klassiek"],"Gradient":["Gradi\u00ebnt"],"Horizontal":["Horizontaal"],"Vertical":["Verticaal"],"Background":["Achtergrond"],"Cover":["Omslag"],"Contain":["Bevatten"],"Layout":["Indeling"],"Overlay":["Overlay"],"No Repeat":["Geen herhaling"],"Overlay Opacity":["Overlay-opaciteit"],"Conditional Logic":["Conditionele logica"],"Upgrade to the SureForms Starter Plan to create dynamic forms that adapt based on user input, offering a personalised and efficient form experience.":["Upgrade naar het SureForms Starter Plan om dynamische formulieren te maken die zich aanpassen op basis van gebruikersinvoer, en zo een gepersonaliseerde en effici\u00ebnte formulierervaring bieden."],"Enable Conditional Logic":["Voorwaardelijke logica inschakelen"],"this field if":["dit veld indien"],"Configure Conditions":["Voorwaarden configureren"],"Premium":["Premium"],"Overlay Type":["Overlaytype"],"Image Overlay Color":["Afbeelding Overlay Kleur"],"Image Position":["Afbeeldingspositie"],"Attachment":["Bijlage"],"Fixed":["Vast"],"Blend Mode":["Overvloeimodus"],"Multiply":["Vermenigvuldigen"],"Screen":["Scherm"],"Darken":["Verduisteren"],"Lighten":["Verlichten"],"Color Dodge":["Kleur Dodge"],"Saturation":["Verzadiging"],"Repeat-x":["Herhaal-x"],"Repeat-y":["Herhaal-y"],"PX":["PX"],"Button":["Knop"],"Prefix Label":["Voorvoegsel Label"],"Suffix Label":["Achtervoegsel Label"],"Border Radius":["Randstraal"],"Form Theme":["Formulier Thema"],"Select Gradient":["Selecteer verloop"],"Unlock Conditional Logic Editor":["Ontgrendel de voorwaardelijke logica-editor"],"Rich Text Editor":["Rich Text Editor"],"Read Only":["Alleen lezen"],"Select Country":["Selecteer land"],"Default Country":["Standaardland"],"Subscription":["Abonnement"],"One Time":["E\u00e9n keer"],"Unique Entry":["Unieke invoer"],"Maximum Characters":["Maximale tekens"],"Textarea Height":["Hoogte van tekstvak"],"Minimum Selections":["Minimale selecties"],"Maximum Selections":["Maximale selecties"],"Add Numeric Values to Options":["Numerieke waarden aan opties toevoegen"],"Single Choice Only":["Enkel \u00e9\u00e9n keuze"],"Enable Dropdown Search":["Dropdown zoeken inschakelen"],"Allow Multiple":["Meerdere toestaan"],"%1$s fields are required. Please configure these fields in the block settings.":["%1$s velden zijn verplicht. Configureer deze velden in de blokinstellingen."],"%1$s field is required. Please configure this field in the block settings.":["%1$s veld is verplicht. Configureer dit veld in de blokinstellingen."],"You need to configure a payment account to collect payments from this form. Please configure your payment provider to proceed.":["U moet een betaalrekening configureren om betalingen van dit formulier te innen. Configureer uw betalingsprovider om door te gaan."],"Configure Payment Account":["Betaalrekening configureren"],"This is a placeholder for the Payment block. The actual payment fields for your configured payment provider(s) will only appear when you preview or publish the form.":["Dit is een tijdelijke aanduiding voor het betalingsblok. De daadwerkelijke betalingsvelden voor uw geconfigureerde betalingsprovider(s) verschijnen alleen wanneer u het formulier bekijkt of publiceert."],"2 Payments":["2 Betalingen"],"3 Payments":["3 Betalingen"],"4 Payments":["4 Betalingen"],"5 Payments":["5 Betalingen"],"Never":["Nooit"],"Stop Subscription After":["Abonnement Stoppen Na"],"Choose when to automatically stop the subscription":["Kies wanneer het abonnement automatisch moet worden stopgezet"],"Number of Payments":["Aantal betalingen"],"Enter a number between 1 to 100":["Voer een getal in tussen 1 en 100"],"Form Field":["Formulier Veld"],"Payment Type":["Betalingstype"],"Subscription Plan Name":["Abonnementsplan Naam"],"Billing Interval":["Factureringsinterval"],"Daily":["Dagelijks"],"Weekly":["Wekelijks"],"Monthly":["Maandelijks"],"Quarterly":["Per kwartaal"],"Yearly":["Jaarlijks"],"Amount Type":["Bedragstype"],"Fixed Amount":["Vast Bedrag"],"Dynamic Amount":["Dynamisch Bedrag"],"Choose whether to charge a fixed amount or charge the amount based on user input in other form fields.":["Kies of u een vast bedrag wilt rekenen of het bedrag wilt berekenen op basis van gebruikersinvoer in andere formuliervelden."],"Set the exact amount you want to charge. Users won\u2019t be able to change it":["Stel het exacte bedrag in dat u wilt berekenen. Gebruikers kunnen het niet wijzigen"],"Choose Amount Field":["Kies bedragveld"],"Select a field\u2026":["Selecteer een veld\u2026"],"Pick a field from your form like a number, dropdown, or multichoice whose value should decide the payment amount.":["Kies een veld uit uw formulier, zoals een nummer, dropdown of meerkeuze, waarvan de waarde het betalingsbedrag moet bepalen."],"Minimum Amount":["Minimumbedrag"],"Set the minimum amount users can enter (0 for no minimum)":["Stel het minimale bedrag in dat gebruikers kunnen invoeren (0 voor geen minimum)"],"Customer Name Field (Required)":["Klantnaamveld (Verplicht)"],"Customer Name Field (Optional)":["Klantnaamveld (Optioneel)"],"Select the input field that contains the customer name (Required for subscriptions)":["Selecteer het invoerveld dat de klantnaam bevat (Vereist voor abonnementen)"],"Select the input field that contains the customer name":["Selecteer het invoerveld dat de klantnaam bevat"],"Customer Email Field (Required)":["Klant e-mailveld (verplicht)"],"Select the email field that contains the customer email":["Selecteer het e-mailveld dat het e-mailadres van de klant bevat"],"Payment":["Betaling"],"%s - Order ID":["%s - Bestel-ID"],"%s - Amount":["%s - Bedrag"],"%s - Customer Email":["%s - Klant e-mail"],"%s - Customer Name":["%s - Klantnaam"],"%s - Status":["%s - Status"],"Button Alignment":["Knopuitlijning"],"Placeholder":["Placeholder"],"Preselect this option":["Selecteer deze optie vooraf"],"Restrict Country Codes":["Beperk landcodes"],"Restriction Type":["Beperkingstype"],"Allow":["Toestaan"],"Block":["Blok"],"Select Allowed Countries":["Selecteer Toegestane Landen"],"Choose countries\u2026":["Kies landen\u2026"],"Choose which country codes users can select in the phone number field. Leave empty to allow all country codes.":["Kies welke landcodes gebruikers kunnen selecteren in het telefoonnummer veld. Laat leeg om alle landcodes toe te staan."],"Select Blocked Countries":["Selecteer geblokkeerde landen"],"These countries will be hidden from the dropdown.":["Deze landen worden verborgen in de dropdown."],"Bulk Edit":["Bulk bewerken"],"Select Layout":["Selecteer indeling"],"Number of Columns":["Aantal kolommen"],"Validation Message for Duplicate":["Validatiebericht voor duplicaat"],"Click here to insert a form":["Klik hier om een formulier in te voegen"],"Inherit Form's Original Style":["De oorspronkelijke stijl van het formulier overnemen"],"Text on Primary":["Tekst op primair"],"%s - Description":["%s - Beschrijving"],"Upgrade to Unlock":["Upgrade om te ontgrendelen"],"Custom (Premium)":["Aangepast (Premium)"],"Select a theme style for this form embed.":["Selecteer een themastijl voor deze formulierinsluiting."],"Colors":["Kleuren"],"Advanced Styling":["Geavanceerde styling"],"Unlock Custom Styling":["Aangepaste styling ontgrendelen"],"Switch to Custom Mode to take full control of your form's design and spacing.":["Schakel over naar Aangepaste Modus om volledige controle te krijgen over het ontwerp en de ruimte van uw formulier."],"Full color control (buttons, fields, text)":["Volledige kleurcontrole (knoppen, velden, tekst)"],"Row and column gap control":["Regel de rij- en kolomafstand"],"Field spacing and layout precision":["Veldafstand en lay-outprecisie"],"Complete button styling":["Voltooi knopstijl"],"Payment Description":["Betalingsomschrijving"],"Shown on payment receipts and in your payment dashboard (Stripe and PayPal). Leave blank to use the default.":["Weergegeven op betalingsbewijzen en in uw betalingsdashboard (Stripe en PayPal). Laat leeg om de standaard te gebruiken."],"Slug":["Naaktslak"],"Auto-generated on save":["Automatisch gegenereerd bij opslaan"],"This slug is already used by another field. It will revert to the previous value.":["Deze slug wordt al gebruikt door een ander veld. Het zal terugkeren naar de vorige waarde."],"Changing the slug may break form submissions, conditional logic, integrations, or any other feature currently referencing this slug. You will need to update all such references manually.":["Het wijzigen van de slug kan ervoor zorgen dat formulierinzendingen, voorwaardelijke logica, integraties of andere functies die momenteel naar deze slug verwijzen, niet meer werken. U moet al deze verwijzingen handmatig bijwerken."],"Field Slug":["Veld Slug"],"Location Services":["Locatiediensten"],"Unlock Address Autocomplete":["Adres automatisch aanvullen ontgrendelen"],"Upgrade to enable Google Address Autocomplete with interactive map preview, making address entry faster and more accurate for your users.":["Upgrade om Google Address Autocomplete met interactieve kaartvoorvertoning in te schakelen, waardoor het invoeren van adressen sneller en nauwkeuriger wordt voor uw gebruikers."],"Enable Google Autocomplete":["Google Autocomplete inschakelen"],"Show Interactive Map":["Interactieve kaart weergeven"],"Payments Per Page":["Betalingen Per Pagina"],"Show Subscriptions Section":["Abonnementssectie weergeven"],"Show a dedicated subscriptions section above payment history.":["Toon een speciale abonnementssectie boven de betalingsgeschiedenis."],"Payment Dashboard":["Betalingsdashboard"],"View your payments and manage subscriptions in a single dashboard.":["Bekijk uw betalingen en beheer abonnementen in \u00e9\u00e9n dashboard."]}}} \ No newline at end of file +{"translation-revision-date":"2024-12-13T12:33:48+00:00","generator":"WP-CLI\/2.12.0","source":"assets\/build\/blocks.js","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","lang":"en","plural-forms":"nplurals=2; plural=(n != 1);"},"Settings":["Instellingen"],"Search":["Zoeken"],"Fields":["Velden"],"Image":["Afbeelding"],"Submit":["Indienen"],"Required":["Vereist"],"Form Title":["Formuliertitel"],"Show":["Tonen"],"Hide":["Verbergen"],"Edit Form":["Formulier bewerken"],"Icon":["Icoon"],"Desktop":["Bureaublad"],"Medium":["Middelgroot"],"Mobile":["Mobiel"],"Repeat":["Herhaal"],"Scroll":["Scrollen"],"Tablet":["Tablet"],"Basic":["Basis"],"(no title)":["(geen titel)"],"Select a Form":["Selecteer een formulier"],"No forms found\u2026":["Geen formulieren gevonden\u2026"],"Choose":["Kies"],"Create New":["Nieuw maken"],"Change Form":["Formulier wijzigen"],"This form has been deleted or is unavailable.":["Dit formulier is verwijderd of is niet beschikbaar."],"Form Settings":["Formulierinstellingen"],"Show Form Title on this Page":["Toon formulier titel op deze pagina"],"Note: For editing SureForms, please refer to the SureForms Editor - ":["Opmerking: Voor het bewerken van SureForms, raadpleeg de SureForms Editor -"],"Field preview":["Veldvoorbeeld"],"General":["Algemeen"],"Style":["Stijl"],"Advanced":["Geavanceerd"],"No tags available":["Geen tags beschikbaar"],"Device":["Apparaat"],"Select Shortcodes":["Selecteer shortcodes"],"Page Break Label":["Pagina-einde label"],"Next":["Volgende"],"Back":["Terug"],"Reset":["Resetten"],"Generic tags":["Algemene tags"],"Pixel":["Pixel"],"Em":["Em"],"Select Units":["Selecteer eenheden"],"%s units":["%s eenheden"],"Margin":["Marge"],"Attributes":["Kenmerken"],"Input Pattern":["Invoermuster"],"None":["Geen"],"(###) ###-####":["(###) ###-####"],"(##) ####-####":["(##) ####-####"],"27\/08\/2024":["27\/08\/2024"],"23:59:59":["23:59:59"],"27\/08\/2024 23:59:59":["27\/08\/2024 23:59:59"],"Custom":["Aangepast"],"Custom Mask":["Aangepast masker"],"Please check the documentation to manage custom input pattern ":["Controleer de documentatie om het aangepaste invoerpatroon te beheren"],"here":["hier"],"Default Value":["Standaardwaarde"],"Error Message":["Foutmelding"],"Help Text":["Helptekst"],"Number Format":["Getalnotatie"],"US Style (Eg: 9,999.99)":["VS-stijl (Bijv: 9.999,99)"],"EU Style (Eg: 9.999,99)":["EU-stijl (Bijv: 9.999,99)"],"Minimum Value":["Minimumwaarde"],"Maximum Value":["Maximale waarde"],"Please check the Minimum and Maximum value":["Controleer de minimum- en maximumwaarde"],"Enable Email Confirmation":["E-mailbevestiging inschakelen"],"Checked by Default":["Standaard aangevinkt"],"Error message":["Foutmelding"],"Checked by default":["Standaard aangevinkt"],"Please add a option props to MultiButtonsControl":["Voeg alstublieft een optie-eigenschap toe aan MultiButtonsControl"],"Icon Library":["Iconenbibliotheek"],"Close":["Sluiten"],"All Icons":["Alle pictogrammen"],"Other":["Anders"],"No Icons Found":["Geen pictogrammen gevonden"],"Insert Icon":["Pictogram invoegen"],"Change Icon":["Pictogram wijzigen"],"Choose Icon":["Kies pictogram"],"Confirm":["Bevestigen"],"Cancel":["Annuleren"],"Processing\u2026":["Bezig met verwerken\u2026"],"Select Video":["Selecteer video"],"Change Video":["Video wijzigen"],"Select Lottie Animation":["Selecteer Lottie-animatie"],"Change Lottie Animation":["Wijzig Lottie-animatie"],"Upload SVG":["SVG uploaden"],"Change SVG":["SVG wijzigen"],"Select Image":["Selecteer afbeelding"],"Change Image":["Afbeelding wijzigen"],"Upload SVG?":["SVG uploaden?"],"Upload SVG can be potentially risky. Are you sure?":["Het uploaden van SVG kan potentieel riskant zijn. Weet je het zeker?"],"Upload Anyway":["Toch uploaden"],"Bulk Add":["Bulk toevoegen"],"Bulk Add Options":["Bulkopties toevoegen"],"Enter each option on a new line.":["Voer elke optie op een nieuwe regel in."],"Insert Options":["Opties invoegen"],"Full Width":["Volledige breedte"],"Option Type":["Optietype"],"Edit Options":["Bewerk opties"],"Add New Option":["Nieuwe optie toevoegen"],"ADD":["TOEVOEGEN"],"Enable Auto Country Detection":["Automatische landdetectie inschakelen"],"%s Width":["%s Breedte"],"Upgrade":["Upgrade"],"Clear":["Duidelijk"],"Select Color":["Selecteer kleur"],"Primary Color":["Primaire kleur"],"Text Color":["Tekstkleur"],"Field Spacing":["Veldafstand"],"Small":["Klein"],"Large":["Groot"],"Left":["Links"],"Center":["Centrum"],"Right":["Rechts"],"Color":["Kleur"],"Background Color":["Achtergrondkleur"],"Auto":["Auto"],"Default":["Standaard"],"Normal":["Normaal"],"%":["%"],"Top":["Top"],"Bottom":["Onderkant"],"Width":["Breedte"],"Size":["Grootte"],"EM":["EM"],"Padding":["Opvulling"],"Color 1":["Kleur 1"],"Color 2":["Kleur 2"],"Type":["Type"],"Linear":["Lineair"],"Radial":["Radiaal"],"Location 1":["Locatie 1"],"Location 2":["Locatie 2"],"Angle":["Hoek"],"Classic":["Klassiek"],"Gradient":["Gradi\u00ebnt"],"Horizontal":["Horizontaal"],"Vertical":["Verticaal"],"Background":["Achtergrond"],"Cover":["Omslag"],"Contain":["Bevatten"],"Layout":["Indeling"],"Overlay":["Overlay"],"No Repeat":["Geen herhaling"],"Overlay Opacity":["Overlay-opaciteit"],"Conditional Logic":["Conditionele logica"],"Upgrade to the SureForms Starter Plan to create dynamic forms that adapt based on user input, offering a personalised and efficient form experience.":["Upgrade naar het SureForms Starter Plan om dynamische formulieren te maken die zich aanpassen op basis van gebruikersinvoer, en zo een gepersonaliseerde en effici\u00ebnte formulierervaring bieden."],"Enable Conditional Logic":["Voorwaardelijke logica inschakelen"],"this field if":["dit veld indien"],"Configure Conditions":["Voorwaarden configureren"],"Premium":["Premium"],"Overlay Type":["Overlaytype"],"Image Overlay Color":["Afbeelding Overlay Kleur"],"Image Position":["Afbeeldingspositie"],"Attachment":["Bijlage"],"Fixed":["Vast"],"Blend Mode":["Overvloeimodus"],"Multiply":["Vermenigvuldigen"],"Screen":["Scherm"],"Darken":["Verduisteren"],"Lighten":["Verlichten"],"Color Dodge":["Kleur Dodge"],"Saturation":["Verzadiging"],"Repeat-x":["Herhaal-x"],"Repeat-y":["Herhaal-y"],"PX":["PX"],"Button":["Knop"],"Prefix Label":["Voorvoegsel Label"],"Suffix Label":["Achtervoegsel Label"],"Border Radius":["Randstraal"],"Form Theme":["Formulier Thema"],"Select Gradient":["Selecteer verloop"],"Unlock Conditional Logic Editor":["Ontgrendel de voorwaardelijke logica-editor"],"Rich Text Editor":["Rich Text Editor"],"Read Only":["Alleen lezen"],"Select Country":["Selecteer land"],"Default Country":["Standaardland"],"Subscription":["Abonnement"],"One Time":["E\u00e9n keer"],"Unique Entry":["Unieke invoer"],"Maximum Characters":["Maximale tekens"],"Textarea Height":["Hoogte van tekstvak"],"Minimum Selections":["Minimale selecties"],"Maximum Selections":["Maximale selecties"],"Add Numeric Values to Options":["Numerieke waarden aan opties toevoegen"],"Single Choice Only":["Enkel \u00e9\u00e9n keuze"],"Enable Dropdown Search":["Dropdown zoeken inschakelen"],"Allow Multiple":["Meerdere toestaan"],"%1$s fields are required. Please configure these fields in the block settings.":["%1$s velden zijn verplicht. Configureer deze velden in de blokinstellingen."],"%1$s field is required. Please configure this field in the block settings.":["%1$s veld is verplicht. Configureer dit veld in de blokinstellingen."],"You need to configure a payment account to collect payments from this form. Please configure your payment provider to proceed.":["U moet een betaalrekening configureren om betalingen van dit formulier te innen. Configureer uw betalingsprovider om door te gaan."],"Configure Payment Account":["Betaalrekening configureren"],"This is a placeholder for the Payment block. The actual payment fields for your configured payment provider(s) will only appear when you preview or publish the form.":["Dit is een tijdelijke aanduiding voor het betalingsblok. De daadwerkelijke betalingsvelden voor uw geconfigureerde betalingsprovider(s) verschijnen alleen wanneer u het formulier bekijkt of publiceert."],"2 Payments":["2 Betalingen"],"3 Payments":["3 Betalingen"],"4 Payments":["4 Betalingen"],"5 Payments":["5 Betalingen"],"Never":["Nooit"],"Stop Subscription After":["Abonnement Stoppen Na"],"Choose when to automatically stop the subscription":["Kies wanneer het abonnement automatisch moet worden stopgezet"],"Number of Payments":["Aantal betalingen"],"Enter a number between 1 to 100":["Voer een getal in tussen 1 en 100"],"Form Field":["Formulier Veld"],"Payment Type":["Betalingstype"],"Subscription Plan Name":["Abonnementsplan Naam"],"Billing Interval":["Factureringsinterval"],"Daily":["Dagelijks"],"Weekly":["Wekelijks"],"Monthly":["Maandelijks"],"Quarterly":["Per kwartaal"],"Yearly":["Jaarlijks"],"Amount Type":["Bedragstype"],"Fixed Amount":["Vast Bedrag"],"Dynamic Amount":["Dynamisch Bedrag"],"Choose whether to charge a fixed amount or charge the amount based on user input in other form fields.":["Kies of u een vast bedrag wilt rekenen of het bedrag wilt berekenen op basis van gebruikersinvoer in andere formuliervelden."],"Set the exact amount you want to charge. Users won\u2019t be able to change it":["Stel het exacte bedrag in dat u wilt berekenen. Gebruikers kunnen het niet wijzigen"],"Choose Amount Field":["Kies bedragveld"],"Select a field\u2026":["Selecteer een veld\u2026"],"Pick a field from your form like a number, dropdown, or multichoice whose value should decide the payment amount.":["Kies een veld uit uw formulier, zoals een nummer, dropdown of meerkeuze, waarvan de waarde het betalingsbedrag moet bepalen."],"Minimum Amount":["Minimumbedrag"],"Set the minimum amount users can enter (0 for no minimum)":["Stel het minimale bedrag in dat gebruikers kunnen invoeren (0 voor geen minimum)"],"Customer Name Field (Required)":["Klantnaamveld (Verplicht)"],"Customer Name Field (Optional)":["Klantnaamveld (Optioneel)"],"Select the input field that contains the customer name (Required for subscriptions)":["Selecteer het invoerveld dat de klantnaam bevat (Vereist voor abonnementen)"],"Select the input field that contains the customer name":["Selecteer het invoerveld dat de klantnaam bevat"],"Customer Email Field (Required)":["Klant e-mailveld (verplicht)"],"Select the email field that contains the customer email":["Selecteer het e-mailveld dat het e-mailadres van de klant bevat"],"Payment":["Betaling"],"%s - Order ID":["%s - Bestel-ID"],"%s - Amount":["%s - Bedrag"],"%s - Customer Email":["%s - Klant e-mail"],"%s - Customer Name":["%s - Klantnaam"],"%s - Status":["%s - Status"],"Button Alignment":["Knopuitlijning"],"Placeholder":["Placeholder"],"Preselect this option":["Selecteer deze optie vooraf"],"Restrict Country Codes":["Beperk landcodes"],"Restriction Type":["Beperkingstype"],"Allow":["Toestaan"],"Block":["Blok"],"Select Allowed Countries":["Selecteer Toegestane Landen"],"Choose countries\u2026":["Kies landen\u2026"],"Choose which country codes users can select in the phone number field. Leave empty to allow all country codes.":["Kies welke landcodes gebruikers kunnen selecteren in het telefoonnummer veld. Laat leeg om alle landcodes toe te staan."],"Select Blocked Countries":["Selecteer geblokkeerde landen"],"These countries will be hidden from the dropdown.":["Deze landen worden verborgen in de dropdown."],"Bulk Edit":["Bulk bewerken"],"Select Layout":["Selecteer indeling"],"Number of Columns":["Aantal kolommen"],"Validation Message for Duplicate":["Validatiebericht voor duplicaat"],"Click here to insert a form":["Klik hier om een formulier in te voegen"],"Inherit Form's Original Style":["De oorspronkelijke stijl van het formulier overnemen"],"Text on Primary":["Tekst op primair"],"%s - Description":["%s - Beschrijving"],"Upgrade to Unlock":["Upgrade om te ontgrendelen"],"Custom (Premium)":["Aangepast (Premium)"],"Select a theme style for this form embed.":["Selecteer een themastijl voor deze formulierinsluiting."],"Colors":["Kleuren"],"Advanced Styling":["Geavanceerde styling"],"Unlock Custom Styling":["Aangepaste styling ontgrendelen"],"Switch to Custom Mode to take full control of your form's design and spacing.":["Schakel over naar Aangepaste Modus om volledige controle te krijgen over het ontwerp en de ruimte van uw formulier."],"Full color control (buttons, fields, text)":["Volledige kleurcontrole (knoppen, velden, tekst)"],"Row and column gap control":["Regel de rij- en kolomafstand"],"Field spacing and layout precision":["Veldafstand en lay-outprecisie"],"Complete button styling":["Voltooi knopstijl"],"Payment Description":["Betalingsomschrijving"],"Shown on payment receipts and in your payment dashboard (Stripe and PayPal). Leave blank to use the default.":["Weergegeven op betalingsbewijzen en in uw betalingsdashboard (Stripe en PayPal). Laat leeg om de standaard te gebruiken."],"Slug":["Naaktslak"],"Auto-generated on save":["Automatisch gegenereerd bij opslaan"],"This slug is already used by another field. It will revert to the previous value.":["Deze slug wordt al gebruikt door een ander veld. Het zal terugkeren naar de vorige waarde."],"Changing the slug may break form submissions, conditional logic, integrations, or any other feature currently referencing this slug. You will need to update all such references manually.":["Het wijzigen van de slug kan ervoor zorgen dat formulierinzendingen, voorwaardelijke logica, integraties of andere functies die momenteel naar deze slug verwijzen, niet meer werken. U moet al deze verwijzingen handmatig bijwerken."],"Field Slug":["Veld Slug"],"Location Services":["Locatiediensten"],"Unlock Address Autocomplete":["Adres automatisch aanvullen ontgrendelen"],"Upgrade to enable Google Address Autocomplete with interactive map preview, making address entry faster and more accurate for your users.":["Upgrade om Google Address Autocomplete met interactieve kaartvoorvertoning in te schakelen, waardoor het invoeren van adressen sneller en nauwkeuriger wordt voor uw gebruikers."],"Enable Google Autocomplete":["Google Autocomplete inschakelen"],"Show Interactive Map":["Interactieve kaart weergeven"],"Payments Per Page":["Betalingen Per Pagina"],"Show Subscriptions Section":["Abonnementssectie weergeven"],"Show a dedicated subscriptions section above payment history.":["Toon een speciale abonnementssectie boven de betalingsgeschiedenis."],"Payment Dashboard":["Betalingsdashboard"],"View your payments and manage subscriptions in a single dashboard.":["Bekijk uw betalingen en beheer abonnementen in \u00e9\u00e9n dashboard."],"Dynamic Default Value":["Dynamische Standaardwaarde"]}}} \ No newline at end of file diff --git a/languages/sureforms-nl_NL-51635fe6489fc8288d603fe596c755ca.json b/languages/sureforms-nl_NL-51635fe6489fc8288d603fe596c755ca.json index c4ff58b77..1fc23baba 100644 --- a/languages/sureforms-nl_NL-51635fe6489fc8288d603fe596c755ca.json +++ b/languages/sureforms-nl_NL-51635fe6489fc8288d603fe596c755ca.json @@ -1 +1 @@ -{"translation-revision-date":"2024-12-13T12:33:48+00:00","generator":"WP-CLI\/2.12.0","source":"assets\/build\/settings.js","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","lang":"en","plural-forms":"nplurals=2; plural=(n != 1);"},"Dashboard":["Dashboard"],"Settings":["Instellingen"],"Entries":["Inzendingen"],"Activated":["Geactiveerd"],"Activate":["Activeren"],"Monday":["Maandag"],"Forms":["Formulieren"],"GitHub":["GitHub"],"General":["Algemeen"],"Other":["Anders"],"Confirm":["Bevestigen"],"Cancel":["Annuleren"],"Install":["Installeren"],"Plugin Installation failed, Please try again later.":["Installatie van de plugin mislukt, probeer het later opnieuw."],"Plugin activation failed, Please try again later.":["Plug-in activering mislukt, probeer het later opnieuw."],"Integrations":["Integraties"],"What's New?":["Wat is er nieuw?"],"Core":["Kern"],"Unlicensed":["Ongeautoriseerd"],"Connecting\u2026":["Verbinden\u2026"],"Install & Activate":["Installeren & Activeren"],"Send Email To":["E-mail verzenden naar"],"Google reCAPTCHA":["Google reCAPTCHA"],"hCaptcha":["hCaptcha"],"reCAPTCHA v2 Invisible":["reCAPTCHA v2 Onzichtbaar"],"reCAPTCHA v3":["reCAPTCHA v3"],"Validations":["Validaties"],"Spam Protection":["Spam Bescherming"],"If this option is turned on, the user's IP address will be saved with the form data":["Als deze optie is ingeschakeld, wordt het IP-adres van de gebruiker samen met de formuliergegevens opgeslagen"],"Enable Honeypot Security":["Honeypot-beveiliging inschakelen"],"Enable Honeypot Security for better spam protection":["Schakel Honeypot-beveiliging in voor betere spambeveiliging"],"%s represents the minimum selections needed. For example: \u201cMinimum 2 selections are required.\u201d":["%s vertegenwoordigt het minimum aantal selecties dat nodig is. Bijvoorbeeld: \"Minimaal 2 selecties zijn vereist.\""],"%s represents the maximum selections allowed. For example: \u201cMaximum 4 selections are allowed.\u201d":["%s vertegenwoordigt het maximale aantal toegestane selecties. Bijvoorbeeld: \"Maximaal 4 selecties zijn toegestaan.\""],"%s represents the minimum choices needed. For example: \u201cMinimum 1 selection is required.\u201d":["%s vertegenwoordigt de minimale keuzes die nodig zijn. Bijvoorbeeld: \"Minimaal 1 selectie is vereist.\""],"%s represents the maximum choices allowed. For example: \u201cMaximum 3 selections are allowed.\u201d":["%s vertegenwoordigt het maximale aantal toegestane keuzes. Bijvoorbeeld: \"Maximaal 3 selecties zijn toegestaan.\""]," Error Message":["Foutmelding"],"Email Summaries":["E-mailoverzichten"],"Tuesday":["Dinsdag"],"Wednesday":["Woensdag"],"Thursday":["Donderdag"],"Friday":["Vrijdag"],"Saturday":["Zaterdag"],"Sunday":["Zondag"],"Schedule Reports":["Rapporten plannen"],"Auto":["Auto"],"Light":["Licht"],"Dark":["Donker"],"Turnstile":["Draaikruis"],"Get Keys":["Verkrijg sleutels"],"Documentation":["Documentatie"],"Site Key":["Sitecode"],"Secret Key":["Geheime Sleutel"],"Cloudflare Turnstile":["Cloudflare Turnstile"],"Appearance Mode":["Weergavemodus"],"This field cannot be left blank.":["Dit veld mag niet leeg worden gelaten."],"Test Email":["Test e-mail"],"IP Logging":["IP-logboek"],"Honeypot":["Honeypot"],"Confirmation Email Mismatch Message":["Bevestigingsmail komt niet overeen bericht"],"%s represents the minimum input value. For example: \"Minimum value is 10.\"":["%s vertegenwoordigt de minimale invoerwaarde. Bijvoorbeeld: \"Minimale waarde is 10.\""],"%s represents the maximum input value. For example: \"Maximum value is 100.\"":["%s vertegenwoordigt de maximale invoerwaarde. Bijvoorbeeld: \"Maximale waarde is 100.\""],"OttoKit":["OttoKit"],"Connect with OttoKit":["Verbind met OttoKit"],"reCAPTCHA":["reCAPTCHA"],"Ready to go beyond free plan?":["Klaar om verder te gaan dan het gratis plan?"],"Upgrade now":["Nu upgraden"],"and unlock the full power of SureForms!":["en ontgrendel de volledige kracht van SureForms!"],"Upgrade SureForms":["Upgrade SureForms"],"Upgrade Now":["Nu upgraden"],"Form Validation":["Formuliercontrole"],"Required Error Messages":["Vereiste foutmeldingen"],"Other Error Messages":["Andere foutmeldingen"],"Input Field Unique":["Uniek invoerveld"],"Email Field Unique":["E-mailveld uniek"],"Invalid URL":["Ongeldige URL"],"Phone Field Unique":["Telefoonveld Uniek"],"Invalid Field Number Block":["Ongeldige Veldnummer Blok"],"Invalid Email":["Ongeldig e-mailadres"],"Number Minimum Value":["Nummer Minimumwaarde"],"Number Maximum Value":["Maximale waarde van het nummer"],"Dropdown Minimum Selections":["Minimale selecties in dropdown"],"Dropdown Maximum Selections":["Maximale selecties in dropdown"],"Multiple Choice Minimum Selections":["Meerdere keuzes minimumselecties"],"Multiple Choice Maximum Selections":["Meerdere Keuzes Maximale Selecties"],"Input Field":["Invoerveld"],"Email Field":["E-mailveld"],"URL Field":["URL-veld"],"Phone Field":["Telefoonveld"],"Textarea Field":["Tekstvakveld"],"Checkbox Field":["Selectievakjeveld"],"Dropdown Field":["Keuzelijstveld"],"Multiple Choice Field":["Meerkeuzeveld"],"Address Field":["Adresveld"],"Number Field":["Nummer veld"],"reCAPTCHA v2":["reCAPTCHA v2"],"To enable reCAPTCHA feature on your SureForms Please enable reCAPTCHA option on your blocks setting and select version. Add google reCAPTCHA secret and site key here. reCAPTCHA will be added to your page on front-end.":["Om de reCAPTCHA-functie op uw SureForms in te schakelen, schakelt u de reCAPTCHA-optie in uw blokinstellingen in en selecteert u de versie. Voeg hier de Google reCAPTCHA-secret en site key toe. reCAPTCHA wordt aan uw pagina toegevoegd aan de voorkant."],"Enter your %s here":["Voer hier uw %s in"],"To enable hCAPTCHA, please add your site key and secret key. Configure these settings within the individual form.":["Om hCAPTCHA in te schakelen, voeg uw site-sleutel en geheime sleutel toe. Configureer deze instellingen binnen het individuele formulier."],"To enable Cloudflare Turnstile, please add your site key and secret key. Configure these settings within the individual form.":["Om Cloudflare Turnstile in te schakelen, voeg uw site-sleutel en geheime sleutel toe. Configureer deze instellingen binnen het individuele formulier."],"Save":["Opslaan"],"Anonymous Analytics":["Anonieme Analytics"],"Learn More":["Meer informatie"],"Admin Notification":["Beheerdersmelding"],"Enable Admin Notification":["Beheerdermelding inschakelen"],"Admin notifications keep you informed about new form entries since your last visit.":["Beheerdersmeldingen houden je op de hoogte van nieuwe formulierinzendingen sinds je laatste bezoek."],"Continue":["Doorgaan"],"Get Started":["Beginnen"],"Integration":["Integratie"],"Connect Native Integrations with SureForms":["Verbind native integraties met SureForms"],"Unlock powerful integrations in the Premium plan to automate your workflows and connect SureForms directly with your favourite tools.":["Ontgrendel krachtige integraties in het Premium-plan om je workflows te automatiseren en SureForms direct te verbinden met je favoriete tools."],"Send form submissions straight to CRMs, email, and marketing platforms":["Stuur formulierinzendingen rechtstreeks naar CRM's, e-mail en marketingplatforms"],"Automate repetitive tasks with seamless data syncing":["Automatiseer repetitieve taken met naadloze gegevenssynchronisatie"],"Access exclusive native integrations for faster workflows":["Toegang tot exclusieve native integraties voor snellere workflows"],"Payments":["Betalingen"],"Stripe account disconnected successfully.":["Stripe-account succesvol losgekoppeld."],"Failed to create webhook.":["Het is niet gelukt om de webhook te maken."],"Failed to connect to Stripe.":["Verbinding met Stripe mislukt."],"Webhook":["Webhook"],"Knowledge Base":["Kennisbank"],"What\u2019s New":["Wat is er nieuw"],"delete":["verwijderen"],"Please type \"%s\" in the input box":["Typ alstublieft \"%s\" in het invoerveld"],"To confirm, type \"%s\" in the box below:":["Om te bevestigen, typ \"%s\" in het vak hieronder:"],"Type \"%s\"":["Typ \"%s\""],"Go to OttoKit Settings":["Ga naar OttoKit-instellingen"],"USD - US Dollar":["USD - Amerikaanse dollar"],"Payment Mode":["Betaalwijze"],"Test Mode":["Testmodus"],"Live Mode":["Live-modus"],"General Settings":["Algemene instellingen"],"Set up email summaries, admin alerts, and data preferences to manage your forms with ease.":["Stel e-mailsamenvattingen, beheerderswaarschuwingen en gegevensvoorkeuren in om uw formulieren eenvoudig te beheren."],"Customize default error messages shown when users submit invalid or incomplete form entries.":["Pas standaardfoutmeldingen aan die worden weergegeven wanneer gebruikers ongeldige of onvolledige formulierinvoer indienen."],"Enable spam protection for your forms using CAPTCHA services or honeypot security.":["Schakel spambeveiliging voor uw formulieren in met behulp van CAPTCHA-diensten of honeypot-beveiliging."],"Connect and manage your payment gateways to securely accept transactions through your forms.":["Verbind en beheer uw betalingsgateways om veilig transacties via uw formulieren te accepteren."],"1% transaction and payment gateway fees apply.":["1% transactiekosten en kosten voor de betalingsgateway zijn van toepassing."],"2.9% transaction and payment gateway fees apply. Activate license to reduce transaction fees.":["2,9% transactiekosten en kosten voor de betalingsgateway zijn van toepassing. Activeer de licentie om de transactiekosten te verlagen."],"2.9% transaction and payment gateway fees apply.":["Er zijn 2,9% transactiekosten en kosten voor de betalingsgateway van toepassing."],"Please visit %1$s, delete an unused webhook, then click below to retry.":["Bezoek %1$s, verwijder een ongebruikte webhook en klik vervolgens hieronder om het opnieuw te proberen."],"SureForms could not create a webhook because your Stripe account has run out of free slots. Webhooks are needed to receive updates about payments.":["SureForms kon geen webhook maken omdat je Stripe-account geen gratis slots meer heeft. Webhooks zijn nodig om updates over betalingen te ontvangen."],"Stripe Dashboard":["Stripe-dashboard"],"Creating\u2026":["Aan het cre\u00ebren\u2026"],"Create Webhook":["Webhook maken"],"Successfully connected to Stripe!":["Succesvol verbonden met Stripe!"],"Invalid response from server. Please try again.":["Ongeldig antwoord van de server. Probeer het alstublieft opnieuw."],"Failed to disconnect Stripe account.":["Het is niet gelukt om de Stripe-account los te koppelen."],"Webhook created successfully!":["Webhook succesvol aangemaakt!"],"Select Currency":["Selecteer valuta"],"Select the default currency for payment forms.":["Selecteer de standaardvaluta voor betalingsformulieren."],"Connection Status":["Verbindingsstatus"],"Disconnect Stripe Account":["Stripe-account loskoppelen"],"Are you sure you want to disconnect your Stripe account? This will stop all active payments, subscriptions, and form transactions connected to this account.":["Weet u zeker dat u uw Stripe-account wilt loskoppelen? Dit zal alle actieve betalingen, abonnementen en formuliertransacties die aan dit account zijn gekoppeld, stoppen."],"Disconnect":["Verbreken"],"Disconnecting\u2026":["Verbinding verbreken\u2026"],"Webhook successfully connected, all Stripe events are being tracked.":["Webhook succesvol verbonden, alle Stripe-evenementen worden gevolgd."],"Connect your Stripe account to start accepting payments through your forms.":["Verbind uw Stripe-account om betalingen via uw formulieren te accepteren."],"Connect to Stripe":["Verbinden met Stripe"],"Securely connect to Stripe with just a few clicks to begin accepting payments! ":["Maak veilig verbinding met Stripe met slechts een paar klikken om betalingen te accepteren!"],"Payment Methods":["Betaalmethoden"],"Test mode allows you to process payments without real charges. Switch to Live mode for actual transactions.":["Met de testmodus kunt u betalingen verwerken zonder echte kosten. Schakel over naar de Live-modus voor daadwerkelijke transacties."],"General Payment Settings":["Algemene betalingsinstellingen"],"These settings apply to all payment gateways.":["Deze instellingen zijn van toepassing op alle betalingsgateways."],"Stripe Settings":["Stripe-instellingen"],"Left ($100)":["Links ($100)"],"Right (100$)":["Rechts (100$)"],"Left Space ($ 100)":["Linker ruimte ($ 100)"],"Right Space (100 $)":["Rechterruimte (100 $)"],"Currency Sign Position":["Positie van het valutateken"],"Select the position of the currency symbol relative to the amount.":["Selecteer de positie van het valutasymbool ten opzichte van het bedrag."],"Learn":["Leren"],"Enable email summaries":["E-mailoverzichten inschakelen"],"Enable IP logging":["IP-logboek inschakelen"],"Turn on Admin Notification from here.":["Zet hier de beheerdersmelding aan."],"Send entries to 100+ popular apps.":["Verzend inzendingen naar meer dan 100 populaire apps."],"Build automated workflows that run instantly.":["Bouw geautomatiseerde workflows die direct worden uitgevoerd."],"Create custom app integrations using our Custom App feature.":["Maak aangepaste app-integraties met behulp van onze functie Aangepaste App."],"Keep your tools in sync automatically.":["Houd je gereedschap automatisch gesynchroniseerd."],"This will install and activate OttoKit on your WordPress site to enable automation features.":["Hiermee wordt OttoKit op je WordPress-site ge\u00efnstalleerd en geactiveerd om automatiseringsfuncties mogelijk te maken."],"Automate Your Forms with OttoKit":["Automatiseer uw formulieren met OttoKit"],"Every form submission should trigger something \u2014 a Slack alert, a CRM lead, a follow-up email, or a new row in Google Sheets.":["Elke formulierinzending zou iets moeten activeren \u2014 een Slack-melding, een CRM-lead, een opvolg-e-mail of een nieuwe rij in Google Sheets."],"MCP":["MCP"],"Configure AI client permissions and MCP server settings.":["Configureer AI-clientmachtigingen en MCP-serverinstellingen."],"View documentation":["Documentatie bekijken"],"Copy to clipboard":["Kopi\u00ebren naar klembord"],"Claude Desktop":["Claude Desktop"],"~\/Library\/Application Support\/Claude\/claude_desktop_config.json (macOS) or %APPDATA%\\Claude\\claude_desktop_config.json (Windows)":["~\/Library\/Application Support\/Claude\/claude_desktop_config.json (macOS) of %APPDATA%\\Claude\\claude_desktop_config.json (Windows)"],"Claude Code":["Claude Code"],".mcp.json (project) or ~\/.claude.json (global)":[".mcp.json (project) of ~\/.claude.json (globaal)"],"Cursor":["Cursor"],"~\/.cursor\/mcp.json":["~\/.cursor\/mcp.json"],"VS Code (Copilot)":["VS Code (Copilot)"],".vscode\/mcp.json (project) or settings.json > mcp.servers (global)":[".vscode\/mcp.json (project) of settings.json > mcp.servers (globaal)"],"~\/.continue\/config.yaml or config.json":["~\/.continue\/config.yaml of config.json"],"Your client's MCP configuration file":["Het MCP-configuratiebestand van uw klant"],"Connect Your AI Client":["Verbind uw AI-client"],"AI Client":["AI-client"],"Create an Application Password \u2014 ":["Maak een applicatiewachtwoord aan \u2014"],"Open Application Passwords":["Open toepassingswachtwoorden"],"Or use this CLI command to add the server quickly (you will still need to set the environment variables):":["Of gebruik deze CLI-opdracht om de server snel toe te voegen (je moet nog steeds de omgevingsvariabelen instellen):"],"Copy the JSON config below into: ":["Kopieer de JSON-configuratie hieronder naar:"],"Replace \"your-application-password\" with the password from Step 1.":["Vervang \"your-application-password\" door het wachtwoord uit Stap 1."],"WP_API_URL \u2014 your site's MCP endpoint. WP_API_USERNAME \u2014 your WordPress username. WP_API_PASSWORD \u2014 the application password you generated.":["WP_API_URL \u2014 het MCP-eindpunt van je site. WP_API_USERNAME \u2014 je WordPress-gebruikersnaam. WP_API_PASSWORD \u2014 het applicatiewachtwoord dat je hebt gegenereerd."],"View setup docs":["Bekijk de installatiehandleidingen"],"The MCP Adapter plugin is installed but not active. Activate it to configure MCP settings.":["De MCP Adapter-plugin is ge\u00efnstalleerd maar niet actief. Activeer het om MCP-instellingen te configureren."],"The MCP Adapter plugin is required to connect AI clients to your forms. Download and install it from GitHub, then activate it.":["De MCP Adapter-plugin is vereist om AI-clients met uw formulieren te verbinden. Download en installeer het vanaf GitHub en activeer het vervolgens."],"Download the latest release from":["Download de nieuwste release van"],"Install the plugin via Plugins > Add New Plugin > Upload Plugin.":["Installeer de plugin via Plugins > Nieuwe plugin toevoegen > Plugin uploaden."],"Activate the MCP Adapter plugin.":["Activeer de MCP Adapter-plugin."],"Activating\u2026":["Activeren\u2026"],"Activate MCP Adapter":["Activeer MCP-adapter"],"Download MCP Adapter":["Download MCP Adapter"],"Experimental":["Experimenteel"],"Enable Abilities":["Vermogen inschakelen"],"Register SureForms abilities with the WordPress Abilities API. When enabled, AI clients can list, read, create, edit, and delete your forms and entries. When disabled, no abilities are registered and AI clients cannot perform any actions on your forms.":["Registreer SureForms-mogelijkheden bij de WordPress Abilities API. Wanneer ingeschakeld, kunnen AI-clients uw formulieren en inzendingen opsommen, lezen, maken, bewerken en verwijderen. Wanneer uitgeschakeld, worden er geen mogelijkheden geregistreerd en kunnen AI-clients geen acties uitvoeren op uw formulieren."],"Abilities API \u2014 Edit":["Vaardigheden-API \u2014 Bewerken"],"Enable Edit Abilities":["Bewerkingsmogelijkheden inschakelen"],"When enabled, AI clients can create new forms, update form titles, fields, and settings, duplicate forms, and modify entry statuses. When disabled, these abilities are unregistered and AI clients can only read your data.":["Wanneer ingeschakeld, kunnen AI-clients nieuwe formulieren maken, formuliertitels, velden en instellingen bijwerken, formulieren dupliceren en de status van inzendingen wijzigen. Wanneer uitgeschakeld, worden deze mogelijkheden uitgeschakeld en kunnen AI-clients alleen uw gegevens lezen."],"Abilities API \u2014 Delete":["Vaardigheden API \u2014 Verwijderen"],"Enable Delete Abilities":["Verwijdermogelijkheden inschakelen"],"When enabled, AI clients can permanently delete forms and entries. Deleted data cannot be recovered. When disabled, delete abilities are unregistered and AI clients cannot remove any data.":["Wanneer ingeschakeld, kunnen AI-clients formulieren en invoer permanent verwijderen. Verwijderde gegevens kunnen niet worden hersteld. Wanneer uitgeschakeld, worden verwijdermogelijkheden uitgeschakeld en kunnen AI-clients geen gegevens verwijderen."],"MCP Server":["MCP-server"],"Enable MCP Server":["MCP-server inschakelen"],"Creates a dedicated SureForms MCP endpoint that AI clients like Claude can connect to. When disabled, the endpoint is removed and external AI clients cannot discover or call any SureForms abilities.":["Maakt een speciale SureForms MCP-eindpunt aan waarmee AI-clients zoals Claude verbinding kunnen maken. Wanneer deze is uitgeschakeld, wordt het eindpunt verwijderd en kunnen externe AI-clients geen SureForms-mogelijkheden ontdekken of oproepen."],"Learn more":["Meer informatie"],"MCP Adapter Required":["MCP-adapter vereist"],"Google Maps":["Google Maps"],"Configure Google Maps API key for address autocomplete and map preview.":["Configureer de Google Maps API-sleutel voor adres-autocompletie en kaartvoorbeeld."],"Help shape the future of SureForms":["Help de toekomst van SureForms vormgeven"],"Share how you use the plugin so we can build features that matter, fix issues faster, and make smarter decisions. ":["Deel hoe je de plugin gebruikt, zodat we functies kunnen ontwikkelen die ertoe doen, problemen sneller kunnen oplossen en slimmere beslissingen kunnen nemen. "],"Enable Google Address Autocomplete":["Google-adres automatisch aanvullen inschakelen"],"Upgrade to the SureForms Business Plan to add Google-powered address autocomplete with interactive map preview to your forms.":["Upgrade naar het SureForms Business Plan om Google-aangedreven adres-autocompletie met interactieve kaartvoorvertoning aan uw formulieren toe te voegen."],"Auto-suggest addresses as users type for faster, error-free submissions":["Stel automatisch adressen voor terwijl gebruikers typen voor snellere, foutloze inzendingen"],"Show an interactive map preview with draggable pin for precise locations":["Toon een interactieve kaartvoorvertoning met een sleepbare pin voor precieze locaties"],"Automatically populate address fields like city, state, and postal code":["Automatisch adresvelden zoals stad, staat en postcode invullen"]}}} \ No newline at end of file +{"translation-revision-date":"2024-12-13T12:33:48+00:00","generator":"WP-CLI\/2.12.0","source":"assets\/build\/settings.js","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","lang":"en","plural-forms":"nplurals=2; plural=(n != 1);"},"Dashboard":["Dashboard"],"Settings":["Instellingen"],"Entries":["Inzendingen"],"Activated":["Geactiveerd"],"Activate":["Activeren"],"Monday":["Maandag"],"Forms":["Formulieren"],"GitHub":["GitHub"],"General":["Algemeen"],"Other":["Anders"],"Confirm":["Bevestigen"],"Cancel":["Annuleren"],"Install":["Installeren"],"Plugin Installation failed, Please try again later.":["Installatie van de plugin mislukt, probeer het later opnieuw."],"Plugin activation failed, Please try again later.":["Plug-in activering mislukt, probeer het later opnieuw."],"Integrations":["Integraties"],"What's New?":["Wat is er nieuw?"],"Core":["Kern"],"Unlicensed":["Ongeautoriseerd"],"Connecting\u2026":["Verbinden\u2026"],"Install & Activate":["Installeren & Activeren"],"Send Email To":["E-mail verzenden naar"],"Google reCAPTCHA":["Google reCAPTCHA"],"hCaptcha":["hCaptcha"],"reCAPTCHA v2 Invisible":["reCAPTCHA v2 Onzichtbaar"],"reCAPTCHA v3":["reCAPTCHA v3"],"Validations":["Validaties"],"Spam Protection":["Spam Bescherming"],"If this option is turned on, the user's IP address will be saved with the form data":["Als deze optie is ingeschakeld, wordt het IP-adres van de gebruiker samen met de formuliergegevens opgeslagen"],"Enable Honeypot Security":["Honeypot-beveiliging inschakelen"],"Enable Honeypot Security for better spam protection":["Schakel Honeypot-beveiliging in voor betere spambeveiliging"],"%s represents the minimum selections needed. For example: \u201cMinimum 2 selections are required.\u201d":["%s vertegenwoordigt het minimum aantal selecties dat nodig is. Bijvoorbeeld: \"Minimaal 2 selecties zijn vereist.\""],"%s represents the maximum selections allowed. For example: \u201cMaximum 4 selections are allowed.\u201d":["%s vertegenwoordigt het maximale aantal toegestane selecties. Bijvoorbeeld: \"Maximaal 4 selecties zijn toegestaan.\""],"%s represents the minimum choices needed. For example: \u201cMinimum 1 selection is required.\u201d":["%s vertegenwoordigt de minimale keuzes die nodig zijn. Bijvoorbeeld: \"Minimaal 1 selectie is vereist.\""],"%s represents the maximum choices allowed. For example: \u201cMaximum 3 selections are allowed.\u201d":["%s vertegenwoordigt het maximale aantal toegestane keuzes. Bijvoorbeeld: \"Maximaal 3 selecties zijn toegestaan.\""]," Error Message":["Foutmelding"],"Email Summaries":["E-mailoverzichten"],"Tuesday":["Dinsdag"],"Wednesday":["Woensdag"],"Thursday":["Donderdag"],"Friday":["Vrijdag"],"Saturday":["Zaterdag"],"Sunday":["Zondag"],"Schedule Reports":["Rapporten plannen"],"Auto":["Auto"],"Light":["Licht"],"Dark":["Donker"],"Turnstile":["Draaikruis"],"Get Keys":["Verkrijg sleutels"],"Documentation":["Documentatie"],"Site Key":["Sitecode"],"Secret Key":["Geheime Sleutel"],"Cloudflare Turnstile":["Cloudflare Turnstile"],"Appearance Mode":["Weergavemodus"],"This field cannot be left blank.":["Dit veld mag niet leeg worden gelaten."],"Test Email":["Test e-mail"],"IP Logging":["IP-logboek"],"Honeypot":["Honeypot"],"Confirmation Email Mismatch Message":["Bevestigingsmail komt niet overeen bericht"],"%s represents the minimum input value. For example: \"Minimum value is 10.\"":["%s vertegenwoordigt de minimale invoerwaarde. Bijvoorbeeld: \"Minimale waarde is 10.\""],"%s represents the maximum input value. For example: \"Maximum value is 100.\"":["%s vertegenwoordigt de maximale invoerwaarde. Bijvoorbeeld: \"Maximale waarde is 100.\""],"OttoKit":["OttoKit"],"Connect with OttoKit":["Verbind met OttoKit"],"reCAPTCHA":["reCAPTCHA"],"Ready to go beyond free plan?":["Klaar om verder te gaan dan het gratis plan?"],"Upgrade now":["Nu upgraden"],"and unlock the full power of SureForms!":["en ontgrendel de volledige kracht van SureForms!"],"Upgrade SureForms":["Upgrade SureForms"],"Upgrade Now":["Nu upgraden"],"Form Validation":["Formuliercontrole"],"Required Error Messages":["Vereiste foutmeldingen"],"Other Error Messages":["Andere foutmeldingen"],"Input Field Unique":["Uniek invoerveld"],"Email Field Unique":["E-mailveld uniek"],"Invalid URL":["Ongeldige URL"],"Phone Field Unique":["Telefoonveld Uniek"],"Invalid Field Number Block":["Ongeldige Veldnummer Blok"],"Invalid Email":["Ongeldig e-mailadres"],"Number Minimum Value":["Nummer Minimumwaarde"],"Number Maximum Value":["Maximale waarde van het nummer"],"Dropdown Minimum Selections":["Minimale selecties in dropdown"],"Dropdown Maximum Selections":["Maximale selecties in dropdown"],"Multiple Choice Minimum Selections":["Meerdere keuzes minimumselecties"],"Multiple Choice Maximum Selections":["Meerdere Keuzes Maximale Selecties"],"Input Field":["Invoerveld"],"Email Field":["E-mailveld"],"URL Field":["URL-veld"],"Phone Field":["Telefoonveld"],"Textarea Field":["Tekstvakveld"],"Checkbox Field":["Selectievakjeveld"],"Dropdown Field":["Keuzelijstveld"],"Multiple Choice Field":["Meerkeuzeveld"],"Address Field":["Adresveld"],"Number Field":["Nummer veld"],"reCAPTCHA v2":["reCAPTCHA v2"],"To enable reCAPTCHA feature on your SureForms Please enable reCAPTCHA option on your blocks setting and select version. Add google reCAPTCHA secret and site key here. reCAPTCHA will be added to your page on front-end.":["Om de reCAPTCHA-functie op uw SureForms in te schakelen, schakelt u de reCAPTCHA-optie in uw blokinstellingen in en selecteert u de versie. Voeg hier de Google reCAPTCHA-secret en site key toe. reCAPTCHA wordt aan uw pagina toegevoegd aan de voorkant."],"Enter your %s here":["Voer hier uw %s in"],"To enable hCAPTCHA, please add your site key and secret key. Configure these settings within the individual form.":["Om hCAPTCHA in te schakelen, voeg uw site-sleutel en geheime sleutel toe. Configureer deze instellingen binnen het individuele formulier."],"To enable Cloudflare Turnstile, please add your site key and secret key. Configure these settings within the individual form.":["Om Cloudflare Turnstile in te schakelen, voeg uw site-sleutel en geheime sleutel toe. Configureer deze instellingen binnen het individuele formulier."],"Save":["Opslaan"],"Anonymous Analytics":["Anonieme Analytics"],"Learn More":["Meer informatie"],"Admin Notification":["Beheerdersmelding"],"Enable Admin Notification":["Beheerdermelding inschakelen"],"Admin notifications keep you informed about new form entries since your last visit.":["Beheerdersmeldingen houden je op de hoogte van nieuwe formulierinzendingen sinds je laatste bezoek."],"Continue":["Doorgaan"],"Get Started":["Beginnen"],"Integration":["Integratie"],"Connect Native Integrations with SureForms":["Verbind native integraties met SureForms"],"Unlock powerful integrations in the Premium plan to automate your workflows and connect SureForms directly with your favourite tools.":["Ontgrendel krachtige integraties in het Premium-plan om je workflows te automatiseren en SureForms direct te verbinden met je favoriete tools."],"Send form submissions straight to CRMs, email, and marketing platforms":["Stuur formulierinzendingen rechtstreeks naar CRM's, e-mail en marketingplatforms"],"Automate repetitive tasks with seamless data syncing":["Automatiseer repetitieve taken met naadloze gegevenssynchronisatie"],"Access exclusive native integrations for faster workflows":["Toegang tot exclusieve native integraties voor snellere workflows"],"Payments":["Betalingen"],"Stripe account disconnected successfully.":["Stripe-account succesvol losgekoppeld."],"Failed to create webhook.":["Het is niet gelukt om de webhook te maken."],"Failed to connect to Stripe.":["Verbinding met Stripe mislukt."],"Webhook":["Webhook"],"Knowledge Base":["Kennisbank"],"What\u2019s New":["Wat is er nieuw"],"delete":["verwijderen"],"Please type \"%s\" in the input box":["Typ alstublieft \"%s\" in het invoerveld"],"To confirm, type \"%s\" in the box below:":["Om te bevestigen, typ \"%s\" in het vak hieronder:"],"Type \"%s\"":["Typ \"%s\""],"Go to OttoKit Settings":["Ga naar OttoKit-instellingen"],"USD - US Dollar":["USD - Amerikaanse dollar"],"Payment Mode":["Betaalwijze"],"Test Mode":["Testmodus"],"Live Mode":["Live-modus"],"General Settings":["Algemene instellingen"],"Set up email summaries, admin alerts, and data preferences to manage your forms with ease.":["Stel e-mailsamenvattingen, beheerderswaarschuwingen en gegevensvoorkeuren in om uw formulieren eenvoudig te beheren."],"Customize default error messages shown when users submit invalid or incomplete form entries.":["Pas standaardfoutmeldingen aan die worden weergegeven wanneer gebruikers ongeldige of onvolledige formulierinvoer indienen."],"Enable spam protection for your forms using CAPTCHA services or honeypot security.":["Schakel spambeveiliging voor uw formulieren in met behulp van CAPTCHA-diensten of honeypot-beveiliging."],"Connect and manage your payment gateways to securely accept transactions through your forms.":["Verbind en beheer uw betalingsgateways om veilig transacties via uw formulieren te accepteren."],"1% transaction and payment gateway fees apply.":["1% transactiekosten en kosten voor de betalingsgateway zijn van toepassing."],"2.9% transaction and payment gateway fees apply. Activate license to reduce transaction fees.":["2,9% transactiekosten en kosten voor de betalingsgateway zijn van toepassing. Activeer de licentie om de transactiekosten te verlagen."],"2.9% transaction and payment gateway fees apply.":["Er zijn 2,9% transactiekosten en kosten voor de betalingsgateway van toepassing."],"Please visit %1$s, delete an unused webhook, then click below to retry.":["Bezoek %1$s, verwijder een ongebruikte webhook en klik vervolgens hieronder om het opnieuw te proberen."],"SureForms could not create a webhook because your Stripe account has run out of free slots. Webhooks are needed to receive updates about payments.":["SureForms kon geen webhook maken omdat je Stripe-account geen gratis slots meer heeft. Webhooks zijn nodig om updates over betalingen te ontvangen."],"Stripe Dashboard":["Stripe-dashboard"],"Creating\u2026":["Aan het cre\u00ebren\u2026"],"Create Webhook":["Webhook maken"],"Successfully connected to Stripe!":["Succesvol verbonden met Stripe!"],"Invalid response from server. Please try again.":["Ongeldig antwoord van de server. Probeer het alstublieft opnieuw."],"Failed to disconnect Stripe account.":["Het is niet gelukt om de Stripe-account los te koppelen."],"Webhook created successfully!":["Webhook succesvol aangemaakt!"],"Select Currency":["Selecteer valuta"],"Select the default currency for payment forms.":["Selecteer de standaardvaluta voor betalingsformulieren."],"Connection Status":["Verbindingsstatus"],"Disconnect Stripe Account":["Stripe-account loskoppelen"],"Are you sure you want to disconnect your Stripe account? This will stop all active payments, subscriptions, and form transactions connected to this account.":["Weet u zeker dat u uw Stripe-account wilt loskoppelen? Dit zal alle actieve betalingen, abonnementen en formuliertransacties die aan dit account zijn gekoppeld, stoppen."],"Disconnect":["Verbreken"],"Disconnecting\u2026":["Verbinding verbreken\u2026"],"Webhook successfully connected, all Stripe events are being tracked.":["Webhook succesvol verbonden, alle Stripe-evenementen worden gevolgd."],"Connect your Stripe account to start accepting payments through your forms.":["Verbind uw Stripe-account om betalingen via uw formulieren te accepteren."],"Connect to Stripe":["Verbinden met Stripe"],"Securely connect to Stripe with just a few clicks to begin accepting payments! ":["Maak veilig verbinding met Stripe met slechts een paar klikken om betalingen te accepteren!"],"Payment Methods":["Betaalmethoden"],"Test mode allows you to process payments without real charges. Switch to Live mode for actual transactions.":["Met de testmodus kunt u betalingen verwerken zonder echte kosten. Schakel over naar de Live-modus voor daadwerkelijke transacties."],"General Payment Settings":["Algemene betalingsinstellingen"],"These settings apply to all payment gateways.":["Deze instellingen zijn van toepassing op alle betalingsgateways."],"Stripe Settings":["Stripe-instellingen"],"Left ($100)":["Links ($100)"],"Right (100$)":["Rechts (100$)"],"Left Space ($ 100)":["Linker ruimte ($ 100)"],"Right Space (100 $)":["Rechterruimte (100 $)"],"Currency Sign Position":["Positie van het valutateken"],"Select the position of the currency symbol relative to the amount.":["Selecteer de positie van het valutasymbool ten opzichte van het bedrag."],"Learn":["Leren"],"Enable email summaries":["E-mailoverzichten inschakelen"],"Enable IP logging":["IP-logboek inschakelen"],"Turn on Admin Notification from here.":["Zet hier de beheerdersmelding aan."],"Send entries to 100+ popular apps.":["Verzend inzendingen naar meer dan 100 populaire apps."],"Build automated workflows that run instantly.":["Bouw geautomatiseerde workflows die direct worden uitgevoerd."],"Create custom app integrations using our Custom App feature.":["Maak aangepaste app-integraties met behulp van onze functie Aangepaste App."],"Keep your tools in sync automatically.":["Houd je gereedschap automatisch gesynchroniseerd."],"This will install and activate OttoKit on your WordPress site to enable automation features.":["Hiermee wordt OttoKit op je WordPress-site ge\u00efnstalleerd en geactiveerd om automatiseringsfuncties mogelijk te maken."],"Automate Your Forms with OttoKit":["Automatiseer uw formulieren met OttoKit"],"Every form submission should trigger something \u2014 a Slack alert, a CRM lead, a follow-up email, or a new row in Google Sheets.":["Elke formulierinzending zou iets moeten activeren \u2014 een Slack-melding, een CRM-lead, een opvolg-e-mail of een nieuwe rij in Google Sheets."],"MCP":["MCP"],"Configure AI client permissions and MCP server settings.":["Configureer AI-clientmachtigingen en MCP-serverinstellingen."],"View documentation":["Documentatie bekijken"],"Copy to clipboard":["Kopi\u00ebren naar klembord"],"Claude Desktop":["Claude Desktop"],"~\/Library\/Application Support\/Claude\/claude_desktop_config.json (macOS) or %APPDATA%\\Claude\\claude_desktop_config.json (Windows)":["~\/Library\/Application Support\/Claude\/claude_desktop_config.json (macOS) of %APPDATA%\\Claude\\claude_desktop_config.json (Windows)"],"Claude Code":["Claude Code"],".mcp.json (project) or ~\/.claude.json (global)":[".mcp.json (project) of ~\/.claude.json (globaal)"],"Cursor":["Cursor"],"~\/.cursor\/mcp.json":["~\/.cursor\/mcp.json"],"VS Code (Copilot)":["VS Code (Copilot)"],".vscode\/mcp.json (project) or settings.json > mcp.servers (global)":[".vscode\/mcp.json (project) of settings.json > mcp.servers (globaal)"],"~\/.continue\/config.yaml or config.json":["~\/.continue\/config.yaml of config.json"],"Your client's MCP configuration file":["Het MCP-configuratiebestand van uw klant"],"Connect Your AI Client":["Verbind uw AI-client"],"AI Client":["AI-client"],"Create an Application Password \u2014 ":["Maak een applicatiewachtwoord aan \u2014"],"Open Application Passwords":["Open toepassingswachtwoorden"],"Or use this CLI command to add the server quickly (you will still need to set the environment variables):":["Of gebruik deze CLI-opdracht om de server snel toe te voegen (je moet nog steeds de omgevingsvariabelen instellen):"],"Copy the JSON config below into: ":["Kopieer de JSON-configuratie hieronder naar:"],"Replace \"your-application-password\" with the password from Step 1.":["Vervang \"your-application-password\" door het wachtwoord uit Stap 1."],"WP_API_URL \u2014 your site's MCP endpoint. WP_API_USERNAME \u2014 your WordPress username. WP_API_PASSWORD \u2014 the application password you generated.":["WP_API_URL \u2014 het MCP-eindpunt van je site. WP_API_USERNAME \u2014 je WordPress-gebruikersnaam. WP_API_PASSWORD \u2014 het applicatiewachtwoord dat je hebt gegenereerd."],"View setup docs":["Bekijk de installatiehandleidingen"],"The MCP Adapter plugin is installed but not active. Activate it to configure MCP settings.":["De MCP Adapter-plugin is ge\u00efnstalleerd maar niet actief. Activeer het om MCP-instellingen te configureren."],"The MCP Adapter plugin is required to connect AI clients to your forms. Download and install it from GitHub, then activate it.":["De MCP Adapter-plugin is vereist om AI-clients met uw formulieren te verbinden. Download en installeer het vanaf GitHub en activeer het vervolgens."],"Download the latest release from":["Download de nieuwste release van"],"Install the plugin via Plugins > Add New Plugin > Upload Plugin.":["Installeer de plugin via Plugins > Nieuwe plugin toevoegen > Plugin uploaden."],"Activate the MCP Adapter plugin.":["Activeer de MCP Adapter-plugin."],"Activating\u2026":["Activeren\u2026"],"Activate MCP Adapter":["Activeer MCP-adapter"],"Download MCP Adapter":["Download MCP Adapter"],"Experimental":["Experimenteel"],"Enable Abilities":["Vermogen inschakelen"],"Register SureForms abilities with the WordPress Abilities API. When enabled, AI clients can list, read, create, edit, and delete your forms and entries. When disabled, no abilities are registered and AI clients cannot perform any actions on your forms.":["Registreer SureForms-mogelijkheden bij de WordPress Abilities API. Wanneer ingeschakeld, kunnen AI-clients uw formulieren en inzendingen opsommen, lezen, maken, bewerken en verwijderen. Wanneer uitgeschakeld, worden er geen mogelijkheden geregistreerd en kunnen AI-clients geen acties uitvoeren op uw formulieren."],"Abilities API \u2014 Edit":["Vaardigheden-API \u2014 Bewerken"],"Enable Edit Abilities":["Bewerkingsmogelijkheden inschakelen"],"When enabled, AI clients can create new forms, update form titles, fields, and settings, duplicate forms, and modify entry statuses. When disabled, these abilities are unregistered and AI clients can only read your data.":["Wanneer ingeschakeld, kunnen AI-clients nieuwe formulieren maken, formuliertitels, velden en instellingen bijwerken, formulieren dupliceren en de status van inzendingen wijzigen. Wanneer uitgeschakeld, worden deze mogelijkheden uitgeschakeld en kunnen AI-clients alleen uw gegevens lezen."],"Abilities API \u2014 Delete":["Vaardigheden API \u2014 Verwijderen"],"Enable Delete Abilities":["Verwijdermogelijkheden inschakelen"],"When enabled, AI clients can permanently delete forms and entries. Deleted data cannot be recovered. When disabled, delete abilities are unregistered and AI clients cannot remove any data.":["Wanneer ingeschakeld, kunnen AI-clients formulieren en invoer permanent verwijderen. Verwijderde gegevens kunnen niet worden hersteld. Wanneer uitgeschakeld, worden verwijdermogelijkheden uitgeschakeld en kunnen AI-clients geen gegevens verwijderen."],"MCP Server":["MCP-server"],"Enable MCP Server":["MCP-server inschakelen"],"Creates a dedicated SureForms MCP endpoint that AI clients like Claude can connect to. When disabled, the endpoint is removed and external AI clients cannot discover or call any SureForms abilities.":["Maakt een speciale SureForms MCP-eindpunt aan waarmee AI-clients zoals Claude verbinding kunnen maken. Wanneer deze is uitgeschakeld, wordt het eindpunt verwijderd en kunnen externe AI-clients geen SureForms-mogelijkheden ontdekken of oproepen."],"Learn more":["Meer informatie"],"MCP Adapter Required":["MCP-adapter vereist"],"Google Maps":["Google Maps"],"Configure Google Maps API key for address autocomplete and map preview.":["Configureer de Google Maps API-sleutel voor adres-autocompletie en kaartvoorbeeld."],"Help shape the future of SureForms":["Help de toekomst van SureForms vormgeven"],"Share how you use the plugin so we can build features that matter, fix issues faster, and make smarter decisions. ":["Deel hoe je de plugin gebruikt, zodat we functies kunnen ontwikkelen die ertoe doen, problemen sneller kunnen oplossen en slimmere beslissingen kunnen nemen."],"Enable Google Address Autocomplete":["Google-adres automatisch aanvullen inschakelen"],"Upgrade to the SureForms Business Plan to add Google-powered address autocomplete with interactive map preview to your forms.":["Upgrade naar het SureForms Business Plan om Google-aangedreven adres-autocompletie met interactieve kaartvoorvertoning aan uw formulieren toe te voegen."],"Auto-suggest addresses as users type for faster, error-free submissions":["Stel automatisch adressen voor terwijl gebruikers typen voor snellere, foutloze inzendingen"],"Show an interactive map preview with draggable pin for precise locations":["Toon een interactieve kaartvoorvertoning met een sleepbare pin voor precieze locaties"],"Automatically populate address fields like city, state, and postal code":["Automatisch adresvelden zoals stad, staat en postcode invullen"]}}} \ No newline at end of file diff --git a/languages/sureforms-nl_NL.mo b/languages/sureforms-nl_NL.mo index 5d4505886249d4a524a2458bf1e3e8cd784db609..7a8292f14df17a942fd6cd55150f7077c704d96b 100644 GIT binary patch delta 66535 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 delta 66430 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

'; - -// URLs -echo ''; - -// Rich text (allows safe HTML) -echo wp_kses_post( $content ); -``` - -### Database Queries - -```php -global $wpdb; - -// ✅ Good - Prepared statement -$results = $wpdb->get_results( - $wpdb->prepare( - "SELECT * FROM {$wpdb->prefix}sureforms_entries WHERE form_id = %d AND status = %s", - $form_id, - $status - ) -); - -// ❌ Bad - SQL injection risk -$results = $wpdb->query("DELETE FROM {$wpdb->prefix}sureforms_entries WHERE id = $_POST[id]"); -``` - ---- - -## Testing Your Changes - -### Before Committing - -```bash -# 1. Lint PHP -composer lint - -# 2. Run PHP tests -composer test - -# 3. Lint JavaScript -npm run lint-js - -# 4. Run JS tests -npm run test:unit - -# 5. Build assets -npm run build - -# 6. Test in browser -# - Create form -# - Submit form -# - Check entries -# - Verify no console errors -``` - -### E2E Testing - -```bash -# Start environment -npm run play:up - -# Run tests -npm run play:run - -# Interactive mode (with browser) -npm run play:run:interactive -``` - ---- - -## Database Queries - Common Patterns - -### Get Entries - -```php -use SRFM\Inc\Database\Tables\Entries; - -// Get all for form -$entries = Entries::get_all([ - 'where' => [ - ['key' => 'form_id', 'value' => 123, 'compare' => '='] - ], - 'orderby' => 'created_at', - 'order' => 'DESC', -]); - -// With pagination -$entries = Entries::get_all([ - 'where' => [['key' => 'form_id', 'value' => 123, 'compare' => '=']], - 'limit' => 20, - 'offset' => 40 // Page 3 (20 per page) -]); - -// Count entries -$count = Entries::get_count([ - 'where' => [['key' => 'status', 'value' => 'published', 'compare' => '=']] -]); -``` - -### Get Payments - -```php -use SRFM\Inc\Database\Tables\Payments; - -// Get completed payments -$payments = Payments::get_all([ - 'where' => [ - ['key' => 'status', 'value' => 'completed', 'compare' => '='] - ] -]); - -// Get payment by transaction ID -$payment = Payments::get_by_transaction_id('ch_xxxxx', 'stripe'); -``` - ---- - -## Hooks - When to Use - -### Modify Data Before Save - -```php -// Filter entry data before save -add_filter('sureforms_submit_form_data', function($data, $form_id) { - // Add custom field - $data['custom_timestamp'] = current_time('mysql'); - return $data; -}, 10, 2); -``` - -### Trigger External Action - -```php -// Action after entry save -add_action('sureforms_after_entry_save', function($entry_id, $form_id, $data) { - // Send to external CRM - send_to_crm($data); -}, 10, 3); -``` - -### Modify Email - -```php -// Filter email template -add_filter('sureforms_email_template', function($html, $entry_id) { - // Add custom header - return '
...
' . $html; -}, 10, 2); -``` - ---- - -## Debugging Tips - -### Enable Debug Mode - -```php -// wp-config.php -define('WP_DEBUG', true); -define('WP_DEBUG_LOG', true); -define('WP_DEBUG_DISPLAY', false); -``` - -### Check Debug Log - -```bash -tail -f wp-content/debug.log -``` - -### JavaScript Console - -```javascript -// Check for errors -// Open browser DevTools → Console - -// SureForms global -console.log(window.sureforms); -``` - -### Database Queries - -```php -// Install Query Monitor plugin -// Shows all queries, slow queries, errors -``` - ---- - -## Common Pitfalls to Avoid - -1. **Don't bypass sanitization:** "It's internal, it's safe" → Still sanitize -2. **Don't skip nonce checks:** Every AJAX/REST endpoint needs verification -3. **Don't use `$_POST` directly:** Always sanitize first -4. **Don't concatenate SQL:** Use `$wpdb->prepare()` -5. **Don't echo user data raw:** Use `esc_html()`, `esc_attr()`, etc. -6. **Don't modify database schema without migration:** Breaks existing sites -7. **Don't remove existing hooks:** Other plugins may depend on them -8. **Don't hardcode `wp_` prefix:** Use `$wpdb->prefix` - ---- - -## Getting Help - -**Documentation:** -- This folder: All internal docs -- WordPress Codex: https://codex.wordpress.org/ -- React Docs: https://react.dev/ - -**Code Search:** -- Use Glob/Grep tools to find patterns -- Example: `grep -r "sanitize_text_field" inc/` → See how sanitization is used - -**Ask Before:** -- Breaking changes -- Database schema changes -- Removing existing functionality - ---- - -**Next:** [Troubleshooting](troubleshooting.md) - Common problems and solutions diff --git a/internal-docs/apis.md b/internal-docs/apis.md deleted file mode 100644 index 0a7a16ec7..000000000 --- a/internal-docs/apis.md +++ /dev/null @@ -1,418 +0,0 @@ -# APIs - -Complete API reference for SureForms Free & Pro. - ---- - -## REST API Endpoints - -### Free (`/sureforms/v1/`) - -**Form Management:** -```http -POST /sureforms/v1/generate-form -GET /sureforms/v1/forms -GET /sureforms/v1/forms/{id} -DELETE /sureforms/v1/forms/{id} -``` - -**Form Submission:** -```http -POST /sureforms/v1/submit-form -``` -**Body:** `{ form_id, nonce, field_data... }` -**Response:** `{ success, message, entry_id }` - -**Entries:** -```http -GET /sureforms/v1/entries/list -GET /sureforms/v1/entries/{id} -DELETE /sureforms/v1/entries/{id} -POST /sureforms/v1/entries/export -``` - -**Payments:** -```http -GET /sureforms/v1/payments/list -GET /sureforms/v1/payments/{id} -``` - -**Stripe Webhooks:** -```http -POST /sureforms/webhook_test # Stripe webhooks -POST /sureforms/webhook_live -``` - -**Settings:** -```http -GET /sureforms/v1/settings -POST /sureforms/v1/settings/update -``` - -### Pro (`/sureforms-pro/v1/`) - -**OAuth:** -```http -POST /sureforms-pro/v1/oauth/authorize -POST /sureforms-pro/v1/oauth/callback -``` - -**PayPal Webhooks:** -```http -POST /sureforms-pro/paypal-test-webhook -POST /sureforms-pro/paypal-live-webhook -``` - -**User Registration:** -```http -POST /sureforms-pro/v1/login -POST /sureforms-pro/v1/lost-password -POST /sureforms-pro/v1/reset-password -``` - ---- - -## AJAX Handlers - -### Free (30 handlers) - -**Admin:** -```php -'srfm_admin_action' # Generic admin handler -'srfm_get_forms' # Fetch forms list -'srfm_delete_form' # Delete form -'srfm_duplicate_form' # Duplicate form -'srfm_export_entries' # Export CSV -``` - -**Payments (Public):** -```php -'wp_ajax_srfm_create_payment_intent' # Stripe payment -'wp_ajax_nopriv_srfm_create_payment_intent' -'wp_ajax_srfm_create_subscription_intent' # Stripe subscription -'wp_ajax_nopriv_srfm_create_subscription_intent' -``` - -**Admin Stripe:** -```php -'srfm_stripe_cancel_subscription' # Cancel subscription -'srfm_stripe_pause_subscription' # Pause subscription -``` - -**Admin Payments:** -```php -'srfm_create_payment_refund' # Create refund -``` - -**Form Validation (Public):** -```php -'wp_ajax_srfm_field_unique_validation' # Check unique fields -'wp_ajax_nopriv_srfm_field_unique_validation' -``` - -### Pro (22 handlers) - -**PayPal (Public):** -```php -'wp_ajax_srfm_pro_create_paypal_order' -'wp_ajax_nopriv_srfm_pro_create_paypal_order' -'wp_ajax_srfm_pro_create_paypal_subscription' -'wp_ajax_nopriv_srfm_pro_create_paypal_subscription' -``` - -**PayPal Admin:** -```php -'srfm_pro_paypal_cancel_subscription' -'srfm_pro_paypal_pause_subscription' -``` - -**PDF:** -```php -'srfm_pro_generate_pdf' # Generate PDF from entry -'srfm_pro_download_pdf' # Download PDF -``` - -**Licensing:** -```php -'srfm_pro_activate_license' -'srfm_pro_deactivate_license' -``` - -**Entries:** -```php -'sureforms_pro_entry_delete_file' # Delete uploaded file -``` - ---- - -## WordPress Hooks - -### Actions (Form Submission) - -```php -// Before entry save -do_action('sureforms_before_entry_save', $form_id, $entry_data); - -// After entry save -do_action('sureforms_after_entry_save', $entry_id, $form_id, $entry_data); - -// After payment completed -do_action('sureforms_payment_completed', $payment_id, $entry_id, $gateway); - -// After integration success -do_action('sureforms_integration_success', $integration_type, $response); - -// Before email send -do_action('sureforms_before_email_send', $to, $subject, $message); - -// After form submission (success) -do_action('sureforms_form_submitted', $entry_id, $form_id); -``` - -### Filters (Data Modification) - -```php -// Modify form data before save -$entry_data = apply_filters('sureforms_submit_form_data', $entry_data, $form_id); - -// Modify payment amount -$amount = apply_filters('sureforms_payment_amount', $amount, $form_id, $entry_data); - -// Modify email template -$html = apply_filters('sureforms_email_template', $html, $entry_id, $form_id); - -// Modify email subject -$subject = apply_filters('sureforms_email_subject', $subject, $form_id); - -// Modify email recipients -$to = apply_filters('sureforms_email_recipients', $to, $entry_id, $form_id); - -// Modify confirmation message -$message = apply_filters('sureforms_confirmation_message', $message, $entry_id); - -// Modify field validation -$is_valid = apply_filters('sureforms_validate_field', $is_valid, $field, $value); - -// Modify sanitized value -$value = apply_filters("sureforms_sanitize_{$field_type}", $value, $field); -``` - -### Integration Hooks (Pro) - -```php -// Before integration request -do_action('sureforms_pro_before_integration', $integration, $data); - -// After integration request -do_action('sureforms_pro_after_integration', $integration, $response); - -// Integration error -do_action('sureforms_pro_integration_error', $integration, $error); -``` - ---- - -## JavaScript APIs - -### Global Objects - -```javascript -// Form settings -window.sureforms = { - ajaxUrl: '/wp-admin/admin-ajax.php', - nonce: 'xxx', - formId: 123, - settings: {...} -}; - -// Block editor -window.sureformsBlocks = { - registerBlock: (name, settings) => {...}, - getBlock: (name) => {...} -}; -``` - -### Custom Events - -```javascript -// Form submitted -document.addEventListener('sureforms-form-submitted', (e) => { - console.log('Entry ID:', e.detail.entryId); -}); - -// Payment completed -document.addEventListener('sureforms-payment-completed', (e) => { - console.log('Payment ID:', e.detail.paymentId); -}); - -// Validation error -document.addEventListener('sureforms-validation-error', (e) => { - console.log('Field:', e.detail.field, 'Error:', e.detail.message); -}); -``` - ---- - -## Database APIs - -### Entry Operations - -```php -use SRFM\Inc\Database\Tables\Entries; - -// Get all entries for a form -$entries = Entries::get_all([ - 'where' => [ - ['key' => 'form_id', 'value' => 123, 'compare' => '='] - ], - 'orderby' => 'created_at', - 'order' => 'DESC', - 'limit' => 20, - 'offset' => 0 -]); - -// Get single entry -$entry = Entries::get_by_id(456); - -// Insert entry -$entry_id = Entries::insert([ - 'form_id' => 123, - 'entry_data' => json_encode($data), - 'status' => 'published' -]); - -// Update entry -Entries::update(456, ['status' => 'trash']); - -// Delete entry -Entries::delete(456); -``` - -### Payment Operations - -```php -use SRFM\Inc\Database\Tables\Payments; - -// Get payments -$payments = Payments::get_all_main_payments([ - 'where' => [ - ['key' => 'status', 'value' => 'completed', 'compare' => '='] - ] -]); - -// Create payment -$payment_id = Payments::insert([ - 'entry_id' => 456, - 'transaction_id' => 'ch_xxx', - 'gateway' => 'stripe', - 'status' => 'pending', - 'total_amount' => 99.99, - 'currency' => 'USD' -]); - -// Update payment status -Payments::update($payment_id, ['status' => 'completed']); -``` - ---- - -## Helper APIs - -### Sanitization - -```php -use SRFM\Inc\Helper; - -// Sanitize by field type -$clean = Helper::sanitize_by_field_type('email', $value); -$clean = Helper::sanitize_by_field_type('textarea', $value); -$clean = Helper::sanitize_by_field_type('number', $value); - -// Email-specific -$email = Helper::sanitize_email_header($raw_email); - -// Recursive sanitization -$clean_array = Helper::sanitize_array_recursively($array); -``` - -### Validation - -```php -use SRFM\Inc\Field_Validation; - -// Validate field -$result = Field_Validation::validate_field($field_config, $value); -// Returns: ['valid' => true/false, 'message' => 'Error message'] - -// Validate entire form -$result = Field_Validation::validate_form_data($form_id, $data); -``` - -### Payment Helpers - -```php -use SRFM\Inc\Payments\Payment_Helper; - -// Validate amount against form config -$result = Payment_Helper::validate_payment_amount($amount, $currency, $form_id, $block_id); - -// Get currency -$currency = Payment_Helper::get_currency(); -``` - ---- - -## Encryption API (Pro) - -```php -use SRFM_PRO\Inc\Pro\Native_Integrations\Encryption; - -$enc = new Encryption(); - -// Encrypt sensitive data -$encrypted = $enc->encrypt('oauth_token_12345'); - -// Decrypt -$decrypted = $enc->decrypt($encrypted); - -// Storage: wp_sureforms_integrations.data column -``` - -**Algorithm:** AES-256-CTR -**Key:** `SRFM_ENCRYPTION_KEY` constant or `LOGGED_IN_KEY` - ---- - -## Integration Workflow API (Pro) - -```php -use SRFM_PRO\Inc\Pro\Native_Integrations\Services\Workflow_Processor; - -// Execute integration workflow -$processor = new Workflow_Processor(); -$result = $processor->execute_workflow($integration_config, $entry_data); - -// Returns: ['success' => true/false, 'response' => API response] -``` - ---- - -## Rate Limiting - -**Note:** No built-in rate limiting. Implementations should add: - -```php -// Example pattern (not in core) -$key = 'form_submit_' . $user_ip; -$attempts = get_transient($key) ?: 0; - -if ($attempts >= 5) { - wp_send_json_error('Too many submissions', 429); -} - -set_transient($key, $attempts + 1, 15 * MINUTE_IN_SECONDS); -``` - ---- - -**Next:** [Coding Standards](coding-standards.md) - PHP/JS conventions diff --git a/internal-docs/architecture.md b/internal-docs/architecture.md deleted file mode 100644 index 9e59e0b81..000000000 --- a/internal-docs/architecture.md +++ /dev/null @@ -1,329 +0,0 @@ -# Architecture - -**Version:** 2.5.0 - ---- - -## System Overview - -SureForms is a WordPress form builder with a **Free + Pro** plugin architecture: - -``` -WordPress Site -├── SureForms Free (Required) -│ ├── Core form functionality -│ ├── Stripe payments -│ ├── AI form builder -│ └── Entry management -└── SureForms Pro (Optional Extension) - ├── Advanced features (conditional logic, multi-step) - ├── PayPal payments - ├── User registration/login - └── 24+ native integrations -``` - ---- - -## High-Level Architecture - -``` -┌─────────────────────────────────────────────────────────┐ -│ WordPress Admin │ -│ ┌──────────────────────────────────────────────────┐ │ -│ │ React Admin UI (src/) │ │ -│ │ - Form Builder (Gutenberg Blocks) │ │ -│ │ - Entry Dashboard │ │ -│ │ - Settings Panels │ │ -│ └──────────────────────────────────────────────────┘ │ -└─────────────────────────────────────────────────────────┘ - ↕ -┌─────────────────────────────────────────────────────────┐ -│ REST API Layer │ -│ - /sureforms/v1/* (Free) │ -│ - /sureforms-pro/v1/* (Pro) │ -│ - AJAX handlers (wp_ajax_*) │ -└─────────────────────────────────────────────────────────┘ - ↕ -┌─────────────────────────────────────────────────────────┐ -│ Business Logic (inc/) │ -│ ┌──────────┬──────────┬──────────┬──────────────────┐ │ -│ │ Forms │ Payments │ AI │ Integrations │ │ -│ │ Submit │ Stripe │ Builder │ (Pro: 24+) │ │ -│ │ Validate │ PayPal │ Field │ Mailchimp, etc │ │ -│ │ Store │ Webhooks │ Mapping │ │ │ -│ └──────────┴──────────┴──────────┴──────────────────┘ │ -└─────────────────────────────────────────────────────────┘ - ↕ -┌─────────────────────────────────────────────────────────┐ -│ Data Layer │ -│ ┌──────────────┬────────────────┬──────────────────┐ │ -│ │ WP Options │ Custom Tables │ Encrypted Data │ │ -│ │ Form configs │ Entries │ OAuth tokens │ │ -│ │ Settings │ Payments │ API keys │ │ -│ └──────────────┴────────────────┴──────────────────┘ │ -└─────────────────────────────────────────────────────────┘ - ↕ -┌─────────────────────────────────────────────────────────┐ -│ Frontend Rendering │ -│ - Gutenberg Blocks (PHP + JS) │ -│ - Form submission (AJAX) │ -│ - reCAPTCHA/Turnstile │ -│ - Real-time validation │ -└─────────────────────────────────────────────────────────┘ -``` - ---- - -## Component Breakdown - -### 1. Block System (Gutenberg) - -**Free Blocks (16):** -- Input types: Text, Email, Number, Phone, URL, Textarea, Dropdown -- Special: Address, Checkbox, Multiple Choice, GDPR, Payment -- Layout: Separator, Heading, Image, Icon, Custom Button - -**Pro Blocks (8):** -- Input: Date Picker, Time Picker, Rating, Slider, Hidden, Password -- Advanced: File Upload, HTML, Page Break (multi-step) -- User Registration: Login, Register, Lost Password, Reset Password - -**Location:** `inc/blocks/*/block.php` and `src/blocks/*/` - -### 2. Form Submission Pipeline - -``` -User Submits Form - ↓ -1. Nonce Verification (inc/form-submit.php:91-95) - ↓ -2. Field Validation (inc/field-validation.php) - - Type validation (email, URL, number) - - Required fields - - Min/max constraints - - Custom regex - ↓ -3. Sanitization (inc/helper.php:258-274) - - Per-field type sanitization - - XSS prevention (wp_kses_post) - - SQL injection prevention - ↓ -4. CAPTCHA Validation (inc/form-submit.php:317-386) - - reCAPTCHA v2/v3 - - Cloudflare Turnstile - - hCaptcha - ↓ -5. Business Logic (Pro: Conditional Logic) - ↓ -6. Payment Processing (if enabled) - - Stripe: Create PaymentIntent - - PayPal: Create Order - ↓ -7. Entry Storage (inc/database/tables/entries.php) - ↓ -8. Integrations (Pro: Send to external services) - ↓ -9. Email Notifications (inc/email/email-template.php) - ↓ -10. Confirmation/Redirect -``` - -### 3. Payment Processing - -**Stripe (Free):** -- Location: `inc/payments/stripe/` -- Flow: - 1. Frontend creates PaymentIntent (AJAX) - 2. User completes payment on Stripe - 3. Webhook updates payment status - 4. Entry marked as paid - -**PayPal (Pro):** -- Location: `inc/business/payments/pay-pal/` -- Flow: - 1. Frontend creates Order via API - 2. User redirected to PayPal - 3. Webhook confirms payment - 4. Entry status updated - -**Database:** `wp_sureforms_payments` table - -### 4. AI Form Builder - -**Location:** `inc/ai-form-builder/` - -**Flow:** -``` -User Prompt ("Create a contact form") - ↓ -AI Middleware (SRFM_AI_MIDDLEWARE) - ↓ -Field Mapping (field-mapping.php) - ↓ -Gutenberg Block Generation - ↓ -Form Preview -``` - -**API:** `https://credits.startertemplates.com/sureforms/` - -### 5. Native Integrations (Pro) - -**Location:** `inc/pro/native-integrations/` - -**Supported Services (24+):** -- Email: Mailchimp, Brevo, Constant Contact -- CRM: HubSpot, Salesforce, Zoho -- Messaging: Telegram, Slack, Discord -- Marketing: FluentCRM, MailerPress -- Booking: LatePoint -- Automation: Zapier, OttoKit - -**Architecture:** -``` -Generic Provider Base Class - ↓ -Integration-Specific Classes -(inc/pro/native-integrations/integrations/*/actions/) - ↓ -OAuth Handler (oauth-handler.php) - ↓ -Encrypted Storage (encryption.php - AES-256-CTR) - ↓ -Workflow Processor (services/workflow-processor.php) -``` - -### 6. Database Schema - -**Custom Tables:** - -```sql --- Entries -wp_sureforms_entries -- id (INT, PK) -- form_id (INT) -- entry_data (LONGTEXT, JSON) -- created_at (DATETIME) -- updated_at (DATETIME) -- status (VARCHAR - 'published', 'trash') -- user_agent (TEXT) -- ip_address (VARCHAR) - --- Payments -wp_sureforms_payments -- id (INT, PK) -- entry_id (INT, FK) -- transaction_id (VARCHAR) -- gateway (ENUM 'stripe', 'paypal') -- status (ENUM 'pending', 'completed', 'failed', 'refunded') -- total_amount (DECIMAL) -- refunded_amount (DECIMAL) -- currency (VARCHAR) - --- Integrations (Pro) -wp_sureforms_integrations -- id (INT, PK) -- type (VARCHAR - 'mailchimp', 'hubspot', etc.) -- data (LONGTEXT, encrypted JSON) -- status (ENUM 'active', 'inactive') - --- Save & Resume (Pro) -wp_sureforms_save_resume -- id (INT, PK) -- form_id (INT) -- token (VARCHAR, unique) -- form_data (LONGTEXT, JSON) -- expires_at (DATETIME) -``` - ---- - -## Security Architecture - -**Input Validation:** -- Nonce verification on all AJAX/REST requests -- Sanitization via `sanitize_*` functions -- Type casting (absint, floatval) - -**Output Escaping:** -- `esc_html()`, `esc_attr()`, `esc_url()` throughout -- `wp_kses_post()` for rich text - -**SQL Security:** -- `$wpdb->prepare()` for all queries -- No direct SQL concatenation - -**Payment Security:** -- Webhook signature verification (Stripe, PayPal) -- Server-side amount validation -- PCI-DSS compliant (payments handled by Stripe/PayPal) - -**Encryption (Pro):** -- AES-256-CTR for OAuth tokens -- Key derivation: `SRFM_ENCRYPTION_KEY` constant or `LOGGED_IN_KEY` -- Storage: `wp_sureforms_integrations.data` (encrypted JSON) - ---- - -## Performance Optimizations - -1. **Lazy Loading:** React components loaded on-demand -2. **Asset Minification:** Grunt uglifies JS/CSS -3. **Database Indexing:** Indexes on `form_id`, `entry_id`, `status` -4. **Caching:** Transients for integration API calls -5. **Query Optimization:** `SELECT` only needed columns - ---- - -## Extensibility - -**Hooks (Filters):** -- `sureforms_submit_form_data` - Modify data before save -- `sureforms_email_template` - Customize email HTML -- `sureforms_payment_amount` - Modify payment amount - -**Hooks (Actions):** -- `sureforms_after_entry_save` - Trigger after entry created -- `sureforms_payment_completed` - After successful payment -- `sureforms_integration_success` - After integration sends data - -**Developer APIs:** -- REST: `/sureforms/v1/*` -- PHP: `SRFM\Inc\Helper` class -- JavaScript: `window.sureforms.*` globals - ---- - -## Technology Stack - -| Layer | Technologies | -|-------|-------------| -| Frontend (Admin) | React 18, @wordpress/components, TanStack Query | -| Frontend (Public) | Vanilla JS, DOMPurify, intl-tel-input | -| Backend | PHP 7.4+, WordPress 6.4+ | -| Build | webpack 5, Babel, Sass, Grunt | -| Testing | PHPUnit, Jest, Playwright | -| Database | MySQL 5.7+, MariaDB 10.3+ | - ---- - -## Deployment Architecture - -``` -Developer Machine - ↓ -Git Commit → GitHub Actions CI - ↓ -Automated Tests (PHPUnit, Playwright) - ↓ -Build Assets (npm run build) - ↓ -Free: WordPress.org SVN -Pro: Licensing Server (ZIP) - ↓ -End User WordPress Sites (300,000+) -``` - ---- - -**Next:** [Codebase Map](codebase-map.md) for detailed folder structure diff --git a/internal-docs/codebase-map.md b/internal-docs/codebase-map.md deleted file mode 100644 index 9d85000c2..000000000 --- a/internal-docs/codebase-map.md +++ /dev/null @@ -1,303 +0,0 @@ -# Codebase Map - -**Version:** 2.5.0 - -Complete folder-by-folder guide to both plugins. - ---- - -## SureForms Free (`sureforms/`) - -### Root Files - -| File | Purpose | -|------|---------| -| `sureforms.php` | Main plugin file, defines constants, loads `plugin-loader.php` | -| `plugin-loader.php` | Bootstraps plugin, registers hooks, loads dependencies | -| `composer.json` | PHP dependencies (nps-survey, bsf-analytics, astra-notices) | -| `package.json` | JS dependencies, build scripts | -| `Gruntfile.js` | Grunt tasks (minify, compress, release) | - -### `admin/` - WordPress Admin UI - -| File | Purpose | -|------|---------| -| `admin.php` | Admin page registration, AJAX handlers for admin actions | -| `analytics.php` | Usage analytics, event tracking | -| `notice-manager.php` | Admin notices, dismissible alerts | - -### `inc/` - Core PHP Logic - -#### `inc/blocks/` - Gutenberg Block Definitions (PHP) - -Each block has a `block.php` with: -- Block registration (`register_block_type`) -- Server-side rendering callback -- Attribute schema -- Enqueue scripts/styles - -**Blocks (16):** -- `address/`, `checkbox/`, `dropdown/`, `email/`, `gdpr/`, `inlinebutton/` -- `input/`, `multichoice/`, `number/`, `payment/`, `phone/`, `sform/`, `textarea/`, `url/` -- `base.php` - Base block class - -#### `inc/fields/` - Field Markup Generation - -Mirrors `blocks/` - generates HTML markup for each field type. - -**Pattern:** -```php -*-markup.php files: -- render_field() method -- Outputs escaped HTML -- Handles field attributes, validation states -``` - -#### `inc/payments/` - Payment Processing - -**Core Files:** -| File | Purpose | -|------|---------| -| `front-end.php` | Public AJAX handlers (`srfm_create_payment_intent`, `srfm_create_subscription_intent`) | -| `payment-helper.php` | Utility functions, amount validation, currency formatting | - -**`payments/stripe/`:** -| File | Purpose | -|------|---------| -| `stripe-webhook.php` | Webhook handler (charge, refund, subscription events) | -| `stripe-helper.php` | Stripe API wrapper, PaymentIntent creation | -| `admin-stripe-handler.php` | Admin AJAX for subscription management | -| `payments-settings.php` | Stripe connection settings, API keys | - -**`payments/admin/`:** -| File | Purpose | -|------|---------| -| `admin-handler.php` | Admin AJAX for refunds, payment management | - -#### `inc/ai-form-builder/` - AI Form Generation - -| File | Purpose | -|------|---------| -| `ai-form-builder.php` | Main AI form builder class, API integration | -| `ai-auth.php` | Middleware authentication | -| `ai-helper.php` | Helper functions, prompt processing | -| `field-mapping.php` | Maps AI response to Gutenberg blocks | - -**API:** `SRFM_AI_MIDDLEWARE` - `https://credits.startertemplates.com/sureforms/` - -#### `inc/database/` - Custom Database Tables - -| File | Purpose | -|------|---------| -| `base.php` | Abstract base class for all table classes (CRUD operations) | -| `register.php` | Table registration, schema creation | -| `tables/entries.php` | `wp_sureforms_entries` table (1,300+ lines) | -| `tables/payments.php` | `wp_sureforms_payments` table (1,200+ lines) | - -**Key Methods:** -- `get_all()`, `get_by_id()`, `insert()`, `update()`, `delete()` -- `get_all_main_payments()` - Payment queries with filtering - -#### Other `inc/` Files - -| File | Purpose | Lines | -|------|---------|-------| -| `form-submit.php` | Form submission handler (AJAX + REST) | 1,280 | -| `helper.php` | Utility functions (sanitization, escaping, validation) | 1,500+ | -| `field-validation.php` | Server-side field validation | 800+ | -| `rest-api.php` | REST API registration (`/sureforms/v1/*`) | 800 | -| `entries.php` | Entry management (list, view, export) | 1,000+ | -| `email/email-template.php` | Email notification templates | 400 | -| `frontend-assets.php` | Enqueue public scripts/styles | 300 | - -### `src/` - React Admin UI - -**Structure:** -``` -src/ -├── admin/ # Main admin app -│ ├── components/ # Reusable React components -│ ├── pages/ # Page-level components -│ └── index.js # Entry point -├── blocks/ # Block editor components -│ ├── address/ # Block-specific React -│ ├── email/ -│ └── ... -└── common/ # Shared utilities - ├── api.js # API client (wp.apiFetch) - └── utils.js # Helper functions -``` - -**Build:** webpack via `@wordpress/scripts` - ---- - -## SureForms Pro (`sureforms-pro/`) - -### Root Files - -| File | Purpose | -|------|---------| -| `sureforms-pro.php` | Main plugin file, requires Free plugin | -| `plugin-loader.php` | Bootstraps Pro features | - -### `inc/business/` - Pro Business Features - -#### `inc/business/payments/pay-pal/` - PayPal Integration - -| File | Purpose | Lines | -|------|---------|-------| -| `webhook-listener.php` | PayPal webhook handler (orders, refunds, subscriptions) | 1,173 | -| `frontend.php` | Public AJAX for PayPal orders, subscriptions | 1,100 | -| `api-payments.php` | PayPal API wrapper (create order, capture, refund) | 178 | -| `helper.php` | PayPal utilities, amount formatting | 520 | -| `settings.php` | PayPal connection settings | AJAX | - -#### `inc/business/user-registration/` - Login & Registration - -| File | Purpose | Lines | -|------|---------|-------| -| `init.php` | REST API registration, login/password endpoints | 600+ | -| `processor.php` | Registration processing, `wp_insert_user()` | 1,000+ | -| `login/block.php` | Login block definition | | -| `register/block.php` | Registration block | | -| `lost-password/block.php` | Lost password block | | -| `reset-password/block.php` | Reset password block | | - -**⚠️ Security Note:** Registration processor creates WordPress users from form submissions. - -#### `inc/business/pdf/` - PDF Generation - -| File | Purpose | -|------|---------| -| `pdf.php` | PDF generation API, AJAX handlers | -| `document.php` | PDF document builder (uses TCPDF or similar) | -| `utils.php` | PDF utilities | - -#### `inc/business/custom-app/` - Custom Application Builder - -| File | Purpose | -|------|---------| -| `load.php` | Custom post type forms, standalone applications | -| `utils.php` | App utilities | - -#### `inc/business/custom-post-type/` - Custom Post Type Integration - -Allows forms to create/update custom post types. - -### `inc/pro/native-integrations/` - 24+ Service Integrations - -**Core:** -| File | Purpose | Lines | -|------|---------|-------| -| `native-integrations.php` | Main integration manager | | -| `encryption.php` | AES-256-CTR encryption for OAuth tokens | 200 | -| `oauth-handler.php` | OAuth authorization flow | 400+ | -| `generic-provider.php` | Base provider class | | -| `integration-provider.php` | Provider interface | | - -**`inc/pro/native-integrations/integrations/`:** - -Each integration has its own folder: -``` -mailchimp/ -├── config.json # API endpoints, auth method -└── actions/ - ├── add-contact.php # Action: Add subscriber - └── remove-contact.php - -hubspot/ -├── config.json -└── actions/ - └── create-contact.php - -...24+ integrations -``` - -**Supported:** -- Email: Mailchimp, Brevo, Constant Contact -- CRM: HubSpot, Salesforce, Zoho -- Messaging: Telegram, Slack, Discord -- WP: FluentCRM, MailerPress, MailPoet -- Booking: LatePoint -- Automation: Zapier, OttoKit - -**Encryption:** OAuth tokens encrypted via `encryption.php` before storage in `wp_sureforms_integrations`. - -### `inc/pro/database/tables/` - Pro Database Tables - -| File | Purpose | -|------|---------| -| `integrations.php` | `wp_sureforms_integrations` table | -| `save-resume.php` | `wp_sureforms_save_resume` table (draft forms) | - -### `inc/extensions/` - Pro Extensions - -| File | Purpose | -|------|---------| -| `conditional-logic.php` | Show/hide fields based on conditions | -| `conditional-emails.php` | Conditional email notifications | -| `conditional-confirmations.php` | Conditional redirects | -| `field-validation.php` | Extended validation (file uploads, MIME types) | -| `entries-management.php` | Enhanced entry features (edit, delete files) | -| `page-break.php` | Multi-step form logic | - -### `inc/blocks/` - Pro Blocks (8) - -- `date-picker/`, `time-picker/`, `rating/`, `slider/` -- `upload/`, `hidden/`, `html/`, `page-break/` - ---- - -## Key Patterns & Conventions - -### Naming Conventions - -**Functions:** -- Public: `srfm_function_name()` -- Internal: `_srfm_internal_function()` - -**Classes:** -- Namespaced: `SRFM\Inc\ClassName` -- Pro: `SRFM_PRO\Inc\ClassName` - -**Hooks:** -- Actions: `sureforms_action_name` -- Filters: `sureforms_filter_name` - -**Database:** -- Tables: `wp_sureforms_table_name` -- Options: `sureforms_option_name` - -### File Organization - -``` -feature/ -├── block.php # Block registration -├── feature-markup.php # HTML generation -├── api-handler.php # AJAX/REST handlers -└── helper.php # Utilities -``` - -### REST API Convention - -**Free:** `/sureforms/v1/endpoint` -**Pro:** `/sureforms-pro/v1/endpoint` - ---- - -## Where to Find Things - -**Need to:** -- **Add a new field type?** → `inc/blocks/` + `inc/fields/` + `src/blocks/` -- **Modify form submission?** → `inc/form-submit.php` -- **Change email template?** → `inc/email/email-template.php` -- **Add payment gateway?** → `inc/payments/` (copy Stripe/PayPal pattern) -- **Add integration?** → `inc/pro/native-integrations/integrations/new-service/` -- **Debug entries?** → `inc/database/tables/entries.php` -- **Fix validation?** → `inc/field-validation.php` -- **Customize admin UI?** → `src/admin/` - ---- - -**Next:** [APIs](apis.md) - REST endpoints, AJAX handlers, hooks diff --git a/internal-docs/coding-standards.md b/internal-docs/coding-standards.md deleted file mode 100644 index 0b746674c..000000000 --- a/internal-docs/coding-standards.md +++ /dev/null @@ -1,312 +0,0 @@ -# Coding Standards - -**Version:** 2.5.0 - ---- - -## PHP Standards - -**WordPress Coding Standards:** https://developer.wordpress.org/coding-standards/wordpress-coding-standards/php/ - -### Code Style - -- **PSR-12 inspired** but follows WordPress conventions -- **Tabs for indentation** (not spaces) -- **Yoda conditions:** `if ( 'value' === $variable )` -- **Braces:** Required for all control structures - -```php -// ✅ Good -if ( $condition ) { - do_something(); -} - -// ❌ Bad -if ($condition) do_something(); -``` - -### Naming Conventions - -**Functions:** -```php -srfm_public_function() // Public functions -_srfm_private_function() // Internal (leading underscore) -``` - -**Classes:** -```php -namespace SRFM\Inc; -class Form_Submit { } // Underscores in class names - -namespace SRFM_PRO\Inc\Business; -class PayPal_Helper { } -``` - -**Variables:** -```php -$snake_case_variable = 'value'; // Lowercase with underscores -``` - -**Constants:** -```php -define( 'SRFM_CONSTANT', 'value' ); -``` - -### Security - -**Always:** -- Sanitize input: `sanitize_text_field()`, `absint()`, `sanitize_email()` -- Validate: Check types, ranges, allowed values -- Escape output: `esc_html()`, `esc_attr()`, `esc_url()` -- Use nonces: `wp_verify_nonce()` for AJAX/forms -- Use `$wpdb->prepare()` for SQL queries -- Check capabilities: `current_user_can()` - -**Example:** -```php -// Input -$email = sanitize_email( wp_unslash( $_POST['email'] ?? '' ) ); - -// Database -$results = $wpdb->get_results( - $wpdb->prepare( - "SELECT * FROM {$wpdb->prefix}sureforms_entries WHERE form_id = %d", - $form_id - ) -); - -// Output -echo '
' . esc_html( $user_name ) . '
'; -``` - -### Documentation - -**PHPDoc blocks:** -```php -/** - * Short description. - * - * Longer description if needed. - * - * @since 2.5.0 - * - * @param int $form_id Form ID. - * @param array $data Entry data. - * @return int|false Entry ID on success, false on failure. - */ -function srfm_create_entry( $form_id, $data ) { - // Implementation -} -``` - ---- - -## JavaScript Standards - -**WordPress JavaScript Coding Standards:** https://developer.wordpress.org/coding-standards/wordpress-coding-standards/javascript/ - -### Code Style (ESLint) - -**Config:** `@wordpress/eslint-plugin` - -```javascript -// ✅ Good - ES6+, const/let, arrow functions -const handleSubmit = (event) => { - event.preventDefault(); - const formData = new FormData(event.target); - // ... -}; - -// ❌ Bad - var, function expressions -var handleSubmit = function(event) { - event.preventDefault(); -}; -``` - -### React Conventions - -**Functional components with hooks:** -```jsx -import { useState, useEffect } from '@wordpress/element'; - -function FormBuilder({ formId }) { - const [fields, setFields] = useState([]); - - useEffect(() => { - fetchFields(formId).then(setFields); - }, [formId]); - - return ( -
- {fields.map(field => )} -
- ); -} -``` - -**Naming:** -- Components: `PascalCase` -- Hooks: `useCamelCase` -- Functions: `camelCase` -- Constants: `UPPER_SNAKE_CASE` - ---- - -## CSS/SCSS Standards - -**BEM-inspired naming:** -```scss -.srfm-form { - &__field { - // Field styles - } - - &__field--error { - // Error state - } -} -``` - -**Prefix:** All classes start with `srfm-` to avoid conflicts. - ---- - -## Database Standards - -### Table Names - -```php -$wpdb->prefix . 'sureforms_entries' -$wpdb->prefix . 'sureforms_payments' -``` - -**Always use `$wpdb->prefix`**, never hardcode `wp_`. - -### Queries - -**Always use prepared statements:** -```php -// ✅ Good -$wpdb->get_results( - $wpdb->prepare( - "SELECT * FROM {$wpdb->prefix}sureforms_entries WHERE id = %d", - $entry_id - ) -); - -// ❌ Bad -$wpdb->query( "DELETE FROM wp_sureforms_entries WHERE id = $entry_id" ); -``` - ---- - -## Git Commit Messages - -**Format:** -``` -type(scope): brief description - -Longer explanation if needed. - -Co-Authored-By: Name -``` - -**Types:** -- `feat`: New feature -- `fix`: Bug fix -- `docs`: Documentation -- `style`: Formatting, no code change -- `refactor`: Code restructuring -- `test`: Adding tests -- `chore`: Build/tooling - -**Example:** -``` -feat(payments): add PayPal subscription support - -- Implement PayPal billing agreement API -- Add webhook handler for subscription events -- Update admin UI for PayPal subscriptions - -Co-Authored-By: Claude Sonnet 4.5 -``` - ---- - -## File Organization - -**One class per file:** -``` -inc/payments/stripe/stripe-helper.php → class Stripe_Helper -``` - -**Group related functionality:** -``` -inc/payments/ -├── payment-helper.php # Shared utilities -├── front-end.php # Public AJAX handlers -├── stripe/ -│ ├── stripe-helper.php -│ ├── stripe-webhook.php -│ └── admin-stripe-handler.php -└── admin/ - └── admin-handler.php -``` - ---- - -## Testing Standards - -**PHPUnit:** -```php -class Test_Form_Submit extends WP_UnitTestCase { - public function test_form_submission_saves_entry() { - $entry_id = srfm_submit_form( $data ); - $this->assertIsInt( $entry_id ); - } -} -``` - -**Playwright:** -```javascript -test('form submission works', async ({ page }) => { - await page.goto('/test-form/'); - await page.fill('[name="email"]', 'test@example.com'); - await page.click('button[type="submit"]'); - await expect(page.locator('.success-message')).toBeVisible(); -}); -``` - ---- - -## Code Review Checklist - -Before submitting PR: - -- [ ] Code follows WordPress/project standards -- [ ] All inputs sanitized -- [ ] All outputs escaped -- [ ] SQL queries use `prepare()` -- [ ] Nonces verified for AJAX/forms -- [ ] Capabilities checked for admin actions -- [ ] PHPDoc blocks added -- [ ] No PHP/JS errors in console -- [ ] Tested in latest WordPress version -- [ ] Tests pass: `composer test && npm run test:unit` -- [ ] Linting passes: `composer lint && npm run lint-js` - ---- - -**Automated Checks:** - -```bash -# PHP linting -composer lint # PHP_CodeSniffer - -# JS linting -npm run lint-js # ESLint - -# Auto-fix -composer format # phpcbf -npm run lint-js:fix # ESLint --fix -``` diff --git a/internal-docs/faq.md b/internal-docs/faq.md deleted file mode 100644 index 8e174c45f..000000000 --- a/internal-docs/faq.md +++ /dev/null @@ -1,1003 +0,0 @@ -# Frequently Asked Questions - -**Version:** 2.5.0 - ---- - -## General Questions - -### What is SureForms? - -SureForms is an AI-powered WordPress form builder that uses Gutenberg blocks. - -**Key features:** -- AI form generation (describe in plain language, get complete form) -- Built-in payments (Stripe in Free, PayPal in Pro) -- Mobile-first design -- Native WordPress (no proprietary builder) -- Custom database tables (not post meta) - -**Target users:** Website owners, designers, developers who need forms without complexity. - ---- - -### What's the difference between Free and Pro? - -**Free (sureforms):** -- Unlimited forms & submissions -- All 15+ field types -- Stripe payments (one-time & subscriptions) -- Email notifications -- Spam protection (reCAPTCHA, Honeypot) -- Form analytics -- CSV export - -**Pro (sureforms-pro):** -- **All Free features, plus:** -- PayPal payments -- 24+ native integrations (Mailchimp, HubSpot, Salesforce, etc.) -- Conditional logic -- Multi-step & conversational forms -- User registration & login -- PDF generation -- File upload fields -- Priority support (< 24hr response) - -**Pricing:** -- Free: $0 (WordPress.org) -- Pro: $99-$299/year (3 sites to unlimited) - ---- - -### Can I use SureForms on multiple sites? - -**Free:** Yes, unlimited sites. - -**Pro:** Depends on license: -- Essential ($99/year): 3 sites -- Plus ($199/year): 20 sites -- Agency ($299/year): Unlimited sites - -**License activation:** -- Enter license key in SureForms → Settings → License -- Deactivate from one site to move to another -- All sites must be owned by you (not for client sites unless Agency plan) - ---- - -### Is SureForms GDPR compliant? - -**Yes.** SureForms provides tools for GDPR compliance: - -**Features:** -- GDPR checkbox field (explicit consent) -- Data export (users can request their data) -- Data deletion (users can request deletion) -- No third-party data sharing (unless you enable integrations) -- Privacy policy link support - -**What you must do:** -1. Add GDPR checkbox to forms collecting personal data -2. Link to your privacy policy -3. Honor data export/deletion requests -4. Configure data retention policies - -**Data storage:** -- Submissions stored in your WordPress database -- No data sent to SureForms servers (AI calls go through middleware but don't store data) -- Payment data stored encrypted (PCI-compliant) - ---- - -### Does SureForms work with my theme? - -**Yes.** SureForms is designed to work with any properly-coded WordPress theme. - -**Tested with:** -- Astra -- GeneratePress -- Kadence -- Neve -- Blocksy -- Twenty Twenty-Three/Four -- Page builder themes (Elementor, Divi, Beaver Builder) - -**If you experience styling conflicts:** -1. Check [troubleshooting guide](troubleshooting.md#form-breaks-after-theme-update) -2. Use SureForms → Settings → Custom CSS to override -3. Contact support with theme name - ---- - -### Can I use SureForms with page builders? - -**Yes.** SureForms works with: -- **Gutenberg** (native, best experience) -- **Elementor** (via shortcode or WordPress widget) -- **Divi** (via shortcode or code module) -- **Beaver Builder** (via WordPress widget) -- **Bricks** (via shortcode or WordPress element) - -**How to add:** - -**Elementor:** -1. Add "Shortcode" widget -2. Paste: `[sureforms id="123"]` -3. Replace 123 with your form ID - -**Divi:** -1. Add "Code" module -2. Paste shortcode -3. Save - -**Beaver Builder:** -1. Add "WordPress Widget" module -2. Select "SureForms" widget -3. Choose form - ---- - -## Technical Questions - -### What are the system requirements? - -**Minimum:** -- WordPress 6.4+ -- PHP 7.4+ -- MySQL 5.6+ or MariaDB 10.1+ -- HTTPS (for payments) - -**Recommended:** -- WordPress 6.6+ -- PHP 8.1+ -- MySQL 8.0+ or MariaDB 10.6+ -- 256MB PHP memory limit -- Object caching (Redis or Memcached) - -**Browser support:** -- Chrome 90+ -- Firefox 88+ -- Safari 14+ -- Edge 90+ - ---- - -### Does SureForms slow down my site? - -**No.** SureForms is optimized for performance: - -**Impact on page load:** -- Additional CSS: ~15KB (minified) -- Additional JS: ~25KB (minified, deferred) -- Total: ~40KB additional assets - -**Database queries:** -- Form render: 2-3 queries (cached) -- Form submission: 4-5 queries (optimized with indexes) -- No N+1 query issues - -**Performance features:** -- Lazy loading for non-critical assets -- Custom database tables (not post meta) -- Query optimization (indexed columns) -- Minified & concatenated assets -- CDN-friendly (versioned static files) - -**Benchmarks:** -- Lighthouse score: 95+ (with proper hosting) -- Time to Interactive: < 2 seconds on 3G -- Form submission latency: < 500ms - ---- - -### Can I export my data? - -**Yes.** Multiple export options: - -**Entries export:** -1. Go to SureForms → Entries -2. Select entries (or "Select All") -3. Click "Export to CSV" -4. Download file - -**Format:** CSV with all fields as columns - -**Form export:** -- Export form as JSON (Settings → Export) -- Import on another site (Settings → Import) - -**Database export:** -```bash -# Export all SureForms data -wp db export sureforms-backup.sql --tables=wp_sureforms_entries,wp_sureforms_payments,wp_sureforms_integrations -``` - ---- - -### How do I migrate forms to another site? - -**Method 1: Export/Import (Recommended)** - -**On old site:** -1. Go to SureForms → Forms -2. Hover over form → "Export" -3. Download JSON file - -**On new site:** -1. Install SureForms (same version) -2. Go to SureForms → Import -3. Upload JSON file -4. Map any dependencies (integrations, etc.) - -**Method 2: Database migration** - -```bash -# On old site -wp db export sureforms-data.sql --tables=wp_sureforms_entries,wp_sureforms_payments - -# Transfer file to new site - -# On new site -wp db import sureforms-data.sql - -# Update URLs in entries (if domain changed) -wp search-replace 'https://oldsite.com' 'https://newsite.com' wp_sureforms_entries -``` - ---- - -### Can I use SureForms offline / localhost? - -**Yes, with limitations:** - -**Works offline:** -- Form creation -- Form editing -- Local submissions (saved to database) - -**Requires internet:** -- AI form generation (external API) -- Payment processing (Stripe/PayPal API) -- Native integrations (Mailchimp, HubSpot, etc.) -- Google Fonts (if used) -- reCAPTCHA (if enabled) - -**Development setup:** -```bash -# Use Local by Flywheel or similar -# Or manual setup: -cd ~/Sites/my-wordpress-site -wp core download -wp core config --dbname=sureforms_dev --dbuser=root -wp core install --url=http://localhost:8080 --title="Dev Site" -wp plugin install sureforms --activate -``` - ---- - -## Payment Questions - -### Which payment gateways are supported? - -**Free plugin:** -- Stripe (one-time payments & subscriptions) - -**Pro plugin:** -- Stripe (one-time payments & subscriptions) -- PayPal (one-time payments & subscriptions) - -**Coming soon:** -- Razorpay (India) -- Mollie (Europe) - -**Not planned:** -- WooCommerce (use WooCommerce for full e-commerce) -- Square (low demand) -- Bitcoin/crypto (regulatory complexity) - ---- - -### How do I test payments before going live? - -**Stripe test mode:** - -1. Get test API keys: - - Go to https://dashboard.stripe.com/test/apikeys - - Copy "Publishable key" (pk_test_...) - - Copy "Secret key" (sk_test_...) - -2. In SureForms: - - Go to Settings → Payments → Stripe - - Enable "Test Mode" - - Paste test keys - - Save - -3. Test with card: - - Card number: `4242 4242 4242 4242` - - Expiry: Any future date (e.g., 12/28) - - CVC: Any 3 digits (e.g., 123) - -4. Verify in Stripe dashboard: - - Go to Payments → Test Mode - - See your test payment - -**PayPal sandbox (Pro):** - -1. Create sandbox account: - - Go to https://developer.paypal.com/ - - Sign in with PayPal account - - Create sandbox business & buyer accounts - -2. Get sandbox credentials: - - Apps & Credentials → Sandbox - - Copy Client ID & Secret - -3. In SureForms: - - Settings → Payments → PayPal - - Enable "Sandbox Mode" - - Paste credentials - - Save - -4. Test with sandbox buyer account - ---- - -### How are payment fees handled? - -**SureForms fees:** $0 (we charge nothing) - -**Gateway fees:** - -**Stripe:** -- Standard: 2.9% + $0.30 per transaction -- International cards: +1.5% -- Currency conversion: +1% -- (Varies by country, see Stripe pricing) - -**PayPal:** -- Standard: 2.9% + $0.30 per transaction -- International: +1.5% -- (Varies by country, see PayPal pricing) - -**Who pays fees:** -- Fees deducted from amount received -- Example: $100 charge → You receive ~$97 - -**Passing fees to customer:** -- Not built-in (would require payment gateway approval) -- Workaround: Add fee as separate amount field - ---- - -### Can I accept subscriptions? - -**Yes** (both Stripe and PayPal). - -**Setup:** - -1. Create form with Payment block -2. Payment block settings: - - Payment Type: ● Subscription - - Interval: Monthly/Yearly/Weekly - - Amount: [price] - -3. Customer pays once, charged automatically recurring - -**Management:** - -**Stripe:** -- View subscriptions: Stripe Dashboard → Subscriptions -- Cancel: Click subscription → "Cancel subscription" -- Refund: Not automatic, manual refund in Stripe - -**PayPal (Pro):** -- View subscriptions: PayPal Dashboard → Subscriptions -- Cancel: Click subscription → "Cancel" - -**Customer cancellation:** -- Customers can cancel in Stripe/PayPal customer portal -- You can provide link in confirmation email - ---- - -## AI & Form Generation Questions - -### How does AI form generation work? - -**Technical flow:** - -``` -User enters prompt ("job application form") - ↓ -SureForms sends to AI middleware - ↓ -Middleware calls GPT-4 API - ↓ -GPT-4 returns structured JSON (field types, labels, validations) - ↓ -Middleware sends back to SureForms - ↓ -SureForms creates Gutenberg blocks from JSON - ↓ -Form appears in editor, ready to customize -``` - -**What data is sent:** -- Your prompt ("create a contact form") -- Form context (if modifying existing form) -- No user data, no submissions, no PII - -**What data is stored:** -- None. AI responses are not logged. -- Form configuration stored in WordPress database only - -**Privacy:** -- AI calls routed through SureForms middleware (not direct to OpenAI) -- No data retention -- No training on your data - ---- - -### Can I use AI without internet? - -**No.** AI requires external API call to GPT-4. - -**Offline alternatives:** -- Create forms manually (no AI) -- Use templates (no AI needed) -- Import pre-made forms - ---- - -### What languages does AI support? - -**Prompts:** Any language GPT-4 supports (100+ languages) - -**Field labels:** Generated in same language as prompt - -**Example:** -- Prompt (Spanish): "formulario de contacto" -- Result: Fields with Spanish labels ("Nombre", "Correo electrónico", etc.) - -**Limitations:** -- Some languages better than others (English, Spanish, French, German excellent) -- Less common languages may have lower quality - ---- - -## Integration Questions (Pro) - -### What integrations are available? - -**24+ native integrations:** - -**Email Marketing:** -- Mailchimp -- Brevo (Sendinblue) -- ActiveCampaign -- ConvertKit -- MailerLite - -**CRM:** -- HubSpot -- Salesforce -- Zoho CRM -- Pipedrive - -**Communication:** -- Slack -- Telegram -- Discord (coming soon) - -**Productivity:** -- Google Sheets -- Airtable (coming soon) -- Notion (coming soon) - -**WordPress Plugins:** -- FluentCRM (native) -- OttoKit (SureTriggers) - -**Webhooks:** -- Custom webhooks (POST to any URL) - -**Not included:** -- Zapier (use webhooks instead) -- Make/Integromat (use webhooks) - ---- - -### How do I connect Mailchimp? - -**Setup (OAuth):** - -1. Go to SureForms → Settings → Integrations -2. Click "Mailchimp" → "Connect" -3. Redirected to Mailchimp → "Allow access" -4. Redirected back, connection confirmed - -**Use in form:** - -1. Edit form -2. Settings → Actions → "Add Action" -3. Select "Mailchimp" -4. Choose audience (list) -5. Map fields: - - Email field → Mailchimp EMAIL - - Name field → Mailchimp FNAME -6. Save - -**On form submission:** -- Contact added to Mailchimp list automatically -- Tags applied (if configured) -- Double opt-in email sent (if enabled in Mailchimp) - ---- - -### Can I send form data to custom webhook? - -**Yes** (Pro feature). - -**Setup:** - -1. Form settings → Actions → "Add Action" -2. Select "Webhook" -3. Configure: - - URL: `https://yourapi.com/endpoint` - - Method: POST (or GET, PUT) - - Headers: (optional, e.g., `Authorization: Bearer token`) -4. Save - -**Payload format:** - -```json -{ - "form_id": 123, - "entry_id": 456, - "fields": { - "email": "user@example.com", - "name": "John Doe", - "message": "Hello!" - }, - "meta": { - "submitted_at": "2026-02-12 10:30:00", - "user_ip": "192.168.1.1", - "user_agent": "Mozilla/5.0..." - } -} -``` - -**Retry logic:** -- Failed webhooks retried 3 times -- Exponential backoff (1s, 5s, 25s) -- After 3 failures, logged as error - ---- - -## Security & Privacy Questions - -### Is SureForms secure? - -**Yes.** Security is a core priority. - -**Security measures:** - -**Input sanitization:** -- All user input sanitized before storage -- WordPress functions: `sanitize_text_field()`, `sanitize_email()`, etc. -- Custom sanitization for complex fields - -**Output escaping:** -- All output escaped before rendering -- `esc_html()`, `esc_attr()`, `esc_url()` used throughout -- Prevents XSS attacks - -**SQL injection prevention:** -- All database queries use `$wpdb->prepare()` -- No direct SQL concatenation -- Custom database class with built-in protection - -**CSRF protection:** -- Nonce verification on all AJAX/REST endpoints -- `wp_verify_nonce()` checked before state-changing operations - -**Authorization:** -- Capability checks: `current_user_can()` -- Admin actions require `manage_options` capability -- User-specific data access controlled - -**Payment security:** -- PCI DSS compliant (no card storage) -- Stripe/PayPal handle sensitive data -- API credentials encrypted at rest (AES-256) - -**File uploads (Pro):** -- MIME type validation (server-side) -- File size limits enforced -- Path traversal prevention -- Disallowed file types: `.php`, `.js`, `.exe`, etc. - ---- - -### Where is my data stored? - -**Form submissions:** -- Your WordPress database -- Table: `wp_sureforms_entries` -- No data sent to SureForms servers - -**Payment data:** -- Stripe: Stored in Stripe (not in WordPress) -- PayPal: Stored in PayPal (not in WordPress) -- WordPress stores: Transaction ID, amount, status only - -**Integration credentials (Pro):** -- WordPress database -- Table: `wp_sureforms_integrations` -- Encrypted with AES-256 -- Encryption key in `wp-config.php` (recommended) - -**AI prompts:** -- Sent to AI middleware → OpenAI GPT-4 -- Not stored or logged -- Not used for training - ---- - -### Can users delete their data? - -**Yes** (GDPR requirement). - -**Manual deletion:** - -1. User requests deletion via email -2. Admin finds submissions by email -3. Delete from SureForms → Entries - -**Automatic (Pro):** -- Data retention policy: Auto-delete entries after X days -- Settings → Privacy → Data Retention -- Configure per form or globally - -**What gets deleted:** -- Entry data (all fields) -- Entry metadata (IP, user agent) -- File uploads (if any) - -**What's preserved:** -- Form configuration (for re-use) -- Analytics (anonymized counts only) - ---- - -## Troubleshooting Questions - -### My forms aren't showing on the frontend. Why? - -**Common causes:** - -**1. Form not published:** -- Check form status in SureForms → Forms -- Must be "Published" not "Draft" - -**2. Form not embedded:** -- Add SureForms block to page -- Select your form from dropdown -- Or use shortcode: `[sureforms id="123"]` - -**3. Theme conflict:** -- Try default theme: `wp theme activate twentytwentythree` -- If works → Theme issue, contact theme developer - -**4. JavaScript disabled:** -- Check browser console for errors -- Disable other plugins to find conflict - -**Debug:** -```bash -# Enable debugging -wp config set WP_DEBUG true --raw -wp config set WP_DEBUG_LOG true --raw - -# Check debug log -tail -f wp-content/debug.log -``` - -See [troubleshooting guide](troubleshooting.md) for more. - ---- - -### Form submissions aren't saving. What's wrong? - -**Check:** - -**1. Database tables exist:** -```bash -wp db query "SHOW TABLES LIKE '%sureforms%';" -``` - -Should show `wp_sureforms_entries` table. - -**2. Database permissions:** -```bash -wp db query "SHOW GRANTS;" -``` - -User must have INSERT privilege. - -**3. Nonce verification:** -- If using caching, exclude AJAX endpoints -- WP Super Cache: Exclude `/wp-admin/admin-ajax.php` - -**4. Debug log:** -```bash -tail -f wp-content/debug.log -# Submit form, watch for errors -``` - -See [troubleshooting: submissions not saving](troubleshooting.md#form-submissions-not-saving) - ---- - -### Email notifications aren't sending. Help! - -**Diagnose:** - -```bash -# Test WordPress mail function -wp eval "wp_mail('your@email.com', 'Test', 'Testing');" -``` - -If no email received → Server mail() disabled. - -**Fix:** - -**Install SMTP plugin:** -```bash -wp plugin install wp-mail-smtp --activate -``` - -**Configure with:** -- Gmail -- SendGrid -- Mailgun -- Amazon SES - -**Check spam folder:** -- Default WordPress sender: `wordpress@yourdomain.com` -- Often flagged as spam -- SMTP fixes this - -See [troubleshooting: emails not sending](troubleshooting.md#email-notifications-not-sending) - ---- - -## Customization Questions - -### Can I customize form styling? - -**Yes.** Multiple options: - -**Option 1: Settings panel (no code):** -1. Edit form -2. Settings sidebar → Design -3. Customize: - - Colors (background, text, buttons) - - Typography (fonts, sizes) - - Spacing (padding, margins) - - Border radius - -**Option 2: Custom CSS:** -1. SureForms → Settings → Custom CSS -2. Add your styles: -```css -.srfm-form { - background: #f9f9f9; - padding: 30px; - border-radius: 8px; -} - -.srfm-form input { - border: 2px solid #333; -} -``` - -**Option 3: Theme stylesheet:** - -Add to `style.css`: -```css -.srfm-form { /* Your styles */ } -``` - -**Option 4: Page builder:** - -Use page builder's CSS editor (if using Elementor/Divi). - ---- - -### Can I add custom fields? - -**Yes** (requires development). - -**Process:** - -1. Create block folder: `inc/blocks/my-field/` -2. Register block: `block.php` -3. Create React component: `src/blocks/my-field/edit.js` -4. Add sanitization: `inc/helper.php` -5. Add validation: `inc/field-validation.php` - -**Example:** See [onboarding guide](onboarding.md#step-2-create-block-structure) - -**Pre-built custom fields (Pro):** -- Star rating -- Signature -- File upload -- Date/time picker - ---- - -### Can I change the submit button text? - -**Yes.** - -**Per form:** -1. Edit form -2. Click submit button block -3. Settings sidebar → Button Text -4. Change text -5. Update form - -**Globally:** - -Add to `functions.php`: -```php -add_filter('sureforms_submit_button_text', function($text) { - return __('Send Message', 'sureforms'); -}); -``` - ---- - -## Business & Licensing Questions - -### Can I use SureForms on client sites? - -**Free:** Yes, unlimited sites. - -**Pro:** -- **Agency license required** ($299/year, unlimited sites) -- Essential ($99/year, 3 sites) - only for your own sites -- Plus ($199/year, 20 sites) - only for your own sites - -**License terms:** -- You must own the sites (not client-owned sites with Essential/Plus) -- Agency license allows client sites -- Each site needs separate activation - ---- - -### Can I white-label SureForms? - -**Not officially.** - -**What you can do:** -- Remove branding from admin (CSS) -- Custom email footer (replace "Powered by SureForms") -- Custom confirmation messages - -**What you can't do:** -- Remove copyright notices from code -- Rebrand and resell as your own product -- Remove attribution from free plugin - -**Enterprise white-label:** -- Contact sales for custom licensing -- Available for high-volume agencies - ---- - -### What's your refund policy? - -**14-day money-back guarantee** (Pro licenses) - -**Refund eligibility:** -- Purchased within last 14 days -- Tried to use but encountered issues -- Support unable to resolve - -**Not eligible:** -- After 14 days -- Changed mind (not technical issue) -- Purchased wrong license (can upgrade instead) - -**Process:** -1. Contact support: support@sureforms.com -2. Describe issue (we'll try to help first) -3. If unresolved, refund processed within 3-5 business days - ---- - -### How long do I get updates? - -**Free:** Lifetime updates. - -**Pro:** -- Updates: For duration of license (1 year) -- Renewals: Discounted renewal price after year 1 -- If license expires: Plugin continues working, no new updates - -**Version compatibility:** -- Major updates: Included -- Security updates: Prioritized -- Feature updates: Based on roadmap - ---- - -## Developer Questions - -### Is the code open source? - -**Free plugin:** Yes. -- License: GPL v2 or later -- GitHub: https://github.com/brainstormforce/sureforms - -**Pro plugin:** No. -- Proprietary license -- Source code visible but not redistributable - ---- - -### Can I contribute to SureForms? - -**Yes!** We welcome contributions. - -**How to contribute:** - -1. Fork repo: https://github.com/brainstormforce/sureforms -2. Create branch: `git checkout -b feat/my-feature` -3. Make changes -4. Run tests: `composer test && npm run test:unit` -5. Submit PR - -**Contribution guidelines:** -- Follow [coding standards](coding-standards.md) -- Add tests for new features -- Update docs if needed -- Sign off commits: `Co-Authored-By: Your Name ` - ---- - -### Where can I find the API documentation? - -**API docs:** [apis.md](apis.md) - -**Key resources:** -- REST endpoints: [apis.md#rest-api](apis.md#rest-api) -- Hooks & filters: [apis.md#hooks--filters](apis.md#hooks--filters) -- JavaScript APIs: [apis.md#javascript-apis](apis.md#javascript-apis) -- Database APIs: [apis.md#database-apis](apis.md#database-apis) - -**Code examples:** [ai-agent-guide.md](ai-agent-guide.md) - ---- - -## Need More Help? - -**Documentation:** -- [README.md](README.md) - Quick start -- [Troubleshooting](troubleshooting.md) - Common problems -- [Onboarding](onboarding.md) - Developer guide -- [Glossary](glossary.md) - Technical terms - -**Support:** -- **Free users:** WordPress.org forum, GitHub issues -- **Pro users:** https://support.brainstormforce.com/ (< 24hr response) - -**Community:** -- Facebook: https://www.facebook.com/groups/surecart -- GitHub Discussions: https://github.com/brainstormforce/sureforms/discussions - ---- - -**Next:** [Glossary](glossary.md) diff --git a/internal-docs/glossary.md b/internal-docs/glossary.md deleted file mode 100644 index 440e34b70..000000000 --- a/internal-docs/glossary.md +++ /dev/null @@ -1,723 +0,0 @@ -# Glossary - -**Version:** 2.5.0 - ---- - -## A - -### AJAX (Asynchronous JavaScript and XML) -Technique for updating parts of a page without full reload. Used in SureForms for form submissions, payment processing, and file uploads. - -**Example:** -```javascript -// AJAX request to submit form -wp.ajax.post('srfm_submit_form', { data: formData }); -``` - -### API (Application Programming Interface) -Set of functions and methods for interacting with software. SureForms provides REST API, database API, and JavaScript API. - -**Types in SureForms:** -- **REST API:** HTTP endpoints for external access -- **Database API:** Methods to query entries/payments -- **JavaScript API:** Frontend form manipulation - -### Attribute (Gutenberg) -Data stored with a block. In SureForms, attributes define field configuration (label, required, placeholder, etc.). - -**Example:** -```json -{ - "label": "Email", - "required": true, - "placeholder": "name@example.com" -} -``` - ---- - -## B - -### Block (Gutenberg) -Reusable component in WordPress editor. SureForms forms are composed of blocks (Email block, Textarea block, Submit button block, etc.). - -**Types:** -- **Static blocks:** Rendered client-side (React) -- **Dynamic blocks:** Rendered server-side (PHP) - -### Block Editor -WordPress's editing interface (formerly called "Gutenberg"). Native to WordPress 5.0+. - -**Why SureForms uses it:** -- Users already familiar -- No proprietary builder to learn -- Future-proof (WordPress core) - ---- - -## C - -### Capability -WordPress permission level. SureForms checks capabilities before allowing admin actions. - -**Common capabilities:** -- `manage_options` - Admin settings access -- `edit_posts` - Create forms (default) -- `read` - View forms (logged-in users) - -**Example:** -```php -if (current_user_can('manage_options')) { - // Allow admin action -} -``` - -### Conditional Logic (Pro) -Show or hide form fields based on user answers. Example: Show "Dietary restrictions" only if user selects "Yes" to "Will you attend?" - -**Types:** -- **Show when:** Display field if condition matches -- **Hide when:** Hide field if condition matches -- **AND/OR logic:** Multiple conditions combined - -### Conversational Form (Pro) -Form that displays one question at a time, like a chat conversation. Increases engagement and completion rates. - -**Benefits:** -- Less overwhelming than long forms -- Higher completion rate (3x vs single-page) -- Better mobile experience - -### CSRF (Cross-Site Request Forgery) -Attack where malicious site tricks user into submitting request to your site. SureForms prevents with nonce verification. - -**Example attack (prevented):** -```html - -
- - -
- -``` - -### CSV (Comma-Separated Values) -File format for spreadsheet data. SureForms can export form entries as CSV. - -**Example:** -``` -Name,Email,Message -John Doe,john@example.com,Hello! -Jane Smith,jane@example.com,Question about... -``` - ---- - -## D - -### Database Table -MySQL table storing structured data. SureForms uses 4 custom tables: -- `wp_sureforms_entries` - Form submissions -- `wp_sureforms_payments` - Payment records -- `wp_sureforms_integrations` - OAuth credentials -- `wp_sureforms_save_resume` - Draft submissions (Pro) - -**Why custom tables?** -- Faster queries (indexed columns) -- More efficient than post meta -- Easier to export - -### Dynamic Block -Gutenberg block rendered server-side (PHP). Most SureForms field blocks are dynamic for security (server-side validation). - -**Example:** -```php -register_block_type('sureforms/email', [ - 'render_callback' => 'render_email_field' -]); -``` - ---- - -## E - -### Encryption -Converting data to unreadable format. SureForms encrypts OAuth credentials and API keys. - -**Algorithm:** AES-256-CTR - -**Example:** -```php -$encrypted = Encryption::encrypt($api_key); -// Stored in database: "base64encodedIV.encryptedData" -``` - -### Entry -Single form submission. Stored in `wp_sureforms_entries` table. - -**Contains:** -- Form ID -- User ID (if logged in) -- Field values (JSON) -- Metadata (IP, user agent, timestamp) -- Status (published, spam, trash) - -### Escaping (Output Escaping) -Converting special characters to prevent XSS. SureForms escapes all user data before display. - -**Functions:** -- `esc_html()` - For HTML content -- `esc_attr()` - For HTML attributes -- `esc_url()` - For URLs -- `esc_js()` - For JavaScript strings - -**Example:** -```php -echo '
' . esc_html($user_input) . '
'; -``` - ---- - -## F - -### Field Type -Type of input field (email, text, number, etc.). SureForms has 15+ field types. - -**Common types:** -- Text, Email, URL, Textarea -- Number, Phone -- Multiple Choice, Checkbox, Dropdown -- Address, Upload (Pro) - -### Filter (WordPress Hook) -Function that modifies data. SureForms provides 30+ filters for customization. - -**Example:** -```php -add_filter('sureforms_email_subject', function($subject, $form_id) { - return "[Form $form_id] $subject"; -}, 10, 2); -``` - ---- - -## G - -### GDPR (General Data Protection Regulation) -European privacy law. SureForms provides GDPR-compliance features (consent checkbox, data export/deletion). - -**Requirements:** -- Explicit consent for data collection -- Right to access data (export) -- Right to deletion -- Privacy policy link - -### Gutenberg -WordPress's block editor (officially called "Block Editor"). Named after Johannes Gutenberg, inventor of printing press. - -**Why "Gutenberg"?** -- Revolutionized content creation (like printing press) -- Blocks are reusable components - ---- - -## H - -### Honeypot -Anti-spam technique using hidden field. Bots fill all fields (including hidden), revealing themselves. - -**How it works:** -```html - - -``` - -**SureForms logic:** -```php -if (!empty($_POST['srfm-honeypot'])) { - // Spam detected -} -``` - -### Hook (WordPress) -Point where developers can inject custom code. Two types: actions and filters. - -**SureForms hooks:** -- 50+ action hooks (e.g., `sureforms_after_entry_save`) -- 30+ filter hooks (e.g., `sureforms_email_template`) - ---- - -## I - -### Integration (Native Integration) -Connection to third-party service. SureForms Pro has 24+ native integrations (Mailchimp, HubSpot, etc.). - -**Types:** -- **OAuth:** User authorizes connection (Mailchimp, Google) -- **API Key:** User provides key from service -- **Webhook:** SureForms sends POST request to URL - -### Instant Form -SureForms feature allowing forms to be published with unique URL (no embedding needed). - -**Example URL:** -``` -https://yoursite.com/?srfm_form=abc123 -``` - -**Use cases:** -- Email signatures -- Social media links -- QR codes - ---- - -## J - -### JSON (JavaScript Object Notation) -Data format for structured information. SureForms stores entry data and block attributes as JSON. - -**Example entry data:** -```json -{ - "email": "john@example.com", - "name": "John Doe", - "message": "Hello!" -} -``` - ---- - -## L - -### Localization (l10n) -Adapting software for specific language/region. SureForms supports translation. - -**Files:** -- `languages/sureforms-{locale}.po` - Translation strings -- `languages/sureforms-{locale}.mo` - Compiled translations - -**Functions:** -```php -__('Email', 'sureforms'); // Translate string -_e('Submit', 'sureforms'); // Translate and echo -``` - ---- - -## M - -### Middleware -Intermediate server between client and API. SureForms uses middleware for AI form generation (client → middleware → OpenAI). - -**Why middleware?** -- Hides API keys from client -- Rate limiting -- Request logging -- Caching - -### Multi-Step Form (Pro) -Form split into multiple pages/steps. Improves completion rate by reducing cognitive load. - -**Example:** -``` -Step 1: Personal Information (name, email) -Step 2: Address Details -Step 3: Payment Information -``` - ---- - -## N - -### Namespace -PHP feature to organize code and prevent name conflicts. SureForms uses namespaces. - -**Example:** -```php -namespace SRFM\Inc\Database\Tables; - -class Entries { - // ... -} -``` - -### Native Integration -Integration built into SureForms (not requiring Zapier or external connector). - -**Examples:** -- Mailchimp (OAuth) -- HubSpot (OAuth) -- Slack (Webhook URL) - -### Nonce (Number Used Once) -Security token to verify request came from your site. SureForms verifies nonces on all AJAX/REST requests. - -**Example:** -```php -// Generate nonce -$nonce = wp_create_nonce('srfm_submit_form'); - -// Verify nonce -if (!wp_verify_nonce($_POST['nonce'], 'srfm_submit_form')) { - die('Invalid nonce'); -} -``` - ---- - -## O - -### OAuth (Open Authorization) -Protocol for secure authorization. Used by SureForms integrations (Mailchimp, HubSpot, etc.). - -**Flow:** -1. User clicks "Connect to Mailchimp" -2. Redirected to Mailchimp login -3. User approves access -4. Mailchimp redirects back with token -5. SureForms stores encrypted token - ---- - -## P - -### Payment Gateway -Service that processes credit card payments. SureForms supports Stripe and PayPal. - -**Comparison:** -- **Stripe:** 2.9% + $0.30, better for US/Europe -- **PayPal:** 2.9% + $0.30, more global recognition - -### Payment Intent (Stripe) -Stripe object representing payment attempt. Created before customer enters card details. - -**States:** -- `requires_payment_method` - Awaiting card -- `requires_confirmation` - Card entered, needs confirm -- `succeeded` - Payment successful -- `canceled` - Payment canceled - -### PCI DSS (Payment Card Industry Data Security Standard) -Security standard for handling credit card data. SureForms is PCI-compliant (never stores card data). - -**Compliance:** -- Card data sent directly to Stripe/PayPal -- SureForms only stores transaction ID -- No PAN (Primary Account Number) stored - -### Placeholder -Example text shown in empty input field. Disappears when user types. - -**Example:** -```html - -``` - -**Accessibility note:** Never use placeholder as label (screen readers may miss it). - -### Post Meta -WordPress method for storing additional data with posts. SureForms **doesn't** use post meta (uses custom tables instead). - -**Why not post meta?** -- Slow queries (no indexes) -- Hard to search -- Not optimized for large datasets - -### Post Type (Custom Post Type) -WordPress content type. SureForms forms are stored as custom post type `sureforms_form`. - -**Advantages:** -- Uses WordPress admin UI -- Revision history -- Trash/restore functionality - ---- - -## R - -### reCAPTCHA -Google anti-spam service. SureForms supports reCAPTCHA v2 and v3. - -**Versions:** -- **v2:** "I'm not a robot" checkbox -- **v3:** Invisible, scores user behavior (0-1) - -**Setup:** -1. Get API keys from Google reCAPTCHA admin -2. Add to SureForms → Settings → Security -3. Enable on forms - -### REST API -HTTP API for accessing SureForms data. Used by frontend, mobile apps, integrations. - -**Base URL:** `/wp-json/sureforms/v1/` - -**Example endpoints:** -- `POST /submit-form` - Submit form -- `GET /forms/{id}` - Get form data -- `POST /generate-form` - AI form generation - -### RTL (Right-to-Left) -Text direction for languages like Arabic, Hebrew. SureForms supports RTL. - -**CSS:** -```css -.srfm-field { - margin-inline-start: 10px; /* Not margin-left */ -} -``` - ---- - -## S - -### Sanitization (Input Sanitization) -Cleaning user input to prevent attacks. SureForms sanitizes all input before storage. - -**Functions:** -- `sanitize_text_field()` - Remove HTML/PHP -- `sanitize_email()` - Validate email format -- `sanitize_url()` - Validate URL format -- `absint()` - Force integer - -**Example:** -```php -$email = sanitize_email($_POST['email']); -$id = absint($_POST['id']); -``` - -### Schema (Database Schema) -Structure of database table (columns, types, indexes). - -**Example (wp_sureforms_entries):** -```sql -CREATE TABLE wp_sureforms_entries ( - id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, - form_id BIGINT UNSIGNED NOT NULL, - user_id BIGINT UNSIGNED, - entry_data LONGTEXT NOT NULL, - status VARCHAR(20) DEFAULT 'published', - created_at DATETIME NOT NULL, - INDEX idx_form_id (form_id), - INDEX idx_created_at (created_at) -); -``` - -### Shortcode -WordPress feature for embedding content. SureForms forms can be embedded via shortcode. - -**Syntax:** -``` -[sureforms id="123"] -``` - -**Parameters:** -- `id` - Form ID (required) -- `title` - Show title (true/false) -- `description` - Show description (true/false) - -### SQL Injection -Attack injecting malicious SQL into queries. SureForms prevents with `$wpdb->prepare()`. - -**Vulnerable code (DON'T DO THIS):** -```php -$id = $_GET['id']; -$wpdb->query("DELETE FROM table WHERE id = $id"); -// Attack: ?id=1 OR 1=1 (deletes all records!) -``` - -**Safe code:** -```php -$id = absint($_GET['id']); -$wpdb->query($wpdb->prepare("DELETE FROM table WHERE id = %d", $id)); -``` - -### Subscription -Recurring payment. SureForms supports subscriptions via Stripe and PayPal. - -**Intervals:** -- Daily -- Weekly -- Monthly -- Yearly - ---- - -## T - -### Template (Form Template) -Pre-built form configuration. SureForms provides 100+ templates (contact, registration, survey, etc.). - -**Structure:** -```json -{ - "name": "Contact Form", - "fields": [ - { "type": "text", "label": "Name" }, - { "type": "email", "label": "Email" }, - { "type": "textarea", "label": "Message" } - ] -} -``` - -### Transient -WordPress temporary cache. SureForms uses transients for AI rate limiting and API responses. - -**Example:** -```php -// Store for 1 hour -set_transient('srfm_ai_rate_limit_' . $user_id, true, HOUR_IN_SECONDS); - -// Check -if (get_transient('srfm_ai_rate_limit_' . $user_id)) { - // Rate limited -} -``` - ---- - -## U - -### User Agent -String identifying browser/device. SureForms logs user agent for spam detection. - -**Example:** -``` -Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 -``` - ---- - -## V - -### Validation (Form Validation) -Checking if user input meets requirements. SureForms validates both client-side (JavaScript) and server-side (PHP). - -**Types:** -- **Required:** Field must not be empty -- **Format:** Email/URL must be valid -- **Range:** Number within min/max -- **Length:** String length constraints - -**Example:** -```php -if (empty($email) || !is_email($email)) { - $errors[] = 'Please enter a valid email'; -} -``` - ---- - -## W - -### Webhook -HTTP callback sent when event occurs. SureForms can send webhooks on form submission (Pro). - -**Flow:** -``` -User submits form - ↓ -SureForms processes submission - ↓ -Sends POST to webhook URL - ↓ -External service receives data -``` - -**Example payload:** -```json -{ - "event": "form_submit", - "form_id": 123, - "entry_id": 456, - "fields": { ... } -} -``` - -### WordPress Coding Standards (WPCS) -PHP coding style guide for WordPress. SureForms follows WPCS. - -**Key rules:** -- Tabs for indentation (not spaces) -- Yoda conditions: `if ( 'value' === $variable )` -- Braces required for all control structures -- Space after control keywords: `if (` not `if(` - -**Check compliance:** -```bash -composer lint -``` - ---- - -## X - -### XSS (Cross-Site Scripting) -Attack injecting malicious JavaScript into pages. SureForms prevents with output escaping. - -**Vulnerable code (DON'T DO THIS):** -```php -echo '
' . $_POST['name'] . '
'; -// Attack: -``` - -**Safe code:** -```php -echo '
' . esc_html($_POST['name']) . '
'; -// Output: <script>steal(document.cookie)</script> -``` - ---- - -## Z - -### Zapier -Third-party automation service. SureForms doesn't have native Zapier integration but supports webhooks (which Zapier can consume). - -**Alternative:** Use SureForms webhooks to trigger Zapier zaps. - ---- - -## Acronyms Quick Reference - -| Acronym | Full Term | Meaning | -|---------|-----------|---------| -| AJAX | Asynchronous JavaScript and XML | Update page without reload | -| API | Application Programming Interface | Methods to interact with software | -| CSRF | Cross-Site Request Forgery | Attack tricking users into unwanted actions | -| CSV | Comma-Separated Values | Spreadsheet file format | -| GDPR | General Data Protection Regulation | EU privacy law | -| JSON | JavaScript Object Notation | Data format | -| OAuth | Open Authorization | Secure authorization protocol | -| PCI DSS | Payment Card Industry Data Security Standard | Credit card security | -| REST | Representational State Transfer | Web API architecture | -| RTL | Right-to-Left | Text direction (Arabic, Hebrew) | -| SQL | Structured Query Language | Database query language | -| URL | Uniform Resource Locator | Web address | -| WCAG | Web Content Accessibility Guidelines | Accessibility standards | -| WPCS | WordPress Coding Standards | PHP coding style | -| XSS | Cross-Site Scripting | JavaScript injection attack | - ---- - -## Common Abbreviations - -| Abbr | Full Term | -|------|-----------| -| Pro | SureForms Pro (premium plugin) | -| CRM | Customer Relationship Management | -| UI | User Interface | -| UX | User Experience | -| CPT | Custom Post Type | -| DB | Database | -| WP | WordPress | -| PHP | PHP: Hypertext Preprocessor | -| JS | JavaScript | -| CSS | Cascading Style Sheets | - ---- - -**Next:** [Maintenance](maintenance.md) diff --git a/internal-docs/maintenance.md b/internal-docs/maintenance.md deleted file mode 100644 index 71c2f2604..000000000 --- a/internal-docs/maintenance.md +++ /dev/null @@ -1,842 +0,0 @@ -# Documentation Maintenance Guide - -**Version:** 2.5.0 - ---- - -## Purpose - -This guide explains how to keep SureForms internal documentation accurate and useful. - -**Goal:** Documentation should always reflect current reality. - -**Principle:** Update docs when code changes, not as afterthought. - ---- - -## When to Update Documentation - -### Always Update - -**1. New Feature Added** -- Update: `architecture.md`, `apis.md`, `product-vision.md` -- Add: Code examples to `ai-agent-guide.md` -- Update: Onboarding guide if workflow changes - -**2. API Changes** -- Update: `apis.md` (new endpoints, hooks, parameters) -- Update: Code examples in all docs referencing changed API -- Mark deprecated APIs in `apis.md` - -**3. Database Schema Changes** -- Update: `architecture.md` (database section) -- Update: `codebase-map.md` (new files) -- Update: Migration guide if schema change requires migration - -**4. Security Fix** -- Update: `ai-agent-guide.md` (add to common pitfalls) -- Update: `troubleshooting.md` if fix addresses known issue -- Add example of vulnerable pattern to avoid - -**5. Breaking Changes** -- Update: `README.md` (migration guide) -- Update: `onboarding.md` (new workflows) -- Update: `faq.md` (address upgrade questions) - ---- - -### Update if Needed - -**6. Bug Fixes** -- Update: `troubleshooting.md` if common issue -- Add: To FAQ if frequently asked - -**7. Performance Improvements** -- Update: `architecture.md` if architecture changed -- Update: Benchmarks in `README.md` - -**8. UI/UX Changes** -- Update: `ui-and-copy.md` (new patterns, copy) -- Update: `onboarding.md` (user journeys) - ---- - -### Don't Update - -**9. Code Refactoring (No Behavior Change)** -- No doc update unless internal architecture significantly changed - -**10. Minor Copy Changes** -- No doc update unless it changes UX patterns - -**11. Version Bumps** -- Update version number at top of each doc -- That's it (unless other changes) - ---- - -## How to Update Documentation - -### Step 1: Identify Affected Docs - -**Use this decision tree:** - -``` -Did you change... - -┌─ Database schema? -│ └─> Update: architecture.md, codebase-map.md -│ -┌─ REST API? -│ └─> Update: apis.md, ai-agent-guide.md (examples) -│ -┌─ AJAX handlers? -│ └─> Update: apis.md -│ -┌─ Hooks/filters? -│ └─> Update: apis.md, ai-agent-guide.md (patterns) -│ -┌─ User-facing UI? -│ └─> Update: ui-and-copy.md, onboarding.md -│ -┌─ Security patterns? -│ └─> Update: ai-agent-guide.md, coding-standards.md -│ -┌─ Build process? -│ └─> Update: README.md, onboarding.md -│ -└─ New file/folder? - └─> Update: codebase-map.md -``` - ---- - -### Step 2: Read Existing Doc - -**Before editing:** -1. Read entire document -2. Identify outdated sections -3. Check for consistency with your changes - -**Don't:** -- Blindly add new section without reading context -- Create duplicate information -- Use different terminology than existing docs - ---- - -### Step 3: Make Minimal Changes - -**Best practices:** - -**Do:** -- Update only what changed -- Keep existing structure -- Match existing tone and style -- Add code examples if helpful - -**Don't:** -- Rewrite entire document (unless necessary) -- Change unrelated sections -- Reorganize without discussion -- Remove information (mark deprecated instead) - ---- - -### Step 4: Verify Examples Still Work - -**All code examples must be tested:** - -**PHP examples:** -```bash -# Create test file -cat > /tmp/test-example.php << 'EOF' - [ - ['key' => 'form_id', 'value' => 123, 'compare' => '='] - ], - 'limit' => 20 -]); -``` - -**❌ Bad:** -```php -// Vague, generic -$data = SomeClass::get_stuff($args); -``` - ---- - -### Cross-Referencing - -**Internal links:** -```markdown -See [Architecture Guide](architecture.md) for details. -See [Database Schema](architecture.md#database-schema) for table structure. -``` - -**External links:** -```markdown -Read [WordPress Coding Standards](https://developer.wordpress.org/coding-standards/). -``` - -**Code references:** -```markdown -See `inc/form-submit.php:88-119` for nonce verification. -``` - ---- - -### Code Block Guidelines - -**Always specify language:** - -````markdown -```php -// PHP code here -``` - -```javascript -// JavaScript here -``` - -```bash -# Shell commands here -``` - -```sql --- SQL queries here -``` -```` - -**Include comments:** -```php -// Good: Explain what code does -$entries = Entries::get_all([ - 'where' => [ - ['key' => 'status', 'value' => 'published', 'compare' => '='] - ] -]); -``` - -**Show output if helpful:** -```bash -wp plugin list --status=active -# Output: -# sureforms active -# sureforms-pro active -``` - ---- - -## Deprecation Process - -**When removing features:** - -### Step 1: Mark as Deprecated - -**In code:** -```php -/** - * Old function. - * - * @deprecated 2.5.0 Use new_function() instead. - */ -function old_function() { - _deprecated_function(__FUNCTION__, '2.5.0', 'new_function'); - return new_function(); -} -``` - -**In docs:** -```markdown -## ~~Old Feature~~ (Deprecated) - -**Deprecated in:** 2.5.0 -**Removed in:** 3.0.0 -**Replacement:** [New Feature](#new-feature) - -This feature is deprecated and will be removed in version 3.0.0. -Use [New Feature](#new-feature) instead. - -~~Old documentation here...~~ -``` - ---- - -### Step 2: Update Migration Guide - -**In README.md:** - -```markdown -## Upgrading from 2.4.x to 2.5.0 - -### Breaking Changes - -**Old Feature Deprecated:** -- **What changed:** `old_function()` is now deprecated -- **Action required:** Replace with `new_function()` -- **Code example:** - ```php - // Old (deprecated) - old_function($data); - - // New (recommended) - new_function($data); - ``` -``` - ---- - -### Step 3: Remove After Major Version - -**On next major version (3.0.0):** -1. Remove deprecated code -2. Remove ~~strikethrough~~ docs -3. Update changelog - ---- - -## Changelog Management - -**Keep CHANGELOG.md updated:** - -### Format - -```markdown -# Changelog - -## [2.5.1] - 2026-02-15 - -### Added -- New REST endpoint: `/sureforms/v1/forms/{id}/duplicate` -- Support for custom date formats in email notifications - -### Changed -- Improved performance of entry queries (20% faster) -- Updated Stripe API to v2024-01-01 - -### Deprecated -- `old_function()` - Use `new_function()` instead - -### Fixed -- Bug where conditional logic didn't work with checkboxes -- Memory leak in AI form generation - -### Security -- Fixed XSS vulnerability in admin settings (CVE-2026-0001) - -## [2.5.0] - 2026-02-01 - -... -``` - -**Categories:** -- **Added:** New features -- **Changed:** Changes to existing features -- **Deprecated:** Features marked for removal -- **Removed:** Features removed -- **Fixed:** Bug fixes -- **Security:** Security fixes - ---- - -## Documentation Review Checklist - -**Before committing doc changes:** - -### Content -- [ ] Information is accurate (tested code examples) -- [ ] No outdated information (double-checked) -- [ ] Cross-references updated (links work) -- [ ] Version number updated -- [ ] Terminology consistent with other docs - -### Style -- [ ] Clear and concise (no fluff) -- [ ] Code examples formatted correctly -- [ ] Spelling and grammar correct -- [ ] Tone matches existing docs - -### Technical -- [ ] All code examples tested -- [ ] All commands verified (on dev environment) -- [ ] All links work (no 404s) -- [ ] File paths correct (checked in codebase) - -### Accessibility -- [ ] Headings in logical order (H1 → H2 → H3) -- [ ] Code blocks have language specified -- [ ] Alt text for images (if any) -- [ ] Tables have headers - ---- - -## Automation & Tools - -### Linting Documentation - -**Check Markdown syntax:** - -```bash -# Install markdownlint -npm install -g markdownlint-cli - -# Lint all docs -cd internal-docs/ -markdownlint *.md -``` - -**Common issues caught:** -- Inconsistent heading levels -- Trailing whitespace -- Missing blank lines around code blocks - ---- - -### Link Checking - -**Verify all links work:** - -```bash -# Install markdown-link-check -npm install -g markdown-link-check - -# Check links -markdown-link-check internal-docs/*.md -``` - -**Fix broken links:** -- Update to correct URL -- Remove if resource no longer exists -- Use Internet Archive if critical resource - ---- - -### Spell Checking - -**Use spell checker:** - -```bash -# Install aspell -brew install aspell # macOS -apt install aspell # Linux - -# Check spelling -aspell check internal-docs/README.md -``` - -**Custom dictionary:** - -Create `.aspell.en.pws`: -``` -personal_ws-1.1 en 50 -SureForms -WordPress -Gutenberg -Mailchimp -PayPal -``` - ---- - -## Documentation Templates - -### New Feature Documentation Template - -**When adding new feature:** - -```markdown -## [Feature Name] - -**Since:** [version] -**Type:** [Free/Pro] - -### Overview - -[2-3 sentence description of what feature does and why it exists] - -### Use Cases - -- [Use case 1] -- [Use case 2] -- [Use case 3] - -### How to Use - -**Step 1: [Action]** - -[Description] - -```php -// Code example -``` - -**Step 2: [Action]** - -[Description] - -### Configuration - -| Option | Type | Default | Description | -|--------|------|---------|-------------| -| `option_name` | string | 'default' | What this does | - -### API Reference - -**REST Endpoint:** -``` -POST /sureforms/v1/feature -``` - -**Parameters:** -- `param1` (string, required) - Description -- `param2` (integer, optional) - Description - -**Response:** -```json -{ - "success": true, - "data": { ... } -} -``` - -### Examples - -**Example 1: [Use case]** -```php -// Code here -``` - -**Example 2: [Use case]** -```php -// Code here -``` - -### Troubleshooting - -**Issue:** [Common problem] -**Solution:** [How to fix] - -### Related - -- [Related feature 1](link) -- [Related feature 2](link) -``` - ---- - -### Bug Fix Documentation Template - -**When fixing bug:** - -**In troubleshooting.md:** - -```markdown -### [Issue Description] - -**Symptom:** [What user sees] - -**Diagnosis:** - -[How to identify the issue] - -```bash -# Commands to diagnose -``` - -**Fixes:** - -**Option 1: [Fix description]** -```php -// Code or command -``` - -**Option 2: [Alternative fix]** -```php -// Alternative code -``` - -**Prevents:** [What this prevents] - -**See also:** [Related issues] -``` - ---- - -## Review & Approval Process - -### Before Merging Docs - -**Self-review:** -1. Read your changes out loud -2. Test all code examples -3. Run linters -4. Check cross-references - -**Peer review:** -1. Request review from team member -2. Address feedback -3. Update based on comments - -**Final checks:** -1. Rebase on main branch -2. Verify no conflicts -3. One last proofread - ---- - -### Documentation Pull Request Template - -**PR description:** - -```markdown -## Documentation Update - -**Plugin Version:** 2.5.1 -**Docs Changed:** [List files] - -### Changes Made - -- [ ] Added documentation for [feature] -- [ ] Updated [section] in [file] -- [ ] Fixed typos in [file] - -### Verification - -- [x] All code examples tested -- [x] All links checked -- [x] Spelling checked -- [x] Cross-references updated -- [x] Version numbers updated - -### Related - -- Related PR: #123 -- Related Issue: #456 -``` - ---- - -## Documentation Metrics - -**Track documentation quality:** - -### Metrics to Monitor - -**Coverage:** -- % of features documented -- % of APIs documented -- % of code examples tested - -**Freshness:** -- Days since last update -- Number of outdated sections -- Deprecated content count - -**Quality:** -- Broken link count -- Spelling error count -- User-reported doc issues - -**Engagement:** -- Doc views (if analytics enabled) -- Time spent reading -- Bounce rate (if high, docs unclear) - ---- - -## Long-Term Maintenance - -### Quarterly Review - -**Every 3 months:** - -1. **Audit all docs:** - - Read each document start to finish - - Test all code examples - - Verify all links - - Update outdated info - -2. **User feedback:** - - Review GitHub issues tagged "documentation" - - Survey users about doc clarity - - Identify gaps in coverage - -3. **Reorganize if needed:** - - Move sections to better fit structure - - Split large docs if too long - - Merge duplicate information - ---- - -### Annual Review - -**Every year:** - -1. **Major cleanup:** - - Remove deprecated content - - Archive old versions - - Rewrite outdated sections - -2. **Structure evaluation:** - - Does structure still make sense? - - Should we add/remove files? - - Are cross-references clear? - -3. **Voice & tone:** - - Is tone consistent? - - Is it still beginner-friendly? - - Does it match product evolution? - ---- - -## Questions? - -**For documentation questions:** -- Create GitHub issue: `[Docs] Your question` -- Tag: `documentation` -- Assign: Documentation maintainer - -**For urgent doc bugs:** -- Ping in Slack: `#sureforms-docs` -- Include: File name, line number, issue description - ---- - -## Conclusion - -**Documentation is code.** - -Treat it with same care: -- Test before committing -- Review changes -- Keep it DRY (Don't Repeat Yourself) -- Refactor when needed - -**Good documentation:** -- Saves support time -- Accelerates onboarding -- Prevents bugs -- Shows we care - -**Thank you for maintaining SureForms docs!** 📚 - ---- - -**Version:** 2.5.0 -**Last Updated:** 2026-02-12 -**Maintainer:** SureForms Team diff --git a/internal-docs/onboarding.md b/internal-docs/onboarding.md deleted file mode 100644 index ab5b83ad3..000000000 --- a/internal-docs/onboarding.md +++ /dev/null @@ -1,1086 +0,0 @@ -# Developer Onboarding - -**Version:** 2.5.0 - ---- - -## Welcome to SureForms - -This guide helps you become productive quickly, whether you have 1 hour, 1 day, or 1 week. - -**What you're working on:** -- **SureForms Free:** AI-powered WordPress form builder (219 PHP files, 50+ blocks) -- **SureForms Pro:** Premium extension (206 PHP files, payments, integrations, advanced features) - -**Architecture:** WordPress + Gutenberg blocks + React 18 + Custom database - ---- - -## Prerequisites - -Before starting: -- [ ] WordPress 6.4+ installed locally -- [ ] Node.js 18+ and npm 8+ -- [ ] PHP 7.4+ with Composer -- [ ] Git configured -- [ ] IDE with PHP/JavaScript support -- [ ] Both plugins cloned from GitHub - -**Test environment:** -```bash -# If using Local by Flywheel or similar -http://localhost:10003/wp-admin/ -Username: admin -Password: admin -``` - ---- - -## 1-Hour Quick Start - -**Goal:** Make your first successful change - -### Step 1: Get Code Running (15 min) - -```bash -# Clone repositories (if not already) -cd /path/to/wp-content/plugins/ -git clone https://github.com/brainstormforce/sureforms.git -git clone https://github.com/brainstormforce/sureforms-pro.git - -# Install dependencies - SureForms Free -cd sureforms/ -npm install -composer install - -# Build assets -npm run build - -# Install dependencies - SureForms Pro -cd ../sureforms-pro/ -npm install -composer install -npm run build -``` - -**Verify installation:** -```bash -# In WordPress admin -wp plugin activate sureforms sureforms-pro -wp plugin list | grep sureforms -``` - -### Step 2: Create Your First Form (15 min) - -**Via WordPress admin:** -1. Go to **SureForms → Add New** -2. Click **Create with AI** or **Start from Blank** -3. Add fields: Email, Name, Message -4. Click **Publish** -5. Add to a page with the SureForms block - -**Via WP-CLI:** -```bash -# Create form programmatically -wp post create \ - --post_type=sureforms_form \ - --post_title="Test Contact Form" \ - --post_status=publish \ - --post_content='' -``` - -### Step 3: Make a Simple Change (20 min) - -**Task:** Change the submit button text - -**Files to modify:** -``` -src/blocks/form/edit.js ← React component -inc/blocks/form/block.php ← Server-side rendering -``` - -**Change 1: Edit the React component** - -Open `src/blocks/form/edit.js`: - -```javascript -// Find around line 45-50 -const { submitButtonText } = attributes; - -// Change default value -const defaultSubmitText = __('Send Message', 'sureforms'); // ← Change this -``` - -**Change 2: Rebuild** - -```bash -npm run build -``` - -**Verify:** Create new form, check if default button text changed. - -### Step 4: Debug Your Change (10 min) - -**Enable debugging:** - -Edit `wp-config.php`: -```php -define('WP_DEBUG', true); -define('WP_DEBUG_LOG', true); -define('WP_DEBUG_DISPLAY', false); -define('SCRIPT_DEBUG', true); // Loads unminified JS -``` - -**Check debug log:** -```bash -tail -f wp-content/debug.log -``` - -**Browser console:** -- Open DevTools → Console -- Look for JavaScript errors -- Check Network tab for AJAX failures - ---- - -## 1-Day Deep Dive - -**Goal:** Understand architecture and make meaningful contributions - -### Morning: Core Concepts (4 hours) - -#### Hour 1: Architecture Overview - -**Read these docs first:** -1. [README.md](README.md) - Project overview -2. [architecture.md](architecture.md) - System design -3. [codebase-map.md](codebase-map.md) - File structure - -**Key concepts to understand:** -- **Gutenberg blocks:** React components that render forms -- **Custom post type:** `sureforms_form` stores form configurations -- **Custom database tables:** `wp_sureforms_entries`, `wp_sureforms_payments` -- **REST API:** Handles form submissions, AI generation -- **AJAX handlers:** Payment processing, file uploads - -**Test your understanding:** -- Where is form submission data saved? (Answer: `wp_sureforms_entries` table) -- How does AI form generation work? (Answer: REST endpoint → external middleware → GPT API) -- What's the difference between Free and Pro? (Answer: Pro adds payments, integrations, conditional logic) - -#### Hour 2: Data Flow - -**Trace a form submission from start to finish:** - -``` -User fills form → Frontend validation → AJAX request - ↓ -inc/form-submit.php (Line 88-119: Nonce verification) - ↓ -Field validation (inc/field-validation.php) - ↓ -Sanitization (inc/helper.php::sanitize_by_field_type()) - ↓ -Database insert (inc/database/tables/entries.php::insert()) - ↓ -Email notification (inc/email/email-handler.php) - ↓ -Confirmation message (or redirect) -``` - -**Hands-on exercise:** -1. Enable MySQL query logging -2. Submit a test form -3. Check `wp_sureforms_entries` table -4. Verify entry data matches submission - -```bash -# View recent entries -wp db query "SELECT * FROM wp_sureforms_entries ORDER BY id DESC LIMIT 5;" -``` - -#### Hour 3: Payment Processing - -**Understand Stripe payment flow:** - -``` -User clicks "Pay" → Frontend creates payment intent - ↓ -AJAX: wp_ajax_nopriv_srfm_create_payment_intent - ↓ -inc/payments/front-end.php (Line 77-83: Create Stripe PaymentIntent) - ↓ -Stripe API processes payment - ↓ -Webhook received: sureforms/webhook_test - ↓ -inc/payments/stripe/stripe-webhook.php (Line 220-637: Handle events) - ↓ -Update wp_sureforms_payments table - ↓ -Send confirmation email -``` - -**Hands-on exercise:** -1. Set up Stripe test keys -2. Create a payment form -3. Use Stripe test card: `4242 4242 4242 4242` -4. Check `wp_sureforms_payments` table for payment record - -#### Hour 4: Pro Features - -**Explore key Pro additions:** - -**1. User Registration:** -- File: `inc/business/user-registration/processor.php` -- Creates WordPress user accounts from form submissions -- Handles login/password reset - -**2. Native Integrations:** -- Folder: `inc/pro/native-integrations/integrations/` -- 24+ services: Mailchimp, Brevo, HubSpot, Salesforce, etc. -- OAuth authentication with encrypted token storage - -**3. Conditional Logic:** -- Frontend: `src/pro/conditional-logic/` -- Show/hide fields based on user selections -- Real-time UI updates - -**Hands-on exercise:** -1. Create form with registration block -2. Submit form, verify user created: `wp user list` -3. Enable Mailchimp integration (test mode) -4. Submit form, check integration logs - -### Afternoon: Build Your First Feature (4 hours) - -**Challenge:** Add a new field type - -**Example: "Star Rating" field** - -#### Step 1: Plan (30 min) - -**Requirements:** -- Display 5 stars (clickable) -- Save selected rating (1-5) -- Validate: Required if configured -- Display in entries table - -**Files to create/modify:** -``` -src/blocks/star-rating/ ← New React component -inc/blocks/star-rating/block.php ← Server-side rendering -inc/helper.php ← Add sanitization -inc/field-validation.php ← Add validation -``` - -#### Step 2: Create Block Structure (1 hour) - -**Create block files:** - -```bash -# Create directories -mkdir -p src/blocks/star-rating -mkdir -p inc/blocks/star-rating - -# Copy from existing field (Phone is a good template) -cp -r src/blocks/phone/* src/blocks/star-rating/ -cp inc/blocks/phone/block.php inc/blocks/star-rating/ -``` - -**Edit `src/blocks/star-rating/block.json`:** - -```json -{ - "$schema": "https://schemas.wp.org/trunk/block.json", - "apiVersion": 3, - "name": "sureforms/star-rating", - "title": "Star Rating", - "category": "sureforms", - "icon": "star-filled", - "description": "Display a star rating input", - "attributes": { - "label": { - "type": "string", - "default": "Rate your experience" - }, - "required": { - "type": "boolean", - "default": false - }, - "maxRating": { - "type": "number", - "default": 5 - } - }, - "supports": { - "html": false - } -} -``` - -**Edit `src/blocks/star-rating/edit.js`:** - -```javascript -import { __ } from '@wordpress/i18n'; -import { useBlockProps } from '@wordpress/block-editor'; -import { TextControl, ToggleControl, RangeControl } from '@wordpress/components'; - -export default function Edit({ attributes, setAttributes }) { - const { label, required, maxRating } = attributes; - - return ( -
- setAttributes({ label: value })} - /> - setAttributes({ required: value })} - /> - setAttributes({ maxRating: value })} - min={1} - max={10} - /> -
- {[...Array(maxRating)].map((_, i) => ( - - ))} -
-
- ); -} -``` - -#### Step 3: Server-Side Rendering (45 min) - -**Edit `inc/blocks/star-rating/block.php`:** - -```php - [__CLASS__, 'render'], - ] - ); - } - - public static function render($attributes) { - $label = esc_html($attributes['label'] ?? 'Rate your experience'); - $required = !empty($attributes['required']); - $max_rating = absint($attributes['maxRating'] ?? 5); - $field_name = 'srfm-star-rating-' . uniqid(); - - ob_start(); - ?> -
- -
- - - ★ - - -
- > -
- { - const stars = container.querySelectorAll('.srfm-star'); - const input = container.nextElementSibling; - const maxRating = parseInt(container.dataset.max); - - stars.forEach(star => { - star.addEventListener('click', function() { - const value = parseInt(this.dataset.value); - input.value = value; - - // Visual update - stars.forEach((s, index) => { - if (index < value) { - s.classList.add('selected'); - } else { - s.classList.remove('selected'); - } - }); - }); - - // Hover effect - star.addEventListener('mouseenter', function() { - const value = parseInt(this.dataset.value); - stars.forEach((s, index) => { - if (index < value) { - s.classList.add('hover'); - } else { - s.classList.remove('hover'); - } - }); - }); - }); - - container.addEventListener('mouseleave', function() { - stars.forEach(s => s.classList.remove('hover')); - }); - }); -}); -``` - -#### Step 5: Register Block (15 min) - -**Edit `inc/blocks/register.php`:** - -```php -// Add to existing blocks registration -Star_Rating\Block::register(); -``` - -**Edit `src/blocks/star-rating/index.js`:** - -```javascript -import { registerBlockType } from '@wordpress/blocks'; -import edit from './edit'; -import metadata from './block.json'; - -registerBlockType(metadata.name, { - edit, - save: () => null, // Server-side rendering -}); -``` - -#### Step 6: Add Sanitization & Validation (30 min) - -**Edit `inc/helper.php`:** - -Find `sanitize_by_field_type()` method and add: - -```php -case 'star-rating': - $value = absint($value); - // Ensure value is between 1 and max rating - return ($value >= 1 && $value <= 10) ? $value : 0; -``` - -**Edit `inc/field-validation.php`:** - -Find validation logic and add: - -```php -if ($field_type === 'star-rating' && $is_required && empty($value)) { - $errors[] = __('Please select a rating', 'sureforms'); -} -``` - -#### Step 7: Build & Test (30 min) - -```bash -# Build assets -npm run build - -# Test in browser -# 1. Create new form -# 2. Add "Star Rating" block -# 3. Configure settings (label, required, max stars) -# 4. Publish form -# 5. Submit test entry -# 6. Verify data saved correctly - -# Check database -wp db query "SELECT * FROM wp_sureforms_entries ORDER BY id DESC LIMIT 1;" -``` - ---- - -## 1-Week Mastery - -**Goal:** Expert-level understanding and complex feature development - -### Day 1: Architecture Deep Dive - -**Morning:** -- Complete 1-day onboarding -- Read all internal docs thoroughly -- Map data flow for all major features - -**Afternoon:** -- Trace payment processing end-to-end -- Understand webhook verification -- Study integration architecture - -### Day 2: Security & Best Practices - -**Focus areas:** -1. **Input sanitization:** Understand all 15+ sanitization methods -2. **Output escaping:** When to use `esc_html()`, `esc_attr()`, `esc_url()` -3. **SQL injection prevention:** Always use `$wpdb->prepare()` -4. **CSRF protection:** Nonce verification patterns -5. **Authorization:** `current_user_can()` checks - -**Hands-on exercises:** -- Review `inc/form-submit.php` (Lines 88-119: Security checks) -- Study `inc/helper.php` sanitization methods -- Find and fix intentional security bugs in test code - -**Read:** -- [coding-standards.md](coding-standards.md) -- [ai-agent-guide.md](ai-agent-guide.md) - Security section - -### Day 3: React & Gutenberg Blocks - -**Topics:** -1. **Block architecture:** How Gutenberg blocks work -2. **Attributes:** Data storage and retrieval -3. **Inspector controls:** Settings sidebar -4. **Block variations:** Different field configurations -5. **Dynamic blocks:** Server-side rendering - -**Build complex block:** -- **Multi-step form block** (if not using Pro feature) -- Add step navigation -- Save progress between steps -- Implement validation per step - -**Resources:** -- Official Gutenberg docs: https://developer.wordpress.org/block-editor/ -- Example: Study `src/blocks/phone/` for complex field - -### Day 4: Database & REST API - -**Morning: Database operations** - -**Study these classes:** -- `inc/database/base.php` - Base table class -- `inc/database/tables/entries.php` - Entries CRUD -- `inc/database/tables/payments.php` - Payment records - -**Practice:** -```php -// Create custom query -use SRFM\Inc\Database\Tables\Entries; - -$entries = Entries::get_all([ - 'where' => [ - ['key' => 'form_id', 'value' => 123, 'compare' => '='], - ['key' => 'status', 'value' => 'published', 'compare' => '='] - ], - 'orderby' => 'created_at', - 'order' => 'DESC', - 'limit' => 20 -]); -``` - -**Afternoon: REST API development** - -**Create custom endpoint:** - -```php -// In new file: inc/rest-api-custom.php -namespace SRFM\Inc; - -class Rest_API_Custom { - public function register_routes() { - register_rest_route('sureforms/v1', '/custom-stats', [ - 'methods' => 'GET', - 'callback' => [$this, 'get_stats'], - 'permission_callback' => [$this, 'check_permissions'] - ]); - } - - public function check_permissions() { - return current_user_can('manage_options'); - } - - public function get_stats($request) { - // Your logic here - return ['success' => true, 'data' => []]; - } -} -``` - -### Day 5: Pro Features & Integrations - -**Morning: Payment processing** - -**Study both gateways:** -- Stripe: `inc/payments/stripe/` -- PayPal (Pro): `inc/business/payments/pay-pal/` - -**Understand webhook handling:** -- Signature verification -- Event processing -- Database updates -- Error handling - -**Afternoon: Build custom integration** - -**Example: Slack integration** - -1. Create integration folder: -``` -inc/pro/native-integrations/integrations/slack/ -├── config.json -└── actions/ - └── send-message.php -``` - -2. Define config: -```json -{ - "name": "Slack", - "slug": "slack", - "auth_method": "webhook_url", - "actions": [ - { - "name": "Send Message", - "slug": "send-message", - "endpoint": "chat.postMessage" - } - ] -} -``` - -3. Implement action: -```php -format_message($form_data); - - $response = wp_remote_post($webhook_url, [ - 'body' => json_encode(['text' => $message]), - 'headers' => ['Content-Type' => 'application/json'] - ]); - - if (is_wp_error($response)) { - return ['success' => false, 'error' => $response->get_error_message()]; - } - - return ['success' => true]; - } - - private function format_message($form_data) { - // Format form data as Slack message - return "New form submission:\n" . print_r($form_data, true); - } -} -``` - ---- - -## Testing Your Changes - -### Local Testing - -**PHP Unit Tests:** -```bash -# Run all tests -composer test - -# Run specific test file -vendor/bin/phpunit tests/unit/test-helper.php - -# Run with coverage -composer test-coverage -``` - -**JavaScript Tests:** -```bash -# Run all JS tests -npm run test:unit - -# Watch mode -npm run test:unit:watch - -# Coverage -npm run test:unit:coverage -``` - -### E2E Testing (Playwright) - -```bash -# Start test environment -npm run play:up - -# Run E2E tests -npm run play:run - -# Interactive mode (see browser) -npm run play:run:interactive - -# Stop environment -npm run play:down -``` - -### Manual Testing Checklist - -Before submitting PR: -- [ ] Form creation works -- [ ] Form submission saves entry -- [ ] Email notifications sent -- [ ] Payment processing works (if touched) -- [ ] No JavaScript console errors -- [ ] No PHP errors in debug.log -- [ ] Works in latest WordPress version -- [ ] Works in Firefox, Chrome, Safari -- [ ] Mobile responsive -- [ ] Accessibility: keyboard navigation works - ---- - -## Code Review Process - -### Before Creating PR - -**Self-review:** -1. Run linters: -```bash -composer lint # PHP_CodeSniffer -npm run lint-js # ESLint -``` - -2. Auto-fix minor issues: -```bash -composer format # phpcbf -npm run lint-js:fix # ESLint --fix -``` - -3. Check for common issues: -- [ ] All inputs sanitized -- [ ] All outputs escaped -- [ ] SQL queries use `prepare()` -- [ ] Nonces verified for AJAX/forms -- [ ] Capabilities checked for admin actions -- [ ] No hardcoded strings (use `__()` for i18n) - -### Creating PR - -**Branch naming:** -```bash -git checkout -b feat/star-rating-field -git checkout -b fix/payment-webhook-error -git checkout -b refactor/database-queries -``` - -**Commit message format:** -``` -type(scope): brief description - -Longer explanation if needed. - -Co-Authored-By: Your Name -``` - -**Types:** feat, fix, docs, style, refactor, test, chore - -**Example:** -``` -feat(blocks): add star rating field - -- Add new star-rating block -- Implement frontend JavaScript -- Add sanitization and validation -- Update docs with new field type - -Co-Authored-By: Claude Sonnet 4.5 -``` - -### PR Checklist - -- [ ] Tests pass: `composer test && npm run test:unit` -- [ ] Linting passes: `composer lint && npm run lint-js` -- [ ] No console errors -- [ ] Database migrations documented (if any) -- [ ] Breaking changes documented -- [ ] Changelog updated -- [ ] Screenshots attached (for UI changes) - ---- - -## Common Tasks & Patterns - -### Add New AJAX Handler - -**Pattern:** -```php -// In controller file -public function register_ajax_actions() { - add_action('wp_ajax_srfm_my_action', [$this, 'handle_my_action']); - add_action('wp_ajax_nopriv_srfm_my_action', [$this, 'handle_my_action']); -} - -public function handle_my_action() { - // CRITICAL: Always verify nonce - check_ajax_referer('srfm_my_action_nonce', 'security'); - - // Check permissions if needed - if (!current_user_can('manage_options')) { - wp_send_json_error(['message' => 'Insufficient permissions']); - } - - // Sanitize inputs - $data = Helper::sanitize_array_recursively($_POST['data'] ?? []); - - // Process... - - wp_send_json_success(['result' => $result]); -} -``` - -### Add New REST Endpoint - -**Pattern:** -```php -// In inc/rest-api.php -public function register_routes() { - register_rest_route('sureforms/v1', '/my-endpoint', [ - 'methods' => 'POST', - 'callback' => [$this, 'handle_request'], - 'permission_callback' => [$this, 'check_permissions'] - ]); -} - -public function check_permissions() { - return current_user_can('manage_options'); -} - -public function handle_request($request) { - // Always verify nonce - $nonce = $request->get_header('X-WP-Nonce'); - if (!wp_verify_nonce($nonce, 'wp_rest')) { - return new \WP_Error('invalid_nonce', 'Invalid nonce', ['status' => 403]); - } - - // Get and sanitize parameters - $params = $request->get_params(); - $clean_params = Helper::sanitize_array_recursively($params); - - // Process... - - return ['success' => true, 'data' => $result]; -} -``` - -### Add WordPress Hook - -**Action hook (notify about event):** -```php -// Trigger action after entry save -do_action('sureforms_after_entry_save', $entry_id, $form_id, $entry_data); - -// Other plugins/themes can listen: -add_action('sureforms_after_entry_save', function($entry_id, $form_id, $data) { - // Custom logic -}, 10, 3); -``` - -**Filter hook (modify data):** -```php -// Allow filtering of email subject -$subject = apply_filters('sureforms_email_subject', $subject, $form_id, $entry_data); - -// Other plugins/themes can modify: -add_filter('sureforms_email_subject', function($subject, $form_id, $data) { - return "[Form $form_id] $subject"; -}, 10, 3); -``` - -### Database Operations - -**Insert entry:** -```php -use SRFM\Inc\Database\Tables\Entries; - -$entry_id = Entries::insert([ - 'form_id' => 123, - 'user_id' => get_current_user_id(), - 'status' => 'published', - 'entry_data' => wp_json_encode($form_data) -]); -``` - -**Update entry:** -```php -Entries::update($entry_id, [ - 'status' => 'spam' -]); -``` - -**Delete entry:** -```php -Entries::delete($entry_id); -``` - -**Query entries:** -```php -$entries = Entries::get_all([ - 'where' => [ - ['key' => 'form_id', 'value' => 123, 'compare' => '='] - ], - 'limit' => 20, - 'offset' => 0 -]); -``` - ---- - -## Debugging Tips - -### Enable Debug Mode - -**wp-config.php:** -```php -define('WP_DEBUG', true); -define('WP_DEBUG_LOG', true); -define('WP_DEBUG_DISPLAY', false); -define('SCRIPT_DEBUG', true); -define('SAVEQUERIES', true); -``` - -### Check Debug Log - -```bash -# Real-time log monitoring -tail -f wp-content/debug.log - -# Search for errors -grep "SureForms" wp-content/debug.log -``` - -### JavaScript Debugging - -**Browser console:** -```javascript -// Check global object -console.log(window.sureforms); - -// Check block attributes -wp.data.select('core/block-editor').getBlocks(); - -// Check form data -document.querySelector('form').addEventListener('submit', (e) => { - console.log('Form data:', new FormData(e.target)); -}); -``` - -### Database Queries - -**Install Query Monitor plugin:** -```bash -wp plugin install query-monitor --activate -``` - -**Check slow queries:** -- Visit any admin page -- Click "Query Monitor" in admin bar -- View "Queries" tab -- Sort by time -- Optimize slow queries - -**Manual query inspection:** -```php -// Add to code temporarily -global $wpdb; -$wpdb->show_errors(); -$wpdb->print_error(); -``` - -### AJAX Debugging - -**Check network tab:** -1. Open DevTools → Network -2. Filter: XHR -3. Submit form -4. Click request -5. Check Response tab for errors - -**Add debug output:** -```php -public function handle_ajax() { - error_log('AJAX data: ' . print_r($_POST, true)); - // ... rest of code -} -``` - ---- - -## Resources - -### Internal Documentation -- [README.md](README.md) - Quick start -- [architecture.md](architecture.md) - System design -- [codebase-map.md](codebase-map.md) - File structure -- [apis.md](apis.md) - API reference -- [coding-standards.md](coding-standards.md) - Code standards -- [ai-agent-guide.md](ai-agent-guide.md) - AI agent guidance -- [troubleshooting.md](troubleshooting.md) - Common problems - -### External Resources -- **WordPress Codex:** https://codex.wordpress.org/ -- **Block Editor Handbook:** https://developer.wordpress.org/block-editor/ -- **REST API Handbook:** https://developer.wordpress.org/rest-api/ -- **React Docs:** https://react.dev/ -- **WP-CLI:** https://wp-cli.org/ - -### Community -- **GitHub Issues:** Report bugs, request features -- **Facebook Group:** https://www.facebook.com/groups/surecart -- **Support:** https://support.brainstormforce.com/ - ---- - -## Next Steps - -After completing onboarding: - -1. **Pick a starter issue:** - - Look for "good first issue" label on GitHub - - Start with documentation or small bug fixes - - Work up to features - -2. **Read code:** - - Pick a feature you use - - Trace it from UI to database - - Understand every line - -3. **Write tests:** - - For code you touch - - Increases confidence - - Helps others understand your changes - -4. **Ask questions:** - - Don't hesitate to ask - - Better to ask than assume - - Document answers for others - -**Welcome to the team!** 🚀 diff --git a/internal-docs/product-vision.md b/internal-docs/product-vision.md deleted file mode 100644 index f41f1951c..000000000 --- a/internal-docs/product-vision.md +++ /dev/null @@ -1,688 +0,0 @@ -# Product Vision - -**Version:** 2.5.0 - ---- - -## Mission - -**Empower anyone to build beautiful, high-converting forms without code.** - -SureForms exists to solve a fundamental problem: creating forms on WordPress is unnecessarily complex, resulting in ugly forms that hurt conversion rates. - ---- - -## The Problem We Solve - -### Pain Points (Before SureForms) - -**1. Complexity** -- Learning curve: New interfaces, proprietary builders -- Time waste: Hours configuring simple contact forms -- Technical barriers: Requires developer for custom fields - -**2. Design Limitations** -- Generic templates that don't match site design -- Limited styling options without CSS knowledge -- Mobile responsiveness as afterthought - -**3. Low Engagement** -- Long, intimidating single-page forms -- No personalization or conditional logic -- High abandonment rates (avg 67% for long forms) - -**4. Spam & Security** -- Constant bot submissions -- Security vulnerabilities in popular plugins -- GDPR compliance challenges - -**5. Integration Friction** -- Payment processing requires multiple plugins -- Manual data export/import to CRMs -- Webhook setup requires developer knowledge - ---- - -## Our Solution - -### Core Differentiators - -**1. Native WordPress (Gutenberg)** -- **Why:** Users already know the interface -- **Benefit:** Zero learning curve, instant productivity -- **Technical:** React blocks, no proprietary builder - -**2. AI-Powered Form Building** -- **Innovation:** First AI form builder for WordPress -- **How:** Natural language → complete functional form in seconds -- **Examples:** - - "Create a job application form" → 12-field form with file upload - - "Simple contact form" → 3 fields, perfectly styled - - "Event RSVP with dietary restrictions" → Conditional logic auto-configured - -**3. Built-in Payments** -- **Why:** No WooCommerce, no add-ons required -- **Gateways:** Stripe (Free), PayPal (Pro) -- **Features:** One-time, subscriptions, custom amounts -- **Security:** PCI-compliant, encrypted credentials - -**4. Mobile-First Design** -- **Approach:** Responsive by default, not opt-in -- **Testing:** Every block tested on iOS/Android -- **Performance:** Fast load times on 3G networks - -**5. Engagement Features (Pro)** -- **Conversational Forms:** Chat-like, one question at a time -- **Multi-Step Forms:** Break long forms into digestible steps -- **Conditional Logic:** Show/hide based on answers -- **Result:** 3x higher completion rates vs single-page forms - ---- - -## Target Users - -### Primary Personas - -#### 1. Website Owner (40% of users) -**Profile:** -- Small business owner or solopreneur -- Limited technical skills -- DIY mentality -- Budget-conscious - -**Needs:** -- Contact forms, quote requests, bookings -- Easy setup (< 10 minutes) -- Professional appearance -- Spam protection - -**Pain Points:** -- Frustrated with complex form builders -- Can't afford developer -- Generic templates don't match brand - -**How SureForms Helps:** -- AI creates form in 30 seconds -- Instant Form feature (no embedding needed) -- Built-in anti-spam (reCAPTCHA, Honeypot) -- Modern, customizable design - ---- - -#### 2. WordPress Designer (30% of users) -**Profile:** -- Freelancer or agency designer -- Strong design skills, basic code knowledge -- Builds sites for clients -- Values aesthetics and UX - -**Needs:** -- Forms that match site design -- Custom styling without CSS -- Fast deployment -- Client-friendly interface - -**Pain Points:** -- Form plugins look "generic" -- CSS overrides are tedious -- Clients can't update forms themselves -- Other plugins don't use Gutenberg - -**How SureForms Helps:** -- Gutenberg-native (feels like page building) -- Extensive styling options in UI -- Client can edit without breaking design -- Block patterns for reusability - ---- - -#### 3. WordPress Developer (20% of users) -**Profile:** -- Full-stack developer -- Builds custom WordPress solutions -- Values clean code and extensibility -- Performance-conscious - -**Needs:** -- Developer-friendly APIs -- Hooks and filters -- Custom field types -- Database access -- Integration capabilities - -**Pain Points:** -- Other plugins have messy codebases -- Limited extensibility -- Poor documentation -- Performance issues (N+1 queries, bloat) - -**How SureForms Helps:** -- Clean, modern codebase (PSR-12-inspired) -- Extensive hooks: 50+ actions/filters -- Well-documented APIs -- Optimized queries (custom tables, not post meta) -- GitHub access for contributions - ---- - -#### 4. E-commerce Store Owner (10% of users) -**Profile:** -- Runs WooCommerce or custom store -- Needs payment forms (not full checkout) -- Sells services, memberships, donations -- Wants simplicity - -**Needs:** -- Accept payments without WooCommerce -- Subscription billing -- Custom pricing fields -- Receipt emails - -**Pain Points:** -- WooCommerce is overkill for simple payments -- Other payment forms require add-ons -- Can't customize payment flow -- Poor mobile checkout experience - -**How SureForms Helps:** -- Built-in Stripe/PayPal (no plugins) -- Subscription support included -- Custom amount fields (donations, tips) -- Mobile-optimized payment UI - ---- - -## Feature Philosophy - -### Design Principles - -**1. Simplicity Over Features** -- Don't add features just because competitors have them -- Every feature must solve real user problem -- Hide complexity behind smart defaults - -**Example:** -- ❌ Bad: 50 font options overwhelming users -- ✅ Good: 5 curated fonts + custom font option - -**2. Progressive Disclosure** -- Show basic options first -- Advanced settings collapsed by default -- Help text on hover, not always visible - -**Example:** -- Default form settings: 4 essential options -- Advanced panel: 15+ options (collapsed) - -**3. Convention Over Configuration** -- Smart defaults based on common use cases -- Zero config for 80% of users -- Power users can customize - -**Example:** -- Email notification auto-configured with sensible template -- User can override if needed - -**4. Performance First** -- Lazy load non-critical assets -- Minimize HTTP requests -- Database queries optimized (no N+1) -- CSS/JS minified and cached - -**Metrics:** -- Page load impact: < 50KB additional assets -- Time to Interactive: < 2 seconds on 3G -- Database queries: Max 5 per form render - -**5. Accessibility Built-In** -- WCAG 2.1 Level AA compliance -- Keyboard navigation -- Screen reader support -- Focus indicators - -**Testing:** -- Every block tested with NVDA/JAWS -- Keyboard-only testing required -- Color contrast checked - ---- - -## Free vs Pro Strategy - -### Free Plugin (Core Experience) - -**Philosophy:** Full-featured, not crippled trial - -**Included:** -- Unlimited forms -- Unlimited submissions -- All 15+ field types -- Email notifications -- Spam protection (reCAPTCHA, Honeypot) -- Stripe payments (one-time, subscriptions) -- Form analytics -- Export entries (CSV) -- GDPR compliance -- Instant Forms - -**Limitations:** -- No PayPal -- No native integrations (Mailchimp, etc.) -- No conditional logic -- No multi-step/conversational forms -- No user registration -- No PDF generation - -**Goal:** Provide genuine value, build trust, convert 5-10% to Pro - ---- - -### Pro Plugin (Power Features) - -**Philosophy:** Advanced features for serious users - -**Added Value:** -- **Payments:** PayPal (one-time, subscriptions) -- **Integrations:** 24+ native (Mailchimp, Brevo, HubSpot, Salesforce, etc.) -- **Logic:** Conditional show/hide, calculations -- **Forms:** Multi-step, conversational, save & resume -- **Users:** Registration, login, password reset -- **Output:** PDF generation from submissions -- **Advanced Fields:** Upload (images, files), signature, calculator -- **Priority Support:** < 24hr response time - -**Pricing Tiers:** -- **Essential:** $99/year (3 sites) -- **Plus:** $199/year (20 sites) -- **Agency:** $299/year (unlimited sites) - -**Conversion Strategy:** -- Free users see "Pro" badge on locked features -- No nag screens or popups -- Upgrade CTA in logical places (when user needs feature) -- 14-day money-back guarantee - ---- - -## Competitive Landscape - -### Direct Competitors - -**1. Gravity Forms** -- **Strengths:** Mature, extensive add-ons, trusted -- **Weaknesses:** Old UI, not Gutenberg-native, expensive -- **Our Advantage:** Modern interface, AI builder, lower cost - -**2. WPForms** -- **Strengths:** Beginner-friendly, drag-and-drop -- **Weaknesses:** Generic designs, limited styling -- **Our Advantage:** Better design flexibility, Gutenberg-native - -**3. Formidable Forms** -- **Strengths:** Advanced features, views/reporting -- **Weaknesses:** Steep learning curve, performance issues -- **Our Advantage:** Simpler, faster, AI-assisted - -**4. Fluent Forms** -- **Strengths:** Conversational forms, modern UI -- **Weaknesses:** Not Gutenberg-native, separate builder -- **Our Advantage:** Native Gutenberg, simpler UX - -**5. Contact Form 7** -- **Strengths:** Free, lightweight, popular -- **Weaknesses:** No UI, requires shortcodes, ugly default styles -- **Our Advantage:** Visual builder, beautiful defaults, AI - ---- - -### Market Positioning - -**SureForms:** The AI-powered Gutenberg form builder - -**Tagline:** "Beautiful forms without code" - -**Positioning Statement:** -> For WordPress users who want high-converting forms without complexity, SureForms is the AI-powered form builder that creates beautiful, mobile-first forms in seconds—unlike outdated plugins that require hours of configuration and result in generic-looking forms. - -**Why Users Choose SureForms:** -1. **Speed:** AI creates forms in 30 seconds vs 30 minutes -2. **Design:** Modern, mobile-first vs generic templates -3. **Ease:** Gutenberg-native vs proprietary builder -4. **Value:** Built-in payments vs add-ons required - ---- - -## Product Roadmap - -### Current Focus (2026 Q1) - -**Theme:** Stability & Performance - -**Priorities:** -1. Bug fixes from user reports -2. Performance optimization (lazy loading, query optimization) -3. Security hardening (code audit, penetration testing) -4. Documentation improvements -5. Accessibility compliance (WCAG 2.2 Level AA) - ---- - -### Near-Term (2026 Q2-Q3) - -**Theme:** Advanced Features & Integrations - -**Planned:** -1. **More Integrations:** - - Google Sheets (native, no Zapier) - - Airtable - - Notion - - Slack (native) - -2. **Field Types:** - - Star rating - - Matrix/grid (Pro) - - File upload enhancements (drag & drop, preview) - -3. **Conditional Logic Enhancements (Pro):** - - Show/hide blocks (not just fields) - - Calculation fields (price quotes, BMI calculators) - - Conditional email notifications - -4. **Analytics:** - - Conversion funnel visualization - - A/B testing (form variations) - - Heatmaps (where users drop off) - -5. **Templates:** - - 100+ pre-built form templates - - Industry-specific (real estate, healthcare, education) - - Import/export custom templates - ---- - -### Long-Term Vision (2027+) - -**Theme:** AI-Driven Personalization - -**Research Areas:** -1. **AI Form Optimization:** - - Auto-suggest field improvements based on completion rates - - Predictive text for common fields - - Smart field ordering (ML-driven) - -2. **Advanced Conversational Forms:** - - Voice input support - - Natural language processing for responses - - Branching logic based on sentiment - -3. **Global Expansion:** - - Multi-language support (WPML, Polylang) - - Currency localization - - Regional compliance (CCPA, PIPEDA, etc.) - -4. **Enterprise Features:** - - Team collaboration (roles, permissions) - - Advanced approval workflows - - Audit logs - - White-label options - -5. **Mobile App:** - - iOS/Android app for managing entries - - Push notifications for new submissions - - Offline form viewing - ---- - -## Success Metrics - -### North Star Metric -**Active Forms:** Number of forms receiving at least 1 submission per month - -**Why:** Indicates genuine usage, not just installs - -**Target:** 100,000 active forms by end of 2026 - ---- - -### Secondary Metrics - -**Growth:** -- New installations per month: 50,000+ -- Activation rate: 60% (user creates first form within 7 days) -- Retention: 80% still active after 30 days - -**Engagement:** -- Forms created per user: 3.5 average -- Submissions per form: 25/month average -- Feature adoption (Pro): 40% use conditional logic - -**Conversion:** -- Free → Pro conversion: 5-7% -- Trial → Paid: 25% -- Annual renewal rate: 85% - -**Quality:** -- Support ticket volume: < 2% of active users -- Bug reports: < 0.5% of installations -- 4.5+ star rating on WordPress.org - -**Performance:** -- Average page load impact: < 40KB -- Time to first form submission: < 5 minutes (from install) -- Support response time: < 12 hours - ---- - -## User Feedback Integration - -### How We Listen - -**1. Support Tickets** -- Every ticket tagged by topic -- Monthly review of common issues -- Feature requests tracked in GitHub - -**2. User Surveys** -- Annual user satisfaction survey -- Post-purchase survey (Pro users) -- Exit survey (churned Pro users) - -**3. Analytics** -- Feature usage tracking (opt-in) -- Error logging (anonymized) -- Performance metrics - -**4. Community** -- Facebook group discussions -- GitHub issues and discussions -- WordPress.org support forum - -**5. Direct Outreach** -- User interviews (quarterly) -- Beta tester program -- Power user advisory board - ---- - -### Decision Framework - -**Feature Requests Evaluation:** - -**Criteria:** -1. **Impact:** How many users need this? (1-10) -2. **Effort:** Development complexity? (1-10) -3. **Strategic Fit:** Aligns with vision? (Yes/No) -4. **Competitive:** Do competitors have it? (Yes/No) -5. **Revenue:** Drives conversions? (Yes/No) - -**Scoring:** -- Impact / Effort = Priority score -- Strategic Fit = multiplier (2x if yes) -- Build if score > 5 - -**Example:** -- Feature: "Drag & drop file upload" -- Impact: 8 (many requests) -- Effort: 4 (moderate complexity) -- Strategic Fit: Yes (better UX) -- Score: (8/4) × 2 = 4 → **Build later** - ---- - -## Brand & Voice - -### Brand Personality - -**Adjectives:** -- Approachable (not intimidating) -- Modern (not trendy) -- Reliable (not boring) -- Empowering (not condescending) - -**Tone:** -- Friendly but professional -- Clear over clever -- Helpful without being pushy -- Honest about limitations - ---- - -### Writing Guidelines - -**Do:** -- Use "you" (conversational) -- Short sentences -- Active voice -- Explain "why" not just "how" - -**Don't:** -- Jargon without explanation -- Marketing fluff ("revolutionary", "game-changing") -- Passive voice ("the form was created") -- Unnecessary exclamation marks!!!! - -**Examples:** - -❌ Bad: "SureForms revolutionizes form building with cutting-edge AI technology!" - -✅ Good: "SureForms uses AI to create forms in seconds. Describe what you need, and we'll build it." - ---- - -❌ Bad: "The form submission process has been optimized for maximum conversion potential." - -✅ Good: "We designed our forms to load fast and look great on mobile, so more people complete them." - ---- - -## Technical Vision - -### Architecture Goals - -**1. Performance** -- Custom database tables (not post meta) -- Lazy loading for non-critical assets -- Query optimization (no N+1) -- CDN-friendly (static assets versioned) - -**2. Scalability** -- Handle 100,000+ submissions per form -- Efficient database queries (indexed columns) -- Background processing for heavy tasks (webhooks, PDFs) -- Caching strategy (transients, object cache) - -**3. Security** -- Input sanitization (all user data) -- Output escaping (all rendered content) -- Nonce verification (all AJAX/REST) -- SQL injection prevention (prepared statements) -- Regular security audits - -**4. Extensibility** -- 50+ hooks (actions and filters) -- Clean, documented APIs -- Developer-friendly codebase -- Backward compatibility promise - -**5. Maintainability** -- WordPress coding standards (PHP_CodeSniffer) -- ESLint for JavaScript -- Automated testing (PHPUnit, Playwright) -- Clear documentation (inline and external) - ---- - -## Values & Principles - -**1. User Privacy** -- No tracking without consent -- GDPR compliance built-in -- Data portability (easy export) -- Clear privacy policy - -**2. Open Source (Free Plugin)** -- Public GitHub repository -- Accept community contributions -- Transparent roadmap -- Active maintenance - -**3. Quality Over Speed** -- Test thoroughly before release -- Fix bugs before adding features -- Code review required for all changes -- No "move fast and break things" - -**4. Accessibility** -- WCAG 2.1 Level AA minimum -- Keyboard navigation always -- Screen reader testing required -- Color contrast compliance - -**5. Sustainability** -- Reasonable pricing (not subscription trap) -- Long-term support commitment -- No vendor lock-in (data always exportable) -- Transparent upgrade policies - ---- - -## What We Won't Do - -**Out of Scope:** - -**1. Full CRM System** -- Why: Bloat, complexity, competing with specialists -- Alternative: Integrate with existing CRMs (HubSpot, Salesforce) - -**2. Email Marketing Platform** -- Why: Already solved by Mailchimp, Brevo, etc. -- Alternative: Native integrations with 24+ email platforms - -**3. Complete E-commerce Solution** -- Why: WooCommerce exists, does it well -- Alternative: Simple payment forms (our niche) - -**4. Website Builder** -- Why: Outside core competency (forms) -- Alternative: Work seamlessly with any page builder - -**5. Survey & Quiz Builder** -- Why: Different use case, different UX requirements -- Alternative: Forms work for simple surveys - ---- - -## Conclusion - -**Core Belief:** -Forms are critical touchpoints between businesses and customers. They should be beautiful, fast, and easy to create. - -**Our Promise:** -We'll keep building tools that make form creation accessible to everyone, without sacrificing power or flexibility. - -**For Developers:** -Your feedback shapes this product. Keep the issues and PRs coming. We're listening. - ---- - -**Next:** [UI & Copy Guidelines](ui-and-copy.md) diff --git a/internal-docs/troubleshooting.md b/internal-docs/troubleshooting.md deleted file mode 100644 index b7f256af5..000000000 --- a/internal-docs/troubleshooting.md +++ /dev/null @@ -1,1031 +0,0 @@ -# Troubleshooting Guide - -**Version:** 2.5.0 - ---- - -## Quick Diagnostic - -**Before diving deep, check these common issues:** - -```bash -# 1. WordPress & PHP versions -wp core version -php -v - -# 2. Plugin status -wp plugin list | grep sureforms - -# 3. Theme compatibility -wp theme list --status=active - -# 4. Recent errors -tail -50 wp-content/debug.log | grep -i "sureforms\|fatal\|error" - -# 5. Database tables exist -wp db query "SHOW TABLES LIKE '%sureforms%';" -``` - ---- - -## Installation & Activation Issues - -### Plugin Won't Activate - -**Symptom:** "Plugin activation failed" or white screen - -**Common Causes:** - -**1. PHP Version Too Old** -```bash -php -v -# Required: PHP 7.4+ -``` - -**Fix:** -```bash -# Update PHP (contact host if shared hosting) -# Or add to wp-config.php temporarily to see error: -define('WP_DEBUG', true); -define('WP_DEBUG_DISPLAY', true); -``` - -**2. WordPress Version Too Old** -```bash -wp core version -# Required: WordPress 6.4+ -``` - -**Fix:** -```bash -wp core update -``` - -**3. Conflicting Plugin** - -**Check for conflicts:** -```bash -# Deactivate all other plugins -wp plugin deactivate --all --exclude=sureforms,sureforms-pro - -# Try activating SureForms -wp plugin activate sureforms - -# Reactivate plugins one by one -wp plugin activate plugin-name -``` - -**Common conflicts:** -- Old caching plugins (W3 Total Cache < 2.0) -- Security plugins with aggressive rules -- Other form builders (namespace collisions) - -**4. Memory Limit Too Low** - -**Check current limit:** -```bash -wp eval 'echo WP_MEMORY_LIMIT;' -``` - -**Fix (wp-config.php):** -```php -define('WP_MEMORY_LIMIT', '256M'); -``` - ---- - -### Pro Plugin Shows "Base Plugin Required" - -**Symptom:** SureForms Pro won't activate - -**Diagnosis:** -```bash -wp plugin list | grep sureforms -# Ensure both sureforms AND sureforms-pro are installed -``` - -**Fix:** -1. Install SureForms Free first -2. Activate SureForms Free -3. Then activate SureForms Pro - -**Check version compatibility:** -```bash -# Free and Pro versions should match -# Both should be 2.5.0 (or same major.minor) -``` - ---- - -### Database Tables Not Created - -**Symptom:** Form submissions fail, entries not showing - -**Check tables exist:** -```bash -wp db query "SHOW TABLES LIKE '%sureforms%';" -``` - -**Expected output:** -``` -wp_sureforms_entries -wp_sureforms_payments -wp_sureforms_integrations -wp_sureforms_save_resume -``` - -**Fix: Force database creation** -```bash -# Deactivate plugin -wp plugin deactivate sureforms sureforms-pro - -# Delete plugin (backup first!) -wp plugin delete sureforms - -# Reinstall -wp plugin install sureforms --activate - -# Tables should be created on activation -``` - -**Manual creation (last resort):** - -Read schema from: -- `inc/database/tables/entries.php` -- `inc/database/tables/payments.php` - -Run CREATE TABLE statements manually. - ---- - -## Form Builder (Editor) Issues - -### Forms Won't Load in Editor - -**Symptom:** Blank screen or infinite loading spinner - -**Diagnosis:** - -**1. Check browser console:** -``` -Open DevTools → Console -Look for JavaScript errors -``` - -**Common errors:** - -**a) "wp.blockEditor is undefined"** -- **Cause:** Outdated WordPress version -- **Fix:** `wp core update` - -**b) "React version mismatch"** -- **Cause:** Another plugin using old React version -- **Fix:** Deactivate other plugins one by one to find conflict - -**c) "Uncaught SyntaxError"** -- **Cause:** JavaScript file corrupted or not minified correctly -- **Fix:** Rebuild assets: `npm run build` in plugin directory - -**2. Check network tab:** -``` -DevTools → Network -Filter: JS -Look for failed requests (red, 404, 500) -``` - -**Common failures:** -- `form-editor.js` (404) → Rebuild assets -- `chunk-vendors.js` (500) → Server misconfiguration - -**3. Enable SCRIPT_DEBUG:** - -In `wp-config.php`: -```php -define('SCRIPT_DEBUG', true); -``` - -This loads unminified JS, easier to debug. - ---- - -### Blocks Not Appearing in Inserter - -**Symptom:** SureForms blocks missing from block library - -**Diagnosis:** -```bash -# Check if blocks are registered -wp eval "print_r(get_option('srfm_blocks_registration'));" -``` - -**Fixes:** - -**1. Re-register blocks:** -```bash -wp plugin deactivate sureforms -wp plugin activate sureforms -``` - -**2. Clear block cache:** -```bash -wp cache flush -wp transient delete --all -``` - -**3. Check block.json files exist:** -```bash -find wp-content/plugins/sureforms/inc/blocks -name "block.json" -# Should return multiple files -``` - ---- - -### Form Preview Shows "Invalid Block" - -**Symptom:** Form renders as "This block contains unexpected or invalid content" - -**Cause:** Block HTML structure changed, saved form has old structure - -**Fix:** - -**Option 1: Update block (preserves data):** -1. Click "Attempt Block Recovery" -2. Verify content looks correct -3. Update form - -**Option 2: Clear and rebuild:** -1. Delete the invalid block -2. Add fresh block -3. Reconfigure settings - -**Prevention:** -- Always test after plugin updates -- Keep staging environment for testing - ---- - -## Form Submission Issues - -### Form Submissions Not Saving - -**Symptom:** User submits form, success message shows, but no entry in database - -**Diagnosis:** - -**1. Check debug log:** -```bash -tail -f wp-content/debug.log -# Submit form while watching log -``` - -**Common errors:** -- "Database insert failed" → Check table permissions -- "Nonce verification failed" → Caching issue (see below) -- "Call to undefined method" → PHP version or missing dependency - -**2. Check database directly:** -```bash -# Get latest entry -wp db query "SELECT * FROM wp_sureforms_entries ORDER BY id DESC LIMIT 1;" -``` - -**3. Test with minimal form:** -Create form with ONLY: -- Email field -- Submit button - -If this works, issue is with specific field type. - -**Fixes:** - -**Database Permissions:** -```bash -# Check MySQL user has INSERT privilege -wp db query "SHOW GRANTS;" -``` - -**Fix permissions (MySQL):** -```sql -GRANT INSERT, UPDATE, DELETE ON database_name.* TO 'wp_user'@'localhost'; -FLUSH PRIVILEGES; -``` - -**Caching Interference:** - -Caching plugins cache nonce values, causing verification failures. - -**Fix:** -1. Exclude `/wp-admin/admin-ajax.php` from cache -2. Exclude REST API `/wp-json/` from cache -3. Or disable caching temporarily to test - ---- - -### Email Notifications Not Sending - -**Symptom:** Form submitted successfully, but no email received - -**Diagnosis:** - -**1. Check if emails are being sent at all:** -```bash -# Install WP Mail SMTP or similar -wp plugin install wp-mail-smtp --activate - -# Or test with simple command: -wp eval "wp_mail('your@email.com', 'Test', 'Testing SureForms');" -``` - -**2. Check SureForms email settings:** -```bash -# View form meta -wp post meta list | grep email -``` - -**3. Check spam folder** -- WordPress default `from` address: `wordpress@yourdomain.com` -- Often flagged as spam - -**Fixes:** - -**Configure SMTP:** - -Install WP Mail SMTP plugin: -```bash -wp plugin install wp-mail-smtp --activate -``` - -Configure with: -- Gmail -- SendGrid -- Mailgun -- Amazon SES - -**Check email template:** - -In form settings → Email Notification: -- Verify "To" address is correct -- Check "From" address is valid domain -- Test with simple subject/message - -**Server mail() function:** - -Some hosts disable PHP `mail()` function. - -Test: -```bash -php -r "mail('test@example.com', 'Test', 'Test message');" -``` - -If no email received, `mail()` is disabled. Use SMTP. - ---- - -### Form Validation Not Working - -**Symptom:** Form submits even with empty required fields - -**Causes:** - -**1. JavaScript disabled** (frontend validation skipped) -**2. Theme CSS hiding error messages** -**3. Custom JavaScript conflict** - -**Diagnosis:** - -**Check browser console:** -``` -Look for JavaScript errors -Check if srfm-validation.js loaded -``` - -**Test with default theme:** -```bash -wp theme activate twentytwentythree -# Submit form again -``` - -If works with default theme → Theme conflict. - -**Fixes:** - -**Theme conflict:** - -Add to theme's `functions.php`: -```php -add_action('wp_enqueue_scripts', function() { - // Ensure SureForms scripts load - wp_enqueue_script('srfm-frontend'); -}, 20); -``` - -**CSS hiding errors:** - -Check if theme has: -```css -.srfm-error { display: none !important; } -``` - -Remove or override. - ---- - -## Payment Processing Issues - -### Stripe Payments Failing - -**Symptom:** "Payment failed" error after entering card details - -**Diagnosis:** - -**1. Check Stripe API keys:** -```bash -# In WordPress admin: SureForms → Settings → Payments → Stripe -# Verify: -# - Using correct keys (test vs live) -# - Keys match Stripe dashboard -``` - -**2. Check Stripe webhook:** -```bash -# In Stripe Dashboard → Developers → Webhooks -# Verify webhook URL is: -https://yoursite.com/wp-json/sureforms/webhook_test - -# Check recent webhook deliveries for errors -``` - -**3. Check browser console:** -``` -DevTools → Console -Look for Stripe.js errors -``` - -**Common Errors:** - -**"Invalid API Key"** -- Using test key in live mode (or vice versa) -- API key revoked in Stripe dashboard -- Fix: Copy fresh keys from Stripe - -**"Payment Intent creation failed"** -- Amount is $0 or negative -- Currency mismatch -- Fix: Check form configuration, amount field - -**"Webhook signature verification failed"** -- Webhook secret incorrect -- Middleware issue -- Fix: Copy webhook signing secret from Stripe, update settings - -**Fixes:** - -**Test mode checklist:** -```bash -# 1. Use test API keys (starts with pk_test_ / sk_test_) -# 2. Test card: 4242 4242 4242 4242 -# 3. Any future expiry date -# 4. Any 3-digit CVC -``` - -**Live mode checklist:** -```bash -# 1. Use live API keys (starts with pk_live_ / sk_live_) -# 2. SSL certificate valid (https://) -# 3. Webhook verified in Stripe dashboard -# 4. Test with real card (refund immediately) -``` - ---- - -### PayPal Payments Failing (Pro) - -**Symptom:** Redirected to PayPal but payment doesn't process - -**Diagnosis:** - -**Check PayPal credentials:** -```bash -# SureForms → Settings → Payments → PayPal -# Verify: -# - Client ID matches PayPal dashboard -# - Secret matches -# - Using sandbox for testing, live for production -``` - -**Check webhook endpoint:** -```bash -# PayPal Dashboard → Apps & Credentials → Webhooks -# Webhook URL should be: -https://yoursite.com/wp-json/sureforms-pro/paypal-live-webhook -``` - -**Fixes:** - -**Test in sandbox mode first:** -1. Create PayPal sandbox account: https://developer.paypal.com/ -2. Use sandbox credentials in SureForms -3. Test with sandbox buyer account - -**Common issues:** -- **Wrong environment:** Using sandbox credentials in live mode -- **Webhook not subscribed:** Must subscribe to payment events in PayPal dashboard -- **SSL certificate:** PayPal requires valid HTTPS - ---- - -## Integration Issues (Pro) - -### Native Integration Not Connecting - -**Symptom:** "Connection failed" when adding integration (Mailchimp, HubSpot, etc.) - -**Diagnosis:** - -**1. Check OAuth redirect URL:** - -For OAuth integrations (Mailchimp, HubSpot, Salesforce): -``` -Redirect URL must be: -https://yoursite.com/wp-json/sureforms-pro/v1/oauth/callback -``` - -**2. Test API credentials:** - -For API key integrations (Brevo, etc.): -```bash -# Test API key directly -curl -X GET "https://api.brevo.com/v3/account" \ - -H "api-key: YOUR_API_KEY" -``` - -Should return account info, not error. - -**3. Check error logs:** -```bash -tail -f wp-content/debug.log | grep -i "integration\|oauth" -``` - -**Fixes:** - -**OAuth issues:** -- Ensure site uses HTTPS (required for OAuth) -- Whitelist redirect URL in service's developer console -- Check OAuth app has correct permissions/scopes - -**API key issues:** -- Regenerate key in service dashboard -- Copy entire key (no spaces, no quotes) -- Check key has required permissions (read/write) - ---- - -### Webhook Not Firing - -**Symptom:** Form submitted, but data not sent to integrated service - -**Diagnosis:** - -**Check webhook logs:** - -Install Query Monitor plugin: -```bash -wp plugin install query-monitor --activate -``` - -Submit form, check "HTTP API Calls" panel for webhook requests. - -**Manually trigger webhook:** -```bash -# Find integration ID -wp db query "SELECT * FROM wp_sureforms_integrations;" - -# Trigger webhook manually (developer test) -wp eval "do_action('sureforms_after_entry_save', 123, 456, []);" -``` - -**Fixes:** - -**Webhook URL validation:** - -In `inc/pro/integrations/webhooks.php`, ensure URL is valid: -- HTTPS only (no HTTP) -- No localhost (unless testing) -- Responds with 200 OK - -**Timeout issues:** - -Increase timeout in `wp-config.php`: -```php -define('WP_HTTP_BLOCK_EXTERNAL', false); -define('WP_ACCESSIBLE_HOSTS', 'api.mailchimp.com,api.hubspot.com'); -``` - ---- - -## Performance Issues - -### Form Editor Slow to Load - -**Symptom:** Takes 10+ seconds to load form in editor - -**Diagnosis:** - -**1. Check database size:** -```bash -wp db query "SELECT COUNT(*) FROM wp_sureforms_entries;" -# If > 100,000 entries, database may be slow -``` - -**2. Check server resources:** -```bash -# Memory usage -free -h - -# CPU usage -top - -# Disk I/O -iostat -``` - -**3. Profile with Query Monitor:** -```bash -wp plugin install query-monitor --activate -# Open form editor, check QM panel for slow queries -``` - -**Fixes:** - -**Optimize database:** -```bash -# Clean old entries (backup first!) -wp db query "DELETE FROM wp_sureforms_entries WHERE created_at < DATE_SUB(NOW(), INTERVAL 1 YEAR);" - -# Optimize tables -wp db optimize -``` - -**Increase PHP limits:** - -In `php.ini` or `.htaccess`: -``` -max_execution_time = 300 -memory_limit = 256M -``` - -**Enable object caching:** - -Install Redis or Memcached: -```bash -wp plugin install redis-cache --activate -wp redis enable -``` - ---- - -### Frontend Form Loads Slowly - -**Symptom:** Form takes 5+ seconds to appear on page - -**Diagnosis:** - -**Check asset loading:** -``` -DevTools → Network → Slow 3G simulation -Watch which assets are slow -``` - -**Common bottlenecks:** -- Google Fonts loading slowly -- Large CSS/JS files -- Unoptimized images in form - -**Fixes:** - -**Lazy load non-critical assets:** - -In `functions.php`: -```php -add_filter('script_loader_tag', function($tag, $handle) { - if ($handle === 'srfm-frontend') { - return str_replace(' src', ' defer src', $tag); - } - return $tag; -}, 10, 2); -``` - -**Use CDN for Google Fonts:** - -In form settings → Design → Typography: -- Limit to 1-2 font families -- Use system fonts for faster load (e.g., -apple-system) - -**Minify and combine assets:** -```bash -npm run build # Ensures assets are minified -``` - -**Enable caching:** - -Install caching plugin: -```bash -wp plugin install wp-super-cache --activate -``` - -Configure to cache pages with forms. - ---- - -## Block Compatibility Issues - -### Form Breaks After Theme Update - -**Symptom:** Form displays incorrectly or not at all after theme update - -**Diagnosis:** - -**Compare theme CSS:** - -Check if new theme has conflicting styles: -```css -/* Common conflicts */ -.srfm-form input { /* Theme override */ } -.srfm-field { /* Theme override */ } -``` - -**Test with default theme:** -```bash -wp theme activate twentytwentythree -``` - -If works → Theme issue. - -**Fixes:** - -**Add theme compatibility CSS:** - -In child theme `style.css`: -```css -/* Reset SureForms blocks */ -.srfm-form, -.srfm-field, -.srfm-form input, -.srfm-form textarea { - all: revert; -} - -/* Then apply minimal SureForms styles */ -``` - -**Use !important (last resort):** - -In SureForms settings → Custom CSS: -```css -.srfm-form input { - border: 1px solid #ccc !important; - padding: 10px !important; -} -``` - ---- - -### Conflicts with Page Builders - -**Symptom:** Forms don't work inside Elementor/Divi/Beaver Builder - -**Common Issues:** - -**1. JavaScript conflicts:** -- Page builder loads own jQuery version -- Conflicts with SureForms scripts - -**Fix:** -```php -// In functions.php -add_action('wp_enqueue_scripts', function() { - if (class_exists('Elementor\Plugin')) { - wp_dequeue_script('jquery'); - wp_enqueue_script('jquery'); - } -}, 100); -``` - -**2. CSS specificity:** -- Page builder CSS overrides SureForms - -**Fix:** - -Use SureForms settings → Custom CSS with higher specificity: -```css -.elementor-widget-container .srfm-form input { - /* Your styles */ -} -``` - ---- - -## Database & Query Issues - -### "Too many connections" Error - -**Symptom:** Site crashes during high form submission volume - -**Diagnosis:** -```bash -wp db query "SHOW STATUS LIKE 'max_used_connections';" -wp db query "SHOW VARIABLES LIKE 'max_connections';" -``` - -**Fixes:** - -**Increase max connections (MySQL):** - -In `my.cnf`: -``` -[mysqld] -max_connections = 500 -``` - -**Use persistent connections:** - -In `wp-config.php`: -```php -define('DB_CHARSET', 'utf8mb4'); -define('DB_COLLATE', ''); -define('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_PERSISTENT); -``` - -**Add connection pooling:** - -Use ProxySQL or PgBouncer for connection pooling. - ---- - -### Slow Query: "SELECT * FROM wp_sureforms_entries" - -**Symptom:** Admin page very slow when viewing entries - -**Diagnosis:** -```bash -wp plugin install query-monitor --activate -# View entries page, check QM for slow queries -``` - -**Fixes:** - -**Add database indexes:** -```sql -ALTER TABLE wp_sureforms_entries -ADD INDEX idx_form_id (form_id), -ADD INDEX idx_created_at (created_at), -ADD INDEX idx_status (status); -``` - -**Limit entries displayed:** - -In admin, reduce entries per page from 100 to 20. - -**Paginate large result sets:** - -Ensure code uses `LIMIT` and `OFFSET`: -```php -$entries = Entries::get_all([ - 'limit' => 20, - 'offset' => ($page - 1) * 20 -]); -``` - ---- - -## WordPress.org Review Issues - -### Plugin Rejected for Security - -**Common reasons:** - -**1. Direct database calls without prepare():** -```php -// ❌ Bad -$wpdb->query("DELETE FROM table WHERE id = $id"); - -// ✅ Good -$wpdb->query($wpdb->prepare("DELETE FROM table WHERE id = %d", $id)); -``` - -**2. Unsanitized user input:** -```php -// ❌ Bad -echo $_POST['name']; - -// ✅ Good -echo esc_html(sanitize_text_field($_POST['name'] ?? '')); -``` - -**3. Missing nonce verification:** -```php -// ❌ Bad -if (isset($_POST['action'])) { do_action(); } - -// ✅ Good -if (isset($_POST['action']) && check_ajax_referer('my_action_nonce')) { - do_action(); -} -``` - -**Fix:** - -Run WordPress Coding Standards checker: -```bash -composer require --dev wp-coding-standards/wpcs -vendor/bin/phpcs --standard=WordPress inc/ -``` - -Fix all errors before resubmitting. - ---- - -## Getting Help - -### Before Asking for Help - -**Gather this information:** - -```bash -# 1. WordPress & PHP versions -wp core version -php -v - -# 2. Plugin version -wp plugin list | grep sureforms - -# 3. Active theme -wp theme list --status=active - -# 4. Other active plugins -wp plugin list --status=active - -# 5. Recent errors -tail -50 wp-content/debug.log - -# 6. Browser/OS (if frontend issue) -# Example: Chrome 120 on macOS 14 -``` - -### Where to Get Help - -**1. Documentation** (check first) -- This troubleshooting guide -- [FAQ](faq.md) -- [Architecture](architecture.md) - -**2. GitHub Issues** (bugs & feature requests) -- Search existing issues first -- Provide minimal reproduction steps -- Include system info from above - -**3. Support Portal** (Pro users) -- https://support.brainstormforce.com/ -- < 24hr response time for Pro users - -**4. Community** -- Facebook group: https://www.facebook.com/groups/surecart -- WordPress.org forum (Free only) - ---- - -## Still Stuck? - -If none of the above solutions work: - -**Create detailed bug report:** - -```markdown -**Environment:** -- WordPress: 6.4.2 -- PHP: 8.1 -- SureForms: 2.5.0 (Free/Pro) -- Theme: Astra 4.5.0 -- Browser: Chrome 120 - -**Steps to Reproduce:** -1. Create form with email field -2. Mark field as required -3. Submit form with empty email -4. [Describe unexpected behavior] - -**Expected:** Validation error shows -**Actual:** Form submits anyway - -**Debug Log:** -[Paste relevant errors from debug.log] - -**Screenshots:** -[Attach if visual issue] -``` - -Submit to: https://github.com/brainstormforce/sureforms/issues - ---- - -**Next:** [FAQ](faq.md) diff --git a/internal-docs/ui-and-copy.md b/internal-docs/ui-and-copy.md deleted file mode 100644 index e12a9a45a..000000000 --- a/internal-docs/ui-and-copy.md +++ /dev/null @@ -1,1077 +0,0 @@ -# UI & Copy Guidelines - -**Version:** 2.5.0 - ---- - -## User Experience Philosophy - -**Principle:** Every word and interaction should make the user feel capable, not confused. - -**User Mindset:** -- "I just want to create a form quickly" -- "I don't have time to read documentation" -- "I'm not a developer" - -**Our Responsibility:** -- Make obvious what to do next -- Explain why, not just how -- Never blame the user - ---- - -## User Journeys - -### Journey 1: First-Time User Creates Contact Form - -**Goal:** Create and publish first form in < 5 minutes - -**Steps:** - -**1. Plugin Activation (30 seconds)** - -``` -User activates plugin - ↓ -Redirect to welcome screen - ↓ -Show 2 options: - [Create with AI] [Start from Blank] -``` - -**Copy:** -``` -Welcome to SureForms! - -Let's create your first form. - -[Create with AI] ← Recommended for beginners - Let AI build your form from a simple description - -[Start from Blank] - Build your form block-by-block -``` - -**Design notes:** -- Large, friendly buttons -- "Recommended" badge on AI option -- No walls of text - ---- - -**2. AI Form Creation (2 minutes)** - -``` -User clicks "Create with AI" - ↓ -Modal appears with text input - ↓ -User types: "simple contact form" - ↓ -AI generates form (3-5 seconds) - ↓ -Form opens in editor, ready to publish -``` - -**Copy:** - -``` -Create Form with AI - -Describe the form you need: -┌─────────────────────────────────────┐ -│ Example: "job application with │ -│ file upload" or "event RSVP" │ -└─────────────────────────────────────┘ - -[Cancel] [Generate Form →] -``` - -**Loading state:** -``` -✨ Creating your form... - -AI is adding fields based on your description. -This usually takes 3-5 seconds. -``` - -**Success state:** -``` -✅ Your form is ready! - -We added: -• Name field -• Email field -• Message field -• Submit button - -You can add, remove, or rearrange fields below. - -[Publish Form] -``` - -**Design notes:** -- Loading spinner + encouraging message -- Success message lists what was created -- Clear next action (Publish) - ---- - -**3. Form Publishing (1 minute)** - -``` -User clicks "Publish" - ↓ -Gutenberg publish panel opens - ↓ -SureForms shows additional options -``` - -**Copy in publish panel:** - -``` -📋 Form Settings - -Where should submissions be sent? - -Email: [admin@yoursite.com ▼] - -After submission, show: -○ Confirmation message -○ Redirect to page -● Confirmation message (selected by default) - -Message: -┌─────────────────────────────────────┐ -│ Thank you! We'll respond within │ -│ 24 hours. │ -└─────────────────────────────────────┘ - -[Publish Form] -``` - -**Design notes:** -- Sensible defaults (confirmation message, admin email) -- Inline editing (no separate settings page) -- Jargon-free labels - ---- - -**4. Embedding Form (30 seconds)** - -``` -User wants to add form to page - ↓ -Edit page in Gutenberg - ↓ -Add SureForms block - ↓ -Select form from dropdown -``` - -**Copy in block inserter:** - -``` -SureForms - -Display a form on your page. - -📝 No form yet? Create one in SureForms > Add New -``` - -**Copy in block settings:** - -``` -Form - -Select a form: -[Contact Form ▼] [Create New] - -Display settings: -☑ Show form title -☑ Show form description -☐ Hide labels (show placeholders only) -``` - -**Design notes:** -- Help text guides to form creation if needed -- Checkbox labels explain what they do -- Preview updates in real-time - ---- - -### Journey 2: Pro User Sets Up Payment Form - -**Goal:** Create payment form and collect first payment - -**Complexity:** Higher (involves Stripe setup) - -**Steps:** - -**1. Payment Gateway Setup (5 minutes)** - -``` -User navigates to: -SureForms → Settings → Payments → Stripe -``` - -**Copy:** - -``` -Stripe Payments - -Accept credit card payments with Stripe. - -🔒 Secure: We never store card details. Payments are processed directly by Stripe. - -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - -Test Mode (for testing) - -☑ Enable test mode - -Use these while testing: - Test card: 4242 4242 4242 4242 - Any future expiry, any CVC - -Publishable Key (starts with pk_test_) -┌─────────────────────────────────────┐ -│ │ -└─────────────────────────────────────┘ - -Secret Key (starts with sk_test_) -┌─────────────────────────────────────┐ -│ •••••••••••••••••••••••••••••••• │ -└─────────────────────────────────────┘ - -Where to get keys: -→ Stripe Dashboard > Developers > API Keys - https://dashboard.stripe.com/apikeys - -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - -Live Mode (for real payments) - -⚠️ Only use after testing - -Publishable Key (starts with pk_live_) -┌─────────────────────────────────────┐ -│ │ -└─────────────────────────────────────┘ - -Secret Key (starts with sk_live_) -┌─────────────────────────────────────┐ -│ │ -└─────────────────────────────────────┘ - -[Save Settings] -``` - -**Design notes:** -- Test mode emphasized first -- Clear instructions where to get keys -- Security reassurance ("We never store") -- Direct link to Stripe dashboard - ---- - -**2. Creating Payment Form (3 minutes)** - -``` -User creates new form - ↓ -Adds "Payment" block - ↓ -Configures amount and currency -``` - -**Copy in Payment block settings:** - -``` -Payment Details - -Amount -○ Fixed amount - ┌──────┐ - │ 50 │ USD ▼ - └──────┘ - -● Let user choose amount - Min: [10] Max: [1000] USD ▼ - Default: [50] - -Payment Type -● One-time payment -○ Subscription - Interval: [Monthly ▼] - -Button Text -┌─────────────────────────────────────┐ -│ Pay Now │ -└─────────────────────────────────────┘ -``` - -**Design notes:** -- Radio buttons for mutually exclusive options -- Currency dropdown next to amount -- Clear labels (no "recurring" jargon, use "subscription") - ---- - -**3. Testing Payment (2 minutes)** - -**Copy on frontend form:** - -``` -Payment Information - -Amount: $50.00 - -Card Number -┌─────────────────────────────────────┐ -│ 1234 5678 9012 3456 │ [Card icon] -└─────────────────────────────────────┘ - -Expiry CVC -┌──────────┐ ┌─────┐ -│ MM / YY │ │ 123 │ -└──────────┘ └─────┘ - -🔒 Secure payment powered by Stripe - Your card details are encrypted and never stored. - -[Pay $50.00] -``` - -**Success message after payment:** - -``` -✅ Payment Successful! - -Receipt sent to: john@example.com - -Transaction ID: ch_1A2B3C4D5E6F - -[View Receipt] [Back to Home] -``` - -**Error message if payment fails:** - -``` -❌ Payment Failed - -Your card was declined. - -Common reasons: -• Insufficient funds -• Incorrect card number or expiry date -• Card requires 3D Secure verification - -Please try again or use a different card. - -[Try Again] -``` - -**Design notes:** -- Security reassurance prominent -- Success message includes receipt email and transaction ID -- Error message explains why and how to fix - ---- - -### Journey 3: Power User Builds Conditional Logic Form (Pro) - -**Goal:** Show/hide fields based on user selection - -**Example:** Event RSVP with dietary restrictions (only show if attending) - -**Steps:** - -**1. Creating Base Form (2 minutes)** - -``` -User adds fields: - - "Will you attend?" (Multiple Choice: Yes/No) - - "Dietary restrictions" (Dropdown) -``` - -**2. Adding Conditional Logic (3 minutes)** - -``` -User clicks "Dietary restrictions" block - ↓ -Opens block settings panel - ↓ -Enables conditional logic -``` - -**Copy in block settings:** - -``` -Conditional Logic - -Show this field only when certain conditions are met. - -☑ Enable conditional logic - -Show this field when: - -[Will you attend? ▼] [is ▼] [Yes ▼] - -[+ Add Condition] - -Logic: -● Show if ALL conditions match (AND) -○ Show if ANY condition matches (OR) -``` - -**Design notes:** -- Toggle to enable -- Dropdown-based condition builder (no code) -- Visual feedback: field grays out in editor preview when hidden - ---- - -**3. Testing Logic (1 minute)** - -**Copy in editor preview mode:** - -``` -💡 Preview Mode - -This is how your form will appear to users. - -Try selecting different options to see conditional logic in action. - -[Exit Preview] -``` - -**Behavior:** -- User selects "Yes" → Dietary field appears -- User selects "No" → Dietary field disappears - -**Design notes:** -- Clear indication of preview mode -- Real-time updates (no reload) - ---- - -## Microcopy Guidelines - -### Field Labels - -**Be concise and conversational** - -❌ Bad: "Please enter your electronic mail address" -✅ Good: "Email" - -❌ Bad: "Input telephone number (optional)" -✅ Good: "Phone (optional)" - -**Use sentence case, not title case** - -❌ Bad: "First Name" -✅ Good: "First name" - -❌ Bad: "Company Name (If Applicable)" -✅ Good: "Company name (if applicable)" - ---- - -### Help Text - -**Explain why or provide examples** - -**Email field:** -❌ Bad: "Enter email" -✅ Good: "We'll send a confirmation to this email" - -**Phone field:** -❌ Bad: "Phone number" -✅ Good: "We'll only call if there's an issue with your order" - -**File upload:** -❌ Bad: "Upload file" -✅ Good: "Upload your resume (PDF or DOCX, max 10MB)" - ---- - -### Error Messages - -**Be specific and actionable** - -**Email validation:** -❌ Bad: "Invalid email" -✅ Good: "Please enter a valid email (e.g., name@example.com)" - -**Required field:** -❌ Bad: "This field is required" -✅ Good: "Please enter your name" - -**File size:** -❌ Bad: "File too large" -✅ Good: "File must be under 10MB. Yours is 15MB. Try compressing it." - -**Payment failed:** -❌ Bad: "Transaction error" -✅ Good: "Your card was declined. Please check your card details or try a different card." - ---- - -### Success Messages - -**Be enthusiastic but not over-the-top** - -**Form submission:** -❌ Bad: "Form submitted" -✅ Good: "Thanks! We'll get back to you within 24 hours." - -**Payment successful:** -❌ Bad: "Payment processed successfully. Transaction ID: 1234." -✅ Good: "✅ Payment received! Receipt sent to your email." - -**Registration:** -❌ Bad: "Account created. Please log in." -✅ Good: "Welcome! Check your email to verify your account." - ---- - -### Button Labels - -**Use verbs that describe the action** - -❌ Bad: "Submit" -✅ Good: "Send Message" - -❌ Bad: "Click Here" -✅ Good: "Download Receipt" - -❌ Bad: "Proceed" -✅ Good: "Continue to Payment" - -**For payment buttons, include amount** - -❌ Bad: "Pay" -✅ Good: "Pay $50.00" - -❌ Bad: "Subscribe" -✅ Good: "Subscribe for $9.99/month" - ---- - -### Settings & Options - -**Explain consequences, not just features** - -**Email notification:** -❌ Bad: "Send email notification" -✅ Good: "Email me when someone submits this form" - -**Required field:** -❌ Bad: "Required" -✅ Good: "Make this field required" (checkbox label) - -**Conditional logic:** -❌ Bad: "Enable conditional logic" -✅ Good: "Show or hide this field based on other answers" - ---- - -## Visual Design Patterns - -### Empty States - -**When user has no forms yet:** - -``` -┌─────────────────────────────────────────┐ -│ │ -│ 📝 │ -│ │ -│ No forms yet │ -│ │ -│ Forms help you collect information │ -│ from your website visitors. │ -│ │ -│ [Create Your First Form] │ -│ │ -└─────────────────────────────────────────┘ -``` - -**Copy principles:** -- Icon relevant to context -- 1-sentence explanation -- Clear call-to-action button - ---- - -**When form has no submissions:** - -``` -┌─────────────────────────────────────────┐ -│ │ -│ 📭 │ -│ │ -│ No submissions yet │ -│ │ -│ Share this form to start collecting │ -│ responses. │ -│ │ -│ [Copy Form Link] [Embed on Page] │ -│ │ -└─────────────────────────────────────────┘ -``` - -**Design notes:** -- Actionable next steps -- Multiple options (link vs embed) - ---- - -### Loading States - -**Form submission in progress:** - -``` -┌─────────────────────────────────────┐ -│ ⏳ Sending... │ -│ │ -│ Please don't close this page. │ -└─────────────────────────────────────┘ -``` - -**AI form generation:** - -``` -┌─────────────────────────────────────┐ -│ ✨ Creating your form... │ -│ │ -│ [████████░░] 80% │ -│ │ -│ Adding email validation... │ -└─────────────────────────────────────┘ -``` - -**Design notes:** -- Spinner or progress indicator -- Explain what's happening -- Show progress if possible - ---- - -### Confirmation Dialogs - -**Deleting a form:** - -``` -┌─────────────────────────────────────┐ -│ Delete "Contact Form"? │ -│ │ -│ This will permanently delete: │ -│ • The form │ -│ • 47 submissions │ -│ • All settings │ -│ │ -│ This cannot be undone. │ -│ │ -│ [Cancel] [Delete Form] │ -└─────────────────────────────────────┘ -``` - -**Design notes:** -- Specific about what will be deleted -- Use red/destructive style for delete button -- Cancel button should be default (easier to accidentally click) - ---- - -### Tooltips & Hints - -**When to use:** -- Explaining technical terms -- Providing examples -- Showing keyboard shortcuts - -**Format:** - -``` -Field Name [?] - ↓ (on hover) -┌─────────────────────────────────────┐ -│ This is the internal name used in │ -│ the database. │ -│ │ -│ Example: "first_name" │ -└─────────────────────────────────────┘ -``` - -**Guidelines:** -- Keep under 2 sentences -- Provide example if helpful -- Don't repeat the label - ---- - -## Accessibility - -### Screen Reader Text - -**Form structure:** - -```html -
-
-

Personal Information

- -
-
-``` - -**Error announcements:** - -```html -
- Please fix 2 errors before submitting. -
- - - - Please enter a valid email address - -``` - ---- - -### Keyboard Navigation - -**Required interactions:** -- Tab through all fields -- Space to toggle checkboxes/radio buttons -- Enter to submit form -- Escape to close modals - -**Visual focus indicators:** - -```css -.srfm-field input:focus { - outline: 2px solid #0073aa; - outline-offset: 2px; -} -``` - -**Never:** -```css -:focus { - outline: none; /* ❌ Never remove focus outline */ -} -``` - ---- - -### Color Contrast - -**WCAG 2.1 Level AA Requirements:** -- Normal text: 4.5:1 minimum -- Large text (18pt+): 3:1 minimum -- UI components: 3:1 minimum - -**Test tools:** -- WebAIM Contrast Checker -- Chrome DevTools (Lighthouse) - -**Safe color combinations:** -- White text on dark backgrounds (#333 or darker) -- Dark text on light backgrounds (#F0F0F0 or lighter) -- Avoid gray text on gray backgrounds - ---- - -## Tone & Voice - -### Voice Characteristics - -**Friendly but professional** -- Use "we" and "you" -- Conversational, not formal -- Helpful, not condescending - -**Example:** -❌ Formal: "The system has detected an error in your input." -✅ Friendly: "Oops! We couldn't save that. Check for any errors above." - ---- - -**Clear over clever** -- Avoid puns and wordplay -- Be direct -- Technical accuracy over marketing fluff - -**Example:** -❌ Clever: "Houston, we have a problem!" -✅ Clear: "Something went wrong. Please try again." - ---- - -**Empowering, not blaming** -- Focus on solutions, not problems -- Use "we" for errors, "you" for successes - -**Example:** -❌ Blaming: "You entered an invalid email." -✅ Empowering: "Hmm, that email doesn't look quite right. Mind double-checking it?" - ---- - -### Writing for Different Contexts - -**First-time users:** -- More explanation -- Examples provided -- Encouraging tone - -**Example:** -``` -Welcome to SureForms! - -Creating your first form is easy. We'll walk you through each step. - -Let's start by choosing what kind of form you need. -``` - ---- - -**Power users:** -- Less explanation -- Assume knowledge -- Efficiency-focused - -**Example:** -``` -Advanced Settings - -Show field if: [condition builder] -Custom CSS class: [input] -``` - ---- - -**Error states:** -- Apologetic but not dramatic -- Specific about what went wrong -- Clear next steps - -**Example:** -``` -We couldn't save your changes. - -The connection to the server timed out. - -Please try again. If this keeps happening, check your internet connection. - -[Try Again] -``` - ---- - -**Success states:** -- Positive reinforcement -- What happens next -- Optional next action - -**Example:** -``` -✅ Form published! - -Your form is now live at: -https://yoursite.com/contact - -[View Form] [Create Another] -``` - ---- - -## Form Field Best Practices - -### Required vs Optional - -**Default:** Make fields optional - -**Require only when absolutely necessary:** -- Name (if sending personalized response) -- Email (if you need to contact them) -- Payment details (if collecting payment) - -**Label optional fields:** -``` -Phone (optional) -Company name (optional) -``` - -**Don't label required fields:** -❌ Bad: "Email (required)" -✅ Good: "Email" (with * indicator) - ---- - -### Field Order - -**Logical flow:** -1. Personal info (Name, Email) -2. Specific questions -3. Payment details (if applicable) -4. Submit button - -**Example contact form:** -``` -1. Name -2. Email -3. Subject -4. Message -5. [Submit] -``` - -**Example order form:** -``` -1. Name -2. Email -3. Product selection -4. Quantity -5. Payment details -6. [Complete Purchase] -``` - ---- - -### Placeholder Text - -**Use sparingly** - -Only for examples, not as labels: - -❌ Bad: -``` -Label: [empty] -Placeholder: "Enter your email" -``` - -✅ Good: -``` -Label: Email -Placeholder: "name@example.com" -``` - -**Never use placeholders as only label** (accessibility issue) - ---- - -### Multi-Step Forms (Pro) - -**Step indicators:** - -``` -Step 1 of 3: Your Information -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -●━━━━━━━━━━━━○━━━━━━━━━━━━━○ - -[Fields here] - -[Continue to Step 2 →] -``` - -**Navigation:** -- Show progress (Step 1 of 3) -- Visual progress bar -- Allow back navigation (not just forward) - -**Button labels:** -- Step 1: "Continue" (not "Next") -- Step 2: "Continue" -- Step 3: "Submit Form" (or "Complete Order") - ---- - -## Internationalization (i18n) - -### Text Translation - -**All user-facing strings must be translatable:** - -```php -// ✅ Good -__('Email', 'sureforms'); -_e('Submit Form', 'sureforms'); - -// ❌ Bad -echo 'Email'; // Hardcoded English -``` - -**Placeholders for dynamic content:** - -```php -// ✅ Good -sprintf(__('You have %d new submissions', 'sureforms'), $count); - -// ❌ Bad -echo "You have $count new submissions"; -``` - ---- - -### Date & Number Formatting - -**Use WordPress functions:** - -```php -// Dates -echo date_i18n(get_option('date_format'), $timestamp); - -// Numbers -echo number_format_i18n($number); - -// Currency -echo '$' . number_format_i18n($amount, 2); -``` - ---- - -### RTL Support - -**CSS for right-to-left languages:** - -```css -/* Use logical properties */ -.srfm-field { - margin-inline-start: 10px; /* Not margin-left */ - padding-inline-end: 20px; /* Not padding-right */ -} -``` - -**Test with RTL languages:** -- Arabic -- Hebrew -- Persian - ---- - -## Quality Checklist - -Before shipping UI copy: - -- [ ] Spell check passed -- [ ] Grammar correct -- [ ] Tone matches guidelines -- [ ] Actionable error messages -- [ ] Examples provided where helpful -- [ ] Accessibility: screen reader friendly -- [ ] Accessibility: color contrast ≥ 4.5:1 -- [ ] Keyboard navigation works -- [ ] i18n: All strings translatable -- [ ] RTL languages supported -- [ ] Tested with real users (if major UI) - ---- - -**Next:** [FAQ](faq.md)