WebToffee Import Export for WooCommerce
When importing products with WebToffee’s Product Import Export for WooCommerce or Import Export Suite for WooCommerce plugins, FacetWP’s automatic indexer is triggered. This happens because posts and/or terms are being inserted and/or saved during the import process. Normally this is a good thing, but because importing happens at a very high frequency, this can lead to several issues:
Indexing and server issues during importing
FacetWP’s automatic indexer running during the import process is not optimal. We’ve seen the following issues happening:
500
fatal errors.502
errors caused by the server not being able to handle all necessary processing. This issue can specifically happen in multi-lingual setups with WPML and FacetWP’s Multilingual add-on installed.- (Child) terms not being added to imported posts for non-default languages, in multi-lingual setups with WPML and FacetWP’s Multilingual add-on installed. If this happens depends on the language of the imported posts and the language used on the import admin page.
To prevent these issues, two things need to be done:
- FacetWP’s indexer needs to be prevented from running during the import process.
- The indexer needs to be triggered to run after the import process has finished.
1. Prevent re-indexing during importing
To prevent the above issues, FacetWP’s automatic indexer needs to be prevented from running during the import process.
There are two ways to do this:
You can do this manually by temporarily disabling FacetWP’s “Enable automatic indexing” setting (introduced in version 4.3.4) during the import. Make sure to re-enable it when the import has finished.
To automatically stop FacetWP’s indexer from running during the import process, add the following snippet to your (child) theme’s functions.php.
The code works for the free and Pro versions of WebToffee (Product) Import Export for WooCommerce, for both manual and scheduled/cron imports. Note that it needs FacetWP v4.3.4+ to function correctly.
How to use custom PHP code?
PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info
// Disable FacetWP automatic indexing during manual and cron importing by 'Product Import Export for WooCommerce' plugin by WebToffee // Needs FacetWP v4.3.4+ add_filter( 'facetwp_indexer_is_enabled', function( $enabled ) { if ( defined( 'WT_P_IEW_VERSION' ) || defined( 'WT_IEW_VERSION' ) ) { // WebToffee Free or Pro if ( wp_doing_ajax() && ( isset( $_POST['data_type'] ) && 'json' === $_POST['data_type'] ) && ( isset( $_POST['import_action'] ) && 'import' === $_POST['import_action'] ) ) { return false; // Disable indexing during manual importing } if ( defined( 'WT_IEW_CRON' ) ) { return false; // Disable indexing during cron importing } } return $enabled; }, 5 );
2. Trigger re-indexing after a finished import
To re-index after the import has finished, you could just click the Re-index button. But if you run regular or scheduled imports, you may want to automate this.
The way to do this depends on the type of import: manual or scheduled. For each, the WebToffee plugin fires a different hook when the import is finished:
wt_iew_importer_done_import
– fires after a manual import.wt_ier_scheduled_action_finished
– fires after a succesful scheduled import.
Trigger a full re-index after a manual import
The following code triggers a full re-index after a manual import. This hook will always fire after a manual import, also when the import does not change any post content.
How to use custom PHP code?
PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info
// Triggers a full re-index after a manual import // Works only in the Pro version of WebToffee Import Export for WooCommerce function fwp_reindex_posts_after_manual_import() { if ( function_exists( 'FWP' ) ) { FWP()->indexer->index(); } } add_filter('wt_iew_importer_done_import', 'fwp_reindex_posts_after_manual_import', 10);
Trigger a full re-index after a scheduled import
To trigger a full re-index after WebToffee has finished with a scheduled import, add the following code to your (child) theme’s functions.php. Scheduled imports are imports running on a (cron) schedule, and are visible on the “Scheduled Actions” page.
Be aware that the wt_ier_scheduled_action_finished
hook only fires after a successful scheduled import. When the import triggers any errors, or when the import does not change any post content, the hook will not fire, and the re-index will not run.
Also important to note is that the snippet below will only work when you choose “WordPress Cron” as Schedule type. If you need to use “Server Cron”, see the section below.
How to use custom PHP code?
PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info
// Triggers a full re-index after a successful scheduled import // Only works with "WP Cron" schedule type, NOT with "Server Cron" // Works only in the Pro version of WebToffee Import Export for WooCommerce function fwp_reindex_posts_after_scheduled_import( $out ) { if ( function_exists( 'FWP' ) ) { FWP()->indexer->index(); } } add_action('wt_ier_scheduled_action_finished', 'fwp_reindex_posts_after_scheduled_import', 10, 1);
Using the “Server Cron” import schedule type
The above snippet will only work when you choose “WordPress Cron” as Schedule type in the schedule’s settings. When you select “Server Cron” and use a server cron job to visit the provided import URL, the snippet will result in a fatal error:
Uncaught Error: Call to a member function index() on null
This error which will only be visible in the server’s error log, and the indexer will not run as a result. This is caused by FacetWP’s indexer functions not being available at the moment this URL is triggered.
If you need to use “Server Cron” scheduled importing, you can use the below snippet instead. This snippet uses a one-time cron event to trigger indexing after the import (triggered by server cron) has successfully finished. This setup makes sure that the indexing process runs in a separate process, in which FacetWP’s functions are available.
Note that WP_Cron only runs when there is front-end activity. So when the indexer runs exactly, depends on when the one-time cron indexing event is triggered by WP_Cron.
If you have disabled WP_Cron and replaced it with server cron, you’ll need to time the WP (server) cron schedule in such a way that it never runs at the same time an import is running.
Instead of triggering a one-time event based on the wt_ier_scheduled_action_finished
hook, you could also use WP-Cli to trigger a re-index on a custom server cron schedule. Also in this setup you’ll need to time the WP (server) cron schedule in such a way that it never runs when an import is running.
Alternative: trigger re-indexing after importing with WP-Cron
Instead of running the indexer directly after importing, when the WebToffee hooks fire, you could also automatically trigger the indexer with a one-time WP-Cron event.
The advantage would be that the indexing process runs in a separate process from the importing process, preventing any (server) issues caused by running the two processes at the same time, in direct succession. And it also makes it possible to use import scheduling with the “Server Cron” schedule type.
The disadvantage of this setup is that it uses WP-Cron, which is only triggered when there is front-end activity. Which means it can take time for the re-indexing to start. So if you don’t see it running, visit a front-end page. To check on cron activity, you can use the WP Crontrol plugin.
To schedule a one-time WP-Cron event that starts a full re-index after a manual import, use the following instead:
How to use custom PHP code?
PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info
// Schedules a one-time WP-Cron event to trigger a full re-index after a manual import // Works only in the Pro version of WebToffee Import Export for WooCommerce function fwp_all_index() { FWP()->indexer->index(); } add_action( 'fwp_all_index', 'fwp_all_index' ); function facetwp_reindex_all_posts( $import_id ) { wp_schedule_single_event( time(), 'fwp_all_index'); } // Trigger a one-time cron event to start the indexer after a manual import add_action( 'wt_iew_importer_done_import', 'facetwp_reindex_all_posts' );
To schedule a one-time WP-Cron event that starts a full re-index after a scheduled import, add the following to your (child) theme’s functions.php:
How to use custom PHP code?
PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info
// Schedules a one-time WP-Cron event to trigger a full re-index after a successful scheduled import // Works only in the Pro version of WebToffee Import Export for WooCommerce function fwp_all_index() { FWP()->indexer->index(); } add_action( 'fwp_all_index', 'fwp_all_index' ); function facetwp_reindex_all_posts( $import_id ) { wp_schedule_single_event( time(), 'fwp_all_index'); } // Trigger a one-time cron event to start the indexer after a successful scheduled import add_action( 'wt_ier_scheduled_action_finished', 'facetwp_reindex_all_posts' );
Send an e-mail after importing
Both hooks mentioned above can also be used to send an email after the import is finished.
The following code triggers a full re-index and sends an e-mail after a successful scheduled import. You can use the same lines within the hook for a manual import.
How to use custom PHP code?
PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info
// Triggers a full re-index and sends an email after a successful scheduled import // Works only in the Pro version of WebToffee Import Export for WooCommerce function fwp_reindex_posts_send_email( $out ) { // do a full re-index if ( function_exists( 'FWP' ) ) { FWP()->indexer->index(); } // send a basic e-mail $email = 'me@example.com, someone@example.com'; // change to your e-mail address(es) wp_mail( $email, 'Product Auto Import Export', 'Product scheduled import completed.' ); // Specify the subject and message of the e-mail } add_action('wt_ier_scheduled_action_finished', 'fwp_reindex_posts_send_email', 10, 1);
The following also sends an e-mail after a successful scheduled import, including a detailed log file of the import:
How to use custom PHP code?
PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info
// Triggers a full re-index and sends an email with log after a successful scheduled import // Works only in the Pro version of WebToffee Import Export for WooCommerce function fwp_reindex_posts_send_email_log( $out ) { // do a full re-index if ( function_exists( 'FWP' ) ) { FWP()->indexer->index(); } // send an e-mail with import log file ini_set('max_execution_time', -1); ini_set('memory_limit', -1); $wt_log_path = WP_CONTENT_DIR . '/webtoffee_iew_log'; $files = glob("$wt_log_path/*.*"); $files = array_combine($files, array_map('filectime', $files)); arsort($files); $destination = key($files); $email = 'me@example.com'; // change to your e-mail address(es) $object= 'Product scheduled import completed'; // Specify the subject of the e-mail $message = 'Product scheduled import completed.'; // Specify the message of the e-mail $mail_attachment = array($destination); $headers = ''; wp_mail( $email, $object, $message,$headers,$mail_attachment ); } add_action('wt_ier_scheduled_action_finished', 'fwp_reindex_posts_send_email_log', 10, 1);
Prevent duplicate results with imported posts
If you are regularly importing posts, be aware that imported posts often end up having the exact same post date.
This can lead to issues when queries are using the post date in their orderby
query argument. Adding to the problem is that WordPress by default will order queries by post date.
In this scenario with multiple posts sharing the same date, if no specific order is set for a query, or if it is intentionally set to date
, MySQL will not have a fallback and will often sort erratically. This can lead to duplicate results in your listing, most visibly when you are using a Pager/Load more facet or a Sort facet.
The problem can be easily fixed by setting something else than date
in the orderby
argument of your queries. Or by introducing a secondary, fallback sorting method.