Php 发送一封自定义电子邮件,其中包含存储在Woocommerce 3中的其他帐户字段值

Php 发送一封自定义电子邮件,其中包含存储在Woocommerce 3中的其他帐户字段值,php,wordpress,woocommerce,custom-fields,email-notifications,Php,Wordpress,Woocommerce,Custom Fields,Email Notifications,在插件“高级自定义字段”的基础上,为WooCommerce用户的个人帐户创建了其他字段。使用第二个“ACF for WooCommerce”插件,我将这些字段放在编辑帐户页面上 如果用户填写或编辑了这些字段,管理员将收到一封包含这些字段值的电子邮件。以下代码负责通知: if (!class_exists('WooCommerceNotifyChanges')) { class WooCommerceNotifyChanges { function __construc

在插件“高级自定义字段”的基础上,为WooCommerce用户的个人帐户创建了其他字段。使用第二个“ACF for WooCommerce”插件,我将这些字段放在编辑帐户页面上

如果用户填写或编辑了这些字段,管理员将收到一封包含这些字段值的电子邮件。以下代码负责通知:

if (!class_exists('WooCommerceNotifyChanges')) {

    class WooCommerceNotifyChanges {

        function __construct() {                        
            add_action('woocommerce_save_account_details', array($this, 'woocommerce_send_notification'), 15, 1);
        }

        function woocommerce_send_notification($user_id) {
            $body = '';
            $to = 'info@domain.com'; 
            $subject = 'Edit profile data';

            update_meta_cache('user', $user_id); // delete cache   

            $user = new WP_User($user_id);
            $user_name = $user->user_login;

            $body .= '<table>';
            $body .= '<tr><td>'.__("Profile"). '</td></tr>';                        
            $body .= '<tr><td>Login: </td><td>'.$user_name. '</td></tr>';
            $body .= '<tr><td>First Name: </td><td>'.$user->billing_first_name. '</td></tr>';
            $body .= '<tr><td>Last Name: </td><td>'.$user->billing_last_name. '</td></tr>';
            $body .= '<tr><td>Phone: </td><td>'.get_user_meta($user_id, 'field_5b4640119354c', $single=true). '</td></tr>'; //text field
            $body .= '<tr><td>Age: </td><td>'.get_user_meta($user_id, 'field_5b462d304b101', $single=true). '</td></tr>'; //text field
            $body .= '<tr><td>Family: </td><td>'.get_user_meta($user_id, 'field_5b4bd7d9f0031', $single=true). '</td></tr>'; // selector                       
            $body .= '<tr><td>What style do you prefer? </td><td>'.get_user_meta($user_id, 'field_5b47917a378ed', $single=true). '</td></tr>'; // checkbox                      

            $body .= '</table>';

            //set content type as HTML
            $headers = array('Content-Type: text/html; charset=UTF-8;');

            //send email
            if (wp_mail($to, $subject, $body, $headers)) {
                //echo 'email sent';
            } else {
                //echo 'email NOT sent';                
            }
            //exit();
        }
    }
    new WooCommerceNotifyChanges();
}
但它不起作用,旧的数据仍在出现。显然,我做错了什么

  • 所有字段的数据都正确存储在数据库中,并正确显示在发送给管理员的电子邮件中。复选框的问题。

    在本例中,将显示“您喜欢什么样式?”三个复选框“经典”、“休闲”和“运动”。用户选中了“休闲”复选框。此字段的值已正确存储在数据库中。

    但是在发送给管理员的电子邮件中,只有“Array”一词,而不是该值

  • 告诉我怎么修

    非常感谢您的帮助。

    Update 1-解决插件问题。 1)缓存问题:我终于在“ACF for WooCommerce”插件源代码中找到了问题

    您需要使用更高的优先级值,因为插件的优先级为100

    因此,您将在代码中替换(在构造函数中):

    优先级值为
    150
    (或更多),例如:

    add_action('woocommerce_save_account_details', array($this, 'woocommerce_send_notification'), 150, 1);
    
    它将彻底解决您的假“缓存”问题(感谢Kashalo)


    2)用于“您喜欢什么样式?”的复选框字段

    您需要将数组转换为具有分隔值的字符串

    使用以下命令:

    function woocommerce_send_notification($user_id) {
        // Recipient
        $to = 'info@domain.com'; 
        
        $subject = 'Edit profile data';
    
        $user =      new WP_User($user_id);
        $user_name = $user->user_login;
        
        $phone  = get_user_meta( $user_id, 'field_5b4640119354c', true ); // Phone - text field
        $age    = get_user_meta( $user_id, 'field_5b462d304b101', true ); // Age- text field
        $family = get_user_meta( $user_id, 'field_5b4bd7d9f0031', true ); // Family - select field 
        $fstyle = get_user_meta( $user_id, 'field_5b47917a378ed', true ); // Favorited styles - Multiple Checkboxes 
    
         // Convert the array to a coma separated list (Favorited styles)
        $fstyle = implode( ', ',  $fstyle ); 
        
        // Body output
        $body = '<h3>'. __("Profile") .'</h3>
        <table>
        <tr><td>Login: </td><td>'.      $user->user_login         .'</td></tr>
        <tr><td>First Name: </td><td>'. $user->billing_first_name .'</td></tr>
        <tr><td>Last Name: </td><td>'.  $user->billing_last_name  .'</td></tr>
        <tr><td>Phone: </td><td>'.      $phone                    .'</td></tr>
        <tr><td>Age: </td><td>'.        $age                      .'</td></tr>
        <tr><td>Family: </td><td>'.     $family                   .'</td></tr>  
        <tr><td>What style do you prefer? </td><td>'. $fstyle     .'</td></tr> 
        </table>';
    
        //set content type as HTML
        $headers = array('Content-Type: text/html; charset=UTF-8;');
    
        //send email
        $sent = wp_mail( $to, $subject, $body, $headers );
    }
    
    功能发送通知($user\u id){
    //接受者
    $to$info@domain.com'; 
    $subject='编辑配置文件数据';
    $user=新的WP\u用户($user\u id);
    $user\u name=$user->user\u login;
    $phone=get_user_meta($user_id,'field_5b464011935c',true);//电话-文本字段
    $age=get_user_meta($user_id,'field_5b462d304b101',true);//年龄-文本字段
    $family=get_user_meta($user_id,'field_5b4bd7d9f0031',true);//family-选择字段
    $fstyle=get_user_meta($user_id,'field5b47917a378ed',true);//常用样式-多个复选框
    //将数组转换为分隔列表(常用样式)
    $fstyle=内爆(“,”,$fstyle);
    //身体输出
    $body=''。_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
    登录:'.$user->user\u Login'
    名字:'.$user->账单名称'
    姓氏:'.$user->billing_Last_Name'
    电话:'.$Phone'
    年龄:‘.$Age。’
    家庭:‘.$Family。’
    你喜欢什么款式?“$fstyle”
    ';
    //将内容类型设置为HTML
    $headers=array('Content-Type:text/html;charset=UTF-8;');
    //发送电子邮件
    $sent=wp_邮件($to、$subject、$body、$headers);
    }
    

    原始答复: 在本问题中提供的信息和代码范围内,不可能测试和尝试再现您的问题,因为没有人能够猜到您的ACF设置和相关上下文

    在执行多个自定义时,使用高级自定义字段不是一个好主意。你浪费了太多的时间,从一段时间以来一直试图找出问题所在

    最好的方法是手工编写自定义字段,而无需像开发人员那样使用插件

    在以下代码中,我是:

  • 在类本身中添加并显示附加字段,而不使用ACF
  • 验证字段数据
  • 保存数据并发送包含正确数据的电子邮件通知(无任何缓存问题)
  • 在“电子商务账单”部分下的“管理员用户编辑”页面中显示这些附加字段
  • 现在,由于您没有为“族”选择字段和“首选样式”复选框提供选项值,因此您必须在每个阵列的“设置”部分中设置所需的值

    测试此代码时,必须禁用相关的ACF字段。

    完整的功能代码(无ACF):

    如果(!class\u存在('WC\u附加\u帐户\u字段')){
    类别WC\u其他\u帐户\u字段{
    //1.建造师
    函数_u构造(){
    ##A.设置
    //文本域
    $this->text_domain='aafields';
    //当前用户WP_用户对象
    $this->user=wp\u get\u current\u user();
    //管理员电子邮件
    $this->admin_email=get_选项(“admin_email”);
    //“系列”和“首选样式”的选项数组
    $this->fields\u options=array(
    //族可用选项阵列
    'family'=>数组(
    __(“没有孩子,$this->text\u域),
    __(“一个子“,$this->text\u域),
    __(“2个孩子,$this->text\u域),
    __(“3个或更多儿童,$this->text\u域),
    ),
    //首选样式可用选项阵列
    “首选_样式”=>数组(
    __(“样式1,$this->text\u域),
    __(“样式2,$this->text\u域),
    __(“样式3,$this->text\u域),
    __(“样式4”,$this->text\u域),
    ),
    );
    ##B.挂钩功能
    添加操作('woocommerce\u edit\u account\u form',数组('this,'add\u other\u fields\u in\u edit\u account\u form');
    添加操作('woocommerce\u save\u account\u details',数组($this,'sa
    
    add_action('woocommerce_save_account_details', array($this, 'woocommerce_send_notification'), 150, 1);
    
    function woocommerce_send_notification($user_id) {
        // Recipient
        $to = 'info@domain.com'; 
        
        $subject = 'Edit profile data';
    
        $user =      new WP_User($user_id);
        $user_name = $user->user_login;
        
        $phone  = get_user_meta( $user_id, 'field_5b4640119354c', true ); // Phone - text field
        $age    = get_user_meta( $user_id, 'field_5b462d304b101', true ); // Age- text field
        $family = get_user_meta( $user_id, 'field_5b4bd7d9f0031', true ); // Family - select field 
        $fstyle = get_user_meta( $user_id, 'field_5b47917a378ed', true ); // Favorited styles - Multiple Checkboxes 
    
         // Convert the array to a coma separated list (Favorited styles)
        $fstyle = implode( ', ',  $fstyle ); 
        
        // Body output
        $body = '<h3>'. __("Profile") .'</h3>
        <table>
        <tr><td>Login: </td><td>'.      $user->user_login         .'</td></tr>
        <tr><td>First Name: </td><td>'. $user->billing_first_name .'</td></tr>
        <tr><td>Last Name: </td><td>'.  $user->billing_last_name  .'</td></tr>
        <tr><td>Phone: </td><td>'.      $phone                    .'</td></tr>
        <tr><td>Age: </td><td>'.        $age                      .'</td></tr>
        <tr><td>Family: </td><td>'.     $family                   .'</td></tr>  
        <tr><td>What style do you prefer? </td><td>'. $fstyle     .'</td></tr> 
        </table>';
    
        //set content type as HTML
        $headers = array('Content-Type: text/html; charset=UTF-8;');
    
        //send email
        $sent = wp_mail( $to, $subject, $body, $headers );
    }
    
    if ( ! class_exists('WC_Additional_Account_fields') ) {
    
        class WC_Additional_Account_fields {
            // 1. Constructor
            function __construct() {
    
                ## A. Settings
    
                // The text domain
                $this->text_domain    = 'aafields';
    
                // The current user WP_User object
                $this->user           = wp_get_current_user();
    
                // The Admin email
                $this->admin_email    = get_option('admin_email');
    
                // The array of options for "Family" and "preferred style"
                $this->fields_options = array(
                    // FAMILY available options array
                    'family' => array(
                        __("No childs", $this->text_domain ),
                        __("One child", $this->text_domain ),
                        __("2 childs", $this->text_domain ),
                        __("3 or more childs", $this->text_domain ),
                    ),
                    // PREFERRED STYLE available options array
                    'preferred_styles' => array(
                        __("Style 1", $this->text_domain ),
                        __("Style 2", $this->text_domain ),
                        __("Style 3", $this->text_domain ),
                        __("Style 4", $this->text_domain ),
                    ),
                );
    
                ## B. Hooking functions
    
                add_action('woocommerce_edit_account_form', array($this, 'add_other_fields_in_edit_account_form') );
                add_action('woocommerce_save_account_details', array($this, 'save_other_fields_in_edit_account_form'), 15, 1);
                add_action('woocommerce_save_account_details_errors', array($this, 'validate_other_fields_in_edit_account_form'), 15, 1 );
                add_filter('woocommerce_customer_meta_fields', array($this, 'add_customer_meta_fields_to_admin_user_list'), 15, 1 );
            }
    
    
            // 1. Displaying additional account fields (+ jQuery script to handle checkboxes as radio buttons)
            public function add_other_fields_in_edit_account_form() {
                $text_domain = $this->text_domain;
                $user        = $this->user;
                $options     = $this->fields_options;
    
                $phone  = isset($user->phone) ? $user->phone : '';
                $age    = isset($user->billing_age) ? $user->billing_age : '';
                $family = isset($user->billing_family) ? $user->billing_family : '';
                $pstyle = isset($user->billing_pref_style) ? $user->billing_pref_style : '';
    
                // Inline styles
                ?>
                <style>
                    #billing_pref_style_field span.label {padding:0 12px 0 6px;}
                    div.clear {clear:both;margin-bottom:1.4em;}
                </style>
                <?php
    
                // Fields 1 and 2
                ?>
                <p class="woocommerce-form-row woocommerce-form-row--first form-row form-row-first">
                    <label for="phone"><?php _e( "Phone number", $text_domain ); ?><span class="required">*</span></label>
                    <input type="text" class="woocommerce-Input woocommerce-Input--text input-text" name="phone" id="phone" value="<?php echo $phone; ?>" />
                </p>
                <p class="woocommerce-form-row woocommerce-form-row--last form-row form-row-last">
                    <label for="billing_age"><?php _e( "Age", $text_domain ); ?><span class="required">*</span></label>
                    <input type="text" class="woocommerce-Input woocommerce-Input--text input-text" name="billing_age" id="billing_age" value="<?php echo $age; ?>" />
                </p>
                <?php
    
                // Fields 3 and 4 (Select field + Grouped checkboxes)
                ?>
                <p class="woocommerce-form-row woocommerce-form-row--last form-row form-row-first">
                    <label for="billing_family"><?php _e( "Family", $text_domain ); ?><span class="required">*</span></label>
                    <select id="billing_family" class="woocommerce-Select woocommerce-Select--option select" name="billing_family">
                        <option value=""><?php _e( "Select a value", $text_domain ); ?></option>
                        <?php
                            foreach( $options['family'] as $option ) :
                                $selected = ( $family == $option ) ? ' selected="selected"' : '';
                                echo '<option value="' . $option . '"' . $selected . '>' . $option . '</option>';
                            endforeach;
                        ?>
                    </select>
                </p>
                <p id="billing_pref_style_field" class="woocommerce-form-row woocommerce-form-row--last form-row form-row-last">
                    <label for="preferred_styles"><?php _e( "What style do you prefer? ", $text_domain ); ?><span class="required">*</span></label>
                        <?php
                            foreach( $options['preferred_styles'] as $key => $option ) :
                                $checked = $pstyle == $option ? ' checked="checked"' : '';
                                echo '<span><input type="checkbox" class="woocommerce-Input woocommerce-Input--checkbox input-checkbox" name="pref_style" value="' . $option . '"' . $checked . '><span class="label">' . $option . '</span></span>';
                            endforeach;
                        ?>
                    </select>
                    <?php $value = ! empty($pstyle) ? $pstyle : $options['preferred_styles'][0];
                    // Hidden field that catch the active checkbox value ?>
                    <input type="hidden"  name="billing_pref_style" value="<?php echo $value; ?>">
                </p>
                <div class="clear"></div>
                <?php
    
                // jQuery code: Enabling grouped checkboxes and passing the chosen value to the hidden field
                ?>
                <script type="text/javascript">
                jQuery(function($){
                    var a = '#billing_pref_style_field',        b = a+' input[type="checkbox"]',
                        c = a+' input[type="hidden"]';
    
                    $(b+'[value="'+$(c).val()+'"]').attr('checked', true);
                    $(b).click( function(){
                        var d = $(this).val();
                        $(c).val(d);
                        $(b).each( function( i, v ) {
                            if( d != $(v).val() ){
                                $(v).prop('checked', false);
                            } else {
                                $(v).prop('checked', true);
                            }
                        });
                    });
                });
                </script>
                <?php
            }
    
            // 2. Additional account fields validation
            public function validate_other_fields_in_edit_account_form( $args ){
                if ( isset($_POST['phone']) && empty($_POST['phone']) )
                    $args->add( 'error', __( 'Please fill in the "Phone" field', 'woocommerce' ),'');
    
                if ( isset($_POST['billing_age']) && empty($_POST['billing_age']) )
                    $args->add( 'error', __( 'Please fill in the "Age" field', 'woocommerce' ),'');
    
                if ( isset($_POST['billing_family']) && empty($_POST['billing_family']) )
                    $args->add( 'error', __( 'Please choose a value for the "Family" field', 'woocommerce' ),'');
    
                if ( isset($_POST['billing_pref_style']) && empty($_POST['billing_pref_style']) )
                    $args->add( 'error', __( 'Please choose a "Preferred style"', 'woocommerce' ),'');
            }
    
            // 3. Save custom additional fields value + Send custom email
            public function save_other_fields_in_edit_account_form( $user_id ) {
                $text_domain = $this->text_domain;
                $send_notification = false;
    
                if( isset( $_POST['phone'] ) ){
                    update_user_meta( $user_id, 'phone', sanitize_text_field( $_POST['phone'] ) );
                    update_user_meta( $user_id, 'billing_phone', sanitize_text_field( $_POST['phone'] ) );
                    if( ! empty( $_POST['phone'] ) )
                        $send_notification = true;
                }
    
                // For Favorite color 2
                if( isset( $_POST['billing_age'] ) ){
                    update_user_meta( $user_id, 'billing_age', sanitize_text_field( $_POST['billing_age'] ) );
                    if( ! empty( $_POST['billing_age'] ) )
                        $send_notification = true;
                }
    
                // For Billing email (added related to your comment)
                if( isset( $_POST['billing_family'] ) ){
                    update_user_meta( $user_id, 'billing_family', esc_attr( $_POST['billing_family'] ) );
                    if( ! empty( $_POST['billing_family'] ) )
                        $send_notification = true;
                }
    
                // For Billing email (added related to your comment)
                if( isset( $_POST['billing_pref_style'] ) ){
                    update_user_meta( $user_id, 'billing_pref_style', esc_attr( $_POST['billing_pref_style'] ) );
                    if( ! empty( $_POST['billing_pref_style'] ) )
                        $send_notification = true;
                }
    
                if( $send_notification ){
                    $user = new WP_User($user_id);
    
                    $to = $this->admin_email;
                    $subject = __('Edited profile data for: ') . $user->billing_first_name . ' ' . $user->billing_last_name;
    
                    $body = '<h3>' . __("Profile", $text_domain ) . '</h3>
                    <table>
                    <tr><th align="left">' . __("Login:", $text_domain ) . '</th><td>'. $user->user_login . '</td></tr>
                    <tr><th align="left">' . __("First Name:", $text_domain ) . ' </th><td>' . $user->billing_first_name . '</td></tr>
                    <tr><th align="left">' . __("Last Name:", $text_domain ) . ' </th><td>' . $user->billing_last_name . '</td></tr>
                    <tr><th align="left">' . __("Phone:", $text_domain ) . ' </th><td>' . $user->phone . '</td></tr>
                    <tr><th align="left">' . __("Age:", $text_domain ) . ' </th><td>' . $user->billing_age . '</td></tr>
                    <tr><th align="left">' . __("Family:", $text_domain ) . ' </th><td>' . $user->billing_family . '</td></tr>
                    <tr><th align="left">' . __("Preferred style", $text_domain ) . ' </th><td>' . $user->billing_pref_style . '</td></tr>
                    </table>';
    
                    //set content type as HTML
                    $headers = array('Content-Type: text/html; charset=UTF-8;');
    
                    //send email
                    wp_mail($to, $subject, $body, $headers);
                }
            }
    
            // 4. Add the additional fields in admin user list in the billing section
            public function add_customer_meta_fields_to_admin_user_list( $args ) {
                $domain  = $this->text_domain;
                $options = $this->fields_options;
    
                // Age
                $args['billing']['fields']['billing_age'] = array(
                    'label'       => __( "Age", $text_domain ),
                    'description' => '',
                );
    
                // Family
                $args['billing']['fields']['billing_family'] = array(
                    'label'       => __( 'Family', 'woocommerce' ),
                    'description' => '',
                    'type'        => 'select',
                    'options'     => array( '' => __( 'Select a value', $domain ) ) + array_combine($options['family'], $options['family']),
                );
    
                // Preferred styles
                $args['billing']['fields']['billing_pref_style'] = array(
                    'label'       => __( 'Preferred styles', 'woocommerce' ),
                    'description' => '',
                    'type'        => 'select',
                    'options'     => array( '' => __( 'Select a value', $domain ) ) + array_combine($options['preferred_styles'], $options['prefered_styles']),
                );
    
                return $args;
            }
        }
        new WC_Additional_Account_fields();
    }