{"id":329611,"date":"2026-06-23T23:52:52","date_gmt":"2026-06-23T23:52:52","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/csv-resumable-importer-for-tainacan\/"},"modified":"2026-06-23T23:52:32","modified_gmt":"2026-06-23T23:52:32","slug":"csv-resumable-importer-for-tainacan","status":"publish","type":"plugin","link":"https:\/\/fr.wordpress.org\/plugins\/csv-resumable-importer-for-tainacan\/","author":23519298,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.0","stable_tag":"1.0.0","tested":"7.0","requires":"5.9","requires_php":"7.4","requires_plugins":null,"header_name":"CSV Resumable Importer for Tainacan","header_author":"Bauhaus Tech","header_description":"Adds a Tainacan CSV importer that processes attachments (special_attachments) one per background iteration instead of all at once. Prevents PHP max_execution_time fatals on items with many attachments and the resulting import restart\/duplication. Does not modify Tainacan core. Independent add-on, not affiliated with the Tainacan project.","assets_banners_color":"fff7d6","last_updated":"2026-06-23 23:52:32","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"https:\/\/bauhaustech.com\/","rating":0,"author_block_rating":0,"active_installs":0,"downloads":74,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"bauhaustech","date":"2026-06-23 23:52:32"}},"upgrade_notice":{"1.0.0":"<p>Initial release.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3583877,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3583877,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256},"icon.svg":{"filename":"icon.svg","revision":3583877,"resolution":false,"location":"assets","locale":false}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3583877,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3583877,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.0"],"block_files":[],"assets_screenshots":[],"screenshots":[]},"plugin_section":[],"plugin_tags":[1346,268623,567,6606,225063],"plugin_category":[50,59],"plugin_contributors":[268624,268625],"plugin_business_model":[],"class_list":["post-329611","plugin","type-plugin","status-publish","hentry","plugin_tags-attachments","plugin_tags-background-process","plugin_tags-csv","plugin_tags-importer","plugin_tags-tainacan","plugin_category-media","plugin_category-utilities-and-tools","plugin_contributors-bauhaustech","plugin_contributors-marvila","plugin_committers-bauhaustech"],"banners":{"banner":"https:\/\/ps.w.org\/csv-resumable-importer-for-tainacan\/assets\/banner-772x250.png?rev=3583877","banner_2x":"https:\/\/ps.w.org\/csv-resumable-importer-for-tainacan\/assets\/banner-1544x500.png?rev=3583877","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":"https:\/\/ps.w.org\/csv-resumable-importer-for-tainacan\/assets\/icon.svg?rev=3583877","icon":"https:\/\/ps.w.org\/csv-resumable-importer-for-tainacan\/assets\/icon.svg?rev=3583877","icon_2x":false,"generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>This add-on registers an extra CSV importer in <a href=\"https:\/\/tainacan.org\/\">Tainacan<\/a> whose attachment processing is <strong>resumable<\/strong>: the files listed in the <code>special_attachments<\/code> column are imported <strong>one per background iteration<\/strong>, instead of all at once.<\/p>\n\n<p>It does <strong>not<\/strong> modify Tainacan core \u2014 it registers an additional importer through the <code>tainacan-register-importers<\/code> hook, so it keeps working across Tainacan updates.<\/p>\n\n<p>This is an independent add-on developed by Bauhaus Tech. It is <strong>not affiliated with, endorsed by, or part of<\/strong> the Tainacan project.<\/p>\n\n<h4>The problem it solves<\/h4>\n\n<p>A CSV import in which a single item has many attachments (e.g. 150 images in <code>special_attachments<\/code>) fails with:<\/p>\n\n<pre><code>PHP Fatal error: Maximum execution time of 360 seconds exceeded in ...\/class-wp-image-editor-imagick.php\n<\/code><\/pre>\n\n<p>\u2026and then <strong>restarts from the beginning, duplicating items<\/strong>.<\/p>\n\n<p>The stock Tainacan CSV importer imports <strong>all<\/strong> of an item's attachments inside a single <code>after_inserted_item()<\/code> call. Each file triggers <code>wp_generate_attachment_metadata()<\/code>, which generates thumbnails through Imagick \u2014 an expensive operation. The background process only checks its soft time limit (~20s) <strong>between<\/strong> <code>task()<\/code> iterations; since the 150 attachments run inside a single iteration, that limit is never checked mid-loop. The item alone exceeds PHP's hard <code>max_execution_time<\/code>, the process dies mid-task <strong>without persisting progress<\/strong>, and the cron healthcheck <strong>re-dispatches the batch from the last checkpoint<\/strong> \u2014 recreating already-imported items.<\/p>\n\n<h4>How it works<\/h4>\n\n<p>Instead of importing attachments inline, this importer:<\/p>\n\n<ol>\n<li><strong>Queues<\/strong> the item's attachment paths\/URLs (stored in a transient serialized together with the process state).<\/li>\n<li>Processes <strong>one attachment per iteration<\/strong>, staying on the current item until the queue is empty.<\/li>\n<\/ol>\n\n<p>Because each attachment becomes its own iteration, the soft 20s limit applies <strong>between files<\/strong>: the batch checkpoints regularly and the import becomes resumable. Idempotency is reinforced by persisting the already-created item id, so a resume continues the attachments instead of recreating the item.<\/p>\n\n<h4>Known limitations<\/h4>\n\n<p>Because this plugin <strong>cannot modify Tainacan core<\/strong>:<\/p>\n\n<ul>\n<li>A single file whose processing alone exceeds <code>max_execution_time<\/code> still fails (pathological case).<\/li>\n<li>Progress is still persisted at the core's ~20s <code>handle()<\/code> checkpoint, not per iteration (forcing a per-iteration checkpoint would require changing <code>Background_Importer::task()<\/code> in core). A fatal <strong>within the same 20s window<\/strong> may reprocess what was done since the last checkpoint. The definitive fix is the equivalent change upstream in Tainacan.<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>csv-resumable-importer-for-tainacan<\/code> folder to <code>\/wp-content\/plugins\/<\/code>, or install the ZIP via <strong>Plugins \u2192 Add New \u2192 Upload Plugin<\/strong>.<\/li>\n<li>Activate <strong>CSV Resumable Importer for Tainacan<\/strong> in <strong>Plugins<\/strong>.<\/li>\n<li>Requires the <strong>Tainacan<\/strong> plugin to be installed and active.<\/li>\n<li>In <strong>Tainacan \u2192 Importers<\/strong>, choose <strong>\"CSV (resumable attachments)\"<\/strong> instead of the default CSV importer.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20it%20modify%20tainacan%20core%3F\"><h3>Does it modify Tainacan core?<\/h3><\/dt>\n<dd><p>No. It registers an additional importer through Tainacan's <code>tainacan-register-importers<\/code> hook and subclasses the core CSV importer. Tainacan updates do not overwrite it.<\/p><\/dd>\n<dt id=\"are%20the%20import%20options%20different%20from%20the%20native%20csv%20importer%3F\"><h3>Are the import options different from the native CSV importer?<\/h3><\/dt>\n<dd><p>No. Delimiter, mapping, <code>server_path<\/code> and the special columns (<code>special_document<\/code>, <code>special_thumbnail<\/code>, <code>special_attachments[|APPEND|REPLACE]<\/code>) work exactly as in the native importer. Only the way attachments are processed changes.<\/p><\/dd>\n<dt id=\"is%20this%20an%20official%20tainacan%20plugin%3F\"><h3>Is this an official Tainacan plugin?<\/h3><\/dt>\n<dd><p>No. It is an independent add-on by Bauhaus Tech, not affiliated with the Tainacan project.<\/p><\/dd>\n<dt id=\"does%20it%20fix%20every%20possible%20timeout%3F\"><h3>Does it fix every possible timeout?<\/h3><\/dt>\n<dd><p>It removes the real-world cause (a single item importing many attachments in one uninterruptible call). See \"Known limitations\" for the residual edge cases that would require a core change.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release. Resumable CSV importer that processes <code>special_attachments<\/code> one per background iteration.<\/li>\n<\/ul>","raw_excerpt":"Resumable CSV importer for Tainacan: imports attachments one at a time to avoid execution timeouts and duplicate items on large imports.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/fr.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/329611","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fr.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/fr.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/fr.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=329611"}],"author":[{"embeddable":true,"href":"https:\/\/fr.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/bauhaustech"}],"wp:attachment":[{"href":"https:\/\/fr.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=329611"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/fr.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=329611"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/fr.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=329611"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/fr.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=329611"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/fr.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=329611"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/fr.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=329611"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}