VOOZH about

URL: https://deepwiki.com/hypervel/support/3.5-data-object-system

⇱ Data Object System | hypervel/support | DeepWiki


Loading...
Menu

Data Object System

The Data Object System provides a structured approach to data hydration, transforming raw arrays into strongly-typed objects with automatic type conversion, nested object resolution, and bidirectional serialization. This system implements the Data Transfer Object (DTO) pattern with reflection-based automation.

For collection manipulation utilities, see Collections. For general data manipulation helpers using dot notation, see Data Manipulation.


Position in Architecture

The DataObject abstract class src/DataObject.php22 sits in the Core Infrastructure Layer and is used throughout the package:

  • HTTP Layer: Request input hydration, response serialization
  • View Layer: View data preparation, component props
  • Data Layer: Database result mapping, cache value objects
  • Testing: Test fixture creation, assertion data structures

Sources: src/DataObject.php1-588


Overview

The DataObject abstract class src/DataObject.php22 enables developers to define typed data structures that automatically hydrate from arrays (e.g., HTTP request data, database results, API responses) and serialize back to arrays or JSON. The system handles:

  • Property mapping between snake_case keys and camelCase properties
  • Type casting for primitive types (int, float, string, bool, array)
  • Auto-resolution of nested DataObject instances, enums, and DateTime objects
  • Bidirectional serialization with custom serializers
  • Array access interface for read-only access
  • Reflection-based caching for performance optimization

Sources: src/DataObject.php1-588

Instantiation Flow

The following diagram illustrates how the make() method transforms raw array data into a hydrated DataObject instance:


Sources: src/DataObject.php62-93


Instantiation Flow

The following diagram illustrates how raw array data is transformed into a fully-hydrated DataObject instance:


Sources: src/DataObject.php62-93


Factory Methods

make() and from()

The primary entry points for creating DataObject instances:


  • $data: Raw array data with snake_case keys (or camelCase if auto-casting is disabled)
  • $autoResolve: When true, recursively resolves nested DataObject instances, enums, and DateTime objects before hydration

The from() method src/DataObject.php99-102 is an alias of make() for semantic clarity.

Example Usage:


Sources: src/DataObject.php62-102


Property Mapping System

The property mapping system translates between external data formats (snake_case) and PHP property names (camelCase).

Mapping Architecture


Mapping Methods

MethodPurposeLocation
convertPropertyToDataKey()Convert camelCase → snake_casesrc/DataObject.php376-379
convertDataKeyToProperty()Convert snake_case → camelCasesrc/DataObject.php385-388
getPropertyMap()Get snake_case → camelCase mapsrc/DataObject.php454-473
getReversedPropertyMap()Get camelCase → snake_case mapsrc/DataObject.php480-489

Both mapping caches ($propertyMapCache and $reversedPropertyMapCache) are class-level static properties that persist across instances for performance.

Sources: src/DataObject.php30-489


Type Casting System

Auto-Casting Configuration

Auto-casting is controlled by the static $autoCasting flag src/DataObject.php42:


Sources: src/DataObject.php42-370

Primitive Type Conversion

The convertValueToType() method src/DataObject.php411-432 handles primitive type casting:

TypeConversionExample
int(int) $value"42"42
float(float) $value"3.14"3.14
string(string) $value42"42"
bool(bool) $value"1"true
arrayWrap scalar in array if needed"value"["value"]

Nullable types are respected—if the type allows null and the value is null, no casting occurs.

Sources: src/DataObject.php411-432


Auto-Resolution System

Auto-resolution enables recursive hydration of complex nested structures when the autoResolve parameter is true.

Dependency Resolution Flow


Supported Dependency Types

TypeHandlerExample
DataObject subclass[ClassName, 'make']AddressData::make($data['address'])
Enum (PHP 8.1+)[EnumName, 'from']StatusEnum::from($data['status'])
DateTimeInterfaceasDateTime() callableParses timestamp/string to Carbon
CarbonInterfaceasDateTime() callableSame as above
DateTimeasDateTime() callableSame as above
CarbonasDateTime() callableSame as above

Sources: src/DataObject.php109-313

DateTime Resolution

