Сделать продукт для покупки только один раз или нет, если какой-либо элемент из определенной категории продуктов был приобретен в Woocommerce - PullRequest
3 голосов
/ 26 марта 2019

В woocommerce я просто использую простые продукты, и у меня есть специальный продукт "бесплатный пробный пакет" из категории продуктов "A", который я готов:

  1. разрешить клиенту приобретать этот «бесплатный пробный пакет» только один раз
  2. если клиент сначала покупает другие продукты из той же категории "А", то он больше не может приобрести этот "бесплатный пробный пакет"

Это означает, что клиент сможет получить «бесплатный пробный пакет» только в том случае, если это первая покупка данной категории «А».

Мой код, кажется, не работает должным образом, и это только 1-й пункт.

Другая проблема состоит в том, что, если пользовательский заказ заканчивается, в следующий раз, когда пользователь открывает корзину, он показывает странное сообщение: «Вы больше не можете выбирать этот продукт, вы уже купили этот пакет» . Это похоже на проблему с кэшем Woocommerce или что-то в этом роде ...

Вот мой код:

function sv_disable_repeat_purchase( $purchasable, $product ) {
    $non_purchasable = 190;

    $product_id = $product->is_type( 'variation' ) ? $product->variation_id : $product->id;

    if ( $product_id != $non_purchasable ) {
        $purchasable = true;
    }

    if ( wc_customer_bought_product( wp_get_current_user()->user_email, get_current_user_id(), $product_id ) ) {
        $purchasable = false;
    }

    if ( $purchasable && $product->is_type( 'variation' ) ) {
        $purchasable = $product->parent->is_purchasable();
    }

    return $purchasable;
}
add_filter( 'woocommerce_variation_is_purchasable', 'sv_disable_repeat_purchase', 10, 2 );
add_filter( 'woocommerce_is_purchasable', 'sv_disable_repeat_purchase', 10, 2 );

Любая помощь приветствуется.

Ответы [ 2 ]

2 голосов
/ 26 марта 2019

Обновление 2

На основе " Проверьте, приобрел ли клиент определенные продукты в коде ответа WooCommerce " , следующее предотвратит покупки из продукта "пробной упаковки", если он уже был куплен один раз, или если какой-либо продукт для определенной категории продуктов "А" уже был приобретен.

Ваш реальный код устарел со времен Woocommerce 3, и есть некоторые ошибки ...

Я использую пользовательскую условную функцию, основанную на wc_customer_bought_product() исходном коде , чтобы проверить, может ли покупатель приобрести продукт "бесплатной пробной версии". Эта функция также проверяет идентификатор продукта или категорию продукта:

function has_bought_items( $user_id = 0, $product_ids = 0, $categories_slugs = '' ) {
    global $wpdb;
    $customer_id = $user_id == 0 || $user_id == '' ? get_current_user_id() : $user_id;
    $statuses    = array_map( 'esc_sql', wc_get_is_paid_statuses() );

    if ( is_array( $product_ids ) ) {
        $product_ids = implode(',', $product_ids);
    }

    if ( $product_ids !=  ( 0 || '' ) ) {
        $query_in = "IN ($product_ids)";
    }
    else {
        $categories = is_array( $categories_slugs ) ? implode("','", $categories_slugs) : $categories_slugs;

        $query_in = "IN (
        SELECT DISTINCT products.ID  FROM {$wpdb->prefix}posts AS products
        INNER JOIN {$wpdb->prefix}term_relationships as term_rel
            ON products.ID = term_rel.object_id
        INNER JOIN {$wpdb->prefix}term_taxonomy as term_tax
            ON term_rel.term_taxonomy_id = term_tax.term_taxonomy_id
        INNER JOIN {$wpdb->prefix}terms as terms
            ON term_tax.term_taxonomy_id = terms.term_id
        WHERE products.post_status = 'publish'
        AND term_tax.taxonomy = 'product_cat'
        AND terms.slug IN ('$categories')
        )";
    }

    // Count the number of products
    $product_count_query = $wpdb->get_var( "
        SELECT DISTINCT COUNT(orders.ID)
        FROM {$wpdb->prefix}posts AS orders
        INNER JOIN {$wpdb->prefix}postmeta AS order_meta
            ON orders.ID = order_meta.post_id
        INNER JOIN {$wpdb->prefix}woocommerce_order_items AS order_items
            ON orders.ID = order_items.order_id
        INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS order_itemmeta
            ON order_items.order_item_id = order_itemmeta.order_item_id
        WHERE orders.post_status IN ( 'wc-" . implode( "','wc-", $statuses ) . "' )
        AND order_meta.meta_key = '_customer_user'
        AND order_meta.meta_value = $customer_id
        AND order_itemmeta.meta_key IN ( '_product_id', '_variation_id' )
        AND order_itemmeta.meta_value $query_in
    " );

    // Return a boolean value if count is higher than 0
    return $product_count_query > 0 ? true : false;
}

