Skip to content
This repository has been archived by the owner on Apr 29, 2024. It is now read-only.

OzzyCzech/fromArray

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FromArray data loader

fromArray trait allow create objects instances loaded with initial data array:

class Example {
  use \DataLoader\FromArray;
  public $a;
  public $b;
  public $c;
}

$data = [
  'a' => 'value of A',
  'b' => 'value of B', 
  'c' => 'value of C'
];

// return new instance of Example object with $data
$example = Example::fromArray($data); 

echo json_encode($example, JSON_PRETTY_PRINT);

And that will be results...

{
  "a": "value of A",
  "b": "value of B",
  "c": "value of C"
}

Install

composer require om/from-array

SCHEME and nesting

Default object scheme is defined with SCHEME constant. You can use callable functions:

function alwaysFalse() { return false; }

class Example {
  use \DataLoader\FromArray;
  const SCHEME = ['id' => 'intval', 'isFalse' => 'alwaysFalse', 'date' => DateTime::class];
  public $id;  
  public $date;  
  public $isFalse = true;  
}

$data = ['id'=> '12345', 'isFalse' => true, 'date' => '2020-01-01'];
$example = Example::fromArray($data);
echo $example->id; // will return integer 12345
echo $example->isFalse; // will return false
echo $example->date->format('c'); // will return date

Or you can use class names:

class Nested {
  public $data = [];
  public function __construct($data) {
    $this->data = $data;
  }
}

class Example {
  use \DataLoader\FromArray;
  const SCHEME = ['nested' => Nested::class];
  public $nested;
}
$example = Example::fromArray(['nested' => ['some', 'data', 'here']]);
var_dump($example->nested); // will return instance of Nested class

If you are use class that use same trait object::fromArray() then fromArray function (with same $filter) will be called instead of class constructor. That allow you to made nested structures and load structured data:

class A {
  use \DataLoader\FromArray;
  public $value;
}

class B {
  use \DataLoader\FromArray;
  public $value;
}

class Nested {
  use \DataLoader\FromArray;
  const SCHEME = ['a' => A::class, 'b' => B::class];
  /** @var A */
  public $a;
  /** @var B */
  public $b;
}

You can also change scheme like that:

$scheme = Nested::fromArray($data, null, ['a' => function($data) { return $data; }]);

In this case $data in $a will remain unchanged...

Mapping

class Example {
  use \DataLoader\FromArray;
  const MAPPING = ['anotherId'=>'id'];
  public $id;
}
$example = Example::fromArray(['anotherId' => 1234]);
var_dump($example->id); // will return 1234

Value filter

class Filter {
  /** @var DateTime */
  public $date;
  /** @var string */
  public $notDate;
}

$data = ['date'=> '2017-11-01', 'notDate'=> '2017-11-01'];
$example = Filter::fromArray($data, function ($value, $property) {
  return ($property === 'date') ? new DateTime($value) : $value;
});

echo $example->notDate; // will return '2017-11-01' string
var_dump($example->date); // will return DateTime object

Filter can be useful when you for example load data from MongoDb:

function ($value, $property) {
  if ($property === '_id') return new \MongoId((string)$value);
  if ($value instanceof \MongoDate) return new \DateTime('@' . $value->sec);
  return $value;
}

Testing

composer install
composer test # will run Nette Tester

Resources

About

fromArray trait allow create objects instances loaded with initial data array

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages