register_steps_section();
$this->register_fields_section();
$this->register_settings_section();
$this->register_integrations_section();
$this->register_style_form_section();
$this->register_style_fields_section();
$this->register_style_steps_section();
$this->register_style_button_section();
$this->register_style_messages_section();
}
// =========================================================================
// Content Controls
// =========================================================================
private function register_steps_section(): void {
$this->start_controls_section( 'section_steps', [
'label' => __( 'Steps', 'admore-widgets-suite' ),
'tab' => Controls_Manager::TAB_CONTENT,
] );
$this->add_control( 'enable_multistep', [
'label' => __( 'Multi-Step Form', 'admore-widgets-suite' ),
'type' => Controls_Manager::SWITCHER,
'return_value' => 'yes',
] );
$steps = new Repeater();
$steps->add_control( 'step_title', [
'label' => __( 'Step Title', 'admore-widgets-suite' ),
'type' => Controls_Manager::TEXT,
'default' => __( 'Step', 'admore-widgets-suite' ),
] );
$this->add_control( 'steps', [
'type' => Controls_Manager::REPEATER,
'fields' => $steps->get_controls(),
'default' => [
[ 'step_title' => __( 'Contact Info', 'admore-widgets-suite' ) ],
[ 'step_title' => __( 'Details', 'admore-widgets-suite' ) ],
],
'title_field' => '{{{ step_title }}}',
'condition' => [ 'enable_multistep' => 'yes' ],
] );
$this->end_controls_section();
}
private function register_fields_section(): void {
$this->start_controls_section( 'section_fields', [
'label' => __( 'Fields', 'admore-widgets-suite' ),
'tab' => Controls_Manager::TAB_CONTENT,
] );
$r = new Repeater();
$r->add_control( 'field_id', [
'label' => __( 'Field ID', 'admore-widgets-suite' ),
'type' => Controls_Manager::TEXT,
'default' => 'field_1',
'description' => __( 'Unique ID for conditional logic.', 'admore-widgets-suite' ),
] );
$r->add_control( 'field_type', [
'label' => __( 'Type', 'admore-widgets-suite' ),
'type' => Controls_Manager::SELECT,
'default' => 'text',
'options' => [
'text' => __( 'Text', 'admore-widgets-suite' ),
'email' => __( 'Email', 'admore-widgets-suite' ),
'tel' => __( 'Phone', 'admore-widgets-suite' ),
'url' => __( 'URL', 'admore-widgets-suite' ),
'number' => __( 'Number', 'admore-widgets-suite' ),
'date' => __( 'Date', 'admore-widgets-suite' ),
'time' => __( 'Time', 'admore-widgets-suite' ),
'textarea' => __( 'Textarea', 'admore-widgets-suite' ),
'select' => __( 'Select', 'admore-widgets-suite' ),
'radio' => __( 'Radio', 'admore-widgets-suite' ),
'checkbox' => __( 'Checkbox', 'admore-widgets-suite' ),
'acceptance' => __( 'Acceptance (Terms / Privacy)', 'admore-widgets-suite' ),
'file' => __( 'File Upload', 'admore-widgets-suite' ),
'hidden' => __( 'Hidden', 'admore-widgets-suite' ),
'html' => __( 'HTML / Text', 'admore-widgets-suite' ),
],
] );
$r->add_control( 'field_label', [
'label' => __( 'Label', 'admore-widgets-suite' ),
'type' => Controls_Manager::TEXT,
'default' => __( 'Field Label', 'admore-widgets-suite' ),
'dynamic' => [ 'active' => true ],
] );
$r->add_control( 'placeholder', [
'label' => __( 'Placeholder', 'admore-widgets-suite' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [ 'active' => true ],
'description' => __( 'For a Select, this is the text of the empty first option.', 'admore-widgets-suite' ),
'condition' => [ 'field_type' => [ 'text', 'email', 'tel', 'url', 'number', 'textarea', 'select' ] ],
] );
$r->add_control( 'field_default', [
'label' => __( 'Default Value', 'admore-widgets-suite' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [ 'active' => true ],
'description' => __( 'Pre-filled value. For a Select or Radio, enter one of the options.', 'admore-widgets-suite' ),
'conditions' => [
'relation' => 'or',
'terms' => [
[ 'name' => 'field_type', 'operator' => 'in', 'value' => [ 'text', 'email', 'tel', 'url', 'number', 'date', 'time', 'textarea', 'select', 'radio' ] ],
[
'relation' => 'and',
'terms' => [
[ 'name' => 'field_type', 'operator' => '===', 'value' => 'hidden' ],
[ 'name' => 'hidden_source', 'operator' => '===', 'value' => 'static' ],
],
],
],
],
] );
// ── Hidden field ──
$r->add_control( 'hidden_source', [
'label' => __( 'Value From', 'admore-widgets-suite' ),
'type' => Controls_Manager::SELECT,
'default' => 'static',
'options' => [
'static' => __( 'Fixed value', 'admore-widgets-suite' ),
'url_param' => __( 'URL parameter (e.g. utm_source)', 'admore-widgets-suite' ),
'page_url' => __( 'Page URL', 'admore-widgets-suite' ),
'page_title' => __( 'Page title', 'admore-widgets-suite' ),
'referrer' => __( 'Referrer (previous page)', 'admore-widgets-suite' ),
],
'condition' => [ 'field_type' => 'hidden' ],
] );
$r->add_control( 'hidden_param', [
'label' => __( 'Parameter Name', 'admore-widgets-suite' ),
'type' => Controls_Manager::TEXT,
'placeholder' => 'utm_source',
'condition' => [ 'field_type' => 'hidden', 'hidden_source' => 'url_param' ],
] );
// ── Date range ──
$r->add_control( 'date_min', [
'label' => __( 'Earliest Date', 'admore-widgets-suite' ),
'type' => Controls_Manager::DATE_TIME,
'picker_options' => [ 'enableTime' => false ],
'condition' => [ 'field_type' => 'date' ],
] );
$r->add_control( 'date_max', [
'label' => __( 'Latest Date', 'admore-widgets-suite' ),
'type' => Controls_Manager::DATE_TIME,
'picker_options' => [ 'enableTime' => false ],
'condition' => [ 'field_type' => 'date' ],
] );
// ── Acceptance ──
$r->add_control( 'acceptance_text', [
'label' => __( 'Checkbox Text', 'admore-widgets-suite' ),
'type' => Controls_Manager::TEXTAREA,
'default' => __( 'I agree to the Privacy Policy.', 'admore-widgets-suite' ),
'description' => __( 'Links are allowed, e.g. <a href="/privacy-policy">Privacy Policy</a>.', 'admore-widgets-suite' ),
'condition' => [ 'field_type' => 'acceptance' ],
] );
// ── HTML / Text block ──
$r->add_control( 'html_content', [
'label' => __( 'Content', 'admore-widgets-suite' ),
'type' => Controls_Manager::WYSIWYG,
'default' => '
' . __( 'Section title', 'admore-widgets-suite' ) . '
',
'condition' => [ 'field_type' => 'html' ],
] );
$r->add_control( 'field_required', [
'label' => __( 'Required', 'admore-widgets-suite' ),
'type' => Controls_Manager::SWITCHER,
'return_value' => 'yes',
'condition' => [ 'field_type!' => [ 'hidden', 'html' ] ],
] );
$r->add_control( 'field_options', [
'label' => __( 'Options (one per line)', 'admore-widgets-suite' ),
'type' => Controls_Manager::TEXTAREA,
'default' => "Option 1\nOption 2\nOption 3",
'condition' => [ 'field_type' => [ 'select', 'radio', 'checkbox' ] ],
] );
$r->add_control( 'allowed_types', [
'label' => __( 'Allowed Extensions', 'admore-widgets-suite' ),
'type' => Controls_Manager::TEXT,
'default' => 'jpg,jpeg,png,pdf',
'condition' => [ 'field_type' => 'file' ],
] );
$r->add_control( 'step_index', [
'label' => __( 'Step Index (0-based)', 'admore-widgets-suite' ),
'type' => Controls_Manager::NUMBER,
'default' => 0,
'min' => 0,
] );
$r->add_control( 'column_width', [
'label' => __( 'Width', 'admore-widgets-suite' ),
'type' => Controls_Manager::SELECT,
'default' => '100',
'options' => [ '100' => '100%', '50' => '50%', '33' => '33%', '25' => '25%' ],
] );
// Tablet / Mobile width overrides. Left on "Default", the field keeps the
// automatic behaviour (33% / 25% become 50% on tablet, every field is full
// width on mobile). The "(tablet)" / "(mobile)" selector prefixes make
// Elementor wrap the rule in its own breakpoint media query.
$width_options = [
'' => __( 'Default', 'admore-widgets-suite' ),
'100' => '100%',
'75' => '75%',
'66' => '66%',
'50' => '50%',
'33' => '33%',
'25' => '25%',
];
$width_css = 'flex-basis: calc({{VALUE}}% - var(--eppro-form-gap) * (1 - {{VALUE}} / 100)); max-width: calc({{VALUE}}% - var(--eppro-form-gap) * (1 - {{VALUE}} / 100));';
$r->add_control( 'column_width_tablet', [
'label' => __( 'Width (Tablet)', 'admore-widgets-suite' ),
'type' => Controls_Manager::SELECT,
'default' => '',
'options' => $width_options,
'selectors' => [ '(tablet){{WRAPPER}} .eppro-form-grid > {{CURRENT_ITEM}}' => $width_css ],
] );
$r->add_control( 'column_width_mobile', [
'label' => __( 'Width (Mobile)', 'admore-widgets-suite' ),
'type' => Controls_Manager::SELECT,
'default' => '',
'options' => $width_options,
'selectors' => [ '(mobile){{WRAPPER}} .eppro-form-grid > {{CURRENT_ITEM}}' => $width_css ],
] );
$r->add_control( 'field_icon', [
'label' => __( 'Field Icon', 'admore-widgets-suite' ),
'type' => Controls_Manager::ICONS,
'separator' => 'before',
'condition' => [ 'field_type' => [ 'text', 'email', 'tel', 'url', 'number', 'textarea' ] ],
] );
$r->add_control( 'field_icon_position', [
'label' => __( 'Icon Position', 'admore-widgets-suite' ),
'type' => Controls_Manager::SELECT,
'default' => 'prefix',
'options' => [
'prefix' => __( 'Prefix (Left)', 'admore-widgets-suite' ),
'suffix' => __( 'Suffix (Right)', 'admore-widgets-suite' ),
],
'condition' => [ 'field_type' => [ 'text', 'email', 'tel', 'url', 'number', 'textarea' ] ],
] );
// Conditional logic
$r->add_control( 'condition_heading', [
'label' => __( 'Conditional Logic', 'admore-widgets-suite' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
] );
$r->add_control( 'condition_enabled', [
'label' => __( 'Enable', 'admore-widgets-suite' ),
'type' => Controls_Manager::SWITCHER,
'return_value' => 'yes',
] );
$r->add_control( 'condition_field', [
'label' => __( 'Watch Field ID', 'admore-widgets-suite' ),
'type' => Controls_Manager::TEXT,
'condition' => [ 'condition_enabled' => 'yes' ],
] );
$r->add_control( 'condition_operator', [
'label' => __( 'Operator', 'admore-widgets-suite' ),
'type' => Controls_Manager::SELECT,
'default' => 'equals',
'options' => [
'equals' => __( '= Equals', 'admore-widgets-suite' ),
'not_equals' => __( '≠ Not Equals', 'admore-widgets-suite' ),
'contains' => __( '⊃ Contains', 'admore-widgets-suite' ),
'not_contains' => __( '⊅ Not Contains', 'admore-widgets-suite' ),
'starts_with' => __( '↦ Starts With', 'admore-widgets-suite' ),
'ends_with' => __( '↤ Ends With', 'admore-widgets-suite' ),
'is_empty' => __( '○ Is Empty', 'admore-widgets-suite' ),
'not_empty' => __( '● Is Not Empty', 'admore-widgets-suite' ),
],
'condition' => [ 'condition_enabled' => 'yes' ],
] );
$r->add_control( 'condition_value', [
'label' => __( 'Value', 'admore-widgets-suite' ),
'type' => Controls_Manager::TEXT,
'condition' => [
'condition_enabled' => 'yes',
'condition_operator' => [ 'equals', 'not_equals', 'contains', 'not_contains', 'starts_with', 'ends_with' ],
],
] );
$this->add_control( 'form_fields', [
'type' => Controls_Manager::REPEATER,
'fields' => $r->get_controls(),
'default' => [
[ 'field_id' => 'name', 'field_type' => 'text', 'field_label' => __( 'Full Name', 'admore-widgets-suite' ), 'placeholder' => __( 'Enter your full name', 'admore-widgets-suite' ), 'field_required' => 'yes' ],
[ 'field_id' => 'email', 'field_type' => 'email', 'field_label' => __( 'Email Address', 'admore-widgets-suite' ), 'placeholder' => __( 'Enter your email address', 'admore-widgets-suite' ), 'field_required' => 'yes' ],
[ 'field_id' => 'message', 'field_type' => 'textarea', 'field_label' => __( 'Message', 'admore-widgets-suite' ), 'placeholder' => __( 'Write your message here…', 'admore-widgets-suite' ), 'field_required' => 'yes' ],
],
'title_field' => '<# var t=field_label||field_id; #>{{{ t }}} ({{{ field_type }}})',
] );
$this->end_controls_section();
}
private function register_settings_section(): void {
$this->start_controls_section( 'section_settings', [
'label' => __( 'Settings', 'admore-widgets-suite' ),
'tab' => Controls_Manager::TAB_CONTENT,
] );
$this->add_control( 'form_name', [
'label' => __( 'Form Name', 'admore-widgets-suite' ),
'type' => Controls_Manager::TEXT,
'default' => __( 'Contact Form', 'admore-widgets-suite' ),
'description' => __( 'Used to identify submissions in Form Entries.', 'admore-widgets-suite' ),
'separator' => 'after',
] );
$this->add_control( 'submit_text', [ 'label' => __( 'Submit Text', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXT, 'default' => __( 'Send Message', 'admore-widgets-suite' ) ] );
$this->add_control( 'submit_icon', [
'label' => __( 'Submit Button Icon', 'admore-widgets-suite' ),
'type' => Controls_Manager::ICONS,
] );
$this->add_control( 'submit_icon_position', [
'label' => __( 'Icon Position', 'admore-widgets-suite' ),
'type' => Controls_Manager::SELECT,
'default' => 'after',
'options' => [ 'before' => __( 'Before Text', 'admore-widgets-suite' ), 'after' => __( 'After Text', 'admore-widgets-suite' ) ],
'condition' => [ 'submit_icon[value]!' => '' ],
] );
$this->add_control( 'next_text', [ 'label' => __( 'Next Text', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXT, 'default' => __( 'Next', 'admore-widgets-suite' ), 'condition' => [ 'enable_multistep' => 'yes' ], 'separator' => 'before' ] );
$this->add_control( 'prev_text', [ 'label' => __( 'Previous Text', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXT, 'default' => __( 'Back', 'admore-widgets-suite' ), 'condition' => [ 'enable_multistep' => 'yes' ] ] );
$this->add_control( 'email_to', [
'label' => __( 'Send Email To', 'admore-widgets-suite' ),
'type' => Controls_Manager::TEXT,
'default' => self::default_notify_email(),
'placeholder' => __( 'you@example.com', 'admore-widgets-suite' ),
'description' => __( 'Separate multiple addresses with commas. Leave empty to turn off email notifications.', 'admore-widgets-suite' ),
'separator' => 'before',
] );
$this->add_control( 'email_subject', [ 'label' => __( 'Email Subject', 'admore-widgets-suite' ), 'type' => Controls_Manager::TEXT, 'default' => __( 'New Form Submission', 'admore-widgets-suite' ) ] );
$this->add_control( 'webhook_url', [
'label' => __( 'Webhook URL', 'admore-widgets-suite' ),
'type' => Controls_Manager::TEXT,
'placeholder' => 'https://hooks.example.com/...',
'description' => __( 'Each submission is sent here as JSON. Stored on the server only — never shown to visitors.', 'admore-widgets-suite' ),
] );
$this->add_control( 'success_message', [
'label' => __( 'Success Message', 'admore-widgets-suite' ),
'type' => Controls_Manager::TEXTAREA,
'default' => __( 'Thank you! Your message has been received.', 'admore-widgets-suite' ),
'separator' => 'before',
] );
$this->add_control( 'error_message', [
'label' => __( 'Error Message', 'admore-widgets-suite' ),
'type' => Controls_Manager::TEXTAREA,
'default' => __( 'Something went wrong. Please try again.', 'admore-widgets-suite' ),
] );
$this->add_control( 'redirect_url', [
'label' => __( 'Redirect After Submit', 'admore-widgets-suite' ),
'type' => Controls_Manager::URL,
'placeholder' => home_url( '/thank-you/' ),
'options' => false,
'dynamic' => [ 'active' => true ],
'description' => __( 'Optional. Visitors go to this page after a successful submission (e.g. a thank-you page for ad conversion tracking).', 'admore-widgets-suite' ),
'separator' => 'before',
] );
$this->add_control( 'redirect_delay', [
'label' => __( 'Redirect Delay (seconds)', 'admore-widgets-suite' ),
'type' => Controls_Manager::NUMBER,
'min' => 0,
'max' => 10,
'default' => 1,
'condition' => [ 'redirect_url[url]!' => '' ],
] );
// ── CAPTCHA ───────────────────────────────────────────────────────────
$this->add_control( 'captcha_heading', [
'label' => __( 'CAPTCHA', 'admore-widgets-suite' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
] );
$this->add_control( 'enable_captcha', [
'label' => __( 'Enable CAPTCHA', 'admore-widgets-suite' ),
'type' => Controls_Manager::SWITCHER,
'default' => '',
'description' => __( 'Configure CAPTCHA type and API keys in Essential Pro Pack → Integrations settings first.', 'admore-widgets-suite' ),
] );
$this->end_controls_section();
}
/**
* Per-form integrations. API keys are set once in Essential Pro Pack →
* Integrations; the submit handler runs EPPRO_Form_Integrations.
*/
private function register_integrations_section(): void {
$this->start_controls_section( 'section_integrations', [
'label' => __( 'Integrations', 'admore-widgets-suite' ),
'tab' => Controls_Manager::TAB_CONTENT,
] );
$this->add_control( 'integrations_note', [
'type' => Controls_Manager::RAW_HTML,
'raw' => sprintf(
/* translators: %s: link to the plugin's Integrations settings */
esc_html__( 'Add your Mailchimp / Brevo API keys in %s first.', 'admore-widgets-suite' ),
'' . esc_html__( 'Essential Pro Pack → Integrations', 'admore-widgets-suite' ) . ''
),
'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
] );
// ── Mailchimp ──
$this->add_control( 'mc_enable', [
'label' => __( 'Mailchimp', 'admore-widgets-suite' ),
'type' => Controls_Manager::SWITCHER,
'return_value' => 'yes',
'separator' => 'before',
] );
$this->add_control( 'mc_audience', [
'label' => __( 'Audience ID', 'admore-widgets-suite' ),
'type' => Controls_Manager::TEXT,
'description' => __( 'Mailchimp → Audience → Settings → Audience name and defaults.', 'admore-widgets-suite' ),
'condition' => [ 'mc_enable' => 'yes' ],
] );
$this->add_control( 'mc_double_optin', [
'label' => __( 'Double Opt-in', 'admore-widgets-suite' ),
'type' => Controls_Manager::SWITCHER,
'return_value' => 'yes',
'default' => 'yes',
'description' => __( 'New contacts confirm by e-mail before they are subscribed (recommended, required in many countries).', 'admore-widgets-suite' ),
'condition' => [ 'mc_enable' => 'yes' ],
] );
$this->add_control( 'mc_tags', [
'label' => __( 'Tags', 'admore-widgets-suite' ),
'type' => Controls_Manager::TEXT,
'placeholder' => 'website, inquiry',
'condition' => [ 'mc_enable' => 'yes' ],
] );
// ── Brevo ──
$this->add_control( 'brevo_enable', [
'label' => __( 'Brevo (Sendinblue)', 'admore-widgets-suite' ),
'type' => Controls_Manager::SWITCHER,
'return_value' => 'yes',
'separator' => 'before',
] );
$this->add_control( 'brevo_list', [
'label' => __( 'List ID', 'admore-widgets-suite' ),
'type' => Controls_Manager::NUMBER,
'min' => 1,
'description' => __( 'Brevo → Contacts → Lists (the number in the ID column). Phone numbers are sent only in +countrycode format.', 'admore-widgets-suite' ),
'condition' => [ 'brevo_enable' => 'yes' ],
] );
// ── Field mapping (Mailchimp + Brevo) — shown when either is on ──
$mc_or_brevo = [
'relation' => 'or',
'terms' => [
[ 'name' => 'mc_enable', 'operator' => '===', 'value' => 'yes' ],
[ 'name' => 'brevo_enable', 'operator' => '===', 'value' => 'yes' ],
],
];
$this->add_control( 'map_heading', [
'label' => __( 'Field Mapping (Field IDs)', 'admore-widgets-suite' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
'conditions' => $mc_or_brevo,
] );
$map = [
'map_email' => [ __( 'Email Field ID', 'admore-widgets-suite' ), 'email', __( 'Empty = the first Email field.', 'admore-widgets-suite' ) ],
'map_name' => [ __( 'Full Name Field ID', 'admore-widgets-suite' ), 'name', __( 'Split into first / last name when the two fields below are empty.', 'admore-widgets-suite' ) ],
'map_first_name' => [ __( 'First Name Field ID', 'admore-widgets-suite' ), '', '' ],
'map_last_name' => [ __( 'Last Name Field ID', 'admore-widgets-suite' ), '', '' ],
'map_phone' => [ __( 'Phone Field ID', 'admore-widgets-suite' ), '', '' ],
];
foreach ( $map as $key => $info ) {
$this->add_control( $key, [
'label' => $info[0],
'type' => Controls_Manager::TEXT,
'default' => $info[1],
'description' => $info[2],
'label_block' => false,
'conditions' => $mc_or_brevo,
] );
}
// ── Google Sheets ──
$this->add_control( 'sheets_enable', [
'label' => __( 'Google Sheets', 'admore-widgets-suite' ),
'type' => Controls_Manager::SWITCHER,
'return_value' => 'yes',
'separator' => 'before',
] );
$this->add_control( 'sheets_url', [
'label' => __( 'Apps Script Web App URL', 'admore-widgets-suite' ),
'type' => Controls_Manager::TEXT,
'placeholder' => 'https://script.google.com/macros/s/…/exec',
'label_block' => true,
'description' => __( 'Setup steps and the script: Essential Pro Pack → Integrations → Google Sheets setup.', 'admore-widgets-suite' ),
'condition' => [ 'sheets_enable' => 'yes' ],
] );
// ── Slack / Discord ──
$this->add_control( 'slack_enable', [
'label' => __( 'Slack / Discord Notification', 'admore-widgets-suite' ),
'type' => Controls_Manager::SWITCHER,
'return_value' => 'yes',
'separator' => 'before',
] );
$this->add_control( 'slack_url', [
'label' => __( 'Webhook URL', 'admore-widgets-suite' ),
'type' => Controls_Manager::TEXT,
'placeholder' => 'https://hooks.slack.com/services/…',
'label_block' => true,
'description' => __( 'A Slack incoming webhook or a Discord channel webhook.', 'admore-widgets-suite' ),
'condition' => [ 'slack_enable' => 'yes' ],
] );
$this->end_controls_section();
}
// =========================================================================
// Style Controls
// =========================================================================
private function register_style_form_section(): void {
$this->start_controls_section( 'style_form', [
'label' => __( 'Form', 'admore-widgets-suite' ),
'tab' => Controls_Manager::TAB_STYLE,
] );
$this->add_responsive_control( 'form_gap', [
'label' => __( 'Field Gap', 'admore-widgets-suite' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px' ],
'default' => [ 'size' => 16 ],
'selectors' => [ '{{WRAPPER}} .eppro-form-grid' => '--eppro-form-gap: {{SIZE}}{{UNIT}};' ],
] );
$this->add_group_control( Group_Control_Box_Shadow::get_type(), [
'name' => 'form_shadow',
'selector' => '{{WRAPPER}} .eppro-form-wrap',
] );
$this->add_responsive_control( 'form_padding', [
'label' => __( 'Padding', 'admore-widgets-suite' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', 'em' ],
'selectors' => [ '{{WRAPPER}} .eppro-form-wrap' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ],
] );
$this->add_control( 'form_bg', [
'label' => __( 'Background', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [ '{{WRAPPER}} .eppro-form-wrap' => 'background-color: {{VALUE}};' ],
] );
$this->add_control( 'form_radius', [
'label' => __( 'Border Radius', 'admore-widgets-suite' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px' ],
'selectors' => [ '{{WRAPPER}} .eppro-form-wrap' => 'border-radius: {{SIZE}}{{UNIT}};' ],
] );
$this->end_controls_section();
}
private function register_style_fields_section(): void {
$this->start_controls_section( 'style_fields', [
'label' => __( 'Fields', 'admore-widgets-suite' ),
'tab' => Controls_Manager::TAB_STYLE,
] );
// ── Label ──────────────────────────────────────────────────────────────
$this->add_control( 'label_position', [
'label' => __( 'Label Position', 'admore-widgets-suite' ),
'type' => Controls_Manager::SELECT,
'default' => 'top',
'options' => [
'top' => __( 'Above Field', 'admore-widgets-suite' ),
'inline' => __( 'Inline (left)', 'admore-widgets-suite' ),
'hidden' => __( 'Hidden (placeholder only)', 'admore-widgets-suite' ),
],
] );
$this->add_group_control( Group_Control_Typography::get_type(), [
'name' => 'label_typography',
'label' => __( 'Label Typography', 'admore-widgets-suite' ),
'selector' => '{{WRAPPER}} .eppro-field-label',
] );
$this->add_control( 'label_color', [
'label' => __( 'Label Color', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [ '{{WRAPPER}} .eppro-field-label' => 'color: {{VALUE}};' ],
] );
$this->add_responsive_control( 'label_spacing', [
'label' => __( 'Label Bottom Spacing', 'admore-widgets-suite' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px' ],
'range' => [ 'px' => [ 'min' => 0, 'max' => 30 ] ],
'selectors' => [ '{{WRAPPER}} .eppro-field-label' => 'margin-bottom: {{SIZE}}{{UNIT}};' ],
'condition' => [ 'label_position' => 'top' ],
] );
// ── Input fields ───────────────────────────────────────────────────────
$this->add_group_control( Group_Control_Typography::get_type(), [
'name' => 'field_typography',
'selector' => '{{WRAPPER}} .eppro-field input, {{WRAPPER}} .eppro-field textarea, {{WRAPPER}} .eppro-field select',
'separator' => 'before',
] );
$this->add_control( 'field_text_color', [
'label' => __( 'Text Color', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [ '{{WRAPPER}} .eppro-field input, {{WRAPPER}} .eppro-field textarea, {{WRAPPER}} .eppro-field select' => 'color: {{VALUE}};' ],
] );
$this->add_control( 'placeholder_color', [
'label' => __( 'Placeholder Color', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .eppro-field input::placeholder' => 'color: {{VALUE}};',
'{{WRAPPER}} .eppro-field textarea::placeholder' => 'color: {{VALUE}};',
],
] );
$this->add_control( 'field_bg', [
'label' => __( 'Background', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'default' => '#ffffff',
'selectors' => [ '{{WRAPPER}} .eppro-field input, {{WRAPPER}} .eppro-field textarea, {{WRAPPER}} .eppro-field select' => 'background-color: {{VALUE}};' ],
] );
$this->add_group_control( Group_Control_Border::get_type(), [
'name' => 'field_border',
'selector' => '{{WRAPPER}} .eppro-field input, {{WRAPPER}} .eppro-field textarea, {{WRAPPER}} .eppro-field select',
] );
$this->add_control( 'field_radius', [
'label' => __( 'Border Radius', 'admore-widgets-suite' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px' ],
'selectors' => [ '{{WRAPPER}} .eppro-field input, {{WRAPPER}} .eppro-field textarea, {{WRAPPER}} .eppro-field select' => 'border-radius: {{SIZE}}{{UNIT}};' ],
] );
$this->add_responsive_control( 'field_padding', [
'label' => __( 'Padding', 'admore-widgets-suite' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', 'em' ],
'selectors' => [ '{{WRAPPER}} .eppro-field input, {{WRAPPER}} .eppro-field textarea, {{WRAPPER}} .eppro-field select' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ],
] );
// ── Field icon style ───────────────────────────────────────────────────
$this->add_control( 'field_icon_heading', [
'label' => __( 'Field Icon', 'admore-widgets-suite' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
] );
$this->add_control( 'field_icon_color', [
'label' => __( 'Icon Color', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'default' => '#9ca3af',
'selectors' => [
'{{WRAPPER}} .eppro-field-icon i' => 'color: {{VALUE}};',
'{{WRAPPER}} .eppro-field-icon svg' => 'fill: {{VALUE}};',
],
] );
$this->add_control( 'field_icon_size', [
'label' => __( 'Icon Size (px)', 'admore-widgets-suite' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px' ],
'range' => [ 'px' => [ 'min' => 10, 'max' => 36 ] ],
'default' => [ 'size' => 16 ],
'selectors' => [
'{{WRAPPER}} .eppro-field-icon i' => 'font-size: {{SIZE}}{{UNIT}};',
'{{WRAPPER}} .eppro-field-icon svg' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};',
],
] );
// ── Focus state ────────────────────────────────────────────────────────
$this->add_control( 'field_focus_heading', [
'label' => __( 'Focus State', 'admore-widgets-suite' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
] );
$this->add_control( 'field_focus_border_color', [
'label' => __( 'Border Color', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'default' => EPPRO_Elementor_Helper::brand_color(),
'selectors' => [
'{{WRAPPER}} .eppro-field input:focus' => 'border-color: {{VALUE}}; outline: none;',
'{{WRAPPER}} .eppro-field textarea:focus' => 'border-color: {{VALUE}}; outline: none;',
'{{WRAPPER}} .eppro-field select:focus' => 'border-color: {{VALUE}}; outline: none;',
],
] );
$this->add_control( 'field_focus_shadow', [
'label' => __( 'Glow / Ring Color', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'default' => EPPRO_Elementor_Helper::brand_color( 'primary', 0.15 ),
'selectors' => [
'{{WRAPPER}} .eppro-field input:focus' => 'box-shadow: 0 0 0 3px {{VALUE}};',
'{{WRAPPER}} .eppro-field textarea:focus' => 'box-shadow: 0 0 0 3px {{VALUE}};',
'{{WRAPPER}} .eppro-field select:focus' => 'box-shadow: 0 0 0 3px {{VALUE}};',
],
] );
$this->add_control( 'field_focus_bg', [
'label' => __( 'Background on Focus', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .eppro-field input:focus' => 'background-color: {{VALUE}};',
'{{WRAPPER}} .eppro-field textarea:focus' => 'background-color: {{VALUE}};',
'{{WRAPPER}} .eppro-field select:focus' => 'background-color: {{VALUE}};',
],
] );
$this->add_control( 'field_error_heading', [
'label' => __( 'Error / Invalid State', 'admore-widgets-suite' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
] );
$this->add_control( 'field_error_border_color', [
'label' => __( 'Border Color', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'default' => '#ef4444',
'selectors' => [
// The script marks invalid inputs with .eppro-has-error.
'{{WRAPPER}} .eppro-field .eppro-input.eppro-has-error' => 'border-color: {{VALUE}};',
],
] );
$this->add_control( 'field_error_bg', [
'label' => __( 'Background Color', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
// The script marks invalid inputs with .eppro-has-error.
'{{WRAPPER}} .eppro-field .eppro-input.eppro-has-error' => 'background-color: {{VALUE}};',
],
] );
$this->add_control( 'field_error_msg_color', [
'label' => __( 'Error Message Color', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'default' => '#ef4444',
'selectors' => [ '{{WRAPPER}} .eppro-field-error' => 'color: {{VALUE}};' ],
] );
$this->add_group_control( Group_Control_Typography::get_type(), [
'name' => 'field_error_typography',
'label' => __( 'Error Message Typography', 'admore-widgets-suite' ),
'selector' => '{{WRAPPER}} .eppro-field-error',
] );
$this->end_controls_section();
}
/**
* Multi-step progress indicator. Every colour is a CSS variable on the
* indicator (see style.css); Completed falls back to the Active colours.
*/
private function register_style_steps_section(): void {
$ind = '{{WRAPPER}} .eppro-step-indicator';
$this->start_controls_section( 'style_steps', [
'label' => __( 'Step Indicator', 'admore-widgets-suite' ),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [ 'enable_multistep' => 'yes' ],
] );
$this->add_responsive_control( 'step_size', [
'label' => __( 'Circle Size', 'admore-widgets-suite' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px' ],
'range' => [ 'px' => [ 'min' => 16, 'max' => 80 ] ],
'selectors' => [ $ind => '--eppro-step-size: {{SIZE}}{{UNIT}};' ],
] );
$this->add_control( 'step_radius', [
'label' => __( 'Circle Radius', 'admore-widgets-suite' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%' ],
'range' => [ 'px' => [ 'min' => 0, 'max' => 40 ], '%' => [ 'min' => 0, 'max' => 50 ] ],
'selectors' => [ $ind => '--eppro-step-radius: {{SIZE}}{{UNIT}};' ],
] );
$this->add_control( 'step_line', [
'label' => __( 'Line Thickness', 'admore-widgets-suite' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px' ],
'range' => [ 'px' => [ 'min' => 0, 'max' => 10 ] ],
'selectors' => [ $ind => '--eppro-step-line: {{SIZE}}{{UNIT}};' ],
] );
$this->add_control( 'step_shadow', [
'label' => __( 'Circle Shadow', 'admore-widgets-suite' ),
'type' => Controls_Manager::SELECT,
'default' => 'show',
'options' => [
'show' => __( 'Show', 'admore-widgets-suite' ),
'hide' => __( 'Hide', 'admore-widgets-suite' ),
],
'selectors_dictionary' => [ 'show' => '', 'hide' => 'box-shadow: none;' ],
'selectors' => [ $ind . ' .eppro-step-dot .eppro-step-num' => '{{VALUE}}' ],
] );
$this->start_controls_tabs( 'step_color_tabs', [ 'separator' => 'before' ] );
// ── Normal (upcoming steps) ──
$this->start_controls_tab( 'step_tab_normal', [ 'label' => __( 'Normal', 'admore-widgets-suite' ) ] );
$this->add_control( 'step_bg', [
'label' => __( 'Circle Background', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [ $ind => '--eppro-step-bg: {{VALUE}};' ],
] );
$this->add_control( 'step_color', [
'label' => __( 'Number Color', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [ $ind => '--eppro-step-color: {{VALUE}};' ],
] );
$this->add_control( 'step_label_color', [
'label' => __( 'Label Color', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [ $ind => '--eppro-step-label: {{VALUE}};' ],
] );
$this->add_control( 'step_line_color', [
'label' => __( 'Line Color', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [ $ind => '--eppro-step-line-color: {{VALUE}};' ],
] );
$this->end_controls_tab();
// ── Active (current step) ──
$this->start_controls_tab( 'step_tab_active', [ 'label' => __( 'Active', 'admore-widgets-suite' ) ] );
$this->add_control( 'step_active_bg', [
'label' => __( 'Circle Background', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [ $ind => '--eppro-step-active-bg: {{VALUE}};' ],
] );
$this->add_control( 'step_active_color', [
'label' => __( 'Number Color', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [ $ind => '--eppro-step-active-color: {{VALUE}};' ],
] );
$this->add_control( 'step_active_label', [
'label' => __( 'Label Color', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [ $ind => '--eppro-step-active-label: {{VALUE}};' ],
] );
$this->end_controls_tab();
// ── Completed (previous steps) ──
$this->start_controls_tab( 'step_tab_done', [ 'label' => __( 'Completed', 'admore-widgets-suite' ) ] );
$this->add_control( 'step_done_bg', [
'label' => __( 'Circle Background', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'description' => __( 'Empty = same as Active.', 'admore-widgets-suite' ),
'selectors' => [ $ind => '--eppro-step-done-bg: {{VALUE}};' ],
] );
$this->add_control( 'step_done_color', [
'label' => __( 'Number Color', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [ $ind => '--eppro-step-done-color: {{VALUE}};' ],
] );
$this->add_control( 'step_done_label', [
'label' => __( 'Label Color', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [ $ind => '--eppro-step-done-label: {{VALUE}};' ],
] );
$this->add_control( 'step_line_done', [
'label' => __( 'Progress Line Color', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'selectors' => [ $ind => '--eppro-step-line-done: {{VALUE}};' ],
] );
$this->end_controls_tab();
$this->end_controls_tabs();
$this->add_group_control( Group_Control_Typography::get_type(), [
'name' => 'step_num_typography',
'label' => __( 'Number Typography', 'admore-widgets-suite' ),
'selector' => $ind . ' .eppro-step-num',
'separator' => 'before',
] );
$this->add_group_control( Group_Control_Typography::get_type(), [
'name' => 'step_label_typography',
'label' => __( 'Label Typography', 'admore-widgets-suite' ),
'selector' => $ind . ' .eppro-step-label',
] );
$this->add_control( 'step_label_gap', [
'label' => __( 'Label Spacing', 'admore-widgets-suite' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px' ],
'range' => [ 'px' => [ 'min' => 0, 'max' => 30 ] ],
'selectors' => [ $ind => '--eppro-step-label-gap: {{SIZE}}{{UNIT}};' ],
] );
$this->add_responsive_control( 'step_spacing', [
'label' => __( 'Space Below', 'admore-widgets-suite' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px' ],
'range' => [ 'px' => [ 'min' => 0, 'max' => 80 ] ],
'selectors' => [ $ind => 'margin-bottom: {{SIZE}}{{UNIT}};' ],
] );
$this->end_controls_section();
}
private function register_style_button_section(): void {
$this->start_controls_section( 'style_button', [
'label' => __( 'Buttons', 'admore-widgets-suite' ),
'tab' => Controls_Manager::TAB_STYLE,
] );
$this->start_controls_tabs( 'button_tabs' );
$this->start_controls_tab( 'btn_normal', [ 'label' => __( 'Normal', 'admore-widgets-suite' ) ] );
$this->add_control( 'btn_bg', [ 'label' => __( 'Background', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .eppro-form-btn' => 'background-color: {{VALUE}};' ] ] );
$this->add_control( 'btn_color', [ 'label' => __( 'Text Color', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'default' => '#ffffff', 'selectors' => [ '{{WRAPPER}} .eppro-form-btn' => 'color: {{VALUE}};' ] ] );
$this->end_controls_tab();
$this->start_controls_tab( 'btn_hover', [ 'label' => __( 'Hover', 'admore-widgets-suite' ) ] );
$this->add_control( 'btn_bg_hover', [ 'label' => __( 'Background', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .eppro-form-btn:hover' => 'background-color: {{VALUE}};' ] ] );
$this->add_control( 'btn_color_hover', [ 'label' => __( 'Text Color', 'admore-widgets-suite' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .eppro-form-btn:hover' => 'color: {{VALUE}};' ] ] );
$this->end_controls_tab();
$this->end_controls_tabs();
$this->add_group_control( Group_Control_Typography::get_type(), [
'name' => 'btn_typography',
'selector' => '{{WRAPPER}} .eppro-form-btn',
'separator' => 'before',
] );
$this->add_responsive_control( 'btn_padding', [
'label' => __( 'Padding', 'admore-widgets-suite' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', 'em' ],
'default' => [ 'top' => '12', 'right' => '28', 'bottom' => '12', 'left' => '28', 'unit' => 'px', 'isLinked' => false ],
'selectors' => [ '{{WRAPPER}} .eppro-form-btn' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ],
] );
$this->add_control( 'btn_radius', [
'label' => __( 'Border Radius', 'admore-widgets-suite' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px' ],
'default' => [ 'size' => 6 ],
'selectors' => [ '{{WRAPPER}} .eppro-form-btn' => 'border-radius: {{SIZE}}{{UNIT}};' ],
] );
$this->add_control( 'btn_width', [
'label' => __( 'Submit Button Width', 'admore-widgets-suite' ),
'type' => Controls_Manager::SELECT,
'default' => 'auto',
'options' => [
'auto' => __( 'Auto', 'admore-widgets-suite' ),
'full' => __( 'Full Width', 'admore-widgets-suite' ),
],
'separator' => 'before',
] );
$this->add_responsive_control( 'btn_align', [
'label' => __( 'Alignment', 'admore-widgets-suite' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'flex-start' => [ 'title' => __( 'Left', 'admore-widgets-suite' ), 'icon' => 'eicon-text-align-left' ],
'center' => [ 'title' => __( 'Center', 'admore-widgets-suite' ), 'icon' => 'eicon-text-align-center' ],
'flex-end' => [ 'title' => __( 'Right', 'admore-widgets-suite' ), 'icon' => 'eicon-text-align-right' ],
],
'default' => 'flex-start',
'selectors' => [ '{{WRAPPER}} .eppro-form-actions' => 'justify-content: {{VALUE}};' ],
'condition' => [ 'btn_width' => 'auto' ],
] );
$this->end_controls_section();
}
private function register_style_messages_section(): void {
$this->start_controls_section( 'style_messages', [
'label' => __( 'Success / Error Messages', 'admore-widgets-suite' ),
'tab' => Controls_Manager::TAB_STYLE,
] );
$this->add_control( 'success_msg_color', [
'label' => __( 'Success Text Color', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'default' => '#15803d',
'selectors' => [ '{{WRAPPER}} .eppro-form-success' => 'color: {{VALUE}};' ],
] );
$this->add_control( 'success_msg_bg', [
'label' => __( 'Success Background', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'default' => '#dcfce7',
'selectors' => [ '{{WRAPPER}} .eppro-form-success' => 'background-color: {{VALUE}};' ],
] );
$this->add_group_control( Group_Control_Typography::get_type(), [
'name' => 'success_msg_typography',
'selector' => '{{WRAPPER}} .eppro-form-success',
] );
$this->add_control( 'error_msg_color', [
'label' => __( 'Error Text Color', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'default' => '#b91c1c',
'separator' => 'before',
'selectors' => [ '{{WRAPPER}} .eppro-form-error-global' => 'color: {{VALUE}};' ],
] );
$this->add_control( 'error_msg_bg', [
'label' => __( 'Error Background', 'admore-widgets-suite' ),
'type' => Controls_Manager::COLOR,
'default' => '#fee2e2',
'selectors' => [ '{{WRAPPER}} .eppro-form-error-global' => 'background-color: {{VALUE}};' ],
] );
$this->add_responsive_control( 'msg_padding', [
'label' => __( 'Padding', 'admore-widgets-suite' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', 'em' ],
'default' => [ 'top' => '12', 'right' => '16', 'bottom' => '12', 'left' => '16', 'unit' => 'px' ],
'selectors' => [
'{{WRAPPER}} .eppro-form-success' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
'{{WRAPPER}} .eppro-form-error-global' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'separator' => 'before',
] );
$this->add_control( 'msg_border_radius', [
'label' => __( 'Border Radius', 'admore-widgets-suite' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px' ],
'default' => [ 'size' => 6 ],
'selectors' => [
'{{WRAPPER}} .eppro-form-success' => 'border-radius: {{SIZE}}{{UNIT}};',
'{{WRAPPER}} .eppro-form-error-global' => 'border-radius: {{SIZE}}{{UNIT}};',
],
] );
$this->end_controls_section();
}
// =========================================================================
// Render
// =========================================================================
/** Default recipient: the notification email chosen in the Setup Wizard (if any). */
private static function default_notify_email(): string {
if ( ! class_exists( 'EPPRO_Admin_Settings' ) ) return '';
$settings = EPPRO_Admin_Settings::get_settings();
return sanitize_email( (string) ( $settings['wizard_notify_email'] ?? '' ) );
}
protected function render(): void {
$s = $this->get_settings_for_display();
$fields = EPPRO_Form_Handler::normalize_fields( (array) ( $s['form_fields'] ?? [] ) );
$multistep = ( $s['enable_multistep'] ?? '' ) === 'yes';
$steps = (array) ( $s['steps'] ?? [] );
$widget_id = $this->get_id();
if ( empty( $fields ) ) {
if ( \Elementor\Plugin::$instance->editor->is_edit_mode() ) {
echo '
' . esc_html__( 'Form', 'admore-widgets-suite' ) . '
' . esc_html__( 'Add fields in the Content tab → Form Fields.', 'admore-widgets-suite' ) . '
';
}
return;
}
// The Elementor document that stores this widget (page, popup or template).
// The submit handler loads the form configuration from it.
$post_id = EPPRO_Elementor_Helper::current_document_id();
// Only non-sensitive values go to the browser. Recipients, webhook,
// file rules and messages stay on the server.
$config = [
'widgetId' => $widget_id,
'postId' => $post_id,
'pageId' => (int) get_queried_object_id(),
'multistep' => $multistep,
'totalSteps' => $multistep ? max( 1, count( $steps ) ) : 1,
'errorMessage' => wp_kses_post( $s['error_message'] ?? '' ),
'i18n' => [
/* translators: %s: form field label */
'required' => __( '%s is required.', 'admore-widgets-suite' ),
'invalidEmail' => __( 'Please enter a valid email address.', 'admore-widgets-suite' ),
'invalidPhone' => __( 'Please enter a valid phone number.', 'admore-widgets-suite' ),
'invalidUrl' => __( 'Please enter a valid URL.', 'admore-widgets-suite' ),
'acceptance' => __( 'Please accept to continue.', 'admore-widgets-suite' ),
'genericError' => __( 'Something went wrong. Please try again.', 'admore-widgets-suite' ),
],
];
$fields_config = [];
foreach ( $fields as $def ) {
$fields_config[] = [
'id' => $def['id'],
'type' => $def['type'],
'label' => $def['label'],
'required' => $def['required'],
];
}
$label_pos = $s['label_position'] ?? 'top';
$btn_width = $s['btn_width'] ?? 'auto';
?>
';
} elseif ( 'recaptcha_v3' === $captcha['type'] ) {
wp_enqueue_script( 'google-recaptcha-v3', 'https://www.google.com/recaptcha/api.js?render=' . rawurlencode( $captcha['site_key'] ), [], '3.0', true );
$captcha_html = '';
} elseif ( 'hcaptcha' === $captcha['type'] ) {
wp_enqueue_script( 'hcaptcha-api', 'https://js.hcaptcha.com/1/api.js', [], '1.0', true );
$captcha_html = '';
}
}
$allowed_captcha = [
'div' => [ 'class' => [], 'data-sitekey' => [] ],
'input' => [ 'type' => [], 'name' => [], 'class' => [], 'data-sitekey' => [] ],
];
echo wp_kses( $captcha_html, $allowed_captcha );
?>
' . esc_textarea( $default ) . '';
break;
case 'select':
echo '';
break;
case 'radio':
case 'checkbox':
$suffix = 'checkbox' === $ftype ? '[]' : '';
echo '' . esc_html( $def['row']['field_label'] ?? '' );
if ( $required ) echo '*';
echo '
';
foreach ( $def['options'] as $i => $opt ) {
echo '';
}
echo '
';
break;
case 'acceptance':
$text = (string) ( $def['row']['acceptance_text'] ?? '' );
if ( '' === trim( $text ) ) {
$text = __( 'I agree to the Privacy Policy.', 'admore-widgets-suite' );
}
$allowed = [
'a' => [ 'href' => [], 'target' => [], 'rel' => [] ],
'strong' => [],
'em' => [],
'b' => [],
'i' => [],
];
echo '';
break;
case 'hidden':
// form.js fills in values that only the browser knows (URL parameter,
// page URL / title, referrer); a fixed value is printed here.
$source = $def['hidden_source'];
echo '';
break;
case 'html':
echo '' . wp_kses_post( (string) ( $def['row']['html_content'] ?? '' ) ) . '
';
break;
case 'file':
$accept = '.' . implode( ',.', $def['allowed_types'] );
echo '';
break;
default: // text, email, tel, url, number, date, time
echo '';
break;
}
}
}