I'm trying to display the attribute description of an attribute on a single product page in an accordeon. I've read a lot of tutorials and about term description, i tried it via ACF fields, but i didnt' find a way to handle this.
I found this thread here on stackoverflow but it is just for the title of an attribute: Woocommerce - Display single product attribute(s) with shortcodes in Frontend
Is there a solution to display the descripton of an attribute in Woocommerce as a shortcode? Maybe there is one standard woocommerce shortcode?
Here is an example code, I am not making an accordion here, but I am providing $values array with term_id, name, slug & description You can use the array and create an accordion with your own design.
/**
* Callback to `vkh_display_attribute_accordian` shortcode.
*
* #param array $atts Shortcode attributes.
* #return string Shortcode output.
* #throws Exception Throws an error when available.
*/
function vkh_display_attribute_accordian_shortcode( $atts ) {
// Don't run if admin page or not a single product page.
if ( is_admin() || ! is_product() ) {
return;
}
// Prepare shortcode attributes.
$atts = shortcode_atts(
array(
'name' => '',
),
$atts,
'vkh_display_attribute_accordian'
);
try {
if ( empty( $atts['name'] ) ) {
throw new Exception( __( 'Please pass the attribute slug as name attribute. e.g. [vkh_display_attribute_accordian name="#YOUR_ATTRIBUTE_SLUG"].', 'text-domain' ) );
}
global $product;
$attributes = $product->get_attributes();
if ( empty( $attributes ) ) {
throw new Exception( __( 'Product does not have any attributes.', 'text-domain' ) );
}
$selected_attr = '';
foreach ( $attributes as $attribute ) {
if ( $attribute->is_taxonomy() && $attribute->get_name() === $atts['name'] ) {
$selected_attr = $attribute;
break;
}
}
if ( empty( $selected_attr ) || ! $selected_attr->is_taxonomy() ) {
throw new Exception( __( 'Unable to find matching attributes.', 'text-domain' ) );
}
$attribute_values = wc_get_product_terms( $product->get_id(), $attribute->get_name(), array( 'fields' => 'all' ) );
if ( empty( $attribute_values ) ) {
throw new Exception( __( 'Product does not have any attribute values.', 'text-domain' ) );
}
$values = array_map(
function( $_term ) {
return (object) array(
'term_id' => $_term->term_id,
'name' => $_term->name,
'slug' => $_term->slug,
'description' => term_description( $_term ),
);
},
$attribute_values
);
ob_start();
var_dump( $values );
$content = ob_get_clean();
return '<pre>'.$content.'</pre>';
} catch ( Exception $e ) {
if ( $e->getMessage() ) {
if ( current_user_can( 'manage_options' ) ) {
return '<p>' . esc_html( $e->getMessage() ) . '</p>';
}
}
}
}
add_shortcode( 'vkh_display_attribute_accordian', 'vkh_display_attribute_accordian_shortcode' );
I want to change the download_url on My account downloads section in WooCommerce
current url: http://localhost/i/?download_file=
new url: http://localhost/i/account/downloads/?download_file=
Therefore I changed home_url( '/' ) to home_url( '/account/downloads/' ) using the hook below:
function filter_woocommerce_customer_available_downloads( $downloads, $customer_id ) {
$downloads = array();
$_product = null;
$order = null;
$file_number = 0;
// Get results from valid orders only.
$results = wc_get_customer_download_permissions( $customer_id );
if ( $results ) {
foreach ( $results as $result ) {
$order_id = intval( $result->order_id );
if ( ! $order || $order->get_id() !== $order_id ) {
// New order.
$order = wc_get_order( $order_id );
$_product = null;
}
// Make sure the order exists for this download.
if ( ! $order ) {
continue;
}
// Check if downloads are permitted.
if ( ! $order->is_download_permitted() ) {
continue;
}
$product_id = intval( $result->product_id );
if ( ! $_product || $_product->get_id() !== $product_id ) {
// New product.
$file_number = 0;
$_product = wc_get_product( $product_id );
}
// Check product exists and has the file.
if ( ! $_product || ! $_product->exists() || ! $_product->has_file( $result->download_id ) ) {
continue;
}
$download_file = $_product->get_file( $result->download_id );
// If the downloadable file has been disabled (it may be located in an untrusted location) then do not return it.
if ( ! $download_file->get_enabled() ) {
continue;
}
// Download name will be 'Product Name' for products with a single downloadable file, and 'Product Name - File X' for products with multiple files.
$download_name = apply_filters(
'woocommerce_downloadable_product_name',
$download_file['name'],
$_product,
$result->download_id,
$file_number
);
$downloads[] = array(
'download_url' => add_query_arg(
array(
'download_file' => $product_id,
'order' => $result->order_key,
'email' => rawurlencode( $result->user_email ),
'key' => $result->download_id,
),
home_url( '/account/downloads/' )
),
'download_id' => $result->download_id,
'product_id' => $_product->get_id(),
'product_name' => $_product->get_name(),
'product_url' => $_product->is_visible() ? $_product->get_permalink() : '', // Since 3.3.0.
'download_name' => $download_name,
'order_id' => $order->get_id(),
'order_key' => $order->get_order_key(),
'downloads_remaining' => $result->downloads_remaining,
'access_expires' => $result->access_expires,
'file' => array(
'name' => $download_file->get_name(),
'file' => $download_file->get_file(),
),
);
$file_number++;
}
}
return $downloads;
} add_filter( 'woocommerce_customer_available_downloads', 'filter_woocommerce_customer_available_downloads', 10, 2 );
Code is based on the wc_get_customer_available_downloads( $customer_id ) function, which can be found in /includes/wc-user-functions.php file
Is it possible to summarize the hook?
The woocommerce_customer_available_downloads filter hook does indeed allow you to change download_url, however it is not necessary to rewrite the entire function via the hook, as you only want to change a certain part.
This can be done using the following code, which uses str_replace() in the code :
/**
* Function for `woocommerce_customer_available_downloads` filter-hook.
*
* #param $downloads
* #param $customer_id
*
* #return
*/
function filter_woocommerce_customer_available_downloads( $downloads, $customer_id ) {
// Only on my account downloads section
if ( ! is_wc_endpoint_url( 'downloads' ) )
return $downloads;
// Loop though downloads
foreach( $downloads as $key => $download ) {
// Replace
$downloads[$key]['download_url'] = str_replace( '/?download_file', '/account/downloads/?download_file', $download['download_url'] );
}
return $downloads;
}
add_filter( 'woocommerce_customer_available_downloads', 'filter_woocommerce_customer_available_downloads', 10, 2 );
I have a wordpress plugin that I'm looking to call one of the functions on a custom template. The function I want to call is get_ship_now_adjust_date_link.
Is it possible to just do the following on a template:
echo get_ship_now_adjust_date_link( $subscription['id'] );
Here's the plugins full code:
<?php
namespace Javorszky\Toolbox;
add_filter( 'wcs_view_subscription_actions', __NAMESPACE__ . '\\add_ship_reschedule_action', 10, 2 );
add_action( 'wp_loaded', __NAMESPACE__ . '\\handle_ship_now_adjust_date_request' );
/**
* Extra actions on the subscription. Only there if the subscription is active.
*
* #param array $actions existing actions on the subscription
* #param \WC_Subscription $subscription the subscription we're adding new actions to
* #return array $actions
*/
function add_ship_reschedule_action( $actions, $subscription ) {
$next_timestamp = $subscription->get_time( 'next_payment' );
if ( 0 != $next_timestamp && 'active' == $subscription->get_status() ) {
$new_actions = array(
'ship_now_recalculate' => array(
'url' => get_ship_now_adjust_date_link( $subscription ),
'name' => Utilities\replace_key_dates( Utilities\get_button_text( 'ship_reschedule_button_text', 'Ship now and recalculate from today' ), $subscription ),
),
);
$actions = array_merge( $actions, $new_actions );
}
return $actions;
}
/**
* URL to be used on the "Ship now and adjust the date" button.
*
* #param \WC_Subscription $subscription Subscription we're getting the link for
* #return string URL to trigger shipping now and keeping the date with
*/
function get_ship_now_adjust_date_link( $subscription ) {
if ( version_compare( \WC_Subscriptions::$version, '2.6.0', '>=' ) ) {
$completed_payments = $subscription->get_payment_count('completed');
} else {
$completed_payments = $subscription->get_completed_payment_count();
}
$action_link = Utilities\strip_custom_query_args();
$action_link = add_query_arg( array( 'subscription_id' => $subscription->get_id(), 'ship_now_adjust_date' => 1 ), $action_link );
$action_link = wp_nonce_url( $action_link, $subscription->get_id() . '_completed_adjust_' . $completed_payments );
return $action_link;
}
/**
* Hooked into `wp_loaded`, this is responsible for charging the subscription now and adjusting the date if certain
* GET variables are present.
*/
function handle_ship_now_adjust_date_request() {
if ( isset( $_GET['ship_now_adjust_date'] ) && isset( $_GET['subscription_id'] ) && isset( $_GET['_wpnonce'] ) && !isset( $_GET['wc-ajax'] ) ) {
$user_id = get_current_user_id();
$subscription = wcs_get_subscription( $_GET['subscription_id'] );
$nonce = $_GET['_wpnonce'];
if ( Utilities\Process\process_ship_now_adjust_date( $user_id, $subscription, $nonce ) ) {
wc_add_notice( _x( 'Your order has been placed!', 'Notice after ship now adjust date request succeeded.', 'jg-toolbox' ) );
wp_safe_redirect( wc_get_endpoint_url( 'view-subscription', $subscription->get_id(), wc_get_page_permalink( 'myaccount' ) ) );
exit;
}
}
}
try to use \Javorszky\Toolbox\get_ship_now_adjust_date_link
I have a WordPress Woo-commerce store with the Pro version of the delivery drivers for woo-commerce plugin (https://wordpress.org/plugins/delivery-drivers-for-woocommerce/).
Everything works fine as any user who is of user role : 'delivery driver' can view and claim all orders that are processed through the website, at the moment using woo-commerce delivery/shipping zones settings I have configured it so only customers who reside in a certain city can place an order and I am only approving delivery drivers in that area.
But I want to roll this out to other cities, I can add the postcodes so users can order from those postcodes but the problem is with the delivery drivers plugin - drivers will see all orders from all cities in their dashboard. I only want the drivers to view and claim orders in the city they reside in (the city they have assigned themselves to).
Here is the code to the functionality that displays all orders placed on the website to user role type 'delivery driver' :
driver-dashboard-shortcode.php
<?php
/**
* The Unclaimed Orders Shortcode.
**/
function ddwc_pro_dashboard_shortcode() {
// Check if user is logged in.
if ( is_user_logged_in() ) {
// Get the user ID.
$user_id = get_current_user_id();
// Get the user object.
$user_meta = get_userdata( $user_id );
// If user_id doesn't equal zero.
if ( 0 != $user_id ) {
// If claim delivery button is pushed.
if ( ! empty( $_GET['claim_delivery'] ) ) {
// Get deliver ID to claim.
$claim_delivery = $_GET['claim_delivery'];
// Update order status.
$order = wc_get_order( $claim_delivery );
$order->update_status( 'driver-assigned' );
// Update order with driver ID.
update_post_meta( $claim_delivery, 'ddwc_driver_id', $user_id, -1 );
// Redirect URL.
$redirect_url = apply_filters( 'ddwc_pro_claim_order_redirect_url', get_permalink( get_option( 'woocommerce_myaccount_page_id' ) ) . '/driver-dashboard/?orderid=' . $claim_delivery, $claim_delivery );
// Redirect driver to the order details.
wp_redirect( $redirect_url );
}
// Get all the user roles as an array.
$user_roles = $user_meta->roles;
// Check if the role you're interested in, is present in the array.
if ( in_array( 'driver', $user_roles, true ) ) {
// Set variable for driver ID.
if ( isset( $_GET['orderid'] ) && ( '' != $_GET['orderid'] ) ) {
$driver_id = get_post_meta( $_GET['orderid'], 'ddwc_driver_id', true );
}
/**
* Args for Orders with no driver ID attached.
*/
$args = array(
'post_type' => 'shop_order',
'posts_per_page' => -1,
'post_status' => 'any',
'post_parent' => 0
);
/**
* Get Orders with Driver ID attached
*/
$unclaimed_orders = get_posts( $args );
/**
* If there are orders to loop through.
*/
if ( $unclaimed_orders ) {
// Total for table thead.
$total_title = '<td>' . esc_attr__( 'Total', 'ddwc' ) . '</td>';
do_action( 'ddwc_pro_unclaimed_orders_table_before' );
echo '<table class="ddwc-dashboard">';
echo '<thead><tr><td>' . esc_attr__( 'Date', 'ddwc-pro' ) . '</td><td>' . esc_attr__( 'Address', 'ddwc-pro' ) . '</td>' . apply_filters( 'ddwc_pro_driver_dashboard_unclaimed_orders_total_title', $total_title ) . '<td></td></tr></thead>';
echo '<tbody>';
do_action( 'ddwc_pro_unclaimed_orders_table_tbody_before' );
foreach ( $unclaimed_orders as $driver_order ) {
// Get Driver ID (if set).
$driver_id_setting = get_post_meta( $driver_order->ID, 'ddwc_driver_id', TRUE );
// Get an instance of the WC_Order object.
$order = wc_get_order( $driver_order->ID );
// Get the required order data.
$order_data = $order->get_data();
$currency_code = $order_data['currency'];
$currency_symbol = get_woocommerce_currency_symbol( $currency_code );
$order_id = $order_data['id'];
$order_status = $order_data['status'];
$order_date_created = $order_data['date_created']->date( 'm-d-Y' );
## CART INFORMATION:
$order_total = $order_data['total'];
## BILLING INFORMATION:
$order_billing_city = $order_data['billing']['city'];
$order_billing_state = $order_data['billing']['state'];
$order_billing_postcode = $order_data['billing']['postcode'];
## SHIPPING INFORMATION:
$order_shipping_city = $order_data['shipping']['city'];
$order_shipping_state = $order_data['shipping']['state'];
$order_shipping_postcode = $order_data['shipping']['postcode'];
// Create address to use in the table.
$address = $order_billing_city . ' ' . $order_billing_state . ', ' . $order_billing_postcode;
// Set address to shipping (if available).
if ( isset( $order_shipping_city ) ) {
$address = $order_shipping_city . ' ' . $order_shipping_state . ', ' . $order_shipping_postcode;
}
// Allowed statuses.
$status_array = apply_filters( 'ddwc_pro_driver_dashboard_unclaimed_orders_status_array', array( 'processing' ) );
// Display unassigned orders.
if ( in_array( $order_status, $status_array ) && ( -1 == $driver_id_setting || '' === $driver_id_setting ) ) {
echo '<tr>';
echo '<td>' . $order_date_created . '</td>';
echo '<td>' . apply_filters( 'ddwc_pro_driver_dashboard_unclaimed_orders_table_address', $address ) . '</td>';
if ( isset( $order_total ) ) {
$order_total = '<td>' . $currency_symbol . $order_total . '</td>';
echo apply_filters( 'ddwc_pro_driver_dashboard_unclaimed_orders_total', $order_total );
} else {
echo '<td>-</td>';
}
echo '<td>' . apply_filters( 'ddwc_pro_driver_dashboard_unclaimed_orders_button_text', __( 'CLAIM', 'ddwc-pro' ) ) . '</td>';
echo '</tr>';
} else {
// Do nothing.
}
}
do_action( 'ddwc_pro_unclaimed_orders_table_tbody_after' );
echo '</tbody>';
echo '</table>';
do_action( 'ddwc_pro_unclaimed_orders_table_after' );
// Driver dashboard button.
$dashboard_button = '← ' . __( 'Driver Dashboard', 'ddwc-pro' ) . '';
// Filter "Driver Dashboard" button.
echo apply_filters( 'ddwc_pro_back_to_driver_dashboard_button', $dashboard_button );
} else {
do_action( 'ddwc_pro_assigned_orders_empty_before' );
// Message - No assigned orders.
$empty = '<h3 class="ddwc assigned-orders">' . __( 'Assigned Orders', 'ddwc-pro' ) . '</h3>';
$empty .= '<p>' . __( 'You do not have any assigned orders.', 'ddwc-pro' ) . '</p>';
echo apply_filters( 'ddwc_pro_assigned_orders_empty', $empty );
do_action( 'ddwc_pro_assigned_orders_empty_after' );
}
} else {
// Set the Access Denied page text.
$access_denied = '<h3 class="ddwc access-denied">' . __( 'Access Denied', 'ddwc-pro' ) . '</h3><p>' . __( 'Sorry, but you are not able to view this page.', 'ddwc-pro' ) . '</p>';
// Filter Access Denied text.
echo apply_filters( 'ddwc_access_denied', $access_denied );
}
} else {
// Do nothing.
}
} else {
apply_filters( 'ddwc_pro_dashboard_login_form', wp_login_form() );
}
}
add_shortcode( 'ddwc_pro_dashboard', 'ddwc_pro_dashboard_shortcode' );
I had thought of a way to implement this functionality - I have created a custom field (just for delivery drivers) in the woocommerce account details section 'my-account/edit-account'. The field is a dropdown list of cities a delivery driver can assign to himself in his account details.
And I want to call a function that checks if the 'town/city' address label matches the selected city in a drivers profile, if it does then the driver can see that order (orders). If a driver has not selected a city in that drop-down then he will not see any orders.
Here is how I have added the drop-down city list:
<?php
/**
* Get additional account fields.
*
* #return array
*/
function iconic_get_account_fields() {
return apply_filters( 'iconic_account_fields', array(
'city_select' => array(
'type' => 'select',
'label' => __( 'Select City', 'iconic' ),
'hide_in_account' => false,
'hide_in_admin' => false,
'required' => false,
'options' => array(
'' => __( 'Select an option...', 'iconic' ),
1 => __( 'Manchester', 'iconic' ),
2 => __( 'Birmingham', 'iconic' ),
3 => __( 'London', 'iconic' ),
),
'bank_name' => array(
'type' => 'text',
'label' => __( 'Bank Name', 'iconic' ),
'hide_in_account' => false,
'hide_in_admin' => false,
'required' => false,
),
) );
}
/**
* Add post values to account fields if set.
*
* #param array $fields
*
* #return array
*/
function iconic_add_post_data_to_account_fields( $fields ) {
if ( empty( $_POST ) ) {
return $fields;
}
foreach ( $fields as $key => $field_args ) {
if ( empty( $_POST[ $key ] ) ) {
$fields[ $key ]['value'] = '';
continue;
}
$fields[ $key ]['value'] = $_POST[ $key ];
}
return $fields;
}
add_filter( 'iconic_account_fields', 'iconic_add_post_data_to_account_fields', 10, 1 );
/**
* Add field to account area.
*/
function iconic_print_user_frontend_fields() {
$fields = iconic_get_account_fields();
$is_user_logged_in = is_user_logged_in();
foreach ( $fields as $key => $field_args ) {
$value = null;
if ( ! iconic_is_field_visible( $field_args ) ) {
continue;
}
if ( $is_user_logged_in ) {
$user_id = iconic_get_edit_user_id();
$value = iconic_get_userdata( $user_id, $key );
}
$value = isset( $field_args['value'] ) ? $field_args['value'] : $value;
woocommerce_form_field( $key, $field_args, $value );
}
}
add_action( 'woocommerce_edit_account_form', 'iconic_print_user_frontend_fields', 10 ); // my account
/**
* Get user data.
*
* #param $user_id
* #param $key
*
* #return mixed|string
*/
function iconic_get_userdata( $user_id, $key ) {
if ( ! iconic_is_userdata( $key ) ) {
return get_user_meta( $user_id, $key, true );
}
$userdata = get_userdata( $user_id );
if ( ! $userdata || ! isset( $userdata->{$key} ) ) {
return '';
}
return $userdata->{$key};
}
/**
* Get currently editing user ID (frontend account/edit profile/edit other user).
*
* #return int
*/
function iconic_get_edit_user_id() {
return isset( $_GET['user_id'] ) ? (int) $_GET['user_id'] : get_current_user_id();
}
/**
* Save registration fields.
*
* #param int $customer_id
*/
function iconic_save_account_fields( $customer_id ) {
$fields = iconic_get_account_fields();
$sanitized_data = array();
foreach ( $fields as $key => $field_args ) {
if ( ! iconic_is_field_visible( $field_args ) ) {
continue;
}
$sanitize = isset( $field_args['sanitize'] ) ? $field_args['sanitize'] : 'wc_clean';
$value = isset( $_POST[ $key ] ) ? call_user_func( $sanitize, $_POST[ $key ] ) : '';
if ( iconic_is_userdata( $key ) ) {
$sanitized_data[ $key ] = $value;
continue;
}
update_user_meta( $customer_id, $key, $value );
}
if ( ! empty( $sanitized_data ) ) {
$sanitized_data['ID'] = $customer_id;
wp_update_user( $sanitized_data );
}
}
add_action( 'personal_options_update', 'iconic_save_account_fields' ); // edit own account admin
add_action( 'edit_user_profile_update', 'iconic_save_account_fields' ); // edit other account
add_action( 'woocommerce_save_account_details', 'iconic_save_account_fields' ); // edit WC account
/**
* Is this field core user data.
*
* #param $key
*
* #return bool
*/
function iconic_is_userdata( $key ) {
$userdata = array(
'user_pass',
'user_login',
'user_nicename',
'user_url',
'user_email',
'display_name',
'nickname',
'first_name',
'last_name',
'description',
'rich_editing',
'user_registered',
'role',
'jabber',
'aim',
'yim',
'show_admin_bar_front',
);
return in_array( $key, $userdata );
}
/**
* Is field visible.
*
* #param $field_args
*
* #return bool
*/
function iconic_is_field_visible( $field_args ) {
$visible = true;
$action = filter_input( INPUT_POST, 'action' );
if ( is_admin() && ! empty( $field_args['hide_in_admin'] ) ) {
$visible = false;
} elseif ( ( is_account_page() || $action === 'save_account_details' ) && is_user_logged_in() && ! empty( $field_args['hide_in_account'] ) ) {
$visible = false;
}
return $visible;
}
/**
* Add fields to admin area.
*/
function iconic_print_user_admin_fields() {
$fields = iconic_get_account_fields();
?>
<h2><?php _e( 'Additional Information', 'iconic' ); ?></h2>
<table class="form-table" id="iconic-additional-information">
<tbody>
<?php foreach ( $fields as $key => $field_args ) { ?>
<?php
if ( ! iconic_is_field_visible( $field_args ) ) {
continue;
}
$user_id = iconic_get_edit_user_id();
$value = iconic_get_userdata( $user_id, $key );
?>
<tr>
<th>
<label for="<?php echo $key; ?>"><?php echo $field_args['label']; ?></label>
</th>
<td>
<?php $field_args['label'] = false; ?>
<?php woocommerce_form_field( $key, $field_args, $value ); ?>
</td>
</tr>
<?php } ?>
</tbody>
</table>
<?php
}
add_action( 'show_user_profile', 'iconic_print_user_admin_fields', 30 ); // admin: edit profile
add_action( 'edit_user_profile', 'iconic_print_user_admin_fields', 30 ); // admin: edit other users
/**
* Validate fields on frontend.
*
* #param WP_Error $errors
*
* #return WP_Error
*/
function iconic_validate_user_frontend_fields( $errors ) {
$fields = iconic_get_account_fields();
foreach ( $fields as $key => $field_args ) {
if ( empty( $field_args['required'] ) ) {
continue;
}
if ( ! isset( $_POST['register'] ) && ! empty( $field_args['hide_in_account'] ) ) {
continue;
}
if ( empty( $_POST[ $key ] ) ) {
$message = sprintf( __( '%s is a required field.', 'iconic' ), '<strong>' . $field_args['label'] . '</strong>' );
$errors->add( $key, $message );
}
}
return $errors;
}
add_filter( 'woocommerce_save_account_details_errors', 'iconic_validate_user_frontend_fields', 10 )
I am a novice to programming (especially PHP) I have tried different ways in adding a if statement to check if I can make functionality where before it displays the list of orders in the table, it checks if the drivers selected city matches the city in the customers address and then displays the same orders as the city the driver resides in, if not no orders should be displayed.
But I keep breaking my site, any assistance would be appreciated (as im beginning to think maybe this is not the file to add this sort of function).
Here's what I would do:
On the site options side (custom, or trough woocommerce delivery zone options):
Admin store a list of cities, with name and ID
You could do an ACF option field list, where you can fill a City name, and an ID (or postcode) (to prevent make queries based on cities name only)
Woocommerce also has delivery options where you can store shipping areas, so you could store your cities here and use them. Depending on how you integrated with Woocommerce.
On the user/driver side:
Your additional city field should let the user be able to select multiple cities from the list you defined
Data will store as a user_meta a serialized array of IDs or Postcode from selected cities
So each driver has a postcode/IDs of cities stored as user meta, that he can edits
On the order checkout process side :
If the postcode of delivery address is "locked" to the available cities list you made: great
If the postcode is a free field, you'll need to add something so the order is associated with a postcode/ID of the available city you've defined. To be able to match drivers and orders.
Depending on your checkout process, you could add an order field so the customer selects a city based on your admin list. Or make the postal_code field limited to your list. You need something so an order can be matched to one of the cities from your list.
On the driver orders list page :
You'll edit the WP_query querying that query orders, to add a meta_query
meta_query will query orders based on the postcode/IDs of user_meta from the current user driver
You are able to foreach on the user meta array values, and add meta_query "OR" for each drivers cities ID/Postcode to the orders query
order matching one of the driver's city IDs/postcodes will be displayed
Im using this code in displaying the sum of the product variable stock quantities from a parent variable products based on:
Display the stock availability for all product types in Woocommerce archive pages.
How can I make the sorting options to look at in the above script rather than the _stock meta? here is the script that i am using to sort the products.
protected function get_settings_options() {
$options = array(
'by_stock' => __( 'Available Stock', 'woocommerce-extra-product-sorting-options' ),
);
if ( ! self::is_wc_gte( '3.0' ) ) {
$options['featured_first'] = __( 'Featured First', 'woocommerce-extra-product-sorting-options' );
}
return $options;
}
foreach( $new_sorting_options as $option ) {
switch ( $option ) {
case 'by_stock':
$sortby['by_stock'] = __( 'Sort by availability', 'woocommerce-extra-product-sorting-options' );
break;
}
}
return $sortby;
}
public function add_new_shop_ordering_args( $sort_args ) {
// If we have the orderby via URL, let's pass it in.
// This means we're on a shop / archive, so if we don't have it, use the default.
if ( isset( $_GET['orderby'] ) ) {
$orderby_value = wc_clean( $_GET['orderby'] );
} else {
$orderby_value = apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) );
}
// Since a shortcode can be used on a non-WC page, we won't have $_GET['orderby'] --
// grab it from the passed in sorting args instead for non-WC pages.
// Don't use this on WC archives so we don't break the default option
if ( ! is_post_type_archive( 'product' ) && ! is_shop() && isset( $sort_args['orderby'] ) ) {
$orderby_value = $sort_args['orderby'];
}
$fallback = apply_filters( 'wc_extra_sorting_options_fallback', 'title', $orderby_value );
$fallback_order = apply_filters( 'wc_extra_sorting_options_fallback_order', 'ASC', $orderby_value );
switch( $orderby_value ) {
case 'by_stock':
$sort_args['orderby'] = array( 'meta_value_num' => 'DESC', $fallback => $fallback_order );
$sort_args['meta_key'] = '_stock';
break;
}
return $sort_args;
}