Completed
Push — 1.x ( 2c7718...1ed52f )
by Akihito
10s
created

HalRenderer::valuateElements()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 16
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 7.1753

Importance

Changes 0
Metric Value
dl 0
loc 16
ccs 5
cts 12
cp 0.4167
rs 9.2
c 0
b 0
f 0
cc 4
eloc 11
nc 4
nop 1
crap 7.1753
1
<?php
2
3
declare(strict_types=1);
4
/**
5
 * This file is part of the BEAR.Resource package.
6
 *
7
 * @license http://opensource.org/licenses/MIT MIT
8
 */
9
namespace BEAR\Resource;
10
11
use BEAR\Resource\Annotation\Link;
12
use Doctrine\Common\Annotations\Reader;
13
use Nocarrier\Hal;
14
15
class HalRenderer implements RenderInterface
16
{
17
    /**
18
     * @var Reader
19
     */
20
    private $reader;
21
22 1
    public function __construct(Reader $reader)
23
    {
24 1
        $this->reader = $reader;
25 1
    }
26
27
    /**
28
     * {@inheritdoc}
29
     *
30
     * @throws \RuntimeException
31
     */
32 1
    public function render(ResourceObject $ro)
33
    {
34 1
        list($ro, $body) = $this->valuate($ro);
35
36 1
        $method = 'on' . ucfirst($ro->uri->method);
37 1
        $hasMethod = method_exists($ro, $method);
38 1
        $annotations = $hasMethod ? $this->reader->getMethodAnnotations(new \ReflectionMethod($ro, $method)) : [];
39
        /* @var $annotations Link[] */
40 1
        $hal = $this->getHal($ro->uri, $body, $annotations);
41 1
        $ro->view = $hal->asJson(true) . PHP_EOL;
42 1
        $ro->headers['Content-Type'] = 'application/hal+json';
43
44 1
        return $ro->view;
45
    }
46
47 1
    private function valuateElements(ResourceObject &$ro)
48
    {
49 1
        foreach ($ro->body as $key => &$embeded) {
50 1
            if ($embeded instanceof AbstractRequest) {
51
                $isDefferentSchema = $this->isDifferentSchema($ro, $embeded->resourceObject);
52
                if ($isDefferentSchema === true) {
53
                    $ro->body['_embedded'][$key] = $embeded()->body;
54
                    unset($ro->body[$key]);
55
                    continue;
56
                }
57
                unset($ro->body[$key]);
58
                $view = $this->render($embeded());
59 1
                $ro->body['_embedded'][$key] = json_decode($view);
60
            }
61
        }
62 1
    }
63
64
    /**
65
     * Return "is different schema" (page <-> app)
66
     */
67
    private function isDifferentSchema(ResourceObject $parentRo, ResourceObject $childRo) : bool
68
    {
69
        return $parentRo->uri->scheme . $parentRo->uri->host !== $childRo->uri->scheme . $childRo->uri->host;
70
    }
71
72 1
    private function getReverseMatchedLink(string $uri) : string
73
    {
74 1
        return $uri;
75
    }
76
77 1
    private function getHal(AbstractUri $uri, array $body, array $annotations) : Hal
78
    {
79 1
        $query = $uri->query ? '?' . http_build_query($uri->query) : '';
80 1
        $path = $uri->path . $query;
81 1
        $selfLink = $this->getReverseMatchedLink($path);
82 1
        $hal = new Hal($selfLink, $body);
83 1
        $this->addLinks($body, $annotations, $hal);
84
85 1
        return $hal;
86
    }
87
88 1
    private function valuate(ResourceObject $ro) : array
89
    {
90
        // evaluate all request in body.
91 1
        if (is_array($ro->body)) {
92 1
            $this->valuateElements($ro);
93
        }
94
        // HAL
95 1
        $body = $ro->body ?: [];
96 1
        if (is_scalar($body)) {
97
            $body = ['value' => $body];
98
99
            return [$ro, $body];
100
        }
101
102 1
        return[$ro, (array) $body];
103
    }
104
105 1
    private function addLinks(array $body, array $annotations, Hal $hal)
106
    {
107 1
        foreach ($annotations as $annotation) {
108 1
            if ($annotation instanceof Link) {
109 1
                $uri = uri_template($annotation->href, $body);
110 1
                $reverseUri = $this->getReverseMatchedLink($uri);
111 1
                $hal->addLink($annotation->rel, $reverseUri);
112
            }
113
        }
114 1
    }
115
}
116