---
title: "Value objects — Campaigns for Laravel | Roundly"
description: "Campaign, CampaignRecipient and CampaignProgress — constructors, fields and their toArray() shapes."
url: https://roundly-consulting.com/open-source/docs/campaigns-for-laravel/value-objects
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Campaigns for Laravel](https://roundly-consulting.com/open-source/docs/campaigns-for-laravel.md)

# Value objects

The facade, the manager and every store speak three plain PHP value objects — no Eloquent model involved, whichever store you use:

```php
use RoundlyConsulting\Campaigns\Campaign;
use RoundlyConsulting\Campaigns\CampaignProgress;
use RoundlyConsulting\Campaigns\CampaignRecipient;
use RoundlyConsulting\Campaigns\Enums\CampaignStatus;

new Campaign(
    uuid: 'e184d08f-5081-4fbb-9604-7a2460c3fb3a',
    subject: 'Our spring collection is here',
    content: '<p>Hello, the spring collection just landed.</p>',
    fromName: 'Example Shop',
    fromAddress: 'news@example.com',
    progress: new CampaignProgress,   // optional — Created, every counter 0
    startedAt: null,                  // optional ?Carbon
    endedAt: null,                    // optional ?Carbon
    batch: null,                      // optional Laravel batch id, set by prepare()
);

new CampaignRecipient(
    uuid: '7f3eb754-709e-4837-b82a-49c83223eed6',
    name: 'Ana Horvat',
    reachableAt: 'ana@example.com',   // an email address, phone number or any route
    hasBeenProcessed: false,          // optional
    errorOccured: false,              // optional
    errorMessage: null,               // optional
    campaignUuid: null,               // optional — set when the recipient is added to a campaign
);

new CampaignProgress(status: CampaignStatus::Created, sent: 0, pending: 0, total: 0, failed: 0);
```

- Campaign — uuid, subject, content, fromName, fromAddress, progress, startedAt, endedAt and batch (the Laravel batch id).
- CampaignRecipient — uuid, name, reachableAt, hasBeenProcessed, errorOccured, errorMessage (null when there is no error) and campaignUuid (set once it is added to a campaign), plus belongsTo($campaignUuid).
- CampaignProgress — status, sent (delivered), failed, pending (no outcome yet) and total, plus percentage() (share delivered, 0–100), remaining(), isRunning() and isComplete().

The flag is spelled errorOccured (column error\_occured) throughout the package — use that exact name.

## Array form

toArray() returns JSON-ready arrays — dates as ISO 8601 strings, the status as its value, remaining and percentage included:

```php
$campaign->toArray();
// [
//     'uuid' => 'e184d08f-5081-4fbb-9604-7a2460c3fb3a',
//     'subject' => 'Our spring collection is here',
//     'content' => '<p>Hello, the spring collection just landed.</p>',
//     'fromName' => 'Example Shop',
//     'fromAddress' => 'news@example.com',
//     'progress' => [
//         'status' => 'Completed',
//         'sent' => 2,
//         'failed' => 0,
//         'pending' => 0,
//         'total' => 2,
//         'remaining' => 0,
//         'percentage' => 100.0,
//     ],
//     'startedAt' => '2026-03-02T09:00:00+00:00',
//     'endedAt' => '2026-03-02T09:00:04+00:00',
//     'batch' => '9d3c6a1e-…',
// ]

$recipient->toArray();
// [
//     'uuid' => '7f3eb754-709e-4837-b82a-49c83223eed6',
//     'name' => 'Ana Horvat',
//     'reachableAt' => 'ana@example.com',
//     'hasBeenProcessed' => true,
//     'errorOccured' => false,
//     'errorMessage' => null,
//     'campaignUuid' => 'e184d08f-5081-4fbb-9604-7a2460c3fb3a',
// ]
```

## 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 crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## 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.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/campaigns-for-laravel.md)
