wordpress: ¿Cómo obtener los ID de categoría de producto más vendidos en WooCommerce?

CorePress2024-01-24  9

Estoy buscando una manera de mostrar las 6 categorías de productos más vendidos. esto es lo que tengo ahora:

$termsprent = get_terms(
    array(
        'taxonomy'    => 'product_cat',
        'hide_empty'  => true,
        'numberposts' => 4,
        'meta_key'    => 'total_sales',
        'orderby'     => 'meta_value_num',
        'order'       => 'desc',
    )
);

¿Alguien sabe alguna forma de modificarlo para que muestre las categorías de productos más vendidos?



------------------------------------

OBTENGA LA SUMA TOTAL DE VENTAS DE UNA CATEGORÍA DE PRODUCTO

Puede utilizar la siguiente función para obtener la suma total de las ventas de productos pertenecientes a una categoría de producto específica.

El único parámetro de la función es el ID de la categoría del producto. (term_id)

// gets the total sales count of a specific product category
function counts_total_sales_by_product_category( $term_id ) {
    global $wpdb;
    $total_sales = $wpdb->get_var("
        SELECT sum(meta_value)
        FROM $wpdb->postmeta
        INNER JOIN {$wpdb->term_relationships} ON ( {$wpdb->term_relationships}.object_id = {$wpdb->postmeta}.post_id )
        WHERE ( {$wpdb->term_relationships}.term_taxonomy_id IN ($term_id) )
        AND {$wpdb->postmeta}.meta_key = 'total_sales'"
    );
    return $total_sales;
}

OBTENGA LAS CATEGORÍAS DE PRODUCTOS MÁS VENDIDAS

La siguiente función devolverá una matriz con el producto más vendidocategorías ordenadas en orden descendente.

El único parámetro de la función es el límite de categorías de productos. para ser devuelto.

// gets the n product categories with the best sales
function gets_best_selling_product_categories( $limit ) {

    $total_sales = array();
    $product_categories = get_terms( 'product_cat' );
    foreach ( $product_categories as $product_cat ) {
        $product_cat_id = $product_cat->term_id;
        $total_sales[$product_cat_id] = counts_total_sales_by_product_category( $product_cat_id );
    }

    // removes empty values from the array
    $total_sales = array_filter( $total_sales );

    // sorts the array values in descending order
    arsort( $total_sales );

    // gets the first n ($limit) product categories with the most sales
    $best_product_categories = array_slice( $total_sales, 0, $limit, true );

    return $best_product_categories;
}

RESULTADO

A continuación se muestra el resultado de var_dump() de gets_best_selling_product_categories( 4 ); función:

array(4) {
    [15]=> string(3) "209"
    [30]=> string(3) "160"
    [32]=> string(2) "56"
    [31]=> string(2) "18"
}

La clave de la matriz será el ID de la categoría del producto y su valor será la suma total de las ventas de esa categoría.

El código ha sido probado y funciona. Agréguelo al archivo funciones.php de su tema activo.

1

Si cambiamos gets_best_selling_product_categoriesfirma de la función en $limit = null podemos usar la función sin limitar la salida

- MTpH9

15 de diciembre de 2023 a las 12:33



------------------------------------

Una versión ligeramente modificada y ampliada de la respuesta de @vincenzo-di-gaetano.

La función devuelve inmediatamente la matriz de WP_Terms. En cuanto a mí, es más conveniente, aunque se modifica el objeto. El resultado será como:

array(2) {
  [0]=> object(WP_Term)#3977 (11) { 
    ["term_id"]=> int(15)
    ["name"]=> string(13) "Uncategorized"
    ...
    ["sales"]=> string(1) "5" 
  } 
  [1]=> object(WP_Term)#3978 (11) { 
    ["term_id"]=> int(16)
    ["name"]=> string(13) "Uncategorized 2"
    ...
    ["sales"]=> string(1) "3" 
  } 
}
function popular_product_categories( $limit = null ): array {
    $terms = array();
    $product_categories = get_terms( 'product_cat' );
    foreach ( $product_categories as $product_cat ) {
        // set total sales property
        $product_cat->sales = counts_total_sales_by_product_category( $product_cat->term_id );
        $terms[$product_cat->term_id] = $product_cat;
    }

    // filter out empty terms
    $terms = array_filter( $terms, fn($term) => $term->sales > 0 );

    // sort the terms by sales values in descending order
    usort($terms, fn($a, $b) => $a->sales <=> $b->sales);

    return array_slice( $terms, 0, $limit, true );
}

El almacenamiento en caché también es apropiado para este tipo de operaciones, así que lo agregué al ejemplo:

// Return total sales number for a product category
function counts_total_sales_by_product_category( $term_id, $use_cache = true ): ?string {
    global $wpdb;
    $cache = $use_cache ? get_transient( 'total_sales_term_'.$term_id ) : false;
    
    // Check if we can return value early
    if ( false !== $cache ) {
        return $cache;
    }
    $total_sales = $wpdb->get_var("
        SELECT sum(meta_value)
        FROM $wpdb->postmeta
        INNER JOIN {$wpdb->term_relationships} ON ( {$wpdb->term_relationships}.object_id = {$wpdb->postmeta}.post_id )
        WHERE ( {$wpdb->term_relationships}.term_taxonomy_id IN ($term_id) )
        AND {$wpdb->postmeta}.meta_key = 'total_sales'"
    );
    // Update cache value
    set_transient( 'total_sales_term_'.$term_id, $total_sales, 12 * HOUR_IN_SECONDS );
    return $total_sales;
}

Además, podemos actualizar el caché cuando se completa el pedido


// Update counts_total_sales_by_product_category transient when a product is sold
function update_total_sales_term_transient( $order_id ): void {
    $order = wc_get_order( $order_id );
    $items = $order->get_items();

    foreach ( $items as $item ) {
        $product_id = $item->get_product_id();
        $product_categories = get_the_terms( $product_id, 'product_cat' );
        if ( ! empty( $product_categories ) ) {
            // recalculate total sales for each category
            foreach ( $product_categories as $product_category ) {
                counts_total_sales_by_product_category( $product_category->term_id, false); // use the second parameter to override the cache
            }
        }
    }
}
add_action('woocommerce_order_status_completed', 'update_total_sales_term_transient');

randomThread
Python 3.x: calcular el porcentaje de valores agrupadosc++ - Uso de std::cin en un bucle while para leer varios números mientras se agregan (el bucle no termina)c# - ¿Cómo se actualizan varias tablas con 1 consulta?Usando Loop dentro de una función con declaración If en R¿Por qué el código funciona cuando escribo myArray[i] y no cuando guardo myArray[i] en una variable?javascript - reaccionar-partículas-js: No se puede establecer un fondo y un anchohtml: uso de consulta de medios para ejecutar