# Contacts API The Contacts API provides methods for creating, finding, and managing contacts (subscribers). ## Initialization ```php $contactApi = FluentCrmApi('contacts'); ``` Returns an instance of `FluentCrm\App\Api\Classes\Contacts`. --- ## Methods ### getContact() Find a contact by email address or subscriber ID. ```php $contact = $contactApi->getContact($idOrEmail); ``` **Parameters** - `$idOrEmail` `int|string` — Subscriber ID or email address **Returns** `false` | [Subscriber](/database/models/subscriber) --- ### getContactByUserRef() Find a contact by WordPress user ID or email. If a user ID is provided, looks up by `user_id` first, then falls back to the user's email address. Auto-links the `user_id` field if the contact is found by email. ```php $contact = $contactApi->getContactByUserRef($userIdOrEmail); ``` **Parameters** - `$userIdOrEmail` `int|string` — WordPress user ID or email **Returns** `false` | [Subscriber](/database/models/subscriber) --- ### getContactByUserId() Find a contact by WordPress user ID only (no email fallback). ```php $contact = $contactApi->getContactByUserId($userId); ``` **Parameters** - `$userId` `int` — WordPress user ID **Returns** `false` | [Subscriber](/database/models/subscriber) --- ### getCurrentContact() Get the current logged-in user's contact profile. Falls back to the secure cookie for logged-out users if enabled. ```php $contact = $contactApi->getCurrentContact($cached = true, $useSecureCookie = false); ``` **Parameters** - `$cached` `bool` — Use static cache on repeated calls within the same request - `$useSecureCookie` `bool` — Check `fc_hash_secure` cookie for logged-out users **Returns** `false` | [Subscriber](/database/models/subscriber) --- ### getContactBySecureHash() Find a contact by their long-lived secure hash (from email links). ```php $contact = $contactApi->getContactBySecureHash($hash); ``` **Parameters** - `$hash` `string|null` **Returns** `null` | [Subscriber](/database/models/subscriber) --- ### getContactByManagedSecureHash() Find a contact by their managed secure hash (auto-rotates every 30 days). ```php $contact = $contactApi->getContactByManagedSecureHash($hash); ``` **Parameters** - `$hash` `string|null` **Returns** `null` | [Subscriber](/database/models/subscriber) --- ### createOrUpdate() Create a new contact or update an existing one. Matches by `email` address. ```php $contact = $contactApi->createOrUpdate($data, $forceUpdate = false, $deleteOtherValues = false, $sync = false); ``` **Parameters** - `$data` `array` — Contact data (must include `email`). Can include `tags`, `lists`, `detach_tags`, `detach_lists`, and `custom_values`. - `$forceUpdate` `bool` — If `true`, updates status even on existing contacts regardless of their current status - `$deleteOtherValues` `bool` — If `true`, replaces all custom field data (deletes fields not in the new data) - `$sync` `bool` — Reserved for future use **Returns** `false` | [Subscriber](/database/models/subscriber) **Example:** ```php $contactApi = FluentCrmApi('contacts'); $contact = $contactApi->createOrUpdate([ 'first_name' => 'John', 'last_name' => 'Doe', 'email' => 'john@example.com', // required 'status' => 'subscribed', 'tags' => [1, 2, 'Dynamic Tag'], // IDs, slugs, or titles 'lists' => [4, 'Dynamic List'], // IDs, slugs, or titles 'detach_tags' => [6, 'another_tag'], // remove these tags 'detach_lists' => [10, 'list_slug'], // remove these lists 'custom_values' => [ 'custom_field_slug' => 'value', ] ]); // Send double opt-in email if status is pending if ($contact && $contact->status == 'pending') { $contact->sendDoubleOptinEmail(); } ``` For `tags` and `lists` you can pass IDs, slugs, or titles (or mix them). String values that don't match an existing tag/list will create a new one. **Fillable fields:** | Field | Type | Notes | |-------|------|-------| | `email` | String | **Required** for creation | | `first_name` | String | | | `last_name` | String | | | `prefix` | String | Name prefix (Mr, Mrs, etc.) | | `user_id` | Integer | WordPress user ID | | `company_id` | Integer | Primary company ID | | `status` | String | `pending`, `subscribed`, `unsubscribed`, `transactional`, `bounced`, `complained` | | `contact_type` | String | `lead`, `customer` | | `source` | String | | | `avatar` | String/URL | Custom photo URL | | `date_of_birth` | Date | `Y-m-d` format | | `phone` | String | | | `timezone` | String | ISO timezone string | | `address_line_1` | String | | | `address_line_2` | String | | | `city` | String | | | `state` | String | | | `postal_code` | String | | | `country` | String | | | `ip` | String | | | `latitude` | Decimal | | | `longitude` | Decimal | | | `last_activity` | DateTime | | | `updated_at` | DateTime | | --- ### query() Get a `ContactsQuery` builder instance for advanced contact queries. ```php $query = $contactApi->query($args); ``` **Parameters** - `$args` `array` — Query arguments **Returns** `\FluentCrm\App\Services\ContactsQuery` --- ### getCustomFields() Get the custom field definitions for contacts. ```php $fields = $contactApi->getCustomFields($types = [], $byOptions = false); ``` **Parameters** - `$types` `array` — Filter by field types (e.g., `['text', 'select']`). Empty array returns all. - `$byOptions` `bool` — If `true`, returns simplified `[['id' => slug, 'title' => label], ...]` format **Returns** `array` --- ### getInstance() Get the underlying [Subscriber](/database/models/subscriber) model for direct Eloquent-style queries. ```php $subscriberModel = $contactApi->getInstance(); ``` **Returns** `\FluentCrm\App\Models\Subscriber` --- ### Proxy Methods The Contacts API proxies these methods to the underlying Subscriber model via `__call()`: - `all()` — Get all contacts - `get()` — Get contacts collection - `find($id)` — Find by primary key (accepts single ID or array) - `first()` — Get the first contact - `paginate($perPage)` — Paginate results --- ## Filtering Contacts Use `getInstance()` to access the full query builder: ```php $contactApi = FluentCrmApi('contacts'); // Get subscribed contacts $subscribed = $contactApi->getInstance() ->where('status', 'subscribed') ->get(); // Get contacts in multiple statuses $contacts = $contactApi->getInstance() ->whereIn('status', ['unsubscribed', 'pending']) ->get(); // Get contacts by tag IDs $tagged = $contactApi->getInstance() ->filterByTags([1, 2]) ->get(); // Get contacts by list IDs $listed = $contactApi->getInstance() ->filterByLists([1, 2]) ->get(); // Search contacts $results = $contactApi->getInstance() ->searchBy('search_string') ->get(); // Paginate $paginated = $contactApi->getInstance() ->where('status', 'subscribed') ->paginate(15); ``` --- ## Subscriber Model Methods Once you have a [Subscriber](/database/models/subscriber) instance, these methods are available: ### attachTags() / detachTags() ```php $subscriber->attachTags([1, 2, 'tag_title_or_slug']); $subscriber->detachTags([1, 2, 'tag_title_or_slug']); ``` Accepts tag IDs, slugs, or titles. Returns `Subscriber`. ### attachLists() / detachLists() ```php $subscriber->attachLists([1, 2, 'list_slug']); $subscriber->detachLists([1, 2, 'list_slug']); ``` Accepts list IDs, slugs, or titles. Returns `Subscriber`. ### custom_fields() Get the contact's custom field values. ```php $customData = $subscriber->custom_fields(); // Returns array ``` ### stats() Get sent emails, opens, and clicks count. ```php $stats = $subscriber->stats(); // Returns array ``` ### sendDoubleOptinEmail() Send a double opt-in confirmation email (only works if contact status is `pending`). ```php $subscriber->sendDoubleOptinEmail(); // Returns bool ``` ### hasAnyTagId() / hasAnyListId() Check if a contact belongs to any of the given tags or lists. ```php $inTags = $subscriber->hasAnyTagId([1, 2, 'tag_slug']); $inLists = $subscriber->hasAnyListId([1, 2, 'list_slug']); // Returns bool ``` ### unsubscribeReason() / unsubscribeReasonDate() Get the unsubscribe reason and date if the contact unsubscribed. ```php $reason = $subscriber->unsubscribeReason(); // string $date = $subscriber->unsubscribeReasonDate(); // string or empty ``` ### getWpUser() / getWpUserId() Get the linked WordPress user. ```php $user = $subscriber->getWpUser(); // \WP_User or null $userId = $subscriber->getWpUserId(); // int or null ``` **Source:** `app/Api/Classes/Contacts.php`, `app/Models/Subscriber.php`