Polyscope - The agent-first dev environment for Laravel

Data Model Helper

Data Model Helper stats

Downloads
591
Stars
1
Open Issues
0
Forks
0

View on GitHub →

Helpers for a DataModel.

Zerotoprod\DataModelHelper

Utilities for casting values using the DataModel package.

Installation

Install the package via Composer:

composer require zero-to-prod/data-model-helper

Usage

Including the Trait

Include the DataModelHelper trait in your class to access helper methods:

class DataModelHelper
{
use \Zerotoprod\DataModelHelper\DataModelHelper;
}

Helper Methods

  • mapOf: Create a map of any type by using
  • pregReplace: Perform a regular expression search and replace.
  • pregMatch: Perform a regular expression match.
  • isUrl: Validates a url.
  • isEmail: Validates an email.

mapOf

Create a map of any type by using the DataModelHelper::mapOf() method.

use Zerotoprod\DataModel\Describe;
 
class User
{
use \Zerotoprod\DataModel\DataModel;
use \Zerotoprod\DataModelHelper\DataModelHelper;
 
/** @var Collection<int, Alias> $Aliases */
#[Describe([
'cast' => [self::class, 'mapOf'], // Casting method to use
'type' => Alias::class, // Target type for each item
'required', // Throws PropertyRequiredException when value not present
'coerce' => true, // Coerce single elements into an array
'using' => [self::class, 'map'], // Custom mapping function
'map_via' => 'mapper', // Custom mapping method (defaults to 'map')
'map' => [self::class, 'keyBy'], // Run a function for that value.
'level' => 1, // The dimension of the array. Defaults to 1.
'key_by' => 'key', // Key an associative array by a field.
])]
public Collection $Aliases;
}

Usage

In this case the mapOf() method returns an array of Alias instances.

use Zerotoprod\DataModel\Describe;
 
class User
{
use \Zerotoprod\DataModel\DataModel;
use \Zerotoprod\DataModelHelper\DataModelHelper;
 
/** @var Alias[] $Aliases */
#[Describe([
'cast' => [self::class, 'mapOf'], // Use the mapOf helper method
'type' => Alias::class, // Target type for each item
'required', // Throws PropertyRequiredException when value not present
])]
public array $Aliases;
}
 
class Alias
{
use \Zerotoprod\DataModel\DataModel;
 
public string $name;
}
 
$User = User::from([
'Aliases' => [
['name' => 'John Doe'],
['name' => 'John Smith'],
]
]);
 
echo $User->Aliases[0]->name; // Outputs: John Doe
echo $User->Aliases[1]->name; // Outputs: John Smith

Laravel Collection Example

The mapOf helper is designed to work will with the \Illuminate\Support\Collection class.

use Zerotoprod\DataModel\Describe;
 
class User
{
use \Zerotoprod\DataModel\DataModel;
use \Zerotoprod\DataModelHelper\DataModelHelper;
 
/** @var Collection<int, Alias> $Aliases */
#[Describe([
'cast' => [self::class, 'mapOf'],
'type' => Alias::class,
'required', // Throws PropertyRequiredException when value not present
])]
public \Illuminate\Support\Collection $Aliases;
}
 
class Alias
{
use \Zerotoprod\DataModel\DataModel;
 
public string $name;
}
 
$User = User::from([
'Aliases' => [
['name' => 'John Doe'],
['name' => 'John Smith'],
]
]);
 
echo $User->Aliases->first()->name; // Outputs: John Doe

Coercing

Sometimes, an attribute may contain either a single element or an array of elements. By setting 'coerce' => true, you can ensure that single elements are coerced into an array.

use Zerotoprod\DataModel\Describe;
 
class User
{
use \Zerotoprod\DataModel\DataModel;
use \Zerotoprod\DataModelHelper\DataModelHelper;
 
/** @var Alias[] $Aliases */
#[Describe([
'cast' => [self::class, 'mapOf'],
'type' => Alias::class,
'coerce' => true, // Coerce single elements into an array
'required', // Throws PropertyRequiredException when value not present
])]
public array $Aliases;
}
 
class Alias
{
use \Zerotoprod\DataModel\DataModel;
 
public string $name;
}
 
$User = User::from([
'Aliases' => ['name' => 'John Doe'], // Single element instead of an array
]);
 
echo $User->Aliases[0]->name; // Outputs: John Doe

Using a Custom Mapping Function

Specify your mapping function by setting the using option.

use Zerotoprod\DataModel\Describe;
 
