Plugin Directory

Changeset 3798363


Ignore:
Timestamp:
11/12/2026 01:05:34 PM (38 hours ago)
Author:
markutos987
Message:

Update ux

Location:
filter-plus
Files:
179 added
21 edited

Legend:

Unmodified
Added
Removed
  • filter-plus/trunk/assets/css/admin.css

    r3783118 r3798363  
    230230        display: flex;
    231231}
     232
     233.custom-switcher.is-mode-disabled { opacity: .5; pointer-events: none; cursor: not-allowed; }
    232234
    233235/* Setting Tab Style */
    … …  
    22472249        animation: spin .75s linear infinite;
    22482250}
     2251
     2252
     2253/* Filter Sets list page */
     2254#filter-set-list-wrap {
     2255        max-width: 1440px;
     2256        margin: 24px 20px 40px 0;
     2257}
     2258.filter-set-page-head {
     2259        display: flex;
     2260        align-items: center;
     2261        justify-content: flex-start;
     2262        gap: 24px;
     2263        margin: 0 0 22px;
     2264}
     2265.filter-set-title-row {
     2266        display: flex;
     2267        align-items: center;
     2268        gap: 16px;
     2269}
     2270.filter-set-title-row .add-filter-set {
     2271        margin: 0;
     2272}
     2273.filter-set-page-copy h1 {
     2274        margin: 0 0 6px;
     2275        color: #1d2327;
     2276        font-size: 24px;
     2277        font-weight: 600;
     2278        line-height: 1.3;
     2279}
     2280.filter-set-title-row h1 {
     2281        margin: 0;
     2282}
     2283.filter-set-page-copy p,
     2284.filter-set-list-heading p {
     2285        margin: 0;
     2286        color: #646970;
     2287        font-size: 13px;
     2288}
     2289.filter-set-page-head .add-filter-set {
     2290        display: inline-flex;
     2291        align-items: center;
     2292        gap: 8px;
     2293        min-height: 40px;
     2294        padding: 0 14px;
     2295        white-space: nowrap;
     2296        font-weight: 600;
     2297}
     2298.filter-set-add-icon {
     2299        font-size: 20px;
     2300        font-weight: 400;
     2301        line-height: 1;
     2302}
     2303#filter-set-list-wrap .filter-sets-saved {
     2304        margin: 0;
     2305        padding: 20px 22px 10px;
     2306        border: 1px solid #dcdcde;
     2307        border-radius: 8px;
     2308        background: #fff;
     2309        box-shadow: 0 1px 2px rgba(0, 0, 0, .04);
     2310}
     2311.filter-set-list-heading {
     2312        margin: 0 0 16px;
     2313}
     2314.filter-set-list-heading h2 {
     2315        margin: 0 0 5px;
     2316        color: #1d2327;
     2317        font-size: 16px;
     2318        font-weight: 600;
     2319}
     2320#filter-set-list-wrap .filter-options-list,
     2321#filter-set-list-wrap form {
     2322        margin: 0;
     2323}
     2324#filter-set-list-wrap .tablenav {
     2325        min-height: 40px;
     2326        margin: 8px 0 12px;
     2327}
     2328#filter-set-list-wrap .tablenav.top {
     2329        margin-top: 0;
     2330}
     2331#filter-set-list-wrap .wp-list-table {
     2332        border: 1px solid #e2e4e7;
     2333        border-radius: 6px;
     2334        border-spacing: 0;
     2335        box-shadow: none;
     2336        overflow: hidden;
     2337}
     2338#filter-set-list-wrap .wp-list-table thead tr,
     2339#filter-set-list-wrap .wp-list-table tfoot tr {
     2340        height: 48px;
     2341        background: #f6f7f7;
     2342}
     2343#filter-set-list-wrap .wp-list-table tfoot {
     2344        display: none;
     2345}
     2346#filter-set-list-wrap .wp-list-table th,
     2347#filter-set-list-wrap .wp-list-table td {
     2348        padding: 12px 14px;
     2349        vertical-align: middle;
     2350}
     2351#filter-set-list-wrap .wp-list-table .check-column {
     2352        width: 42px;
     2353        padding-right: 0;
     2354        padding-left: 12px;
     2355}
     2356#filter-set-list-wrap .wp-list-table th.column-name,
     2357#filter-set-list-wrap .wp-list-table td.column-name {
     2358        width: 24%;
     2359}
     2360#filter-set-list-wrap .wp-list-table tbody tr {
     2361        background: #fff;
     2362}
     2363#filter-set-list-wrap .wp-list-table tbody tr:hover {
     2364        background: #fbfcfd;
     2365}
     2366#filter-set-list-wrap .wp-list-table td.column-name {
     2367        color: #1d2327;
     2368        font-weight: 500;
     2369}
     2370#filter-set-list-wrap .row-actions {
     2371        padding-top: 5px;
     2372}
     2373#filter-set-list-wrap .shortcode-cell {
     2374        align-items: stretch;
     2375        gap: 10px;
     2376}
     2377#filter-set-list-wrap .shortcode-cell .saved-shortcode {
     2378        box-sizing: border-box;
     2379        min-height: 66px;
     2380        max-height: 120px;
     2381        padding: 9px 11px;
     2382        border: 1px solid #dcdcde;
     2383        border-radius: 5px;
     2384        background: #f6f7f7;
     2385        color: #3c434a;
     2386        font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
     2387        font-size: 12px;
     2388        line-height: 1.5;
     2389        white-space: pre-wrap;
     2390        overflow-wrap: anywhere;
     2391        resize: vertical;
     2392}
     2393#filter-set-list-wrap .shortcode-cell .copy-filter-set {
     2394        align-self: center;
     2395        min-height: 36px;
     2396        padding: 0 14px;
     2397        font-weight: 600;
     2398}
     2399@media (max-width: 782px) {
     2400        #filter-set-list-wrap {
     2401                margin: 18px 10px 30px 0;
     2402        }
     2403        .filter-set-page-head {
     2404                align-items: flex-start;
     2405        }
     2406        .filter-set-title-row {
     2407                align-items: flex-start;
     2408                flex-wrap: wrap;
     2409                gap: 10px 14px;
     2410        }
     2411        #filter-set-list-wrap .filter-sets-saved {
     2412                padding: 16px 12px 8px;
     2413        }
     2414        #filter-set-list-wrap .wp-list-table th,
     2415        #filter-set-list-wrap .wp-list-table td {
     2416                padding: 10px 8px;
     2417        }
     2418        #filter-set-list-wrap .shortcode-cell {
     2419                align-items: stretch;
     2420                flex-direction: column;
     2421        }
     2422        #filter-set-list-wrap .shortcode-cell .copy-filter-set {
     2423                align-self: flex-start;
     2424        }
     2425}
     2426
     2427.flp-image-mode-notice {
     2428        display: flex;
     2429        align-items: flex-start;
     2430        gap: 8px;
     2431        margin: 4px 0 12px !important;
     2432        padding: 10px 12px;
     2433        border: 1px solid #c8d7e8;
     2434        border-left: 3px solid #2271b1;
     2435        border-radius: 4px;
     2436        background: #f6f9fc;
     2437        color: #3c434a;
     2438}
     2439.flp-image-mode-notice .dashicons {
     2440        flex: 0 0 auto;
     2441        color: #2271b1;
     2442}
     2443.flp-image-mode-notice p {
     2444        margin: 0;
     2445        font-size: 13px;
     2446        line-height: 1.5;
     2447}
     2448
     2449#filter-set-list-wrap .shortcode-cell .saved-shortcode { height: 38px; min-height: 38px; max-height: 38px; padding: 0 11px; line-height: 36px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; resize: none; }
     2450
     2451/* Make the image mode guidance easier to spot. */
     2452#filter-set-form-wrap .flp-image-mode-notice { background: #eaf3ff !important; border: 1px solid #9fc5f8 !important; border-left: 4px solid #2271b1 !important; box-shadow: 0 2px 8px rgba(34, 113, 177, .12); color: #1d3b5c; }
     2453#filter-set-form-wrap .flp-image-mode-notice .dashicons { color: #135e96; }
     2454#filter-set-form-wrap .flp-image-mode-notice p { font-weight: 500; }
     2455
     2456#filter-set-form-wrap .flp-image-mode-notice { width: fit-content; max-width: 100%; margin-left: auto !important; box-sizing: border-box; }
  • filter-plus/trunk/assets/css/public.css

    r3796324 r3798363  
    29962996        gap: 10px;
    29972997}
     2998.color-option {
     2999        display: contents;
     3000}
     3001.color-style-2 .color-option {
     3002        display: inline-flex;
     3003        flex: 0 0 calc(50% - 5px);
     3004        align-items: center;
     3005        gap: 8px;
     3006        box-sizing: border-box;
     3007}
    29983008.color-style-2 .color-item{
    29993009        width: 30px !important;
    … …  
    30023012}
    30033013.color-style-2 .meta-count{
    3004         width: 27% !important;
     3014        width: auto !important;
     3015        white-space: nowrap;
    30053016}
    30063017.color-style-3 .color-item{
    … …  
    33783389        }
    33793390
     3391        .price-input-2 .price-input-wrapper {
     3392                flex-direction: row;
     3393                align-items: center;
     3394                gap: 8px;
     3395        }
     3396
     3397        .price-input-2 .field {
     3398                flex: 1 1 85px;
     3399                width: 85px;
     3400        }
     3401
     3402        .price-input-2 .separator-wrapper {
     3403                display: flex;
     3404                padding-top: 25px;
     3405        }
     3406
    33803407        .separator-wrapper {
    33813408                display: none;
    … …  
    34003427
    34013428/* Template 2 specific styles */
     3429.price-input-2 .price-input-wrapper {
     3430        width: 100%;
     3431        min-width: 0;
     3432        gap: 12px;
     3433}
     3434
     3435.price-input-2 .field {
     3436        flex: 1 1 85px;
     3437        width: 85px;
     3438        max-width: 100%;
     3439        min-width: 0;
     3440}
     3441
     3442.price-input-2 .input-container {
     3443        box-sizing: border-box;
     3444        width: 100%;
     3445        min-width: 0;
     3446}
     3447
     3448.price-input-2 .currency-symbol {
     3449        flex: 0 0 auto;
     3450        box-sizing: border-box;
     3451        height: 100%;
     3452}
     3453
     3454.price-input-2 .price-input {
     3455        box-sizing: border-box;
     3456        flex: 1 1 auto;
     3457        width: 0;
     3458        min-width: 0;
     3459        padding: 0 8px;
     3460}
     3461
    34023462.sidebar-style-2 .input-container:focus-within {
    34033463        border-color: #17c6aa;
    … …  
    38033863        line-height: 1.5;
    38043864}
     3865
     3866/* Keep quick view compact so standard product forms fit without a modal scrollbar. */
     3867.fp-qv-modal {
     3868        max-height: calc(100vh - 32px);
     3869}
     3870
     3871.fp-qv-layout {
     3872        min-height: 0;
     3873}
     3874
     3875.fp-qv-gallery {
     3876        gap: 8px;
     3877        padding: 20px;
     3878}
     3879
     3880.fp-qv-main-image {
     3881        min-height: 0;
     3882        height: clamp(220px, 38vh, 300px);
     3883}
     3884
     3885.fp-qv-main-image img {
     3886        max-height: 100%;
     3887}
     3888
     3889.fp-qv-thumbnail {
     3890        flex-basis: 54px;
     3891        width: 54px;
     3892        height: 54px;
     3893}
     3894
     3895.fp-qv-summary {
     3896        padding: 24px 28px 20px;
     3897}
     3898
     3899.fp-qv-summary h2 {
     3900        margin-bottom: 8px;
     3901}
     3902
     3903.fp-qv-rating,
     3904.fp-qv-price {
     3905        margin-bottom: 9px;
     3906}
     3907
     3908.fp-qv-description {
     3909        margin-bottom: 12px;
     3910}
     3911
     3912.fp-qv-cart .group_table td {
     3913        padding: 7px 8px;
     3914}
     3915
     3916@media (max-width: 640px) {
     3917        .fp-qv-main-image {
     3918                height: min(30vh, 220px);
     3919        }
     3920        .fp-qv-summary {
     3921                padding: 16px 18px 20px;
     3922        }
     3923}
  • filter-plus/trunk/assets/js/admin.js

    r3783118 r3798363  
    255255
    256256                function shortcode_input_disable($this) {
    257                         const disable = $this.parent().hasClass('disable');
     257                        const disable = $this.parent().hasClass('disable') || $this.parent().hasClass('is-mode-disabled');
    258258                        const disable_pro = $this.parent().hasClass('pro-disable');
    259259                        const d_none = $this.parents('.d-none');
    … …  
    263263                        return false;
    264264                }
     265
     266                function syncProductImageModes($block, changed) {
     267                        const $rollover = $block.find('#rollover_image').first();
     268                        const $slider = $block.find('#gallery_slider').first();
     269                        if (!$rollover.length || !$slider.length) return;
     270                        if (changed === 'rollover_image' && $rollover.is(':checked')) $slider.prop('checked', false);
     271                        if (changed === 'gallery_slider' && $slider.is(':checked')) $rollover.prop('checked', false);
     272                        if (!changed && $rollover.is(':checked') && $slider.is(':checked')) $rollover.prop('checked', false);
     273                        const rolloverOn = $rollover.is(':checked');
     274                        const sliderOn = $slider.is(':checked');
     275                        $block.find('#rollover_image_number, #rollover_effect').closest('.single-block').toggleClass('d-none', !rolloverOn);
     276                }
     277                $(document).on('change', '.shortcode-block #rollover_image, .shortcode-block #gallery_slider', function () {
     278                        syncProductImageModes($(this).closest('.shortcode-block'), this.id);
     279                });
     280                $('.shortcode-block').each(function () {
     281                        syncProductImageModes($(this), null);
     282                });
    265283
    266284                /**
    … …  
    399417                                                $this.removeClass('loading');
    400418                                                if (response && response.success) {
     419                                                        if (id) {
     420                                                                const saved_set = response.data?.data;
     421                                                                if (saved_set?.ID) {
     422                                                                        $filter_set_id.val(saved_set.ID);
     423                                                                }
     424                                                                $this.text('Updated');
     425                                                                setTimeout(function () {
     426                                                                        $this.text(edit_button_text);
     427                                                                }, 1400);
     428                                                                return;
     429                                                        }
    401430                                                        location.reload();
    402431                                                } else {
  • filter-plus/trunk/assets/js/search-filter.js

    r3796324 r3798363  
    754754                                image_width,
    755755                                image_height,
     756                                rollover_image: $('#shopContainer').data('rollover_image') || 'no',
     757                                rollover_image_number: $('#shopContainer').data('rollover_image_number') || 1,
     758                                rollover_effect: $('#shopContainer').data('rollover_effect') || 'fade',
     759                                gallery_slider: $('#shopContainer').data('gallery_slider') || 'no',
    756760                                hide_prod_title,
    757761                                hide_prod_desc,
  • filter-plus/trunk/base/data-factory.php

    r3796324 r3798363  
    5858            'price_range_label' => esc_html__('Price Range','filter-plus'),
    5959            'on_sale'                   => '',
     60                        'on_sale_template' => '1',
    6061            'on_sale_label'     => esc_html__('Sale','filter-plus'),
    6162            'stock'                     => '',
     63                        'stock_template' => '1',
    6264            'stock_label'               => esc_html__('Stock','filter-plus'),
    6365            'product_categories'=> 'yes',
    … …  
    7678            'image_width'            => '',
    7779            'image_height'           => '',
     80            'rollover_image'         => 'no',
     81            'rollover_image_number'  => '1',
     82            'rollover_effect'        => 'fade',
     83            'gallery_slider'         => 'no',
    7884            'hide_prod_rating'       => 'yes',
    7985            'enable_category_layout' => 'no',
    … …  
    198204                $default_data['price_range_label'] = ! empty( $price_range_label ) ? $price_range_label : esc_html__( 'Price Range', 'filter-plus' );
    199205                $default_data['stock'] = ( isset( $settings['stock'] ) && ( $settings['stock'] === true || $settings['stock'] === 'yes' || $settings['stock'] === '1' || $settings['stock'] == 1 ) ) ? 'yes' : 'no';
     206                $default_data['stock_template'] = $this->normalize_filter_layout( $settings['stock_template'] ?? '1' );
    200207                $default_data['stock_label'] = ! empty( $stock_label ) ? $stock_label : esc_html__( 'Stock', 'filter-plus' );
    201208                $default_data['on_sale'] = ( isset( $settings['on_sale'] ) && ( $settings['on_sale'] === true || $settings['on_sale'] === 'yes' || $settings['on_sale'] === '1' || $settings['on_sale'] == 1 ) ) ? 'yes' : 'no';
     209                $default_data['on_sale_template'] = $this->normalize_filter_layout( $settings['on_sale_template'] ?? '1' );
    202210                $default_data['on_sale_label'] = ! empty( $on_sale_label ) ? $on_sale_label : esc_html__( 'Sale', 'filter-plus' );
    203211                $default_data['hide_prod_title']    = ! empty( $hide_prod_title ) && ( $hide_prod_title == true ||  $hide_prod_title == 'yes' )  ?  'yes' : 'no';
    … …  
    210218                $default_data['image_width']        = ( class_exists( 'FilterPlusPro' ) && ! empty( $settings['image_width'] ) )  ? intval( $settings['image_width'] )  : '';
    211219                $default_data['image_height']       = ( class_exists( 'FilterPlusPro' ) && ! empty( $settings['image_height'] ) ) ? intval( $settings['image_height'] ) : '';
     220                $default_data['rollover_image']      = ( class_exists( 'FilterPlusPro' ) && ! empty( $settings['rollover_image'] ) ) ? 'yes' : 'no';
     221                $default_data['rollover_image_number'] = ( class_exists( 'FilterPlusPro' ) && isset( $settings['rollover_image_number'] ) ) ? max( 1, min( 5, absint( $settings['rollover_image_number'] ) ) ) : 1;
     222                $default_data['rollover_effect'] = ( class_exists( 'FilterPlusPro' ) && in_array( $settings['rollover_effect'] ?? 'fade', array( 'fade', 'zoom', 'none' ), true ) ) ? $settings['rollover_effect'] : 'fade';
     223                $default_data['gallery_slider']      = ( class_exists( 'FilterPlusPro' ) && ! empty( $settings['gallery_slider'] ) ) ? 'yes' : 'no';
     224                // Gallery Slider and Rollover Image are exclusive modes; prefer the slider if legacy settings enable both.
     225                if ( 'yes' === $default_data['gallery_slider'] ) {
     226                        $default_data['rollover_image'] = 'no';
     227                }
    212228                $default_data['hide_prod_rating']   = ! empty( $hide_prod_rating ) && ( $hide_prod_rating == true || $hide_prod_rating == 'yes' ) ?  'yes' : 'no';
    213229                $default_data['sorting']            = ! empty( $sorting ) && ( $sorting == true || $sorting == 'yes') ?  'yes' : 'no';
    … …  
    291307                        'image_width' => $image_width,
    292308                        'image_height' => $image_height,
     309                        'rollover_image' => $rollover_image,
     310                        'rollover_image_number' => $rollover_image_number,
     311                        'rollover_effect' => $rollover_effect,
     312                        'gallery_slider' => $gallery_slider,
    293313                        'hide_prod_rating' => $hide_prod_rating,
    294314                        'size_label' => $size_label,
    … …  
    677697    }
    678698
     699        /** Layout choices for sale and stock filters. Layouts 2 and 3 require Pro. */
     700        public static function sale_stock_template( $type = 'shortcode' ) {
     701                $pro = class_exists( 'FilterPlusPro' ) ? '' : ' (' . esc_html__( 'Pro', 'filter-plus' ) . ')';
     702                $options = array(
     703                        1 => esc_html__( 'Layout 1', 'filter-plus' ),
     704                        2 => esc_html__( 'Layout 2', 'filter-plus' ) . $pro,
     705                        3 => esc_html__( 'Layout 3', 'filter-plus' ) . $pro,
     706                );
     707                if ( 'elementor' === $type ) {
     708                        return array( 'template' => $options, 'template_disable' => class_exists( 'FilterPlusPro' ) ? '' : 1 );
     709                }
     710                return array( 'template' => $options, 'template_disable' => class_exists( 'FilterPlusPro' ) ? '' : 1 );
     711        }
     712
     713        /** Keep unsupported Pro layouts from being stored by the free plugin. */
     714        private function normalize_filter_layout( $layout ) {
     715                $layout = absint( $layout );
     716                if ( ! class_exists( 'FilterPlusPro' ) || ! in_array( $layout, array( 1, 2, 3 ), true ) ) {
     717                        return '1';
     718                }
     719                return (string) $layout;
     720        }
     721
     722        /** Locate the selected sale or stock filter layout with a safe free fallback. */
     723        public static function sale_stock_layout_url( $filter, $layout ) {
     724                if ( ! in_array( $filter, array( 'on-sale', 'stock' ), true ) ) {
     725                        return '';
     726                }
     727                $layout = class_exists( 'FilterPlusPro' ) ? absint( $layout ) : 1;
     728                if ( 1 === $layout || ! class_exists( 'FilterPlusPro' ) ) {
     729                        return \FilterPlus::locate_template( 'woo-filter/template-1/' . $filter . '.php' );
     730                }
     731                if ( 3 === $layout ) {
     732                        $path = \FilterPlusPro::locate_template( 'woo-filter/template-3/' . $filter . '.php' );
     733                } else {
     734                        $path = \FilterPlusPro::locate_template( 'woo-filter/parts/' . $filter . '.php' );
     735                }
     736                return file_exists( $path ) ? $path : \FilterPlusPro::locate_template( 'woo-filter/parts/' . $filter . '.php' );
     737        }
     738
    679739}
  • filter-plus/trunk/core/admin/filter-set.php

    r3781399 r3798363  
    22
    33<div id="filter-set-list-wrap">
    4   <div class="mt-2 content-header">
    5     <div class="title mr-1"><?php esc_html_e( 'Filter Sets', 'filter-plus' ); ?></div>
    6     <button type="button" class="button add-filter-set"><?php esc_html_e( 'Add New Filter Set', 'filter-plus' ); ?></button>
     4  <div class="filter-set-page-head">
     5    <div class="filter-set-page-copy">
     6      <div class="filter-set-title-row">
     7        <h1><?php esc_html_e( 'Filter Sets', 'filter-plus' ); ?></h1>
     8        <button type="button" class="button button-primary add-filter-set">
     9          <span class="filter-set-add-icon" aria-hidden="true">+</span>
     10          <?php esc_html_e( 'Add New Filter Set', 'filter-plus' ); ?>
     11        </button>
     12      </div>
     13      <p><?php esc_html_e( 'Save and reuse product filter configurations with a shortcode.', 'filter-plus' ); ?></p>
     14    </div>
    715  </div>
    816
    9   <section class="filter-sets-saved mt-2">
     17  <section class="filter-sets-saved">
    1018    <div class="filter-options-list">
    1119      <form method="POST">
  • filter-plus/trunk/core/admin/filter-sets/table.php

    r3672602 r3798363  
    9696        protected function column_shortcode( $item ) {
    9797                return '<div class="shortcode-cell">'
    98                         . '<input type="text" readonly class="full_input saved-shortcode" value="' . esc_attr( $item['shortcode'] ) . '" />'
    99                         . '<button type="button" class="button copy-filter-set">' . esc_html__( 'Copy', 'filter-plus' ) . '</button>'
     98                        . '<input type="text" readonly class="saved-shortcode" aria-label="' . esc_attr( sprintf( __( 'Shortcode for %s', 'filter-plus' ), $item['name'] ) ) . '" value="' . esc_attr( $item['shortcode'] ) . '">'
     99                        . '<button type="button" class="button copy-filter-set" title="' . esc_attr__( 'Copy shortcode', 'filter-plus' ) . '">' . esc_html__( 'Copy', 'filter-plus' ) . '</button>'
    100100                        . '</div>';
    101101        }
  • filter-plus/trunk/core/admin/settings/tab-content/short-codes.php

    r3783118 r3798363  
    331331                        'data_label' => 'stock_label','condition_class' => 'stock d-none' );
    332332                        filterplus_number_input_field($filterplus_args);
     333                        $filterplus_args = array('label'=>esc_html__("Stock Filter Layout:","filter-plus"),'id' => 'stock_template',
     334                        'data_label' => 'stock_template','options'=> DataFactory::sale_stock_template()['template'],'type'=>'named_template',
     335                        'condition_class' => 'stock d-none','template_disable' => DataFactory::sale_stock_template()['template_disable'] );
     336                        filterplus_select_field($filterplus_args);
    333337
    334338                        filterplus_field_group_end();
    … …  
    345349
    346350                        filterplus_number_input_field($filterplus_args);
     351                        $filterplus_args = array('label'=>esc_html__("On Sale Filter Layout:","filter-plus"),'id' => 'on_sale_template',
     352                        'data_label' => 'on_sale_template','options'=> DataFactory::sale_stock_template()['template'],'type'=>'named_template',
     353                        'condition_class' => 'on_sale d-none','template_disable' => DataFactory::sale_stock_template()['template_disable'] );
     354                        filterplus_select_field($filterplus_args);
    347355
    348356                        filterplus_field_group_end();
    … …  
    402410                        filterplus_number_input_field($filterplus_args);
    403411
     412                        filterplus_field_group_start( "woo_product_images", esc_html__( "Product Image Settings", "filter-plus" ), true, false );
     413
    404414                        // Product image size (Pro)
    405415                        $filterplus_args = array('label'=>esc_html__("Image Size:","filter-plus"),'id' => 'product_image_size',
    … …  
    420430                        'disable' => class_exists('FilterPlusPro') ? false : true);
    421431                        filterplus_number_input_field($filterplus_args);
     432
     433                        // Pro gallery image display options
     434                        ?>
     435                        <div class="single-block flp-image-mode-notice"><span class="dashicons dashicons-info-outline" aria-hidden="true"></span><p><?php esc_html_e("Choose one image mode: Rollover Image or Gallery Slider. They cannot be enabled at the same time.", "filter-plus"); ?></p></div>
     436                        <?php
     437                        $filterplus_args = array('label'=>esc_html__("Rollover Image:","filter-plus"),'id' => 'rollover_image',
     438                        'data_label' => 'rollover_image','disable' => ! class_exists('FilterPlusPro'));
     439                        filterplus_checkbox_field($filterplus_args);
     440                        $filterplus_args = array('label'=>esc_html__("Hover Gallery Image (1-5):","filter-plus"),'id' => 'rollover_image_number','data_label' => 'rollover_image_number','field_type' => 'number','placeholder' => '1','min' => 1,'max' => 5,'disable' => ! class_exists('FilterPlusPro'));
     441                        filterplus_number_input_field($filterplus_args);
     442                        $filterplus_args = array('label'=>esc_html__("Rollover Transition:","filter-plus"),'id' => 'rollover_effect','data_label' => 'rollover_effect','options' => array('fade' => 'Fade','zoom' => 'Fade + Zoom','none' => 'None'),'type' => 'random','selected' => 'fade','disable' => ! class_exists('FilterPlusPro'));
     443                        filterplus_select_field($filterplus_args);
     444                        $filterplus_args = array('label'=>esc_html__("Gallery Slider:","filter-plus"),'id' => 'gallery_slider',
     445                        'data_label' => 'gallery_slider','disable' => ! class_exists('FilterPlusPro'));
     446                        filterplus_checkbox_field($filterplus_args);
     447                        filterplus_field_group_end();
    422448
    423449                        // show Rating
  • filter-plus/trunk/core/frontend/search-filter/actions.php

    r3783118 r3798363  
    764764                                                        isset($post_data['hide_prod_desc']) ? $post_data['hide_prod_desc'] : 'yes',
    765765                                                        isset($post_data['hide_prod_rating']) ? $post_data['hide_prod_rating'] : 'yes',
    766                                                         isset($post_data['hide_prod_price']) ? $post_data['hide_prod_price'] : 'yes'
     766                                                        isset($post_data['hide_prod_price']) ? $post_data['hide_prod_price'] : 'yes',
     767                                                        isset($post_data['rollover_image']) && 'yes' === $post_data['rollover_image'] && ( ! isset($post_data['gallery_slider']) || 'yes' !== $post_data['gallery_slider'] ) ? 'yes' : 'no',
     768                                                        isset($post_data['rollover_image_number']) ? max(1, min(5, absint($post_data['rollover_image_number']))) : 1,
     769                                                        isset($post_data['rollover_effect']) ? sanitize_key($post_data['rollover_effect']) : 'fade',
     770                                                        isset($post_data['gallery_slider']) && 'yes' === $post_data['gallery_slider'] ? 'yes' : 'no'
    767771                                                );
    768772                                        } else {
    … …  
    783787                                                        isset($post_data['hide_prod_desc']) ? $post_data['hide_prod_desc'] : 'yes',
    784788                                                        isset($post_data['hide_prod_rating']) ? $post_data['hide_prod_rating'] : 'yes',
    785                                                         isset($post_data['hide_prod_price']) ? $post_data['hide_prod_price'] : 'yes'
     789                                                        isset($post_data['hide_prod_price']) ? $post_data['hide_prod_price'] : 'yes',
     790                                                        isset($post_data['rollover_image']) && 'yes' === $post_data['rollover_image'] && ( ! isset($post_data['gallery_slider']) || 'yes' !== $post_data['gallery_slider'] ) ? 'yes' : 'no',
     791                                                        isset($post_data['rollover_image_number']) ? max(1, min(5, absint($post_data['rollover_image_number']))) : 1,
     792                                                        isset($post_data['rollover_effect']) ? sanitize_key($post_data['rollover_effect']) : 'fade'
    786793                                                );
    787794                                        } else {
  • filter-plus/trunk/core/frontend/shortcodes.php

    r3796324 r3798363  
    9999                        data-image_width="<?php echo esc_attr($image_width)?>"
    100100                        data-image_height="<?php echo esc_attr($image_height)?>"
     101                        data-rollover_image="<?php echo esc_attr($rollover_image)?>"
     102                        data-rollover_image_number="<?php echo esc_attr($rollover_image_number)?>"
     103                        data-rollover_effect="<?php echo esc_attr($rollover_effect)?>"
     104                        data-gallery_slider="<?php echo esc_attr($gallery_slider)?>"
    101105                        data-hide_prod_title="<?php echo esc_attr($hide_prod_title)?>"
    102106                        data-hide_prod_desc="<?php echo esc_attr($hide_prod_desc)?>"
  • filter-plus/trunk/core/widgets/bricks/components/woo-filter.php

    r3783118 r3798363  
    551551                );
    552552
     553                $this->controls['stock_template'] = array(
     554                        'tab' => 'content',
     555                        'group' => 'filter_options',
     556                        'label' => esc_html__( 'Stock Filter Layout', 'filter-plus' ),
     557                        'type' => 'select',
     558                        'options' => DataFactory::sale_stock_template( 'elementor' )['template'],
     559                        'default' => '1',
     560                        'required' => array( 'stock', '=', true ),
     561                );
     562
    553563                // on sale
    554564
    … …  
    569579                        'type' => 'text',
    570580                        'default' => esc_html__( 'Place On Sale Label Here', 'filter-plus' ),
     581                        'required' => array( 'on_sale', '=', true ),
     582                );
     583
     584                $this->controls['on_sale_template'] = array(
     585                        'tab' => 'content',
     586                        'group' => 'filter_options',
     587                        'label' => esc_html__( 'On Sale Filter Layout', 'filter-plus' ),
     588                        'type' => 'select',
     589                        'options' => DataFactory::sale_stock_template( 'elementor' )['template'],
     590                        'default' => '1',
    571591                        'required' => array( 'on_sale', '=', true ),
    572592                );
    … …  
    651671                        'required' => array( 'product_image_size', '=', 'custom' ),
    652672                );
     673        $this->controls['rollover_image'] = array( 'tab' => 'content', 'group' => 'filter-result', 'label' => esc_html__( 'Rollover Image', 'filter-plus' ) . ( class_exists( 'FilterPlusPro' ) ? '' : ' (Pro)' ), 'type' => 'checkbox', 'default' => false, 'disabled' => ! class_exists( 'FilterPlusPro' ), 'required' => array( 'gallery_slider', '=', false ), 'description' => class_exists( 'FilterPlusPro' ) ? esc_html__( 'Choose one image mode: Rollover Image or Gallery Slider. They cannot be enabled at the same time.', 'filter-plus' ) : esc_html__( 'Upgrade to Pro to use this feature.', 'filter-plus' ) );
     674        $this->controls['rollover_image_number'] = array( 'tab' => 'content', 'group' => 'filter-result', 'label' => esc_html__( 'Hover Gallery Image (1-5)', 'filter-plus' ) . ( class_exists( 'FilterPlusPro' ) ? '' : ' (Pro)' ), 'type' => 'number', 'min' => 1, 'max' => 5, 'default' => 1, 'disabled' => ! class_exists( 'FilterPlusPro' ), 'required' => array( 'rollover_image', '=', true ), 'description' => class_exists( 'FilterPlusPro' ) ? esc_html__( 'Select the gallery image shown on hover; the last available image is used when needed.', 'filter-plus' ) : esc_html__( 'Upgrade to Pro to use this feature.', 'filter-plus' ) );
     675        $this->controls['rollover_effect'] = array( 'tab' => 'content', 'group' => 'filter-result', 'label' => esc_html__( 'Rollover Transition', 'filter-plus' ) . ( class_exists( 'FilterPlusPro' ) ? '' : ' (Pro)' ), 'type' => 'select', 'options' => array( 'fade' => 'Fade', 'zoom' => 'Fade + Zoom', 'none' => 'None' ), 'default' => 'fade', 'disabled' => ! class_exists( 'FilterPlusPro' ), 'required' => array( 'rollover_image', '=', true ), 'description' => class_exists( 'FilterPlusPro' ) ? '' : esc_html__( 'Upgrade to Pro to use this feature.', 'filter-plus' ) );
     676        $this->controls['gallery_slider'] = array( 'tab' => 'content', 'group' => 'filter-result', 'label' => esc_html__( 'Gallery Slider', 'filter-plus' ) . ( class_exists( 'FilterPlusPro' ) ? '' : ' (Pro)' ), 'type' => 'checkbox', 'default' => false, 'disabled' => ! class_exists( 'FilterPlusPro' ), 'required' => array( 'rollover_image', '=', false ), 'description' => class_exists( 'FilterPlusPro' ) ? esc_html__( 'Choose one image mode: Rollover Image or Gallery Slider. They cannot be enabled at the same time.', 'filter-plus' ) : esc_html__( 'Upgrade to Pro to use this feature.', 'filter-plus' ) );
    653677                $this->controls['hide_prod_rating'] = array(
    654678                        'tab' => 'content',
  • filter-plus/trunk/core/widgets/elementor/woo-filter/woo-filter.php

    r3783118 r3798363  
    542542
    543543                $this->add_control(
     544                        'stock_template',
     545                        array(
     546                                'label' => esc_html__( 'Stock Filter Layout', 'filter-plus' ),
     547                                'type' => Controls_Manager::SELECT,
     548                                'default' => '1',
     549                                'options' => DataFactory::sale_stock_template( 'elementor' )['template'],
     550                                'condition' => array( 'stock' => 'yes' ),
     551                        )
     552                );
     553                $this->add_control(
    544554                        'stock_label',
    545555                        array(
    … …  
    563573                );
    564574
     575                $this->add_control(
     576                        'on_sale_template',
     577                        array(
     578                                'label' => esc_html__( 'On Sale Filter Layout', 'filter-plus' ),
     579                                'type' => Controls_Manager::SELECT,
     580                                'default' => '1',
     581                                'options' => DataFactory::sale_stock_template( 'elementor' )['template'],
     582                                'condition' => array( 'on_sale' => 'yes' ),
     583                        )
     584                );
    565585                $this->add_control(
    566586                        'on_sale_label',
    … …  
    617637                        )
    618638                );
     639        $this->add_control( 'rollover_image', array( 'label' => esc_html__( 'Rollover Image', 'filter-plus' ) . ( class_exists( 'FilterPlusPro' ) ? '' : ' (Pro)' ), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => '', 'disabled' => ! class_exists( 'FilterPlusPro' ), 'condition' => array( 'gallery_slider' => '' ), 'description' => class_exists( 'FilterPlusPro' ) ? esc_html__( 'Choose one image mode: Rollover Image or Gallery Slider. They cannot be enabled at the same time.', 'filter-plus' ) : esc_html__( 'Upgrade to Pro to use this feature.', 'filter-plus' ) ) );
     640        $this->add_control( 'rollover_image_number', array( 'label' => esc_html__( 'Hover Gallery Image (1-5)', 'filter-plus' ) . ( class_exists( 'FilterPlusPro' ) ? '' : ' (Pro)' ), 'type' => Controls_Manager::NUMBER, 'min' => 1, 'max' => 5, 'default' => 1, 'disabled' => ! class_exists( 'FilterPlusPro' ), 'condition' => array( 'rollover_image' => 'yes', 'gallery_slider' => '' ), 'description' => class_exists( 'FilterPlusPro' ) ? esc_html__( 'Choose the gallery image shown on hover; the last available image is used when needed.', 'filter-plus' ) : esc_html__( 'Upgrade to Pro to use this feature.', 'filter-plus' ) ) );
     641        $this->add_control( 'rollover_effect', array( 'label' => esc_html__( 'Rollover Transition', 'filter-plus' ) . ( class_exists( 'FilterPlusPro' ) ? '' : ' (Pro)' ), 'type' => Controls_Manager::SELECT, 'options' => array( 'fade' => 'Fade', 'zoom' => 'Fade + Zoom', 'none' => 'None' ), 'default' => 'fade', 'disabled' => ! class_exists( 'FilterPlusPro' ), 'condition' => array( 'rollover_image' => 'yes', 'gallery_slider' => '' ), 'description' => class_exists( 'FilterPlusPro' ) ? '' : esc_html__( 'Upgrade to Pro to use this feature.', 'filter-plus' ) ) );
     642        $this->add_control( 'gallery_slider', array( 'label' => esc_html__( 'Gallery Slider', 'filter-plus' ) . ( class_exists( 'FilterPlusPro' ) ? '' : ' (Pro)' ), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => '', 'disabled' => ! class_exists( 'FilterPlusPro' ), 'condition' => array( 'rollover_image' => '' ), 'description' => class_exists( 'FilterPlusPro' ) ? esc_html__( 'Choose one image mode: Rollover Image or Gallery Slider. They cannot be enabled at the same time.', 'filter-plus' ) : esc_html__( 'Upgrade to Pro to use this feature.', 'filter-plus' ) ) );
    619643                $this->add_control('hide_prod_title',
    620644                        array(
  • filter-plus/trunk/core/widgets/gutenburg-block/blocks/woo-filter.php

    r3783118 r3798363  
    164164                    'default' => ''
    165165                ),
     166                'stock_template' => array(
     167                    'type' => 'string',
     168                    'default' => '1'
     169                ),
    166170                'on_sale' => array(
    167171                    'type' => 'boolean',
    … …  
    171175                    'type' => 'string',
    172176                    'default' => ''
     177                ),
     178                'on_sale_template' => array(
     179                    'type' => 'string',
     180                    'default' => '1'
    173181                ),
    174182                'hide_prod_title' => array(
    … …  
    204212                    'default' => 0
    205213                ),
     214                'rollover_image' => array( 'type' => 'boolean', 'default' => false ),
     215                'rollover_image_number' => array( 'type' => 'number', 'default' => 1 ),
     216                'rollover_effect' => array( 'type' => 'string', 'default' => 'fade' ),
     217                'gallery_slider' => array( 'type' => 'boolean', 'default' => false ),
    206218                'hide_prod_rating' => array(
    207219                    'type' => 'boolean',
    … …  
    282294        'show_reviews', 'stock', 'on_sale', 'hide_prod_title', 'hide_prod_desc',
    283295        'hide_prod_price', 'hide_prod_add_cart', 'hide_prod_rating', 'sorting',
     296        'rollover_image', 'gallery_slider',
    284297        'product_categories', 'show_sale_badge', 'product_tags', 'apply_button_mode',
    285298        'show_brands', 'hide_empty_brand', 'brand_count'
  • filter-plus/trunk/core/widgets/gutenburg-block/init.php

    r3783118 r3798363  
    7979add_action( 'init', 'filterplus_block_assets', 99 );
    8080
     81// Add image display controls to the existing Woo filter block.
     82add_action( 'enqueue_block_editor_assets', function() {
     83    wp_enqueue_script(
     84        'filter-plus-gallery-image-controls',
     85        \FilterPlus::assets_url() . 'js/gallery-image-controls.js',
     86        array( 'wp-element', 'wp-components', 'wp-compose', 'wp-hooks', 'wp-block-editor', 'filter-plus-block-js' ),
     87        \FilterPlus::asset_version( 'js/gallery-image-controls.js' ),
     88        true
     89    );
     90} );
     91
    8192// Enqueue frontend styles in the block editor so previews match the frontend.
    8293add_action( 'enqueue_block_editor_assets', function() {
  • filter-plus/trunk/filter-plus.php

    r3796324 r3798363  
    55 * Plugin URI:        https://wpbens.com/filter-plus/
    66 * Description:       Advanced Product Filter plugin that enable filter anything features like filter by by Ratings, Tags, Price Range on website. It allows users to filter anything based on different taxonomies.
    7  * Version:           1.1.42
     7 * Version:           1.1.43
    88 * Requires at least: 5.8
    99 * Requires PHP:      7.4
  • filter-plus/trunk/readme.txt

    r3796324 r3798363  
    55Requires at least: 5.8
    66Tested up to: 7.0
    7 Stable tag: 1.1.42
     7Stable tag: 1.1.43
    88Requires PHP: 7.4
    99License: GPLv2 or later
    … …  
    204204
    205205== Changelog ==
     206
     207= 1.1.43 (November 12, 2026) =
     208* Tweak: Filter Sets list now uses a compact shortcode field with a full-value Copy action and a simpler page header.
     209* Tweak: Clarified the exclusive rollover and gallery slider image modes, and keep both switches enabled while turning the other mode off.
     210
    206211
    207212= 1.1.42 (November 11, 2026) =
  • filter-plus/trunk/templates/woo-filter/parts/filter-color.php

    r3570817 r3798363  
    2424                                                $filterplus_style = ( $color_template !== '3' ) ? 'style="background-color: ' . esc_attr( $filterplus_value->name ) . ';"' : '';
    2525                                                ?>
     26                                                        <div class="color-option">
    2627                                                        <div class="checkbox-item color-item <?php echo esc_attr( $filterplus_tooltip ); ?>" title="<?php echo esc_attr( $filterplus_value->name ); ?>"
    2728                                                                data-term_id="<?php echo esc_attr( $filterplus_value->term_id ); ?>"
    … …  
    4849                                                                <div class="meta-count"><?php echo '(' . intval( $filterplus_value->count ) . ')'; ?></div>
    4950                                                        <?php } ?>
     51                                                        </div>
    5052                                                <?php
    5153                                        }
  • filter-plus/trunk/templates/woo-filter/template-1/right-side/product-template.php

    r3779321 r3798363  
    99 */
    1010if (!function_exists('filterplus_render_grid_product')) {
    11 function filterplus_render_grid_product($product, $hide_prod_add_cart, $hide_prod_title, $hide_prod_desc, $hide_prod_rating, $hide_prod_price) {
     11function filterplus_render_grid_product($product, $hide_prod_add_cart, $hide_prod_title, $hide_prod_desc, $hide_prod_rating, $hide_prod_price, $rollover_image = 'no', $rollover_image_number = 1, $rollover_effect = 'fade') {
    1212        ?>
    1313        <div class="product-style product-style-<?php echo esc_attr($product['template']); ?>">
    … …  
    2222                                                $grid_image = wp_get_attachment_image(get_post_thumbnail_id($product['id']), $grid_image_size, false, array('style' => 'width:100%;height:100%;object-fit:cover;display:block;'));
    2323                                        }
    24                                         if (empty($grid_image)) {
    25                                                 echo wp_kses_post( preg_replace('/<img/', '<img style="width:100%;height:100%;object-fit:cover;display:block;"', $product['post_image']) );
    26                                         } else {
    27                                                 echo wp_kses_post( $grid_image );
    28                                         }
     24                    $fp_primary_markup = empty($grid_image)
     25                        ? wp_kses_post( preg_replace('/<img/', '<img style="width:100%;height:100%;object-fit:cover;display:block;"', $product['post_image']) )
     26                        : wp_kses_post( $grid_image );
     27                    $fp_gallery_product = class_exists('FilterPlusPro') && function_exists('wc_get_product') ? wc_get_product(absint($product['id'])) : false;
     28                    $fp_gallery_ids = $fp_gallery_product instanceof WC_Product ? $fp_gallery_product->get_gallery_image_ids() : array();
     29                    $fp_rollover_effect = in_array($rollover_effect, array('fade', 'zoom', 'none'), true) ? $rollover_effect : 'fade';
     30                    $fp_rollover_enabled = class_exists('FilterPlusPro') && 'yes' === $rollover_image && !empty($fp_gallery_ids);
     31                    if ($fp_rollover_enabled) {
     32                        $fp_gallery_index = min(max(1, absint($rollover_image_number)), count($fp_gallery_ids)) - 1;
     33                        $fp_hover_id = absint($fp_gallery_ids[$fp_gallery_index]);
     34                        $fp_image_attrs = array('class' => 'fp-rollover-secondary-image', 'style' => 'width:100%;height:100%;object-fit:cover;display:block;');
     35                        $fp_hover_markup = is_array($grid_image_size)
     36                            ? Helper::custom_sized_attachment_image($fp_hover_id, $grid_image_size[0], $grid_image_size[1], $fp_image_attrs)
     37                            : wp_get_attachment_image($fp_hover_id, $grid_image_size, false, $fp_image_attrs);
     38                        echo '<span class="fp-rollover-wrap fp-rollover-effect-' . esc_attr($fp_rollover_effect) . '"><span class="fp-rollover-primary">' . $fp_primary_markup . '</span><span class="fp-rollover-secondary">' . wp_kses_post($fp_hover_markup) . '</span></span>';
     39                    } else {
     40                        echo $fp_primary_markup;
     41                    }
    2942                                        ?>
    3043                                        <?php
  • filter-plus/trunk/templates/woo-filter/template-1/template-1.php

    r3783118 r3798363  
    8989                \FilterPlus\Base\SidebarSections::start( 'on_sale' );
    9090                if ( 'yes'== $on_sale ) {
    91                         include_once \FilterPlus::locate_template( "woo-filter/template-".$template."/on-sale.php" );
     91                        $_fp_sale_layout = \FilterPlus\Base\DataFactory::sale_stock_layout_url( 'on-sale', $on_sale_template ?? '1' );
     92                        if ( file_exists( $_fp_sale_layout ) ) {
     93                                include_once $_fp_sale_layout;
     94                        }
    9295                }
    9396                \FilterPlus\Base\SidebarSections::end();
    … …  
    9598                \FilterPlus\Base\SidebarSections::start( 'stock' );
    9699                if ( 'yes'== $stock ) {
    97                         include_once \FilterPlus::locate_template( "woo-filter/template-".$template."/stock.php" );
     100                        $_fp_stock_layout = \FilterPlus\Base\DataFactory::sale_stock_layout_url( 'stock', $stock_template ?? '1' );
     101                        if ( file_exists( $_fp_stock_layout ) ) {
     102                                include_once $_fp_stock_layout;
     103                        }
    98104                }
    99105                \FilterPlus\Base\SidebarSections::end();
  • filter-plus/trunk/templates/woo-filter/template-2/right-side/product-template.php

    r3779321 r3798363  
    88 * Grid template for products
    99 */
    10 function filterplus_render_grid_product($product, $hide_prod_add_cart, $hide_prod_title, $hide_prod_desc, $hide_prod_rating, $hide_prod_price) {
     10function filterplus_render_grid_product($product, $hide_prod_add_cart, $hide_prod_title, $hide_prod_desc, $hide_prod_rating, $hide_prod_price, $rollover_image = 'no', $rollover_image_number = 1, $rollover_effect = 'fade') {
    1111        ?>
    1212        <div class="product-style product-style-<?php echo intval($product['template']); ?>">
    … …  
    2222                                                        $grid_image = wp_get_attachment_image(get_post_thumbnail_id($product['id']), $grid_image_size, false, array('style' => 'width:100%;height:100%;object-fit:cover;display:block;'));
    2323                                                }
    24                                                 if (empty($grid_image)) {
    25                                                         echo wp_kses_post( preg_replace('/<img/', '<img style="width:100%;height:100%;object-fit:cover;display:block;"', $product['post_image']) );
    26                                                 } else {
    27                                                         echo wp_kses_post( $grid_image );
    28                                                 }
     24                    $fp_primary_markup = empty($grid_image)
     25                        ? wp_kses_post( preg_replace('/<img/', '<img style="width:100%;height:100%;object-fit:cover;display:block;"', $product['post_image']) )
     26                        : wp_kses_post( $grid_image );
     27                    $fp_gallery_product = class_exists('FilterPlusPro') && function_exists('wc_get_product') ? wc_get_product(absint($product['id'])) : false;
     28                    $fp_gallery_ids = $fp_gallery_product instanceof WC_Product ? $fp_gallery_product->get_gallery_image_ids() : array();
     29                    $fp_rollover_effect = in_array($rollover_effect, array('fade', 'zoom', 'none'), true) ? $rollover_effect : 'fade';
     30                    $fp_rollover_enabled = class_exists('FilterPlusPro') && 'yes' === $rollover_image && !empty($fp_gallery_ids);
     31                    if ($fp_rollover_enabled) {
     32                        $fp_gallery_index = min(max(1, absint($rollover_image_number)), count($fp_gallery_ids)) - 1;
     33                        $fp_hover_id = absint($fp_gallery_ids[$fp_gallery_index]);
     34                        $fp_image_attrs = array('class' => 'fp-rollover-secondary-image', 'style' => 'width:100%;height:100%;object-fit:cover;display:block;');
     35                        $fp_hover_markup = is_array($grid_image_size)
     36                            ? Helper::custom_sized_attachment_image($fp_hover_id, $grid_image_size[0], $grid_image_size[1], $fp_image_attrs)
     37                            : wp_get_attachment_image($fp_hover_id, $grid_image_size, false, $fp_image_attrs);
     38                        echo '<span class="fp-rollover-wrap fp-rollover-effect-' . esc_attr($fp_rollover_effect) . '"><span class="fp-rollover-primary">' . $fp_primary_markup . '</span><span class="fp-rollover-secondary">' . wp_kses_post($fp_hover_markup) . '</span></span>';
     39                    } else {
     40                        echo $fp_primary_markup;
     41                    }
    2942                                                ?>
    3043                                        <?php
  • filter-plus/trunk/templates/woo-filter/template-2/template-2.php

    r3783118 r3798363  
    6767                                \FilterPlus\Base\SidebarSections::start( 'reviews' );
    6868                                if ( 'yes'== $show_reviews && file_exists( $_fp_tpl ) ) {
     69                                        // The Pro rating template's review template 2 uses the shared header.
     70                                        $filterplus_label = ! empty( $review_label ) ? $review_label : esc_html__( 'Rating', 'filter-plus' );
    6971                                        include_once $_fp_tpl;
    7072                                }
    … …  
    105107                if ( class_exists( 'FilterPlusPro' ) ) {
    106108                        // on sale
    107                         $_fp_tpl = \FilterPlusPro::locate_template( "woo-filter/parts/on-sale.php" );
     109                        $_fp_tpl = \FilterPlus\Base\DataFactory::sale_stock_layout_url( 'on-sale', $on_sale_template ?? '1' );
    108110                        \FilterPlus\Base\SidebarSections::start( 'on_sale' );
    109111                        if ( 'yes'== $on_sale && file_exists( $_fp_tpl ) ) {
    … …  
    112114                        \FilterPlus\Base\SidebarSections::end();
    113115                        // stock
    114                         $_fp_tpl = \FilterPlusPro::locate_template( "woo-filter/parts/stock.php" );
     116                        $_fp_tpl = \FilterPlus\Base\DataFactory::sale_stock_layout_url( 'stock', $stock_template ?? '1' );
    115117                        \FilterPlus\Base\SidebarSections::start( 'stock' );
    116118                        if ( 'yes'== $stock && file_exists( $_fp_tpl ) ) {
Note: See TracChangeset for help on using the changeset viewer.