如何添加功能以便 woocommerce 订单对同一城市的司机用户角色可见?

Swi*_*ter 5 php wordpress function woocommerce

我有一个 WordPress Woo-commerce 商店,里面有 woo-commerce 插件(https://wordpress.org/plugins/delivery-drivers-for-woocommerce/)的交付驱动程序的专业版。

作为用户角色的任何用户,一切正常:“送货司机”可以查看和领取通过网站处理的所有订单,目前使用 woo-commerce 送货/送货区域设置我已经配置了它,因此只有居住的客户在某个城市可以下订单,我只批准该地区的送货司机。

但我想将其推广到其他城市,我可以添加邮政编码,以便用户可以从这些邮政编码订购,但问题在于送货司机插件 - 司机将在他们的仪表板中看到来自所有城市的所有订单。我只希望司机在他们居住的城市(他们分配给自己的城市)中查看和领取订单。

以下是将网站上所有订单显示给用户角色类型“送货司机”的功能代码:

驱动程序仪表板-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' );
Run Code Online (Sandbox Code Playgroud)

我已经想到了一种实现此功能的方法 - 我在 woocommerce 帐户详细信息部分“我的帐户/编辑帐户”中创建了一个自定义字段(仅适用于送货司机)。该字段是送货司机可以在其帐户详细信息中分配给自己的城市的下拉列表。

我想调用一个函数来检查“城镇/城市”地址标签是否与驱动程序配置文件中的选定城市匹配,如果匹配,则驱动程序可以看到该订单(订单)。如果司机没有在该下拉菜单中选择一个城市,那么他将看不到任何订单。

这是我添加下拉城市列表的方式:

  <?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 )
Run Code Online (Sandbox Code Playgroud)

我是编程的新手(尤其是 PHP)我尝试了不同的方法来添加 if 语句来检查我是否可以在显示表中的订单列表之前创建功能,它会检查驱动程序选择的城市是否与城市匹配客户地址然后显示与司机居住的城市相同的订单,如果不是,则不应显示任何订单。

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

Mtx*_*txz 1

这就是我要做的:

在网站选项方面(自定义或通过 woocommerce 交付区域选项):

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

在用户/驱动程序方面:

  • 您的附加城市字段应该让用户能够从您定义的列表中选择多个城市
  • 数据将存储为 user_meta 的序列化数组,其中包含选定城市的 ID 或邮政编码
  • 因此,每个司机都有一个存储为用户元数据的城市邮政编码/ID,他可以对其进行编辑

在订单结帐流程方面:

  • 如果送货地址的邮政编码被“锁定”到您创建的可用城市列表中:很好
  • 如果邮政编码是自由字段,您需要添加一些内容,以便订单与您定义的可用城市的邮政编码/ID 相关联。能够匹配司机和订单。
  • 根据您的结账流程,您可以添加订单字段,以便客户根据您的管理列表选择城市。或者将邮政编码字段限制为您的列表。您需要一些东西,以便订单可以与您列表中的城市之一相匹配。

在司机订单列表页面上:

  • 您将编辑查询订单的 WP_query,以添加 meta_query
  • meta_query 将根据当前用户驱动程序中 user_meta 的邮政编码/ID 查询订单
  • 您可以对用户元数组值进行 foreach,并将每个驱动程序城市 ID/邮政编码的元查询“OR”添加到订单查询中
  • 将显示与司机的城市 ID/邮政编码之一匹配的订单