DTOs
Every response row from the BioTime API — a raw associative array — is mapped into a small, readonly PHP object (a "Data Transfer Object"). This is what every resource method returns instead of arrays.
Why DTOs
- Typed properties —
$employee->firstNameinstead of$employee['first_name'], with IDE autocomplete and static-analysis support. - A stable shape — even if the device's raw payload has fields you don't need, the DTO exposes the fields the SDK models.
- Nothing is lost — every DTO also carries the complete original array under
->raw.
$employee = $biotime->employees()->find('EMP001');
$employee->empCode; // 'EMP001'
$employee->firstName; // 'Jane'
$employee->department; // 'Engineering' (flattened from the nested API object)
$employee->raw; // the full original array returned by the APIAccessing raw data
Every DTO's raw property is a plain array containing the exact response body for that row, unmodified. Use it for any field the DTO itself doesn't expose:
$employee->raw['email'] ?? null;
$employee->raw['mobile'] ?? null;DTO reference
Every DTO class lives in BioTime\DTO and is built via a static fromArray() factory. For the full property list of each one, see the DTO reference.
| DTO | Returned by |
|---|---|
Employee | employees()->find(), findById(), create(), update(), entries in list()/all() |
AttendanceRecord | attendances()->find(), entries in list()/all() |
Device | devices()->find(), get(), create(), update(), entries in list()/all() |
Department | departments()->find(), create(), update(), entries in list()/all() |
Position | positions()->find(), create(), update(), entries in list()/all() |
Area | areas()->find(), create(), update(), entries in list()/all() |
Resign | resigns()->find(), create(), update(), entries in list()/all() (embeds an Employee DTO) |
DTO vs. raw API response
A DTO is a typed projection of the raw response — it is not a 1:1 mirror. Some DTOs flatten nested API objects into simpler scalar fields (for example Employee::$department reads the nested department.dept_name when present, falling back to a plain department value). If you need the untouched nested structure, read it from ->raw instead of the typed property.