Plugin Directory

Changeset 3489936


Ignore:
Timestamp:
03/24/2026 12:00:23 PM (11 days ago)
Author:
nakedcatplugins
Message:

Update to version 8.1 from GitHub

Location:
taxonomy-discounts-woocommerce
Files:
8 edited
1 copied

Legend:

Unmodified
Added
Removed
  • taxonomy-discounts-woocommerce/tags/8.1/admin/functions.js

    r3404819 r3489936  
    66    function ($) {
    77
    8         function tdw_reset_form_add(complete) {
    9             if (complete) {
     8        function tdw_reset_form_add( complete ) {
     9            if ( complete ) {
    1010                $( '#tdw-form-add-taxonomy' ).val( '' );
     11                $( '#tdw-form-add' ).find( 'select' ).each( function() {
     12                    $( this ).val( $( this ).find( 'option:first' ).val() );
     13                } );
    1114            }
    1215            $( '.tdw-edit-rule' ).hide();
     
    2124            // Really reset
    2225            $( '#tdw-form-add' ).find( 'input[type=text], input[type=number], textarea' ).val( '' );
     26            $( '#tdw-form-add' ).find( 'input[type=checkbox]' ).prop( 'checked', false );
     27            // Special cases
     28            $( '#tdw-form-add-role' ).val( '_all_users_' );
    2329            $( '#tdw-form-add-type' ).val( '' );
    2430            $( '#tdw-form-add-disable-coupon' ).val( '1' );
    2531            $( '#tdw-form-add-active' ).val( '1' );
     32            // Pro
     33            $( '#tdw-form-pro-exclude-sale-products' ).val( '0' );
    2634        }
    2735
     
    6068        function tdw_form_add_term() {
    6169            $( '#tdw-form-add' ).addClass( 'tdw-ajax-loading' );
    62             if ( $( '#tdw-form-add-term' ).val() === '' ) {
     70            var add_term_val = [].concat( $( '#tdw-form-add-term' ).val() || [] );
     71            if ( ! add_term_val.filter( v => v !== '' ).length ) {
    6372                $( '#tdw-form-add-div-2' ).hide();
    6473                $( '#tdw-form-add-div-3' ).hide();
     
    95104                } else {
    96105                    $( '#tdw-form-add-choose-type-' + $( '#tdw-form-add-type' ).val() ).show();
     106                    $( '#tdw-form-add-choose-type-description-' + $( '#tdw-form-add-type' ).val() ).show();
    97107                    $( '[class*="tdw-form-add-choose-hide-"]' ).show();
    98108                    $( '.tdw-form-add-choose-hide-' + $( '#tdw-form-add-type' ).val() ).hide();
     
    116126            '#tdw-form-add',
    117127            function () {
     128                var add_term_val = [].concat( $( '#tdw-form-add-term' ).val() || [] );
    118129                $( '#tdw-form-add .form-invalid' ).removeClass( 'form-invalid' );
    119130                if (
    120131                $( '#tdw-form-add-taxonomy' ).val() != ''
    121132                &&
    122                 $( '#tdw-form-add-term' ).val() != ''
     133                add_term_val.filter( v => v !== '' ).length
    123134                &&
    124135                $( '#tdw-form-add-priority' ).val() > 0
     
    162173                                break;
    163174                        }
    164                         if (go) {
     175                        if ( go ) {
    165176                            $( '#tdw-form-add' ).addClass( 'tdw-ajax-loading' );
    166177                            $.post(
    167178                                ajaxurl,
    168179                                $( '#tdw-form-add' ).serialize() + '&action=tdw_form_add_submit&nonce=' + $( '#tdw-form-add #_wpnonce' ).val(),
    169                                 function (response) {
     180                                function ( response ) {
    170181                                    if ( response == '1' ) {
    171182                                        // Clear form
  • taxonomy-discounts-woocommerce/tags/8.1/includes/class-wc-taxonomy-discounts-webdados.php

    r3488358 r3489936  
    173173            apply_filters( 'tdw_perc_sale_badge', false )
    174174        ) {
     175            // Classic
    175176            add_filter( 'woocommerce_sale_flash', array( &$this, 'woocommerce_sale_flash' ), 10, 3 );
     177            // Blocks
     178            add_filter( 'woocommerce_sale_badge_text', array( &$this, 'woocommerce_sale_badge_text' ), 10, 2 );
    176179        }
    177180        // Show discount information on the loop
     
    451454        }
    452455        return $name;
     456    }
     457
     458    /**
     459     * Get human-readable description for a discount rule type
     460     *
     461     * @param string $type       The rule type identifier (e.g., 'percentage', 'x-for-y').
     462     * @param bool   $strip_tags Whether to strip HTML tags from the description (default: false).
     463     * @return string      The translated human-readable description for the rule type.
     464     */
     465    public function get_rule_type_description( $type, $strip_tags = false ) {
     466        switch ( $type ) {
     467            case 'percentage':
     468                $description = esc_html__( 'Percentage: apply an absolute percentage discount to all the products that match the conditions.', 'taxonomy-discounts-woocommerce' );
     469                break;
     470            case 'x-for-y':
     471                $description = esc_html__( 'Buy x get y free (BOGO): offer y items when x (of the same product that match the conditions) are bought.', 'taxonomy-discounts-woocommerce' );
     472                break;
     473            default:
     474                $description = apply_filters( 'tdw_non_default_rule_type_description', '', $type );
     475                break;
     476        }
     477        if ( $strip_tags ) {
     478            $description = wp_strip_all_tags( $description );
     479        }
     480        return $description;
    453481    }
    454482
     
    690718                        foreach ( $rules as $rule_key => $rule ) {
    691719                            if ( WC_Taxonomy_Discounts_Webdados()->valid_rule_user_role( $rule ) && WC_Taxonomy_Discounts_Webdados()->valid_rule_date( $rule ) && isset( $rule['type'] ) ) {
    692                                 if (
    693                                     has_term( $term_id, $rule['taxonomy'], $product_id )
    694                                     ||
    695                                     // Allow PRO add-on or other plugins to extend the has_term check and return valid even if the product does not have the term
    696                                     apply_filters( 'tdw_has_term_or_valid', false, has_term( $term_id, $rule['taxonomy'], $product_id ), $term_id, $rule['taxonomy'], $product_id )
    697                                 ) {
     720                                if ( $this->has_term( $term_id, $rule['taxonomy'], $product_id ) ) {
    698721                                    return apply_filters( 'tdw_get_product_applied_rule', $rule, $product );
    699722                                }
     
    705728        }
    706729        return false;
     730    }
     731
     732    /**
     733     * Check if a product has a specific term in a taxonomy or if the term is considered valid for the product by external filters
     734     * For example, sitewide discounts
     735     *
     736     * @param int    $term_id    The term ID to check.
     737     * @param string $taxonomy   The taxonomy name to check the term in.
     738     * @param int    $product_id The product ID to check the term against.
     739     * @return boolean
     740     */
     741    private function has_term( $term_id, $taxonomy, $product_id ) {
     742        return (
     743            has_term( $term_id, $taxonomy, $product_id )
     744            ||
     745            // Allow PRO add-on or other plugins to extend the has_term check and return valid even if the product does not have the term
     746            apply_filters(
     747                'tdw_has_term_or_valid',
     748                false,
     749                has_term( $term_id, $taxonomy, $product_id ),
     750                $term_id,
     751                $taxonomy,
     752                $product_id
     753            )
     754        );
    707755    }
    708756
     
    10361084                                    isset( $rule['type'] )
    10371085                                    &&
    1038                                     has_term( $term_id, $rule['taxonomy'], $cart_item['product_id'] )
     1086                                    $this->has_term( $term_id, $rule['taxonomy'], $cart_item['product_id'] )
    10391087                                    &&
    10401088                                    ! in_array( (int) $cart_item['product_id'], $this->cache_do_not_apply_discount, true ) // Fix on sale removal
     
    13741422                    foreach ( $terms as $term_id => $rules ) {
    13751423                        foreach ( $rules as $rule_key => $rule ) {
    1376                             if ( self::valid_rule_user_role( $rule ) && self::valid_rule_date( $rule ) && isset( $rule['type'] ) && has_term( $term_id, $rule['taxonomy'], $product_id ) ) {
     1424                            if ( self::valid_rule_user_role( $rule ) && self::valid_rule_date( $rule ) && isset( $rule['type'] ) && $this->has_term( $term_id, $rule['taxonomy'], $product_id ) ) {
    13771425                                switch ( $rule['type'] ) {
    13781426                                    case 'percentage':
     
    17321780     * Modifies the WooCommerce sale badge to display the actual discount percentage
    17331781     *
    1734      * @param string     $html    The original sale badge HTML.
    1735      * @param WP_Post    $post    The product post object.
    1736      * @param WC_Product $product The product object.
     1782     * @param string     $html      The original sale badge HTML.
     1783     * @param WP_Post    $post      The product post object.
     1784     * @param WC_Product $product   The product object.
     1785     * @param bool       $only_text Whether to return only text (for blocks) or full HTML.
    17371786     * @return string             Modified sale badge HTML with percentage or original HTML.
    17381787     */
    1739     public function woocommerce_sale_flash( $html, $post, $product ) {
     1788    public function woocommerce_sale_flash( $html, $post, $product, $only_text = false ) {
    17401789        $new_html = false;
    17411790        $rule     = self::get_product_applied_rule( $product );
     
    17461795                        $found = true;
    17471796                        if ( floatval( $rule['min-qtt'] ) === (float) 0 || floatval( $rule['min-qtt'] ) === (float) 1 ) {
    1748                             $new_html = sprintf( '-%d%', intval( $rule['value'] ) );
     1797                            $new_html = sprintf( '-%d%%', intval( $rule['value'] ) );
    17491798                        }
    17501799                        // We need to keep it short
     
    17681817        $new_html = apply_filters( 'tdw_perc_sale_badge_html', $new_html, $product, $rule );
    17691818        if ( $new_html ) {
    1770             if ( $this->flatsome_active ) {
     1819            if ( $only_text ) {
     1820                $html = $new_html;
     1821            } elseif ( $this->flatsome_active ) {
    17711822                $search = '/(<span class="onsale">).*?(<\/span>)/';
    17721823                $html   = preg_replace( $search, '<span class="onsale">' . $new_html . '</span>', $html );
     
    17761827        }
    17771828        return $html;
     1829    }
     1830
     1831    /**
     1832     * Customize sale badge text for blocks
     1833     *
     1834     * Modifies the sale badge text when only text is requested (e.g. for Gutenberg blocks) to show discount percentage
     1835     *
     1836     * @param string     $text    The original sale badge text.
     1837     * @param WC_Product $product The product object.
     1838     * @return string             Modified sale badge text with percentage or original text.
     1839     */
     1840    public function woocommerce_sale_badge_text( $text, $product ) {
     1841        return $this->woocommerce_sale_flash( $text, null, $product, true );
    17781842    }
    17791843
     
    19191983                        <div id="tdw-form-add-div-2" class="tdw-hidden">
    19201984                            <p id="tdw-form-add-choose-role" class="tdw-float-left">
    1921                                 <label for="tdw-form-add-type"><strong><?php esc_html_e( 'User role', 'taxonomy-discounts-woocommerce' ); ?></strong>:</label>
     1985                                <label for="tdw-form-add-role"><strong><?php esc_html_e( 'User role', 'taxonomy-discounts-woocommerce' ); ?></strong>:</label>
    19221986                                <br>
    19231987                                <?php self::wp_dropdown_roles( 'add', '' ); ?>
     
    19372001                                    ?>
    19382002                                </select>
     2003                                <?php
     2004                                foreach ( $this->discount_types as $discount_type ) {
     2005                                    $description = self::get_rule_type_description( $discount_type, true );
     2006                                    if ( trim( $description ) === '' ) {
     2007                                        continue;
     2008                                    }
     2009                                    ?>
     2010                                    <span id="tdw-form-add-choose-type-description-<?php echo esc_attr( $discount_type ); ?>" class="tdw-hidden tdw-hide-empty-type">
     2011                                        <?php
     2012                                        echo wp_kses_post(
     2013                                            wc_help_tip(
     2014                                                $description
     2015                                            )
     2016                                        );
     2017                                        ?>
     2018                                    </span>
     2019                                    <?php
     2020                                }
     2021                                ?>
    19392022                            </p>
    19402023                            <p id="tdw-form-add-choose-type-percentage" class="tdw-float-left tdw-hidden tdw-hide-empty-type">
     
    19552038                                            sprintf(
    19562039                                                /* translators: %1$s: strong open tag, %2$s: Aggregate variations, %3$s: strong close tag */
    1957                                                 __( '%1$s%2$s%3$s: if enabled, the quantity will be the sum of all the variations of a product.', 'taxonomy-discounts-woocommerce' ),
     2040                                                __( '%1$s%2$s%3$s: if enabled, the quantity will be the sum of all the variations of a product in the cart.', 'taxonomy-discounts-woocommerce' ),
    19582041                                                '<strong>',
    19592042                                                __( 'Aggregate variations', 'taxonomy-discounts-woocommerce' ),
     
    20102093                        <div id="tdw-form-add-div-4" class="tdw-hidden">
    20112094                            <p id="tdw-form-add-choose-active" class="tdw-float-left">
    2012                                 <label for="tdw-form-add-priority"><strong><?php esc_html_e( 'Active', 'taxonomy-discounts-woocommerce' ); ?></strong>:</label>
     2095                                <label for="tdw-form-add-active"><strong><?php esc_html_e( 'Active', 'taxonomy-discounts-woocommerce' ); ?></strong>:</label>
    20132096                                <br>
    20142097                                <select id="tdw-form-add-active" name="tdw-form-add-active">
     
    24362519                    );
    24372520                    // Not escaped because wp_dropdown_categories does not need it (and it fails with wp_kses_post)
    2438                     echo trim( $terms ) !== '' ? trim( $terms ) : esc_html__( 'No terms available', 'taxonomy-discounts-woocommerce' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
     2521                    if ( trim( $terms ) !== '' ) {
     2522                        echo $terms; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
     2523                        do_action( 'tdw_admin_after_add_terms_dropdown' );
     2524                    } else {
     2525                        esc_html_e( 'No terms available', 'taxonomy-discounts-woocommerce' );
     2526                    }
    24392527                } else {
    24402528                    ?>
     
    24452533                }
    24462534                ?>
    2447 
    24482535            <?php
    24492536            wp_die();
     
    25082595                        $data['advanced_id'] = isset( $_POST['tdw-form-advanced-id'] ) ? trim( sanitize_text_field( wp_unslash( $_POST['tdw-form-advanced-id'] ) ) ) : '';
    25092596                    }
    2510                     if ( intval( $_POST['tdw-form-add-term'] ) > 0 ) {
     2597                    $data = apply_filters( 'tdw_form_add_data_before_save', $data, $_POST ); // Let pro or others manipulate the final data
     2598                    // This is where we should check for integer or array of integers and add to several termns at the same time
     2599                    // The interface should only be implemented on the PRO Add-on, but the logic needs to be here
     2600                    // See: https://github.com/webdados/Taxonomy-Term-and-Role-based-Discounts-for-WooCommerce---PRO-add-on/issues/12
     2601                    if ( ( ! is_array( $_POST['tdw-form-add-term'] ) ) && intval( $_POST['tdw-form-add-term'] ) > 0 ) {
     2602                        // Default: save to one term
    25112603                        add_term_meta( intval( $_POST['tdw-form-add-term'] ), $this->discount_rule_meta_key, $data );
     2604                    } elseif ( is_array( $_POST['tdw-form-add-term'] ) ) {
     2605                        // If an array of terms is sent, we loop through it and add the rule to each term - From PRO Add-on
     2606                        foreach ( $_POST['tdw-form-add-term'] as $term_id ) {
     2607                            if ( intval( $term_id ) > 0 ) {
     2608                                add_term_meta( intval( $term_id ), $this->discount_rule_meta_key, $data );
     2609                            }
     2610                        }
    25122611                    }
    25132612                    do_action( 'tdw_rule_add', intval( $_POST['tdw-form-add-term'] ), $data['taxonomy'], $data );
     
    25952694                }
    25962695                if ( $results && isset( $_POST['tdw-form-edit-term'] ) && intval( $_POST['tdw-form-edit-term'] ) > 0 && isset( $_POST['meta_id'] ) && intval( $_POST['meta_id'] ) > 0 ) {
     2696                    $data = apply_filters( 'tdw_form_edit_data_before_save', $data, $_POST ); // Let pro or others manipulate the final data
    25972697                    update_term_meta( intval( $_POST['tdw-form-edit-term'] ), $this->discount_rule_meta_key, $data, $old_data );
    25982698                }
  • taxonomy-discounts-woocommerce/tags/8.1/readme.txt

    r3488358 r3489936  
    66Tested up to: 7.0
    77Requires PHP: 7.2
    8 Stable tag: 8.0
     8Stable tag: 8.1
    99License: GPLv3
    1010License URI: https://www.gnu.org/licenses/gpl-3.0.html
     
    154154== Changelog ==
    155155
     156= 8.1 - 2026-03-24 =
     157* [NEW] [PRO add-on](https://nakedcatplugins.com/product/taxonomy-term-and-role-based-discounts-for-woocommerce-pro-add-on/?utm_source=wordpress.org&utm_medium=link&utm_campaign=taxonomydiscounts_woocommerce_plugin) 6.2: Add discount to multiple terms at the same time
     158* [TWEAK] Show discount type description helper when adding a discount
     159* [FIX] Sitewide discounts from the [PRO add-on](https://nakedcatplugins.com/product/taxonomy-term-and-role-based-discounts-for-woocommerce-pro-add-on/?utm_source=wordpress.org&utm_medium=link&utm_campaign=taxonomydiscounts_woocommerce_plugin) were not correctly applied to the cart
     160* [FIX] Show percentage on the product sale badge block
     161* [FIX] Reset the add new rule form after each interaction
     162* [DEV] New `tdw_form_add_data_before_save` and `tdw_form_edit_data_before_save` filters to allow the PRO Add-on or 3rd Party developers to manipulate the rule data before it is saved to term meta
     163
    156164= 8.0 - 2026-03-22 =
    157165* [NEW] [PRO add-on](https://nakedcatplugins.com/product/taxonomy-term-and-role-based-discounts-for-woocommerce-pro-add-on/?utm_source=wordpress.org&utm_medium=link&utm_campaign=taxonomydiscounts_woocommerce_plugin) 6.0: New discount type: Fixed value
  • taxonomy-discounts-woocommerce/tags/8.1/taxonomy-discounts-woocommerce.php

    r3488358 r3489936  
    33 * Plugin Name:          Taxonomy/Term and Role based Discounts for WooCommerce
    44 * Description:          "Taxonomy/Term based Discounts for WooCommerce" lets you configure discount/pricing rules for products based on any product taxonomy terms and WordPress user roles
    5  * Version:              8.0
     5 * Version:              8.1
    66 * Author:               Naked Cat Plugins (by Webdados)
    77 * Author URI:           https://nakedcatplugins.com
  • taxonomy-discounts-woocommerce/trunk/admin/functions.js

    r3404819 r3489936  
    66    function ($) {
    77
    8         function tdw_reset_form_add(complete) {
    9             if (complete) {
     8        function tdw_reset_form_add( complete ) {
     9            if ( complete ) {
    1010                $( '#tdw-form-add-taxonomy' ).val( '' );
     11                $( '#tdw-form-add' ).find( 'select' ).each( function() {
     12                    $( this ).val( $( this ).find( 'option:first' ).val() );
     13                } );
    1114            }
    1215            $( '.tdw-edit-rule' ).hide();
     
    2124            // Really reset
    2225            $( '#tdw-form-add' ).find( 'input[type=text], input[type=number], textarea' ).val( '' );
     26            $( '#tdw-form-add' ).find( 'input[type=checkbox]' ).prop( 'checked', false );
     27            // Special cases
     28            $( '#tdw-form-add-role' ).val( '_all_users_' );
    2329            $( '#tdw-form-add-type' ).val( '' );
    2430            $( '#tdw-form-add-disable-coupon' ).val( '1' );
    2531            $( '#tdw-form-add-active' ).val( '1' );
     32            // Pro
     33            $( '#tdw-form-pro-exclude-sale-products' ).val( '0' );
    2634        }
    2735
     
    6068        function tdw_form_add_term() {
    6169            $( '#tdw-form-add' ).addClass( 'tdw-ajax-loading' );
    62             if ( $( '#tdw-form-add-term' ).val() === '' ) {
     70            var add_term_val = [].concat( $( '#tdw-form-add-term' ).val() || [] );
     71            if ( ! add_term_val.filter( v => v !== '' ).length ) {
    6372                $( '#tdw-form-add-div-2' ).hide();
    6473                $( '#tdw-form-add-div-3' ).hide();
     
    95104                } else {
    96105                    $( '#tdw-form-add-choose-type-' + $( '#tdw-form-add-type' ).val() ).show();
     106                    $( '#tdw-form-add-choose-type-description-' + $( '#tdw-form-add-type' ).val() ).show();
    97107                    $( '[class*="tdw-form-add-choose-hide-"]' ).show();
    98108                    $( '.tdw-form-add-choose-hide-' + $( '#tdw-form-add-type' ).val() ).hide();
     
    116126            '#tdw-form-add',
    117127            function () {
     128                var add_term_val = [].concat( $( '#tdw-form-add-term' ).val() || [] );
    118129                $( '#tdw-form-add .form-invalid' ).removeClass( 'form-invalid' );
    119130                if (
    120131                $( '#tdw-form-add-taxonomy' ).val() != ''
    121132                &&
    122                 $( '#tdw-form-add-term' ).val() != ''
     133                add_term_val.filter( v => v !== '' ).length
    123134                &&
    124135                $( '#tdw-form-add-priority' ).val() > 0
     
    162173                                break;
    163174                        }
    164                         if (go) {
     175                        if ( go ) {
    165176                            $( '#tdw-form-add' ).addClass( 'tdw-ajax-loading' );
    166177                            $.post(
    167178                                ajaxurl,
    168179                                $( '#tdw-form-add' ).serialize() + '&action=tdw_form_add_submit&nonce=' + $( '#tdw-form-add #_wpnonce' ).val(),
    169                                 function (response) {
     180                                function ( response ) {
    170181                                    if ( response == '1' ) {
    171182                                        // Clear form
  • taxonomy-discounts-woocommerce/trunk/includes/class-wc-taxonomy-discounts-webdados.php

    r3488358 r3489936  
    173173            apply_filters( 'tdw_perc_sale_badge', false )
    174174        ) {
     175            // Classic
    175176            add_filter( 'woocommerce_sale_flash', array( &$this, 'woocommerce_sale_flash' ), 10, 3 );
     177            // Blocks
     178            add_filter( 'woocommerce_sale_badge_text', array( &$this, 'woocommerce_sale_badge_text' ), 10, 2 );
    176179        }
    177180        // Show discount information on the loop
     
    451454        }
    452455        return $name;
     456    }
     457
     458    /**
     459     * Get human-readable description for a discount rule type
     460     *
     461     * @param string $type       The rule type identifier (e.g., 'percentage', 'x-for-y').
     462     * @param bool   $strip_tags Whether to strip HTML tags from the description (default: false).
     463     * @return string      The translated human-readable description for the rule type.
     464     */
     465    public function get_rule_type_description( $type, $strip_tags = false ) {
     466        switch ( $type ) {
     467            case 'percentage':
     468                $description = esc_html__( 'Percentage: apply an absolute percentage discount to all the products that match the conditions.', 'taxonomy-discounts-woocommerce' );
     469                break;
     470            case 'x-for-y':
     471                $description = esc_html__( 'Buy x get y free (BOGO): offer y items when x (of the same product that match the conditions) are bought.', 'taxonomy-discounts-woocommerce' );
     472                break;
     473            default:
     474                $description = apply_filters( 'tdw_non_default_rule_type_description', '', $type );
     475                break;
     476        }
     477        if ( $strip_tags ) {
     478            $description = wp_strip_all_tags( $description );
     479        }
     480        return $description;
    453481    }
    454482
     
    690718                        foreach ( $rules as $rule_key => $rule ) {
    691719                            if ( WC_Taxonomy_Discounts_Webdados()->valid_rule_user_role( $rule ) && WC_Taxonomy_Discounts_Webdados()->valid_rule_date( $rule ) && isset( $rule['type'] ) ) {
    692                                 if (
    693                                     has_term( $term_id, $rule['taxonomy'], $product_id )
    694                                     ||
    695                                     // Allow PRO add-on or other plugins to extend the has_term check and return valid even if the product does not have the term
    696                                     apply_filters( 'tdw_has_term_or_valid', false, has_term( $term_id, $rule['taxonomy'], $product_id ), $term_id, $rule['taxonomy'], $product_id )
    697                                 ) {
     720                                if ( $this->has_term( $term_id, $rule['taxonomy'], $product_id ) ) {
    698721                                    return apply_filters( 'tdw_get_product_applied_rule', $rule, $product );
    699722                                }
     
    705728        }
    706729        return false;
     730    }
     731
     732    /**
     733     * Check if a product has a specific term in a taxonomy or if the term is considered valid for the product by external filters
     734     * For example, sitewide discounts
     735     *
     736     * @param int    $term_id    The term ID to check.
     737     * @param string $taxonomy   The taxonomy name to check the term in.
     738     * @param int    $product_id The product ID to check the term against.
     739     * @return boolean
     740     */
     741    private function has_term( $term_id, $taxonomy, $product_id ) {
     742        return (
     743            has_term( $term_id, $taxonomy, $product_id )
     744            ||
     745            // Allow PRO add-on or other plugins to extend the has_term check and return valid even if the product does not have the term
     746            apply_filters(
     747                'tdw_has_term_or_valid',
     748                false,
     749                has_term( $term_id, $taxonomy, $product_id ),
     750                $term_id,
     751                $taxonomy,
     752                $product_id
     753            )
     754        );
    707755    }
    708756
     
    10361084                                    isset( $rule['type'] )
    10371085                                    &&
    1038                                     has_term( $term_id, $rule['taxonomy'], $cart_item['product_id'] )
     1086                                    $this->has_term( $term_id, $rule['taxonomy'], $cart_item['product_id'] )
    10391087                                    &&
    10401088                                    ! in_array( (int) $cart_item['product_id'], $this->cache_do_not_apply_discount, true ) // Fix on sale removal
     
    13741422                    foreach ( $terms as $term_id => $rules ) {
    13751423                        foreach ( $rules as $rule_key => $rule ) {
    1376                             if ( self::valid_rule_user_role( $rule ) && self::valid_rule_date( $rule ) && isset( $rule['type'] ) && has_term( $term_id, $rule['taxonomy'], $product_id ) ) {
     1424                            if ( self::valid_rule_user_role( $rule ) && self::valid_rule_date( $rule ) && isset( $rule['type'] ) && $this->has_term( $term_id, $rule['taxonomy'], $product_id ) ) {
    13771425                                switch ( $rule['type'] ) {
    13781426                                    case 'percentage':
     
    17321780     * Modifies the WooCommerce sale badge to display the actual discount percentage
    17331781     *
    1734      * @param string     $html    The original sale badge HTML.
    1735      * @param WP_Post    $post    The product post object.
    1736      * @param WC_Product $product The product object.
     1782     * @param string     $html      The original sale badge HTML.
     1783     * @param WP_Post    $post      The product post object.
     1784     * @param WC_Product $product   The product object.
     1785     * @param bool       $only_text Whether to return only text (for blocks) or full HTML.
    17371786     * @return string             Modified sale badge HTML with percentage or original HTML.
    17381787     */
    1739     public function woocommerce_sale_flash( $html, $post, $product ) {
     1788    public function woocommerce_sale_flash( $html, $post, $product, $only_text = false ) {
    17401789        $new_html = false;
    17411790        $rule     = self::get_product_applied_rule( $product );
     
    17461795                        $found = true;
    17471796                        if ( floatval( $rule['min-qtt'] ) === (float) 0 || floatval( $rule['min-qtt'] ) === (float) 1 ) {
    1748                             $new_html = sprintf( '-%d&percnt;', intval( $rule['value'] ) );
     1797                            $new_html = sprintf( '-%d%%', intval( $rule['value'] ) );
    17491798                        }
    17501799                        // We need to keep it short
     
    17681817        $new_html = apply_filters( 'tdw_perc_sale_badge_html', $new_html, $product, $rule );
    17691818        if ( $new_html ) {
    1770             if ( $this->flatsome_active ) {
     1819            if ( $only_text ) {
     1820                $html = $new_html;
     1821            } elseif ( $this->flatsome_active ) {
    17711822                $search = '/(<span class="onsale">).*?(<\/span>)/';
    17721823                $html   = preg_replace( $search, '<span class="onsale">' . $new_html . '</span>', $html );
     
    17761827        }
    17771828        return $html;
     1829    }
     1830
     1831    /**
     1832     * Customize sale badge text for blocks
     1833     *
     1834     * Modifies the sale badge text when only text is requested (e.g. for Gutenberg blocks) to show discount percentage
     1835     *
     1836     * @param string     $text    The original sale badge text.
     1837     * @param WC_Product $product The product object.
     1838     * @return string             Modified sale badge text with percentage or original text.
     1839     */
     1840    public function woocommerce_sale_badge_text( $text, $product ) {
     1841        return $this->woocommerce_sale_flash( $text, null, $product, true );
    17781842    }
    17791843
     
    19191983                        <div id="tdw-form-add-div-2" class="tdw-hidden">
    19201984                            <p id="tdw-form-add-choose-role" class="tdw-float-left">
    1921                                 <label for="tdw-form-add-type"><strong><?php esc_html_e( 'User role', 'taxonomy-discounts-woocommerce' ); ?></strong>:</label>
     1985                                <label for="tdw-form-add-role"><strong><?php esc_html_e( 'User role', 'taxonomy-discounts-woocommerce' ); ?></strong>:</label>
    19221986                                <br>
    19231987                                <?php self::wp_dropdown_roles( 'add', '' ); ?>
     
    19372001                                    ?>
    19382002                                </select>
     2003                                <?php
     2004                                foreach ( $this->discount_types as $discount_type ) {
     2005                                    $description = self::get_rule_type_description( $discount_type, true );
     2006                                    if ( trim( $description ) === '' ) {
     2007                                        continue;
     2008                                    }
     2009                                    ?>
     2010                                    <span id="tdw-form-add-choose-type-description-<?php echo esc_attr( $discount_type ); ?>" class="tdw-hidden tdw-hide-empty-type">
     2011                                        <?php
     2012                                        echo wp_kses_post(
     2013                                            wc_help_tip(
     2014                                                $description
     2015                                            )
     2016                                        );
     2017                                        ?>
     2018                                    </span>
     2019                                    <?php
     2020                                }
     2021                                ?>
    19392022                            </p>
    19402023                            <p id="tdw-form-add-choose-type-percentage" class="tdw-float-left tdw-hidden tdw-hide-empty-type">
     
    19552038                                            sprintf(
    19562039                                                /* translators: %1$s: strong open tag, %2$s: Aggregate variations, %3$s: strong close tag */
    1957                                                 __( '%1$s%2$s%3$s: if enabled, the quantity will be the sum of all the variations of a product.', 'taxonomy-discounts-woocommerce' ),
     2040                                                __( '%1$s%2$s%3$s: if enabled, the quantity will be the sum of all the variations of a product in the cart.', 'taxonomy-discounts-woocommerce' ),
    19582041                                                '<strong>',
    19592042                                                __( 'Aggregate variations', 'taxonomy-discounts-woocommerce' ),
     
    20102093                        <div id="tdw-form-add-div-4" class="tdw-hidden">
    20112094                            <p id="tdw-form-add-choose-active" class="tdw-float-left">
    2012                                 <label for="tdw-form-add-priority"><strong><?php esc_html_e( 'Active', 'taxonomy-discounts-woocommerce' ); ?></strong>:</label>
     2095                                <label for="tdw-form-add-active"><strong><?php esc_html_e( 'Active', 'taxonomy-discounts-woocommerce' ); ?></strong>:</label>
    20132096                                <br>
    20142097                                <select id="tdw-form-add-active" name="tdw-form-add-active">
     
    24362519                    );
    24372520                    // Not escaped because wp_dropdown_categories does not need it (and it fails with wp_kses_post)
    2438                     echo trim( $terms ) !== '' ? trim( $terms ) : esc_html__( 'No terms available', 'taxonomy-discounts-woocommerce' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
     2521                    if ( trim( $terms ) !== '' ) {
     2522                        echo $terms; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
     2523                        do_action( 'tdw_admin_after_add_terms_dropdown' );
     2524                    } else {
     2525                        esc_html_e( 'No terms available', 'taxonomy-discounts-woocommerce' );
     2526                    }
    24392527                } else {
    24402528                    ?>
     
    24452533                }
    24462534                ?>
    2447 
    24482535            <?php
    24492536            wp_die();
     
    25082595                        $data['advanced_id'] = isset( $_POST['tdw-form-advanced-id'] ) ? trim( sanitize_text_field( wp_unslash( $_POST['tdw-form-advanced-id'] ) ) ) : '';
    25092596                    }
    2510                     if ( intval( $_POST['tdw-form-add-term'] ) > 0 ) {
     2597                    $data = apply_filters( 'tdw_form_add_data_before_save', $data, $_POST ); // Let pro or others manipulate the final data
     2598                    // This is where we should check for integer or array of integers and add to several termns at the same time
     2599                    // The interface should only be implemented on the PRO Add-on, but the logic needs to be here
     2600                    // See: https://github.com/webdados/Taxonomy-Term-and-Role-based-Discounts-for-WooCommerce---PRO-add-on/issues/12
     2601                    if ( ( ! is_array( $_POST['tdw-form-add-term'] ) ) && intval( $_POST['tdw-form-add-term'] ) > 0 ) {
     2602                        // Default: save to one term
    25112603                        add_term_meta( intval( $_POST['tdw-form-add-term'] ), $this->discount_rule_meta_key, $data );
     2604                    } elseif ( is_array( $_POST['tdw-form-add-term'] ) ) {
     2605                        // If an array of terms is sent, we loop through it and add the rule to each term - From PRO Add-on
     2606                        foreach ( $_POST['tdw-form-add-term'] as $term_id ) {
     2607                            if ( intval( $term_id ) > 0 ) {
     2608                                add_term_meta( intval( $term_id ), $this->discount_rule_meta_key, $data );
     2609                            }
     2610                        }
    25122611                    }
    25132612                    do_action( 'tdw_rule_add', intval( $_POST['tdw-form-add-term'] ), $data['taxonomy'], $data );
     
    25952694                }
    25962695                if ( $results && isset( $_POST['tdw-form-edit-term'] ) && intval( $_POST['tdw-form-edit-term'] ) > 0 && isset( $_POST['meta_id'] ) && intval( $_POST['meta_id'] ) > 0 ) {
     2696                    $data = apply_filters( 'tdw_form_edit_data_before_save', $data, $_POST ); // Let pro or others manipulate the final data
    25972697                    update_term_meta( intval( $_POST['tdw-form-edit-term'] ), $this->discount_rule_meta_key, $data, $old_data );
    25982698                }
  • taxonomy-discounts-woocommerce/trunk/readme.txt

    r3488358 r3489936  
    66Tested up to: 7.0
    77Requires PHP: 7.2
    8 Stable tag: 8.0
     8Stable tag: 8.1
    99License: GPLv3
    1010License URI: https://www.gnu.org/licenses/gpl-3.0.html
     
    154154== Changelog ==
    155155
     156= 8.1 - 2026-03-24 =
     157* [NEW] [PRO add-on](https://nakedcatplugins.com/product/taxonomy-term-and-role-based-discounts-for-woocommerce-pro-add-on/?utm_source=wordpress.org&utm_medium=link&utm_campaign=taxonomydiscounts_woocommerce_plugin) 6.2: Add discount to multiple terms at the same time
     158* [TWEAK] Show discount type description helper when adding a discount
     159* [FIX] Sitewide discounts from the [PRO add-on](https://nakedcatplugins.com/product/taxonomy-term-and-role-based-discounts-for-woocommerce-pro-add-on/?utm_source=wordpress.org&utm_medium=link&utm_campaign=taxonomydiscounts_woocommerce_plugin) were not correctly applied to the cart
     160* [FIX] Show percentage on the product sale badge block
     161* [FIX] Reset the add new rule form after each interaction
     162* [DEV] New `tdw_form_add_data_before_save` and `tdw_form_edit_data_before_save` filters to allow the PRO Add-on or 3rd Party developers to manipulate the rule data before it is saved to term meta
     163
    156164= 8.0 - 2026-03-22 =
    157165* [NEW] [PRO add-on](https://nakedcatplugins.com/product/taxonomy-term-and-role-based-discounts-for-woocommerce-pro-add-on/?utm_source=wordpress.org&utm_medium=link&utm_campaign=taxonomydiscounts_woocommerce_plugin) 6.0: New discount type: Fixed value
  • taxonomy-discounts-woocommerce/trunk/taxonomy-discounts-woocommerce.php

    r3488358 r3489936  
    33 * Plugin Name:          Taxonomy/Term and Role based Discounts for WooCommerce
    44 * Description:          "Taxonomy/Term based Discounts for WooCommerce" lets you configure discount/pricing rules for products based on any product taxonomy terms and WordPress user roles
    5  * Version:              8.0
     5 * Version:              8.1
    66 * Author:               Naked Cat Plugins (by Webdados)
    77 * Author URI:           https://nakedcatplugins.com
Note: See TracChangeset for help on using the changeset viewer.