Passed
Pull Request — 1.x (#321)
by Akihito
02:24
created

OptionsRenderer   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 60
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 15
dl 0
loc 60
rs 10
c 0
b 0
f 0
wmc 8

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getAllows() 0 12 3
A __construct() 0 5 1
A getEntityBody() 0 8 2
A render() 0 8 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BEAR\Resource\Options;
6
7
use BEAR\Resource\Annotation\OptionsBody;
8
use BEAR\Resource\RenderInterface;
9
use BEAR\Resource\ResourceObject;
10
use ReflectionClass;
11
use ReflectionMethod;
12
13
use function implode;
14
use function in_array;
15
use function json_encode;
16
use function strtoupper;
17
use function substr;
18
19
use const JSON_PRETTY_PRINT;
20
use const JSON_UNESCAPED_SLASHES;
21
use const PHP_EOL;
22
23
/**
24
 * RFC2616 OPTIONS method renderer
25
 *
26
 * Set resource request information to `headers` and `view` in ResourceObject.
27
 *
28
 * @see https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
29
 * @see /docs/options/README.md
30
 * @psalm-import-type OptionParamDoc from OptionsMethods
31
 */
32
final class OptionsRenderer implements RenderInterface
33
{
34
    /** @SuppressWarnings(PHPMD.BooleanArgumentFlag) */
35
    public function __construct(
36
        private readonly OptionsMethods $optionsMethod,
37
        #[OptionsBody]
38
        private readonly bool $optionsBody = true,
39
    ) {
40
    }
41
42
    /**
43
     * {@inheritDoc}
44
     */
45
    public function render(ResourceObject $ro)
46
    {
47
        $ro->headers['Content-Type'] = 'application/json';
48
        $allows = $this->getAllows((new ReflectionClass($ro))->getMethods());
49
        $ro->headers['Allow'] = implode(', ', $allows);
50
        $ro->view = $this->optionsBody ? json_encode($this->getEntityBody($ro, $allows), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . PHP_EOL : '';
51
52
        return $ro->view;
53
    }
54
55
    /**
56
     * Return allowed methods
57
     *
58
     * @param ReflectionMethod[] $methods
59
     *
60
     * @return string[]
61
     * @psalm-return list<string>
62
     */
63
    private function getAllows(array $methods): array
64
    {
65
        $allows = [];
66
        foreach ($methods as $method) {
67
            if (! in_array($method->name, ['onGet', 'onPost', 'onPut', 'onPatch', 'onDelete', 'onHead'], true)) {
68
                continue;
69
            }
70
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
0 ignored issues
show
Bug introduced by
The type BEAR\Resource\Options\list was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
81
     *
82
     * @return array<string, OptionParamDoc>
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