Building a private WordPress plugin for our own managed client sites.
Iβm building a private WordPress plugin for our own managed client sites. It reconciles FluentCRM contacts and Fluent Forms submissions into an external reporting/export workflow. It does not modify FluentCRM contact state during export, but it does need to read contact data, contact custom fields, tags/lists, and batch-select contacts with a specific tag/status.
I want to avoid relying on unstable internals if there is a preferred public API surface.
Could you advise on the recommended/stable way for a third-party plugin to do the following?
-
Read a FluentCRM contact by contact ID, including standard fields and custom field values.
-
Read the global FluentCRM contact custom-field definitions.
-
Determine whether a specific contact has a specific tag or list.
-
Query contacts that have a specific tag/list for batch processing.
-
Is direct use of FluentCRM Eloquent models and relationships, such as querying contacts with
whereHas('tags', ...), considered supported/stable for plugin integrations, or should that be avoided?
We are currently using the FluentCRM API where available, but candidate discovery by tag is the area where we are unsure whether the model relationship is safe to depend on across FluentCRM updates.
This is for an internal/private plugin, not a public repository plugin. Iβm mainly looking for guidance on which integration surface is safest across future FluentCRM releases.
For a read-only reconciliation/export integration like yours, almost everything you need is available through our stable PHP API wrapper, and I'd steer you toward that surface over raw model/relationship queries wherever there's a choice.
Here's the recommended approach for each item.
1: Read a contact by ID, including standard + custom fields
Use the contacts API wrapper. getContact() accepts an ID or email and returns the Subscriber model:
$contact = FluentCrmApi('contacts')->getContact($contactId); // int ID or email string
if (!$contact) {
// not found
}
// Standard fields are model attributes:
$email = $contact->email;
$firstName = $contact->first_name;
$status = $contact->status;
// Custom field values (keyed by field slug, formatted/filtered):
$customValues = $contact->custom_fields();
custom_fields() is the supported accessor β it resolves the global definitions, pulls the contact's values, and runs them through our formatting filter, so you get a clean slug => value array.
2: Read the global custom-field definitions
Two equivalent stable options. The API wrapper is the one I'd recommend:
$fields = FluentCrmApi('contacts')->getCustomFields();
// or the helper:
$fields = fluentcrm_get_custom_contact_fields();
Each definition includes slug, label, type, and (for select/radio/checkbox types) options. getCustomFields() also takes an optional $types filter and a $byOptions flag if you want a simplified id/title list.
3: Does a contact have a specific tag/list?
The Subscriber model exposes dedicated, stable helpers for this β use them instead of inspecting the relationship collection yourself:
$contact->hasAnyTagId([$tagId]); // true if the contact has ANY of the given tag IDs
$contact->hasAnyListId([$listId]); // same for lists
They accept arrays, so they double as "has any of these" checks.
On direct Eloquent + whereHas('tags', ...)
You can use this as it's a stable method from version 1.