galawork/data-helpers

Framework-agnostic helpers for structured data access, mutation, and mapping using dot-notation paths with wildcards. Works with Laravel, Symfony/Doctrine, or standalone PHP.

Fund package maintenance!
event4u-app
matze4u

Installs: 1

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 1

pkg:composer/galawork/data-helpers

1.0.1 2025-10-29 20:28 UTC

This package is auto-updated.

Last update: 2025-10-29 20:30:58 UTC


README

event4u Data Helpers

Data Helpers

Packagist Version PHP License: MIT GitHub Code Quality Action Status GitHub PHPStan Action Status GitHub Test Matrix Action Status

A powerful, framework-agnostic PHP library for accessing, transforming, and mapping complex nested data structures with ease.

Stop writing nested loops and array checks. Access, transform, and map complex data structures with simple, expressive syntax.

// From this messy API response...
$apiResponse = [
    'data' => [
        'departments' => [
            ['users' => [['email' => 'alice@example.com'], ['email' => 'bob@example.com']]],
            ['users' => [['email' => 'charlie@example.com']]],
        ],
    ],
];

// ...to this clean result in a few lines
$accessor = new DataAccessor($apiResponse);
$emails = $accessor->get('data.departments.*.users.*.email');
// ['alice@example.com', 'bob@example.com', 'charlie@example.com']

Framework-agnostic โ€ข Works with Laravel, Symfony/Doctrine, or standalone PHP โ€ข Zero required dependencies

๐Ÿ“– Full Documentation โ€ข Getting Started โ€ข API Reference

๐Ÿ’– Support the Development - Help us build better tools for the PHP community

๐Ÿ’ก Why Data Helpers?

๐ŸŽฏ Stop Writing Nested Loops

// โŒ Without Data Helpers
$emails = [];
foreach ($data['departments'] ?? [] as $dept) {
    foreach ($dept['users'] ?? [] as $user) {
        if (isset($user['email'])) {
            $emails[] = $user['email'];
        }
    }
}

// โœ… With Data Helpers
$emails = $accessor->get('departments.*.users.*.email');

๐Ÿš€ Key Benefits

  • Type-Safe - PHPStan Level 9 compliant with 3500+ tests
  • Fast - SimpleDto with #[UltraFast] is up to 34.0x faster than Other Serializer
  • Framework-Agnostic - Works with Laravel, Symfony, Doctrine, or plain PHP
  • Zero Dependencies - No required dependencies, optional framework integrations
  • No-Code Mapping - Store templates in database, create with drag-and-drop editors

๐Ÿ“ฆ Installation

composer require event4u/data-helpers

Requirements: PHP 8.2+

Framework support (all optional):

  • ๐Ÿ”ด Laravel 9+ - Collections, Eloquent Models
  • โšซ Symfony/Doctrine 6+ - Collections, Entities
  • ๐Ÿ”ง Standalone PHP - Works out of the box

๐Ÿ“– Installation Guide โ€ข Configuration

โšก Core Components

1๏ธโƒฃ DataAccessor - Read Nested Data

Access deeply nested data with dot notation and wildcards:

$data = [
    'users' => [
        ['email' => 'alice@example.com'],
        ['email' => 'bob@example.com'],
    ],
];

$accessor = new DataAccessor($data);
$emails = $accessor->get('users.*.email');
// $emails = ['alice@example.com', 'bob@example.com']

๐Ÿ“– DataAccessor Documentation

2๏ธโƒฃ DataMutator - Modify Nested Data

Safely modify nested structures:

$data = ['user' => ['profile' => []]];
DataMutator::make($data)
    ->set('user.profile.name', 'Alice')
    ->merge('user.profile', ['age' => 30]);
// $data is now modified: ['user' => ['profile' => ['name' => 'Alice', 'age' => 30]]]

๐Ÿ“– DataMutator Documentation

4๏ธโƒฃ DataFilter - Query Data

Filter and query data with SQL-like API:

$products = [
    ['id' => 1, 'name' => 'Laptop', 'category' => 'Electronics', 'price' => 1200],
    ['id' => 2, 'name' => 'Mouse', 'category' => 'Electronics', 'price' => 25],
    ['id' => 3, 'name' => 'Monitor', 'category' => 'Electronics', 'price' => 400],
];

$result = DataFilter::query($products)
    ->where('category', '=', 'Electronics')
    ->where('price', '>', 100)
    ->orderBy('price', 'DESC')
    ->get();
// Result: [Laptop ($1200), Monitor ($400)]

