php 我如何使用拖放操作使Woocommerce购物车项目可排序?

rseugnpd  于 2023-01-08  发布在  PHP
关注(0)|答案(1)|浏览(127)

我使用mPdf来创建我的woocommerce购物车中的项目的pdf文件,我需要一种方法来排序购物车表中的项目使用拖放,并输出项目的新顺序为$cart_contents的pdf文件来识别项目的顺序。我的想法是,我可以使用jquery sortable使cart表可以拖放,然后使用cart为cart表中的每个项目添加一个位置编号项数据。然后我可以使用更新:函数事件并根据它在购物车中的位置更新位置号。之后我可以使用asort和分配给它们的位置号输出排序的购物车项目。我不确定我是否使这种方式比它应该更困难,因为我是jquery和php的新手。我一直在寻找一个答案,这一切在互联网上相当长的一段时间,但无济于事,所以任何指针或帮助的答案将不胜感激。
在这里,我通过拖放的方式对购物车中的商品进行排序,然后将产品ID作为一个字符串,按照它们在 AJAX 中的放置顺序进行发送:

function wc_sortable_cart_items() {
    if ( class_exists( 'WooCommerce' ) ) {
        if( is_cart() && (count(WC()->cart->get_cart()) > 0) ){
?>
<script>
jQuery(function($) {
      $('table.shop_table.cart tbody').sortable({
        items: 'tr.cart_item',
        cursor: 'move',
            axis: 'y',
            update: function(event, ui) {
                $('#loading-animation').show();
                opts = {
                    url: ajaxurl,
                    type: 'POST',
                    async: true,
                    cache: false,
                    dataType: 'json',
                    data:{
                        action: 'item_sort',
                        order: $(this).sortable('toArray').toString(),
                    },
                    success: function(response) {
                        $('#loading-animation').hide();
                        return; 
                    },
                    error: function(xhr,textStatus,e) {
                        alert(e);
                        alert('There was an error saving the updates');
                        $('#loading-animation').hide();
                        return; 
                    }
                };
                $.ajax(opts);
            }
        });
});
</script>
<?php
        }
    }
}
add_action( 'wp_footer', 'wc_sortable_cart_items' );

在这里,我接收产品ID并通过$wpdb更新menu_order meta数据。

function my_save_item_order() {
    global $wpdb;
    $counter = 0;
    $order = explode(',', $_POST['order']);
    foreach ($order as $item_id) {
$wpdb->update($wpdb->posts, array( 'menu_order' => $counter ), array( 'ID' => $item_id) );
        $counter++;
}
wp_die(1);
}
add_action('wp_ajax_item_sort', 'my_save_item_order');
add_action('wp_ajax_nopriv_item_sort', 'my_save_item_order');

这里我使用menu_order meta对购物车进行排序:

add_action('woocommerce_cart_loaded_from_session', 'sort_cart_items_by_customfield', 100);
function sort_cart_items_by_customfield() {
    $items_to_sort = $cart_contents = array();
    foreach (WC()->cart->cart_contents as $item_key => $cart_item) {
        $product        = $cart_item['data'];
        $menu_order     = $product->get_menu_order();
        $order_number   = intval($menu_order);
        $items_to_sort[$item_key] = $order_number;

    }
        asort($items_to_sort);
        foreach ($items_to_sort as $cart_item_key => $order_number) {
        $cart_contents[$cart_item_key] = WC()->cart->cart_contents[$cart_item_key];
    }
        WC()->cart->cart_contents = $cart_contents;
}

所有这些都是有效的,但是由于我使用menu_order meta来对产品进行排序,因此可能会出现一些问题。例如,如果您的购物车中有两个相同的产品,并且位于不同的表行中,或者如果两个人同时在购物车中有相同的商品,那么这种方法根本就不起作用。
这里有没有人有过类似的经验,但是使用了一个唯一的标识符,比如购物车项目键,并将位置存储在会话数据中,或者我可以利用一个隐藏的输入字段和购物车项目的索引,并相应地更新它们?
我已经没有主意了,真的很想得到一些帮助。
这是我第一次在这里问问题,所以如果你需要更多的信息或如果有什么不清楚,请告诉我。
先谢了!