The asDateTime() method src/DataObject.php139-180 handles multiple input formats:

  1. Carbon instances: Returns as-is wrapped in Carbon::instance()
  2. DateTimeInterface: Converts to Carbon preserving timezone
  3. Numeric values: Interprets as UNIX timestamp
  4. Standard date format (Y-m-d): Creates from format
  5. Custom date format: Uses $dateFormat property src/DataObject.php52
  6. String parsing: Falls back to Carbon::parse()

Sources: src/DataObject.php52-188

Union Type Support

For union types (e.g., DataObject|null), the system:

  1. Extracts the DataObject or DateTimeInterface type via getDependencyFromUnionType() src/DataObject.php219-232
  2. Checks nullability via hasNullableUnionType() src/DataObject.php237-246
  3. Respects the nullable flag during replacement src/DataObject.php326-328

Sources: src/DataObject.php219-275


Serialization System

Serialization Flow


Custom Serializers

The getSerializers() method src/DataObject.php125-134 returns handlers for specific types:


Subclasses can override this method to provide custom serialization for additional types.

Sources: src/DataObject.php125-569

JSON Serialization

The jsonSerialize() method src/DataObject.php574-577 implements the JsonSerializable interface, delegating to toArray():


This enables direct usage in json_encode():


Sources: src/DataObject.php574-577


Array Access Interface

The DataObject class implements ArrayAccess src/DataObject.php22 to provide array-like read access:

Array Access Methods

MethodBehaviorLocation
offsetExists($offset)Checks if snake_case key exists in property mapsrc/DataObject.php509-512
offsetGet($offset)Returns value for snake_case key from toArray()src/DataObject.php517-524
offsetSet($offset, $value)Throws LogicException (immutable)src/DataObject.php529-532
offsetUnset($offset)Throws LogicException (immutable)src/DataObject.php537-540

Usage Example


Design Rationale: DataObjects are designed to be immutable value objects. Mutation should occur through the update() method or by creating a new instance.

Sources: src/DataObject.php507-540


Mutation and Refresh

update() Method

The update() method src/DataObject.php494-504 allows controlled mutation:


This method:

  1. Maps snake_case keys to camelCase properties
  2. Directly updates property values (no type casting)
  3. Clears the internal cache via refresh()
  4. Returns $this for method chaining

refresh() Method

The refresh() method src/DataObject.php582-587 clears the serialization cache:


This should be called after any direct property modification to ensure toArray() returns updated values.

Sources: src/DataObject.php494-587


Caching Strategy

The DataObject system employs multiple caching layers for performance optimization:

Cache Types

CacheScopePurposeLocation
$reflectionParametersCacheStatic (per class)Constructor parameterssrc/DataObject.php27
$propertyMapCacheStatic (per class)snake_case → camelCase mapsrc/DataObject.php32
$reversedPropertyMapCacheStatic (per class)camelCase → snake_case mapsrc/DataObject.php37
$dependenciesMapCacheStatic (per class)Auto-resolve dependency treesrc/DataObject.php47
$arrayCacheInstanceSerialized array representationsrc/DataObject.php57

Cache Lifecycle


Performance Impact: Static caches eliminate reflection overhead for all instances after the first. Instance caches eliminate serialization overhead for repeated toArray() calls.

Sources: src/DataObject.php27-57


Extension Points

The DataObject class provides several extension points for customization:

Custom Dependency Handlers

Override getCustomizedDependencies() src/DataObject.php109-118 to handle custom types during auto-resolution:


Custom Serializers

Override getSerializers() src/DataObject.php125-134 to customize serialization for specific types:


Custom Property Mapping

Override convertPropertyToDataKey() and convertDataKeyToProperty() to use alternative naming conventions:


Sources: src/DataObject.php109-388


Integration with Collections

DataObjects integrate seamlessly with the Collection system. See Collections for:

  • collect() helper for creating collections of DataObjects
  • Collection::toResourceCollection() for transforming DataObjects to API resources
  • Collection methods (map, filter, etc.) for processing DataObject collections

Sources: src/DataObject.php1-588


Error Handling

The DataObject system throws specific exceptions for error conditions:

ExceptionConditionLocation
RuntimeExceptionMissing required constructor parameter (non-nullable, no default)src/DataObject.php444-446
RuntimeExceptionNo valid dependency in union typesrc/DataObject.php231
OutOfBoundsExceptionArray access to non-existent offsetsrc/DataObject.php523
LogicExceptionAttempt to mutate via array accesssrc/DataObject.php531-539

Sources: src/DataObject.php231-539