WooCommerce: как я могу разделить заказ между двумя клиентами? - PullRequest
0 голосов
/ 02 октября 2018

неделю назад я начал строить магазин WooCommerce, в котором должна быть возможность делиться заказами между двумя покупателями.Вот небольшая диаграмма, которую я сделал для вас, чтобы вы могли понять, как это должно быть (пожалуйста, посмотрите на это):

enter image description here

Итаквот что я сделал шаг за шагом


Пользователь B нажимает кнопку -> (Сохранить идентификатор второго пользователя в заказе):

$related_order = $_POST['related_order'];
$current_user = wp_get_current_user();
$userID = $current_user->ID;
update_post_meta($related_order, 'second_user_id', $userID);

Пользователь B нажимает другойкнопка -> (Удалить второй идентификатор пользователя из заказа)

$related_order = $_POST['related_order'];
$current_user = wp_get_current_user();
$user_id = $current_user->ID;
delete_post_meta($related_order , 'second_user_id');

Эти два шага (показать и скрыть заказ для пользователя B) работают нормально - я проверил это.Поле устанавливается и сбрасывается.


Теперь становится все хуже:

Я много искал и просил некоторых людей найти в WooCommerce функцию, которая получает все заказы для клиента.После того, как я нашел его, я попытался изменить его, чтобы поле second_user_id было проверено.Я просто подумал, что могу показать заказ от клиента А до Б следующим образом:

function woocommerce_account_orders( $current_page ) {
    $current_page    = empty( $current_page ) ? 1 : absint( $current_page );
    $customer_orders = wc_get_orders( apply_filters( 'woocommerce_my_account_my_orders_query', array(
        'customer' => get_current_user_id(),
        'second_user_id' => get_current_user_id(),
        'page'     => $current_page,
        'paginate' => true,
    ) ) );

    wc_get_template(
        'myaccount/orders.php',
        array(
            'current_page'    => absint( $current_page ),
            'customer_orders' => $customer_orders,
            'has_orders'      => 0 < $customer_orders->total,
        )
    );
}

Метод находится в: https://docs.woocommerce.com/wc-apidocs/source-function-woocommerce_account_orders.html#2465-2486


Как вы видите, я 'мы попытались добавить second_user_id к запросу, который возвращает заказы для клиента.Это мое настраиваемое поле, сохраняемое в каждом заказе:

[5] => WC_Meta_Data Object (
     [current_data:protected] => Array (
          [id] => 3477
          [key] => second_user_id
          [value] => 2
)

После того, как это не сработало, я получил помощь от дружелюбного парня, который сказал мне, что это не может работать так, как я это сделал.Есть разрешение, которое должно быть предоставлено пользователю B для просмотра заказа от A и многих других вещей ... Так есть ли кто-то, кто может помочь мне с этой частью?Что не так с моей реализацией и как я могу изменить функциональность так, как мне нужно?

1 Ответ

0 голосов
/ 07 октября 2018

если мы посмотрим на функцию responsebile, которую WooCommerce использует для запроса клиента, вы выберете WooCommerce для выбора всех заказов, связанных с пользователем, на основе идентификатора пользователя.

Исходный код функции:

function woocommerce_account_orders( $current_page ) {
    $current_page    = empty( $current_page ) ? 1 : absint( $current_page );
    $customer_orders = wc_get_orders( apply_filters( 'woocommerce_my_account_my_orders_query', array(
        'customer' => get_current_user_id(),
        'page'     => $current_page,
        'paginate' => true,
    ) ) );

    wc_get_template(
        'myaccount/orders.php',
        array(
            'current_page'    => absint( $current_page ),
            'customer_orders' => $customer_orders,
            'has_orders'      => 0 < $customer_orders->total,
        )
    );
}
}

Если вы хотите изменить этот запрос и добавить конкретные идентификаторы заказов, которые не принадлежат этому пользователю, помимо заказов по умолчанию, нам нужно сделать своего рода хак для этого запроса и возможный вариант, который я могу представитьсейчас используется post__in вместо получения заказов по идентификатору клиента.

мы будем использовать фильтр woocommerce_my_account_my_orders_query для изменения запроса.

я буду считать, что дополнительные заказы для этого пользователя хранятся в wp_usermeta таблице

Решение будет таким:

add_filter( 'woocommerce_my_account_my_orders_query',  'modify_my_order_query'  , 20, 1 );

function modify_my_order_query( $q ) {
    global $wpdb;
    $current_user_id = get_current_user_id();
    //Check if the user have addtional orders
    $secondary_post_ids = get_user_meta( $current_user_id, 'additional_orders', false );
    if ( ! empty( $secondary_post_ids ) ) {

        // Get All Orders ID for the main customers
        $prepare_query = $wpdb->prepare(
            " SELECT post_id  FROM {$wpdb->postmeta}
    WHERE meta_key LIKE %s and meta_value LIKE %d ",
            '_customer_user',
            $current_user_id
        );
        $results       = $wpdb->get_results( $prepare_query, ARRAY_A );
        $main_post_ids = wp_list_pluck( $results, 'post_id' );

        // Merge All Orders IDs

        $all_posts_ids = ( isset( $secondary_post_ids[0] ) ) ? array_merge( $main_post_ids, $secondary_post_ids[0] ) : $main_post_ids;
        //Modify the my Order Query to include all orders ID including the additional ones
        unset( $q['customer'] );
        $q['post__in'] = $all_posts_ids;
    }

    return $q;
}

Сначала вы увидите, что в приведенном выше решении мы проверяем, есть ли у текущего пользователя дополнительный заказ, если да, тогда мы выбираем все его значения по умолчанию.ID заказов и объединить массив с его дополнительным заказом, а затем мы изменили запрос, чтобы мы могли получить все эти заказы.

Теперь осталось только позволить пользователю увидеть его дополнительные заказы, и для этого нам нужно использовать user_has_cap hook.

 add_filter( 'user_has_cap',   'give_permissions'  , 10, 3 );

 function give_permissions( $allcaps, $cap, $args ) {

    if ( isset( $cap[0] ) && $cap[0] == 'view_order' ) {
        $get_additional_ids = get_user_meta( get_current_user_id(), 'additional_orders', false );
        if ( isset( $get_additional_ids[0] ) && in_array( $args[2], $get_additional_ids[0] ) ) {
            $allcaps[ $cap[0] ] = true;
        }
    }
    return ( $allcaps );
}

Я верю, что это решение достигнет вашей целевой цели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...