All packages
Contacts for Laravel
The HasContacts trait
Add the HasContacts trait to any Eloquent model — a user, a company, an order. No schema change per model:
use Illuminate\Database\Eloquent\Model;
use RoundlyConsulting\Contacts\Concerns\HasContacts;
class User extends Model
{
use HasContacts;
}Adding contacts
The trait is sugar over the same manager the Contacts facade uses — every helper goes through it, so values are normalized and validated, auto-primary applies, events fire and Contacts::fake() records the call:
use RoundlyConsulting\Contacts\DataTransferObjects\ContactData;
use RoundlyConsulting\Contacts\Enums\ContactType;
// Add — normalized + validated, primary guaranteed unique per kind.
$user->addEmail('[email protected] ', label: 'Work', primary: true);
$user->addPhone('+421 900 000 000', label: 'Mobile');
$user->addUrl('example.com');
$user->addAddress('12 Main St');
// Any kind, from a DTO
$user->addContact(new ContactData(ContactType::Social, '@janedoe', label: 'Mastodon'));- addEmail(), addPhone(), addUrl(), addAddress() — each takes (string $value, ?string $label = null, bool $primary = false).
- addContact(ContactData $data) — any kind, including registered custom kinds.
- addStructuredAddress(AddressData $data, ?string $label = null, bool $primary = false) — see Structured addresses.
Reading contacts
$user->primaryEmail()?->value; // '[email protected]'
$user->primaryPhone()?->value; // '+421900000000'
$user->primaryContact(ContactType::Url); // ?Contact — enum or string kind
$user->contactsOfType('phone'); // ordered EloquentCollection<Contact>
$user->contactBook(); // the ContactBook — same as Contacts::for($user)
$user->contacts; // Collection — every contact
$user->contacts()->primary()->verified()->get(); // scopes chain on the relation- contacts() — the MorphMany relation; every Contact scope chains on it.
- contactsOfType(ContactType|string) — one kind, ordered by position then id.
- primaryContact(ContactType|string) — the primary of a kind, or null.
- primaryEmail() / primaryPhone() — shortcuts for the two most common kinds.
- contactBook() — the owner’s ContactBook, the same object Contacts::for($user) returns.
The Contact model
Each Contact exposes its kind, value, flags and metadata:
$contact->type; // ContactType::Email
$contact->kind; // 'email' — the raw stored kind
$contact->value; // '[email protected]'
$contact->label; // 'Work' — free-text label for this one contact
$contact->name; // display name ('' when not set)
$contact->category; // ?string
$contact->is_primary; // bool
$contact->position; // int — order within the kind
$contact->verified_at; // ?Carbon
$contact->meta; // Collection (JSON column)
$contact->owner; // the owning model (MorphTo), or null
$contact->isVerified(); // bool
$contact->kindLabel(); // 'Email'
$contact->kindIcon(); // 'envelope'Show your open-source love
This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.
More ways to support, including cryptoBy donating, you agree to our donation terms.
Want this built into your product?
We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.