{"id":286119,"date":"2026-03-11T22:34:03","date_gmt":"2026-03-11T22:34:03","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/skwirrel-pim-sync\/"},"modified":"2026-06-24T07:09:30","modified_gmt":"2026-06-24T07:09:30","slug":"skwirrel-pim-sync","status":"publish","type":"plugin","link":"https:\/\/el.wordpress.org\/plugins\/skwirrel-pim-sync\/","author":23459475,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"3.11.0","stable_tag":"3.11.0","tested":"7.0","requires":"6.9","requires_php":"8.3","requires_plugins":null,"header_name":"Skwirrel PIM sync for WooCommerce","header_author":"Skwirrel B.V.","header_description":"Sync plugin for Skwirrel PIM via Skwirrel JSON-RPC API to WooCommerce.","assets_banners_color":"abce8f","last_updated":"2026-06-24 07:09:30","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/github.com\/Skwirrel-B-V\/skwirrel-pim-sync-for-woocommerce","header_author_uri":"https:\/\/skwirrel.eu","rating":0,"author_block_rating":0,"active_installs":0,"downloads":994,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"2.0.4":{"tag":"2.0.4","author":"jkoomen","date":"2026-03-11 23:05:06"},"2.0.5":{"tag":"2.0.5","author":"jkoomen","date":"2026-03-12 09:02:39"},"2.0.6":{"tag":"2.0.6","author":"jkoomen","date":"2026-03-17 13:26:15"},"2.0.7":{"tag":"2.0.7","author":"jkoomen","date":"2026-03-17 13:27:44"},"2.6.2":{"tag":"2.6.2","author":"jkoomen","date":"2026-03-19 20:44:11"},"3.10.0":{"tag":"3.10.0","author":"jkoomen","date":"2026-05-27 21:22:21"},"3.10.1":{"tag":"3.10.1","author":"jkoomen","date":"2026-05-28 04:12:30"},"3.10.2":{"tag":"3.10.2","author":"jkoomen","date":"2026-06-11 08:48:07"},"3.10.3":{"tag":"3.10.3","author":"jkoomen","date":"2026-06-22 13:23:54"},"3.11.0":{"tag":"3.11.0","author":"jkoomen","date":"2026-06-24 07:09:30"},"3.2.0":{"tag":"3.2.0","author":"jkoomen","date":"2026-03-30 10:36:12"},"3.2.1":{"tag":"3.2.1","author":"jkoomen","date":"2026-03-30 13:55:33"},"3.4.0":{"tag":"3.4.0","author":"jkoomen","date":"2026-04-17 19:40:47"},"3.6.0":{"tag":"3.6.0","author":"jkoomen","date":"2026-04-30 16:41:01"},"3.6.1":{"tag":"3.6.1","author":"jkoomen","date":"2026-05-01 19:46:46"},"3.7.0":{"tag":"3.7.0","author":"jkoomen","date":"2026-05-07 11:35:22"},"3.8.0":{"tag":"3.8.0","author":"jkoomen","date":"2026-05-07 13:10:08"},"3.8.1":{"tag":"3.8.1","author":"jkoomen","date":"2026-05-07 13:41:06"},"3.8.2":{"tag":"3.8.2","author":"jkoomen","date":"2026-05-07 16:54:57"},"3.9.0":{"tag":"3.9.0","author":"jkoomen","date":"2026-05-26 10:07:29"},"3.9.1":{"tag":"3.9.1","author":"jkoomen","date":"2026-05-26 10:26:51"}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.jpg":{"filename":"icon-128x128.jpg","revision":3509241,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.jpg":{"filename":"icon-256x256.jpg","revision":3509241,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.jpg":{"filename":"banner-1544x500.jpg","revision":3509241,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.jpg":{"filename":"banner-772x250.jpg","revision":3509241,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["2.0.4","2.0.5","2.0.6","2.0.7","2.6.2","3.10.0","3.10.1","3.10.2","3.10.3","3.11.0","3.2.0","3.2.1","3.4.0","3.6.0","3.6.1","3.7.0","3.8.0","3.8.1","3.8.2","3.9.0","3.9.1"],"block_files":[],"assets_screenshots":[],"screenshots":[]},"plugin_section":[],"plugin_tags":[175448,42241,257556,1558,286],"plugin_category":[45],"plugin_contributors":[257557],"plugin_business_model":[],"class_list":["post-286119","plugin","type-plugin","status-publish","hentry","plugin_tags-pim","plugin_tags-product-sync","plugin_tags-skwirrel","plugin_tags-sync","plugin_tags-woocommerce","plugin_category-ecommerce","plugin_contributors-jkoomen","plugin_committers-jkoomen"],"banners":{"banner":"https:\/\/ps.w.org\/skwirrel-pim-sync\/assets\/banner-772x250.jpg?rev=3509241","banner_2x":"https:\/\/ps.w.org\/skwirrel-pim-sync\/assets\/banner-1544x500.jpg?rev=3509241","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/skwirrel-pim-sync\/assets\/icon-128x128.jpg?rev=3509241","icon_2x":"https:\/\/ps.w.org\/skwirrel-pim-sync\/assets\/icon-256x256.jpg?rev=3509241","generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>Skwirrel PIM sync for WooCommerce connects your WooCommerce webshop to the Skwirrel PIM system. Products, variations, categories, brands, manufacturers, images, and documents are synchronised automatically or on demand.<\/p>\n\n<p><strong>Features:<\/strong><\/p>\n\n<ul>\n<li>Full and delta (incremental) product synchronisation<\/li>\n<li>Simple and variable product support with ETIM classification for variation axes<\/li>\n<li>Automatic category tree sync with parent-child hierarchy<\/li>\n<li>Brand sync via WooCommerce native product_brand taxonomy<\/li>\n<li>Manufacturer sync with dedicated product_manufacturer taxonomy<\/li>\n<li>Product image and document import into the WordPress media library<\/li>\n<li>Custom class attributes (alphanumeric, logical, numeric, range, date, multi)<\/li>\n<li>Configurable product URL slugs (source field, suffix, update on re-sync)<\/li>\n<li>GTIN and manufacturer product code search filter on the product list page<\/li>\n<li>Scheduled synchronisation via WP-Cron or Action Scheduler<\/li>\n<li>Manual synchronisation from the admin dashboard with live progress tracking<\/li>\n<li>Date-grouped sync history (last 20 runs)<\/li>\n<li>Stale product and category purge after full sync<\/li>\n<li>Delete protection with warnings and automatic full re-sync<\/li>\n<li>Multilingual support with 7 locales (nl_NL, nl_BE, de_DE, fr_FR, fr_BE, en_US, en_GB)<\/li>\n<li>Optional integration with the WordPress 7.0 Connections Screen for centralised API key management<\/li>\n<\/ul>\n\n<p><strong>Requirements:<\/strong><\/p>\n\n<ul>\n<li>WordPress 6.0 or higher<\/li>\n<li>WooCommerce 8.0 or higher (9.6+ recommended for native brand support; tested up to 10.6)<\/li>\n<li>PHP 8.3 or higher<\/li>\n<li>An active Skwirrel account with API access<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin files to <code>\/wp-content\/plugins\/skwirrel-pim-sync\/<\/code>, or install the plugin directly through the WordPress plugin screen.<\/li>\n<li>Activate the plugin through the 'Plugins' screen in WordPress.<\/li>\n<li>Navigate to WooCommerce &gt; Skwirrel Sync to configure the plugin.<\/li>\n<li>Enter your Skwirrel API URL and authentication token.<\/li>\n<li>Click 'Sync now' to start the first synchronisation.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"which%20skwirrel%20api%20version%20is%20supported%3F\"><h3>Which Skwirrel API version is supported?<\/h3><\/dt>\n<dd><p>The plugin works with the Skwirrel JSON-RPC 2.0 API.<\/p><\/dd>\n<dt id=\"how%20often%20are%20products%20synchronised%3F\"><h3>How often are products synchronised?<\/h3><\/dt>\n<dd><p>You can set an automatic schedule (hourly, twice daily, or daily) or synchronise manually from the settings page.<\/p><\/dd>\n<dt id=\"are%20existing%20products%20overwritten%3F\"><h3>Are existing products overwritten?<\/h3><\/dt>\n<dd><p>The plugin uses the Skwirrel external ID as a unique key. Existing products are updated, not duplicated.<\/p><\/dd>\n<dt id=\"i%20use%20a%20media%20offload%20plugin%20%28wp%20offload%20media%2C%20s3%20uploads%2C%20%E2%80%A6%29%20%E2%80%94%20will%20the%20sync%20delete%20my%20offloaded%20files%3F\"><h3>I use a media offload plugin (WP Offload Media, S3 Uploads, \u2026) \u2014 will the sync delete my offloaded files?<\/h3><\/dt>\n<dd><p>No, the sync never invokes <code>wp_delete_attachment()<\/code> on a missing-file event in 3.8.0+. When the local file is gone, the plugin only clears its own Skwirrel-side meta keys from the WP attachment record so the next sync can download fresh; the WP record itself (and any remote copy your offload plugin manages) is left untouched.<\/p>\n\n<p>If you want to go a step further and have the sync <strong>reuse<\/strong> the existing WP attachment (no fresh download, no churn) when the local file is gone but the remote copy is fine, hook into the <code>skwirrel_wc_sync_attachment_is_valid<\/code> filter. The simplest implementation as a mu-plugin:<\/p>\n\n<pre><code>&lt;?php\nadd_filter( 'skwirrel_wc_sync_attachment_is_valid', function ( $local_present, $att_id ) {\n    return $local_present || (bool) wp_get_attachment_url( $att_id );\n}, 10, 2 );\n<\/code><\/pre>\n\n<p>Returning <code>true<\/code> tells the sync the attachment is still valid even though the local file is missing. The plugin ships a more thorough reference implementation (URL-equals-uploads-baseurl check) you can adapt \u2014 see the project's <code>mu-plugins\/skwirrel-offload-compat.php<\/code>.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>3.11.0<\/h4>\n\n<ul>\n<li>Change: a \"normal\" batch sync now imports each product fully in one pass \u2014 create, categories, attributes, and images together \u2014 exactly like syncing a single product from the product screen. Previously batch sync worked in separate global phases (all products created first, then all categorised, then all imaged, \u2026), so a run interrupted by a timeout or server limit could leave products half-built (created but without images or attributes) and a later sync would not go back to finish them. Each product is now committed completely before the next, so an interrupted run only leaves not-yet-started products, which are picked up cleanly next time. Same work, same speed \u2014 just no half-finished products.<\/li>\n<li>Safety: a newly-created product now stays a draft until its categories, attributes, and images are all in place, then goes live. This prevents a sync that is interrupted while importing a brand-new product from briefly showing an empty product on your shop. (Existing products are never affected \u2014 they are never unpublished during a sync.)<\/li>\n<li>Fix: re-syncs no longer create duplicate products with a suffixed SKU (e.g. <code>4250366870007-14768<\/code>). When a product's SKU already exists, the sync now reuses the existing product (or, for grouped\/variable products, leaves it to the grouped-product path) instead of minting a second copy.<\/li>\n<li>Fix: an interrupted sync no longer \"loses\" products. The delta checkpoint that tracks what has been synced is now advanced only when a run fully completes (and is stamped with the run's start time), so a run that dies partway through is simply re-done next time instead of silently skipping the products it never finished.<\/li>\n<li>Fix: the live \"Sync in progress\" panel now shows the steps that actually run (Fetch, Create &amp; sync products, Finalize variable products, Link related products, Cleanup) instead of the old phase list, so steps no longer appear stuck and the counts make sense.<\/li>\n<li>Change: re-syncs now report products as \"unchanged\" instead of marking every product \"updated\". A product counts as updated only when it actually changed in Skwirrel (its update timestamp advanced) \u2014 not just because a sync ran. Unchanged products are skipped (no re-save), so a repeat sync of a mostly-unchanged catalog finishes in seconds, and the result shows a new \"Unchanged\" count. Changing a sync setting (or upgrading the plugin) automatically reprocesses everything once.<\/li>\n<\/ul>\n\n<h4>3.10.3<\/h4>\n\n<ul>\n<li>Fix: the internal <code>wp_skwirrel_sync_queue<\/code> working table no longer grows without bound. This table is temporary scratch space used during a sync, and is cleaned up when a run finishes. Runs that ended abnormally \u2014 a fatal error, an out-of-memory kill, a server timeout, or a hard-killed process \u2014 left their rows behind, and over time these accumulated and could fill the disk. Each sync now sweeps away leftovers from earlier interrupted runs at the start, and cleanup is hardened to run on every failure path, so the table stays small automatically. (No product data is affected \u2014 this is purely temporary working data.)<\/li>\n<\/ul>\n\n<h4>Older versions<\/h4>\n\n<p>Earlier changelog entries (3.10.2 and before) are in the full changelog on GitHub:\nhttps:\/\/github.com\/Skwirrel-B-V\/skwirrel-pim-sync-for-woocommerce\/blob\/main\/CHANGELOG.md<\/p>","raw_excerpt":"Synchronises products from the Skwirrel PIM system to WooCommerce via a JSON-RPC 2.0 API.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/el.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/286119","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/el.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/el.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/el.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=286119"}],"author":[{"embeddable":true,"href":"https:\/\/el.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/jkoomen"}],"wp:attachment":[{"href":"https:\/\/el.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=286119"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/el.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=286119"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/el.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=286119"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/el.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=286119"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/el.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=286119"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/el.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=286119"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}