Agregue el nombre principal a la lista de términos en el menú desplegable (por ejemplo, lista de categorías de cupones)

6 minutos de lectura

Tenemos una tienda de ropa WooCommerce y queremos crear cupones que excluyan ciertas categorías. Nuestra estructura de categorías es la siguiente (simplificada):

– Men
– – Shirts
– – Jeans
– – Sale
– Women
– – Shirts
– – Jeans
– – Sale

Sin embargo, cuando queremos seleccionar [Men » Sale] desde el Excluir categorías selector desplegable en [WooCommerce » Marketing » Coupons » Usage Restriction] la lista se aplana:

– Jeans
– Men
– Sale
– Sale
– Shirts
– Shirts
– Women

Ahora no está claro qué categorías son realmente las que queremos excluir. Tener en min, esta es una estructura muy simplificada, en el entorno en vivo esto es aún peor.

yo esperaba un apply_filter pero el get_terms() aparentemente no tiene ninguno en código, ver código fuente en github aquí » (línea #233)

$categories = get_terms('product_cat', 'orderby=name&hide_empty=0');

Dado que esto no está filtrado, no veo una forma de agregar una categoría principal para tener este como el resultado deseado:

- Men
- Men » Jeans
- Men » Shirts
- Men » Sale
- Women
- Women » Jeans
- Women » Shirts
- Women » Sale

¿Alguna idea de cómo obtener esa lista ahora que no hay filtro en el código?

Por ejemplo, esto es lo que usamos para un complemento de terceros que también usa los términos de la categoría WooCommerce, pero que en realidad hace tiene un filtro en get_terms y el código nativo de WooCommerce en los cupones no…

Ejemplo:

if (!function_exists('yith_wcbep_add_parent_category_name')) {
    function yith_wcbep_add_parent_category_name($terms, $args) {
        $term_name="";
        $taxonomy  = isset($args['taxonomy']) ? $args['taxonomy'] : '';
        foreach ($terms as $term_id => $term_name) {
            $term = get_term_by('id', $term_id, $taxonomy);
            $term_name = isset($term->name) ? $term->name : '';
            if (isset($term->parent) && $term->parent > 0) {
                $parent = get_term_by('id', $term->parent, $term->taxonomy);
                $term_name = $parent->name . ' > ' . $term_name;
                $terms[$term_id] = $term_name;
            }
        }
        return $terms;
    }
    add_filter('yith_plugin_fw_json_search_found_terms', 'yith_wcbep_add_parent_category_name', 10, 2);
}

  • Si está tratando de excluir productos en oferta de los cupones, simplemente agregue la restricción en el cupón. Es un gran error tener 10 categorías nombradas venta. Puedes filtrar productos en oferta.

    – Snuffy

    12 de junio a las 9:09


Avatar de usuario de Buttered_Toast
Tostada con mantequilla

Esta fue una característica interesante para resolver, parece un poco extraño Woocommerce no tiene nombres de jerarquía en las categorías de cupones.
Investigué un poco y descubrí que el único filtro apropiado parece ser get_termsdespués de algunas pruebas y errores se me ocurrió esto.

if (!function_exists('btAddHierarchyNameToCouponsCat')) {
    function btAddHierarchyNameToCouponsCat($terms)
    {
        if (!is_admin()) {
            return $terms;
        }
    
        global $pagenow;
    
        if ($pagenow !== 'post-new.php' && $pagenow !== 'post.php') {
            return $terms;
        }
    
        if (
            (
                !empty($_GET['post_type'])
                && $_GET['post_type'] === 'shop_coupon'
            )
            || (
                !empty($_GET['post'])
                && get_post_type($_GET['post']) === 'shop_coupon'
                && !empty($_GET['action'])
                && $_GET['action'] === 'edit'
            )
        ) {
            foreach ($terms as &$term) {
                $term->name = (function ($term) {
                    $fullName = array_map(function ($ancestorId) {
                        $ancestor = get_term_by('term_id', $ancestorId, 'product_cat');
    
                        return $ancestor->name;
                    }, array_reverse(get_ancestors($term->term_id, 'product_cat')));
    
                    $fullName[] = $term->name;
    
                    return implode(' -> ', $fullName);
                })($term);
            }
    
            return $terms;
        }
    
        return $terms;
    }

    add_filter('get_terms', 'btAddHierarchyNameToCouponsCat');
}

Aquí está el antes.

ingrese la descripción de la imagen aquí

Y aquí está el después.

ingrese la descripción de la imagen aquí

La idea general de este filtro es que funcione específicamente solo al crear o editar un cupón en el tablero.
Luego actualiza el nombre de la categoría para que contenga toda la jerarquía de los nombres de las categorías.
Puede que esto no sea perfecto, pero es un punto de partida.

  • Eso es lo que pensé, es extraño que no tengan un filtro en su lugar por defecto, ¿verdad? Pero me gusta este método, es limpio y simple (más o menos) y funcionó de maravilla. ¡Gracias @Buttered_Toast!

    – Ronaldt

    12 de junio a las 13:28


Avatar de usuario de LoicTheAztec
LoicTheAztec

Para resolver este problema, lo que puede hacer es clonar la sección de restricciones de categorías de productos de cupones de WooCommerce, personalizando la salida de categorías como desee * (aquí Agrego el nombre del término padre al nombre de la categoría)eliminando con JavaScript la salida HTML relacionada de las predeterminadas de WooCommerce.

Entonces obtendrás lo siguiente:

ingrese la descripción de la imagen aquí

Aquí está el código de la función enganchada:

// Prepend the parent term name to the term name output
function prepend_parent_term_name( $term, $sep = ' > ' ) {
    if (isset($term->parent) && $term->parent > 0) {
        $parent_name = get_term_by('id', $term->parent, $term->taxonomy)->name;
        return esc_html( $parent_name ) . $sep . esc_html( $term->name );
    } else {
        return esc_html( $term->name );
    }
}

// Replace WooCommerce Admin Coupon product categories restictions section with a custom one
add_action( 'woocommerce_coupon_options_usage_restriction', 'action_coupon_options_usage_restriction', 10, 2 );
function action_coupon_options_usage_restriction( $coupon_id, $coupon ) {
    echo '<div class="options_group">';

    // Categories.
    ?>
    <p class="form-field">
        <label for="product_categories2"><?php _e( 'Product categories', 'woocommerce' ); ?></label>
        <select id="product_categories2" name="product_categories[]" style="width: 50%;"  class="wc-enhanced-select" multiple="multiple" data-placeholder="<?php esc_attr_e( 'Any category', 'woocommerce' ); ?>">
            <?php
            $category_ids = $coupon->get_product_categories( 'edit' );
            $categories   = get_terms( 'product_cat', 'orderby=name&hide_empty=0' );

            if ( $categories ) {
                foreach ( $categories as $cat ) {
                    echo '<option value="' . esc_attr( $cat->term_id ) . '"' . wc_selected( $cat->term_id, $category_ids ) . '>' . prepend_parent_term_name( $cat ) . '</option>';
                }
            }
            ?>
        </select> <?php echo wc_help_tip( __( 'Product categories that the coupon will be applied to, or that need to be in the cart in order for the "Fixed cart discount" to be applied.', 'woocommerce' ) ); ?>
    </p>

    <?php // Exclude Categories. ?>
    <p class="form-field">
        <label for="exclude_product_categories2"><?php _e( 'Exclude categories', 'woocommerce' ); ?></label>
        <select id="exclude_product_categories2" name="exclude_product_categories[]" style="width: 50%;"  class="wc-enhanced-select" multiple="multiple" data-placeholder="<?php esc_attr_e( 'No categories', 'woocommerce' ); ?>">
            <?php
            $category_ids = $coupon->get_excluded_product_categories( 'edit' );
            $categories   = get_terms( 'product_cat', 'orderby=name&hide_empty=0' );

            if ( $categories ) {
                foreach ( $categories as $cat ) {
                    echo '<option value="' . esc_attr( $cat->term_id ) . '"' . wc_selected( $cat->term_id, $category_ids ) . '>' . prepend_parent_term_name( $cat ) . '</option>';
                }
            }
            ?>
        </select>
        <?php echo wc_help_tip( __( 'Product categories that the coupon will not be applied to, or that cannot be in the cart in order for the "Fixed cart discount" to be applied.', 'woocommerce' ) ); ?>
    </p>
    <?php // Removing default product categories restrictions html  ?>
    <script>
    jQuery(function($){
        $('#product_categories').parent().parent().remove();
    });
    </script>
    <?php 
    echo '</div>';
}

El código va en el archivo functions.php de su tema secundario activo (o tema activo). Probado y funciona.

  • Eventualmente terminé usando @Buttered_Toast, su método, que es un poco más limpio, ya que solo cambia la lista de términos reales sin tocar html/javascript. Pero aunque no usé su código, veo lo que está haciendo aquí y me gusta la solución creativa. +1

    – Ronaldt

    12 de junio a las 13:30

¿Ha sido útil esta solución?