You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Elementor表单字段按属性分配数组失败,求代码修复

问题:Elementor表单无法根据field_attribute分类字段到ADF XML节点

我在Elementor表单中添加了自定义的field_attribute字段(用于标记字段属于vehicle/customer/vendor),但无法根据该属性值将表单字段分配到对应的数组,最终生成的ADF XML不符合预期——无法将Model(设为vehicle)、Name(设为customer)、Phone(设为vendor)分别放入对应的<vehicle>、<customer>、<vendor>节点中。

错误核心代码片段

global $selected_option;
// ...
if ( $selected_option === 'vehicle' ) 
{
$vehicleFields[] = [$field_name => $field_value];
} 
// ...

问题原因分析

  1. 全局变量使用错误:在maybe_add_attribute方法中,每次处理字段都会重置$selected_option = array();,导致最终只保留最后一个字段的属性值,且为数组类型,后续$selected_option === 'vehicle'的判断永远不成立。
  2. 字段与属性未关联:在new_record钩子中,没有将每个字段的field_attribute和对应值绑定,无法区分单个字段的属性分类。
  3. 遍历逻辑错误:分类判断代码不在字段循环内,无法逐个处理每个表单字段。

修复后的完整代码

<?php
class Elementor_Forms_Patterns_Validation {
    public $allowed_fields = [
        'text',
        'email',
        'textarea',
    ];

    public function __construct() {
        add_action( 'elementor/element/form/section_form_fields/before_section_end', [ $this, 'add_attribute_field_control' ], 100, 2 );
        // 改用form_fields_registered钩子存储字段属性,避免渲染阶段的全局变量问题
        add_action( 'elementor_pro/forms/form_fields_registered', [ $this, 'store_field_attributes' ], 10, 1 );
    }

    public function add_attribute_field_control( $element, $args ) {
        $elementor = \Elementor\Plugin::instance();
        $control_data = $elementor->controls_manager->get_control_from_stack( $element->get_name(), 'form_fields' );

        if ( is_wp_error( $control_data ) ) {
            return;
        }

        $tmp = new \Elementor\Repeater();
        $tmp->add_control(
            'field_attribute',
            [
                'label' => 'Attribute',
                'inner_tab' => 'form_fields_advanced_tab',
                'tab' => 'content',
                'tabs_wrapper' => 'form_fields_tabs',
                'type' => 'select',
                'options' => [
                    '' => 'None',
                    'vehicle' => 'vehicle',
                    'customer' => 'customer',
                    'vendor' => 'vendor',
                ],
                'conditions' => [
                    'terms' => [
                        [
                            'name' => 'field_type',
                            'operator' => 'in',
                            'value' => $this->allowed_fields,
                        ],
                    ],
                ],
            ]
        );

        $attribute_field = $tmp->get_controls();
        $attribute_field = $attribute_field['field_attribute'];

        $new_order = [];
        foreach ( $control_data['fields'] as $field_key => $field ) {
            if ( 'custom_id' === $field['name'] ) {
                $new_order['field_attribute'] = $attribute_field;
            }
            $new_order[ $field_key ] = $field;
        }
        $control_data['fields'] = $new_order;

        $element->update_control( 'form_fields', $control_data );
    }

    // 存储表单字段的属性映射,键为字段名称(或custom_id),值为field_attribute
    public function store_field_attributes( $form ) {
        $form_settings = $form->get_settings_for_display();
        if ( empty( $form_settings['form_fields'] ) ) {
            return;
        }

        $field_attributes = [];
        foreach ( $form_settings['form_fields'] as $field ) {
            $field_name = ! empty( $field['custom_id'] ) ? $field['custom_id'] : $field['field_label'];
            $field_name = str_replace( ' ', '_', $field_name );
            if ( isset( $field['field_attribute'] ) && ! empty( $field['field_attribute'] ) ) {
                $field_attributes[ $field_name ] = $field['field_attribute'];
            }
        }

        // 将属性映射存储到表单实例,方便后续钩子调用
        $form->field_attributes = $field_attributes;
    }
}