Ваш повторный код, используя пользовательскую условную функцию выше:

// add_filter( 'woocommerce_variation_is_purchasable', 'trial_package_purchasable_once', 10, 2 );
add_filter( 'woocommerce_is_purchasable', 'trial_package_purchasable_once', 10, 2 );
function trial_package_purchasable_once( $purchasable, $product ) {
    // HERE set the free trial product Id to be purchased only once (can be an array of Ids too)
    $free_trial_id = 50;

    // HERE set the specific product category SLUG (could be an array of slugs too)
    $categories = array('lettering'); // Only slug terms

        if ( $product->get_id() == $free_trial_id ) {
            // Check if any item of the specific product category has already been purchased once
            if ( has_bought_items( get_current_user_id(), '', $categories ) ) {
                return false;
            }
            // Check if the free trial product has already been purchased once
            elseif ( has_bought_items( get_current_user_id(), $free_trial_id ) ) {
                return false;
            }
        }
    }

    return $purchasable;
}

Код помещается в файл function.php вашей активной дочерней темы (или активной темы). Проверено и работает.


Для обработки категорий товаров вместо идентификаторов терминов используются идентификаторы терминов: вместо них используется следующая условная функция:

// For Product category(ies) Id(s)
function has_bought_items( $user_id = 0, $product_ids = 0, $categories_ids = '' ) {
    global $wpdb;
    $customer_id = $user_id == 0 || $user_id == '' ? get_current_user_id() : $user_id;
    $statuses    = array_map( 'esc_sql', wc_get_is_paid_statuses() );

    if ( is_array( $product_ids ) ) {
        $product_ids = implode(',', $product_ids);
    }

    if ( $product_ids !=  ( 0 || '' ) ) {
        $query_in = "IN ($product_ids)";
    }
    else {
        $categories = is_array( $categories_ids ) ? implode(',', $categories_ids) : $categories_ids;

        $query_in = "IN (
        SELECT DISTINCT products.ID  FROM {$wpdb->prefix}posts AS products
        INNER JOIN {$wpdb->prefix}term_relationships as term_rel
            ON products.ID = term_rel.object_id
        INNER JOIN {$wpdb->prefix}term_taxonomy as term_tax
            ON term_rel.term_taxonomy_id = term_tax.term_taxonomy_id
        INNER JOIN {$wpdb->prefix}terms as terms
            ON term_tax.term_taxonomy_id = terms.term_id
        WHERE products.post_status = 'publish'
        AND term_tax.taxonomy = 'product_cat'
        AND terms.term_id IN ($categories)
        )";
    }

    // Count the number of products
    $product_count_query = $wpdb->get_var( "
        SELECT DISTINCT COUNT(orders.ID)
        FROM {$wpdb->prefix}posts AS orders
        INNER JOIN {$wpdb->prefix}postmeta AS order_meta
            ON orders.ID = order_meta.post_id
        INNER JOIN {$wpdb->prefix}woocommerce_order_items AS order_items
            ON orders.ID = order_items.order_id
        INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS order_itemmeta
            ON order_items.order_item_id = order_itemmeta.order_item_id
        WHERE orders.post_status IN ( 'wc-" . implode( "','wc-", $statuses ) . "' )
        AND order_meta.meta_key = '_customer_user'
        AND order_meta.meta_value = $customer_id
        AND order_itemmeta.meta_key IN ( '_product_id', '_variation_id' )
        AND order_itemmeta.meta_value $query_in
    " );

    // Return a boolean value if count is higher than 0
    return $product_count_query > 0 ? true : false;
}

Лучшая альтернатива для иностранных языков со специальными символами.

0 голосов
/ 26 марта 2019
function wc_customer_purchased_product_in_cat( $product ) {

    // enter the category for which a single purchase is allowed
    $non_repeatable = 'ADD YOUR CATEGORY HERE';

    // bail if this product is in not in our target category
    if ( ! has_term( $non_repeatable, 'product_cat', $product->get_id() ) ) {
        return false;
    }

    // the product has our target category, so return whether the customer purchased
    return wc_customer_bought_product( wp_get_current_user()->user_email, get_current_user_id(), $product->get_id() );
}

function wc_disable_repeat_purchase( $purchasable, $product ) {

    if ( wc_customer_purchased_product_in_cat( $product ) ) {
        $purchasable = false;
    }

    // double-check for variations: if parent is not purchasable, then variation is not
    if ( $purchasable && $product->is_type( 'variation' ) ) {
        $purchasable = $product->parent->is_purchasable();
    }

    return $purchasable;
}
add_filter( 'woocommerce_variation_is_purchasable', 'wc_disable_repeat_purchase', 10, 2 );
add_filter( 'woocommerce_is_purchasable', 'wc_disable_repeat_purchase', 10, 2 );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...