Проверьте, приобрел ли клиент определенные продукты в WooCommerce

Мне нужно проверить, покупал ли клиент определенный продукт ранее в WooCommerce.

Дело в том, что клиент не может приобретать продукты «c», «d», «e», если они ранее не приобрели продукт «a» или «b».

Если клиент ранее приобрел продукт «a» или «b», активируется кнопка покупки продуктов «c», «d» и «e», и им разрешается покупать их.

Если они ранее не приобрели «a» или «b», им не разрешается приобретать «c», «d», «e», и кнопка покупки деактивируется.

Как я могу это достичь?

Благодарю.

Обновлено (совместимость для Woocommerce 3+)

Да, возможно, запись условной функции, которая возвращает «истина», если текущий клиент уже купил специфические идентификаторы продуктов. Этот код продолжается в файле functions.php вашей активной дочерней темы или темы .

Вот условная функция:

function has_bought_items() { $bought = false; // Set HERE ine the array your specific target product IDs $prod_arr = array( '21', '67' ); // Get all customer orders $customer_orders = get_posts( array( 'numberposts' => -1, 'meta_key' => '_customer_user', 'meta_value' => get_current_user_id(), 'post_type' => 'shop_order', // WC orders post type 'post_status' => 'wc-completed' // Only orders with status "completed" ) ); foreach ( $customer_orders as $customer_order ) { // Updated compatibility with WooCommerce 3+ $order_id = method_exists( $order, 'get_id' ) ? $order->get_id() : $order->id; $order = wc_get_order( $customer_order ); // Iterating through each current customer products bought in the order foreach ($order->get_items() as $item) { // WC 3+ compatibility if ( version_compare( WC_VERSION, '3.0', '<' ) ) $product_id = $item['product_id']; else $product_id = $item->get_product_id(); // Your condition related to your 2 specific products Ids if ( in_array( $product_id, $prod_arr ) ) $bought = true; } } // return "true" if one the specifics products have been bought before by customer return $bought; } 

Этот код проверен и работает.


ПРИМЕНЕНИЕ:
Например, вы можете использовать его в некоторых шаблонах WooCommerce, которые вы предварительно скопировали в свою активную дочернюю тему или тему:

  • Шаблон для страницы магазина, касающийся кнопки « add-to-cart , – это loop/add-to-cart.php .
  • Шаблоны страниц продукта, касающиеся кнопки « add-to-cart , находятся в папке с single-product/add-to-cart зависимости от ваших типов продуктов.

Вот пример, который вы можете использовать в этих шаблонах (выше) :

 // Replace the numbers by your special restricted products IDs $restricted_products = array( '20', '32', '75' ); // compatibility with WC +3 $product_id = method_exists( $product, 'get_id' ) ? $product->get_id() : $product->id; // customer has NOT already bought a specific product for this restricted products if ( !has_bought_items() && in_array( $product_id, $restricted_products ) ) { // Displaying an INACTIVE add-to-cart button (With a custom text, style and without the link). // (AND optionally) an explicit message for example. // ALL OTHER PRODUCTS OR RESTRICTED PRODUCTS IF COSTUMER HAS ALREADY BOUGHT SPECIAL PRODUCTS } else { // place for normal Add-To-Cart button code here } 

И здесь полный прикладной пример шаблона кнопки « add-to-cart на странице «Магазин» :

 <?php /** * Loop Add to Cart * * This template can be overridden by copying it to yourtheme/woocommerce/loop/add-to-cart.php. * * HOWEVER, on occasion WooCommerce will need to update template files and you * (the theme developer) will need to copy the new files to your theme to * maintain compatibility. We try to do this as little as possible, but it does * happen. When this occurs the version of the template file will be bumped and * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ * @author WooThemes * @package WooCommerce/Templates * @version 2.5.0 */ if ( ! defined( 'ABSPATH' ) ) { exit; } global $product; // Replace the numbers by your special restricted products IDs $restricted_products = array( '37', '53', '70' ); // compatibility with WC +3 $product_id = method_exists( $product, 'get_id' ) ? $product->get_id() : $product->id; if ( !has_bought_items() && in_array( $product_id, $restricted_products ) ) { echo '<a class="button greyed_button">' . __("Disabled", "your_theme_slug") . '</a>'; echo '<br><span class="greyed_button-message">' . __("Your message goes here…", "your_theme_slug") . '</span>'; } else { echo apply_filters( 'woocommerce_loop_add_to_cart_link', sprintf( '<a rel="nofollow" href="%s" data-quantity="%s" data-product_id="%s" data-product_sku="%s" class="%s">%s</a>', esc_url( $product->add_to_cart_url() ), esc_attr( isset( $quantity ) ? $quantity : 1 ), esc_attr( $product_id ), esc_attr( $product->get_sku() ), esc_attr( isset( $class ) ? $class : 'button' ), esc_html( $product->add_to_cart_text() ) ), $product ); } 

Вы greyed_button неактивную кнопку с классом style.css файле style.css вашей активной дочерней темы или темы. То же самое для сообщения с greyed_button-message .

Я бы так делал;

это не будет делать модификацию шаблона woocommerce, но использовать фильтр woocommerce_is_purchasable

Это все функции,

  1. убедитесь, что текущий идентификатор продукта уже внесен клиентом, в версии 2.6 + woocommerce реализовала функцию wc_customer_bought_product чтобы проверить, уже ли клиент привез продукт, я никогда не использовал его раньше, но на основе документов вы можете создать такую ​​функцию, как ниже проверить массив идентификатора продукта, если один из них уже был доставлен;

     function cmk_check_product_brought( $ids=array() ) { if ( ! $ids ) return false; foreach ( $ids as $product => $id ) { if ( wc_customer_bought_product( wp_get_current_user()->user_email, get_current_user_id(), $id ) ) { return true; } } } 

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

 function cmk_product_ordered( $id ) { // Get All order of current user $orders = get_posts( array( 'numberposts' => -1, 'meta_key' => '_customer_user', 'meta_value' => get_current_user_id(), 'post_type' => wc_get_order_types( 'view-orders' ), 'post_status' => array_keys( wc_get_order_statuses() ) ) ); if ( !$orders ) return false; // return if no order found $all_ordered_product = array(); // store all products ordered by ID in an array foreach ( $orders as $order => $data ) { // Loop through each order $order_data = new WC_Order( $data->ID ); // create new object for each order foreach ( $order_data->get_items() as $key => $item ) { // loop through each order item // store in array with product ID as key and order date a value $all_ordered_product[ $item['product_id'] ] = $data->post_date; } } // check if defined ID is found in array if ( isset( $all_ordered_product[ $id ] ) ) return true; else return false; } 
  1. Теперь, когда мы можем проверить, уже введен ли идентификатор продукта, мы можем просто добавить фильтр на woocommerce_is_purchasable чтобы создать собственное условие, эта функция ниже – просто пример того, чего вы пытаетесь достичь,

просто изменили значения $required_purchased и $conditional_purchase .

 function cmk_disable_product_purchase( $purchasable, $product ) { // array of products required to be purchase first $required_purchased = array( 1, 2); // array of restricted/conditional products to be purchase $conditional_purchase = array( 3,4,5); // Get the ID for the current product $product_id = $product->is_type( 'variation' ) ? $product->variation_id : $product->id; //return default $purchasable if current product ID is not in restricted array if ( !in_array($product_id, $conditional_purchase)) return $purchasable; /** ** Check if one required products has been purchase; **/ // using cmk_check_product_brought() function, return false if product is not purchase if ( ! cmk_check_product_brought( $required_purchased ) ) $purchasable = false; // using cmk_product_ordered() function, you can use this instead /*if ( cmk_product_ordered( 1 ) || cmk_product_ordered( 2 ) ) { $purchasable = $purchasable; //return default if one product is purchased } else { $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', 'cmk_disable_product_purchase', 10, 2 ); add_filter( 'woocommerce_is_purchasable', 'cmk_disable_product_purchase', 10, 2 ); 

И это должно установить продукт как не покупаемый (кнопка «Добавить в корзину» будет автоматически скрыта). Теперь, если вы хотите добавить сообщение для не-покупаемого продукта, вы можете просто использовать одно и то же условие cmk_disable_product_purchase , добавить свое сообщение и просто подключить его к woocommerce_single_product_summary или в любом месте, где хотите его отобразить.

В этом случае также можно использовать встроенную функцию wc_customer_bought_product .

См. Функцию использования здесь .

Новая версия компактна, легче, быстрее и совместима со всеми версиями woocommerce (2.4+)

Найдите ниже новую версию моей условной функции, частично основанной на встроенной функции wc_customer_bought_product :

Существует 2 необязательных аргумента $user_id и $product_ids :

  • $user_id позволит вам указать определенный идентификатор пользователя (если он не используется для текущего пользователя) ;
  • $product_ids (array) позволит указать определенные идентификаторы продукта для проверки

Вот этот код:

 function has_bought_items( $user_id = 0, $product_ids = 0 ) { 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_line = "AND woim.meta_value IN ($product_ids)"; else $query_line = "AND woim.meta_value != 0"; // Count the number of products $product_count_query = $wpdb->get_col( " SELECT COUNT(woim.meta_value) FROM {$wpdb->prefix}posts AS p INNER JOIN {$wpdb->prefix}postmeta AS pm ON p.ID = pm.post_id INNER JOIN {$wpdb->prefix}woocommerce_order_items AS woi ON p.ID = woi.order_id INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS woim ON woi.order_item_id = woim.order_item_id WHERE p.post_status IN ( 'wc-" . implode( "','wc-", $statuses ) . "' ) AND pm.meta_key = '_customer_user' AND pm.meta_value = $customer_id AND woim.meta_key IN ( '_product_id', '_variation_id' ) $query_line " ); // Set the count in a string $count = reset($product_count_query); // Return a boolean value if count is higher than 0 return $count > 0 ? true : false; } 

Код идет в файле function.php вашей активной дочерней темы (или темы), а также в любом файле плагина.

Этот код проверяется на Woocommerce 3+ и работает (он также должен работать и с предыдущими версиями).


ПРИМЕРЫ ПРИМЕНЕНИЯ:

Пример 1 (зарегистрированный клиент) : обнаружение, если текущий пользователь купил один из определенных продуктов (идентификаторы продуктов должны быть массивом)

 // Define the targeted Products IDs $product_ids = array( 38, 41, 85, 95 ); if( has_bought_items( '', $product_ids ) ) echo "<p>You have already purchased one of this products</p>"; else echo "<p>You have not yet purchased one of this products</p>"; 

Пример 2 (установка $user_id ) Обнаружение, если определенный пользователь приобрел один из определенных продуктов (идентификаторы продуктов должны быть массивом)

 // Define the user ID $user_id = 85; // Define the targeted Products IDs $product_ids = array( 38, 41, 85, 95 ); if( has_bought_items( $user_id, $product_ids ) ) echo "<p>This user have already purchased one of this products</p>"; else echo "<p>This user have not yet purchased one of this products</p>"; 

Если $user_id не определен и текущий пользователь не зарегистрирован, эта функция вернет false .

Пример 3 (зарегистрированный клиент) : обнаружение, если текущий пользователь уже выполнил покупку

 if( has_bought_items() ) echo '<p>You have already maid a purchase</p>'; else echo '<p>Welcome, for your first purchase you will get a discount of 10%</p>'; 

Пример 4 (установка $user_id ) Обнаружение, если определенный пользователь уже $user_id покупку

 // Define the user ID $user_id = 85; if( has_bought_items( $user_id ) ) echo '<p>customer have already maid a purchase</p>'; else echo '<p>Customer with 0 purshases</p>'; 

Если $user_id не определен и текущий пользователь не зарегистрирован, эта функция вернет false .