Skip to content

DataMapper API

Complete API reference for DataMapper.

DataMapper::source(mixed $source): FluentDataMapper

Section titled “DataMapper::source(mixed $source): FluentDataMapper”

Create mapper with source data.

use event4u\DataHelpers\DataMapper;
$source = ['user' => ['name' => 'John', 'email' => 'john@example.com']];
$mapper = DataMapper::source($source);

DataMapper::template(array $template): FluentDataMapper

Section titled “DataMapper::template(array $template): FluentDataMapper”

Create mapper with template.

use event4u\DataHelpers\DataMapper;
$mapper = DataMapper::template([
'name' => '{{ user.name }}',
'email' => '{{ user.email }}',
]);

DataMapper::sourceFile(string $filePath): FluentDataMapper

Section titled “DataMapper::sourceFile(string $filePath): FluentDataMapper”

Create mapper with data loaded from a JSON or XML file.

use event4u\DataHelpers\DataMapper;
// Load from JSON file
$mapper = DataMapper::sourceFile('/path/to/data.json');
// Load from XML file
$mapper = DataMapper::sourceFile('/path/to/data.xml');

⚠️ Important for XML files: The root element name is preserved and must be included in mapping paths:

// For XML: <company><name>TechCorp</name></company>
$mapper = DataMapper::sourceFile('/path/to/company.xml')
->template([
'name' => '{{ company.name }}', // ✅ Include root element
]);

Set source data.

use event4u\DataHelpers\DataMapper;
$source = ['user' => ['name' => 'John']];
$mapper = DataMapper::source($source);

Set target data.

use event4u\DataHelpers\DataMapper;
$source = ['id' => 1];
$target = ['id' => null];
$mapper = DataMapper::source($source)->target($target);

Set mapping template.

use event4u\DataHelpers\DataMapper;
$mapper = DataMapper::source([])
->template([
'name' => '{{ user.name }}',
'email' => '{{ user.email }}',
]);

Skip null values in mapping.

use event4u\DataHelpers\DataMapper;
$mapper = DataMapper::source(['name' => null])
->template(['name' => '{{ name }}'])
->skipNull(true);

When skipNull(true) is enabled, DataMapper will:

  • Skip source values that resolve to null after applying defaults and template filters
  • Apply the same behavior for simple and structured mappings
  • For wildcard mappings (* paths), skip items that are null at the raw value level (before hooks/pipelines)

In addition, hooks can actively skip writes by returning the special value "__skip__":

  • beforeTransform / afterTransform value hooks: returning "__skip__" skips the current pair/item entirely
  • beforeWrite value hooks:
    • For non-wildcard values, returning "__skip__" prevents the write but the pair is still considered processed
    • For wildcard items, returning "__skip__" skips the current item (it is treated like a skipped element in the wildcard iteration)

This ensures that skipNull and hook-based skips behave consistently across simple, structured and wildcard mappings while still allowing fine-grained control via hooks.

reindexWildcard(bool $reindex = true): self

Section titled “reindexWildcard(bool $reindex = true): self”

Reindex wildcard results.

use event4u\DataHelpers\DataMapper;
$mapper = DataMapper::source([])
->reindexWildcard(false);

Allow or disallow modification of readonly properties.

When enabled, the mapper will attempt to modify readonly properties by:

  • Using the constructor when target is a class name (string)
  • Creating a new instance via reflection when target is an object and readonly properties would be modified

When disabled (default), readonly properties that are already initialized will be skipped.

use event4u\DataHelpers\DataMapper;
class UserDto
{
public function __construct(
public readonly int $id,
public readonly string $name,
) {}
}
// Default behavior - readonly properties are skipped
$dto = new UserDto(999, 'Original');
$result = DataMapper::source(['id' => 123, 'name' => 'John'])
->target($dto)
->modifyReadOnly(false) // Default
->template(['id' => '{{ id }}', 'name' => '{{ name }}'])
->map()
->getTarget();
// Result: id=999, name='Original' (unchanged)
// Enable modification - creates new instance
$result = DataMapper::source(['id' => 123, 'name' => 'John'])
->target($dto)
->modifyReadOnly(true) // Enable
->template(['id' => '{{ id }}', 'name' => '{{ name }}'])
->map()
->getTarget();
// Result: id=123, name='John' (new instance)

See Working with Readonly Properties for detailed examples.

map(bool $withQuery = true): DataMapperResult

Section titled “map(bool $withQuery = true): DataMapperResult”

Execute mapping and return result.

use event4u\DataHelpers\DataMapper;
$source = ['user' => ['name' => 'John', 'email' => 'john@example.com']];
$result = DataMapper::source($source)
->template(['name' => '{{ user.name }}'])
->map();
$target = $result->getTarget();

autoMap(?bool $deep = null): DataMapperResult

Section titled “autoMap(?bool $deep = null): DataMapperResult”

Automatically map matching fields.

use event4u\DataHelpers\DataMapper;
$source = ['user_name' => 'John', 'user_email' => 'john@example.com'];
$result = DataMapper::source($source)
->autoMap();

Execute reverse mapping (target → source).

use event4u\DataHelpers\DataMapper;
$source = ['name' => 'John'];
$target = ['full_name' => 'John Doe'];
$result = DataMapper::source($source)
->target($target)
->template(['full_name' => '{{ name }}'])
->reverseMap();

Create query on wildcard path.

use event4u\DataHelpers\DataMapper;
$source = ['users' => [
['name' => 'John', 'age' => 25],
['name' => 'Jane', 'age' => 30],
]];
$result = DataMapper::source($source)
->template(['users' => ['*' => ['name' => '{{ users.*.name }}']]])
->query('users.*')
->where('age', '>', 18)
->orderBy('name', 'ASC')
->limit(10)
->end()
->map();

property(string $property): DataMapperProperty

Section titled “property(string $property): DataMapperProperty”

Access property for filters.

use event4u\DataHelpers\DataMapper;
use event4u\DataHelpers\DataMapper\Pipeline\Filters\TrimStrings;
$result = DataMapper::source(['name' => ' John '])
->template(['name' => '{{ name }}'])
->property('name')
->setFilter(new TrimStrings())
->end()
->map();
'{{ source.path }}'
'{{ source.path | default:"N/A" }}'
'{{ source.path | upper | trim }}'
'{{ users.*.name }}'