根据Woocommerce自定义结帐选择字段将CPT数据保存到订单中

时间:2018-04-03 14:01:25

标签: php wordpress woocommerce advanced-custom-fields checkout

在WooCommerce中,我正在开发一个从自定义帖子类型(CTP)中提取姓名和地址的插件。我想将它们加载到自定义结帐下拉字段中,我已经完成了所有工作。

但我需要做的是将来自CTP的信息加载到'options'数组中,如下所示:

我已经完成了大部分代码,我现在唯一的问题就是让它加载这个CPT中的所有帖子(有四个)。现在它只加载“请选择一些东西......”和一个帖子(最近的一个)。我的代码如下:

*修订代码*

add_filter( 'woocommerce_checkout_fields' , 'add_addressbook_checkout_field', 20, 1 );
function add_addressbook_checkout_field( $fields ) {

    $options = array();

    // First option
    $options[0] = 'Please select something…';

// Get 'addressbook' posts
    // $posts = array();
    $args = array('post_type'=>'addressbook', 'posts_per_page'=>3000,'order'=>'asc');
    $query = New WP_Query($args);
    if($query->have_posts()):while($query->have_posts()):$query->the_post();

        $temp = array();
        $temp['id'] = get_the_id();
        $temp['fname'] = get_field('fname');
        $temp['lname'] = get_field('lname');
        $temp['company'] = get_field('company');
        $posts = $temp;

    endwhile;endif;wp_reset_postdata();

// Loop through 'addressbook' posts (to set all other select options)
foreach( $posts as $post ){
    // Set each complete name as an option (Where key is the post ID)
    // $options[$posts['id']] = $posts['fname','id'] . ' ' . $posts['lname','id'] . ' ' . $posts['company','id'];
            $options[$post->ID] = $posts['fname'] . ' ' . $posts['lname'] . ', ' . $posts['company'];
}
    //, $post->ID

$fields['shipping']['addressbook'] = array(
    'type'          => 'select',
    'label'         => __('Address Book', 'woocommerce'),
    'placeholder'   => _x('Pick an address', 'placeholder', 'woocommerce'),
    'options'       =>  $options, // Here we set the options
    'required'      => false,
    'priority'      => 1,
    'class'         => array('form-row-wide'),
    'clear'         => true
);

return $fields;
}

更新

我有填充select选项的地址列表,现在我只需要使用AJAX和查询结果填充表单的其余部分。代码如下:     //广告'地址簿'自定义结帐选择字段