mklgxw1f

mklgxw1f1#

所以我最终设法解决了这个问题。
我为将来可能寻找类似解决方案的任何人创造了这个答案。
1.我通过编辑cart.php模板添加cart项目键作为每个cart项目表行的ID,理想的做法是将cart.php添加到/wp-content/themes/YOURTHEME/woocommerce/cart中,以避免在更新过程中被覆盖。

<tr class="woocommerce-cart-form__cart-item <?php echo esc_attr( apply_filters( 'woocommerce_cart_item_class', 'cart_item', $cart_item, $cart_item_key ) ); ?>"id="<?php echo $cart_item['key']; ?>">

1.我将所需的脚本排队并本地化admin-ajax.php:

wp_localize_script( 'admin-js', 'dtAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php')));

function enqueue_script_jquery() {
    if( is_cart() && (count(WC()->cart->get_cart()) > 0) ){
        wp_enqueue_script( 'jquery-ui');
        wp_enqueue_script( 'jquery-ui-sortable');
    }
}
add_action('wp_enqueue_scripts', 'enqueue_script_jquery');

1.我添加了脚本来使表行可排序,并将ID的顺序发送到服务器。

function wc_sortable_cart_items() {
    if ( class_exists( 'WooCommerce' ) ) {
        if( is_cart() && (count(WC()->cart->get_cart()) > 0) ){
?>
<script async>
jQuery(document).ready(function($){
    $(document).ajaxComplete(function() {
        $('table.shop_table.cart tbody').sortable({
            items: 'tr.cart_item',
            cursor: 'move',
            axis: 'y',
            opacity: 0.6,
            delay: 75,
            containment: "document",
            update: function(event, ui) {
                var cart_keys = $(".cart_item[id]").map(function(){ return this.id; }).get();
                opts = {
                    url: ajaxurl,
                    type: 'POST',
                    async: true,
                    cache: false,
                    dataType: 'json',
                    data:{
                        security: $('#woocommerce-cart-nonce').val(),
                        action: 'item_sort',
                        order: cart_keys,
                    },
                };
                $.ajax(opts);
            }
        });
    });
});
</script>
<?php
        }
    }
}
add_action( 'wp_footer', 'wc_sortable_cart_items' );

1.然后保存进程中购物车项目(购物车项目键)的顺序:

function my_save_item_order() {
 if( ! isset( $_POST['security'] ) || ! wp_verify_nonce( $_POST['security'], 'woocommerce-cart' ) ) {
 wp_send_json( array( 'nonce_fail' => 1 ) );
 exit;
 }
  $order = $_POST['order'];
        WC()->session->set( 'sort_order', $order );
        wp_send_json( [
            'sort_order' => $order,
        ] );
wp_die(1);
}
add_action('wp_ajax_item_sort', 'my_save_item_order');
add_action('wp_ajax_nopriv_item_sort', 'my_save_item_order');

1.然后,我根据设置的会话订购购物车项目:

function sort_cart_items_by_dd() {
    $sort_order = WC()->session->get( 'sort_order' ) ;
        if( empty( $sort_order ) )
            return;
        
        WC()->session->__unset( 'sort_order' );
        
        $cart_contents = array();
        foreach( $sort_order as $cart_key )
        {
            foreach( WC()->cart->cart_contents as $item_key => $cart_item )
            {
                if( $item_key == $cart_key )
                {
                    $cart_contents[$item_key] = $cart_item;
                }
                
            }
        }
        
        WC()->cart->cart_contents = $cart_contents;
}
add_action('woocommerce_cart_loaded_from_session', 'sort_cart_items_by_dd', 100);

就这样,现在您可以使用拖放操作对购物车表中的购物车项目进行排序。

相关问题