You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:实现WooCommerce产品Add To Cart按钮点击统计并后台展示

WooCommerce 加入购物车点击量统计失效问题修复

核心需求

统计所有场景(产品列表、归档页、详情页等)下,访客/登录用户点击「Add To Cart」按钮的次数,初始值为0,每点击一次递增1,以此判断产品关注度;结账完成属于后续统计环节。

当前状态

已在WooCommerce>Products后台创建统计列,但点击量始终无法被统计,尝试零散方案无效,对JS逻辑和列创建有初步理解。

现有代码

Part 1:替换详情页Add To Cart按钮

// remove all versions of the "Add To Cart" and replace them
remove_action(' woocommerce_simple_add_to_cart', 'woocommerce_simple_add_to_cart', 30 );

add_action('woocommerce_simple_add_to_cart', 'count_add_to_cart_with_clicks', 1);
function count_add_to_cart_with_clicks() {

    // add our own version
    add_action( 'woocommerce_simple_add_to_cart', 'count_simple_add_to_cart_with_clicks', 30 );
}

function count_simple_add_to_cart_with_clicks() {

    global $product;

        if ( ! $product->add_to_cart_url() ) return;

            echo '<p><a href="' . $product->add_to_cart_url() . '" class="single_add_to_cart_button button alt countable" 
            data-pid="' . $product->get_id() . '">' . $product->single_add_to_cart_text() . '</a></p>';

        // js that should count each click and show the number in wp-admin under WoooCommerce > Products
        wc_enqueue_js( "
            $( 'a.countable' ).click( function( e ) {
            e.preventDefault();
            $.post( '" . '/wp-admin/admin-ajax.php' . "', { action: 'increment_counter', pid: $( this ).data( 'pid' ) } );
            window.open($ ( this ).attr( 'href' ) );
            }
        );
    ");
}

Part 2:AJAX计数处理

add_action( 'wp_ajax_increment_counter', 'count_increment_counter' );
add_action( 'wp_ajax_nopriv_increment_counter', 'count_increment_counter' );
function count_increment_counter() {

    $pid = $_POST['pid'];

    $click = get_post_meta( $pid, '_click_counter', true ) ? (int) get_post_meta( $pid, '_click_counter', true ) + 1 : 1; update_post_meta( $pid, '_click_counter', $click );

    wp_die();
}

Part 3:后台添加统计列

add_filter( 'manage_edit-product_columns', 'count_clicks_in_admin_products_column', 9999);
function count_clicks_in_admin_products_column( $columns ) {

    $columns['click'] = 'click';
    
    return $columns;
}

Part 4:填充统计列内容

add_action( 'manage_product_posts_custom_column', 'click_admin_products_views_column_content', 9999, 2 );
function click_admin_products_views_column_content( $column, $product_id ) {

    if ( $column == 'click' ) {

            echo get_post_meta( $product_id, '_click_counter', true );
    }
}

问题分析

现有代码存在4个核心问题导致统计失效:

  • 覆盖场景不全:仅替换了简单产品详情页的按钮,忽略了产品列表/归档页、可变产品等其他场景的按钮。
  • 事件绑定缺陷:使用静态click绑定,无法触发动态加载产品的按钮事件;window.open导致跳转行为异常。
  • 初始值与安全问题:无计数数据时直接设为1,不符合初始值0的需求;AJAX请求未对pid做安全校验。
  • 钩子移除错误:remove_action的钩子名前有空格,导致原按钮未被成功替换。

修复后的完整代码

1. 全局替换所有场景的Add To Cart按钮

// 处理产品列表/归档页的Add To Cart按钮
add_filter('woocommerce_loop_add_to_cart_link', 'add_countable_attr_to_loop_button', 10, 3);
function add_countable_attr_to_loop_button($html, $product, $args) {
    $html = str_replace('class="', 'class="countable ', $html);
    $html = str_replace('href=', 'data-pid="' . esc_attr($product->get_id()) . '" href=', $html);
    return $html;
}

// 替换简单产品详情页的Add To Cart按钮
remove_action('woocommerce_simple_add_to_cart', 'woocommerce_simple_add_to_cart', 30);
add_action('woocommerce_simple_add_to_cart', 'replace_simple_add_to_cart_button', 30);
function replace_simple_add_to_cart_button() {
    global $product;
    if (!$product->add_to_cart_url()) return;
    
    echo '<p><a href="' . esc_url($product->add_to_cart_url()) . '" class="single_add_to_cart_button button alt countable" 
    data-pid="' . esc_attr($product->get_id()) . '">' . esc_html($product->single_add_to_cart_text()) . '</a></p>';
}

// 替换可变产品详情页的Add To Cart按钮(按需启用)
remove_action('woocommerce_single_variation_add_to_cart_button', 'woocommerce_single_variation_add_to_cart_button', 20);
add_action('woocommerce_single_variation_add_to_cart_button', 'replace_variable_add_to_cart_button', 20);
function replace_variable_add_to_cart_button() {
    global $product;
    echo '<button type="submit" class="single_add_to_cart_button button alt countable" data-pid="' . esc_attr($product->get_id()) . '">' . esc_html($product->single_add_to_cart_text()) . '</button>';
}

2. 优化JS事件绑定与AJAX请求

add_action('wp_footer', 'enqueue_add_to_cart_count_js');
function enqueue_add_to_cart_count_js() {
    if (!is_woocommerce()) return;
    
    ?>
    <script>
    jQuery(document).on('click', 'a.countable, button.countable', function(e) {
        var $this = jQuery(this);
        var pid = $this.data('pid');
        
        // 发送AJAX统计请求
        jQuery.post('<?php echo esc_url(admin_url('admin-ajax.php')); ?>', {
            action: 'increment_counter',
            pid: pid
        });
        
        // 区分按钮类型处理跳转/提交
        if ($this.is('button')) {
            $this.closest('form').submit();
        } else {
            window.location.href = $this.attr('href');
        }
        e.preventDefault();
    });
    </script>
    <?php
}

3. 安全优化的AJAX计数逻辑

add_action('wp_ajax_increment_counter', 'count_increment_counter');
add_action('wp_ajax_nopriv_increment_counter', 'count_increment_counter');
function count_increment_counter() {
    // 校验请求合法性
    if (!isset($_POST['pid']) || !is_numeric($_POST['pid'])) {
        wp_die();
    }
    
    $pid = intval($_POST['pid']);
    // 初始值设为0,点击后递增
    $current_count = get_post_meta($pid, '_click_counter', true);
    $current_count = $current_count ? intval($current_count) : 0;
    update_post_meta($pid, '_click_counter', $current_count + 1);
    
    wp_die();
}

4. 后台列优化(显示初始值0)

add_filter('manage_edit-product_columns', 'count_clicks_in_admin_products_column', 9999);
function count_clicks_in_admin_products_column($columns) {
    $columns['click_counter'] = '加入购物车点击量'; // 更直观的列名
    return $columns;
}

add_action('manage_product_posts_custom_column', 'click_admin_products_views_column_content', 9999, 2);
function click_admin_products_views_column_content($column, $product_id) {
    if ($column == 'click_counter') {
        $count = get_post_meta($product_id, '_click_counter', true);
        echo $count ? intval($count) : 0; // 无数据时显示0
    }
}

关键修复说明

  • 全场景覆盖:通过钩子处理列表、详情页、可变产品等所有添加到购物车的按钮。
  • 事件委托:使用document.on绑定事件,支持动态加载的产品按钮。
  • 安全合规:对AJAX参数做校验,使用esc_*系列函数处理输出,符合WordPress安全规范。
  • 初始值修正:无计数数据时显示0,点击后从0开始递增。
  • 行为修复:正确处理链接和表单按钮的跳转/提交逻辑,避免异常。

内容的提问来源于stack exchange,提问作者Learning WooStoreFront

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 21:08:14