๐Ÿ“– DataFilter Documentation

5๏ธโƒฃ SimpleDto - Immutable Dtos

Create type-safe, immutable Data Transfer Objects with automatic type casting:

use event4u\DataHelpers\SimpleDto\Attributes\AutoCast;

#[AutoCast]  // Enable automatic type casting (opt-in for performance)
class ReadmeUserDto extends SimpleDto
{
    public function __construct(
        public readonly string $name,
        public readonly string $email,
        public readonly int $age,
    ) {}
}

// Automatic type conversion with #[AutoCast]
$user = ReadmeUserDto::fromArray([
    'name' => 'John',
    'email' => 'john@example.com',
    'age' => '30'  // String "30" โ†’ int 30 (automatic)
]);

// Without #[AutoCast]: Strict types, better performance
class StrictUserDto extends SimpleDto
{
    public function __construct(
        public readonly string $name,
        public readonly int $age,  // Must be int, no conversion
    ) {}
}

๐Ÿ“– SimpleDto Documentation

6๏ธโƒฃ LiteDto - Ultra-Fast Dtos

Create ultra-fast, minimalistic DTOs with essential features:

use event4u\DataHelpers\LiteDto\LiteDto;
use event4u\DataHelpers\LiteDto\Attributes\MapFrom;
use event4u\DataHelpers\LiteDto\Attributes\Hidden;

class UserDto extends LiteDto
{
    public function __construct(
        public readonly string $name,

        #[MapFrom('email_address')]
        public readonly string $email,

        #[Hidden]
        public readonly string $password,
    ) {}
}

$user = UserDto::from([
    'name' => 'John',
    'email_address' => 'john@example.com',
    'password' => 'secret',
]);

$array = $user->toArray();
// ['name' => 'John', 'email' => 'john@example.com']
// password is hidden

Performance: LiteDto is 7.6x faster than SimpleDto Normal (~2.3ฮผs vs ~18.5ฮผs)

๐Ÿ“– LiteDto Documentation

3๏ธโƒฃ DataMapper - Transform Data

Map between different data structures with templates:

$source = [
    'user' => ['name' => 'John Doe', 'email' => 'john@example.com'],
    'orders' => [
        ['id' => 1, 'status' => 'shipped', 'total' => 100],
        ['id' => 2, 'status' => 'pending', 'total' => 50],
        ['id' => 3, 'status' => 'shipped', 'total' => 200],
    ],
];

$result = DataMapper::from($source)
    ->template([
        'customer_name' => '{{ user.name }}',
        'customer_email' => '{{ user.email }}',
        'shipped_orders' => [
            'WHERE' => [
                '{{ orders.*.status }}' => 'shipped',
            ],
            'ORDER BY' => [
                '{{ orders.*.total }}' => 'DESC',
            ],
            '*' => [
                'id' => '{{ orders.*.id }}',
                'total' => '{{ orders.*.total }}',
            ],
        ],
    ])
    ->map()
    ->getTarget();

๐Ÿ’ก No-Code Data Mapping: Templates can be stored in a database and created with a drag-and-drop editor - perfect for import wizards, API integrations, and ETL pipelines without writing code!

๐Ÿ“– DataMapper Documentation

๐ŸŽฏ Advanced Features

No-Code Data Mapping

Store templates in database and create mappings without programming:

// Load template from database (created with drag-and-drop editor)
$template = Mappings::find(3)->template;

$result = DataMapper::from($source)
    ->template($template)
    ->map()
    ->getTarget();

Perfect for:

  • ๐Ÿ“ฅ Import Wizards - Let users map CSV/Excel columns to your data model
  • ๐Ÿ”Œ API Integration - Configure API mappings without code changes
  • ๐Ÿข Multi-Tenant Systems - Each tenant can have custom data mappings
  • ๐Ÿ”„ Dynamic ETL - Build data transformation pipelines visually
  • ๐Ÿ“ Form Builders - Map form submissions to different data structures

๐Ÿ“– Template-Based Mapping Guide

Complex Nested Mapping

Map complex nested structures to Eloquent Models or Doctrine Entities:

// Automatic relation detection for Eloquent/Doctrine
$company = new Company();
$result = DataMapper::from($jsonData)
    ->target($company)
    ->template([
        'name' => '{{ company.name }}',
        'departments' => [
            '*' => [
                'name' => '{{ company.departments.*.name }}',
                'budget' => '{{ company.departments.*.budget }}',
            ],
        ],
    ])
    ->map()
    ->getTarget();
  • โœ… Automatic Relation Detection
  • โœ… Type Casting (string โ†’ int/float/bool)
  • โœ… Snake_case โ†’ camelCase conversion
  • โœ… Nested Wildcards

