【问题标题】:Add a dropdown Filter for a custom metakey on WooCommerce admin orders为 WooCommerce 管理员订单上的自定义元键添加下拉过滤器
【发布时间】:2020-08-24 07:25:40
【问题描述】:

我有以下自定义元键,它是结帐期间的一个选择复选框:

//1. ADD OPT IN OPTION IN CHECKOUT AND SAVE IN THE ORDER

// Add checkbox optin before T&Cs
add_action( 'woocommerce_checkout_before_terms_and_conditions', 'marketing_opting_field' );
function marketing_opting_field() {
    echo '<div id="marketing_opting_field">';
    woocommerce_form_field( 'marketing_opting', array(
        'type'      => 'checkbox',
        'class'     => array('input-checkbox'),
        'label'     => __('Yes, sign me up'),
        'default'   => 1,
    ),  WC()->checkout->get_value( 'marketing_opting' ) );
    echo '</div>';
}

// Save the optin field in the order meta, when checkbox has been checked
add_action( 'woocommerce_checkout_update_order_meta', 'custom_checkout_field_update_order_meta', 10, 1 );
function custom_checkout_field_update_order_meta( $order_id ) {
    if ( ! empty( $_POST['marketing_opting'] ) )
        update_post_meta( $order_id, 'marketing_opting', $_POST['marketing_opting'] );
}

// Display the result of the checked optin in the order under billing address
add_action( 'woocommerce_admin_order_data_after_billing_address', 'display_custom_field_on_order_edit_pages', 10, 1 );
function display_custom_field_on_order_edit_pages( $order ){
    $marketing_opting = get_post_meta( $order->get_id(), 'marketing_opting', true );
    if( $marketing_opting == 1 )
        echo '<p><strong>Has opted in for marketing purposes.</p>';
}

// 2. SHOW CUSTOM COLUMN FOR THE OPTIN OPTION

// Adding custom column title
add_filter( 'manage_edit-shop_order_columns', 'custom_shop_order_column', 12, 1 );
function custom_shop_order_column($columns)
{
    $action_column = $columns['order_actions'];
    unset($columns['order_actions']);
    //add the new column "Opt in"
    $columns['order_marketing'] = '<p align="center">Opted in?</p>'; // title
    $columns['order_actions'] = $action_column;
    return $columns;
}

// Add the data for each order
add_action( 'manage_shop_order_posts_custom_column' , 'custom_order_list_column_content', 10, 2 );
function custom_order_list_column_content( $column, $post_id ){
    $marketing_opting = get_post_meta( $post_id, 'marketing_opting', true );
    if( $marketing_opting == 1)
    switch($column){
        case 'order_marketing' : echo '<p align="center"><span class="dashicons dashicons-yes"></span><span style="color: #F21891; font-weight: 600;">Signed Up</span></p>';
        break;
    }
}

所以上面的工作并显示在列下方,但我想在管理栏中有一个过滤器,搜索 Signed Up 会得到所需的结果:

  1. 搜索不工作,因为checked 复选框的值为1 并且不识别其他词。我在下面添加了,但没有给出结果:
add_filter( 'woocommerce_shop_order_search_fields', 'marketing_search_fields', 10, 1 );
function marketing_search_fields( $meta_keys ){
    $meta_keys[] = 'marketing_opting';
    return $meta_keys;
}

  1. 管理栏过滤器;我能找到的唯一相关帖子都是关于订单状态的,而不是自定义元键。我不知道如何正确添加这个,我从下面开始,但是有明显的错误,我被卡住了。
add_filter( 'views_edit-shop_order' , 'marketing_opt_in_filter', 10, 1);
function marketing_opt_in_filter( $views ) {
    $marketing_opting = get_post_meta( $post_id, 'marketing_opting', true );
    if( $marketing_opting == 1)
    $query_string = admin_url( 'edit.php?post_type=shop_order' ) ;
    $query_string = add_query_arg( 'marketing_opting' , 'yes' , $query_string ) ;
    $views[ 'marketing_opting' ] = '<a href="' . esc_url( $query_string ) . '">Opted In (%s)</a>' ;
    return $views ;
}

