Plugin Directory

Changeset 3775162


Ignore:
Timestamp:
10/30/2026 12:00:06 PM (33 hours ago)
Author:
loopstates
Message:

Release 1.0.2

Location:
swiftsearch-for-algolia
Files:
55 added
13 edited

Legend:

Unmodified
Added
Removed
  • swiftsearch-for-algolia/trunk/CHANGELOG.md

    r3725773 r3775162  
    55The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
    66and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
     7
     8## [1.0.2] - 2026-10-30
     9
     10### Added
     11- **WooCommerce HPOS Compatibility**: Declared official compatibility with WooCommerce High-Performance Order Storage (`custom_order_tables`) and Cart/Checkout Blocks (`cart_checkout_blocks`).
     12- **Extensibility Hooks**: Added `swift_search_algolia_term_document`, `swift_search_algolia_default_post_types`, `swift_search_algolia_default_taxonomies`, and `swift_search_algolia_default_sort_options` filter hooks.
     13
     14### Enhanced
     15- **Administrative Query Hygiene**: Applied `'suppress_filters' => true` to all bulk indexing queries in WP-CLI, Background Indexer, and REST API controllers to ensure smooth database queries alongside multilingual plugins (Polylang, WPML) and custom query interceptors.
     16- **Centralized Safe Defaults**: Unified default post type, taxonomy, and replica sort definitions into `ConfigLoader` as a single source of truth with automatic WooCommerce detection.
     17- **Algolia Replica Quota Optimization**: Avoided generating unnecessary price-sorting replica indices on standard content sites without WooCommerce.
     18
     19### Fixed
     20- **Defensive Option Management**: Added defensive typing during connection testing to ensure settings are preserved safely without data loss.
    721
    822## [1.0.1] - 2026-09-25
  • swiftsearch-for-algolia/trunk/readme.txt

    r3725773 r3775162  
    33Tags: algolia, woocommerce search, instant search, autocomplete, facets
    44Requires at least: 5.8
    5 Tested up to: 7.1
    6 Stable tag: 1.0.1
     5Tested up to: 7.1.4
     6Stable tag: 1.0.2
    77Requires PHP: 7.4
    88License: GPLv2 or later
    … …  
    225225== Changelog ==
    226226
     227= 1.0.2 =
     228* Enhancement: Declared full compatibility with WooCommerce High-Performance Order Storage (HPOS) and cart/checkout blocks.
     229* Enhancement: Centralized default post types and taxonomies with WooCommerce detection and developer filter hooks.
     230* Enhancement: Isolated administrative batch indexing queries (`suppress_filters => true`) across WP-CLI, background workers, and REST endpoints for full compatibility with multilingual plugins (Polylang, WPML).
     231* Enhancement: Added `swift_search_algolia_term_document` filter hook for custom taxonomy term transformations.
     232* Optimization: Made sorting replica indices WooCommerce-aware to conserve Algolia index quotas on standard content sites.
     233* Fix: Ensured defensive option management during connection tests to preserve existing configuration.
     234
    227235= 1.0.1 =
    228236* Fix: Defer recurring cron event scheduling to the init action to prevent early translation loading notices in WordPress 6.7+.
  • swiftsearch-for-algolia/trunk/src/Admin/AdminController.php

    r3725773 r3775162  
    44use SwiftSearchAlgolia\Core\Gatekeeper;
    55use SwiftSearchAlgolia\Client\Client;
     6use SwiftSearchAlgolia\Engine\ConfigLoader;
    67
    78if (!defined('ABSPATH')) {
    … …  
    119120                'search_key'     => $settings['search_api_key'] ?? ($settings['search_key'] ?? ''),
    120121            ),
    121             'indexed_post_types'   => isset($settings['indexed_post_types']) ? $settings['indexed_post_types'] : array('product', 'post', 'page'),
    122             'indexed_taxonomies'   => isset($settings['indexed_taxonomies']) ? $settings['indexed_taxonomies'] : array('category', 'post_tag', 'product_cat'),
     122            'indexed_post_types'   => isset($settings['indexed_post_types']) ? $settings['indexed_post_types'] : ConfigLoader::get_default_post_types(),
     123            'indexed_taxonomies'   => isset($settings['indexed_taxonomies']) ? $settings['indexed_taxonomies'] : ConfigLoader::get_default_taxonomies(),
    123124            'indexed_users'        => isset($settings['indexed_users']) ? (bool) $settings['indexed_users'] : false,
    124125            'custom_fields'        => isset($settings['custom_fields']) ? $settings['custom_fields'] : array(),
  • swiftsearch-for-algolia/trunk/src/Api/RestController.php

    r3725773 r3775162  
    167167
    168168        $existing_settings = get_option('swift_search_algolia_settings', array());
     169        if (!is_array($existing_settings)) {
     170            $existing_settings = array();
     171        }
    169172        $config = array_merge($existing_settings, array(
    170173            'app_id'         => $app_id,
    … …  
    322325
    323326        if ($type === 'terms') {
    324             $taxonomies = isset($config['indexed_taxonomies']) ? $config['indexed_taxonomies'] : array('category', 'post_tag');
     327            $taxonomies = isset($config['indexed_taxonomies']) ? $config['indexed_taxonomies'] : ConfigLoader::get_default_taxonomies();
    325328
    326329            if (empty($taxonomies)) {
    … …  
    332335
    333336            $args = array(
    334                 'taxonomy'   => $taxonomies,
    335                 'hide_empty' => false,
    336                 'number'     => $per_page,
    337                 'offset'     => $offset,
    338                 'fields'     => 'ids',
     337                'taxonomy'         => $taxonomies,
     338                'hide_empty'       => false,
     339                'number'           => $per_page,
     340                'offset'           => $offset,
     341                'fields'           => 'ids',
     342                'suppress_filters' => true,
    339343            );
    340344
    … …  
    419423        } else {
    420424            // Posts (Default)
    421             $post_types = isset($config['indexed_post_types']) ? $config['indexed_post_types'] : array('post', 'page', 'product');
     425            $post_types = isset($config['indexed_post_types']) ? $config['indexed_post_types'] : ConfigLoader::get_default_post_types();
    422426
    423427            $args = array(
    424                 'post_type'      => $post_types,
    425                 'post_status'    => 'publish',
    426                 'posts_per_page' => $per_page,
    427                 'paged'          => $page,
    428                 'fields'         => 'ids',
    429                 'orderby'        => 'ID',
    430                 'order'          => 'ASC',
     428                'post_type'        => $post_types,
     429                'post_status'      => 'publish',
     430                'posts_per_page'   => $per_page,
     431                'paged'            => $page,
     432                'fields'           => 'ids',
     433                'orderby'          => 'ID',
     434                'order'            => 'ASC',
     435                'suppress_filters' => true,
    431436            );
    432437
    … …  
    853858
    854859        $args = array(
    855             'post_type'      => array('product', 'post', 'page'),
    856             'post_status'    => 'publish',
    857             's'              => $term,
    858             'posts_per_page' => 10,
     860            'post_type'        => ConfigLoader::get_default_post_types(),
     861            'post_status'      => 'publish',
     862            's'                => $term,
     863            'posts_per_page'   => 10,
     864            'suppress_filters' => true,
    859865        );
    860866
  • swiftsearch-for-algolia/trunk/src/CLI/IndexCommand.php

    r3725773 r3775162  
    5353        $config        = $config_loader->get_config();
    5454
    55         $post_types = isset($config['indexed_post_types']) ? (array) $config['indexed_post_types'] : array('product', 'post', 'page');
     55        $post_types = isset($config['indexed_post_types']) ? (array) $config['indexed_post_types'] : ConfigLoader::get_default_post_types();
    5656
    5757        WP_CLI::line('Querying post IDs to index...');
    … …  
    5959
    6060        $query_args = array(
    61             'post_type'      => $post_types,
    62             'post_status'    => 'publish',
    63             'fields'         => 'ids',
    64             'posts_per_page' => -1,
     61            'post_type'        => $post_types,
     62            'post_status'      => 'publish',
     63            'fields'           => 'ids',
     64            'posts_per_page'   => -1,
     65            'suppress_filters' => true,
    6566        );
    6667
  • swiftsearch-for-algolia/trunk/src/Engine/BackgroundIndexer.php

    r3725773 r3775162  
    5050
    5151        $args = array(
    52             'post_type' => 'any', // Or configured types
    53             'post_status' => 'publish',
    54             'posts_per_page' => self::BATCH_SIZE,
    55             'offset' => $offset,
    56             'fields' => 'ids',
    57             'orderby' => 'ID',
    58             'order' => 'ASC',
     52            'post_type'        => 'any', // Or configured types
     53            'post_status'      => 'publish',
     54            'posts_per_page'   => self::BATCH_SIZE,
     55            'offset'           => $offset,
     56            'fields'           => 'ids',
     57            'orderby'          => 'ID',
     58            'order'            => 'ASC',
     59            'suppress_filters' => true,
    5960        );
    6061
  • swiftsearch-for-algolia/trunk/src/Engine/ConfigLoader.php

    r3725773 r3775162  
    1414class ConfigLoader
    1515{
     16    /**
     17     * Centralized default post types.
     18     * Core WordPress defaults to ['post', 'page']. Adds 'product' only if WooCommerce is active.
     19     *
     20     * @return array
     21     */
     22    public static function get_default_post_types()
     23    {
     24        $defaults = array('post', 'page');
     25        if (class_exists('WooCommerce')) {
     26            $defaults[] = 'product';
     27        }
     28        return apply_filters('swift_search_algolia_default_post_types', $defaults);
     29    }
     30
     31    /**
     32     * Centralized default taxonomies.
     33     * Core WordPress defaults to ['category', 'post_tag']. Adds 'product_cat' only if WooCommerce is active.
     34     *
     35     * @return array
     36     */
     37    public static function get_default_taxonomies()
     38    {
     39        $defaults = array('category', 'post_tag');
     40        if (class_exists('WooCommerce')) {
     41            $defaults[] = 'product_cat';
     42        }
     43        return apply_filters('swift_search_algolia_default_taxonomies', $defaults);
     44    }
     45
     46    /**
     47     * Centralized default sort options.
     48     * Core WordPress defaults to ['date_desc']. Adds 'price_asc' and 'price_desc' only if WooCommerce is active.
     49     *
     50     * @return array
     51     */
     52    public static function get_default_sort_options()
     53    {
     54        $defaults = array('date_desc');
     55        if (class_exists('WooCommerce')) {
     56            $defaults = array('price_asc', 'price_desc', 'date_desc');
     57        }
     58        return apply_filters('swift_search_algolia_default_sort_options', $defaults);
     59    }
     60
    1661    /**
    1762     * Get the unified configuration.
    … …  
    3782            'enable_facets'       => true,
    3883            'show_algolia_badge'  => true,
    39             'indexed_post_types'  => array('product', 'post', 'page'),
    40             'indexed_taxonomies'  => array('category', 'post_tag', 'product_cat'),
    41             'sort_options'        => array('price_asc', 'price_desc', 'date_desc'),
     84            'indexed_post_types'  => self::get_default_post_types(),
     85            'indexed_taxonomies'  => self::get_default_taxonomies(),
     86            'sort_options'        => self::get_default_sort_options(),
    4287            'typo_tolerance'      => true,
    4388        );
  • swiftsearch-for-algolia/trunk/src/Engine/DocumentBuilder.php

    r3725773 r3775162  
    3737        // 1. Strict Whitelist Check
    3838        $settings      = get_option('swift_search_algolia_settings', array());
    39         $allowed_types = isset($settings['indexed_post_types']) ? (array) $settings['indexed_post_types'] : array('product', 'post', 'page');
     39        $allowed_types = isset($settings['indexed_post_types']) ? (array) $settings['indexed_post_types'] : ConfigLoader::get_default_post_types();
    4040
    4141        if (!in_array($post->post_type, $allowed_types)) {
  • swiftsearch-for-algolia/trunk/src/Engine/Indexer.php

    r3725773 r3775162  
    7979
    8080        // 2. Calculate Totals
    81         $post_types = isset($config['indexed_post_types']) ? (array) $config['indexed_post_types'] : array('product', 'post', 'page');
     81        $post_types = isset($config['indexed_post_types']) ? (array) $config['indexed_post_types'] : ConfigLoader::get_default_post_types();
    8282
    8383        $args = array(
    84             'post_type'      => $post_types,
    85             'post_status'    => 'publish',
    86             'fields'         => 'ids',
    87             'posts_per_page' => -1,
     84            'post_type'        => $post_types,
     85            'post_status'      => 'publish',
     86            'fields'           => 'ids',
     87            'posts_per_page'   => -1,
     88            'suppress_filters' => true,
    8889        );
    8990
    … …  
    122123    {
    123124        $config     = $this->config_loader->get_config();
    124         $post_types = isset($config['indexed_post_types']) ? (array) $config['indexed_post_types'] : array('product', 'post', 'page');
     125        $post_types = isset($config['indexed_post_types']) ? (array) $config['indexed_post_types'] : ConfigLoader::get_default_post_types();
    125126
    126127        $args = array(
    127             'post_type'      => $post_types,
    128             'post_status'    => 'publish',
    129             'fields'         => 'ids',
    130             'posts_per_page' => $limit,
    131             'offset'         => $offset,
    132             'orderby'        => 'ID',
    133             'order'          => 'ASC',
     128            'post_type'        => $post_types,
     129            'post_status'      => 'publish',
     130            'fields'           => 'ids',
     131            'posts_per_page'   => $limit,
     132            'offset'           => $offset,
     133            'orderby'          => 'ID',
     134            'order'            => 'ASC',
     135            'suppress_filters' => true,
    134136        );
    135137
    … …  
    458460
    459461        // 3. Configure replicas ranking
    460         $sort_options = $config['sort_options'] ?? array('price_asc', 'price_desc', 'date_desc');
     462        $sort_options = $config['sort_options'] ?? ConfigLoader::get_default_sort_options();
    461463        foreach ($sort_options as $sort_key) {
    462464            $replica_name     = Schema::get_replica_index_name($base_index, $sort_key);
    … …  
    486488
    487489        $config       = $this->config_loader->get_config();
    488         $sort_options = $config['sort_options'] ?? array('price_asc', 'price_desc', 'date_desc');
     490        $sort_options = $config['sort_options'] ?? ConfigLoader::get_default_sort_options();
    489491        foreach ($sort_options as $sort_key) {
    490492            $replica_name = Schema::get_replica_index_name($base_index, $sort_key);
  • swiftsearch-for-algolia/trunk/src/Engine/Schema.php

    r3725773 r3775162  
    112112        $sort_options = isset($config['sort_options']) && is_array($config['sort_options'])
    113113            ? $config['sort_options']
    114             : array('price_asc', 'price_desc', 'date_desc');
     114            : ConfigLoader::get_default_sort_options();
    115115
    116116        $replicas = array();
  • swiftsearch-for-algolia/trunk/src/Engine/TermIndexer.php

    r3725773 r3775162  
    4242        $allowed_taxonomies = isset($this->config['indexed_taxonomies'])
    4343            ? $this->config['indexed_taxonomies']
    44             : array('category', 'post_tag', 'product_cat');
     44            : ConfigLoader::get_default_taxonomies();
    4545
    4646        if (!in_array($term->taxonomy, $allowed_taxonomies)) {
    … …  
    5353        }
    5454
    55         return array(
     55        return apply_filters('swift_search_algolia_term_document', array(
    5656            'objectID' => 'term_' . $term->term_id,
    5757            'id'       => (string) $term->term_id,
    … …  
    6262            'count'    => (int) $term->count,
    6363            'url'      => (string) $url,
    64         );
     64        ), $term);
    6565    }
    6666}
  • swiftsearch-for-algolia/trunk/src/Frontend/SearchController.php

    r3725773 r3775162  
    44
    55use SwiftSearchAlgolia\Engine\Schema;
     6use SwiftSearchAlgolia\Engine\ConfigLoader;
    67use SwiftSearchAlgolia\Client\Client;
    78
    … …  
    114115                'replicas'           => $replicas,
    115116                'showAlgoliaBadge'   => isset($settings['show_algolia_badge']) ? (bool) $settings['show_algolia_badge'] : true,
    116                 'indexed_taxonomies' => isset($settings['indexed_taxonomies']) ? $settings['indexed_taxonomies'] : array(),
     117                'indexed_post_types' => isset($settings['indexed_post_types']) ? $settings['indexed_post_types'] : ConfigLoader::get_default_post_types(),
     118                'indexed_taxonomies' => isset($settings['indexed_taxonomies']) ? $settings['indexed_taxonomies'] : ConfigLoader::get_default_taxonomies(),
    117119                'indexed_users'      => isset($settings['indexed_users']) ? (bool) $settings['indexed_users'] : false,
    118120                'experience'         => isset($settings['experience']) ? $settings['experience'] : array(),
  • swiftsearch-for-algolia/trunk/swift-search-algolia.php

    r3725773 r3775162  
    44 * Plugin URI:  https://docs.loopstates.com/swiftsearch-for-algolia/
    55 * Description: Lightning-fast, intelligent search for WordPress & WooCommerce powered by Algolia. Features instant modal search, visual facets builder, field weighting, synonyms, visual merchandising & pinning, and local search analytics.
    6  * Version:           1.0.1
     6 * Version:           1.0.2
    77 * Requires at least: 5.8
    88 * Requires PHP:      7.4
    … …  
    2020
    2121// Define Constants
    22 define('SWIFT_SEARCH_ALGOLIA_VERSION', '1.0.1');
     22define('SWIFT_SEARCH_ALGOLIA_VERSION', '1.0.2');
    2323define('SWIFT_SEARCH_ALGOLIA_DB_VERSION', '1.0.0');
    2424define('SWIFT_SEARCH_ALGOLIA_FILE', __FILE__);
    … …  
    3737}
    3838
     39// Declare WooCommerce HPOS Compatibility
     40add_action('before_woocommerce_init', function () {
     41        if (class_exists(\Automattic\WooCommerce\Utilities\FeaturesUtil::class)) {
     42                \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('custom_order_tables', __FILE__, true);
     43                \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('cart_checkout_blocks', __FILE__, true);
     44        }
     45});
     46
    3947// Activation Hook
    4048register_activation_hook(__FILE__, array(\SwiftSearchAlgolia\Core\DB::class, 'install'));
Note: See TracChangeset for help on using the changeset viewer.