class User
{
use \Zerotoprod\DataModel\DataModel;
use \Zerotoprod\DataModelHelper\DataModelHelper;
 
/** @var Collection $Aliases */
#[Describe([
'cast' => [self::class, 'mapOf'],
'type' => Alias::class,
'using' => [self::class, 'map'], // Use custom mapping function
'required', // Throws PropertyRequiredException when value not present
])]
public Collection $Aliases;
 
public static function map(array $values): Collection
{
// Map each value to an Alias instance
$items = array_map(fn($value) => Alias::from($value), $values);
 
// Return as a Collection
return new Collection($items);
}
}
 
class Alias
{
use \Zerotoprod\DataModel\DataModel;
 
public string $name;
}
 
class Collection
{
public array $items;
 
public function __construct(array $items = [])
{
$this->items = $items;
}
}
 
$User = User::from([
'Aliases' => [
['name' => 'John Doe'],
],
]);
 
echo $User->Aliases->items[0]->name; // Outputs: John Doe

Specifying a Custom Mapping Method

By default, the map method is used to map over elements. You can specify a different method using the map_via option.

use Zerotoprod\DataModel\Describe;
 
class User
{
use \Zerotoprod\DataModel\DataModel;
use \Zerotoprod\DataModelHelper\DataModelHelper;
 
/** @var Collection $Aliases */
#[Describe([
'cast' => [self::class, 'mapOf'],
'type' => Alias::class,
'map_via' => 'mapper', // Use custom mapping method for the `Collection` class.
'required', // Throws PropertyRequiredException when value not present
])]
public Collection $Aliases;
}
 
class Alias
{
use \Zerotoprod\DataModel\DataModel;
 
public string $name;
}
 
class Collection
{
public array $items;
 
public function __construct(array $values)
{
$this->items = $values;
}
 
public function mapper(callable $callable): Collection
{
$this->items = array_map($callable, $this->items);
return $this;
}
}
 
$User = User::from([
'Aliases' => [
['name' => 'John Doe'],
],
]);
 
echo $User->Aliases->items[0]->name; // Outputs: John Doe

Deep Mapping

You can set the level for mapping deep arrays.

use Zerotoprod\DataModel\Describe;
 
class User
{
use \Zerotoprod\DataModel\DataModel;
use \Zerotoprod\DataModelHelper\DataModelHelper;
 
/** @var Alias[] $Aliases */
#[Describe([
'cast' => [self::class, 'mapOf'], // Use the mapOf helper method
'type' => Alias::class, // Target type for each item
'level' => 2, // The dimension of the array. Defaults to 1.
'required', // Throws PropertyRequiredException when value not present
])]
public array $Aliases;
}
 
class Alias
{
use \Zerotoprod\DataModel\DataModel;
 
public string $name;
}
 
$User = User::from([
'Aliases' => [
[
['name' => 'John Doe'],
['name' => 'John Smith'],
]
]
]);
 
echo $User->Aliases[0][0]->name; // Outputs: John Doe
echo $User->Aliases[0][1]->name; // Outputs: John Smith

KeyBy

Key an array by an element value by using the key_by argument.

This also supports deep mapping.

Note: this only applies to arrays.

class User
{
use \Zerotoprod\DataModel\DataModel;
use \Zerotoprod\DataModelHelper\DataModelHelper;
 
/** @var Alias[] $Aliases */
#[Describe([
'cast' => [self::class, 'mapOf'],
'type' => Alias::class,
'key_by' => 'id',
'required', // Throws PropertyRequiredException when value not present
])]
public array $Aliases;
}
 
class Alias
{
use \Zerotoprod\DataModel\DataModel;
 
public string $id;
public string $name;
}
 
$User = User::from([
'Aliases' => [
[
'id' => 'jd1',
'name' => 'John Doe',
],
[
'id' => 'js1',
'name' => 'John Smith'
],
]
]);
 
echo $User->Aliases['jd1']->name; // 'John Doe'
echo $User->Aliases['js1']->name); // 'John Smith'

Map

Call a function for that value.

Note: This does not work with arrays.

class User
{
use \Zerotoprod\DataModel\DataModel;
use \Zerotoprod\DataModelHelper\DataModelHelper;
 
/** @var Alias[] $Aliases */
#[Describe([
'cast' => [self::class, 'mapOf'],
'type' => Alias::class,
'map' => [self::class, 'keyBy'],
'required', // Throws PropertyRequiredException when value not present
])]
public Collection $Aliases;
 
public static function keyBy(Collection $values): Collection
{
return $values->keyBy('id');
}
}
 
class Alias
{
use \Zerotoprod\DataModel\DataModel;
 
public string $id;
public string $name;
}
 
