Super Speedy Imports changelog
Easy to use. Built for speed.
Latest version2.85
Released6 August 2026
Tested up toWordPress 7.0
Product page
What Super Speedy Imports does, what it costs and who it is for.
Knowledge base
Setup guides, how-tos and troubleshooting for Super Speedy Imports.
Discord support
Ask a question in the Super Speedy Imports channel and get an answer from Dave.
Downloads & licence
Grab the latest build or check your licence and renewal status.
2.856 August 2026
- Fixed larger variable-product imports failing at
Finalizing fix-attributeswith "Error: timeout" - The attribute filter table build now refreshes the database's optimizer statistics first, fixing multi-minute
Finalizing fix-attributeswaits on a brand-new or freshly restored store - Every stage's finalize now has the same timeout recovery as the stages themselves, so work that outruns the browser's request timeout is watched to completion and re-run automatically where safe
- The After Import "Attribute filter table" choice is now radio buttons, with the fast bulk rebuild selected by default
- Deleting an import's products no longer starts WooCommerce's background attribute-lookup rebuild, because the delete already removes those rows in bulk
- With the option set to WooCommerce's own rebuild, a rebuild already in progress when an import finishes is restarted so it covers the newly imported products
- "Leave the table alone" now also applies when deleting an import's products
- Fixed term images and other term data not reaching hierarchical terms that already existed on the site, such as the leaf of a
Clothing > Hoodiescategory path - A product attribute's type, such as a colour swatch, now survives exporting your taxonomies and importing them again
- The term data mapper offers
product_attribute_color, the swatch colour key the Variation Swatches plugins read, alongside the Super Speedy Filters one - The bundled product demos carry colour swatches on their colour terms and icons on their category, brand, colour and size terms, and the variable products demo has gained brands
- New
superspeedyimports_stage_finalizedaction for add-ons whose work depends on a stage's finalize results rather than its body
2.845 August 2026
- Fixed imports failing at setup with "specified key was too long; max key length is 1000 bytes" on hosts whose default storage engine is MyISAM
- Every table the plugin creates now specifies
ENGINE=InnoDB ROW_FORMAT=DYNAMIC, and an import stops with a clear message if the server hands back anything else - Preview and Run now tells you when your WordPress tables are still MyISAM, and gives you the SQL to convert every table in the database to InnoDB
- Imports on MyISAM tables now use a single worker, because MyISAM locks a whole table while writing and extra workers only queue behind each other
- The plugin now refuses to activate on a MySQL server with no InnoDB support, explaining why, instead of activating and then reporting missing tables
- Fixed "Failed to insert or find term" during load-csv on category paths longer than 500 characters, which also left the affected branch of the tree built twice
- Fixed simple products being left without a product type, which made them invisible to
wc_get_products()and anything built on it untilsave-postswas run - Imported products now carry WooCommerce's own default settings (tax status, virtual, downloadable, sold individually, backorders and the rest), so a product created by an import is complete without running the optional save-posts job
- Fixed an update run overwriting total sales, average rating and review count with zero, and clearing the virtual and downloadable flags, on products the CSV said nothing about
- A product whose feed supplies a download URL is now correctly marked downloadable
- Stock quantity and low-stock amount are now cleared on products that do not manage stock, matching WooCommerce, instead of leaving a quantity that reads as "zero in stock"
- Variation names now use only the attributes the parent product actually varies on, so a size that only the variation rows mention no longer appears in the name
- Fixed an update-only import replacing a variation's name with the raw name from the CSV instead of keeping the "Parent - Red, Small" form WooCommerce uses
- Fixed variable products being invisible to the shop's price filter and sorted wrongly under "sort by price", because the parent product was never given a price built from its variations
- Variable parents now get their price range rebuilt from their variations on every import, including on a prices-only run and after variations are deleted, so a daily price feed keeps the shop's price filter and price sorting correct
- Variations that are out of stock are now left out of the parent's price range when "Hide out of stock items from the catalog" is switched on, matching WooCommerce
- Fixed two strings in the InnoDB activation notice that could not be picked up for translation
- Moved the parallel worker engine into
functions/spawn-workers.phpso the wp.org Lite edition ships with no subprocess code at all
2.83.04 August 2026
- New After Import options group, listing the rebuild tasks that other plugins on your site need once an import has written to the database directly
- New WooCommerce's attribute filter table is now rebuilt in bulk during the import instead of by its own background process, which took over a day on a million products and left layered-nav filtering degraded until it finished
- Choose per import whether that table is rebuilt in bulk, left to WooCommerce's own rebuild, or left alone
- Third-party rebuild tools are never run inside the import process; they start as separate background tasks where the host allows it, and are otherwise reported with the exact command to run
- An unfinished third-party rebuild no longer affects whether your import succeeded, and the completion output names each outstanding task with its command
- Back In Stock Notifier restock notifications are now delivered by the import itself rather than relying on WP-Cron, so a site with cron disabled still sends them
- Fixed
wp ssi <id> save-postsleaving WooCommerce's attribute filter table empty - Add-ons can add their own after-import tasks with the
superspeedyimports_after_import_tasksfilter - Stock notifications are now sent in bounded batches by up to four parallel workers, so an import with a very large number of restocks no longer loads every pending notification into memory at once
- New
wp ssi deliver-events <id>command finishes any outstanding notification delivery, and is safe to run repeatedly or alongside itself - Fixed
save-postsand the post-save triggers passing the wrong arguments to WooCommerce'swoocommerce_update_producthook, which could fatal with plugins that listen to it - Stock notification delivery can be switched back to running in the background with the
superspeedyimports_change_event_deliver_inlinefilter, if you would rather imports finished without waiting for it - Tested up to WordPress 7.0
2.82.13 August 2026
- Updated the shared Super Speedy settings module: AI agents can check your licence and install other Super Speedy plugins over MCP, now also exposed on AI Engine's MCP endpoint when AI Engine is active
- New Check frequency setting - cap licence, update and changelog checks to once a day or once a week, and see when the licence was last checked
- Licence and changelog checks fail fast when superspeedyplugins.com cannot be reached, instead of hanging the settings page
- The newest installed copy of the shared Super Speedy settings code now runs site-wide, whichever plugin loads first - previously the alphabetically-first plugin's often-older copy won
2.82.03 August 2026
- Fixed simple-product imports not assigning the
product_typetaxonomy term, whichwc_get_products()based tools and WooCommerce's attribute-lookup regeneration rely on; existing catalogues are backfilled automatically on their next import - New Back In Stock Notifier for WooCommerce compatibility, on by default when that plugin is active, so products an import genuinely restores to stock notify their subscribers through the notifier's own checks and mail queue
- New a Follow-up tasks panel on the import complete screen shows how many products came back in stock, live progress as notifications hand over, a Run now button, and links to the notifier queue and background jobs
- New Import History shows the same follow-up counts for past runs
- New
wp ssi changesandwp ssi retry-eventsshow and drain the integration queue for a history or import - Only genuine out-of-stock to in-stock transitions notify, so blank or missing stock values in a CSV never count as a restock
- A restock reversed by a later import or edit before its notification goes out is superseded and never mailed
- The integration waits with an explanation while the notifier's own periodic third-party scanner or keep-subscribed setting is enabled
- Undo restores never trigger customer notifications
2.81.031 July 2026
- The CSV is now opened by the
load-csvstage rather than at the start of every run, groundwork for add-ons and templates that generate their own import file - A run that does not need the CSV, such as
--delete-all, no longer stops with "CSV file not found" - Worker segment row numbers and ID ranges are integers rather than floats
- Save Import now sits next to Preview & Run at the top of the Config tab instead of at the foot of the form
- The Config tab's run panel stays pinned to the top while you scroll, so Save Import and Preview & Run are always reachable
2.80.029 July 2026
- Every function, class, hook, option and AJAX action now uses the
superspeedyimports_prefix instead ofssi_, required by the WordPress.org plugin review - Your existing imports, settings and licence data migrate automatically the first time you open the admin or run an import, so no action is needed
- Custom code hooking the old
ssi_*filters and actions must be updated tosuperspeedyimports_*, for examplessi_filter_updatesis nowsuperspeedyimports_filter_updates - The Houzez add-on needs its matching update, or it will fail to activate
- Database table names and the
wp ssicommand are unchanged - Replaced the bundled select2 library with a built-in dropdown, so the plugin no longer ships any third-party JavaScript
- Table and column names in the
fix-attributesstage and the bulk insert are now bound throughwpdb::prepare()placeholders - Fixed the config import endpoint storing a configuration without sanitising it or applying the Lite edition restrictions
- Attribute order on imported products now follows the order the taxonomies appear in your import config, with terms inside one attribute ordered by name
- The demo data browser that downloads samples from GitHub, and lifting the PHP execution time limit, are now paid-edition only
2.79.025 July 2026
- Row counts in the GUI are now the real row count of your CSV (previous was estimate for performance reasons). The upload receipt, the "Row 1 of N" label on the CSV preview and the Rows line in the "Ready to import?" summary were all capped at 5,000, so a 100,000-row file was reported as 5,000 rows
- The count is taken by streaming the file and counting line breaks at the byte level rather than parsing every row, so it is about 10 times faster than the old capped count and uses about 1MB of memory whatever the file size. Line breaks inside quoted values are not counted as rows
- Updated super-speedy-settings (shared across all Super Speedy plugins): added a settings-version report to the licence-check and download requests for better licence and update-download debugging
2.78.023 July 2026
- Fixed saving an import in the admin HTML-encoded the taxonomy separator, turning
>into>. Hierarchical categories such asParent > Child > Grandchild(as in the demo catalogue'sCategoriescolumn) then failed to import: the terms were created but the finalize step matches the built hierarchy path against a literal>, so nothing matched, every term was left unresolved, and the run aborted with "Failed to import hierarchical terms". The config save ran every value throughwp_kses_postduring the wp.org compliance pass, which entity-encodes bare<,>and&. Config values are now sanitised without encoding those literal characters, so separators (and any source or template value containing them) round-trip intact while scripts are still stripped.
2.77.022 July 2026
- Added auto-mapping now works in the Lite editions too, not just Pro. The recognition engine was split out of the export file into
functions/import-recognition.phpso every edition can auto-configure an import from its CSV. - Improved auto-mapping is now instant on large files. It samples the first rows to detect column shapes rather than streaming the whole CSV; identity uniqueness and parent references are still validated when the import runs.
- Added product attributes are recognised from the data (short repeating values, and any
_Description/_Imagesibling columns) and offered as one-click accepts in the setup checklist. The attribute taxonomy is created when the import runs. - Added creating an import streams a live discovery list - each column and its destination prints as it is recognised, ending with a mapped/to confirm/unmatched summary. The popover stays up until the mapping form and CSV preview are fully rendered, so nothing loads in behind it.
- Improved selecting a CSV in the create dialog is instant. The receipt shows cheap facts only (rows, columns, type guess); all recognition happens once, after Create. Row counts on huge files are capped at 5,000 ("5,000+ rows") in both the receipt and the preview panel's row navigator instead of streaming the whole file.
- Fixed clicking Create before the CSV type detection had returned could run the auto-mapper against the wrong import type (posts instead of WooCommerce products), mapping only a handful of columns. The server now derives the import type itself via
ssi_suggest_template_for_csvunless the user explicitly chose one. - Fixed recognised-but-unregistered product attributes with
_Description/_Imagesibling columns now auto-map fully (attribute plus term data) instead of waiting in the accept list. - Fixed the CSV preview panel's mapped-column colouring no longer depends on load timing; it is recomputed once the mapping form has finished rendering.
- Fixed the Create Import button can no longer be double-submitted into an "import already exists" error.
- Fixed term-data columns (term descriptions, images) auto-mapped onto a taxonomy or attribute now show as mapped in the setup checklist instead of reading as unmapped.
- Fixed term data mapped onto a
pa_product attribute (image, description, swatch colour) was dropped on save; it now persists like taxonomy term data. - Fixed when a stage hit a hard error mid-run (for example a taxonomy term that could not be created), the buffered progress text was flushed ahead of the JSON error, so the browser runner reported an opaque "non-JSON response" instead of the real cause. The runner now discards buffered progress before the error and carries it in the response, so the actual error message is shown.
2.76.422 July 2026
- Fixed loading an import configuration (including Demo Data and freshly-mapped imports) failed with a "not valid JSON" error after the 2.76.2 wp.org compliance pass switched the AJAX handlers to
wp_send_json. The JavaScript now accepts both string and pre-parsed object responses.
2.76.322 July 2026
- Improved WordPress.org Plugin Check compliance - the runner's
stageandfilerequest parameters are unslashed and sanitised, and web callers can only name an alternate CSV inside the plugin's imports folder (WP-CLI keeps absolute paths). - Improved all debug logging (
error_log, backtraces, deprecation-warning suppression) moved to Pro-only files, so the Lite editions ship no development functions at all. Error detail in import logs is formatted withwp_json_encodeinstead ofprint_r. Lite user-facing error reporting is unchanged. - Improved the wp.org build now truncates the shipped readme changelog to the most recent releases (the full history stays in the repo) and refuses to build if any development function creeps back in.
2.76.222 July 2026
- Improved WordPress.org review compliance - inline admin scripts and styles moved to the enqueue API, all AJAX responses sent via wp_send_json, JSON config intake is unslashed and sanitised on arrival, AJAX action names and the import history classes are ssi_ prefixed, and a stray development SQL file no longer ships. No behaviour changes.
2.76.122 July 2026
- Improved WordPress.org Plugin Check compliance pass - file cleanup now goes through wp_delete_file, disabled form controls are rendered with the disabled() helper, and the import history, import issues and staging-table cleanup queries use prepared identifier placeholders. No behaviour changes.
2.76.021 July 2026
- New the auto-mapper now detects term data. Columns like Color_Image, Color_Description and Color_Hex alongside a mapped Color column are recognised (by name AND by their data) and mapped to the term's thumbnail image, term description and swatch colour. It also works backwards: an unrecognised column with term-data siblings, such as Pattern with Pattern_Image, is mapped as that product attribute.
- New when the External Images plugin is active, image columns are automatically mapped to its URL fields (external_image_url and gallery_urls) instead of the media library - products get their images served straight from the URLs and nothing is downloaded during the import.
- Improved variation attributes are now observed from your data rather than assumed. Only attributes whose values actually differ between a parent's variations (typically colour and size) are marked as variation attributes; material, pattern and the like stay as plain attributes.
- Improved the auto-mapper recognises more columns - manage stock, rating, review count and MPN - and the product type column is reported as driving the simple/variable detection instead of showing as unrecognised.
- New the auto-mapper understands the standard WooCommerce exporter CSV format. Punctuated headers ("Weight (lbs)", "In stock?"), the "Meta: key" convention, tax status/class, backorders, sold individually, sale price dates, purchase note, shipping class, download limits, external URL and pivoted attribute columns ("Attribute 1 name" + "Attribute 1 value(s)") all map automatically when the attribute is consistent, with clear explanations for anything that genuinely needs a human (per-row pivoted attributes, upsell/cross-sell references, source-site IDs).
- New the auto-mapper now understands Magento, Squarespace, Wix, PrestaShop, Etsy and BigCommerce export formats. Magento gets its category paths configured automatically ('/' separators, 'Default Category' root stripped) and its enabled/disabled flags translated; Squarespace and Wix variant groupings synthesise variable products the same way Shopify's Handle does, including Squarespace's space-separated image lists; PrestaShop's semicolon lists, tax-excluded prices and EAN13 map directly; Etsy's variation pairs and materials become attributes. Structural columns each platform carries (Magento's configurable_variations, BigCommerce's row-order variants, SKU reference lists, store-scoping flags) are explained in plain English rather than left unrecognised.
- New a raw Shopify product export now imports with zero manual mapping. The auto-mapper recognises the Handle grouping, switches on the variations-only import mode (one variable product synthesised per Handle, Options become the variation attributes) and translates Shopify statuses.
- New value transforms. When a column's meaning is clear but its values speak another tool's vocabulary - the WooCommerce exporter's 1/0/-1 publish flags, Shopify's active/archived statuses, TRUE/FALSE flags - the auto-mapper attaches a translation instead of refusing the column. Hand-written configs can use them too (additional_options.value_transforms), and the registry is filterable for custom transforms.
- New Shopify and WebToffee exports are understood too - Handle, Body (HTML), Vendor, Option1/2 Name+Value pivots, Variant columns with correct Compare At Price semantics (it is the regular price, Variant Price is the selling price), and the tax:/attribute:/meta: prefixed-header conventions. A Shopify file with no parent column gets a plain-English note explaining the Handle grouping.
2.75.021 July 2026
- New (Pro) import term metadata alongside your items. Each taxonomy row on the mapping screen gains a "+ Term data" control for mapping term descriptions, custom term meta and term images from CSV columns. Image URLs are detected automatically and sideloaded into the media library. In Lite the control is visible but locked.
- Improved Lite now shows the Beta features and Performance Options panels on the Settings tab greyed out with a PRO Only badge, instead of hiding them, so you can see what Pro adds. Their engine and saves remain Pro-only.
- Fixed clicking "+ New Import" with unsaved changes to the current import config now shows the Unsaved Changes popover instead of silently discarding the edits. Refreshing or leaving the page with unsaved changes now triggers the browser's leave confirmation too.
- Changed the Lite builds no longer ship the term metadata engine (
term-metadata.php,term-metadata-writer.php) or the unused undo helper files (undo-change-detection.php,undo-chunked-restore.php). - New bundled demo data "Variable products with term images" - 10 variable products with 90 colour/size variations, with images on the colour, size and category terms.
- New handle-slug-duplicates stage. Duplicate slugs for NEW items are resolved in their own stage (between match-existing and insert/update), gated so imports with no collisions skip the work entirely. On large sites the old approach scanned the whole posts table on every import; numbering is now also aware of which slugs the site actually occupies, fixing a rare collision.
- Changed duplicate unique identifiers now stop the import with clear instructions instead of quietly importing renamed copies. This covers both directions - two CSV rows sharing an identifier, and an identifier that matches more than one existing item on the site. Where a differing column can be found (e.g. variations sharing their parent SKU), the message suggests the composite identifier to use, such as {SKU} {Colour}.
- Improved the load-csv finalisation on large imports is much faster - all batch-table indexes are built in a single pass instead of nine - and every statement in it now records its own duration in import history.
- Improved post-import tasks (WooCommerce term recounts, cache clears, lookup table regeneration) now appear in import history as their own stage with per-task durations.
- Fixed a successful large import no longer shows "Import failed" when completion arrives via the recovery poll after a client timeout.
- Fixed exporting and re-importing taxonomies no longer accumulates duplicate WooCommerce attribute labels.
- Fixed the imports-list row icons (schedule, configure, history) now update the URL hash, so refreshing the page keeps the tab you were on.
- Fixed run-screen buttons keep proper padding when their labels wrap to two lines.
2.74.218 July 2026
- Updated super-speedy-settings to the latest version
2.74.018 July 2026
- New Undo is now a site-wide Beta setting (Settings > Beta features, off by default) rather than a per-import option. When it is on, imports snapshot their target post type first so the whole run can be reverted from the Imports tab or
wp ssi undo <id>. The Preview & Run popover gains a "Take snapshot" toggle (on by default) so you can skip the snapshot for a single run. It adds IO to every run, so test on a staging copy first and keep a backup. - New you can now delete an import from the Imports tab. The row actions are icons - delete, history, config and schedule - each with a tooltip. Deleting shows a confirmation popover that can also drop the import's staging tables and remove any header-compatible CSV files it no longer needs. CSV removal is opt-in and off by default, and each file lists how many other imports share it.
- Improved the mapping screen now loads an import even when its original CSV file has been moved or deleted. The CSV column headers are stored with the import - captured when it is created, on save, and before a shared CSV is deleted - so the source fields still populate from a header-compatible sibling, or from the stored headers alone.
- Fixed listing compatible CSV files no longer fatals on hosts using musl libc (Alpine, many Docker images). The
get_compatible_csvsandget_csv_filesfile listings usedGLOB_BRACE, a glibc-only flag, and now use a portable two-pass glob instead.
2.73.118 July 2026
- New the Setup checklist is now an opt-in Beta feature (Settings > Beta features), off by default. When enabled it sits above Import Fields on the mapping screen, styled to match it.
- Fixed dragging a column from the Setup checklist onto a field inserted
{undefined}instead of the column name - the checklist pills were missing their header data. - Improved Import Fields cards now use fixed-width columns with ellipsis, so the ignore button stays visible however long the column name or value.
- Improved the Import Fields hover now shows the full content of the currently-selected preview row (newlines and all, capped), rather than a fixed three-row sample.
2.73.017 July 2026
- Fixed re-importing trashed items now restores them from the trash. Deleting products - through the WordPress trash or the plugin's delete-all - and then re-running the import used to match the trashed items, update every field and report a clean run while the store stayed empty, because nothing set
post_statusback. Theupdate-postsstage now lifts matched posts out of the trash as part of the same update, so a re-import brings a trashed catalogue back. Verified at 500,000 rows. - Improved the
process-variable-productsstage is dramatically faster on large catalogues. A 500,000-row import could sit in this stage for 40 minutes or more; the columns its self-joins use are now indexed before the joins run. Applies to variable-product imports (Pro). - New after a run that moves items to the trash, the import shows how many of its items are in the Trash with a "Delete trashed items permanently" link, and the product count is split live versus trashed so a delete-to-trash run no longer looks like it did nothing. The permanent delete runs through the normal runner as a
process-deletespass rather than the WordPress trash screen, which is per-item and unusable at scale. A new--trashed-onlyflag does the same from WP CLI. - Fixed a long-running stage made of many quick statements is no longer misreported as a dead or timed-out run. The stage-status check now treats a heartbeat from the last 30 seconds as still running, so polling or re-opening a live import -
process-variable-productsin particular, now that its joins are indexed - shows "running" instead of falsely offering to recover it.
2.72.017 July 2026
- New email alerts. The Schedule tab now has an Email alerts panel with two checkboxes - an email after every import completes (browser, CLI or scheduled) with the run's counters and any row issues, and a daily summary at a time you choose listing every run from the last 24 hours, which also emails when nothing ran so a broken schedule cannot fail silently. You choose the address alerts go to (defaults to the site admin email). All editions.
- New
ssi_import_run_completeaction for developers - fires exactly once for every completed run on all three runners (browser, CLI and scheduled), passing the import id, the history row id and the run's summary counters. The panel also documents the existingssi_scheduled_import_completehook and links to a worked example in the knowledge base. - New (shipped quietly in 2.71, announced now): automatic column mapping for CSVs from anywhere - Shopify exports, supplier feeds, spreadsheets you made yourself. The auto-mapper reads your column names against a large alias list and then reads the first rows of actual data to work out what each column really is - prices, GTINs and EANs, stock statuses, image URLs, weights, slugs, category paths and their separators - and only maps a column when name and data agree. It also picks the best match key (SKU over slug over GTIN over title), detects whether your file contains variations and sets the parent linkage up, and reports everything it could not decide as suggestions you accept or dismiss on the mapping screen. Previously only CSVs exported by Super Speedy Imports itself were configured automatically. Pro feature.
- Changed the field mapping screen has been rebuilt. Every mapping is now one row - a drag handle, the destination field, an arrow, then the CSV columns as pills you can add, remove or drag onto - so the whole import reads top to bottom in one list. Typing in the source box searches your columns and never creates text. Anything more than plain columns (merge templates like
{title} by {brand}, the rich editor for Description, custom PHP) lives behind the row's cogwheel, which shows a blue dot when a row is more than pills. The mapping is saved in exactly the same shapes as before, so existing imports load, save and run unchanged. - Changed the mapping has two views of the same list. Ungrouped is the new default - one flat list you can reorder by dragging, with your order saved on the import. Group fields shows the identical rows under group headings (Main, Inventory, Taxonomies, Attributes, Images, Post Meta and so on), reorderable within their group. The old Advanced view is gone and Drag & Drop is now Grouped; imports reopen in whichever view you saved them in.
- New attributes, gallery images and ACF/SCF custom fields are now rows in the same list instead of separate panels. Attribute rows keep their Used for variations / Is visible / Is taxonomy checkboxes and separator underneath; Featured Image and each gallery image carry their alt text, title, caption and description underneath as label plus source. Type an attribute name and it is matched to a registered
pa_taxonomy where one exists, otherwise it is created as a custom attribute - no need to know about thepa_prefix. - New required fields are enforced. The match field (plus the parent linkage fields when your file structure needs them) and at least one field to import are marked REQUIRED, pinned to the top of the destination picker, and listed in the checklist. Preview and Run stay disabled until they are mapped, so an import that cannot do anything can no longer be started.
- New ghost suggestion rows. Columns the auto-mapper nearly matched appear as dashed rows ("Colour -> Product colour?") with Accept and Dismiss, so near misses are one click rather than a hunt.
- Changed the CSV Preview sidebar is now Import Fields - a wider column of chip cards, one line each: the column name and its first sample value, with the full name and first three rows on hover. A card fills green as soon as a mapping uses that column, so unmapped columns stand out, and each card can be ignored in place.
- Changed the set-up checklist is now a collapsed card under Import Fields with its progress on the header ("15 of 20 columns handled"), so it is there when you want it and out of the way when you don't. The match-key confirmation moved to the match-field selector, which is now the one place matching is chosen and reviewed.
- Changed the New Import dialog is down to what it needs: a name (filled in from your filename), a drop zone for your CSV, and the receipt. The import type is guessed from your file ("Looks like WooCommerce products") and the two behaviour questions moved to the Ready to import popover, where they were already editable. Import type, behaviour, separator and decimal point all sit behind a cog on the dialog, pre-filled by detection - nothing is asked, everything is correctable.
- New import from URL. Paste a link to a CSV and Super Speedy Imports downloads it server-side (with the same checks as an upload) and sets the import up from it. No size cap of ours - your server's PHP limits apply, same as an upload.
- Changed the WordPress image sizes to create moved into Additional Options, and the Images panel is gone now that featured and gallery images are rows in the list.
- Changed the configuration file (JSON) tools are always visible and are now just Export and Import - Import opens the file browser and applies the JSON you pick, instead of a separate Browse step.
- Changed changing a row's destination keeps the row where it is in your list instead of moving it to the bottom, and converts the row properly in both directions - move a mapping onto an attribute and its checkboxes appear, move it off and they go.
- Removed the technical-details toggle. The configuration JSON tools are simply always shown, file paths are on hover, and the WP CLI command moved to the Schedule tab.
- Changed the Scheduled tab is now Schedule, and shows the WP CLI command for the selected import plus a ready-made crontab line for the cadence you chose - so if you would rather run it from a real server cron than the built-in scheduler, the line is written for you.
- Improved the config screen is quicker. Closing a cogwheel now keeps its editor alive so reopening is instant, the PHP editor only loads when you click into it, the mapping list reuses rows instead of rebuilding them, and around 100 hidden dropdowns are no longer initialised behind the scenes. On a 60 column import on a mid-range laptop, loading an import went from about 1.0s to 0.7s, reopening the Description editor from 140ms to 22ms, and opening the PHP tab from 99ms to 16ms.
- Fixed the undo snapshot now runs on browser and scheduled imports. With Enable undo (BETA) on, only WP CLI runs were recording a snapshot, so undoing a GUI or scheduled run had nothing to restore.
- Fixed browser imports now honour the import mode. Choosing "Only update prices" (or any preset) and pressing Run Now ran the full pipeline anyway; the browser runner ignored the mode presets and the
ssi_filter_stages_to_runfilter that CLI runs used. Browser and scheduled runs now also apply the unique-identifier pre-run guards that were CLI-only. - New running the same import twice at once is refused across all three runners. WP CLI and scheduled runs now claim, heartbeat and release the same run slot the browser uses, and the scheduled tick lock is atomic, so a cron tick can no longer start a second copy of a run that is already going.
- Fixed "Only create new items" now links variations to parents that already exist. The preset was missing the parent and variation stages, so a top-up file of new variations imported them as unlinked simple products.
- Improved Preview first item now previews the whole first item including all of its variations, straight from the real pipeline, and publishes the variations under the draft parent so the preview shows real dropdowns and prices instead of "out of stock". If the first item already exists it says so plainly and links to it, rather than reporting a configuration error. Preview drafts are isolated from your real data and discarded automatically before the next real run.
- Fixed a race between browser workers could randomly fail four-worker runs by dropping and recreating the gallery images table underneath each other.
- Fixed WP CLI worker failures now abort the run instead of warning and carrying on with the remaining rows.
- Improved
enable_db_tuningnow applies per stage to scheduled runs (as it already did on the command line; deliberately never for browser runs). - Improved the imports lists, selectors and Export tab refresh in place after a demo-data load, a finished run or a beta-features save, instead of reloading the page and throwing away unsaved Config edits.
2.71.014 July 2026
- Changed Undo (BETA) has been rebuilt from the ground up as a per-table raw snapshot with an exact-ID restore, replacing the old export-then-reimport approach. Before an import runs it now dumps one file per table (posts, postmeta, term relationships, terms, term taxonomy, attribute definitions) at one consistent instant. Undo then deletes the post type's rows and loads the snapshot back with their original IDs, all inside a single database transaction, so it is byte-identical, keeps every ID and link intact, and either fully applies or does nothing. It is far faster than the old re-import, cannot mangle serialized data or emoji, and correctly rolls back categories, attributes and product images the import created. Still BETA - test in staging and keep a database backup.
- Changed the "Enable undo (BETA)" option is available again in Additional Options now that the new engine is in.
- Improved the completion screen now leads with the outcome: "Import complete - 20,000 products imported in 13.8s", large tiles for items created, updated, removed and rows with issues, and an import-details strip (import name, file, match key, duration, finished time). The stage table, velocity stats and raw debug output moved under a collapsed "Technical performance details" section. A run with row problems says "Import completed with N issues" in amber and skips the confetti.
- Improved a details-only run (prices, stock, categories) now reports how many products it actually updated instead of "0 posts updated". The engine counts the distinct items each run touched and the completion screen and import history carry it as
items_affected. - New rows with problems are now recorded individually and reported. Rows skipped for a blank unique identifier and rows dropped because another row uses the same identifier (previously dropped silently) appear on the completion screen as issue classes with counts, and a "Download error report" button gives a CSV of row number, column and reason for the latest run.
- Improved the failure screen leads with the plain-language error and a suggested next step; the full log and stack trace sit under a collapsed "Engine details" section. Mid-run fatals get the same calm treatment.
- Improved the progress screen headline now shows real rows ("5,177 of 16,713 rows - 31%") with plain stage names ("Reading your file", "Finding existing products"), a live error count chip, and an honest "keep this tab open" note. The Live Engine Console starts collapsed under "Engine details" and remembers if you open it.
- New a technical-details toggle (terminal icon in the top bar) reveals the WP CLI command, configuration JSON, full file paths, import IDs and the run screen's System Configuration panel. Off by default, remembered per browser, and nothing is removed from the page - support can always ask for it.
- Improved the identity section now asks "How should existing products be matched?" in plain words, states the consequence ("rows with the same SKU update the existing product"), and surfaces the blank-identifier Stop/Skip choice inline instead of burying it in Additional Options.
- New a "Ready to import?" review popover between Run Now and the run: file, row count, what the import will do in plain words, the match key, how many columns are mapped or ignored, warnings for important unmapped fields, and a red flag when delete-missing is on.
- New a set-up checklist in the Config sidebar turns unmapped columns into a triage list: progress bar ("15 of 20 columns handled"), a one-click confirm for the match key, one-click Accept for near-miss auto-map suggestions, a searchable "Map..." destination picker (including a new custom field), per-column Ignore with a bulk ignore, and jump links that scroll to the real control. Ignores persist in the config and the auto-mapper respects them everywhere it runs.
- New the New Import dialog asks the two behaviour questions up front: "What should this import do?" and "If an item is missing from your file..." (destructive choice flagged red), and shows an upload receipt after you pick a file: row count, column count and how many columns will be mapped automatically.
- Improved pointing an import at a different CSV now refreshes its auto-map report against the new file, so the set-up checklist describes the columns you actually have.
2.70.013 July 2026
- Security exported CSVs now neutralise spreadsheet formula injection (OWASP CSV injection). Any cell starting with
=,+,-,@, tab or carriage return is prefixed with an apostrophe so Excel, LibreOffice and Google Sheets treat it as text instead of running it as a formula. Applies to the Export tab download,wp ssi exportand the diagnostic exporter; plain numbers (like a -5 stock adjustment) and the undo snapshot are left untouched so restores stay byte-accurate. The importer strips the escape apostrophe again on load (the same convention Excel and the WooCommerce importer use), so an export from one site re-imports on another byte-identical. - Security image captions and descriptions coming from a CSV are now sanitised with
wp_kses_postbefore being written to the attachment. Previously a<script>tag in a feed cell was stored verbatim (admins haveunfiltered_html, so WordPress did not filter it) and could fire as stored XSS on any theme that renders attachment captions. - Security a batch of smaller hardening fixes from the security audit - an external/affiliate product's
_product_urlis now run throughesc_url_rawso ajavascript:value from a feed can't be stored verbatim; the CSV filename and per-stage metric values in Import History are now HTML-escaped before being rendered; the "products from this import" admin filter now casts the import ID withintvalinstead of accepting a raw string; the config-import JSON decode has a depth limit; a hard-error's full file-path stack trace is only included in the AJAX/REST response whenWP_DEBUGis on (still logged in full either way); and the taxonomy JSON upload now checksis_uploaded_file, caps the file size and limits JSON nesting depth. - New the Demo Data tab can download larger sample imports on demand from GitHub. Browse demo data from GitHub lists a 100,000-post demo, a 100,000 simple-product demo and a 500,000-row variable-product demo (Pro); picking one downloads its CSV and config, checksum-verifies them and sets the import up ready for Run Now. Each also carries direct-download links so you can set it up by hand on shared hosting where a large server-side download would time out. The small demos stay bundled in the plugin.
- New uploading or selecting a CSV that was made by the Export to CSV panel (or
wp ssi export) now configures the whole import automatically - post fields, postmeta, taxonomies with the right hierarchy separators, featured image and gallery with their alt/title/caption/description text, and variation parent linkage. Export products on one site, create a new import on another site, choose the file and everything is mapped for you, with a banner confirming the auto-configuration. Works from the CLI too:wp ssi create mysite product export.csvwith no config file. - Fixed undoing or re-importing an exported variable product no longer loses the "Used for variations" flag on its attributes. The config generated from a snapshot marked every attribute non-variable, so
fix-attributesrewrote_product_attributeswithis_variationoff. - Fixed undoing or re-importing an exported variable product no longer blanks the variations' attribute selections (the "Any colour / Any size" symptom). Flat taxonomies such as
pa_*attributes were being routed down the hierarchical import path, soprocess-variable-productscould not rebuild theattribute_*selector postmeta. - Fixed re-importing an exported catalogue no longer doubles variation titles ("Shirt - Red, Small - Red, Small"). The attribute engine now leaves a title alone when it already ends with that variation's attribute names.
- Changed Undo is now clearly marked as a BETA feature in the option, the Undo last run link and the confirmation dialog - test it in staging and do not rely on it until it is out of beta.
- New scheduled imports now recover from crashes the same way browser runs do. A run whose PHP process dies (host
max_execution_time, out-of-memory) is detected by the due scanner, diagnosed via the sameSHOW PROCESSLISTfingerprint + stage-status logic as browser recovery, and continued: finished-but-unrecorded stages advance, idempotent stages re-run,insert-postsresumes from its checkpoint. Two failures with no progress abort with the real error in the schedule's last-result; recurring schedules stay armed for their next occurrence. - New scheduled imports run at a chosen time. Once takes a date and time, hourly a minutes-past-the-hour, daily a time plus day-of-week checkboxes, weekly a day and time - all in server time, with the current server clock shown live in the tab. A precise cron wake-up fires the run at the chosen time rather than up to an hour late on the hourly scanner.
- Improved the Scheduled Imports tab has its own import selector (like the Config tab) instead of relying on the Config tab's selection, and drops the collapsible wrapper and heading.
- Improved when a stage dies server-side, the failure banner and log now show the actual PHP fatal (for example "Allowed memory size exhausted" with file and line) instead of a generic "died server-side" message. A shutdown handler records the fatal against the run's history row and the recovery poll reads it back.
- New browser imports now recover from bulk-stage timeouts instead of failing. If
insert-posts,update-postmeta,insert-postmeta,match-existing,upsert-relationshipsorprocess-variable-productsoutlives the request, the runner polls the database every 15 seconds until the SQL settles, then continues: a stage that finished server-side is detected and skipped, idempotent stages re-run safely, andinsert-postsresumes from immediately after its atomicINSERTwhen that committed - or retries it once if it rolled back. Every stage's statements are auto-stamped with anssi:{import}:{stage}comment, so in-flight work is identifiable in plainSHOW PROCESSLIST. - Fixed re-importing variable products no longer adds a duplicate
_default_attributespostmeta row per parent on every run. The stage now deletes-and-rewrites that key for the parents in the import (the same idiom as the variation-selector postmeta), so sites that accumulated duplicates from earlier versions self-heal on their next import. Values were never wrong - the old update path refreshed all copies - but postmeta bloated invisibly. - New a "DB Rows Processed" metric - the sum of inserted, updated and deleted rows on real WordPress tables across every stage (CSV staging excluded). Shown as a per-stage rows-per-second badge in the Run Now screen, a DB Rows figure and count breakdown on the completion screen, a DB Rows column in Import History (older runs show a dash), and a monthly total in the Imports tab stats. The existing Rows Processed remains and is labelled CSV Rows.
- Improved browser imports now batch
load-csvadaptively - each worker grows its rows-per-request while calls return quickly and backs off as they approach the PHP time limit, settling in a 20-25s band. On a 500,000-row CSV this cut theload-csvstage from around an hour to about a minute, since small fixed batches were dominated by HTTP round-trip overhead. - New the admin tabs are hash-routed -
#imports,#config,#scheduled,#history,#settingsopen that tab directly, refresh keeps your tab, and with no hash the new Imports tab is the landing view. The Imports tab also shows live stats panels: rows processed this month, average import velocity with a per-run sparkline, and the engine version. - Fixed clicking the X on the "Import failed" banner now closes the Run Now dialog.
- Improved the Imports tab's compatible-files count now includes the import's own CSV, so a healthy import always shows at least 1; zero only appears as the red "CSV missing" state. Actions are now Configure / Schedule / Run Now with a small Import History link underneath.
- New browser runs support alternative CSV files without re-pointing the import - choosing a compatible file via Change File sets a per-run override, shown in the WP CLI command as
--file=other.csv(the REST runner now honours afileparameter exactly like the CLI flag). The import's reference CSV is only permanently changed when recovering from a missing file. - Improved each row in the Taxonomies and Post Meta panels shows its X delete button in Drag & Drop mode (previously only visible in Advanced), and the Import History Reset button is now a small text link under Apply Filters.
- New an Imports tab lists every import as a card - post-type icon, ID and created date, compatible-CSV count, last-run performance and total runs - with View History, Schedule and Run Now buttons wired to the existing flows.
- New a "+ NEW IMPORT" button opens the Create New Import form in a popover (same blurred backdrop as the Run Now screen). It merges the old Create Import and Upload CSV panels - "Upload New" browses for a CSV and uploads it in one step, then selects it, so there's no separate Browse and Upload.
- Changed the admin screen is organised into tabs - Import configuration, Scheduled imports, Import History and Settings. Import History now has its own tab (loading when opened) and Performance Options moved into a Settings tab.
- New a Drag & Drop mapping mode for product imports, now the default view. The product-data fields are reorganised into a "Product Info" panel with vertical tabs in the standard WooCommerce order (General/Prices, Inventory, Shipping, Attributes & Taxonomies, Downloadable, External/Affiliate, Advanced), with Title/Description/Short description lifted into a Main section and Images, Taxonomies, Custom Fields and Post Meta as their own panels. Map a field by dragging a CSV column onto it, or type an Editor value mixing
{Column}tokens and literal text - custom product attributes, Featured Image and Gallery included. Switch back to the flat Advanced layout at any time; the chosen view is saved with the import. - New an "Export to CSV" panel in the right-hand sidebar exports any post type to a CSV you can download and re-import - full taxonomy paths and hierarchy, all post meta, image URLs and dates. Also on the command line as
wp ssi export <post_type>. - New scheduled imports. A "Scheduled imports" tab lets you set an import to run automatically on a cadence, in the background on a resumable, timeout-proof runner that records the same import history as a manual run. Chunkable stages (
load-csvand the image stages) run in bounded batches so a run survives a host'smax_execution_time; bulk-SQL stages run whole. - New a Pause button on the Run Now screen pauses an in-progress import and resumes it from where it left off.
- Improved importing a product attribute (
pa_*) that doesn't exist yet now creates it as a proper global WooCommerce attribute viawc_create_attribute, so it persists and appears under Products > Attributes. Previously the on-the-fly path only registered the taxonomy for the duration of the import, leaving orphaned terms. - New a "Need a taxonomy that isn't listed?" helper in the Taxonomies section generates a
register_taxonomysnippet to paste into your theme'sfunctions.php. Add it, save the import and refresh, and the custom taxonomy appears in the list to map against - so the taxonomy is owned by your own code, not this plugin. Points brands at WooCommerce's built-inproduct_brandwhere available. - Improved the
attach-gallery-imagesstage now runs in parallel across workers.
2.68.211 July 2026
- Updated super-speedy-settings refreshed the Super Speedy settings page with new plugin and service-panel icons (shared across all Super Speedy plugins).
2.68.110 July 2026
- Updated super-speedy-settings (shared across all Super Speedy plugins): re-enabled TLS certificate verification on the licence/update check, escaped all dynamic output in the admin licence table, and added a capability check to the licence recheck handler.
2.68.010 July 2026
- New an "Enable undo" option in Additional Import Options. When set, Super Speedy Imports snapshots the target post type before the import runs, so you can reverse that run in one click from the "Undo last run" link on the import summary (or with
wp ssi undo <id>). Products the import created are deleted and products it changed are reverted to the snapshot, categories and their hierarchy included. One snapshot is kept per import, so Undo always targets the most recent run. - New
wp ssi snapshot <id>,wp ssi undo <id>andwp ssi undo-list <id>commands to take, run and inspect undo points from the CLI. - Changed removed the last legacy in-process import runner (
runStages) and its two unused entry points. Browser (REST) and CLI imports now share one execution path, so they cannot drift apart.
2.67.09 July 2026
- New an "Editor" field-mapping method (in every edition) that builds a value from literal text plus
{Column Name}merge tokens, so you can concatenate several CSV columns and fixed text into one field with no PHP. Works for post fields, post meta and taxonomies; the description field uses a full TinyMCE editor with an "Insert field" button on the toolbar. - New the product
GTIN, UPC, EAN, or ISBNfield (_global_unique_id) can now be mapped, in the renamed Stock Management/Inventory section. - New a Shipping section (PRO) for mapping Weight, Length, Width, Height and Shipping Class. Shipping Class is written to the
product_shipping_classtaxonomy, creating new classes as needed. - Changed the Stock Management section is now "Stock Management/Inventory", with SKU moved into it and shown first.
- Fixed the destination hint under a mapping field now shows the correct target for computed fields - Shipping Class and the Featured/Catalog Visibility fields read
Taxonomy: ...instead of wrongly saying "Posts column". - Fixed switching a field's mapping method no longer leaves an expanded PHP editor stuck on screen.
2.66.08 July 2026
- New the Run Now screen has been redesigned. While an import runs you now see each stage with its own progress and worker activity, an overall percentage and elapsed timer, a system-configuration panel, live peak throughput, and a colour-coded live engine console.
- New when an import finishes, the popover transitions to a completion screen with a per-stage efficiency table (duration, peak memory, throughput), a velocity panel showing average throughput and a full count breakdown (posts created and updated, post meta, terms, relationships, taxonomies), auto-fix and integrity totals, an Export Summary download and a link to view the updated posts/products.
- New set Featured and Catalog Visibility on import - map a Featured column (1/yes) and a Catalog Visibility column (
visible,catalog,searchorhidden) in Publication Info. These combine with stock status into the product'sproduct_visibilityterms. Mapping theproduct_visibilitytaxonomy directly overrides them for the whole import. - Improved imported out-of-stock products now get WooCommerce's
outofstockcatalog-visibility term, improves performance and eliminates the need to run save-posts after run. - Fixed when the slug (post_name) is left unmapped, products sharing a title now get their
-2/-3slug suffixes in CSV row order every time, instead of an order that could vary between runs.
2.65.08 July 2026
- New a "Load sample imports" button in the right-hand panel sets up ready-to-run sample imports in one click - it registers the product taxonomies (categories, brands, colours), copies the sample CSV into your uploads folder, and creates the import configuration. Pro includes a 1000-product simple import and a comprehensive import; the free edition includes the simple import. Nothing is imported until you pick one and press Run Now.
- New once an import has been run, its summary shows a "Delete all products loaded by this import (x)" link, where x is the number that will be deleted. It moves every product that import created to the Trash (the same as the CLI
--delete-all), alongside the existing "View products affected" link. - Fixed re-running an import through the browser no longer strips the products' categories, tags and attributes. The browser (AJAX) importer now runs the exact same per-stage code as the CLI, so the two can no longer drift apart.
- Fixed the comprehensive (variable products) import no longer fails in the browser with an opaque "parsererror". Stage errors are now surfaced in the on-screen debug log so they can be diagnosed.
- Fixed the per-section "Show All" buttons now respond immediately after creating a new import, without needing a page refresh.
- Fixed browser (AJAX) imports now record the correct row count and run details in the import history - both the summary at the top of the page and the history list. Previously an AJAX run showed 0 rows (or "NA") while the same import run via CLI was correct.
- Changed after a browser import finishes, the import summary at the top of the page updates automatically (last run date, rows and total runs) instead of needing a page refresh.
- Changed the field mapping-method dropdown now reads "PHP" (or "PHP (PRO Only)" in the free edition) instead of the longer "PHP Function", which was overflowing the layout.
- Changed database queries that reference plugin tables by name now run through
$wpdb->prepare()using the%iidentifier placeholder, to satisfy the WordPress.org Plugin Check for the free edition. This raises the minimum WordPress version to 6.2, where%iwas introduced. - Fixed the sequence-helper table seed on activation now binds its row values through
$wpdb->prepare()rather than building the SQL string by hand.
2.64.08 July 2026
- New the automatic post-import maintenance now refreshes the whole WooCommerce storefront - it recounts terms (including product attributes), clears the product and shop transients, and regenerates the product and attribute lookup tables that drive shop sorting and layered-navigation filters. Previously only category and tag counts were updated. Runs for both CLI and browser (AJAX) imports.
- New in the free edition, the top-level "Super Speedy" menu now shows a plugins overview page instead of an empty screen.
2.63.07 July 2026
- New a free edition of Super Speedy Imports. Paid-only sections stay visible but are clearly marked "PRO Only" (with a link to upgrade) so you can see exactly what the Pro version adds.
- Fixed category and tag counts are now recounted automatically at the end of every import, for both CLI and browser (AJAX) runs. Previously they could show 0 until you ran a manual
wp term recount. - Fixed a runtime error in one of your custom PHP functions (for example, referencing a CSV column that does not exist) now stops the browser import with a clear on-screen error, instead of appearing to run but importing nothing.
- Fixed importing a saved configuration over an already-loaded import no longer duplicates every field.
- New an animated "Import Complete" confirmation at the end of a browser import, and pressing Escape now closes the progress dialog once the import has finished.
2.62.07 July 2026
- New the unique item identifier now has its own collapsible section with a preset dropdown and a live summary of what it matches on, so most users never need the field builder. Products default to
SKU, posts toPost title(withPost title + categoryalso offered), andCustomexpands the panel for combining fields by hand. The identifier section now shows for every template - previously it only appeared for WooCommerce. - Changed the Custom builder no longer lists every postmeta field. It offers a short whitelist (
_skuplus common GTIN keys) checked cheaply for existence, so it stays fast on large sites. Add any other key by hand. Extendable via thessi_uid_postmeta_whitelistfilter. - Changed Additional Options is now collapsed by default, to signal these settings are not usually needed.
- Fixed the Show All buttons now have a solid white background instead of appearing greyed/transparent.
2.61.03 July 2026
- Fixed a performance regression (introduced in the unreleased 2.59.0) that slowed large fresh imports. A 50,000-product fresh import that had been taking around 16 minutes now completes in around 30 seconds. Correctness and the 2.59.0 interrupted-import safety fix are unchanged.
2.60.03 July 2026
- New a free edition of Super Speedy Imports is now available on WordPress.org.
2.59.02 July 2026
- Fixed an import that was interrupted part-way through inserting new items at a specific stage (insert-posts) with specific interrupt causes (e.g. an out-of-memory kill, host timeout, or the process being stopped) could in theory, on the next run, create zombie posts.
2.58.027 June 2026
- New a Value mapping method, alongside CSV Field and PHP Function. Pick Value to set a constant for a field/postmeta/taxonomy on every row — no PHP needed. Selecting Value with an empty box clears that field. This also replaces the internal per-row function the importer used to stamp each item, so a normal field-based import no longer evaluates any PHP at all.
- Changed custom PHP function code is now isolated in a single file. If a malware scanner (e.g. Imunify) quarantines or empties that file, only custom functions are affected - normal field-based imports keep working with a clear message, instead of a core file being broken.
- Changed a runtime error inside one of your custom PHP functions now aborts the import and reports the error, instead of continuing with empty/incorrect data.
2.57.023 June 2026
- New the unique item identifier can now combine multiple fields - any mix of post fields (Title, Slug, GUID), postmeta keys (e.g. SKU), and taxonomies (e.g.
product_cat,pa_color). Items match when all chosen fields are equal. This solves the common "same SKU, different colour/size" case where a single SKU isn't unique. Matching runs against the data your catalogue already holds, so re-imports update existing items instead of duplicating them, even for products SSI didn't create. - New if a composite identifier can't tell two rows (or two existing items) apart, the import now aborts with a clear report listing the affected rows, instead of silently updating the wrong item.
- New when the identifier includes a taxonomy, import modes that skip taxonomy resolution ("Update prices/postmeta only", "Refresh images only") are disabled, since taxonomy matching needs the term-resolution stage to run.
- Changed the old PHP-function and raw-CSV-column identifiers have been removed - a value computed from the CSV row can't be matched against existing items, which was the root cause of duplicate-on-update. Choose post / postmeta / taxonomy fields instead.
- Note composite identifiers aren't yet supported for variable / synthesised-parent products - use a single SKU there.
2.5623 June 2026
- A mapped
post_name(product slug) is now imported verbatim instead of being overwritten with a de-duplicated slug derived from the title. - Fixed choosing a field as the unique item identifier now matches your existing items on that field's native postmeta key (e.g. SKU on
_sku) instead of SSI's private key. Previously, using your SKU field as the identifier failed to find products created outside SSI (manually, or by another importer), so a re-import duplicated every existing product instead of updating it. Existing imports are migrated automatically; no reconfiguration needed.
2.55.94 June 2026
- New products now get assigned every level of a category path, not just the deepest one. When a product is in
Men > T-Shirts, bothMenandT-Shirtsare attached (matching WP All Import), so parent category pages list the product, breadcrumbs show the full path, and layered-navigation filters include parent categories. A new "Assign every category level" option in Additional Options controls it. New imports default it ON; imports created before this release keep their previous leaf-only behaviour until you switch it on.
2.55.83 June 2026
- Fixed a duplicate-key crash during taxonomy import on large catalogues (50,000+ terms per taxonomy), where parallel workers racing to create the same shared term could abort the whole import. Term creation is now serialised and recovers safely if a term already exists. Relationship assignment stays fully parallel, and there is no meaningful speed cost (parallelism was buying almost nothing at this step).
2.55.72 June 2026
- Changed if your CSV lists the featured image in the gallery column too, it now stays in the gallery instead of being silently removed (WooCommerce allows the featured image and gallery to overlap, so that is your choice). This also removes a query that could hang the gallery stage for 20-30 minutes on catalogues where many products share the same image URLs.
2.55.62 June 2026
- Performance gallery image data is now written to the database in batches instead of one write per image, cutting a large chunk of time off the gallery stage on big catalogues (and removing a source of run-to-run variance). No change to what gets written.
- The image-upload stage now records download, image-processing, and thumbnail timings in the import history, so you can see whether a slow image import is network-bound or CPU-bound.
2.55.326 May 2026
- Performance gallery image attachment rewritten with bulk database writes instead of per-image round-trips, saving significant time on large galleries. Existing gallery entries you added manually are preserved.
- Performance the postmeta-update stage now warms the database cache up front, avoiding a slow cold-cache first update on large imports.
2.55.226 May 2026
- Fixed with the opt-in "Merge duplicate term slugs" policy, hierarchical terms whose slug had been auto-renamed to avoid a clash (e.g. a second
T-Shirtsunder a different parent) could fail to import. They now match by name as well as slug. - Performance reworked the hierarchical taxonomy update to use an indexed temporary table, speeding up large taxonomies and sidestepping some database-version optimiser quirks.
2.55.126 May 2026
- Improved diagnostics the postmeta-update stage now prints per-key progress (name, row count, elapsed time) so a slow individual update is visible instead of the stage appearing to hang, and failures to import hierarchical terms now report the likely cause (e.g. collation mismatch or an invisible character) rather than a raw row dump.
2.55.026 May 2026
- Performance image URL to attachment matching now uses a dedicated lookup table, giving fast constant-time lookups regardless of URL length (including long CDN-signed URLs that previously matched poorly).
- Fixed a gallery query that could hang for 20+ minutes on catalogues where many products share the same image URLs.
- A one-off migration builds the lookup table on the first import after upgrading. New
wp ssi resync-image-lookupcommand rebuilds it on demand after manual media-library edits or a backup restore. - Note for add-on / custom-template authors: stages that looked up an attachment by the old
original_image_urlpostmeta should now use thewp_ssi_image_lookuptable.
2.54.425 May 2026
- Performance CSVs where many products share the same image URL (placeholders, product-family hero shots, etc.) no longer re-download that image once per product. Only the first occurrence is fetched; the rest reuse the same attachment. A 50,000-product CSV with 5,000 unique images now does 5,000 downloads instead of 50,000.
- Performance image downloads now distribute evenly across parallel workers regardless of CSV ordering. Previously certain orderings could leave one worker doing all the work while the others idled.
- Combined, a large import with lots of repeated image URLs can drop from around 5 hours to 5-10 minutes.
- Note products sharing an image URL now share a single attachment and its metadata (alt / title / caption / description), which matches standard WordPress behaviour. Nothing changes for CSVs with unique image URLs.
2.54.325 May 2026
- New
ssi_allow_private_image_hostsfilter to opt into fetching images from private / loopback / LAN hosts. Default off (secure by default); useful for staging setups or an internal image server. Only the private-IP rejection is bypassable, and only for hosts you explicitly allow.
2.54.224 May 2026
- Critical fix:
--file=(import an alternate CSV) was ignored by parallel workers, so multi-worker imports loaded the original file instead. It is now applied correctly across all workers. - Critical fix:
--show-sqlbehaved incorrectly on multi-worker imports, where workers could execute writes the parent was only meant to print. It is now safe across all workers. - Improved ACF / SCF custom-field import support, including groups, repeaters and multi-value choice fields, plus a warning if a mapped ACF field has been deleted, renamed or changed type since you saved the import.
2.5424 May 2026
- New
ssi_stage_startingandssi_stage_endingaction hooks fire around every stage, so add-on plugins can extend any stage (current or future) without modifying core code. - New ACF / SCF custom-field import support (Phase 1), writing postmeta via bulk SQL for around 17 field types including text, number, date/time, select, checkbox, radio, true/false, WYSIWYG, link, group and repeater. Image, file, gallery, flexible-content and multi-value relational fields are not yet covered (handled separately or planned for a later phase).
- Changed the database schema upgrade check now also runs at the start of CLI / cron imports, so sites that auto-update without visiting wp-admin stay on the correct schema.
2.53.120 May 2026
- New a "Recheck Licenses" button on the Super Speedy Settings page to refresh licence status after a renewal or upgrade. It bypasses the licence cache, so a very recent renewal shows immediately rather than still appearing expired. Applies to every Super Speedy plugin.
2.5320 May 2026
- New an "Import mode" option restricts the import to a narrower set of stages without typing a CLI stage list. Presets: Full import (default), Only insert new items, Only update existing items, Update prices / postmeta only (cheapest path for daily price feeds), Re-sync taxonomies only, and Refresh images only. Saved per import; each preset's stage list is shown in its tooltip.
- A CLI stage list still overrides the saved preset, and
--delete-allstill takes precedence over everything. - Fixed a "Could not get WooCommerce product" error when running a preset that skips the insert stages.
2.5219 May 2026
- Fixed the "Import Types" dropdown on the Create New Import form was empty after an internal class rename. Templates register correctly again.
- Fixed after a WP Reset (or any wipe that drops the plugin's meta table), imports appeared with empty Additional Options. The plugin's tables now self-heal on the next admin page load.
2.5118 May 2026
- Fixed duplicate rows could build up in the internal taxonomy tables during large parallel imports (5-8x their expected size on an 868k-row import), massively slowing taxonomy relationship assignment. Deduplication now works correctly across all workers, for both flat and hierarchical taxonomies.
- Requires MariaDB 10.2+ / MySQL 5.7.6+ (both from 2016, already within the plugin's supported range). Applied automatically on the next import; no migration step needed.
2.5018 May 2026
- New
--show-sqlCLI debug mode prints the SQL a stage would run. Writes are print-only (never executed), so it is safe for read-only diagnostics on production data. This first release covers theupsert-relationshipsstage, with more stages to follow.
2.4915 May 2026
- New per-taxonomy progress output for the term-relationship stage, showing each taxonomy with its type, rows created / deleted, and elapsed time, so you can see which taxonomy is slow instead of just a single summary at the end. The same per-taxonomy timings are saved to the import history panel.
2.4815 May 2026
- New an opt-in "Optimise DB session settings for slow stages" option in Additional Options. It raises MySQL buffer sizes for the import's own database connection only (not globally, so web traffic is unaffected), giving a 10x-100x speedup on term-relationship assignment for very large imports. Default off to protect low-RAM hosts; recommended on for 100k+ row imports on 4GB+ RAM. Uses up to around 600MB during the tuned stage, released afterwards.
2.4715 May 2026
- Performance major speedup for term-relationship assignment on large imports (100,000+ rows). New indexes remove an unindexed join that, at around 868,000 rows, meant billions of row comparisons per taxonomy. Expected 100x-1000x faster on affected imports.
2.4614 May 2026
- Fixed the "Duplicate term-slug behaviour" option wasn't appearing in the admin UI.
- New (for template / add-on authors): support for plain-text additional options, and a way to pre-populate a default set of taxonomies so users don't have to add each one by hand.
2.4514 May 2026
- Internal test-suite improvements only; no change to plugin behaviour.
2.4414 May 2026
- Fixed an image listed both as a featured image and inside a multi-URL gallery value could be uploaded twice, creating a duplicate attachment. Each unique image URL is now uploaded once and reused.
2.4314 May 2026
- Fixed several internal steps relied on row order that could vary across parallel-worker runs, so values like duplicate-SKU slugs and synthesised parent titles / SKUs could drift between imports. They now follow the CSV row order, making re-imports stable.
2.4214 May 2026
- Fixed product slugs (post_name) that look like de-duplicated slugs (e.g.
dk-1512-005) could drift between re-imports, with the slug being renumbered each run. Re-imports are now stable and leave the slug alone.
2.4113 May 2026
- Fixed hierarchical taxonomy assignments (e.g.
product_cat) were dropped on every re-import once the terms already existed. Re-imports now keep the categories. - Security the CSV column-name check now accepts real-world headers like
Price (USD)orPrice/Caratwhile still blocking characters that could be unsafe.
2.4013 May 2026
- Security SSRF hardening for the remote-image downloader. Image URLs are restricted to http/https, addresses in private / loopback / cloud-metadata ranges are refused (so a CSV can't be used to reach internal services like
http://169.254.169.254/), redirects are limited, and each downloaded file is verified to be a real image before it is stored. The allowed image types are filterable viassi_allowed_downloaded_image_mimes. - Security when an alternate CSV path (
--file) doesn't exist, the path is no longer echoed back to web callers, where it could act as a file-existence oracle.
2.3913 May 2026
- Security added
current_user_can('manage_options')checks to the older AJAX handlers that previously only verified the nonce —ajax_new_import_handler,ajax_save_import_config_handler,ajax_import_config_handler,ajax_export_config_handler,ajax_get_csv_files,ajax_upload_csv_file, plus the taxonomy import/export AJAX handlers. Nonces verify request origin; the new capability checks make sure only an admin can actually call them, so a leaked nonce from another plugin's XSS no longer hands a low-privilege user the ability to create imports, overwrite configs, or upload files. - Security
?run_import=1&import_id=…GET URLs now require a CSRF nonce. Running an import has heavyweight side effects (DB writes, remote image fetches, optional delete-all), so the action is no longer triggerable by a hostile site embedding the URL in an<img>tag against a logged-in admin. Removed the dead#removedthis-devonlyJS block that was the only place those URLs ever got rendered. - Security the "Functions" PHP code editor now honours
DISALLOW_FILE_MODSandDISALLOW_FILE_EDIT. When either constant is true the save handler refuses to update thefunctionsblob (the existing value is preserved) so production hosts that disable file edits also lock down the eval surface. - Security CSV upload tightened — capability raised from
upload_files(Author) tomanage_options(Admin); extension and MIME validated viawp_check_filetype_and_extagainst a CSV / TXT whitelist; filename sanitized withsanitize_file_nameso a path like../../wp-config.phpcan't escape the imports dir. Plugin activation and every subsequent upload now drop a.htaccess(deny-all) plus an emptyindex.htmlinto the imports directory, so even if the server is misconfigured to execute PHP underwp-content/uploads/the imports dir is still non-executable / non-listable. - Security SQL injection hardening in the postmeta / relationships / variation stages. The strict
ssi_is_safe_identifier()helper is now called at every SQL site that interpolates a CSV-derived column name, meta_key, taxonomy, or unique_id_meta_key — not just at table-creation time.validate_column_name()itself switched from a permissive blocklist (which missed backslash, null byte, and%/_LIKE wildcards) to a strict allow-list ([A-Za-z_][A-Za-z0-9_ \-]*, max 64 chars). String-literal interpolations of those names were converted to$wpdb->prepare()with%splaceholders; the LIKE pattern ininsert-postmeta.phpadditionally goes throughwpdb->esc_like()so a meta_key containing%can't match unintended columns. Files touched:stages/core/insert-postmeta.php,update-postmeta.php,upsert-relationships.php,match-existing.php,insert-posts.php,stages/woocommerce/variable-products.php. - Security stripped
user:password(and the URL fragment) from image URLs before they hiterror_log. Supplier-feed CSVs sometimes carry credentialed URLs and shared-host PHP error logs can leak to other tenants. New helperredactUrlCredentials()onSSI_PostTemplate.
2.3813 May 2026
- Renamed the import-template classes to carry an
SSI_prefix so they no longer occupy generic global-namespace names that any theme or plugin might also want to declare.ImportTemplate→SSI_ImportTemplate,PostTemplate→SSI_PostTemplate,CustomPostTypeTemplate→SSI_CustomPostTypeTemplate,WooCommerceProductTemplate→SSI_WooCommerceProductTemplate. Thewp_ssi_imports.base_templatecolumn is unchanged — existing rows still carry the legacy strings (e.g.'PostTemplate') and a newssi_resolve_template_class()resolver rewrites them at read time, just beforenew $class($import). No DB migration, noclass_alias()(which would keep the old global names occupied and defeat the point of the rename). New imports created via the admin UI orwp ssi createsave the SSI-prefixed string directly because the template registry was updated to match. Thessi_template_js_filesandssi_template_css_filesfilters now pass the SSI-prefixed class name; any add-on that gates on the class name will need to match the new value. - Note for add-on authors external templates that extend
PostTemplatedirectly will need to rename theirextendsclause toSSI_PostTemplate. The legacy resolver only rewrites at instantiation; it doesn't help with inheritance.
2.3712 May 2026
- Fixed
wp ssi <id> --workers=1crashed with "Duplicate key name 'sss_tid'" during the load-csv stage. The 1-worker bypass leftsegment_fromnull, which sent load-csv.php down its historical "AJAX/REST/sequential" path — that path drops + recreates the batch table (losing the ssi_uid UNIQUE index that setupBatchTables had just made) and creates its own copies of the sss_tid / sss_post_id indexes, which then collide with the same indexes added by finalizeStage immediately afterwards. The bypass now sets segment_from / segment_to / byte_offset to pose as a single worker covering the whole CSV, so load-csv.php takes the worker code path (tables stay as setupBatchTables left them, inline finalization is skipped) and finalizeStage owns the post-load index creation. Multi-worker mode behaviour is unchanged. Other parallel stages (upload-remote-images, attach-existing-images, fix-attributes) do not have inline finalization that conflicts with finalizeStage, so their bypass behaviour stays as-is.
2.3612 May 2026
- Gallery image metadata UI is now per-row. Each gallery URL row carries its own four metadata sub-rows (alt text, title, caption, description) directly beneath it. Click "+ Add another image column" to add a fresh URL row complete with its own four metadata sub-rows — handy for CSVs that split each gallery image across separate columns. Pipe-separated single-column users still see one row of five fields and continue to work unchanged. Each metadata sub-row supports CSV Field OR PHP Function, matching every other field mapping in the GUI.
- Featured image metadata sub-fields now also expose the standard CSV Field / PHP Function method selector, so the user can compute alt / title / caption / description via a function instead of being forced to pick a raw CSV column.
- load-csv: when gallery metadata is supplied as multiple CSV columns (one per gallery URL row), positions are preserved verbatim — empty metadata slots are emitted as empty strings between pipes rather than being silently dropped, so the metadata stays aligned with the gallery URL list even when individual cells are blank.
2.359 May 2026
- Image metadata: optional alt / title / caption / description fields for both featured images and gallery images. Four new sub-rows appear under each parent media field in the admin GUI — pick a CSV column for each, leave blank to skip. Gallery metadata is pipe-separated and position-aligned with the gallery URL list (same
|or,separator the URLs use). Metadata is applied during upload-remote-images, attach-existing-images (for posts whose featured image already exists in the media library), and all three branches of attach-gallery-images (previously-imported, freshly-uploaded, and local-search). Existing attachment metadata is updated in place when the user provides new values, so re-running an import refreshes alt text / titles without having to delete the attachment first. Skipped (empty) fields leave existing values untouched. - Added 8 new batch-table columns (4 featured_image_*, 4 gallery_image_*) and 4 new columns on the gallery_images aux table (alt_text, title_text, caption, description). New helper
applyAttachmentMetadata()on PostTemplate handles the WP-side writes (wp_update_post for title/caption/description, update_post_meta for _wp_attachment_image_alt).
2.349 May 2026
- Added External / Affiliate product support for the WooCommerce template — new "External / Affiliate" subsection in the Product Data area with two fields: External URL (
_product_url) and Button Text (_button_text). Setting an External URL on any row automatically switches that product toproduct_type=externalso WooCommerce renders the external-link button instead of Add to Cart. Mirrors the existing Downloadable Products pattern; no extra stages, no extra SQL.
2.3330 April 2026
- Gallery Images now supports multiple CSV columns via a + button in the admin GUI — no PHP function needed when image URLs are split across several CSV fields. Single-column configs save unchanged; multi-column configs save as an array. load-csv collapses everything to a single pipe-separated string so attach-gallery-images stays a single code path.
- Per-taxonomy multi-value separator. New small input next to each taxonomy field accepts ; , or any character used between multiple terms (flat) or multiple hierarchy paths (hierarchical). Leave blank to keep the existing pipe-then-comma fallback so existing imports do not change behaviour.
- import-taxonomies CLI progress now shows a single rolling counter ("Adding missing terms: N") instead of per-row SSI_PROGRESS lines. No extra SQL — the counter just increments per actual insert.
- attach-gallery-images CLI progress is now a single rolling line ("Images Attached: X/Y (N%)") instead of one log line per image.
- Fixed Parent grouping field in the GUI was not repopulating from saved JSON on import reload. The schema key is now aligned with the input name everywhere, restoring the round-trip.
- Fixed parent synthesized rows now correctly grab terms from first child and aggregated terms where those are used in variations
2.3229 April 2026
- Added live X/Y progress reporting to five parallel stages: upload-remote-images, attach-existing-images, attach-gallery-images, fix-attributes, and import-taxonomies
- CLI displays stage progress in the same format as load-csv ("Upload Remote Images: 120/500 — 24%") by parsing SSI_PROGRESS lines emitted by worker subprocesses — no extra DB queries
- AJAX admin page shows per-worker progress bars and a stage-wide X/Y label driven by processed/segment_total values returned in each batch result — no polling endpoint needed
- Workers emit SSI_PROGRESS:X/Y to stdout; the CLI orchestrator accumulates worker stdout and parses it, replacing the previous approach that ignored worker output entirely
- Fixed fix-attributes multi-batch continuation — offset was not being passed back on subsequent AJAX batch calls
2.31.129 April 2026
- Stage plan is now driven by import post type rather requiring import id
- Stages are registered immediately after authorization, making them available to the GUI without needing to run an import
- Clear error message when no stages are available, with explanation to enter a valid license key
- Added filter for getMappings for use by add-ons
- Added multiple public methods to the abstract class for use by add-ons
2.323 April 2026
- Added end-to-end test suite for variable products covering all four import methods (parent+child rows, variations with grouping column, parents only, variations with existing parents) — one test per method under tests/woocommerce/variable-products/
- Fixed synthesised parent row causing unique-index conflict on
_ssi_unique_item_idin composite-UID mode — parent rows now write{group_key}|at INSERT time instead of being blanked and rewritten in a later UPDATE - Fixed composite-UID rewrite incorrectly re-concatenating synthesised parent rows (producing
{group}|{group}|) — the UPDATE now only targets variation rows - Fixed synthesised parent rows missing
post_type = 'product'— without itwc_get_product()couldn't resolve the parent, so variations failed to link on the first run - Fixed Method 4 (variations with parents already in DB) overwriting the existing parent's title and SKU with blanks — the placeholder batch row now pre-populates with the existing parent's current title / status / post_type / _sku so update-posts is a no-op for those columns
- Fixed parent matching in composite-UID mode (Method 2 with blank
Auto-created parent SKU) —WooCommerceProductTemplatenow setsunique_id_meta_keyto_ssi_unique_item_idso the parent lookup uses the composite key instead of_sku(which synthesised parents don't have) - Added
--regenerate <filter>flag to tests/run-tests.sh for rewriting expected-result baselines when plugin output changes legitimately - Added CSV normalisation in the test harness so diffs are stable across WP resets —
guid,post_parent, andmeta__default_attributescolumns are masked before comparison (post IDs drift between resets and were causing every test to spuriously "fail") - Added tests/README.md documenting the test harness (flags, directory layout,
data1.csv/correct-results1.csvincremental pattern, per-method manual verification guide) - Added knowledge-base article "Importing Variable Products" — covers CSV layout, settings, and re-run behaviour for each of the four methods
- Fixed stray character at top of tests/run-tests.sh and an incomplete
ONLYRESETvariable declaration that broke arg parsing
2.231 March 2026
- Fixed variation settings (Auto-Create Parent Products) not saving/reloading — typo in save handler checked wrong POST field; load handler passed field definitions instead of flat saved values to the UI
- Reorganised admin UI: Unique Item Identifier now renders at the top of the Product Data section; variation settings moved into the Variable Products subsection
- Added import file type radio selector (parent+child rows, variations with grouping column, parents only, variations with existing parents) — controls which variation settings are visible and is saved for use by the import runtime
- Additional options now support section/subsection properties, mirroring the field mapping pattern — templates can place options in specific UI sections by setting section and subsection in PHP
- Added field_with_method additional option type — renders CSV Field / PHP Function selector matching the standard field mapping layout; used for parent grouping, parent title and parent SKU fields
- Parent title and parent SKU fields now support PHP Function mode in addition to CSV Field
- Removed delete (X) button from template-defined fields rendered in Product Data sections
- Updated tooltips Unique Item Identifier now mentions "Typically SKU"; Parent Identifier Value now mentions "Typically parent_sku"
2.113 March 2026
- Added "Parent identifier field" option to Additional Options for WooCommerce variable product imports — parent lookup is no longer hardcoded to SKU; supports matching against any postmeta key, Post ID, or Post Title
- Updated "Parent SKU" field label to "Parent identifier value" to reflect that any identifier (not just SKU) can be used, including PHP functions
- Fixed default attributes CTE to use resolved post_parent linkage rather than hardcoded SKU join — default attributes now work correctly for all parent identifier configurations
- Parent linking SQL now prevents variation rows matching each other in the batch table (added IS NULL guard on parent_sku for batch-table join path)
2.013 March 2026
- Added CSV data quality validation inside load-csv stage: blank unique identifier values are now detected across the full CSV in a single pass and surfaced as a hard error with a per-row summary (up to 10 rows shown) before any WordPress data is written — prevents potential dirty data from bad import data
- Import is aborted immediately if the configured unique identifier column is missing from the CSV headers entirely
1.993 March 2026
- Updated import selector to use select2 to show more meta data about each import and allow imports to be searchable
- Updated meta data about import after import is selected including last run info and link to import history
- Added visuals to RUN NOW button from interface to show progress
- Added multiple workers to process from CLI or Ajax for stages which allow multiple workers
- Added custom attributes specific to products (non-taxonomy)
- Added fallback for default hierarchical taxonomy so that items will always have the taxonomy allocated.
- Added default language if Polylang installed and user does not select language taxonomy
1.9828 January 2026
- Added 'sections' for template data - e.g. 'products' section for product-specific data for woo template
- Fixed CSV Field/PHP Function toggle not hiding the Select2 dropdown when switching to PHP Function mode - was only hiding the original select element, not the Select2 container
- Added tooltips to fields to help users understand purpose of each field
- Fixed "View products affected by this import" link
- Added ability to choose unique identifier for each item rather than requiring SKU
1.9720 November 2025
- Fixed featured image extractor so that if it's passed a list of images it will use the first one (i.e. you can pass the gallery and featured images the same CSV field)
- Added individual metric timings as well as the overall stage timings - this will help highlight any potential performance issues that come up in future
- Added term_exists caching to import-taxonomies stage (reduced 194s to 98s for test file)
- Massive optimisation for the import-taxonomies stage with batched inserts (reduced 98s to 4s for test file)
- De-dup of post_names based on existing post_names + new ones (i.e. uses same technique as WP but through SQL)
1.9619 November 2025
- Further optimisation for local image searching to use post_name instead of post_title and no longer needs to use open-ended LIKE wildcard so it's FAST!
1.9519 November 2025
- Fixed bug in 'import config' handler where it was not parsing the json
- Fixed taxonomies list so it only lists taxonomies from the import post type (e.g. not showing Categories on Products, only product_cat instead)
- Made CSV select searchable and made all select boxes same height
- Changed default options for new imports to 'delete items missing from previous import'
- Added new CLI paramter --delete-all - will delete all posts/products/cpts added by this import id (does not delete terms or images)
- Added 'thorough image search' option defaulted to off, to speed up local image search for Zippas & GetWaffled
1.9418 November 2025
- Removed early access auto-update prevention
- Added full namespacing for plugin update checker to prevent conflicts with 3rd party plugins
1.9310 November 2025
- Further hardening for collation checks and forced collation for virtual columns in CTEs
1.924 November 2025
- Re-added SSI_COLLATION override for those who have mixed or incorrect collation settings in their WP config compared to already created tables
- add the likes of this to your wp-config.php if you have collation issues: define('SSI_COLLATION', 'DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci');
1.9128 October 2025
- Fixed issue with custom DB connection (to avoid $wpdb caching overhead) where some servers could provide socket + host
1.906 August 2025
- Fixed bug that required a price to be present for new imports
1.8927 August 2025
- Rewrote the local image searcher code completely for easier maintenance and better performance with big files
- Fixed local image search for featured image (image must be in the database, i.e. uploaded somehow)
- Fixed local image search for galleries
- Fixed issue with variable products - was incorrectly marking parent as variation
- Improved variable product hardiness - if you incorrectly set parent_sku on the parent in your data, we will figure it out now
1.8820 August 2025
- Fixed product_type handler so that if users add a product_type taxonomy themselves then that takes precedent (except for variations)
- Fixed term importer so that e.g. A > B > A is allowed without being considered circular (2nd A should have a different slug)
- Fixed process-variable-products stage so that product_type is only applied to the parent product, not to variations
- Fixed issue with duplicate SKUs for child products - duplicate SKUs will now be uniquified
1.875 August 2025
- Upgraded terms table so source terms value can be 1000 characters long
- Added actions ssi_before_import_stages and ssi_after_import_stages
- Added visuals for Stock control in WooCommerce template
1.8625 June 2025
- Fixed new automatic stock code so that it will insert/update to postmeta if fields are auto calculated
- Fixed issue with updating postmeta where existing postmeta value was null
1.8524 June 2025
- Fixed handling of 4 byte unicode characters coming from Windows CSV files, it now handles 1-4 byte characters from any platform
- Added automatic handling for WooCommerce stock so you only need to set the _stock field (you can still overrule the automated calc by adding postmeta for any of _manage_stock,_stock_status,_backorders,_low_stock_amount)
1.8421 June 2025
- Upgraded load-csv again to lower RAM consumption further while handling special characters
1.8321 June 2025
- Re-added previous load-csv ram-optimisation. Fixed now so it handles 4-byte characters like emoticons etc.
1.8220 June 2025
- Upgraded keep-sold SQL to account for cancelled orders, pending orders etc, it will only count as sold actually sold and paid for items
- Keep-sold was also upgraded to work with both traditional and HPOS order processing
- Minor upgrades to CSS to improve visuals for those with long CSV header names (to avoid wrapping as much as possible on 1080p)
- Moved keep-sold & other product related deletes SQL code into the WooCommerce template using filters so it has been removed from the abstract class
- Fixed ocassional collation error at import-taxonomies stage
- Added new filter for posts and postmeta updates https://www.superspeedyplugins.com/kb/super-speedy-imports/advanced/customising-imports-using-sql-filters/
- Upgraded attach-gallery-images stage to handle comma separated images as well as pipe separated
- Added ability to use csv list of stages in the CLI, e.g. wp ssi 1 load-csv,match-existing,update-postmeta
- Consolidated image upload code and in the process fixed initial featured image upload. There were cases where it would fail on first run, then the image would appear on 2nd run.
- Refactored some code to tidy up duplicate code and remove unused code
- Fixed export config to include additional options! (e.g. deletes, continue-on-error)
- Fixed import history to include rows processed - Clicking the history will show more detail about each stage
- Merged some edits from @grambam
- scan uploads for local images (if you do not have // in the image URL, it will search the uploads folder)
- import history upgraded to format numeric values
- fixed running imports from JS (through SSI interface)
1.8111 June 2025
- Added mb_convert_encoding to post_excerpt (short description) too
- Added validated direct SQL for load-csv stage rather than using wpdb to eliminate memory leak - previously, after 800,000 rows of test file, it consumed 16GB! Now it's about 200MB.
1.8010 June 2025
- Added mb_convert_encoding to load-csv stage to handle cases where weird encoding can break $wpdb->insert, this on top of wp_kses_post
- Added full error logging and import abort if any CSV rows fail to import
1.795 June 2025
- Improved insert special character handling with improved db insert technique
- Added wp_kses_post to post_content and post_excerpt (let me know if this slows down your load-csv stage!)
1.783 June 2025
- Upgraded flat-term handler inside load-csv stage to fallback to comma-separated values instead of demanding | separated term names
- hierarchical taxonomies like product categories still require pipe separation, since categories are far more likely to have commas in their names
1.773 June 2025
- Reduced index length further
1.763 June 2025
- Added index length restriction for cases where term source values are too large for mysql indexes while retaining performance
1.752 June 2025
- Fixed bug in utils so that save-posts and sanitize-terms work correctly now
1.742 June 2025
- Upgraded stage detector so you can delete all post entries and it will automatically avoid running update-posts and insert-posts stages
- Added filter so other templates can adjust the stages executed
1.736 May 2025
- Added a bunch more tests focusing on permalinks
- Fixed bug in insert-posts stage where it now correctly inserts whatever has had a default mapping applied (e.g. post_name)
- Added post_name to the list of required fields (for the batch table, it includes defaults to figure out the permalink)
- Improved the interface code to load the template and check the config before it decides if fields (e.g. post_slug) should be hidden or shown
- only if you previously used post_slug in the past will post_slug appear - everyone should use post_name to set the slug
1.7217 April 2025
- Fixed bug with product_type warning which was affecting the load-csv stage.
1.7112 April 2025
- Fixed downloadable product support with new fields for download type, expiry, and limits - just add meta: _downloadable=yes and _downloadable_url to use
- Fixed attribute serialization to preserve original attribute order for update items tests
- Fixed product_type taxonomy - refactored so it uses other taxonomy stages
- Refactored taxonomy and postmeta processing loop to use new function to guarantee retrieval of all but exactly the columns required from the imports tables
- Fixed meta updates on 2nd runs and added tests for posts, taxonomy and postmeta updates to different values
1.7011 April 2025
- Improved auto collation handling - the value back from $wpdb->get_charset_collate is often not what is in use in the database, and for importing, being able to join the tables without adding a collation override is important
- Cleaned up a lot of code, mostly involving switching to using the class properties instead of duplicating them into local variables
- Fixed duplicate image upload issue if duplicates were inside the galleries
1.6910 April 2025
- Fixed bug with WooTemplate extending PostTemplate where Woo child was replacing rather than adding to postmeta to update
- Added automated test to confirm custom meta like above is loaded and available
1.688 April 2025
- Updated JS to show special fields under Post Fields section - these will probably move somewhere else soon, but for now they are back
1.678 April 2025
- Enhanced image handling:
- Fixed featured image import to correctly grab the first image if pipe separated
- Fixed broken code in image gallery upload, previously images were only importing correctly for galleries if you used delayed image import
- Increased timeout for image downloads from 100ms to 3000ms - if this slows down your import, use Delayed Image Import
- Fixed config export to prevent JSON double-encoding issues
- Added enhanced export functionality for testing:
- Added featured image URLs to exports
- Added gallery image URLs to exports
- Added new simple products test with images & gallery images
1.664 April 2025
- Added .gitattributes file to exclude tests folder from released zip file
1.652 April 2025
- Enhanced user interface for better usability:
- Redesigned file upload interface with improved visual feedback
- Auto open sections at relevant times, e.g. upload CSV opens the CREATE IMPORT section
- Added toggle to show/hide unused fields for cleaner interface, defaults to hide when reloading previously saved imports
- Improved taxonomies sorting in template selection (prioritizing Post and WooCommerce templates for new imports)
- Other CSS improvements in admin interface
- Added support for CSV files with full paths from CLI imports tool into the admin interface
- Enhanced testing infrastructure:
- Added verbose mode to test scripts with optional detailed output (--verbose flag)
- Added human-friendly descriptions for postmeta fields
1.641 April 2025
- Created comprehensive tools management system with standalone classes
- Added new CLI commands for better import/export workflow:
- Export: wp ssi export ./exports/products.csv product - Export products to CSV file
- Export with options: wp ssi export ./exports/posts.csv --exclude-dates - Export posts excluding date columns
- Export taxonomies: wp ssi export-taxonomies product ./taxonomy-export.json - Export product taxonomies
- Import taxonomies: wp ssi import-taxonomies ./taxonomy-export.json - Import taxonomies from file
- Load config: wp ssi load-config 10 ./import-config.json - Load config into import ID 10
- Save config: wp ssi save-config 10 ./export-config.json - Save config from import ID 10
- Create import: wp ssi create "New Import" ./products.csv WooProductTemplate - Create new import
- Enhanced export functionality with options to exclude date columns
- Improved SQL generation for more consistent and reliable exports
- Added SQL syntax error detection to prevent failed imports
- Improved automated testing infrastructure with better error reporting
- Added comprehensive test suite for regression prevention
1.6331 March 2025
- Added new CLI export command to help with automated testing: wp ssi export $post_type $file_name - no config, it just exports everything from wp_posts, wp_postmeta and all the terms for that post type
- Fixed big issue with fix-attributes - this was only working on 2nd runs, not sure how long for, tests added to prevent it ever happening again
- Fixed issue with hierarchical taxonomies - child leaf was not getting the correct term_taxonomy_id until UPDATE (2nd run)
- Added comprehensive tests to wipe, run, export, re-run, export, diff - more to come to guarantee no regressions and get us to Beta
1.6227 March 2025
- Fixed error handling so that if an actual SQL error occurs then it aborts properly
- Upgraded hard-error reporting so that it uses the :error from WP CLI (it shows in red in the console rather than white)
- Upgraded insert-postmeta stage so that it will skip missing meta columns from the import table which can happen, e.g. if _sale_price was not defined
- Upgraded valid-CSV detection so it works for exports from other places - instead of checking mime type, actually reads the first header row
1.6125 March 2025
- Fixed bug with deletes from refactoring job
1.6025 March 2025
- Added all remaining missing columns for config from wp_posts
- defaults will be used if they are missing (e.g. author will be the current user, date will be current date)
- any items NOT configured will guarantee those items will NOT be updated, but may be inserted as required (e.g. author, dates, other sensible defaults)
- Fixed last refactor job - it was working for posts, but not for products
- Added new CPT template in case anyone wants to experiment with post types other than post or product
- Found and fixed 1 place preventing simultaneous import execution (so long as it's different import ids)
- Found and fixed a bunch of other bugs that arose from the refactor job
- In particular, inserts always insert defaults now for any unspecified import whereas updates never will use defaults
1.5910 March 2025
- Minor refactoring
- Added Post template, tested, working
- Separated all product related stuff out into the WooCommerce-specific template
- Added import history to admin interface
- Added import details to admin interface
- Hardened checks for additional options
- Fixed issue with HTML special characters in term names (flat terms & hierarchical)
- Upgraded the sanitize term function to exactly mimic wp_insert_term - should fix any remaining broken term names
- Added new import-taxonomies stage specific to posts and specific to products
- Added fallback for terms failing to insert to grab the duplicate term_id and continue the import
- Added sanitize_terms to clean up the term mess I made
- Added 2 new tables to record ambiguous term names - e.g. if
Dave's stuffis a term name, that could be inserted either html encoded or not, and may not be discovered by the join - Added handler to update the term_taxonomy_id's from the ambiguous terms tables
- Added SSI_RUNNING_IMPORT definition in case anything wants to do or not do stuff when SSI is running
- Batched up the insert-posts command into 100,000 per batch and added performance metrics to trace slow (200 minutes) performance for 2.7 million row CSV file
- Renamed save_posts to save-posts, renamed sanitize_terms to sanitize-terms
- Added --perf option to save_posts to show what's taking time, which function, which plugin
1.584 March 2025
- Code refactoring of runtime
- Improved performance reporting summary
- Improved logging
- Fixed issue with attributes to ensure it only updates attributes mentioned in the import
- Improved resilience of save_posts for the Woo Product template, now uses wc_get_product and $product->save etc
- Added extra output to end of import to inform admin of how to run the builds for regular woocommerce attributes
- Fixed issue with attribute/taxonomy import - changed to use wc_create_attribute instead of standard wordpress taxonomy code for attributes
1.5721 February 2025
- Fixed force delete not working
- Fixed 'keep sold' items option not being recognised
- Added lots more logging everywhere
- Added import summary table at end of import
1.567 February 2025
- Fixed progress indicator on save_posts
1.555 February 2025
- Fixed 'permanently delete' items vs move to trash - thanks to @AdamDar for this one!
- Fixed issue with SQL to keep 'previously sold items'
1.544 February 2025
- Improved RAM usage for fix-attributes stage
- Added new execution URL which can be useful for profiling with Code Profiler Pro
1.5314 January 2025
- Further improvements to image download to ensure it works on as many hosts as possible
- Fixed fatal error in some paths for image downloads
1.5214 January 2025
- Increased image download timeout
- Fixed issue with source image URLs containing query parameters
1.5110 January 2025
- Fixed CSV upload ajax for brand new users so that the CSV file correctly appears in the dropdown after upload
- Fixed New Import creation for brand new imports, so that the import loads properly after creation
- Fixed deletes - it was referencing the old meta key name, updated to use ssi_updated and deletes are working like before
1.5024 December 2024
- Added continue-on-error functionality for CSV imports - if a row or term fails, it will be logged and the import will continue
- Fixed function editor initialization to properly use full code editor with PHP syntax highlighting
1.4923 December 2024
- Optimised load-csv stage by eliminating need for get_existing_terms at small cost of extra RAM consumption
- Small optimisation for the insert_flat_terms code by moving index creation on that table to the end of load-csv stage
- Optimised load-csv stage using more memory efficient way of reading the CSV file
1.4820 December 2024
- Added version number to output so I can be sure which version clients are using - some hosts set opcache really high so it can still be using old code on some hosts even if updated through wp-admin
1.4720 December 2024
- Fixed bug with hierarchies being too long - previous limit of 200 characters was lifted (no limit now other than 200 char limit for each term name in the hierarchy)
- However, this is in contradiction with WordPress - because they uniquify the slug, their uniquify function can create slugs > 200 characters which then fail
- There's a new filter added to wp_unique_term_slug to reduce the size of the slug and still ensure it's unique so our import can handle any number of X > Y > Z terms so long as each component term name is < 200 characters
1.4618 December 2024
- Fixed memory leak in fix-attributes stage - it was from a call to WordPress core function update_user_meta - even though I only asked to update user meta, it also caches the meta for that item
1.4513 December 2024
- Added PHP directive to display errors to CLI output for cases of some hosting environments having everything off
- Added better debug to failed function eval so you now find out exactly which column has a bad function defined for it
1.4412 December 2024
- Fixed issue with saving PHP functions - was working if the function was still in codemirror/expanded view, otherwise was saving nothing
1.4311 December 2024
- Fixed taxonomy matching bug introduced in 1.35
- Fixed save import broken if taxonomy with function (not csv mapping) was in the import
- Found and fixed a bug affecting terms with parents being mistakenly matched with parentless terms
- this in turn caused some terms to not be attempted to import and subsequent checks to fail because of these terms being missing
- Added CSV file name for configured template to template info at top of interface
- Added links to let admins see products affected by this import
- also added dropdown filter to edit.php?post_type=product so users can filter on there to view products last affected by X import
- Big speed boost for upsert-relationships stage - it's as fast as it should be again, e.g. 50,000 items 0.5s now compared to 5+ minutes previously
- Strengthed wp_posts update so it runs one update per column and checks which rows to set based on source being not null and not empty
- Added performance info for load-csv stage which is often the slowest stage
1.426 December 2024
- Proper fix for tab-separated files - previously I only fixed the import interface, now fixed the actual import run too to handle tab separated files properly
1.416 December 2024
- Fix for tab-separated files
1.4029 November 2024
- Fix to allow spaces in CSV file names...
1.3929 November 2024
- Added alert if trying to load an import to edit when the CSV file has been deleted - it's currently needed for reference
- Added early-access auto-update prevention mechanism - users have to very clearly and deliberately enable auto-updates to mess up their live site - if you want to enable auto updates on dev or staging, add define('SSI_ALLOW_AUTO_UPDATE', true); to your wp-config.php
- Added run now button to interface for small imports
1.3829 November 2024
- Improved default template to remove unused fields
- Hidden tax and postmeta entries which are meant to be hidden
- Added prevent creation of import with no name
- Added duplicate import name check
- Added new cli parameter list-files - e.g. wp ssi 20 list-files - will list files compatible with this import template
- Added new cli --file parameter - e.g. wp ssi 20 --file="alternative.csv" will use import 20 but against the alternative.csv file - this will barf if the headers are different
1.3727 November 2024
- Fix for new settings to clear the local transient cache when the license key is changed
- Added a new 'recheck now' button on the license key page for when users renew or upgrade
1.3621 November 2024
- Tidy up and standardisation of new license/settings page
1.3521 November 2024
- Speed boost for stage 1 - load-csv stage
- Fix for stage 2 - import-taxonomies - no more reporting error when no error occurred, and fixed bug with duplicate term names in different taxonomies
- Upgraded warning messages inside functions to Fatal Errors - this helps debug failing functions, just fix all the warnings so the code can run
1.3420 November 2024
- Fixed broken function calls - since I added the pretty textareas, the functions were not saving properly
- Updated the JS to use time() for admin so ugosprint definitely gets the latest JS
1.3319 November 2024
- Added _default_attributes hidden field to batch import table
- Use _default_attributes to store first variation from table selected per variable product
- Updates variable product parents efficiently to set the default variation using _default_attributes
- Fixed all slugs to be sanitized - for post_name and for attribute names when they are used as keys
1.3216 November 2024
- Fixed JS/CSS loading issue for certain versions of Scalability Pro (shared Settings file)
1.3113 November 2024
- Fixed issue with additional options (delete items missing from previous import) from appearing multiple times as you loaded each import
- Added code to hide the 'hidden' fields in posts
1.3012 November 2024
- Fixed various warnings
1.2912 November 2024
- Fixed bug where everything was being marked as variable product, even simple products
- Fixed new bug with postmeta _regular_price where it was checking the function rather than the stage table for whether it should upsert or not
1.2812 November 2024
- update-postmeta stage adjusted to increase performance
- Updated post-update and post-insert to not set the value if the source column is null
- Added post-slug field - by default, a sanitized post_title will be used for the post slug, but you can overrule this by setting a value for the post slug - if slug and post title are not set, the post_name will not be changed
- Added variation control into the taxonomy section
- Integrated variation control with previous hard-coded variations list
1.278 November 2024
- Reduced key size for hierarchical tables to acommodate 4-byte unicode collations
- Removed fallback to try to convert from wpallimport function - it was failing badly
1.268 November 2024
- Renamed stages to useful names
- Tidied up SQL code especially since no guarantee of execution order
- Fixed some warnings
1.258 November 2024
- Commented out the eval method for function calling in postmeta
1.248 November 2024
- Added variable product capability
- in dev, you need to configure your variation attributes with: define('SSI_HARD_CODED_VARIABLE_TAXONOMY_ARRAY', array('pa_size', 'pa_colour'));
1.237 November 2024
- Added new code to let templates add and alter additional options
- Added additional options section to end of import with save/load/conditional appearance
- Added 3 new delete options to let people configure how they want their deletes handled
1.224 November 2024
- Fixed bug with flat term import where import failed if term name was empty in csv
1.2122 October 2024
- Fixed hierarchical taxonomies so they are correctly set with parents in the database - also confirmed existing terms are being retrieved correctly
- Also upgraded multi-term inserts, so if you have e.g. Cat1|Cat2|Cat3 > Cat4 then the item will be allocated to Cat 1, Cat 2 and Cat 4 correctly
- Fixed term inserts and checks for terms when you have the likes of: Salt & Pepper > Salt|Salt & Pepper > Pepper, so it correctly assigns the parent for the 2nd term Pepper to be Salt & Pepper
- Updated code to use the decimal separator correctly for prices
1.203 October 2024
- Fixed bug in wp ssi 3 save_posts command - it was just re-running all instead of doing the save_posts
1.1930 September 2024
- Fixed bug for terms with html encodable text in their name (typically &)
- Improved speed by fixing collation issue
- rather than trusting default collations in WP, i pull the collation from wp_terms since this is what ultimately is joined to on text columns
- Hard errors now correctly stop the script and output the error in RED
- Vastly improved debug and error output to help trace problems more quickly
1.1825 September 2024
- Added gallery image support
- Added checks at start to ensure you have an SKU (for now, there will be other ways of identifying the same item in future)
1.1724 September 2024
- Added featured image import
- Added --verbose mode
1.1617 September 2024
- Fixed the collation issue some users were having
- Added taxonomy export/import as extra option - this makes it far easier for me to replicate exactly what users see
- Fixed an issue with importing terms where the term name was used in another taxonomy
- Tested multiple imports, everything imported fully
1.1514 September 2024
- Added pa_ real name indicators to interface for taxonomy
- Fixed flat taxonomy issue with missing terms after import - all terms are fully loaded now
1.1412 September 2024
- Improved error logging for broken functions so you can see which one needs attention
1.136 September 2024
- Added optional collation config for those who have mismatching collations in their defaults versus actual tables
- add the following to your wp-config: define('SSI_COLLATION', 'DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci');
- change the collation to whatever your tables are and this will fix collation issues
- to see your table collations run SHOW TABLE STATUS
1.124 September 2024
- Fixed stupid mistake of hardcoding my dev table name into stage 2!
1.114 September 2024
- Much more work and fixes for hiearchical taxonomies
- tested with flat and hiearchical, tested 5 levels deep
- only setting leaf term, not all the ancestors
- Fixed attributes
- product attributes now work properly and are loaded in stage 10
- this stage may be removed if I can get this back into stage 1 where the array should be defined and where this should work
1.103 September 2024
- Speed boost by eliminating duplicates in the _hieararchies table
1.093 September 2024
- Code inspected everything related to taxonomies
- fixed hierarchical taxonomies not being set in destination
1.0829 August 2024
- Added debug for user functions
- Added check for array type to avoid potential fatal error
1.0728 August 2024
- Added export/import for templates
- export will export to file, but also gives you the export in the textarea to copy/paste
- import involves pasting the import config in the textarea then hitting import
- Fixed error with decimal place not being sent to the server for new imports
- Changed default mapping types to 'Direct Mapping' rather than 'function' since this should be most of the cases
- Ajaxified everything to reduce confusion for new users
1.0613 June 2024
- Added txt file compatibility
- Added semi-colon separator compatibility
- Tidied up the interface a little
- Added multi-hierachical term capability (so you can have 2+ product cats per item)
- Fixed other taxonomy related bugs
- Optimised the code a bit
- Found a bunch of bugs in taxonomy, fixed more
- Added multi-product_cat compatibility
- Fixed collation and charset so it pulls from $wpdb
1.0531 January 2024
- Fixed additional columns defined in template
- these are now correctly added to the flat mappings table if the user did not add them
- the mapData function is properly called now so any template mappings or additional data massage can occur
1.0430 January 2024
- Added commas as decimals handler in the Woo import template
- Added infinite time limit in case wp cli badly configured
1.0330 January 2024
- Fixed import bug to handle dashes in attribute names and postmeta keys
1.0230 January 2024
- Added functions editor to interface
- also eval these functions at import time through wp cli
- you must trust people who can edit these functions obviously
1.0129 January 2024
- JS Fix for new imports to load default values for postmeta
1.0029 January 2024
- Very first working version including interface
- please read the knowledge-base guide to understand how to use this, in particular how to use the function system
