Passed
Push — master ( a9c512...146f63 )
by Michael
02:32
created

ObjectMapper::toResourceIdentifier()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 9
ccs 5
cts 5
cp 1
rs 9.6666
cc 1
eloc 5
nc 1
nop 1
crap 1
1
<?php
2
declare(strict_types = 1);
3
4
namespace Mikemirten\Component\JsonApi\Mapper;
5
6
use Mikemirten\Component\JsonApi\Document\ResourceIdentifierObject;
7
use Mikemirten\Component\JsonApi\Document\ResourceObject;
8
use Mikemirten\Component\JsonApi\Mapper\Definition\DefinitionProviderInterface;
9
use Mikemirten\Component\JsonApi\Mapper\Handler\HandlerInterface;
10
use Mikemirten\Component\JsonApi\Mapper\Handler\IdentifierHandler\IdentifierHandlerInterface;
11
use Mikemirten\Component\JsonApi\Mapper\Handler\TypeHandler\TypeHandlerInterface;
12
13
/**
14
 * Object mapper.
15
 *
16
 * Maps data between object and resource of document.
17
 * Can be helpful for serialization of objects to JSON API document.
18
 *
19
 * Each handler responsible for certain part of resource (links, metadata, relationships...).
20
 * Identifier and type handlers are specific and required to resolve id and type of resource.
21
 * Other handlers are optional.
22
 *
23
 * @package Mikemirten\Component\JsonApi\Mapper
24
 */
25
class ObjectMapper
26
{
27
    /**
28
     * Provider of mapping definition
29
     *
30
     * @var DefinitionProviderInterface
31
     */
32
    protected $definitionProvider;
33
34
    /**
35
     * Required identifier handler
36
     * Must always be present regardless of other handlers
37
     *
38
     * @var IdentifierHandlerInterface
39
     */
40
    protected $identifierHandler;
41
42
    /**
43
     * Required type handler
44
     * Must always be present regardless of other handlers
45
     *
46
     * @var TypeHandlerInterface
47
     */
48
    protected $typeHandler;
49
50
    /**
51
     * Mapping handlers
52
     *
53
     * @var HandlerInterface[]
54
     */
55
    protected $handlers = [];
56
57
    /**
58
     * ObjectMapper constructor.
59
     *
60
     * @param DefinitionProviderInterface $definitionProvider
61
     * @param IdentifierHandlerInterface  $identifierHandler
62
     * @param TypeHandlerInterface        $typeHandler
63
     */
64 3
    public function __construct(
65
        DefinitionProviderInterface $definitionProvider,
66
        IdentifierHandlerInterface  $identifierHandler,
67
        TypeHandlerInterface        $typeHandler
68
    ) {
69 3
        $this->definitionProvider = $definitionProvider;
70 3
        $this->identifierHandler  = $identifierHandler;
71 3
        $this->typeHandler        = $typeHandler;
72 3
    }
73
74
    /**
75
     * Add mapping handler
76
     *
77
     * @param HandlerInterface $handler
78
     */
79 2
    public function addHandler(HandlerInterface $handler)
80
    {
81 2
        $this->handlers[] = $handler;
82 2
    }
83
84
    /**
85
     * Map object's data to resource
86
     *
87
     * @param  mixed $object
88
     * @return ResourceObject
89
     */
90 1
    public function toResource($object): ResourceObject
91
    {
92 1
        $context = $this->createContext(get_class($object));
93
94 1
        $id   = $this->identifierHandler->getIdentifier($object, $context);
95 1
        $type = $this->resolveType($object, $context);
96
97 1
        $resource = new ResourceObject($id, $type);
98
99 1
        foreach ($this->handlers as $handler)
100
        {
101 1
            $handler->toResource($object, $resource, $context);
102
        }
103
104 1
        return $resource;
105
    }
106
107
    /**
108
     * Map object's identification to resource-identifier
109
     *
110
     * @param  $object
111
     * @return ResourceIdentifierObject
112
     */
113 1
    public function toResourceIdentifier($object): ResourceIdentifierObject
114
    {
115 1
        $context = $this->createContext(get_class($object));
116
117 1
        $id   = $this->identifierHandler->getIdentifier($object, $context);
118 1
        $type = $this->resolveType($object, $context);
119
120 1
        return new ResourceIdentifierObject($id, $type);
121
    }
122
123
    /**
124
     * Map resource's data to provided object
125
     *
126
     * @param mixed $object
127
     * @param ResourceObject $resource
128
     */
129 1
    public function fromResource($object, ResourceObject $resource)
130
    {
131 1
        $context = $this->createContext(get_class($object));
132
133 1
        $this->identifierHandler->setIdentifier($object, $resource->getId(), $context);
134
135 1
        foreach ($this->handlers as $handler)
136
        {
137 1
            $handler->fromResource($object, $resource, $context);
138
        }
139 1
    }
140
141
    /**
142
     * Resolve type of resource
143
     *
144
     * @param  $object
145
     * @param  MappingContext $context
146
     * @return string
147
     */
148 2
    protected function resolveType($object, MappingContext $context): string
149
    {
150 2
        $definition = $context->getDefinition();
151
152 2
        if ($definition->hasType()) {
153
            return $definition->getType();
154
        }
155
156 2
        return $this->typeHandler->getType($object, $context);
157
    }
158
159
    /**
160
     * Create mapping context for given class
161
     *
162
     * @param  string $class
163
     * @return MappingContext
164
     */
165 3
    protected function createContext(string $class): MappingContext
166
    {
167 3
        $definition = $this->definitionProvider->getDefinition($class);
168
169 3
        return new MappingContext($this, $definition);
170
    }
171
}