Skip to content

CRM Contact Entity

The CRM Contact entity (crm_contact) is the core entity of the CRM system, representing individuals, organizations, and households that your organization interacts with. Contacts are revisionable, publishable content entities that support flexible contact management with multiple communication channels.

Overview

A contact represents any entity (person, organization, or household) that can be contacted or has a relationship with your organization. The contact system is designed to be flexible and extensible, supporting various types of contacts with their specific attributes and contact details.

Key Features

  • Multi-bundle support: Three built-in contact types (Person, Organization, Household)
  • Revisionable: Full revision tracking with metadata
  • Publishable: Status-based visibility control
  • Contact details: Structured email, telephone, and address management
  • Computed fields: Age calculation for persons
  • Flexible naming: Advanced name formatting for persons
  • External identifiers: Support for external system integration
  • Relationships: Connect contacts to each other through relationships
  • Comments integration: Built-in commenting system

Contact Types (Bundles)

Person

Individual people with personal attributes.

Specific Fields: - full_name: Structured name field with components (title, given, middle, family, generational, credentials) - preferred_name: How the person prefers to be addressed - aliases: Alternative names or nicknames - comment: Internal notes about the person

Date Fields (Person-specific labels): - start_date: Date of birth - end_date: Date of death

Computed Fields: - age: Automatically calculated from date of birth

Organization

Businesses, non-profits, government agencies, and other institutional entities.

Specific Fields: - aliases: Alternative names, DBA names, or acronyms - comment: Internal notes about the organization

Date Fields (Organization-specific labels): - start_date: Date of establishment - end_date: Date of dissolution

Household

Family units or groups of people living at the same address.

Specific Fields: - comment: Internal notes about the household

Date Fields (Household-specific labels): - start_date: Date of establishment - end_date: Date of dissolution

Base Fields

All contact types share these common fields:

Core Identification

  • name (required): Display name for the contact
  • For persons: Auto-generated from full_name field using configurable format
  • For organizations/households: Manually entered
  • id: Unique internal identifier
  • uuid: Universally unique identifier
  • bundle: Contact type (person/organization/household)

Status and Dates

  • status: Active/inactive status (boolean)
  • start_date: Beginning date (context varies by bundle)
  • end_date: End date (context varies by bundle)
  • created: Entity creation timestamp
  • changed: Last modification timestamp

Contact Details

  • emails: Multiple email addresses with types (work, home, etc.)
  • telephones: Multiple phone numbers with types (mobile, work, fax, etc.)
  • addresses: Multiple addresses with types (home, work, billing, etc.)

Each contact detail is a separate entity with its own type classification, allowing for flexible organization and display.

Revision System

  • revision_id: Current revision identifier
  • revision_uid: User who created the revision
  • revision_timestamp: When the revision was created
  • revision_log: Description of changes

Entity Features

Automatic Name Generation (Persons)

For person contacts, the name field is automatically generated from the full_name field using a configurable name format. The system supports: - Multiple name components (title, given, middle, family, generational, credentials) - Preferred name integration - Alternative names from aliases - Configurable name formatting patterns

Computed Age Field

Person contacts include an automatically computed age field that calculates the current age based on the date of birth (start_date).

Revision Management

All contacts are revisionable by default: - New revisions created on every save - Complete revision history with user and timestamp tracking - Configurable per contact type

Access Control

Built-in access control system with: - View, create, edit, delete permissions - Bundle-specific permissions - Integration with Drupal's permission system

Contact Details Integration

Contacts integrate seamlessly with the Contact Detail system:

---
title: Contact Detail Integration
---
erDiagram
    Contact ||--o{ Email: has
    Contact ||--o{ Telephone: has
    Contact ||--o{ Address: has
    Contact {
        int id
        string name
        string bundle
        boolean status
    }
    Email {
        int id
        string email
        string type
    }
    Telephone {
        int id
        string telephone
        string type
    }
    Address {
        int id
        string address_line1
        string city
        string type
    }

Configuration Options

Contact Types

  • Create custom contact types beyond the default three
  • Configure fields per contact type
  • Set default revision behavior
  • Configure date field labels
  • Lock/unlock contact types

Name Formatting (Persons)

Configure how person names are formatted: - Default format patterns - Component requirements - Display preferences

Field Configuration

  • Add custom fields to any contact type
  • Configure display modes
  • Set up form displays
  • Configure field permissions

Administrative Features

List Management

  • Sortable contact lists
  • Filter by contact type
  • Bulk operations support
  • Search functionality

Form Integration

  • Inline entity forms for contact details
  • Auto-complete for contact selection
  • Validation and constraints
  • Multi-step forms support

API Examples

Creating a Person Contact

use Drupal\crm\Entity\Contact;

$contact = Contact::create([
  'bundle' => 'person',
  'full_name' => [
    'title' => 'Dr.',
    'given' => 'Jane',
    'family' => 'Smith',
    'credentials' => 'PhD',
  ],
  'preferred_name' => 'Jane',
  'status' => TRUE,
  'start_date' => '1980-05-15',
]);

$contact->save();

Adding Contact Details

use Drupal\crm\Entity\ContactDetail;

// Create email
$email = ContactDetail::create([
  'bundle' => 'email',
  'email' => 'jane.smith@example.com',
  'type' => 'work',
]);
$email->save();

// Add to contact
$contact->get('emails')->appendItem($email);
$contact->save();

Loading and Accessing Contact Data

$contact = Contact::load($contact_id);

// Get formatted name
$name = $contact->get('name')->value;

// Get age (computed field for persons)
if ($contact->bundle() === 'person') {
  $age = $contact->get('age')->value;
}

// Access contact details
$emails = $contact->get('emails')->referencedEntities();
foreach ($emails as $email_entity) {
  $email = $email_entity->get('email')->value;
  $type = $email_entity->get('type')->value;
}

Database Schema

---
title: Database Schema
---
classDiagram
  class crm_contact {
    int id
    uuid uuid
    string name
    bool status
    datetime start_date
    datetime end_date
    int revision_id
    string bundle
    int created
    int changed
  }

  class crm_contact_revision {
    int id
    int revision_id
    uuid uuid
    string name
    bool status
    datetime start_date
    datetime end_date
    int revision_uid
    int revision_timestamp
    string revision_log
  }

  class crm_contact__emails {
    int entity_id
    int revision_id
    int delta
    int target_id
  }

  class crm_contact__telephones {
    int entity_id
    int revision_id
    int delta
    int target_id
  }

  class crm_contact__addresses {
    int entity_id
    int revision_id
    int delta
    int target_id
  }

  class crm_contact__full_name {
    int entity_id
    int revision_id
    int delta
    string full_name_title
    string full_name_given
    string full_name_middle
    string full_name_family
    string full_name_generational
    string full_name_credentials
  }

  class crm_contact_detail {
    int id
    uuid uuid
    string type
    string name
    bool status
    int created
    int changed
  }

  crm_contact --> crm_contact__emails : emails
  crm_contact --> crm_contact__telephones : telephones
  crm_contact --> crm_contact__addresses : addresses
  crm_contact --> crm_contact__full_name : full_name
  crm_contact__emails --> crm_contact_detail : target_id
  crm_contact__telephones --> crm_contact_detail : target_id
  crm_contact__addresses --> crm_contact_detail : target_id
  crm_contact --> crm_contact_revision : revisions

Integration Points

Views Integration

  • Contact lists and displays
  • Relationship views
  • Administrative interfaces

Search Integration

  • Full-text search across contact fields
  • Faceted search by contact type
  • Advanced filtering options

REST API

  • Full CRUD operations via REST
  • JSON API support
  • Custom endpoints for specialized operations

External Systems

  • External identifier field for system integration
  • Import/export capabilities
  • Sync relationship management