// Convert Elementor form data to ADF format and send email
add_action( 'elementor_pro/forms/new_record', function( $record, $handler ) {
    // Get form data and form name
    $data = $record->get_formatted_data();
    $form_id = $record->get_form_settings( 'form_id' );
    $form_name = $record->get_form_settings( 'form_name' );

    // 获取存储的字段属性映射
    $field_attributes = $handler->form->field_attributes ?? [];

    $vehicleFields = [];
    $customerFields = [];
    $vendorFields = [];

    // 遍历每个字段,根据属性分类
    foreach ( $data as $field_label => $field_value ) {
        // 替换空格为下划线,和存储的键保持一致
        $field_name = str_replace( ' ', '_', $field_label );
        // 获取当前字段的属性
        $selected_option = $field_attributes[ $field_name ] ?? '';

        if ( $selected_option === 'vehicle' ) {
            $vehicleFields[] = [ $field_name => $field_value ];
        } elseif ( $selected_option === 'customer' ) {
            $customerFields[] = [ $field_name => $field_value ];
        } elseif ( $selected_option === 'vendor' ) {
            $vendorFields[] = [ $field_name => $field_value ];
        }
    }

    // Generate ADF XML
    $xml = new DOMDocument( "1.0", "UTF-8" );
    $adf = $xml->createElement( "adf" );
    $prospect = $xml->createElement( "prospect" );

    // Add request date to prospect
    $requestdate = $xml->createElement( "requestdate", date( 'c' ) );
    $prospect->appendChild( $requestdate );

    // Add vehicle data to prospect
    if ( ! empty( $vehicleFields ) ) {
        $vehicle = $xml->createElement( "vehicle" );
        foreach ( $vehicleFields as $field ) {
            foreach ( $field as $field_name => $field_value ) {
                $fieldElement = $xml->createElement( $field_name, $xml->createTextNode( $field_value ) );
                $vehicle->appendChild( $fieldElement );
            }
        }
        $prospect->appendChild( $vehicle );
    }

    // Add customer data to prospect
    if ( ! empty( $customerFields ) ) {
        $customer = $xml->createElement( "customer" );
        $contact = $xml->createElement( "contact" );
        foreach ( $customerFields as $field ) {
            foreach ( $field as $field_name => $field_value ) {
                $fieldElement = $xml->createElement( $field_name, $xml->createTextNode( $field_value ) );
                $contact->appendChild( $fieldElement );
            }
        }
        $customer->appendChild( $contact );
        $prospect->appendChild( $customer );
    }

    // Add vendor data to prospect
    if ( ! empty( $vendorFields ) ) {
        $vendor = $xml->createElement( "vendor" );
        $contact = $xml->createElement( "contact" );
        foreach ( $vendorFields as $field ) {
            foreach ( $field as $field_name => $field_value ) {
                $fieldElement = $xml->createElement( $field_name, $xml->createTextNode( $field_value ) );
                $contact->appendChild( $fieldElement );
            }
        }
        $vendor->appendChild( $contact );
        $prospect->appendChild( $vendor );
    }

    $adf->appendChild( $prospect );
    $xml->appendChild( $adf );

    // Format ADF XML for readability
    $xml->formatOutput = true;
    $adf_xml = $xml->saveXML();

    // Send email with ADF XML in body
    $to = array( 'example@mail.com');
    $subject = 'Subject ';
    $headers = array(
        'Content-Type: text/plain; charset=UTF-8',
        'From: From <email@example.com>'
    );
    wp_mail( $to, $subject, $adf_xml, $headers );
}, 10, 2 );

new Elementor_Forms_Patterns_Validation();

关键修改说明

  • 移除全局变量:改用elementor_pro/forms/form_fields_registered钩子将字段属性存储到表单实例中,避免全局变量的覆盖问题。
  • 关联字段与属性:在字段循环中,通过处理后的字段名匹配对应的field_attribute,实现每个字段的精准分类。
  • XML安全处理:使用createTextNode()包裹字段值,避免特殊字符破坏XML结构。
  • 优化逻辑结构:删除无用的前端渲染钩子,专注后端属性存储与分类逻辑。

内容的提问来源于stack exchange,提问作者Hussain Ahmed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 01:04:58