CreatedResourceRenderer::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BEAR\Package\Provide\Representation;
6
7
use BEAR\Package\Exception\LocationHeaderRequestException;
8
use BEAR\Resource\RenderInterface;
9
use BEAR\Resource\ResourceInterface;
10
use BEAR\Resource\ResourceObject;
11
use BEAR\Sunday\Extension\Router\RouterInterface;
12
use Throwable;
13
14
use function is_string;
15
use function parse_str;
16
use function parse_url;
17
use function sprintf;
18
19
use const PHP_URL_HOST;
20
use const PHP_URL_PATH;
21
use const PHP_URL_QUERY;
22
use const PHP_URL_SCHEME;
23
24
/**
25
 * 201 CreatedResource renderer
26
 */
27
class CreatedResourceRenderer implements RenderInterface
28
{
29
    /** @var RouterInterface */
30
    private $router;
31
32
    /** @var ResourceInterface */
33
    private $resource;
34
35
    public function __construct(RouterInterface $router, ResourceInterface $resource)
36
    {
37
        $this->router = $router;
38
        $this->resource = $resource;
39
    }
40
41
    /**
42
     * {@inheritdoc}
43
     */
44
    public function render(ResourceObject $ro)
45
    {
46
        $urlSchema = (string) parse_url((string) $ro->uri, PHP_URL_SCHEME);
47
        $urlHost = (string) parse_url((string) $ro->uri, PHP_URL_HOST);
48
        $locationUri = sprintf('%s://%s%s', $urlSchema, $urlHost, $ro->headers['Location']);
49
        try {
50
            $locatedResource = $this->resource->uri($locationUri)();
51
        } catch (Throwable $e) {
52
            $ro->code = 500;
53
            $ro->view = '';
54
55
            throw new LocationHeaderRequestException($locationUri, 0, $e);
56
        }
57
58
        $this->updateHeaders($ro);
59
        $ro->view = $locatedResource->toString();
60
61
        return $ro->view;
62
    }
63
64
    private function getReverseMatchedLink(string $uri): string
65
    {
66
        $routeName = (string) parse_url($uri, PHP_URL_PATH);
67
        $urlQuery = (string) parse_url($uri, PHP_URL_QUERY);
68
        $urlQuery ? parse_str($urlQuery, $value) : $value = [];
69
        if ($value === []) {
70
            return $uri;
71
        }
72
73
        /** @var array<string, mixed> $value */
74
        $reverseUri = $this->router->generate($routeName, $value);
75
        if (is_string($reverseUri)) {
76
            return $reverseUri;
77
        }
78
79
        return $uri;
80
    }
81
82
    private function updateHeaders(ResourceObject $ro): void
83
    {
84
        $ro->headers['content-type'] = 'application/hal+json';
85
        if (isset($ro->headers['Location'])) {
86
            $ro->headers['Location'] = $this->getReverseMatchedLink($ro->headers['Location']);
87
        }
88
    }
89
}
90