-
-
Notifications
You must be signed in to change notification settings - Fork 50
FHIR DataTypes
All 32 DataType classes in src/DataType/. Every DataType extends the abstract DataType class which provides a recursive toArray() method — nested DataType objects serialize to clean FHIR JSON automatically.
namespace Satusehat\Integration\DataType;
abstract class DataType
{
public function toArray(): array;
protected function toArrayRecursive($value);
protected function bool(?bool $val): ?bool;
protected function str(?string $val): ?string;
protected function int(?int $val): ?int;
protected function float(?float $val): ?float;
protected function dt(?string $val): ?string;
}All subtypes override toArray() to handle their specific nested DataTypes. build() on every PayloadBuilder calls toArray() recursively.
Unique identifier with a system namespace.
use Satusehat\Integration\DataType\Identifier;
use Satusehat\Integration\DataType\Period;
$identifier = new Identifier(
system: 'https://fhir.kemkes.go.id/id/NIK',
value: '3312345678901234',
use: 'official',
type: null,
period: new Period(start: '2020-01-01', end: null),
);
// toArray():
// [
// 'system' => 'https://fhir.kemkes.go.id/id/NIK',
// 'value' => '3312345678901234',
// 'use' => 'official',
// 'period' => ['start' => '2020-01-01']
// ]| Property | Type | Description |
|---|---|---|
use |
?string |
usual, official, temp, nickname, anonymous, old, maiden
|
type |
?CodeableConcept |
Type of identifier |
system |
?string |
Namespace URI (e.g. https://fhir.kemkes.go.id/id/NIK) |
value |
?string |
The actual identifier value |
period |
?Period |
Time period the identifier is valid |
assigner |
?Reference |
Organization that assigned the identifier |
A human name with family, given, prefix, and suffix.
use Satusehat\Integration\DataType\HumanName;
use Satusehat\Integration\DataType\Period;
$name = new HumanName(
family: 'Doe',
given: ['John', 'Michael'],
use: 'official',
prefix: ['Dr.'],
suffix: ['PhD'],
text: null,
period: new Period(start: '2020-01-01'),
);
// toArray():
// [
// 'family' => 'Doe',
// 'given' => ['John', 'Michael'],
// 'use' => 'official',
// 'prefix' => ['Dr.'],
// 'suffix' => ['PhD'],
// 'period' => ['start' => '2020-01-01']
// ]| Property | Type | Description |
|---|---|---|
use |
?string |
usual, official, temp, nickname, anonymous, old, maiden
|
text |
?string |
Text representation of the full name |
family |
?string |
Family name (surname) |
given |
array |
Given names (first, middle) |
prefix |
array |
Prefix (e.g. Dr., Mr.) |
suffix |
array |
Suffix (e.g. PhD, Jr.) |
period |
?Period |
Time period the name is valid |
A physical address.
use Satusehat\Integration\DataType\Address;
$address = new Address(
use: 'home',
type: 'physical',
text: null,
line: ['Jl. Sudirman No.1', 'Lt. 5'],
city: 'Jakarta Selatan',
district: 'Kebayoran Baru',
state: 'DKI Jakarta',
postalCode: '12190',
country: 'ID',
);
// toArray():
// [
// 'use' => 'home',
// 'type' => 'physical',
// 'line' => ['Jl. Sudirman No.1', 'Lt. 5'],
// 'city' => 'Jakarta Selatan',
// 'district' => 'Kebayoran Baru',
// 'state' => 'DKI Jakarta',
// 'postalCode' => '12190',
// 'country' => 'ID'
// ]| Property | Type | Description |
|---|---|---|
use |
?string |
home, work, temp, old, billing
|
type |
?string |
postal, physical, both
|
text |
?string |
Text representation |
line |
array |
Street address lines |
city |
?string |
City/municipality |
district |
?string |
District (kecamatan) |
state |
?string |
State/province |
postalCode |
?string |
Postal code |
country |
?string |
Country (ISO 3166-1 alpha-2) |
Phone, fax, email, or other contact.
use Satusehat\Integration\DataType\ContactPoint;
$phone = new ContactPoint(
system: 'phone',
value: '081234567890',
use: 'mobile',
rank: 1,
);
// toArray():
// [
// 'system' => 'phone',
// 'value' => '081234567890',
// 'use' => 'mobile',
// 'rank' => 1
// ]| Property | Type | Description |
|---|---|---|
system |
?string |
phone, fax, email, pager, url, sms, other
|
value |
?string |
The actual value |
use |
?string |
home, work, temp, old, billing
|
rank |
?int |
Preferred contact (1 = highest) |
A reference to another FHIR resource.
use Satusehat\Integration\DataType\Reference;
$ref = new Reference(
reference: 'Patient/12345678-1234-1234-1234-123456789012',
display: 'John Doe',
type: 'Patient',
);
// toArray():
// [
// 'reference' => 'Patient/12345678-1234-1234-1234-123456789012',
// 'display' => 'John Doe',
// 'type' => 'Patient'
// ]| Property | Type | Description |
|---|---|---|
reference |
?string |
The reference string (e.g. Patient/123) |
display |
?string |
Human-readable label |
type |
?string |
Resource type (e.g. Patient) |
A time range with start and end.
use Satusehat\Integration\DataType\Period;
$period = new Period(
start: '2024-01-01',
end: '2024-12-31',
);
// toArray():
// ['start' => '2024-01-01', 'end' => '2024-12-31']| Property | Type | Description |
|---|---|---|
start |
?string |
Start date/time (ISO 8601) |
end |
?string |
End date/time (ISO 8601) |
A single code from a terminology system.
use Satusehat\Integration\DataType\Coding;
$gender = new Coding(
system: 'http://hl7.org/fhir/administrative-gender',
code: 'male',
display: 'Male',
version: '4.0.1',
);
// toArray():
// [
// 'system' => 'http://hl7.org/fhir/administrative-gender',
// 'code' => 'male',
// 'display' => 'Male',
// 'version' => '4.0.1'
// ]| Property | Type | Description |
|---|---|---|
system |
?string |
The terminology system URI |
version |
?string |
Version of the code system |
code |
?string |
The code value |
display |
?string |
Human-readable display text |
A concept that may be defined by multiple Codings, with optional text.
use Satusehat\Integration\DataType\CodeableConcept;
use Satusehat\Integration\DataType\Coding;
$concept = new CodeableConcept(
coding: [
new Coding(
system: 'http://terminology.hl7.org/CodeSystem/condition-clinical',
code: 'active',
display: 'Active'
)
],
text: 'Active Condition'
);
// toArray():
// [
// 'coding' => [
// ['system' => '...', 'code' => 'active', 'display' => 'Active']
// ],
// 'text' => 'Active Condition'
// ]| Property | Type | Description |
|---|---|---|
coding |
Coding[] |
Array of Coding objects |
text |
?string |
Plain text representation |
Human-readable text, typically XHTML.
use Satusehat\Integration\DataType\Narrative;
$narrative = new Narrative(
status: 'generated',
div: '<div xmlns="http://www.w3.org/1999/xhtml">Patient John Doe</div>',
);
// toArray():
// [
// 'status' => 'generated',
// 'div' => '<div xmlns="http://www.w3.org/1999/xhtml">...</div>'
// ]Content attachment — data, URL, or reference.
use Satusehat\Integration\DataType\Attachment;
$attachment = new Attachment(
contentType: 'application/pdf',
language: 'id-ID',
data: base64_encode('PDF content here'),
url: null,
size: null,
hash: null,
title: 'Medical Report',
creation: '2024-01-15',
);A measured or measurable amount.
use Satusehat\Integration\DataType\Quantity;
$q = new Quantity(
value: 72,
comparator: null,
unit: 'beats/minute',
system: 'http://unitsofmeasure.org',
code: '/min',
);| Property | Type | Description |
|---|---|---|
value |
?float |
Numeric value |
comparator |
?string |
<, <=, >=, >
|
unit |
?string |
Human-readable unit |
system |
?string |
UCUM system URI |
code |
?string |
UCUM unit code |
Quantity constrained to a single value/unit (no comparator).
use Satusehat\Integration\DataType\SimpleQuantity;
$sq = new SimpleQuantity(
value: 500,
unit: 'mg',
system: 'http://unitsofmeasure.org',
code: 'mg',
);A range of values (low to high).
use Satusehat\Integration\DataType\Range;
use Satusehat\Integration\DataType\Quantity;
$range = new Range(
low: new Quantity(value: 60, unit: 'bpm', system: 'http://unitsofmeasure.org', code: '/min'),
high: new Quantity(value: 100, unit: 'bpm', system: 'http://unitsofmeasure.org', code: '/min'),
text: '60-100 bpm',
);A ratio of two quantities.
use Satusehat\Integration\DataType\Ratio;
use Satusehat\Integration\DataType\Quantity;
$ratio = new Ratio(
numerator: new Quantity(value: 500, unit: 'mg', system: 'http://unitsofmeasure.org', code: 'mg'),
denominator: new Quantity(value: 1, unit: 'tablet', system: null, code: null),
);All extend Quantity with domain-specific semantics:
use Satusehat\Integration\DataType\Age;
$age = new Age(value: 35, unit: 'years', system: 'http://unitsofmeasure.org', code: 'a');
use Satusehat\Integration\DataType\Distance;
$distance = new Distance(value: 10, unit: 'kilometers', system: 'http://unitsofmeasure.org', code: 'km');
use Satusehat\Integration\DataType\Duration;
$duration = new Duration(value: 7, unit: 'days', system: 'http://unitsofmeasure.org', code: 'd');
use Satusehat\Integration\DataType\Count;
$count = new Count(value: 3, unit: 'tablets', system: null, code: null);
use Satusehat\Integration\DataType\Money;
$money = new Money(value: 15000.00, currency: 'IDR');Event scheduling with repeat pattern.
use Satusehat\Integration\DataType\Timing;
use Satusehat\Integration\DataType\TimingRepeat;
$timing = new Timing(
event: ['2024-01-15T09:00:00+07:00'],
repeat: new TimingRepeat(
frequency: 3,
period: 1,
periodUnit: 'd',
timeOfDay: ['09:00:00', '13:00:00', '18:00:00'],
dayOfWeek: ['mon', 'tue', 'wed', 'thu', 'fri'],
),
code: new CodeableConcept(coding: [new Coding(
system: 'http://terminology.hl7.org/CodeSystem/v3-GTSAbbreviation',
code: 'BID',
display: 'BID'
)]),
);Repeat pattern for Timing events.
use Satusehat\Integration\DataType\TimingRepeat;
$repeat = new TimingRepeat(
frequency: 2,
frequencyMax: 4,
period: 1,
periodUnit: 'd', // s|min|h|d|wk|mo|a
dayOfWeek: ['mon', 'wed', 'fri'],
timeOfDay: ['08:00:00', '20:00:00'],
when: ['CM', 'AC'],
offset: 0,
);Medication dosage instruction.
use Satusehat\Integration\DataType\Dosage;
use Satusehat\Integration\DataType\DosageDoseAndRate;
use Satusehat\Integration\DataType\Quantity;
use Satusehat\Integration\DataType\CodeableConcept;
use Satusehat\Integration\DataType\Coding;
$dosage = new Dosage(
sequence: 1,
text: 'Amoxicillin 500mg — 3x1 sehari setelah makan',
timing: null,
route: new CodeableConcept(coding: [new Coding(
system: 'http://www.whocc.no/atc',
code: 'ORAL',
display: 'Oral'
)]),
doseAndRate: [
new DosageDoseAndRate(
doseQuantity: new Quantity(
value: 500,
unit: 'mg',
system: 'http://unitsofmeasure.org',
code: 'mg'
)
)
],
);Dose quantity and optional rate.
use Satusehat\Integration\DataType\DosageDoseAndRate;
use Satusehat\Integration\DataType\Quantity;
use Satusehat\Integration\DataType\CodeableConcept;
use Satusehat\Integration\DataType\Coding;
$doseRate = new DosageDoseAndRate(
type: new CodeableConcept(coding: [new Coding(
system: 'http://terminology.hl7.org/CodeSystem/dose-rate-type',
code: 'ordered',
display: 'Ordered'
)]),
doseQuantity: new Quantity(value: 500, unit: 'mg', system: 'http://unitsofmeasure.org', code: 'mg'),
);A text note with optional author and time.
use Satusehat\Integration\DataType\Annotation;
use Satusehat\Integration\DataType\Reference;
$note = new Annotation(
authorReference: new Reference(reference: 'Practitioner/10009880728', display: 'Dr. Smith'),
time: '2024-01-15T10:30:00+07:00',
text: 'Pasien mengeluh pusing sejak 3 hari terakhir',
);FHIR extension wrapper for extra data not covered by the base spec.
use Satusehat\Integration\DataType\Extension;
use Satusehat\Integration\DataType\CodeableConcept;
use Satusehat\Integration\DataType\Coding;
$ext = new Extension(
url: 'http://hl7.org/fhir/StructureDefinition/condition-assertedDate',
valueCodeableConcept: new CodeableConcept(coding: [new Coding(
system: 'http://hl7.org/fhir/valueset-condition-ver-status',
code: 'confirmed',
display: 'Confirmed'
)]),
);Digital signature.
use Satusehat\Integration\DataType\Signature;
use Satusehat\Integration\DataType\Coding;
use Satusehat\Integration\DataType\Reference;
$signature = new Signature(
type: [new Coding(
system: 'urn:iso-astm:E1762-2013',
code: '1.2.840.10065.1.12',
display: 'Author签名'
)],
when: '2024-01-15T12:00:00+07:00',
whoReference: new Reference(reference: 'Practitioner/10009880728'),
onBehalfOfReference: null,
);Related resources or citations.
use Satusehat\Integration\DataType\RelatedArtifact;
use Satusehat\Integration\DataType\Coding;
$citation = new RelatedArtifact(
type: 'citation',
label: 'Journal Article',
display: 'Smith et al. 2024',
citation: 'Smith J, et al. Effects of X on Y. JAMA 2024.',
url: 'https://doi.org/10.1000/journal.2024',
document: null,
);| Property | Type | Description |
|---|---|---|
type |
?string |
documentation, justification, citation, predecessor, successor, derived-from, depends-on, composed-of
|
label |
?string |
Short label |
display |
?string |
Human-readable summary |
citation |
?string |
Citation text |
url |
?string |
URL reference |
document |
?Attachment |
Actual document |
FHIRPath expression.
use Satusehat\Integration\DataType\Expression;
$expr = new Expression(
description: 'Patient age calculation',
language: 'text/fhirpath',
expression: '%context.birthDate.value',
);Event trigger definition.
use Satusehat\Integration\DataType\TriggerDefinition;
$trigger = new TriggerDefinition(
type: 'named-event',
name: 'patient-create',
timingTiming: null,
timingReference: null,
timingDate: null,
timingDateTime: '2024-01-15T00:00:00+07:00',
data: null,
condition: null,
);Data requirements for a module definition.
use Satusehat\Integration\DataType\DataRequirement;
use Satusehat\Integration\DataType\Coding;
$req = new DataRequirement(
type: 'Observation',
profile: ['http://hl7.org/fhir/StructureDefinition/vitalsigns'],
mustSupport: ['code', 'valueQuantity'],
codeFilter: [
(object)['path' => 'code', valueSet: 'http://loinc.org/vs/LH7VID'],
],
);Parameter definition for operation definitions.
use Satusehat\Integration\DataType\ParameterDefinition;
$param = new ParameterDefinition(
name: 'patientId',
use: 'in',
min: 1,
max: '1',
documentation: 'The logical ID of the patient',
type: 'string',
searchType: null,
);DataTypes nest inside each other and toArray() handles the conversion:
$observation = (new PayloadBuilderObservation)
->setSubject(new Reference(
reference: "Patient/{$patientId}",
display: 'John Doe'
))
->setValueQuantity(new Quantity(
value: 72,
unit: 'beats/minute',
system: 'http://unitsofmeasure.org',
code: '/min'
))
->build();
// The Reference → {'reference': '...', 'display': '...'}
// The Quantity → {'value': 72, 'unit': '...', ...}
// All nested automatically via toArray()