$User = User::from([
'Aliases' => [
[
'id' => 'jd1',
'name' => 'John Doe',
]
]
]);
 
echo $User->Aliases->get('jd1')->name; // 'John Doe'

pregReplace

Use pregReplace to perform a regular expression search and replace.

class User
{
use \Zerotoprod\DataModel\DataModel;
use \Zerotoprod\DataModelHelper\DataModelHelper;
 
public const ascii_only = '/[^\x00-\x7F]/';
 
#[Describe([
'cast' => [self::class, 'pregReplace'],
'pattern' => ascii_only,
'replacement' => '!' // defaults to '' when not specified
'required', // Throws PropertyRequiredException when value not present
])]
public string $name;
}
 
$User = User::from([
'name' => 'Trophy🏆',
]);
 
echo $User->name; // Outputs: 'Trophy!'

pregMatch

Use pregMatch to perform a regular expression match.

class User
{
use \Zerotoprod\DataModel\DataModel;
use \Zerotoprod\DataModelHelper\DataModelHelper;
 
#[Describe([
'cast' => [self::class, 'pregMatch'],
'pattern' => '/s/', // Required
'match_on' => 0 // Index of the $matches to return
'flags' => PREG_UNMATCHED_AS_NULL
'offset' => 0,
'required', // Throws PropertyRequiredException when value not present
])]
public string $name;
}
 
$User = User::from([
'name' => 'sarah',
]);
 
echo $User->name; // Outputs: 's'

isUrl

Use isUrl to validate a url.

class User
{
use \Zerotoprod\DataModel\DataModel;
use \Zerotoprod\DataModelHelper\DataModelHelper;
 
#[Describe([
'cast' => [self::class, 'isUrl'],
'protocols' => ['http', 'udp'], // Optional. Defaults to all.
'on_fail' => [MyAction::class, 'method'], // Optional. Invoked when validation fails.
'exception' => MyCustomException::class, // Optional. Throws an exception when not url.
'required' // Optional. Throws \Zerotoprod\DataModel\PropertyRequiredException::class
])]
public string $url;
}

isEmail

Use isEmail to validate an email.

class User
{
use \Zerotoprod\DataModel\DataModel;
use \Zerotoprod\DataModelHelper\DataModelHelper;
 
#[Describe([
'cast' => [self::class, 'isEmail'],
'on_fail' => [MyAction::class, 'method'], // Optional. Invoked when validation fails.
'exception' => MyCustomException::class, // Optional. Throws an exception when not url.
'required' // Optional. Throws \Zerotoprod\DataModel\PropertyRequiredException::class
])]
public string $url;
}
zero-to-prod photo

Senior Full Stack Developer

Cube

Laravel Newsletter

Join 40k+ other developers and never miss out on new tips, tutorials, and more.


Zero To Prod Data Model Helper Related Articles

Inertia.js v3.0.0 Is Here with Optimistic Updates, useHttp, and More image

Inertia.js v3.0.0 Is Here with Optimistic Updates, useHttp, and More

Read article
Get Free Access to all 70+ Vue School Courses - 1-2 March image

Get Free Access to all 70+ Vue School Courses - 1-2 March

Read article
How to add unlimited custom domains to Laravel Vapor image

How to add unlimited custom domains to Laravel Vapor

Read article
Cloudflare has been leaking custom HTTPS sessions image

Cloudflare has been leaking custom HTTPS sessions

Read article
Lucky Media logo

Lucky Media

Get Lucky Now - the ideal choice for Laravel Development, with over a decade of experience!

Lucky Media
Typesense Search logo

Typesense Search

Typesense is an open source, blazing-fast search engine, optimized for helping you build delightful search experiences for your sites and apps. Natively integrated with Laravel Scout.

Typesense Search
Tighten logo

Tighten

We help companies turn great ideas into amazing apps, products, and services.

Tighten
Kirschbaum logo

Kirschbaum

Providing innovation and stability to ensure your web application succeeds.

Kirschbaum
DreamzTech logo

DreamzTech

Hire 6-10+ Yrs. experienced skilled Laravel Developers from DreamzTech. We ensure NDA protected, 100% quality delivery. Contact Us & Discuss Your Need.

DreamzTech
The Certification of Competence for Laravel logo

The Certification of Competence for Laravel

A community-driven, proctored assessment across 4 levels designed to validate real-world Laravel knowledge, from Junior to mastery-level Artisan. Official Vue.js, Official Nuxt, Angular, React, JS certifications also available.

The Certification of Competence for Laravel