#php #wordpress #function #woocommerce
#php #wordpress #функция #woocommerce
Вопрос:
У меня есть WordPress магазин Woo-commerce с Pro-версией плагина драйверы доставки для woo-commerce (https://wordpress.org/plugins/delivery-drivers-for-woocommerce /).
Все работает нормально, поскольку любой пользователь с пользовательской ролью: «водитель доставки» может просматривать и запрашивать все заказы, которые обрабатываются через веб-сайт, на данный момент с помощью настроек зон доставки / доставки woo-commerce я настроил его так, что только клиенты, которые проживают в определенном городе, могут размещать заказ, и яя утверждаю только водителей доставки в этой области.
Но я хочу распространить это на другие города, я могу добавить почтовые индексы, чтобы пользователи могли делать заказы по этим почтовым кодам, но проблема с плагином драйверов доставки — водители будут видеть все заказы из всех городов на своей панели управления. Я хочу, чтобы водители просматривали и запрашивали заказы только в том городе, в котором они проживают (город, к которому они себя причислили).
Вот код функции, которая отображает все заказы, размещенные на веб-сайте, для типа роли пользователя «водитель доставки» :
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'] ) amp;amp; ( '' != $_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 ) amp;amp; ( -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><a href="' . apply_filters( 'ddwc_pro_driver_dashboard_unclaimed_orders_button_url', '?claim_delivery=' . $order_id, $order_id ) . '" class="button">' . apply_filters( 'ddwc_pro_driver_dashboard_unclaimed_orders_button_text', __( 'CLAIM', 'ddwc-pro' ) ) . '</a></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 = '<a href="' . apply_filters( 'ddwc_pro_back_to_driver_dashboard_link', get_permalink( get_option( 'woocommerce_myaccount_page_id' ) ) . 'driver-dashboard/' ) . '">amp;larr; ' . __( 'Driver Dashboard', 'ddwc-pro' ) . '</a>';
// 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' );
Я придумал способ реализовать эту функциональность — я создал настраиваемое поле (только для водителей доставки) в разделе сведений об учетной записи woocommerce «моя учетная запись / редактировать учетную запись». Поле представляет собой выпадающий список городов, которые водитель доставки может назначить себе в данных своей учетной записи.
И я хочу вызвать функцию, которая проверяет, соответствует ли метка адреса ‘town / city’ выбранному городу в профиле водителя, если это так, то водитель может видеть этот заказ (заказы). Если водитель не выбрал город в этом раскрывающемся списке, он не увидит никаких заказов.
Вот как я добавил выпадающий список городов:
<?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() amp;amp; ! empty( $field_args['hide_in_admin'] ) ) {
$visible = false;
} elseif ( ( is_account_page() || $action === 'save_account_details' ) amp;amp; is_user_logged_in() amp;amp; ! 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'] ) amp;amp; ! 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 )
Я новичок в программировании (особенно PHP) Я пробовал разные способы добавления оператора if, чтобы проверить, могу ли я создать функциональность, где перед отображением списка заказов в таблице проверяется, соответствует ли выбранный город водителей городу в адресе клиентов, а затем отображаются те же заказы, что и город, в котором проживает водитель, если нет, нетзаказы должны отображаться.
Но я продолжаю ломать свой сайт, буду признателен за любую помощь (поскольку я начинаю думать, что, возможно, это не тот файл, в который можно добавить такую функцию).
Комментарии:
1. Какими различными способами вы пытались добавить эту логику? Любая дополнительная информация облегчит помощь. На мой взгляд, похоже, что вы хорошо начали — вам просто нужно получить информацию об учетной записи водителя (похоже, это вызов
iconic_get_userdata
), а затем внутри цикла невостребованных заказов:foreach ( $unclaimed_orders as $driver_order ) {...
проверьте, совпадает ли город адреса доставки заказа (при условии, что я правильно понял проблему).2. Одним из возможных решений может быть изменение массива $ args, добавив предложение «where», чтобы показывать заказы только в пределах досягаемости драйвера. Логика была бы такой: «где order.postcode в $arrayOfPostcodesNearDriver». $arrayOfPostcodesNearDriver = get_postcode_api($driver_postcode, $allowed_range). Это решение позволяет водителям работать в одном или нескольких близлежащих районах, в зависимости от заданного вами ограничения диапазона. Я попытаюсь что-нибудь закодировать на выходных, если у меня будет такая возможность.
Ответ №1:
Вот что я бы сделал:
На стороне параметров сайта (пользовательские или через параметры зоны доставки woocommerce):
- Администратор хранит список городов с именем и идентификатором
- Вы могли бы создать список полей параметров ACF, где вы можете ввести название города и идентификатор (или почтовый индекс) (чтобы предотвратить создание запросов только на основе названий городов)
- В Woocommerce также есть варианты доставки, в которых вы можете хранить области доставки, чтобы вы могли хранить здесь свои города и использовать их. В зависимости от того, как вы интегрировались с Woocommerce.
На стороне пользователя / водителя:
- Ваше дополнительное поле города должно позволять пользователю выбирать несколько городов из определенного вами списка
- Данные будут храниться как user_meta сериализованный массив идентификаторов или почтовых индексов из выбранных городов
- Таким образом, у каждого водителя есть почтовый индекс / идентификаторы городов, сохраненные как пользовательские мета, которые он может редактировать
На стороне процесса оформления заказа :
- Если почтовый индекс адреса доставки «привязан» к списку доступных городов, который вы создали: отлично
- Если почтовый индекс является свободным полем, вам нужно будет добавить что-то, чтобы заказ был связан с почтовым индексом / идентификатором доступного города, который вы определили. Чтобы иметь возможность сопоставлять драйверы и заказы.
- В зависимости от вашего процесса оформления заказа вы можете добавить поле заказа, чтобы клиент выбирал город на основе вашего списка администраторов. Или сделайте поле postal_code ограниченным вашим списком. Вам нужно что-то, чтобы заказ можно было сопоставить с одним из городов из вашего списка.
На странице списка заказов водителей :
- Вы отредактируете запрос WP_Query, запрашивающий этот запрос заказов, чтобы добавить мета_запрос
- meta_query будет запрашивать заказы на основе почтового индекса / идентификаторов user_meta из текущего пользовательского драйвера
- Вы можете получить доступ к значениям пользовательского мета-массива и добавить мета_запрос «ИЛИ» для каждого идентификатора / почтового индекса городов драйверов в запрос заказов
- будет отображаться заказ, соответствующий одному из идентификаторов / почтовых индексов города водителя