Plugin Directory

Changeset 3483393


Ignore:
Timestamp:
03/16/2026 04:33:56 AM (2 weeks ago)
Author:
htplugins
Message:

Update to version 1.3.5 from GitHub

Location:
ever-compare
Files:
26 edited
1 copied

Legend:

Unmodified
Added
Removed
  • ever-compare/tags/1.3.5/assets/js/frontend.js

    r3108021 r3483393  
    11;(function($){
    22"use strict";
    3    
     3
    44    var $body = $('body'),
    5         $popup = $('.htcompare-popup');
    6        
    7     $body.append(`<div id="htcompare-error-modal" class="htcompare-error-modal" style="display:none">
    8         <div class="htcompare-error-modal-content">
    9             <button class="htcompare-error-modal-close">&times;</button>
    10             <div class="htcompare-error-modal-body"></div>
    11         </div>
    12     </div>`);
    13     const $htcompareErrorModal = $("#htcompare-error-modal");
     5        $popup = $('.htcompare-popup'),
     6        cachedNonce = null,
     7        noncePromise = null;
     8
     9    // Cookie helper: read compare list from cookie
     10    function getCompareListFromCookie() {
     11        var cookieName = evercompare.cookie_name;
     12        var cookies = document.cookie.split(';');
     13        for (var i = 0; i < cookies.length; i++) {
     14            var cookie = cookies[i].trim();
     15            if (cookie.indexOf(cookieName + '=') === 0) {
     16                var value = decodeURIComponent(cookie.substring(cookieName.length + 1));
     17                try {
     18                    var parsed = JSON.parse(value);
     19                    if (Array.isArray(parsed)) {
     20                        return parsed.map(function(id) { return parseInt(id, 10); }).filter(function(id) { return id > 0; });
     21                    }
     22                } catch(e) {}
     23            }
     24        }
     25        return [];
     26    }
     27
     28    // Deferred nonce: fetch on first interaction, cache in memory
     29    function getNonce() {
     30        if (cachedNonce) {
     31            return $.Deferred().resolve(cachedNonce).promise();
     32        }
     33        if (noncePromise) {
     34            return noncePromise;
     35        }
     36        noncePromise = $.ajax({
     37            url: evercompare.ajaxurl,
     38            data: { action: 'ever_compare_get_nonce' },
     39            dataType: 'json',
     40            method: 'GET',
     41        }).then(function(response) {
     42            cachedNonce = response.nonce;
     43            noncePromise = null;
     44            return cachedNonce;
     45        }).fail(function() {
     46            noncePromise = null;
     47        });
     48        return noncePromise;
     49    }
     50
     51    // Sync button states from cookie on DOM ready
     52    function syncButtonStates() {
     53        var compareList = getCompareListFromCookie();
     54        $('a.htcompare-btn').each(function() {
     55            var $btn = $(this);
     56            var productId = parseInt($btn.data('product_id'), 10);
     57            if (compareList.indexOf(productId) >= 0) {
     58                $btn.addClass('added');
     59                $btn.html('<span class="htcompare-btn-text">' + $btn.data('added-text') + '</span>');
     60            }
     61        });
     62    }
     63
     64    // Sync counter from cookie on DOM ready
     65    function syncCounter() {
     66        var compareList = getCompareListFromCookie();
     67        $body.find('.htcompare-counter').html(compareList.length);
     68    }
     69
     70    // Load compare table via AJAX for cookie-based pages
     71    function loadCompareTable() {
     72        var $tables = $('.htcompare-table[data-ajax-load]');
     73        if ($tables.length === 0) return;
     74
     75        var compareList = getCompareListFromCookie();
     76        if (compareList.length === 0) {
     77            // Show empty state — fetch table with no IDs to get proper empty template
     78            $.ajax({
     79                url: evercompare.ajaxurl,
     80                data: {
     81                    action: 'ever_compare_get_table',
     82                    ids: '',
     83                },
     84                dataType: 'json',
     85                method: 'GET',
     86                success: function(response) {
     87                    if (typeof response.table !== 'undefined') {
     88                        $tables.each(function() {
     89                            $(this).replaceWith(response.table || '<div class="htcompare-table htcompare-empty"></div>');
     90                        });
     91                        bindShareableLinkHandler();
     92                    }
     93                }
     94            });
     95            return;
     96        }
     97
     98        $.ajax({
     99            url: evercompare.ajaxurl,
     100            data: {
     101                action: 'ever_compare_get_table',
     102                ids: compareList.join(','),
     103            },
     104            dataType: 'json',
     105            method: 'GET',
     106            success: function(response) {
     107                if (response.table) {
     108                    $tables.each(function() {
     109                        $(this).replaceWith(response.table);
     110                    });
     111                    bindShareableLinkHandler();
     112                }
     113            }
     114        });
     115    }
     116
     117    function bindShareableLinkHandler() {
     118        $('.evercompare-copy-link').on('click', function(e) {
     119            evercompareCopyToClipboard($(this).closest('.ever-compare-shareable-link').find('.evercompare-share-link'), this);
     120        });
     121    }
     122
     123    // Error modal
     124    $body.append('<div id="htcompare-error-modal" class="htcompare-error-modal" style="display:none"><div class="htcompare-error-modal-content"><button class="htcompare-error-modal-close">&times;</button><div class="htcompare-error-modal-body"></div></div></div>');
     125    var $htcompareErrorModal = $("#htcompare-error-modal");
    14126    $('.htcompare-error-modal-close').on('click', function() {
    15127        $htcompareErrorModal.css('display', 'none');
    16     })
     128    });
    17129    $(window).on('click', function(e) {
    18130        if(e.target == $htcompareErrorModal[0]) {
    19131            $htcompareErrorModal.css('display', 'none');
    20132        }
    21     })
    22     $('a.htcompare-btn').each(function() {
    23         const $this = $(this);
    24         if($this.hasClass('added')) {
    25             $this.html('<span class="htcompare-btn-text">'+$this.data('added-text')+'</span>');
    26         }
    27     });
     133    });
     134
     135    // Sync states on DOM ready
     136    syncButtonStates();
     137    syncCounter();
     138    loadCompareTable();
    28139
    29140    // Notification Markup
    30     const notificationMarkup = `<div class="htcompare-notification">
    31         <div class="htcompare-notification-text">${evercompare.option_data.success_added_notification_text}</div>
    32         <span class="htcompare-notification-close">close</span>
    33     </div>`
    34     // Insert Notification Markup in body & notification close method if notification is enabled
     141    var notificationMarkup = '<div class="htcompare-notification"><div class="htcompare-notification-text">' + evercompare.option_data.success_added_notification_text + '</div><span class="htcompare-notification-close">close</span></div>';
    35142    if(evercompare.option_data.enable_success_notification === 'on') {
    36143        $body.append(notificationMarkup);
     
    40147    }
    41148    // Notification Show Function
    42     const ShowNotification = (message) => {
     149    var ShowNotification = function(message) {
    43150        if(evercompare.option_data.enable_success_notification === 'on') {
    44151            $body.find('.htcompare-notification-text').html(message);
     
    47154                setTimeout(function() {
    48155                    $body.find('.htcompare-notification').removeClass('open');
    49                 }, +evercompare.option_data.removed_notification_after * 1000)
    50             }
    51         }
    52     }
     156                }, +evercompare.option_data.removed_notification_after * 1000);
     157            }
     158        }
     159    };
    53160
    54161    // Add product in compare table
     
    73180        $this.addClass('loading');
    74181
    75         $.ajax({
    76             url: evercompare.ajaxurl,
    77             data: {
    78                 action: 'ever_compare_add_to_compare',
    79                 nonce: evercompare.nonce,
    80                 id: id,
    81             },
    82             dataType: 'json',
    83             method: 'GET',
    84             success: function ( response ) {
    85                 const $products = typeof response.products === 'array' ? response.products : Object.values(response.products);
    86                 if ( response.table && $products.indexOf(id.toString()) >= 0 ) {
    87                     updateCompareData( response );
    88                     $popup.addClass('open');
    89                 } else {
    90                     $('.htcompare-error-modal-body').html(response.limitReached)
    91                     $htcompareErrorModal.css('display', 'flex');
    92                     console.log( 'Something wrong loading compare data' );
    93                 }
    94                 $body.find('.htcompare-counter').html( response.count );
    95             },
    96             error: function ( data ) {
    97                 console.log('Something wrong with AJAX response.');
    98             },
    99             complete: function (res) {
    100                 $this.removeClass('loading');
    101                 const $products = typeof res.responseJSON.products === 'array' ? res.responseJSON.products : Object.values(res.responseJSON.products);
    102                 if($products.indexOf(id.toString()) >= 0) {
    103                     $this.addClass('added');
    104                     $this.html('<span class="htcompare-btn-text">'+addedText+'</span>');
    105                 }
    106                 ShowNotification(success_message);
    107             },
     182        getNonce().then(function(nonce) {
     183            $.ajax({
     184                url: evercompare.ajaxurl,
     185                data: {
     186                    action: 'ever_compare_add_to_compare',
     187                    nonce: nonce,
     188                    id: id,
     189                },
     190                dataType: 'json',
     191                method: 'GET',
     192                success: function ( response ) {
     193                    if ( !response || !response.products ) {
     194                        $body.find('.htcompare-counter').html( response ? response.count : 0 );
     195                        return;
     196                    }
     197                    var $products = typeof response.products === 'object' ? Object.values(response.products) : response.products;
     198                    var productStrings = $products.map(function(p) { return p.toString(); });
     199                    if ( response.table && productStrings.indexOf(id.toString()) >= 0 ) {
     200                        updateCompareData( response );
     201                        $popup.addClass('open');
     202                    } else {
     203                        $('.htcompare-error-modal-body').html(response.limitReached);
     204                        $htcompareErrorModal.css('display', 'flex');
     205                    }
     206                    $body.find('.htcompare-counter').html( response.count );
     207                },
     208                error: function ( data ) {
     209                    console.log('Something wrong with AJAX response.');
     210                },
     211                complete: function (res) {
     212                    $this.removeClass('loading');
     213                    if (res.responseJSON && res.responseJSON.products) {
     214                        var $products = typeof res.responseJSON.products === 'object' ? Object.values(res.responseJSON.products) : res.responseJSON.products;
     215                        var productStrings = $products.map(function(p) { return p.toString(); });
     216                        if(productStrings.indexOf(id.toString()) >= 0) {
     217                            $this.addClass('added');
     218                            $this.html('<span class="htcompare-btn-text">'+addedText+'</span>');
     219                            ShowNotification(success_message);
     220                        }
     221                    }
     222                },
     223            });
     224        }).fail(function() {
     225            $this.removeClass('loading');
    108226        });
    109227
     
    117235                success_message = evercompare.option_data.success_removed_notification_text.replace('{product_name}', $this.data('product_title'));
    118236            $this.addClass('loading');
     237            getNonce().then(function(nonce) {
     238                jQuery.ajax({
     239                    url: evercompare.ajaxurl,
     240                    data: {
     241                        action: 'ever_compare_remove_from_compare',
     242                        nonce: nonce,
     243                        id: id,
     244                    },
     245                    dataType: 'json',
     246                    method: 'GET',
     247                    success: function (response) {
     248                        if (response) {
     249                            $body.find('.htcompare-counter').html( response.count );
     250                        } else {
     251                            console.log( 'Something wrong loading compare data' );
     252                        }
     253                    },
     254                    error: function (data) {
     255                        console.log('Something wrong with AJAX response.');
     256                    },
     257                    complete: function (res) {
     258                        $this.removeClass('loading added').html('<span class="htcompare-btn-text">'+$this.data('text')+'</span>');
     259                        if (res.responseJSON && res.responseJSON.count !== undefined) {
     260                            ShowNotification(success_message);
     261                        }
     262                    },
     263                });
     264            }).fail(function() {
     265                $this.removeClass('loading');
     266            });
     267        });
     268    }
     269
     270    // Remove data from compare table
     271    $body.on('click', 'a.htcompare-remove', function (e) {
     272        var $table = $('.htcompare-table');
     273
     274        e.preventDefault();
     275        var $this = $(this),
     276            id = $this.data('product_id'),
     277            success_message = evercompare.option_data.success_removed_notification_text.replace('{product_name}', $this.data('product_title'));
     278
     279        $table.addClass('loading');
     280        $this.addClass('loading');
     281
     282        getNonce().then(function(nonce) {
    119283            jQuery.ajax({
    120284                url: evercompare.ajaxurl,
    121285                data: {
    122286                    action: 'ever_compare_remove_from_compare',
    123                     nonce: evercompare.nonce,
     287                    nonce: nonce,
    124288                    id: id,
    125289                },
     
    127291                method: 'GET',
    128292                success: function (response) {
    129                     if (response) {
    130                         $body.find('.htcompare-counter').html( response.count );
     293                    if (response.table) {
     294                        updateCompareData(response);
    131295                    } else {
    132296                        console.log( 'Something wrong loading compare data' );
    133297                    }
     298                    $('a.htcompare-btn').each(function() {
     299                        if($(this).data('product_id') === id) {
     300                            $(this).removeClass('added');
     301                            $(this).html('<span class="htcompare-btn-text">'+$(this).data('text')+'</span>');
     302                        }
     303                    });
     304                    $body.find('.htcompare-counter').html( response.count );
    134305                },
    135306                error: function (data) {
    136307                    console.log('Something wrong with AJAX response.');
    137308                },
    138                 complete: function () {
    139                     $this.removeClass('loading added').html('<span class="htcompare-btn-text">'+$this.data('text')+'</span>');
    140                     ShowNotification(success_message);
     309                complete: function (res) {
     310                    $table.removeClass('loading');
     311                    $this.removeClass('loading');
     312                    if (res.responseJSON && res.responseJSON.table) {
     313                        ShowNotification(success_message);
     314                    }
    141315                },
    142316            });
    143         });
    144     }
    145 
    146     // Remove data from compare table
    147     $body.on('click', 'a.htcompare-remove', function (e) {
    148         var $table = $('.htcompare-table');
    149 
    150         e.preventDefault();
    151         var $this = $(this),
    152             id = $this.data('product_id'),
    153             success_message = evercompare.option_data.success_removed_notification_text.replace('{product_name}', $this.data('product_title'));
    154 
    155         $table.addClass('loading');
    156         $this.addClass('loading');
    157 
    158         jQuery.ajax({
    159             url: evercompare.ajaxurl,
    160             data: {
    161                 action: 'ever_compare_remove_from_compare',
    162                 nonce: evercompare.nonce,
    163                 id: id,
    164             },
    165             dataType: 'json',
    166             method: 'GET',
    167             success: function (response) {
    168                 if (response.table) {
    169                     updateCompareData(response);
    170                 } else {
    171                     console.log( 'Something wrong loading compare data' );
    172                 }
    173                 $('a.htcompare-btn').each(function() {
    174                     if($(this).data('product_id') === id) {
    175                         $(this).removeClass('added');
    176                         $(this).html('<span class="htcompare-btn-text">'+$(this).data('text')+'</span>');
    177                     }
    178                 })
    179                 $body.find('.htcompare-counter').html( response.count );
    180             },
    181             error: function (data) {
    182                 console.log('Something wrong with AJAX response.');
    183             },
    184             complete: function () {
    185                 $table.removeClass('loading');
    186                 $this.addClass('loading');
    187                 ShowNotification(success_message);
    188             },
     317        }).fail(function() {
     318            $table.removeClass('loading');
     319            $this.removeClass('loading');
    189320        });
    190321
     
    195326        if ( $('.htcompare-table').length > 0 ) {
    196327            $('.htcompare-table').replaceWith( data.table );
    197             $('.evercompare-copy-link').on('click',function(e){
    198                 evercompareCopyToClipboard( $(this).closest('.ever-compare-shareable-link').find('.evercompare-share-link') , this );
    199             });
     328            bindShareableLinkHandler();
    200329        }
    201330    }
     
    208337
    209338    // Copy Shareable link
    210     $('.evercompare-copy-link').on('click',function(e){
    211         evercompareCopyToClipboard( $(this).closest('.ever-compare-shareable-link').find('.evercompare-share-link') , this );
    212     });
     339    bindShareableLinkHandler();
    213340    function evercompareCopyToClipboard( element, button ) {
    214341        var $tempdata = $("<input>");
     
    218345        $tempdata.remove();
    219346        $(button).text( $(button).data('copytext') );
    220         setTimeout(function() { 
     347        setTimeout(function() {
    221348            $( button ).text( $(button).data('btntext') );
    222349        }, 1000);
  • ever-compare/tags/1.3.5/assets/js/frontend.min.js

    r3108021 r3483393  
    1 !function(t){"use strict";var o=t("body"),e=t(".htcompare-popup");o.append(`<div id="htcompare-error-modal" class="htcompare-error-modal" style="display:none">
    2     <div class="htcompare-error-modal-content">
    3         <button class="htcompare-error-modal-close">&times;</button>
    4         <div class="htcompare-error-modal-body"></div>
    5     </div>
    6 </div>`);let a=t("#htcompare-error-modal");t(".htcompare-error-modal-close").on("click",function(){a.css("display","none")}),t(window).on("click",function(t){t.target==a[0]&&a.css("display","none")}),t("a.htcompare-btn").each(function(){let o=t(this);o.hasClass("added")&&o.html('<span class="htcompare-btn-text">'+o.data("added-text")+"</span>")});let n=`<div class="htcompare-notification">
    7     <div class="htcompare-notification-text">${evercompare.option_data.success_added_notification_text}</div>
    8     <span class="htcompare-notification-close">close</span>
    9 </div>`;"on"===evercompare.option_data.enable_success_notification&&(o.append(n),o.on("click",".htcompare-notification-close",function(){o.find(".htcompare-notification").removeClass("open")}));let c=t=>{"on"===evercompare.option_data.enable_success_notification&&(o.find(".htcompare-notification-text").html(t),o.find(".htcompare-notification").addClass("open"),+evercompare.option_data.removed_notification_after>-1&&setTimeout(function(){o.find(".htcompare-notification").removeClass("open")},1e3*+evercompare.option_data.removed_notification_after))};function i(o){t(".htcompare-table").length>0&&(t(".htcompare-table").replaceWith(o.table),t(".evercompare-copy-link").on("click",function(o){r(t(this).closest(".ever-compare-shareable-link").find(".evercompare-share-link"),this)}))}function r(o,e){var a=t("<input>");t("body").append(a),a.val(t(o).text()).select(),document.execCommand("copy"),a.remove(),t(e).text(t(e).data("copytext")),setTimeout(function(){t(e).text(t(e).data("btntext"))},1e3)}o.on("click","a.htcompare-btn",function(n){var r=t(this),d=r.data("product_id"),s=r.data("added-text"),p=evercompare.option_data.success_added_notification_text.replace("{product_name}",r.data("product_title"));if("yes"===evercompare.popup&&"off"===evercompare.option_data.remove_on_click){if(n.preventDefault(),r.hasClass("added"))return o.find(".htcompare-popup").addClass("open"),!0}else if(r.hasClass("added"))return!0;n.preventDefault(),r.addClass("loading"),t.ajax({url:evercompare.ajaxurl,data:{action:"ever_compare_add_to_compare",nonce:evercompare.nonce,id:d},dataType:"json",method:"GET",success:function(n){let c="array"==typeof n.products?n.products:Object.values(n.products);n.table&&c.indexOf(d.toString())>=0?(i(n),e.addClass("open")):(t(".htcompare-error-modal-body").html(n.limitReached),a.css("display","flex"),console.log("Something wrong loading compare data")),o.find(".htcompare-counter").html(n.count)},error:function(t){console.log("Something wrong with AJAX response.")},complete:function(t){r.removeClass("loading");let o="array"==typeof t.responseJSON.products?t.responseJSON.products:Object.values(t.responseJSON.products);o.indexOf(d.toString())>=0&&(r.addClass("added"),r.html('<span class="htcompare-btn-text">'+s+"</span>")),c(p)}})}),evercompare.option_data.remove_on_click&&"on"===evercompare.option_data.remove_on_click&&o.on("click","a.htcompare-btn.added",function(e){e.preventDefault();var a=t(this),n=a.data("product_id"),i=evercompare.option_data.success_removed_notification_text.replace("{product_name}",a.data("product_title"));a.addClass("loading"),jQuery.ajax({url:evercompare.ajaxurl,data:{action:"ever_compare_remove_from_compare",nonce:evercompare.nonce,id:n},dataType:"json",method:"GET",success:function(t){t?o.find(".htcompare-counter").html(t.count):console.log("Something wrong loading compare data")},error:function(t){console.log("Something wrong with AJAX response.")},complete:function(){a.removeClass("loading added").html('<span class="htcompare-btn-text">'+a.data("text")+"</span>"),c(i)}})}),o.on("click","a.htcompare-remove",function(e){var a=t(".htcompare-table");e.preventDefault();var n=t(this),r=n.data("product_id"),d=evercompare.option_data.success_removed_notification_text.replace("{product_name}",n.data("product_title"));a.addClass("loading"),n.addClass("loading"),jQuery.ajax({url:evercompare.ajaxurl,data:{action:"ever_compare_remove_from_compare",nonce:evercompare.nonce,id:r},dataType:"json",method:"GET",success:function(e){e.table?i(e):console.log("Something wrong loading compare data"),t("a.htcompare-btn").each(function(){t(this).data("product_id")===r&&(t(this).removeClass("added"),t(this).html('<span class="htcompare-btn-text">'+t(this).data("text")+"</span>"))}),o.find(".htcompare-counter").html(e.count)},error:function(t){console.log("Something wrong with AJAX response.")},complete:function(){a.removeClass("loading"),n.addClass("loading"),c(d)}})}),o.on("click",".htcompare-popup-close",function(o){t(this).parent(".htcompare-popup.open").removeClass("open"),e.removeClass("open")}),t(".evercompare-copy-link").on("click",function(o){r(t(this).closest(".ever-compare-shareable-link").find(".evercompare-share-link"),this)})}(jQuery);
     1!function(e){"use strict";var o=e("body"),t=e(".htcompare-popup"),a=null,n=null;function r(){for(var e=evercompare.cookie_name,o=document.cookie.split(";"),t=0;t<o.length;t++){var a=o[t].trim();if(0===a.indexOf(e+"=")){var n=decodeURIComponent(a.substring(e.length+1));try{var r=JSON.parse(n);if(Array.isArray(r))return r.map(function(e){return parseInt(e,10)}).filter(function(e){return e>0})}catch(e){}}}return[]}function c(){return a?e.Deferred().resolve(a).promise():n||(n=e.ajax({url:evercompare.ajaxurl,data:{action:"ever_compare_get_nonce"},dataType:"json",method:"GET"}).then(function(e){return a=e.nonce,n=null,a}).fail(function(){n=null}))}function i(){e(".evercompare-copy-link").on("click",function(o){var t,a,n;t=e(this).closest(".ever-compare-shareable-link").find(".evercompare-share-link"),a=this,n=e("<input>"),e("body").append(n),n.val(e(t).text()).select(),document.execCommand("copy"),n.remove(),e(a).text(e(a).data("copytext")),setTimeout(function(){e(a).text(e(a).data("btntext"))},1e3)})}o.append('<div id="htcompare-error-modal" class="htcompare-error-modal" style="display:none"><div class="htcompare-error-modal-content"><button class="htcompare-error-modal-close">&times;</button><div class="htcompare-error-modal-body"></div></div></div>');var s,d=e("#htcompare-error-modal");e(".htcompare-error-modal-close").on("click",function(){d.css("display","none")}),e(window).on("click",function(e){e.target==d[0]&&d.css("display","none")}),s=r(),e("a.htcompare-btn").each(function(){var o=e(this),t=parseInt(o.data("product_id"),10);s.indexOf(t)>=0&&(o.addClass("added"),o.html('<span class="htcompare-btn-text">'+o.data("added-text")+"</span>"))}),function(){var e=r();o.find(".htcompare-counter").html(e.length)}(),function(){var o=e(".htcompare-table[data-ajax-load]");if(0!==o.length){var t=r();0!==t.length?e.ajax({url:evercompare.ajaxurl,data:{action:"ever_compare_get_table",ids:t.join(",")},dataType:"json",method:"GET",success:function(t){t.table&&(o.each(function(){e(this).replaceWith(t.table)}),i())}}):e.ajax({url:evercompare.ajaxurl,data:{action:"ever_compare_get_table",ids:""},dataType:"json",method:"GET",success:function(t){void 0!==t.table&&(o.each(function(){e(this).replaceWith(t.table||'<div class="htcompare-table htcompare-empty"></div>')}),i())}})}}();var p='<div class="htcompare-notification"><div class="htcompare-notification-text">'+evercompare.option_data.success_added_notification_text+'</div><span class="htcompare-notification-close">close</span></div>';"on"===evercompare.option_data.enable_success_notification&&(o.append(p),o.on("click",".htcompare-notification-close",function(){o.find(".htcompare-notification").removeClass("open")}));var l=function(e){"on"===evercompare.option_data.enable_success_notification&&(o.find(".htcompare-notification-text").html(e),o.find(".htcompare-notification").addClass("open"),+evercompare.option_data.removed_notification_after>-1&&setTimeout(function(){o.find(".htcompare-notification").removeClass("open")},1e3*+evercompare.option_data.removed_notification_after))};function m(o){e(".htcompare-table").length>0&&(e(".htcompare-table").replaceWith(o.table),i())}o.on("click","a.htcompare-btn",function(a){var n=e(this),r=n.data("product_id"),i=n.data("added-text"),s=evercompare.option_data.success_added_notification_text.replace("{product_name}",n.data("product_title"));if("yes"===evercompare.popup&&"off"===evercompare.option_data.remove_on_click){if(a.preventDefault(),n.hasClass("added"))return o.find(".htcompare-popup").addClass("open"),!0}else if(n.hasClass("added"))return!0;a.preventDefault(),n.addClass("loading"),c().then(function(a){e.ajax({url:evercompare.ajaxurl,data:{action:"ever_compare_add_to_compare",nonce:a,id:r},dataType:"json",method:"GET",success:function(a){if(a&&a.products){var n=("object"==typeof a.products?Object.values(a.products):a.products).map(function(e){return e.toString()});a.table&&n.indexOf(r.toString())>=0?(m(a),t.addClass("open")):(e(".htcompare-error-modal-body").html(a.limitReached),d.css("display","flex")),o.find(".htcompare-counter").html(a.count)}else o.find(".htcompare-counter").html(a?a.count:0)},error:function(e){console.log("Something wrong with AJAX response.")},complete:function(e){(n.removeClass("loading"),e.responseJSON&&e.responseJSON.products)&&(("object"==typeof e.responseJSON.products?Object.values(e.responseJSON.products):e.responseJSON.products).map(function(e){return e.toString()}).indexOf(r.toString())>=0&&(n.addClass("added"),n.html('<span class="htcompare-btn-text">'+i+"</span>"),l(s)))}})}).fail(function(){n.removeClass("loading")})}),evercompare.option_data.remove_on_click&&"on"===evercompare.option_data.remove_on_click&&o.on("click","a.htcompare-btn.added",function(t){t.preventDefault();var a=e(this),n=a.data("product_id"),r=evercompare.option_data.success_removed_notification_text.replace("{product_name}",a.data("product_title"));a.addClass("loading"),c().then(function(e){jQuery.ajax({url:evercompare.ajaxurl,data:{action:"ever_compare_remove_from_compare",nonce:e,id:n},dataType:"json",method:"GET",success:function(e){e?o.find(".htcompare-counter").html(e.count):console.log("Something wrong loading compare data")},error:function(e){console.log("Something wrong with AJAX response.")},complete:function(e){a.removeClass("loading added").html('<span class="htcompare-btn-text">'+a.data("text")+"</span>"),e.responseJSON&&void 0!==e.responseJSON.count&&l(r)}})}).fail(function(){a.removeClass("loading")})}),o.on("click","a.htcompare-remove",function(t){var a=e(".htcompare-table");t.preventDefault();var n=e(this),r=n.data("product_id"),i=evercompare.option_data.success_removed_notification_text.replace("{product_name}",n.data("product_title"));a.addClass("loading"),n.addClass("loading"),c().then(function(t){jQuery.ajax({url:evercompare.ajaxurl,data:{action:"ever_compare_remove_from_compare",nonce:t,id:r},dataType:"json",method:"GET",success:function(t){t.table?m(t):console.log("Something wrong loading compare data"),e("a.htcompare-btn").each(function(){e(this).data("product_id")===r&&(e(this).removeClass("added"),e(this).html('<span class="htcompare-btn-text">'+e(this).data("text")+"</span>"))}),o.find(".htcompare-counter").html(t.count)},error:function(e){console.log("Something wrong with AJAX response.")},complete:function(e){a.removeClass("loading"),n.removeClass("loading"),e.responseJSON&&e.responseJSON.table&&l(i)}})}).fail(function(){a.removeClass("loading"),n.removeClass("loading")})}),o.on("click",".htcompare-popup-close",function(o){e(this).parent(".htcompare-popup.open").removeClass("open"),t.removeClass("open")}),i()}(jQuery);
  • ever-compare/tags/1.3.5/ever-compare.php

    r3331136 r3483393  
    66 * Author: HasTheme
    77 * Author URI: https://hasthemes.com/
    8  * Version: 1.3.4
     8 * Version: 1.3.5
    99 * License: GPL2 or later
    1010 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    2626     * @var string
    2727     */
    28     const version = '1.3.4';
     28    const version = '1.3.5';
    2929
    3030    /**
     
    5858        add_action( 'plugins_loaded', [ $this, 'init_plugin' ] );
    5959
    60         // Compatible With WooCommerce Custom Order Tables
     60        // Compatible With WooCommerce Features
    6161        add_action( 'before_woocommerce_init', function() {
    6262            if ( class_exists( '\Automattic\WooCommerce\Utilities\FeaturesUtil' ) ) {
    6363                \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', EVERCOMPARE_FILE, true );
     64                \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'cart_checkout_blocks', EVERCOMPARE_FILE, true );
     65                \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'product_block_editor', EVERCOMPARE_FILE, true );
    6466            }
    6567        } );
     
    107109        EverCompare\Assets::instance();
    108110
    109         if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
    110             EverCompare\Ajax::instance();
    111         }
    112 
    113111        if ( is_admin() ) {
    114112            $this->admin_notices();
    115113            EverCompare\Admin::instance();
    116114        }
     115
     116        if ( ! ever_compare_woocommerce_installed() ) {
     117            return;
     118        }
     119
     120        if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
     121            EverCompare\Ajax::instance();
     122        }
     123
    117124        EverCompare\Frontend::instance();
    118125
  • ever-compare/tags/1.3.5/includes/classes/Admin/Settings_APi.php

    r3314387 r3483393  
    2727     * Enqueue scripts and styles
    2828     */
    29     function admin_enqueue_scripts() {
     29    function admin_enqueue_scripts( $hook ) {
     30        if ( false === strpos( $hook, 'evercompare' ) ) {
     31            return;
     32        }
    3033        wp_enqueue_style( 'wp-color-picker' );
    3134        wp_enqueue_media();
  • ever-compare/tags/1.3.5/includes/classes/Ajax.php

    r3144815 r3483393  
    3636        add_action( 'wp_ajax_nopriv_ever_compare_remove_from_compare', [ $this,'remove_from_compare' ] );
    3737
     38        // Get Nonce endpoint (no nonce verification needed)
     39        add_action( 'wp_ajax_ever_compare_get_nonce', [ $this, 'get_nonce' ] );
     40        add_action( 'wp_ajax_nopriv_ever_compare_get_nonce', [ $this, 'get_nonce' ] );
     41
     42        // Get Table endpoint
     43        add_action( 'wp_ajax_ever_compare_get_table', [ $this, 'get_table' ] );
     44        add_action( 'wp_ajax_nopriv_ever_compare_get_table', [ $this, 'get_table' ] );
     45
    3846    }
    3947
     
    4452        check_ajax_referer('ever_compare_nonce', 'nonce');
    4553        if(!empty($_GET['id'])) {
    46             $id = sanitize_text_field( wp_unslash($_GET['id']) );
     54            $id = absint( $_GET['id'] );
    4755            \EverCompare\Frontend\Manage_Compare::instance()->add_to_compare( $id );
    4856        }
     
    5664        check_ajax_referer('ever_compare_nonce', 'nonce');
    5765        if(!empty($_GET['id'])) {
    58             $id = sanitize_text_field( wp_unslash($_GET['id']) );
     66            $id = absint( $_GET['id'] );
    5967            \EverCompare\Frontend\Manage_Compare::instance()->remove_from_compare( $id );
    6068        }
    6169    }
    6270
     71    /**
     72     * [get_nonce] Return a fresh nonce for AJAX operations
     73     * @return [void]
     74     */
     75    public function get_nonce(){
     76        wp_send_json( array(
     77            'nonce' => wp_create_nonce( 'ever_compare_nonce' ),
     78        ) );
     79    }
     80
     81    /**
     82     * [get_table] Return compare table HTML for given product IDs
     83     * @return [void]
     84     */
     85    public function get_table(){
     86        $ids = array();
     87        if ( ! empty( $_GET['ids'] ) ) {
     88            $raw_ids = sanitize_text_field( wp_unslash( $_GET['ids'] ) );
     89            $ids = array_filter( array_map( 'absint', explode( ',', $raw_ids ) ) );
     90            $ids = array_slice( $ids, 0, \EverCompare\Frontend\Manage_Compare::instance()->max_limit );
     91        }
     92
     93        if ( empty( $ids ) ) {
     94            wp_send_json( array(
     95                'table' => '',
     96                'count' => 0,
     97            ) );
     98        }
     99
     100        $cookie_name = \EverCompare\Frontend\Manage_Compare::instance()->get_cookie_name();
     101        $_COOKIE[ $cookie_name ] = wp_json_encode( $ids );
     102
     103        ob_start();
     104        \EverCompare\Frontend\Manage_Compare::instance()->get_response_html();
     105        $table_html = ob_get_clean();
     106
     107        wp_send_json( array(
     108            'table' => $table_html,
     109            'count' => count( $ids ),
     110            'products' => $ids,
     111        ) );
     112    }
     113
    63114}
  • ever-compare/tags/1.3.5/includes/classes/Assets.php

    r3108021 r3483393  
    116116            'removed_notification_after' => ever_compare_get_option( 'removed_notification_after', 'ever_compare_settings_general', -1 ),
    117117        );
     118        $cookie_name = 'ever_compare_compare_list';
     119        if ( is_multisite() ) {
     120            $cookie_name .= '_' . get_current_blog_id();
     121        }
    118122        $localize_data = array(
    119             'ajaxurl'       => admin_url( 'admin-ajax.php' ),
    120             'nonce'         => wp_create_nonce('ever_compare_nonce'),
    121             'popup'         => ( ever_compare_get_option( 'open_popup', 'ever_compare_settings_tabs', 'on' ) === 'on' ) ? 'yes' : 'no',
    122             'option_data'   => $option_data,
     123            'ajaxurl'          => admin_url( 'admin-ajax.php' ),
     124            'cookie_name'      => $cookie_name,
     125            'compare_page_url' => esc_url( get_permalink( ever_compare_get_option( 'compare_page', 'ever_compare_table_settings_tabs' ) ) ),
     126            'popup'            => ( ever_compare_get_option( 'open_popup', 'ever_compare_settings_tabs', 'on' ) === 'on' ) ? 'yes' : 'no',
     127            'option_data'      => $option_data,
    123128        );
    124129
  • ever-compare/tags/1.3.5/includes/classes/Frontend/Manage_Compare.php

    r3314387 r3483393  
    126126        }
    127127
    128         /**
    129          * Manage maximum product added message
    130          */
    131         if( isset( $_COOKIE[ 'ever_compare_max_limit' ] ) && $_COOKIE[ 'ever_compare_max_limit' ] == 'yes' ) {
    132             setcookie( 'ever_compare_max_limit', 'no', 0, COOKIEPATH, COOKIE_DOMAIN, false, false );
    133             $this->reached_max_limit = true;
    134         }
    135128
    136129
     
    171164     */
    172165    public function pop_up_html(){
    173         echo '<div class="htcompare-popup"><div class="htcompare-popup-content-area"><span class="htcompare-popup-close">&nbsp;</span>'.do_shortcode( '[evercompare_table]' ).'</div></div>';
     166        echo '<div class="htcompare-popup"><div class="htcompare-popup-content-area"><span class="htcompare-popup-close">&nbsp;</span><div class="htcompare-table" data-ajax-load="true"></div></div></div>';
    174167    }
    175168
     
    201194        $ids = $this->get_compared_products();
    202195
    203          if ( isset( $_GET['evcompare'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
     196         if ( ! empty( $_GET['evcompare'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
    204197            $query_perametter_ids = sanitize_text_field( wp_unslash($_GET['evcompare']) ); //phpcs:ignore WordPress.Security.NonceVerification.Recommended
    205198            if( !empty( $query_perametter_ids ) ){
    206                 $ids = explode( ',', $query_perametter_ids );
     199                $ids = array_filter( array_map( 'absint', explode( ',', $query_perametter_ids ) ) );
    207200            }
    208201        }
     
    238231        // Reached Maximum Limit
    239232        if( $this->reached_max_limit() ) {
    240             setcookie( 'ever_compare_max_limit', 'yes', 0, COOKIEPATH, COOKIE_DOMAIN, false, false );
    241233            $this->compare_json_response();
    242234        }
     
    289281            }
    290282        }
     283
     284        $products = array_values( $products );
    291285
    292286        if ( empty( $products ) ) {
     
    338332        // For shareable link
    339333        $shareable_link = ever_compare_get_option('enable_shareable_link','ever_compare_table_settings_tabs','off');
    340         if ( ( $shareable_link === 'on' ) && isset( $_GET['evcompare'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
     334        if ( ( $shareable_link === 'on' ) && ! empty( $_GET['evcompare'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
    341335            $query_perametter_ids = sanitize_text_field( wp_unslash($_GET['evcompare']) ); //phpcs:ignore WordPress.Security.NonceVerification.Recommended
    342336            if( !empty( $query_perametter_ids ) ){
    343                 $ids = explode( ',', $query_perametter_ids );
     337                $ids = array_filter( array_map( 'absint', explode( ',', $query_perametter_ids ) ) );
    344338            }
    345339        }
     
    606600    public function is_product_in_compare( $id ) {
    607601        $list = $this->get_compared_products();
    608         return in_array( strval($id), $list, true );
     602        return in_array( absint($id), $list, true );
    609603    }
    610604
     
    616610        $cookie_name = $this->get_cookie_name();
    617611        if(!empty( $_COOKIE[ $cookie_name ] )) {
    618             return json_decode( sanitize_text_field(wp_unslash( $_COOKIE[ $cookie_name ] )), true );
     612            $decoded = json_decode( sanitize_text_field(wp_unslash( $_COOKIE[ $cookie_name ] )), true );
     613            if ( is_array( $decoded ) ) {
     614                return array_filter( array_map( 'absint', $decoded ) );
     615            }
    619616        }
    620617        return [];
  • ever-compare/tags/1.3.5/includes/classes/Frontend/Shortcode.php

    r3041668 r3483393  
    8989        } else {
    9090            $button_added_text = '<span class="evercompare-btn-text">'.$button_remove_text.'</span>';
    91         }
    92 
    93         if(\EverCompare\Frontend\Manage_Compare::instance()->is_product_in_compare( $product_id )) {
    94             $button_class[] = 'added';
    9591        }
    9692
     
    118114     */
    119115    public function table_shortcode( $atts, $content = '' ){
    120        
     116
    121117        wp_enqueue_style( 'evercompare-frontend' );
    122118        wp_enqueue_script( 'evercompare-frontend' );
    123119
    124         /* Fetch From option data */
    125         $empty_compare_text = ever_compare_get_option('empty_table_text','ever_compare_table_settings_tabs');
    126         $return_shop_button = ever_compare_get_option('shop_button_text','ever_compare_table_settings_tabs','Return to shop');
    127 
    128         /* Product and Field */
    129         $products   = Manage_Compare::instance()->get_compared_products_data();
    130         $fields     = Manage_Compare::instance()->get_compare_fields();
    131 
    132         $custom_heading = !empty( ever_compare_get_option( 'table_heading', 'ever_compare_table_settings_tabs' ) ) ? ever_compare_get_option( 'table_heading', 'ever_compare_table_settings_tabs' ) : array();
    133 
    134         $default_atts = array(
    135             'evercompare'  => Manage_Compare::instance(),
    136             'products'     => $products,
    137             'fields'       => $fields,
    138             'return_shop_button'=> $return_shop_button,
    139             'heading_txt'       => $custom_heading,
    140             'empty_compare_text'=> $empty_compare_text,
    141         );
    142 
    143         $atts = shortcode_atts( $default_atts, $atts, $content );
    144         return Manage_Compare::instance()->table_html( $atts );
     120        // Shareable link via query param — render server-side (not cached due to query param)
     121        if ( ! empty( $_GET['evcompare'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
     122            /* Fetch From option data */
     123            $empty_compare_text = ever_compare_get_option('empty_table_text','ever_compare_table_settings_tabs');
     124            $return_shop_button = ever_compare_get_option('shop_button_text','ever_compare_table_settings_tabs','Return to shop');
     125
     126            /* Product and Field */
     127            $products   = Manage_Compare::instance()->get_compared_products_data();
     128            $fields     = Manage_Compare::instance()->get_compare_fields();
     129
     130            $custom_heading = !empty( ever_compare_get_option( 'table_heading', 'ever_compare_table_settings_tabs' ) ) ? ever_compare_get_option( 'table_heading', 'ever_compare_table_settings_tabs' ) : array();
     131
     132            $default_atts = array(
     133                'evercompare'  => Manage_Compare::instance(),
     134                'products'     => $products,
     135                'fields'       => $fields,
     136                'return_shop_button'=> $return_shop_button,
     137                'heading_txt'       => $custom_heading,
     138                'empty_compare_text'=> $empty_compare_text,
     139            );
     140
     141            $atts = shortcode_atts( $default_atts, $atts, $content );
     142            return Manage_Compare::instance()->table_html( $atts );
     143        }
     144
     145        // Cookie-based: render placeholder that JS will populate via AJAX
     146        return '<div class="htcompare-table" data-ajax-load="true"></div>';
    145147
    146148    }
     
    159161
    160162        $default_atts = array(
    161             'count'      => count(Manage_Compare::instance()->get_compared_products()),
     163            'count'      => 0,
    162164            'page_url'      => Manage_Compare::instance()->get_compare_page_url(),
    163165        );
  • ever-compare/tags/1.3.5/includes/helper-functions.php

    r3108021 r3483393  
    2121function ever_compare_update_option( $section, $option_key, $new_value ){
    2222    $options_data = get_option( $section );
    23     if( isset( $options_data[$option_key] ) ){
    24         $options_data[$option_key] = $new_value;
    25     }else{
    26         $options_data = array( $option_key => $new_value );
    27     }
     23    if ( ! is_array( $options_data ) ) {
     24        $options_data = array();
     25    }
     26    $options_data[ $option_key ] = $new_value;
    2827    update_option( $section, $options_data );
    2928}
     
    4443    $options = array();
    4544    $options['0'] = __('Select','ever-compare');
    46     $perpage = -1;
     45    $perpage = 200;
    4746    $all_post = array( 'posts_per_page' => $perpage, 'post_type'=> $post_type );
    4847    $post_terms = get_posts( $all_post );
     
    8887
    8988    if ( $args && is_array( $args ) ) {
    90         extract( $args );
     89        $evercompare_args = $args;
     90        // Backward compat: if template is overridden in theme, extract for legacy support
     91        $default_path = EVERCOMPARE_PATH . '/includes/templates/' . $tmp_name;
     92        if ( $located !== $default_path ) {
     93            extract( $args, EXTR_SKIP ); // phpcs:ignore WordPress.PHP.DontExtract.extract_extract
     94        }
    9195    }
    9296
  • ever-compare/tags/1.3.5/includes/templates/evercompare-button-add.php

    r3108021 r3483393  
    1 <span class="htcompare-button-area"><a href="<?php echo esc_url( $button_url ); ?>" class="<?php echo esc_attr($button_class); ?>" data-text="<?php echo esc_attr( $button_text ); ?>" data-added-text="<?php echo esc_attr( $button_added_text); ?>" data-product_id="<?php echo esc_attr( $product_id ); ?>" data-product_title="<?php echo esc_attr( $product_title ); ?>" ><?php echo wp_kses($button_text, get_allowed_tags_for_svg()); ?></a></span>
     1<span class="htcompare-button-area"><a href="<?php echo esc_url( $evercompare_args['button_url'] ); ?>" class="<?php echo esc_attr($evercompare_args['button_class']); ?>" data-text="<?php echo esc_attr( $evercompare_args['button_text'] ); ?>" data-added-text="<?php echo esc_attr( $evercompare_args['button_added_text']); ?>" data-product_id="<?php echo esc_attr( $evercompare_args['product_id'] ); ?>" data-product_title="<?php echo esc_attr( $evercompare_args['product_title'] ); ?>" ><?php echo wp_kses($evercompare_args['button_text'], get_allowed_tags_for_svg()); ?></a></span>
  • ever-compare/tags/1.3.5/includes/templates/evercompare-count.php

    r2927305 r3483393  
    1 <a href="<?php echo esc_url( $page_url );?>" class="htcompare-counter-area">
     1<a href="<?php echo esc_url( $evercompare_args['page_url'] );?>" class="htcompare-counter-area">
    22    <span class="htcompare-counter-icon">
    33        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 471.701 471.701" height="20px" width="20px" >
     
    66    </span>
    77    <?php
    8         echo '<span class="htcompare-counter">'.esc_html( $count ).'</span>';
     8        echo '<span class="htcompare-counter">'.esc_html( $evercompare_args['count'] ).'</span>';
    99    ?>
    1010</a>
  • ever-compare/tags/1.3.5/includes/templates/evercompare-table.php

    r3108021 r3483393  
    33        // do_action( 'ever_compare_before_table' );
    44
    5         if ( ! empty( $products ) ) {
     5        if ( ! empty( $evercompare_args['products'] ) ) {
     6            $products = $evercompare_args['products'];
    67            array_unshift( $products, array() );
    7             foreach ( $fields as $field_id => $field ) {
    8                 if ( ! $evercompare->is_products_have_field( $field_id, $products ) ) {
     8            foreach ( $evercompare_args['fields'] as $field_id => $field ) {
     9                if ( ! $evercompare_args['evercompare']->is_products_have_field( $field_id, $products ) ) {
    910                    continue;
    1011                }
    1112
    1213                // Generate Filed name
    13                 $name = $evercompare->field_name( $field );
    14                 if( array_key_exists( $field_id, $heading_txt ) && !empty( $heading_txt[$field_id] ) ){
    15                     $name = $evercompare->field_name( $heading_txt[$field_id], true );
     14                $name = $evercompare_args['evercompare']->field_name( $field );
     15                if( array_key_exists( $field_id, $evercompare_args['heading_txt'] ) && !empty( $evercompare_args['heading_txt'][$field_id] ) ){
     16                    $name = $evercompare_args['evercompare']->field_name( $evercompare_args['heading_txt'][$field_id], true );
    1617                }
    1718
     
    2122                            <?php if ( ! empty( $product ) ) : ?>
    2223                                <div class="htcompare-col htcolumn-value" data-title="<?php echo esc_attr( $name ); ?>">
    23                                     <?php $evercompare->compare_display_field( $field_id, $product ); ?>
     24                                    <?php $evercompare_args['evercompare']->compare_display_field( $field_id, $product ); ?>
    2425                                </div>
    2526                            <?php else: ?>
     
    3233                <?php
    3334            }
    34             echo '<div class="htcompare-table-loader"></div>'; 
     35            echo '<div class="htcompare-table-loader"></div>';
    3536        } else {
    36             if ( $empty_compare_text ){
    37                 echo '<div class="htcompare-empty-page-text">'.wp_kses_post( $empty_compare_text ).'</div>';
     37            if ( $evercompare_args['empty_compare_text'] ){
     38                echo '<div class="htcompare-empty-page-text">'.wp_kses_post( $evercompare_args['empty_compare_text'] ).'</div>';
    3839            }
    3940
    40             if( $return_shop_button ){
    41                 echo '<div class="htcompare-return-to-shop"><a href="'.esc_url( wc_get_page_permalink( 'shop' ) ).'" class="button">'.esc_html( $return_shop_button ).'</a></div>';
     41            if( $evercompare_args['return_shop_button'] ){
     42                echo '<div class="htcompare-return-to-shop"><a href="'.esc_url( wc_get_page_permalink( 'shop' ) ).'" class="button">'.esc_html( $evercompare_args['return_shop_button'] ).'</a></div>';
    4243            }
    4344        }
  • ever-compare/tags/1.3.5/readme.txt

    r3407749 r3483393  
    44Requires at least: 5.0
    55Tested up to: 6.9
    6 Stable tag: 1.3.4
     6Stable tag: 1.3.5
    77License: GPLv2 or later
    88License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    9090
    9191== Changelog ==
     92
     93= Version: 1.3.5 - Date: 2026-03-16 =
     94* Fixed: Empty evcompare query parameter no longer generates broken shareable links.
     95* Improved: Cache compatibility for compare page using cookie-based AJAX loading.
    9296
    9397= Version: 1.3.4 - Date: 2025-07-21 =
  • ever-compare/trunk/assets/js/frontend.js

    r3108021 r3483393  
    11;(function($){
    22"use strict";
    3    
     3
    44    var $body = $('body'),
    5         $popup = $('.htcompare-popup');
    6        
    7     $body.append(`<div id="htcompare-error-modal" class="htcompare-error-modal" style="display:none">
    8         <div class="htcompare-error-modal-content">
    9             <button class="htcompare-error-modal-close">&times;</button>
    10             <div class="htcompare-error-modal-body"></div>
    11         </div>
    12     </div>`);
    13     const $htcompareErrorModal = $("#htcompare-error-modal");
     5        $popup = $('.htcompare-popup'),
     6        cachedNonce = null,
     7        noncePromise = null;
     8
     9    // Cookie helper: read compare list from cookie
     10    function getCompareListFromCookie() {
     11        var cookieName = evercompare.cookie_name;
     12        var cookies = document.cookie.split(';');
     13        for (var i = 0; i < cookies.length; i++) {
     14            var cookie = cookies[i].trim();
     15            if (cookie.indexOf(cookieName + '=') === 0) {
     16                var value = decodeURIComponent(cookie.substring(cookieName.length + 1));
     17                try {
     18                    var parsed = JSON.parse(value);
     19                    if (Array.isArray(parsed)) {
     20                        return parsed.map(function(id) { return parseInt(id, 10); }).filter(function(id) { return id > 0; });
     21                    }
     22                } catch(e) {}
     23            }
     24        }
     25        return [];
     26    }
     27
     28    // Deferred nonce: fetch on first interaction, cache in memory
     29    function getNonce() {
     30        if (cachedNonce) {
     31            return $.Deferred().resolve(cachedNonce).promise();
     32        }
     33        if (noncePromise) {
     34            return noncePromise;
     35        }
     36        noncePromise = $.ajax({
     37            url: evercompare.ajaxurl,
     38            data: { action: 'ever_compare_get_nonce' },
     39            dataType: 'json',
     40            method: 'GET',
     41        }).then(function(response) {
     42            cachedNonce = response.nonce;
     43            noncePromise = null;
     44            return cachedNonce;
     45        }).fail(function() {
     46            noncePromise = null;
     47        });
     48        return noncePromise;
     49    }
     50
     51    // Sync button states from cookie on DOM ready
     52    function syncButtonStates() {
     53        var compareList = getCompareListFromCookie();
     54        $('a.htcompare-btn').each(function() {
     55            var $btn = $(this);
     56            var productId = parseInt($btn.data('product_id'), 10);
     57            if (compareList.indexOf(productId) >= 0) {
     58                $btn.addClass('added');
     59                $btn.html('<span class="htcompare-btn-text">' + $btn.data('added-text') + '</span>');
     60            }
     61        });
     62    }
     63
     64    // Sync counter from cookie on DOM ready
     65    function syncCounter() {
     66        var compareList = getCompareListFromCookie();
     67        $body.find('.htcompare-counter').html(compareList.length);
     68    }
     69
     70    // Load compare table via AJAX for cookie-based pages
     71    function loadCompareTable() {
     72        var $tables = $('.htcompare-table[data-ajax-load]');
     73        if ($tables.length === 0) return;
     74
     75        var compareList = getCompareListFromCookie();
     76        if (compareList.length === 0) {
     77            // Show empty state — fetch table with no IDs to get proper empty template
     78            $.ajax({
     79                url: evercompare.ajaxurl,
     80                data: {
     81                    action: 'ever_compare_get_table',
     82                    ids: '',
     83                },
     84                dataType: 'json',
     85                method: 'GET',
     86                success: function(response) {
     87                    if (typeof response.table !== 'undefined') {
     88                        $tables.each(function() {
     89                            $(this).replaceWith(response.table || '<div class="htcompare-table htcompare-empty"></div>');
     90                        });
     91                        bindShareableLinkHandler();
     92                    }
     93                }
     94            });
     95            return;
     96        }
     97
     98        $.ajax({
     99            url: evercompare.ajaxurl,
     100            data: {
     101                action: 'ever_compare_get_table',
     102                ids: compareList.join(','),
     103            },
     104            dataType: 'json',
     105            method: 'GET',
     106            success: function(response) {
     107                if (response.table) {
     108                    $tables.each(function() {
     109                        $(this).replaceWith(response.table);
     110                    });
     111                    bindShareableLinkHandler();
     112                }
     113            }
     114        });
     115    }
     116
     117    function bindShareableLinkHandler() {
     118        $('.evercompare-copy-link').on('click', function(e) {
     119            evercompareCopyToClipboard($(this).closest('.ever-compare-shareable-link').find('.evercompare-share-link'), this);
     120        });
     121    }
     122
     123    // Error modal
     124    $body.append('<div id="htcompare-error-modal" class="htcompare-error-modal" style="display:none"><div class="htcompare-error-modal-content"><button class="htcompare-error-modal-close">&times;</button><div class="htcompare-error-modal-body"></div></div></div>');
     125    var $htcompareErrorModal = $("#htcompare-error-modal");
    14126    $('.htcompare-error-modal-close').on('click', function() {
    15127        $htcompareErrorModal.css('display', 'none');
    16     })
     128    });
    17129    $(window).on('click', function(e) {
    18130        if(e.target == $htcompareErrorModal[0]) {
    19131            $htcompareErrorModal.css('display', 'none');
    20132        }
    21     })
    22     $('a.htcompare-btn').each(function() {
    23         const $this = $(this);
    24         if($this.hasClass('added')) {
    25             $this.html('<span class="htcompare-btn-text">'+$this.data('added-text')+'</span>');
    26         }
    27     });
     133    });
     134
     135    // Sync states on DOM ready
     136    syncButtonStates();
     137    syncCounter();
     138    loadCompareTable();
    28139
    29140    // Notification Markup
    30     const notificationMarkup = `<div class="htcompare-notification">
    31         <div class="htcompare-notification-text">${evercompare.option_data.success_added_notification_text}</div>
    32         <span class="htcompare-notification-close">close</span>
    33     </div>`
    34     // Insert Notification Markup in body & notification close method if notification is enabled
     141    var notificationMarkup = '<div class="htcompare-notification"><div class="htcompare-notification-text">' + evercompare.option_data.success_added_notification_text + '</div><span class="htcompare-notification-close">close</span></div>';
    35142    if(evercompare.option_data.enable_success_notification === 'on') {
    36143        $body.append(notificationMarkup);
     
    40147    }
    41148    // Notification Show Function
    42     const ShowNotification = (message) => {
     149    var ShowNotification = function(message) {
    43150        if(evercompare.option_data.enable_success_notification === 'on') {
    44151            $body.find('.htcompare-notification-text').html(message);
     
    47154                setTimeout(function() {
    48155                    $body.find('.htcompare-notification').removeClass('open');
    49                 }, +evercompare.option_data.removed_notification_after * 1000)
    50             }
    51         }
    52     }
     156                }, +evercompare.option_data.removed_notification_after * 1000);
     157            }
     158        }
     159    };
    53160
    54161    // Add product in compare table
     
    73180        $this.addClass('loading');
    74181
    75         $.ajax({
    76             url: evercompare.ajaxurl,
    77             data: {
    78                 action: 'ever_compare_add_to_compare',
    79                 nonce: evercompare.nonce,
    80                 id: id,
    81             },
    82             dataType: 'json',
    83             method: 'GET',
    84             success: function ( response ) {
    85                 const $products = typeof response.products === 'array' ? response.products : Object.values(response.products);
    86                 if ( response.table && $products.indexOf(id.toString()) >= 0 ) {
    87                     updateCompareData( response );
    88                     $popup.addClass('open');
    89                 } else {
    90                     $('.htcompare-error-modal-body').html(response.limitReached)
    91                     $htcompareErrorModal.css('display', 'flex');
    92                     console.log( 'Something wrong loading compare data' );
    93                 }
    94                 $body.find('.htcompare-counter').html( response.count );
    95             },
    96             error: function ( data ) {
    97                 console.log('Something wrong with AJAX response.');
    98             },
    99             complete: function (res) {
    100                 $this.removeClass('loading');
    101                 const $products = typeof res.responseJSON.products === 'array' ? res.responseJSON.products : Object.values(res.responseJSON.products);
    102                 if($products.indexOf(id.toString()) >= 0) {
    103                     $this.addClass('added');
    104                     $this.html('<span class="htcompare-btn-text">'+addedText+'</span>');
    105                 }
    106                 ShowNotification(success_message);
    107             },
     182        getNonce().then(function(nonce) {
     183            $.ajax({
     184                url: evercompare.ajaxurl,
     185                data: {
     186                    action: 'ever_compare_add_to_compare',
     187                    nonce: nonce,
     188                    id: id,
     189                },
     190                dataType: 'json',
     191                method: 'GET',
     192                success: function ( response ) {
     193                    if ( !response || !response.products ) {
     194                        $body.find('.htcompare-counter').html( response ? response.count : 0 );
     195                        return;
     196                    }
     197                    var $products = typeof response.products === 'object' ? Object.values(response.products) : response.products;
     198                    var productStrings = $products.map(function(p) { return p.toString(); });
     199                    if ( response.table && productStrings.indexOf(id.toString()) >= 0 ) {
     200                        updateCompareData( response );
     201                        $popup.addClass('open');
     202                    } else {
     203                        $('.htcompare-error-modal-body').html(response.limitReached);
     204                        $htcompareErrorModal.css('display', 'flex');
     205                    }
     206                    $body.find('.htcompare-counter').html( response.count );
     207                },
     208                error: function ( data ) {
     209                    console.log('Something wrong with AJAX response.');
     210                },
     211                complete: function (res) {
     212                    $this.removeClass('loading');
     213                    if (res.responseJSON && res.responseJSON.products) {
     214                        var $products = typeof res.responseJSON.products === 'object' ? Object.values(res.responseJSON.products) : res.responseJSON.products;
     215                        var productStrings = $products.map(function(p) { return p.toString(); });
     216                        if(productStrings.indexOf(id.toString()) >= 0) {
     217                            $this.addClass('added');
     218                            $this.html('<span class="htcompare-btn-text">'+addedText+'</span>');
     219                            ShowNotification(success_message);
     220                        }
     221                    }
     222                },
     223            });
     224        }).fail(function() {
     225            $this.removeClass('loading');
    108226        });
    109227
     
    117235                success_message = evercompare.option_data.success_removed_notification_text.replace('{product_name}', $this.data('product_title'));
    118236            $this.addClass('loading');
     237            getNonce().then(function(nonce) {
     238                jQuery.ajax({
     239                    url: evercompare.ajaxurl,
     240                    data: {
     241                        action: 'ever_compare_remove_from_compare',
     242                        nonce: nonce,
     243                        id: id,
     244                    },
     245                    dataType: 'json',
     246                    method: 'GET',
     247                    success: function (response) {
     248                        if (response) {
     249                            $body.find('.htcompare-counter').html( response.count );
     250                        } else {
     251                            console.log( 'Something wrong loading compare data' );
     252                        }
     253                    },
     254                    error: function (data) {
     255                        console.log('Something wrong with AJAX response.');
     256                    },
     257                    complete: function (res) {
     258                        $this.removeClass('loading added').html('<span class="htcompare-btn-text">'+$this.data('text')+'</span>');
     259                        if (res.responseJSON && res.responseJSON.count !== undefined) {
     260                            ShowNotification(success_message);
     261                        }
     262                    },
     263                });
     264            }).fail(function() {
     265                $this.removeClass('loading');
     266            });
     267        });
     268    }
     269
     270    // Remove data from compare table
     271    $body.on('click', 'a.htcompare-remove', function (e) {
     272        var $table = $('.htcompare-table');
     273
     274        e.preventDefault();
     275        var $this = $(this),
     276            id = $this.data('product_id'),
     277            success_message = evercompare.option_data.success_removed_notification_text.replace('{product_name}', $this.data('product_title'));
     278
     279        $table.addClass('loading');
     280        $this.addClass('loading');
     281
     282        getNonce().then(function(nonce) {
    119283            jQuery.ajax({
    120284                url: evercompare.ajaxurl,
    121285                data: {
    122286                    action: 'ever_compare_remove_from_compare',
    123                     nonce: evercompare.nonce,
     287                    nonce: nonce,
    124288                    id: id,
    125289                },
     
    127291                method: 'GET',
    128292                success: function (response) {
    129                     if (response) {
    130                         $body.find('.htcompare-counter').html( response.count );
     293                    if (response.table) {
     294                        updateCompareData(response);
    131295                    } else {
    132296                        console.log( 'Something wrong loading compare data' );
    133297                    }
     298                    $('a.htcompare-btn').each(function() {
     299                        if($(this).data('product_id') === id) {
     300                            $(this).removeClass('added');
     301                            $(this).html('<span class="htcompare-btn-text">'+$(this).data('text')+'</span>');
     302                        }
     303                    });
     304                    $body.find('.htcompare-counter').html( response.count );
    134305                },
    135306                error: function (data) {
    136307                    console.log('Something wrong with AJAX response.');
    137308                },
    138                 complete: function () {
    139                     $this.removeClass('loading added').html('<span class="htcompare-btn-text">'+$this.data('text')+'</span>');
    140                     ShowNotification(success_message);
     309                complete: function (res) {
     310                    $table.removeClass('loading');
     311                    $this.removeClass('loading');
     312                    if (res.responseJSON && res.responseJSON.table) {
     313                        ShowNotification(success_message);
     314                    }
    141315                },
    142316            });
    143         });
    144     }
    145 
    146     // Remove data from compare table
    147     $body.on('click', 'a.htcompare-remove', function (e) {
    148         var $table = $('.htcompare-table');
    149 
    150         e.preventDefault();
    151         var $this = $(this),
    152             id = $this.data('product_id'),
    153             success_message = evercompare.option_data.success_removed_notification_text.replace('{product_name}', $this.data('product_title'));
    154 
    155         $table.addClass('loading');
    156         $this.addClass('loading');
    157 
    158         jQuery.ajax({
    159             url: evercompare.ajaxurl,
    160             data: {
    161                 action: 'ever_compare_remove_from_compare',
    162                 nonce: evercompare.nonce,
    163                 id: id,
    164             },
    165             dataType: 'json',
    166             method: 'GET',
    167             success: function (response) {
    168                 if (response.table) {
    169                     updateCompareData(response);
    170                 } else {
    171                     console.log( 'Something wrong loading compare data' );
    172                 }
    173                 $('a.htcompare-btn').each(function() {
    174                     if($(this).data('product_id') === id) {
    175                         $(this).removeClass('added');
    176                         $(this).html('<span class="htcompare-btn-text">'+$(this).data('text')+'</span>');
    177                     }
    178                 })
    179                 $body.find('.htcompare-counter').html( response.count );
    180             },
    181             error: function (data) {
    182                 console.log('Something wrong with AJAX response.');
    183             },
    184             complete: function () {
    185                 $table.removeClass('loading');
    186                 $this.addClass('loading');
    187                 ShowNotification(success_message);
    188             },
     317        }).fail(function() {
     318            $table.removeClass('loading');
     319            $this.removeClass('loading');
    189320        });
    190321
     
    195326        if ( $('.htcompare-table').length > 0 ) {
    196327            $('.htcompare-table').replaceWith( data.table );
    197             $('.evercompare-copy-link').on('click',function(e){
    198                 evercompareCopyToClipboard( $(this).closest('.ever-compare-shareable-link').find('.evercompare-share-link') , this );
    199             });
     328            bindShareableLinkHandler();
    200329        }
    201330    }
     
    208337
    209338    // Copy Shareable link
    210     $('.evercompare-copy-link').on('click',function(e){
    211         evercompareCopyToClipboard( $(this).closest('.ever-compare-shareable-link').find('.evercompare-share-link') , this );
    212     });
     339    bindShareableLinkHandler();
    213340    function evercompareCopyToClipboard( element, button ) {
    214341        var $tempdata = $("<input>");
     
    218345        $tempdata.remove();
    219346        $(button).text( $(button).data('copytext') );
    220         setTimeout(function() { 
     347        setTimeout(function() {
    221348            $( button ).text( $(button).data('btntext') );
    222349        }, 1000);
  • ever-compare/trunk/assets/js/frontend.min.js

    r3108021 r3483393  
    1 !function(t){"use strict";var o=t("body"),e=t(".htcompare-popup");o.append(`<div id="htcompare-error-modal" class="htcompare-error-modal" style="display:none">
    2     <div class="htcompare-error-modal-content">
    3         <button class="htcompare-error-modal-close">&times;</button>
    4         <div class="htcompare-error-modal-body"></div>
    5     </div>
    6 </div>`);let a=t("#htcompare-error-modal");t(".htcompare-error-modal-close").on("click",function(){a.css("display","none")}),t(window).on("click",function(t){t.target==a[0]&&a.css("display","none")}),t("a.htcompare-btn").each(function(){let o=t(this);o.hasClass("added")&&o.html('<span class="htcompare-btn-text">'+o.data("added-text")+"</span>")});let n=`<div class="htcompare-notification">
    7     <div class="htcompare-notification-text">${evercompare.option_data.success_added_notification_text}</div>
    8     <span class="htcompare-notification-close">close</span>
    9 </div>`;"on"===evercompare.option_data.enable_success_notification&&(o.append(n),o.on("click",".htcompare-notification-close",function(){o.find(".htcompare-notification").removeClass("open")}));let c=t=>{"on"===evercompare.option_data.enable_success_notification&&(o.find(".htcompare-notification-text").html(t),o.find(".htcompare-notification").addClass("open"),+evercompare.option_data.removed_notification_after>-1&&setTimeout(function(){o.find(".htcompare-notification").removeClass("open")},1e3*+evercompare.option_data.removed_notification_after))};function i(o){t(".htcompare-table").length>0&&(t(".htcompare-table").replaceWith(o.table),t(".evercompare-copy-link").on("click",function(o){r(t(this).closest(".ever-compare-shareable-link").find(".evercompare-share-link"),this)}))}function r(o,e){var a=t("<input>");t("body").append(a),a.val(t(o).text()).select(),document.execCommand("copy"),a.remove(),t(e).text(t(e).data("copytext")),setTimeout(function(){t(e).text(t(e).data("btntext"))},1e3)}o.on("click","a.htcompare-btn",function(n){var r=t(this),d=r.data("product_id"),s=r.data("added-text"),p=evercompare.option_data.success_added_notification_text.replace("{product_name}",r.data("product_title"));if("yes"===evercompare.popup&&"off"===evercompare.option_data.remove_on_click){if(n.preventDefault(),r.hasClass("added"))return o.find(".htcompare-popup").addClass("open"),!0}else if(r.hasClass("added"))return!0;n.preventDefault(),r.addClass("loading"),t.ajax({url:evercompare.ajaxurl,data:{action:"ever_compare_add_to_compare",nonce:evercompare.nonce,id:d},dataType:"json",method:"GET",success:function(n){let c="array"==typeof n.products?n.products:Object.values(n.products);n.table&&c.indexOf(d.toString())>=0?(i(n),e.addClass("open")):(t(".htcompare-error-modal-body").html(n.limitReached),a.css("display","flex"),console.log("Something wrong loading compare data")),o.find(".htcompare-counter").html(n.count)},error:function(t){console.log("Something wrong with AJAX response.")},complete:function(t){r.removeClass("loading");let o="array"==typeof t.responseJSON.products?t.responseJSON.products:Object.values(t.responseJSON.products);o.indexOf(d.toString())>=0&&(r.addClass("added"),r.html('<span class="htcompare-btn-text">'+s+"</span>")),c(p)}})}),evercompare.option_data.remove_on_click&&"on"===evercompare.option_data.remove_on_click&&o.on("click","a.htcompare-btn.added",function(e){e.preventDefault();var a=t(this),n=a.data("product_id"),i=evercompare.option_data.success_removed_notification_text.replace("{product_name}",a.data("product_title"));a.addClass("loading"),jQuery.ajax({url:evercompare.ajaxurl,data:{action:"ever_compare_remove_from_compare",nonce:evercompare.nonce,id:n},dataType:"json",method:"GET",success:function(t){t?o.find(".htcompare-counter").html(t.count):console.log("Something wrong loading compare data")},error:function(t){console.log("Something wrong with AJAX response.")},complete:function(){a.removeClass("loading added").html('<span class="htcompare-btn-text">'+a.data("text")+"</span>"),c(i)}})}),o.on("click","a.htcompare-remove",function(e){var a=t(".htcompare-table");e.preventDefault();var n=t(this),r=n.data("product_id"),d=evercompare.option_data.success_removed_notification_text.replace("{product_name}",n.data("product_title"));a.addClass("loading"),n.addClass("loading"),jQuery.ajax({url:evercompare.ajaxurl,data:{action:"ever_compare_remove_from_compare",nonce:evercompare.nonce,id:r},dataType:"json",method:"GET",success:function(e){e.table?i(e):console.log("Something wrong loading compare data"),t("a.htcompare-btn").each(function(){t(this).data("product_id")===r&&(t(this).removeClass("added"),t(this).html('<span class="htcompare-btn-text">'+t(this).data("text")+"</span>"))}),o.find(".htcompare-counter").html(e.count)},error:function(t){console.log("Something wrong with AJAX response.")},complete:function(){a.removeClass("loading"),n.addClass("loading"),c(d)}})}),o.on("click",".htcompare-popup-close",function(o){t(this).parent(".htcompare-popup.open").removeClass("open"),e.removeClass("open")}),t(".evercompare-copy-link").on("click",function(o){r(t(this).closest(".ever-compare-shareable-link").find(".evercompare-share-link"),this)})}(jQuery);
     1!function(e){"use strict";var o=e("body"),t=e(".htcompare-popup"),a=null,n=null;function r(){for(var e=evercompare.cookie_name,o=document.cookie.split(";"),t=0;t<o.length;t++){var a=o[t].trim();if(0===a.indexOf(e+"=")){var n=decodeURIComponent(a.substring(e.length+1));try{var r=JSON.parse(n);if(Array.isArray(r))return r.map(function(e){return parseInt(e,10)}).filter(function(e){return e>0})}catch(e){}}}return[]}function c(){return a?e.Deferred().resolve(a).promise():n||(n=e.ajax({url:evercompare.ajaxurl,data:{action:"ever_compare_get_nonce"},dataType:"json",method:"GET"}).then(function(e){return a=e.nonce,n=null,a}).fail(function(){n=null}))}function i(){e(".evercompare-copy-link").on("click",function(o){var t,a,n;t=e(this).closest(".ever-compare-shareable-link").find(".evercompare-share-link"),a=this,n=e("<input>"),e("body").append(n),n.val(e(t).text()).select(),document.execCommand("copy"),n.remove(),e(a).text(e(a).data("copytext")),setTimeout(function(){e(a).text(e(a).data("btntext"))},1e3)})}o.append('<div id="htcompare-error-modal" class="htcompare-error-modal" style="display:none"><div class="htcompare-error-modal-content"><button class="htcompare-error-modal-close">&times;</button><div class="htcompare-error-modal-body"></div></div></div>');var s,d=e("#htcompare-error-modal");e(".htcompare-error-modal-close").on("click",function(){d.css("display","none")}),e(window).on("click",function(e){e.target==d[0]&&d.css("display","none")}),s=r(),e("a.htcompare-btn").each(function(){var o=e(this),t=parseInt(o.data("product_id"),10);s.indexOf(t)>=0&&(o.addClass("added"),o.html('<span class="htcompare-btn-text">'+o.data("added-text")+"</span>"))}),function(){var e=r();o.find(".htcompare-counter").html(e.length)}(),function(){var o=e(".htcompare-table[data-ajax-load]");if(0!==o.length){var t=r();0!==t.length?e.ajax({url:evercompare.ajaxurl,data:{action:"ever_compare_get_table",ids:t.join(",")},dataType:"json",method:"GET",success:function(t){t.table&&(o.each(function(){e(this).replaceWith(t.table)}),i())}}):e.ajax({url:evercompare.ajaxurl,data:{action:"ever_compare_get_table",ids:""},dataType:"json",method:"GET",success:function(t){void 0!==t.table&&(o.each(function(){e(this).replaceWith(t.table||'<div class="htcompare-table htcompare-empty"></div>')}),i())}})}}();var p='<div class="htcompare-notification"><div class="htcompare-notification-text">'+evercompare.option_data.success_added_notification_text+'</div><span class="htcompare-notification-close">close</span></div>';"on"===evercompare.option_data.enable_success_notification&&(o.append(p),o.on("click",".htcompare-notification-close",function(){o.find(".htcompare-notification").removeClass("open")}));var l=function(e){"on"===evercompare.option_data.enable_success_notification&&(o.find(".htcompare-notification-text").html(e),o.find(".htcompare-notification").addClass("open"),+evercompare.option_data.removed_notification_after>-1&&setTimeout(function(){o.find(".htcompare-notification").removeClass("open")},1e3*+evercompare.option_data.removed_notification_after))};function m(o){e(".htcompare-table").length>0&&(e(".htcompare-table").replaceWith(o.table),i())}o.on("click","a.htcompare-btn",function(a){var n=e(this),r=n.data("product_id"),i=n.data("added-text"),s=evercompare.option_data.success_added_notification_text.replace("{product_name}",n.data("product_title"));if("yes"===evercompare.popup&&"off"===evercompare.option_data.remove_on_click){if(a.preventDefault(),n.hasClass("added"))return o.find(".htcompare-popup").addClass("open"),!0}else if(n.hasClass("added"))return!0;a.preventDefault(),n.addClass("loading"),c().then(function(a){e.ajax({url:evercompare.ajaxurl,data:{action:"ever_compare_add_to_compare",nonce:a,id:r},dataType:"json",method:"GET",success:function(a){if(a&&a.products){var n=("object"==typeof a.products?Object.values(a.products):a.products).map(function(e){return e.toString()});a.table&&n.indexOf(r.toString())>=0?(m(a),t.addClass("open")):(e(".htcompare-error-modal-body").html(a.limitReached),d.css("display","flex")),o.find(".htcompare-counter").html(a.count)}else o.find(".htcompare-counter").html(a?a.count:0)},error:function(e){console.log("Something wrong with AJAX response.")},complete:function(e){(n.removeClass("loading"),e.responseJSON&&e.responseJSON.products)&&(("object"==typeof e.responseJSON.products?Object.values(e.responseJSON.products):e.responseJSON.products).map(function(e){return e.toString()}).indexOf(r.toString())>=0&&(n.addClass("added"),n.html('<span class="htcompare-btn-text">'+i+"</span>"),l(s)))}})}).fail(function(){n.removeClass("loading")})}),evercompare.option_data.remove_on_click&&"on"===evercompare.option_data.remove_on_click&&o.on("click","a.htcompare-btn.added",function(t){t.preventDefault();var a=e(this),n=a.data("product_id"),r=evercompare.option_data.success_removed_notification_text.replace("{product_name}",a.data("product_title"));a.addClass("loading"),c().then(function(e){jQuery.ajax({url:evercompare.ajaxurl,data:{action:"ever_compare_remove_from_compare",nonce:e,id:n},dataType:"json",method:"GET",success:function(e){e?o.find(".htcompare-counter").html(e.count):console.log("Something wrong loading compare data")},error:function(e){console.log("Something wrong with AJAX response.")},complete:function(e){a.removeClass("loading added").html('<span class="htcompare-btn-text">'+a.data("text")+"</span>"),e.responseJSON&&void 0!==e.responseJSON.count&&l(r)}})}).fail(function(){a.removeClass("loading")})}),o.on("click","a.htcompare-remove",function(t){var a=e(".htcompare-table");t.preventDefault();var n=e(this),r=n.data("product_id"),i=evercompare.option_data.success_removed_notification_text.replace("{product_name}",n.data("product_title"));a.addClass("loading"),n.addClass("loading"),c().then(function(t){jQuery.ajax({url:evercompare.ajaxurl,data:{action:"ever_compare_remove_from_compare",nonce:t,id:r},dataType:"json",method:"GET",success:function(t){t.table?m(t):console.log("Something wrong loading compare data"),e("a.htcompare-btn").each(function(){e(this).data("product_id")===r&&(e(this).removeClass("added"),e(this).html('<span class="htcompare-btn-text">'+e(this).data("text")+"</span>"))}),o.find(".htcompare-counter").html(t.count)},error:function(e){console.log("Something wrong with AJAX response.")},complete:function(e){a.removeClass("loading"),n.removeClass("loading"),e.responseJSON&&e.responseJSON.table&&l(i)}})}).fail(function(){a.removeClass("loading"),n.removeClass("loading")})}),o.on("click",".htcompare-popup-close",function(o){e(this).parent(".htcompare-popup.open").removeClass("open"),t.removeClass("open")}),i()}(jQuery);
  • ever-compare/trunk/ever-compare.php

    r3331136 r3483393  
    66 * Author: HasTheme
    77 * Author URI: https://hasthemes.com/
    8  * Version: 1.3.4
     8 * Version: 1.3.5
    99 * License: GPL2 or later
    1010 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    2626     * @var string
    2727     */
    28     const version = '1.3.4';
     28    const version = '1.3.5';
    2929
    3030    /**
     
    5858        add_action( 'plugins_loaded', [ $this, 'init_plugin' ] );
    5959
    60         // Compatible With WooCommerce Custom Order Tables
     60        // Compatible With WooCommerce Features
    6161        add_action( 'before_woocommerce_init', function() {
    6262            if ( class_exists( '\Automattic\WooCommerce\Utilities\FeaturesUtil' ) ) {
    6363                \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', EVERCOMPARE_FILE, true );
     64                \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'cart_checkout_blocks', EVERCOMPARE_FILE, true );
     65                \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'product_block_editor', EVERCOMPARE_FILE, true );
    6466            }
    6567        } );
     
    107109        EverCompare\Assets::instance();
    108110
    109         if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
    110             EverCompare\Ajax::instance();
    111         }
    112 
    113111        if ( is_admin() ) {
    114112            $this->admin_notices();
    115113            EverCompare\Admin::instance();
    116114        }
     115
     116        if ( ! ever_compare_woocommerce_installed() ) {
     117            return;
     118        }
     119
     120        if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
     121            EverCompare\Ajax::instance();
     122        }
     123
    117124        EverCompare\Frontend::instance();
    118125
  • ever-compare/trunk/includes/classes/Admin/Settings_APi.php

    r3314387 r3483393  
    2727     * Enqueue scripts and styles
    2828     */
    29     function admin_enqueue_scripts() {
     29    function admin_enqueue_scripts( $hook ) {
     30        if ( false === strpos( $hook, 'evercompare' ) ) {
     31            return;
     32        }
    3033        wp_enqueue_style( 'wp-color-picker' );
    3134        wp_enqueue_media();
  • ever-compare/trunk/includes/classes/Ajax.php

    r3144815 r3483393  
    3636        add_action( 'wp_ajax_nopriv_ever_compare_remove_from_compare', [ $this,'remove_from_compare' ] );
    3737
     38        // Get Nonce endpoint (no nonce verification needed)
     39        add_action( 'wp_ajax_ever_compare_get_nonce', [ $this, 'get_nonce' ] );
     40        add_action( 'wp_ajax_nopriv_ever_compare_get_nonce', [ $this, 'get_nonce' ] );
     41
     42        // Get Table endpoint
     43        add_action( 'wp_ajax_ever_compare_get_table', [ $this, 'get_table' ] );
     44        add_action( 'wp_ajax_nopriv_ever_compare_get_table', [ $this, 'get_table' ] );
     45
    3846    }
    3947
     
    4452        check_ajax_referer('ever_compare_nonce', 'nonce');
    4553        if(!empty($_GET['id'])) {
    46             $id = sanitize_text_field( wp_unslash($_GET['id']) );
     54            $id = absint( $_GET['id'] );
    4755            \EverCompare\Frontend\Manage_Compare::instance()->add_to_compare( $id );
    4856        }
     
    5664        check_ajax_referer('ever_compare_nonce', 'nonce');
    5765        if(!empty($_GET['id'])) {
    58             $id = sanitize_text_field( wp_unslash($_GET['id']) );
     66            $id = absint( $_GET['id'] );
    5967            \EverCompare\Frontend\Manage_Compare::instance()->remove_from_compare( $id );
    6068        }
    6169    }
    6270
     71    /**
     72     * [get_nonce] Return a fresh nonce for AJAX operations
     73     * @return [void]
     74     */
     75    public function get_nonce(){
     76        wp_send_json( array(
     77            'nonce' => wp_create_nonce( 'ever_compare_nonce' ),
     78        ) );
     79    }
     80
     81    /**
     82     * [get_table] Return compare table HTML for given product IDs
     83     * @return [void]
     84     */
     85    public function get_table(){
     86        $ids = array();
     87        if ( ! empty( $_GET['ids'] ) ) {
     88            $raw_ids = sanitize_text_field( wp_unslash( $_GET['ids'] ) );
     89            $ids = array_filter( array_map( 'absint', explode( ',', $raw_ids ) ) );
     90            $ids = array_slice( $ids, 0, \EverCompare\Frontend\Manage_Compare::instance()->max_limit );
     91        }
     92
     93        if ( empty( $ids ) ) {
     94            wp_send_json( array(
     95                'table' => '',
     96                'count' => 0,
     97            ) );
     98        }
     99
     100        $cookie_name = \EverCompare\Frontend\Manage_Compare::instance()->get_cookie_name();
     101        $_COOKIE[ $cookie_name ] = wp_json_encode( $ids );
     102
     103        ob_start();
     104        \EverCompare\Frontend\Manage_Compare::instance()->get_response_html();
     105        $table_html = ob_get_clean();
     106
     107        wp_send_json( array(
     108            'table' => $table_html,
     109            'count' => count( $ids ),
     110            'products' => $ids,
     111        ) );
     112    }
     113
    63114}
  • ever-compare/trunk/includes/classes/Assets.php

    r3108021 r3483393  
    116116            'removed_notification_after' => ever_compare_get_option( 'removed_notification_after', 'ever_compare_settings_general', -1 ),
    117117        );
     118        $cookie_name = 'ever_compare_compare_list';
     119        if ( is_multisite() ) {
     120            $cookie_name .= '_' . get_current_blog_id();
     121        }
    118122        $localize_data = array(
    119             'ajaxurl'       => admin_url( 'admin-ajax.php' ),
    120             'nonce'         => wp_create_nonce('ever_compare_nonce'),
    121             'popup'         => ( ever_compare_get_option( 'open_popup', 'ever_compare_settings_tabs', 'on' ) === 'on' ) ? 'yes' : 'no',
    122             'option_data'   => $option_data,
     123            'ajaxurl'          => admin_url( 'admin-ajax.php' ),
     124            'cookie_name'      => $cookie_name,
     125            'compare_page_url' => esc_url( get_permalink( ever_compare_get_option( 'compare_page', 'ever_compare_table_settings_tabs' ) ) ),
     126            'popup'            => ( ever_compare_get_option( 'open_popup', 'ever_compare_settings_tabs', 'on' ) === 'on' ) ? 'yes' : 'no',
     127            'option_data'      => $option_data,
    123128        );
    124129
  • ever-compare/trunk/includes/classes/Frontend/Manage_Compare.php

    r3314387 r3483393  
    126126        }
    127127
    128         /**
    129          * Manage maximum product added message
    130          */
    131         if( isset( $_COOKIE[ 'ever_compare_max_limit' ] ) && $_COOKIE[ 'ever_compare_max_limit' ] == 'yes' ) {
    132             setcookie( 'ever_compare_max_limit', 'no', 0, COOKIEPATH, COOKIE_DOMAIN, false, false );
    133             $this->reached_max_limit = true;
    134         }
    135128
    136129
     
    171164     */
    172165    public function pop_up_html(){
    173         echo '<div class="htcompare-popup"><div class="htcompare-popup-content-area"><span class="htcompare-popup-close">&nbsp;</span>'.do_shortcode( '[evercompare_table]' ).'</div></div>';
     166        echo '<div class="htcompare-popup"><div class="htcompare-popup-content-area"><span class="htcompare-popup-close">&nbsp;</span><div class="htcompare-table" data-ajax-load="true"></div></div></div>';
    174167    }
    175168
     
    201194        $ids = $this->get_compared_products();
    202195
    203          if ( isset( $_GET['evcompare'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
     196         if ( ! empty( $_GET['evcompare'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
    204197            $query_perametter_ids = sanitize_text_field( wp_unslash($_GET['evcompare']) ); //phpcs:ignore WordPress.Security.NonceVerification.Recommended
    205198            if( !empty( $query_perametter_ids ) ){
    206                 $ids = explode( ',', $query_perametter_ids );
     199                $ids = array_filter( array_map( 'absint', explode( ',', $query_perametter_ids ) ) );
    207200            }
    208201        }
     
    238231        // Reached Maximum Limit
    239232        if( $this->reached_max_limit() ) {
    240             setcookie( 'ever_compare_max_limit', 'yes', 0, COOKIEPATH, COOKIE_DOMAIN, false, false );
    241233            $this->compare_json_response();
    242234        }
     
    289281            }
    290282        }
     283
     284        $products = array_values( $products );
    291285
    292286        if ( empty( $products ) ) {
     
    338332        // For shareable link
    339333        $shareable_link = ever_compare_get_option('enable_shareable_link','ever_compare_table_settings_tabs','off');
    340         if ( ( $shareable_link === 'on' ) && isset( $_GET['evcompare'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
     334        if ( ( $shareable_link === 'on' ) && ! empty( $_GET['evcompare'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
    341335            $query_perametter_ids = sanitize_text_field( wp_unslash($_GET['evcompare']) ); //phpcs:ignore WordPress.Security.NonceVerification.Recommended
    342336            if( !empty( $query_perametter_ids ) ){
    343                 $ids = explode( ',', $query_perametter_ids );
     337                $ids = array_filter( array_map( 'absint', explode( ',', $query_perametter_ids ) ) );
    344338            }
    345339        }
     
    606600    public function is_product_in_compare( $id ) {
    607601        $list = $this->get_compared_products();
    608         return in_array( strval($id), $list, true );
     602        return in_array( absint($id), $list, true );
    609603    }
    610604
     
    616610        $cookie_name = $this->get_cookie_name();
    617611        if(!empty( $_COOKIE[ $cookie_name ] )) {
    618             return json_decode( sanitize_text_field(wp_unslash( $_COOKIE[ $cookie_name ] )), true );
     612            $decoded = json_decode( sanitize_text_field(wp_unslash( $_COOKIE[ $cookie_name ] )), true );
     613            if ( is_array( $decoded ) ) {
     614                return array_filter( array_map( 'absint', $decoded ) );
     615            }
    619616        }
    620617        return [];
  • ever-compare/trunk/includes/classes/Frontend/Shortcode.php

    r3041668 r3483393  
    8989        } else {
    9090            $button_added_text = '<span class="evercompare-btn-text">'.$button_remove_text.'</span>';
    91         }
    92 
    93         if(\EverCompare\Frontend\Manage_Compare::instance()->is_product_in_compare( $product_id )) {
    94             $button_class[] = 'added';
    9591        }
    9692
     
    118114     */
    119115    public function table_shortcode( $atts, $content = '' ){
    120        
     116
    121117        wp_enqueue_style( 'evercompare-frontend' );
    122118        wp_enqueue_script( 'evercompare-frontend' );
    123119
    124         /* Fetch From option data */
    125         $empty_compare_text = ever_compare_get_option('empty_table_text','ever_compare_table_settings_tabs');
    126         $return_shop_button = ever_compare_get_option('shop_button_text','ever_compare_table_settings_tabs','Return to shop');
    127 
    128         /* Product and Field */
    129         $products   = Manage_Compare::instance()->get_compared_products_data();
    130         $fields     = Manage_Compare::instance()->get_compare_fields();
    131 
    132         $custom_heading = !empty( ever_compare_get_option( 'table_heading', 'ever_compare_table_settings_tabs' ) ) ? ever_compare_get_option( 'table_heading', 'ever_compare_table_settings_tabs' ) : array();
    133 
    134         $default_atts = array(
    135             'evercompare'  => Manage_Compare::instance(),
    136             'products'     => $products,
    137             'fields'       => $fields,
    138             'return_shop_button'=> $return_shop_button,
    139             'heading_txt'       => $custom_heading,
    140             'empty_compare_text'=> $empty_compare_text,
    141         );
    142 
    143         $atts = shortcode_atts( $default_atts, $atts, $content );
    144         return Manage_Compare::instance()->table_html( $atts );
     120        // Shareable link via query param — render server-side (not cached due to query param)
     121        if ( ! empty( $_GET['evcompare'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
     122            /* Fetch From option data */
     123            $empty_compare_text = ever_compare_get_option('empty_table_text','ever_compare_table_settings_tabs');
     124            $return_shop_button = ever_compare_get_option('shop_button_text','ever_compare_table_settings_tabs','Return to shop');
     125
     126            /* Product and Field */
     127            $products   = Manage_Compare::instance()->get_compared_products_data();
     128            $fields     = Manage_Compare::instance()->get_compare_fields();
     129
     130            $custom_heading = !empty( ever_compare_get_option( 'table_heading', 'ever_compare_table_settings_tabs' ) ) ? ever_compare_get_option( 'table_heading', 'ever_compare_table_settings_tabs' ) : array();
     131
     132            $default_atts = array(
     133                'evercompare'  => Manage_Compare::instance(),
     134                'products'     => $products,
     135                'fields'       => $fields,
     136                'return_shop_button'=> $return_shop_button,
     137                'heading_txt'       => $custom_heading,
     138                'empty_compare_text'=> $empty_compare_text,
     139            );
     140
     141            $atts = shortcode_atts( $default_atts, $atts, $content );
     142            return Manage_Compare::instance()->table_html( $atts );
     143        }
     144
     145        // Cookie-based: render placeholder that JS will populate via AJAX
     146        return '<div class="htcompare-table" data-ajax-load="true"></div>';
    145147
    146148    }
     
    159161
    160162        $default_atts = array(
    161             'count'      => count(Manage_Compare::instance()->get_compared_products()),
     163            'count'      => 0,
    162164            'page_url'      => Manage_Compare::instance()->get_compare_page_url(),
    163165        );
  • ever-compare/trunk/includes/helper-functions.php

    r3108021 r3483393  
    2121function ever_compare_update_option( $section, $option_key, $new_value ){
    2222    $options_data = get_option( $section );
    23     if( isset( $options_data[$option_key] ) ){
    24         $options_data[$option_key] = $new_value;
    25     }else{
    26         $options_data = array( $option_key => $new_value );
    27     }
     23    if ( ! is_array( $options_data ) ) {
     24        $options_data = array();
     25    }
     26    $options_data[ $option_key ] = $new_value;
    2827    update_option( $section, $options_data );
    2928}
     
    4443    $options = array();
    4544    $options['0'] = __('Select','ever-compare');
    46     $perpage = -1;
     45    $perpage = 200;
    4746    $all_post = array( 'posts_per_page' => $perpage, 'post_type'=> $post_type );
    4847    $post_terms = get_posts( $all_post );
     
    8887
    8988    if ( $args && is_array( $args ) ) {
    90         extract( $args );
     89        $evercompare_args = $args;
     90        // Backward compat: if template is overridden in theme, extract for legacy support
     91        $default_path = EVERCOMPARE_PATH . '/includes/templates/' . $tmp_name;
     92        if ( $located !== $default_path ) {
     93            extract( $args, EXTR_SKIP ); // phpcs:ignore WordPress.PHP.DontExtract.extract_extract
     94        }
    9195    }
    9296
  • ever-compare/trunk/includes/templates/evercompare-button-add.php

    r3108021 r3483393  
    1 <span class="htcompare-button-area"><a href="<?php echo esc_url( $button_url ); ?>" class="<?php echo esc_attr($button_class); ?>" data-text="<?php echo esc_attr( $button_text ); ?>" data-added-text="<?php echo esc_attr( $button_added_text); ?>" data-product_id="<?php echo esc_attr( $product_id ); ?>" data-product_title="<?php echo esc_attr( $product_title ); ?>" ><?php echo wp_kses($button_text, get_allowed_tags_for_svg()); ?></a></span>
     1<span class="htcompare-button-area"><a href="<?php echo esc_url( $evercompare_args['button_url'] ); ?>" class="<?php echo esc_attr($evercompare_args['button_class']); ?>" data-text="<?php echo esc_attr( $evercompare_args['button_text'] ); ?>" data-added-text="<?php echo esc_attr( $evercompare_args['button_added_text']); ?>" data-product_id="<?php echo esc_attr( $evercompare_args['product_id'] ); ?>" data-product_title="<?php echo esc_attr( $evercompare_args['product_title'] ); ?>" ><?php echo wp_kses($evercompare_args['button_text'], get_allowed_tags_for_svg()); ?></a></span>
  • ever-compare/trunk/includes/templates/evercompare-count.php

    r2927305 r3483393  
    1 <a href="<?php echo esc_url( $page_url );?>" class="htcompare-counter-area">
     1<a href="<?php echo esc_url( $evercompare_args['page_url'] );?>" class="htcompare-counter-area">
    22    <span class="htcompare-counter-icon">
    33        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 471.701 471.701" height="20px" width="20px" >
     
    66    </span>
    77    <?php
    8         echo '<span class="htcompare-counter">'.esc_html( $count ).'</span>';
     8        echo '<span class="htcompare-counter">'.esc_html( $evercompare_args['count'] ).'</span>';
    99    ?>
    1010</a>
  • ever-compare/trunk/includes/templates/evercompare-table.php

    r3108021 r3483393  
    33        // do_action( 'ever_compare_before_table' );
    44
    5         if ( ! empty( $products ) ) {
     5        if ( ! empty( $evercompare_args['products'] ) ) {
     6            $products = $evercompare_args['products'];
    67            array_unshift( $products, array() );
    7             foreach ( $fields as $field_id => $field ) {
    8                 if ( ! $evercompare->is_products_have_field( $field_id, $products ) ) {
     8            foreach ( $evercompare_args['fields'] as $field_id => $field ) {
     9                if ( ! $evercompare_args['evercompare']->is_products_have_field( $field_id, $products ) ) {
    910                    continue;
    1011                }
    1112
    1213                // Generate Filed name
    13                 $name = $evercompare->field_name( $field );
    14                 if( array_key_exists( $field_id, $heading_txt ) && !empty( $heading_txt[$field_id] ) ){
    15                     $name = $evercompare->field_name( $heading_txt[$field_id], true );
     14                $name = $evercompare_args['evercompare']->field_name( $field );
     15                if( array_key_exists( $field_id, $evercompare_args['heading_txt'] ) && !empty( $evercompare_args['heading_txt'][$field_id] ) ){
     16                    $name = $evercompare_args['evercompare']->field_name( $evercompare_args['heading_txt'][$field_id], true );
    1617                }
    1718
     
    2122                            <?php if ( ! empty( $product ) ) : ?>
    2223                                <div class="htcompare-col htcolumn-value" data-title="<?php echo esc_attr( $name ); ?>">
    23                                     <?php $evercompare->compare_display_field( $field_id, $product ); ?>
     24                                    <?php $evercompare_args['evercompare']->compare_display_field( $field_id, $product ); ?>
    2425                                </div>
    2526                            <?php else: ?>
     
    3233                <?php
    3334            }
    34             echo '<div class="htcompare-table-loader"></div>'; 
     35            echo '<div class="htcompare-table-loader"></div>';
    3536        } else {
    36             if ( $empty_compare_text ){
    37                 echo '<div class="htcompare-empty-page-text">'.wp_kses_post( $empty_compare_text ).'</div>';
     37            if ( $evercompare_args['empty_compare_text'] ){
     38                echo '<div class="htcompare-empty-page-text">'.wp_kses_post( $evercompare_args['empty_compare_text'] ).'</div>';
    3839            }
    3940
    40             if( $return_shop_button ){
    41                 echo '<div class="htcompare-return-to-shop"><a href="'.esc_url( wc_get_page_permalink( 'shop' ) ).'" class="button">'.esc_html( $return_shop_button ).'</a></div>';
     41            if( $evercompare_args['return_shop_button'] ){
     42                echo '<div class="htcompare-return-to-shop"><a href="'.esc_url( wc_get_page_permalink( 'shop' ) ).'" class="button">'.esc_html( $evercompare_args['return_shop_button'] ).'</a></div>';
    4243            }
    4344        }
  • ever-compare/trunk/readme.txt

    r3407749 r3483393  
    44Requires at least: 5.0
    55Tested up to: 6.9
    6 Stable tag: 1.3.4
     6Stable tag: 1.3.5
    77License: GPLv2 or later
    88License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    9090
    9191== Changelog ==
     92
     93= Version: 1.3.5 - Date: 2026-03-16 =
     94* Fixed: Empty evcompare query parameter no longer generates broken shareable links.
     95* Improved: Cache compatibility for compare page using cookie-based AJAX loading.
    9296
    9397= Version: 1.3.4 - Date: 2025-07-21 =
Note: See TracChangeset for help on using the changeset viewer.