当前位置: 首页 > 知识库问答 >
问题:

如何添加功能,以便在同一城市中的驱动程序用户角色可以看到WooCommerce订单?

盛柏
2023-03-14

我有一个WordPress Woo商务商店与专业版的交付驱动程序为Woo商务插件(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'] ) && ( '' != $_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><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/' ) . '">&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帐户详细信息部分'my-帐户/edit-帐户'。该字段是送货司机可以在其帐户详细信息中分配给自己的城市的下拉列表。

我想调用一个函数,检查“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() && ! 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 )

我是编程新手(尤其是PHP),我尝试了不同的方法添加if语句,以检查我是否能够实现功能,在它显示表中的订单列表之前,它会检查所选城市的驱动程序是否与客户地址中的城市匹配,然后显示与驱动程序所在城市相同的订单,如果没有,则不应显示订单。

但我一直在破坏我的网站,任何帮助都将不胜感激(因为我开始认为这可能不是添加此类功能的文件)。

共有1个答案

夏嘉德
2023-03-14

下面是我要做的:

网站选项侧(自定义,或槽WooCommerce交付区选项):

  • 管理员存储城市列表,包括名称和ID
  • 您可以创建一个ACF选项字段列表,在其中您可以填写城市名称和ID(或邮政编码)(以防止仅基于城市名称进行查询)
  • Woocommerce还提供了配送选项,您可以在其中存储配送区域,这样您就可以将您的城市存储在这里并使用它们。取决于您与Woocommerce的集成方式

在用户/驱动端:

  • 您的附加城市字段应允许用户从您定义的列表中选择多个城市

在订单签出流程方面:

  • 如果送货地址的邮政编码“锁定”在您制作的可用城市列表中:太好了

在驱动程序订单列表页上:

  • 您将编辑查询订单的WP_查询,以添加元查询
  • meta\u query将根据当前用户驱动程序中用户\u meta的邮政编码/ID查询订单
  • 您可以查看用户元数组值,并在订单查询中为每个驾驶员城市ID/邮政编码添加元查询“或”
  • 将显示与其中一个驾驶员城市ID/邮政编码匹配的订单
 类似资料:
  • 我需要在Liferay的用户登录应用程序时为他们分配角色。 我已经实现了实现“身份验证器”的自定义类的“身份验证器”方法中的所有逻辑。 示例代码: 当我登录时,很明显它可以工作,我检查liferay数据库的表并更新它们,我的用户分配了“管理员”角色。但是,前端的门户不显示“Admin”选项。 但如果我转到“我的帐户”,按“保存”按钮,注销并再次登录,我有可用的管理选项。 有人知道为什么会这样吗?,

  • 我正试图在我的注册功能中为用户分配一个角色。 通过使用以下代码: 当我试图运行上面的代码时,我得到了以下错误。 E/AndroidRuntime:致命异常:AsyncTask#2进程:info,pid:967 java.lang.runtimeException:在Android.os.AsyncTask$3处执行doInBackground()时发生错误。done(AsyncTask.java:

  • 我在网站上有一个表单,允许用户创建可预订的产品。但是,我找不到如何使用php函数创建可用性间隔。有人有主意吗? 下面是我如何创建我的产品 在这个项目的另一部分中,我使用get_post_元函数来获取可用性。我从文章中了解到可用性是元数据,但我不确定如何更改这些。我试着使用通常的

  • 除了“再次订购”按钮外,是否有一个钩子/过滤器来添加另一个按钮?我想把这个加入我的帐户

  • 我自己想了一个实现,但觉得有点过头了,而且笨重? 我将使用用户ID作为密钥 Id然后在value部分中存储JWT令牌的hashmap。 示例 null null 这意味着在每个对受保护的apiendpoint的请求中,我必须按userId进行搜索,反序列化hashmap,循环遍历hashmap并尝试匹配在头中发送的JWT。这看起来像是一个很大的工作?还有别的办法吗? 如果一个用户想要注销,那么这个

  • 我希望能够运行以开始的命令!suspend,提到一个用户,然后确定一个时间长度,并在指定的时间长度内向提到的用户添加一个名为“suspend”的角色。 我不知道该怎么做,因为我对JDA太不熟悉,无法让它工作。除了实际添加的名为“暂停”的角色之外,我的一切都正常。