LinkHandler   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 126
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 92.68%

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 9
dl 0
loc 126
ccs 38
cts 41
cp 0.9268
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A toResource() 0 4 1
A handleLinks() 0 22 2
A createLink() 0 11 1
A resolveParameters() 0 28 5
A fromResource() 0 4 1
1
<?php
2
declare(strict_types = 1);
3
4
namespace Mikemirten\Component\JsonApi\Mapper\Handler\LinkHandler;
5
6
use Mikemirten\Component\JsonApi\Document\LinkObject;
7
use Mikemirten\Component\JsonApi\Document\ResourceObject;
8
use Mikemirten\Component\JsonApi\Mapper\Definition\Link as LinkDefinition;
9
use Mikemirten\Component\JsonApi\Mapper\Handler\HandlerInterface;
10
use Mikemirten\Component\JsonApi\Mapper\Handler\LinkRepository\Link as LinkData;
11
use Mikemirten\Component\JsonApi\Mapper\Handler\LinkRepository\RepositoryProvider as LinkRepositoryProvider;
12
use Mikemirten\Component\JsonApi\Mapper\Handler\PropertyAccessor\PropertyAccessorInterface;
13
use Mikemirten\Component\JsonApi\Mapper\MappingContext;
14
use Mikemirten\Component\JsonApi\Mapper\Definition\Behaviour\LinksAwareInterface as LinksAwareDefinitionInterface;
15
use Mikemirten\Component\JsonApi\Document\Behaviour\LinksAwareInterface as LinksAwareDocumentInterface;
16
17
/**
18
 * An implementation of links handler based on repositories of links.
19
 *
20
 * @package Mikemirten\Component\JsonApi\Mapper\Handler\LinkHandler
21
 */
22
class LinkHandler implements HandlerInterface, LinkHandlerInterface
23
{
24
    /**
25
     * Provider of links' repositories
26
     *
27
     * @var LinkRepositoryProvider
28
     */
29
    protected $provider;
30
31
    /**
32
     * Property accessor
33
     *
34
     * @var PropertyAccessorInterface
35
     */
36
    protected $accessor;
37
38
    /**
39
     * LinkHandler constructor.
40
     *
41
     * @param LinkRepositoryProvider    $provider
42
     * @param PropertyAccessorInterface $accessor
43
     */
44 2
    public function __construct(LinkRepositoryProvider $provider, PropertyAccessorInterface $accessor)
45
    {
46 2
        $this->provider = $provider;
47 2
        $this->accessor = $accessor;
48 2
    }
49
50
    /**
51
     * {@inheritdoc}
52
     */
53 1
    public function toResource($object, ResourceObject $resource, MappingContext $context)
54
    {
55 1
        $this->handleLinks($object, $context->getDefinition(), $resource);
56 1
    }
57
58
    /**
59
     * {@inheritdoc}
60
     */
61 2
    public function handleLinks(
62
        $object,
63
        LinksAwareDefinitionInterface $definition,
64
        LinksAwareDocumentInterface   $document,
65
        array $scope = []
66
    ) {
67 2
        foreach ($definition->getLinks() as $linkDefinition)
68
        {
69 2
            $repoName = $linkDefinition->getRepositoryName();
70 2
            $linkName = $linkDefinition->getLinkName();
71
72 2
            $parameters = $this->resolveParameters($object, $linkDefinition, $scope);
73
74 2
            $linkData = $this->provider
75 2
                ->getRepository($repoName)
76 2
                ->getLink($linkName, $parameters);
77
78 2
            $link = $this->createLink($linkDefinition, $linkData);
79
80 2
            $document->setLink($linkDefinition->getName(), $link);
81
        }
82 2
    }
83
84
    /**
85
     * Create link-object
86
     *
87
     * @param  LinkDefinition $definition
88
     * @param  LinkData       $data
89
     * @return LinkObject
90
     */
91 2
    protected function createLink(LinkDefinition $definition, LinkData $data): LinkObject
92
    {
93 2
        $reference = $data->getReference();
94
95 2
        $metadata = array_replace(
96 2
            $data->getMetadata(),
97 2
            $definition->getMetadata()
98
        );
99
100 2
        return new LinkObject($reference, $metadata);
101
    }
102
103
    /**
104
     * Resolve parameters
105
     *
106
     * @param  mixed          $object
107
     * @param  LinkDefinition $definition
108
     * @param  array          $scope
109
     * @return array
110
     */
111 2
    protected function resolveParameters($object, LinkDefinition $definition, array $scope): array
112
    {
113 2
        $resolved = [];
114
115 2
        foreach ($definition->getParameters() as $name => $value)
116
        {
117 2
            if (! preg_match('~@(?:(?<namespace>[a-z0-9_\.]+)\:)?(?<name>[a-z0-9_\.]+)~i', $value, $matches)) {
118 2
                $resolved[$name] = $value;
119 2
                continue;
120
            }
121
122 1
            if (empty($matches['namespace'])) {
123 1
                $resolved[$name] = $this->accessor->getValue($object, $matches['name']);
124 1
                continue;
125
            }
126
127 1
            if (! isset($scope[$matches['namespace']])) {
128
                throw new \LogicException(sprintf('Object "%s" not found in the scope.', $matches['namespace']));
129
            }
130
131 1
            $resolved[$name] = $this->accessor->getValue(
132 1
                $scope[$matches['namespace']],
133 1
                $matches['name']
134
            );
135
        }
136
137 2
        return $resolved;
138
    }
139
140
    /**
141
     * {@inheritdoc}
142
     */
143
    public function fromResource($object, ResourceObject $resource, MappingContext $context)
144
    {
145
        // Do nothing
146
    }
147
}