-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathObjectFactory.php
91 lines (75 loc) · 2.86 KB
/
ObjectFactory.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
<?php
/*
* This file is part of the Klipper package.
*
* (c) François Pluchino <francois.pluchino@klipper.dev>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Klipper\Component\DefaultValue;
use Klipper\Component\DefaultValue\Exception\UnexpectedTypeException;
/**
* @author François Pluchino <francois.pluchino@klipper.dev>
*/
class ObjectFactory implements ObjectFactoryInterface
{
protected ObjectRegistryInterface $registry;
protected ResolvedObjectTypeFactoryInterface $resolvedTypeFactory;
public function __construct(
ObjectRegistryInterface $registry,
ResolvedObjectTypeFactoryInterface $resolvedTypeFactory
) {
$this->registry = $registry;
$this->resolvedTypeFactory = $resolvedTypeFactory;
}
public function inject($data, array $options = []): object
{
if (!\is_object($data)) {
throw new UnexpectedTypeException(\gettype($data), 'object');
}
return $this->create(\get_class($data), $data, $options);
}
public function create($type, ?object $data = null, array $options = []): object
{
return $this->createBuilder($type, $data, $options)->getObject();
}
public function createBuilder($type, ?object $data = null, array $options = []): ObjectBuilderInterface
{
if ($type instanceof ObjectTypeInterface) {
$type = $this->resolveType($type);
} elseif (\is_string($type)) {
$type = $this->registry->getType($type);
} elseif (!$type instanceof ResolvedObjectTypeInterface) {
throw new UnexpectedTypeException($type, 'string, Klipper\Component\DefaultValue\ResolvedObjectTypeInterface or Klipper\Component\DefaultValue\ObjectTypeInterface');
}
$builder = $type->createBuilder($this, $options);
if (null !== $data) {
$builder->setData($data);
}
return $builder;
}
/**
* Wraps a type into a ResolvedObjectTypeInterface implementation and connects
* it with its parent type.
*
* @param ObjectTypeInterface $type The type to resolve
*
* @return ResolvedObjectTypeInterface The resolved type
*/
private function resolveType(ObjectTypeInterface $type): ResolvedObjectTypeInterface
{
$parentType = $type->getParent();
if (null !== $parentType) {
$parentType = $this->registry->getType($parentType);
}
return $this->resolvedTypeFactory->createResolvedType(
$type,
// Type extensions are not supported for unregistered type instances,
// i.e. type instances that are passed to the ObjectFactory directly,
// nor for their parents, if getParent() also returns a type instance.
[],
$parentType
);
}
}