Object Instantiation
Without a Constructor
If a class does not define a constructor, Speca will fill the public properties directly from the input array.
class User extends Data {
public string $name;
public int $age;
}
$data = [
'name' => 'John Doe',
'age' => 30,
];
$user = User::from($data);
With a Constructor
If a class defines a constructor, it will be initialized with properties from the input array with the corresponding name (possibly "mapped" through ParseFrom
).
Data Sources
Currently, object instantiation supports two types of data sources: arrays and Data objects.
If a Data object is provided as input, it will be converted into an array with the appropriate rules applied.
Nested Data
Speca supports nested data, allowing you to create complex aggregates that include other objects.
use Looqey\Speca\Data;
class Percent extends ScalarValue {}
class ScalarValueParser implements Transformer {
public function transform(mixed $value, Property $property): mixed {
// implement parsing of scalar ValueObject
// - let's find type that will be subclass of ScalarValue
$types = $property->getTypes();
foreach ($types as $type) {
if (is_subclass_of($type, ScalarValue::class)) {
// Found, return value wrapped in given type
return new $type($value);
}
}
// Did not found any compatible types.
// So we can throw an exception,
// but (if required) you could just return original value and add another parser by
// second ParseBy attribute
throw new \Exception("No ScalarValue childs were declared in $property->name");
}
}
class SpecialDiscount extends Data {
public function __construct(
#[ParseBy(ScalarValueParser::class)]
public Percent $amount,
public array $category_ids
) {}
}
class UserDiscountAggregate extends Data {
public function __construct(
public User $user,
public ?SpecialDiscount $discount = null
) {}
}
Input data can be either regular arrays or Data objects:
$data = [
'user' => [
'name' => 'John Doe',
'age' => 25
],
'discount' => [
'amount' => 10,
'category_ids' => [1, 2, 3]
]
];
$agg = UserDiscountAggregate::from($data);