add_filter( 'woocommerce_checkout_fields' , add_addressbook_checkout_field', 20, 1 );

function add_addressbook_checkout_field( $fields ) {

    $options = array();

    // First option
    $options[0] = 'Please select something…';

// Get 'addressbook' posts
    $posts = array();
    $args = array('post_type'=>'addressbook', 'posts_per_page'=>-1,'order'=>'asc');
    $query = New WP_Query($args);
    if($query->have_posts()):while($query->have_posts()):$query->the_post();

        $temp = array();
        $temp['id'] = get_the_id();
        $temp['fname'] = get_field('fname');
        $temp['lname'] = get_field('lname');
        $temp['company'] = get_field('company');
        $temp['addr1'] = get_field('address_line_1');
        $temp['addr2'] = get_field('address_line_2');
        $temp['city'] = get_field('city');
        $temp['state'] = get_field('state');
        $temp['zip'] = get_field('zip');
        $posts = $temp;

        $id             =   $posts['id'];
        $fname      = $posts['fname'];
        $lname      = $posts['lname'];
        $company    = $posts['company'];
        $addr1      = $posts['addr1'];
        $addr2      = $posts['addr2'];
        $city       = $posts['city'];
        $state      = $posts['state'];
        $zip            = $posts['zip'];
        // Loop through 'addressbook' posts (to set all other select options)
    foreach( $posts as $post ){
        // Set each complete name as an option (Where key is the post ID)
        $options[$id] = $company  . ', '. $fname  . ' '. $lname . ', ' . $addr1 . '....';
    }

    endwhile;endif;wp_reset_postdata();
    $fields['shipping']['addressbook'] = array(
    'type'          => 'select',
    'label'         => __('Address Book', 'woocommerce'),
    'placeholder'   => _x('Pick an address', 'placeholder', 'woocommerce'),
    'options'       =>  $options, // Here we set the options
    'required'      => false,
    'priority'      => 1,
    'class'         => array('form-row-wide'),
    'clear'         => true
);

return $fields;

}
// process custom checkout field
add_action('woocommerce_checkout_process', 'check_addressbook_checkout_field', 20 );

function check_addressbook_checkout_field( $order, $data ) {

    if ( isset($_POST['addressbook']) && empty($_POST['addressbook']) )

            wc_add_notice( __("Please pick an address from the Address Book"),

    'error' );

}

// Add custom meta data (or existing change data) to the order before saving 
//it

add_action('woocommerce_checkout_create_order',
'set_meta_data_in_checkout_create_order', 20, 2 );
function set_meta_data_in_checkout_create_order( $order, $data ) {

  if ( isset($_POST['addressbook']) ){
    // Set the meta data in the order

        if( ! empty($fname) )
        $order->update_meta_data( 'ab_fname', esc_attr( $fname ) );

        if( ! empty($lname) )
        $order->update_meta_data( 'ab_lname', esc_attr( $lname ) );

        if( ! empty($company) )
        $order->update_meta_data( 'ab_company', esc_attr( $company ) );

        if( ! empty($addr1) )
        $order->update_meta_data( 'ab_addr1', esc_attr( $addr1 ) );

        if( ! empty($addr2) )
        $order->update_meta_data( 'ab_addr2', esc_attr( $addr2 ) );

        if( ! empty($city) )
        $order->update_meta_data( 'ab_city', esc_attr( $city ) );

        if( ! empty($state) )
        $order->update_meta_data( 'ab_state', esc_attr( $state ) );

        if( ! empty($zip) )
        $order->update_meta_data( 'ab_zip', esc_attr( $zip ) );

  }

}
?>

<script>

</script>

1 个答案:

答案 0 :(得分:0)

首先,不要使用ACF函数the_field()作为此函数echo的值,而应使用ACF函数get_field()代替在变量或某些PHP代码中设置值。

也无法在<option>中加载所有数据...您需要选择一些并将其包装为字符串...所以我选择了完整的名称作为与帖子相关的显示值ID选项键。然后使用该选项密钥(来自CTP的帖子ID),可以轻松检索相关数据......

然后是这样做的方法:

  1. 第一个功能将添加您的自定义结帐字段
  2. 第二个函数将检查自定义字段是否为空
  3. 第三个函数将获取相关数据并将其作为自定义元数据添加到订单
  4. 代码:

    // Ad 'addressbook' custom checkout select field
    add_filter( 'woocommerce_checkout_fields' , 'add_address_book_checkout_field', 20, 1 );
    function add_address_book_checkout_field( $fields ) {
        if ( ! is_ssl() ) return $fields; // if needed (?)
    
        // Get 'addressbook' posts
        $addressbook_posts = get_post(array('post_type'=>'addressbook', 'posts_per_page' => -1 ));
        // First option
        $options = array( '' => 'Please select something…');
    
        // Loop through 'addressbook' posts (to set all other select options)
        foreach( $addressbook_posts as $post ){
            // Set each complete name as an option (Where key is the post ID)
            $options[$post->ID] = get_field( 'fname', $post->ID ) . ' ' . get_field( 'lname', $post->ID );
        }
    
        $fields['shipping']['address_book'] = array(
            'type'          => 'select',
            'label'         => __('Address Book', 'woocommerce'),
            'placeholder'   => _x('Pick an address', 'placeholder', 'woocommerce'),
            'options'       =>  $options, // Here we set the options
            'required'      => false,
            'priority'      => 1,
            'class'         => array('form-row-wide'),
            'clear'         => true
        );
    
        return $fields;
    }
    
    // process custom checkout field
    add_action('woocommerce_checkout_process', 'check_address_book_checkout_field', 20 );
    function check_address_book_checkout_field( $order, $data ) {
        if ( isset($_POST['address_book']) && empty($_POST['address_book']) )
            wc_add_notice( __("Please pick an address from the Address Book"), 'error' );
    }
    
    // Add custom meta data (or existing change data) to the order before saving it
    add_action('woocommerce_checkout_create_order', 'set_meta_data_in_checkout_create_order', 20, 2 );
    function set_meta_data_in_checkout_create_order( $order, $data ) {
        if ( isset($_POST['address_book']) ){
            // The selected "Adress book" Post ID
            $post_id = $_POST['address_book'];
    
            // Get the data for the selected "Adress book" Post ID
            $fname      = get_field( 'fname', $post_id );
            $lname      = get_field( 'lname', $post_id );
            $company    = get_field( 'company', $post_id );
            $addr1      = get_field( 'address_line_1', $post_id );
            $addr2      = get_field( 'address_line_2', $post_id );
            $city       = get_field( 'city', $post_id );
            $state      = get_field( 'state', $post_id );
            $zip        = get_field( 'zip', $post_id );
    
            // Set the meta data in the order
            if( ! empty($fname) )
                $order->update_meta_data( 'ab_fname', esc_attr( $fname ) );
            if( ! empty($lname) )
                $order->update_meta_data( 'ab_lname', esc_attr( $lname ) );
            if( ! empty($company) )
                $order->update_meta_data( 'ab_company', esc_attr( $company ) );
            if( ! empty($addr1) )
                $order->update_meta_data( 'ab_addr1', esc_attr( $addr1 ) );
            if( ! empty($addr2) )
                $order->update_meta_data( 'ab_addr2', esc_attr( $addr2 ) );
            if( ! empty($city) )
                $order->update_meta_data( 'ab_city', esc_attr( $city ) );
            if( ! empty($state) )
                $order->update_meta_data( 'ab_state', esc_attr( $state ) );
            if( ! empty($zip) )
                $order->update_meta_data( 'ab_zip', esc_attr( $zip ) );
        }
    }
    

    代码放在活动子主题(或活动主题)的function.php文件中。它应该工作。