Получить непокупаемые товары, разбитые на страницы как Пользовательский контент моей учетной записи в Woocommerce - PullRequest
0 голосов
/ 05 сентября 2018

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

Теперь, на мой первый вопрос ...

В моей настройке woocommerce каждый продукт загружается в цифровом формате, и покупатели могут покупать его только один раз. Срок действия всех загрузок истекает через 14 дней по соображениям безопасности.

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

Теперь мой вопрос в два раза. Во-первых, для приведенного ниже кода, который показывает страницу на панели инструментов их учетной записи, я не могу заставить paginav работать, поэтому, если вы видите, что там может быть не так, пожалуйста, дайте мне знать.

Но главный вопрос в том, как превратить запрос в функцию сортировки? Это означает, что если клиент выбирает, он может сортировать по «Еще не куплен»

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

Вот код, который я сейчас использую для отображения страницы, на которой показаны продукты, которые у них "еще не куплены"

// *NOT PURCHASED
add_filter ( 'woocommerce_account_menu_items',     'custom_purchased_products_link', 40 );
add_action( 'init', 'custom_add_products_endpoint' );
add_action( 'woocommerce_account_purchased-products_endpoint',     'custom_populate_products_page' );

// here we hook the My Account menu links and add our custom one
function custom_purchased_products_link( $menu_links ){
    // we use array_slice() because we want our link to be on the 3rd position
    return array_slice( $menu_links, 0, 2, true )
    + array( 'purchased-products' => 'Not Purchased Yet' )
    + array_slice( $menu_links, 2, NULL, true );
}

// here we register our rewrite rule
function custom_add_products_endpoint() {
    add_rewrite_endpoint( 'purchased-products', EP_PAGES );
}

// here we populate the new page with the content
function custom_populate_products_page() {
    global $wpdb;

    // this SQL query allows to get all the products purchased by the current     user
    // in this example we sort products by date but you can reorder them another     way
    $purchased_products_ids = $wpdb->get_col( $wpdb->prepare(
        "
        SELECT      itemmeta.meta_value
        FROM        " . $wpdb->prefix . "woocommerce_order_itemmeta itemmeta
        INNER JOIN  " . $wpdb->prefix . "woocommerce_order_items items
                    ON itemmeta.order_item_id = items.order_item_id
        INNER JOIN  $wpdb->posts orders
                    ON orders.ID = items.order_id
        INNER JOIN  $wpdb->postmeta ordermeta
                    ON orders.ID = ordermeta.post_id
        WHERE       itemmeta.meta_key = '_product_id'
                    AND ordermeta.meta_key = '_customer_user'
                    AND ordermeta.meta_value = %s
        ORDER BY    orders.post_date DESC
        ",
        get_current_user_id()
    ) );

    // some orders may contain the same product, but we do not need it twice
    $purchased_products_ids = array_unique( $purchased_products_ids );

    // if the customer purchased something
    if( !empty( $purchased_products_ids ) ) :

        // it is time for a regular WP_Query
        $purchased_products = new WP_Query( array(
            'post_type' => 'product',
            'paginate' => true,
            'posts_per_page' => 50,
            'paginate' => true,
            'post_status' => 'publish',
            'post__not_in' => $purchased_products_ids,
        ) );

        echo '<div class="woocommerce columns-3">';
        echo '<h3>Some Products you have not yet purchased (Max display 39)    
        </h3>';

        woocommerce_product_loop_start();

        while ( $purchased_products->have_posts() ) : $purchased_products- 
        >the_post();

            wc_get_template_part( 'content', 'product' );

        endwhile;
        woocommerce_product_loop_end();

        woocommerce_reset_loop();
        wp_reset_postdata();

    else:
        echo 'Nothing purchased yet.';
    endif;
}

add_action( 'woocommerce_after_shop_loop_item', 
'user_logged_in_product_already_bought', 30 );

1 Ответ

0 голосов
/ 05 сентября 2018

Вы можете упростить и оптимизировать код, создавая уникальный запрос SQL, чтобы получить идентификаторы продуктов, не купленные текущим клиентом. Затем вы можете использовать шорткод Woocommerce [products], чтобы получить страничную страницу этого не купленного продукта.

Таким образом, код будет намного легче и эффективнее, с нумерацией страниц (в Woocommerce 3.2 +) :

// Add a new custom menu item to tabbed "My account" menu
add_filter ( 'woocommerce_account_menu_items', 'add_account_new_menu_item', 30, 1 );
function add_account_new_menu_item( $items ){
    // Define the new item position in the tabbed menu
    $position = 3;

    // Define the new item to include in the tabbed menu
    $item = array( 'unpurchased-products' => 'Not purchased' );

    return array_slice( $items, 0, ($position - 1), true ) + $item + array_slice( $items, ($position - 1), NULL, true );
}

// Enable the new custom menu item tabbed "My account" menu
add_action( 'init', 'add_account_new_menu_item_endpoint' );
function add_account_new_menu_item_endpoint() {
    add_rewrite_endpoint( 'unpurchased-products', EP_PAGES );

    // ==> Always reflush rewrite rules the first time:
    // ==> Go to the Permalinks options page and re-save the permalinks
}

// Add the corresponding content for this new custom menu item
add_action( 'woocommerce_account_unpurchased-products_endpoint', 'custom_populate_products_page' );
function custom_populate_products_page() {
    global $wpdb;

    //Unique SQL query to get tne non purchased product Ids
    $not_purchased_ids = $wpdb->get_col( "SELECT DISTINCT ID
        FROM {$wpdb->prefix}posts
        WHERE post_type = 'product'
        AND post_status = 'publish'
        AND ID NOT IN (SELECT DISTINCT woim.meta_value
        FROM {$wpdb->prefix}woocommerce_order_itemmeta AS woim
        JOIN {$wpdb->prefix}woocommerce_order_items AS woi ON woim.order_item_id = woi.order_item_id
        JOIN {$wpdb->prefix}posts AS p ON woi.order_id = p.ID
        JOIN {$wpdb->prefix}postmeta AS pm ON p.ID = pm.post_id
        WHERE woim.meta_key = '_product_id' AND pm.meta_key = '_customer_user'
        AND pm.meta_value != '{get_current_user_id()}')
    " );

    $included_ids = implode(',', $not_purchased_ids);

    echo do_shortcode("[products limit='9' columns='3' paginate='true' orderby='' ids='$included_ids']");
}

// Rename the default option from sorting select field in My account only
add_filter ( 'woocommerce_catalog_orderby', 'custom_catalog_orderby', 30, 1 );
function custom_catalog_orderby( $options ){
    if( is_account_page() )
        $options['menu_order'] = __( 'Not purchased yet', 'woocommerce' );

    return $options;
}

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

Включить новый пункт меню с вкладкой Мой аккаунт

После сохранения этого кода вам необходимо сбросить правила переписывания Wordpress:
Перейти в настройки WordPress на странице Постоянные ссылки и заново сохранить постоянные ссылки.


Изменение количества товаров на странице и количества столбцов:

В коротком коде limit - количество товаров на странице и columns - количество столбцов.

 [products limit='9' columns='3' paginate='true' orderby='' ids='$included_ids']

enter image description here


Полезные ссылки:

...