Passed
Pull Request — 1.x (#339)
by Akihito
05:17 queued 02:26
created

OptionsRenderer   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 61
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 16
dl 0
loc 61
ccs 17
cts 17
cp 1
rs 10
c 1
b 0
f 0
wmc 8
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BEAR\Resource;
6
7
use BEAR\Resource\Annotation\OptionsBody;
8
use Override;
9
use ReflectionClass;
10
use ReflectionMethod;
11
12
use function implode;
13
use function in_array;
14
use function json_encode;
15
use function strtoupper;
16
use function substr;
17
18
use const JSON_PRETTY_PRINT;
19
use const JSON_UNESCAPED_SLASHES;
20
use const PHP_EOL;
21
22 99
/**
23
 * RFC2616 OPTIONS method renderer
24 99
 *
25 99
 * Set resource request information to `headers` and `view` in ResourceObject.
26
 *
27
 * @see https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
28
 * @see /docs/options/README.md
29
 * @psalm-import-type OptionsEntityBody from Types
30 7
 */
31
final readonly class OptionsRenderer implements RenderInterface
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected T_READONLY, expecting T_CLASS on line 31 at column 6
Loading history...
32 7
{
33 7
    /** @SuppressWarnings(PHPMD.BooleanArgumentFlag) $optionsBody is configuration flag, not behavior control */
34 7
    public function __construct(
35 7
        private OptionsMethods $optionsMethod,
36 7
        #[OptionsBody]
37
        private bool $optionsBody = true,
38 7
    ) {
39
    }
40
41
    /**
42
     * {@inheritDoc}
43
     */
44
    #[Override]
45
    public function render(ResourceObject $ro)
46
    {
47
        $ro->headers['Content-Type'] = 'application/json';
48 7
        $allows = $this->getAllows((new ReflectionClass($ro))->getMethods());
49
        $ro->headers['Allow'] = implode(', ', $allows);
50 7
        $ro->view = $this->optionsBody ? (string) json_encode($this->getEntityBody($ro, $allows), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . PHP_EOL : '';
51 7
52 7
        return $ro->view;
53 7
    }
54
55
    /**
56
     * Return allowed methods
57 7
     *
58
     * @param ReflectionMethod[] $methods
59
     *
60
     * @return string[]
61
     * @psalm-return list<string>
62
     */
63 7
    private function getAllows(array $methods): array
64
    {
65 7
        $allows = [];
66 7
        foreach ($methods as $method) {
67 7
            if (! in_array($method->name, ['onGet', 'onPost', 'onPut', 'onPatch', 'onDelete', 'onHead'], true)) {
68
                continue;
69
            }
70 7
71
            $allows[] = strtoupper(substr($method->name, 2));
72
        }
73
74
        return $allows;
75
    }
76
77
    /**
78
     * Return OPTIONS entity body
79
     *
80
     * @param list<string> $allows
81
     *
82
     * @return OptionsEntityBody
83
     */
84
    private function getEntityBody(ResourceObject $ro, array $allows): array
85
    {
86
        $mehtodList = [];
87
        foreach ($allows as $method) {
88
            $mehtodList[$method] = ($this->optionsMethod)($ro, $method);
89
        }
90
91
        return $mehtodList;
92
    }
93
}
94