All packages
Contacts for Laravel
Syncing contacts
Contacts::for($owner)->sync() is built for a “manage contacts” form: hand it the full list for one kind and it works out what to add, update and remove:
use RoundlyConsulting\Contacts\Facades\Contacts;
use RoundlyConsulting\Contacts\DataTransferObjects\ContactData;
use RoundlyConsulting\Contacts\Enums\ContactType;
$phones = Contacts::for($user)->sync(ContactType::Phone, [
new ContactData(ContactType::Phone, '+421900000000', label: 'Mobile', isPrimary: true),
new ContactData(ContactType::Phone, '+421900111222', label: 'Office'),
]);
$phones->pluck('position'); // [0, 1] — input order- Existing contacts whose normalized value matches an item are updated in place — label, category, meta and position; isPrimary: true promotes one.
- Items with no match are created through the add action (normalized, validated, auto-primary).
- Existing contacts of that kind missing from the list are soft-deleted.
- If the primary is among the deleted and no item asks for isPrimary, the first synced contact becomes the primary (auto_primary) — the returned collection already reflects it.
- position follows input order, and the returned collection keeps that order.
- Every change fires its own ContactAdded, ContactUpdated or ContactDeleted event.
Each item is stored under the kind you pass to sync(), whatever type the DTO carries. Syncing an empty list removes every contact of that kind.
From a controller
public function update(Request $request): RedirectResponse
{
$validated = $request->validate([
'phones' => ['array'],
'phones.*.value' => ContactType::Phone->rules(),
'phones.*.label' => ['nullable', 'string'],
]);
Contacts::for($request->user())->sync(ContactType::Phone, array_map(
fn (array $row) => new ContactData(ContactType::Phone, $row['value'], label: $row['label'] ?? null),
$validated['phones'] ?? [],
));
return back();
}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.