【问题讨论】:

    标签: php wordpress woocommerce checkout orders


    【解决方案1】:

    我重新审视了您现有的代码,并为“marketing optin”自定义字段添加了一个下拉过滤器:

    //1. ADD OPT IN OPTION IN CHECKOUT AND SAVE IN THE ORDER
    
    // Add checkbox optin before T&Cs
    add_action( 'woocommerce_checkout_before_terms_and_conditions', 'marketing_opting_field' );
    function marketing_opting_field() {
        echo '<div id="marketing_opting_field">';
        woocommerce_form_field( 'marketing_opting', array(
            'type'      => 'checkbox',
            'class'     => array('input-checkbox'),
            'label'     => __('Yes, sign me up'),
            'default'   => 1,
        ),  WC()->checkout->get_value( 'marketing_opting' ) );
        echo '</div>';
    }
    
    // Save the optin field as custom order meta, when checkbox has been checked
    add_action( 'woocommerce_checkout_create_order', 'action_checkout_update_order_meta', 10, 2 );
    function action_checkout_update_order_meta( $order, $data ) {
        if( isset($_POST['marketing_opting']) )
            $order->update_meta_data( '_marketing_opting', empty($_POST['marketing_opting']) ? 'no' : 'yes' );
    }
    
    // Save the optin field as custom user meta, when checkbox has been checked
    add_action( 'woocommerce_checkout_update_customer', 'action_checkout_update_customer_meta', 10, 2 );
    function action_checkout_update_customer_meta( $customer, $data ) {
        if( isset($_POST['marketing_opting']) )
            $customer->update_meta_data( 'marketing_opting', empty($_POST['marketing_opting']) ? 'no' : 'yes' );
    }
    
    // Display the result of the checked optin in the order under billing address
    add_action( 'woocommerce_admin_order_data_after_billing_address', 'display_custom_field_on_order_edit_pages', 10, 1 );
    function display_custom_field_on_order_edit_pages( $order ){
        if( $order->get_meta( '_marketing_opting' ) === 'yes' )
            echo '<p><strong>Has opted in for marketing purposes.</p>';
    }
    
    // 2. SHOW CUSTOM COLUMN FOR THE OPTIN OPTION
    
    // Adding custom column title
    add_filter( 'manage_edit-shop_order_columns', 'custom_shop_order_column', 12, 1 );
    function custom_shop_order_column($columns)
    {
        $action_column = $columns['order_actions'];
        unset($columns['order_actions']);
    
        //add the new column "Opt in"
        $columns['order_marketing'] = '<div align="center">' .__("Opted in?") . '</div>'; // title
        $columns['order_actions'] = $action_column;
    
        return $columns;
    }
    
    // Add the data for each order
    add_action( 'manage_shop_order_posts_custom_column' , 'custom_order_list_column_content', 10, 2 );
    function custom_order_list_column_content( $column, $post_id ){
        global $post, $the_order;
    
    
        if ($column ==='order_marketing') { 
            $value = $the_order->get_meta( '_marketing_opting' );
            $label = $value === 'yes' ? __('Signed Up') : ucfirst($value);
            $color = $value === 'yes' ? 'color:#00cc00;' : 'color:#bbbbbb;';
    
            echo '<p align="center" style="'.$color.'"><span class="dashicons dashicons-'.$value.'"></span><span style="font-weight:600;">'.$label.'</span></p>';
        }
    }
    
    // 3. Make marketing optin meta searchable from search field (can't work very well for 'yes' or 'no' values!)
    
    // Make a custom meta field searchable from the admin order list search field
    add_filter( 'woocommerce_shop_order_search_fields', 'marketing_search_fields', 10, 1 );
    function marketing_search_fields( $meta_keys ){
        $meta_keys[] = '_marketing_opting';
        return $meta_keys;
    }
    
    // 4. Add a dropdown filter to get orders by marketing optin meta value
    
    // Add a dropdown to filter orders by Marketing optin
    add_action( 'restrict_manage_posts', 'display_admin_shop_order_marketing_opting_filter' );
    function display_admin_shop_order_marketing_opting_filter(){
        global $pagenow, $post_type;
    
        if( 'shop_order' === $post_type && 'edit.php' === $pagenow ) {
            $domain    = 'woocommerce';
            $current   = isset($_GET['filter_shop_order_marketing'])? $_GET['filter_shop_order_marketing'] : '';
    
            echo '<select name="filter_shop_order_marketing">
            <option value="">' . __('Filter Marketing optin', $domain) . '</option>';
    
            $options = ['yes' => __('Signed Up'), 'no' => __('No')];
    
            foreach ( $options as $key => $label ) {
                printf( '<option value="%s"%s>%s</option>', $key, 
                    $key === $current ? '" selected="selected"' : '', $label );
            }
            echo '</select>';
        }
    }
    
    // Process the filter dropdown for orders by Marketing optin
    add_filter( 'request', 'process_admin_shop_order_marketing_opting_filter', 99 );
    function process_admin_shop_order_marketing_opting_filter( $vars ) {
        global $pagenow, $typenow;
    
        if ( $pagenow == 'edit.php' && isset( $_GET['filter_shop_order_marketing'] ) 
            && $_GET['filter_shop_order_marketing'] != '' && 'shop_order' === $typenow ) {
            $vars['meta_key']   = '_marketing_opting';
            $vars['meta_value'] = wc_clean( $_GET['filter_shop_order_marketing'] );
        }
        return $vars;
    }
    

    注意:我已将 meta_key 的顺序更改为 _marketing_opting,与大多数其他现有元键一样,以下划线开头...

    我还添加了一个在用户元数据中注册“marketing optin”值的函数,因为它会在WC()-&gt;checkout-&gt;get_value( 'marketing_opting' ) 上为已经下单的客户结帐时使用。

    字段验证(可选)

    如果您将此结帐字段设为必填,则需要进行字段验证...然后添加以下内容:

    // Custom Checkout field validation
    add_action('woocommerce_checkout_process', 'custom_checkout_field_validation');
    function custom_checkout_field_validation() {
        if ( isset($_POST['marketing_opting']) ) {
            wc_add_notice( '<strong>'. __("Please select a value", "woocommerce") . '</strong> | '.$_POST['marketing_opting'], 'error' );
        }
    }    
    

    代码在您的活动子主题(或活动主题)的functions.php 文件中。经过测试并且可以工作。

    【讨论】:

    • 非常感谢,我现在正在测试这个,第一个问题:为什么要添加Custom Checkout field validation?对我来说,它是选中或未选中的复选框,所以不需要验证对吗?
    • 我在检查时也面临后端错误,因为它声明“添加值1”,我认为这与我之前的问题有关。当我消除验证时,它会引发内部服务器错误。
    • 我删除了,我收到 wc-admin ajax 的内部服务器错误,请参阅我的第二条评论:http://prnt.sc/sf8lam。它在代码中的某个地方,因为没有它结帐工作。
    • @Demian 抱歉,我在结帐时没有测试字段本身……我已经更新了我的代码……再试一次。
    猜你喜欢
    • 2021-12-03
    • 2018-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多