Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ $event = new CloudEvent(
id: uniqid(),
subject: 'user-123',
time: CloudEvent::now(),
datacontenttype: 'application/json',
data: [
'userId' => '123',
'email' => 'user@example.com',
Expand All @@ -49,7 +48,7 @@ $event = new CloudEvent(
);
```

When using the constructor, only `type`, `source` and `id` are required. All other attributes are optional. Arrays passed to `CloudEvent::fromArray()` must also carry an explicit `specversion`.
When using the constructor, only `type`, `source` and `id` are required. All other attributes are optional. `datacontenttype` defaults to `application/json`; pass `null` to leave it unset. Arrays passed to `CloudEvent::fromArray()` must also carry an explicit `specversion`.

`CloudEvent::now()` returns the current time as an RFC 3339 UTC timestamp with millisecond precision (e.g., `2025-11-07T10:00:00.123Z`), ready to use as the `time` attribute.

Expand Down Expand Up @@ -136,7 +135,7 @@ The `CloudEvent` class supports the following context attributes according to th
- **source** (required): URI-reference identifying the context in which the event happened (e.g., "https://example.com/user-service")
- **specversion** (required): CloudEvents specification version (default: "1.0")
- **type** (required): Event type identifier, ideally reverse-DNS prefixed (e.g., "com.example.user.created")
- **datacontenttype** (optional): RFC 2046 content type of the data field (e.g., "application/json")
- **datacontenttype** (optional): RFC 2046 content type of the data field (constructor default: "application/json")
- **dataschema** (optional): URI identifying the schema that data adheres to
- **subject** (optional): Subject of the event in the context of the source
- **time** (optional): Timestamp of when the occurrence happened (RFC 3339 format)
Expand Down
9 changes: 7 additions & 2 deletions src/CloudEvents/CloudEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class CloudEvent
* @param string $specversion CloudEvents spec version (default: "1.0")
* @param string|null $subject Optional subject of the event in the context of the source
* @param string|null $time Optional event timestamp in RFC 3339 format
* @param string|null $datacontenttype Optional content type of data (RFC 2046, e.g., "application/json")
* @param string|null $datacontenttype Content type of data (RFC 2046, default: "application/json"); pass null to leave it unset
* @param mixed $data Optional event payload of any type
* @param string|null $dataschema Optional URI identifying the schema that data adheres to
* @param array<string, mixed> $extensions Extension attributes (lowercase alphanumeric names, boolean/integer/string values)
Expand All @@ -58,7 +58,7 @@ public function __construct(
public readonly string $specversion = '1.0',
public readonly ?string $subject = null,
public readonly ?string $time = null,
public readonly ?string $datacontenttype = null,
public readonly ?string $datacontenttype = 'application/json',
public readonly mixed $data = null,
public readonly ?string $dataschema = null,
public readonly array $extensions = []
Expand All @@ -81,6 +81,11 @@ public static function now(): string
/**
* Create CloudEvent from array
*
* Unlike the constructor, datacontenttype is not defaulted here: a
* parsed event keeps the wire form, so an absent attribute stays
* absent (per the JSON format, absent datacontenttype already
* implies a JSON payload).
*
* @param array<string, mixed> $array
* @return self
* @throws InvalidArgumentException
Expand Down
19 changes: 16 additions & 3 deletions tests/CloudEvents/CloudEventTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,23 @@ public function testConstructorWithDefaults(): void
$this->assertNull($event->subject);
$this->assertEquals('test-id', $event->id);
$this->assertNull($event->time);
$this->assertNull($event->datacontenttype);
$this->assertEquals('application/json', $event->datacontenttype);
$this->assertNull($event->data);
}

public function testDatacontenttypeAllowsExplicitNull(): void
{
$event = new CloudEvent(
type: 'test.event',
source: 'test-service',
id: 'test-id',
datacontenttype: null
);

$this->assertNull($event->datacontenttype);
$this->assertArrayNotHasKey('datacontenttype', $event->toArray());
}

public function testFromArray(): void
{
$data = [
Expand Down Expand Up @@ -228,11 +241,11 @@ public function testToArrayOmitsAbsentOptionalAttributes(): void
'specversion' => '1.0',
'type' => 'test.event',
'source' => 'test-service',
'id' => 'test-id'
'id' => 'test-id',
'datacontenttype' => 'application/json'
], $array);
$this->assertArrayNotHasKey('subject', $array);
$this->assertArrayNotHasKey('time', $array);
$this->assertArrayNotHasKey('datacontenttype', $array);
$this->assertArrayNotHasKey('data', $array);
}

Expand Down
Loading