๐Ÿ“– Advanced Mapping Guide

Pipeline API

Transform data with composable filters:

use Tests\Utils\Docu\TrimStrings;
use Tests\Utils\Docu\LowercaseEmails;
use Tests\Utils\Docu\SkipEmptyValues;

$source = ['name' => '  John  ', 'email' => 'JOHN@EXAMPLE.COM'];
$mapping = ['name' => '{{ name }}', 'email' => '{{ email }}'];

$result = DataMapper::from($source)
    ->template($mapping)
    ->pipeline([
        new TrimStrings(),
        new LowercaseEmails(),
        new SkipEmptyValues(),
    ])
    ->map()
    ->getTarget();

// $result = ['name' => 'John', 'email' => 'john@example.com']

๐Ÿ“– Pipeline Documentation

Template Expressions

Use Twig-like expressions with 18+ built-in filters:

$mapping = [
    'name' => '{{ user.firstName | ucfirst }} {{ user.lastName | ucfirst }}',
    'email' => '{{ user.email | lower | trim }}',
    'role' => '{{ user.role | upper ?? "USER" }}',
];

๐Ÿ“– Template Expressions

Query Builder

Laravel-style fluent interface for building queries:

$result = DataMapper::query()
    ->source('products', $data)
    ->where('category', 'Electronics')
    ->where('price', '>', 100)
    ->orderBy('price', 'DESC')
    ->groupBy('category', ['total' => ['COUNT']])
    ->get();

๐Ÿ“– Query Builder Documentation

๐Ÿ“š Documentation

Comprehensive documentation with guides, examples, and API reference is available at:

๐Ÿ”— event4u-app.github.io/data-helpers

The documentation includes:

  • ๐Ÿ“– Getting Started Guides - Installation, configuration, and quick start tutorials
  • ๐Ÿ”ง Main Classes - Detailed guides for DataAccessor, DataMutator, DataMapper, and DataFilter
  • ๐ŸŽฏ SimpleDto - Type-safe Dtos with validation, casting, and collections
  • โšก LiteDto - Ultra-fast, minimalistic Dtos (7.6x faster than SimpleDto)
  • ๐Ÿš€ Advanced Features - Template expressions, query builder, pipelines, and reverse mapping
  • ๐Ÿ”Œ Framework Integration - Laravel, Symfony, and Doctrine integration guides
  • ๐Ÿ’ก 90+ Code Examples - Runnable examples for every feature
  • ๐Ÿ“Š Performance Benchmarks - Optimization tips and benchmark results
  • ๐Ÿ” Complete API Reference - Full API documentation for all classes and methods

๐Ÿงช Testing & Quality

  • โœ… 3500+ tests with comprehensive coverage
  • โœ… PHPStan Level 9 - Highest static analysis level
  • โœ… 100% type coverage - All methods fully typed
  • โœ… Continuous Integration - Automated testing across PHP 8.2, 8.3, 8.4

๐Ÿ“– Contributing Guide โ€ข Development Setup

โšก Performance

All operations are highly optimized:

  • Simple access: ~0.2ฮผs
  • Nested access: ~0.3ฮผs
  • Wildcards: ~5ฮผs
  • SimpleDto #[UltraFast] is up to 34.0x faster than Other Serializer

๐Ÿ“– Performance Benchmarks โ€ข Optimization Tips

๐Ÿค Contributing

Contributions are welcome! Please see the Contributing Guide for details.

# Install dependencies
composer install

# Run tests
composer test

# Run quality checks
composer quality

๐Ÿ’– Sponsoring

This package is part of the event4u ecosystem - a comprehensive event management platform. Your sponsorship helps us:

  • ๐Ÿš€ Develop event4u - The next-generation event management app
  • ๐Ÿ“ฆ Maintain open-source packages - Like this Data Helpers library
  • ๐Ÿ”ง Build new tools - More packages and utilities for the PHP community
  • ๐Ÿ“š Improve documentation - Better guides and examples
  • ๐Ÿ› Fix bugs faster - Dedicated time for maintenance and support

Support the Development

Sponsor @matze4u ย ย  Sponsor event4u-app

Every contribution, no matter how small, makes a difference and is greatly appreciated! ๐Ÿ™

๐Ÿ“„ License

MIT License. See LICENSE for details.

๐ŸŒŸ Show Your Support

If this package helps you, please consider: