问题
I have the below custom metakey which is an optin checkbox during checkout:
//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;
}
}
So above is working and shows below the column, but I would like to have a filter in the admin bar and a search for Signed Up gives the desired result:
- The search is not working, because the value of the checkbox for
checked
is 1 and does not resognise other words. I have added below, but it's not giving the result:
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;
}
- The admin bar filter; the only related posts I could find are all about order statuses and not a custom metakey. I am not sure how to add this correctly, I started with the below, but there are obvious errors, and I am stuck.
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 ;
}
回答1:
I have revisited your existing code a bit and added a dropdown filter for the "marketing optin" custom field:
//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;
}
Note: I have change the order meta_key to _marketing_opting
starting with an underscore as most other existing metakeys...
Also I have added a function that register that "marketing optin" value in user meta data, as it will be used by checkout on WC()->checkout->get_value( 'marketing_opting' )
for customers that have already made an order.
Field validation (optional)
If you make this checkout field required, you will need field validation… Then add the following:
// 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' ); } }
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
来源:https://stackoverflow.com/questions/61684222/add-a-dropdown-filter-for-a-custom-metakey-on-woocommerce-admin-orders