Contact Filters
FluentCRM Core IntermediateThese filter hooks let you customize contact data, profile sections, custom fields, avatars, smart codes, bulk actions, and more.
Contact Statuses & Types
fluent_crm/contact_statuses
Filter the list of valid contact subscription statuses.
Parameters
$statusesArray - a plain list of status slugs. Defaults tosubscribed,pending,unsubscribed,transactional,bounced,complained,spammed
Usage:
add_filter('fluent_crm/contact_statuses', function($statuses) {
// Add a custom status
$statuses[] = 'on_hold';
return $statuses;
});Source: app/Functions/helpers.php
fluent_crm/contact_editable_statuses
Filter which contact statuses are user-editable (can be set manually by an admin). The incoming list is fluent_crm/contact_statuses with the three system-only statuses — bounced, complained and spammed — already removed.
TIP
Adding a status here only affects the editable list. Register it on fluent_crm/contact_statuses as well, or the rest of the CRM will not recognise it.
Parameters
$statusesArray - the status list minusbounced,complainedandspammed. Array keys are preserved fromarray_diff(), so the list is not re-indexed.
Usage:
add_filter('fluent_crm/contact_editable_statuses', function($statuses) {
// Remove a status from the editable list
return array_diff($statuses, ['complained']);
});Source: app/Functions/helpers.php
fluent_crm/contact_types
Filter the contact type definitions (e.g., Lead, Customer).
Parameters
$typesArray - Associative array ofslug => label
Usage:
add_filter('fluent_crm/contact_types', function($types) {
$types['partner'] = __('Partner', 'fluent-crm');
return $types;
});Source: app/Functions/helpers.php
fluent_crm/contact_activity_types
Filter the activity/timeline event type definitions shown on the contact profile.
Parameters
$typesArray - Associative array ofslug => label(e.g.,note,call,email,meeting)
Usage:
add_filter('fluent_crm/contact_activity_types', function($types) {
$types['sms'] = __('SMS', 'fluent-crm');
return $types;
});Source: app/Functions/helpers.php
fluent_crm/status_text
Filter the mapping of internal status keys to human-readable labels.
Parameters
$mapStatusArray - Associative array ofstatus_key => display_label
Usage:
add_filter('fluent_crm/status_text', function($mapStatus) {
$mapStatus['subscribed'] = 'Active Member';
return $mapStatus;
});Source: app/Services/Helper.php
fluent_crm/contact_name_prefixes
Filter the name prefix/salutation options (Mr, Mrs, Ms, etc.). This is the current hook (since 2.7.0).
Note: A legacy hook
fluentcrm_contact_name_prefixesalso exists (since 2.5.5) and fires first. The current hook applies on top of it.
Parameters
$prefixesArray - List of prefix strings
Usage:
add_filter('fluent_crm/contact_name_prefixes', function($prefixes) {
$prefixes[] = 'Dr';
$prefixes[] = 'Prof';
return $prefixes;
});Source: app/Services/Helper.php
fluent_crm/email_sendable_statuses
Filter which contact statuses are eligible to receive campaign emails.
Parameters
$statusesArray - Default:['subscribed', 'transactional']
Usage:
add_filter('fluent_crm/email_sendable_statuses', function($statuses) {
// Only send to subscribed contacts
return ['subscribed'];
});Source: app/Functions/helpers.php
Profile Sections & Widgets
fluentcrm_profile_sections
Filter the array of tab sections displayed on the contact profile page. Use this to add custom tabs.
Parameters
$sectionsArray - Each section hasslug,title,icon, and other properties
Usage:
add_filter('fluentcrm_profile_sections', function($sections) {
$sections['my_custom_tab'] = [
'slug' => 'my_custom_tab',
'title' => __('My Tab', 'fluent-crm'),
'icon' => 'el-icon-setting'
];
return $sections;
});Source: app/Services/Helper.php
fluent_crm/subscriber_top_widgets
Filter the array of "top" widgets shown above the timeline on a contact profile. The incoming array holds the built-in commerce widget when one applies, and the returned array is passed through array_filter(), so returning a falsy entry removes that widget.
Escape your widget content
Each widget's content is rendered as raw HTML in the admin UI (Vue v-html) with no client-side sanitization. Escape any contact-authored data with esc_html() or wp_kses_post() before returning it, or you introduce stored XSS in the admin. Rich markup is allowed by design — the responsibility sits with the code producing the widget.
Parameters
$widgetsArray - widget definitions, each withtitleandcontent$subscriberSubscriber Model
Usage:
add_filter('fluent_crm/subscriber_top_widgets', function($widgets, $subscriber) {
$widgets[] = [
'title' => 'Custom Widget',
'content' => '<p>Custom content for ' . $subscriber->email . '</p>'
];
return $widgets;
}, 10, 2);Source: app/Http/Controllers/SubscriberController.php
fluent_crm/subscriber_info_widgets
Filter additional sidebar info widgets on a contact profile page. Starts as an empty array. Also consulted when the MCP contact tools assemble a contact profile. A widget may additionally set has_pagination, total, per_page and current_page keys — the profile sidebar then re-fetches that single widget page by page through fluent_crm/subscriber_info_widget_{$widgetKey}.
Escape your widget content
Same as fluent_crm/subscriber_top_widgets — content is rendered with Vue v-html and is not sanitized. Escape contact-authored data before returning it.
Parameters
$widgetsArray - widget definitions, each withtitleandcontent; empty by default$subscriberSubscriber Model
Usage:
add_filter('fluent_crm/subscriber_info_widgets', function($widgets, $subscriber) {
$widgets[] = [
'title' => 'Membership',
'content' => '<p>Gold Member</p>'
];
return $widgets;
}, 10, 2);Source: app/Http/Controllers/SubscriberController.php, app/Modules/MCP/Tools/ContactTools.php
fluent_crm/subscriber_info_widget_{$widgetKey}
Lazy-load or refresh a single sidebar info widget. When the profile sidebar requests subscribers/{id}/info-widgets with a by_widget parameter — which the admin UI does when paging a widget that was registered with has_pagination on fluent_crm/subscriber_info_widgets — only this dynamic filter runs instead of the full widget registry. The dynamic portion, $widgetKey, is the array key the widget was registered under.
Return an array of widget definitions: the controller runs it through array_values() and uses the first element as the refreshed widget, falling back to ['content' => 'No content found'] when the array is empty. In practice producers register the same callback on both hooks — core's Event Tracking handler registers addSubscriberInfoWidgets on fluent_crm/subscriber_info_widgets and fluent_crm/subscriber_info_widget_event_tracking alike, and reads the request's page parameter to build the requested page.
Parameters
$widgetsArray - always empty; return an array whose first element is the widget definition (title,content, and optionallyhas_pagination,total,per_page,current_page)$subscriberSubscriber Model
Usage:
add_filter('fluent_crm/subscriber_info_widget_my_widget', function($widgets, $subscriber) {
$page = isset($_REQUEST['page']) ? max(1, (int) $_REQUEST['page']) : 1;
$widgets['my_widget'] = [
'title' => __('My Widget', 'my-plugin'),
'content' => '<p>Page ' . $page . ' content for ' . esc_html($subscriber->email) . '</p>'
];
return $widgets;
}, 10, 2);Source: app/Http/Controllers/SubscriberController.php (example producer: app/Hooks/Handlers/EventTrackingHandler.php)
fluentcrm_commerce_provider
Declare the active commerce provider for the CRM. The unfiltered value is an empty string; a non-empty slug switches on the purchase widget on contact profiles, the commerce_stat payload of the contact API and the commerce columns of the contacts table query. FluentCampaign Pro hooks this in fluentcampaign-pro/app/Hooks/filters.php and returns woo or edd (via Commerce::getCommerceProvider()) when the matching deep-integration sync is enabled.
TIP
The returned slug becomes the dynamic part of fluent_crm/contact_purchase_stat_{$provider}, so a custom provider must implement that filter too or the purchase widget stays empty.
Parameters
$providerString - commerce provider slug. Default''(no provider)
Usage:
add_filter('fluentcrm_commerce_provider', function($provider) {
return $provider ?: 'my_shop';
});Source: app/Http/Controllers/SubscriberController.php, app/Hooks/Handlers/PurchaseHistory.php, app/Hooks/Handlers/AdminMenu.php, app/Services/ContactsQuery.php (implemented in fluentcampaign-pro/app/Hooks/filters.php)
fluent_crm/contact_purchase_stat_{$provider}
Supply the purchase statistics shown on a contact profile (the "commerce stat" blocks of the purchase widget and the commerce_stat field of the contact API response). The dynamic portion, $provider, is whatever fluentcrm_commerce_provider returned. FluentCampaign Pro registers the woo and edd variants (fluentcampaign-pro/app/Services/Integrations/WooCommerce/DeepIntegration.php and .../Edd/DeepIntegration.php).
Parameters
$statsArray - stat blocks, empty by default. Pro returns a list of blocks, each withtitle(label),value(display HTML),key(machine key such ascustomer_since,last_order_date,order_count,lifetime_value,aov) andactual_value(raw value)$subscriberIdINT - the contact id (not the model)
Usage:
add_filter('fluent_crm/contact_purchase_stat_my_shop', function($stats, $subscriberId) {
$stats[] = [
'title' => __('Order Count', 'my-plugin'),
'value' => '12',
'key' => 'order_count',
'actual_value' => 12
];
return $stats;
}, 10, 2);Source: app/Http/Controllers/SubscriberController.php, app/Hooks/Handlers/PurchaseHistory.php
fluentcrm_get_form_submissions_{$provider}
Supply the rows of the Forms tab on a contact profile for one form plugin. The dynamic portion, $provider, is the slug the tab was registered under via fluent_crm/form_submission_providers. Core ships the fluentform implementation in app/Hooks/Handlers/FormSubmissions.php; the request's page and per_page parameters are available for pagination.
Escape your column values
The returned column values are rendered as raw HTML in the admin UI (Vue v-html) with no client-side sanitization. Escape any contact-authored data with esc_html() or wp_kses_post() before returning it. Structural markup (links, badges) is allowed by design.
TIP
Besides data and total, the return array may carry a columns_config map (column_key => ['label' => ..., 'width' => ..., 'quick_action' => true]) to control the table. A row that includes a __id key and 'action' => 'view' gets a View button that opens a detail drawer via fluent_crm/dynamic_contact_item_view_{$provider}, receiving the full row as $params.
Parameters
$dataArray -['data' => [], 'total' => 0]by default;datais a list of rows (column key => cell HTML),totalthe overall submission count$subscriberSubscriber Model
Usage:
add_filter('fluentcrm_get_form_submissions_my_forms', function($data, $subscriber) {
$data['data'][] = [
'__id' => 123,
'id' => '#123',
'title' => esc_html('Contact Form'),
'action' => 'view'
];
$data['total'] = 1;
return $data;
}, 10, 2);Source: app/Http/Controllers/SubscriberController.php (example producer: app/Hooks/Handlers/FormSubmissions.php)
fluent_crm/dynamic_contact_item_view_{$provider}
Supply the content of the detail drawer that opens from a contact-profile list row — for example the single-submission view of the Forms tab. The admin UI calls subscribers/{id}/dynamic-item-view with a provider and the originating row as params, and this dynamic filter builds what the drawer shows. Core implements the fluentform variant (app/Hooks/Handlers/FormSubmissions.php), which reads __id from $params to load the submission.
The drawer sanitizes content_html and footer_content client-side ($sanitize/DOMPurify) before rendering — still escape contact-authored data server-side rather than relying on it.
WARNING
A second call site in app/Http/Controllers/FormsController.php (getEntry()) fires fluent_crm/dynamic_contact_item_view_fluentform with only two arguments — the default array and ['__id' => $id] — so a callback on this hook must not require the $subscriber argument. Core's own handler registers with 10, 2 for exactly that reason. That call site also passes a smaller default array (only content_html), so do not assume every default key is present.
Parameters
$dataViewArray - Default['type' => 'html', 'title' => 'no title', 'content_html' => 'sorry, no content found', 'footer_content' => '']$paramsArray - parameters sent by the UI; for Forms-tab rows this is the row returned byfluentcrm_get_form_submissions_{$provider}, including__id$subscriberSubscriber Model - not passed on theFormsControllercall site (see warning)
Usage:
add_filter('fluent_crm/dynamic_contact_item_view_my_forms', function($dataView, $params) {
$entryId = isset($params['__id']) ? (int) $params['__id'] : 0;
$dataView['title'] = sprintf(__('Entry #%d', 'my-plugin'), $entryId);
$dataView['content_html'] = '<div>' . esc_html(my_plugin_get_entry_text($entryId)) . '</div>';
return $dataView;
}, 10, 2);Source: app/Http/Controllers/SubscriberController.php, app/Http/Controllers/FormsController.php
fluent_crm/contact_note_fields
Filter the array of additional fields shown on the Add Note form for contacts.
Parameters
$fieldsArray - Additional field definitions
Usage:
add_filter('fluent_crm/contact_note_fields', function($fields) {
$fields[] = [
'key' => 'priority',
'label' => __('Priority', 'fluent-crm'),
'type' => 'select',
'options' => ['low' => 'Low', 'medium' => 'Medium', 'high' => 'High']
];
return $fields;
});Source: app/Services/Helper.php
Custom Fields & Avatars
fluent_crm/global_field_types
Filter the list of available custom contact field types (text, date, checkbox, etc.).
Parameters
$fieldTypesArray - Field type definitions
Usage:
add_filter('fluent_crm/global_field_types', function($fieldTypes) {
$fieldTypes['color_picker'] = [
'label' => 'Color Picker',
'type' => 'color_picker'
];
return $fieldTypes;
});Source: app/Models/CustomContactField.php
fluent_crm/modify_custom_field_value
Filter a custom field value when it is read back — once per value from Subscriber::custom_fields(), and once per value when ContactsQuery bulk-loads custom fields for a contact list.
WARNING
Only the value is passed. There is no field key, no field type and no contact, so a callback cannot tell which field it is transforming or who it belongs to. Treat it as a blanket transform over every custom field value.
Parameters
$valueMixed - the raw stored value
Usage:
add_filter('fluent_crm/modify_custom_field_value', function($value) {
// Applies to every custom field value — keep it type-safe
return is_string($value) ? trim($value) : $value;
});Source: app/Models/Subscriber.php, app/Services/ContactsQuery.php
fluent_crm/default_avatar
Filter the default avatar URL. This only runs when Enable Gravatar is switched off in the compliance settings — when Gravatar is on, fluent_crm/get_avatar runs instead and this one never fires.
Parameters
$urlString - Default avatar image URL,assets/images/avatar.pngfrom the plugin$emailString - Contact's email address
Usage:
add_filter('fluent_crm/default_avatar', function($url, $email) {
return 'https://example.com/custom-avatar.png';
}, 10, 2);Source: app/Functions/helpers.php
fluent_crm/get_avatar
Filter the final avatar URL for a contact. Only runs when Enable Gravatar is switched on; the default value is the Gravatar URL, with a ui-avatars.com fallback appended when Gravatar fallback is enabled and a name is available.
Parameters
$urlString - the Gravatar URL, sized at 128px$emailString - Contact's email address
Usage:
add_filter('fluent_crm/get_avatar', function($url, $email) {
// Use a custom avatar service
return 'https://avatars.example.com/' . md5($email);
}, 10, 2);Source: app/Functions/helpers.php
fluent_crm/allowed_html_tags
Filter the array of allowed HTML tags and attributes used in wp_kses() for sanitizing content.
Parameters
$tagsArray - Associative array of tag => attributes
Usage:
add_filter('fluent_crm/allowed_html_tags', function($tags) {
$tags['iframe'] = [
'src' => true,
'width' => true,
'height' => true
];
return $tags;
});Source: app/Services/Helper.php
Smart Codes
fluentcrm_contact_smartcodes
Filter the array of contact smart codes (e.g., contact.first_name, contact.email) shown in the smart code picker.
Parameters
$smartCodesArray - Array of smart code definitions
Usage:
add_filter('fluentcrm_contact_smartcodes', function($smartCodes) {
$smartCodes[] = [
'key' => '{{contact.custom_field}}',
'title' => 'Custom Field'
];
return $smartCodes;
});Source: app/Services/Helper.php
fluent_crm/general_smartcodes
Filter the array of general CRM and WordPress smart codes (e.g., crm.business_name, wp.admin_email).
Parameters
$smartCodesArray - Array of general smart code definitions
Usage:
add_filter('fluent_crm/general_smartcodes', function($smartCodes) {
$smartCodes[] = [
'key' => '{{crm.site_phone}}',
'title' => 'Site Phone Number'
];
return $smartCodes;
});Source: app/Services/Helper.php
fluent_crm/smartcode_groups
Filter the full grouped array of smart code groups returned by getGlobalSmartCodes().
Parameters
$smartCodesArray - Grouped smart code array
Usage:
add_filter('fluent_crm/smartcode_groups', function($smartCodes) {
// Add a custom smart code group
$smartCodes['my_group'] = [
'title' => 'My Custom Codes',
'shortcodes' => [
'{{my_group.key1}}' => 'Description 1'
]
];
return $smartCodes;
});Source: app/Services/Helper.php
fluent_crm/extended_smart_codes
Filter the array of additional smart code groups registered by add-ons.
Parameters
$extendedCodesArray - Default[]
Usage:
add_filter('fluent_crm/extended_smart_codes', function($codes) {
$codes[] = [
'title' => 'WooCommerce',
'shortcodes' => [
'{{woo.last_order_total}}' => 'Last Order Total'
]
];
return $codes;
});Source: app/Services/Helper.php
Bulk Actions & Filters
fluent_crm/custom_contact_bulk_actions
Add custom bulk actions to the contacts table dropdown.
Parameters
$actionsArray - Default[]
Usage:
add_filter('fluent_crm/custom_contact_bulk_actions', function($actions) {
$actions[] = [
'label' => __('Sync to External', 'fluent-crm'),
'value' => 'sync_external'
];
return $actions;
});Tip: Handle the action via the
fluent_crm/contact_bulk_action_{$actionName}dynamic filter.
Source: app/Hooks/Handlers/AdminMenu.php
fluent_crm/contact_bulk_action_limit
Filter the maximum number of contacts to process in a single bulk-action request.
Parameters
$limitINT - Default400. Values below1are clamped to1.$requestRequest Object - the incoming bulk-action request, so the limit can vary by action
Usage:
add_filter('fluent_crm/contact_bulk_action_limit', function($limit, $request) {
return 1000;
}, 10, 2);Source: app/Http/Controllers/SubscriberController.php
fluentcrm_advanced_filter_options
Filter the full array of advanced filter groups for the contact filter UI.
Parameters
$groupsArray - Filter group definitions
Usage:
add_filter('fluentcrm_advanced_filter_options', function($groups) {
// Add a custom filter group
$groups['my_filters'] = [
'label' => 'My Custom Filters',
'options' => [
['label' => 'Has Purchased', 'value' => 'has_purchased']
]
];
return $groups;
});Source: app/Services/Helper.php
fluentcrm_ajax_options_{$optionKey}
Supply the options of a searchable AJAX selector. The advanced contact filters, automation condition UIs and several funnel settings load their dropdown choices from the ajax-options REST endpoint; a handful of option keys (woo_categories, company_industries, company_types, users, …) are answered directly by OptionsController::getAjaxOptions(), and every other key falls through to this dynamic filter. The dynamic portion, $optionKey, is the option_key the selector component was configured with.
Core registers event_tracking_keys (app/Hooks/Handlers/EventTrackingHandler.php); FluentCampaign Pro registers around a dozen variants such as product_selector_lifterlms (fluentcampaign-pro/app/Services/Integrations/LifterLms/DeepIntegration.php), woo_coupons, edd_coupons, surecart_products and product_selector_pmpro.
Parameters
$optionsArray - always empty; return a list of option arrays, each with anidand atitle(display label). Some producers return extra keys — e.g. the Woo coupon provider usesnameinstead oftitlefor its specific selector component (the EDD coupon provider sticks toid/title) — butid/titleis the shape generic selectors expect$searchString - the term typed into the selector; filter your query with it$includedIdsArray|String - the values already selected in the UI (valuesrequest parameter); include them in the result so saved selections keep their labels
Usage:
add_filter('fluentcrm_ajax_options_my_products', function($options, $search, $includedIds) {
$products = my_plugin_search_products($search, (array) $includedIds);
foreach ($products as $product) {
$options[] = [
'id' => $product->id,
'title' => $product->name
];
}
return $options;
}, 10, 3);Source: app/Http/Controllers/OptionsController.php
CSV Export & Import Mapping
fluentcrm_csv_mimes
Filter the MIME-type whitelist a CSV upload must match when contacts (or companies) are imported (CsvController::upload() validates the file with a mimetypes: rule built from this list).
TIP
This filter matters on hosts whose PHP finfo reports unusual MIME types for CSV files — the default list already includes oddballs like application/vnd.ms-excel and application/octet-stream for that reason. If valid CSVs are rejected on a specific server, add the type that server reports.
Parameters
$mimesArray - Default['text/csv', 'text/plain', 'application/csv', 'text/comma-separated-values', 'application/excel', 'application/vnd.ms-excel', 'application/vnd.msexcel', 'text/anytext', 'application/octet-stream', 'application/txt']
Usage:
add_filter('fluentcrm_csv_mimes', function($mimes) {
$mimes[] = 'application/x-csv';
return $mimes;
});Source: app/Functions/helpers.php (fluentcrmCsvMimes(), consumed by app/Http/Controllers/CsvController.php)
fluent_crm/subscriber_table_columns
Filter the contact columns offered as mapping targets when a CSV is uploaded for import (CsvController::upload()). It does not affect CSV export.
Parameters
$columnsArray - a plain list of column slugs a CSV header can be mapped onto
Usage:
add_filter('fluent_crm/subscriber_table_columns', function($columns) {
$columns[] = 'custom_field';
return $columns;
});Source: app/Http/Controllers/CsvController.php
fluentcrm_user_map_data
Filter the Subscriber data array when mapping a WordPress user to a CRM contact during sync.
Parameters
$subscriberArray - Subscriber data being mapped$user\WP_User - WordPress user object
Usage:
add_filter('fluentcrm_user_map_data', function($subscriber, $user) {
$subscriber['company_id'] = get_user_meta($user->ID, 'company_id', true);
return $subscriber;
}, 10, 2);Source: app/Services/Helper.php
fluentcrm_update_wp_user_email_on_change
Control whether a CRM email change is pushed to the linked WordPress user. It is consulted in two places:
Subscribermodel — when a saved contact's email no longer matches its linked WP user, returningtruewrites the new address onto the WP user viawp_update_user().SubscriberController— when a contact is edited to an email that matches no WP user, returningtruekeeps the contact linked to its existing WP user instead of unlinking it.
Parameters
$updateBoolean - Defaultfalse
Usage:
add_filter('fluentcrm_update_wp_user_email_on_change', function($update) {
return true; // Sync email changes to WP user
});Source: app/Models/Subscriber.php, app/Http/Controllers/SubscriberController.php
fluent_crm/get_import_driver_{$driver}
First phase of a custom contact-import driver: build the configuration screen. Any import driver that is not the built-in users (or CSV) handler is dispatched through this dynamic filter by ImporterController::getDriver(). The dynamic portion, $driver, is the key the driver was registered under on fluent_crm/import_providers — without that registration the driver never shows up in the import UI.
The controller calls the same filter twice in the wizard:
- Screen definition — return
['config' => [...defaults...], 'fields' => [...field definitions...]]describing the driver's settings form. - Summary/preview — when the request carries
summary, return['import_info' => ['subscribers' => [...], 'total' => N, 'has_list_config' => true, 'has_status_config' => true, 'has_update_config' => true, 'has_silent_config' => true]]so the wizard can show a preview and the standard list/status/update options.
Returning false (the default) or a WP_Error aborts with "Sorry no driver found for this import" (or the WP_Error message). The actual row processing happens in the second hook, fluent_crm/post_import_driver_{$driver}.
TIP
FluentCampaign Pro's fluentcampaign-pro/app/Services/Integrations/BaseImporter.php wires both phases for its LMS/membership importers; PMProImporter in the same directory is a complete reference implementation of the two-phase contract.
Parameters
$responseBoolean|Array|\WP_Error - Defaultfalse$requestRequest Object - the current wizard request; readconfigandsummaryfrom it
Usage:
add_filter('fluent_crm/get_import_driver_my_source', function($response, $request) {
if ($request->get('summary')) {
return [
'import_info' => [
'subscribers' => my_source_preview_rows(5),
'total' => my_source_total(),
'has_list_config' => true,
'has_status_config' => true,
'has_update_config' => true,
'has_silent_config' => true
]
];
}
return [
'config' => ['import_type' => 'all'],
'fields' => [
'import_type' => [
'label' => __('Import by', 'my-plugin'),
'type' => 'input-radio',
'options' => [
['id' => 'all', 'label' => __('All Customers', 'my-plugin')]
]
]
]
];
}, 10, 2);Source: app/Http/Controllers/ImporterController.php
fluent_crm/post_import_driver_{$driver}
Second phase of a custom contact-import driver: process one page of the actual import. ImporterController::importData() fires this repeatedly — once per batch — with the config collected by fluent_crm/get_import_driver_{$driver} and an incrementing page number, until the returned progress data reports no more pages. Import your batch (Pro's importers use Subscriber::import() with a limit of 100 users per page) and return the progress array the wizard polls on.
Returning false (the default) or a WP_Error aborts with an error message, so an unrecognized config is safe to reject.
Parameters
$responseBoolean|Array|\WP_Error - Defaultfalse. On success return progress data:['page_total' => ..., 'record_total' => ..., 'has_more' => bool, 'current_page' => $page, 'next_page' => $page + 1]$configArray - the driver config the user filled in on the screen from phase one$pageINT - the 1-based batch number for this request
Usage:
add_filter('fluent_crm/post_import_driver_my_source', function($response, $config, $page) {
$perPage = 100;
$total = my_source_total();
my_source_import_batch($config, $page, $perPage);
return [
'page_total' => ceil($total / $perPage),
'record_total' => $total,
'has_more' => $total > ($page * $perPage),
'current_page' => $page,
'next_page' => $page + 1
];
}, 10, 3);Source: app/Http/Controllers/ImporterController.php